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/components/script/dom/node.rs | |
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/components/script/dom/node.rs')
-rw-r--r-- | src/components/script/dom/node.rs | 84 |
1 files changed, 82 insertions, 2 deletions
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 { |