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 |