From ab75cf8e8557980be98fd29ba10029acc8030e09 Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Wed, 11 Jan 2023 09:58:36 -0800 Subject: [PATCH] Implement dialog initial focus proposal This has been discussed here: https://github.com/whatwg/html/pull/4184 https://github.com/whatwg/html/pull/8199 The gist of the changes are: 1. Make the dialog focusing steps look at keyboard focusable elements instead of any focusable element. 2. Make the dialog element itself get focus if it has the autofocus attribute set. 3. Make the dialog element itself get focus as a fallback instead of focus being "reset" to the body element. Fixed: 1193482 Change-Id: I1fee5981f72039a4467cbb35b2317832dd31bbea --- .../anchor-position-top-layer-001.html | 1 + .../anchor-position-top-layer-002.html | 1 + .../anchor-position-top-layer-003.html | 1 + .../anchor-position-top-layer-004.html | 1 + .../anchor-position-top-layer-005.html | 1 + .../anchor-position-top-layer-006.html | 1 + ...content-visibility-with-top-layer-003.html | 1 + .../content-with-top-layer-ref.html | 1 + ...og-in-top-layer-during-transition-new.html | 2 + ...og-in-top-layer-during-transition-old.html | 2 + .../backdrop-stacking-order.html | 1 + .../child-sequential-focus.html | 110 +++++++++++++++++ .../dialog-focus-shadow.html | 112 +++++++++--------- ...alog-focusing-steps-prevent-autofocus.html | 2 +- .../the-dialog-element/dialog-showModal.html | 2 +- .../dont-share-style-to-top-layer-ref.html | 3 + .../dont-share-style-to-top-layer.html | 3 + ...-from-top-layer-has-original-position.html | 1 + ...-position-child-with-contain-ancestor.html | 3 + ...fixed-position-child-with-fo-ancestor.html | 3 + ...ition-child-with-transformed-ancestor.html | 3 + ...ition-child-with-will-change-ancestor.html | 3 + .../the-dialog-element/inert-label-focus.html | 9 +- .../inert-node-is-unfocusable.html | 5 + .../modal-dialog-backdrop.html | 1 + .../modal-dialog-generated-content.html | 1 + .../show-modal-focusing-steps.html | 4 +- .../top-layer-containing-block.html | 2 +- .../top-layer-display-none.html | 1 + .../the-dialog-element/top-layer-nesting.html | 1 + .../top-layer-parent-clip.html | 1 + .../top-layer-parent-filter.html | 1 + .../top-layer-parent-mask.html | 1 + .../top-layer-parent-opacity.html | 1 + .../top-layer-parent-overflow-clip.html | 1 + .../top-layer-parent-overflow-hidden.html | 1 + .../top-layer-parent-overflow-scroll.html | 1 + .../top-layer-parent-transform.html | 1 + ...r-stacking-correct-order-remove-readd.html | 1 + .../top-layer-stacking-dynamic.html | 1 + 40 files changed, 226 insertions(+), 66 deletions(-) create mode 100644 html/semantics/interactive-elements/the-dialog-element/child-sequential-focus.html diff --git a/css/css-anchor-position/anchor-position-top-layer-001.html b/css/css-anchor-position/anchor-position-top-layer-001.html index c96f6eef558f3c..ffa1c1cbd1eabd 100644 --- a/css/css-anchor-position/anchor-position-top-layer-001.html +++ b/css/css-anchor-position/anchor-position-top-layer-001.html @@ -22,6 +22,7 @@ height: 100px; background: lime; anchor-scroll: --a; + outline: none; } body { diff --git a/css/css-anchor-position/anchor-position-top-layer-002.html b/css/css-anchor-position/anchor-position-top-layer-002.html index e626e6b93566c7..849558f0f8c9e6 100644 --- a/css/css-anchor-position/anchor-position-top-layer-002.html +++ b/css/css-anchor-position/anchor-position-top-layer-002.html @@ -22,6 +22,7 @@ height: 100px; background: lime; anchor-scroll: --a; + outline: none; } body { diff --git a/css/css-anchor-position/anchor-position-top-layer-003.html b/css/css-anchor-position/anchor-position-top-layer-003.html index 39f3c362c7ba11..5012b52f5f9453 100644 --- a/css/css-anchor-position/anchor-position-top-layer-003.html +++ b/css/css-anchor-position/anchor-position-top-layer-003.html @@ -22,6 +22,7 @@ height: 100px; background: lime; anchor-scroll: --a; + outline: none; } body { diff --git a/css/css-anchor-position/anchor-position-top-layer-004.html b/css/css-anchor-position/anchor-position-top-layer-004.html index 8e189e0e7b7098..84e9296a1094bd 100644 --- a/css/css-anchor-position/anchor-position-top-layer-004.html +++ b/css/css-anchor-position/anchor-position-top-layer-004.html @@ -22,6 +22,7 @@ height: 100px; background: lime; anchor-scroll: --a; + outline: none; } body { diff --git a/css/css-anchor-position/anchor-position-top-layer-005.html b/css/css-anchor-position/anchor-position-top-layer-005.html index d9e4fa86e10dcc..6adf8961a4bdcf 100644 --- a/css/css-anchor-position/anchor-position-top-layer-005.html +++ b/css/css-anchor-position/anchor-position-top-layer-005.html @@ -35,6 +35,7 @@ border: 0; padding: 0; inset: auto; + outline: none; } dialog::backdrop { diff --git a/css/css-anchor-position/anchor-position-top-layer-006.html b/css/css-anchor-position/anchor-position-top-layer-006.html index 5f5cd67a1d709b..d2a39eae6d66ac 100644 --- a/css/css-anchor-position/anchor-position-top-layer-006.html +++ b/css/css-anchor-position/anchor-position-top-layer-006.html @@ -34,6 +34,7 @@ margin: 0; border: 0; padding: 0; + outline: none; } dialog::backdrop { diff --git a/css/css-contain/content-visibility/content-visibility-with-top-layer-003.html b/css/css-contain/content-visibility/content-visibility-with-top-layer-003.html index b8685954ff8356..7fb1f20b7ecd38 100644 --- a/css/css-contain/content-visibility/content-visibility-with-top-layer-003.html +++ b/css/css-contain/content-visibility/content-visibility-with-top-layer-003.html @@ -12,6 +12,7 @@
diff --git a/css/css-contain/content-visibility/content-with-top-layer-ref.html b/css/css-contain/content-visibility/content-with-top-layer-ref.html index 1a3cad327839c3..eadc5f65d1e8bd 100644 --- a/css/css-contain/content-visibility/content-with-top-layer-ref.html +++ b/css/css-contain/content-visibility/content-with-top-layer-ref.html @@ -4,6 +4,7 @@
diff --git a/css/css-view-transitions/dialog-in-top-layer-during-transition-new.html b/css/css-view-transitions/dialog-in-top-layer-during-transition-new.html index e84167a24892cb..0473209fa9df78 100644 --- a/css/css-view-transitions/dialog-in-top-layer-during-transition-new.html +++ b/css/css-view-transitions/dialog-in-top-layer-during-transition-new.html @@ -18,6 +18,8 @@ view-transition-name: dialog; contain: layout; + + outline: none; } #target::backdrop { diff --git a/css/css-view-transitions/dialog-in-top-layer-during-transition-old.html b/css/css-view-transitions/dialog-in-top-layer-during-transition-old.html index 672295cd3bd725..3634f65d8c99ae 100644 --- a/css/css-view-transitions/dialog-in-top-layer-during-transition-old.html +++ b/css/css-view-transitions/dialog-in-top-layer-during-transition-old.html @@ -18,6 +18,8 @@ view-transition-name: dialog; contain: layout; + + outline: none; } #target::backdrop { diff --git a/html/semantics/interactive-elements/the-dialog-element/backdrop-stacking-order.html b/html/semantics/interactive-elements/the-dialog-element/backdrop-stacking-order.html index 57cc63aab4802e..897f54a53fbaea 100644 --- a/html/semantics/interactive-elements/the-dialog-element/backdrop-stacking-order.html +++ b/html/semantics/interactive-elements/the-dialog-element/backdrop-stacking-order.html @@ -6,6 +6,7 @@ padding: 0px; border: none; margin: 0px; + outline: none; } #bottom::backdrop { diff --git a/html/semantics/interactive-elements/the-dialog-element/child-sequential-focus.html b/html/semantics/interactive-elements/the-dialog-element/child-sequential-focus.html new file mode 100644 index 00000000000000..4aed5273e87333 --- /dev/null +++ b/html/semantics/interactive-elements/the-dialog-element/child-sequential-focus.html @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + + + + + diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-focus-shadow.html b/html/semantics/interactive-elements/the-dialog-element/dialog-focus-shadow.html index e9ea15516e2711..7e5768542559a8 100644 --- a/html/semantics/interactive-elements/the-dialog-element/dialog-focus-shadow.html +++ b/html/semantics/interactive-elements/the-dialog-element/dialog-focus-shadow.html @@ -9,21 +9,21 @@ We focus this one between each test, to ensure that for non-modal dialogs, if there is no focus delegate, it stays focused (instead of causing focus to reset to the body). --> - + - + @@ -31,25 +31,25 @@ - + - + @@ -57,26 +57,26 @@ - + - + - + @@ -84,34 +84,34 @@ - + - + - + @@ -119,25 +119,25 @@ - + - + @@ -145,91 +145,91 @@ - + - + - + - + - + - +
- +
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html b/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html index c511631f9fbb71..5edff18614225d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html +++ b/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html @@ -116,7 +116,7 @@ d6.showModal(); this.add_cleanup(function() { d6.close(); }); assert_true(d6.open); - assert_equals(document.activeElement, document.body); + assert_equals(document.activeElement, d6); }, "opening dialog without focusable children"); test(function(){ diff --git a/html/semantics/interactive-elements/the-dialog-element/dont-share-style-to-top-layer-ref.html b/html/semantics/interactive-elements/the-dialog-element/dont-share-style-to-top-layer-ref.html index 535ac935607094..7e6112b3cee091 100644 --- a/html/semantics/interactive-elements/the-dialog-element/dont-share-style-to-top-layer-ref.html +++ b/html/semantics/interactive-elements/the-dialog-element/dont-share-style-to-top-layer-ref.html @@ -1,5 +1,8 @@

Test that a non-top layer element doesn't share style with a top layer element. The test passes if you see two boxes.

diff --git a/html/semantics/interactive-elements/the-dialog-element/element-removed-from-top-layer-has-original-position.html b/html/semantics/interactive-elements/the-dialog-element/element-removed-from-top-layer-has-original-position.html index d78051a9b3eec7..0dead331636355 100644 --- a/html/semantics/interactive-elements/the-dialog-element/element-removed-from-top-layer-has-original-position.html +++ b/html/semantics/interactive-elements/the-dialog-element/element-removed-from-top-layer-has-original-position.html @@ -14,6 +14,7 @@ border: none; padding: 0; margin: 0; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-contain-ancestor.html b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-contain-ancestor.html index 98835cb795fb0e..5ee64fc1d9e31d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-contain-ancestor.html +++ b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-contain-ancestor.html @@ -8,6 +8,9 @@ ::backdrop { display: none; } +#dialog { + outline: none; +} diff --git a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-fo-ancestor.html b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-fo-ancestor.html index fe625f1c9bfb49..2bc294be2fae16 100644 --- a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-fo-ancestor.html +++ b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-fo-ancestor.html @@ -8,6 +8,9 @@ ::backdrop { display: none; } +#dialog { + outline: none; +} diff --git a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-transformed-ancestor.html b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-transformed-ancestor.html index 58627443dae194..527d508252c15d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-transformed-ancestor.html +++ b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-transformed-ancestor.html @@ -8,6 +8,9 @@ ::backdrop { display: none; } +#dialog { + outline: none; +} diff --git a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-will-change-ancestor.html b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-will-change-ancestor.html index 14f4391e6bfbc2..e9db7321cd703d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-will-change-ancestor.html +++ b/html/semantics/interactive-elements/the-dialog-element/fixed-position-child-with-will-change-ancestor.html @@ -8,6 +8,9 @@ ::backdrop { display: none; } +#dialog { + outline: none; +} diff --git a/html/semantics/interactive-elements/the-dialog-element/inert-label-focus.html b/html/semantics/interactive-elements/the-dialog-element/inert-label-focus.html index 05f4069d78f57e..61e3ddeaf23e69 100644 --- a/html/semantics/interactive-elements/the-dialog-element/inert-label-focus.html +++ b/html/semantics/interactive-elements/the-dialog-element/inert-label-focus.html @@ -39,12 +39,15 @@ document.querySelector('#text').focus(); label = document.querySelector('label'); + submit = document.querySelector('#submit'); label.focus(); - assert_equals(document.activeElement, document.querySelector('#submit'), + assert_equals(document.activeElement, submit, 'label.focus() should send focus to the target.'); await clickOn(label); - assert_equals(document.activeElement, document.body, - 'Clicking the label should be the same as clicking the document body.'); + assert_not_equals(document.activeElement, label, + 'Clicking the label should not focus the label.'); + assert_not_equals(document.activeElement, submit, + 'Clicking the label should not focus the submit input.'); }, 'Tests focusing of an inert label for a non-inert target.'); diff --git a/html/semantics/interactive-elements/the-dialog-element/inert-node-is-unfocusable.html b/html/semantics/interactive-elements/the-dialog-element/inert-node-is-unfocusable.html index 56f31f35924974..74379f50e22c70 100644 --- a/html/semantics/interactive-elements/the-dialog-element/inert-node-is-unfocusable.html +++ b/html/semantics/interactive-elements/the-dialog-element/inert-node-is-unfocusable.html @@ -7,6 +7,11 @@ +
diff --git a/html/semantics/interactive-elements/the-dialog-element/modal-dialog-backdrop.html b/html/semantics/interactive-elements/the-dialog-element/modal-dialog-backdrop.html index a18af0d30ea45a..55d7132f8cefa6 100644 --- a/html/semantics/interactive-elements/the-dialog-element/modal-dialog-backdrop.html +++ b/html/semantics/interactive-elements/the-dialog-element/modal-dialog-backdrop.html @@ -7,6 +7,7 @@ height: 100px; width: 100px; background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/modal-dialog-generated-content.html b/html/semantics/interactive-elements/the-dialog-element/modal-dialog-generated-content.html index 86f43e52c2eb09..96b97f8ec3c490 100644 --- a/html/semantics/interactive-elements/the-dialog-element/modal-dialog-generated-content.html +++ b/html/semantics/interactive-elements/the-dialog-element/modal-dialog-generated-content.html @@ -11,6 +11,7 @@ height: 100px; width: 100px; background: green; + outline: none; } dialog::before { diff --git a/html/semantics/interactive-elements/the-dialog-element/show-modal-focusing-steps.html b/html/semantics/interactive-elements/the-dialog-element/show-modal-focusing-steps.html index 164b41459d1760..6a2ad8c4a0a4eb 100644 --- a/html/semantics/interactive-elements/the-dialog-element/show-modal-focusing-steps.html +++ b/html/semantics/interactive-elements/the-dialog-element/show-modal-focusing-steps.html @@ -10,10 +10,10 @@ outerButton = document.getElementById('outer-button'); assert_equals(document.activeElement, outerButton); - // Test that focus goes to body if the dialog has no focusable elements, including itself + // Test that focus goes to the dialog if the dialog has no focusable elements var outerDialog = document.getElementById('outer-dialog'); outerDialog.showModal(); - assert_equals(document.activeElement, document.body); + assert_equals(document.activeElement, outerDialog); // Test that an autofocus element in the dialog gets focus. var dialog = document.getElementById('dialog'); diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-containing-block.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-containing-block.html index 10f6c69fbe188a..0886c2cd2c2a0c 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-containing-block.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-containing-block.html @@ -14,7 +14,7 @@ This tests that a modal dialog's containing block is in the initial containing block and that it is unaffected by ancestor elements with overflow or opacity.
- + This dialog should be unaffected by its ancestor with opacity.
diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-display-none.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-display-none.html index 5257823eca00c3..ba790c1db9a561 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-display-none.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-display-none.html @@ -7,6 +7,7 @@ dialog { height: 150px; width: 150px; + outline: none; } ::backdrop { diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-nesting.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-nesting.html index 6397584387fc4b..9e0616e9520336 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-nesting.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-nesting.html @@ -7,6 +7,7 @@ dialog { height: 150px; width: 150px; + outline: none; } ::backdrop { diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-clip.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-clip.html index 9a621e7594eb23..6e3c52aa02a50d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-clip.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-clip.html @@ -15,6 +15,7 @@ dialog::backdrop, dialog { background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-filter.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-filter.html index 020d90a0c8121c..589d5397791ab4 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-filter.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-filter.html @@ -16,6 +16,7 @@ dialog { background: green; position: absolute; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-mask.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-mask.html index daa5ccbbe106dc..8ba3ed47c27750 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-mask.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-mask.html @@ -16,6 +16,7 @@ dialog::backdrop, dialog { background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-opacity.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-opacity.html index 82aa09d6c5729c..46c5de2a6dd54a 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-opacity.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-opacity.html @@ -16,6 +16,7 @@ dialog::backdrop, dialog { background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-clip.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-clip.html index 86587254cf0603..d80595496929d0 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-clip.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-clip.html @@ -21,6 +21,7 @@ dialog { background: green; position: absolute; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-hidden.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-hidden.html index afcde733d2f64a..f5389ddc09a234 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-hidden.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-hidden.html @@ -20,6 +20,7 @@ dialog::backdrop, dialog { background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-scroll.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-scroll.html index dd04c2ed47af56..a230defeeab10d 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-scroll.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-overflow-scroll.html @@ -21,6 +21,7 @@ dialog { background: green; position: absolute; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-transform.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-transform.html index cf35a713f33695..ac6f3cffc3ccc0 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-transform.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-parent-transform.html @@ -15,6 +15,7 @@ dialog::backdrop, dialog { background: green; + outline: none; } diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-correct-order-remove-readd.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-correct-order-remove-readd.html index 3b3e3368925573..4fdd28820dbb27 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-correct-order-remove-readd.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-correct-order-remove-readd.html @@ -8,6 +8,7 @@ dialog { height: 100px; width: 100px; + outline: none; } ::backdrop { diff --git a/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-dynamic.html b/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-dynamic.html index 8ab7068d306ab9..ebccdc66cf9f62 100644 --- a/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-dynamic.html +++ b/html/semantics/interactive-elements/the-dialog-element/top-layer-stacking-dynamic.html @@ -8,6 +8,7 @@ dialog { height: 150px; width: 150px; + outline: none; } ::backdrop {