diff --git a/components/style/gecko/pseudo_element.rs b/components/style/gecko/pseudo_element.rs index 888fdbdc33c7..d768eceffe73 100644 --- a/components/style/gecko/pseudo_element.rs +++ b/components/style/gecko/pseudo_element.rs @@ -77,6 +77,12 @@ impl PseudoElement { matches!(*self, PseudoElement::Before | PseudoElement::After) } + /// Whether this pseudo-element is ::first-letter. + #[inline] + pub fn is_first_letter(&self) -> bool { + *self == PseudoElement::FirstLetter + } + /// Whether this pseudo-element is lazily-cascaded. #[inline] pub fn is_lazy(&self) -> bool { diff --git a/components/style/matching.rs b/components/style/matching.rs index 542bd512a0bc..fd1a9badb489 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -1507,9 +1507,25 @@ pub trait MatchMethods : TElement { // triggering any change. return StyleDifference::new(RestyleDamage::empty(), StyleChange::Unchanged) } + // FIXME(bz): This will keep reframing replaced elements. Do we + // need this at all? Seems like if we add/remove ::before or + // ::after styles we would get reframed over in match_pseudos and if + // that part didn't change and we had no frame for the + // ::before/::after then we don't care. Need to double-check that + // we handle the "content" and "display" properties changing + // correctly, though. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1376352 return StyleDifference::new(RestyleDamage::reconstruct(), StyleChange::Changed) } + if pseudo.map_or(false, |p| p.is_first_letter()) { + // No one cares about this pseudo, and we've checked above that + // we're not switching from a "cares" to a "doesn't care" state + // or vice versa. + return StyleDifference::new(RestyleDamage::empty(), + StyleChange::Unchanged) + } + // Something else. Be conservative for now. warn!("Reframing due to lack of old style source: {:?}, pseudo: {:?}", self, pseudo); diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 235f5fc0f805..9ea3fb4e6c39 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -38,6 +38,7 @@ pub enum PseudoElement { After = 0, Before, Selection, + // If/when :first-letter is added, update is_first_letter accordingly. // Non-eager pseudos. DetailsSummary, DetailsContent, @@ -110,6 +111,12 @@ impl PseudoElement { matches!(*self, PseudoElement::After | PseudoElement::Before) } + /// Whether the current pseudo element is :first-letter + #[inline] + pub fn is_first_letter(&self) -> bool { + false + } + /// Whether this pseudo-element is eagerly-cascaded. #[inline] pub fn is_eager(&self) -> bool {