瀏覽代碼

LibWeb: Allow inserting text at the cursor by typing characters :^)

This works everywhere right now, but it's obviously not going to stay
that way forever. :^)

Note that this does not advance the cursor correctly for whitespace
since the cursor is DOM-based and doesn't take whitespace collapsing
into account yet.
Andreas Kling 5 年之前
父節點
當前提交
bc299754f6

+ 2 - 0
Libraries/LibWeb/DOM/Position.h

@@ -38,6 +38,8 @@ public:
 
     ~Position();
 
+    bool is_valid() const { return m_node; }
+
     Node* node() { return m_node; }
     const Node* node() const { return m_node; }
 

+ 19 - 0
Libraries/LibWeb/Page/EventHandler.cpp

@@ -28,6 +28,7 @@
 #include <LibGUI/Window.h>
 #include <LibJS/Runtime/Value.h>
 #include <LibWeb/DOM/Document.h>
+#include <LibWeb/DOM/Text.h>
 #include <LibWeb/HTML/HTMLAnchorElement.h>
 #include <LibWeb/HTML/HTMLIFrameElement.h>
 #include <LibWeb/Layout/LayoutDocument.h>
@@ -228,4 +229,22 @@ void EventHandler::dump_selection(const char* event_name) const
 #endif
 }
 
+bool EventHandler::handle_keydown(KeyCode, unsigned, u32 code_point)
+{
+    if (code_point && m_frame.cursor_position().is_valid() && is<DOM::Text>(*m_frame.cursor_position().node())) {
+        auto& text_node = downcast<DOM::Text>(*m_frame.cursor_position().node());
+        StringBuilder builder;
+        builder.append(text_node.data().substring_view(0, m_frame.cursor_position().offset()));
+        builder.append_codepoint(code_point);
+        builder.append(text_node.data().substring_view(m_frame.cursor_position().offset(), text_node.data().length() - m_frame.cursor_position().offset()));
+        text_node.set_data(builder.to_string());
+        // FIXME: This will advance the cursor incorrectly when inserting multiple whitespaces (DOM vs layout whitespace collapse difference.)
+        m_frame.set_cursor_position({ *m_frame.cursor_position().node(), m_frame.cursor_position().offset() + 1 });
+        // FIXME: This should definitely use incremental layout invalidation instead!
+        text_node.document().force_layout();
+        return true;
+    }
+    return true;
+}
+
 }

+ 3 - 0
Libraries/LibWeb/Page/EventHandler.h

@@ -27,6 +27,7 @@
 #pragma once
 
 #include <AK/Forward.h>
+#include <Kernel/API/KeyCode.h>
 #include <LibGUI/Forward.h>
 #include <LibGfx/Forward.h>
 #include <LibWeb/Forward.h>
@@ -44,6 +45,8 @@ public:
     bool handle_mousedown(const Gfx::IntPoint&, unsigned button, unsigned modifiers);
     bool handle_mousemove(const Gfx::IntPoint&, unsigned buttons, unsigned modifiers);
 
+    bool handle_keydown(KeyCode, unsigned modifiers, u32 code_point);
+
 private:
     LayoutDocument* layout_root();
     const LayoutDocument* layout_root() const;

+ 1 - 0
Libraries/LibWeb/Page/Frame.h

@@ -85,6 +85,7 @@ public:
     Gfx::IntPoint to_main_frame_position(const Gfx::IntPoint&);
     Gfx::IntRect to_main_frame_rect(const Gfx::IntRect&);
 
+    DOM::Position& cursor_position() { return m_cursor_position; }
     const DOM::Position& cursor_position() const { return m_cursor_position; }
     void set_cursor_position(const DOM::Position&);
 

+ 5 - 0
Libraries/LibWeb/Page/Page.cpp

@@ -65,4 +65,9 @@ bool Page::handle_mousemove(const Gfx::IntPoint& position, unsigned buttons, uns
     return main_frame().event_handler().handle_mousemove(position, buttons, modifiers);
 }
 
+bool Page::handle_keydown(KeyCode key, unsigned modifiers, u32 code_point)
+{
+    return main_frame().event_handler().handle_keydown(key, modifiers, code_point);
+}
+
 }

+ 3 - 0
Libraries/LibWeb/Page/Page.h

@@ -29,6 +29,7 @@
 #include <AK/Noncopyable.h>
 #include <AK/OwnPtr.h>
 #include <AK/RefPtr.h>
+#include <Kernel/API/KeyCode.h>
 #include <LibGUI/Window.h>
 #include <LibGfx/Forward.h>
 #include <LibGfx/Palette.h>
@@ -58,6 +59,8 @@ public:
     bool handle_mousedown(const Gfx::IntPoint&, unsigned button, unsigned modifiers);
     bool handle_mousemove(const Gfx::IntPoint&, unsigned buttons, unsigned modifiers);
 
+    bool handle_keydown(KeyCode, unsigned modifiers, u32 code_point);
+
     Gfx::Palette palette() const;
 
 private:

+ 2 - 0
Libraries/LibWeb/PageView.cpp

@@ -335,6 +335,8 @@ void PageView::mouseup_event(GUI::MouseEvent& event)
 
 void PageView::keydown_event(GUI::KeyEvent& event)
 {
+    page().handle_keydown(event.key(), event.modifiers(), event.code_point());
+
     if (event.modifiers() == 0) {
         switch (event.key()) {
         case Key_Home: