@@ -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<Utf16FlyString> const &);
6769static 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);
100102extern " C" void ladybird_html_parser_set_script_source_line (void *, size_t , size_t );
101103extern " C" void ladybird_html_parser_mark_script_already_started (void *, size_t );
102104extern " 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 );
103107extern " 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 );
104108extern " C" void ladybird_html_parser_append_child (size_t , size_t );
105109extern " 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+
21072129extern " 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+
22252255extern " 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