diff options
author | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-02-09 04:21:51 -0400 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-02-10 11:01:12 -0400 |
commit | 4d4495b015af1e35759696718c63082241c3af49 (patch) | |
tree | dc7a86ed11579391e6ce600420e388f466c20a9d /src | |
parent | f26cdcf235c6c323eaa15ac45c76ccadb837bef4 (diff) | |
download | servo-4d4495b015af1e35759696718c63082241c3af49.tar.gz servo-4d4495b015af1e35759696718c63082241c3af49.zip |
Implement Node.isEqualNode
Spec:
http://dom.spec.whatwg.org/#dom-node-isequalnode
Closes #1645.
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 1 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 84 | ||||
-rw-r--r-- | src/components/script/dom/webidls/Node.webidl | 2 | ||||
-rw-r--r-- | src/test/html/content/test_node_isEqualNode.html | 39 |
4 files changed, 123 insertions, 3 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index f99bbf890b0..cf2c99855f5 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -325,6 +325,7 @@ DOMInterfaces = { 'textContent', 'childNodes', 'contains', + 'isEqualNode', ] }, diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 5cca4c0cbcf..4f6639123b5 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -1540,8 +1540,88 @@ impl Node { fail!("stub") } - pub fn IsEqualNode(&self, _node: Option<AbstractNode>) -> bool { - false + // http://dom.spec.whatwg.org/#dom-node-isequalnode + pub fn IsEqualNode(&self, abstract_self: AbstractNode, maybe_node: Option<AbstractNode>) -> bool { + fn is_equal_doctype(node: AbstractNode, other: AbstractNode) -> bool { + node.with_imm_doctype(|doctype| { + other.with_imm_doctype(|other_doctype| { + (doctype.name == other_doctype.name) && + (doctype.public_id == other_doctype.public_id) && + (doctype.system_id == other_doctype.system_id) + }) + }) + } + fn is_equal_element(node: AbstractNode, other: AbstractNode) -> bool { + node.with_imm_element(|element| { + other.with_imm_element(|other_element| { + // FIXME: namespace prefix + (element.namespace == other_element.namespace) && + (element.tag_name == other_element.tag_name) && + (element.attrs.len() == other_element.attrs.len()) + }) + }) + } + fn is_equal_processinginstruction(node: AbstractNode, other: AbstractNode) -> bool { + node.with_imm_processing_instruction(|pi| { + other.with_imm_processing_instruction(|other_pi| { + (pi.target == other_pi.target) && + (pi.element.data == other_pi.element.data) + }) + }) + } + fn is_equal_characterdata(node: AbstractNode, other: AbstractNode) -> bool { + node.with_imm_characterdata(|characterdata| { + other.with_imm_characterdata(|other_characterdata| { + characterdata.data == other_characterdata.data + }) + }) + } + fn is_equal_element_attrs(node: AbstractNode, other: AbstractNode) -> bool { + node.with_imm_element(|element| { + other.with_imm_element(|other_element| { + assert!(element.attrs.len() == other_element.attrs.len()); + element.attrs.iter().all(|attr| { + other_element.attrs.iter().any(|other_attr| { + (attr.namespace == other_attr.namespace) && + (attr.local_name == other_attr.local_name) && + (attr.value == other_attr.value) + }) + }) + }) + }) + } + fn is_equal_node(this: AbstractNode, node: AbstractNode) -> bool { + // Step 2. + if this.type_id() != node.type_id() { + return false; + } + + match node.type_id() { + // Step 3. + DoctypeNodeTypeId if !is_equal_doctype(this, node) => return false, + ElementNodeTypeId(..) if !is_equal_element(this, node) => return false, + ProcessingInstructionNodeTypeId if !is_equal_processinginstruction(this, node) => return false, + TextNodeTypeId | + CommentNodeTypeId if !is_equal_characterdata(this, node) => return false, + // Step 4. + ElementNodeTypeId(..) if !is_equal_element_attrs(this, node) => return false, + _ => () + } + + // Step 5. + if this.children().len() != node.children().len() { + return false; + } + + // Step 6. + this.children().zip(node.children()).all(|(child, other_child)| is_equal_node(child, other_child)) + } + match maybe_node { + // Step 1. + None => false, + // Step 2-6. + Some(node) => is_equal_node(abstract_self, node) + } } pub fn CompareDocumentPosition(&self, _other: AbstractNode) -> u16 { diff --git a/src/components/script/dom/webidls/Node.webidl b/src/components/script/dom/webidls/Node.webidl index ba48fd94e11..c81a4228ae2 100644 --- a/src/components/script/dom/webidls/Node.webidl +++ b/src/components/script/dom/webidls/Node.webidl @@ -69,7 +69,7 @@ interface Node : EventTarget { [Throws] Node cloneNode(optional boolean deep = true); - // boolean isEqualNode(Node? node); //XXXjdm we don't deal well with Node? parameters + boolean isEqualNode(Node? node); const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01; const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02; diff --git a/src/test/html/content/test_node_isEqualNode.html b/src/test/html/content/test_node_isEqualNode.html new file mode 100644 index 00000000000..e7c55743725 --- /dev/null +++ b/src/test/html/content/test_node_isEqualNode.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + <head> + <script src="harness.js"></script> + <script> + // test1: simple checks + { + var elem = document.createElement("div"); + var other = document.createElement("div"); + is(elem.isEqualNode(elem), true); + is(elem.isEqualNode(other), true); + is(other.isEqualNode(elem), true); + is(elem.isEqualNode(document), false); + } + + // test2: non-element children + { + var parent_elem = document.createElement("div"); + var child_elem = document.createElement("div"); + parent_elem.appendChild(child_elem); + + var other_parent = document.createElement("div"); + var other_child = document.createElement("div"); + other_parent.appendChild(other_child); + + is(parent_elem.isEqualNode(other_parent), true); + is(child_elem.isEqualNode(other_child), true); + + var child_text = document.createTextNode("lorem ipsum"); + child_elem.appendChild(child_text); + + is(parent_elem.isEqualNode(other_parent), false); + is(child_elem.isEqualNode(other_child), false); + } + + finish(); + </script> + </head> +</html> |