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

Serialize using html5ever #5029

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

@@ -40,14 +40,13 @@ use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers};
use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElementTypeId;
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers, HTMLInputElementHelpers};
use dom::htmlserializer::serialize;
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers};
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers};
use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementHelpers};
use dom::htmltablesectionelement::{HTMLTableSectionElement, HTMLTableSectionElementHelpers};
use dom::htmltextareaelement::{HTMLTextAreaElement, RawLayoutHTMLTextAreaElementHelpers};
use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node, NodeHelpers, NodeTypeId};
use dom::node::{NodeIterator, document_from_node, NodeDamage};
use dom::node::{document_from_node, NodeDamage};
use dom::node::{window_from_node};
use dom::nodelist::NodeList;
use dom::virtualmethods::{VirtualMethods, vtable_for};
@@ -60,6 +59,10 @@ use style;
use util::namespace;
use util::str::{DOMString, LengthOrPercentageOrAuto};

use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{IncludeNode, ChildrenOnly};
use html5ever::tree_builder::{NoQuirks, LimitedQuirks, Quirks};

use cssparser::RGBA;
@@ -68,6 +71,7 @@ use std::borrow::{IntoCow, ToOwned};
use std::cell::{Ref, RefMut};
use std::default::Default;
use std::mem;
use std::old_io::{MemWriter, Writer};
use std::sync::Arc;
use string_cache::{Atom, Namespace, QualName};
use url::UrlParser;
@@ -424,6 +428,7 @@ pub trait ElementHelpers<'a> {
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
}

impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
@@ -569,6 +574,19 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
.map(|decl| decl.clone())
})
}

fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
let node: JSRef<Node> = NodeCast::from_ref(self);
let mut writer = MemWriter::new();
match serialize(&mut writer, &node,
SerializeOpts {
traversal_scope: traversal_scope,
.. Default::default()
}) {
Ok(()) => Ok(String::from_utf8(writer.into_inner()).unwrap()),
Err(_) => panic!("Cannot serialize element"),
}
}
}

pub trait AttributeHandlers {
@@ -1114,11 +1132,11 @@ impl<'a> ElementMethods for JSRef<'a, Element> {

fn GetInnerHTML(self) -> Fallible<DOMString> {
//XXX TODO: XML case
Ok(serialize(&mut NodeIterator::new(NodeCast::from_ref(self), false, false)))
self.serialize(ChildrenOnly)
}

fn GetOuterHTML(self) -> Fallible<DOMString> {
Ok(serialize(&mut NodeIterator::new(NodeCast::from_ref(self), true, false)))
self.serialize(IncludeNode)
}

// http://dom.spec.whatwg.org/#dom-parentnode-children

This file was deleted.

@@ -272,7 +272,6 @@ pub mod htmlprogresselement;
pub mod htmlquoteelement;
pub mod htmlscriptelement;
pub mod htmlselectelement;
pub mod htmlserializer;
pub mod htmlspanelement;
pub mod htmlsourceelement;
pub mod htmlstyleelement;
@@ -7,14 +7,17 @@
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};
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) {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.