Diff
Modified: trunk/LayoutTests/ChangeLog (283934 => 283935)
--- trunk/LayoutTests/ChangeLog 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/ChangeLog 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,3 +1,43 @@
+2021-10-11 Tim Nguyen <n...@apple.com>
+
+ 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:
+ - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
+ - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
+
+ 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.
+
+ * 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:
+
2021-10-11 Ayumi Kojima <ayumi_koj...@apple.com>
[ iOS BigSur wk1 ] webgl/1.0.3/conformance/uniforms/uniform-default-values.html is flaky timing out.
Modified: trunk/LayoutTests/TestExpectations (283934 => 283935)
--- trunk/LayoutTests/TestExpectations 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/TestExpectations 2021-10-11 20:59:43 UTC (rev 283935)
@@ -806,7 +806,6 @@
imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/combination_history_002.html [ Failure Pass ]
imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/combination_history_003.html [ Failure Pass ]
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html [ Failure Pass ]
-imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html [ Failure Pass ]
imported/w3c/web-platform-tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html [ Failure Pass ]
imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html [ Failure Pass ]
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/cross-origin-to-whom.window.html [ Failure Pass ]
Modified: trunk/LayoutTests/fast/dom/Window/window-scroll-ignore-null-frame.html (283934 => 283935)
--- trunk/LayoutTests/fast/dom/Window/window-scroll-ignore-null-frame.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/dom/Window/window-scroll-ignore-null-frame.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -2,14 +2,20 @@
<script>
function runTest() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
select1.appendChild(inputParent);
input1.autofocus = true;
input1.setSelectionRange(1, 0);
document.body.appendChild(input1);
- frame1.contentWindow.scrollBy({left: 1, top: 0});
+ requestAnimationFrame(() => {
+ frame1.contentWindow.scrollBy({left: 1, top: 0});
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
</script>
Modified: trunk/LayoutTests/fast/dom/adopt-node-crash-2-expected.txt (283934 => 283935)
--- trunk/LayoutTests/fast/dom/adopt-node-crash-2-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/dom/adopt-node-crash-2-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,2 +1,4 @@
-Tests for a crash due to adopting a DOM node during DOMFocusOut event. Test passes if it doesn't crash.
+Tests for a crash due to adopting a DOM node when unfocusing. Test passes if it doesn't crash.
+PASS: Focused node should be keygen
+PASS: Focused node should no longer be keygen
Modified: trunk/LayoutTests/fast/dom/adopt-node-crash-2.html (283934 => 283935)
--- trunk/LayoutTests/fast/dom/adopt-node-crash-2.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/dom/adopt-node-crash-2.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,6 +1,6 @@
<!DOCTYPE html><!-- webkit-test-runner [ KeygenElementEnabled=true ] -->
<html>
-<div>Tests for a crash due to adopting a DOM node during DOMFocusOut event. Test passes if it doesn't crash.</div>
+<div>Tests for a crash due to adopting a DOM node when unfocusing. Test passes if it doesn't crash.</div>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
@@ -14,29 +14,32 @@
</iframe>
</applet>
<header id="header1">
- <keygen autofocus>
+ <keygen id="keygen" autofocus>
</header>
</div>
+<div id="logs"></div>
<script>
-function doit()
-{
- div2.addEventListener("DOMFocusOut", function () {
- document.implementation.createDocument("", "", null).adoptNode(div2);
- setTimeout(() => {
- if (window.internals)
- internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
- if (window.testRunner)
- testRunner.notifyDone();
- }, 0);
- }, false);
+function assert_true(assert, text) {
+ const div = document.createElement("div");
+ if (assert)
+ div.textContent = "PASS: " + text;
+ else
+ div.textContent = "FAIL: " + text;
+ logs.append(div);
+}
+
+function doit() {
+ assert_true(document.activeElement == keygen, "Focused node should be keygen");
div1.outerHTML = header1.outerHTML;
-}
-window._onload_ = function() {
+ assert_true(document.activeElement != keygen, "Focused node should no longer be keygen");
+ document.implementation.createDocument("", "", null).adoptNode(div2);
if (window.internals)
internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
- else
- div2.getBoundingClientRect();
- setTimeout("doit()", 1);
+ if (window.testRunner)
+ testRunner.notifyDone();
}
+window._onload_ = function() {
+ requestAnimationFrame(doit);
+};
</script>
</html>
Modified: trunk/LayoutTests/fast/dom/window-inner-width-crash.html (283934 => 283935)
--- trunk/LayoutTests/fast/dom/window-inner-width-crash.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/dom/window-inner-width-crash.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -6,8 +6,8 @@
testRunner.dumpAsText();
function runTest() {
- button.autofocus = true;
body.appendChild(paragraph);
+ button.focus();
var testVal = window[0].innerWidth;
}
Modified: trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,2 +1,7 @@
-CONSOLE MESSAGE: INPUT
-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).
+This tests having an input element with autofocus content attribute inside a sandboxed iframe.
+The input element should be autofocused since scripts are allowed.
+
+--------
+Frame: '<!--frame1-->'
+--------
+PASS
Modified: trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-in-sandbox-with-allow-scripts.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,8 +1,19 @@
<script>
-if (window.testRunner)
+if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.dumpChildFramesAsText();
+}
</script>
-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).
-<iframe sandbox="allow-scripts allow-modals"
- src="" autofocus onfocus><script>window._onload_ = function() { console.log(document.activeElement.tagName) }</script>"></iframe>
+This tests having an input element with autofocus content attribute inside a sandboxed iframe.<br>
+The input element should be autofocused since scripts are allowed.
+<iframe sandbox="allow-scripts"
+ src="" id=input autofocus onfocus><script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ window._onload_ = function () {
+ requestAnimationFrame(() => {
+ document.body.append(document.activeElement == input ? 'PASS' : 'FAIL');
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+ }</script>"></iframe>
Modified: trunk/LayoutTests/fast/forms/autofocus-keygen.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-keygen.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-keygen.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -6,9 +6,11 @@
window.jsTestIsAsync = true;
function onLoad() {
- shouldBe('document.activeElement', 'document.querySelector("keygen")');
- shouldBe('document.activeElement.autofocus', 'true');
- finishJSTest();
+ requestAnimationFrame(() => {
+ shouldBe('document.activeElement', 'document.querySelector("keygen")');
+ shouldBe('document.activeElement.autofocus', 'true');
+ finishJSTest();
+ });
}
</script>
</head>
Modified: trunk/LayoutTests/fast/forms/autofocus-opera-001.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-opera-001.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-opera-001.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -11,13 +11,19 @@
}
function test() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
- if (document.activeElement == document.getElementsByTagName("input")[0])
- log("SUCCESS");
- else
- log("FAILURE");
+ requestAnimationFrame(() => {
+ if (document.activeElement == document.getElementsByTagName("input")[0])
+ log("SUCCESS");
+ else
+ log("FAILURE");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
</script>
</head>
Modified: trunk/LayoutTests/fast/forms/autofocus-opera-002.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-opera-002.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-opera-002.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -11,13 +11,19 @@
}
function test() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
- if (document.activeElement == document.getElementsByTagName("input")[0])
- log("SUCCESS");
- else
- log("FAILURE");
+ requestAnimationFrame(() => {
+ if (document.activeElement == document.getElementsByTagName("input")[0])
+ log("SUCCESS");
+ else
+ log("FAILURE");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
</script>
</head>
Modified: trunk/LayoutTests/fast/forms/autofocus-opera-003.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-opera-003.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-opera-003.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -12,14 +12,20 @@
}
function test() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
- if (document.activeElement == document.getElementsByTagName("input")[0] &&
- document.scrollingElement.scrollTop != 0)
- log("SUCCESS");
- else
- log("FAILURE");
+ requestAnimationFrame(() => {
+ if (document.activeElement == document.getElementsByTagName("input")[0] &&
+ document.scrollingElement.scrollTop != 0)
+ log("SUCCESS");
+ else
+ log("FAILURE");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
</script>
</head>
Modified: trunk/LayoutTests/fast/forms/autofocus-opera-006.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-opera-006.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-opera-006.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -11,24 +11,31 @@
}
function test() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
- if (document.activeElement == document.getElementById("test"))
- log("SUCCESS");
- else
- log("FAILURE");
+ requestAnimationFrame(() => {
+ if (document.activeElement == document.getElementById("test"))
+ log("SUCCESS");
+ else
+ log("FAILURE");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+
}
</script>
</head>
<body _onload_="test()">
<p>All form controls below should have a green background:</p>
+<p><input autofocus id="test">
<p><input autofocus>
<p><input autofocus>
+<p><input>
<p><input autofocus>
<p><input>
-<p><input autofocus id="test">
-<p><input>
<hr/>
<ol id="console"></ol>
</body>
Modified: trunk/LayoutTests/fast/forms/autofocus-opera-007.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/autofocus-opera-007.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/autofocus-opera-007.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -17,13 +17,19 @@
}
function test() {
- if (window.testRunner)
+ if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
- if (gotBlur)
- log("SUCCESS");
- else
- log("FAILURE");
+ requestAnimationFrame(() => {
+ if (gotBlur)
+ log("SUCCESS");
+ else
+ log("FAILURE");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
</script>
</head>
Modified: trunk/LayoutTests/fast/forms/change-input-type-in-focus-handler.html (283934 => 283935)
--- trunk/LayoutTests/fast/forms/change-input-type-in-focus-handler.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/forms/change-input-type-in-focus-handler.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -10,16 +10,25 @@
function focused() {
if (input.autofocus) {
input.type = "checkbox";
- document.body.innerHTML = "<code style='color: green'>PASS</code>";
+ document.body.innerHTML = "FAIL - focus event handler called for autofocus";
+ if (window.testRunner)
+ testRunner.notifyDone();
return;
}
document.body.appendChild(input);
input.autofocus = true;
+ requestAnimationFrame(() => {
+ document.body.textContent = document.activeElement == document.body ? "PASS" : "FAIL";
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
}
-if (window.testRunner)
+if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
input.focus();
</script>
Modified: trunk/LayoutTests/fast/frames/crash-when-iframe-is-remove-in-eventhandler.html (283934 => 283935)
--- trunk/LayoutTests/fast/frames/crash-when-iframe-is-remove-in-eventhandler.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/frames/crash-when-iframe-is-remove-in-eventhandler.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -6,13 +6,20 @@
<span id=wrapper></span>
<textarea id=textarea _onfocus_="eventhandler()"></textarea>
<script>
-if (window.testRunner)
+if (window.testRunner) {
testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
document.offsetHeight;
textarea.autofocus = true;
var iframe = document.createElement("iframe");
span.appendChild(iframe);
wrapper.appendChild(textarea);
+requestAnimationFrame(() => {
+ if (window.testRunner)
+ testRunner.notifyDone();
+});
iframe.contentDocument.caretRangeFromPoint();
function eventhandler() {
Modified: trunk/LayoutTests/fast/history/page-cache-execute-script-during-restore.html (283934 => 283935)
--- trunk/LayoutTests/fast/history/page-cache-execute-script-during-restore.html 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/fast/history/page-cache-execute-script-during-restore.html 2021-10-11 20:59:43 UTC (rev 283935)
@@ -16,8 +16,10 @@
}
window.addEventListener("pageshow", (event) => {
- if (event.persisted)
+ if (event.persisted) {
+ requestAnimationFrame(finish);
return;
+ }
if (window.testRunner)
setTimeout(runTest, 0);
});
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,3 +1,30 @@
+2021-10-11 Tim Nguyen <n...@apple.com>
+
+ 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:
+ - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
+ - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
+
+ 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.
+
+ * 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
+
2021-10-11 Ben Nham <n...@apple.com>
Add push registration stubs
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,5 +1,5 @@
-FAIL Autofocus elements in iframed documents with empty fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
+PASS Autofocus elements in iframed documents with empty fragments should work.
PASS Autofocus elements in top-level browsing context's documents with empty fragments should work.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,5 +1,5 @@
-FAIL Autofocus elements in iframed documents with non-existent fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
+PASS Autofocus elements in iframed documents with non-existent fragments should work.
PASS Autofocus elements in top-level browsing context's documents with non-existent fragments should work.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,5 +1,5 @@
-FAIL Autofocus elements in iframed documents with "top" fragments should work. assert_not_equals: got disallowed value Element node <input autofocus=""></input>
+PASS Autofocus elements in iframed documents with "top" fragments should work.
PASS Autofocus elements in top-level browsing context's documents with "top" fragments should work.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,4 +1,4 @@
-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>
+PASS The first autofocus element in the document should win.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/first-when-later-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,4 +1,4 @@
-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>
+PASS The first autofocus in the document wins, even if elements are inserted later.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,4 +1,4 @@
-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>
+PASS If the first autofocus element is not focusable, but becomes focusable before a frame, it should be focused.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,4 +1,3 @@
+PASS "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks
-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
-
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt (283934 => 283935)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -9,4 +9,5 @@
RenderTextControl {INPUT} at (2,2) size 147x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
layer at (5,605) size 141x13
RenderBlock {DIV} at (3,3) size 141x13
-caret: position 1 of body
+caret: position 0 of child 0 {DIV} of {#document-fragment} of child 2 {INPUT} of child 0 {HTML} of document
+scrolled to 0,23
Modified: trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt (283934 => 283935)
--- trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/selection/selection-select-all-move-input-crash-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -9,4 +9,4 @@
RenderTextControl {INPUT} at (2,2) size 155x22 [bgcolor=#FFFFFF] [border: (1px solid #3C3C4399)]
layer at (9,605) size 141x14
RenderBlock {DIV} at (6,3) size 143x15
-caret: position 1 of body
+caret: position 0 of child 0 {DIV} of {#document-fragment} of child 2 {INPUT} of child 0 {HTML} of document
Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (283934 => 283935)
--- trunk/LayoutTests/platform/ios-wk2/TestExpectations 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations 2021-10-11 20:59:43 UTC (rev 283935)
@@ -2062,7 +2062,7 @@
webkit.org/b/227998 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-network-error.sub.html [ Pass Failure ]
-webkit.org/b/227762 [ Debug ] imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html [ Pass Failure ]
+webkit.org/b/227762 imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html [ Pass Failure ]
webkit.org/b/226789 imported/w3c/web-platform-tests/webstorage/event_case_sensitive.html [ Pass Failure ]
Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt (283934 => 283935)
--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering-expected.txt 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,4 +1,3 @@
+FAIL "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
-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"
-
Modified: trunk/LayoutTests/platform/win/TestExpectations (283934 => 283935)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-10-11 20:59:43 UTC (rev 283935)
@@ -4607,8 +4607,8 @@
fast/events/wheel/redispatched-wheel-event.html [ Timeout ]
fast/inline/crash-when-negative-spacing-produce-nan.html [ Timeout ]
imported/blink/fast/dom/Window/open-window-features-fuzz.html [ Timeout ]
+fast/forms/form-submission-crash-3.html [ Timeout ]
-
webkit.org/b/227896 fast/text/pua-charactersTreatedAsSpace.html [ ImageOnlyFailure ]
webkit.org/b/227802 imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/top-layer-display-none.html [ ImageOnlyFailure ]
Modified: trunk/Source/WebCore/ChangeLog (283934 => 283935)
--- trunk/Source/WebCore/ChangeLog 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/ChangeLog 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1,3 +1,42 @@
+2021-10-11 Tim Nguyen <n...@apple.com>
+
+ 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:
+ - https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
+ - https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
+
+ 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.
+
+ * 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:
+
2021-10-11 Alex Christensen <achristen...@webkit.org>
Unified build fix
Modified: trunk/Source/WebCore/dom/Document.cpp (283934 => 283935)
--- trunk/Source/WebCore/dom/Document.cpp 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/dom/Document.cpp 2021-10-11 20:59:43 UTC (rev 283935)
@@ -4470,6 +4470,40 @@
}
}
+void Document::appendAutofocusCandidate(Element& candidate)
+{
+ ASSERT(isTopDocument());
+ ASSERT(!m_isAutofocusProcessed);
+ auto it = m_autofocusCandidates.findIf([&candidate](auto& c) {
+ return c == &candidate;
+ });
+ if (it != m_autofocusCandidates.end())
+ m_autofocusCandidates.remove(it);
+ m_autofocusCandidates.append(makeWeakPtr(candidate));
+}
+
+void Document::flushAutofocusCandidates()
+{
+ ASSERT(isTopDocument());
+ if (m_isAutofocusProcessed)
+ return;
+ while (!m_autofocusCandidates.isEmpty()) {
+ RefPtr element = m_autofocusCandidates.takeFirst().get();
+ if (!element || !element->document().isFullyActive() || &element->document().topDocument() != this)
+ continue;
+ if (auto* parser = scriptableDocumentParser(); parser && parser->hasScriptsWaitingForStylesheets())
+ break;
+ // FIXME: Need to ignore if the inclusive ancestor documents has a target element.
+ // FIXME: Use the result of getting the focusable area for element if element is not focusable.
+ if (element->isFocusable()) {
+ m_autofocusCandidates.clear();
+ setAutofocusProcessed();
+ element->runFocusingStepsForAutofocus();
+ return;
+ }
+ }
+}
+
void Document::hoveredElementDidDetach(Element& element)
{
if (!m_hoveredElement || &element != m_hoveredElement)
Modified: trunk/Source/WebCore/dom/Document.h (283934 => 283935)
--- trunk/Source/WebCore/dom/Document.h 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/dom/Document.h 2021-10-11 20:59:43 UTC (rev 283935)
@@ -788,6 +788,11 @@
void adjustFocusedNodeOnNodeRemoval(Node&, NodeRemoval = NodeRemoval::Node);
void adjustFocusNavigationNodeOnNodeRemoval(Node&, NodeRemoval = NodeRemoval::Node);
+ bool isAutofocusProcessed() const { return m_isAutofocusProcessed; }
+ void setAutofocusProcessed() { m_isAutofocusProcessed = true; }
+ void appendAutofocusCandidate(Element&);
+ void flushAutofocusCandidates();
+
void hoveredElementDidDetach(Element&);
void elementInActiveChainDidDetach(Element&);
@@ -1801,6 +1806,7 @@
std::unique_ptr<DOMImplementation> m_implementation;
RefPtr<Node> m_focusNavigationStartingNode;
+ Deque<WeakPtr<Element>> m_autofocusCandidates;
RefPtr<Element> m_focusedElement;
RefPtr<Element> m_hoveredElement;
RefPtr<Element> m_activeElement;
@@ -2113,6 +2119,8 @@
bool m_isSynthesized { false };
bool m_isNonRenderedPlaceholder { false };
+ bool m_isAutofocusProcessed { false };
+
bool m_sawElementsInKnownNamespaces { false };
bool m_isSrcdocDocument { false };
Modified: trunk/Source/WebCore/dom/Element.cpp (283934 => 283935)
--- trunk/Source/WebCore/dom/Element.cpp 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/dom/Element.cpp 2021-10-11 20:59:43 UTC (rev 283935)
@@ -3176,6 +3176,11 @@
}
}
+void Element::runFocusingStepsForAutofocus()
+{
+ focus();
+}
+
void Element::dispatchFocusInEvent(const AtomString& eventType, RefPtr<Element>&& oldFocusedElement)
{
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed() || !isInWebProcess());
Modified: trunk/Source/WebCore/dom/Element.h (283934 => 283935)
--- trunk/Source/WebCore/dom/Element.h 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/dom/Element.h 2021-10-11 20:59:43 UTC (rev 283935)
@@ -422,6 +422,7 @@
virtual RefPtr<Element> focusAppearanceUpdateTarget();
virtual void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode = SelectionRevealMode::Reveal);
virtual void blur();
+ virtual void runFocusingStepsForAutofocus();
WEBCORE_EXPORT String innerHTML() const;
WEBCORE_EXPORT String outerHTML() const;
Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (283934 => 283935)
--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp 2021-10-11 20:59:43 UTC (rev 283935)
@@ -72,7 +72,6 @@
, m_willValidate(true)
, m_isValid(true)
, m_wasChangedSinceLastFormControlChangeEvent(false)
- , m_hasAutofocused(false)
{
setHasCustomStyleResolveCallbacks();
}
@@ -203,13 +202,11 @@
static bool shouldAutofocus(const HTMLFormControlElement& element)
{
- if (!element.renderer())
- return false;
if (!element.hasAttributeWithoutSynchronization(autofocusAttr))
return false;
auto& document = element.document();
- if (!element.isConnected() || !document.renderView())
+ if (!element.isConnected() || !document.hasBrowsingContext())
return false;
if (document.isSandboxed(SandboxAutomaticFeatures)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
@@ -221,11 +218,10 @@
return false;
}
- if (element.hasAutofocused())
+ if (document.topDocument().isAutofocusProcessed())
return false;
- // FIXME: Should this set of hasTagName checks be replaced by a
- // virtual member function?
+ // FIXME: autofocus is a global attribute.
if (is<HTMLInputElement>(element))
return !downcast<HTMLInputElement>(element).isInputTypeHidden();
if (element.hasTagName(selectTag))
@@ -247,22 +243,6 @@
// on the renderer.
if (renderer())
renderer()->updateFromElement();
-
- if (shouldAutofocus(*this)) {
- setAutofocused();
-
- RefPtr<HTMLFormControlElement> element = this;
- RefPtr frameView = document().view();
- if (frameView && frameView->layoutContext().isInLayout()) {
- frameView->queuePostLayoutCallback([element] {
- element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
- });
- } else {
- Style::deprecatedQueuePostResolutionCallback([element] {
- element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
- });
- }
- }
}
void HTMLFormControlElement::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
@@ -301,6 +281,10 @@
setAncestorDisabled(computeIsDisabledByFieldsetAncestor());
HTMLElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
FormAssociatedElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
+
+ if (shouldAutofocus(*this))
+ document().topDocument().appendAutofocusCandidate(*this);
+
return InsertedIntoAncestorResult::NeedsPostInsertionCallback;
}
@@ -396,6 +380,11 @@
#endif
}
+void HTMLFormControlElement::runFocusingStepsForAutofocus()
+{
+ focus({ SelectionRestorationMode::PlaceCaretAtStart });
+}
+
bool HTMLFormControlElement::matchesValidPseudoClass() const
{
return willValidate() && isValidFormControlElement();
Modified: trunk/Source/WebCore/html/HTMLFormControlElement.h (283934 => 283935)
--- trunk/Source/WebCore/html/HTMLFormControlElement.h 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.h 2021-10-11 20:59:43 UTC (rev 283935)
@@ -116,9 +116,6 @@
bool isReadOnly() const { return m_isReadOnly; }
bool isDisabledOrReadOnly() const { return isDisabledFormControl() || m_isReadOnly; }
- bool hasAutofocused() const { return m_hasAutofocused; }
- void setAutofocused() { m_hasAutofocused = true; }
-
WEBCORE_EXPORT String autocomplete() const;
WEBCORE_EXPORT void setAutocomplete(const String&);
@@ -170,6 +167,8 @@
void refFormAssociatedElement() override { ref(); }
void derefFormAssociatedElement() override { deref(); }
+ void runFocusingStepsForAutofocus() final;
+
bool matchesValidPseudoClass() const override;
bool matchesInvalidPseudoClass() const override;
@@ -215,8 +214,6 @@
unsigned m_isValid : 1;
unsigned m_wasChangedSinceLastFormControlChangeEvent : 1;
-
- unsigned m_hasAutofocused : 1;
};
class DelayedUpdateValidityScope {
Modified: trunk/Source/WebCore/page/Page.cpp (283934 => 283935)
--- trunk/Source/WebCore/page/Page.cpp 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/page/Page.cpp 2021-10-11 20:59:43 UTC (rev 283935)
@@ -1560,7 +1560,10 @@
forEachDocument(perDocumentFunction);
};
- // FIXME: Flush autofocus candidates.
+ runProcessingStep(RenderingUpdateStep::FlushAutofocusCandidates, [] (Document& document) {
+ if (document.isTopDocument())
+ document.flushAutofocusCandidates();
+ });
runProcessingStep(RenderingUpdateStep::Resize, [] (Document& document) {
document.runResizeSteps();
@@ -3605,6 +3608,7 @@
WTF::TextStream& operator<<(WTF::TextStream& ts, RenderingUpdateStep step)
{
switch (step) {
+ case RenderingUpdateStep::FlushAutofocusCandidates: ts << "FlushAutofocusCandidates"; break;
case RenderingUpdateStep::Resize: ts << "Resize"; break;
case RenderingUpdateStep::Scroll: ts << "Scroll"; break;
case RenderingUpdateStep::MediaQueryEvaluation: ts << "MediaQueryEvaluation"; break;
Modified: trunk/Source/WebCore/page/Page.h (283934 => 283935)
--- trunk/Source/WebCore/page/Page.h 2021-10-11 20:37:27 UTC (rev 283934)
+++ trunk/Source/WebCore/page/Page.h 2021-10-11 20:59:43 UTC (rev 283935)
@@ -208,9 +208,11 @@
#if ENABLE(ASYNC_SCROLLING)
ScrollingTreeUpdate = 1 << 13,
#endif
+ FlushAutofocusCandidates = 1 << 14,
};
constexpr OptionSet<RenderingUpdateStep> updateRenderingSteps = {
+ RenderingUpdateStep::FlushAutofocusCandidates,
RenderingUpdateStep::Resize,
RenderingUpdateStep::Scroll,
RenderingUpdateStep::MediaQueryEvaluation,