⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 283935 in webkit


Ignore:
Timestamp:
Oct 11, 2021, 1:59:43 PM (5 years ago)
Author:
ntim@apple.com
Message:

Implement new autofocus behavior
https://bugs.webkit.org/show_bug.cgi?id=203139
<rdar://problem/56397019>

Reviewed by Wenson Hsieh.

Make WebKit match the new autofocus spec:

The new autofocus behavior queues up all autofocusable elements (visible or not), then
fires autofocus asynchronously during the "update rendering" steps, unlike the old behavior
which runs focus synchronously whenever it finds a visible autofocusable element.

Original patch by Ryosuke Niwa.

LayoutTests/imported/w3c:

  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt:
  • web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
  • web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt: Expected change since input autofocus now places caret at start

Source/WebCore:

  • dom/Document.cpp:

(WebCore::Document::appendAutofocusCandidate):
(WebCore::Document::flushAutofocusCandidates):

  • dom/Document.h:

(WebCore::Document::isAutofocusProcessed const):
(WebCore::Document::setAutofocusProcessed):

  • dom/Element.cpp:

(WebCore::Element::runFocusingStepsForAutofocus):

  • dom/Element.h:
  • html/HTMLFormControlElement.cpp:

(WebCore::shouldAutofocus):
(WebCore::HTMLFormControlElement::didAttachRenderers):
(WebCore::HTMLFormControlElement::insertedIntoAncestor):
(WebCore::HTMLFormControlElement::runFocusingStepsForAutofocus):

  • html/HTMLFormControlElement.h:

(WebCore::HTMLFormControlElement::hasAutofocused const): Deleted.
(WebCore::HTMLFormControlElement::setAutofocused): Deleted.

  • page/Page.cpp:

(WebCore::Page::updateRendering):

  • page/Page.h:

LayoutTests:

  • TestExpectations:
  • fast/dom/Window/window-scroll-ignore-null-frame.html:
  • fast/dom/adopt-node-crash-2-expected.txt:
  • fast/dom/adopt-node-crash-2.html:
  • fast/dom/window-inner-width-crash.html:
  • fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt:
  • fast/forms/autofocus-in-sandbox-with-allow-scripts.html:
  • fast/forms/autofocus-keygen.html:
  • fast/forms/autofocus-opera-001.html:
  • fast/forms/autofocus-opera-002.html:
  • fast/forms/autofocus-opera-003.html:
  • fast/forms/autofocus-opera-006.html:
  • fast/forms/autofocus-opera-007.html:
  • fast/forms/change-input-type-in-focus-handler.html:
  • fast/frames/crash-when-iframe-is-remove-in-eventhandler.html:
  • fast/history/page-cache-execute-script-during-restore.html:
  • platform/ios-wk2/TestExpectations:
  • platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
  • platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt:
  • platform/mac-wk1/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
  • platform/win/TestExpectations:
Location:
trunk
Files:
1 deleted
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r283918 r283935  
     12021-10-11  Tim Nguyen  <ntim@apple.com>
     2
     3        Implement new autofocus behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=203139
     5        <rdar://problem/56397019>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Make WebKit match the new autofocus spec:
     10        - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
     11        - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
     12
     13        The new autofocus behavior queues up all autofocusable elements (visible or not), then
     14        fires autofocus asynchronously during the "update rendering" steps, unlike the old behavior
     15        which runs focus synchronously whenever it finds a visible autofocusable element.
     16
     17        Original patch by Ryosuke Niwa.
     18
     19        * TestExpectations:
     20        * fast/dom/Window/window-scroll-ignore-null-frame.html:
     21        * fast/dom/adopt-node-crash-2-expected.txt:
     22        * fast/dom/adopt-node-crash-2.html:
     23        * fast/dom/window-inner-width-crash.html:
     24        * fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt:
     25        * fast/forms/autofocus-in-sandbox-with-allow-scripts.html:
     26        * fast/forms/autofocus-keygen.html:
     27        * fast/forms/autofocus-opera-001.html:
     28        * fast/forms/autofocus-opera-002.html:
     29        * fast/forms/autofocus-opera-003.html:
     30        * fast/forms/autofocus-opera-006.html:
     31        * fast/forms/autofocus-opera-007.html:
     32        * fast/forms/change-input-type-in-focus-handler.html:
     33        * fast/frames/crash-when-iframe-is-remove-in-eventhandler.html:
     34        * fast/history/page-cache-execute-script-during-restore.html:
     35        * platform/ios-wk2/TestExpectations:
     36        * platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
     37        * platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt:
     38        * platform/mac-wk1/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
     39        * platform/win/TestExpectations:
     40
    1412021-10-11  Ayumi Kojima  <ayumi_kojima@apple.com>
    242
  • trunk/LayoutTests/TestExpectations

    r283892 r283935  
    807807imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/combination_history_003.html [ Failure Pass ]
    808808imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html [ Failure Pass ]
    809 imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html [ Failure Pass ]
    810809imported/w3c/web-platform-tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html [ Failure Pass ]
    811810imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html [ Failure Pass ]
  • trunk/LayoutTests/fast/dom/Window/window-scroll-ignore-null-frame.html

    r255334 r283935  
    33
    44function runTest() {
    5     if (window.testRunner)
     5    if (window.testRunner) {
    66        testRunner.dumpAsText();
     7        testRunner.waitUntilDone();
     8    }
    79
    810    select1.appendChild(inputParent);
     
    1012    input1.setSelectionRange(1, 0);
    1113    document.body.appendChild(input1);
    12     frame1.contentWindow.scrollBy({left: 1, top: 0});
     14    requestAnimationFrame(() => {
     15        frame1.contentWindow.scrollBy({left: 1, top: 0});
     16        if (window.testRunner)
     17            testRunner.notifyDone();
     18    });
    1319}
    1420
  • trunk/LayoutTests/fast/dom/adopt-node-crash-2-expected.txt

    r234485 r283935  
    1 Tests for a crash due to adopting a DOM node during DOMFocusOut event. Test passes if it doesn't crash.
     1Tests for a crash due to adopting a DOM node when unfocusing. Test passes if it doesn't crash.
    22
     3PASS: Focused node should be keygen
     4PASS: Focused node should no longer be keygen
  • trunk/LayoutTests/fast/dom/adopt-node-crash-2.html

    r268400 r283935  
    11<!DOCTYPE html><!-- webkit-test-runner [ KeygenElementEnabled=true ] -->
    22<html>
    3 <div>Tests for a crash due to adopting a DOM node during DOMFocusOut event. Test passes if it doesn't crash.</div>
     3<div>Tests for a crash due to adopting a DOM node when unfocusing. Test passes if it doesn't crash.</div>
    44<script>
    55if (window.testRunner) {
     
    1515  </applet>
    1616  <header id="header1">
    17     <keygen autofocus>
     17    <keygen id="keygen" autofocus>
    1818  </header>
    1919</div>
     20<div id="logs"></div>
    2021<script>
    21 function doit()
    22 {
    23     div2.addEventListener("DOMFocusOut", function () {
    24         document.implementation.createDocument("", "", null).adoptNode(div2);
    25         setTimeout(() => {
    26             if (window.internals)
    27                 internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
    28             if (window.testRunner)
    29                 testRunner.notifyDone();
    30         }, 0);
    31     }, false);
     22function assert_true(assert, text) {
     23    const div = document.createElement("div");
     24    if (assert)
     25        div.textContent = "PASS: " + text;
     26    else
     27        div.textContent = "FAIL: " + text;
     28    logs.append(div);
     29}
     30
     31function doit() {
     32    assert_true(document.activeElement == keygen, "Focused node should be keygen");
    3233    div1.outerHTML = header1.outerHTML;
     34    assert_true(document.activeElement != keygen, "Focused node should no longer be keygen");
     35    document.implementation.createDocument("", "", null).adoptNode(div2);
     36    if (window.internals)
     37        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
     38    if (window.testRunner)
     39        testRunner.notifyDone();
    3340}
    3441window.onload = function() {
    35     if (window.internals)
    36         internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
    37     else
    38         div2.getBoundingClientRect();
    39     setTimeout("doit()", 1);
    40 }
     42    requestAnimationFrame(doit);
     43};
    4144</script>
    4245</html>
  • trunk/LayoutTests/fast/dom/window-inner-width-crash.html

    r245509 r283935  
    77
    88function runTest() {
    9     button.autofocus = true;
    109    body.appendChild(paragraph);
     10    button.focus();
    1111    var testVal = window[0].innerWidth;
    1212}
  • trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt

    r272607 r283935  
    1 CONSOLE MESSAGE: INPUT
    2 This test passes if the activeElement is the input element rather than the body (which it would be if the sandbox didn't allow autofocus although allow-scripts flag is set).
     1This tests having an input element with autofocus content attribute inside a sandboxed iframe.
     2The input element should be autofocused since scripts are allowed.
     3
     4--------
     5Frame: '<!--frame1-->'
     6--------
     7PASS
  • trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts.html

    r272607 r283935  
    11<script>
    2 if (window.testRunner)
     2if (window.testRunner) {
    33    testRunner.dumpAsText();
     4    testRunner.dumpChildFramesAsText();
     5}
    46</script>
    5 This test passes if the activeElement is the input element rather than the body
    6 (which it would be if the sandbox didn't allow autofocus although allow-scripts flag is set).
    7 <iframe sandbox="allow-scripts allow-modals"
    8     src="data:text/html,<input autofocus onfocus><script>window.onload = function() { console.log(document.activeElement.tagName) }</script>"></iframe>
     7This tests having an input element with autofocus content attribute inside a sandboxed iframe.<br>
     8The input element should be autofocused since scripts are allowed.
     9<iframe sandbox="allow-scripts"
     10    src="data:text/html,<input id=input autofocus onfocus><script>
     11    if (window.testRunner)
     12        testRunner.waitUntilDone();
     13    window.onload = function () {
     14        requestAnimationFrame(() => {
     15            document.body.append(document.activeElement == input ? 'PASS' : 'FAIL');
     16            if (window.testRunner)
     17                testRunner.notifyDone();
     18        });
     19    }</script>"></iframe>
  • trunk/LayoutTests/fast/forms/autofocus-keygen.html

    r268400 r283935  
    77
    88function onLoad() {
    9     shouldBe('document.activeElement', 'document.querySelector("keygen")');
    10     shouldBe('document.activeElement.autofocus', 'true');
    11     finishJSTest();
     9    requestAnimationFrame(() => {
     10        shouldBe('document.activeElement', 'document.querySelector("keygen")');
     11        shouldBe('document.activeElement.autofocus', 'true');
     12        finishJSTest();
     13    });
    1214}
    1315</script>
  • trunk/LayoutTests/fast/forms/autofocus-opera-001.html

    r283659 r283935  
    1212
    1313    function test() {
    14         if (window.testRunner)
     14        if (window.testRunner) {
    1515            testRunner.dumpAsText();
     16            testRunner.waitUntilDone();
     17        }
    1618
    17         if (document.activeElement == document.getElementsByTagName("input")[0])
    18             log("SUCCESS");
    19         else
    20             log("FAILURE");
     19        requestAnimationFrame(() => {
     20            if (document.activeElement == document.getElementsByTagName("input")[0])
     21                log("SUCCESS");
     22            else
     23                log("FAILURE");
     24            if (window.testRunner)
     25                testRunner.notifyDone();
     26        });
    2127    }
    2228</script>
  • trunk/LayoutTests/fast/forms/autofocus-opera-002.html

    r283659 r283935  
    1212
    1313    function test() {
    14         if (window.testRunner)
     14        if (window.testRunner) {
    1515            testRunner.dumpAsText();
     16            testRunner.waitUntilDone();
     17        }
    1618
    17         if (document.activeElement == document.getElementsByTagName("input")[0])
    18             log("SUCCESS");
    19         else
    20             log("FAILURE");
     19        requestAnimationFrame(() => {
     20            if (document.activeElement == document.getElementsByTagName("input")[0])
     21                log("SUCCESS");
     22            else
     23                log("FAILURE");
     24            if (window.testRunner)
     25                testRunner.notifyDone();
     26        });
    2127    }
    2228</script>
  • trunk/LayoutTests/fast/forms/autofocus-opera-003.html

    r283659 r283935  
    1313
    1414    function test() {
    15         if (window.testRunner)
     15        if (window.testRunner) {
    1616            testRunner.dumpAsText();
     17            testRunner.waitUntilDone();
     18        }
    1719
    18         if (document.activeElement == document.getElementsByTagName("input")[0] &&
    19             document.scrollingElement.scrollTop != 0)
    20             log("SUCCESS");
    21         else
    22             log("FAILURE");
     20        requestAnimationFrame(() => {
     21            if (document.activeElement == document.getElementsByTagName("input")[0] &&
     22                document.scrollingElement.scrollTop != 0)
     23                log("SUCCESS");
     24            else
     25                log("FAILURE");
     26            if (window.testRunner)
     27                testRunner.notifyDone();
     28        });
    2329    }
    2430</script>
  • trunk/LayoutTests/fast/forms/autofocus-opera-006.html

    r283659 r283935  
    1212
    1313    function test() {
    14         if (window.testRunner)
     14        if (window.testRunner) {
    1515            testRunner.dumpAsText();
     16            testRunner.waitUntilDone();
     17        }
    1618
    17         if (document.activeElement == document.getElementById("test"))
    18             log("SUCCESS");
    19         else
    20             log("FAILURE");
     19        requestAnimationFrame(() => {
     20            if (document.activeElement == document.getElementById("test"))
     21                log("SUCCESS");
     22            else
     23                log("FAILURE");
     24            if (window.testRunner)
     25                testRunner.notifyDone();
     26        });
     27
    2128    }
    2229</script>
     
    2431<body onload="test()">
    2532<p>All form controls below should have a green background:</p>
    26 <p><input autofocus>
     33<p><input autofocus id="test">
    2734<p><input autofocus>
    2835<p><input autofocus>
    2936<p><input>
    30 <p><input autofocus id="test">
     37<p><input autofocus>
    3138<p><input>
    3239<hr/>
  • trunk/LayoutTests/fast/forms/autofocus-opera-007.html

    r283659 r283935  
    1818
    1919    function test() {
    20         if (window.testRunner)
     20        if (window.testRunner) {
    2121            testRunner.dumpAsText();
     22            testRunner.waitUntilDone();
     23        }
    2224
    23         if (gotBlur)
    24             log("SUCCESS");
    25         else
    26             log("FAILURE");
     25        requestAnimationFrame(() => {
     26            if (gotBlur)
     27                log("SUCCESS");
     28            else
     29                log("FAILURE");
     30            if (window.testRunner)
     31                testRunner.notifyDone();
     32        });
    2733    }
    2834</script>
  • trunk/LayoutTests/fast/forms/change-input-type-in-focus-handler.html

    r222114 r283935  
    1111    if (input.autofocus) {
    1212        input.type = "checkbox";
    13         document.body.innerHTML = "<code style='color: green'>PASS</code>";
     13        document.body.innerHTML = "FAIL - focus event handler called for autofocus";
     14        if (window.testRunner)
     15            testRunner.notifyDone();
    1416        return;
    1517    }
     
    1719    document.body.appendChild(input);
    1820    input.autofocus = true;
     21    requestAnimationFrame(() => {
     22        document.body.textContent = document.activeElement == document.body ? "PASS" : "FAIL";
     23        if (window.testRunner)
     24            testRunner.notifyDone();
     25    });
    1926}
    2027
    21 if (window.testRunner)
     28if (window.testRunner) {
    2229    testRunner.dumpAsText();
     30    testRunner.waitUntilDone();
     31}
    2332
    2433input.focus();
  • trunk/LayoutTests/fast/frames/crash-when-iframe-is-remove-in-eventhandler.html

    r225719 r283935  
    77<textarea id=textarea onfocus="eventhandler()"></textarea>
    88<script>
    9 if (window.testRunner)
     9if (window.testRunner) {
    1010    testRunner.dumpAsText();
     11    testRunner.waitUntilDone();
     12}
     13
    1114document.offsetHeight;
    1215textarea.autofocus = true;
     
    1417span.appendChild(iframe);
    1518wrapper.appendChild(textarea);
     19requestAnimationFrame(() => {
     20    if (window.testRunner)
     21        testRunner.notifyDone();
     22});
    1623iframe.contentDocument.caretRangeFromPoint();
    1724
  • trunk/LayoutTests/fast/history/page-cache-execute-script-during-restore.html

    r268400 r283935  
    1717
    1818window.addEventListener("pageshow", (event) => {
    19     if (event.persisted)
     19    if (event.persisted) {
     20        requestAnimationFrame(finish);
    2021        return;
     22    }
    2123    if (window.testRunner)
    2224        setTimeout(runTest, 0);
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r283916 r283935  
     12021-10-11  Tim Nguyen  <ntim@apple.com>
     2
     3        Implement new autofocus behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=203139
     5        <rdar://problem/56397019>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Make WebKit match the new autofocus spec:
     10        - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
     11        - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
     12
     13        The new autofocus behavior queues up all autofocusable elements (visible or not), then
     14        fires autofocus asynchronously during the "update rendering" steps, unlike the old behavior
     15        which runs focus synchronously whenever it finds a visible autofocusable element.
     16
     17        Original patch by Ryosuke Niwa.
     18
     19        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt:
     20        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt:
     21        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt:
     22        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt:
     23        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt:
     24        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt:
     25        * web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt:
     26        * web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt: Expected change since input autofocus now places caret at start
     27
    1282021-10-11  Ben Nham  <nham@apple.com>
    229
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt

    r279427 r283935  
    11
    22
    3 FAIL Autofocus elements in iframed documents with empty fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
     3PASS Autofocus elements in iframed documents with empty fragments should work.
    44PASS Autofocus elements in top-level browsing context's documents with empty fragments should work.
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt

    r279427 r283935  
    11
    22
    3 FAIL Autofocus elements in iframed documents with non-existent fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
     3PASS Autofocus elements in iframed documents with non-existent fragments should work.
    44PASS Autofocus elements in top-level browsing context's documents with non-existent fragments should work.
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt

    r279427 r283935  
    11
    22
    3 FAIL Autofocus elements in iframed documents with "top" fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
     3PASS Autofocus elements in iframed documents with "top" fragments should work.
    44PASS Autofocus elements in top-level browsing context's documents with "top" fragments should work.
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt

    r267646 r283935  
    11
    22
    3 FAIL The first autofocus element in the document should win. assert_equals: expected Element node <input autofocus=""></input> but got Element node <input autofocus=""></input>
     3PASS The first autofocus element in the document should win.
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt

    r267646 r283935  
    11
    22
    3 FAIL The first autofocus in the document wins, even if elements are inserted later. assert_equals: expected Element node <input autofocus=""></input> but got Element node <input autofocus=""></input>
     3PASS The first autofocus in the document wins, even if elements are inserted later.
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt

    r267646 r283935  
    11
    22
    3 FAIL If the first autofocus element is not focusable, but becomes focusable before a frame, it should be focused. assert_equals: expected Element node <textarea autofocus=""></textarea> but got Element node <select autofocus=""></select>
     3PASS If the first autofocus element is not focusable, but becomes focusable before a frame, it should be focused.
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt

    r250823 r283935  
    11
     2PASS "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks
    23
    3 FAIL "Flush autofocus candidates" should be happen after the first animation frame callbacks, and before a resize event in the next iteration of window event loop. assert_array_equals: lengths differ, expected 3 got 4
    4 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt

    r266784 r283935  
    1010layer at (5,605) size 141x13
    1111  RenderBlock {DIV} at (3,3) size 141x13
    12 caret: position 1 of body
     12caret: position 0 of child 0 {DIV} of {#document-fragment} of child 2 {INPUT} of child 0 {HTML} of document
     13scrolled to 0,23
  • trunk/LayoutTests/platform/ios-wk2/TestExpectations

    r283918 r283935  
    20632063webkit.org/b/227998 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-network-error.sub.html [ Pass Failure ]
    20642064
    2065 webkit.org/b/227762 [ Debug ] imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html [ Pass Failure ]
     2065webkit.org/b/227762 imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html [ Pass Failure ]
    20662066
    20672067webkit.org/b/226789 imported/w3c/web-platform-tests/webstorage/event_case_sensitive.html [ Pass Failure ]
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt

    r250823 r283935  
    11
     2FAIL "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks assert_array_equals: autofocus,animationFrame lengths differ, expected array ["autofocus", "scroll", "animationFrame"] length 3, got ["autofocus", "animationFrame"] length 2
    23
    3 FAIL "Flush autofocus candidates" should be happen after the first animation frame callbacks, and before a resize event in the next iteration of window event loop. assert_array_equals: property 0, expected "animationFrame" but got "autofocus"
    4 
  • trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt

    r279795 r283935  
    1010layer at (9,605) size 141x14
    1111  RenderBlock {DIV} at (6,3) size 143x15
    12 caret: position 1 of body
     12caret: position 0 of child 0 {DIV} of {#document-fragment} of child 2 {INPUT} of child 0 {HTML} of document
  • trunk/LayoutTests/platform/win/TestExpectations

    r283799 r283935  
    46084608fast/inline/crash-when-negative-spacing-produce-nan.html [ Timeout ]
    46094609imported/blink/fast/dom/Window/open-window-features-fuzz.html [ Timeout ]
    4610 
     4610fast/forms/form-submission-crash-3.html [ Timeout ]
    46114611
    46124612webkit.org/b/227896 fast/text/pua-charactersTreatedAsSpace.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r283930 r283935  
     12021-10-11  Tim Nguyen  <ntim@apple.com>
     2
     3        Implement new autofocus behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=203139
     5        <rdar://problem/56397019>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Make WebKit match the new autofocus spec:
     10        - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
     11        - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
     12
     13        The new autofocus behavior queues up all autofocusable elements (visible or not), then
     14        fires autofocus asynchronously during the "update rendering" steps, unlike the old behavior
     15        which runs focus synchronously whenever it finds a visible autofocusable element.
     16
     17        Original patch by Ryosuke Niwa.
     18
     19        * dom/Document.cpp:
     20        (WebCore::Document::appendAutofocusCandidate):
     21        (WebCore::Document::flushAutofocusCandidates):
     22        * dom/Document.h:
     23        (WebCore::Document::isAutofocusProcessed const):
     24        (WebCore::Document::setAutofocusProcessed):
     25        * dom/Element.cpp:
     26        (WebCore::Element::runFocusingStepsForAutofocus):
     27        * dom/Element.h:
     28        * html/HTMLFormControlElement.cpp:
     29        (WebCore::shouldAutofocus):
     30        (WebCore::HTMLFormControlElement::didAttachRenderers):
     31        (WebCore::HTMLFormControlElement::insertedIntoAncestor):
     32        (WebCore::HTMLFormControlElement::runFocusingStepsForAutofocus):
     33        * html/HTMLFormControlElement.h:
     34        (WebCore::HTMLFormControlElement::hasAutofocused const): Deleted.
     35        (WebCore::HTMLFormControlElement::setAutofocused): Deleted.
     36        * page/Page.cpp:
     37        (WebCore::Page::updateRendering):
     38        * page/Page.h:
     39
    1402021-10-11  Alex Christensen  <achristensen@webkit.org>
    241
  • trunk/Source/WebCore/dom/Document.cpp

    r283851 r283935  
    44714471}
    44724472
     4473void Document::appendAutofocusCandidate(Element& candidate)
     4474{
     4475    ASSERT(isTopDocument());
     4476    ASSERT(!m_isAutofocusProcessed);
     4477    auto it = m_autofocusCandidates.findIf([&candidate](auto& c) {
     4478        return c == &candidate;
     4479    });
     4480    if (it != m_autofocusCandidates.end())
     4481        m_autofocusCandidates.remove(it);
     4482    m_autofocusCandidates.append(makeWeakPtr(candidate));
     4483}
     4484
     4485void Document::flushAutofocusCandidates()
     4486{
     4487    ASSERT(isTopDocument());
     4488    if (m_isAutofocusProcessed)
     4489        return;
     4490    while (!m_autofocusCandidates.isEmpty()) {
     4491        RefPtr element = m_autofocusCandidates.takeFirst().get();
     4492        if (!element || !element->document().isFullyActive() || &element->document().topDocument() != this)
     4493            continue;
     4494        if (auto* parser = scriptableDocumentParser(); parser && parser->hasScriptsWaitingForStylesheets())
     4495            break;
     4496        // FIXME: Need to ignore if the inclusive ancestor documents has a target element.
     4497        // FIXME: Use the result of getting the focusable area for element if element is not focusable.
     4498        if (element->isFocusable()) {
     4499            m_autofocusCandidates.clear();
     4500            setAutofocusProcessed();
     4501            element->runFocusingStepsForAutofocus();
     4502            return;
     4503        }
     4504    }
     4505}
     4506
    44734507void Document::hoveredElementDidDetach(Element& element)
    44744508{
  • trunk/Source/WebCore/dom/Document.h

    r283526 r283935  
    789789    void adjustFocusNavigationNodeOnNodeRemoval(Node&, NodeRemoval = NodeRemoval::Node);
    790790
     791    bool isAutofocusProcessed() const { return m_isAutofocusProcessed; }
     792    void setAutofocusProcessed() { m_isAutofocusProcessed = true; }
     793    void appendAutofocusCandidate(Element&);
     794    void flushAutofocusCandidates();
     795
    791796    void hoveredElementDidDetach(Element&);
    792797    void elementInActiveChainDidDetach(Element&);
     
    18021807
    18031808    RefPtr<Node> m_focusNavigationStartingNode;
     1809    Deque<WeakPtr<Element>> m_autofocusCandidates;
    18041810    RefPtr<Element> m_focusedElement;
    18051811    RefPtr<Element> m_hoveredElement;
     
    21132119    bool m_isSynthesized { false };
    21142120    bool m_isNonRenderedPlaceholder { false };
     2121
     2122    bool m_isAutofocusProcessed { false };
    21152123
    21162124    bool m_sawElementsInKnownNamespaces { false };
  • trunk/Source/WebCore/dom/Element.cpp

    r283851 r283935  
    31773177}
    31783178
     3179void Element::runFocusingStepsForAutofocus()
     3180{
     3181    focus();
     3182}
     3183
    31793184void Element::dispatchFocusInEvent(const AtomString& eventType, RefPtr<Element>&& oldFocusedElement)
    31803185{
  • trunk/Source/WebCore/dom/Element.h

    r283851 r283935  
    423423    virtual void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode = SelectionRevealMode::Reveal);
    424424    virtual void blur();
     425    virtual void runFocusingStepsForAutofocus();
    425426
    426427    WEBCORE_EXPORT String innerHTML() const;
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r283851 r283935  
    7373    , m_isValid(true)
    7474    , m_wasChangedSinceLastFormControlChangeEvent(false)
    75     , m_hasAutofocused(false)
    7675{
    7776    setHasCustomStyleResolveCallbacks();
     
    204203static bool shouldAutofocus(const HTMLFormControlElement& element)
    205204{
    206     if (!element.renderer())
    207         return false;
    208205    if (!element.hasAttributeWithoutSynchronization(autofocusAttr))
    209206        return false;
    210207
    211208    auto& document = element.document();
    212     if (!element.isConnected() || !document.renderView())
     209    if (!element.isConnected() || !document.hasBrowsingContext())
    213210        return false;
    214211    if (document.isSandboxed(SandboxAutomaticFeatures)) {
     
    222219    }
    223220
    224     if (element.hasAutofocused())
     221    if (document.topDocument().isAutofocusProcessed())
    225222        return false;
    226223
    227     // FIXME: Should this set of hasTagName checks be replaced by a
    228     // virtual member function?
     224    // FIXME: autofocus is a global attribute.
    229225    if (is<HTMLInputElement>(element))
    230226        return !downcast<HTMLInputElement>(element).isInputTypeHidden();
     
    248244    if (renderer())
    249245        renderer()->updateFromElement();
    250 
    251     if (shouldAutofocus(*this)) {
    252         setAutofocused();
    253 
    254         RefPtr<HTMLFormControlElement> element = this;
    255         RefPtr frameView = document().view();
    256         if (frameView && frameView->layoutContext().isInLayout()) {
    257             frameView->queuePostLayoutCallback([element] {
    258                 element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
    259             });
    260         } else {
    261             Style::deprecatedQueuePostResolutionCallback([element] {
    262                 element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
    263             });
    264         }
    265     }
    266246}
    267247
     
    302282    HTMLElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
    303283    FormAssociatedElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
     284
     285    if (shouldAutofocus(*this))
     286        document().topDocument().appendAutofocusCandidate(*this);
     287
    304288    return InsertedIntoAncestorResult::NeedsPostInsertionCallback;
    305289}
     
    395379    return false;
    396380#endif
     381}
     382
     383void HTMLFormControlElement::runFocusingStepsForAutofocus()
     384{
     385    focus({ SelectionRestorationMode::PlaceCaretAtStart });
    397386}
    398387
  • trunk/Source/WebCore/html/HTMLFormControlElement.h

    r283851 r283935  
    117117    bool isDisabledOrReadOnly() const { return isDisabledFormControl() || m_isReadOnly; }
    118118
    119     bool hasAutofocused() const { return m_hasAutofocused; }
    120     void setAutofocused() { m_hasAutofocused = true; }
    121 
    122119    WEBCORE_EXPORT String autocomplete() const;
    123120    WEBCORE_EXPORT void setAutocomplete(const String&);
     
    171168    void derefFormAssociatedElement() override { deref(); }
    172169
     170    void runFocusingStepsForAutofocus() final;
     171
    173172    bool matchesValidPseudoClass() const override;
    174173    bool matchesInvalidPseudoClass() const override;
     
    216215
    217216    unsigned m_wasChangedSinceLastFormControlChangeEvent : 1;
    218 
    219     unsigned m_hasAutofocused : 1;
    220217};
    221218
  • trunk/Source/WebCore/page/Page.cpp

    r283522 r283935  
    15611561    };
    15621562
    1563     // FIXME: Flush autofocus candidates.
     1563    runProcessingStep(RenderingUpdateStep::FlushAutofocusCandidates, [] (Document& document) {
     1564        if (document.isTopDocument())
     1565            document.flushAutofocusCandidates();
     1566    });
    15641567
    15651568    runProcessingStep(RenderingUpdateStep::Resize, [] (Document& document) {
     
    36063609{
    36073610    switch (step) {
     3611    case RenderingUpdateStep::FlushAutofocusCandidates: ts << "FlushAutofocusCandidates"; break;
    36083612    case RenderingUpdateStep::Resize: ts << "Resize"; break;
    36093613    case RenderingUpdateStep::Scroll: ts << "Scroll"; break;
  • trunk/Source/WebCore/page/Page.h

    r283522 r283935  
    209209    ScrollingTreeUpdate             = 1 << 13,
    210210#endif
     211    FlushAutofocusCandidates        = 1 << 14,
    211212};
    212213
    213214constexpr OptionSet<RenderingUpdateStep> updateRenderingSteps = {
     215    RenderingUpdateStep::FlushAutofocusCandidates,
    214216    RenderingUpdateStep::Resize,
    215217    RenderingUpdateStep::Scroll,
Note: See TracChangeset for help on using the changeset viewer.