Skip to content

Commit 7651e98

Browse files
committed
LibWeb: Use an adjusted insertion location struct
1 parent 5c62c62 commit 7651e98

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<FlyString> const&);
6769
static RustFfiHtmlAttributeNamespace attribute_namespace_to_html_parser_ffi(Optional<FlyString> const&);
@@ -84,6 +86,8 @@ extern "C" void ladybird_html_parser_prepare_svg_script(void*, size_t, size_t);
8486
extern "C" void ladybird_html_parser_set_script_source_line(void*, size_t, size_t);
8587
extern "C" void ladybird_html_parser_mark_script_already_started(void*, size_t);
8688
extern "C" size_t ladybird_html_parser_parent_node(size_t);
89+
extern "C" size_t ladybird_html_parser_node_index(size_t);
90+
extern "C" size_t ladybird_html_parser_child_count(size_t);
8791
extern "C" size_t ladybird_html_parser_create_element(void*, size_t, RustFfiHtmlNamespace, u8 const*, size_t, u8 const*, size_t, RustFfiHtmlParserAttribute const*, size_t, bool, size_t, bool);
8892
extern "C" void ladybird_html_parser_append_child(size_t, size_t);
8993
extern "C" void ladybird_html_parser_insert_node(size_t, size_t, size_t, bool);
@@ -2075,6 +2079,24 @@ static DOM::Node& node_from_html_parser_ffi(size_t node)
20752079
return *reinterpret_cast<DOM::Node*>(node);
20762080
}
20772081

2082+
struct NodeAndOffset {
2083+
GC::Ref<DOM::Node> node;
2084+
size_t offset;
2085+
2086+
DOM::Node* child_at_offset() const
2087+
{
2088+
VERIFY(offset <= node->child_count());
2089+
return node->child_at_index(offset);
2090+
}
2091+
};
2092+
2093+
static NodeAndOffset node_and_offset_from_html_parser_ffi(size_t node, size_t offset)
2094+
{
2095+
auto& dom_node = node_from_html_parser_ffi(node);
2096+
VERIFY(offset <= dom_node.child_count());
2097+
return { dom_node, offset };
2098+
}
2099+
20782100
extern "C" size_t ladybird_html_parser_document_node(void* parser)
20792101
{
20802102
return reinterpret_cast<size_t>(&parser_from_html_parser_ffi(parser).document());
@@ -2112,26 +2134,24 @@ extern "C" size_t ladybird_html_parser_create_comment(void* parser, u8 const* da
21122134
return reinterpret_cast<size_t>(comment.ptr());
21132135
}
21142136

2115-
extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t before, u8 const* data_ptr, size_t data_len)
2137+
extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t offset, u8 const* data_ptr, size_t data_len)
21162138
{
2117-
auto& parent_node = node_from_html_parser_ffi(parent);
2139+
auto insertion_location = node_and_offset_from_html_parser_ffi(parent, offset);
2140+
auto& parent_node = insertion_location.node;
21182141
if (parent_node.is_document())
21192142
return;
21202143

21212144
auto data = Utf16String::from_utf8(ffi_string(data_ptr, data_len));
2122-
if (before) {
2123-
auto& before_node = node_from_html_parser_ffi(before);
2124-
if (auto* previous_text = as_if<DOM::Text>(before_node.previous_sibling())) {
2145+
if (offset > 0) {
2146+
if (auto* previous_text = as_if<DOM::Text>(parent_node.child_at_index(offset - 1))) {
21252147
(void)previous_text->append_data(data);
21262148
return;
21272149
}
2128-
auto text = parent_node.document().realm().create<DOM::Text>(parent_node.document(), data);
2129-
parent_node.insert_before(*text, &before_node);
2130-
return;
21312150
}
21322151

2133-
if (auto* last_text = as_if<DOM::Text>(parent_node.last_child())) {
2134-
(void)last_text->append_data(data);
2152+
if (auto* before_node = insertion_location.child_at_offset()) {
2153+
auto text = parent_node.document().realm().create<DOM::Text>(parent_node.document(), data);
2154+
parent_node.insert_before(*text, before_node);
21352155
return;
21362156
}
21372157

@@ -2192,6 +2212,16 @@ extern "C" size_t ladybird_html_parser_parent_node(size_t node)
21922212
return reinterpret_cast<size_t>(parent);
21932213
}
21942214

2215+
extern "C" size_t ladybird_html_parser_node_index(size_t node)
2216+
{
2217+
return node_from_html_parser_ffi(node).index();
2218+
}
2219+
2220+
extern "C" size_t ladybird_html_parser_child_count(size_t node)
2221+
{
2222+
return node_from_html_parser_ffi(node).child_count();
2223+
}
2224+
21952225
extern "C" size_t ladybird_html_parser_create_element(void* parser, size_t intended_parent, RustFfiHtmlNamespace namespace_, u8 const* namespace_uri_ptr, size_t namespace_uri_len, u8 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)
21962226
{
21972227
auto& html_parser = parser_from_html_parser_ffi(parser);
@@ -2225,20 +2255,19 @@ extern "C" void ladybird_html_parser_append_child(size_t parent, size_t child)
22252255
MUST(node_from_html_parser_ffi(parent).append_child(node_from_html_parser_ffi(child)));
22262256
}
22272257

2228-
extern "C" void ladybird_html_parser_insert_node(size_t parent, size_t before, size_t child, bool queue_custom_element_reactions)
2258+
extern "C" void ladybird_html_parser_insert_node(size_t parent, size_t offset, size_t child, bool queue_custom_element_reactions)
22292259
{
2230-
auto& parent_node = node_from_html_parser_ffi(parent);
2260+
auto insertion_location = node_and_offset_from_html_parser_ffi(parent, offset);
2261+
auto& parent_node = insertion_location.node;
22312262
auto& child_node = node_from_html_parser_ffi(child);
22322263
auto* child_element = as_if<DOM::Element>(child_node);
22332264
if (queue_custom_element_reactions && child_element)
22342265
relevant_similar_origin_window_agent(*child_element).custom_element_reactions_stack.element_queue_stack.append({});
22352266

2236-
if (!before) {
2267+
if (auto* before_node = insertion_location.child_at_offset())
2268+
parent_node.insert_before(child_node, before_node, false);
2269+
else
22372270
MUST(parent_node.append_child(child_node));
2238-
} else {
2239-
auto& before_node = node_from_html_parser_ffi(before);
2240-
parent_node.insert_before(child_node, &before_node, false);
2241-
}
22422271

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

0 commit comments

Comments
 (0)