Auto merge of #14867 - nox:a-base-de-popopopop, r=metajack

Properly insert text in document when parsing

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14867)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-01-07 10:57:36 -08:00 committed by GitHub
commit f313e8baff
19 changed files with 87 additions and 41 deletions

View file

@ -38,7 +38,7 @@ fnv = "1.0"
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.6"
heapsize_derive = "0.1"
html5ever = {version = "0.10.2", features = ["heap_size", "unstable"]}
html5ever = {version = "0.12.1", features = ["heap_size", "unstable"]}
html5ever-atoms = {version = "0.1", features = ["heap_size"]}
hyper = "0.9.9"
hyper_serde = "0.1.4"
@ -81,7 +81,7 @@ time = "0.1.12"
url = {version = "1.2", features = ["heap_size", "query_encoding"]}
uuid = {version = "0.3.1", features = ["v4"]}
websocket = "0.17"
xml5ever = {version = "0.2", features = ["unstable"]}
xml5ever = {version = "0.3.1", features = ["unstable"]}
[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"

View file

@ -36,6 +36,7 @@ pub struct HTMLStyleElement {
cssom_stylesheet: MutNullableJS<CSSStyleSheet>,
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
parser_inserted: Cell<bool>,
in_stack_of_open_elements: Cell<bool>,
pending_loads: Cell<u32>,
any_failed_load: Cell<bool>,
}
@ -50,6 +51,7 @@ impl HTMLStyleElement {
stylesheet: DOMRefCell::new(None),
cssom_stylesheet: MutNullableJS::new(None),
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
in_stack_of_open_elements: Cell::new(creator == ElementCreator::ParserCreated),
pending_loads: Cell::new(0),
any_failed_load: Cell::new(false),
}
@ -124,20 +126,38 @@ impl VirtualMethods for HTMLStyleElement {
}
fn children_changed(&self, mutation: &ChildrenMutation) {
if let Some(ref s) = self.super_type() {
s.children_changed(mutation);
}
if self.upcast::<Node>().is_in_doc() {
self.super_type().unwrap().children_changed(mutation);
// https://html.spec.whatwg.org/multipage/#update-a-style-block
// Handles the case when:
// "The element is not on the stack of open elements of an HTML parser or XML parser,
// and one of its child nodes is modified by a script."
// TODO: Handle Text child contents being mutated.
if self.upcast::<Node>().is_in_doc() && !self.in_stack_of_open_elements.get() {
self.parse_own_css();
}
}
fn bind_to_tree(&self, tree_in_doc: bool) {
if let Some(ref s) = self.super_type() {
s.bind_to_tree(tree_in_doc);
}
self.super_type().unwrap().bind_to_tree(tree_in_doc);
if tree_in_doc {
// https://html.spec.whatwg.org/multipage/#update-a-style-block
// Handles the case when:
// "The element is not on the stack of open elements of an HTML parser or XML parser,
// and it becomes connected or disconnected."
if tree_in_doc && !self.in_stack_of_open_elements.get() {
self.parse_own_css();
}
}
fn pop(&self) {
self.super_type().unwrap().pop();
// https://html.spec.whatwg.org/multipage/#update-a-style-block
// Handles the case when:
// "The element is popped off the stack of open elements of an HTML parser or XML parser."
self.in_stack_of_open_elements.set(false);
if self.upcast::<Node>().is_in_doc() {
self.parse_own_css();
}
}

View file

@ -425,6 +425,13 @@ impl VirtualMethods for HTMLTextAreaElement {
}
}
}
fn pop(&self) {
self.super_type().unwrap().pop();
// https://html.spec.whatwg.org/multipage/#the-textarea-element:stack-of-open-elements
self.reset();
}
}
impl FormControl for HTMLTextAreaElement {}

View file

@ -20,6 +20,7 @@ use dom::htmltemplateelement::HTMLTemplateElement;
use dom::node::Node;
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
use dom::virtualmethods::vtable_for;
use html5ever::Attribute;
use html5ever::serialize::{AttrRef, Serializable, Serializer};
use html5ever::serialize::TraversalScope;
@ -124,7 +125,7 @@ struct Sink {
document: JS<Document>,
}
impl<'a> TreeSink for Sink {
impl TreeSink for Sink {
type Output = Self;
fn finish(self) -> Self { self }
@ -233,7 +234,11 @@ impl<'a> TreeSink for Sink {
while let Some(ref child) = node.GetFirstChild() {
new_parent.AppendChild(&child).unwrap();
}
}
fn pop(&mut self, node: JS<Node>) {
let node = Root::from_ref(&*node);
vtable_for(&node).pop();
}
}
@ -243,10 +248,13 @@ fn insert(parent: &Node, reference_child: Option<&Node>, child: NodeOrText<JS<No
assert!(parent.InsertBefore(&n, reference_child).is_ok());
},
NodeOrText::AppendText(t) => {
// FIXME(ajeffrey): convert directly from tendrils to DOMStrings
let s: String = t.into();
let text = Text::new(DOMString::from(s), &parent.owner_doc());
assert!(parent.InsertBefore(text.upcast(), reference_child).is_ok());
if let Some(text) = parent.GetLastChild().and_then(Root::downcast::<Text>) {
text.upcast::<CharacterData>().append_data(&t);
} else {
let s: String = t.into();
let text = Text::new(DOMString::from(s), &parent.owner_doc());
parent.InsertBefore(text.upcast(), reference_child).unwrap();
}
}
}
}

View file

@ -17,6 +17,7 @@ use dom::htmlscriptelement::HTMLScriptElement;
use dom::node::Node;
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
use dom::virtualmethods::vtable_for;
use html5ever::tokenizer::buffer_queue::BufferQueue;
use html5ever_atoms::{Prefix, QualName};
use js::jsapi::JSTracer;
@ -42,7 +43,7 @@ impl Tokenizer {
script: Default::default(),
};
let tb = XmlTreeBuilder::new(sink);
let tb = XmlTreeBuilder::new(sink, Default::default());
let tok = XmlTokenizer::new(tb, Default::default());
Tokenizer {
@ -100,9 +101,14 @@ struct Sink {
script: MutNullableJS<HTMLScriptElement>,
}
impl<'a> TreeSink for Sink {
impl TreeSink for Sink {
type Output = Self;
type Handle = JS<Node>;
fn finish(self) -> Self {
self
}
fn parse_error(&mut self, msg: Cow<'static, str>) {
debug!("Parse error: {}", msg);
}
@ -191,4 +197,9 @@ impl<'a> TreeSink for Sink {
NextParserState::Continue
}
}
fn pop(&mut self, node: Self::Handle) {
let node = Root::from_ref(&*node);
vtable_for(&node).pop();
}
}

View file

@ -124,6 +124,14 @@ pub trait VirtualMethods {
s.cloning_steps(copy, maybe_doc, clone_children);
}
}
/// Called on an element when it is popped off the stack of open elements
/// of a parser.
fn pop(&self) {
if let Some(ref s) = self.super_type() {
s.pop();
}
}
}
/// Obtain a VirtualMethods instance for a given Node-derived object. Any