Diff
Modified: trunk/LayoutTests/ChangeLog (273811 => 273812)
--- trunk/LayoutTests/ChangeLog 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/ChangeLog 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,3 +1,14 @@
+2021-03-02 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] :focus-visible implementation
+ https://bugs.webkit.org/show_bug.cgi?id=222028
+ <rdar://problem/74679243>
+
+ Reviewed by Darin Adler.
+
+ * platform/ios/TestExpectations: Skip focus-visible-008.html and focus-visible-011.html as they timeout in iOS.
+ * platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt.
+
2021-03-02 Lauro Moura <[email protected]>
[GLIB] Rebaseline and update expectations
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,3 +1,29 @@
+2021-03-02 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] :focus-visible implementation
+ https://bugs.webkit.org/show_bug.cgi?id=222028
+ <rdar://problem/74679243>
+
+ Reviewed by Darin Adler.
+
+ Update expectations, most of the :focus-visible tests are passing now.
+
+ * web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt:
+ * web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-001-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-002-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-006-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-007-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-007.html: Import last changes on this test
+ * web-platform-tests/css/selectors/focus-visible-008-expected.txt:
+ (see https://github.com/web-platform-tests/wpt/pull/27656).
+ * web-platform-tests/css/selectors/focus-visible-011-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-011.html: Import last changes on this test
+ (see https://github.com/web-platform-tests/wpt/pull/27700).
+ * web-platform-tests/css/selectors/focus-visible-013-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-014-expected.txt:
+ * web-platform-tests/css/selectors/focus-visible-016-expected.txt:
+
2021-03-02 Rob Buis <[email protected]>
Take box-sizing into account in replaced element intrinsic sizing
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,6 +1,6 @@
PASS Checks that ':focus' pseudo-class matches inside 'focus' event handler
-FAIL Checks that ':focus-visible' pseudo-class matches inside 'focus' event handler assert_unreached: ':focus-visible' is an invalid selector. SyntaxError: Error: assert_equals: ':focus-visible' matches event.target expected null but got Element node <input type="text"></input> Reached unreachable code
+PASS Checks that ':focus-visible' pseudo-class matches inside 'focus' event handler
PASS Checks that ':focus-within' pseudo-class matches inside 'focus' event handler
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,6 +1,6 @@
PASS Checks that ':focus' pseudo-class matches inside 'focusin' event handler
-FAIL Checks that ':focus-visible' pseudo-class matches inside 'focusin' event handler assert_unreached: ':focus-visible' is an invalid selector. SyntaxError: Error: assert_equals: ':focus-visible' matches event.target expected null but got Element node <input type="text"></input> Reached unreachable code
+PASS Checks that ':focus-visible' pseudo-class matches inside 'focusin' event handler
PASS Checks that ':focus-within' pseudo-class matches inside 'focusin' event handler
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-001-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-001-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-001-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -5,5 +5,5 @@
Focus me.
-FAIL Keyboard focus should match :focus-visible assert_equals: outlineColor for DIV#el should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+PASS Keyboard focus should match :focus-visible
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-002-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-002-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-002-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -18,18 +18,18 @@
-FAIL Focus element INPUT#input1 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input1 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input2 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input2 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input3 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input3 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input4 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input4 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input5 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input5 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input6 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input6 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input7 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input7 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input8 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input8 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input9 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input9 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input10 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input10 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input11 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input11 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input12 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input12 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element INPUT#input13 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for INPUT#input13 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-FAIL Focus element TEXTAREA#input14 via mouse should match :focus-visible as it supports keyboard input assert_equals: outlineColor for TEXTAREA#input14 should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+PASS Focus element INPUT#input1 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input2 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input3 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input4 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input5 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input6 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input7 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input8 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input9 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input10 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input11 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input12 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element INPUT#input13 via mouse should match :focus-visible as it supports keyboard input
+PASS Focus element TEXTAREA#input14 via mouse should match :focus-visible as it supports keyboard input
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-006-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-006-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-006-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -5,5 +5,5 @@
Focus me
-FAIL Focus should always match :focus-visible on content editable divs assert_equals: outlineColor for SPAN#el should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+PASS Focus should always match :focus-visible on content editable divs
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -2,9 +2,9 @@
If the user-agent does not claim to support the :focus-visible pseudo-class then SKIP this test.
Use the mouse to focus the element below that says "Click me."
If the element has a red outline, then the test result is FAILURE.
-Press the SHIFT key.
+Press the ENTER key.
If the element now has a green outline and not red background, then the test result is SUCCESS.
Click me.
-FAIL Using keyboard while element is focused should trigger :focus-visible; using mouse without moving focus should not cancel it; moving focus using mouse should cancel it. assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+PASS Using keyboard while element is focused should trigger :focus-visible; using mouse without moving focus should not cancel it; moving focus using mouse should cancel it.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html 2021-03-03 06:43:53 UTC (rev 273812)
@@ -36,7 +36,7 @@
<li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
<li>Use the mouse to focus the element below that says "Click me."</li>
<li>If the element has a red outline, then the test result is FAILURE.</li>
- <li>Press the SHIFT key.</li>
+ <li>Press the ENTER key.</li>
<li>If the element now has a green outline and not red background, then the test result is SUCCESS.</li>
</ol>
@@ -65,7 +65,8 @@
one.addEventListener("keyup", t.step_func(test_modality_change));
one.removeEventListener("focus", handle_initial_focus);
- test_driver.send_keys(one, "\uE050");
+ const enter = "\uE007";
+ test_driver.send_keys(one, enter);
});
const test_modality_change = t.step_func(() => {
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -6,7 +6,5 @@
Tab to me and press ENTER.
I will be focused programmatically.
-Harness Error (TIMEOUT), message = null
+FAIL Programmatic focus after keypress should match :focus-visible assert_equals: outlineColor for DIV#el should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-TIMEOUT Programmatic focus after keypress should match :focus-visible Test timed out
-
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,11 +1,9 @@
This test checks that :focus-visible matches after a keyboard event, even if the event handler calls preventDefault() on the event.
Click "Click here and press right arrow.".
Press the right arrow key.
-If "Focus moves here." has a red background, then the test result is FAILURE. If it has a green outline, then the test result is SUCCESS.
+If the element has a red background, then the test result is FAILURE. If it has a green outline, then the test result is SUCCESS.
-Click here and press right arrow. Focus moves here.
+Click here and press right arrow.
-Harness Error (TIMEOUT), message = null
+PASS :focus-visible matches even if preventDefault() is called
-TIMEOUT :focus-visible matches even if preventDefault() is called Test timed out
-
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html 2021-03-03 06:43:53 UTC (rev 273812)
@@ -21,11 +21,11 @@
border: 0;
}
- #next:focus-visible {
+ :focus-visible {
outline: green solid 5px;
}
- #next:focus:not(:focus-visible) {
+ :focus:not(:focus-visible) {
background-color: red;
outline: 0;
}
@@ -37,30 +37,33 @@
<ul id="instructions">
<li>Click "Click here and press right arrow.".</li>
<li>Press the right arrow key.</li>
- <li>If "Focus moves here." has a red background, then the test result is FAILURE.
+ <li>If the element has a red background, then the test result is FAILURE.
If it has a green outline, then the test result is SUCCESS.</li>
</ul>
<br />
- <button id="start" tabindex="0">Click here and press right arrow.</button>
- <button id="next" tabindex="-1">Focus moves here.</button>
+ <div id="target" tabindex="0">Click here and press right arrow.</div>
<script>
- start.addEventListener('keydown', (e) => {
+ target.addEventListener("keydown", (e) => {
e.preventDefault();
- next.focus();
});
+ target.addEventListener("keyup", (e) => {
+ e.preventDefault();
+ });
+ target.addEventListener("keypress", (e) => {
+ e.preventDefault();
+ });
+ async_test(function(t) {
+ target.addEventListener("focus", () => {
+ const arrow_right = "\ue014";
+ test_driver.send_keys(target, arrow_right);
+ });
- async_test(function(t) {
- next.addEventListener("focus", t.step_func(() => {
- assert_equals(getComputedStyle(next).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${next.tagName}#${next.id} should be green`);
- assert_not_equals(getComputedStyle(next).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${next.tagName}#${next.id} should NOT be red`);
- t.done()
+ target.addEventListener("keyup", t.step_func_done((e) => {
+ assert_equals(getComputedStyle(target).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${target.tagName}#${target.id} should be green`);
+ assert_not_equals(getComputedStyle(target).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${target.tagName}#${target.id} should NOT be red`);
}));
- // \ue014 -> ARROW_RIGHT
- test_driver.send_keys(start, "\ue014").catch(t.step_func(() => {
- assert_true(false, "send_keys not implemented yet");
- t.done();
- }));
+ test_driver.click(target);
}, ":focus-visible matches even if preventDefault() is called");
</script>
</body>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-013-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-013-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-013-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -8,7 +8,5 @@
Initial
Target
-Harness Error (TIMEOUT), message = null
+PASS :focus-visible does not match after mouse click even if previous focused element was matching :focus-visible
-FAIL :focus-visible does not match after mouse click even if previous focused element was matching :focus-visible assert_equals: outlineColor for DIV#initial should be green expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
-
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-014-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-014-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-014-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,5 +1,5 @@
Target
-FAIL :focus-visible matches after script focus move assert_equals: backgroundColor for INPUT#input should be lime expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
+FAIL :focus-visible matches after script focus move assert_equals: backgroundColor for DIV#target should be lime expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-016-expected.txt (273811 => 273812)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-016-expected.txt 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-016-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,5 +1,5 @@
Initial
-FAIL :focus-visible always match on text inputs assert_equals: backgroundColor for INPUT#target should be lime expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
+PASS :focus-visible always match on text inputs
Modified: trunk/LayoutTests/platform/ios/TestExpectations (273811 => 273812)
--- trunk/LayoutTests/platform/ios/TestExpectations 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2021-03-03 06:43:53 UTC (rev 273812)
@@ -3394,7 +3394,9 @@
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-001.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html [ Skip ]
+webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-008.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-009.html [ Skip ]
+webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-012.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-013.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/hover-002.html [ Skip ]
Copied: trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt (from rev 273811, trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt) (0 => 273812)
--- trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt 2021-03-03 06:43:53 UTC (rev 273812)
@@ -0,0 +1,12 @@
+This test checks that programmatically focusing an element after a keypress causes :focus-visible to match.
+Use the tab key to move focus to the button below that says "Tab to me and press ENTER."
+Press ENTER.
+If the element that says "I will be focused programmatically." has a red background, then the test result is FAILURE. If the element has a green outline, then the test result is SUCCESS.
+
+Tab to me and press ENTER.
+I will be focused programmatically.
+
+Harness Error (TIMEOUT), message = null
+
+TIMEOUT Programmatic focus after keypress should match :focus-visible Test timed out
+
Modified: trunk/Source/WebCore/ChangeLog (273811 => 273812)
--- trunk/Source/WebCore/ChangeLog 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/ChangeLog 2021-03-03 06:43:53 UTC (rev 273812)
@@ -1,3 +1,37 @@
+2021-03-02 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] :focus-visible implementation
+ https://bugs.webkit.org/show_bug.cgi?id=222028
+ <rdar://problem/74679243>
+
+ Reviewed by Darin Adler.
+
+ Add basic :focus-visible implementation behind the FocusVisibleEnabled experimental feature flag.
+ This patch implements the heuristics defined in the spec (https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo),
+ except the ones related to script focus.
+
+ Test: imported/w3c/web-platform-tests/css/selectors/focus-visible-*
+
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::matchesFocusVisiblePseudoClass): Check element.hasFocusVisible().
+ * dom/Element.cpp:
+ (WebCore::Element::setFocus): When an element loses focus it always call setHasFocusVisible(false). When an element gets focused
+ it calls setHasFocusVisible(true) for elements that support keyboard input (as they always match :focus-visible).
+ (WebCore::Element::setHasFocusVisible): New method gated behind the experimental flag.
+ * dom/Element.h:
+ (WebCore::Element::hasFocusVisible const): Add new method.
+ * dom/Node.h:
+ (WebCore::Node::flagHasFocusVisible): Add new flag for :focus-visible matching.
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::internalKeyEvent): If the user interacts with the page via keyboard, call setHasFocusVisible(true).
+ Avoid that for modifier keys.
+ * page/FocusController.cpp:
+ (WebCore::FocusController::advanceFocusInDocumentOrder): Call setHasFocusVisible(true) for keyboard focus.
+ * page/FrameView.cpp:
+ (WebCore::FrameView::scrollToFragmentInternal): Call setHasFocusVisible(true) for anchor focus.
+ * style/StyleSharingResolver.cpp:
+ (WebCore::Style::SharingResolver::canShareStyleWithElement const): Add check for hasFocusVisible().
+
2021-03-02 Julian Gonzalez <[email protected]>
Crash in removeSymbolElementsFromSubtree()
Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (273811 => 273812)
--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2021-03-03 06:43:53 UTC (rev 273812)
@@ -474,7 +474,10 @@
ALWAYS_INLINE bool matchesFocusVisiblePseudoClass(const Element& element)
{
- return InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassFocusVisible);
+ if (InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassFocusVisible))
+ return true;
+
+ return element.hasFocusVisible() && isFrameFocused(element);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Element.cpp (273811 => 273812)
--- trunk/Source/WebCore/dom/Element.cpp 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/dom/Element.cpp 2021-03-03 06:43:53 UTC (rev 273812)
@@ -744,8 +744,28 @@
for (auto* element = this; element; element = element->parentElementInComposedTree())
element->setHasFocusWithin(flag);
+
+ auto computeHasFocusVisible = [&] {
+ if (!flag)
+ return false;
+ // Elements that support keyboard input (form inputs and contenteditable) always match :focus-visible when focused.
+ return hasFocusVisible() || isTextField() || isContentEditable();
+ };
+ setHasFocusVisible(computeHasFocusVisible());
}
+void Element::setHasFocusVisible(bool flag)
+{
+ if (!document().settings().focusVisibleEnabled())
+ return;
+
+ if (hasFocusVisible() == flag)
+ return;
+
+ Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusVisible);
+ setNodeFlag(NodeFlag::HasFocusVisible, flag);
+}
+
void Element::setHasFocusWithin(bool flag)
{
if (hasFocusWithin() == flag)
Modified: trunk/Source/WebCore/dom/Element.h (273811 => 273812)
--- trunk/Source/WebCore/dom/Element.h 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/dom/Element.h 2021-03-03 06:43:53 UTC (rev 273812)
@@ -319,6 +319,7 @@
bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
bool isBeingDragged() const { return isUserActionElement() && isUserActionElementDragged(); }
+ bool hasFocusVisible() const { return hasNodeFlag(NodeFlag::HasFocusVisible); };
bool hasFocusWithin() const { return hasNodeFlag(NodeFlag::HasFocusWithin); };
virtual void setActive(bool = true, bool pause = false, Style::InvalidationScope = Style::InvalidationScope::All);
@@ -325,6 +326,7 @@
virtual void setHovered(bool = true, Style::InvalidationScope = Style::InvalidationScope::All);
virtual void setFocus(bool);
void setBeingDragged(bool);
+ void setHasFocusVisible(bool);
void setHasFocusWithin(bool);
Optional<int> tabIndexSetExplicitly() const;
Modified: trunk/Source/WebCore/dom/Node.h (273811 => 273812)
--- trunk/Source/WebCore/dom/Node.h 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/dom/Node.h 2021-03-03 06:43:53 UTC (rev 273812)
@@ -508,6 +508,7 @@
static int32_t flagIsShadowRoot() { return static_cast<int32_t>(NodeFlag::IsShadowRoot); }
static int32_t flagIsHTML() { return static_cast<int32_t>(NodeFlag::IsHTMLElement); }
static int32_t flagIsLink() { return static_cast<int32_t>(NodeFlag::IsLink); }
+ static int32_t flagHasFocusVisible() { return static_cast<int32_t>(NodeFlag::HasFocusVisible); }
static int32_t flagHasFocusWithin() { return static_cast<int32_t>(NodeFlag::HasFocusWithin); }
static int32_t flagIsParsingChildrenFinished() { return static_cast<int32_t>(NodeFlag::IsParsingChildrenFinished); }
#endif // ENABLE(JIT)
@@ -549,6 +550,7 @@
#endif
IsComputedStyleInvalidFlag = 1 << 26,
+ HasFocusVisible = 1 << 27,
// Bits 27-31 are free.
};
Modified: trunk/Source/WebCore/page/EventHandler.cpp (273811 => 273812)
--- trunk/Source/WebCore/page/EventHandler.cpp 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2021-03-03 06:43:53 UTC (rev 273812)
@@ -3532,6 +3532,11 @@
keydown->preventDefault();
keydown->setTarget(element);
+ // If the user interacts with the page via the keyboard, the currently focused element should match :focus-visible.
+ // Just typing a modifier key is not considered user interaction with the page, but Shift + a (or Caps Lock + a) is considered an interaction.
+ if (keydown->modifierKeys().isEmpty() || ((keydown->shiftKey() || keydown->capsLockKey()) && !initialKeyEvent.text().isEmpty()))
+ element->setHasFocusVisible(true);
+
if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
element->dispatchEvent(keydown);
// If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
Modified: trunk/Source/WebCore/page/FocusController.cpp (273811 => 273812)
--- trunk/Source/WebCore/page/FocusController.cpp 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/page/FocusController.cpp 2021-03-03 06:43:53 UTC (rev 273812)
@@ -533,6 +533,7 @@
}
}
+ element->setHasFocusVisible(true);
element->focus(SelectionRestorationMode::SelectAll, direction);
return true;
}
Modified: trunk/Source/WebCore/page/FrameView.cpp (273811 => 273812)
--- trunk/Source/WebCore/page/FrameView.cpp 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/page/FrameView.cpp 2021-03-03 06:43:53 UTC (rev 273812)
@@ -2268,9 +2268,10 @@
// If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
if (anchorElement) {
- if (anchorElement->isFocusable())
+ if (anchorElement->isFocusable()) {
+ anchorElement->setHasFocusVisible(true);
document.setFocusedElement(anchorElement.get());
- else {
+ } else {
document.setFocusedElement(nullptr);
document.setFocusNavigationStartingNode(anchorElement.get());
}
Modified: trunk/Source/WebCore/style/StyleSharingResolver.cpp (273811 => 273812)
--- trunk/Source/WebCore/style/StyleSharingResolver.cpp 2021-03-03 05:05:30 UTC (rev 273811)
+++ trunk/Source/WebCore/style/StyleSharingResolver.cpp 2021-03-03 06:43:53 UTC (rev 273812)
@@ -227,6 +227,8 @@
return false;
if (candidateElement.focused() != element.focused())
return false;
+ if (candidateElement.hasFocusVisible() != element.hasFocusVisible())
+ return false;
if (candidateElement.hasFocusWithin() != element.hasFocusWithin())
return false;
if (candidateElement.isBeingDragged() != element.isBeingDragged())