diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2015-12-05 03:08:40 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2015-12-05 03:08:40 +0530 |
commit | 368dd1dc53cd595bbbcf6f9fb139e9ac573a351b (patch) | |
tree | 8f290554341c7f40ebd79fc2c2796be7ef7ba68c /components/script/parse | |
parent | 2cfcc26d9e5cc732a7594f0c0d96d4174c6b0a8a (diff) | |
parent | d38a1a0d032dfeabd5451c96f85280fd1fa1b830 (diff) | |
download | servo-368dd1dc53cd595bbbcf6f9fb139e9ac573a351b.tar.gz servo-368dd1dc53cd595bbbcf6f9fb139e9ac573a351b.zip |
Auto merge of #8829 - jdm:xmlparser2, r=jdm
M1503 : Integrate XML Parser : First 2 of 4 Subsequent Steps
Rebase of #8746. Introduce and use an XML parser for text/xml network responses when loading web pages.
Diffstat (limited to 'components/script/parse')
-rw-r--r-- | components/script/parse/xml.rs | 102 |
1 files changed, 97 insertions, 5 deletions
diff --git a/components/script/parse/xml.rs b/components/script/parse/xml.rs index 907c1600f0c..30cd5138348 100644 --- a/components/script/parse/xml.rs +++ b/components/script/parse/xml.rs @@ -4,17 +4,109 @@ #![allow(unrooted_must_root)] +use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, Root, RootedReference}; +use dom::comment::Comment; use dom::document::Document; +use dom::documenttype::DocumentType; +use dom::element::{Element, ElementCreator}; +use dom::node::Node; +use dom::processinginstruction::ProcessingInstruction; +use dom::servoxmlparser; +use dom::servoxmlparser::ServoXMLParser; +use dom::text::Text; +use msg::constellation_msg::PipelineId; +use parse::Parser; +use std::borrow::Cow; +use string_cache::QualName; +use tendril::StrTendril; use url::Url; use util::str::DOMString; +use xml5ever::tokenizer::Attribute; +use xml5ever::tree_builder::{NodeOrText, TreeSink}; + +impl<'a> TreeSink for servoxmlparser::Sink { + type Handle = JS<Node>; + + fn parse_error(&mut self, msg: Cow<'static, str>) { + debug!("Parse error: {}", msg); + } + + fn get_document(&mut self) -> JS<Node> { + JS::from_ref(self.document.upcast()) + } + + fn elem_name(&self, target: &JS<Node>) -> QualName { + let elem = target.downcast::<Element>() + .expect("tried to get name of non-Element in XML parsing"); + QualName { + ns: elem.namespace().clone(), + local: elem.local_name().clone(), + } + } + + fn create_element(&mut self, name: QualName, attrs: Vec<Attribute>) + -> JS<Node> { + let elem = Element::create(name, None, &*self.document, + ElementCreator::ParserCreated); + + for attr in attrs { + elem.set_attribute_from_parser(attr.name, DOMString::from(String::from(attr.value)), None); + } + + JS::from_ref(elem.upcast()) + } + + fn create_comment(&mut self, text: StrTendril) -> JS<Node> { + let comment = Comment::new(DOMString::from(String::from(text)), &*self.document); + JS::from_ref(comment.upcast()) + } + + fn append(&mut self, parent: JS<Node>, child: NodeOrText<JS<Node>>) { + let child = match child { + NodeOrText::AppendNode(n) => Root::from_ref(&*n), + NodeOrText::AppendText(t) => { + let s: String = t.into(); + let text = Text::new(DOMString::from(s), &self.document); + Root::upcast(text) + } + }; + assert!(parent.AppendChild(child.r()).is_ok()); + } + + fn append_doctype_to_document(&mut self, name: StrTendril, public_id: StrTendril, + system_id: StrTendril) { + let doc = &*self.document; + let doctype = DocumentType::new( + DOMString::from(String::from(name)), Some(DOMString::from(String::from(public_id))), + Some(DOMString::from(String::from(system_id))), doc); + doc.upcast::<Node>().AppendChild(doctype.upcast()).expect("Appending failed"); + } + + fn create_pi(&mut self, target: StrTendril, data: StrTendril) -> JS<Node> { + let doc = &*self.document; + let pi = ProcessingInstruction::new( + DOMString::from(String::from(target)), DOMString::from(String::from(data)), + doc); + JS::from_ref(pi.upcast()) + } +} + pub enum ParseContext { - Owner(Option<i32>) + Owner(Option<PipelineId>) } -pub fn parse_xml(_document: &Document, - _input: DOMString, - _url: Url, - _context: ParseContext) { +pub fn parse_xml(document: &Document, + input: DOMString, + url: Url, + context: ParseContext) { + let parser = match context { + ParseContext::Owner(owner) => + ServoXMLParser::new(Some(url), document, owner), + }; + parser.parse_chunk(String::from(input)); } + |