commit | 02ef73f562659ed4df9fbf54d2733f43aeb71c5b | [log] [tgz] |
---|---|---|
author | Byungwoo Lee <blee@igalia.com> | Fri Oct 21 13:14:16 2022 |
committer | Blink WPT Bot <blink-w3c-test-autoroller@chromium.org> | Fri Oct 21 13:21:02 2022 |
tree | 62c3d2d706183f16a99dfb20ea9dff9759ac5681 | |
parent | 053b74dd29da1e75b0ab96dedcded9187c50eede [diff] |
Fix :has() invalidation error when removing an element The InvalidateAncestorsOrSiblingsAffectedByHas(<parent>, <previous- sibling>, <flag-for-pseudo-change>) method doesn't traverse to ancestors for a removed element even if the removed element can affect the :has() state of a :has() anchor element. These are more specific conditions of the case: - there is only one :has() pseudo class (has-child or has-descendant relationship) that is tested on the :has() anchor element, - and the :has() anchor element matched the :has() pseudo class from the initial style calculation - and the removed element has a previous sibling element. The reason of this bug is the lack of cohesiveness of the logic that determines the traversal direction for :has() invalidation. The method gets the :has() invalidation traversal direction from the affected-by flags (AncestorsOrAncestorSiblingsAffectedByHas, SiblingsAffectedByHas) of the <previous-sibling> element and starts the traversal from the element if the <previous-sibling> is not null. This is based on the assumption that, the previous sibling element of the mutated element will have the affected-by flags set if the previous sibling is in the :has() argument testing traversal range. The assumption is true when the :has() pseudo class have tested on the :has() anchor element but it didn't matched before, because the SelectorChecker marks the flags of all the elements in the :has() argument testing traversal range while testing the :has() argument. But the assumption cannot be true when the :has() pseudo class have tested and matched on the :has() anchor element, because the SelectorChecker stops the :has() argument testing traversal at the first :has() argument matched element. So, the previous sibling of the :has() argument matched element doesn't have the flags set. Currently, the has-descendant relationship invalidation for an attribute change or pseudo state change works well on the :has() argument matched element even if the element has a previous sibling and the previous sibling doesn't have the AncestorsOrAncestorSiblingsAffectedByHas flag set. It is because of the conditional argument passing logic in the Invalidate...AffectedByHas(<changed-element>) method. The method calls the Invalidate...AffectedByHas(<parent>, <previous-sibling>) with nullptr as the <previous-sibling> if the <changed-element> doesn't have the SiblingsAffectedByHas flags set. When the <previous-sibling> is nullptr, the Invalidate...AffectedByHas(<parent>, <previous- sibling>, <flag-for-pseudo-change>) method can get the AncestorsOrAncestorSiblingsAffectedByHas flag from the <parent>. The problem is that, for insertion or removal, StyleEngine calls the Invalidate...AffectedByHas(<parent>, <previous-sibling>) without the conditional argument passing logic. So even if the parent has the Ancestors...AffectedByHas flag set, the Invalidate...AffectedByHas( <parent>, <previous-sibling>, <flag-for-pseudo-change>) method determines the ancestor traversal direction from the flag of the <previous-sibling>. In case that the <previous-sibling> doesn't have the flag set, the method will not traverse to ancestors. This CL added PseudoHasInvalidationTraversalContext class in StyleEngine so that these logic can be collected within the class: - logic of determining the :has() invalidation traversal direction - logic of getting the first element of the traversal To remove unnecessary method overloading, this is moved to the context class: - functionality of passing the flag of indicating whether the :has() invalidation is only for the pseudo state change or for all mutation types To fix the bug, this CL adds the missing logic of determining the traversal direction for the insertion and removal: - Determine the ancestor traversal direction from the flag of <parent> for insertion or removing all children. - Determine the ancestor traversal direction from the flag of <removed-element> for removal The missing tests are also added: - unittest to check affected-by flags after removal - web test to check :has() invalidation after removing non-first element. Bug: 1375248 Change-Id: Ia08bcdfaadf6e8a2973b1b4ba6b640d51e56516c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3960181 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Byungwoo Lee <blee@igalia.com> Cr-Commit-Position: refs/heads/main@{#1062093}
The web-platform-tests Project is a cross-browser test suite for the Web-platform stack. Writing tests in a way that allows them to be run in all browsers gives browser projects confidence that they are shipping software that is compatible with other implementations, and that later implementations will be compatible with their implementations. This in turn gives Web authors/developers confidence that they can actually rely on the Web platform to deliver on the promise of working across browsers and devices without needing extra layers of abstraction to paper over the gaps left by specification editors and implementors.
The most important sources of information and activity are:
wpt:matrix.org
matrix channel; includes participants located around the world, but busiest during the European working day.If you'd like clarification about anything, don't hesitate to ask in the chat room or on the mailing list.
Clone or otherwise get https://github.com/web-platform-tests/wpt.
Note: because of the frequent creation and deletion of branches in this repo, it is recommended to “prune” stale branches when fetching updates, i.e. use git pull --prune
(or git fetch -p && git merge
).
See the documentation website and in particular the system setup for running tests locally.
The wpt
command provides a frontend to a variety of tools for working with and running web-platform-tests. Some of the most useful commands are:
wpt serve
- For starting the wpt http serverwpt run
- For running tests in a browserwpt lint
- For running the lint against all testswpt manifest
- For updating or generating a MANIFEST.json
test manifestwpt install
- For installing the latest release of a browser or webdriver server on the local machine.wpt serve-wave
- For starting the wpt http server and the WAVE test runner. For more details on how to use the WAVE test runner see the documentation.On Windows wpt
commands must be prefixed with python
or the path to the python binary (if python
is not in your %PATH%
).
python wpt [command]
Alternatively, you may also use Bash on Ubuntu on Windows in the Windows 10 Anniversary Update build, then access your windows partition from there to launch wpt
commands.
Please make sure git and your text editor do not automatically convert line endings, as it will cause lint errors. For git, please set git config core.autocrlf false
in your working tree.
The master branch is automatically synced to wpt.live and w3c-test.org.
Save the Web, Write Some Tests!
Absolutely everyone is welcome to contribute to test development. No test is too small or too simple, especially if it corresponds to something for which you've noted an interoperability bug in a browser.
The way to contribute is just as usual:
git checkout -b topic
../wpt lint
as described above.If you spot an issue with a test and are not comfortable providing a pull request per above to fix it, please file a new issue. Thank you!