Closed
Bug 1376073
Opened 6 years ago
Closed 6 years ago
stylo: We reframe too eagerly for ::before/::after
Categories
(Core :: CSS Parsing and Computation, enhancement)
Tracking
()
RESOLVED
FIXED
mozilla56
Tracking | Status | |
---|---|---|
firefox56 | --- | fixed |
People
(Reporter: bzbarsky, Assigned: bzbarsky)
References
Details
Attachments
(1 file)
The layout/base/tests/test_frame_reconstruction_for_pseudo_elements.html mochitest catches this. Simple testcase: <style> .x::before { color: green; } </style> <span onclick="this.className = 'x'">Some text; click me to reframe</span> What happens is that in match_pseudos (matching.rs) we discover we have rules for the pseudo and do: matches_different_pseudos |= !data.styles.pseudos.has(&pseudo); ... if matches_different_pseudos && data.restyle.is_restyle() { // Any changes to the matched pseudo-elements trigger // reconstruction. data.restyle.damage |= RestyleDamage::reconstruct(); which is not needed in this case, because the ::before has "content: none" and hence doesn't actually render in any way. I wonder whether we can just stop reframing here for ::before/::after and rely on compute_style_difference() triggering reframes as needed or something.
Comment 1•6 years ago
|
||
Hmm... I guess so, yeah. We only arrive there when there's an old pseudo-style right now, but we can probably massage a little the logic there to make it more general.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
![]() |
Assignee | |
Updated•6 years ago
|
Assignee: nobody → bzbarsky
Comment 5•6 years ago
|
||
mozreview-review |
Comment on attachment 8891421 [details] Bug 1376073. Don't reframe when going from no pseudo to pseudo with no content for ::before and ::after. https://reviewboard.mozilla.org/r/162582/#review167988 Mostly semi-opinionated nits, feel free to address as you wish. It'd be nice to extend `layout/style/test/test_reframe_pseudo_element.html` to exercise this case, and shouldn't be too hard. ::: servo/components/style/matching.rs:550 (Diff revision 3) > + // It's possible that we're switching from not having > + // ::before/::after at all to having styles for them but not > + // actually having a useful pseudo-element. Check for that > + // case. > + let pseudo = PseudoElement::from_eager_index(i); > + if old.as_ref().map_or(false, nit: do you think this would benefit from splitting it in two different variables? ``` let new_pseudo_should_exist = ...; let old_pseudo_should_exist = ...; if new_pseudo_should_exist != new_pseudo_should_exist { // ... ``` ::: servo/components/style/matching.rs:802 (Diff revision 3) > > if pseudo.map_or(false, |p| p.is_before_or_after()) { > + // FIXME(bz) This duplicates some of the logic in > + // PseudoElement::should_exist, but it's not clear how best to share > + // that logic without redoing the "get the display" work. > let old_style_generates_no_pseudo = (I think getting the display value again is not a big deal, but your call) ::: servo/components/style/servo/selector_parser.rs:197 (Diff revision 3) > None > } > + > + /// Whether this pseudo-element should actually exist if it has > + /// the given styles. > + pub fn should_exist(&self, nit: This fits in the same line: ``` pub fn should_exist(&self, style: &ComputedValues) -> bool { ``` ::: servo/components/style/servo/selector_parser.rs:201 (Diff revision 3) > + /// the given styles. > + pub fn should_exist(&self, > + style: &ComputedValues) > + { > + let display = style.get_box().clone_display(); > + display != display::T::none && Do you think this would be clearer (even if slightly longer) written like: ``` if display == display::T::none { return false; } if pseudo.is_before_or_after() && style.ineffective_content_property() { return false; } true ``` Seems slightly easier to extend if needed. But not a big deal anyway.
Attachment #8891421 -
Flags: review?(emilio+bugs) → review+
![]() |
Assignee | |
Comment 6•6 years ago
|
||
mozreview-review-reply |
Comment on attachment 8891421 [details] Bug 1376073. Don't reframe when going from no pseudo to pseudo with no content for ::before and ::after. https://reviewboard.mozilla.org/r/162582/#review167988 Yeah, I'll give extending that a shot. > nit: do you think this would benefit from splitting it in two different variables? > > ``` > let new_pseudo_should_exist = ...; > let old_pseudo_should_exist = ...; > > if new_pseudo_should_exist != new_pseudo_should_exist { > // ... > ``` Yeah, probably a good idea. Done. > (I think getting the display value again is not a big deal, but your call) I'm really not sure how hot this various code is and how slow the readback from the Gecko struct is... > nit: This fits in the same line: > > ``` > pub fn should_exist(&self, style: &ComputedValues) -> bool { > ``` Done. > Do you think this would be clearer (even if slightly longer) written like: > > ``` > if display == display::T::none { > return false; > } > > if pseudo.is_before_or_after() && style.ineffective_content_property() { > return false; > } > > true > ``` > > Seems slightly easier to extend if needed. But not a big deal anyway. I went back and forth a few times here. I guess it probably is clearer like that, will change it to that.
![]() |
Assignee | |
Comment 7•6 years ago
|
||
https://github.com/servo/servo/pull/17909
![]() |
Assignee | |
Comment 8•6 years ago
|
||
mozreview-review-reply |
Comment on attachment 8891421 [details] Bug 1376073. Don't reframe when going from no pseudo to pseudo with no content for ::before and ::after. https://reviewboard.mozilla.org/r/162582/#review167988 Oh, actually, this case is already exercised by layout/base/tests/test_frame_reconstruction_for_pseudo_elements.html which we're failing without this patch. So not going to worry about the test bit.
![]() |
Assignee | |
Comment 9•6 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/a2cb823abab5c8c14b4a25c58b6ed5fa398b371b
![]() |
||
Comment 10•6 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/a2cb823abab5
Status: NEW → RESOLVED
Closed: 6 years ago
status-firefox56:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
You need to log in
before you can comment on or make changes to this bug.
Description
•