Changeset 273812 in webkit


Ignore:
Timestamp:
Mar 2, 2021 10:43:53 PM (3 years ago)
Author:
Manuel Rego Casasnovas
Message:

[selectors] :focus-visible implementation
https://bugs.webkit.org/show_bug.cgi?id=222028
<rdar://problem/74679243>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

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:

Source/WebCore:

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().

LayoutTests:

  • 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.
Location:
trunk
Files:
25 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r273811 r273812  
     12021-03-02  Manuel Rego Casasnovas  <rego@igalia.com>
     2
     3        [selectors] :focus-visible implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=222028
     5        <rdar://problem/74679243>
     6
     7        Reviewed by Darin Adler.
     8
     9        * platform/ios/TestExpectations: Skip focus-visible-008.html and focus-visible-011.html as they timeout in iOS.
     10        * 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.
     11
    1122021-03-02  Lauro Moura  <lmoura@igalia.com>
    213
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r273753 r273812  
     12021-03-02  Manuel Rego Casasnovas  <rego@igalia.com>
     2
     3        [selectors] :focus-visible implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=222028
     5        <rdar://problem/74679243>
     6
     7        Reviewed by Darin Adler.
     8
     9        Update expectations, most of the :focus-visible tests are passing now.
     10
     11        * web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt:
     12        * web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt:
     13        * web-platform-tests/css/selectors/focus-visible-001-expected.txt:
     14        * web-platform-tests/css/selectors/focus-visible-002-expected.txt:
     15        * web-platform-tests/css/selectors/focus-visible-006-expected.txt:
     16        * web-platform-tests/css/selectors/focus-visible-007-expected.txt:
     17        * web-platform-tests/css/selectors/focus-visible-007.html: Import last changes on this test
     18        * web-platform-tests/css/selectors/focus-visible-008-expected.txt:
     19        (see https://github.com/web-platform-tests/wpt/pull/27656).
     20        * web-platform-tests/css/selectors/focus-visible-011-expected.txt:
     21        * web-platform-tests/css/selectors/focus-visible-011.html: Import last changes on this test
     22        (see https://github.com/web-platform-tests/wpt/pull/27700).
     23        * web-platform-tests/css/selectors/focus-visible-013-expected.txt:
     24        * web-platform-tests/css/selectors/focus-visible-014-expected.txt:
     25        * web-platform-tests/css/selectors/focus-visible-016-expected.txt:
     26
    1272021-03-02  Rob Buis  <rbuis@igalia.com>
    228
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focus-event-001-expected.txt

    r272983 r273812  
    22
    33PASS Checks that ':focus' pseudo-class matches inside 'focus' event handler
    4 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
     4PASS Checks that ':focus-visible' pseudo-class matches inside 'focus' event handler
    55PASS Checks that ':focus-within' pseudo-class matches inside 'focus' event handler
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-in-focusin-event-001-expected.txt

    r272983 r273812  
    22
    33PASS Checks that ':focus' pseudo-class matches inside 'focusin' event handler
    4 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
     4PASS Checks that ':focus-visible' pseudo-class matches inside 'focusin' event handler
    55PASS Checks that ':focus-within' pseudo-class matches inside 'focusin' event handler
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-001-expected.txt

    r272983 r273812  
    66Focus me.
    77
    8 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)"
     8PASS Keyboard focus should match :focus-visible
    99
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-002-expected.txt

    r272983 r273812  
    1919
    2020
    21 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)"
    22 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)"
    23 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)"
    24 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)"
    25 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)"
    26 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)"
    27 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)"
    28 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)"
    29 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)"
    30 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)"
    31 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)"
    32 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)"
    33 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)"
    34 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)"
     21PASS Focus element INPUT#input1 via mouse should match :focus-visible as it supports keyboard input
     22PASS Focus element INPUT#input2 via mouse should match :focus-visible as it supports keyboard input
     23PASS Focus element INPUT#input3 via mouse should match :focus-visible as it supports keyboard input
     24PASS Focus element INPUT#input4 via mouse should match :focus-visible as it supports keyboard input
     25PASS Focus element INPUT#input5 via mouse should match :focus-visible as it supports keyboard input
     26PASS Focus element INPUT#input6 via mouse should match :focus-visible as it supports keyboard input
     27PASS Focus element INPUT#input7 via mouse should match :focus-visible as it supports keyboard input
     28PASS Focus element INPUT#input8 via mouse should match :focus-visible as it supports keyboard input
     29PASS Focus element INPUT#input9 via mouse should match :focus-visible as it supports keyboard input
     30PASS Focus element INPUT#input10 via mouse should match :focus-visible as it supports keyboard input
     31PASS Focus element INPUT#input11 via mouse should match :focus-visible as it supports keyboard input
     32PASS Focus element INPUT#input12 via mouse should match :focus-visible as it supports keyboard input
     33PASS Focus element INPUT#input13 via mouse should match :focus-visible as it supports keyboard input
     34PASS Focus element TEXTAREA#input14 via mouse should match :focus-visible as it supports keyboard input
    3535
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-006-expected.txt

    r272983 r273812  
    66Focus me
    77
    8 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)"
     8PASS Focus should always match :focus-visible on content editable divs
    99
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007-expected.txt

    r272983 r273812  
    33Use the mouse to focus the element below that says "Click me."
    44If the element has a red outline, then the test result is FAILURE.
    5 Press the SHIFT key.
     5Press the ENTER key.
    66If the element now has a green outline and not red background, then the test result is SUCCESS.
    77Click me.
    88
    9 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)"
     9PASS 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.
    1010
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html

    r272007 r273812  
    3737    <li>Use the mouse to focus the element below that says "Click me."</li>
    3838    <li>If the element has a red outline, then the test result is FAILURE.</li>
    39     <li>Press the SHIFT key.</li>
     39    <li>Press the ENTER key.</li>
    4040    <li>If the element now has a green outline and not red background, then the test result is SUCCESS.</li>
    4141  </ol>
     
    6666        one.removeEventListener("focus", handle_initial_focus);
    6767
    68         test_driver.send_keys(one, "\uE050");
     68        const enter = "\uE007";
     69        test_driver.send_keys(one, enter);
    6970      });
    7071
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-008-expected.txt

    r271395 r273812  
    77I will be focused programmatically.
    88
    9 Harness Error (TIMEOUT), message = null
     9FAIL 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)"
    1010
    11 TIMEOUT Programmatic focus after keypress should match :focus-visible Test timed out
    12 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011-expected.txt

    r259194 r273812  
    22Click "Click here and press right arrow.".
    33Press the right arrow key.
    4 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.
     4If the element has a red background, then the test result is FAILURE. If it has a green outline, then the test result is SUCCESS.
    55
    6 Click here and press right arrow.  Focus moves here.
     6Click here and press right arrow.
    77
    8 Harness Error (TIMEOUT), message = null
     8PASS :focus-visible matches even if preventDefault() is called
    99
    10 TIMEOUT :focus-visible matches even if preventDefault() is called Test timed out
    11 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html

    r272007 r273812  
    2222    }
    2323
    24     #next:focus-visible {
     24    :focus-visible {
    2525      outline: green solid 5px;
    2626    }
    2727
    28     #next:focus:not(:focus-visible) {
     28    :focus:not(:focus-visible) {
    2929      background-color: red;
    3030      outline: 0;
     
    3838    <li>Click "Click here and press right arrow.".</li>
    3939    <li>Press the right arrow key.</li>
    40     <li>If "Focus moves here." has a red background, then the test result is FAILURE.
     40    <li>If the element has a red background, then the test result is FAILURE.
    4141        If it has a green outline, then the test result is SUCCESS.</li>
    4242  </ul>
    4343  <br />
    44   <button id="start" tabindex="0">Click here and press right arrow.</button>
    45   <button id="next" tabindex="-1">Focus moves here.</button>
     44  <div id="target" tabindex="0">Click here and press right arrow.</div>
    4645  <script>
    47     start.addEventListener('keydown', (e) => {
     46    target.addEventListener("keydown", (e) => {
    4847      e.preventDefault();
    49       next.focus();
    5048    });
     49    target.addEventListener("keyup", (e) => {
     50      e.preventDefault();
     51    });
     52    target.addEventListener("keypress", (e) => {
     53      e.preventDefault();
     54    });
     55    async_test(function(t) {
     56      target.addEventListener("focus", () => {
     57        const arrow_right = "\ue014";
     58        test_driver.send_keys(target, arrow_right);
     59      });
    5160
    52     async_test(function(t) {
    53       next.addEventListener("focus", t.step_func(() => {
    54         assert_equals(getComputedStyle(next).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${next.tagName}#${next.id} should be green`);
    55         assert_not_equals(getComputedStyle(next).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${next.tagName}#${next.id} should NOT be red`);
    56         t.done()
     61      target.addEventListener("keyup", t.step_func_done((e) => {
     62        assert_equals(getComputedStyle(target).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${target.tagName}#${target.id} should be green`);
     63        assert_not_equals(getComputedStyle(target).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${target.tagName}#${target.id} should NOT be red`);
    5764      }));
    5865
    59       // \ue014 -> ARROW_RIGHT
    60       test_driver.send_keys(start, "\ue014").catch(t.step_func(() => {
    61         assert_true(false, "send_keys not implemented yet");
    62         t.done();
    63       }));
     66      test_driver.click(target);
    6467    }, ":focus-visible matches even if preventDefault() is called");
    6568  </script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-013-expected.txt

    r272007 r273812  
    99Target
    1010
    11 Harness Error (TIMEOUT), message = null
     11PASS :focus-visible does not match after mouse click even if previous focused element was matching :focus-visible
    1212
    13 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)"
    14 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-014-expected.txt

    r271395 r273812  
    22Target
    33
    4 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)"
     4FAIL :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)"
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/focus-visible-016-expected.txt

    r272983 r273812  
    22
    33
    4 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)"
     4PASS :focus-visible always match on text inputs
    55
  • trunk/LayoutTests/platform/ios/TestExpectations

    r273745 r273812  
    33953395webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-001.html [ Skip ]
    33963396webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-007.html [ Skip ]
     3397webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-008.html [ Skip ]
    33973398webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-009.html [ Skip ]
     3399webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-011.html [ Skip ]
    33983400webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-012.html [ Skip ]
    33993401webkit.org/b/209734 imported/w3c/web-platform-tests/css/selectors/focus-visible-013.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r273809 r273812  
     12021-03-02  Manuel Rego Casasnovas  <rego@igalia.com>
     2
     3        [selectors] :focus-visible implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=222028
     5        <rdar://problem/74679243>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add basic :focus-visible implementation behind the FocusVisibleEnabled experimental feature flag.
     10        This patch implements the heuristics defined in the spec (https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo),
     11        except the ones related to script focus.
     12
     13        Test: imported/w3c/web-platform-tests/css/selectors/focus-visible-*
     14
     15        * css/SelectorCheckerTestFunctions.h:
     16        (WebCore::matchesFocusVisiblePseudoClass): Check element.hasFocusVisible().
     17        * dom/Element.cpp:
     18        (WebCore::Element::setFocus): When an element loses focus it always call setHasFocusVisible(false). When an element gets focused
     19        it calls setHasFocusVisible(true) for elements that support keyboard input (as they always match :focus-visible).
     20        (WebCore::Element::setHasFocusVisible): New method gated behind the experimental flag.
     21        * dom/Element.h:
     22        (WebCore::Element::hasFocusVisible const): Add new method.
     23        * dom/Node.h:
     24        (WebCore::Node::flagHasFocusVisible): Add new flag for :focus-visible matching.
     25        * page/EventHandler.cpp:
     26        (WebCore::EventHandler::internalKeyEvent): If the user interacts with the page via keyboard, call setHasFocusVisible(true).
     27        Avoid that for modifier keys.
     28        * page/FocusController.cpp:
     29        (WebCore::FocusController::advanceFocusInDocumentOrder): Call setHasFocusVisible(true) for keyboard focus.
     30        * page/FrameView.cpp:
     31        (WebCore::FrameView::scrollToFragmentInternal): Call setHasFocusVisible(true) for anchor focus.
     32        * style/StyleSharingResolver.cpp:
     33        (WebCore::Style::SharingResolver::canShareStyleWithElement const): Add check for hasFocusVisible().
     34
    1352021-03-02  Julian Gonzalez  <julian_a_gonzalez@apple.com>
    236
  • trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h

    r272983 r273812  
    475475ALWAYS_INLINE bool matchesFocusVisiblePseudoClass(const Element& element)
    476476{
    477     return InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassFocusVisible);
     477    if (InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassFocusVisible))
     478        return true;
     479
     480    return element.hasFocusVisible() && isFrameFocused(element);
    478481}
    479482
  • trunk/Source/WebCore/dom/Element.cpp

    r273622 r273812  
    745745    for (auto* element = this; element; element = element->parentElementInComposedTree())
    746746        element->setHasFocusWithin(flag);
     747
     748    auto computeHasFocusVisible = [&] {
     749        if (!flag)
     750            return false;
     751        // Elements that support keyboard input (form inputs and contenteditable) always match :focus-visible when focused.
     752        return hasFocusVisible() || isTextField() || isContentEditable();
     753    };
     754    setHasFocusVisible(computeHasFocusVisible());
     755}
     756
     757void Element::setHasFocusVisible(bool flag)
     758{
     759    if (!document().settings().focusVisibleEnabled())
     760        return;
     761
     762    if (hasFocusVisible() == flag)
     763        return;
     764
     765    Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusVisible);
     766    setNodeFlag(NodeFlag::HasFocusVisible, flag);
    747767}
    748768
  • trunk/Source/WebCore/dom/Element.h

    r272433 r273812  
    320320    bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
    321321    bool isBeingDragged() const { return isUserActionElement() && isUserActionElementDragged(); }
     322    bool hasFocusVisible() const { return hasNodeFlag(NodeFlag::HasFocusVisible); };
    322323    bool hasFocusWithin() const { return hasNodeFlag(NodeFlag::HasFocusWithin); };
    323324
     
    326327    virtual void setFocus(bool);
    327328    void setBeingDragged(bool);
     329    void setHasFocusVisible(bool);
    328330    void setHasFocusWithin(bool);
    329331
  • trunk/Source/WebCore/dom/Node.h

    r273622 r273812  
    509509    static int32_t flagIsHTML() { return static_cast<int32_t>(NodeFlag::IsHTMLElement); }
    510510    static int32_t flagIsLink() { return static_cast<int32_t>(NodeFlag::IsLink); }
     511    static int32_t flagHasFocusVisible() { return static_cast<int32_t>(NodeFlag::HasFocusVisible); }
    511512    static int32_t flagHasFocusWithin() { return static_cast<int32_t>(NodeFlag::HasFocusWithin); }
    512513    static int32_t flagIsParsingChildrenFinished() { return static_cast<int32_t>(NodeFlag::IsParsingChildrenFinished); }
     
    550551        IsComputedStyleInvalidFlag = 1 << 26,
    551552
     553        HasFocusVisible = 1 << 27,
    552554        // Bits 27-31 are free.
    553555    };
  • trunk/Source/WebCore/page/EventHandler.cpp

    r273077 r273812  
    35333533    keydown->setTarget(element);
    35343534
     3535    // If the user interacts with the page via the keyboard, the currently focused element should match :focus-visible.
     3536    // Just typing a modifier key is not considered user interaction with the page, but Shift + a (or Caps Lock + a) is considered an interaction.
     3537    if (keydown->modifierKeys().isEmpty() || ((keydown->shiftKey() || keydown->capsLockKey()) && !initialKeyEvent.text().isEmpty()))
     3538        element->setHasFocusVisible(true);
     3539
    35353540    if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
    35363541        element->dispatchEvent(keydown);
  • trunk/Source/WebCore/page/FocusController.cpp

    r269587 r273812  
    534534    }
    535535
     536    element->setHasFocusVisible(true);
    536537    element->focus(SelectionRestorationMode::SelectAll, direction);
    537538    return true;
  • trunk/Source/WebCore/page/FrameView.cpp

    r273275 r273812  
    22692269    // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
    22702270    if (anchorElement) {
    2271         if (anchorElement->isFocusable())
     2271        if (anchorElement->isFocusable()) {
     2272            anchorElement->setHasFocusVisible(true);
    22722273            document.setFocusedElement(anchorElement.get());
    2273         else {
     2274        } else {
    22742275            document.setFocusedElement(nullptr);
    22752276            document.setFocusNavigationStartingNode(anchorElement.get());
  • trunk/Source/WebCore/style/StyleSharingResolver.cpp

    r271054 r273812  
    228228    if (candidateElement.focused() != element.focused())
    229229        return false;
     230    if (candidateElement.hasFocusVisible() != element.hasFocusVisible())
     231        return false;
    230232    if (candidateElement.hasFocusWithin() != element.hasFocusWithin())
    231233        return false;
Note: See TracChangeset for help on using the changeset viewer.