servo: Merge #18104 - style: Skip matching :nth-child if element is the root of anonymous subtree (from aethanyc:fix-nth-child-xbl-bug1382102); r=emilio

This was reviewed in https://bugzilla.mozilla.org/show_bug.cgi?id=1382102

Source-Repo: https://github.com/servo/servo
Source-Revision: 24270f93571e0a1254d402f1c897bcc1ebbbd459

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 85d26b1d4274515b33d5b2cb55e461e863ab4a0b
This commit is contained in:
Ting-Yu Lin 2017-08-16 01:47:46 -05:00
parent e6b40af388
commit 01b76e9c9a
3 changed files with 21 additions and 2 deletions

View File

@ -776,6 +776,10 @@ fn matches_generic_nth_child<E, F>(element: &E,
where E: Element,
F: FnMut(&E, ElementSelectorFlags),
{
if element.ignores_nth_child_selectors() {
return false;
}
flags_setter(element, if is_from_end {
HAS_SLOW_SELECTOR
} else {

View File

@ -86,6 +86,12 @@ pub trait Element: Sized + Debug {
/// if the parent node is a `DocumentFragment`.
fn is_root(&self) -> bool;
/// Returns whether this element should ignore matching nth child
/// selector.
fn ignores_nth_child_selectors(&self) -> bool {
false
}
/// Return true if we want to stop lookup ancestor of the current
/// element while matching complex selectors with descendant/child
/// combinator.

View File

@ -729,6 +729,12 @@ impl<'le> GeckoElement<'le> {
debug!("(Element not styled, discarding hints)");
}
}
/// This logic is duplicated in Gecko's nsIContent::IsRootOfAnonymousSubtree.
fn is_root_of_anonymous_subtree(&self) -> bool {
use gecko_bindings::structs::NODE_IS_ANONYMOUS_ROOT;
self.flags() & (NODE_IS_ANONYMOUS_ROOT as u32) != 0
}
}
/// Converts flags from the layout used by rust-selectors to the layout used
@ -1970,9 +1976,12 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
node.owner_doc().mType == structs::root::nsIDocument_Type::eHTML
}
fn ignores_nth_child_selectors(&self) -> bool {
self.is_root_of_anonymous_subtree()
}
fn blocks_ancestor_combinators(&self) -> bool {
use gecko_bindings::structs::NODE_IS_ANONYMOUS_ROOT;
if self.flags() & (NODE_IS_ANONYMOUS_ROOT as u32) == 0 {
if !self.is_root_of_anonymous_subtree() {
return false
}