- Revision
- 286415
- Author
- [email protected]
- Date
- 2021-12-02 00:06:24 -0800 (Thu, 02 Dec 2021)
Log Message
[selectors] :focus-visible should stop matching after blur
https://bugs.webkit.org/show_bug.cgi?id=233688
Reviewed by Antti Koivisto.
LayoutTests/imported/w3c:
Add new test to check that :focus-visible stop matching after blur.
* web-platform-tests/css/selectors/focus-visible-023-expected.txt: Added.
* web-platform-tests/css/selectors/focus-visible-023.html: Added.
Source/WebCore:
Move PseudoClassChangeInvalidation for :focus-visible together with the one for :focus,
as we need to keep both flags in sync when computing the invalidations
(it's not possible to have an element that matches :focus-visible but not :focus,
and that was happening before this change).
Test: imported/w3c/web-platform-tests/css/selectors/focus-visible-023.html
* dom/Element.cpp:
(WebCore::Element::setFocus): Add PseudoClassChangeInvalidation for :focus-visible change,
and put it in the same scope as the flags changes.
(WebCore::Element::setHasFocusVisible): Remove PseudoClassChangeInvalidation from this method.
* page/EventHandler.cpp:
(WebCore::EventHandler::internalKeyEvent): Use PseudoClassChangeInvalidation for :focus-visible change.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (286414 => 286415)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-12-02 06:27:47 UTC (rev 286414)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-12-02 08:06:24 UTC (rev 286415)
@@ -1,3 +1,15 @@
+2021-12-02 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] :focus-visible should stop matching after blur
+ https://bugs.webkit.org/show_bug.cgi?id=233688
+
+ Reviewed by Antti Koivisto.
+
+ Add new test to check that :focus-visible stop matching after blur.
+
+ * web-platform-tests/css/selectors/focus-visible-023-expected.txt: Added.
+ * web-platform-tests/css/selectors/focus-visible-023.html: Added.
+
2021-12-01 Chris Dumez <[email protected]>
validity.valueMissing should not rely on element's disabled state for inputs of type radio/file/checkbox
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023-expected.txt (0 => 286415)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023-expected.txt 2021-12-02 08:06:24 UTC (rev 286415)
@@ -0,0 +1,5 @@
+Target
+
+PASS ":focus-visible" should be a valid selector
+PASS :focus-visible stop matching after blur
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023.html (0 => 286415)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-023.html 2021-12-02 08:06:24 UTC (rev 286415)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Test (Selectors): Element doesn't match :focus-visiblel after blur</title>
+<link rel="author" title="Manuel Rego Casasnovas" href=""
+<link rel="help" href="" />
+<script src=""
+<script src=""
+<script src=""
+<style>
+ :focus-visible {
+ outline: green solid 5px;
+ }
+</style>
+
+<div id="target" tabindex="0">Target</div>
+<script>
+ // Check that :focus-visible is supported.
+ test_valid_selector(':focus-visible');
+
+ async_test(function(t) {
+ target.addEventListener("focus", t.step_func(function() {
+ assert_equals(getComputedStyle(target).outlineStyle, "solid", `outline-style for ${target.tagName}#${target.id} should be solid`);
+ assert_equals(getComputedStyle(target).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${target.tagName}#${target.id} should be green`);
+ target.blur();
+ }));
+ target.addEventListener("blur", t.step_func(function() {
+ assert_equals(getComputedStyle(target).outlineStyle, "none", `outline-style for ${target.tagName}#${target.id} should be none`);
+ t.done();
+ }));
+ target.focus();
+ }, ":focus-visible stop matching after blur");
+</script>
+
Modified: trunk/Source/WebCore/ChangeLog (286414 => 286415)
--- trunk/Source/WebCore/ChangeLog 2021-12-02 06:27:47 UTC (rev 286414)
+++ trunk/Source/WebCore/ChangeLog 2021-12-02 08:06:24 UTC (rev 286415)
@@ -1,3 +1,24 @@
+2021-12-02 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] :focus-visible should stop matching after blur
+ https://bugs.webkit.org/show_bug.cgi?id=233688
+
+ Reviewed by Antti Koivisto.
+
+ Move PseudoClassChangeInvalidation for :focus-visible together with the one for :focus,
+ as we need to keep both flags in sync when computing the invalidations
+ (it's not possible to have an element that matches :focus-visible but not :focus,
+ and that was happening before this change).
+
+ Test: imported/w3c/web-platform-tests/css/selectors/focus-visible-023.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::setFocus): Add PseudoClassChangeInvalidation for :focus-visible change,
+ and put it in the same scope as the flags changes.
+ (WebCore::Element::setHasFocusVisible): Remove PseudoClassChangeInvalidation from this method.
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::internalKeyEvent): Use PseudoClassChangeInvalidation for :focus-visible change.
+
2021-12-01 Sihui Liu <[email protected]>
FileSystemSyncAccessHandle should be invalidated when network process crashes
Modified: trunk/Source/WebCore/dom/Element.cpp (286414 => 286415)
--- trunk/Source/WebCore/dom/Element.cpp 2021-12-02 06:27:47 UTC (rev 286414)
+++ trunk/Source/WebCore/dom/Element.cpp 2021-12-02 08:06:24 UTC (rev 286415)
@@ -815,20 +815,21 @@
return;
{
Style::PseudoClassChangeInvalidation focusStyleInvalidation(*this, CSSSelector::PseudoClassFocus);
+ Style::PseudoClassChangeInvalidation focusVisibleStyleInvalidation(*this, CSSSelector::PseudoClassFocusVisible);
Style::PseudoClassChangeInvalidation directFocusStyleInvalidation(*this, CSSSelector::PseudoClassDirectFocus);
document().userActionElements().setFocused(*this, flag);
- }
- // Shadow host with a slot that contain focused element is not considered focused.
- for (auto* root = containingShadowRoot(); root; root = root->host()->containingShadowRoot()) {
- root->setContainsFocusedElement(flag);
- root->host()->invalidateStyle();
- }
+ // Shadow host with a slot that contain focused element is not considered focused.
+ for (auto* root = containingShadowRoot(); root; root = root->host()->containingShadowRoot()) {
+ root->setContainsFocusedElement(flag);
+ root->host()->invalidateStyle();
+ }
- for (auto* element = this; element; element = element->parentElementInComposedTree())
- element->setHasFocusWithin(flag);
+ for (auto* element = this; element; element = element->parentElementInComposedTree())
+ element->setHasFocusWithin(flag);
- setHasFocusVisible(flag && (visibility == FocusVisibility::Visible || shouldAlwaysHaveFocusVisibleWhenFocused(*this)));
+ setHasFocusVisible(flag && (visibility == FocusVisibility::Visible || shouldAlwaysHaveFocusVisibleWhenFocused(*this)));
+ }
}
void Element::setHasFocusVisible(bool flag)
@@ -844,7 +845,6 @@
if (hasFocusVisible() == flag)
return;
- Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusVisible);
document().userActionElements().setHasFocusVisible(*this, flag);
}
Modified: trunk/Source/WebCore/page/EventHandler.cpp (286414 => 286415)
--- trunk/Source/WebCore/page/EventHandler.cpp 2021-12-02 06:27:47 UTC (rev 286414)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2021-12-02 08:06:24 UTC (rev 286415)
@@ -85,6 +85,7 @@
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginDocument.h"
+#include "PseudoClassChangeInvalidation.h"
#include "Range.h"
#include "RenderFrameSet.h"
#include "RenderImage.h"
@@ -3631,8 +3632,10 @@
// Just typing a modifier key is not considered user interaction with the page, but Shift + a (or Caps Lock + a) is considered an interaction.
bool userHasInteractedViaKeyword = keydown->modifierKeys().isEmpty() || ((keydown->shiftKey() || keydown->capsLockKey()) && !initialKeyEvent.text().isEmpty());
- if (element.focused() && userHasInteractedViaKeyword)
+ if (element.focused() && userHasInteractedViaKeyword) {
+ Style::PseudoClassChangeInvalidation focusVisibleStyleInvalidation(element, CSSSelector::PseudoClassFocusVisible);
element.setHasFocusVisible(true);
+ }
};
setHasFocusVisibleIfNeeded(*element);