mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #17252 - heycam:flattened-tree, r=emilio
style: don't perform selector matching on the flattened tree From https://bugzilla.mozilla.org/show_bug.cgi?id=1369954. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17252) <!-- Reviewable:end -->
This commit is contained in:
commit
969047bb7c
14 changed files with 2015 additions and 1956 deletions
|
@ -165,12 +165,32 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
|
|||
transmute(node)
|
||||
}
|
||||
|
||||
fn children(self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
|
||||
fn parent_node(&self) -> Option<Self> {
|
||||
unsafe {
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
fn children(&self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
|
||||
LayoutIterator(ServoChildrenIterator {
|
||||
current: self.first_child(),
|
||||
})
|
||||
}
|
||||
|
||||
fn traversal_parent(&self) -> Option<ServoLayoutElement<'ln>> {
|
||||
self.parent_element()
|
||||
}
|
||||
|
||||
fn traversal_children(&self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
|
||||
self.children()
|
||||
}
|
||||
|
||||
fn children_and_traversal_children_might_differ(&self) -> bool {
|
||||
// Servo doesn't have to worry about nodes being rearranged in the
|
||||
// flattened tree like Gecko does (for XBL and Shadow DOM). Yet.
|
||||
false
|
||||
}
|
||||
|
||||
fn opaque(&self) -> OpaqueNode {
|
||||
unsafe { self.get_jsmanaged().opaque() }
|
||||
}
|
||||
|
@ -199,12 +219,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
|
|||
self.node.set_flag(CAN_BE_FRAGMENTED, value)
|
||||
}
|
||||
|
||||
fn parent_node(&self) -> Option<ServoLayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
}
|
||||
}
|
||||
|
||||
fn is_in_doc(&self) -> bool {
|
||||
unsafe { (*self.node.unsafe_get()).is_in_doc() }
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
pub fn push(&mut self, element: E) {
|
||||
if cfg!(debug_assertions) {
|
||||
if self.elements.is_empty() {
|
||||
assert!(element.parent_element().is_none());
|
||||
assert!(element.traversal_parent().is_none());
|
||||
}
|
||||
}
|
||||
self.push_internal(element);
|
||||
|
@ -139,7 +139,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
pub fn rebuild(&mut self, mut element: E) {
|
||||
self.clear();
|
||||
|
||||
while let Some(parent) = element.parent_element() {
|
||||
while let Some(parent) = element.traversal_parent() {
|
||||
self.push_internal(parent);
|
||||
element = parent;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
pub fn assert_complete(&self, mut element: E) {
|
||||
if cfg!(debug_assertions) {
|
||||
let mut checked = 0;
|
||||
while let Some(parent) = element.parent_element() {
|
||||
while let Some(parent) = element.traversal_parent() {
|
||||
assert_eq!(parent, *self.elements[self.elements.len() - 1 - checked]);
|
||||
element = parent;
|
||||
checked += 1;
|
||||
|
@ -190,7 +190,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
return;
|
||||
}
|
||||
|
||||
let parent_element = match element.parent_element() {
|
||||
let traversal_parent = match element.traversal_parent() {
|
||||
Some(parent) => parent,
|
||||
None => {
|
||||
// Yay, another easy case.
|
||||
|
@ -199,7 +199,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
}
|
||||
};
|
||||
|
||||
if self.current_parent() == Some(parent_element) {
|
||||
if self.current_parent() == Some(traversal_parent) {
|
||||
// Ta da, cache hit, we're all done.
|
||||
return;
|
||||
}
|
||||
|
@ -232,8 +232,8 @@ impl<E: TElement> StyleBloom<E> {
|
|||
}
|
||||
|
||||
// Now let's try to find a common parent in the bloom filter chain,
|
||||
// starting with parent_element.
|
||||
let mut common_parent = parent_element;
|
||||
// starting with traversal_parent.
|
||||
let mut common_parent = traversal_parent;
|
||||
let mut common_parent_depth = element_depth - 1;
|
||||
|
||||
// Let's collect the parents we are going to need to insert once we've
|
||||
|
@ -247,7 +247,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
// reverse the slice.
|
||||
parents_to_insert.push(common_parent);
|
||||
common_parent =
|
||||
common_parent.parent_element().expect("We were lied");
|
||||
common_parent.traversal_parent().expect("We were lied to");
|
||||
common_parent_depth -= 1;
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ impl<E: TElement> StyleBloom<E> {
|
|||
while **self.elements.last().unwrap() != common_parent {
|
||||
parents_to_insert.push(common_parent);
|
||||
self.pop().unwrap();
|
||||
common_parent = match common_parent.parent_element() {
|
||||
common_parent = match common_parent.traversal_parent() {
|
||||
Some(parent) => parent,
|
||||
None => {
|
||||
debug_assert!(self.elements.is_empty());
|
||||
|
|
|
@ -108,17 +108,31 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
|
|||
/// Get a node back from an `UnsafeNode`.
|
||||
unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
|
||||
|
||||
/// Returns an iterator over this node's children.
|
||||
fn children(self) -> LayoutIterator<Self::ConcreteChildrenIterator>;
|
||||
|
||||
/// Converts self into an `OpaqueNode`.
|
||||
fn opaque(&self) -> OpaqueNode;
|
||||
/// Get this node's parent node.
|
||||
fn parent_node(&self) -> Option<Self>;
|
||||
|
||||
/// Get this node's parent element if present.
|
||||
fn parent_element(&self) -> Option<Self::ConcreteElement> {
|
||||
self.parent_node().and_then(|n| n.as_element())
|
||||
}
|
||||
|
||||
/// Returns an iterator over this node's children.
|
||||
fn children(&self) -> LayoutIterator<Self::ConcreteChildrenIterator>;
|
||||
|
||||
/// Get this node's parent element from the perspective of a restyle
|
||||
/// traversal.
|
||||
fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
|
||||
|
||||
/// Get this node's children from the perspective of a restyle traversal.
|
||||
fn traversal_children(&self) -> LayoutIterator<Self::ConcreteChildrenIterator>;
|
||||
|
||||
/// Returns whether `children()` and `traversal_children()` might return
|
||||
/// iterators over different nodes.
|
||||
fn children_and_traversal_children_might_differ(&self) -> bool;
|
||||
|
||||
/// Converts self into an `OpaqueNode`.
|
||||
fn opaque(&self) -> OpaqueNode;
|
||||
|
||||
/// A debug id, only useful, mm... for debugging.
|
||||
fn debug_id(self) -> usize;
|
||||
|
||||
|
@ -138,9 +152,6 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
|
|||
/// Set whether this node can be fragmented.
|
||||
unsafe fn set_can_be_fragmented(&self, value: bool);
|
||||
|
||||
/// Get this node's parent node.
|
||||
fn parent_node(&self) -> Option<Self>;
|
||||
|
||||
/// Whether this node is in the document right now needed to clear the
|
||||
/// restyle data appropriately on some forced restyles.
|
||||
fn is_in_doc(&self) -> bool;
|
||||
|
@ -222,7 +233,7 @@ fn fmt_subtree<F, N: TNode>(f: &mut fmt::Formatter, stringify: &F, n: N, indent:
|
|||
try!(write!(f, " "));
|
||||
}
|
||||
try!(stringify(f, n));
|
||||
for kid in n.children() {
|
||||
for kid in n.traversal_children() {
|
||||
try!(writeln!(f, ""));
|
||||
try!(fmt_subtree(f, stringify, kid, indent + 1));
|
||||
}
|
||||
|
@ -256,7 +267,7 @@ pub unsafe fn raw_note_descendants<E, B>(element: E) -> bool
|
|||
break;
|
||||
}
|
||||
B::set(el);
|
||||
curr = el.parent_element();
|
||||
curr = el.traversal_parent();
|
||||
}
|
||||
|
||||
// Note: We disable this assertion on servo because of bugs. See the
|
||||
|
@ -297,7 +308,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
|||
fn depth(&self) -> usize {
|
||||
let mut depth = 0;
|
||||
let mut curr = *self;
|
||||
while let Some(parent) = curr.parent_element() {
|
||||
while let Some(parent) = curr.traversal_parent() {
|
||||
depth += 1;
|
||||
curr = parent;
|
||||
}
|
||||
|
@ -305,21 +316,18 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
|||
depth
|
||||
}
|
||||
|
||||
/// While doing a reflow, the element at the root has no parent, as far as we're
|
||||
/// concerned. This method returns `None` at the reflow root.
|
||||
fn layout_parent_element(self, reflow_root: OpaqueNode) -> Option<Self> {
|
||||
if self.as_node().opaque() == reflow_root {
|
||||
None
|
||||
} else {
|
||||
self.parent_element()
|
||||
}
|
||||
/// Get this node's parent element from the perspective of a restyle
|
||||
/// traversal.
|
||||
fn traversal_parent(&self) -> Option<Self> {
|
||||
self.as_node().traversal_parent()
|
||||
}
|
||||
|
||||
/// Returns the parent element we should inherit from.
|
||||
///
|
||||
/// This is pretty much always the parent element itself, except in the case
|
||||
/// of Gecko's Native Anonymous Content, which may need to find the closest
|
||||
/// non-NAC ancestor.
|
||||
/// of Gecko's Native Anonymous Content, which uses the traversal parent
|
||||
/// (i.e. the flattened tree parent) and which also may need to find the
|
||||
/// closest non-NAC ancestor.
|
||||
fn inheritance_parent(&self) -> Option<Self> {
|
||||
self.parent_element()
|
||||
}
|
||||
|
@ -442,7 +450,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
|||
let mut current = Some(*self);
|
||||
while let Some(el) = current {
|
||||
if !B::has(el) { return false; }
|
||||
current = el.parent_element();
|
||||
current = el.traversal_parent();
|
||||
}
|
||||
|
||||
true
|
||||
|
|
|
@ -507,7 +507,7 @@ extern "C" {
|
|||
whitespace_is_significant: bool) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_GetParentNode(node: RawGeckoNodeBorrowed)
|
||||
pub fn Gecko_GetFlattenedTreeParentNode(node: RawGeckoNodeBorrowed)
|
||||
-> RawGeckoNodeBorrowedOrNull;
|
||||
}
|
||||
extern "C" {
|
||||
|
@ -567,6 +567,11 @@ extern "C" {
|
|||
pub fn Gecko_GetNextStyleChild(it: StyleChildrenIteratorBorrowedMut)
|
||||
-> RawGeckoNodeBorrowedOrNull;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ElementHasBindingWithAnonymousContent(element:
|
||||
RawGeckoElementBorrowed)
|
||||
-> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -34,6 +34,7 @@ use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_
|
|||
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
||||
use gecko_bindings::bindings::Gecko_ClassOrClassList;
|
||||
use gecko_bindings::bindings::Gecko_ElementHasAnimations;
|
||||
use gecko_bindings::bindings::Gecko_ElementHasBindingWithAnonymousContent;
|
||||
use gecko_bindings::bindings::Gecko_ElementHasCSSAnimations;
|
||||
use gecko_bindings::bindings::Gecko_ElementHasCSSTransitions;
|
||||
use gecko_bindings::bindings::Gecko_GetActiveLinkAttrDeclarationBlock;
|
||||
|
@ -204,6 +205,16 @@ impl<'ln> GeckoNode<'ln> {
|
|||
true
|
||||
}
|
||||
|
||||
fn flattened_tree_parent(&self) -> Option<Self> {
|
||||
let fast_path = self.flattened_tree_parent_is_parent();
|
||||
debug_assert!(fast_path == unsafe { bindings::Gecko_FlattenedTreeParentIsParent(self.0) });
|
||||
if fast_path {
|
||||
unsafe { self.0.mParent.as_ref().map(GeckoNode) }
|
||||
} else {
|
||||
unsafe { bindings::Gecko_GetFlattenedTreeParentNode(self.0).map(GeckoNode) }
|
||||
}
|
||||
}
|
||||
|
||||
/// This logic is duplicated in Gecko's nsIContent::IsRootOfNativeAnonymousSubtree.
|
||||
fn is_root_of_native_anonymous_subtree(&self) -> bool {
|
||||
use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS_ROOT;
|
||||
|
@ -240,15 +251,31 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
|||
GeckoNode(&*(n.0 as *mut RawGeckoNode))
|
||||
}
|
||||
|
||||
fn children(self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
|
||||
fn parent_node(&self) -> Option<Self> {
|
||||
unsafe { self.0.mParent.as_ref().map(GeckoNode) }
|
||||
}
|
||||
|
||||
fn children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
|
||||
LayoutIterator(self.dom_children())
|
||||
}
|
||||
|
||||
fn traversal_parent(&self) -> Option<GeckoElement<'ln>> {
|
||||
self.flattened_tree_parent().and_then(|n| n.as_element())
|
||||
}
|
||||
|
||||
fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
|
||||
let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) };
|
||||
if let Some(iter) = maybe_iter.into_owned_opt() {
|
||||
LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter))
|
||||
} else {
|
||||
LayoutIterator(GeckoChildrenIterator::Current(self.first_child()))
|
||||
LayoutIterator(self.dom_children())
|
||||
}
|
||||
}
|
||||
|
||||
fn children_and_traversal_children_might_differ(&self) -> bool {
|
||||
self.as_element().map_or(false, |e| unsafe { Gecko_ElementHasBindingWithAnonymousContent(e.0) })
|
||||
}
|
||||
|
||||
fn opaque(&self) -> OpaqueNode {
|
||||
let ptr: usize = self.0 as *const _ as usize;
|
||||
OpaqueNode(ptr)
|
||||
|
@ -277,16 +304,6 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
|||
// Maybe this isn’t useful for Gecko?
|
||||
}
|
||||
|
||||
fn parent_node(&self) -> Option<Self> {
|
||||
let fast_path = self.flattened_tree_parent_is_parent();
|
||||
debug_assert!(fast_path == unsafe { bindings::Gecko_FlattenedTreeParentIsParent(self.0) });
|
||||
if fast_path {
|
||||
unsafe { self.0.mParent.as_ref().map(GeckoNode) }
|
||||
} else {
|
||||
unsafe { bindings::Gecko_GetParentNode(self.0).map(GeckoNode) }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_in_doc(&self) -> bool {
|
||||
unsafe { bindings::Gecko_IsInDocument(self.0) }
|
||||
}
|
||||
|
@ -644,9 +661,10 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
|
||||
fn inheritance_parent(&self) -> Option<Self> {
|
||||
if self.is_native_anonymous() {
|
||||
return self.closest_non_native_anonymous_ancestor();
|
||||
self.closest_non_native_anonymous_ancestor()
|
||||
} else {
|
||||
self.as_node().flattened_tree_parent().and_then(|n| n.as_element())
|
||||
}
|
||||
return self.parent_element();
|
||||
}
|
||||
|
||||
fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> {
|
||||
|
|
|
@ -166,7 +166,7 @@ impl StylesheetInvalidationSet {
|
|||
|
||||
let mut any_children_invalid = false;
|
||||
|
||||
for child in element.as_node().children() {
|
||||
for child in element.as_node().traversal_children() {
|
||||
let child = match child.as_element() {
|
||||
Some(e) => e,
|
||||
None => continue,
|
||||
|
|
|
@ -230,7 +230,7 @@ trait PrivateMatchMethods: TElement {
|
|||
fn layout_parent(&self) -> Self {
|
||||
let mut current = self.clone();
|
||||
loop {
|
||||
current = match current.parent_element() {
|
||||
current = match current.traversal_parent() {
|
||||
Some(el) => el,
|
||||
None => return current,
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
|
|||
// it on the context to make it available to the bottom-up phase.
|
||||
let depth = if token.traverse_unstyled_children_only() {
|
||||
debug_assert!(!D::needs_postorder_traversal());
|
||||
for kid in root.as_node().children() {
|
||||
for kid in root.as_node().traversal_children() {
|
||||
if kid.as_element().map_or(false, |el| el.get_data().is_none()) {
|
||||
nodes.push(unsafe { SendNode::new(kid) });
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
|
|||
let root_depth = root.depth();
|
||||
|
||||
if token.traverse_unstyled_children_only() {
|
||||
for kid in root.as_node().children() {
|
||||
for kid in root.as_node().traversal_children() {
|
||||
if kid.as_element().map_or(false, |el| el.get_data().is_none()) {
|
||||
discovered.push_back(WorkItem(kid, root_depth + 1));
|
||||
}
|
||||
|
|
|
@ -185,10 +185,10 @@ impl ValidationData {
|
|||
// filter, to avoid thrashing the filter.
|
||||
let bloom_to_use = if bloom_known_valid {
|
||||
debug_assert_eq!(bloom.current_parent(),
|
||||
element.parent_element());
|
||||
element.traversal_parent());
|
||||
Some(bloom.filter())
|
||||
} else {
|
||||
if bloom.current_parent() == element.parent_element() {
|
||||
if bloom.current_parent() == element.traversal_parent() {
|
||||
Some(bloom.filter())
|
||||
} else {
|
||||
None
|
||||
|
@ -344,7 +344,7 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
return StyleSharingResult::CannotShare;
|
||||
}
|
||||
debug_assert_eq!(bloom_filter.current_parent(),
|
||||
self.element.parent_element());
|
||||
self.element.traversal_parent());
|
||||
|
||||
let result = cache
|
||||
.share_style_if_possible(shared_context,
|
||||
|
@ -500,7 +500,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
dom_depth: usize) {
|
||||
use selectors::matching::AFFECTED_BY_PRESENTATIONAL_HINTS;
|
||||
|
||||
let parent = match element.parent_element() {
|
||||
let parent = match element.traversal_parent() {
|
||||
Some(element) => element,
|
||||
None => {
|
||||
debug!("Failing to insert to the cache: no parent element");
|
||||
|
@ -572,7 +572,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
return StyleSharingResult::CannotShare
|
||||
}
|
||||
|
||||
if target.parent_element().is_none() {
|
||||
if target.traversal_parent().is_none() {
|
||||
debug!("{:?} Cannot share style: element has no parent",
|
||||
target.element);
|
||||
return StyleSharingResult::CannotShare
|
||||
|
@ -644,8 +644,8 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
|||
// Check that we have the same parent, or at least the same pointer
|
||||
// identity for parent computed style. The latter check allows us to
|
||||
// share style between cousins if the parents shared style.
|
||||
let parent = target.parent_element();
|
||||
let candidate_parent = candidate.element.parent_element();
|
||||
let parent = target.traversal_parent();
|
||||
let candidate_parent = candidate.element.traversal_parent();
|
||||
if parent != candidate_parent &&
|
||||
!checks::same_computed_values(parent, candidate_parent) {
|
||||
miss!(Parent)
|
||||
|
|
|
@ -192,7 +192,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
if node.opaque() == root {
|
||||
break;
|
||||
}
|
||||
let parent = node.parent_element().unwrap();
|
||||
let parent = node.traversal_parent().unwrap();
|
||||
let remaining = parent.did_process_child();
|
||||
if remaining != 0 {
|
||||
// The parent has other unprocessed descendants. We only
|
||||
|
@ -308,7 +308,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
// But it may be that we no longer match, so detect that case
|
||||
// and act appropriately here.
|
||||
if el.is_native_anonymous() {
|
||||
if let Some(parent) = el.parent_element() {
|
||||
if let Some(parent) = el.traversal_parent() {
|
||||
let parent_data = parent.borrow_data().unwrap();
|
||||
let going_to_reframe = parent_data.get_restyle().map_or(false, |r| {
|
||||
(r.damage | r.damage_handled())
|
||||
|
@ -467,7 +467,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
return;
|
||||
}
|
||||
|
||||
for kid in parent.as_node().children() {
|
||||
for kid in parent.as_node().traversal_children() {
|
||||
if Self::node_needs_traversal(kid, self.shared_context().traversal_flags) {
|
||||
// If we are in a restyle for reconstruction, there is no need to
|
||||
// perform a post-traversal, so we don't need to set the dirty
|
||||
|
@ -527,7 +527,7 @@ fn resolve_style_internal<E, F>(context: &mut StyleContext<E>,
|
|||
// If the Element isn't styled, we need to compute its style.
|
||||
if data.get_styles().is_none() {
|
||||
// Compute the parent style if necessary.
|
||||
let parent = element.parent_element();
|
||||
let parent = element.traversal_parent();
|
||||
if let Some(p) = parent {
|
||||
display_none_root = resolve_style_internal(context, p, ensure_data);
|
||||
}
|
||||
|
@ -604,7 +604,7 @@ pub fn resolve_style<E, F, G, H>(context: &mut StyleContext<E>, element: E,
|
|||
break;
|
||||
}
|
||||
clear_data(curr);
|
||||
curr = match curr.parent_element() {
|
||||
curr = match curr.traversal_parent() {
|
||||
Some(parent) => parent,
|
||||
None => break,
|
||||
};
|
||||
|
@ -632,7 +632,7 @@ pub fn resolve_default_style<E, F, G, H>(context: &mut StyleContext<E>,
|
|||
let mut e = element;
|
||||
loop {
|
||||
old_data.push((e, set_data(e, None)));
|
||||
match e.parent_element() {
|
||||
match e.traversal_parent() {
|
||||
Some(parent) => e = parent,
|
||||
None => break,
|
||||
}
|
||||
|
@ -862,8 +862,8 @@ fn preprocess_children<E, D>(context: &mut StyleContext<E>,
|
|||
{
|
||||
trace!("preprocess_children: {:?}", element);
|
||||
|
||||
// Loop over all the children.
|
||||
for child in element.as_node().children() {
|
||||
// Loop over all the traversal children.
|
||||
for child in element.as_node().traversal_children() {
|
||||
// FIXME(bholley): Add TElement::element_children instead of this.
|
||||
let child = match child.as_element() {
|
||||
Some(el) => el,
|
||||
|
@ -919,7 +919,7 @@ fn preprocess_children<E, D>(context: &mut StyleContext<E>,
|
|||
|
||||
/// Clear style data for all the subtree under `el`.
|
||||
pub fn clear_descendant_data<E: TElement, F: Fn(E)>(el: E, clear_data: &F) {
|
||||
for kid in el.as_node().children() {
|
||||
for kid in el.as_node().traversal_children() {
|
||||
if let Some(kid) = kid.as_element() {
|
||||
// We maintain an invariant that, if an element has data, all its ancestors
|
||||
// have data as well. By consequence, any element without data has no
|
||||
|
|
|
@ -198,7 +198,7 @@ fn traverse_subtree(element: GeckoElement,
|
|||
snapshots: &ServoElementSnapshotTable) {
|
||||
// When new content is inserted in a display:none subtree, we will call into
|
||||
// servo to try to style it. Detect that here and bail out.
|
||||
if let Some(parent) = element.parent_element() {
|
||||
if let Some(parent) = element.traversal_parent() {
|
||||
if parent.borrow_data().map_or(true, |d| d.styles().is_display_none()) {
|
||||
debug!("{:?} has unstyled parent {:?} - ignoring call to traverse_subtree", element, parent);
|
||||
return;
|
||||
|
@ -2398,7 +2398,7 @@ unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut<ElementData>,
|
|||
}
|
||||
|
||||
// Propagate the bit up the chain.
|
||||
if let Some(p) = element.parent_element() {
|
||||
if let Some(p) = element.traversal_parent() {
|
||||
if animation_only {
|
||||
p.note_descendants::<AnimationOnlyDirtyDescendants>();
|
||||
} else {
|
||||
|
@ -2735,7 +2735,7 @@ pub extern "C" fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed) {
|
|||
let root = GeckoElement(root);
|
||||
fn assert_subtree_is_clean<'le>(el: GeckoElement<'le>) {
|
||||
debug_assert!(!el.has_dirty_descendants() && !el.has_animation_only_dirty_descendants());
|
||||
for child in el.as_node().children() {
|
||||
for child in el.as_node().traversal_children() {
|
||||
if let Some(child) = child.as_element() {
|
||||
assert_subtree_is_clean(child);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue