Add XMLDocument object

This commit is contained in:
Guillaume Gomez 2015-11-25 08:46:51 +01:00
parent 831979d6a7
commit adf8b359bb
18 changed files with 169 additions and 73 deletions

View file

@ -1439,7 +1439,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
Some(NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction)) | Some(NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction)) |
Some(NodeTypeId::DocumentType) | Some(NodeTypeId::DocumentType) |
Some(NodeTypeId::DocumentFragment) | Some(NodeTypeId::DocumentFragment) |
Some(NodeTypeId::Document) => { Some(NodeTypeId::Document(_)) => {
(display::T::none, float::T::none, position::T::static_) (display::T::none, float::T::none, position::T::static_)
} }
}; };
@ -1587,7 +1587,7 @@ impl<'ln> NodeUtils for ServoThreadSafeLayoutNode<'ln> {
Some(NodeTypeId::CharacterData(_)) | Some(NodeTypeId::CharacterData(_)) |
Some(NodeTypeId::DocumentType) | Some(NodeTypeId::DocumentType) |
Some(NodeTypeId::DocumentFragment) | Some(NodeTypeId::DocumentFragment) |
Some(NodeTypeId::Document) | Some(NodeTypeId::Document(_)) |
Some(NodeTypeId::Element(ElementTypeId::HTMLElement( Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLImageElement))) | HTMLElementTypeId::HTMLImageElement))) |
Some(NodeTypeId::Element(ElementTypeId::HTMLElement( Some(NodeTypeId::Element(ElementTypeId::HTMLElement(

View file

@ -629,7 +629,12 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
fn is_root(&self) -> bool { fn is_root(&self) -> bool {
match self.as_node().parent_node() { match self.as_node().parent_node() {
None => false, None => false,
Some(node) => node.type_id() == NodeTypeId::Document, Some(node) => {
match node.type_id() {
NodeTypeId::Document(_) => true,
_ => false
}
},
} }
} }

View file

@ -1392,7 +1392,7 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
} }
impl Document { impl Document {
fn new_inherited(window: &Window, pub fn new_inherited(window: &Window,
url: Option<Url>, url: Option<Url>,
is_html_document: IsHTMLDocument, is_html_document: IsHTMLDocument,
content_type: Option<DOMString>, content_type: Option<DOMString>,

View file

@ -22,6 +22,7 @@ use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmltitleelement::HTMLTitleElement; use dom::htmltitleelement::HTMLTitleElement;
use dom::node::Node; use dom::node::Node;
use dom::text::Text; use dom::text::Text;
use dom::xmldocument::XMLDocument;
use util::str::DOMString; use util::str::DOMString;
// https://dom.spec.whatwg.org/#domimplementation // https://dom.spec.whatwg.org/#domimplementation
@ -64,12 +65,12 @@ impl DOMImplementationMethods for DOMImplementation {
namespace: Option<DOMString>, namespace: Option<DOMString>,
qname: DOMString, qname: DOMString,
maybe_doctype: Option<&DocumentType>) maybe_doctype: Option<&DocumentType>)
-> Fallible<Root<Document>> { -> Fallible<Root<XMLDocument>> {
let win = self.document.window(); let win = self.document.window();
let loader = DocumentLoader::new(&self.document.loader()); let loader = DocumentLoader::new(&self.document.loader());
// Step 1. // Step 1.
let doc = Document::new(win, let doc = XMLDocument::new(win,
None, None,
IsHTMLDocument::NonHTMLDocument, IsHTMLDocument::NonHTMLDocument,
None, None,
@ -80,7 +81,7 @@ impl DOMImplementationMethods for DOMImplementation {
let maybe_elem = if qname.is_empty() { let maybe_elem = if qname.is_empty() {
None None
} else { } else {
match doc.CreateElementNS(namespace, qname) { match doc.upcast::<Document>().CreateElementNS(namespace, qname) {
Err(error) => return Err(error), Err(error) => return Err(error),
Ok(elem) => Some(elem), Ok(elem) => Some(elem),
} }

View file

@ -1370,7 +1370,7 @@ impl ElementMethods for Element {
let parent = match context_parent.type_id() { let parent = match context_parent.type_id() {
// Step 3. // Step 3.
NodeTypeId::Document => return Err(Error::NoModificationAllowed), NodeTypeId::Document(_) => return Err(Error::NoModificationAllowed),
// Step 4. // Step 4.
NodeTypeId::DocumentFragment => { NodeTypeId::DocumentFragment => {

View file

@ -376,6 +376,7 @@ pub mod worker;
pub mod workerglobalscope; pub mod workerglobalscope;
pub mod workerlocation; pub mod workerlocation;
pub mod workernavigator; pub mod workernavigator;
pub mod xmldocument;
pub mod xmlhttprequest; pub mod xmlhttprequest;
pub mod xmlhttprequesteventtarget; pub mod xmlhttprequesteventtarget;
pub mod xmlhttprequestupload; pub mod xmlhttprequestupload;

View file

@ -1333,7 +1333,7 @@ impl Node {
child: Option<&Node>) -> ErrorResult { child: Option<&Node>) -> ErrorResult {
// Step 1. // Step 1.
match parent.type_id() { match parent.type_id() {
NodeTypeId::Document | NodeTypeId::Document(_) |
NodeTypeId::DocumentFragment | NodeTypeId::DocumentFragment |
NodeTypeId::Element(..) => (), NodeTypeId::Element(..) => (),
_ => return Err(Error::HierarchyRequest) _ => return Err(Error::HierarchyRequest)
@ -1367,11 +1367,11 @@ impl Node {
NodeTypeId::Element(_) | NodeTypeId::Element(_) |
NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) | NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) |
NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => (), NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => (),
NodeTypeId::Document => return Err(Error::HierarchyRequest) NodeTypeId::Document(_) => return Err(Error::HierarchyRequest)
} }
// Step 6. // Step 6.
if parent.type_id() == NodeTypeId::Document { if parent.is::<Document>() {
match node.type_id() { match node.type_id() {
// Step 6.1 // Step 6.1
NodeTypeId::DocumentFragment => { NodeTypeId::DocumentFragment => {
@ -1435,7 +1435,7 @@ impl Node {
} }
}, },
NodeTypeId::CharacterData(_) => (), NodeTypeId::CharacterData(_) => (),
NodeTypeId::Document => unreachable!(), NodeTypeId::Document(_) => unreachable!(),
} }
} }
Ok(()) Ok(())
@ -1611,7 +1611,7 @@ impl Node {
let comment = Comment::new(cdata.Data(), document.r()); let comment = Comment::new(cdata.Data(), document.r());
Root::upcast::<Node>(comment) Root::upcast::<Node>(comment)
}, },
NodeTypeId::Document => { NodeTypeId::Document(_) => {
let document = node.downcast::<Document>().unwrap(); let document = node.downcast::<Document>().unwrap();
let is_html_doc = match document.is_html_document() { let is_html_doc = match document.is_html_document() {
true => IsHTMLDocument::HTMLDocument, true => IsHTMLDocument::HTMLDocument,
@ -1657,7 +1657,7 @@ impl Node {
// Step 4 (some data already copied in step 2). // Step 4 (some data already copied in step 2).
match node.type_id() { match node.type_id() {
NodeTypeId::Document => { NodeTypeId::Document(_) => {
let node_doc = node.downcast::<Document>().unwrap(); let node_doc = node.downcast::<Document>().unwrap();
let copy_doc = copy.downcast::<Document>().unwrap(); let copy_doc = copy.downcast::<Document>().unwrap();
copy_doc.set_encoding_name(node_doc.encoding_name().clone()); copy_doc.set_encoding_name(node_doc.encoding_name().clone());
@ -1756,7 +1756,7 @@ impl Node {
Some(parent) => Node::locate_namespace(parent.upcast(), prefix) Some(parent) => Node::locate_namespace(parent.upcast(), prefix)
} }
}, },
NodeTypeId::Document => { NodeTypeId::Document(_) => {
match node.downcast::<Document>().unwrap().GetDocumentElement().r() { match node.downcast::<Document>().unwrap().GetDocumentElement().r() {
// Step 1. // Step 1.
None => ns!(), None => ns!(),
@ -1788,7 +1788,7 @@ impl NodeMethods for Node {
NodeConstants::PROCESSING_INSTRUCTION_NODE, NodeConstants::PROCESSING_INSTRUCTION_NODE,
NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => NodeTypeId::CharacterData(CharacterDataTypeId::Comment) =>
NodeConstants::COMMENT_NODE, NodeConstants::COMMENT_NODE,
NodeTypeId::Document => NodeTypeId::Document(_) =>
NodeConstants::DOCUMENT_NODE, NodeConstants::DOCUMENT_NODE,
NodeTypeId::DocumentType => NodeTypeId::DocumentType =>
NodeConstants::DOCUMENT_TYPE_NODE, NodeConstants::DOCUMENT_TYPE_NODE,
@ -1814,7 +1814,7 @@ impl NodeMethods for Node {
self.downcast::<DocumentType>().unwrap().name().clone() self.downcast::<DocumentType>().unwrap().name().clone()
}, },
NodeTypeId::DocumentFragment => DOMString::from("#document-fragment"), NodeTypeId::DocumentFragment => DOMString::from("#document-fragment"),
NodeTypeId::Document => DOMString::from("#document") NodeTypeId::Document(_) => DOMString::from("#document")
} }
} }
@ -1830,7 +1830,7 @@ impl NodeMethods for Node {
NodeTypeId::Element(..) | NodeTypeId::Element(..) |
NodeTypeId::DocumentType | NodeTypeId::DocumentType |
NodeTypeId::DocumentFragment => Some(self.owner_doc()), NodeTypeId::DocumentFragment => Some(self.owner_doc()),
NodeTypeId::Document => None NodeTypeId::Document(_) => None
} }
} }
@ -1903,7 +1903,7 @@ impl NodeMethods for Node {
Some(characterdata.Data()) Some(characterdata.Data())
} }
NodeTypeId::DocumentType | NodeTypeId::DocumentType |
NodeTypeId::Document => { NodeTypeId::Document(_) => {
None None
} }
} }
@ -1930,7 +1930,7 @@ impl NodeMethods for Node {
characterdata.SetData(value); characterdata.SetData(value);
} }
NodeTypeId::DocumentType | NodeTypeId::DocumentType |
NodeTypeId::Document => {} NodeTypeId::Document(_) => {}
} }
} }
@ -1949,7 +1949,7 @@ impl NodeMethods for Node {
// Step 1. // Step 1.
match self.type_id() { match self.type_id() {
NodeTypeId::Document | NodeTypeId::Document(_) |
NodeTypeId::DocumentFragment | NodeTypeId::DocumentFragment |
NodeTypeId::Element(..) => (), NodeTypeId::Element(..) => (),
_ => return Err(Error::HierarchyRequest) _ => return Err(Error::HierarchyRequest)
@ -1970,7 +1970,7 @@ impl NodeMethods for Node {
NodeTypeId::CharacterData(CharacterDataTypeId::Text) if self.is::<Document>() => NodeTypeId::CharacterData(CharacterDataTypeId::Text) if self.is::<Document>() =>
return Err(Error::HierarchyRequest), return Err(Error::HierarchyRequest),
NodeTypeId::DocumentType if !self.is::<Document>() => return Err(Error::HierarchyRequest), NodeTypeId::DocumentType if !self.is::<Document>() => return Err(Error::HierarchyRequest),
NodeTypeId::Document => return Err(Error::HierarchyRequest), NodeTypeId::Document(_) => return Err(Error::HierarchyRequest),
_ => () _ => ()
} }
@ -2029,7 +2029,7 @@ impl NodeMethods for Node {
} }
}, },
NodeTypeId::CharacterData(..) => (), NodeTypeId::CharacterData(..) => (),
NodeTypeId::Document => unreachable!(), NodeTypeId::Document(_) => unreachable!(),
} }
} }
@ -2279,7 +2279,7 @@ impl NodeMethods for Node {
NodeTypeId::Element(..) => { NodeTypeId::Element(..) => {
self.downcast::<Element>().unwrap().lookup_prefix(namespace) self.downcast::<Element>().unwrap().lookup_prefix(namespace)
}, },
NodeTypeId::Document => { NodeTypeId::Document(_) => {
self.downcast::<Document>().unwrap().GetDocumentElement().and_then(|element| { self.downcast::<Document>().unwrap().GetDocumentElement().and_then(|element| {
element.lookup_prefix(namespace) element.lookup_prefix(namespace)
}) })

View file

@ -797,7 +797,7 @@ impl RangeMethods for Range {
// Step 2. // Step 2.
match new_parent.type_id() { match new_parent.type_id() {
NodeTypeId::Document | NodeTypeId::Document(_) |
NodeTypeId::DocumentType | NodeTypeId::DocumentType |
NodeTypeId::DocumentFragment => return Err(Error::InvalidNodeType), NodeTypeId::DocumentFragment => return Err(Error::InvalidNodeType),
_ => () _ => ()

View file

@ -17,7 +17,7 @@ interface DOMImplementation {
DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId,
DOMString systemId); DOMString systemId);
[NewObject, Throws] [NewObject, Throws]
Document createDocument(DOMString? namespace, XMLDocument createDocument(DOMString? namespace,
[TreatNullAs=EmptyString] DOMString qualifiedName, [TreatNullAs=EmptyString] DOMString qualifiedName,
optional DocumentType? doctype = null); optional DocumentType? doctype = null);
[NewObject] [NewObject]

View file

@ -0,0 +1,13 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* The origin of this IDL file is:
* https://dom.spec.whatwg.org/#interface-document
* https://html.spec.whatwg.org/multipage/#the-document-object
*/
// https://dom.spec.whatwg.org/#interface-document
[Constructor]
interface XMLDocument : Document {};

View file

@ -0,0 +1,97 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use document_loader::DocumentLoader;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::Bindings::XMLDocumentBinding::{self, XMLDocumentMethods};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::document::{Document, DocumentSource, IsHTMLDocument};
use dom::node::Node;
use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use url::Url;
use util::str::DOMString;
// https://dom.spec.whatwg.org/#xmldocument
#[dom_struct]
pub struct XMLDocument {
document: Document,
}
impl XMLDocument {
fn new_inherited(window: &Window,
url: Option<Url>,
is_html_document: IsHTMLDocument,
content_type: Option<DOMString>,
last_modified: Option<String>,
source: DocumentSource,
doc_loader: DocumentLoader) -> XMLDocument {
XMLDocument {
document: Document::new_inherited(window,
url,
is_html_document,
content_type,
last_modified,
source,
doc_loader),
}
}
pub fn new(window: &Window,
url: Option<Url>,
doctype: IsHTMLDocument,
content_type: Option<DOMString>,
last_modified: Option<String>,
source: DocumentSource,
doc_loader: DocumentLoader)
-> Root<XMLDocument> {
let doc = reflect_dom_object(
box XMLDocument::new_inherited(window,
url,
doctype,
content_type,
last_modified,
source,
doc_loader),
GlobalRef::Window(window),
XMLDocumentBinding::Wrap);
{
let node = doc.upcast::<Node>();
node.set_owner_doc(&doc.r().document);
}
doc
}
pub fn Constructor(global: GlobalRef) -> Fallible<Root<XMLDocument>> {
let win = global.as_window();
let doc = win.Document();
let doc = doc.r();
let docloader = DocumentLoader::new(&*doc.loader());
Ok(XMLDocument::new(win,
None,
IsHTMLDocument::NonHTMLDocument,
None,
None,
DocumentSource::NotFromParser,
docloader))
}
}
impl XMLDocumentMethods for XMLDocument {
// https://html.spec.whatwg.org/multipage/#dom-tree-accessors:supported-property-names
fn SupportedPropertyNames(&self) -> Vec<DOMString> {
self.document.SupportedPropertyNames()
}
// https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter
fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString, found: &mut bool) -> *mut JSObject {
self.document.NamedGetter(_cx, name, found)
}
}

View file

@ -195,7 +195,7 @@ impl<'a> Serializable for &'a Node {
Ok(()) Ok(())
}, },
(ChildrenOnly, NodeTypeId::Document) => { (ChildrenOnly, NodeTypeId::Document(_)) => {
for handle in node.children() { for handle in node.children() {
try!(handle.r().serialize(serializer, IncludeNode)); try!(handle.r().serialize(serializer, IncludeNode));
} }
@ -227,7 +227,7 @@ impl<'a> Serializable for &'a Node {
(IncludeNode, NodeTypeId::DocumentFragment) => Ok(()), (IncludeNode, NodeTypeId::DocumentFragment) => Ok(()),
(IncludeNode, NodeTypeId::Document) => panic!("Can't serialize Document node itself"), (IncludeNode, NodeTypeId::Document(_)) => panic!("Can't serialize Document node itself"),
} }
} }
} }

View file

@ -90,21 +90,6 @@
[XMLDocument interface: existence and properties of interface object] [XMLDocument interface: existence and properties of interface object]
expected: FAIL expected: FAIL
[XMLDocument interface object length]
expected: FAIL
[XMLDocument interface: existence and properties of interface prototype object]
expected: FAIL
[XMLDocument interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[XMLDocument must be primary interface of xmlDoc]
expected: FAIL
[Stringification of xmlDoc]
expected: FAIL
[Document interface: xmlDoc must inherit property "origin" with the proper type (3)] [Document interface: xmlDoc must inherit property "origin" with the proper type (3)]
expected: FAIL expected: FAIL

View file

@ -1,8 +1,5 @@
[Document-constructor.html] [Document-constructor.html]
type: testharness type: testharness
[new Document(): interfaces]
expected: FAIL
[new Document(): URL parsing] [new Document(): URL parsing]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,8 @@
[XMLDocument-constructor.html]
type: testharness
[new XMLDocument(): URL parsing]
expected: FAIL
[new XMLDocument(): characterSet aliases]
expected: FAIL

View file

@ -4,15 +4,9 @@
[Should parse correctly in type text/xml] [Should parse correctly in type text/xml]
expected: FAIL expected: FAIL
[XMLDocument interface for correctly parsed document with type text/xml]
expected: FAIL
[Should return an error document for XML wellformedness errors in type text/xml] [Should return an error document for XML wellformedness errors in type text/xml]
expected: FAIL expected: FAIL
[XMLDocument interface for incorrectly parsed document with type text/xml]
expected: FAIL
[Should parse correctly in type application/xml] [Should parse correctly in type application/xml]
expected: TIMEOUT expected: TIMEOUT

View file

@ -990,12 +990,6 @@
[XMLDocument interface: operation load(DOMString)] [XMLDocument interface: operation load(DOMString)]
expected: FAIL expected: FAIL
[XMLDocument must be primary interface of document.implementation.createDocument(null, "", null)]
expected: FAIL
[Stringification of document.implementation.createDocument(null, "", null)]
expected: FAIL
[XMLDocument interface: document.implementation.createDocument(null, "", null) must inherit property "load" with the proper type (0)] [XMLDocument interface: document.implementation.createDocument(null, "", null) must inherit property "load" with the proper type (0)]
expected: FAIL expected: FAIL

View file

@ -224,6 +224,7 @@ var interfaceNamesInGlobalScope = [
"WorkerGlobalScope", // #2823 "WorkerGlobalScope", // #2823
"WorkerLocation", // #2823 "WorkerLocation", // #2823
"WorkerNavigator", // #2823 "WorkerNavigator", // #2823
"XMLDocument",
"XMLHttpRequest", "XMLHttpRequest",
"XMLHttpRequestEventTarget", "XMLHttpRequestEventTarget",
"XMLHttpRequestUpload", "XMLHttpRequestUpload",