Chromium Code Reviews| Index: Source/core/svg/SVGElement.cpp |
| diff --git a/Source/core/svg/SVGElement.cpp b/Source/core/svg/SVGElement.cpp |
| index ca015d3ee51e2cd407a6d61be7d794ee9b1140b7..57c94f3244be0e1e40dde71f52dd03c12ae8fcd6 100644 |
| --- a/Source/core/svg/SVGElement.cpp |
| +++ b/Source/core/svg/SVGElement.cpp |
| @@ -36,7 +36,9 @@ |
| #include "core/dom/ElementTraversal.h" |
| #include "core/dom/shadow/ShadowRoot.h" |
| #include "core/events/Event.h" |
| +#include "core/frame/Settings.h" |
| #include "core/html/HTMLElement.h" |
| +#include "core/html/parser/HTMLParserIdioms.h" |
| #include "core/rendering/RenderObject.h" |
| #include "core/rendering/svg/RenderSVGResourceContainer.h" |
| #include "core/svg/SVGCursorElement.h" |
| @@ -630,6 +632,54 @@ void SVGElement::setCorrespondingElement(SVGElement* correspondingElement) |
| ensureSVGRareData()->setCorrespondingElement(correspondingElement); |
| } |
| +short SVGElement::tabIndex() const |
| +{ |
| + if (supportsFocus()) |
| + return Element::tabIndex(); |
| + return -1; |
| +} |
| + |
| +void SVGElement::setTabIndex(int value) |
| +{ |
| + setIntegralAttribute(tabindexAttr, value); |
| +} |
| + |
| +bool SVGElement::rendererIsFocusable() const |
| +{ |
| + return inDocument() && supportsFocus() && !isInert() && Element::tabIndex() >= 0; |
|
fs
2014/03/14 16:05:12
IIUC, they way this is called the the first three
Erik Dahlström (inactive)
2014/03/17 14:45:29
Hmm, true. I'll remove this.
visibility:hidden on
|
| +} |
| + |
| +bool SVGElement::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 Element::supportsFocus() || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable()) |
| + || supportsSpatialNavigationFocus(); |
| +} |
| + |
| +bool SVGElement::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) |
| + || hasEventListeners(EventTypeNames::focus) |
| + || hasEventListeners(EventTypeNames::blur) |
| + || hasEventListeners(EventTypeNames::focusin) |
| + || hasEventListeners(EventTypeNames::focusout); |
| +} |
| + |
| void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) |
| { |
| if (name == HTMLNames::classAttr) { |
| @@ -641,6 +691,19 @@ void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& v |
| m_className->setBaseValueAsString(value, parseError); |
| reportAttributeParsingError(parseError, name, value); |
| } else if (name.matches(XMLNames::langAttr) || name.matches(XMLNames::spaceAttr)) { |
| + } else 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())))); |
| + } |
| } else { |
| // standard events |
| const AtomicString& eventName = HTMLElement::eventNameForAttributeName(name); |
| @@ -1025,12 +1088,8 @@ RenderStyle* SVGElement::computedStyle(PseudoId pseudoElementSpecifier) |
| bool SVGElement::hasFocusEventListeners() const |
| { |
| - return hasEventListeners(EventTypeNames::focusin) || hasEventListeners(EventTypeNames::focusout); |
| -} |
| - |
| -bool SVGElement::isKeyboardFocusable() const |
| -{ |
| - return isFocusable(); |
| + return hasEventListeners(EventTypeNames::focusin) || hasEventListeners(EventTypeNames::focusout) |
| + || hasEventListeners(EventTypeNames::focus) || hasEventListeners(EventTypeNames::blur); |
| } |
| #ifndef NDEBUG |