diff options
author | Chris Paris <cap@chrisparis.org> | 2015-02-19 17:43:24 -1000 |
---|---|---|
committer | Chris Paris <cap@chrisparis.org> | 2015-03-18 12:17:56 -1000 |
commit | a5d6c6a1fc60975b4901914c183624a13f496c4c (patch) | |
tree | 9a69e62ac618b8889757c68dfe6ec2c10e1fca0d /components/script/parse/html.rs | |
parent | a5217556072390131f41a7a4cd07e8eb5a671d06 (diff) | |
download | servo-a5d6c6a1fc60975b4901914c183624a13f496c4c.tar.gz servo-a5d6c6a1fc60975b4901914c183624a13f496c4c.zip |
Serialize using html5ever
Diffstat (limited to 'components/script/parse/html.rs')
-rw-r--r-- | components/script/parse/html.rs | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 836eac6dfba..29a1de686e8 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -7,6 +7,8 @@ use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLScriptElementCast}; +use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, TextCast, CommentCast}; +use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Root}; use dom::comment::Comment; use dom::document::{Document, DocumentHelpers}; @@ -14,7 +16,8 @@ use dom::documenttype::DocumentType; use dom::element::{Element, AttributeHandlers, ElementHelpers, ElementCreator}; use dom::htmlscriptelement::HTMLScriptElement; use dom::htmlscriptelement::HTMLScriptElementHelpers; -use dom::node::{Node, NodeHelpers}; +use dom::node::{Node, NodeHelpers, NodeTypeId}; +use dom::processinginstruction::ProcessingInstruction; use dom::servohtmlparser; use dom::servohtmlparser::ServoHTMLParser; use dom::text::Text; @@ -27,9 +30,13 @@ use net::resource_task::{ProgressMsg, LoadResponse}; use util::task_state; use util::task_state::IN_HTML_PARSER; use std::ascii::AsciiExt; +use std::old_io::{Writer, IoResult}; use std::string::CowString; use url::Url; use html5ever::Attribute; +use html5ever::serialize::{Serializable, Serializer, AttrRef}; +use html5ever::serialize::TraversalScope; +use html5ever::serialize::TraversalScope::{IncludeNode, ChildrenOnly}; use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, AppendText}; use string_cache::QualName; @@ -169,6 +176,80 @@ impl<'a> TreeSink for servohtmlparser::Sink { } } +impl<'a> Serializable for JSRef<'a, Node> { + fn serialize<'wr, Wr: Writer>(&self, serializer: &mut Serializer<'wr, Wr>, + traversal_scope: TraversalScope) -> IoResult<()> { + let node = *self; + match (traversal_scope, node.type_id()) { + (_, NodeTypeId::Element(..)) => { + let elem: JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let name = QualName::new(elem.namespace().clone(), + elem.local_name().clone()); + if traversal_scope == IncludeNode { + let attrs = elem.attrs().iter().map(|at| { + let attr = at.root(); + let qname = QualName::new(attr.r().namespace().clone(), + attr.r().local_name().clone()); + let value = attr.r().value().clone(); + (qname, value) + }).collect::<Vec<_>>(); + let attr_refs = attrs.iter().map(|&(ref qname, ref value)| { + let ar: AttrRef = (&qname, value.as_slice()); + ar + }); + try!(serializer.start_elem(name.clone(), attr_refs)); + } + + for handle in node.children() { + try!(handle.serialize(serializer, IncludeNode)); + } + + if traversal_scope == IncludeNode { + try!(serializer.end_elem(name.clone())); + } + Ok(()) + }, + + (ChildrenOnly, NodeTypeId::Document) => { + for handle in node.children() { + try!(handle.serialize(serializer, IncludeNode)); + } + Ok(()) + }, + + (ChildrenOnly, _) => Ok(()), + + (IncludeNode, NodeTypeId::DocumentType) => { + let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); + serializer.write_doctype(doctype.name().as_slice()) + }, + + (IncludeNode, NodeTypeId::Text) => { + let text: JSRef<Text> = TextCast::to_ref(node).unwrap(); + let data = text.characterdata().data(); + serializer.write_text(data.as_slice()) + }, + + (IncludeNode, NodeTypeId::Comment) => { + let comment: JSRef<Comment> = CommentCast::to_ref(node).unwrap(); + let data = comment.characterdata().data(); + serializer.write_comment(data.as_slice()) + }, + + (IncludeNode, NodeTypeId::ProcessingInstruction) => { + let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); + let data = pi.characterdata().data(); + serializer.write_processing_instruction(pi.target().as_slice(), + data.as_slice()) + }, + + (IncludeNode, NodeTypeId::DocumentFragment) => Ok(()), + + (IncludeNode, NodeTypeId::Document) => panic!("Can't serialize Document node itself"), + } + } +} + pub fn parse_html(document: JSRef<Document>, input: HTMLInput, url: &Url) { |