stylo: properly handle ::before/::after rules applying to replaced elements.

Bug: 1376352
Reviewed-By: heycam
MozReview-Commit-ID: FO0TyWsPPG7
This commit is contained in:
Emilio Cobos Álvarez 2017-07-03 09:39:46 +02:00
parent 990c4091fe
commit e2bf7d037a
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C

View file

@ -1576,23 +1576,30 @@ pub trait MatchMethods : TElement {
} }
if pseudo.map_or(false, |p| p.is_before_or_after()) { if pseudo.map_or(false, |p| p.is_before_or_after()) {
if (old_style_is_display_none || let old_style_generates_no_pseudo =
old_values.ineffective_content_property()) && old_style_is_display_none ||
(new_style_is_display_none || old_values.ineffective_content_property();
new_values.ineffective_content_property()) {
// The pseudo-element will remain undisplayed, so just avoid let new_style_generates_no_pseudo =
// triggering any change. new_style_is_display_none ||
return StyleDifference::new(RestyleDamage::empty(), StyleChange::Unchanged) new_values.ineffective_content_property();
if old_style_generates_no_pseudo != new_style_generates_no_pseudo {
return StyleDifference::new(RestyleDamage::reconstruct(), StyleChange::Changed)
} }
// FIXME(bz): This will keep reframing replaced elements. Do we
// need this at all? Seems like if we add/remove ::before or // The pseudo-element will remain undisplayed, so just avoid
// ::after styles we would get reframed over in match_pseudos and if // triggering any change.
// that part didn't change and we had no frame for the //
// ::before/::after then we don't care. Need to double-check that // NOTE(emilio): We will only arrive here for pseudo-elements that
// we handle the "content" and "display" properties changing // aren't generated (see the is_existing_before_or_after check in
// correctly, though. // accumulate_damage).
// https://bugzilla.mozilla.org/show_bug.cgi?id=1376352 //
return StyleDifference::new(RestyleDamage::reconstruct(), StyleChange::Changed) // However, it may be the case that the style of this element would
// make us think we need a pseudo, but we don't, like for pseudos in
// replaced elements, that's why we need the old != new instead of
// just check whether the new style would generate a pseudo.
return StyleDifference::new(RestyleDamage::empty(), StyleChange::Unchanged)
} }
if pseudo.map_or(false, |p| p.is_first_letter()) { if pseudo.map_or(false, |p| p.is_first_letter()) {