Diff
Modified: trunk/LayoutTests/ChangeLog (249236 => 249237)
--- trunk/LayoutTests/ChangeLog 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/ChangeLog 2019-08-29 03:14:24 UTC (rev 249237)
@@ -1,3 +1,21 @@
+2019-08-28 Ryosuke Niwa <[email protected]>
+
+ Make tabIndex IDL attribute reflect its content attribute
+ https://bugs.webkit.org/show_bug.cgi?id=199606
+ <rdar://problem/52811448>
+
+ Reviewed by Chris Dumez.
+
+ Added test cases and assertions.
+
+ * fast/dom/tabindex-defaults-expected.txt:
+ * fast/dom/tabindex-defaults.html: Added test cases for iframe, frame, object, video, summary, and SVG elements.
+ Also blur the active element to avoid any race conditions.
+ * plugins/focus-expected.txt:
+ * plugins/focus.html:
+ * svg/custom/tabindex-order-expected.txt:
+ * svg/custom/tabindex-order.html: Made the sequential navigation code not rely on tabIndex IDL attribute.
+
2019-08-28 Devin Rousso <[email protected]>
Unreviewed, fix test failure after r249173
Modified: trunk/LayoutTests/fast/dom/tabindex-defaults-expected.txt (249236 => 249237)
--- trunk/LayoutTests/fast/dom/tabindex-defaults-expected.txt 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/fast/dom/tabindex-defaults-expected.txt 2019-08-29 03:14:24 UTC (rev 249237)
@@ -4,35 +4,62 @@
PASS anchor.tabIndex is 0
+PASS iframe.tabIndex is 0
+PASS frame.tabIndex is 0
+PASS object.tabIndex is 0
PASS button.tabIndex is 0
PASS input.tabIndex is 0
PASS select.tabIndex is 0
PASS textarea.tabIndex is 0
PASS keygen.tabIndex is 0
-PASS editableDiv.tabIndex is 0
+PASS activeSummary.tabIndex is 0
+PASS editableDiv.tabIndex is -1
PASS normalDiv.tabIndex is -1
PASS output.tabIndex is -1
PASS fieldset.tabIndex is -1
+PASS video.tabIndex is -1
+PASS videoWithControls.tabIndex is -1
+PASS summary.tabIndex is -1
+PASS bodyInDesignMode.tabIndex is -1
+PASS g.tabIndex is -1
PASS anchor.setAttribute("tabindex", "invalid"); anchor.tabIndex is 0
+PASS iframe.setAttribute("tabindex", "invalid"); iframe.tabIndex is 0
+PASS frame.setAttribute("tabindex", "invalid"); frame.tabIndex is 0
+PASS object.setAttribute("tabindex", "invalid"); object.tabIndex is 0
PASS button.setAttribute("tabindex", "invalid"); button.tabIndex is 0
PASS input.setAttribute("tabindex", "invalid"); input.tabIndex is 0
PASS select.setAttribute("tabindex", "invalid"); select.tabIndex is 0
PASS textarea.setAttribute("tabindex", "invalid"); textarea.tabIndex is 0
PASS keygen.setAttribute("tabindex", "invalid"); keygen.tabIndex is 0
-PASS editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex is 0
+PASS activeSummary.setAttribute("tabindex", "invalid"); activeSummary.tabIndex is 0
+PASS editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex is -1
PASS normalDiv.setAttribute("tabindex", "invalid"); normalDiv.tabIndex is -1
PASS output.setAttribute("tabindex", "invalid"); output.tabIndex is -1
PASS fieldset.setAttribute("tabindex", "invalid"); fieldset.tabIndex is -1
+PASS video.setAttribute("tabindex", "invalid"); video.tabIndex is -1
+PASS videoWithControls.setAttribute("tabindex", "invalid"); videoWithControls.tabIndex is -1
+PASS summary.setAttribute("tabindex", "invalid"); summary.tabIndex is -1
+PASS bodyInDesignMode.setAttribute("tabindex", "invalid"); bodyInDesignMode.tabIndex is -1
+PASS g.setAttribute("tabindex", "invalid"); g.tabIndex is -1
PASS anchor.setAttribute("tabindex", "9999999999"); anchor.tabIndex is 0
+PASS iframe.setAttribute("tabindex", "9999999999"); iframe.tabIndex is 0
+PASS frame.setAttribute("tabindex", "9999999999"); frame.tabIndex is 0
+PASS object.setAttribute("tabindex", "invalid"); object.tabIndex is 0
PASS button.setAttribute("tabindex", "9999999999"); button.tabIndex is 0
PASS input.setAttribute("tabindex", "9999999999"); input.tabIndex is 0
PASS select.setAttribute("tabindex", "9999999999"); select.tabIndex is 0
PASS textarea.setAttribute("tabindex", "9999999999"); textarea.tabIndex is 0
PASS keygen.setAttribute("tabindex", "9999999999"); keygen.tabIndex is 0
-PASS editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex is 0
+PASS activeSummary.setAttribute("tabindex", "9999999999"); activeSummary.tabIndex is 0
+PASS editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex is -1
PASS normalDiv.setAttribute("tabindex", "9999999999"); normalDiv.tabIndex is -1
PASS output.setAttribute("tabindex", "9999999999"); output.tabIndex is -1
PASS fieldset.setAttribute("tabindex", "9999999999"); fieldset.tabIndex is -1
+PASS video.setAttribute("tabindex", "9999999999"); video.tabIndex is -1
+PASS videoWithControls.setAttribute("tabindex", "9999999999"); videoWithControls.tabIndex is -1
+PASS summary.setAttribute("tabindex", "9999999999"); summary.tabIndex is -1
+PASS bodyInDesignMode.setAttribute("tabindex", "9999999999"); bodyInDesignMode.tabIndex is -1
+PASS g.setAttribute("tabindex", "9999999999"); g.tabIndex is -1
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/tabindex-defaults.html (249236 => 249237)
--- trunk/LayoutTests/fast/dom/tabindex-defaults.html 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/fast/dom/tabindex-defaults.html 2019-08-29 03:14:24 UTC (rev 249237)
@@ -7,6 +7,8 @@
<div id="container">
<!-- Focusable elements -->
<a id="anchor" href=""
+<iframe id="iframe"></iframe>
+<object id="object"></object>
<button id="button">button</button>
<input id="input">
<select id="select"></select>
@@ -13,11 +15,17 @@
<textarea id="textarea"></textarea>
<keygen id="keygen"></keygen>
<div id="editableDiv" contenteditable="true"></div>
+<details><summary id="activeSummary"></summary></details>
<!-- Unfocusable element -->
<div id="normalDiv"></div>
<output id="output"></output>
<fieldset id="fieldset"></fieldset>
+<video id="video"></video>
+<video id="videoWithControls" controls></video>
+<details><summary></summary><summary id="summary"></summary></details>
+<iframe id="iframeForDesignMode"></iframe>
+<svg><g id="g" _onfocus_="alert('fail')"></g></svg>
</div>
<script>
@@ -24,48 +32,88 @@
description('Default value of tabIndex IDL attribute');
var anchor = document.getElementById('anchor');
+var iframe = document.getElementById('iframe');
+iframe.contentDocument.open();
+iframe.contentDocument.write('<!DOCTYPE><html><frameset cols="50%,50%"><frame></frame></frameset>');
+var frame = iframe.contentDocument.querySelector('frame');
+var object = document.getElementById('object');
var button = document.getElementById('button');
var input = document.getElementById('input');
var select = document.getElementById('select');
var textarea = document.getElementById('textarea');
+var keygen = document.getElementById('keygen');
var editableDiv = document.getElementById('editableDiv');
+var normalDiv = document.getElementById('normalDiv');
var output = document.getElementById('output');
var fieldset = document.getElementById('fieldset');
-var keygen = document.getElementById('keygen');
-var normalDiv = document.getElementById('normalDiv');
+var video = document.getElementById('video');
+var videoWithControls = document.getElementById('videoWithControls');
+var summary = document.getElementById('summary');
+var activeSummary = document.getElementById('activeSummary');
+var iframeForDesignMode = document.getElementById('iframeForDesignMode');
+iframeForDesignMode.contentDocument.designMode = 'on';
+var bodyInDesignMode = iframeForDesignMode.contentDocument.body;
+var g = document.getElementById('g');
shouldBe('anchor.tabIndex', '0');
+shouldBe('iframe.tabIndex', '0');
+shouldBe('frame.tabIndex', '0');
+shouldBe('object.tabIndex', '0');
shouldBe('button.tabIndex', '0');
shouldBe('input.tabIndex', '0');
shouldBe('select.tabIndex', '0');
shouldBe('textarea.tabIndex', '0');
shouldBe('keygen.tabIndex', '0');
-shouldBe('editableDiv.tabIndex', '0');
+shouldBe('activeSummary.tabIndex', '0');
+shouldBe('editableDiv.tabIndex', '-1');
shouldBe('normalDiv.tabIndex', '-1');
shouldBe('output.tabIndex', '-1');
shouldBe('fieldset.tabIndex', '-1');
+shouldBe('video.tabIndex', '-1');
+shouldBe('videoWithControls.tabIndex', '-1');
+shouldBe('summary.tabIndex', '-1');
+shouldBe('bodyInDesignMode.tabIndex', '-1');
+shouldBe('g.tabIndex', '-1');
shouldBe('anchor.setAttribute("tabindex", "invalid"); anchor.tabIndex', '0');
+shouldBe('iframe.setAttribute("tabindex", "invalid"); iframe.tabIndex', '0');
+shouldBe('frame.setAttribute("tabindex", "invalid"); frame.tabIndex', '0');
+shouldBe('object.setAttribute("tabindex", "invalid"); object.tabIndex', '0');
shouldBe('button.setAttribute("tabindex", "invalid"); button.tabIndex', '0');
shouldBe('input.setAttribute("tabindex", "invalid"); input.tabIndex', '0');
shouldBe('select.setAttribute("tabindex", "invalid"); select.tabIndex', '0');
shouldBe('textarea.setAttribute("tabindex", "invalid"); textarea.tabIndex', '0');
shouldBe('keygen.setAttribute("tabindex", "invalid"); keygen.tabIndex', '0');
-shouldBe('editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex', '0');
+shouldBe('activeSummary.setAttribute("tabindex", "invalid"); activeSummary.tabIndex', '0');
+shouldBe('editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex', '-1');
shouldBe('normalDiv.setAttribute("tabindex", "invalid"); normalDiv.tabIndex', '-1');
shouldBe('output.setAttribute("tabindex", "invalid"); output.tabIndex', '-1');
shouldBe('fieldset.setAttribute("tabindex", "invalid"); fieldset.tabIndex', '-1');
+shouldBe('video.setAttribute("tabindex", "invalid"); video.tabIndex', '-1');
+shouldBe('videoWithControls.setAttribute("tabindex", "invalid"); videoWithControls.tabIndex', '-1');
+shouldBe('summary.setAttribute("tabindex", "invalid"); summary.tabIndex', '-1');
+shouldBe('bodyInDesignMode.setAttribute("tabindex", "invalid"); bodyInDesignMode.tabIndex', '-1');
+shouldBe('g.setAttribute("tabindex", "invalid"); g.tabIndex', '-1');
shouldBe('anchor.setAttribute("tabindex", "9999999999"); anchor.tabIndex', '0');
+shouldBe('iframe.setAttribute("tabindex", "9999999999"); iframe.tabIndex', '0');
+shouldBe('frame.setAttribute("tabindex", "9999999999"); frame.tabIndex', '0');
+shouldBe('object.setAttribute("tabindex", "invalid"); object.tabIndex', '0');
shouldBe('button.setAttribute("tabindex", "9999999999"); button.tabIndex', '0');
shouldBe('input.setAttribute("tabindex", "9999999999"); input.tabIndex', '0');
shouldBe('select.setAttribute("tabindex", "9999999999"); select.tabIndex', '0');
shouldBe('textarea.setAttribute("tabindex", "9999999999"); textarea.tabIndex', '0');
shouldBe('keygen.setAttribute("tabindex", "9999999999"); keygen.tabIndex', '0');
-shouldBe('editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex', '0');
+shouldBe('activeSummary.setAttribute("tabindex", "9999999999"); activeSummary.tabIndex', '0');
+shouldBe('editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex', '-1');
shouldBe('normalDiv.setAttribute("tabindex", "9999999999"); normalDiv.tabIndex', '-1');
shouldBe('output.setAttribute("tabindex", "9999999999"); output.tabIndex', '-1');
shouldBe('fieldset.setAttribute("tabindex", "9999999999"); fieldset.tabIndex', '-1');
+shouldBe('video.setAttribute("tabindex", "9999999999"); video.tabIndex', '-1');
+shouldBe('videoWithControls.setAttribute("tabindex", "9999999999"); videoWithControls.tabIndex', '-1');
+shouldBe('summary.setAttribute("tabindex", "9999999999"); summary.tabIndex', '-1');
+shouldBe('bodyInDesignMode.setAttribute("tabindex", "9999999999"); bodyInDesignMode.tabIndex', '-1');
+shouldBe('g.setAttribute("tabindex", "9999999999"); g.tabIndex', '-1');
document.getElementById('container').innerHTML = '';
</script>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (249236 => 249237)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2019-08-29 03:14:24 UTC (rev 249237)
@@ -1,3 +1,13 @@
+2019-08-28 Ryosuke Niwa <[email protected]>
+
+ Make tabIndex IDL attribute reflect its content attribute
+ https://bugs.webkit.org/show_bug.cgi?id=199606
+ <rdar://problem/52811448>
+
+ Reviewed by Chris Dumez.
+
+ * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaselined now that test cases for summary are passing.
+
2019-08-28 Alicia Boya GarcĂa <[email protected]>
[MSE][GStreamer] WebKitMediaSrc rework
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-misc-expected.txt (249236 => 249237)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-misc-expected.txt 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-misc-expected.txt 2019-08-29 03:14:24 UTC (rev 249237)
@@ -2786,29 +2786,29 @@
PASS summary.accessKey: IDL set to object "test-toString"
PASS summary.accessKey: IDL set to object "test-valueOf"
PASS summary.tabIndex: typeof IDL attribute
-FAIL summary.tabIndex: setAttribute() to -36 assert_equals: IDL get expected -36 but got -1
+PASS summary.tabIndex: setAttribute() to -36
PASS summary.tabIndex: setAttribute() to -1
-FAIL summary.tabIndex: setAttribute() to 0 assert_equals: IDL get expected 0 but got -1
-FAIL summary.tabIndex: setAttribute() to 1 assert_equals: IDL get expected 1 but got -1
-FAIL summary.tabIndex: setAttribute() to 2147483647 assert_equals: IDL get expected 2147483647 but got -1
-FAIL summary.tabIndex: setAttribute() to -2147483648 assert_equals: IDL get expected -2147483648 but got -1
+PASS summary.tabIndex: setAttribute() to 0
+PASS summary.tabIndex: setAttribute() to 1
+PASS summary.tabIndex: setAttribute() to 2147483647
+PASS summary.tabIndex: setAttribute() to -2147483648
PASS summary.tabIndex: setAttribute() to "-1"
-FAIL summary.tabIndex: setAttribute() to "-0" assert_equals: IDL get expected 0 but got -1
-FAIL summary.tabIndex: setAttribute() to "0" assert_equals: IDL get expected 0 but got -1
-FAIL summary.tabIndex: setAttribute() to "1" assert_equals: IDL get expected 1 but got -1
-FAIL summary.tabIndex: setAttribute() to "\t7" assert_equals: IDL get expected 7 but got -1
-FAIL summary.tabIndex: setAttribute() to "\f7" assert_equals: IDL get expected 7 but got -1
-FAIL summary.tabIndex: setAttribute() to " 7" assert_equals: IDL get expected 7 but got -1
-FAIL summary.tabIndex: setAttribute() to "\n7" assert_equals: IDL get expected 7 but got -1
-FAIL summary.tabIndex: setAttribute() to "\r7" assert_equals: IDL get expected 7 but got -1
-FAIL summary.tabIndex: setAttribute() to 1.5 assert_equals: IDL get expected 1 but got -1
-FAIL summary.tabIndex: setAttribute() to object "2" assert_equals: IDL get expected 2 but got -1
-FAIL summary.tabIndex: IDL set to -36 assert_equals: IDL get expected -36 but got -1
+PASS summary.tabIndex: setAttribute() to "-0"
+PASS summary.tabIndex: setAttribute() to "0"
+PASS summary.tabIndex: setAttribute() to "1"
+PASS summary.tabIndex: setAttribute() to "\t7"
+PASS summary.tabIndex: setAttribute() to "\f7"
+PASS summary.tabIndex: setAttribute() to " 7"
+PASS summary.tabIndex: setAttribute() to "\n7"
+PASS summary.tabIndex: setAttribute() to "\r7"
+PASS summary.tabIndex: setAttribute() to 1.5
+PASS summary.tabIndex: setAttribute() to object "2"
+PASS summary.tabIndex: IDL set to -36
PASS summary.tabIndex: IDL set to -1
-FAIL summary.tabIndex: IDL set to 0 assert_equals: IDL get expected 0 but got -1
-FAIL summary.tabIndex: IDL set to 1 assert_equals: IDL get expected 1 but got -1
-FAIL summary.tabIndex: IDL set to 2147483647 assert_equals: IDL get expected 2147483647 but got -1
-FAIL summary.tabIndex: IDL set to -2147483648 assert_equals: IDL get expected -2147483648 but got -1
+PASS summary.tabIndex: IDL set to 0
+PASS summary.tabIndex: IDL set to 1
+PASS summary.tabIndex: IDL set to 2147483647
+PASS summary.tabIndex: IDL set to -2147483648
PASS menu.title: typeof IDL attribute
PASS menu.title: IDL get with DOM attribute unset
PASS menu.title: setAttribute() to ""
Modified: trunk/LayoutTests/plugins/focus-expected.txt (249236 => 249237)
--- trunk/LayoutTests/plugins/focus-expected.txt 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/plugins/focus-expected.txt 2019-08-29 03:14:24 UTC (rev 249237)
@@ -7,17 +7,29 @@
TEST COMPLETE
PASS "embedElem"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "objectElem"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "embedElemWithFallbackContents"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "objectElemWithFallbackContents"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginEmbedElem"; document.activeElement === pluginElement is false
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginObjectElem"; document.activeElement === pluginElement is false
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginEmbedElemWithFallbackContents"; document.activeElement === pluginElement is false
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginObjectElemWithFallbackContents"; document.activeElement === pluginElement is false
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginEmbedElemWithTabindex"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginObjectElemWithTabindex"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginEmbedElemWithContenteditable"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
PASS "noPluginObjectElemWithContenteditable"; document.activeElement === pluginElement is true
+PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
fast/events/tabindex-focus-blur-all.html
Test for bug 32292: "Unable to focus on embedded plugins such as Flash via _javascript_ focus()"
Modified: trunk/LayoutTests/plugins/focus.html (249236 => 249237)
--- trunk/LayoutTests/plugins/focus.html 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/plugins/focus.html 2019-08-29 03:14:24 UTC (rev 249237)
@@ -9,23 +9,23 @@
"Unable to focus on embedded plugins such as Flash via _javascript_ focus()"</p>
<p>This tests focusing Embeds and Objects. See LayoutTests/java for Applet elements.</p>
<div id=embedOwner>
-<embed id="embedElem" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true></embed>
-<object id="objectElem" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true></object>
+<embed id="embedElem" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true data-expected-tabindex=-1></embed>
+<object id="objectElem" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true data-expected-tabindex=0></object>
-<embed id="embedElemWithFallbackContents" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true>Fallback contents.</embed>
-<object id="objectElemWithFallbackContents" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true>Fallback contents.</object>
+<embed id="embedElemWithFallbackContents" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true data-expected-tabindex=-1>Fallback contents.</embed>
+<object id="objectElemWithFallbackContents" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true data-expected-tabindex=0>Fallback contents.</object>
-<embed id="noPluginEmbedElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false></embed>
-<object id="noPluginObjectElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false></object>
+<embed id="noPluginEmbedElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=-1></embed>
+<object id="noPluginObjectElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=0></object>
-<embed id="noPluginEmbedElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false>Fallback contents.</embed>
-<object id="noPluginObjectElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false>Fallback contents.</object>
+<embed id="noPluginEmbedElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=-1>Fallback contents.</embed>
+<object id="noPluginObjectElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=0>Fallback contents.</object>
-<embed id="noPluginEmbedElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true></embed>
-<object id="noPluginObjectElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true></object>
+<embed id="noPluginEmbedElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true data-expected-tabindex=-1></embed>
+<object id="noPluginObjectElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true data-expected-tabindex=-1></object>
-<embed id="noPluginEmbedElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true></embed>
-<object id="noPluginObjectElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true></object>
+<embed id="noPluginEmbedElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true data-expected-tabindex=-1></embed>
+<object id="noPluginObjectElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true data-expected-tabindex=0></object>
</div>
<script>
@@ -39,6 +39,7 @@
pluginElement.focus();
shouldBe('"' + pluginElement.id + '"; document.activeElement === pluginElement',
pluginElement.getAttribute("shouldFocus").toString());
+ shouldBe('pluginElement.tabIndex', 'parseInt(pluginElement.getAttribute("data-expected-tabindex"))');
pluginElement.blur();
}
}
Modified: trunk/LayoutTests/svg/custom/tabindex-order-expected.txt (249236 => 249237)
--- trunk/LayoutTests/svg/custom/tabindex-order-expected.txt 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/svg/custom/tabindex-order-expected.txt 2019-08-29 03:14:24 UTC (rev 249237)
@@ -16,6 +16,7 @@
id: i tabindex: 0 [object SVGSVGElement] is focused.
id: j tabindex: 0 [object SVGLineElement] is focused.
id: k tabindex: 0 [object SVGPolygonElement] is focused.
+id: a tabindex: 1 [object SVGCircleElement] is focused.
Tabbing backward....
@@ -31,6 +32,7 @@
id: c tabindex: 1 [object SVGEllipseElement] is focused.
id: b tabindex: 1 [object SVGGElement] is focused.
id: a tabindex: 1 [object SVGCircleElement] is focused.
+id: k tabindex: 0 [object SVGPolygonElement] is focused.
Test finished
Modified: trunk/LayoutTests/svg/custom/tabindex-order.html (249236 => 249237)
--- trunk/LayoutTests/svg/custom/tabindex-order.html 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/LayoutTests/svg/custom/tabindex-order.html 2019-08-29 03:14:24 UTC (rev 249237)
@@ -34,6 +34,8 @@
testRunner.dumpAsText();
}
+ document.activeElement.blur();
+
var rects = document.getElementsByClassName('tab');
// Put focus in the page
@@ -43,18 +45,20 @@
addEventListenersToRects(rects);
log('Tabbing forward....\n');
+ let tabCount = 0;
for (var i = 0; i < rects.length; ++i) {
- if (rects[i].tabIndex >= 0)
- dispatchTabPress(document, false);
+ if (i > 1 && document.activeElement.id == 'a')
+ break;
+ dispatchTabPress(document, false);
+ tabCount++;
}
lastFocusedElement.blur();
log('\nTabbing backward....\n');
- for (var i = 0; i < rects.length; ++i) {
- if (rects[i].tabIndex >= 0)
- dispatchTabPress(document, true);
- }
+ previousActiveElement = null;
+ for (var i = 0; i < tabCount; ++i)
+ dispatchTabPress(document, true);
log('\nTest finished\n');
}
Modified: trunk/Source/WebCore/ChangeLog (249236 => 249237)
--- trunk/Source/WebCore/ChangeLog 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/ChangeLog 2019-08-29 03:14:24 UTC (rev 249237)
@@ -1,3 +1,69 @@
+2019-08-28 Ryosuke Niwa <[email protected]>
+
+ Make tabIndex IDL attribute reflect its content attribute
+ https://bugs.webkit.org/show_bug.cgi?id=199606
+ <rdar://problem/52811448>
+
+ Reviewed by Chris Dumez.
+
+ This patch makes tabIndex IDL attribute no longer return 0 when the element is focusable
+ to match the latest HTML5 specification. Instead, the IDL attribute simply reflect the tabindex
+ content attribute with some elements having 0 as the default tab index (see r248784):
+ https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute
+
+ The practical implication is that tabIndex IDL attribute on a root editable element (a.k.a.
+ editing host in HTML5 spec term), body element in design mode, and media elements with
+ media controls would start returning -1 instead of 0.
+
+ Mechanically, this is accomplished by removing the special case in Element::tabIndexForBindings
+ when supportsFocus returned true. The effect, if any, this patch has on each element which
+ overrides Element::supportsFocus is summarized as follows (indentation simplies inheritance):
+
+ HTMLAnchorElement -> No effect since defaultTabIndex returns 0.
+ HTMLAreaElement -> Ditto.
+ HTMLBodyElement -> Changes to return -1 in design mode.
+ HTMLElement -> Changes to return -1 on a root editable element.
+ HTMLFormControlElement
+ HTMLButtonElement -> No effect since defaultTabIndex returns 0.
+ HTMLFieldSetElement -> No effect since this is an override to use HTMLElement's supportsFocus.
+ HTMLFormControlElementWithState
+ HTMLKeygenElement -> No effect since defaultTabIndex returns 0.
+ HTMLSelectElement -> Ditto.
+ HTMLTextFormControlElement -> Ditto.
+ HTMLInputElement -> Ditto.
+ HTMLTextAreaElement -> Ditto.
+ HTMLOutputElement -> No effect since this is an override to use HTMLElement's supportsFocus.
+ HTMLFrameElementBase - No change. Added defaultTabIndex on HTMLIFrameElement and HTMLFrameElement
+ to returns 0.
+ HTMLImageElement - No impact since it only affects when an image is set to be editable via SPI.
+ HTMLMediaElement - Changes to return -1 when media controls is present.
+ HTMLPlugInElement - applet and embed elements change to return -1 when the plugin is available.
+ HTMLSummaryElement - No change. Added defaultTabIndex to return 0 when it's active to match
+ supportsFocus as well as the HTML5 specification.
+ MathMLElement - No effect since tabIndex IDL attribute does not exist in MathML.
+ SVGAElement - No effect since defaultTabIndex returns 0.
+ SVGClipPathElement - No effect since it always returns false.
+ SVGDefsElement - No effect since it always returns false.
+
+ Tests: fast/dom/tabindex-defaults.html
+ plugins/focus.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::tabIndexForBindings const): Made the change.
+ * html/HTMLFrameElement.cpp:
+ (WebCore::HTMLFrameElement::defaultTabIndex const): Added to preserve the existing behavior.
+ * html/HTMLFrameElement.h:
+ * html/HTMLIFrameElement.cpp:
+ (WebCore::HTMLIFrameElement::defaultTabIndex const): Ditto.
+ * html/HTMLIFrameElement.h:
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::defaultTabIndex const): Added. Always return 0 to match the spec.
+ * html/HTMLObjectElement.h:
+ * html/HTMLSummaryElement.cpp:
+ (WebCore::HTMLSummaryElement::defaultTabIndex const): Added. Return 0 when the this summary
+ is the active summary element of the details element.
+ * html/HTMLSummaryElement.h:
+
2019-08-28 Simon Fraser <[email protected]>
Make FillLayer::hasImage() inline
Modified: trunk/Source/WebCore/dom/Element.cpp (249236 => 249237)
--- trunk/Source/WebCore/dom/Element.cpp 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/dom/Element.cpp 2019-08-29 03:14:24 UTC (rev 249237)
@@ -267,12 +267,7 @@
int Element::tabIndexForBindings() const
{
- auto defaultIndex = defaultTabIndex();
- ASSERT(!defaultIndex || defaultIndex == -1);
- // FIXME: supportsFocus() check shouldn't be here.
- if (!defaultIndex || supportsFocus())
- return tabIndexSetExplicitly().valueOr(0);
- return defaultIndex;
+ return valueOrCompute(tabIndexSetExplicitly(), [&] { return defaultTabIndex(); });
}
void Element::setTabIndexForBindings(int value)
Modified: trunk/Source/WebCore/html/HTMLFrameElement.cpp (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLFrameElement.cpp 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLFrameElement.cpp 2019-08-29 03:14:24 UTC (rev 249237)
@@ -74,6 +74,11 @@
m_frameBorder = containingFrameSet->hasFrameBorder();
}
+int HTMLFrameElement::defaultTabIndex() const
+{
+ return 0;
+}
+
void HTMLFrameElement::parseAttribute(const QualifiedName& name, const AtomString& value)
{
if (name == frameborderAttr) {
Modified: trunk/Source/WebCore/html/HTMLFrameElement.h (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLFrameElement.h 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLFrameElement.h 2019-08-29 03:14:24 UTC (rev 249237)
@@ -45,6 +45,7 @@
void didAttachRenderers() final;
bool rendererIsNeeded(const RenderStyle&) final;
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
+ int defaultTabIndex() const final;
void parseAttribute(const QualifiedName&, const AtomString&) final;
bool m_frameBorder { true };
Modified: trunk/Source/WebCore/html/HTMLIFrameElement.cpp (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLIFrameElement.cpp 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLIFrameElement.cpp 2019-08-29 03:14:24 UTC (rev 249237)
@@ -51,6 +51,11 @@
return adoptRef(*new HTMLIFrameElement(tagName, document));
}
+int HTMLIFrameElement::defaultTabIndex() const
+{
+ return 0;
+}
+
DOMTokenList& HTMLIFrameElement::sandbox()
{
if (!m_sandbox) {
Modified: trunk/Source/WebCore/html/HTMLIFrameElement.h (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLIFrameElement.h 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLIFrameElement.h 2019-08-29 03:14:24 UTC (rev 249237)
@@ -49,6 +49,7 @@
private:
HTMLIFrameElement(const QualifiedName&, Document&);
+ int defaultTabIndex() const final;
void parseAttribute(const QualifiedName&, const AtomString&) final;
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomString&, MutableStyleProperties&) final;
Modified: trunk/Source/WebCore/html/HTMLObjectElement.cpp (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLObjectElement.cpp 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLObjectElement.cpp 2019-08-29 03:14:24 UTC (rev 249237)
@@ -86,6 +86,11 @@
return renderWidget(); // This will return 0 if the renderer is not a RenderWidget.
}
+int HTMLObjectElement::defaultTabIndex() const
+{
+ return 0;
+}
+
bool HTMLObjectElement::isPresentationAttribute(const QualifiedName& name) const
{
if (name == borderAttr)
Modified: trunk/Source/WebCore/html/HTMLObjectElement.h (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLObjectElement.h 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLObjectElement.h 2019-08-29 03:14:24 UTC (rev 249237)
@@ -59,6 +59,10 @@
private:
HTMLObjectElement(const QualifiedName&, Document&, HTMLFormElement*);
+ RenderWidget* renderWidgetLoadingPlugin() const final;
+
+ int defaultTabIndex() const final;
+
void parseAttribute(const QualifiedName&, const AtomString&) final;
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomString&, MutableStyleProperties&) final;
@@ -74,8 +78,6 @@
bool isURLAttribute(const Attribute&) const final;
const AtomString& imageSourceURL() const final;
- RenderWidget* renderWidgetLoadingPlugin() const final;
-
void addSubresourceAttributeURLs(ListHashSet<URL>&) const final;
void updateWidget(CreatePlugins) final;
Modified: trunk/Source/WebCore/html/HTMLSummaryElement.cpp (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLSummaryElement.cpp 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLSummaryElement.cpp 2019-08-29 03:14:24 UTC (rev 249237)
@@ -102,6 +102,11 @@
return is<HTMLFormControlElement>(element) || is<HTMLFormControlElement>(element.shadowHost());
}
+int HTMLSummaryElement::defaultTabIndex() const
+{
+ return isActiveSummary() ? 0 : -1;
+}
+
bool HTMLSummaryElement::supportsFocus() const
{
return isActiveSummary();
Modified: trunk/Source/WebCore/html/HTMLSummaryElement.h (249236 => 249237)
--- trunk/Source/WebCore/html/HTMLSummaryElement.h 2019-08-29 03:01:39 UTC (rev 249236)
+++ trunk/Source/WebCore/html/HTMLSummaryElement.h 2019-08-29 03:14:24 UTC (rev 249237)
@@ -46,6 +46,7 @@
RefPtr<HTMLDetailsElement> detailsElement() const;
+ int defaultTabIndex() const final;
bool supportsFocus() const final;
};