aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/node.rs
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-01-14 06:01:01 -0800
committerbors-servo <release+servo@mozilla.com>2014-01-14 06:01:01 -0800
commit8f0f2d9ef50e6ea0b21450a63f9e37b89a6f68d2 (patch)
treecf0940ecb5d800e2b95cd1afe7524f1fa93fb811 /src/components/script/dom/node.rs
parentfc76107a92313f6c2dd9c9b9fc6e588093f73c92 (diff)
parent7aee1cae84704b885988a5985a7604747125ec1e (diff)
downloadservo-8f0f2d9ef50e6ea0b21450a63f9e37b89a6f68d2.tar.gz
servo-8f0f2d9ef50e6ea0b21450a63f9e37b89a6f68d2.zip
auto merge of #1450 : jgraham/servo/innerHTML, r=jdm
XML case is not yet implemented. Not yet well tested, but at a point where review comments are helpful.
Diffstat (limited to 'src/components/script/dom/node.rs')
-rw-r--r--src/components/script/dom/node.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index a98f89b4817..7c58f4d2751 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -684,6 +684,85 @@ impl Iterator<AbstractNode> for TreeIterator {
}
}
+pub struct NodeIterator {
+ start_node: AbstractNode,
+ current_node: Option<AbstractNode>,
+ depth: uint,
+ priv include_start: bool,
+ priv include_descendants_of_void: bool
+}
+
+impl NodeIterator {
+ pub fn new(start_node: AbstractNode, include_start: bool, include_descendants_of_void: bool) -> NodeIterator {
+ NodeIterator {
+ start_node: start_node,
+ current_node: None,
+ depth: 0,
+ include_start: include_start,
+ include_descendants_of_void: include_descendants_of_void
+ }
+ }
+
+ fn next_child(&self, node: AbstractNode) -> Option<AbstractNode> {
+ if !self.include_descendants_of_void &&
+ node.is_element() {
+ node.with_imm_element(|elem| {
+ if elem.is_void() {
+ None
+ } else {
+ node.first_child()
+ }
+ })
+ } else {
+ node.first_child()
+ }
+ }
+}
+
+impl Iterator<AbstractNode> for NodeIterator {
+ fn next(&mut self) -> Option<AbstractNode> {
+ self.current_node = match self.current_node {
+ None => {
+ if self.include_start {
+ Some(self.start_node)
+ } else {
+ self.next_child(self.start_node)
+ }
+ },
+ Some(node) => {
+ match self.next_child(node) {
+ Some(child) => {
+ self.depth += 1;
+ Some(child)
+ },
+ None if node == self.start_node => None,
+ None => {
+ match node.next_sibling() {
+ Some(sibling) => Some(sibling),
+ None => {
+ let mut candidate = node;
+ while candidate.next_sibling().is_none() {
+ candidate = candidate.parent_node().expect("Got to root without reaching start node");
+ self.depth -= 1;
+ if candidate == self.start_node {
+ break;
+ }
+ }
+ if candidate != self.start_node {
+ candidate.next_sibling()
+ } else {
+ None
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ self.current_node
+ }
+}
+
fn gather_abstract_nodes(cur: &AbstractNode, refs: &mut ~[AbstractNode], postorder: bool) {
if !postorder {
refs.push(cur.clone());