| Index: Source/core/dom/Element.cpp
|
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
|
| index 943459796b164060b9f801ac09003f4a163cf835..2bcfb67b9a39ed486f56b3938113cfb869bafdef 100644
|
| --- a/Source/core/dom/Element.cpp
|
| +++ b/Source/core/dom/Element.cpp
|
| @@ -76,6 +76,7 @@
|
| #include "core/events/FocusEvent.h"
|
| #include "core/frame/FrameView.h"
|
| #include "core/frame/LocalFrame.h"
|
| +#include "core/frame/Settings.h"
|
| #include "core/frame/UseCounter.h"
|
| #include "core/frame/csp/ContentSecurityPolicy.h"
|
| #include "core/html/ClassList.h"
|
| @@ -232,6 +233,11 @@ void Element::setTabIndexExplicitly(short tabIndex)
|
| ensureElementRareData().setTabIndexExplicitly(tabIndex);
|
| }
|
|
|
| +void Element::setTabIndex(int value)
|
| +{
|
| + setIntegralAttribute(tabindexAttr, value);
|
| +}
|
| +
|
| short Element::tabIndex() const
|
| {
|
| return hasRareData() ? elementRareData()->tabIndex() : 0;
|
| @@ -1926,6 +1932,24 @@ PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& except
|
| return guard.release();
|
| }
|
|
|
| +void Element::parseAttribute(const QualifiedName& name, const AtomicString& value)
|
| +{
|
| + if (name == tabindexAttr) {
|
| + int tabindex = 0;
|
| + if (value.isEmpty()) {
|
| + clearTabIndexExplicitlyIfNeeded();
|
| + if (treeScope().adjustedFocusedElement() == this) {
|
| + // We might want to call blur(), but it's dangerous to dispatch
|
| + // events here.
|
| + document().setNeedsFocusedElementCheck();
|
| + }
|
| + } else if (parseHTMLInteger(value, tabindex)) {
|
| + // 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()))));
|
| + }
|
| + }
|
| +}
|
| +
|
| bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
|
| {
|
| AtomicString prefix, localName;
|
| @@ -2120,6 +2144,33 @@ void Element::blur()
|
| }
|
| }
|
|
|
| +bool Element::supportsFocus() const
|
| +{
|
| + // FIXME: supportsFocus() can be called when layout is not up to date.
|
| + // Logic that deals with the renderer should be moved to rendererIsFocusable().
|
| + // But supportsFocus must return true when the element is editable, or else
|
| + // it won't be focusable. Furthermore, supportsFocus cannot just return true
|
| + // always or else tabIndex() will change for all HTML elements.
|
| + return hasElementFlag(TabIndexWasSetExplicitly) || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable())
|
| + || supportsSpatialNavigationFocus();
|
| +}
|
| +
|
| +bool Element::supportsSpatialNavigationFocus() const
|
| +{
|
| + // This function checks whether the element satisfies the extended criteria
|
| + // for the element to be focusable, introduced by spatial navigation feature,
|
| + // i.e. checks if click or keyboard event handler is specified.
|
| + // This is the way to make it possible to navigate to (focus) elements
|
| + // which web designer meant for being active (made them respond to click events).
|
| +
|
| + if (!document().settings() || !document().settings()->spatialNavigationEnabled())
|
| + return false;
|
| + return hasEventListeners(EventTypeNames::click)
|
| + || hasEventListeners(EventTypeNames::keydown)
|
| + || hasEventListeners(EventTypeNames::keypress)
|
| + || hasEventListeners(EventTypeNames::keyup);
|
| +}
|
| +
|
| bool Element::isFocusable() const
|
| {
|
| return inDocument() && supportsFocus() && !isInert() && rendererIsFocusable();
|
|
|