diff options
author | Mathieu Hordesseaux <mathieu@adopteunmec.com> | 2015-12-23 17:21:45 +0100 |
---|---|---|
committer | Mathieu Hordesseaux <mathieu@adopteunmec.com> | 2016-01-28 12:35:44 +0100 |
commit | 322b120f8a17876cb97b6d734cfde4f68a04c5cd (patch) | |
tree | 00dc3c08ec5d9b248e70db036b66a5987f0be06a /components/script | |
parent | bc44ae679f0d4a01194777c56e09a48fbebea1ad (diff) | |
download | servo-322b120f8a17876cb97b6d734cfde4f68a04c5cd.tar.gz servo-322b120f8a17876cb97b6d734cfde4f68a04c5cd.zip |
Implement SetNamedItem, SetNamedItemNS, SetAttributeNode and SetAttributeNodeNS
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/attr.rs | 10 | ||||
-rw-r--r-- | components/script/dom/element.rs | 64 | ||||
-rw-r--r-- | components/script/dom/namednodemap.rs | 11 | ||||
-rw-r--r-- | components/script/dom/webidls/Element.webidl | 5 | ||||
-rw-r--r-- | components/script/dom/webidls/NamedNodeMap.webidl | 8 |
5 files changed, 82 insertions, 16 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 34cb8537c86..ec7b999f5b9 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -193,16 +193,12 @@ impl Attr { pub fn set_owner(&self, owner: Option<&Element>) { let ns = &self.identifier.namespace; match (self.owner().r(), owner) { - (None, Some(new)) => { - // Already in the list of attributes of new owner. - assert!(new.get_attribute(&ns, &self.identifier.local_name) == - Some(Root::from_ref(self))) - } (Some(old), None) => { // Already gone from the list of attributes of old owner. - assert!(old.get_attribute(&ns, &self.identifier.local_name).is_none()) + assert!(old.get_attribute(&ns, &self.identifier.local_name).r() != Some(self)) } - (old, new) => assert!(old == new), + (Some(old), Some(new)) => assert!(old == new), + _ => {}, } self.owner.set(owner); } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4fcdea83dcf..66cad82dbb8 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -863,9 +863,7 @@ impl Element { name: Atom, namespace: Namespace, prefix: Option<Atom>) { - self.will_mutate_attr(); let window = window_from_node(self); - let in_empty_ns = namespace == ns!(); let attr = Attr::new(&window, local_name, value, @@ -873,9 +871,15 @@ impl Element { namespace, prefix, Some(self)); - self.attrs.borrow_mut().push(JS::from_rooted(&attr)); - if in_empty_ns { - vtable_for(self.upcast()).attribute_mutated(&attr, AttributeMutation::Set(None)); + self.push_attribute(&attr); + } + + pub fn push_attribute(&self, attr: &Attr) { + assert!(attr.GetOwnerElement().r() == Some(self)); + self.will_mutate_attr(); + self.attrs.borrow_mut().push(JS::from_ref(attr)); + if attr.namespace() == &ns!() { + vtable_for(self.upcast()).attribute_mutated(attr, AttributeMutation::Set(None)); } } @@ -1269,6 +1273,56 @@ impl ElementMethods for Element { Ok(()) } + // https://dom.spec.whatwg.org/#dom-element-setattributenode + fn SetAttributeNode(&self, attr: &Attr) -> Fallible<Option<Root<Attr>>> { + // Step 1. + if let Some(owner) = attr.GetOwnerElement() { + if &*owner != self { + return Err(Error::InUseAttribute); + } + } + + // Step 2. + let position = self.attrs.borrow().iter().position(|old_attr| { + attr.namespace() == old_attr.namespace() && attr.local_name() == old_attr.local_name() + }); + + if let Some(position) = position { + + let old_attr = Root::from_ref(&*self.attrs.borrow()[position]); + + // Step 3. + if old_attr.r() == attr { + return Ok(Some(Root::from_ref(attr))); + } + + // Step 4. + self.will_mutate_attr(); + attr.set_owner(Some(self)); + self.attrs.borrow_mut()[position] = JS::from_ref(attr); + old_attr.set_owner(None); + if attr.namespace() == &ns!() { + vtable_for(self.upcast()).attribute_mutated( + &attr, AttributeMutation::Set(Some(&old_attr.value()))); + } + + // Step 6. + Ok(Some(old_attr)) + } else { + // Step 5. + attr.set_owner(Some(self)); + self.push_attribute(attr); + + // Step 6. + Ok(None) + } + } + + // https://dom.spec.whatwg.org/#dom-element-setattributenodens + fn SetAttributeNodeNS(&self, attr: &Attr) -> Fallible<Option<Root<Attr>>> { + self.SetAttributeNode(attr) + } + // https://dom.spec.whatwg.org/#dom-element-removeattribute fn RemoveAttribute(&self, name: DOMString) { let name = self.parsed_name(name); diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs index 0bb7f438c8e..ca564f04e00 100644 --- a/components/script/dom/namednodemap.rs +++ b/components/script/dom/namednodemap.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::attr::Attr; +use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::NamedNodeMapBinding; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::error::{Error, Fallible}; @@ -58,6 +59,16 @@ impl NamedNodeMapMethods for NamedNodeMap { self.owner.get_attribute(&ns, &Atom::from(&*local_name)) } + // https://dom.spec.whatwg.org/#dom-namednodemap-setnameditem + fn SetNamedItem(&self, attr: &Attr) -> Fallible<Option<Root<Attr>>> { + self.owner.SetAttributeNode(attr) + } + + // https://dom.spec.whatwg.org/#dom-namednodemap-setnameditemns + fn SetNamedItemNS(&self, attr: &Attr) -> Fallible<Option<Root<Attr>>> { + self.SetNamedItem(attr) + } + // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem fn RemoveNamedItem(&self, name: DOMString) -> Fallible<Root<Attr>> { let name = self.owner.parsed_name(name); diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl index 2e3deb6adb0..1a9b74bb9f2 100644 --- a/components/script/dom/webidls/Element.webidl +++ b/components/script/dom/webidls/Element.webidl @@ -50,6 +50,11 @@ interface Element : Node { boolean hasAttribute(DOMString name); boolean hasAttributeNS(DOMString? namespace, DOMString localName); + [Throws] + Attr? setAttributeNode(Attr attr); + [Throws] + Attr? setAttributeNodeNS(Attr attr); + [Pure, Throws] Element? closest(DOMString selectors); diff --git a/components/script/dom/webidls/NamedNodeMap.webidl b/components/script/dom/webidls/NamedNodeMap.webidl index 235de06a802..581c8dc7e89 100644 --- a/components/script/dom/webidls/NamedNodeMap.webidl +++ b/components/script/dom/webidls/NamedNodeMap.webidl @@ -13,10 +13,10 @@ interface NamedNodeMap { getter Attr? getNamedItem(DOMString name); [Pure] Attr? getNamedItemNS(DOMString? namespace, DOMString localName); - //[Throws] - //Attr? setNamedItem(Attr attr); - //[Throws] - //Attr? setNamedItemNS(Attr attr); + [Throws] + Attr? setNamedItem(Attr attr); + [Throws] + Attr? setNamedItemNS(Attr attr); [Throws] Attr removeNamedItem(DOMString name); [Throws] |