diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-03-31 18:41:28 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-05-03 14:18:30 -0400 |
commit | d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1 (patch) | |
tree | efd1e7f7ec1dd30467c2a67306e1a639837abead /src/components/script/dom/htmlcollection.rs | |
parent | ffdc3f5b32a345b88eed774848924e862d47c093 (diff) | |
download | servo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.tar.gz servo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.zip |
Implement safe rooting strategy via Unrooted, Root, JSRef, and JS.
Diffstat (limited to 'src/components/script/dom/htmlcollection.rs')
-rw-r--r-- | src/components/script/dom/htmlcollection.rs | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 8529d4daf64..73b4835ff2e 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, JSRef, RootCollection}; +use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; use dom::node::{Node, NodeHelpers}; @@ -46,19 +46,19 @@ impl HTMLCollection { } } - pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> { + pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> Unrooted<HTMLCollection> { reflect_dom_object(~HTMLCollection::new_inherited(window.unrooted(), collection), window, HTMLCollectionBinding::Wrap) } } impl HTMLCollection { - pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> { + pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> Unrooted<HTMLCollection> { HTMLCollection::new(window, Live(root.unrooted(), filter)) } pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString) - -> JS<HTMLCollection> { + -> Unrooted<HTMLCollection> { struct TagNameFilter { tag: DOMString } @@ -74,7 +74,7 @@ impl HTMLCollection { } pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString, - namespace: Namespace) -> JS<HTMLCollection> { + namespace: Namespace) -> Unrooted<HTMLCollection> { struct TagNameNSFilter { tag: DOMString, namespace: Namespace @@ -92,13 +92,13 @@ impl HTMLCollection { } pub fn by_class_name(window: &JSRef<Window>, root: &JSRef<Node>, classes: DOMString) - -> JS<HTMLCollection> { + -> Unrooted<HTMLCollection> { struct ClassNameFilter { classes: Vec<DOMString> } impl CollectionFilter for ClassNameFilter { fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { - self.classes.iter().all(|class| elem.unrooted().has_class(*class)) + self.classes.iter().all(|class| elem.has_class(*class)) } } let filter = ClassNameFilter { @@ -107,11 +107,11 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> JS<HTMLCollection> { + pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> Unrooted<HTMLCollection> { struct ElementChildFilter; impl CollectionFilter for ElementChildFilter { fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool { - root.unrooted().is_parent_of(NodeCast::from_ref(elem)) + root.is_parent_of(NodeCast::from_ref(elem)) } } HTMLCollection::create(window, root, ~ElementChildFilter) @@ -125,43 +125,43 @@ impl HTMLCollection { match self.collection { Static(ref elems) => elems.len() as u32, Live(ref root, ref filter) => { - let root_root = root.root(&roots); - root.traverse_preorder() + let root = root.root(&roots); + root.deref().traverse_preorder(&roots) .count(|child| { - let elem: Option<JS<Element>> = ElementCast::to(&child); - elem.map_or(false, |elem| { - let elem = elem.root(&roots); - filter.filter(&elem.root_ref(), &root_root.root_ref()) - }) + 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>> { + pub fn Item(&self, index: u32) -> Option<Unrooted<Element>> { let roots = RootCollection::new(); match self.collection { Static(ref elems) => elems .as_slice() .get(index as uint) - .map(|elem| elem.clone()), + .map(|elem| Unrooted::new(elem.clone())), Live(ref root, ref filter) => { - let root_root = root.root(&roots); - root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| { - let elem = elem.root(&roots); - filter.filter(&elem.root_ref(), &root_root.root_ref()) + let root = root.root(&roots); + root.deref().traverse_preorder(&roots) + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .and_then(|elem| Some(elem.clone())) }) - .nth(index as uint).clone() + .nth(index as uint) + .clone() + .map(|elem| Unrooted::new_rooted(&elem)) } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem - pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> { + pub fn NamedItem(&self, key: DOMString) -> Option<Unrooted<Element>> { let roots = RootCollection::new(); + // Step 1. if key.is_empty() { return None; @@ -170,35 +170,36 @@ impl HTMLCollection { // Step 2. match self.collection { Static(ref elems) => elems.iter() + .map(|elem| elem.root(&roots)) .find(|elem| { elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()), + .map(|maybe_elem| Unrooted::new_rooted(&*maybe_elem)), Live(ref root, ref filter) => { - let root_root = root.root(&roots); - root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| { - let elem = elem.root(&roots); - filter.filter(&elem.root_ref(), &root_root.root_ref()) + let root = root.root(&roots); + root.deref().traverse_preorder(&roots) + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .and_then(|elem| Some(elem.clone())) }) .find(|elem| { elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()) + .map(|maybe_elem| Unrooted::new_rooted(&maybe_elem)) } } } } impl HTMLCollection { - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> { + pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<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>> { + pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Unrooted<Element>> { match maybe_name { Some(name) => { let maybe_elem = self.NamedItem(name); |