diff options
author | James Graham <james@hoppipolla.co.uk> | 2014-07-27 22:44:13 +0100 |
---|---|---|
committer | James Graham <james@hoppipolla.co.uk> | 2014-08-08 14:30:34 +0100 |
commit | 0b802ab01882dc43ad5ec0f0e8e8699f22866e71 (patch) | |
tree | bd661db1e97999d116d5bcf5b4c9107b5131db26 /src/components/script/dom/htmlcollection.rs | |
parent | 70e70fd1d9da87bc0a832734b137f2c326641c4e (diff) | |
download | servo-0b802ab01882dc43ad5ec0f0e8e8699f22866e71.tar.gz servo-0b802ab01882dc43ad5ec0f0e8e8699f22866e71.zip |
Fix getElementsByTagName[NS] support to match the spec.
Diffstat (limited to 'src/components/script/dom/htmlcollection.rs')
-rw-r--r-- | src/components/script/dom/htmlcollection.rs | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 42712cf50b4..5bef6c56ff5 100644 --- a/src/components/script/dom/htmlcollection.rs +++ b/src/components/script/dom/htmlcollection.rs @@ -8,14 +8,16 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast}; use dom::bindings::global::Window; use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::element::{Element, AttributeHandlers}; +use dom::element::{Element, AttributeHandlers, ElementHelpers}; use dom::node::{Node, NodeHelpers}; use dom::window::Window; use servo_util::atom::Atom; +use servo_util::namespace; use servo_util::namespace::Namespace; use servo_util::str::{DOMString, split_html_space_chars}; use serialize::{Encoder, Encodable}; +use std::ascii::StrAsciiExt; pub trait CollectionFilter { fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool; @@ -59,36 +61,82 @@ impl HTMLCollection { HTMLCollection::new(window, Live(JS::from_rooted(root), filter)) } + fn all_elements(window: &JSRef<Window>, root: &JSRef<Node>, + namespace_filter: Option<Namespace>) -> Temporary<HTMLCollection> { + struct AllElementFilter { + namespace_filter: Option<Namespace> + } + impl CollectionFilter for AllElementFilter { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + match self.namespace_filter { + None => true, + Some(ref namespace) => elem.namespace == *namespace + } + } + } + let filter = AllElementFilter {namespace_filter: namespace_filter}; + HTMLCollection::create(window, root, box filter) + } + pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString) -> Temporary<HTMLCollection> { + if tag.as_slice() == "*" { + return HTMLCollection::all_elements(window, root, None); + } + struct TagNameFilter { - tag: Atom + tag: Atom, + ascii_lower_tag: Atom, } impl CollectionFilter for TagNameFilter { fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { - elem.deref().local_name == self.tag + if elem.html_element_in_html_document() { + elem.local_name == self.ascii_lower_tag + } else { + elem.local_name == self.tag + } } } let filter = TagNameFilter { - tag: Atom::from_slice(tag.as_slice()) + tag: Atom::from_slice(tag.as_slice()), + ascii_lower_tag: Atom::from_slice(tag.as_slice().to_ascii_lower().as_slice()), }; HTMLCollection::create(window, root, box filter) } pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString, - namespace: Namespace) -> Temporary<HTMLCollection> { + maybe_ns: Option<DOMString>) -> Temporary<HTMLCollection> { + let namespace_filter = match maybe_ns { + Some(namespace) => { + match namespace.as_slice() { + "*" => None, + ns => Some(Namespace::from_str(ns)), + } + }, + None => Some(namespace::Null), + }; + + if tag.as_slice() == "*" { + return HTMLCollection::all_elements(window, root, namespace_filter); + } struct TagNameNSFilter { tag: Atom, - namespace: Namespace + namespace_filter: Option<Namespace> } impl CollectionFilter for TagNameNSFilter { fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { - elem.deref().namespace == self.namespace && elem.deref().local_name == self.tag + let ns_match = match self.namespace_filter { + Some(ref namespace) => { + elem.deref().namespace == *namespace + }, + None => true + }; + ns_match && elem.deref().local_name == self.tag } } let filter = TagNameNSFilter { tag: Atom::from_slice(tag.as_slice()), - namespace: namespace + namespace_filter: namespace_filter }; HTMLCollection::create(window, root, box filter) } |