From cb8b52c5fe2bc77f69aaa9ecb4f859fd27c2c8a3 Mon Sep 17 00:00:00 2001 From: CYBAI Date: Sun, 27 Aug 2017 02:22:11 +0800 Subject: [PATCH 1/2] Update concept of node filter algorithm --- components/script/dom/nodeiterator.rs | 26 ++++++++++++++++---- components/script/dom/treewalker.rs | 35 ++++++++++++++++++--------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs index 5897c4075c9..5da1bffb6d8 100644 --- a/components/script/dom/nodeiterator.rs +++ b/components/script/dom/nodeiterator.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::codegen::Bindings::NodeIteratorBinding; use dom::bindings::codegen::Bindings::NodeIteratorBinding::NodeIteratorMethods; -use dom::bindings::error::Fallible; +use dom::bindings::error::{Error, Fallible}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::root::{Dom, DomRoot, MutDom}; use dom::document::Document; @@ -27,6 +27,7 @@ pub struct NodeIterator { what_to_show: u32, #[ignore_malloc_size_of = "Can't measure due to #6870"] filter: Filter, + active: Cell, } impl NodeIterator { @@ -39,7 +40,8 @@ impl NodeIterator { reference_node: MutDom::new(root_node), pointer_before_reference_node: Cell::new(true), what_to_show: what_to_show, - filter: filter + filter: filter, + active: Cell::new(false), } } @@ -192,15 +194,29 @@ impl NodeIterator { // https://dom.spec.whatwg.org/#concept-node-filter fn accept_node(&self, node: &Node) -> Fallible { // Step 1. - let n = node.NodeType() - 1; + if self.active.get() { + return Err(Error::InvalidState); + } // Step 2. + let n = node.NodeType() - 1; + // Step 3. if (self.what_to_show & (1 << n)) == 0 { return Ok(NodeFilterConstants::FILTER_SKIP) } - // Step 3-5. + match self.filter { + // Step 4. Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT), - Filter::Callback(ref callback) => callback.AcceptNode_(self, node, Rethrow) + Filter::Callback(ref callback) => { + // Step 5. + self.active.set(true); + // Step 6. + let result = callback.AcceptNode_(self, node, Rethrow); + // Step 7. + self.active.set(false); + // Step 8. + result + } } } } diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index de5219a608f..89ef5527e4e 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -8,12 +8,13 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::codegen::Bindings::TreeWalkerBinding; use dom::bindings::codegen::Bindings::TreeWalkerBinding::TreeWalkerMethods; -use dom::bindings::error::Fallible; +use dom::bindings::error::{Error, Fallible}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::root::{Dom, DomRoot, MutDom}; use dom::document::Document; use dom::node::Node; use dom_struct::dom_struct; +use std::cell::Cell; use std::rc::Rc; // https://dom.spec.whatwg.org/#interface-treewalker @@ -24,7 +25,8 @@ pub struct TreeWalker { current_node: MutDom, what_to_show: u32, #[ignore_malloc_size_of = "function pointers and Rc are hard"] - filter: Filter + filter: Filter, + active: Cell, } impl TreeWalker { @@ -36,7 +38,8 @@ impl TreeWalker { root_node: Dom::from_ref(root_node), current_node: MutDom::new(root_node), what_to_show: what_to_show, - filter: filter + filter: filter, + active: Cell::new(false), } } @@ -415,22 +418,30 @@ impl TreeWalker { // https://dom.spec.whatwg.org/#concept-node-filter fn accept_node(&self, node: &Node) -> Fallible { - // "To filter node run these steps:" - // "1. Let n be node's nodeType attribute value minus 1." + // Step 1. + if self.active.get() { + return Err(Error::InvalidState); + } + // Step 2. let n = node.NodeType() - 1; - // "2. If the nth bit (where 0 is the least significant bit) of whatToShow is not set, - // return FILTER_SKIP." + // Step 3. if (self.what_to_show & (1 << n)) == 0 { return Ok(NodeFilterConstants::FILTER_SKIP) } - // "3. If filter is null, return FILTER_ACCEPT." - // "4. Let result be the return value of invoking filter." - // "5. If an exception was thrown, re-throw the exception." - // "6. Return result." match self.filter { + // Step 4. Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT), Filter::Native(f) => Ok((f)(node)), - Filter::Dom(ref callback) => callback.AcceptNode_(self, node, Rethrow) + Filter::Dom(ref callback) => { + // Step 5. + self.active.set(true); + // Step 6. + let result = callback.AcceptNode_(self, node, Rethrow); + // Step 7. + self.active.set(false); + // Step 8. + result + }, } } From 8245aad2fe739cf04ef81147cd27601607ee8c00 Mon Sep 17 00:00:00 2001 From: CYBAI Date: Thu, 19 Oct 2017 22:04:23 +0800 Subject: [PATCH 2/2] Remove legacy tests --- tests/wpt/metadata/dom/traversal/NodeIterator.html.ini | 5 ----- tests/wpt/metadata/dom/traversal/TreeWalker.html.ini | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 tests/wpt/metadata/dom/traversal/NodeIterator.html.ini delete mode 100644 tests/wpt/metadata/dom/traversal/TreeWalker.html.ini diff --git a/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini b/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini deleted file mode 100644 index e6d8f6eb579..00000000000 --- a/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[NodeIterator.html] - type: testharness - [Recursive filters need to throw] - expected: FAIL - diff --git a/tests/wpt/metadata/dom/traversal/TreeWalker.html.ini b/tests/wpt/metadata/dom/traversal/TreeWalker.html.ini deleted file mode 100644 index 254681666cb..00000000000 --- a/tests/wpt/metadata/dom/traversal/TreeWalker.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[TreeWalker.html] - type: testharness - [Recursive filters need to throw] - expected: FAIL -