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) {