@@ -62,6 +62,8 @@ GC_DEFINE_ALLOCATOR(HTMLParser);
6262GC_DEFINE_ALLOCATOR (HTMLParserEndState);
6363
6464static 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 );
6567static HTMLParser& parser_from_html_parser_ffi (void *);
6668static RustFfiHtmlNamespace namespace_to_html_parser_ffi (Optional<FlyString> const &);
6769static 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);
8486extern " C" void ladybird_html_parser_set_script_source_line (void *, size_t , size_t );
8587extern " C" void ladybird_html_parser_mark_script_already_started (void *, size_t );
8688extern " 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 );
8791extern " 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 );
8892extern " C" void ladybird_html_parser_append_child (size_t , size_t );
8993extern " 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+
20782100extern " 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+
21952225extern " 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