| Index: Source/core/dom/Element.cpp
|
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
|
| index 722b45b513d6876403d5cbad97d915c78e29c4cc..6b05bcca642b155358f9310c3885ae273b713265 100644
|
| --- a/Source/core/dom/Element.cpp
|
| +++ b/Source/core/dom/Element.cpp
|
| @@ -211,13 +211,20 @@ void Element::clearElementFlag(ElementFlags mask)
|
|
|
| void Element::clearTabIndexExplicitlyIfNeeded()
|
| {
|
| - if (hasRareData())
|
| + if (hasRareData()) {
|
| elementRareData()->clearTabIndexExplicitly();
|
| + // As tabindex is removed, unless there is an tabstop attribute,
|
| + // revert tabstop to default to match tabindex at this point (0).
|
| + if (!fastHasAttribute(tabstopAttr))
|
| + setTabStopInternal(true);
|
| + }
|
| }
|
|
|
| void Element::setTabIndexExplicitly(short tabIndex)
|
| {
|
| ensureElementRareData().setTabIndexExplicitly(tabIndex);
|
| + if (!fastHasAttribute(tabstopAttr))
|
| + setTabStopInternal(tabIndex >= 0);
|
| }
|
|
|
| void Element::setTabIndex(int value)
|
| @@ -2092,6 +2099,26 @@ void Element::parseAttribute(const QualifiedName& name, const AtomicString& valu
|
| // Clamp tabindex to the range of 'short' to match Firefox's behavior.
|
| setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
|
| }
|
| + } else if (RuntimeEnabledFeatures::tabStopAttributeEnabled() && name == tabstopAttr) {
|
| + if (!hasAttribute(tabstopAttr)) {
|
| + // tabstop attribute removed.
|
| + clearElementFlag(TabStopWasSetExplicitly);
|
| + setTabStopInternal(tabIndex() >= 0);
|
| + } else {
|
| + // Treat empty attribute as true.
|
| + if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, "")) {
|
| + setTabStopInternal(true);
|
| + setElementFlag(TabStopWasSetExplicitly, true);
|
| + } else if (equalIgnoringCase(value, "false")) {
|
| + setTabStopInternal(false);
|
| + setElementFlag(TabStopWasSetExplicitly, true);
|
| + } else {
|
| + // When value is other than "true", "false", "", the value is ignored and
|
| + // falls back the default state.
|
| + clearElementFlag(TabStopWasSetExplicitly);
|
| + setTabStopInternal(tabIndex() >= 0);
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| @@ -2334,12 +2361,21 @@ bool Element::isMouseFocusable() const
|
|
|
| bool Element::tabStop() const
|
| {
|
| - // Any element which never supports focus will always return false.
|
| - return supportsFocus() && (hasRareData() ? elementRareData()->tabStop() : true);
|
| + if (hasElementFlag(TabStopWasSetExplicitly))
|
| + return elementRareData()->tabStop();
|
| + return tabIndex() >= 0;
|
| }
|
|
|
| void Element::setTabStop(bool flag)
|
| {
|
| + // Reflect the value in the HTML attribute. Note that we cannot use setBooleanAttribute()
|
| + // because the tabstop attribute is an enumerated attribute.
|
| + // After tabstop attribute is set, the property value is modified accordingly.
|
| + setAttribute(tabstopAttr, flag ? "true" : "false");
|
| +}
|
| +
|
| +void Element::setTabStopInternal(bool flag)
|
| +{
|
| ensureElementRareData().setTabStop(flag);
|
| focusStateChanged();
|
| }
|
|
|