From 7e07dcc7ee964e89cbb263ebca6db71fac22cf05 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 7 Apr 2015 21:20:57 +0200 Subject: [PATCH 1/4] Add missing NewObject annotation in Document --- components/script/dom/webidls/Document.webidl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl index 984f79eb528..dea9b9c38f6 100644 --- a/components/script/dom/webidls/Document.webidl +++ b/components/script/dom/webidls/Document.webidl @@ -27,27 +27,31 @@ interface Document : Node { HTMLCollection getElementsByClassName(DOMString classNames); Element? getElementById(DOMString elementId); - [Throws] + [NewObject, Throws] Element createElement(DOMString localName); - [Throws] + [NewObject, Throws] Element createElementNS(DOMString? namespace, DOMString qualifiedName); + [NewObject] DocumentFragment createDocumentFragment(); + [NewObject] Text createTextNode(DOMString data); + [NewObject] Comment createComment(DOMString data); - [Throws] + [NewObject, Throws] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data); - [Throws] + [NewObject, Throws] Attr createAttribute(DOMString localName); - [Throws] + [NewObject, Throws] Node importNode(Node node, optional boolean deep = false); [Throws] Node adoptNode(Node node); - [Throws] + [NewObject, Throws] Event createEvent(DOMString interface_); + [NewObject] Range createRange(); // NodeFilter.SHOW_ALL = 0xFFFFFFFF From abc01d598afca71f419053b3e886769d874003b0 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 7 Apr 2015 23:20:56 +0200 Subject: [PATCH 2/4] Add script::dom::utils::validate_qualified_name() --- components/script/dom/bindings/utils.rs | 17 ++++++++++++++++- components/script/dom/document.rs | 16 +++------------- components/script/dom/domimplementation.rs | 21 ++++++--------------- components/script/dom/element.rs | 14 ++++---------- 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 7faca76b6c6..97f6eaf9392 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class}; -use dom::bindings::error::throw_type_error; +use dom::bindings::error::{Error, ErrorResult, throw_type_error}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{Temporary, Root}; use dom::browsercontext; @@ -604,6 +604,21 @@ pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject, return true; } +/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details. +pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult { + match xml_name_type(qualified_name) { + XMLName::InvalidXMLName => { + // Step 1. + return Err(Error::InvalidCharacter); + }, + XMLName::Name => { + // Step 2. + return Err(Error::Namespace); + }, + XMLName::QName => Ok(()) + } +} + /// Results of `xml_name_type`. #[derive(PartialEq)] #[allow(missing_docs)] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 62fdfbeb109..a280507d4ff 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -27,8 +27,8 @@ use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, Temporary use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::utils::reflect_dom_object; -use dom::bindings::utils::xml_name_type; -use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName}; +use dom::bindings::utils::{xml_name_type, validate_qualified_name}; +use dom::bindings::utils::XMLName::InvalidXMLName; use dom::comment::Comment; use dom::customevent::CustomEvent; use dom::documentfragment::DocumentFragment; @@ -976,17 +976,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { namespace: Option, qualified_name: DOMString) -> Fallible> { let ns = namespace::from_domstring(namespace); - match xml_name_type(&qualified_name) { - InvalidXMLName => { - debug!("Not a valid element name"); - return Err(InvalidCharacter); - }, - Name => { - debug!("Not a valid qualified element name"); - return Err(Namespace); - }, - QName => {} - } + try!(validate_qualified_name(&qualified_name)); let (prefix_from_qname, local_name_from_qname) = get_attribute_parts(&qualified_name); match (&ns, prefix_from_qname, local_name_from_qname) { diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 7e2a3dba03a..e5cac62f4e7 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -8,12 +8,10 @@ use dom::bindings::codegen::Bindings::DOMImplementationBinding::DOMImplementatio use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::error::Fallible; -use dom::bindings::error::Error::{InvalidCharacter, Namespace}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Root, Temporary, OptionalRootable}; use dom::bindings::utils::{Reflector, reflect_dom_object}; -use dom::bindings::utils::xml_name_type; -use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName}; +use dom::bindings::utils::validate_qualified_name; use dom::document::{Document, DocumentHelpers, IsHTMLDocument}; use dom::document::DocumentSource; use dom::documenttype::DocumentType; @@ -52,18 +50,11 @@ impl DOMImplementation { // http://dom.spec.whatwg.org/#domimplementation impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype - fn CreateDocumentType(self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible> { - match xml_name_type(&qname) { - // Step 1. - InvalidXMLName => Err(InvalidCharacter), - // Step 2. - Name => Err(Namespace), - // Step 3. - QName => { - let document = self.document.root(); - Ok(DocumentType::new(qname, Some(pubid), Some(sysid), document.r())) - } - } + fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString) + -> Fallible> { + try!(validate_qualified_name(&qualified_name)); + let document = self.document.root(); + Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r())) } // http://dom.spec.whatwg.org/#dom-domimplementation-createdocument diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index c3bf678a48d..0ebf4d02bea 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -30,8 +30,8 @@ use dom::bindings::error::Error::NoModificationAllowed; use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::trace::RootedVec; -use dom::bindings::utils::xml_name_type; -use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName}; +use dom::bindings::utils::{xml_name_type, validate_qualified_name}; +use dom::bindings::utils::XMLName::InvalidXMLName; use dom::create::create_element; use dom::domrect::DOMRect; use dom::domrectlist::DOMRectList; @@ -1037,14 +1037,8 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // Step 1. let namespace = namespace::from_domstring(namespace_url); - let name_type = xml_name_type(&name); - match name_type { - // Step 2. - InvalidXMLName => return Err(InvalidCharacter), - // Step 3. - Name => return Err(Error::Namespace), - QName => {} - } + // Steps 2-3. + try!(validate_qualified_name(&name)); // Step 4. let (prefix, local_name) = get_attribute_parts(&name); From 7b4f6126c87077318355604c279bc0cfed5041e6 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Wed, 8 Apr 2015 01:29:27 +0200 Subject: [PATCH 3/4] Add script::dom::utils::validate_and_extract() Accidentally fixes bugs about Document::createElementNS() where the implementation of "validate and extract" used to check whether the local name extracted from the qualified name was "xmlns" instead of the qualified name itself. --- components/script/dom/bindings/utils.rs | 53 ++++++++++++++- components/script/dom/document.rs | 41 +++--------- components/script/dom/element.rs | 64 ++----------------- .../DOMImplementation-createDocument.html.ini | 35 ---------- .../nodes/Document-createElementNS.html.ini | 35 ---------- 5 files changed, 67 insertions(+), 161 deletions(-) delete mode 100644 tests/wpt/metadata/dom/nodes/DOMImplementation-createDocument.html.ini delete mode 100644 tests/wpt/metadata/dom/nodes/Document-createElementNS.html.ini diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 97f6eaf9392..c8a4e6a9da7 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -7,14 +7,17 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class}; -use dom::bindings::error::{Error, ErrorResult, throw_type_error}; +use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{Temporary, Root}; use dom::browsercontext; use dom::window; +use util::namespace; +use util::str::DOMString; use libc; use libc::c_uint; +use std::borrow::ToOwned; use std::boxed; use std::cell::Cell; use std::ffi::CString; @@ -43,6 +46,7 @@ use js::rust::with_compartment; use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT}; use js::JSFUN_CONSTRUCTOR; use js; +use string_cache::{Atom, Namespace}; /// Proxy handler for a WindowProxy. pub struct WindowProxyHandler(pub *const libc::c_void); @@ -619,6 +623,53 @@ pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult { } } +/// Validate a namespace and qualified name and extract their parts. +/// See https://dom.spec.whatwg.org/#validate-and-extract for details. +pub fn validate_and_extract(namespace: Option, qualified_name: &str) + -> Fallible<(Namespace, Option, Atom)> { + // Step 1. + let namespace = namespace::from_domstring(namespace); + + // Step 2. + try!(validate_qualified_name(qualified_name)); + + let (prefix, local_name) = if qualified_name.contains(":") { + // Step 5. + let mut parts = qualified_name.splitn(1, ':'); + let prefix = parts.next().unwrap(); + debug_assert!(!prefix.is_empty()); + let local_name = parts.next().unwrap(); + debug_assert!(!local_name.contains(":")); + (Some(prefix), local_name) + } else { + (None, qualified_name) + }; + + match (namespace, prefix) { + (ns!(""), Some(_)) => { + // Step 6. + Err(Error::Namespace) + }, + (ref ns, Some("xml")) if ns != &ns!(XML) => { + // Step 7. + Err(Error::Namespace) + }, + (ref ns, p) if ns != &ns!(XMLNS) && + (qualified_name == "xmlns" || p == Some("xmlns")) => { + // Step 8. + Err(Error::Namespace) + }, + (ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => { + // Step 9. + Err(Error::Namespace) + }, + (ns, p) => { + // Step 10. + Ok((ns, p.map(|s| s.to_owned()), Atom::from_slice(local_name))) + } + } +} + /// Results of `xml_name_type`. #[derive(PartialEq)] #[allow(missing_docs)] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index a280507d4ff..3e490fe8ba4 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -21,20 +21,20 @@ use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElem use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security}; -use dom::bindings::error::Error::{HierarchyRequest, Namespace}; +use dom::bindings::error::Error::HierarchyRequest; use dom::bindings::global::GlobalRef; use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::utils::reflect_dom_object; -use dom::bindings::utils::{xml_name_type, validate_qualified_name}; +use dom::bindings::utils::{xml_name_type, validate_and_extract}; use dom::bindings::utils::XMLName::InvalidXMLName; use dom::comment::Comment; use dom::customevent::CustomEvent; use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; use dom::domimplementation::DOMImplementation; -use dom::element::{Element, ElementCreator, AttributeHandlers, get_attribute_parts}; +use dom::element::{Element, ElementCreator, AttributeHandlers}; use dom::element::{ElementTypeId, ActivationElementHelpers}; use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers}; @@ -67,7 +67,7 @@ use net_traits::CookieSource::NonHTTP; use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl}; use script_task::Runnable; use script_traits::{MouseButton, UntrustedNodeAddress}; -use util::{opts, namespace}; +use util::opts; use util::str::{DOMString, split_html_space_chars}; use layout_interface::{ReflowGoal, ReflowQueryType}; @@ -975,35 +975,10 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { fn CreateElementNS(self, namespace: Option, qualified_name: DOMString) -> Fallible> { - let ns = namespace::from_domstring(namespace); - try!(validate_qualified_name(&qualified_name)); - - let (prefix_from_qname, local_name_from_qname) = get_attribute_parts(&qualified_name); - match (&ns, prefix_from_qname, local_name_from_qname) { - // throw if prefix is not null and namespace is null - (&ns!(""), Some(_), _) => { - debug!("Namespace can't be null with a non-null prefix"); - return Err(Namespace); - }, - // throw if prefix is "xml" and namespace is not the XML namespace - (_, Some(ref prefix), _) if "xml" == *prefix && ns != ns!(XML) => { - debug!("Namespace must be the xml namespace if the prefix is 'xml'"); - return Err(Namespace); - }, - // throw if namespace is the XMLNS namespace and neither qualifiedName nor prefix is - // "xmlns" - (&ns!(XMLNS), Some(ref prefix), _) if "xmlns" == *prefix => {}, - (&ns!(XMLNS), _, "xmlns") => {}, - (&ns!(XMLNS), _, _) => { - debug!("The prefix or the qualified name must be 'xmlns' if namespace is the XMLNS namespace "); - return Err(Namespace); - }, - _ => {} - } - - let name = QualName::new(ns, Atom::from_slice(local_name_from_qname)); - Ok(Element::create(name, prefix_from_qname.map(|s| s.to_owned()), self, - ElementCreator::ScriptCreated)) + let (namespace, prefix, local_name) = + try!(validate_and_extract(namespace, &qualified_name)); + let name = QualName::new(namespace, local_name); + Ok(Element::create(name, prefix, self, ElementCreator::ScriptCreated)) } // http://dom.spec.whatwg.org/#dom-document-createattribute diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 0ebf4d02bea..afdd42f6bf6 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -24,13 +24,12 @@ use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextA use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast}; use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast; use dom::bindings::error::{ErrorResult, Fallible}; -use dom::bindings::error::Error; use dom::bindings::error::Error::{InvalidCharacter, Syntax}; use dom::bindings::error::Error::NoModificationAllowed; use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::trace::RootedVec; -use dom::bindings::utils::{xml_name_type, validate_qualified_name}; +use dom::bindings::utils::{xml_name_type, validate_and_extract}; use dom::bindings::utils::XMLName::InvalidXMLName; use dom::create::create_element; use dom::domrect::DOMRect; @@ -1031,52 +1030,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-setattributens fn SetAttributeNS(self, - namespace_url: Option, - name: DOMString, + namespace: Option, + qualified_name: DOMString, value: DOMString) -> ErrorResult { - // Step 1. - let namespace = namespace::from_domstring(namespace_url); - - // Steps 2-3. - try!(validate_qualified_name(&name)); - - // Step 4. - let (prefix, local_name) = get_attribute_parts(&name); - - if let Some(ref prefix_str) = prefix { - // Step 5. - if namespace == ns!("") { - return Err(Error::Namespace); - } - - // Step 6. - if "xml" == *prefix_str && namespace != ns!(XML) { - return Err(Error::Namespace); - } - - // Step 7b. - if "xmlns" == *prefix_str && namespace != ns!(XMLNS) { - return Err(Error::Namespace); - } - } - - let name = Atom::from_slice(&name); - let local_name = Atom::from_slice(local_name); - let xmlns = atom!("xmlns"); - - // Step 7a. - if xmlns == name && namespace != ns!(XMLNS) { - return Err(Error::Namespace); - } - - // Step 8. - if namespace == ns!(XMLNS) && xmlns != name && Some("xmlns") != prefix { - return Err(Error::Namespace); - } - - // Step 9. + let (namespace, prefix, local_name) = + try!(validate_and_extract(namespace, &qualified_name)); + let qualified_name = Atom::from_slice(&qualified_name); let value = self.parse_attribute(&namespace, &local_name, value); - self.do_set_attribute(local_name.clone(), value, name, + self.do_set_attribute(local_name.clone(), value, qualified_name, namespace.clone(), prefix.map(|s| s.to_owned()), |attr| { *attr.local_name() == local_name && @@ -1266,17 +1227,6 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } } -pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) { - //FIXME: Throw for XML-invalid names - //FIXME: Throw for XMLNS-invalid names - if name.contains(":") { - let mut parts = name.splitn(1, ':'); - (Some(parts.next().unwrap()), parts.next().unwrap()) - } else { - (None, name) - } -} - impl<'a> VirtualMethods for JSRef<'a, Element> { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let node: &JSRef = NodeCast::from_borrowed_ref(self); diff --git a/tests/wpt/metadata/dom/nodes/DOMImplementation-createDocument.html.ini b/tests/wpt/metadata/dom/nodes/DOMImplementation-createDocument.html.ini deleted file mode 100644 index 8d02570c391..00000000000 --- a/tests/wpt/metadata/dom/nodes/DOMImplementation-createDocument.html.ini +++ /dev/null @@ -1,35 +0,0 @@ -[DOMImplementation-createDocument.html] - type: testharness - [createDocument test 23: null,"xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 41: undefined,"xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 64: "http://example.com/","xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 69: "http://example.com/","xmlns:foo",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 108: "/","xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 111: "/","xmlns:foo",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 121: "http://www.w3.org/XML/1998/namespace","xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 124: "http://www.w3.org/XML/1998/namespace","xmlns:foo",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 141: "http://www.w3.org/2000/xmlns/","foo:xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 150: "foo:","xmlns",null,"NAMESPACE_ERR"] - expected: FAIL - - [createDocument test 153: "foo:","xmlns:foo",null,"NAMESPACE_ERR"] - expected: FAIL - diff --git a/tests/wpt/metadata/dom/nodes/Document-createElementNS.html.ini b/tests/wpt/metadata/dom/nodes/Document-createElementNS.html.ini deleted file mode 100644 index 69ab187bf8d..00000000000 --- a/tests/wpt/metadata/dom/nodes/Document-createElementNS.html.ini +++ /dev/null @@ -1,35 +0,0 @@ -[Document-createElementNS.html] - type: testharness - [createElementNS test 23: null,"xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 41: undefined,"xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 64: "http://example.com/","xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 69: "http://example.com/","xmlns:foo","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 108: "/","xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 111: "/","xmlns:foo","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 121: "http://www.w3.org/XML/1998/namespace","xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 124: "http://www.w3.org/XML/1998/namespace","xmlns:foo","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 141: "http://www.w3.org/2000/xmlns/","foo:xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 150: "foo:","xmlns","NAMESPACE_ERR"] - expected: FAIL - - [createElementNS test 153: "foo:","xmlns:foo","NAMESPACE_ERR"] - expected: FAIL - From 2353bc4798f074f6b4d249c98c39cc74822a5f2a Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Wed, 8 Apr 2015 02:00:18 +0200 Subject: [PATCH 4/4] Implement Document::CreateAttributeNS() --- components/script/dom/document.rs | 12 ++++++++++++ components/script/dom/webidls/Document.webidl | 8 +++++--- tests/wpt/metadata/dom/interfaces.html.ini | 9 --------- tests/wpt/metadata/html/dom/interfaces.html.ini | 6 ------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 3e490fe8ba4..eccaeabde5e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -997,6 +997,18 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None)) } + // http://dom.spec.whatwg.org/#dom-document-createattributens + fn CreateAttributeNS(self, namespace: Option, qualified_name: DOMString) + -> Fallible> { + let (namespace, prefix, local_name) = + try!(validate_and_extract(namespace, &qualified_name)); + let window = self.window.root(); + let value = AttrValue::String("".to_owned()); + let qualified_name = Atom::from_slice(&qualified_name); + Ok(Attr::new(window.r(), local_name, value, qualified_name, + namespace, prefix, None)) + } + // http://dom.spec.whatwg.org/#dom-document-createdocumentfragment fn CreateDocumentFragment(self) -> Temporary { DocumentFragment::new(self) diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl index dea9b9c38f6..c57b09fff1b 100644 --- a/components/script/dom/webidls/Document.webidl +++ b/components/script/dom/webidls/Document.webidl @@ -40,14 +40,16 @@ interface Document : Node { [NewObject, Throws] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data); - [NewObject, Throws] - Attr createAttribute(DOMString localName); - [NewObject, Throws] Node importNode(Node node, optional boolean deep = false); [Throws] Node adoptNode(Node node); + [NewObject, Throws] + Attr createAttribute(DOMString localName); + [NewObject, Throws] + Attr createAttributeNS(DOMString? namespace, DOMString localName); + [NewObject, Throws] Event createEvent(DOMString interface_); diff --git a/tests/wpt/metadata/dom/interfaces.html.ini b/tests/wpt/metadata/dom/interfaces.html.ini index c3913ed9046..2c1b57f5f92 100644 --- a/tests/wpt/metadata/dom/interfaces.html.ini +++ b/tests/wpt/metadata/dom/interfaces.html.ini @@ -90,9 +90,6 @@ [Document interface: operation importNode(Node,boolean)] expected: FAIL - [Document interface: operation createAttributeNS(DOMString,DOMString)] - expected: FAIL - [Document interface: operation createNodeIterator(Node,unsigned long,NodeFilter)] expected: FAIL @@ -141,9 +138,6 @@ [Document interface: xmlDoc must inherit property "origin" with the proper type (3)] expected: FAIL - [Document interface: calling createAttributeNS(DOMString,DOMString) on xmlDoc with too few arguments must throw TypeError] - expected: FAIL - [Document interface: calling createNodeIterator(Node,unsigned long,NodeFilter) on xmlDoc with too few arguments must throw TypeError] expected: FAIL @@ -1020,9 +1014,6 @@ [DOMTokenList interface object length] expected: FAIL - [Document interface: xmlDoc must inherit property "createAttributeNS" with the proper type (22)] - expected: FAIL - [Document interface: xmlDoc must inherit property "createNodeIterator" with the proper type (25)] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 6bb217f0051..f91c0e52aeb 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -1035,12 +1035,6 @@ [Document interface: document.implementation.createDocument(null, "", null) must inherit property "origin" with the proper type (3)] expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "createAttributeNS" with the proper type (22)] - expected: FAIL - - [Document interface: calling createAttributeNS(DOMString,DOMString) on document.implementation.createDocument(null, "", null) with too few arguments must throw TypeError] - expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "createNodeIterator" with the proper type (25)] expected: FAIL