summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-08-06 19:21:59 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-06 19:59:24 +0200
commit1c7faa89654853eb5b295f67861cca59fa4ef344 (patch)
tree6c6b0451bdb3e938df7b672330db5044b3c300e6 /Libraries/LibWeb
parent90efba95c1637b2c0a1b042aa59a6f604b1645bc (diff)
downloadserenity-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.cpp51
-rw-r--r--Libraries/LibWeb/Page/Frame.h2
-rw-r--r--Libraries/LibWeb/PageView.cpp43
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()