Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use parent to pick proper document during parsing #18536

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Use the correct document when creating elements

The html parser now sends the intended parent when requesting a new
element to be created. This will ensure that elements are created using
the proper document.
  • Loading branch information
cbrewster committed Jul 26, 2018
commit 7608c1d57d3840cfdb4bf05eb206ea3b303338cb
@@ -25,3 +25,7 @@ opt-level = 3
#
# [patch."https://github.com/servo/<repository>"]
# <crate> = { path = "/path/to/local/checkout" }

html5ever = { path = "../html5ever/html5ever" }
xml5ever = { path = "../html5ever/xml5ever" }
markup5ever = { path = "../html5ever/markup5ever" }
@@ -20,7 +20,7 @@ euclid = "0.18"
fnv = "1.0"
gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
html5ever = "0.22"
html5ever = "0.23"
ipc-channel = "0.10"
libc = "0.2"
log = "0.4"
@@ -21,7 +21,7 @@ fnv = "1.0"
gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
histogram = "0.6.8"
html5ever = "0.22"
html5ever = "0.23"
ipc-channel = "0.10"
layout = {path = "../layout"}
layout_traits = {path = "../layout_traits"}
@@ -49,7 +49,7 @@ euclid = "0.18"
fnv = "1.0"
gleam = "0.6"
half = "1.0"
html5ever = "0.22"
html5ever = "0.23"
hyper = "0.10"
hyper_serde = "0.8"
image = "0.19"
@@ -26,7 +26,7 @@ use html5ever::tendril::{SendTendril, StrTendril, Tendril};
use html5ever::tendril::fmt::UTF8;
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
use html5ever::tree_builder::{ElementFlags, NodeOrText as HtmlNodeOrText, NextParserState, QuirksMode, TreeSink};
use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts};
use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts, IntendedParent as HtmlIntendedParent};
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::cell::Cell;
@@ -56,12 +56,20 @@ struct Attribute {
value: String,
}

#[derive(JSTraceable, MallocSizeOf)]
enum IntendedParent {
None,
Parent(ParseNode),
Either(ParseNode, ParseNode),
}

#[derive(JSTraceable, MallocSizeOf)]
enum ParseOperation {
GetTemplateContents { target: ParseNodeId, contents: ParseNodeId },

CreateElement {
node: ParseNodeId,
parent: IntendedParent,
name: QualName,
attrs: Vec<Attribute>,
current_line: u64
@@ -335,15 +343,23 @@ impl Tokenizer {
"Tried to extract contents from non-template element while parsing");
self.insert_node(contents, Dom::from_ref(template.Content().upcast()));
}
ParseOperation::CreateElement { node, name, attrs, current_line } => {
ParseOperation::CreateElement { node, parent, name, attrs, current_line } => {
let attrs = attrs
.into_iter()
.map(|attr| ElementAttribute::new(attr.name, DOMString::from(attr.value)))
.collect();
let document = match parent {
IntendedParent::None => DomRoot::from_ref(&*self.document),
IntendedParent::Parent(parent) => self.get_node(&parent.id).owner_doc(),
IntendedParent::Either(element, prev) => {
let node = if self.has_parent_node(element.id) { element } else { prev };
self.get_node(&node.id).owner_doc()
},
};
let element = create_element_for_token(
name,
attrs,
&*self.document,
&*document,
ElementCreator::ParserCreated(current_line),
ParsingAlgorithm::Normal
);
@@ -584,8 +600,13 @@ impl TreeSink for Sink {
target.qual_name.as_ref().expect("Expected qual name of node!").expanded()
}

fn create_element(&mut self, name: QualName, html_attrs: Vec<HtmlAttribute>, _flags: ElementFlags)
-> Self::Handle {
fn create_element(
&mut self,
name: QualName,
html_attrs: Vec<HtmlAttribute>,
_flags: ElementFlags,
parent: HtmlIntendedParent<&Self::Handle>,
) -> Self::Handle {
let mut node = self.new_parse_node();
node.qual_name = Some(name.clone());
{
@@ -601,8 +622,15 @@ impl TreeSink for Sink {
let attrs = html_attrs.into_iter()
.map(|attr| Attribute { name: attr.name, value: String::from(attr.value) }).collect();

let parent = match parent {
HtmlIntendedParent::None => IntendedParent::None,
HtmlIntendedParent::Parent(parent) => IntendedParent::Parent(parent.clone()),
HtmlIntendedParent::Either(node1, node2) => IntendedParent::Either(node1.clone(), node2.clone()),
};

self.send_op(ParseOperation::CreateElement {
node: node.id,
parent: parent,
name,
attrs,
current_line: self.current_line
@@ -35,6 +35,7 @@ use html5ever::{Attribute, ExpandedName, LocalName, QualName};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
use html5ever::tree_builder::{NodeOrText, TreeSink, NextParserState, QuirksMode, ElementFlags};
use html5ever::tree_builder::IntendedParent;
use hyper::header::ContentType;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper_serde::Serde;
@@ -821,16 +822,30 @@ impl TreeSink for Sink {
}
}

fn create_element(&mut self, name: QualName, attrs: Vec<Attribute>, _flags: ElementFlags)
-> Dom<Node> {
fn create_element(
&mut self,
name: QualName,
attrs: Vec<Attribute>,
_flags: ElementFlags,
parent: IntendedParent<&Dom<Node>>
) -> Dom<Node> {
let attrs = attrs
.into_iter()
.map(|attr| ElementAttribute::new(attr.name, DOMString::from(String::from(attr.value))))
.collect();

let document = match parent {
IntendedParent::None => DomRoot::from_ref(&*self.document),
IntendedParent::Parent(parent) => parent.owner_doc(),
IntendedParent::Either(element, prev) => {
if self.has_parent_node(element) { element.owner_doc() } else { prev.owner_doc() }
},
};

let element = create_element_for_token(
name,
attrs,
&*self.document,
&*document,
ElementCreator::ParserCreated(self.current_line),
self.parsing_algorithm,
);
@@ -16,7 +16,7 @@ canvas_traits = {path = "../canvas_traits"}
cssparser = "0.24"
euclid = "0.18"
gfx_traits = {path = "../gfx_traits"}
html5ever = "0.22"
html5ever = "0.23"
ipc-channel = "0.10"
libc = "0.2"
log = "0.4"
@@ -38,7 +38,7 @@ euclid = "0.18"
fallible = { path = "../fallible" }
fnv = "1.0"
hashglobe = { path = "../hashglobe" }
html5ever = {version = "0.22", optional = true}
html5ever = {version = "0.23", optional = true}
itertools = "0.7.6"
itoa = "0.4"
lazy_static = "1"
@@ -14,7 +14,7 @@ byteorder = "1.0"
app_units = "0.6"
cssparser = "0.24.0"
euclid = "0.18"
html5ever = "0.22"
html5ever = "0.23"
parking_lot = "0.6"
rayon = "1"
serde_json = "1.0"
@@ -1,8 +1,5 @@
[parser-uses-registry-of-owner-document.html]
type: testharness
[HTML parser must not instantiate custom elements inside template elements]
expected: FAIL

[HTML parser must use the registry of window.document in a document created by document.implementation.createHTMLDocument()]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.