diff options
author | asynts <asynts@gmail.com> | 2020-12-02 15:00:55 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-09 21:05:06 +0100 |
commit | 78558c9f301f65cd8d3597a080fe7f477e45fc79 (patch) | |
tree | 055249e032ddf8a5092f9422ae959a7eb48a3a4b /Libraries | |
parent | e96faea1a232a349c4db31657624a577eaa6f7a0 (diff) | |
download | serenity-78558c9f301f65cd8d3597a080fe7f477e45fc79.zip |
LibWeb: Add support for cursor movement and delete.
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibWeb/Page/EditEventHandler.cpp | 35 | ||||
-rw-r--r-- | Libraries/LibWeb/Page/EditEventHandler.h | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/Page/EventHandler.cpp | 43 |
3 files changed, 50 insertions, 29 deletions
diff --git a/Libraries/LibWeb/Page/EditEventHandler.cpp b/Libraries/LibWeb/Page/EditEventHandler.cpp index 20f8b7423c..c849877aca 100644 --- a/Libraries/LibWeb/Page/EditEventHandler.cpp +++ b/Libraries/LibWeb/Page/EditEventHandler.cpp @@ -40,13 +40,13 @@ namespace Web { void EditEventHandler::handle_delete(DOM::Range range) { - // FIXME: Find a better way of updating the selection and cursor position. + // FIXME: Deleting nodes seems to mess up the layout tree. Not sure if this is not entirely + // my fault or not my fault at all. + + dump_tree(*m_frame.document()); if (range.start().node() != range.end().node()) { if (range.start().node()->parent() == range.end().node()->parent()) { - m_frame.document()->layout_node()->set_selection({}); - m_frame.cursor_position().set_offset(range.start().offset()); - // Remove all intermediate nodes. auto* current = range.start().node()->next_sibling(); while (current != range.end().node()) { @@ -55,9 +55,6 @@ void EditEventHandler::handle_delete(DOM::Range range) current = next; } - if (!is<DOM::Text>(*range.start().node()) || !is<DOM::Text>(*range.end().node())) - TODO(); - // Join remaining text together. StringBuilder builder; builder.append(downcast<DOM::Text>(range.start().node())->data().substring_view(0, range.start().offset())); @@ -73,7 +70,6 @@ void EditEventHandler::handle_delete(DOM::Range range) } else { if (is<DOM::Text>(*range.start().node())) { m_frame.document()->layout_node()->set_selection({}); - m_frame.cursor_position().set_offset(range.start().offset()); auto& node = downcast<DOM::Text>(*range.start().node()); @@ -89,24 +85,8 @@ void EditEventHandler::handle_delete(DOM::Range range) // FIXME: We need to remove stale layout nodes when nodes are removed from the DOM. Currently, // this is the only way to get these to disappear. m_frame.document()->force_layout(); -} - -void EditEventHandler::handle_delete(DOM::Position position) -{ - if (position.offset() == 0) - TODO(); - - if (is<DOM::Text>(*position.node())) { - auto& node = downcast<DOM::Text>(*position.node()); - StringBuilder builder; - builder.append(node.data().substring_view(0, position.offset() - 1)); - builder.append(node.data().substring_view(position.offset())); - node.set_data(builder.to_string()); - - m_frame.cursor_position().set_offset(m_frame.cursor_position().offset() - 1); - node.invalidate_style(); - } + dump_tree(*m_frame.document()); } void EditEventHandler::handle_insert(DOM::Position position, u32 code_point) @@ -120,9 +100,12 @@ void EditEventHandler::handle_insert(DOM::Position position, u32 code_point) builder.append(node.data().substring_view(position.offset())); node.set_data(builder.to_string()); - m_frame.cursor_position().set_offset(m_frame.cursor_position().offset() + 1); node.invalidate_style(); } + + // FIXME: We need to remove stale layout nodes when nodes are removed from the DOM. Currently, + // this is the only way to get these to disappear. + m_frame.document()->force_layout(); } } diff --git a/Libraries/LibWeb/Page/EditEventHandler.h b/Libraries/LibWeb/Page/EditEventHandler.h index 3a630d67e3..dbcc04e7a1 100644 --- a/Libraries/LibWeb/Page/EditEventHandler.h +++ b/Libraries/LibWeb/Page/EditEventHandler.h @@ -39,7 +39,6 @@ public: virtual ~EditEventHandler() = default; - virtual void handle_delete(DOM::Position); virtual void handle_delete(DOM::Range); virtual void handle_insert(DOM::Position, u32 code_point); diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index e8e806d57c..93e05adcd6 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -348,6 +348,9 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin if (layout_root()->selection().is_valid()) { auto range = layout_root()->selection().to_dom_range(); + m_frame.document()->layout_node()->set_selection({}); + m_frame.set_cursor_position(range.start()); + if (key == KeyCode::Key_Backspace) { if (range.start().node()->is_editable()) { m_edit_event_handler->handle_delete(range); @@ -355,17 +358,54 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin } } else { m_edit_event_handler->handle_delete(range); + m_edit_event_handler->handle_insert(m_frame.cursor_position(), code_point); + m_frame.cursor_position().set_offset(m_frame.cursor_position().offset() + 1); return true; } } if (m_frame.cursor_position().is_valid() && m_frame.cursor_position().node()->is_editable()) { if (key == KeyCode::Key_Backspace) { - m_edit_event_handler->handle_delete(m_frame.cursor_position()); + auto position = m_frame.cursor_position(); + + if (position.offset() == 0) + TODO(); + + m_frame.cursor_position().set_offset(position.offset() - 1); + m_edit_event_handler->handle_delete({ { *position.node(), position.offset() - 1 }, position }); + + return true; + } else if (key == KeyCode::Key_Delete) { + auto position = m_frame.cursor_position(); + + if (position.offset() >= downcast<DOM::Text>(position.node())->data().length()) + TODO(); + + m_edit_event_handler->handle_delete({ position, { *position.node(), position.offset() + 1 } }); + + return true; + } else if (key == KeyCode::Key_Right) { + auto position = m_frame.cursor_position(); + + if (position.offset() >= downcast<DOM::Text>(position.node())->data().length()) + TODO(); + + m_frame.cursor_position().set_offset(position.offset() + 1); + + return true; + } else if (key == KeyCode::Key_Left) { + auto position = m_frame.cursor_position(); + + if (position.offset() == 0) + TODO(); + + m_frame.cursor_position().set_offset(position.offset() - 1); + return true; } else { m_edit_event_handler->handle_insert(m_frame.cursor_position(), code_point); + m_frame.cursor_position().set_offset(m_frame.cursor_position().offset() + 1); return true; } } @@ -380,5 +420,4 @@ void EventHandler::set_mouse_event_tracking_layout_node(Layout::Node* layout_nod else m_mouse_event_tracking_layout_node = nullptr; } - } |