Skip to content
Permalink
Browse files
[selectors] Script focus and :focus-visible
https://bugs.webkit.org/show_bug.cgi?id=224598

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update expectations as the tests pass now.

* web-platform-tests/css/selectors/focus-visible-008-expected.txt:
* web-platform-tests/css/selectors/focus-visible-009-expected.txt:
* web-platform-tests/css/selectors/focus-visible-010-expected.txt:
* web-platform-tests/css/selectors/focus-visible-014-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-001-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-002.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-003.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-004-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-005-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-006.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-007.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-012-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-013-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-014-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-015-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-016.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-017.tentative-expected.txt:

Source/WebCore:

Implement :focus-visible behavior when a script moves focus.
An element will match :focus-visible when a script move focus if the last focused element was not focused via mouse click.

This patch makes WebKit behaves like Chromium and Firefox and pass all the related tests.

There's an ongoing discussion about 6 tests that are marked as ".tentative" in the following issue:
web-platform-tests/wpt#28505

Test: web-platform-tests/css/selectors/focus-visible-script-focus-*

* dom/Document.cpp:
(WebCore::Document::adjustFocusedNodeOnNodeRemoval): Just update FocusOptions initializer.
(WebCore::Document::setFocusedElement): Store if the last element has been focused by mouse click or not.
* dom/Document.h: New member m_latestFocusTrigger.
(WebCore::Document::wasLastFocusByClick const): Method to check status of m_latestFocusTrigger.
* dom/Element.cpp:
(WebCore::Element::focus): When there's a script focus, this checks if the last element was focused
by mouse click in order to make it match :focus-visible.
* dom/FocusOptions.h: Add FocusTrigger enum to know if an element has been focused via mouse click or not.
This refers to the "focus trigger" concept on the HTML spec (see https://html.spec.whatwg.org/multipage/interaction.html).
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchMouseEvent): Pass FocusTrigger:Click in setFocusedElement() call.

LayoutTests:

Update expectations for tests, most of them are passing on Mac. On iOS a bunch timeout so they're skipped, as other :focus-visible tests.

* platform/ios/TestExpectations:
* platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-009-expected.txt: Removed as test passes now.
* platform/mac/TestExpectations:


Canonical link: https://commits.webkit.org/236746@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@276264 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
mrego committed Apr 19, 2021
1 parent 4876534 commit c72dff08fc0b8fbfc3ede25dfcfb9bce623976bc
Showing 28 changed files with 117 additions and 56 deletions.
@@ -1,3 +1,16 @@
2021-04-19 Manuel Rego Casasnovas <rego@igalia.com>

[selectors] Script focus and :focus-visible
https://bugs.webkit.org/show_bug.cgi?id=224598

Reviewed by Darin Adler.

Update expectations for tests, most of them are passing on Mac. On iOS a bunch timeout so they're skipped, as other :focus-visible tests.

* platform/ios/TestExpectations:
* platform/mac/imported/w3c/web-platform-tests/css/selectors/focus-visible-009-expected.txt: Removed as test passes now.
* platform/mac/TestExpectations:

2021-04-19 Darin Adler <darin@apple.com>

Nullptr crash in CSSCalcValue::category() via HTMLConverterCaches::floatPropertyValueForNode
@@ -1,3 +1,30 @@
2021-04-19 Manuel Rego Casasnovas <rego@igalia.com>

[selectors] Script focus and :focus-visible
https://bugs.webkit.org/show_bug.cgi?id=224598

Reviewed by Darin Adler.

Update expectations as the tests pass now.

* web-platform-tests/css/selectors/focus-visible-008-expected.txt:
* web-platform-tests/css/selectors/focus-visible-009-expected.txt:
* web-platform-tests/css/selectors/focus-visible-010-expected.txt:
* web-platform-tests/css/selectors/focus-visible-014-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-001-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-002.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-003.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-004-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-005-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-006.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-007.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-012-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-013-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-014-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-015-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-016.tentative-expected.txt:
* web-platform-tests/css/selectors/focus-visible-script-focus-017.tentative-expected.txt:

2021-04-19 Darin Adler <darin@apple.com>

Nullptr crash in CSSCalcValue::category() via HTMLConverterCaches::floatPropertyValueForNode
@@ -6,5 +6,5 @@ If the element that says "I will be focused programmatically." has a red backgro
Tab to me and press ENTER.
I will be focused programmatically.

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)"
PASS Programmatic focus after keypress should match :focus-visible

@@ -3,5 +3,5 @@ If the button that says "I will be focused automatically" has a red background,

I will be focused automatically.

FAIL Autofocus should match :focus-visible assert_equals: outlineColor for BUTTON#button should be green expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
PASS Autofocus should match :focus-visible

@@ -3,5 +3,5 @@ If the element that says "I will be focused automatically" has a red background,

I will be focused automatically.

FAIL Programmatic focus on page load 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 Programmatic focus on page load should match :focus-visible

@@ -1,5 +1,5 @@

Target

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)"
PASS :focus-visible matches after script focus move

@@ -4,5 +4,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus without any previous user interaction matches :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus without any previous user interaction matches :focus-visible

@@ -5,5 +5,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after mouse click does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after mouse click does match :focus-visible

@@ -5,5 +5,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after mouse click does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after mouse click does match :focus-visible

@@ -5,5 +5,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after keyboard event does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after keyboard event does match :focus-visible

@@ -5,5 +5,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after keyboard event does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after keyboard event does match :focus-visible

@@ -6,5 +6,5 @@ Click me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after mouse click on a NOT focusable element does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after mouse click on a NOT focusable element does match :focus-visible

@@ -6,5 +6,5 @@ Click me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after mouse click on a NOT focusable element does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after mouse click on a NOT focusable element does match :focus-visible

@@ -6,5 +6,5 @@ Focus me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after keyboard focus does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after keyboard focus does match :focus-visible

@@ -6,5 +6,5 @@ Focus me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after keyboard focus does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after keyboard focus does match :focus-visible

@@ -6,5 +6,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after keyboard input does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after keyboard input does match :focus-visible

@@ -6,5 +6,5 @@ If the element that says "Focused" has a red background then the test result is
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after keyboard input does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after keyboard input does match :focus-visible

@@ -8,5 +8,5 @@ Click me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after mouse click on a NOT focusable element after editing an input does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after mouse click on a NOT focusable element after editing an input does match :focus-visible

@@ -8,5 +8,5 @@ Click me
Focused

PASS ":focus-visible" should be a valid selector
FAIL Script focus after blur after mouse click on a NOT focusable element after editing an input does match :focus-visible assert_equals: outlineColor for DIV#target should be green expected "rgb(0, 128, 0)" but got "rgba(46, 52, 54, 0.59)"
PASS Script focus after blur after mouse click on a NOT focusable element after editing an input does match :focus-visible

@@ -3276,6 +3276,7 @@ webkit.org/b/209250 imported/w3c/web-platform-tests/css/css-text/line-break/line
webkit.org/b/207858 fast/canvas/webgl/simulated-vertexAttrib0-invalid-indicies.html [ Skip ]

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-005.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-006.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 ]
@@ -3284,22 +3285,17 @@ webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-
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/focus-visible-019.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-004.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-005.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-012.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-013.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-014.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-015.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-016.tentative.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-017.tentative.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-018.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-019.html [ Skip ]
webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/hover-002.html [ Skip ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-001.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-002.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-003.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-004.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-005.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-006.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-007.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-012.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-013.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-014.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-015.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-016.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-017.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-018.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-019.html [ Failure ]

# Certain versions of iOS use different text security characters.
webkit.org/b/209692 platform/ios/fast/text/text-security-disc-bullet-pua-ios-new.html [ Pass ]
@@ -2291,16 +2291,5 @@ webkit.org/b/224396 webgl/1.0.3/conformance/glsl/constructors/glsl-construct-ive

webkit.org/b/224631 [ BigSur ] imported/w3c/web-platform-tests/css/css-fonts/font-feature-settings-tibetan.html [ Pass ImageOnlyFailure ]

webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-001.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-002.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-003.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-004.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-005.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-006.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-007.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-012.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-013.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-014.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-015.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-016.tentative.html [ Failure ]
webkit.org/b/224598 imported/w3c/web-platform-tests/css/selectors/focus-visible-script-focus-017.tentative.html [ Failure ]
# Buttons are not focusable on Mac so this test doesn't work as expected.
webkit.org/b/22261 imported/w3c/web-platform-tests/css/selectors/focus-visible-005.html [ Skip ]

This file was deleted.

@@ -1,3 +1,33 @@
2021-04-19 Manuel Rego Casasnovas <rego@igalia.com>

[selectors] Script focus and :focus-visible
https://bugs.webkit.org/show_bug.cgi?id=224598

Reviewed by Darin Adler.

Implement :focus-visible behavior when a script moves focus.
An element will match :focus-visible when a script move focus if the last focused element was not focused via mouse click.

This patch makes WebKit behaves like Chromium and Firefox and pass all the related tests.

There's an ongoing discussion about 6 tests that are marked as ".tentative" in the following issue:
https://github.com/web-platform-tests/wpt/issues/28505

Test: web-platform-tests/css/selectors/focus-visible-script-focus-*

* dom/Document.cpp:
(WebCore::Document::adjustFocusedNodeOnNodeRemoval): Just update FocusOptions initializer.
(WebCore::Document::setFocusedElement): Store if the last element has been focused by mouse click or not.
* dom/Document.h: New member m_latestFocusTrigger.
(WebCore::Document::wasLastFocusByClick const): Method to check status of m_latestFocusTrigger.
* dom/Element.cpp:
(WebCore::Element::focus): When there's a script focus, this checks if the last element was focused
by mouse click in order to make it match :focus-visible.
* dom/FocusOptions.h: Add FocusTrigger enum to know if an element has been focused via mouse click or not.
This refers to the "focus trigger" concept on the HTML spec (see https://html.spec.whatwg.org/multipage/interaction.html).
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchMouseEvent): Pass FocusTrigger:Click in setFocusedElement() call.

2021-04-19 Darin Adler <darin@apple.com>

Nullptr crash in CSSCalcValue::category() via HTMLConverterCaches::floatPropertyValueForNode
@@ -4357,7 +4357,7 @@ void Document::adjustFocusedNodeOnNodeRemoval(Node& node, NodeRemoval nodeRemova
// FIXME: We should avoid synchronously updating the style inside setFocusedElement.
// FIXME: Object elements should avoid loading a frame synchronously in a post style recalc callback.
SubframeLoadingDisabler disabler(is<ContainerNode>(node) ? &downcast<ContainerNode>(node) : nullptr);
setFocusedElement(nullptr, { { }, { }, FocusRemovalEventsMode::DoNotDispatch, { } });
setFocusedElement(nullptr, { { }, { }, FocusRemovalEventsMode::DoNotDispatch, { }, { } });
// Set the focus navigation starting node to the previous focused element so that
// we can fallback to the siblings or parent node for the next search.
// Also we need to call removeFocusNavigationNodeOfSubtree after this function because
@@ -4530,6 +4530,7 @@ bool Document::setFocusedElement(Element* element, const FocusOptions& options)
m_focusedElement = newFocusedElement;
setFocusNavigationStartingNode(m_focusedElement.get());
m_focusedElement->setFocus(true);
m_latestFocusTrigger = options.trigger;

// The setFocus call triggers a blur and a focus event. Event handlers could cause the focused element to be cleared.
if (m_focusedElement != newFocusedElement) {
@@ -761,6 +761,7 @@ class Document
// The element could have already been focused or may not be focusable (e.g. <input disabled>).
WEBCORE_EXPORT bool setFocusedElement(Element*, const FocusOptions& = { });
Element* focusedElement() const { return m_focusedElement.get(); }
bool wasLastFocusByClick() const { return m_latestFocusTrigger == FocusTrigger::Click; }
UserActionElementSet& userActionElements() { return m_userActionElements; }
const UserActionElementSet& userActionElements() const { return m_userActionElements; }

@@ -2126,6 +2127,8 @@ class Document

bool m_updateTitleTaskScheduled { false };

FocusTrigger m_latestFocusTrigger { FocusTrigger::Other };

OrientationNotifier m_orientationNotifier;
mutable RefPtr<Logger> m_logger;
RefPtr<StringCallback> m_consoleMessageListener;

0 comments on commit c72dff0

Please sign in to comment.