diff options
author | David Zbarsky <dzbarsky@gmail.com> | 2015-07-04 17:52:33 -0400 |
---|---|---|
committer | David Zbarsky <dzbarsky@gmail.com> | 2015-07-10 14:41:37 -0400 |
commit | 326b2a7161892f739f525338ee2813d7aa620e2f (patch) | |
tree | e698b6e22d010688219338160abaff642e0dfd61 /components/script/dom/node.rs | |
parent | c04b7bbf6e5efe2e5217b69c9680e4e91bbd6ecd (diff) | |
download | servo-326b2a7161892f739f525338ee2813d7aa620e2f.tar.gz servo-326b2a7161892f739f525338ee2813d7aa620e2f.zip |
Test element prefix for element equality
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r-- | components/script/dom/node.rs | 97 |
1 files changed, 89 insertions, 8 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index c5d435d5156..21c427d07b1 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -69,7 +69,7 @@ use std::iter::{FilterMap, Peekable}; use std::mem; use std::sync::Arc; use uuid; -use string_cache::{Atom, QualName}; +use string_cache::{Atom, Namespace, QualName}; // // The basic Node structure @@ -1903,6 +1903,79 @@ impl Node { } content } + + pub fn namespace_to_string(namespace: Namespace) -> Option<DOMString> { + match namespace { + ns!("") => None, + Namespace(ref ns) => Some((**ns).to_owned()) + } + } + + // https://dom.spec.whatwg.org/#locate-a-namespace + pub fn locate_namespace(node: &Node, prefix: Option<DOMString>) -> Namespace { + fn attr_defines_namespace(attr: &Attr, + prefix: &Option<Atom>) -> bool { + *attr.namespace() == ns!(XMLNS) && + match (attr.prefix(), prefix) { + (&Some(ref attr_prefix), &Some(ref prefix)) => + attr_prefix == &atom!("xmlns") && + attr.local_name() == prefix, + (&None, &None) => *attr.local_name() == atom!("xmlns"), + _ => false + } + } + + match node.type_id { + NodeTypeId::Element(_) => { + let element = ElementCast::to_ref(node).unwrap(); + // Step 1. + if *element.namespace() != ns!("") && *element.prefix() == prefix { + return element.namespace().clone() + } + + + let prefix_atom = prefix.as_ref().map(|s| Atom::from_slice(s)); + + // Step 2. + let namespace_attr = + element.attrs() + .iter() + .map(|attr| attr.root()) + .find(|attr| attr_defines_namespace(attr.r(), + &prefix_atom)); + + // Steps 2.1-2. + if let Some(attr) = namespace_attr { + return namespace_from_domstring(Some(attr.Value())); + } + + match node.GetParentElement() { + // Step 3. + None => ns!(""), + // Step 4. + Some(parent) => Node::locate_namespace(NodeCast::from_ref(parent.r()), prefix) + } + }, + NodeTypeId::Document => { + match DocumentCast::to_ref(node).unwrap().GetDocumentElement().r() { + // Step 1. + None => ns!(""), + // Step 2. + Some(document_element) => { + Node::locate_namespace(NodeCast::from_ref(document_element), prefix) + } + } + }, + NodeTypeId::DocumentType => ns!(""), + NodeTypeId::DocumentFragment => ns!(""), + _ => match node.GetParentElement() { + // Step 1. + None => ns!(""), + // Step 2. + Some(parent) => Node::locate_namespace(NodeCast::from_ref(parent.r()), prefix) + } + } + } } impl<'a> NodeMethods for &'a Node { @@ -2457,15 +2530,23 @@ impl<'a> NodeMethods for &'a Node { } // https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri - fn LookupNamespaceURI(self, _namespace: Option<DOMString>) -> Option<DOMString> { - // FIXME (#1826) implement. - None - } + fn LookupNamespaceURI(self, prefix: Option<DOMString>) -> Option<DOMString> { + // Step 1. + let prefix = match prefix { + Some(ref p) if p.is_empty() => None, + pre => pre + }; + + // Step 2. + Node::namespace_to_string(Node::locate_namespace(self, prefix)) + } // https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace - fn IsDefaultNamespace(self, _namespace: Option<DOMString>) -> bool { - // FIXME (#1826) implement. - false + fn IsDefaultNamespace(self, namespace: Option<DOMString>) -> bool { + // Step 1. + let namespace = namespace_from_domstring(namespace); + // Steps 2 and 3. + Node::locate_namespace(self, None) == namespace } } |