Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Unified Diff: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp

Issue 2589273002: Add sparse accessibility attribute interface to Blink (Closed)
Patch Set: Try to fix win component build compile Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
index ce29eef87566c2319d2193e07301e2b8577c928b..8e0b8ef8c213329aeb5b6f1f984a67b1faabc8fb 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -32,6 +32,7 @@
#include "core/dom/DocumentUserGestureToken.h"
#include "core/dom/Element.h"
#include "core/dom/NodeTraversal.h"
+#include "core/dom/QualifiedName.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/FlatTreeTraversal.h"
#include "core/editing/EditingUtilities.h"
@@ -70,6 +71,111 @@ namespace blink {
using namespace HTMLNames;
+class AddSparseAttributeHelper {
+ public:
+ virtual void Run(const AXObject*,
+ AXSparseAttributeMap&,
+ const AtomicString& value) = 0;
+};
+
+typedef HashMap<QualifiedName, AddSparseAttributeHelper*>
+ AXSparseAttributeHelperMap;
+
+class AddBoolAttributeHelper : public AddSparseAttributeHelper {
+ public:
+ AddBoolAttributeHelper(AXBoolAttribute attribute) : m_attribute(attribute) {}
+
+ private:
+ AXBoolAttribute m_attribute;
+
+ void Run(const AXObject* obj,
+ AXSparseAttributeMap& attributeMap,
+ const AtomicString& value) override {
+ attributeMap.addBoolAttribute(m_attribute,
+ equalIgnoringCase(value, "true"));
+ }
+};
+
+class AddStringAttributeHelper : public AddSparseAttributeHelper {
+ public:
+ AddStringAttributeHelper(AXStringAttribute attribute)
+ : m_attribute(attribute) {}
+
+ private:
+ AXStringAttribute m_attribute;
+
+ void Run(const AXObject* obj,
+ AXSparseAttributeMap& attributeMap,
+ const AtomicString& value) override {
+ attributeMap.addStringAttribute(m_attribute, value);
+ }
+};
+
+class AddObjectAttributeHelper : public AddSparseAttributeHelper {
+ public:
+ AddObjectAttributeHelper(AXObjectAttribute attribute)
+ : m_attribute(attribute) {}
+
+ private:
+ AXObjectAttribute m_attribute;
+
+ void Run(const AXObject* obj,
+ AXSparseAttributeMap& attributeMap,
+ const AtomicString& value) override {
+ if (value.isNull() || value.isEmpty())
+ return;
+
+ Node* node = obj->getNode();
+ if (!node || !node->isElementNode())
+ return;
+ Element* target = toElement(node)->treeScope().getElementById(value);
+ if (!target)
+ return;
+ AXObject* axTarget = obj->axObjectCache().getOrCreate(target);
+ if (axTarget)
+ attributeMap.addObjectAttribute(m_attribute, axTarget);
+ }
+};
+
+class AddObjectVectorAttributeHelper : public AddSparseAttributeHelper {
+ public:
+ AddObjectVectorAttributeHelper(AXObjectVectorAttribute attribute)
+ : m_attribute(attribute) {}
+
+ private:
+ AXObjectVectorAttribute m_attribute;
+
+ void Run(const AXObject* obj,
+ AXSparseAttributeMap& attributeMap,
+ const AtomicString& value) override {
+ Node* node = obj->getNode();
+ if (!node || !node->isElementNode())
+ return;
+
+ String attributeValue = value.getString();
+ if (attributeValue.isEmpty())
+ return;
+
+ attributeValue.simplifyWhiteSpace();
+ Vector<String> ids;
+ attributeValue.split(' ', ids);
+ if (ids.isEmpty())
+ return;
+
+ HeapVector<Member<AXObject>> objects;
+ TreeScope& scope = node->treeScope();
+ for (const auto& id : ids) {
+ if (Element* idElement = scope.getElementById(AtomicString(id))) {
+ AXObject* axIdElement = obj->axObjectCache().getOrCreate(idElement);
+ if (axIdElement && !axIdElement->accessibilityIsIgnored())
+ objects.append(axIdElement);
+ }
+ }
+
+ attributeMap.addObjectVectorAttribute(m_attribute, objects);
+ }
+};
+
AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& axObjectCache)
: AXObject(axObjectCache),
m_ariaRole(UnknownRole),
@@ -752,6 +858,53 @@ void AXNodeObject::detach() {
m_node = nullptr;
}
+void AXNodeObject::getSparseAXAttributes(
+ AXSparseAttributeMap& sparseAttributeMap) const {
+ Node* node = this->getNode();
+ if (!node || !node->isElementNode())
+ return;
+
+ // Use a map from attribute name to properties of that attribute.
+ // That way we only need to iterate over the list of attributes once,
+ // rather than calling getAttribute() once for each possible obscure
+ // accessibility attribute.
+ DEFINE_STATIC_LOCAL(AXSparseAttributeHelperMap, axSparseAttributeHelperMap,
+ ());
+ if (axSparseAttributeHelperMap.isEmpty()) {
+ axSparseAttributeHelperMap.set(
aboxhall 2017/01/10 05:59:59 Perhaps pull this block out into a helper function
dmazzoni 2017/01/12 03:36:24 Done.
+ aria_activedescendantAttr,
+ new AddObjectAttributeHelper(AXObjectAttribute::AriaActiveDescendant));
+ axSparseAttributeHelperMap.set(aria_controlsAttr,
+ new AddObjectVectorAttributeHelper(
+ AXObjectVectorAttribute::AriaControls));
+ axSparseAttributeHelperMap.set(aria_detailsAttr,
+ new AddObjectVectorAttributeHelper(
+ AXObjectVectorAttribute::AriaDetails));
+ axSparseAttributeHelperMap.set(
+ aria_errormessageAttr,
+ new AddObjectAttributeHelper(AXObjectAttribute::AriaErrorMessage));
+ axSparseAttributeHelperMap.set(aria_flowtoAttr,
+ new AddObjectVectorAttributeHelper(
+ AXObjectVectorAttribute::AriaFlowTo));
+ axSparseAttributeHelperMap.set(
+ aria_keyshortcutsAttr,
+ new AddStringAttributeHelper(AXStringAttribute::AriaKeyShortcuts));
+ axSparseAttributeHelperMap.set(
+ aria_modalAttr, new AddBoolAttributeHelper(AXBoolAttribute::AriaModal));
+ axSparseAttributeHelperMap.set(
+ aria_roledescriptionAttr,
+ new AddStringAttributeHelper(AXStringAttribute::AriaRoleDescription));
+ }
+
+ AttributeCollection attributes = toElement(node)->attributesWithoutUpdate();
+ for (const Attribute& attr : attributes) {
+ AddSparseAttributeHelper* helper =
+ axSparseAttributeHelperMap.get(attr.name());
+ if (helper)
+ helper->Run(this, sparseAttributeMap, attr.value());
+ }
+}
+
bool AXNodeObject::isAnchor() const {
return !isNativeImage() && isLink();
}

Powered by Google App Engine
This is Rietveld 408576698