diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 6930f2553c5c..8b0a156842de 100644 --- a/components/script/dom/servoparser/async_html.rs +++ b/components/script/dom/servoparser/async_html.rs @@ -206,6 +206,7 @@ pub struct Tokenizer { #[ignore_malloc_size_of = "Defined in std"] nodes: HashMap>, url: ServoUrl, + parsing_algorithm: ParsingAlgorithm, } impl Tokenizer { @@ -219,12 +220,18 @@ impl Tokenizer { // Messages from HtmlTokenizer and Sink (parser thread) to Tokenizer (main thread) let (to_tokenizer_sender, tokenizer_receiver) = unbounded(); + let algorithm = match fragment_context { + Some(_) => ParsingAlgorithm::Fragment, + None => ParsingAlgorithm::Normal, + }; + let mut tokenizer = Tokenizer { document: Dom::from_ref(document), receiver: tokenizer_receiver, html_tokenizer_sender: to_html_tokenizer_sender, nodes: HashMap::new(), url: url, + parsing_algorithm: algorithm, }; tokenizer.insert_node(0, Dom::from_ref(document.upcast())); @@ -352,7 +359,7 @@ impl Tokenizer { .GetParentNode() .expect("append_before_sibling called on node without parent"); - super::insert(parent, Some(sibling), node); + super::insert(parent, Some(sibling), node, self.parsing_algorithm); } fn append(&mut self, parent: ParseNodeId, node: NodeOrText) { @@ -364,7 +371,7 @@ impl Tokenizer { }; let parent = &**self.get_node(&parent); - super::insert(parent, None, node); + super::insert(parent, None, node, self.parsing_algorithm); } fn has_parent_node(&self, node: ParseNodeId) -> bool { diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 1e172db35fd8..505c699cb6cb 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -950,12 +950,29 @@ pub struct FragmentContext<'a> { } #[allow(unrooted_must_root)] -fn insert(parent: &Node, reference_child: Option<&Node>, child: NodeOrText>) { +fn insert( + parent: &Node, + reference_child: Option<&Node>, + child: NodeOrText>, + parsing_algorithm: ParsingAlgorithm, +) { match child { NodeOrText::AppendNode(n) => { + // https://html.spec.whatwg.org/multipage/#insert-a-foreign-element + // applies if this is an element; if not, it may be + // https://html.spec.whatwg.org/multipage/#insert-a-comment + let element_in_non_fragment = + parsing_algorithm != ParsingAlgorithm::Fragment && n.is::(); + if element_in_non_fragment { + ScriptThread::push_new_element_queue(); + } parent.InsertBefore(&n, reference_child).unwrap(); + if element_in_non_fragment { + ScriptThread::pop_current_element_queue(); + } }, NodeOrText::AppendText(t) => { + // https://html.spec.whatwg.org/multipage/#insert-a-character let text = reference_child .and_then(Node::GetPreviousSibling) .or_else(|| parent.GetLastChild()) @@ -1105,7 +1122,7 @@ impl TreeSink for Sink { .GetParentNode() .expect("append_before_sibling called on node without parent"); - insert(&parent, Some(&*sibling), new_node); + insert(&parent, Some(&*sibling), new_node, self.parsing_algorithm); } fn parse_error(&mut self, msg: Cow<'static, str>) { @@ -1122,7 +1139,7 @@ impl TreeSink for Sink { } fn append(&mut self, parent: &Dom, child: NodeOrText>) { - insert(&parent, None, child); + insert(&parent, None, child, self.parsing_algorithm); } fn append_based_on_parent_node( diff --git a/tests/wpt/metadata/custom-elements/parser/parser-sets-attributes-and-children.html.ini b/tests/wpt/metadata/custom-elements/parser/parser-sets-attributes-and-children.html.ini deleted file mode 100644 index 4a18e1fd225f..000000000000 --- a/tests/wpt/metadata/custom-elements/parser/parser-sets-attributes-and-children.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[parser-sets-attributes-and-children.html] - [HTML parser should call connectedCallback before appending child nodes.] - expected: FAIL -