1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 12:48:10 +00:00

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.
This commit is contained in:
Andreas Kling 2020-08-06 19:21:59 +02:00
parent 90efba95c1
commit 1c7faa8965
3 changed files with 54 additions and 42 deletions

View file

@ -26,7 +26,9 @@
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLAnchorElement.h> #include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/Layout/LayoutBreak.h>
#include <LibWeb/Layout/LayoutDocument.h> #include <LibWeb/Layout/LayoutDocument.h>
#include <LibWeb/Layout/LayoutText.h>
#include <LibWeb/Layout/LayoutWidget.h> #include <LibWeb/Layout/LayoutWidget.h>
#include <LibWeb/Page/Frame.h> #include <LibWeb/Page/Frame.h>
#include <LibWeb/PageView.h> #include <LibWeb/PageView.h>
@ -180,7 +182,7 @@ Gfx::IntPoint Frame::to_main_frame_position(const Gfx::IntPoint& a_position)
return 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) if (m_cursor_position == position)
return; return;
@ -196,4 +198,51 @@ void Frame::set_cursor_position(const DOM::Position & position)
dbg() << "Cursor position: " << m_cursor_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();
}
} }

View file

@ -91,6 +91,8 @@ public:
bool cursor_blink_state() const { return m_cursor_blink_state; } bool cursor_blink_state() const { return m_cursor_blink_state; }
String selected_text() const;
private: private:
explicit Frame(DOM::Element& host_element, Frame& main_frame); explicit Frame(DOM::Element& host_element, Frame& main_frame);
explicit Frame(Page&); explicit Frame(Page&);

View file

@ -115,47 +115,8 @@ void PageView::select_all()
String PageView::selected_text() const String PageView::selected_text() const
{ {
StringBuilder builder; // FIXME: Use focused frame
auto* layout_root = this->layout_root(); return page().main_frame().selected_text();
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();
} }
void PageView::page_did_layout() void PageView::page_did_layout()