 Chromium Code Reviews
 Chromium Code Reviews Issue 2322413003:
  Show ancestor hierarchy in accessibility panel  (Closed)
    
  
    Issue 2322413003:
  Show ancestor hierarchy in accessibility panel  (Closed) 
  | Index: third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp | 
| diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp | 
| index c1762d60d37ab82fa0aad7b88924a6452b53e707..65540313740d7403a8fb80d1a6f5ade429393c60 100644 | 
| --- a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp | 
| +++ b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp | 
| @@ -8,6 +8,7 @@ | 
| #include "core/dom/AXObjectCache.h" | 
| #include "core/dom/DOMNodeIds.h" | 
| #include "core/dom/Element.h" | 
| +#include "core/inspector/IdentifiersFactory.h" | 
| #include "core/inspector/InspectorDOMAgent.h" | 
| #include "core/inspector/InspectorStyleSheet.h" | 
| #include "core/page/Page.h" | 
| @@ -300,7 +301,7 @@ std::unique_ptr<AXValue> createRoleNameValue(AccessibilityRole role) | 
| return roleNameValue; | 
| } | 
| -std::unique_ptr<AXNode> buildObjectForIgnoredNode(Node* node, AXObject* axObject, AXObjectCacheImpl* cacheImpl) | 
| +std::unique_ptr<AXNode> buildObjectForIgnoredNode(Node* node, const AXObject* axObject, AXObjectCacheImpl* cacheImpl) | 
| { | 
| AXObject::IgnoredReasons ignoredReasons; | 
| @@ -311,7 +312,7 @@ std::unique_ptr<AXNode> buildObjectForIgnoredNode(Node* node, AXObject* axObject | 
| axID = axObject->axObjectID(); | 
| AccessibilityRole role = axObject->roleValue(); | 
| ignoredNodeObject->setRole(createRoleNameValue(role)); | 
| - } else if (!node->layoutObject()) { | 
| + } else if (node && !node->layoutObject()) { | 
| ignoredReasons.append(IgnoredReason(AXNotRendered)); | 
| } | 
| @@ -323,12 +324,19 @@ std::unique_ptr<AXNode> buildObjectForIgnoredNode(Node* node, AXObject* axObject | 
| return ignoredNodeObject; | 
| } | 
| -std::unique_ptr<AXNode> buildObjectForNode(Node* node, AXObject* axObject, AXObjectCacheImpl* cacheImpl, std::unique_ptr<protocol::Array<AXProperty>> properties) | 
| +std::unique_ptr<AXNode> buildProtocolAXObject(AXObject* axObject, AXObjectCacheImpl* cacheImpl) | 
| { | 
| AccessibilityRole role = axObject->roleValue(); | 
| std::unique_ptr<AXNode> nodeObject = AXNode::create().setNodeId(String::number(axObject->axObjectID())).setIgnored(false).build(); | 
| nodeObject->setRole(createRoleNameValue(role)); | 
| + std::unique_ptr<protocol::Array<AXProperty>> properties = protocol::Array<AXProperty>::create(); | 
| + fillLiveRegionProperties(axObject, properties.get()); | 
| + fillGlobalStates(axObject, properties.get()); | 
| + fillWidgetProperties(axObject, properties.get()); | 
| + fillWidgetStates(axObject, properties.get()); | 
| + fillRelationships(axObject, properties.get()); | 
| + | 
| AXObject::NameSources nameSources; | 
| String computedName = axObject->name(&nameSources); | 
| if (!nameSources.isEmpty()) { | 
| @@ -364,46 +372,63 @@ InspectorAccessibilityAgent::InspectorAccessibilityAgent(Page* page, InspectorDO | 
| { | 
| } | 
| -void InspectorAccessibilityAgent::getAXNode(ErrorString* errorString, int nodeId, Maybe<AXNode>* accessibilityNode) | 
| +void InspectorAccessibilityAgent::getAXNodeForDOMNode(ErrorString* errorString, int domNodeId, bool fetchAncestors, Maybe<protocol::Array<protocol::Accessibility::AXNode>>* nodes) | 
| { | 
| - Frame* mainFrame = m_page->mainFrame(); | 
| - if (!mainFrame->isLocalFrame()) { | 
| - *errorString = "Can't inspect out of process frames yet"; | 
| - return; | 
| - } | 
| + discardFrontendBindings(); | 
| 
dgozman
2016/09/15 17:45:44
If the cache is not used in subsequent protocol ca
 
aboxhall
2016/09/15 20:30:08
It will be used in later changes, once I add getCh
 | 
| if (!m_domAgent->enabled()) { | 
| *errorString = "DOM agent must be enabled"; | 
| return; | 
| } | 
| - Node* node = m_domAgent->assertNode(errorString, nodeId); | 
| + Node* node = m_domAgent->assertNode(errorString, domNodeId); | 
| if (!node) | 
| return; | 
| Document& document = node->document(); | 
| document.updateStyleAndLayoutIgnorePendingStylesheets(); | 
| DocumentLifecycle::DisallowTransitionScope disallowTransition(document.lifecycle()); | 
| - std::unique_ptr<ScopedAXObjectCache> cache = ScopedAXObjectCache::create(document); | 
| - AXObjectCacheImpl* cacheImpl = toAXObjectCacheImpl(cache->get()); | 
| + LocalFrame* localFrame = document.frame(); | 
| + if (!localFrame) { | 
| + *errorString = "Can't inspect out of process frames yet"; | 
| 
dgozman
2016/09/15 17:45:44
This actually means frame is detached. Out of proc
 
aboxhall
2016/09/15 20:30:08
Ah ok, changed error string.
 | 
| + return; | 
| + } | 
| + AXObjectCache* cache = nullptr; | 
| + String frameId = IdentifiersFactory::frameId(localFrame); | 
| + CacheMap::iterator it = m_frameToAXObjectCacheMap.find(frameId); | 
| + if (it != m_frameToAXObjectCacheMap.end()) { | 
| + cache = it->value; | 
| + } else { | 
| + cache = AXObjectCache::create(document); | 
| + m_frameToAXObjectCacheMap.set(frameId, cache); | 
| + } | 
| + | 
| + AXObjectCacheImpl* cacheImpl = toAXObjectCacheImpl(cache); | 
| 
dgozman
2016/09/15 17:45:44
If we actually need an AXObjectCacheImpl, let's re
 
aboxhall
2016/09/15 20:30:08
Done.
 | 
| AXObject* axObject = cacheImpl->getOrCreate(node); | 
| + *nodes = protocol::Array<protocol::Accessibility::AXNode>::create(); | 
| 
dgozman
2016/09/15 17:45:44
Let's not create nodes if there was no axObject.
 
aboxhall
2016/09/15 20:30:08
I don't follow - either way an object gets added t
 
dgozman
2016/09/17 00:36:23
Then it should not be optional in protocol.
 
aboxhall
2016/09/17 01:12:34
Done.
 | 
| if (!axObject || axObject->accessibilityIsIgnored()) { | 
| - *accessibilityNode = buildObjectForIgnoredNode(node, axObject, cacheImpl); | 
| - return; | 
| + nodes->fromJust()->addItem(buildObjectForIgnoredNode(node, axObject, cacheImpl)); | 
| + } else { | 
| + nodes->fromJust()->addItem(buildProtocolAXObject(axObject, cacheImpl)); | 
| } | 
| - std::unique_ptr<protocol::Array<AXProperty>> properties = protocol::Array<AXProperty>::create(); | 
| - fillLiveRegionProperties(axObject, properties.get()); | 
| - fillGlobalStates(axObject, properties.get()); | 
| - fillWidgetProperties(axObject, properties.get()); | 
| - fillWidgetStates(axObject, properties.get()); | 
| - fillRelationships(axObject, properties.get()); | 
| + if (fetchAncestors && axObject) { | 
| + AXObject* parent = axObject->parentObjectUnignored(); | 
| + while (parent) { | 
| + nodes->fromJust()->addItem(buildProtocolAXObject(parent, cacheImpl)); | 
| + parent = parent->parentObjectUnignored(); | 
| + } | 
| + } | 
| +} | 
| - *accessibilityNode = buildObjectForNode(node, axObject, cacheImpl, std::move(properties)); | 
| +void InspectorAccessibilityAgent::discardFrontendBindings() | 
| +{ | 
| + m_frameToAXObjectCacheMap.clear(); | 
| } | 
| DEFINE_TRACE(InspectorAccessibilityAgent) | 
| { | 
| visitor->trace(m_page); | 
| + visitor->trace(m_frameToAXObjectCacheMap); | 
| visitor->trace(m_domAgent); | 
| InspectorBaseAgent::trace(visitor); | 
| } |