diff options
Diffstat (limited to 'src/components/script/dom/htmlcollection.rs')
-rw-r--r-- | src/components/script/dom/htmlcollection.rs | 120 |
1 files changed, 72 insertions, 48 deletions
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 79b35487634..82b0d54693f 100644 --- a/src/components/script/dom/htmlcollection.rs +++ b/src/components/script/dom/htmlcollection.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast}; use dom::bindings::codegen::BindingDeclarations::HTMLCollectionBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; use dom::node::{Node, NodeHelpers}; @@ -15,7 +15,7 @@ use servo_util::str::{DOMString, split_html_space_chars}; use serialize::{Encoder, Encodable}; pub trait CollectionFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool; + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool; } impl<S: Encoder<E>, E> Encodable<S, E> for ~CollectionFilter { @@ -38,33 +38,33 @@ pub struct HTMLCollection { } impl HTMLCollection { - pub fn new_inherited(window: JS<Window>, collection: CollectionTypeId) -> HTMLCollection { + pub fn new_inherited(window: &JSRef<Window>, collection: CollectionTypeId) -> HTMLCollection { HTMLCollection { collection: collection, reflector_: Reflector::new(), - window: window, + window: window.unrooted(), } } - pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> { - reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection), + pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> Temporary<HTMLCollection> { + reflect_dom_object(~HTMLCollection::new_inherited(window, collection), window, HTMLCollectionBinding::Wrap) } } impl HTMLCollection { - pub fn create(window: &JS<Window>, root: &JS<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> { - HTMLCollection::new(window, Live(root.clone(), filter)) + pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> Temporary<HTMLCollection> { + HTMLCollection::new(window, Live(root.unrooted(), filter)) } - pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag: DOMString) - -> JS<HTMLCollection> { + pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString) + -> Temporary<HTMLCollection> { struct TagNameFilter { tag: DOMString } impl CollectionFilter for TagNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == self.tag + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == self.tag } } let filter = TagNameFilter { @@ -73,15 +73,15 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag: DOMString, - namespace: Namespace) -> JS<HTMLCollection> { + pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString, + namespace: Namespace) -> Temporary<HTMLCollection> { struct TagNameNSFilter { tag: DOMString, namespace: Namespace } impl CollectionFilter for TagNameNSFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().namespace == self.namespace && elem.get().local_name == self.tag + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().namespace == self.namespace && elem.deref().local_name == self.tag } } let filter = TagNameNSFilter { @@ -91,13 +91,13 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) - -> JS<HTMLCollection> { + pub fn by_class_name(window: &JSRef<Window>, root: &JSRef<Node>, classes: DOMString) + -> Temporary<HTMLCollection> { struct ClassNameFilter { classes: Vec<DOMString> } impl CollectionFilter for ClassNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { self.classes.iter().all(|class| elem.has_class(*class)) } } @@ -107,46 +107,65 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn children(window: &JS<Window>, root: &JS<Node>) -> JS<HTMLCollection> { + pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> Temporary<HTMLCollection> { struct ElementChildFilter; impl CollectionFilter for ElementChildFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool { - root.is_parent_of(&NodeCast::from(elem)) + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool { + root.is_parent_of(NodeCast::from_ref(elem)) } } HTMLCollection::create(window, root, ~ElementChildFilter) } } -impl HTMLCollection { +pub trait HTMLCollectionMethods { + fn Length(&self) -> u32; + fn Item(&self, index: u32) -> Option<Temporary<Element>>; + fn NamedItem(&self, key: DOMString) -> Option<Temporary<Element>>; + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Element>>; + fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Temporary<Element>>; +} + +impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { // http://dom.spec.whatwg.org/#dom-htmlcollection-length - pub fn Length(&self) -> u32 { + fn Length(&self) -> u32 { match self.collection { Static(ref elems) => elems.len() as u32, - Live(ref root, ref filter) => root.traverse_preorder() - .count(|child| { - let elem: Option<JS<Element>> = ElementCast::to(&child); - elem.map_or(false, |elem| filter.filter(&elem, root)) - }) as u32 + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .count(|child| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&child); + elem.map_or(false, |elem| filter.filter(elem, &*root)) + }) as u32 + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-item - pub fn Item(&self, index: u32) -> Option<JS<Element>> { + fn Item(&self, index: u32) -> Option<Temporary<Element>> { match self.collection { Static(ref elems) => elems .as_slice() .get(index as uint) - .map(|elem| elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .nth(index as uint).clone() + .map(|elem| Temporary::new(elem.clone())), + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .map(|elem| elem.clone()) + }) + .nth(index as uint) + .clone() + .map(|elem| Temporary::from_rooted(&elem)) + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem - pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> { + fn NamedItem(&self, key: DOMString) -> Option<Temporary<Element>> { // Step 1. if key.is_empty() { return None; @@ -155,29 +174,34 @@ impl HTMLCollection { // Step 2. match self.collection { Static(ref elems) => elems.iter() + .map(|elem| elem.root()) .find(|elem| { elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .find(|elem| { - elem.get_string_attribute("name") == key || - elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()) + .map(|maybe_elem| Temporary::from_rooted(&*maybe_elem)), + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .map(|elem| elem.clone()) + }) + .find(|elem| { + elem.get_string_attribute("name") == key || + elem.get_string_attribute("id") == key }) + .map(|maybe_elem| Temporary::from_rooted(&maybe_elem)) + } } } -} -impl HTMLCollection { - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> { + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Element>> { let maybe_elem = self.Item(index); *found = maybe_elem.is_some(); maybe_elem } - pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> { + fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Temporary<Element>> { match maybe_name { Some(name) => { let maybe_elem = self.NamedItem(name); |