From 4734214ac15d29090797e145ac111a49786e632a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 1 Mar 2023 07:20:36 -0500 Subject: [PATCH] LibWeb: Skip over grapheme clusters on left/right arrow key presses Currently, if you use the left/right arrow keys to move over a multi- code point glyph, we will move through that glyph one code point at a time. This means you can "pause" your movement in the middle of a glyph and delete a subsection of a grapheme cluster. This now moves the cursor across the entire cluster. --- Userland/Libraries/LibWeb/DOM/Position.cpp | 29 ++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Position.cpp b/Userland/Libraries/LibWeb/DOM/Position.cpp index 67b2a7168e..a82e4ba58c 100644 --- a/Userland/Libraries/LibWeb/DOM/Position.cpp +++ b/Userland/Libraries/LibWeb/DOM/Position.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -33,38 +34,30 @@ bool Position::increment_offset() auto& node = verify_cast(*m_node); auto text = Utf8View(node.data()); - for (auto iterator = text.begin(); !iterator.done(); ++iterator) { - if (text.byte_offset_of(iterator) >= m_offset) { - // NOTE: If the current offset is inside a multi-byte code point, it will be moved to the start of the next code point. - m_offset = text.byte_offset_of(++iterator); - return true; - } + if (auto offset = Unicode::next_grapheme_segmentation_boundary(text, m_offset); offset.has_value()) { + m_offset = *offset; + return true; } + // NOTE: Already at end of current node. return false; } bool Position::decrement_offset() { - if (m_offset == 0 || !is(*m_node)) + if (!is(*m_node)) return false; auto& node = verify_cast(*m_node); auto text = Utf8View(node.data()); - size_t last_smaller_offset = 0; - - for (auto iterator = text.begin(); !iterator.done(); ++iterator) { - auto byte_offset = text.byte_offset_of(iterator); - if (byte_offset >= m_offset) { - break; - } - last_smaller_offset = text.byte_offset_of(iterator); + if (auto offset = Unicode::previous_grapheme_segmentation_boundary(text, m_offset); offset.has_value()) { + m_offset = *offset; + return true; } - // NOTE: If the current offset is inside a multi-byte code point, it will be moved to the start of that code point. - m_offset = last_smaller_offset; - return true; + // NOTE: Already at beginning of current node. + return false; } bool Position::offset_is_at_end_of_node() const