Browse Source

LibWeb: Handle inline stylesheets a bit better in the new parser

While we're still supporting both the old and the new parser, we have
to deal with the way they load inline stylesheet (and scripts) a bit
differently.

The old parser loads all the text content up front, and then notifies
the containing element. The new parser creates the containing element
up front and appends text inside it afterwards.

For now, we simply do an empty "children_changed" notification when
first inserting a text node inside an element. This at least prevents
the CSS parser from choking on a single-character stylesheet.
Andreas Kling 5 years ago
parent
commit
f69001339f
1 changed files with 5 additions and 1 deletions
  1. 5 1
      Libraries/LibWeb/Parser/HTMLDocumentParser.cpp

+ 5 - 1
Libraries/LibWeb/Parser/HTMLDocumentParser.cpp

@@ -384,9 +384,11 @@ void HTMLDocumentParser::insert_character(u32 data)
         existing_text_node.set_data(builder.to_string());
         existing_text_node.set_data(builder.to_string());
         return;
         return;
     }
     }
+    auto new_text_node = adopt(*new Text(document(), ""));
+    adjusted_insertion_location->append_child(new_text_node);
     StringBuilder builder;
     StringBuilder builder;
     builder.append(Utf32View { &data, 1 });
     builder.append(Utf32View { &data, 1 });
-    adjusted_insertion_location->append_child(adopt(*new Text(document(), builder.to_string())));
+    new_text_node->set_data(builder.to_string());
 }
 }
 
 
 void HTMLDocumentParser::handle_after_head(HTMLToken& token)
 void HTMLDocumentParser::handle_after_head(HTMLToken& token)
@@ -827,6 +829,8 @@ void HTMLDocumentParser::handle_text(HTMLToken& token)
         return;
         return;
     }
     }
 
 
+    // FIXME: This is a bit hackish, we can simplify this once we don't need to support
+    //        the old parser anymore, since then we don't need to maintain its children_changed() semantics.
     if (token.is_end_tag() && token.tag_name() == "style") {
     if (token.is_end_tag() && token.tag_name() == "style") {
         current_node().children_changed();
         current_node().children_changed();
         // NOTE: We don't return here, keep going.
         // NOTE: We don't return here, keep going.