mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Collapse Selector, SelectorInner, and ComplexSelector into a single Selector.
The refcounting is still internal. We'll fix that up next. MozReview-Commit-ID: CTxZNaR3Qgj
This commit is contained in:
parent
713c9a63f6
commit
5ddabef636
7 changed files with 71 additions and 147 deletions
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
use attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint};
|
use attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint};
|
||||||
use bloom::BloomFilter;
|
use bloom::BloomFilter;
|
||||||
use parser::{AncestorHashes, Combinator, ComplexSelector, Component, LocalName};
|
use parser::{AncestorHashes, Combinator, Component, LocalName};
|
||||||
use parser::{SelectorInner, SelectorIter, SelectorList};
|
use parser::{Selector, SelectorIter, SelectorList};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use tree::Element;
|
use tree::Element;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ pub fn matches_selector_list<E>(selector_list: &SelectorList<E::Impl>,
|
||||||
where E: Element
|
where E: Element
|
||||||
{
|
{
|
||||||
selector_list.0.iter().any(|selector_and_hashes| {
|
selector_list.0.iter().any(|selector_and_hashes| {
|
||||||
matches_selector(&selector_and_hashes.selector.inner,
|
matches_selector(&selector_and_hashes.selector,
|
||||||
&selector_and_hashes.hashes,
|
&selector_and_hashes.hashes,
|
||||||
element,
|
element,
|
||||||
context,
|
context,
|
||||||
|
@ -334,7 +334,7 @@ enum SelectorMatchingResult {
|
||||||
|
|
||||||
/// Matches a selector, fast-rejecting against a bloom filter.
|
/// Matches a selector, fast-rejecting against a bloom filter.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn matches_selector<E, F>(selector: &SelectorInner<E::Impl>,
|
pub fn matches_selector<E, F>(selector: &Selector<E::Impl>,
|
||||||
hashes: &AncestorHashes,
|
hashes: &AncestorHashes,
|
||||||
element: &E,
|
element: &E,
|
||||||
context: &mut MatchingContext,
|
context: &mut MatchingContext,
|
||||||
|
@ -350,13 +350,11 @@ pub fn matches_selector<E, F>(selector: &SelectorInner<E::Impl>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matches_complex_selector(&selector.complex, element, context, flags_setter)
|
matches_complex_selector(selector, element, context, flags_setter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches a complex selector.
|
/// Matches a complex selector.
|
||||||
///
|
pub fn matches_complex_selector<E, F>(complex_selector: &Selector<E::Impl>,
|
||||||
/// Use `matches_selector` if you need to skip pseudos.
|
|
||||||
pub fn matches_complex_selector<E, F>(complex_selector: &ComplexSelector<E::Impl>,
|
|
||||||
element: &E,
|
element: &E,
|
||||||
context: &mut MatchingContext,
|
context: &mut MatchingContext,
|
||||||
flags_setter: &mut F)
|
flags_setter: &mut F)
|
||||||
|
|
|
@ -176,10 +176,10 @@ const NUM_ANCESTOR_HASHES: usize = 4;
|
||||||
pub struct AncestorHashes(pub [u32; NUM_ANCESTOR_HASHES]);
|
pub struct AncestorHashes(pub [u32; NUM_ANCESTOR_HASHES]);
|
||||||
|
|
||||||
impl AncestorHashes {
|
impl AncestorHashes {
|
||||||
pub fn new<Impl: SelectorImpl>(c: &Selector<Impl>) -> Self {
|
pub fn new<Impl: SelectorImpl>(s: &Selector<Impl>) -> Self {
|
||||||
let mut hashes = [0; NUM_ANCESTOR_HASHES];
|
let mut hashes = [0; NUM_ANCESTOR_HASHES];
|
||||||
// Compute ancestor hashes for the bloom filter.
|
// Compute ancestor hashes for the bloom filter.
|
||||||
let mut hash_iter = c.inner.complex.iter_ancestors()
|
let mut hash_iter = s.iter_ancestors()
|
||||||
.map(|x| x.ancestor_hash())
|
.map(|x| x.ancestor_hash())
|
||||||
.filter(|x| x.is_some())
|
.filter(|x| x.is_some())
|
||||||
.map(|x| x.unwrap());
|
.map(|x| x.unwrap());
|
||||||
|
@ -194,81 +194,8 @@ impl AncestorHashes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cores parts of a selector used for matching. This exists to make that
|
|
||||||
/// information accessibly separately from the specificity and pseudo-element
|
|
||||||
/// information that lives on |Selector| proper. We may want to refactor things
|
|
||||||
/// and move that information elsewhere, at which point we could rename this
|
|
||||||
/// to |Selector|.
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
|
||||||
pub struct SelectorInner<Impl: SelectorImpl> {
|
|
||||||
/// The selector data.
|
|
||||||
pub complex: ComplexSelector<Impl>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> SelectorInner<Impl> {
|
|
||||||
pub fn new(c: ComplexSelector<Impl>) -> Self {
|
|
||||||
SelectorInner {
|
|
||||||
complex: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a SelectorInner from a Vec of Components. Used in tests.
|
|
||||||
pub fn from_vec(vec: Vec<Component<Impl>>, specificity_and_flags: u32) -> Self {
|
|
||||||
let complex = ComplexSelector::from_vec(vec, specificity_and_flags);
|
|
||||||
Self::new(complex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
|
||||||
pub struct Selector<Impl: SelectorImpl> {
|
|
||||||
pub inner: SelectorInner<Impl>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> ::std::borrow::Borrow<SelectorInner<Impl>> for Selector<Impl> {
|
|
||||||
fn borrow(&self) -> &SelectorInner<Impl> {
|
|
||||||
&self.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const HAS_PSEUDO_BIT: u32 = 1 << 30;
|
const HAS_PSEUDO_BIT: u32 = 1 << 30;
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> Selector<Impl> {
|
|
||||||
pub fn specificity(&self) -> u32 {
|
|
||||||
self.inner.complex.specificity()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pseudo_element(&self) -> Option<&Impl::PseudoElement> {
|
|
||||||
if !self.has_pseudo_element() {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
for component in self.inner.complex.iter() {
|
|
||||||
if let Component::PseudoElement(ref pseudo) = *component {
|
|
||||||
return Some(pseudo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(false, "has_pseudo_element lied!");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_pseudo_element(&self) -> bool {
|
|
||||||
self.inner.complex.has_pseudo_element()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether this selector (pseudo-element part excluded) matches every element.
|
|
||||||
///
|
|
||||||
/// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
|
|
||||||
pub fn is_universal(&self) -> bool {
|
|
||||||
self.inner.complex.iter_raw().all(|c| matches!(*c,
|
|
||||||
Component::ExplicitUniversalType |
|
|
||||||
Component::ExplicitAnyNamespace |
|
|
||||||
Component::Combinator(Combinator::PseudoElement) |
|
|
||||||
Component::PseudoElement(..)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SelectorMethods {
|
pub trait SelectorMethods {
|
||||||
type Impl: SelectorImpl;
|
type Impl: SelectorImpl;
|
||||||
|
|
||||||
|
@ -279,16 +206,6 @@ pub trait SelectorMethods {
|
||||||
impl<Impl: SelectorImpl> SelectorMethods for Selector<Impl> {
|
impl<Impl: SelectorImpl> SelectorMethods for Selector<Impl> {
|
||||||
type Impl = Impl;
|
type Impl = Impl;
|
||||||
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> bool
|
|
||||||
where V: SelectorVisitor<Impl = Impl>,
|
|
||||||
{
|
|
||||||
self.inner.complex.visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> SelectorMethods for ComplexSelector<Impl> {
|
|
||||||
type Impl = Impl;
|
|
||||||
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> bool
|
fn visit<V>(&self, visitor: &mut V) -> bool
|
||||||
where V: SelectorVisitor<Impl = Impl>,
|
where V: SelectorVisitor<Impl = Impl>,
|
||||||
{
|
{
|
||||||
|
@ -381,7 +298,7 @@ pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl {
|
||||||
Impl::NamespaceUrl::default()
|
Impl::NamespaceUrl::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A ComplexSelectors stores a sequence of simple selectors and combinators. The
|
/// A Selector stores a sequence of simple selectors and combinators. The
|
||||||
/// iterator classes allow callers to iterate at either the raw sequence level or
|
/// iterator classes allow callers to iterate at either the raw sequence level or
|
||||||
/// at the level of sequences of simple selectors separated by combinators. Most
|
/// at the level of sequences of simple selectors separated by combinators. Most
|
||||||
/// callers want the higher-level iterator.
|
/// callers want the higher-level iterator.
|
||||||
|
@ -390,9 +307,9 @@ pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl {
|
||||||
/// canonical iteration order is right-to-left (selector matching order). The
|
/// canonical iteration order is right-to-left (selector matching order). The
|
||||||
/// iterators abstract over these details.
|
/// iterators abstract over these details.
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub struct ComplexSelector<Impl: SelectorImpl>(ArcSlice<Component<Impl>>, u32);
|
pub struct Selector<Impl: SelectorImpl>(ArcSlice<Component<Impl>>, u32);
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> ComplexSelector<Impl> {
|
impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
pub fn specificity(&self) -> u32 {
|
pub fn specificity(&self) -> u32 {
|
||||||
self.1 & !HAS_PSEUDO_BIT
|
self.1 & !HAS_PSEUDO_BIT
|
||||||
}
|
}
|
||||||
|
@ -401,6 +318,34 @@ impl<Impl: SelectorImpl> ComplexSelector<Impl> {
|
||||||
(self.1 & HAS_PSEUDO_BIT) != 0
|
(self.1 & HAS_PSEUDO_BIT) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pseudo_element(&self) -> Option<&Impl::PseudoElement> {
|
||||||
|
if !self.has_pseudo_element() {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
for component in self.iter() {
|
||||||
|
if let Component::PseudoElement(ref pseudo) = *component {
|
||||||
|
return Some(pseudo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert!(false, "has_pseudo_element lied!");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this selector (pseudo-element part excluded) matches every element.
|
||||||
|
///
|
||||||
|
/// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
|
||||||
|
pub fn is_universal(&self) -> bool {
|
||||||
|
self.iter_raw().all(|c| matches!(*c,
|
||||||
|
Component::ExplicitUniversalType |
|
||||||
|
Component::ExplicitAnyNamespace |
|
||||||
|
Component::Combinator(Combinator::PseudoElement) |
|
||||||
|
Component::PseudoElement(..)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns an iterator over the next sequence of simple selectors. When
|
/// Returns an iterator over the next sequence of simple selectors. When
|
||||||
/// a combinator is reached, the iterator will return None, and
|
/// a combinator is reached, the iterator will return None, and
|
||||||
/// next_sequence() may be called to continue to the next sequence.
|
/// next_sequence() may be called to continue to the next sequence.
|
||||||
|
@ -429,25 +374,25 @@ impl<Impl: SelectorImpl> ComplexSelector<Impl> {
|
||||||
AncestorIter::new(self.iter())
|
AncestorIter::new(self.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a ComplexSelector identical to |self| but with the rightmost |index|
|
/// Returns a Selector identical to |self| but with the rightmost |index| entries
|
||||||
/// entries removed.
|
/// removed.
|
||||||
pub fn slice_from(&self, index: usize) -> Self {
|
pub fn slice_from(&self, index: usize) -> Self {
|
||||||
// Note that we convert the slice_from to slice_to because selectors are
|
// Note that we convert the slice_from to slice_to because selectors are
|
||||||
// stored left-to-right but logical order is right-to-left.
|
// stored left-to-right but logical order is right-to-left.
|
||||||
ComplexSelector(self.0.clone().slice_to(self.0.len() - index), self.1)
|
Selector(self.0.clone().slice_to(self.0.len() - index), self.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a ComplexSelector identical to |self| but with the leftmost
|
/// Returns a Selector identical to |self| but with the leftmost |len() - index|
|
||||||
/// |len() - index| entries removed.
|
/// entries removed.
|
||||||
pub fn slice_to(&self, index: usize) -> Self {
|
pub fn slice_to(&self, index: usize) -> Self {
|
||||||
// Note that we convert the slice_to to slice_from because selectors are
|
// Note that we convert the slice_to to slice_from because selectors are
|
||||||
// stored left-to-right but logical order is right-to-left.
|
// stored left-to-right but logical order is right-to-left.
|
||||||
ComplexSelector(self.0.clone().slice_from(self.0.len() - index), self.1)
|
Selector(self.0.clone().slice_from(self.0.len() - index), self.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ComplexSelector from a vec of Components. Used in tests.
|
/// Creates a Selector from a vec of Components. Used in tests.
|
||||||
pub fn from_vec(vec: Vec<Component<Impl>>, specificity_and_flags: u32) -> Self {
|
pub fn from_vec(vec: Vec<Component<Impl>>, specificity_and_flags: u32) -> Self {
|
||||||
ComplexSelector(ArcSlice::new(vec.into_boxed_slice()), specificity_and_flags)
|
Selector(ArcSlice::new(vec.into_boxed_slice()), specificity_and_flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,12 +616,6 @@ impl<Impl: SelectorImpl> Debug for Selector<Impl> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> Debug for SelectorInner<Impl> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.complex.to_css(f) }
|
|
||||||
}
|
|
||||||
impl<Impl: SelectorImpl> Debug for ComplexSelector<Impl> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) }
|
|
||||||
}
|
|
||||||
impl<Impl: SelectorImpl> Debug for Component<Impl> {
|
impl<Impl: SelectorImpl> Debug for Component<Impl> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) }
|
||||||
}
|
}
|
||||||
|
@ -702,12 +641,6 @@ impl<Impl: SelectorImpl> ToCss for SelectorList<Impl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
|
impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
self.inner.complex.to_css(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> ToCss for ComplexSelector<Impl> {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
for item in self.iter_raw_rev() {
|
for item in self.iter_raw_rev() {
|
||||||
item.to_css(dest)?;
|
item.to_css(dest)?;
|
||||||
|
@ -916,13 +849,13 @@ impl From<Specificity> for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn specificity<Impl>(complex_selector: &ComplexSelector<Impl>) -> u32
|
fn specificity<Impl>(complex_selector: &Selector<Impl>) -> u32
|
||||||
where Impl: SelectorImpl
|
where Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
complex_selector_specificity(complex_selector).into()
|
complex_selector_specificity(complex_selector).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complex_selector_specificity<Impl>(selector: &ComplexSelector<Impl>)
|
fn complex_selector_specificity<Impl>(selector: &Selector<Impl>)
|
||||||
-> Specificity
|
-> Specificity
|
||||||
where Impl: SelectorImpl
|
where Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
|
@ -992,15 +925,13 @@ fn complex_selector_specificity<Impl>(selector: &ComplexSelector<Impl>)
|
||||||
fn parse_selector<P, Impl>(parser: &P, input: &mut CssParser) -> Result<Selector<Impl>, ()>
|
fn parse_selector<P, Impl>(parser: &P, input: &mut CssParser) -> Result<Selector<Impl>, ()>
|
||||||
where P: Parser<Impl=Impl>, Impl: SelectorImpl
|
where P: Parser<Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
let (mut complex, has_pseudo_element) = parse_complex_selector(parser, input)?;
|
let (mut selector, has_pseudo_element) = parse_complex_selector(parser, input)?;
|
||||||
let mut specificity = specificity(&complex);
|
let mut specificity = specificity(&selector);
|
||||||
if has_pseudo_element {
|
if has_pseudo_element {
|
||||||
specificity |= HAS_PSEUDO_BIT;
|
specificity |= HAS_PSEUDO_BIT;
|
||||||
}
|
}
|
||||||
complex.1 = specificity;
|
selector.1 = specificity;
|
||||||
Ok(Selector {
|
Ok(selector)
|
||||||
inner: SelectorInner::new(complex),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We use a SmallVec for parsing to avoid extra reallocs compared to using a Vec
|
/// We use a SmallVec for parsing to avoid extra reallocs compared to using a Vec
|
||||||
|
@ -1021,7 +952,7 @@ type ParseVec<Impl> = SmallVec<[Component<Impl>; 8]>;
|
||||||
fn parse_complex_selector<P, Impl>(
|
fn parse_complex_selector<P, Impl>(
|
||||||
parser: &P,
|
parser: &P,
|
||||||
input: &mut CssParser)
|
input: &mut CssParser)
|
||||||
-> Result<(ComplexSelector<Impl>, bool), ()>
|
-> Result<(Selector<Impl>, bool), ()>
|
||||||
where P: Parser<Impl=Impl>, Impl: SelectorImpl
|
where P: Parser<Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
let mut sequence = ParseVec::new();
|
let mut sequence = ParseVec::new();
|
||||||
|
@ -1069,11 +1000,11 @@ fn parse_complex_selector<P, Impl>(
|
||||||
sequence.push(Component::Combinator(combinator));
|
sequence.push(Component::Combinator(combinator));
|
||||||
}
|
}
|
||||||
|
|
||||||
let complex = ComplexSelector(ArcSlice::new(sequence.into_vec().into_boxed_slice()), 0);
|
let complex = Selector(ArcSlice::new(sequence.into_vec().into_boxed_slice()), 0);
|
||||||
Ok((complex, parsed_pseudo_element))
|
Ok((complex, parsed_pseudo_element))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> ComplexSelector<Impl> {
|
impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
/// Parse a complex selector, without any pseudo-element.
|
/// Parse a complex selector, without any pseudo-element.
|
||||||
pub fn parse<P>(parser: &P, input: &mut CssParser) -> Result<Self, ()>
|
pub fn parse<P>(parser: &P, input: &mut CssParser) -> Result<Self, ()>
|
||||||
where P: Parser<Impl=Impl>
|
where P: Parser<Impl=Impl>
|
||||||
|
|
|
@ -8,7 +8,7 @@ use cssparser::{Parser, ToCss};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use gecko_bindings::structs::CSSPseudoClassType;
|
use gecko_bindings::structs::CSSPseudoClassType;
|
||||||
use selector_parser::{SelectorParser, PseudoElementCascadeType};
|
use selector_parser::{SelectorParser, PseudoElementCascadeType};
|
||||||
use selectors::parser::{ComplexSelector, SelectorMethods};
|
use selectors::parser::{Selector, SelectorMethods};
|
||||||
use selectors::visitor::SelectorVisitor;
|
use selectors::visitor::SelectorVisitor;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -47,7 +47,7 @@ macro_rules! pseudo_class_name {
|
||||||
///
|
///
|
||||||
/// TODO(emilio): We disallow combinators and pseudos here, so we
|
/// TODO(emilio): We disallow combinators and pseudos here, so we
|
||||||
/// should use SimpleSelector instead
|
/// should use SimpleSelector instead
|
||||||
MozAny(Box<[ComplexSelector<SelectorImpl>]>),
|
MozAny(Box<[Selector<SelectorImpl>]>),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
}, )*
|
}, )*
|
||||||
"-moz-any" => {
|
"-moz-any" => {
|
||||||
let selectors = parser.parse_comma_separated(|input| {
|
let selectors = parser.parse_comma_separated(|input| {
|
||||||
ComplexSelector::parse(self, input)
|
Selector::parse(self, input)
|
||||||
})?;
|
})?;
|
||||||
// Selectors inside `:-moz-any` may not include combinators.
|
// Selectors inside `:-moz-any` may not include combinators.
|
||||||
if selectors.iter().flat_map(|x| x.iter_raw()).any(|s| s.is_combinator()) {
|
if selectors.iter().flat_map(|x| x.iter_raw()).any(|s| s.is_combinator()) {
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl StylesheetInvalidationSet {
|
||||||
let mut scope: Option<InvalidationScope> = None;
|
let mut scope: Option<InvalidationScope> = None;
|
||||||
|
|
||||||
let mut scan = true;
|
let mut scan = true;
|
||||||
let mut iter = selector.inner.complex.iter();
|
let mut iter = selector.iter();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for component in &mut iter {
|
for component in &mut iter {
|
||||||
|
|
|
@ -23,7 +23,7 @@ use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
|
||||||
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode};
|
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode};
|
||||||
use selectors::matching::{RelevantLinkStatus, VisitedHandlingMode, matches_selector};
|
use selectors::matching::{RelevantLinkStatus, VisitedHandlingMode, matches_selector};
|
||||||
use selectors::parser::{AncestorHashes, Combinator, Component};
|
use selectors::parser::{AncestorHashes, Combinator, Component};
|
||||||
use selectors::parser::{Selector, SelectorAndHashes, SelectorInner, SelectorMethods};
|
use selectors::parser::{Selector, SelectorAndHashes, SelectorMethods};
|
||||||
use selectors::visitor::SelectorVisitor;
|
use selectors::visitor::SelectorVisitor;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -949,7 +949,7 @@ impl DependencySet {
|
||||||
/// Adds a selector to this `DependencySet`.
|
/// Adds a selector to this `DependencySet`.
|
||||||
pub fn note_selector(&mut self, selector_and_hashes: &SelectorAndHashes<SelectorImpl>) {
|
pub fn note_selector(&mut self, selector_and_hashes: &SelectorAndHashes<SelectorImpl>) {
|
||||||
let mut combinator = None;
|
let mut combinator = None;
|
||||||
let mut iter = selector_and_hashes.selector.inner.complex.iter();
|
let mut iter = selector_and_hashes.selector.iter();
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let mut child_combinators_seen = 0;
|
let mut child_combinators_seen = 0;
|
||||||
let mut saw_descendant_combinator = false;
|
let mut saw_descendant_combinator = false;
|
||||||
|
@ -1001,14 +1001,9 @@ impl DependencySet {
|
||||||
|
|
||||||
let (dep_selector, hashes) = if sequence_start == 0 {
|
let (dep_selector, hashes) = if sequence_start == 0 {
|
||||||
// Reuse the bloom hashes if this is the base selector.
|
// Reuse the bloom hashes if this is the base selector.
|
||||||
(selector_and_hashes.selector.clone(),
|
(selector_and_hashes.selector.clone(), selector_and_hashes.hashes.clone())
|
||||||
selector_and_hashes.hashes.clone())
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let inner = SelectorInner::new(selector_and_hashes.selector
|
let selector = selector_and_hashes.selector.slice_from(sequence_start);
|
||||||
.inner
|
|
||||||
.complex.slice_from(sequence_start));
|
|
||||||
let selector = Selector { inner: inner };
|
|
||||||
let hashes = AncestorHashes::new(&selector);
|
let hashes = AncestorHashes::new(&selector);
|
||||||
(selector, hashes)
|
(selector, hashes)
|
||||||
};
|
};
|
||||||
|
@ -1145,7 +1140,7 @@ impl DependencySet {
|
||||||
MatchingContext::new_for_visited(MatchingMode::Normal, None,
|
MatchingContext::new_for_visited(MatchingMode::Normal, None,
|
||||||
VisitedHandlingMode::AllLinksUnvisited);
|
VisitedHandlingMode::AllLinksUnvisited);
|
||||||
let matched_then =
|
let matched_then =
|
||||||
matches_selector(&dep.selector.inner,
|
matches_selector(&dep.selector,
|
||||||
&dep.hashes,
|
&dep.hashes,
|
||||||
&snapshot_el,
|
&snapshot_el,
|
||||||
&mut then_context,
|
&mut then_context,
|
||||||
|
@ -1154,7 +1149,7 @@ impl DependencySet {
|
||||||
MatchingContext::new_for_visited(MatchingMode::Normal, bloom_filter,
|
MatchingContext::new_for_visited(MatchingMode::Normal, bloom_filter,
|
||||||
VisitedHandlingMode::AllLinksUnvisited);
|
VisitedHandlingMode::AllLinksUnvisited);
|
||||||
let matches_now =
|
let matches_now =
|
||||||
matches_selector(&dep.selector.inner,
|
matches_selector(&dep.selector,
|
||||||
&dep.hashes,
|
&dep.hashes,
|
||||||
el,
|
el,
|
||||||
&mut now_context,
|
&mut now_context,
|
||||||
|
@ -1181,14 +1176,14 @@ impl DependencySet {
|
||||||
dep.sensitivities.states.intersects(IN_VISITED_OR_UNVISITED_STATE) {
|
dep.sensitivities.states.intersects(IN_VISITED_OR_UNVISITED_STATE) {
|
||||||
then_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited;
|
then_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited;
|
||||||
let matched_then =
|
let matched_then =
|
||||||
matches_selector(&dep.selector.inner,
|
matches_selector(&dep.selector,
|
||||||
&dep.hashes,
|
&dep.hashes,
|
||||||
&snapshot_el,
|
&snapshot_el,
|
||||||
&mut then_context,
|
&mut then_context,
|
||||||
&mut |_, _| {});
|
&mut |_, _| {});
|
||||||
now_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited;
|
now_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited;
|
||||||
let matches_now =
|
let matches_now =
|
||||||
matches_selector(&dep.selector.inner,
|
matches_selector(&dep.selector,
|
||||||
&dep.hashes,
|
&dep.hashes,
|
||||||
el,
|
el,
|
||||||
&mut now_context,
|
&mut now_context,
|
||||||
|
|
|
@ -231,7 +231,7 @@ impl SelectorMap<Rule> {
|
||||||
F: FnMut(&E, ElementSelectorFlags),
|
F: FnMut(&E, ElementSelectorFlags),
|
||||||
{
|
{
|
||||||
for rule in rules {
|
for rule in rules {
|
||||||
if matches_selector(&rule.selector.inner,
|
if matches_selector(&rule.selector,
|
||||||
&rule.hashes,
|
&rule.hashes,
|
||||||
element,
|
element,
|
||||||
context,
|
context,
|
||||||
|
@ -403,7 +403,7 @@ fn find_from_right<F, R>(selector: &Selector<SelectorImpl>,
|
||||||
-> Option<R>
|
-> Option<R>
|
||||||
where F: FnMut(&Component<SelectorImpl>) -> Option<R>,
|
where F: FnMut(&Component<SelectorImpl>) -> Option<R>,
|
||||||
{
|
{
|
||||||
let mut iter = selector.inner.complex.iter();
|
let mut iter = selector.iter();
|
||||||
for ss in &mut iter {
|
for ss in &mut iter {
|
||||||
if let Some(r) = f(ss) {
|
if let Some(r) = f(ss) {
|
||||||
return Some(r)
|
return Some(r)
|
||||||
|
|
|
@ -1133,7 +1133,7 @@ impl Stylist {
|
||||||
// this in the caller by asserting that the bitvecs are same-length.
|
// this in the caller by asserting that the bitvecs are same-length.
|
||||||
let mut results = BitVec::new();
|
let mut results = BitVec::new();
|
||||||
self.selectors_for_cache_revalidation.lookup(*element, &mut |selector_and_hashes| {
|
self.selectors_for_cache_revalidation.lookup(*element, &mut |selector_and_hashes| {
|
||||||
results.push(matches_selector(&selector_and_hashes.selector.inner,
|
results.push(matches_selector(&selector_and_hashes.selector,
|
||||||
&selector_and_hashes.hashes,
|
&selector_and_hashes.hashes,
|
||||||
element,
|
element,
|
||||||
&mut matching_context,
|
&mut matching_context,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue