blob: 897aa823305752ee7080da440b2424c4485ccccd [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/dom/DOMNodeIds.h"
#include "modules/accessibility/AXObjectCacheImpl.h"
#include "modules/accessibility/AXObjectImpl.h"
namespace blink {
using namespace HTMLNames;
using namespace protocol::Accessibility;
std::unique_ptr<AXProperty> CreateProperty(const String& name,
std::unique_ptr<AXValue> value) {
return AXProperty::create().setName(name).setValue(std::move(value)).build();
}
String IgnoredReasonName(AXIgnoredReason reason) {
switch (reason) {
case kAXActiveModalDialog:
return "activeModalDialog";
case kAXAncestorDisallowsChild:
return "ancestorDisallowsChild";
case kAXAncestorIsLeafNode:
return "ancestorIsLeafNode";
case kAXAriaHiddenElement:
return "ariaHiddenElement";
case kAXAriaHiddenSubtree:
return "ariaHiddenSubtree";
case kAXEmptyAlt:
return "emptyAlt";
case kAXEmptyText:
return "emptyText";
case kAXInertElement:
return "inertElement";
case kAXInertSubtree:
return "inertSubtree";
case kAXInheritsPresentation:
return "inheritsPresentation";
case kAXLabelContainer:
return "labelContainer";
case kAXLabelFor:
return "labelFor";
case kAXNotRendered:
return "notRendered";
case kAXNotVisible:
return "notVisible";
case kAXPresentationalRole:
return "presentationalRole";
case kAXProbablyPresentational:
return "probablyPresentational";
case kAXStaticTextUsedAsNameFor:
return "staticTextUsedAsNameFor";
case kAXUninteresting:
return "uninteresting";
}
NOTREACHED();
return "";
}
std::unique_ptr<AXProperty> CreateProperty(IgnoredReason reason) {
if (reason.related_object)
return CreateProperty(
IgnoredReasonName(reason.reason),
CreateRelatedNodeListValue(*(reason.related_object), nullptr,
AXValueTypeEnum::Idref));
return CreateProperty(IgnoredReasonName(reason.reason),
CreateBooleanValue(true));
}
std::unique_ptr<AXValue> CreateValue(const String& value, const String& type) {
return AXValue::create()
.setType(type)
.setValue(protocol::ValueConversions<String>::toValue(value))
.build();
}
std::unique_ptr<AXValue> CreateValue(int value, const String& type) {
return AXValue::create()
.setType(type)
.setValue(protocol::ValueConversions<int>::toValue(value))
.build();
}
std::unique_ptr<AXValue> CreateValue(float value, const String& type) {
return AXValue::create()
.setType(type)
.setValue(protocol::ValueConversions<double>::toValue(value))
.build();
}
std::unique_ptr<AXValue> CreateBooleanValue(bool value, const String& type) {
return AXValue::create()
.setType(type)
.setValue(protocol::ValueConversions<bool>::toValue(value))
.build();
}
std::unique_ptr<AXRelatedNode> RelatedNodeForAXObjectImpl(
const AXObjectImpl& ax_object,
String* name = nullptr) {
Node* node = ax_object.GetNode();
if (!node)
return nullptr;
int backend_node_id = DOMNodeIds::IdForNode(node);
if (!backend_node_id)
return nullptr;
std::unique_ptr<AXRelatedNode> related_node =
AXRelatedNode::create().setBackendDOMNodeId(backend_node_id).build();
if (!node->IsElementNode())
return related_node;
Element* element = ToElement(node);
String idref = element->GetIdAttribute();
if (!idref.IsEmpty())
related_node->setIdref(idref);
if (name)
related_node->setText(*name);
return related_node;
}
std::unique_ptr<AXValue> CreateRelatedNodeListValue(
const AXObjectImpl& ax_object,
String* name,
const String& value_type) {
std::unique_ptr<protocol::Array<AXRelatedNode>> related_nodes =
protocol::Array<AXRelatedNode>::create();
related_nodes->addItem(RelatedNodeForAXObjectImpl(ax_object, name));
return AXValue::create()
.setType(value_type)
.setRelatedNodes(std::move(related_nodes))
.build();
}
std::unique_ptr<AXValue> CreateRelatedNodeListValue(
AXRelatedObjectVector& related_objects,
const String& value_type) {
std::unique_ptr<protocol::Array<AXRelatedNode>> frontend_related_nodes =
protocol::Array<AXRelatedNode>::create();
for (unsigned i = 0; i < related_objects.size(); i++) {
std::unique_ptr<AXRelatedNode> frontend_related_node =
RelatedNodeForAXObjectImpl(*(related_objects[i]->object),
&(related_objects[i]->text));
if (frontend_related_node)
frontend_related_nodes->addItem(std::move(frontend_related_node));
}
return AXValue::create()
.setType(value_type)
.setRelatedNodes(std::move(frontend_related_nodes))
.build();
}
std::unique_ptr<AXValue> CreateRelatedNodeListValue(
AXObjectImpl::AXObjectVector& ax_objects,
const String& value_type) {
std::unique_ptr<protocol::Array<AXRelatedNode>> related_nodes =
protocol::Array<AXRelatedNode>::create();
for (unsigned i = 0; i < ax_objects.size(); i++) {
std::unique_ptr<AXRelatedNode> related_node =
RelatedNodeForAXObjectImpl(*(ax_objects[i].Get()));
if (related_node)
related_nodes->addItem(std::move(related_node));
}
return AXValue::create()
.setType(value_type)
.setRelatedNodes(std::move(related_nodes))
.build();
}
String ValueSourceType(AXNameFrom name_from) {
switch (name_from) {
case kAXNameFromAttribute:
case kAXNameFromAttributeExplicitlyEmpty:
case kAXNameFromTitle:
case kAXNameFromValue:
return AXValueSourceTypeEnum::Attribute;
case kAXNameFromContents:
return AXValueSourceTypeEnum::Contents;
case kAXNameFromPlaceholder:
return AXValueSourceTypeEnum::Placeholder;
case kAXNameFromCaption:
case kAXNameFromRelatedElement:
return AXValueSourceTypeEnum::RelatedElement;
default:
return AXValueSourceTypeEnum::Implicit; // TODO(aboxhall): what to do
// here?
}
}
String NativeSourceType(AXTextFromNativeHTML native_source) {
switch (native_source) {
case kAXTextFromNativeHTMLFigcaption:
return AXValueNativeSourceTypeEnum::Figcaption;
case kAXTextFromNativeHTMLLabel:
return AXValueNativeSourceTypeEnum::Label;
case kAXTextFromNativeHTMLLabelFor:
return AXValueNativeSourceTypeEnum::Labelfor;
case kAXTextFromNativeHTMLLabelWrapped:
return AXValueNativeSourceTypeEnum::Labelwrapped;
case kAXTextFromNativeHTMLTableCaption:
return AXValueNativeSourceTypeEnum::Tablecaption;
case kAXTextFromNativeHTMLLegend:
return AXValueNativeSourceTypeEnum::Legend;
case kAXTextFromNativeHTMLTitleElement:
return AXValueNativeSourceTypeEnum::Title;
default:
return AXValueNativeSourceTypeEnum::Other;
}
}
std::unique_ptr<AXValueSource> CreateValueSource(NameSource& name_source) {
String type = ValueSourceType(name_source.type);
std::unique_ptr<AXValueSource> value_source =
AXValueSource::create().setType(type).build();
if (!name_source.related_objects.IsEmpty()) {
if (name_source.attribute == aria_labelledbyAttr ||
name_source.attribute == aria_labeledbyAttr) {
std::unique_ptr<AXValue> attribute_value = CreateRelatedNodeListValue(
name_source.related_objects, AXValueTypeEnum::IdrefList);
if (!name_source.attribute_value.IsNull())
attribute_value->setValue(protocol::StringValue::create(
name_source.attribute_value.GetString()));
value_source->setAttributeValue(std::move(attribute_value));
} else if (name_source.attribute == QualifiedName::Null()) {
value_source->setNativeSourceValue(CreateRelatedNodeListValue(
name_source.related_objects, AXValueTypeEnum::NodeList));
}
} else if (!name_source.attribute_value.IsNull()) {
value_source->setAttributeValue(CreateValue(name_source.attribute_value));
}
if (!name_source.text.IsNull())
value_source->setValue(
CreateValue(name_source.text, AXValueTypeEnum::ComputedString));
if (name_source.attribute != QualifiedName::Null())
value_source->setAttribute(name_source.attribute.LocalName().GetString());
if (name_source.superseded)
value_source->setSuperseded(true);
if (name_source.invalid)
value_source->setInvalid(true);
if (name_source.native_source != kAXTextFromNativeHTMLUninitialized)
value_source->setNativeSource(NativeSourceType(name_source.native_source));
return value_source;
}
} // namespace blink