mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 20:45:14 +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:
parent
90efba95c1
commit
1c7faa8965
Notes:
sideshowbarker
2024-07-19 04:12:51 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/1c7faa89654
3 changed files with 54 additions and 42 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Reference in a new issue