diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index e3abbc5ee1a..f4f70020cde 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -440,6 +440,7 @@ pub trait ElementHelpers<'a> { fn get_important_inline_style_declaration(self, property: &Atom) -> Option; fn serialize(self, traversal_scope: TraversalScope) -> Fallible; fn get_root_element(self) -> Option>; + fn lookup_prefix(self, namespace: Option) -> Option; } impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { @@ -599,6 +600,32 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { None => Some(self).map(Temporary::from_rooted), } } + + // https://dom.spec.whatwg.org/#locate-a-namespace-prefix + fn lookup_prefix(self, namespace: Option) -> Option { + for node in NodeCast::from_ref(self).inclusive_ancestors() { + match ElementCast::to_ref(node.root().r()) { + Some(element) => { + // Step 1. + if element.GetNamespaceURI() == namespace && element.GetPrefix().is_some() { + return element.GetPrefix(); + } + + // Step 2. + let attrs = element.Attributes().root(); + for i in 0..attrs.r().Length() { + let attr = attrs.r().Item(i).unwrap().root(); + if attr.r().GetPrefix() == Some("xmlns".to_owned()) && + Some(attr.r().Value()) == namespace { + return Some(attr.r().LocalName()); + } + } + }, + None => return None, + } + } + None + } } pub trait FocusElementHelpers { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index b3fed387468..9d7c8b7e6e1 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -6,6 +6,7 @@ use dom::attr::{Attr, AttrHelpers}; use dom::bindings::cell::DOMRefCell; +use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; @@ -2278,9 +2279,27 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-lookupprefix - fn LookupPrefix(self, _prefix: Option) -> Option { - // FIXME (#1826) implement. - None + fn LookupPrefix(self, namespace: Option) -> Option { + // Step 1. + if null_str_as_empty(&namespace).is_empty() { + return None; + } + + // Step 2. + match self.type_id() { + NodeTypeId::Element(..) => ElementCast::to_ref(self).unwrap().lookup_prefix(namespace), + NodeTypeId::Document => { + DocumentCast::to_ref(self).unwrap().GetDocumentElement().and_then(|element| { + element.root().r().lookup_prefix(namespace) + }) + }, + NodeTypeId::DocumentType | NodeTypeId::DocumentFragment => None, + _ => { + self.GetParentElement().and_then(|element| { + element.root().r().lookup_prefix(namespace) + }) + } + } } // https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri @@ -2517,4 +2536,3 @@ pub enum NodeDamage { /// Other parts of a node changed; attributes, text content, etc. OtherNodeDamage, } - diff --git a/tests/content/test_node_lookupPrefix.html b/tests/content/test_node_lookupPrefix.html new file mode 100644 index 00000000000..a5359f6dcba --- /dev/null +++ b/tests/content/test_node_lookupPrefix.html @@ -0,0 +1,48 @@ + + + + + + + + + + TEST + + + + +