Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SetNamedItem and SetNamedItemNS #9061

Merged
merged 1 commit into from Jan 28, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Implement SetNamedItem, SetNamedItemNS, SetAttributeNode and SetAttri…

…buteNodeNS
  • Loading branch information
Mathieu Hordesseaux
Mathieu Hordesseaux committed Jan 28, 2016
commit 322b120f8a17876cb97b6d734cfde4f68a04c5cd
@@ -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);
}
@@ -863,19 +863,23 @@ 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,
name,
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);
@@ -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);
@@ -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);

@@ -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]
@@ -108,12 +108,6 @@
[Element interface: operation hasAttributes()]
expected: FAIL

[Element interface: operation setAttributeNode(Attr)]
expected: FAIL

[Element interface: operation setAttributeNodeNS(Attr)]
expected: FAIL

[Element interface: operation removeAttributeNode(Attr)]
expected: FAIL

@@ -126,18 +120,6 @@
[Element interface: element must inherit property "hasAttributes" with the proper type (7)]
expected: FAIL

[Element interface: element must inherit property "setAttributeNode" with the proper type (19)]
expected: FAIL

[Element interface: calling setAttributeNode(Attr) on element with too few arguments must throw TypeError]
expected: FAIL

[Element interface: element must inherit property "setAttributeNodeNS" with the proper type (20)]
expected: FAIL

[Element interface: calling setAttributeNodeNS(Attr) on element with too few arguments must throw TypeError]
expected: FAIL

[Element interface: element must inherit property "removeAttributeNode" with the proper type (21)]
expected: FAIL

@@ -156,12 +138,6 @@
[Element interface: calling queryAll(DOMString) on element with too few arguments must throw TypeError]
expected: FAIL

[NamedNodeMap interface: operation setNamedItem(Attr)]
expected: FAIL

[NamedNodeMap interface: operation setNamedItemNS(Attr)]
expected: FAIL

[Range interface: stringifier]
expected: FAIL

@@ -1,17 +1,8 @@
[attributes.html]
type: testharness
[Basic functionality of setAttributeNode]
expected: FAIL

[Basic functionality of removeAttributeNode]
expected: FAIL

[setAttributeNode on bound attribute should throw InUseAttributeError]
expected: FAIL

[Basic functionality of setAttributeNodeNS]
expected: FAIL

[getAttributeNames tests]
expected: FAIL

@@ -27,12 +18,6 @@
[Own property correctness with two namespaced attributes with the same name-with-prefix]
expected: FAIL

[setAttributeNode, if it fires mutation events, should fire one with the new node when resetting an existing attribute (outer shell)]
expected: FAIL

[setAttributeNode called with an Attr that has the same name as an existing one should not change attribute order]
expected: FAIL

[Own property names should only include all-lowercase qualified names for an HTML element in an HTML document]
expected: FAIL

@@ -2013,18 +2013,6 @@
[Element interface: document.createElement("noscript") must inherit property "hasAttributes" with the proper type (7)]
expected: FAIL

[Element interface: document.createElement("noscript") must inherit property "setAttributeNode" with the proper type (19)]
expected: FAIL

[Element interface: calling setAttributeNode(Attr) on document.createElement("noscript") with too few arguments must throw TypeError]
expected: FAIL

[Element interface: document.createElement("noscript") must inherit property "setAttributeNodeNS" with the proper type (20)]
expected: FAIL

[Element interface: calling setAttributeNodeNS(Attr) on document.createElement("noscript") with too few arguments must throw TypeError]
expected: FAIL

[Element interface: document.createElement("noscript") must inherit property "removeAttributeNode" with the proper type (21)]
expected: FAIL

@@ -9101,3 +9089,4 @@

[WebSocket interface: new WebSocket("ws://foo") must inherit property "extensions" with the proper type (10)]
expected: FAIL

@@ -12998,3 +12998,4 @@

[dialog.itemId: IDL set to object "test-valueOf" followed by IDL get]
expected: FAIL

@@ -59,3 +59,4 @@

[Interfaces for RTC]
expected: FAIL

@@ -446,6 +446,26 @@
assert_equals(el2.getAttributeNS("x", "foo"), "bar");
}, "Basic functionality of setAttributeNodeNS")

test(function() {
var el = document.createElement("div");
var other = document.createElement("div");
attr = document.createAttribute("foo");
assert_equals(el.setAttributeNode(attr), null);
assert_equals(attr.ownerElement, el);
assert_throws("INUSE_ATTRIBUTE_ERR",
function() { other.setAttributeNode(attr) },
"Attribute already associated with el")
}, "If attr’s element is neither null nor element, throw an InUseAttributeError.");

test(function() {
var el = document.createElement("div");
attr = document.createAttribute("foo");
assert_equals(el.setAttributeNode(attr), null);
el.setAttribute("bar", "qux");
assert_equals(el.setAttributeNode(attr), attr);
assert_equals(el.attributes[0], attr);
}, "Replacing an attr by itself");

test(function() {
var el = document.createElement("div")
el.setAttribute("foo", "bar")
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.