Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selectors: Revert as many changes from upstream as possible #31365

Merged
merged 1 commit into from Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion components/selectors/Cargo.toml
Expand Up @@ -9,7 +9,6 @@ readme = "README.md"
keywords = ["css", "selectors"]
license = "MPL-2.0"
build = "build.rs"
edition = "2018"

[lib]
name = "selectors"
Expand Down
6 changes: 4 additions & 2 deletions components/selectors/README.md
@@ -1,11 +1,13 @@
rust-selectors
==============

* [Documentation](https://docs.rs/selectors)
* [![Build Status](https://travis-ci.com/servo/rust-selectors.svg?branch=master)](
https://travis-ci.com/servo/rust-selectors)
* [Documentation](https://docs.rs/selectors/)
* [crates.io](https://crates.io/crates/selectors)

CSS Selectors library for Rust.
Includes parsing and serialization of selectors,
Includes parsing and serilization of selectors,
as well as matching against a generic tree of elements.
Pseudo-elements and most pseudo-classes are generic as well.

Expand Down
25 changes: 9 additions & 16 deletions components/selectors/attr.rs
Expand Up @@ -5,19 +5,16 @@
use crate::parser::SelectorImpl;
use cssparser::ToCss;
use std::fmt;
#[cfg(feature = "shmem")]
use to_shmem_derive::ToShmem;

#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[cfg_attr(feature = "shmem", shmem(no_bounds))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
#[shmem(no_bounds)]
pub struct AttrSelectorWithOptionalNamespace<Impl: SelectorImpl> {
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
pub namespace: Option<NamespaceConstraint<(Impl::NamespacePrefix, Impl::NamespaceUrl)>>,
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
pub local_name: Impl::LocalName,
pub local_name_lower: Impl::LocalName,
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
pub operation: ParsedAttrSelectorOperation<Impl::AttrValue>,
}

Expand All @@ -30,17 +27,15 @@ impl<Impl: SelectorImpl> AttrSelectorWithOptionalNamespace<Impl> {
}
}

#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
pub enum NamespaceConstraint<NamespaceUrl> {
Any,

/// Empty string for no namespace
Specific(NamespaceUrl),
}

#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
pub enum ParsedAttrSelectorOperation<AttrValue> {
Exists,
WithValue {
Expand Down Expand Up @@ -80,8 +75,7 @@ impl<AttrValue> AttrSelectorOperation<AttrValue> {
}
}

#[derive(Clone, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Copy, Eq, PartialEq, ToShmem)]
pub enum AttrSelectorOperator {
Equal,
Includes,
Expand Down Expand Up @@ -146,8 +140,7 @@ impl AttrSelectorOperator {
/// The definition of whitespace per CSS Selectors Level 3 § 4.
pub static SELECTOR_WHITESPACE: &[char] = &[' ', '\t', '\n', '\r', '\x0C'];

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, ToShmem)]
pub enum ParsedCaseSensitivity {
/// 's' was specified.
ExplicitCaseSensitive,
Expand Down
2 changes: 2 additions & 0 deletions components/selectors/build.rs
Expand Up @@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

extern crate phf_codegen;

use std::env;
use std::fs::File;
use std::io::{BufWriter, Write};
Expand Down
10 changes: 2 additions & 8 deletions components/selectors/builder.rs
Expand Up @@ -19,16 +19,12 @@

use crate::parser::{Combinator, Component, RelativeSelector, Selector, SelectorImpl};
use crate::sink::Push;
use bitflags::bitflags;
use derive_more::{Add, AddAssign};
use servo_arc::{Arc, HeaderWithLength, ThinArc};
use smallvec::{self, SmallVec};
use std::cmp;
use std::iter;
use std::ptr;
use std::slice;
#[cfg(feature = "shmem")]
use to_shmem_derive::ToShmem;

/// Top-level SelectorBuilder struct. This should be stack-allocated by the
/// consumer and never moved (because it contains a lot of inline data that
Expand Down Expand Up @@ -182,8 +178,7 @@ fn split_from_end<T>(s: &[T], at: usize) -> (&[T], &[T]) {

bitflags! {
/// Flags that indicate at which point of parsing a selector are we.
#[derive(Default)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Default, ToShmem)]
pub (crate) struct SelectorFlags : u8 {
const HAS_PSEUDO = 1 << 0;
const HAS_SLOTTED = 1 << 1;
Expand All @@ -192,8 +187,7 @@ bitflags! {
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, ToShmem)]
pub struct SpecificityAndFlags {
/// There are two free bits here, since we use ten bits for each specificity
/// kind (id, class, element).
Expand Down
19 changes: 19 additions & 0 deletions components/selectors/lib.rs
Expand Up @@ -5,6 +5,25 @@
// Make |cargo bench| work.
#![cfg_attr(feature = "bench", feature(test))]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate cssparser;
#[macro_use]
extern crate debug_unreachable;
#[macro_use]
extern crate derive_more;
extern crate fxhash;
#[macro_use]
extern crate log;
extern crate phf;
extern crate precomputed_hash;
extern crate servo_arc;
extern crate smallvec;
extern crate to_shmem;
#[macro_use]
extern crate to_shmem_derive;

pub mod attr;
pub mod bloom;
mod builder;
Expand Down
2 changes: 0 additions & 2 deletions components/selectors/matching.rs
Expand Up @@ -15,8 +15,6 @@ use crate::parser::{
};
use crate::tree::Element;
use bitflags::bitflags;
use debug_unreachable::debug_unreachable;
use log::debug;
use smallvec::SmallVec;
use std::borrow::Borrow;
use std::iter;
Expand Down
61 changes: 22 additions & 39 deletions components/selectors/parser.rs
Expand Up @@ -14,21 +14,17 @@ use crate::sink::Push;
use crate::visitor::SelectorListKind;
pub use crate::visitor::SelectorVisitor;
use bitflags::bitflags;
use cssparser::{match_ignore_ascii_case, parse_nth};
use cssparser::parse_nth;
use cssparser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind};
use cssparser::{CowRcStr, Delimiter, SourceLocation};
use cssparser::{Parser as CssParser, ToCss, Token};
use debug_unreachable::debug_unreachable;
use precomputed_hash::PrecomputedHash;
use servo_arc::{HeaderWithLength, ThinArc, UniqueArc};
use size_of_test::size_of_test;
use smallvec::SmallVec;
use std::borrow::{Borrow, Cow};
use std::fmt::{self, Debug};
use std::iter::Rev;
use std::slice;
#[cfg(feature = "shmem")]
use to_shmem_derive::ToShmem;

/// A trait that represents a pseudo-element.
pub trait PseudoElement: Sized + ToCss {
Expand Down Expand Up @@ -168,8 +164,6 @@ impl SelectorParsingState {

pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>;

size_of_test!(SelectorParseError, 48);

#[derive(Clone, Debug, PartialEq)]
pub enum SelectorParseErrorKind<'i> {
NoQualifiedNameInAttributeSelector(Token<'i>),
Expand All @@ -194,8 +188,6 @@ pub enum SelectorParseErrorKind<'i> {
ClassNeedsIdent(Token<'i>),
}

size_of_test!(SelectorParseErrorKind, 40);

macro_rules! with_all_bounds {
(
[ $( $InSelector: tt )* ]
Expand Down Expand Up @@ -298,9 +290,6 @@ pub trait Parser<'i> {
true
}

/// Parses non-tree-structural pseudo-classes. Tree structural pseudo-classes,
/// like `:first-child`, are built into this library.
///
/// This function can return an "Err" pseudo-element in order to support CSS2.1
/// pseudo-elements.
fn parse_non_ts_pseudo_class(
Expand Down Expand Up @@ -363,11 +352,10 @@ pub trait Parser<'i> {
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[cfg_attr(feature = "shmem", shmem(no_bounds))]
#[derive(Clone, Debug, Eq, PartialEq, ToShmem)]
#[shmem(no_bounds)]
pub struct SelectorList<Impl: SelectorImpl>(
#[cfg_attr(feature = "shmem", shmem(field_bound))] pub SmallVec<[Selector<Impl>; 1]>,
#[shmem(field_bound)] pub SmallVec<[Selector<Impl>; 1]>,
);

/// Whether or not we're using forgiving parsing mode
Expand Down Expand Up @@ -643,12 +631,10 @@ pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl {
///
/// This reordering doesn't change the semantics of selector matching, and we
/// handle it in to_css to make it invisible to serialization.
#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[cfg_attr(feature = "shmem", shmem(no_bounds))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
#[shmem(no_bounds)]
pub struct Selector<Impl: SelectorImpl>(
#[cfg_attr(feature = "shmem", shmem(field_bound))]
ThinArc<SpecificityAndFlags, Component<Impl>>,
#[shmem(field_bound)] ThinArc<SpecificityAndFlags, Component<Impl>>,
);

impl<Impl: SelectorImpl> Selector<Impl> {
Expand Down Expand Up @@ -1299,8 +1285,7 @@ impl<'a, Impl: SelectorImpl> Iterator for AncestorIter<'a, Impl> {
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, ToShmem)]
pub enum Combinator {
Child, // >
Descendant, // space
Expand Down Expand Up @@ -1541,10 +1526,10 @@ impl CombinatorComposition {
for combinator in CombinatorIter::new(inner_selector.iter_skip_relative_selector_anchor()) {
match combinator {
Combinator::Descendant | Combinator::Child => {
result.insert(CombinatorComposition::DESCENDANTS);
result.insert(Self::DESCENDANTS);
},
Combinator::NextSibling | Combinator::LaterSibling => {
result.insert(CombinatorComposition::SIBLINGS);
result.insert(Self::SIBLINGS);
},
Combinator::Part | Combinator::PseudoElement | Combinator::SlotAssignment => {
continue
Expand Down Expand Up @@ -1637,25 +1622,24 @@ impl<Impl: SelectorImpl> RelativeSelector<Impl> {
/// optimal packing and cache performance, see [1].
///
/// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1357973
#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[cfg_attr(feature = "shmem", shmem(no_bounds))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
#[shmem(no_bounds)]
pub enum Component<Impl: SelectorImpl> {
LocalName(LocalName<Impl>),

ID(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::Identifier),
Class(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::Identifier),
ID(#[shmem(field_bound)] Impl::Identifier),
Class(#[shmem(field_bound)] Impl::Identifier),

AttributeInNoNamespaceExists {
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
local_name: Impl::LocalName,
local_name_lower: Impl::LocalName,
},
// Used only when local_name is already lowercase.
AttributeInNoNamespace {
local_name: Impl::LocalName,
operator: AttrSelectorOperator,
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
value: Impl::AttrValue,
case_sensitivity: ParsedCaseSensitivity,
},
Expand All @@ -1680,7 +1664,7 @@ pub enum Component<Impl: SelectorImpl> {
ParentSelector,
Nth(NthSelectorData),
NthOf(NthOfSelectorData<Impl>),
NonTSPseudoClass(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::NonTSPseudoClass),
NonTSPseudoClass(#[shmem(field_bound)] Impl::NonTSPseudoClass),
/// The ::slotted() pseudo-element:
///
/// https://drafts.csswg.org/css-scoping/#slotted-pseudo
Expand All @@ -1695,7 +1679,7 @@ pub enum Component<Impl: SelectorImpl> {
Slotted(Selector<Impl>),
/// The `::part` pseudo-element.
/// https://drafts.csswg.org/css-shadow-parts/#part
Part(#[cfg_attr(feature = "shmem", shmem(field_bound))] Box<[Impl::Identifier]>),
Part(#[shmem(field_bound)] Box<[Impl::Identifier]>),
/// The `:host` pseudo-class:
///
/// https://drafts.csswg.org/css-scoping/#host-selector
Expand Down Expand Up @@ -1726,7 +1710,7 @@ pub enum Component<Impl: SelectorImpl> {
/// Same comment as above re. the argument.
Has(Box<[RelativeSelector<Impl>]>),
/// An implementation-dependent pseudo-element selector.
PseudoElement(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::PseudoElement),
PseudoElement(#[shmem(field_bound)] Impl::PseudoElement),

Combinator(Combinator),

Expand Down Expand Up @@ -1886,11 +1870,10 @@ impl<Impl: SelectorImpl> Component<Impl> {
}
}

#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(feature = "shmem", derive(ToShmem))]
#[cfg_attr(feature = "shmem", shmem(no_bounds))]
#[derive(Clone, Eq, PartialEq, ToShmem)]
#[shmem(no_bounds)]
pub struct LocalName<Impl: SelectorImpl> {
#[cfg_attr(feature = "shmem", shmem(field_bound))]
#[shmem(field_bound)]
pub name: Impl::LocalName,
pub lower_name: Impl::LocalName,
}
Expand Down
1 change: 0 additions & 1 deletion components/selectors/visitor.rs
Expand Up @@ -8,7 +8,6 @@

use crate::attr::NamespaceConstraint;
use crate::parser::{Combinator, Component, Selector, SelectorImpl};
use bitflags::bitflags;

/// A trait to visit selector properties.
///
Expand Down