Skip to content

Commit 7dffe07

Browse files
committed
LibWeb: Use an adjusted insertion location struct
1 parent b6f584f commit 7dffe07

2 files changed

Lines changed: 133 additions & 59 deletions

File tree

Libraries/LibWeb/HTML/Parser/HTMLParser.cpp

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ GC_DEFINE_ALLOCATOR(HTMLParser);
6262
GC_DEFINE_ALLOCATOR(HTMLParserEndState);
6363

6464
static DOM::Node& node_from_html_parser_ffi(size_t);
65+
struct NodeAndOffset;
66+
static NodeAndOffset node_and_offset_from_html_parser_ffi(size_t, size_t);
6567
static HTMLParser& parser_from_html_parser_ffi(void*);
6668
static RustFfiHtmlNamespace namespace_to_html_parser_ffi(Optional<Utf16FlyString> const&);
6769
static RustFfiHtmlAttributeNamespace attribute_namespace_to_html_parser_ffi(Optional<Utf16FlyString> const&);
@@ -100,6 +102,8 @@ extern "C" void ladybird_html_parser_prepare_svg_script(void*, size_t, size_t);
100102
extern "C" void ladybird_html_parser_set_script_source_line(void*, size_t, size_t);
101103
extern "C" void ladybird_html_parser_mark_script_already_started(void*, size_t);
102104
extern "C" size_t ladybird_html_parser_parent_node(size_t);
105+
extern "C" size_t ladybird_html_parser_node_index(size_t);
106+
extern "C" size_t ladybird_html_parser_child_count(size_t);
103107
extern "C" size_t ladybird_html_parser_create_element(void*, size_t, RustFfiHtmlNamespace, u16 const*, size_t, u16 const*, size_t, RustFfiHtmlParserAttribute const*, size_t, bool, size_t, bool);
104108
extern "C" void ladybird_html_parser_append_child(size_t, size_t);
105109
extern "C" void ladybird_html_parser_insert_node(size_t, size_t, size_t, bool);
@@ -2104,6 +2108,24 @@ static DOM::Node& node_from_html_parser_ffi(size_t node)
21042108
return *reinterpret_cast<DOM::Node*>(node);
21052109
}
21062110

2111+
struct NodeAndOffset {
2112+
GC::Ref<DOM::Node> node;
2113+
size_t offset;
2114+
2115+
DOM::Node* child_at_offset() const
2116+
{
2117+
VERIFY(offset <= node->child_count());
2118+
return node->child_at_index(offset);
2119+
}
2120+
};
2121+
2122+
static NodeAndOffset node_and_offset_from_html_parser_ffi(size_t node, size_t offset)
2123+
{
2124+
auto& dom_node = node_from_html_parser_ffi(node);
2125+
VERIFY(offset <= dom_node.child_count());
2126+
return { dom_node, offset };
2127+
}
2128+
21072129
extern "C" size_t ladybird_html_parser_document_node(void* parser)
21082130
{
21092131
return reinterpret_cast<size_t>(&parser_from_html_parser_ffi(parser).document());
@@ -2141,26 +2163,24 @@ extern "C" size_t ladybird_html_parser_create_comment(void* parser, u8 const* da
21412163
return reinterpret_cast<size_t>(comment.ptr());
21422164
}
21432165

2144-
extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t before, u8 const* data_ptr, size_t data_len)
2166+
extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t offset, u8 const* data_ptr, size_t data_len)
21452167
{
2146-
auto& parent_node = node_from_html_parser_ffi(parent);
2168+
auto insertion_location = node_and_offset_from_html_parser_ffi(parent, offset);
2169+
auto& parent_node = *insertion_location.node;
21472170
if (parent_node.is_document())
21482171
return;
21492172

21502173
auto data = Utf16String::from_utf8(ffi_string(data_ptr, data_len));
2151-
if (before) {
2152-
auto& before_node = node_from_html_parser_ffi(before);
2153-
if (auto* previous_text = as_if<DOM::Text>(before_node.previous_sibling())) {
2174+
if (offset > 0) {
2175+
if (auto* previous_text = as_if<DOM::Text>(parent_node.child_at_index(offset - 1))) {
21542176
(void)previous_text->append_data(data);
21552177
return;
21562178
}
2157-
auto text = parent_node.document().realm().create<DOM::Text>(parent_node.document(), data);
2158-
parent_node.insert_before(*text, &before_node);
2159-
return;
21602179
}
21612180

2162-
if (auto* last_text = as_if<DOM::Text>(parent_node.last_child())) {
2163-
(void)last_text->append_data(data);
2181+
if (auto* before_node = insertion_location.child_at_offset()) {
2182+
auto text = parent_node.document().realm().create<DOM::Text>(parent_node.document(), data);
2183+
parent_node.insert_before(*text, before_node);
21642184
return;
21652185
}
21662186

@@ -2222,6 +2242,16 @@ extern "C" size_t ladybird_html_parser_parent_node(size_t node)
22222242
return reinterpret_cast<size_t>(parent);
22232243
}
22242244

2245+
extern "C" size_t ladybird_html_parser_node_index(size_t node)
2246+
{
2247+
return node_from_html_parser_ffi(node).index();
2248+
}
2249+
2250+
extern "C" size_t ladybird_html_parser_child_count(size_t node)
2251+
{
2252+
return node_from_html_parser_ffi(node).child_count();
2253+
}
2254+
22252255
extern "C" size_t ladybird_html_parser_create_element(void* parser, size_t intended_parent, RustFfiHtmlNamespace namespace_, u16 const* namespace_uri_ptr, size_t namespace_uri_len, u16 const* local_name_ptr, size_t local_name_len, RustFfiHtmlParserAttribute const* attributes, size_t attribute_count, bool had_duplicate_attribute, size_t form_element, bool has_template_element_on_stack)
22262256
{
22272257
auto& html_parser = parser_from_html_parser_ffi(parser);
@@ -2255,20 +2285,19 @@ extern "C" void ladybird_html_parser_append_child(size_t parent, size_t child)
22552285
MUST(node_from_html_parser_ffi(parent).append_child(node_from_html_parser_ffi(child)));
22562286
}
22572287

2258-
extern "C" void ladybird_html_parser_insert_node(size_t parent, size_t before, size_t child, bool queue_custom_element_reactions)
2288+
extern "C" void ladybird_html_parser_insert_node(size_t parent, size_t offset, size_t child, bool queue_custom_element_reactions)
22592289
{
2260-
auto& parent_node = node_from_html_parser_ffi(parent);
2290+
auto insertion_location = node_and_offset_from_html_parser_ffi(parent, offset);
2291+
auto& parent_node = *insertion_location.node;
22612292
auto& child_node = node_from_html_parser_ffi(child);
22622293
auto* child_element = as_if<DOM::Element>(child_node);
22632294
if (queue_custom_element_reactions && child_element)
22642295
relevant_similar_origin_window_agent(*child_element).custom_element_reactions_stack.element_queue_stack.append({});
22652296

2266-
if (!before) {
2297+
if (auto* before_node = insertion_location.child_at_offset())
2298+
parent_node.insert_before(child_node, before_node, false);
2299+
else
22672300
MUST(parent_node.append_child(child_node));
2268-
} else {
2269-
auto& before_node = node_from_html_parser_ffi(before);
2270-
parent_node.insert_before(child_node, &before_node, false);
2271-
}
22722301

22732302
if (queue_custom_element_reactions && child_element) {
22742303
auto queue = relevant_similar_origin_window_agent(*child_element).custom_element_reactions_stack.element_queue_stack.take_last();

0 commit comments

Comments
 (0)