Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement NodeIterator #5981

Merged
merged 5 commits into from May 28, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -58,6 +58,7 @@ use dom::keyboardevent::KeyboardEvent;
use dom::messageevent::MessageEvent;
use dom::node::{self, Node, NodeHelpers, NodeTypeId, CloneChildrenFlag, NodeDamage, window_from_node};
use dom::nodelist::NodeList;
use dom::nodeiterator::NodeIterator;
use dom::text::Text;
use dom::processinginstruction::ProcessingInstruction;
use dom::range::Range;
@@ -1363,6 +1364,12 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
Range::new_with_doc(self)
}

// https://dom.spec.whatwg.org/#dom-document-createnodeiteratorroot-whattoshow-filter
fn CreateNodeIterator(self, root: JSRef<Node>, whatToShow: u32, filter: Option<NodeFilter>)
-> Temporary<NodeIterator> {
NodeIterator::new(self, root, whatToShow, filter)
}

// https://dom.spec.whatwg.org/#dom-document-createtreewalker
fn CreateTreeWalker(self, root: JSRef<Node>, whatToShow: u32, filter: Option<NodeFilter>)
-> Temporary<TreeWalker> {
@@ -426,6 +426,9 @@ pub trait NodeHelpers {
fn child_elements(self) -> ChildElementIterator;
fn following_siblings(self) -> NodeSiblingIterator;
fn preceding_siblings(self) -> ReverseSiblingIterator;
fn following_nodes(self, root: JSRef<Node>) -> FollowingNodeIterator;
fn preceding_nodes(self, root: JSRef<Node>) -> PrecedingNodeIterator;
fn descending_last_children(self) -> LastChildIterator;
fn is_in_doc(self) -> bool;
fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool;
fn is_parent_of(self, child: JSRef<Node>) -> bool;
@@ -785,6 +788,26 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
}
}

fn following_nodes(self, root: JSRef<Node>) -> FollowingNodeIterator {
FollowingNodeIterator {
current: Some(Temporary::from_rooted(self)),
root: Temporary::from_rooted(root),
}
}

fn preceding_nodes(self, root: JSRef<Node>) -> PrecedingNodeIterator {
PrecedingNodeIterator {
current: Some(Temporary::from_rooted(self)),
root: Temporary::from_rooted(root),
}
}

fn descending_last_children(self) -> LastChildIterator {
LastChildIterator {
current: self.GetLastChild(),
}
}

fn is_parent_of(self, child: JSRef<Node>) -> bool {
match child.parent_node.get().root() {
Some(ref parent) => parent.r() == self,
@@ -922,7 +945,6 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
Ok(NodeList::new_simple_list(window.r(), iter))
}


fn ancestors(self) -> AncestorIterator {
AncestorIterator {
current: self.GetParentNode()
@@ -1236,6 +1258,114 @@ impl Iterator for ReverseSiblingIterator {
}
}

pub struct FollowingNodeIterator {
current: Option<Temporary<Node>>,
root: Temporary<Node>,
}

impl Iterator for FollowingNodeIterator {
type Item = Temporary<Node>;

// https://dom.spec.whatwg.org/#concept-tree-following
fn next(&mut self) -> Option<Temporary<Node>> {
let current = match self.current.take() {
None => return None,
Some(current) => current,
};

let node = current.root();
if let Some(first_child) = node.r().GetFirstChild() {
self.current = Some(first_child);
return node.r().GetFirstChild()
}

if self.root == current {
self.current = None;
return None;
}

if let Some(next_sibling) = node.r().GetNextSibling() {
self.current = Some(next_sibling);
return node.r().GetNextSibling()
}

for ancestor in node.r().inclusive_ancestors() {
if self.root == ancestor {
break;
}
if let Some(next_sibling) = ancestor.root().r().GetNextSibling() {
self.current = Some(next_sibling);
return ancestor.root().r().GetNextSibling()
}
}
self.current = None;
return None
}
}

pub struct PrecedingNodeIterator {
current: Option<Temporary<Node>>,
root: Temporary<Node>,
}

impl Iterator for PrecedingNodeIterator {
type Item = Temporary<Node>;

// https://dom.spec.whatwg.org/#concept-tree-preceding
fn next(&mut self) -> Option<Temporary<Node>> {
let current = match self.current.take() {
None => return None,
Some(current) => current,
};

if self.root == current {
self.current = None;
return None
}

let node = current.root();
if let Some(previous_sibling) = node.r().GetPreviousSibling() {
if self.root == previous_sibling {
self.current = None;
return None
}

if let Some(last_child) = previous_sibling.root().r().descending_last_children().last() {
self.current = Some(last_child);
return previous_sibling.root().r().descending_last_children().last()
}

self.current = Some(previous_sibling);
return node.r().GetPreviousSibling()
};

if let Some(parent_node) = node.r().GetParentNode() {
self.current = Some(parent_node);
return node.r().GetParentNode()
}

self.current = None;
return None
}
}

pub struct LastChildIterator {
current: Option<Temporary<Node>>,
}

impl Iterator for LastChildIterator {
type Item = Temporary<Node>;

fn next(&mut self) -> Option<Temporary<Node>> {
let current = match self.current.take() {
None => return None,
Some(current) => current,
}.root();
self.current = current.r().GetLastChild();
Some(Temporary::from_rooted(current.r()))
}
}

pub struct AncestorIterator {
current: Option<Temporary<Node>>,
}
@@ -1298,7 +1428,6 @@ impl Iterator for TreeIterator {
}
}


/// Specifies whether children must be recursively cloned or not.
#[derive(Copy, Clone, PartialEq)]
pub enum CloneChildrenFlag {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.