blob: d2509887016f78cb99f053b6b3accb548821726a [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/accessibility/InspectorTypeBuilderHelper.h"
#include "core/InspectorTypeBuilder.h"
#include "core/dom/DOMNodeIds.h"
#include "modules/accessibility/AXObject.h"
#include "modules/accessibility/AXObjectCacheImpl.h"
namespace blink {
using TypeBuilder::Accessibility::AXValueNativeSourceType;
using TypeBuilder::Accessibility::AXRelatedNode;
using TypeBuilder::Accessibility::AXValueSourceType;
PassRefPtr<AXProperty> createProperty(String name, PassRefPtr<AXValue> value)
{
RefPtr<AXProperty> property = AXProperty::create().setName(name).setValue(value);
return property;
}
PassRefPtr<AXProperty> createProperty(AXGlobalStates::Enum name, PassRefPtr<AXValue> value)
{
return createProperty(TypeBuilder::getEnumConstantValue(name), value);
}
PassRefPtr<AXProperty> createProperty(AXLiveRegionAttributes::Enum name, PassRefPtr<AXValue> value)
{
return createProperty(TypeBuilder::getEnumConstantValue(name), value);
}
PassRefPtr<AXProperty> createProperty(AXRelationshipAttributes::Enum name, PassRefPtr<AXValue> value)
{
return createProperty(TypeBuilder::getEnumConstantValue(name), value);
}
PassRefPtr<AXProperty> createProperty(AXWidgetAttributes::Enum name, PassRefPtr<AXValue> value)
{
return createProperty(TypeBuilder::getEnumConstantValue(name), value);
}
PassRefPtr<AXProperty> createProperty(AXWidgetStates::Enum name, PassRefPtr<AXValue> value)
{
return createProperty(TypeBuilder::getEnumConstantValue(name), value);
}
String ignoredReasonName(AXIgnoredReason reason)
{
switch (reason) {
case AXActiveModalDialog:
return "activeModalDialog";
case AXAncestorDisallowsChild:
return "ancestorDisallowsChild";
case AXAncestorIsLeafNode:
return "ancestorIsLeafNode";
case AXAriaHidden:
return "ariaHidden";
case AXAriaHiddenRoot:
return "ariaHiddenRoot";
case AXEmptyAlt:
return "emptyAlt";
case AXEmptyText:
return "emptyText";
case AXInert:
return "inert";
case AXInheritsPresentation:
return "inheritsPresentation";
case AXLabelContainer:
return "labelContainer";
case AXLabelFor:
return "labelFor";
case AXNotRendered:
return "notRendered";
case AXNotVisible:
return "notVisible";
case AXPresentationalRole:
return "presentationalRole";
case AXProbablyPresentational:
return "probablyPresentational";
case AXStaticTextUsedAsNameFor:
return "staticTextUsedAsNameFor";
case AXUninteresting:
return "uninteresting";
}
ASSERT_NOT_REACHED();
return "";
}
PassRefPtr<AXProperty> createProperty(IgnoredReason reason)
{
if (reason.relatedObject)
return createProperty(ignoredReasonName(reason.reason), createRelatedNodeListValue(reason.relatedObject, nullptr, AXValueType::Idref));
return createProperty(ignoredReasonName(reason.reason), createBooleanValue(true));
}
PassRefPtr<AXValue> createValue(String value, AXValueType::Enum type)
{
RefPtr<AXValue> axValue = AXValue::create().setType(type);
axValue->setValue(JSONString::create(value));
return axValue;
}
PassRefPtr<AXValue> createValue(int value, AXValueType::Enum type)
{
RefPtr<AXValue> axValue = AXValue::create().setType(type);
axValue->setValue(JSONBasicValue::create(value));
return axValue;
}
PassRefPtr<AXValue> createValue(float value, AXValueType::Enum type)
{
RefPtr<AXValue> axValue = AXValue::create().setType(type);
axValue->setValue(JSONBasicValue::create(value));
return axValue;
}
PassRefPtr<AXValue> createBooleanValue(bool value, AXValueType::Enum type)
{
RefPtr<AXValue> axValue = AXValue::create().setType(type);
axValue->setValue(JSONBasicValue::create(value));
return axValue;
}
PassRefPtr<AXRelatedNode> relatedNodeForAXObject(const AXObject* axObject, String* name = nullptr)
{
Node* node = axObject->node();
if (!node)
return PassRefPtr<AXRelatedNode>();
int backendNodeId = DOMNodeIds::idForNode(node);
if (!backendNodeId)
return PassRefPtr<AXRelatedNode>();
RefPtr<AXRelatedNode> relatedNode = AXRelatedNode::create().setBackendNodeId(backendNodeId);
if (!node->isElementNode())
return relatedNode;
Element* element = toElement(node);
const AtomicString& idref = element->getIdAttribute();
if (!idref.isEmpty())
relatedNode->setIdref(idref);
if (name)
relatedNode->setText(*name);
return relatedNode;
}
PassRefPtr<AXValue> createRelatedNodeListValue(const AXObject* axObject, String* name, AXValueType::Enum valueType)
{
RefPtr<AXValue> axValue = AXValue::create().setType(valueType);
RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObject, name);
RefPtr<TypeBuilder::Array<AXRelatedNode>> relatedNodes = TypeBuilder::Array<AXRelatedNode>::create();
relatedNodes->addItem(relatedNode);
axValue->setRelatedNodes(relatedNodes);
return axValue;
}
PassRefPtr<AXValue> createRelatedNodeListValue(AXRelatedObjectVector& relatedObjects, AXValueType::Enum valueType)
{
RefPtr<TypeBuilder::Array<AXRelatedNode>> frontendRelatedNodes = TypeBuilder::Array<AXRelatedNode>::create();
for (unsigned i = 0; i < relatedObjects.size(); i++) {
RefPtr<AXRelatedNode> frontendRelatedNode = relatedNodeForAXObject(relatedObjects[i]->object, &(relatedObjects[i]->text));
if (frontendRelatedNode)
frontendRelatedNodes->addItem(frontendRelatedNode);
}
RefPtr<AXValue> axValue = AXValue::create().setType(valueType);
axValue->setRelatedNodes(frontendRelatedNodes);
return axValue;
}
PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AXObjectVector& axObjects, AXValueType::Enum valueType)
{
RefPtr<TypeBuilder::Array<AXRelatedNode>> relatedNodes = TypeBuilder::Array<AXRelatedNode>::create();
for (unsigned i = 0; i < axObjects.size(); i++) {
RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObjects[i].get());
if (relatedNode)
relatedNodes->addItem(relatedNode);
}
RefPtr<AXValue> axValue = AXValue::create().setType(valueType);
axValue->setRelatedNodes(relatedNodes);
return axValue;
}
AXValueSourceType::Enum valueSourceType(AXNameFrom nameFrom)
{
switch (nameFrom) {
case AXNameFromAttribute:
case AXNameFromTitle:
case AXNameFromValue:
return AXValueSourceType::Attribute;
case AXNameFromContents:
return AXValueSourceType::Contents;
case AXNameFromPlaceholder:
return AXValueSourceType::Placeholder;
case AXNameFromCaption:
case AXNameFromRelatedElement:
return AXValueSourceType::RelatedElement;
default:
return AXValueSourceType::Implicit; // TODO(aboxhall): what to do here?
}
}
AXValueNativeSourceType::Enum nativeSourceType(AXTextFromNativeHTML nativeSource)
{
switch (nativeSource) {
case AXTextFromNativeHTMLFigcaption:
return AXValueNativeSourceType::Figcaption;
case AXTextFromNativeHTMLLabel:
return AXValueNativeSourceType::Label;
case AXTextFromNativeHTMLLabelFor:
return AXValueNativeSourceType::Labelfor;
case AXTextFromNativeHTMLLabelWrapped:
return AXValueNativeSourceType::Labelwrapped;
case AXTextFromNativeHTMLTableCaption:
return AXValueNativeSourceType::Tablecaption;
case AXTextFromNativeHTMLLegend:
return AXValueNativeSourceType::Legend;
case AXTextFromNativeHTMLTitleElement:
return AXValueNativeSourceType::Title;
default:
return AXValueNativeSourceType::Other;
}
}
PassRefPtr<AXValueSource> createValueSource(NameSource& nameSource)
{
String attribute = nameSource.attribute.toString();
AXValueSourceType::Enum type = valueSourceType(nameSource.type);
RefPtr<AXValueSource> valueSource = AXValueSource::create().setType(type);
RefPtr<AXValue> value;
if (!nameSource.relatedObjects.isEmpty()) {
AXValueType::Enum valueType = nameSource.attributeValue.isNull() ? AXValueType::NodeList : AXValueType::IdrefList;
value = createRelatedNodeListValue(nameSource.relatedObjects, valueType);
if (!nameSource.attributeValue.isNull())
value->setValue(JSONString::create(nameSource.attributeValue.string()));
valueSource->setValue(value);
} else if (!nameSource.text.isNull()) {
valueSource->setValue(createValue(nameSource.text));
} else if (!nameSource.attributeValue.isNull()) {
valueSource->setValue(createValue(nameSource.attributeValue));
}
if (nameSource.attribute != QualifiedName::null())
valueSource->setAttribute(nameSource.attribute.localName().string());
if (nameSource.superseded)
valueSource->setSuperseded(true);
if (nameSource.invalid)
valueSource->setInvalid(true);
if (nameSource.nativeSource != AXTextFromNativeHTMLUninitialized)
valueSource->setNativeSource(nativeSourceType(nameSource.nativeSource));
return valueSource;
}
} // namespace blink