diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 735018093009..ac8ad1d060b4 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -5,6 +5,7 @@ #![allow(unsafe_code, unrooted_must_root)] use dom::attr::AttrHelpers; +use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentTypeCast}; @@ -126,6 +127,7 @@ impl<'a> TreeSink for servohtmlparser::Sink { None => return Err(new_node), }; + // FIXME: Merge adjacent text nodes. let child = self.get_or_create(new_node).root(); assert!(parent.r().InsertBefore(child.r(), Some(sibling.r())).is_ok()); Ok(()) @@ -141,11 +143,31 @@ impl<'a> TreeSink for servohtmlparser::Sink { } fn append(&mut self, parent: JS, child: NodeOrText>) { + // FIXME(#3701): Use a simpler algorithm let parent: Root = parent.root(); - let child = self.get_or_create(child).root(); - - // FIXME(#3701): Use a simpler algorithm and merge adjacent text nodes - assert!(parent.r().AppendChild(child.r()).is_ok()); + match child { + AppendNode(n) => { + let node = Temporary::new(n).root(); + assert!(parent.r().AppendChild(node.r()).is_ok()); + }, + AppendText(t) => { + match parent.r().GetLastChild() { + // Append to an existing text node if possible. + Some(ref prev_sibling) if prev_sibling.root().r().is_text() => { + let node = prev_sibling.root(); + let data = CharacterDataCast::to_ref(node.r()).unwrap(); + data.AppendData(t); + }, + // Otherwise, insert a new text node. + _ => { + let doc = self.document.root(); + let text = Text::new(t, doc.r()); + let node = NodeCast::from_temporary(text).root(); + assert!(parent.r().AppendChild(node.r()).is_ok()); + } + } + } + } } fn append_doctype_to_document(&mut self, name: String, public_id: String, system_id: String) {