| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "modules/accessibility/InspectorAccessibilityAgent.h" | 7 #include "modules/accessibility/InspectorAccessibilityAgent.h" |
| 8 | 8 |
| 9 #include "core/dom/AXObjectCache.h" | 9 #include "core/dom/AXObjectCache.h" |
| 10 #include "core/dom/DOMNodeIds.h" | 10 #include "core/dom/DOMNodeIds.h" |
| 11 #include "core/dom/Element.h" | 11 #include "core/dom/Element.h" |
| 12 #include "core/inspector/InspectorDOMAgent.h" | 12 #include "core/inspector/InspectorDOMAgent.h" |
| 13 #include "core/inspector/InspectorState.h" | 13 #include "core/inspector/InspectorState.h" |
| 14 #include "core/inspector/InspectorStyleSheet.h" | 14 #include "core/inspector/InspectorStyleSheet.h" |
| 15 #include "core/page/Page.h" | 15 #include "core/page/Page.h" |
| 16 #include "modules/accessibility/AXObject.h" | 16 #include "modules/accessibility/AXObject.h" |
| 17 #include "modules/accessibility/AXObjectCacheImpl.h" | 17 #include "modules/accessibility/AXObjectCacheImpl.h" |
| 18 #include "modules/accessibility/InspectorTypeBuilderHelper.h" |
| 18 #include "platform/JSONValues.h" | 19 #include "platform/JSONValues.h" |
| 19 | 20 |
| 20 namespace blink { | 21 namespace blink { |
| 21 | 22 |
| 22 using TypeBuilder::Accessibility::AXGlobalStates; | 23 using TypeBuilder::Accessibility::AXGlobalStates; |
| 24 using TypeBuilder::Accessibility::AXIgnoredReasons; |
| 23 using TypeBuilder::Accessibility::AXLiveRegionAttributes; | 25 using TypeBuilder::Accessibility::AXLiveRegionAttributes; |
| 24 using TypeBuilder::Accessibility::AXNode; | 26 using TypeBuilder::Accessibility::AXNode; |
| 25 using TypeBuilder::Accessibility::AXNodeId; | 27 using TypeBuilder::Accessibility::AXNodeId; |
| 26 using TypeBuilder::Accessibility::AXProperty; | 28 using TypeBuilder::Accessibility::AXProperty; |
| 27 using TypeBuilder::Accessibility::AXValueType; | 29 using TypeBuilder::Accessibility::AXValueType; |
| 28 using TypeBuilder::Accessibility::AXRelatedNode; | 30 using TypeBuilder::Accessibility::AXRelatedNode; |
| 29 using TypeBuilder::Accessibility::AXRelationshipAttributes; | 31 using TypeBuilder::Accessibility::AXRelationshipAttributes; |
| 30 using TypeBuilder::Accessibility::AXValue; | 32 using TypeBuilder::Accessibility::AXValue; |
| 31 using TypeBuilder::Accessibility::AXWidgetAttributes; | 33 using TypeBuilder::Accessibility::AXWidgetAttributes; |
| 32 using TypeBuilder::Accessibility::AXWidgetStates; | 34 using TypeBuilder::Accessibility::AXWidgetStates; |
| 33 | 35 |
| 34 namespace { | 36 namespace { |
| 35 | 37 |
| 36 PassRefPtr<AXProperty> createProperty(String name, PassRefPtr<AXValue> value) | |
| 37 { | |
| 38 RefPtr<AXProperty> property = AXProperty::create().setName(name).setValue(va
lue); | |
| 39 return property; | |
| 40 } | |
| 41 | |
| 42 PassRefPtr<AXProperty> createProperty(AXGlobalStates::Enum name, PassRefPtr<AXVa
lue> value) | |
| 43 { | |
| 44 return createProperty(TypeBuilder::getEnumConstantValue(name), value); | |
| 45 } | |
| 46 | |
| 47 PassRefPtr<AXProperty> createProperty(AXLiveRegionAttributes::Enum name, PassRef
Ptr<AXValue> value) | |
| 48 { | |
| 49 return createProperty(TypeBuilder::getEnumConstantValue(name), value); | |
| 50 } | |
| 51 | |
| 52 | |
| 53 PassRefPtr<AXProperty> createProperty(AXRelationshipAttributes::Enum name, PassR
efPtr<AXValue> value) | |
| 54 { | |
| 55 return createProperty(TypeBuilder::getEnumConstantValue(name), value); | |
| 56 } | |
| 57 | |
| 58 PassRefPtr<AXProperty> createProperty(AXWidgetAttributes::Enum name, PassRefPtr<
AXValue> value) | |
| 59 { | |
| 60 return createProperty(TypeBuilder::getEnumConstantValue(name), value); | |
| 61 } | |
| 62 | |
| 63 PassRefPtr<AXProperty> createProperty(AXWidgetStates::Enum name, PassRefPtr<AXVa
lue> value) | |
| 64 { | |
| 65 return createProperty(TypeBuilder::getEnumConstantValue(name), value); | |
| 66 } | |
| 67 | |
| 68 | |
| 69 PassRefPtr<AXValue> createValue(String value, AXValueType::Enum type = AXValueTy
pe::String) | |
| 70 { | |
| 71 RefPtr<AXValue> axValue = AXValue::create().setType(type); | |
| 72 axValue->setValue(JSONString::create(value)); | |
| 73 return axValue; | |
| 74 } | |
| 75 | |
| 76 PassRefPtr<AXValue> createValue(int value, AXValueType::Enum type = AXValueType:
:Integer) | |
| 77 { | |
| 78 RefPtr<AXValue> axValue = AXValue::create().setType(type); | |
| 79 axValue->setValue(JSONBasicValue::create(value)); | |
| 80 return axValue; | |
| 81 } | |
| 82 | |
| 83 PassRefPtr<AXValue> createValue(float value, AXValueType::Enum type = AXValueTyp
e::Number) | |
| 84 { | |
| 85 RefPtr<AXValue> axValue = AXValue::create().setType(type); | |
| 86 axValue->setValue(JSONBasicValue::create(value)); | |
| 87 return axValue; | |
| 88 } | |
| 89 | |
| 90 PassRefPtr<AXValue> createBooleanValue(bool value, AXValueType::Enum type = AXVa
lueType::Boolean) | |
| 91 { | |
| 92 RefPtr<AXValue> axValue = AXValue::create().setType(type); | |
| 93 axValue->setValue(JSONBasicValue::create(value)); | |
| 94 return axValue; | |
| 95 } | |
| 96 | |
| 97 PassRefPtr<AXRelatedNode> relatedNodeForAXObject(const AXObject* axObject) | |
| 98 { | |
| 99 Node* node = axObject->node(); | |
| 100 if (!node) | |
| 101 return PassRefPtr<AXRelatedNode>(); | |
| 102 int backendNodeId = DOMNodeIds::idForNode(node); | |
| 103 if (!backendNodeId) | |
| 104 return PassRefPtr<AXRelatedNode>(); | |
| 105 RefPtr<AXRelatedNode> relatedNode = AXRelatedNode::create().setBackendNodeId
(backendNodeId); | |
| 106 if (!node->isElementNode()) | |
| 107 return relatedNode; | |
| 108 | |
| 109 Element* element = toElement(node); | |
| 110 const AtomicString& idref = element->getIdAttribute(); | |
| 111 if (!idref.isEmpty()) | |
| 112 relatedNode->setIdref(idref); | |
| 113 return relatedNode; | |
| 114 } | |
| 115 | |
| 116 | |
| 117 PassRefPtr<AXValue> createRelatedNodeValue(const AXObject* axObject) | |
| 118 { | |
| 119 RefPtr<AXValue> axValue = AXValue::create().setType(AXValueType::Idref); | |
| 120 RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObject); | |
| 121 axValue->setRelatedNodeValue(relatedNode); | |
| 122 return axValue; | |
| 123 } | |
| 124 | |
| 125 PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AccessibilityChildrenVe
ctor axObjects) | |
| 126 { | |
| 127 RefPtr<TypeBuilder::Array<AXRelatedNode>> relatedNodes = TypeBuilder::Array<
AXRelatedNode>::create(); | |
| 128 for (unsigned i = 0; i < axObjects.size(); i++) { | |
| 129 if (RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObjects
[i].get())) | |
| 130 relatedNodes->addItem(relatedNode); | |
| 131 } | |
| 132 RefPtr<AXValue> axValue = AXValue::create().setType(AXValueType::IdrefList); | |
| 133 axValue->setRelatedNodeArrayValue(relatedNodes); | |
| 134 return axValue; | |
| 135 } | |
| 136 | |
| 137 void fillCoreProperties(AXObject* axObject, PassRefPtr<AXNode> nodeObject) | 38 void fillCoreProperties(AXObject* axObject, PassRefPtr<AXNode> nodeObject) |
| 138 { | 39 { |
| 139 // core properties | 40 // core properties |
| 140 String description = axObject->deprecatedAccessibilityDescription(); | 41 String description = axObject->deprecatedAccessibilityDescription(); |
| 141 if (!description.isEmpty()) | 42 if (!description.isEmpty()) |
| 142 nodeObject->setDescription(createValue(description)); | 43 nodeObject->setDescription(createValue(description)); |
| 143 | 44 |
| 144 if (axObject->supportsRangeValue()) { | 45 if (axObject->supportsRangeValue()) { |
| 145 nodeObject->setValue(createValue(axObject->valueForRange())); | 46 nodeObject->setValue(createValue(axObject->valueForRange())); |
| 146 } else { | 47 } else { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 if (!results.isEmpty()) | 275 if (!results.isEmpty()) |
| 375 properties->addItem(createProperty(AXRelationshipAttributes::Labelledby,
createRelatedNodeListValue(results))); | 276 properties->addItem(createProperty(AXRelationshipAttributes::Labelledby,
createRelatedNodeListValue(results))); |
| 376 results.clear(); | 277 results.clear(); |
| 377 | 278 |
| 378 axObject->ariaOwnsElements(results); | 279 axObject->ariaOwnsElements(results); |
| 379 if (!results.isEmpty()) | 280 if (!results.isEmpty()) |
| 380 properties->addItem(createProperty(AXRelationshipAttributes::Owns, creat
eRelatedNodeListValue(results))); | 281 properties->addItem(createProperty(AXRelationshipAttributes::Owns, creat
eRelatedNodeListValue(results))); |
| 381 results.clear(); | 282 results.clear(); |
| 382 } | 283 } |
| 383 | 284 |
| 384 PassRefPtr<AXNode> buildObjectForNode(Node* node, AXObject* axObject, AXObjectCa
cheImpl* cacheImpl, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) | 285 PassRefPtr<AXValue> createRoleNameValue(AccessibilityRole role) |
| 385 { | 286 { |
| 386 AccessibilityRole role = axObject->roleValue(); | |
| 387 AtomicString roleName = AXObject::roleName(role); | 287 AtomicString roleName = AXObject::roleName(role); |
| 388 RefPtr<AXValue> roleNameValue; | 288 RefPtr<AXValue> roleNameValue; |
| 389 if (!roleName.isNull()) { | 289 if (!roleName.isNull()) { |
| 390 roleNameValue = createValue(roleName, AXValueType::Role); | 290 roleNameValue = createValue(roleName, AXValueType::Role); |
| 391 } else { | 291 } else { |
| 392 roleNameValue = createValue(AXObject::internalRoleName(role), AXValueTyp
e::InternalRole); | 292 roleNameValue = createValue(AXObject::internalRoleName(role), AXValueTyp
e::InternalRole); |
| 393 } | 293 } |
| 394 RefPtr<AXNode> nodeObject = AXNode::create().setNodeId(String::number(axObje
ct->axObjectID())).setRole(roleNameValue).setProperties(properties); | 294 return roleNameValue; |
| 295 } |
| 296 |
| 297 PassRefPtr<AXNode> buildObjectForIgnoredNode(Node* node, AXObject* axObject, AXO
bjectCacheImpl* cacheImpl) |
| 298 { |
| 299 AXObject::IgnoredReasons ignoredReasons; |
| 300 |
| 301 AXID axID = 0; |
| 302 if (axObject) { |
| 303 axObject->computeAccessibilityIsIgnored(&ignoredReasons); |
| 304 axID = axObject->axObjectID(); |
| 305 } else if (!node->layoutObject()) { |
| 306 ignoredReasons.append(IgnoredReason(AXNotRendered)); |
| 307 } |
| 308 |
| 309 RefPtr<TypeBuilder::Array<AXProperty>> ignoredReasonProperties = TypeBuilder
::Array<AXProperty>::create(); |
| 310 for (size_t i = 0; i < ignoredReasons.size(); i++) |
| 311 ignoredReasonProperties->addItem(createProperty(ignoredReasons[i])); |
| 312 RefPtr<AXNode> ignoredNodeObject = AXNode::create().setNodeId(String::number
(axID)).setIgnored(true); |
| 313 ignoredNodeObject->setIgnoredReasons(ignoredReasonProperties); |
| 314 return ignoredNodeObject; |
| 315 } |
| 316 |
| 317 PassRefPtr<AXNode> buildObjectForNode(Node* node, AXObject* axObject, AXObjectCa
cheImpl* cacheImpl, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) |
| 318 { |
| 319 AccessibilityRole role = axObject->roleValue(); |
| 320 RefPtr<AXNode> nodeObject = AXNode::create().setNodeId(String::number(axObje
ct->axObjectID())).setIgnored(false); |
| 321 nodeObject->setRole(createRoleNameValue(role)); |
| 322 nodeObject->setProperties(properties); |
| 395 String computedName = cacheImpl->computedNameForNode(node); | 323 String computedName = cacheImpl->computedNameForNode(node); |
| 396 if (!computedName.isEmpty()) | 324 if (!computedName.isEmpty()) |
| 397 nodeObject->setName(createValue(computedName)); | 325 nodeObject->setName(createValue(computedName)); |
| 398 | 326 |
| 399 fillCoreProperties(axObject, nodeObject); | 327 fillCoreProperties(axObject, nodeObject); |
| 400 return nodeObject; | 328 return nodeObject; |
| 401 } | 329 } |
| 402 | 330 |
| 403 } // namespace | 331 } // namespace |
| 404 | 332 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 417 } | 345 } |
| 418 | 346 |
| 419 InspectorDOMAgent* domAgent = toLocalFrame(mainFrame)->instrumentingAgents()
->inspectorDOMAgent(); | 347 InspectorDOMAgent* domAgent = toLocalFrame(mainFrame)->instrumentingAgents()
->inspectorDOMAgent(); |
| 420 if (!domAgent) { | 348 if (!domAgent) { |
| 421 *errorString = "DOM agent must be enabled"; | 349 *errorString = "DOM agent must be enabled"; |
| 422 return; | 350 return; |
| 423 } | 351 } |
| 424 Node* node = domAgent->assertNode(errorString, nodeId); | 352 Node* node = domAgent->assertNode(errorString, nodeId); |
| 425 if (!node) | 353 if (!node) |
| 426 return; | 354 return; |
| 355 |
| 427 Document& document = node->document(); | 356 Document& document = node->document(); |
| 428 RefPtr<ScopedAXObjectCache> cache(adoptRef(new ScopedAXObjectCache(document)
)); | 357 RefPtr<ScopedAXObjectCache> cache(adoptRef(new ScopedAXObjectCache(document)
)); |
| 429 AXObjectCacheImpl* cacheImpl = toAXObjectCacheImpl(cache->get()); | 358 AXObjectCacheImpl* cacheImpl = toAXObjectCacheImpl(cache->get()); |
| 430 AXObject* axObject = cacheImpl->getOrCreate(node); | 359 AXObject* axObject = cacheImpl->getOrCreate(node); |
| 431 if (!axObject) | 360 if (!axObject || axObject->accessibilityIsIgnored()) { |
| 361 accessibilityNode = buildObjectForIgnoredNode(node, axObject, cacheImpl)
; |
| 432 return; | 362 return; |
| 363 } |
| 433 | 364 |
| 434 RefPtr<TypeBuilder::Array<AXProperty>> properties = TypeBuilder::Array<AXPro
perty>::create(); | 365 RefPtr<TypeBuilder::Array<AXProperty>> properties = TypeBuilder::Array<AXPro
perty>::create(); |
| 435 fillLiveRegionProperties(axObject, properties); | 366 fillLiveRegionProperties(axObject, properties); |
| 436 fillGlobalStates(axObject, properties); | 367 fillGlobalStates(axObject, properties); |
| 437 fillWidgetProperties(axObject, properties); | 368 fillWidgetProperties(axObject, properties); |
| 438 fillWidgetStates(axObject, properties); | 369 fillWidgetStates(axObject, properties); |
| 439 fillRelationships(axObject, properties); | 370 fillRelationships(axObject, properties); |
| 440 | 371 |
| 441 accessibilityNode = buildObjectForNode(node, axObject, cacheImpl, properties
); | 372 accessibilityNode = buildObjectForNode(node, axObject, cacheImpl, properties
); |
| 442 } | 373 } |
| 443 | 374 |
| 444 DEFINE_TRACE(InspectorAccessibilityAgent) | 375 DEFINE_TRACE(InspectorAccessibilityAgent) |
| 445 { | 376 { |
| 446 visitor->trace(m_page); | 377 visitor->trace(m_page); |
| 447 InspectorBaseAgent::trace(visitor); | 378 InspectorBaseAgent::trace(visitor); |
| 448 } | 379 } |
| 449 | 380 |
| 450 } // namespace blink | 381 } // namespace blink |
| OLD | NEW |