⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 249237 in webkit


Ignore:
Timestamp:
Aug 28, 2019, 8:14:24 PM (7 years ago)
Author:
rniwa@webkit.org
Message:

Make tabIndex IDL attribute reflect its content attribute
https://bugs.webkit.org/show_bug.cgi?id=199606
<rdar://problem/52811448>

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

  • web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaselined now that test cases for summary are passing.

Source/WebCore:

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:

LayoutTests:

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.
Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r249220 r249237  
     12019-08-28  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Make tabIndex IDL attribute reflect its content attribute
     4        https://bugs.webkit.org/show_bug.cgi?id=199606
     5        <rdar://problem/52811448>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Added test cases and assertions.
     10
     11        * fast/dom/tabindex-defaults-expected.txt:
     12        * fast/dom/tabindex-defaults.html: Added test cases for iframe, frame, object, video, summary, and SVG elements.
     13        Also blur the active element to avoid any race conditions.
     14        * plugins/focus-expected.txt:
     15        * plugins/focus.html:
     16        * svg/custom/tabindex-order-expected.txt:
     17        * svg/custom/tabindex-order.html: Made the sequential navigation code not rely on tabIndex IDL attribute.
     18
    1192019-08-28  Devin Rousso  <drousso@apple.com>
    220
  • trunk/LayoutTests/fast/dom/tabindex-defaults-expected.txt

    r248914 r249237  
    55
    66PASS anchor.tabIndex is 0
     7PASS iframe.tabIndex is 0
     8PASS frame.tabIndex is 0
     9PASS object.tabIndex is 0
    710PASS button.tabIndex is 0
    811PASS input.tabIndex is 0
     
    1013PASS textarea.tabIndex is 0
    1114PASS keygen.tabIndex is 0
    12 PASS editableDiv.tabIndex is 0
     15PASS activeSummary.tabIndex is 0
     16PASS editableDiv.tabIndex is -1
    1317PASS normalDiv.tabIndex is -1
    1418PASS output.tabIndex is -1
    1519PASS fieldset.tabIndex is -1
     20PASS video.tabIndex is -1
     21PASS videoWithControls.tabIndex is -1
     22PASS summary.tabIndex is -1
     23PASS bodyInDesignMode.tabIndex is -1
     24PASS g.tabIndex is -1
    1625PASS anchor.setAttribute("tabindex", "invalid"); anchor.tabIndex is 0
     26PASS iframe.setAttribute("tabindex", "invalid"); iframe.tabIndex is 0
     27PASS frame.setAttribute("tabindex", "invalid"); frame.tabIndex is 0
     28PASS object.setAttribute("tabindex", "invalid"); object.tabIndex is 0
    1729PASS button.setAttribute("tabindex", "invalid"); button.tabIndex is 0
    1830PASS input.setAttribute("tabindex", "invalid"); input.tabIndex is 0
     
    2032PASS textarea.setAttribute("tabindex", "invalid"); textarea.tabIndex is 0
    2133PASS keygen.setAttribute("tabindex", "invalid"); keygen.tabIndex is 0
    22 PASS editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex is 0
     34PASS activeSummary.setAttribute("tabindex", "invalid"); activeSummary.tabIndex is 0
     35PASS editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex is -1
    2336PASS normalDiv.setAttribute("tabindex", "invalid"); normalDiv.tabIndex is -1
    2437PASS output.setAttribute("tabindex", "invalid"); output.tabIndex is -1
    2538PASS fieldset.setAttribute("tabindex", "invalid"); fieldset.tabIndex is -1
     39PASS video.setAttribute("tabindex", "invalid"); video.tabIndex is -1
     40PASS videoWithControls.setAttribute("tabindex", "invalid"); videoWithControls.tabIndex is -1
     41PASS summary.setAttribute("tabindex", "invalid"); summary.tabIndex is -1
     42PASS bodyInDesignMode.setAttribute("tabindex", "invalid"); bodyInDesignMode.tabIndex is -1
     43PASS g.setAttribute("tabindex", "invalid"); g.tabIndex is -1
    2644PASS anchor.setAttribute("tabindex", "9999999999"); anchor.tabIndex is 0
     45PASS iframe.setAttribute("tabindex", "9999999999"); iframe.tabIndex is 0
     46PASS frame.setAttribute("tabindex", "9999999999"); frame.tabIndex is 0
     47PASS object.setAttribute("tabindex", "invalid"); object.tabIndex is 0
    2748PASS button.setAttribute("tabindex", "9999999999"); button.tabIndex is 0
    2849PASS input.setAttribute("tabindex", "9999999999"); input.tabIndex is 0
     
    3051PASS textarea.setAttribute("tabindex", "9999999999"); textarea.tabIndex is 0
    3152PASS keygen.setAttribute("tabindex", "9999999999"); keygen.tabIndex is 0
    32 PASS editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex is 0
     53PASS activeSummary.setAttribute("tabindex", "9999999999"); activeSummary.tabIndex is 0
     54PASS editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex is -1
    3355PASS normalDiv.setAttribute("tabindex", "9999999999"); normalDiv.tabIndex is -1
    3456PASS output.setAttribute("tabindex", "9999999999"); output.tabIndex is -1
    3557PASS fieldset.setAttribute("tabindex", "9999999999"); fieldset.tabIndex is -1
     58PASS video.setAttribute("tabindex", "9999999999"); video.tabIndex is -1
     59PASS videoWithControls.setAttribute("tabindex", "9999999999"); videoWithControls.tabIndex is -1
     60PASS summary.setAttribute("tabindex", "9999999999"); summary.tabIndex is -1
     61PASS bodyInDesignMode.setAttribute("tabindex", "9999999999"); bodyInDesignMode.tabIndex is -1
     62PASS g.setAttribute("tabindex", "9999999999"); g.tabIndex is -1
    3663PASS successfullyParsed is true
    3764
  • trunk/LayoutTests/fast/dom/tabindex-defaults.html

    r248960 r249237  
    88<!-- Focusable elements -->
    99<a id="anchor" href="tabindex-defaults.html">anchor</a>
     10<iframe id="iframe"></iframe>
     11<object id="object"></object>
    1012<button id="button">button</button>
    1113<input id="input">
     
    1416<keygen id="keygen"></keygen>
    1517<div id="editableDiv" contenteditable="true"></div>
     18<details><summary id="activeSummary"></summary></details>
    1619
    1720<!-- Unfocusable element -->
     
    1922<output id="output"></output>
    2023<fieldset id="fieldset"></fieldset>
     24<video id="video"></video>
     25<video id="videoWithControls" controls></video>
     26<details><summary></summary><summary id="summary"></summary></details>
     27<iframe id="iframeForDesignMode"></iframe>
     28<svg><g id="g" onfocus="alert('fail')"></g></svg>
    2129</div>
    2230
     
    2533
    2634var anchor = document.getElementById('anchor');
     35var iframe = document.getElementById('iframe');
     36iframe.contentDocument.open();
     37iframe.contentDocument.write('<!DOCTYPE><html><frameset cols="50%,50%"><frame></frame></frameset>');
     38var frame = iframe.contentDocument.querySelector('frame');
     39var object = document.getElementById('object');
    2740var button = document.getElementById('button');
    2841var input = document.getElementById('input');
    2942var select = document.getElementById('select');
    3043var textarea = document.getElementById('textarea');
     44var keygen = document.getElementById('keygen');
    3145var editableDiv = document.getElementById('editableDiv');
     46var normalDiv = document.getElementById('normalDiv');
    3247var output = document.getElementById('output');
    3348var fieldset = document.getElementById('fieldset');
    34 var keygen = document.getElementById('keygen');
    35 var normalDiv = document.getElementById('normalDiv');
     49var video = document.getElementById('video');
     50var videoWithControls = document.getElementById('videoWithControls');
     51var summary = document.getElementById('summary');
     52var activeSummary = document.getElementById('activeSummary');
     53var iframeForDesignMode = document.getElementById('iframeForDesignMode');
     54iframeForDesignMode.contentDocument.designMode = 'on';
     55var bodyInDesignMode = iframeForDesignMode.contentDocument.body;
     56var g = document.getElementById('g');
    3657
    3758shouldBe('anchor.tabIndex', '0');
     59shouldBe('iframe.tabIndex', '0');
     60shouldBe('frame.tabIndex', '0');
     61shouldBe('object.tabIndex', '0');
    3862shouldBe('button.tabIndex', '0');
    3963shouldBe('input.tabIndex', '0');
     
    4165shouldBe('textarea.tabIndex', '0');
    4266shouldBe('keygen.tabIndex', '0');
    43 shouldBe('editableDiv.tabIndex', '0');
     67shouldBe('activeSummary.tabIndex', '0');
     68shouldBe('editableDiv.tabIndex', '-1');
    4469shouldBe('normalDiv.tabIndex', '-1');
    4570shouldBe('output.tabIndex', '-1');
    4671shouldBe('fieldset.tabIndex', '-1');
     72shouldBe('video.tabIndex', '-1');
     73shouldBe('videoWithControls.tabIndex', '-1');
     74shouldBe('summary.tabIndex', '-1');
     75shouldBe('bodyInDesignMode.tabIndex', '-1');
     76shouldBe('g.tabIndex', '-1');
    4777
    4878shouldBe('anchor.setAttribute("tabindex", "invalid"); anchor.tabIndex', '0');
     79shouldBe('iframe.setAttribute("tabindex", "invalid"); iframe.tabIndex', '0');
     80shouldBe('frame.setAttribute("tabindex", "invalid"); frame.tabIndex', '0');
     81shouldBe('object.setAttribute("tabindex", "invalid"); object.tabIndex', '0');
    4982shouldBe('button.setAttribute("tabindex", "invalid"); button.tabIndex', '0');
    5083shouldBe('input.setAttribute("tabindex", "invalid"); input.tabIndex', '0');
     
    5285shouldBe('textarea.setAttribute("tabindex", "invalid"); textarea.tabIndex', '0');
    5386shouldBe('keygen.setAttribute("tabindex", "invalid"); keygen.tabIndex', '0');
    54 shouldBe('editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex', '0');
     87shouldBe('activeSummary.setAttribute("tabindex", "invalid"); activeSummary.tabIndex', '0');
     88shouldBe('editableDiv.setAttribute("tabindex", "invalid"); editableDiv.tabIndex', '-1');
    5589shouldBe('normalDiv.setAttribute("tabindex", "invalid"); normalDiv.tabIndex', '-1');
    5690shouldBe('output.setAttribute("tabindex", "invalid"); output.tabIndex', '-1');
    5791shouldBe('fieldset.setAttribute("tabindex", "invalid"); fieldset.tabIndex', '-1');
     92shouldBe('video.setAttribute("tabindex", "invalid"); video.tabIndex', '-1');
     93shouldBe('videoWithControls.setAttribute("tabindex", "invalid"); videoWithControls.tabIndex', '-1');
     94shouldBe('summary.setAttribute("tabindex", "invalid"); summary.tabIndex', '-1');
     95shouldBe('bodyInDesignMode.setAttribute("tabindex", "invalid"); bodyInDesignMode.tabIndex', '-1');
     96shouldBe('g.setAttribute("tabindex", "invalid"); g.tabIndex', '-1');
    5897
    5998shouldBe('anchor.setAttribute("tabindex", "9999999999"); anchor.tabIndex', '0');
     99shouldBe('iframe.setAttribute("tabindex", "9999999999"); iframe.tabIndex', '0');
     100shouldBe('frame.setAttribute("tabindex", "9999999999"); frame.tabIndex', '0');
     101shouldBe('object.setAttribute("tabindex", "invalid"); object.tabIndex', '0');
    60102shouldBe('button.setAttribute("tabindex", "9999999999"); button.tabIndex', '0');
    61103shouldBe('input.setAttribute("tabindex", "9999999999"); input.tabIndex', '0');
     
    63105shouldBe('textarea.setAttribute("tabindex", "9999999999"); textarea.tabIndex', '0');
    64106shouldBe('keygen.setAttribute("tabindex", "9999999999"); keygen.tabIndex', '0');
    65 shouldBe('editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex', '0');
     107shouldBe('activeSummary.setAttribute("tabindex", "9999999999"); activeSummary.tabIndex', '0');
     108shouldBe('editableDiv.setAttribute("tabindex", "9999999999"); editableDiv.tabIndex', '-1');
    66109shouldBe('normalDiv.setAttribute("tabindex", "9999999999"); normalDiv.tabIndex', '-1');
    67110shouldBe('output.setAttribute("tabindex", "9999999999"); output.tabIndex', '-1');
    68111shouldBe('fieldset.setAttribute("tabindex", "9999999999"); fieldset.tabIndex', '-1');
     112shouldBe('video.setAttribute("tabindex", "9999999999"); video.tabIndex', '-1');
     113shouldBe('videoWithControls.setAttribute("tabindex", "9999999999"); videoWithControls.tabIndex', '-1');
     114shouldBe('summary.setAttribute("tabindex", "9999999999"); summary.tabIndex', '-1');
     115shouldBe('bodyInDesignMode.setAttribute("tabindex", "9999999999"); bodyInDesignMode.tabIndex', '-1');
     116shouldBe('g.setAttribute("tabindex", "9999999999"); g.tabIndex', '-1');
    69117
    70118document.getElementById('container').innerHTML = '';
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r249205 r249237  
     12019-08-28  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Make tabIndex IDL attribute reflect its content attribute
     4        https://bugs.webkit.org/show_bug.cgi?id=199606
     5        <rdar://problem/52811448>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaselined now that test cases for summary are passing.
     10
    1112019-08-28  Alicia Boya García  <aboya@igalia.com>
    212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-misc-expected.txt

    r247527 r249237  
    27872787PASS summary.accessKey: IDL set to object "test-valueOf"
    27882788PASS summary.tabIndex: typeof IDL attribute
    2789 FAIL summary.tabIndex: setAttribute() to -36 assert_equals: IDL get expected -36 but got -1
     2789PASS summary.tabIndex: setAttribute() to -36
    27902790PASS summary.tabIndex: setAttribute() to -1
    2791 FAIL summary.tabIndex: setAttribute() to 0 assert_equals: IDL get expected 0 but got -1
    2792 FAIL summary.tabIndex: setAttribute() to 1 assert_equals: IDL get expected 1 but got -1
    2793 FAIL summary.tabIndex: setAttribute() to 2147483647 assert_equals: IDL get expected 2147483647 but got -1
    2794 FAIL summary.tabIndex: setAttribute() to -2147483648 assert_equals: IDL get expected -2147483648 but got -1
     2791PASS summary.tabIndex: setAttribute() to 0
     2792PASS summary.tabIndex: setAttribute() to 1
     2793PASS summary.tabIndex: setAttribute() to 2147483647
     2794PASS summary.tabIndex: setAttribute() to -2147483648
    27952795PASS summary.tabIndex: setAttribute() to "-1"
    2796 FAIL summary.tabIndex: setAttribute() to "-0" assert_equals: IDL get expected 0 but got -1
    2797 FAIL summary.tabIndex: setAttribute() to "0" assert_equals: IDL get expected 0 but got -1
    2798 FAIL summary.tabIndex: setAttribute() to "1" assert_equals: IDL get expected 1 but got -1
    2799 FAIL summary.tabIndex: setAttribute() to "\t7" assert_equals: IDL get expected 7 but got -1
    2800 FAIL summary.tabIndex: setAttribute() to "\f7" assert_equals: IDL get expected 7 but got -1
    2801 FAIL summary.tabIndex: setAttribute() to " 7" assert_equals: IDL get expected 7 but got -1
    2802 FAIL summary.tabIndex: setAttribute() to "\n7" assert_equals: IDL get expected 7 but got -1
    2803 FAIL summary.tabIndex: setAttribute() to "\r7" assert_equals: IDL get expected 7 but got -1
    2804 FAIL summary.tabIndex: setAttribute() to 1.5 assert_equals: IDL get expected 1 but got -1
    2805 FAIL summary.tabIndex: setAttribute() to object "2" assert_equals: IDL get expected 2 but got -1
    2806 FAIL summary.tabIndex: IDL set to -36 assert_equals: IDL get expected -36 but got -1
     2796PASS summary.tabIndex: setAttribute() to "-0"
     2797PASS summary.tabIndex: setAttribute() to "0"
     2798PASS summary.tabIndex: setAttribute() to "1"
     2799PASS summary.tabIndex: setAttribute() to "\t7"
     2800PASS summary.tabIndex: setAttribute() to "\f7"
     2801PASS summary.tabIndex: setAttribute() to " 7"
     2802PASS summary.tabIndex: setAttribute() to "\n7"
     2803PASS summary.tabIndex: setAttribute() to "\r7"
     2804PASS summary.tabIndex: setAttribute() to 1.5
     2805PASS summary.tabIndex: setAttribute() to object "2"
     2806PASS summary.tabIndex: IDL set to -36
    28072807PASS summary.tabIndex: IDL set to -1
    2808 FAIL summary.tabIndex: IDL set to 0 assert_equals: IDL get expected 0 but got -1
    2809 FAIL summary.tabIndex: IDL set to 1 assert_equals: IDL get expected 1 but got -1
    2810 FAIL summary.tabIndex: IDL set to 2147483647 assert_equals: IDL get expected 2147483647 but got -1
    2811 FAIL summary.tabIndex: IDL set to -2147483648 assert_equals: IDL get expected -2147483648 but got -1
     2808PASS summary.tabIndex: IDL set to 0
     2809PASS summary.tabIndex: IDL set to 1
     2810PASS summary.tabIndex: IDL set to 2147483647
     2811PASS summary.tabIndex: IDL set to -2147483648
    28122812PASS menu.title: typeof IDL attribute
    28132813PASS menu.title: IDL get with DOM attribute unset
  • trunk/LayoutTests/plugins/focus-expected.txt

    r199054 r249237  
    88TEST COMPLETE
    99PASS "embedElem"; document.activeElement === pluginElement is true
     10PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1011PASS "objectElem"; document.activeElement === pluginElement is true
     12PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1113PASS "embedElemWithFallbackContents"; document.activeElement === pluginElement is true
     14PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1215PASS "objectElemWithFallbackContents"; document.activeElement === pluginElement is true
     16PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1317PASS "noPluginEmbedElem"; document.activeElement === pluginElement is false
     18PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1419PASS "noPluginObjectElem"; document.activeElement === pluginElement is false
     20PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1521PASS "noPluginEmbedElemWithFallbackContents"; document.activeElement === pluginElement is false
     22PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1623PASS "noPluginObjectElemWithFallbackContents"; document.activeElement === pluginElement is false
     24PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1725PASS "noPluginEmbedElemWithTabindex"; document.activeElement === pluginElement is true
     26PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1827PASS "noPluginObjectElemWithTabindex"; document.activeElement === pluginElement is true
     28PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    1929PASS "noPluginEmbedElemWithContenteditable"; document.activeElement === pluginElement is true
     30PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    2031PASS "noPluginObjectElemWithContenteditable"; document.activeElement === pluginElement is true
     32PASS pluginElement.tabIndex is parseInt(pluginElement.getAttribute("data-expected-tabindex"))
    2133fast/events/tabindex-focus-blur-all.html
    2234Test for bug 32292: "Unable to focus on embedded plugins such as Flash via javascript focus()"
  • trunk/LayoutTests/plugins/focus.html

    r155282 r249237  
    1010<p>This tests focusing Embeds and Objects. See LayoutTests/java for Applet elements.</p>
    1111<div id=embedOwner>
    12 <embed id="embedElem" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true></embed>
    13 <object id="objectElem" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true></object>
     12<embed id="embedElem" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true data-expected-tabindex=-1></embed>
     13<object id="objectElem" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true data-expected-tabindex=0></object>
    1414
    15 <embed id="embedElemWithFallbackContents" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true>Fallback contents.</embed>
    16 <object id="objectElemWithFallbackContents" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true>Fallback contents.</object>
     15<embed id="embedElemWithFallbackContents" type="application/x-webkit-test-netscape" width=100 height=100 shouldFocus=true  data-expected-tabindex=-1>Fallback contents.</embed>
     16<object id="objectElemWithFallbackContents" type="application/x-webkit-test-netscape" windowedPlugin="false" width=100 height=100 shouldFocus=true data-expected-tabindex=0>Fallback contents.</object>
    1717
    18 <embed id="noPluginEmbedElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false></embed>
    19 <object id="noPluginObjectElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false></object>
     18<embed id="noPluginEmbedElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=-1></embed>
     19<object id="noPluginObjectElem" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=0></object>
    2020
    21 <embed id="noPluginEmbedElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false>Fallback contents.</embed>
    22 <object id="noPluginObjectElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false>Fallback contents.</object>
     21<embed id="noPluginEmbedElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=-1>Fallback contents.</embed>
     22<object id="noPluginObjectElemWithFallbackContents" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 shouldFocus=false data-expected-tabindex=0>Fallback contents.</object>
    2323
    24 <embed id="noPluginEmbedElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true></embed>
    25 <object id="noPluginObjectElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true></object>
     24<embed id="noPluginEmbedElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true data-expected-tabindex=-1></embed>
     25<object id="noPluginObjectElemWithTabindex" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 tabindex=-1 shouldFocus=true data-expected-tabindex=-1></object>
    2626
    27 <embed id="noPluginEmbedElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true></embed>
    28 <object id="noPluginObjectElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true></object>
     27<embed id="noPluginEmbedElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true data-expected-tabindex=-1></embed>
     28<object id="noPluginObjectElemWithContenteditable" type="application/x-no-such-plugin" windowedPlugin="false" width=100 height=100 contenteditable=true shouldFocus=true data-expected-tabindex=0></object>
    2929</div>
    3030<script>
     
    4040            shouldBe('"' + pluginElement.id + '"; document.activeElement === pluginElement',
    4141                pluginElement.getAttribute("shouldFocus").toString());
     42            shouldBe('pluginElement.tabIndex', 'parseInt(pluginElement.getAttribute("data-expected-tabindex"))');
    4243            pluginElement.blur();
    4344        }
  • trunk/LayoutTests/svg/custom/tabindex-order-expected.txt

    r248983 r249237  
    1717id: j tabindex: 0 [object SVGLineElement] is focused.
    1818id: k tabindex: 0 [object SVGPolygonElement] is focused.
     19id: a tabindex: 1 [object SVGCircleElement] is focused.
    1920
    2021Tabbing backward....
     
    3233id: b tabindex: 1 [object SVGGElement] is focused.
    3334id: a tabindex: 1 [object SVGCircleElement] is focused.
     35id: k tabindex: 0 [object SVGPolygonElement] is focused.
    3436
    3537Test finished
  • trunk/LayoutTests/svg/custom/tabindex-order.html

    r248983 r249237  
    3535            }
    3636
     37            document.activeElement.blur();
     38
    3739            var rects = document.getElementsByClassName('tab');
    3840
     
    4446
    4547            log('Tabbing forward....\n');
     48            let tabCount = 0;
    4649            for (var i = 0; i < rects.length; ++i) {
    47                 if (rects[i].tabIndex >= 0)
    48                     dispatchTabPress(document, false);
     50                if (i > 1 && document.activeElement.id == 'a')
     51                    break;
     52                dispatchTabPress(document, false);
     53                tabCount++;
    4954            }
    5055
     
    5257
    5358            log('\nTabbing backward....\n');
    54             for (var i = 0; i < rects.length; ++i) {
    55                 if (rects[i].tabIndex >= 0)
    56                     dispatchTabPress(document, true);
    57             }
     59            previousActiveElement = null;
     60            for (var i = 0; i < tabCount; ++i)
     61                dispatchTabPress(document, true);
    5862
    5963            log('\nTest finished\n');
  • trunk/Source/WebCore/ChangeLog

    r249236 r249237  
     12019-08-28  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Make tabIndex IDL attribute reflect its content attribute
     4        https://bugs.webkit.org/show_bug.cgi?id=199606
     5        <rdar://problem/52811448>
     6
     7        Reviewed by Chris Dumez.
     8
     9        This patch makes tabIndex IDL attribute no longer return 0 when the element is focusable
     10        to match the latest HTML5 specification. Instead, the IDL attribute simply reflect the tabindex
     11        content attribute with some elements having 0 as the default tab index (see r248784):
     12        https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute
     13
     14        The practical implication is that tabIndex IDL attribute on a root editable element (a.k.a.
     15        editing host in HTML5 spec term), body element in design mode, and media elements with
     16        media controls would start returning -1 instead of 0.
     17
     18        Mechanically, this is accomplished by removing the special case in Element::tabIndexForBindings
     19        when supportsFocus returned true. The effect, if any, this patch has on each element which
     20        overrides Element::supportsFocus is summarized as follows (indentation simplies inheritance):
     21
     22        HTMLAnchorElement -> No effect since defaultTabIndex returns 0.
     23            HTMLAreaElement -> Ditto.
     24        HTMLBodyElement -> Changes to return -1 in design mode.
     25        HTMLElement -> Changes to return -1 on a root editable element.
     26        HTMLFormControlElement
     27            HTMLButtonElement -> No effect since defaultTabIndex returns 0.
     28            HTMLFieldSetElement -> No effect since this is an override to use HTMLElement's supportsFocus.
     29            HTMLFormControlElementWithState
     30                HTMLKeygenElement -> No effect since defaultTabIndex returns 0.
     31                HTMLSelectElement -> Ditto.
     32                HTMLTextFormControlElement -> Ditto.
     33                    HTMLInputElement -> Ditto.
     34                    HTMLTextAreaElement -> Ditto.
     35            HTMLOutputElement -> No effect since this is an override to use HTMLElement's supportsFocus.
     36        HTMLFrameElementBase - No change. Added defaultTabIndex on HTMLIFrameElement and HTMLFrameElement
     37            to returns 0.
     38        HTMLImageElement - No impact since it only affects when an image is set to be editable via SPI.
     39        HTMLMediaElement - Changes to return -1 when media controls is present.
     40        HTMLPlugInElement - applet and embed elements change to return -1 when the plugin is available.
     41        HTMLSummaryElement - No change. Added defaultTabIndex to return 0 when it's active to match
     42            supportsFocus as well as the HTML5 specification.
     43        MathMLElement - No effect since tabIndex IDL attribute does not exist in MathML.
     44        SVGAElement - No effect since defaultTabIndex returns 0.
     45        SVGClipPathElement - No effect since it always returns false.
     46        SVGDefsElement - No effect since it always returns false.
     47
     48        Tests: fast/dom/tabindex-defaults.html
     49               plugins/focus.html
     50
     51        * dom/Element.cpp:
     52        (WebCore::Element::tabIndexForBindings const): Made the change.
     53        * html/HTMLFrameElement.cpp:
     54        (WebCore::HTMLFrameElement::defaultTabIndex const): Added to preserve the existing behavior.
     55        * html/HTMLFrameElement.h:
     56        * html/HTMLIFrameElement.cpp:
     57        (WebCore::HTMLIFrameElement::defaultTabIndex const): Ditto.
     58        * html/HTMLIFrameElement.h:
     59        * html/HTMLObjectElement.cpp:
     60        (WebCore::HTMLObjectElement::defaultTabIndex const): Added. Always return 0 to match the spec.
     61        * html/HTMLObjectElement.h:
     62        * html/HTMLSummaryElement.cpp:
     63        (WebCore::HTMLSummaryElement::defaultTabIndex const): Added. Return 0 when the this summary
     64        is the active summary element of the details element.
     65        * html/HTMLSummaryElement.h:
     66
    1672019-08-28  Simon Fraser  <simon.fraser@apple.com>
    268
  • trunk/Source/WebCore/dom/Element.cpp

    r248846 r249237  
    268268int Element::tabIndexForBindings() const
    269269{
    270     auto defaultIndex = defaultTabIndex();
    271     ASSERT(!defaultIndex || defaultIndex == -1);
    272     // FIXME: supportsFocus() check shouldn't be here.
    273     if (!defaultIndex || supportsFocus())
    274         return tabIndexSetExplicitly().valueOr(0);
    275     return defaultIndex;
     270    return valueOrCompute(tabIndexSetExplicitly(), [&] { return defaultTabIndex(); });
    276271}
    277272
  • trunk/Source/WebCore/html/HTMLFrameElement.cpp

    r247529 r249237  
    7575}
    7676
     77int HTMLFrameElement::defaultTabIndex() const
     78{
     79    return 0;
     80}
     81
    7782void HTMLFrameElement::parseAttribute(const QualifiedName& name, const AtomString& value)
    7883{
  • trunk/Source/WebCore/html/HTMLFrameElement.h

    r246490 r249237  
    4646    bool rendererIsNeeded(const RenderStyle&) final;
    4747    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
     48    int defaultTabIndex() const final;
    4849    void parseAttribute(const QualifiedName&, const AtomString&) final;
    4950
  • trunk/Source/WebCore/html/HTMLIFrameElement.cpp

    r248846 r249237  
    5050{
    5151    return adoptRef(*new HTMLIFrameElement(tagName, document));
     52}
     53
     54int HTMLIFrameElement::defaultTabIndex() const
     55{
     56    return 0;
    5257}
    5358
  • trunk/Source/WebCore/html/HTMLIFrameElement.h

    r249194 r249237  
    5050    HTMLIFrameElement(const QualifiedName&, Document&);
    5151
     52    int defaultTabIndex() const final;
    5253    void parseAttribute(const QualifiedName&, const AtomString&) final;
    5354    bool isPresentationAttribute(const QualifiedName&) const final;
  • trunk/Source/WebCore/html/HTMLObjectElement.cpp

    r249194 r249237  
    8787}
    8888
     89int HTMLObjectElement::defaultTabIndex() const
     90{
     91    return 0;
     92}
     93
    8994bool HTMLObjectElement::isPresentationAttribute(const QualifiedName& name) const
    9095{
  • trunk/Source/WebCore/html/HTMLObjectElement.h

    r249194 r249237  
    6060    HTMLObjectElement(const QualifiedName&, Document&, HTMLFormElement*);
    6161
     62    RenderWidget* renderWidgetLoadingPlugin() const final;
     63
     64    int defaultTabIndex() const final;
     65
    6266    void parseAttribute(const QualifiedName&, const AtomString&) final;
    6367    bool isPresentationAttribute(const QualifiedName&) const final;
     
    7478    bool isURLAttribute(const Attribute&) const final;
    7579    const AtomString& imageSourceURL() const final;
    76 
    77     RenderWidget* renderWidgetLoadingPlugin() const final;
    7880
    7981    void addSubresourceAttributeURLs(ListHashSet<URL>&) const final;
  • trunk/Source/WebCore/html/HTMLSummaryElement.cpp

    r248846 r249237  
    103103}
    104104
     105int HTMLSummaryElement::defaultTabIndex() const
     106{
     107    return isActiveSummary() ? 0 : -1;
     108}
     109
    105110bool HTMLSummaryElement::supportsFocus() const
    106111{
  • trunk/Source/WebCore/html/HTMLSummaryElement.h

    r229694 r249237  
    4747    RefPtr<HTMLDetailsElement> detailsElement() const;
    4848
     49    int defaultTabIndex() const final;
    4950    bool supportsFocus() const final;
    5051};
Note: See TracChangeset for help on using the changeset viewer.