diff options
author | Andreas Kling <kling@serenityos.org> | 2020-08-06 19:21:59 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-06 19:59:24 +0200 |
commit | 1c7faa89654853eb5b295f67861cca59fa4ef344 (patch) | |
tree | 6c6b0451bdb3e938df7b672330db5044b3c300e6 /Libraries/LibWeb | |
parent | 90efba95c1637b2c0a1b042aa59a6f604b1645bc (diff) | |
download | serenity-1c7faa89654853eb5b295f67861cca59fa4ef344.zip |
LibWeb: Move text selection serialization from PageView to Frame
This logic doesn't depend on anything at the widget layer, so it can
move down to the frame layer.
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r-- | Libraries/LibWeb/Page/Frame.cpp | 51 | ||||
-rw-r--r-- | Libraries/LibWeb/Page/Frame.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/PageView.cpp | 43 |
3 files changed, 54 insertions, 42 deletions
diff --git a/Libraries/LibWeb/Page/Frame.cpp b/Libraries/LibWeb/Page/Frame.cpp index e81e9722b6..6db661242c 100644 --- a/Libraries/LibWeb/Page/Frame.cpp +++ b/Libraries/LibWeb/Page/Frame.cpp @@ -26,7 +26,9 @@ #include <LibWeb/DOM/Document.h> #include <LibWeb/HTML/HTMLAnchorElement.h> +#include <LibWeb/Layout/LayoutBreak.h> #include <LibWeb/Layout/LayoutDocument.h> +#include <LibWeb/Layout/LayoutText.h> #include <LibWeb/Layout/LayoutWidget.h> #include <LibWeb/Page/Frame.h> #include <LibWeb/PageView.h> @@ -180,7 +182,7 @@ Gfx::IntPoint Frame::to_main_frame_position(const Gfx::IntPoint& a_position) return position; } -void Frame::set_cursor_position(const DOM::Position & position) +void Frame::set_cursor_position(const DOM::Position& position) { if (m_cursor_position == position) return; @@ -196,4 +198,51 @@ void Frame::set_cursor_position(const DOM::Position & position) dbg() << "Cursor position: " << m_cursor_position; } +String Frame::selected_text() const +{ + StringBuilder builder; + if (!m_document) + return {}; + auto* layout_root = m_document->layout_node(); + if (!layout_root) + return {}; + if (!layout_root->selection().is_valid()) + return {}; + + auto selection = layout_root->selection().normalized(); + + if (selection.start().layout_node == selection.end().layout_node) { + if (!is<LayoutText>(*selection.start().layout_node)) + return ""; + return downcast<LayoutText>(*selection.start().layout_node).text_for_rendering().substring(selection.start().index_in_node, selection.end().index_in_node - selection.start().index_in_node + 1); + } + + // Start node + auto layout_node = selection.start().layout_node; + if (is<LayoutText>(*layout_node)) { + auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); + builder.append(text.substring(selection.start().index_in_node, text.length() - selection.start().index_in_node)); + } + + // Middle nodes + layout_node = layout_node->next_in_pre_order(); + while (layout_node && layout_node != selection.end().layout_node) { + if (is<LayoutText>(*layout_node)) + builder.append(downcast<LayoutText>(*layout_node).text_for_rendering()); + else if (is<LayoutBreak>(*layout_node) || is<LayoutBlock>(*layout_node)) + builder.append('\n'); + + layout_node = layout_node->next_in_pre_order(); + } + + // End node + ASSERT(layout_node == selection.end().layout_node); + if (is<LayoutText>(*layout_node)) { + auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); + builder.append(text.substring(0, selection.end().index_in_node + 1)); + } + + return builder.to_string(); +} + } diff --git a/Libraries/LibWeb/Page/Frame.h b/Libraries/LibWeb/Page/Frame.h index 8ee452a29e..4be5139ee1 100644 --- a/Libraries/LibWeb/Page/Frame.h +++ b/Libraries/LibWeb/Page/Frame.h @@ -91,6 +91,8 @@ public: bool cursor_blink_state() const { return m_cursor_blink_state; } + String selected_text() const; + private: explicit Frame(DOM::Element& host_element, Frame& main_frame); explicit Frame(Page&); diff --git a/Libraries/LibWeb/PageView.cpp b/Libraries/LibWeb/PageView.cpp index b4f6e34a30..8cab744523 100644 --- a/Libraries/LibWeb/PageView.cpp +++ b/Libraries/LibWeb/PageView.cpp @@ -115,47 +115,8 @@ void PageView::select_all() String PageView::selected_text() const { - StringBuilder builder; - auto* layout_root = this->layout_root(); - if (!layout_root) - return {}; - if (!layout_root->selection().is_valid()) - return {}; - - auto selection = layout_root->selection().normalized(); - - if (selection.start().layout_node == selection.end().layout_node) { - if (!is<LayoutText>(*selection.start().layout_node)) - return ""; - return downcast<LayoutText>(*selection.start().layout_node).text_for_rendering().substring(selection.start().index_in_node, selection.end().index_in_node - selection.start().index_in_node + 1); - } - - // Start node - auto layout_node = selection.start().layout_node; - if (is<LayoutText>(*layout_node)) { - auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); - builder.append(text.substring(selection.start().index_in_node, text.length() - selection.start().index_in_node)); - } - - // Middle nodes - layout_node = layout_node->next_in_pre_order(); - while (layout_node && layout_node != selection.end().layout_node) { - if (is<LayoutText>(*layout_node)) - builder.append(downcast<LayoutText>(*layout_node).text_for_rendering()); - else if (is<LayoutBreak>(*layout_node) || is<LayoutBlock>(*layout_node)) - builder.append('\n'); - - layout_node = layout_node->next_in_pre_order(); - } - - // End node - ASSERT(layout_node == selection.end().layout_node); - if (is<LayoutText>(*layout_node)) { - auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); - builder.append(text.substring(0, selection.end().index_in_node + 1)); - } - - return builder.to_string(); + // FIXME: Use focused frame + return page().main_frame().selected_text(); } void PageView::page_did_layout() |