mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Hold a Temporary in AncestorIterator
This commit is contained in:
parent
6a6ecb9afa
commit
bf7c791e3a
10 changed files with 91 additions and 63 deletions
|
@ -409,8 +409,8 @@ impl<'a> Iterator for QuerySelectorIterator<'a> {
|
|||
}
|
||||
|
||||
pub trait NodeHelpers<'a> {
|
||||
fn ancestors(self) -> AncestorIterator<'a>;
|
||||
fn inclusive_ancestors(self) -> AncestorIterator<'a>;
|
||||
fn ancestors(self) -> AncestorIterator;
|
||||
fn inclusive_ancestors(self) -> AncestorIterator;
|
||||
fn children(self) -> NodeChildrenIterator;
|
||||
fn rev_children(self) -> ReverseChildrenIterator;
|
||||
fn child_elements(self) -> ChildElementIterator<'a>;
|
||||
|
@ -735,8 +735,9 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
|
||||
// 4. Dirty ancestors.
|
||||
for ancestor in self.ancestors() {
|
||||
if !force_ancestors && ancestor.get_has_dirty_descendants() { break }
|
||||
ancestor.set_has_dirty_descendants(true);
|
||||
let ancestor = ancestor.root();
|
||||
if !force_ancestors && ancestor.r().get_has_dirty_descendants() { break }
|
||||
ancestor.r().set_has_dirty_descendants(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,7 +753,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
}
|
||||
|
||||
fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool {
|
||||
self == parent || parent.ancestors().any(|ancestor| ancestor == self)
|
||||
self == parent || parent.ancestors().any(|ancestor| ancestor.root().r() == self)
|
||||
}
|
||||
|
||||
fn following_siblings(self) -> NodeChildrenIterator {
|
||||
|
@ -788,7 +789,8 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
Err(()) => return Err(Syntax),
|
||||
// Step 3.
|
||||
Ok(ref selectors) => {
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
let root = self.ancestors().last().root();
|
||||
let root = root.r().unwrap_or(self.clone());
|
||||
Ok(root.traverse_preorder()
|
||||
.filter_map(ElementCast::to_ref)
|
||||
.find(|element| matches(selectors, &NodeCast::from_ref(*element), &mut None))
|
||||
|
@ -805,7 +807,9 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
-> Fallible<QuerySelectorIterator<'a>> {
|
||||
// Step 1.
|
||||
let nodes;
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
let root = self.ancestors().last().root()
|
||||
.map(|node| node.get_unsound_ref_forever())
|
||||
.unwrap_or(self.clone());
|
||||
match parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
||||
// Step 2.
|
||||
Err(()) => return Err(Syntax),
|
||||
|
@ -830,15 +834,15 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
}
|
||||
|
||||
|
||||
fn ancestors(self) -> AncestorIterator<'a> {
|
||||
fn ancestors(self) -> AncestorIterator {
|
||||
AncestorIterator {
|
||||
current: self.parent_node.get().map(|node| node.root().get_unsound_ref_forever()),
|
||||
current: self.parent_node()
|
||||
}
|
||||
}
|
||||
|
||||
fn inclusive_ancestors(self) -> AncestorIterator<'a> {
|
||||
fn inclusive_ancestors(self) -> AncestorIterator {
|
||||
AncestorIterator {
|
||||
current: Some(self.clone())
|
||||
current: Some(Temporary::from_rooted(self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1148,17 +1152,20 @@ impl Iterator for ReverseChildrenIterator {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct AncestorIterator<'a> {
|
||||
current: Option<JSRef<'a, Node>>,
|
||||
pub struct AncestorIterator {
|
||||
current: Option<Temporary<Node>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for AncestorIterator<'a> {
|
||||
type Item = JSRef<'a, Node>;
|
||||
impl Iterator for AncestorIterator {
|
||||
type Item = Temporary<Node>;
|
||||
|
||||
fn next(&mut self) -> Option<JSRef<'a, Node>> {
|
||||
let node = self.current;
|
||||
self.current = node.and_then(|node| node.parent_node().map(|node| node.root().get_unsound_ref_forever()));
|
||||
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().parent_node();
|
||||
Some(Temporary::from_rooted(current.r()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2174,23 +2181,25 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
// step 2.
|
||||
0
|
||||
} else {
|
||||
let mut lastself = self.clone();
|
||||
let mut lastother = other.clone();
|
||||
let mut lastself = Temporary::from_rooted(self.clone());
|
||||
let mut lastother = Temporary::from_rooted(other.clone());
|
||||
for ancestor in self.ancestors() {
|
||||
if ancestor == other {
|
||||
let ancestor = ancestor.root();
|
||||
if ancestor.r() == other {
|
||||
// step 4.
|
||||
return NodeConstants::DOCUMENT_POSITION_CONTAINS +
|
||||
NodeConstants::DOCUMENT_POSITION_PRECEDING;
|
||||
}
|
||||
lastself = ancestor.clone();
|
||||
lastself = Temporary::from_rooted(ancestor.r());
|
||||
}
|
||||
for ancestor in other.ancestors() {
|
||||
if ancestor == self {
|
||||
let ancestor = ancestor.root();
|
||||
if ancestor.r() == self {
|
||||
// step 5.
|
||||
return NodeConstants::DOCUMENT_POSITION_CONTAINED_BY +
|
||||
NodeConstants::DOCUMENT_POSITION_FOLLOWING;
|
||||
}
|
||||
lastother = ancestor.clone();
|
||||
lastother = Temporary::from_rooted(ancestor.r());
|
||||
}
|
||||
|
||||
if lastself != lastother {
|
||||
|
@ -2208,7 +2217,8 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
|
||||
}
|
||||
|
||||
for child in lastself.traverse_preorder() {
|
||||
let lastself = lastself.root();
|
||||
for child in lastself.r().traverse_preorder() {
|
||||
if child == other {
|
||||
// step 6.
|
||||
return NodeConstants::DOCUMENT_POSITION_PRECEDING;
|
||||
|
@ -2418,7 +2428,10 @@ pub trait DisabledStateHelpers {
|
|||
impl<'a> DisabledStateHelpers for JSRef<'a, Node> {
|
||||
fn check_ancestors_disabled_state_for_form_control(self) {
|
||||
if self.get_disabled_state() { return; }
|
||||
for ancestor in self.ancestors().filter(|ancestor| ancestor.is_htmlfieldsetelement()) {
|
||||
for ancestor in self.ancestors() {
|
||||
let ancestor = ancestor.root();
|
||||
let ancestor = ancestor.r();
|
||||
if !ancestor.is_htmlfieldsetelement() { continue; }
|
||||
if !ancestor.get_disabled_state() { continue; }
|
||||
if ancestor.is_parent_of(self) {
|
||||
self.set_disabled_state(true);
|
||||
|
@ -2431,7 +2444,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> {
|
|||
{
|
||||
Some(legend) => {
|
||||
// XXXabinader: should we save previous ancestor to avoid this iteration?
|
||||
if self.ancestors().any(|ancestor| ancestor == legend.r()) { continue; }
|
||||
if self.ancestors().any(|ancestor| ancestor.root().r() == legend.r()) { continue; }
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue