diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index e0e5534c79e..9d25d2ad7b1 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -627,11 +627,13 @@ pub trait AttributeHandlers { /// Removes the first attribute with any given namespace and case-sensitive local /// name, if any. - fn remove_attribute(self, namespace: &Namespace, local_name: &Atom); + fn remove_attribute(self, namespace: &Namespace, local_name: &Atom) + -> Option>; /// Removes the first attribute with any namespace and given case-sensitive name. - fn remove_attribute_by_name(self, name: &Atom); + fn remove_attribute_by_name(self, name: &Atom) -> Option>; /// Removes the first attribute that satisfies `find`. - fn do_remove_attribute(self, find: F) where F: Fn(JSRef) -> bool; + fn do_remove_attribute(self, find: F) -> Option> + where F: Fn(JSRef) -> bool; fn has_class(self, name: &Atom) -> bool; @@ -764,22 +766,25 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } - fn remove_attribute(self, namespace: &Namespace, local_name: &Atom) { + fn remove_attribute(self, namespace: &Namespace, local_name: &Atom) + -> Option> { self.do_remove_attribute(|attr| { attr.namespace() == namespace && attr.local_name() == local_name - }); + }) } - fn remove_attribute_by_name(self, name: &Atom) { - self.do_remove_attribute(|attr| attr.name() == name); + fn remove_attribute_by_name(self, name: &Atom) -> Option> { + self.do_remove_attribute(|attr| attr.name() == name) } - fn do_remove_attribute(self, find: F) where F: Fn(JSRef) -> bool { + fn do_remove_attribute(self, find: F) -> Option> + where F: Fn(JSRef) -> bool + { let idx = self.attrs.borrow().iter() .map(|attr| attr.root()) .position(|attr| find(attr.r())); - if let Some(idx) = idx { + idx.map(|idx| { let attr = (*self.attrs.borrow())[idx].root(); if attr.r().namespace() == &ns!("") { vtable_for(&NodeCast::from_ref(self)).before_remove_attr(attr.r()); @@ -798,7 +803,8 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { }; document.r().content_changed(node, damage); } - }; + Temporary::from_rooted(attr.r()) + }) } fn has_class(self, name: &Atom) -> bool { diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs index 239fff86fbb..50b24aafcc9 100644 --- a/components/script/dom/namednodemap.rs +++ b/components/script/dom/namednodemap.rs @@ -5,6 +5,7 @@ use dom::attr::Attr; use dom::bindings::codegen::Bindings::NamedNodeMapBinding; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; +use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -64,12 +65,32 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { } // https://dom.spec.whatwg.org/#dom-namednodemap-getnameditemns - fn GetNamedItemNS(self, namespace: Option, name: DOMString) -> Option> { + fn GetNamedItemNS(self, namespace: Option, local_name: DOMString) + -> Option> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); let ns = namespace::from_domstring(namespace); - owner.get_attribute(&ns, &Atom::from_slice(&name)) + owner.get_attribute(&ns, &Atom::from_slice(&local_name)) + } + + // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem + fn RemoveNamedItem(self, name: DOMString) -> Fallible> { + let owner = self.owner.root(); + // FIXME(https://github.com/rust-lang/rust/issues/23338) + let owner = owner.r(); + let name = owner.parsed_name(name); + owner.remove_attribute_by_name(&Atom::from_slice(&name)).ok_or(Error::NotFound) + } + + // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns + fn RemoveNamedItemNS(self, namespace: Option, local_name: DOMString) + -> Fallible> { + let owner = self.owner.root(); + // FIXME(https://github.com/rust-lang/rust/issues/23338) + let owner = owner.r(); + let ns = namespace::from_domstring(namespace); + owner.remove_attribute(&ns, &Atom::from_slice(&local_name)).ok_or(Error::NotFound) } fn IndexedGetter(self, index: u32, found: &mut bool) -> Option> { diff --git a/components/script/dom/webidls/NamedNodeMap.webidl b/components/script/dom/webidls/NamedNodeMap.webidl index f15151b8ce9..5b85e755804 100644 --- a/components/script/dom/webidls/NamedNodeMap.webidl +++ b/components/script/dom/webidls/NamedNodeMap.webidl @@ -11,8 +11,8 @@ interface NamedNodeMap { //Attr? setNamedItem(Attr attr); //[Throws] //Attr? setNamedItemNS(Attr attr); - //[Throws] - //Attr removeNamedItem(DOMString name); - //[Throws] - //Attr removeNamedItemNS(DOMString? namespace, DOMString name); + [Throws] + Attr removeNamedItem(DOMString name); + [Throws] + Attr removeNamedItemNS(DOMString? namespace, DOMString name); }; diff --git a/tests/wpt/metadata/dom/interfaces.html.ini b/tests/wpt/metadata/dom/interfaces.html.ini index 271ee13a1c6..3b41ae6b502 100644 --- a/tests/wpt/metadata/dom/interfaces.html.ini +++ b/tests/wpt/metadata/dom/interfaces.html.ini @@ -345,12 +345,6 @@ [NamedNodeMap interface: operation setNamedItemNS(Attr)] expected: FAIL - [NamedNodeMap interface: operation removeNamedItem(DOMString)] - expected: FAIL - - [NamedNodeMap interface: operation removeNamedItemNS(DOMString,DOMString)] - expected: FAIL - [CharacterData interface: attribute previousElementSibling] expected: FAIL