forked from WebKit/WebKit-http
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the support for ShadowRoot.delegateFocus
https://bugs.webkit.org/show_bug.cgi?id=166484 <rdar://problem/29816058> Reviewed by Antti Koivisto. LayoutTests/imported/w3c: Import W3C tests from web-platform-tests/wpt@a8a89f2. * web-platform-tests/resources/testdriver-vendor.js: * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-click-method-expected.txt: Added. * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-click-method.html: Added. * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies-expected.txt: Added. * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies.html: Added. * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero-expected.txt: Added. * web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero.html: Added. * web-platform-tests/shadow-dom/focus/focus-method-delegatesFocus-expected.txt: Added. * web-platform-tests/shadow-dom/focus/focus-method-delegatesFocus.html: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-negative-delegatesFocus-expected.txt: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-negative-delegatesFocus.html: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-varying-delegatesFocus-expected.txt: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-varying-delegatesFocus.html: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-zero-delegatesFocus-expected.txt: Added. * web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-zero-delegatesFocus.html: Added. Source/WebCore: Implement delegatesFocus as specified in whatwg/html#4796 When the shadow root of an element has delegates focus flag set, focusing on the shadow host would automatically "delegates" focus to the first focusable element in the shadow tree instead. The first focusable element is determined as the first element that is programatically focusable or mouse focusable in the flat tree (composed tree in WebKit's terminology) in the case of the element getting focused via DOM API, Element.prototype.focus, by via mouse down. In the case of sequential focus navigation (via tab key), it's the first keyboard focusable element in the tabIndex order. Tests: imported/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-click-method.html imported/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies.html imported/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero.html imported/w3c/web-platform-tests/shadow-dom/focus/focus-method-delegatesFocus.html imported/w3c/web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-negative-delegatesFocus.html imported/w3c/web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-varying-delegatesFocus.html imported/w3c/web-platform-tests/shadow-dom/focus/focus-tabindex-order-shadow-zero-delegatesFocus.html * dom/Element.cpp: (WebCore::Element::isKeyboardFocusable const): A shadow host with the delegates focus flag is not considered as keyboard focusable. The rest is taken care of by the existing logic in FocusController. (WebCore::isProgramaticallyFocusable): Extracted from Element::focus. (WebCore::findFirstProgramaticallyFocusableElementInComposedTree): Added. (WebCore::Element::focus): Added the support for delegatesFocus. * dom/Element.h: (WebCore::ShadowRootInit::delegatesFocus): Added. * dom/Element.idl: Ditto. * dom/ShadowRoot.cpp: (WebCore::ShadowRoot::ShadowRoot): Added delegatesFocus to the constructor. * dom/ShadowRoot.h: * page/EventHandler.cpp: (WebCore::findFirstMouseFocusableElementInComposedTree): Added. (WebCore::EventHandler::dispatchMouseEvent): Added the support for delegatesFocus. Uses the first mouse focusable element in the flat tree (composed tree) order. * page/FocusController.cpp: (WebCore::FocusController::findFirstFocusableElementInShadowRoot): * page/FocusController.h: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251043 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
rniwa@webkit.org
committed
Oct 12, 2019
1 parent
73c7b7b
commit 22a6dba
Showing
23 changed files
with
780 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
.../web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-click-method-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
slotted | ||
outside | ||
|
||
PASS call click() on host with delegatesFocus, all tabindex=0 | ||
PASS call click() on slotted element in delegatesFocus shadow tree, all tabindex=0 | ||
|
67 changes: 67 additions & 0 deletions
67
...rted/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-click-method.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>HTML Test: click on shadow host with delegatesFocus</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/resources/testdriver.js"></script> | ||
<script src="/resources/testdriver-vendor.js"></script> | ||
<script src="resources/shadow-utils.js"></script> | ||
|
||
<body> | ||
<div id="host"> | ||
<div id="slotted">slotted</div> | ||
</div> | ||
<div id="outside">outside</div> | ||
</body> | ||
|
||
<script> | ||
const host = document.getElementById("host"); | ||
const slotted = document.getElementById("slotted"); | ||
|
||
const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true }); | ||
const aboveSlot = document.createElement("div"); | ||
aboveSlot.innerText = "aboveSlot"; | ||
const slot = document.createElement("slot"); | ||
shadowRoot.appendChild(aboveSlot); | ||
shadowRoot.appendChild(slot); | ||
|
||
const elementsInFlatTreeOrder = [host, aboveSlot, slot, slotted, outside]; | ||
|
||
// Final structure: | ||
// <div #host> (delegatesFocus=true) | ||
// #shadowRoot | ||
// <div #aboveSlot> | ||
// <slot #slot> | ||
// (slotted) <div #slotted> | ||
// <div #outside> | ||
|
||
function setAllTabIndex(value) { | ||
setTabIndex(elementsInFlatTreeOrder, value); | ||
} | ||
|
||
function removeAllTabIndex() { | ||
removeTabIndex(elementsInFlatTreeOrder); | ||
} | ||
|
||
function resetTabIndexAndFocus() { | ||
removeAllTabIndex(); | ||
resetFocus(document); | ||
resetFocus(shadowRoot); | ||
} | ||
|
||
test(() => { | ||
resetTabIndexAndFocus(); | ||
setAllTabIndex(0); | ||
host.click(); | ||
assert_equals(shadowRoot.activeElement, null); | ||
assert_equals(document.activeElement, document.body); | ||
}, "call click() on host with delegatesFocus, all tabindex=0"); | ||
|
||
test(() => { | ||
resetTabIndexAndFocus(); | ||
setAllTabIndex(0); | ||
slotted.click(); | ||
assert_equals(shadowRoot.activeElement, null); | ||
assert_equals(document.activeElement, document.body); | ||
}, "call click() on slotted element in delegatesFocus shadow tree, all tabindex=0"); | ||
</script> |
5 changes: 5 additions & 0 deletions
5
...b-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
slotted | ||
outside | ||
|
||
PASS click on host with delegatesFocus, #aboveSlot tabindex = 2, #slot and #slotted tabindex = 1 | ||
|
68 changes: 68 additions & 0 deletions
68
...d/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>HTML Test: click on shadow host with delegatesFocus</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/resources/testdriver.js"></script> | ||
<script src="/resources/testdriver-vendor.js"></script> | ||
<script src="resources/shadow-utils.js"></script> | ||
|
||
<body> | ||
<div id="host"> | ||
<div id="slotted">slotted</div> | ||
</div> | ||
<div id="outside">outside</div> | ||
</body> | ||
|
||
<script> | ||
const host = document.getElementById("host"); | ||
const slotted = document.getElementById("slotted"); | ||
|
||
const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true }); | ||
const aboveSlot = document.createElement("div"); | ||
aboveSlot.innerText = "aboveSlot"; | ||
const slot = document.createElement("slot"); | ||
// Add an unfocusable spacer, because test_driver.click will click on the | ||
// center point of #host, and we don't want the click to land on #aboveSlot | ||
// or #slot. | ||
const spacer = document.createElement("div"); | ||
spacer.style = "height: 1000px;"; | ||
shadowRoot.appendChild(spacer); | ||
shadowRoot.appendChild(aboveSlot); | ||
shadowRoot.appendChild(slot); | ||
|
||
const elementsInFlatTreeOrder = [host, aboveSlot, spacer, slot, slotted, outside]; | ||
|
||
// Final structure: | ||
// <div #host> (delegatesFocus=true) | ||
// #shadowRoot | ||
// <div #spacer> | ||
// <div #aboveSlot> | ||
// <slot #slot> | ||
// (slotted) <div #slotted> | ||
// <div #outside> | ||
|
||
function setAllTabIndex(value) { | ||
setTabIndex(elementsInFlatTreeOrder, value); | ||
} | ||
|
||
function removeAllTabIndex() { | ||
removeTabIndex(elementsInFlatTreeOrder); | ||
} | ||
|
||
function resetTabIndexAndFocus() { | ||
removeAllTabIndex(); | ||
resetFocus(document); | ||
resetFocus(shadowRoot); | ||
} | ||
|
||
promise_test(async () => { | ||
resetTabIndexAndFocus(); | ||
setTabIndex([aboveSlot], 2); | ||
setTabIndex([slot, slotted], 1); | ||
await test_driver.click(host); | ||
assert_equals(shadowRoot.activeElement, aboveSlot); | ||
assert_equals(document.activeElement, host); | ||
}, "click on host with delegatesFocus, #aboveSlot tabindex = 2, #slot and #slotted tabindex = 1"); | ||
|
||
</script> |
5 changes: 5 additions & 0 deletions
5
...web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
slotted | ||
outside | ||
|
||
PASS click on host with delegatesFocus, all tabindex=0 except spacer | ||
|
68 changes: 68 additions & 0 deletions
68
...ted/w3c/web-platform-tests/shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>HTML Test: click on shadow host with delegatesFocus</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/resources/testdriver.js"></script> | ||
<script src="/resources/testdriver-vendor.js"></script> | ||
<script src="resources/shadow-utils.js"></script> | ||
|
||
<body> | ||
<div id="host"> | ||
<div id="slotted">slotted</div> | ||
</div> | ||
<div id="outside">outside</div> | ||
</body> | ||
|
||
<script> | ||
const host = document.getElementById("host"); | ||
const slotted = document.getElementById("slotted"); | ||
|
||
const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true }); | ||
const aboveSlot = document.createElement("div"); | ||
aboveSlot.innerText = "aboveSlot"; | ||
const slot = document.createElement("slot"); | ||
// Add an unfocusable spacer, because test_driver.click will click on the | ||
// center point of #host, and we don't want the click to land on #aboveSlot | ||
// or #slot. | ||
const spacer = document.createElement("div"); | ||
spacer.style = "height: 1000px;"; | ||
shadowRoot.appendChild(spacer); | ||
shadowRoot.appendChild(aboveSlot); | ||
shadowRoot.appendChild(slot); | ||
|
||
const elementsInFlatTreeOrder = [host, aboveSlot, spacer, slot, slotted, outside]; | ||
|
||
// Final structure: | ||
// <div #host> (delegatesFocus=true) | ||
// #shadowRoot | ||
// <div #spacer> | ||
// <div #aboveSlot> | ||
// <slot #slot> | ||
// (slotted) <div #slotted> | ||
// <div #outside> | ||
|
||
function setAllTabIndex(value) { | ||
setTabIndex(elementsInFlatTreeOrder, value); | ||
} | ||
|
||
function removeAllTabIndex() { | ||
removeTabIndex(elementsInFlatTreeOrder); | ||
} | ||
|
||
function resetTabIndexAndFocus() { | ||
removeAllTabIndex(); | ||
resetFocus(document); | ||
resetFocus(shadowRoot); | ||
} | ||
|
||
promise_test(async () => { | ||
resetTabIndexAndFocus(); | ||
setAllTabIndex(0); | ||
removeTabIndex([spacer]); | ||
await test_driver.click(host); | ||
assert_equals(shadowRoot.activeElement, aboveSlot); | ||
assert_equals(document.activeElement, host); | ||
}, "click on host with delegatesFocus, all tabindex=0 except spacer"); | ||
|
||
</script> |
16 changes: 16 additions & 0 deletions
16
...imported/w3c/web-platform-tests/shadow-dom/focus/focus-method-delegatesFocus-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
slottedToSecondSlot | ||
slottedToFirstSlot | ||
outside | ||
|
||
PASS focus() on host with delegatesFocus, all tabindex=0 | ||
PASS focus() on host with delegatesFocus & tabindex =-1, all other tabindex=0 | ||
PASS focus() on host with delegatesFocus & no tabindex, all other tabindex=0 | ||
PASS focus() on host with delegatesFocus & tabindex = 0, all other tabindex=-1 | ||
PASS focus() on host with delegatesFocus, all without tabindex | ||
PASS focus() on host with delegatesFocus, all tabindex=-1 | ||
PASS focus() on host with delegatesFocus & tabindex=0, #belowSlots with tabindex=0 | ||
PASS focus() on host with delegatesFocus & tabindex=0, #outside with tabindex=0 | ||
PASS focus() on host with delegatesFocus & tabindex=0, #aboveSlots and #belowSlots with tabindex=0 | ||
PASS focus() on host with delegatesFocus & tabindex=0, #aboveSlots with tabindex=0 and #belowSlots with tabindex=1 | ||
PASS focus() on host with delegatesFocus & tabindex=0, #slottedToFirstSlot, #slottedToSecondSlot, #belowSlots with tabindex=0 | ||
|
Oops, something went wrong.