Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[selectors-4] Consider disallowing :scope inside :has() #7211

Closed
byung-woo opened this issue Apr 12, 2022 · 2 comments
Closed

[selectors-4] Consider disallowing :scope inside :has() #7211

byung-woo opened this issue Apr 12, 2022 · 2 comments
Labels
selectors-4 Current Work

Comments

@byung-woo
Copy link
Member

byung-woo commented Apr 12, 2022

:scope inside :has() is related to these two issues:

  • Consider removing the :scope dependency from the relative selectors definition (issue 6399)
  • Consider disallowing the logical combinations pseudo classes inside :has() (issue 6952)

According to the current definition of absolutizing a relative selector using :scope, these 3 selectors are identical.

  • .b:has(.a :scope .c)
  • .b:has(:is(.a :scope) .c)
  • .a .b:has(.c)

As pointed at the previous issues (issue 6399, issue 6952),

  1. :is() inside :has() increases invalidation complexity,
  2. the compound selector in the left side of the :scope inside :has() creates exactly same problem that :is() inside :has() creates,
  3. we don't need to use :scope inside :has() because there can be much simpler expression.

So, it would be better not to use :scope inside :has() when we follow the current spec of absolutizing relative selectors.

Even if we follow the suggestion of (issue 6399), :scope inside :has() will work only when we use it in the snapshot profile.

  • In the style rule, :scope inside :has() will not match any element because any subject element of :has() pseudo class cannot have the root as its descendant or next sibling. (The only possible way is to use :scope with :is() like .a:has(~ :is(:scope > .b) .c))

In the snapshot profile, :scope inside subject :has() will not match any element when we call querySelector(), querySelectorAll(), matches() because the :scope element of the node selector API method call cannot be a descendant or next sibling of the :scope element itself or its descendants. Same with above, the only possible way is to use it with :is().

So, if :is() is disallowed inside :has(), the :scope inside :has() will work only in these usages, but I'm not sure that this is useful in practice.

  • call closest() with a selector using :scope inside subject :has()
    • element.closest(".a:has(:scope ~ .b)")
  • call node selector APIs with a selector using :scope inside non-subject :has()
    • element.querySelectorAll(".a:has(:scope ~ .b) .c")
    • element.querySelector(".a:has(:scope ~ .b) .c")
    • element.matches(".a:has(:scope ~ .b) .c")
    • element.closest(".a:has(:scope ~ .b) .c")

How about avoiding this confusion by disallowing :scope inside :has()?

@jensimmons jensimmons added the selectors-4 Current Work label Apr 21, 2022
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue May 13, 2022
Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
aarongable pushed a commit to chromium/chromium that referenced this issue May 13, 2022
Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue May 13, 2022
Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue May 13, 2022
Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue May 18, 2022
… classes inside :has(), a=testonly

Automatic update from web-platform-tests
Support invalidation for location pseudo classes inside :has()

Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}

--

wpt-commits: 4b68c346624989cf904a632a862fd54520adb1fc
wpt-pr: 34051
@byung-woo
Copy link
Member Author

byung-woo commented May 20, 2022

The issue #6952 seems to converge in the opinion of disallowing nested :has() only.

Based on it, I think it would be desirable to clarify these three issues that are related to each other.

I think that the key point is to resolve the ambiguity between the implicit :has() scope and explicit :scope inside :has(). (described in the #6399)

There can be two options.

Option 1: Accept #7211 (Disallow explicit :scope() inside :has())

It looks simple and clear way to remove the ambiguity. We don't need to think about how the :scope works inside :has(). By banning this, we can simply agree on disallowing :host, :host() and :host-context() inside :has(). (Those can increase complexity of :has() matching/invalidation by expanding the traversal scope to out of the shadow boundary)

The only downside is that we cannot use explicit :scope inside :has().

Option 2: Accept #6399 (Remove :scope dependency from the <relative-selector> definition and allow explicit :scope inside :has())

The only advantage is that we can use :scope inside :has(). (As described at above, it seems only work in selector query for some limited cases)

In this case, to avoid some misunderstanding, we need to clarify that the absolutizing relative-selector doesn't related to the :scope, so the explicit :scope inside :has() will match the same elements as the :scope outside :has(). (At this point, personally I'm confusing whether the :has() is a scoped selector by itself - https://drafts.csswg.org/selectors/#the-scope-pseudo, https://drafts.csswg.org/selectors/#scoped-selector)

About the risk of this option, I don't have any case right now, but I'm not sure that it will not make any tricky issues.

Desired resolution

In my opinion, Option 1 looks better because it is simple and it only limit some rare usages.

Alternative

If the Option 2 is accepted, we need to consider #7212 (disallowing :host) separately.

With the Option 2, the explicit :scope inside :has() doesn't match the :has() scope element (the element affected by :has() state change). So the :scope inside :has() will be available only in the selector query (as described at above).

Based on this, we can think about :host inside :has():

  • Can it be supported with reasonable performance by acceptable effort?

    :host() inside :has() will be only available in the query API. If so, I think it is not difficult. (The problem is on supporting invalidation since we need to cross the shadow boundary)

  • Is there any case having potential security issues?

    It looks not have any specific issue. (:has() inside :host() can have an issue of violating shadow encapsulation, so it was disallowed in Chrome : https://crbug.com/1307281)

  • Does the case have any useful usage?

    I cannot imagine the specific usage that :host() is meaningful only inside :has().

If both not accepted
If both are not accepted (keep the :scope dependency of <relative-selector> and allow explicit :scope), we also need to consider #7212 separately, and this is the difference:

  • Can it be supported with reasonable performance by acceptable effort?

    It will be hard to support invalidation since we need to cross the shadow boundary.

jamienicol pushed a commit to jamienicol/gecko that referenced this issue May 25, 2022
… classes inside :has(), a=testonly

Automatic update from web-platform-tests
Support invalidation for location pseudo classes inside :has()

Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}

--

wpt-commits: 4b68c346624989cf904a632a862fd54520adb1fc
wpt-pr: 34051
@chrishtr
Copy link
Contributor

chrishtr commented Jun 1, 2022

This is a duplicate of #6399, which resolved to remove the special :scope behavior inside of :has.

@chrishtr chrishtr closed this as completed Jun 1, 2022
@astearns astearns removed the Agenda+ label Jun 1, 2022
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 3, 2022
Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
aarongable pushed a commit to chromium/chromium that referenced this issue Jun 3, 2022
Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688773
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1010508}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 3, 2022
Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688773
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1010508}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 3, 2022
Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688773
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1010508}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jun 10, 2022
…licit :scope in :has(), a=testonly

Automatic update from web-platform-tests
Remove 'tentative' from wpt test for explicit :scope in :has()

Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688773
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1010508}

--

wpt-commits: 687d49f633cc46184dd2fcc18a34c04a15d0654c
wpt-pr: 34298
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this issue Oct 14, 2022
Support invalidation for :link, :any-link and :target pseudo class
inside :has().

Invalidation for :visited inside :has() is not needed since :visited
is not matched inside :has() to prevent leaking visitedness.

Ignored invalidation of :scope inside :has() due to an issue in the
csswg-draft.
- w3c/csswg-drafts#7211

Bug: 669058, 1324834
Change-Id: Ice42f0113f0cdc69a8054c2778c9cab3cdd5ef10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645177
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1003038}
NOKEYCHECK=True
GitOrigin-RevId: 1d9eb9e8bb664b1f3117b788f1ab48bcc89648ee
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this issue Oct 14, 2022
Remove 'tentative' from has-argument-with-explicit-scope.tentative.html
according to the issue resolution:
- w3c/csswg-drafts#6399
- w3c/csswg-drafts#7211

Bug: 669058
Change-Id: Iae1946abfb4a5739e95f0b7d90869b6088f87b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688773
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1010508}
NOKEYCHECK=True
GitOrigin-RevId: 496f1a66e6f1f1d4af5f67839fcb94eda6f517cb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants