Closed Bug 1926164 Opened 1 year ago Closed 1 year ago

CSS styles under :not(:not(:x-of-type)) does not apply unless "flushed"

Categories

(Core :: CSS Parsing and Computation, defect)

Firefox 128
defect

Tracking

()

RESOLVED FIXED
133 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr128 --- fixed
firefox131 --- wontfix
firefox132 --- wontfix
firefox133 --- fixed

People

(Reporter: ed7-aspire4925, Assigned: zrhoffman)

References

(Regression)

Details

(Keywords: regression)

Attachments

(3 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Firefox for Android

Steps to reproduce:

  1. On a fresh instance, open: https://ed7n.github.io/net-viewer
  2. Toggle the menu item: View -> Controls
  3. Resize the viewport to toggle between desktop and mobile modes.

Actual results:

  1. The control panel does not disappear on startup.
  2. Toggling said menu item does not affect the visibility of the panel.
  3. Resizing the viewport fixes the issue, and it persists when resizing back.

Expected results:

  1. The control panel should disappear on startup.
  2. Toggling said menu item should affect the visibility of the panel.

The CSS definition of interest:

article.no-panels
  > section:not(:first-of-type):not(:last-of-type)
  > section:not(:not(:first-of-type):not(:last-of-type)) {
  display: none;
}

The Controls menu item toggles the .no-panels class in the article element.

In addition to resizing the viewport to toggle the CSS media rules,
if one were to duplicate the above definition with the Style Editor, then the style applies as it should.

It seems that the style is applied only if some sort of style cache is rebuilt.

Summary: css selector → CSS styles under :not(:not(:x-of-type)) does not apply unless "flushed"

For reference, the behavior is correct as of Chromium, Version 129.0.6668.100 (Official Build, ungoogled-chromium) (64-bit).

For reference:

  • The behavior is likewise incorrect on Fennec F-Droid, 129.0.2 (Built #1290220).
  • The behavior is correct on Chromium, Version 129.0.6668.100 (Official Build, ungoogled-chromium) (64-bit).
  • The behavior is correct on Android System WebView, 129.0.6668.100.
Status: UNCONFIRMED → NEW
Component: Untriaged → CSS Parsing and Computation
Ever confirmed: true
Keywords: regression
Product: Firefox → Core
Regressed by: 1837351

Set release status flags based on info from the regressing bug 1837351

:zrhoffman, since you are the author of the regressor, bug 1837351, could you take a look?

For more information, please visit BugBot documentation.

Attached file testcase (obsolete) —

Thanks for pointing to the problematic CSS selector, it made coming up with a reduced testcase much easier!

Confirmed that commenting out the if statement that skips positional pseudo-class matching during invalidation (https://searchfox.org/mozilla-central/rev/faa7b1b2a7b5/servo/components/selectors/matching.rs#1311-1318) makes the testcase work as expected (with a significant performance cost).

David has significantly improved positional pseudo-class invalidation and expanded on that check more recently than bug 1837351. David, do you know what's making invalidation fail in bug 1926164? :)

Flags: needinfo?(zach) → needinfo?(dshin)
Attached file 1926164-testcase.html

Added a testcase with more delay to keep the testcase from being intermittent.

Attachment #9432448 - Attachment is obsolete: true

Hrm, that's unfortunate.
In the context of invalidation, we pretend these indexed selectors always match, so that the invalidation machinery just marks them for invalidation without doing expensive indexing math (At the cost of over-invalidation).
We account for :not by flipping the result so that it returns True in the context outside of that negation. The problem is of course there being another negation, which flips the result to False and we skip invalidating it.
For these selectors, we need :not(:not(<...>:first-of-type<..>)) to return matching regardless of the depth of nesting.
This sliped through because we only do matching with potential unknown results when we move on invalidating from an inner selector to an outer selector e.g. In .foo :is(.bar .baz) .baa:first-of-type, we invalidate on .bar class change down to .baz, then check to see if the outer selector's matching result changes.

EDIT: Whoops, I put one too many :not there to make it work. Basically, nesting odd numbers of :not will make it work, even numbers will not.

Flags: needinfo?(dshin)
Severity: -- → S3

(In reply to David Shin[:dshin] from comment #8)

Basically, nesting odd numbers of :not will make it work, even numbers will not.

Yep you are right, hard-coding in_negation as true was breaking invalidation. https://searchfox.org/mozilla-central/rev/6ec81d7b1d2f/servo/components/selectors/context.rs#365

Patch incoming...

in_negation was true in cases where it should be false, like
:not(:not(...)).

Assignee: nobody → zach
Status: NEW → ASSIGNED
Pushed by zach@zrhoffman.net: https://hg.mozilla.org/integration/autoland/rev/ecd7dce029ce Negate in_negation when nesting r=dshin,jwatt
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/48823 for changes under testing/web-platform/tests
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 133 Branch
Flags: in-testsuite+
Upstream PR merged by moz-wptsync-bot
Upstream PR merged by moz-wptsync-bot

Is this worth an ESR128 uplift? Not sure how common this is in the wild.

Flags: needinfo?(zach)

(In reply to Ryan VanderMeulen [:RyanVM] from comment #16)

Is this worth an ESR128 uplift? Not sure how common this is in the wild.

Not sure how common it is in the wild, but because the fix is so trivial, it wouldn't hurt.

Flags: needinfo?(zach)

Comment on attachment 9432720 [details]
Bug 1926164 - Negate in_negation when nesting r=dshin,#style

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: One-liner fix.
  • User impact if declined: comment 0
  • Fix Landed on Version: 133
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Trivial fix.
Attachment #9432720 - Flags: approval-mozilla-esr128?

Comment on attachment 9432720 [details]
Bug 1926164 - Negate in_negation when nesting r=dshin,#style

Approved for 128.6esr.

Attachment #9432720 - Flags: approval-mozilla-esr128? → approval-mozilla-esr128+
See Also: → 1964575
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: