Diff
Modified: trunk/LayoutTests/ChangeLog (269058 => 269059)
--- trunk/LayoutTests/ChangeLog 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/LayoutTests/ChangeLog 2020-10-27 18:51:38 UTC (rev 269059)
@@ -1,3 +1,23 @@
+2020-10-27 Tetsuharu Ohzeki <[email protected]>
+
+ Accessory bar next/previous buttons do not work on inputs in shadow roots
+ https://bugs.webkit.org/show_bug.cgi?id=203292
+
+ Reviewed by Ryosuke Niwa.
+
+ Introduced testcases only need to run with iOS family.
+
+ * fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree-expected.txt: Added.
+ * fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html: Added.
+ * TestExpectations:
+ * platform/ios/TestExpectations:
+ Avoid to run introduced tests because we don't have to run them and
+ tests are crashed on these platforms.
+ * resources/ui-helper.js:
+ (window.UIHelper.moveToNextByKeyboardAccessoryBar):
+ (window.UIHelper.moveToPrevByKeyboardAccessoryBar):
+ (window.UIHelper):
+
2020-10-27 Philippe Normand <[email protected]>
[GStreamer] Bad handling of audio files in the ImageDecoder
Modified: trunk/LayoutTests/TestExpectations (269058 => 269059)
--- trunk/LayoutTests/TestExpectations 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/LayoutTests/TestExpectations 2020-10-27 18:51:38 UTC (rev 269059)
@@ -4524,3 +4524,6 @@
fast/layoutformattingcontext/ [ ImageOnlyFailure ]
webkit.org/b/217054 fast/layoutformattingcontext/horizontal-sizing-with-trailing-letter-spacing.html [ Skip ]
+
+# These tests are for iOS port.
+fast/shadow-dom/ios/ [ Skip ]
Added: trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree-expected.txt (0 => 269059)
--- trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree-expected.txt 2020-10-27 18:51:38 UTC (rev 269059)
@@ -0,0 +1,106 @@
+Test that Accessory bar next/previous buttons work on inputs which is not assigned to any slot in shadow tree
+
+To manually test, do following steps.
+
+Focus the 1st of input, then Accessory bar will shown.
+Press "next" icon 4 times.
+Press "prev" icon 4 times.
+It should traverse focusable elements in the increasing numerical order and reverse the order of them.
+
+
+
+
+
+
+Test that Accessory bar next/previous buttons work on inputs which is not assigned to any slot in shadow tree
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+activate 0th input
+activated 0th input
+forward to 1th input
+documentOrShadowRoot.activeElement's placeholder attribute: 1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+forward to 2th input
+documentOrShadowRoot.activeElement's placeholder attribute: 2. input element having a positive tabindex in a element having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 2. input element having a positive tabindex in a element having a positive tabindex
+forward to 3th input
+documentOrShadowRoot.activeElement's placeholder attribute: 3. input element having tabindex=1 in a element having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 3. input element having tabindex=1 in a element having a positive tabindex
+forward to 4th input
+documentOrShadowRoot.activeElement's placeholder attribute: 4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+forward to 5th input
+documentOrShadowRoot.activeElement's placeholder attribute: 5. input element having a positive tabindex in a shadow tree host which does not tabindex
+PASS () => activeElement.getAttribute('placeholder') is 5. input element having a positive tabindex in a shadow tree host which does not tabindex
+forward to 6th input
+documentOrShadowRoot.activeElement's placeholder attribute: 6. input element in closed shadow tree host
+PASS () => activeElement.getAttribute('placeholder') is 6. input element in closed shadow tree host
+forward to 7th input
+documentOrShadowRoot.activeElement's placeholder attribute: 7. input element before nested custom element having shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 7. input element before nested custom element having shadow tree
+forward to 8th input
+documentOrShadowRoot.activeElement's placeholder attribute: 8. input element in nested shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 8. input element in nested shadow tree
+forward to 9th input
+documentOrShadowRoot.activeElement's placeholder attribute: 9. input element after nested custom element having shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 9. input element after nested custom element having shadow tree
+forward to 10th input
+documentOrShadowRoot.activeElement's placeholder attribute: 10. Last sequentially input element outside shadow trees
+PASS () => activeElement.getAttribute('placeholder') is 10. Last sequentially input element outside shadow trees
+focus has moved to the last element and will move to the first reversely
+back to 9th input
+documentOrShadowRoot.activeElement's placeholder attribute: 9. input element after nested custom element having shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 9. input element after nested custom element having shadow tree
+back to 8th input
+documentOrShadowRoot.activeElement's placeholder attribute: 8. input element in nested shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 8. input element in nested shadow tree
+back to 7th input
+documentOrShadowRoot.activeElement's placeholder attribute: 7. input element before nested custom element having shadow tree
+PASS () => activeElement.getAttribute('placeholder') is 7. input element before nested custom element having shadow tree
+back to 6th input
+documentOrShadowRoot.activeElement's placeholder attribute: 6. input element in closed shadow tree host
+PASS () => activeElement.getAttribute('placeholder') is 6. input element in closed shadow tree host
+back to 5th input
+documentOrShadowRoot.activeElement's placeholder attribute: 5. input element having a positive tabindex in a shadow tree host which does not tabindex
+PASS () => activeElement.getAttribute('placeholder') is 5. input element having a positive tabindex in a shadow tree host which does not tabindex
+back to 4th input
+documentOrShadowRoot.activeElement's placeholder attribute: 4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+back to 3th input
+documentOrShadowRoot.activeElement's placeholder attribute: 3. input element having tabindex=1 in a element having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 3. input element having tabindex=1 in a element having a positive tabindex
+back to 2th input
+documentOrShadowRoot.activeElement's placeholder attribute: 2. input element having a positive tabindex in a element having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 2. input element having a positive tabindex in a element having a positive tabindex
+back to 1th input
+documentOrShadowRoot.activeElement's placeholder attribute: 1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+PASS () => activeElement.getAttribute('placeholder') is 1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+back to 0th input
+documentOrShadowRoot.activeElement's placeholder attribute: 0. First sequentially input element outside shadow trees
+PASS () => activeElement.getAttribute('placeholder') is 0. First sequentially input element outside shadow trees
+PASS successfullyParsed is true
+
+TEST COMPLETE
+0. First sequentially input element outside shadow trees
+1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+2. input element having a positive tabindex in a element having a positive tabindex
+3. input element having tabindex=1 in a element having a positive tabindex
+4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+5. input element having a positive tabindex in a shadow tree host which does not tabindex
+6. input element in closed shadow tree host
+7. input element before nested custom element having shadow tree
+8. input element in nested shadow tree
+9. input element after nested custom element having shadow tree
+10. Last sequentially input element outside shadow trees
+9. input element after nested custom element having shadow tree
+8. input element in nested shadow tree
+7. input element before nested custom element having shadow tree
+6. input element in closed shadow tree host
+5. input element having a positive tabindex in a shadow tree host which does not tabindex
+4. input element having tabindex=0 in a shadow tree host having a positive tabindex
+3. input element having tabindex=1 in a element having a positive tabindex
+2. input element having a positive tabindex in a element having a positive tabindex
+1. input element having a positive tabindex in a shadow tree host having a positive tabindex
+0. First sequentially input element outside shadow trees
+
Added: trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html (0 => 269059)
--- trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html 2020-10-27 18:51:38 UTC (rev 269059)
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<h1>Test that Accessory bar next/previous buttons work on inputs which is not assigned to any slot in shadow tree</h1>
+<p>To manually test, do following steps.</p>
+<ol>
+ <li>Focus the 1st of input, then Accessory bar will shown.</li>
+ <li>Press "next" icon 4 times.</li>
+ <li>Press "prev" icon 4 times.</li>
+ <li>It should traverse focusable elements in the increasing numerical order and reverse the order of them.</li>
+</ol>
+
+<input id="first" tabindex="1" _onfocus_="logOnFocus(this)"
+ placeholder="0. First sequentially input element outside shadow trees" />
+
+<div id="host-with-negative-tabindex" tabindex="-1">Should not focus: Shadow host with a negative tabindex but not input element</div>
+
+<div id="host-with-no-tabindex">
+ <input id="host-with-no-tabindex"
+ _onfocus_="logOnFocus(this)"
+ placeholder="Should not focus: input element having no tabindex in a element having no tabindex but will not assigned to slot" />
+</div>
+
+<div id="host-with-positive-tabindex" tabindex="2">
+ <div>
+ <input id="input-in-host-with-positive-tabindex-negative"
+ tabindex="-1"
+ _onfocus_="logOnFocus(this)"
+ placeholder="Should not focus: input element having a negative tabindex in a element having a positive tabindex" />
+ </div>
+ <div>
+ <input id="input-in-host-with-positive-tabindex"
+ tabindex="0"
+ _onfocus_="logOnFocus(this)"
+ placeholder="3. input element having tabindex=1 in a element having a positive tabindex" />
+ </div>
+ <div>
+ <input id="input-in-host-with-positive-tabindex-positive"
+ tabindex="1"
+ _onfocus_="logOnFocus(this)"
+ placeholder="2. input element having a positive tabindex in a element having a positive tabindex" />
+ </div>
+</div>
+
+<div id="closed-shadow-tree-host">
+ <input id="inpunt-descendants-of-closed-shadow-tree-host"
+ _onfocus_="logOnFocus(this)"
+ placeholder="6. input element in closed shadow tree host" />
+</div>
+
+<nest-input-holder></nest-input-holder>
+
+<input id="last" tabindex="0" _onfocus_="logOnFocus(this)"
+ placeholder="10. Last sequentially input element outside shadow trees" />
+
+<div id="description"></div>
+<div id="console"></div>
+<pre id="log"></pre>
+<script src=""
+<script src=""
+<script>
+
+document.getElementById('host-with-negative-tabindex').attachShadow({ mode: 'open' }).innerHTML = `
+ <input tabindex="0"
+ _onfocus_="logOnFocus(this)"
+ placeholder="Should not focus: input element having tabindex=0 in a shadow tree host having negative tabindex"/>
+`;
+
+document.getElementById('host-with-no-tabindex').attachShadow({ mode: 'open' }).innerHTML = `
+ <input tabindex="0"
+ _onfocus_="logOnFocus(this)"
+ placeholder="5. input element having a positive tabindex in a shadow tree host which does not tabindex"/>
+`;
+
+document.getElementById('host-with-positive-tabindex').attachShadow({ mode: 'open' }).innerHTML = `
+ <slot></slot>
+ <div>
+ <input tabindex="0"
+ _onfocus_="logOnFocus(this)"
+ placeholder="4. input element having tabindex=0 in a shadow tree host having a positive tabindex"/>
+ </div>
+ <div>
+ <input tabindex="-1"
+ _onfocus_="logOnFocus(this)"
+ placeholder="Should not focus: input element having negatibe tabindex in a shadow tree host having a positive tabindex"/>
+ </div>
+ <div>
+ <input tabindex="1"
+ _onfocus_="logOnFocus(this)"
+ placeholder="1. input element having a positive tabindex in a shadow tree host having a positive tabindex"/>
+ </div>
+`;
+
+document.getElementById('closed-shadow-tree-host').attachShadow({ mode: 'closed' }).innerHTML = `
+ <slot></slot>
+`;
+
+class InputHolder extends HTMLElement {
+ constructor() {
+ super();
+
+ this.attachShadow({ mode: 'open' })
+ .innerHTML = '<p><input _onfocus_="logOnFocus(this)" placeholder=""/></p>';
+ }
+}
+customElements.define('input-holder', InputHolder);
+
+class NestInputHolder extends HTMLElement {
+ constructor() {
+ super();
+
+ this.attachShadow({ mode: 'open' })
+ .innerHTML = `
+ <input _onfocus_="logOnFocus(this)" placeholder='7. input element before nested custom element having shadow tree' />
+ <input-holder></input-holder>
+ <input _onfocus_="logOnFocus(this)" placeholder='9. input element after nested custom element having shadow tree'/>
+ `;
+ this.shadowRoot.querySelector('input-holder')
+ .shadowRoot.querySelector('input').setAttribute('placeholder', '8. input element in nested shadow tree');
+ }
+}
+customElements.define('nest-input-holder', NestInputHolder);
+
+function logOnFocus(element) {
+ document.getElementById('log').textContent += element.getAttribute('placeholder') + '\n';
+}
+
+function testCase(documentOrShadowRoot, inputGetter) {
+ const inputElement = inputGetter(documentOrShadowRoot);
+ return {
+ documentOrShadowRoot,
+ inputElement,
+ };
+}
+
+async function runTest() {
+ const hostWithPositiveTabIndexShadowRoot = document.getElementById('host-with-positive-tabindex').shadowRoot;
+ const nestInputHolderShadowRoot = document.querySelector('nest-input-holder').shadowRoot;
+
+ const stack = [
+ testCase(document, (_) => document.getElementById('first')),
+
+ testCase(hostWithPositiveTabIndexShadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input[tabindex="1"]')),
+
+ testCase(document, (_) => document.getElementById('input-in-host-with-positive-tabindex-positive')),
+
+ testCase(document, (_) => document.getElementById('input-in-host-with-positive-tabindex')),
+
+ testCase(hostWithPositiveTabIndexShadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input[tabindex="0"]')),
+
+ testCase(document.getElementById('host-with-no-tabindex').shadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input[tabindex="0"]')),
+
+ testCase(document, (_) => document.getElementById('inpunt-descendants-of-closed-shadow-tree-host')),
+
+ testCase(nestInputHolderShadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input:nth-child(1)')),
+
+ testCase(nestInputHolderShadowRoot.querySelector('input-holder').shadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input')),
+
+ testCase(nestInputHolderShadowRoot,
+ (shadowRoot) => shadowRoot.querySelector('input:nth-last-child(1)')),
+
+ testCase(document, (_) => document.getElementById('last')),
+ ];
+
+ {
+ const firstElement = stack[0].inputElement;
+ debug('activate 0th input');
+ await UIHelper.activateElement(firstElement);
+ debug('activated 0th input');
+ }
+
+ for (let i = 1, l = stack.length; i < l; ++i) {
+ const { documentOrShadowRoot, inputElement, } = stack[i];
+
+ debug(`forward to ${String(i)}th input`);
+ await UIHelper.moveToNextByKeyboardAccessoryBar();
+ const activeElement = documentOrShadowRoot.activeElement;
+ debug(`documentOrShadowRoot.activeElement's placeholder attribute: ${activeElement.getAttribute('placeholder')}`);
+ shouldBe(() => activeElement.getAttribute('placeholder'), () => inputElement.getAttribute('placeholder'));
+ }
+
+ debug('focus has moved to the last element and will move to the first reversely');
+
+ for (let i = stack.length - 2; -1 < i; --i) {
+ debug(`back to ${String(i)}th input`);
+ await UIHelper.moveToPrevByKeyboardAccessoryBar();
+ const { documentOrShadowRoot, inputElement, } = stack[i];
+ const activeElement = documentOrShadowRoot.activeElement;
+ debug(`documentOrShadowRoot.activeElement's placeholder attribute: ${activeElement.getAttribute('placeholder')}`);
+ shouldBe(() => activeElement.getAttribute('placeholder'), () => inputElement.getAttribute('placeholder'));
+ }
+}
+
+if (window.testRunner) {
+ description(`Test that Accessory bar next/previous buttons work on inputs which is not assigned to any slot in shadow tree`);
+ const run = runTest().catch((e) => debug(`FAIL: \`${e}\``));
+ UIHelper.wait(run);
+} else
+ document.getElementById('console').style.display = 'none';
+
+</script>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/LayoutTests/platform/ios/TestExpectations (269058 => 269059)
--- trunk/LayoutTests/platform/ios/TestExpectations 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2020-10-27 18:51:38 UTC (rev 269059)
@@ -3507,3 +3507,6 @@
# This test fails in iOS due to subpixel differences for the marker position
imported/w3c/web-platform-tests/css/css-lists/list-style-type-string-002.html [ ImageOnlyFailure ]
+
+# These tests are for iOS port. Should be pass.
+fast/shadow-dom/ios/ [ Pass ]
Modified: trunk/LayoutTests/resources/ui-helper.js (269058 => 269059)
--- trunk/LayoutTests/resources/ui-helper.js 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/LayoutTests/resources/ui-helper.js 2020-10-27 18:51:38 UTC (rev 269059)
@@ -1386,6 +1386,26 @@
})();`, result => resolve(result === "true"));
});
}
+
+ static moveToNextByKeyboardAccessoryBar()
+ {
+ return new Promise((resolve) => {
+ testRunner.runUIScript(`
+ uiController.keyboardAccessoryBarNext();
+ uiController.uiScriptComplete();
+ `, resolve);
+ });
+ }
+
+ static moveToPrevByKeyboardAccessoryBar()
+ {
+ return new Promise((resolve) => {
+ testRunner.runUIScript(`
+ uiController.keyboardAccessoryBarPrevious();
+ uiController.uiScriptComplete();
+ `, resolve);
+ });
+ }
}
UIHelper.EventStreamBuilder = class {
Modified: trunk/Source/WebCore/ChangeLog (269058 => 269059)
--- trunk/Source/WebCore/ChangeLog 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/Source/WebCore/ChangeLog 2020-10-27 18:51:38 UTC (rev 269059)
@@ -1,3 +1,16 @@
+2020-10-27 Tetsuharu Ohzeki <[email protected]>
+
+ Accessory bar next/previous buttons do not work on inputs in shadow roots
+ https://bugs.webkit.org/show_bug.cgi?id=203292
+
+ Reviewed by Ryosuke Niwa.
+
+ Tests: fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::nextFocusableElement):
+ (WebCore::FocusController::previousFocusableElement):
+
2020-10-27 Michael Catanzaro <[email protected]>
Follow-up for: REGRESSION(r267727): Warning spam from JSC_DECLARE_CUSTOM_GETTER
Modified: trunk/Source/WebCore/page/FocusController.cpp (269058 => 269059)
--- trunk/Source/WebCore/page/FocusController.cpp 2020-10-27 18:46:56 UTC (rev 269058)
+++ trunk/Source/WebCore/page/FocusController.cpp 2020-10-27 18:51:38 UTC (rev 269059)
@@ -665,7 +665,7 @@
{
// FIXME: This can return a non-focusable shadow host.
// FIXME: This can't give the correct answer that takes modifier keys into account since it doesn't pass an event.
- return nextFocusableElementOrScopeOwner(FocusNavigationScope::scopeOf(start), &start, nullptr);
+ return findFocusableElementAcrossFocusScope(FocusDirection::Forward, FocusNavigationScope::scopeOf(start), &start, nullptr);
}
Element* FocusController::previousFocusableElement(Node& start)
@@ -672,7 +672,7 @@
{
// FIXME: This can return a non-focusable shadow host.
// FIXME: This can't give the correct answer that takes modifier keys into account since it doesn't pass an event.
- return previousFocusableElementOrScopeOwner(FocusNavigationScope::scopeOf(start), &start, nullptr);
+ return findFocusableElementAcrossFocusScope(FocusDirection::Backward, FocusNavigationScope::scopeOf(start), &start, nullptr);
}
Element* FocusController::nextFocusableElementOrScopeOwner(const FocusNavigationScope& scope, Node* start, KeyboardEvent* event)