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

View file

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

View file

@ -1392,14 +1392,14 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
}
impl Document {
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)
-> Document {
pub 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)
-> Document {
let url = url.unwrap_or_else(|| url!("about:blank"));
let (ready_state, domcontentloaded_dispatched) = if source == DocumentSource::FromParser {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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(())
},
(ChildrenOnly, NodeTypeId::Document) => {
(ChildrenOnly, NodeTypeId::Document(_)) => {
for handle in node.children() {
try!(handle.r().serialize(serializer, IncludeNode));
}
@ -227,7 +227,7 @@ impl<'a> Serializable for &'a Node {
(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]
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)]
expected: FAIL

View file

@ -1,8 +1,5 @@
[Document-constructor.html]
type: testharness
[new Document(): interfaces]
expected: FAIL
[new Document(): URL parsing]
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]
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]
expected: FAIL
[XMLDocument interface for incorrectly parsed document with type text/xml]
expected: FAIL
[Should parse correctly in type application/xml]
expected: TIMEOUT

View file

@ -990,12 +990,6 @@
[XMLDocument interface: operation load(DOMString)]
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)]
expected: FAIL

View file

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