aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorMathieu Hordesseaux <mathieu@adopteunmec.com>2015-12-23 17:21:45 +0100
committerMathieu Hordesseaux <mathieu@adopteunmec.com>2016-01-28 12:35:44 +0100
commit322b120f8a17876cb97b6d734cfde4f68a04c5cd (patch)
tree00dc3c08ec5d9b248e70db036b66a5987f0be06a /components/script
parentbc44ae679f0d4a01194777c56e09a48fbebea1ad (diff)
downloadservo-322b120f8a17876cb97b6d734cfde4f68a04c5cd.tar.gz
servo-322b120f8a17876cb97b6d734cfde4f68a04c5cd.zip
Implement SetNamedItem, SetNamedItemNS, SetAttributeNode and SetAttributeNodeNS
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/attr.rs10
-rw-r--r--components/script/dom/element.rs64
-rw-r--r--components/script/dom/namednodemap.rs11
-rw-r--r--components/script/dom/webidls/Element.webidl5
-rw-r--r--components/script/dom/webidls/NamedNodeMap.webidl8
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]