mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Cleanup Element iteration in dom/htmlcollection.rs
This commit is contained in:
parent
c84b25cc99
commit
03f257697d
1 changed files with 35 additions and 31 deletions
|
@ -15,7 +15,6 @@ use dom::window::Window;
|
||||||
use util::str::{DOMString, split_html_space_chars};
|
use util::str::{DOMString, split_html_space_chars};
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::iter::{FilterMap, Skip};
|
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
|
|
||||||
pub trait CollectionFilter : JSTraceable {
|
pub trait CollectionFilter : JSTraceable {
|
||||||
|
@ -162,36 +161,47 @@ impl HTMLCollection {
|
||||||
HTMLCollection::create(window, root, box ElementChildFilter)
|
HTMLCollection::create(window, root, box ElementChildFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse(root: &Node)
|
fn elements_iter(&self) -> HTMLCollectionElementsIter {
|
||||||
-> FilterMap<Skip<TreeIterator>,
|
let ref filter = self.collection.1;
|
||||||
fn(Root<Node>) -> Option<Root<Element>>> {
|
let root = self.collection.0.root();
|
||||||
fn to_temporary(node: Root<Node>) -> Option<Root<Element>> {
|
let mut node_iter = root.traverse_preorder();
|
||||||
ElementCast::to_root(node)
|
let _ = node_iter.next(); // skip the root node
|
||||||
|
HTMLCollectionElementsIter {
|
||||||
|
node_iter: node_iter,
|
||||||
|
root: root,
|
||||||
|
filter: filter,
|
||||||
}
|
}
|
||||||
root.traverse_preorder()
|
}
|
||||||
.skip(1)
|
}
|
||||||
.filter_map(to_temporary)
|
|
||||||
|
struct HTMLCollectionElementsIter<'a> {
|
||||||
|
node_iter: TreeIterator,
|
||||||
|
root: Root<Node>,
|
||||||
|
filter: &'a Box<CollectionFilter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for HTMLCollectionElementsIter<'a> {
|
||||||
|
type Item = Root<Element>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let filter = self.filter;
|
||||||
|
let root = self.root.r();
|
||||||
|
self.node_iter.by_ref()
|
||||||
|
.filter_map(ElementCast::to_root)
|
||||||
|
.filter(|element| filter.filter(element.r(), root))
|
||||||
|
.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
|
impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
|
||||||
fn Length(self) -> u32 {
|
fn Length(self) -> u32 {
|
||||||
let ref root = self.collection.0.root();
|
self.elements_iter().count() as u32
|
||||||
let ref filter = self.collection.1;
|
|
||||||
HTMLCollection::traverse(root.r())
|
|
||||||
.filter(|element| filter.filter(element.r(), root.r()))
|
|
||||||
.count() as u32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
||||||
fn Item(self, index: u32) -> Option<Root<Element>> {
|
fn Item(self, index: u32) -> Option<Root<Element>> {
|
||||||
let index = index as usize;
|
self.elements_iter().nth(index as usize)
|
||||||
let ref root = self.collection.0.root();
|
|
||||||
let ref filter = self.collection.1;
|
|
||||||
HTMLCollection::traverse(root.r())
|
|
||||||
.filter(|element| filter.filter(element.r(), root.r()))
|
|
||||||
.nth(index)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
|
||||||
|
@ -202,13 +212,10 @@ impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2.
|
// Step 2.
|
||||||
let ref root = self.collection.0.root();
|
self.elements_iter().find(|elem| {
|
||||||
let ref filter = self.collection.1;
|
elem.r().get_string_attribute(&atom!("name")) == key ||
|
||||||
HTMLCollection::traverse(root.r())
|
elem.r().get_string_attribute(&atom!("id")) == key
|
||||||
.filter(|element| filter.filter(element.r(), root.r()))
|
})
|
||||||
.find(|elem| {
|
|
||||||
elem.r().get_string_attribute(&atom!("name")) == key ||
|
|
||||||
elem.r().get_string_attribute(&atom!("id")) == key})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
||||||
|
@ -231,10 +238,7 @@ impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
let root = self.collection.0.root();
|
for elem in self.elements_iter() {
|
||||||
let ref filter = self.collection.1;
|
|
||||||
let elems = HTMLCollection::traverse(root.r()).filter(|element| filter.filter(element.r(), root.r()));
|
|
||||||
for elem in elems {
|
|
||||||
// Step 2.1
|
// Step 2.1
|
||||||
let id_attr = elem.get_string_attribute(&atom!("id"));
|
let id_attr = elem.get_string_attribute(&atom!("id"));
|
||||||
if !id_attr.is_empty() && !result.contains(&id_attr) {
|
if !id_attr.is_empty() && !result.contains(&id_attr) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue