diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-02-14 06:51:47 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-14 06:51:47 -0500 |
commit | 38adec64e15f1b323bffb56ea5e4e4f1da686a0c (patch) | |
tree | 3637a01bdc0ecb76c5b7ad8e559ec8f074d31638 /components/script/dom | |
parent | 455fb18ecaa253d34aa77cb5354306db0cfcee1c (diff) | |
parent | 345470b6b7187b5214135453e79a6d0022baa0cd (diff) | |
download | servo-38adec64e15f1b323bffb56ea5e4e4f1da686a0c.tar.gz servo-38adec64e15f1b323bffb56ea5e4e4f1da686a0c.zip |
Auto merge of #25755 - pshaughn:insertqueue, r=nox
Use CE reaction queue when inserting an element from non-fragment parser
<!-- Please describe your changes on the following line: -->
Changed async_html Tokenizer so it can remember whether it's for a fragment and changed servoparser node insertion to respect the CE queue requirements of https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element; it passes a WPT test.
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #25746
<!-- Either: -->
- [X] There are tests for these changes
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/servoparser/async_html.rs | 11 | ||||
-rw-r--r-- | components/script/dom/servoparser/mod.rs | 23 |
2 files changed, 29 insertions, 5 deletions
diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 6930f2553c5..8b0a156842d 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<ParseNodeId, Dom<Node>>, 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 1e172db35fd..505c699cb6c 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<Dom<Node>>) { +fn insert( + parent: &Node, + reference_child: Option<&Node>, + child: NodeOrText<Dom<Node>>, + 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::<Element>(); + 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<Node>, child: NodeOrText<Dom<Node>>) { - insert(&parent, None, child); + insert(&parent, None, child, self.parsing_algorithm); } fn append_based_on_parent_node( |