Skip to content

Commit 4dfd341

Browse files
author
agoloman
committed
Revert "Bug 1954142 - Fix StyleResolve to account for element-backed pseudo elements; r=emilio" for causing multiple wr failures.
This reverts commit d504988. Revert "Bug 1980215 - Support parsing of `::before::marker`,`::after::marker` r=emilio,firefox-style-system-reviewers" This reverts commit 4eebc17.
1 parent e5739ec commit 4dfd341

File tree

8 files changed

+91
-217
lines changed

8 files changed

+91
-217
lines changed

selectors/parser.rs

Lines changed: 13 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,12 @@ pub trait PseudoElement: Sized + ToCss {
4747
false
4848
}
4949

50-
/// Whether this pseudo-element is valid when directly after a ::before/::after pseudo.
51-
fn valid_after_before_or_after(&self) -> bool {
52-
false
53-
}
54-
5550
/// Whether this pseudo-element is element-backed.
5651
/// https://drafts.csswg.org/css-pseudo-4/#element-like
5752
fn is_element_backed(&self) -> bool {
5853
false
5954
}
6055

61-
/// Whether this pseudo-element is ::before or ::after pseudo element,
62-
/// which are treated specially when deciding what can come after them.
63-
/// https://drafts.csswg.org/css-pseudo-4/#generated-content
64-
fn is_before_or_after(&self) -> bool {
65-
false
66-
}
67-
6856
/// The count we contribute to the specificity from this pseudo-element.
6957
fn specificity_count(&self) -> u32 {
7058
1
@@ -141,30 +129,32 @@ bitflags! {
141129
/// disallowed. If this flag is set, `AFTER_NON_ELEMENT_BACKED_PSEUDO` must be set
142130
/// as well.
143131
const AFTER_NON_STATEFUL_PSEUDO_ELEMENT = 1 << 4;
144-
// Whether we've parsed a generated pseudo-element (as in ::before, ::after).
145-
// If so then some other pseudo elements are disallowed (e.g. another generated pseudo)
146-
// while others allowed (e.g. ::marker).
147-
const AFTER_BEFORE_OR_AFTER_PSEUDO = 1 << 5;
148132

149133
/// Whether we are after any of the pseudo-like things.
150-
const AFTER_PSEUDO = Self::AFTER_PART_LIKE.bits() | Self::AFTER_SLOTTED.bits() | Self::AFTER_NON_ELEMENT_BACKED_PSEUDO.bits() | Self::AFTER_BEFORE_OR_AFTER_PSEUDO.bits();
134+
const AFTER_PSEUDO = Self::AFTER_PART_LIKE.bits() | Self::AFTER_SLOTTED.bits() | Self::AFTER_NON_ELEMENT_BACKED_PSEUDO.bits();
151135

152136
/// Whether we explicitly disallow combinators.
153-
const DISALLOW_COMBINATORS = 1 << 6;
137+
const DISALLOW_COMBINATORS = 1 << 5;
154138

155139
/// Whether we explicitly disallow pseudo-element-like things.
156-
const DISALLOW_PSEUDOS = 1 << 7;
140+
const DISALLOW_PSEUDOS = 1 << 6;
157141

158142
/// Whether we explicitly disallow relative selectors (i.e. `:has()`).
159-
const DISALLOW_RELATIVE_SELECTOR = 1 << 8;
143+
const DISALLOW_RELATIVE_SELECTOR = 1 << 7;
160144

161145
/// Whether we've parsed a pseudo-element which is in a pseudo-element tree (i.e. it is a
162146
/// descendant pseudo of a pseudo-element root).
163-
const IN_PSEUDO_ELEMENT_TREE = 1 << 9;
147+
const IN_PSEUDO_ELEMENT_TREE = 1 << 8;
164148
}
165149
}
166150

167151
impl SelectorParsingState {
152+
#[inline]
153+
fn allows_pseudos(self) -> bool {
154+
// NOTE(emilio): We allow pseudos after ::part and such.
155+
!self.intersects(Self::AFTER_NON_ELEMENT_BACKED_PSEUDO | Self::DISALLOW_PSEUDOS)
156+
}
157+
168158
#[inline]
169159
fn allows_slotted(self) -> bool {
170160
!self.intersects(Self::AFTER_PSEUDO | Self::DISALLOW_PSEUDOS)
@@ -938,32 +928,6 @@ impl<Impl: SelectorImpl> Selector<Impl> {
938928
None
939929
}
940930

941-
#[inline]
942-
pub fn pseudo_elements(&self) -> SmallVec<[&Impl::PseudoElement; 3]> {
943-
let mut pseudos = SmallVec::new();
944-
945-
if !self.has_pseudo_element() {
946-
return pseudos;
947-
}
948-
949-
let mut iter = self.iter();
950-
loop {
951-
for component in &mut iter {
952-
if let Component::PseudoElement(ref pseudo) = *component {
953-
pseudos.push(pseudo);
954-
}
955-
}
956-
match iter.next_sequence() {
957-
Some(Combinator::PseudoElement) => {},
958-
_ => break,
959-
}
960-
}
961-
962-
debug_assert!(!pseudos.is_empty(), "has_pseudo_element lied!");
963-
964-
pseudos
965-
}
966-
967931
/// Whether this selector (pseudo-element part excluded) matches every element.
968932
///
969933
/// Used for "pre-computed" pseudo-elements in components/style/stylist.rs
@@ -2808,7 +2772,6 @@ where
28082772
if state.intersects(SelectorParsingState::AFTER_PSEUDO) {
28092773
debug_assert!(state.intersects(
28102774
SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO |
2811-
SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO |
28122775
SelectorParsingState::AFTER_SLOTTED |
28132776
SelectorParsingState::AFTER_PART_LIKE
28142777
));
@@ -3347,9 +3310,6 @@ where
33473310
state.insert(SelectorParsingState::AFTER_PART_LIKE);
33483311
} else {
33493312
state.insert(SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO);
3350-
if p.is_before_or_after() {
3351-
state.insert(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO);
3352-
}
33533313
}
33543314
if !p.accepts_state_pseudo_classes() {
33553315
state.insert(SelectorParsingState::AFTER_NON_STATEFUL_PSEUDO_ELEMENT);
@@ -3592,15 +3552,7 @@ where
35923552
};
35933553
let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
35943554
if is_pseudo_element {
3595-
// Pseudos after pseudo elements are not allowed in some cases:
3596-
// - Some states will disallow pseudos, such as the interiors of
3597-
// :has/:is/:where/:not (DISALLOW_PSEUDOS).
3598-
// - Non-element backed pseudos do not allow other pseudos to follow (AFTER_NON_ELEMENT_BACKED_PSEUDO)...
3599-
// - ... except ::before and ::after, which allow _some_ pseudos.
3600-
if state.intersects(SelectorParsingState::DISALLOW_PSEUDOS)
3601-
|| (state.intersects(SelectorParsingState::AFTER_NON_ELEMENT_BACKED_PSEUDO)
3602-
&& !state.intersects(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO))
3603-
{
3555+
if !state.allows_pseudos() {
36043556
return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
36053557
}
36063558
let pseudo_element = if is_functional {
@@ -3638,12 +3590,6 @@ where
36383590
P::parse_pseudo_element(parser, location, name)?
36393591
};
36403592

3641-
if state.intersects(SelectorParsingState::AFTER_BEFORE_OR_AFTER_PSEUDO) &&
3642-
!pseudo_element.valid_after_before_or_after()
3643-
{
3644-
return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState));
3645-
}
3646-
36473593
if state.intersects(SelectorParsingState::AFTER_SLOTTED) &&
36483594
!pseudo_element.valid_after_slotted()
36493595
{
@@ -3742,8 +3688,6 @@ pub mod tests {
37423688
pub enum PseudoElement {
37433689
Before,
37443690
After,
3745-
Marker,
3746-
DetailsContent,
37473691
Highlight(String),
37483692
}
37493693

@@ -3758,16 +3702,8 @@ pub mod tests {
37583702
true
37593703
}
37603704

3761-
fn valid_after_before_or_after(&self) -> bool {
3762-
matches!(self, Self::Marker)
3763-
}
3764-
3765-
fn is_before_or_after(&self) -> bool {
3766-
matches!(self, Self::Before | Self::After)
3767-
}
3768-
37693705
fn is_element_backed(&self) -> bool {
3770-
matches!(self, Self::DetailsContent)
3706+
true
37713707
}
37723708
}
37733709

@@ -3810,8 +3746,6 @@ pub mod tests {
38103746
match *self {
38113747
PseudoElement::Before => dest.write_str("::before"),
38123748
PseudoElement::After => dest.write_str("::after"),
3813-
PseudoElement::Marker => dest.write_str("::marker"),
3814-
PseudoElement::DetailsContent => dest.write_str("::details-content"),
38153749
PseudoElement::Highlight(ref name) => {
38163750
dest.write_str("::highlight(")?;
38173751
serialize_identifier(&name, dest)?;
@@ -3981,8 +3915,6 @@ pub mod tests {
39813915
match_ignore_ascii_case! { &name,
39823916
"before" => return Ok(PseudoElement::Before),
39833917
"after" => return Ok(PseudoElement::After),
3984-
"marker" => return Ok(PseudoElement::Marker),
3985-
"details-content" => return Ok(PseudoElement::DetailsContent),
39863918
_ => {}
39873919
}
39883920
Err(
@@ -4647,53 +4579,6 @@ pub mod tests {
46474579
assert_eq!(iter.next_sequence(), None);
46484580
}
46494581

4650-
#[test]
4651-
fn test_pseudo_before_marker() {
4652-
let list = parse("::before::marker").unwrap();
4653-
let selector = &list.slice()[0];
4654-
let mut iter = selector.iter();
4655-
assert_eq!(
4656-
iter.next(),
4657-
Some(&Component::PseudoElement(PseudoElement::Marker))
4658-
);
4659-
assert_eq!(iter.next(), None);
4660-
let combinator = iter.next_sequence();
4661-
assert_eq!(combinator, Some(Combinator::PseudoElement));
4662-
assert!(matches!(iter.next(), Some(&Component::PseudoElement(PseudoElement::Before))));
4663-
assert_eq!(iter.next(), None);
4664-
let combinator = iter.next_sequence();
4665-
assert_eq!(combinator, Some(Combinator::PseudoElement));
4666-
assert_eq!(iter.next(), None);
4667-
assert_eq!(iter.next_sequence(), None);
4668-
}
4669-
4670-
#[test]
4671-
fn test_pseudo_duplicate_before_after_or_marker() {
4672-
assert!(parse("::before::before").is_err());
4673-
assert!(parse("::after::after").is_err());
4674-
assert!(parse("::marker::marker").is_err());
4675-
}
4676-
4677-
#[test]
4678-
fn test_pseudo_on_element_backed_pseudo() {
4679-
let list = parse("::details-content::before").unwrap();
4680-
let selector = &list.slice()[0];
4681-
let mut iter = selector.iter();
4682-
assert_eq!(
4683-
iter.next(),
4684-
Some(&Component::PseudoElement(PseudoElement::Before))
4685-
);
4686-
assert_eq!(iter.next(), None);
4687-
let combinator = iter.next_sequence();
4688-
assert_eq!(combinator, Some(Combinator::PseudoElement));
4689-
assert!(matches!(iter.next(), Some(&Component::PseudoElement(PseudoElement::DetailsContent))));
4690-
assert_eq!(iter.next(), None);
4691-
let combinator = iter.next_sequence();
4692-
assert_eq!(combinator, Some(Combinator::PseudoElement));
4693-
assert_eq!(iter.next(), None);
4694-
assert_eq!(iter.next_sequence(), None);
4695-
}
4696-
46974582
#[test]
46984583
fn test_universal() {
46994584
let list = parse_ns(

style/dom.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -751,12 +751,12 @@ pub trait TElement:
751751
/// element-backed pseudo-element, in which case we return the originating
752752
/// element.
753753
fn rule_hash_target(&self) -> Self {
754-
let mut cur = *self;
755-
while cur.is_pseudo_element() {
756-
cur = cur.pseudo_element_originating_element()
754+
if self.is_pseudo_element() {
755+
self.pseudo_element_originating_element()
757756
.expect("Trying to collect rules for a detached pseudo-element")
757+
} else {
758+
*self
758759
}
759-
cur
760760
}
761761

762762
/// Executes the callback for each applicable style rule data which isn't

style/gecko/pseudo_element.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use crate::string_cache::Atom;
1717
use crate::values::serialize_atom_identifier;
1818
use crate::values::AtomIdent;
1919
use cssparser::{ToCss, Parser};
20-
use selectors::parser::PseudoElement as PseudoElementTrait;
2120
use static_prefs::pref;
2221
use std::fmt;
2322
use style_traits::ParseError;
@@ -171,7 +170,7 @@ impl ToCss for PtNameAndClassSelector {
171170
}
172171
}
173172

174-
impl PseudoElementTrait for PseudoElement {
173+
impl ::selectors::parser::PseudoElement for PseudoElement {
175174
type Impl = SelectorImpl;
176175

177176
// ::slotted() should support all tree-abiding pseudo-elements, see
@@ -190,13 +189,6 @@ impl PseudoElementTrait for PseudoElement {
190189
)
191190
}
192191

193-
// ::before/::after should support ::marker, but no others.
194-
// https://drafts.csswg.org/css-pseudo-4/#marker-pseudo
195-
#[inline]
196-
fn valid_after_before_or_after(&self) -> bool {
197-
matches!(*self, Self::Marker)
198-
}
199-
200192
#[inline]
201193
fn accepts_state_pseudo_classes(&self) -> bool {
202194
// Note: if the pseudo element is a descendants of a pseudo element, `only-child` should be
@@ -224,12 +216,6 @@ impl PseudoElementTrait for PseudoElement {
224216
// element, instead of the snapshot containing block.
225217
self.is_named_view_transition() || *self == PseudoElement::DetailsContent
226218
}
227-
228-
/// Whether the current pseudo element is ::before or ::after.
229-
#[inline]
230-
fn is_before_or_after(&self) -> bool {
231-
matches!(*self, PseudoElement::Before | PseudoElement::After)
232-
}
233219
}
234220

235221
impl PseudoElement {
@@ -275,6 +261,12 @@ impl PseudoElement {
275261
matches!(*self, Self::Before | Self::After | Self::Marker)
276262
}
277263

264+
/// Whether the current pseudo element is ::before or ::after.
265+
#[inline]
266+
pub fn is_before_or_after(&self) -> bool {
267+
matches!(*self, Self::Before | Self::After)
268+
}
269+
278270
/// Whether this pseudo-element is the ::before pseudo.
279271
#[inline]
280272
pub fn is_before(&self) -> bool {

0 commit comments

Comments
 (0)