Commit 0a2243c0 authored by dmazzoni's avatar dmazzoni Committed by Commit bot

Int and Float properties for Accessibility Object Model phase 1

BUG=680345

Review-Url: https://codereview.chromium.org/2894103002
Cr-Commit-Position: refs/heads/master@{#473999}
parent f494f865
<!DOCTYPE HTML>
<script src="../resources/gc.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<!--
Accessibility Object Model
Explainer: https://github.com/WICG/aom/blob/master/explainer.md
Spec: https://wicg.github.io/aom/spec/
-->
<script>
if (window.internals)
internals.runtimeFlags.accessibilityObjectModelEnabled = true;
</script>
<div role="slider" id="slider" aria-valuenow="5"></div>
<script>
test(function(t) {
var node = document.getElementById("slider");
var axNode = accessibilityController.accessibleElementById("slider");
assert_equals(axNode.intValue, 5);
assert_equals(node.accessibleNode.valueNow, null);
node.accessibleNode.valueNow = 9;
assert_equals(axNode.intValue, 9);
node.accessibleNode.valueNow = null;
assert_equals(axNode.intValue, 5);
assert_equals(node.accessibleNode.valueNow, null);
}, "Boolean AOM properties do not reflect ARIA, and can be cleared.");
</script>
<div role="slider" id="slider2"></div>
<script>
test(function(t) {
var node = document.getElementById("slider2");
var axNode = accessibilityController.accessibleElementById("slider2");
assert_equals(axNode.intValue, 0);
assert_equals(axNode.minValue, 0);
assert_equals(axNode.maxValue, 0);
node.accessibleNode.valueNow = 33;
node.accessibleNode.valueMin = -100;
node.accessibleNode.valueMax = 100;;
assert_equals(axNode.intValue, 33);
assert_equals(axNode.minValue, -100);
assert_equals(axNode.maxValue, 100);
}, "Range values in accessible node.");
</script>
<!DOCTYPE HTML>
<script src="../resources/gc.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<!--
Accessibility Object Model
Explainer: https://github.com/WICG/aom/blob/master/explainer.md
Spec: https://wicg.github.io/aom/spec/
-->
<script>
if (window.internals)
internals.runtimeFlags.accessibilityObjectModelEnabled = true;
</script>
<div role=heading id=heading>
<script>
test(function(t) {
var node = document.getElementById("heading");
var axNode = accessibilityController.accessibleElementById("heading");
node.accessibleNode.level = 3;
// For historical reasons intValue returns the heading level.
assert_equals(axNode.intValue, 3);
}, "AOM level property");
</script>
<div role=list>
<div role=listitem id="listitem"></div>
</div>
<script>
test(function(t) {
var node = document.getElementById("listitem");
var axNode = accessibilityController.accessibleElementById("listitem");
node.accessibleNode.posInSet = 9;
node.accessibleNode.setSize = 10;
assert_equals(axNode.posInSet, 9);
assert_equals(axNode.setSize, 10);
}, "AOM posInSet and setSize");
</script>
...@@ -20,6 +20,9 @@ interface AccessibleNode ...@@ -20,6 +20,9 @@ interface AccessibleNode
getter autocomplete getter autocomplete
getter busy getter busy
getter checked getter checked
getter colCount
getter colIndex
getter colSpan
getter current getter current
getter disabled getter disabled
getter expanded getter expanded
...@@ -27,25 +30,37 @@ interface AccessibleNode ...@@ -27,25 +30,37 @@ interface AccessibleNode
getter invalid getter invalid
getter keyShortcuts getter keyShortcuts
getter label getter label
getter level
getter live getter live
getter modal getter modal
getter multiline getter multiline
getter multiselectable getter multiselectable
getter orientation getter orientation
getter placeholder getter placeholder
getter posInSet
getter readOnly getter readOnly
getter relevant getter relevant
getter required getter required
getter role getter role
getter roleDescription getter roleDescription
getter rowCount
getter rowIndex
getter rowSpan
getter selected getter selected
getter setSize
getter sort getter sort
getter valueMax
getter valueMin
getter valueNow
getter valueText getter valueText
method constructor method constructor
setter atomic setter atomic
setter autocomplete setter autocomplete
setter busy setter busy
setter checked setter checked
setter colCount
setter colIndex
setter colSpan
setter current setter current
setter disabled setter disabled
setter expanded setter expanded
...@@ -53,19 +68,28 @@ interface AccessibleNode ...@@ -53,19 +68,28 @@ interface AccessibleNode
setter invalid setter invalid
setter keyShortcuts setter keyShortcuts
setter label setter label
setter level
setter live setter live
setter modal setter modal
setter multiline setter multiline
setter multiselectable setter multiselectable
setter orientation setter orientation
setter placeholder setter placeholder
setter posInSet
setter readOnly setter readOnly
setter relevant setter relevant
setter required setter required
setter role setter role
setter roleDescription setter roleDescription
setter rowCount
setter rowIndex
setter rowSpan
setter selected setter selected
setter setSize
setter sort setter sort
setter valueMax
setter valueMin
setter valueNow
setter valueText setter valueText
interface AmbientLightSensor : Sensor interface AmbientLightSensor : Sensor
attribute @@toStringTag attribute @@toStringTag
......
...@@ -20,6 +20,9 @@ interface AccessibleNode ...@@ -20,6 +20,9 @@ interface AccessibleNode
getter autocomplete getter autocomplete
getter busy getter busy
getter checked getter checked
getter colCount
getter colIndex
getter colSpan
getter current getter current
getter disabled getter disabled
getter expanded getter expanded
...@@ -27,25 +30,37 @@ interface AccessibleNode ...@@ -27,25 +30,37 @@ interface AccessibleNode
getter invalid getter invalid
getter keyShortcuts getter keyShortcuts
getter label getter label
getter level
getter live getter live
getter modal getter modal
getter multiline getter multiline
getter multiselectable getter multiselectable
getter orientation getter orientation
getter placeholder getter placeholder
getter posInSet
getter readOnly getter readOnly
getter relevant getter relevant
getter required getter required
getter role getter role
getter roleDescription getter roleDescription
getter rowCount
getter rowIndex
getter rowSpan
getter selected getter selected
getter setSize
getter sort getter sort
getter valueMax
getter valueMin
getter valueNow
getter valueText getter valueText
method constructor method constructor
setter atomic setter atomic
setter autocomplete setter autocomplete
setter busy setter busy
setter checked setter checked
setter colCount
setter colIndex
setter colSpan
setter current setter current
setter disabled setter disabled
setter expanded setter expanded
...@@ -53,19 +68,28 @@ interface AccessibleNode ...@@ -53,19 +68,28 @@ interface AccessibleNode
setter invalid setter invalid
setter keyShortcuts setter keyShortcuts
setter label setter label
setter level
setter live setter live
setter modal setter modal
setter multiline setter multiline
setter multiselectable setter multiselectable
setter orientation setter orientation
setter placeholder setter placeholder
setter posInSet
setter readOnly setter readOnly
setter relevant setter relevant
setter required setter required
setter role setter role
setter roleDescription setter roleDescription
setter rowCount
setter rowIndex
setter rowSpan
setter selected setter selected
setter setSize
setter sort setter sort
setter valueMax
setter valueMin
setter valueNow
setter valueText setter valueText
interface AmbientLightSensor : Sensor interface AmbientLightSensor : Sensor
attribute @@toStringTag attribute @@toStringTag
......
...@@ -52,6 +52,23 @@ enum class AOMBooleanProperty { ...@@ -52,6 +52,23 @@ enum class AOMBooleanProperty {
kSelected kSelected
}; };
// All of the properties of AccessibleNode that have an unsigned integer type.
enum class AOMUIntProperty {
kColIndex,
kColSpan,
kLevel,
kPosInSet,
kRowIndex,
kRowSpan,
};
// All of the properties of AccessibleNode that have a signed integer type.
// (These all allow the value -1.)
enum class AOMIntProperty { kColCount, kRowCount, kSetSize };
// All of the properties of AccessibleNode that have a floating-point type.
enum class AOMFloatProperty { kValueMax, kValueMin, kValueNow };
// Accessibility Object Model node // Accessibility Object Model node
// Explainer: https://github.com/WICG/aom/blob/master/explainer.md // Explainer: https://github.com/WICG/aom/blob/master/explainer.md
// Spec: https://wicg.github.io/aom/spec/ // Spec: https://wicg.github.io/aom/spec/
...@@ -67,10 +84,13 @@ class CORE_EXPORT AccessibleNode ...@@ -67,10 +84,13 @@ class CORE_EXPORT AccessibleNode
// Returns the given string property if the Element has an AccessibleNode. // Returns the given string property if the Element has an AccessibleNode.
static const AtomicString& GetProperty(Element*, AOMStringProperty); static const AtomicString& GetProperty(Element*, AOMStringProperty);
// Returns the value of the given boolean property if the // Returns the value of the given property if the
// Element has an AccessibleNode. Sets |isNull| if the property and // Element has an AccessibleNode. Sets |isNull| if the property and
// attribute are not present. // attribute are not present.
static bool GetProperty(Element*, AOMBooleanProperty, bool& is_null); static bool GetProperty(Element*, AOMBooleanProperty, bool& is_null);
static float GetProperty(Element*, AOMFloatProperty, bool& is_null);
static int32_t GetProperty(Element*, AOMIntProperty, bool& is_null);
static uint32_t GetProperty(Element*, AOMUIntProperty, bool& is_null);
// Returns the value of the given string property if the // Returns the value of the given string property if the
// Element has an AccessibleNode, otherwise returns the equivalent // Element has an AccessibleNode, otherwise returns the equivalent
...@@ -78,36 +98,54 @@ class CORE_EXPORT AccessibleNode ...@@ -78,36 +98,54 @@ class CORE_EXPORT AccessibleNode
static const AtomicString& GetPropertyOrARIAAttribute(Element*, static const AtomicString& GetPropertyOrARIAAttribute(Element*,
AOMStringProperty); AOMStringProperty);
// Returns the value of the given boolean property if the // Returns the value of the given property if the
// Element has an AccessibleNode, otherwise returns the equivalent // Element has an AccessibleNode, otherwise returns the equivalent
// ARIA attribute. Sets |isNull| if the property and attribute are not // ARIA attribute. Sets |isNull| if the property and attribute are not
// present. // present.
static bool GetPropertyOrARIAAttribute(Element*, static bool GetPropertyOrARIAAttribute(Element*,
AOMBooleanProperty, AOMBooleanProperty,
bool& is_null); bool& is_null);
static float GetPropertyOrARIAAttribute(Element*,
bool atomic(bool&) const; AOMFloatProperty,
bool& is_null);
static int32_t GetPropertyOrARIAAttribute(Element*,
AOMIntProperty,
bool& is_null);
static uint32_t GetPropertyOrARIAAttribute(Element*,
AOMUIntProperty,
bool& is_null);
bool atomic(bool& is_null) const;
void setAtomic(bool, bool is_null); void setAtomic(bool, bool is_null);
AtomicString autocomplete() const; AtomicString autocomplete() const;
void setAutocomplete(const AtomicString&); void setAutocomplete(const AtomicString&);
bool busy(bool&) const; bool busy(bool& is_null) const;
void setBusy(bool, bool is_null); void setBusy(bool, bool is_null);
AtomicString checked() const; AtomicString checked() const;
void setChecked(const AtomicString&); void setChecked(const AtomicString&);
int32_t colCount(bool& is_null) const;
void setColCount(int32_t, bool is_null);
uint32_t colIndex(bool& is_null) const;
void setColIndex(uint32_t, bool is_null);
uint32_t colSpan(bool& is_null) const;
void setColSpan(uint32_t, bool is_null);
AtomicString current() const; AtomicString current() const;
void setCurrent(const AtomicString&); void setCurrent(const AtomicString&);
bool disabled(bool&) const; bool disabled(bool& is_null) const;
void setDisabled(bool, bool is_null); void setDisabled(bool, bool is_null);
bool expanded(bool&) const; bool expanded(bool& is_null) const;
void setExpanded(bool, bool is_null); void setExpanded(bool, bool is_null);
bool hidden(bool&) const; bool hidden(bool& is_null) const;
void setHidden(bool, bool is_null); void setHidden(bool, bool is_null);
AtomicString invalid() const; AtomicString invalid() const;
...@@ -119,16 +157,19 @@ class CORE_EXPORT AccessibleNode ...@@ -119,16 +157,19 @@ class CORE_EXPORT AccessibleNode
AtomicString label() const; AtomicString label() const;
void setLabel(const AtomicString&); void setLabel(const AtomicString&);
uint32_t level(bool& is_null) const;
void setLevel(uint32_t, bool is_null);
AtomicString live() const; AtomicString live() const;
void setLive(const AtomicString&); void setLive(const AtomicString&);
bool modal(bool&) const; bool modal(bool& is_null) const;
void setModal(bool, bool is_null); void setModal(bool, bool is_null);
bool multiline(bool&) const; bool multiline(bool& is_null) const;
void setMultiline(bool, bool is_null); void setMultiline(bool, bool is_null);
bool multiselectable(bool&) const; bool multiselectable(bool& is_null) const;
void setMultiselectable(bool, bool is_null); void setMultiselectable(bool, bool is_null);
AtomicString orientation() const; AtomicString orientation() const;
...@@ -137,13 +178,16 @@ class CORE_EXPORT AccessibleNode ...@@ -137,13 +178,16 @@ class CORE_EXPORT AccessibleNode
AtomicString placeholder() const; AtomicString placeholder() const;
void setPlaceholder(const AtomicString&); void setPlaceholder(const AtomicString&);
bool readOnly(bool&) const; uint32_t posInSet(bool& is_null) const;
void setPosInSet(uint32_t, bool is_null);
bool readOnly(bool& is_null) const;
void setReadOnly(bool, bool is_null); void setReadOnly(bool, bool is_null);
AtomicString relevant() const; AtomicString relevant() const;
void setRelevant(const AtomicString&); void setRelevant(const AtomicString&);
bool required(bool&) const; bool required(bool& is_null) const;
void setRequired(bool, bool is_null); void setRequired(bool, bool is_null);
AtomicString role() const; AtomicString role() const;
...@@ -152,12 +196,33 @@ class CORE_EXPORT AccessibleNode ...@@ -152,12 +196,33 @@ class CORE_EXPORT AccessibleNode
AtomicString roleDescription() const; AtomicString roleDescription() const;
void setRoleDescription(const AtomicString&); void setRoleDescription(const AtomicString&);
bool selected(bool&) const; int32_t rowCount(bool& is_null) const;
void setRowCount(int32_t, bool is_null);
uint32_t rowIndex(bool& is_null) const;
void setRowIndex(uint32_t, bool is_null);
uint32_t rowSpan(bool& is_null) const;
void setRowSpan(uint32_t, bool is_null);
bool selected(bool& is_null) const;
void setSelected(bool, bool is_null); void setSelected(bool, bool is_null);
int32_t setSize(bool& is_null) const;
void setSetSize(int32_t, bool is_null);
AtomicString sort() const; AtomicString sort() const;
void setSort(const AtomicString&); void setSort(const AtomicString&);
float valueMax(bool& is_null) const;
void setValueMax(float, bool is_null);
float valueMin(bool& is_null) const;
void setValueMin(float, bool is_null);
float valueNow(bool& is_null) const;
void setValueNow(float, bool is_null);
AtomicString valueText() const; AtomicString valueText() const;
void setValueText(const AtomicString&); void setValueText(const AtomicString&);
...@@ -166,11 +231,17 @@ class CORE_EXPORT AccessibleNode ...@@ -166,11 +231,17 @@ class CORE_EXPORT AccessibleNode
private: private:
void SetStringProperty(AOMStringProperty, const AtomicString&); void SetStringProperty(AOMStringProperty, const AtomicString&);
void SetBooleanProperty(AOMBooleanProperty, bool value, bool is_null); void SetBooleanProperty(AOMBooleanProperty, bool value, bool is_null);
void SetFloatProperty(AOMFloatProperty, float value, bool is_null);
void SetUIntProperty(AOMUIntProperty, uint32_t value, bool is_null);
void SetIntProperty(AOMIntProperty, int32_t value, bool is_null);
void NotifyAttributeChanged(const blink::QualifiedName&); void NotifyAttributeChanged(const blink::QualifiedName&);
AXObjectCache* GetAXObjectCache(); AXObjectCache* GetAXObjectCache();
Vector<std::pair<AOMStringProperty, AtomicString>> string_properties_; Vector<std::pair<AOMStringProperty, AtomicString>> string_properties_;
Vector<std::pair<AOMBooleanProperty, bool>> boolean_properties_; Vector<std::pair<AOMBooleanProperty, bool>> boolean_properties_;
Vector<std::pair<AOMFloatProperty, float>> float_properties_;
Vector<std::pair<AOMIntProperty, int32_t>> int_properties_;
Vector<std::pair<AOMUIntProperty, uint32_t>> uint_properties_;
// This object's owner Element. // This object's owner Element.
Member<Element> element_; Member<Element> element_;
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
attribute DOMString? autocomplete; attribute DOMString? autocomplete;
attribute boolean? busy; attribute boolean? busy;
attribute DOMString? checked; attribute DOMString? checked;
attribute long? colCount;
attribute unsigned long? colIndex;
attribute unsigned long? colSpan;
attribute DOMString? current; attribute DOMString? current;
attribute boolean? disabled; attribute boolean? disabled;
attribute boolean? expanded; attribute boolean? expanded;
...@@ -19,18 +22,27 @@ ...@@ -19,18 +22,27 @@
attribute DOMString? invalid; attribute DOMString? invalid;
attribute DOMString? keyShortcuts; attribute DOMString? keyShortcuts;
attribute DOMString? label; attribute DOMString? label;
attribute unsigned long? level;
attribute DOMString? live; attribute DOMString? live;
attribute boolean? modal; attribute boolean? modal;
attribute boolean? multiline; attribute boolean? multiline;
attribute boolean? multiselectable; attribute boolean? multiselectable;
attribute DOMString? orientation; attribute DOMString? orientation;
attribute DOMString? placeholder; attribute DOMString? placeholder;
attribute unsigned long? posInSet;
attribute boolean? readOnly; attribute boolean? readOnly;
attribute DOMString? relevant; attribute DOMString? relevant;
attribute boolean? required; attribute boolean? required;
attribute DOMString? role; attribute DOMString? role;
attribute DOMString? roleDescription; attribute DOMString? roleDescription;
attribute long? rowCount;
attribute unsigned long? rowIndex;
attribute unsigned long? rowSpan;
attribute boolean? selected; attribute boolean? selected;
attribute long? setSize;
attribute DOMString? sort; attribute DOMString? sort;
attribute double? valueMax;
attribute double? valueMin;
attribute double? valueNow;
attribute DOMString? valueText; attribute DOMString? valueText;
}; };
...@@ -1334,9 +1334,8 @@ int AXNodeObject::HeadingLevel() const { ...@@ -1334,9 +1334,8 @@ int AXNodeObject::HeadingLevel() const {
return 0; return 0;
if (RoleValue() == kHeadingRole) { if (RoleValue() == kHeadingRole) {
String level_str = GetAttribute(aria_levelAttr); uint32_t level;
if (!level_str.IsEmpty()) { if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) {
int level = level_str.ToInt();
if (level >= 1 && level <= 9) if (level >= 1 && level <= 9)
return level; return level;
return 1; return 1;
...@@ -1369,15 +1368,13 @@ int AXNodeObject::HeadingLevel() const { ...@@ -1369,15 +1368,13 @@ int AXNodeObject::HeadingLevel() const {
} }
unsigned AXNodeObject::HierarchicalLevel() const { unsigned AXNodeObject::HierarchicalLevel() const {
Node* node = this->GetNode(); Element* element = GetElement();
if (!node || !node->IsElementNode()) if (!element)
return 0; return 0;
Element* element = ToElement(node); uint32_t level;
String level_str = element->getAttribute(aria_levelAttr); if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) {
if (!level_str.IsEmpty()) { if (level >= 1 && level <= 9)
int level = level_str.ToInt();
if (level > 0)
return level; return level;
return 1; return 1;
} }
...@@ -1388,7 +1385,7 @@ unsigned AXNodeObject::HierarchicalLevel() const { ...@@ -1388,7 +1385,7 @@ unsigned AXNodeObject::HierarchicalLevel() const {
// Hierarchy leveling starts at 1, to match the aria-level spec. // Hierarchy leveling starts at 1, to match the aria-level spec.
// We measure tree hierarchy by the number of groups that the item is within. // We measure tree hierarchy by the number of groups that the item is within.
unsigned level = 1; level = 1;
for (AXObjectImpl* parent = ParentObject(); parent; for (AXObjectImpl* parent = ParentObject(); parent;
parent = parent->ParentObject()) { parent = parent->ParentObject()) {
AccessibilityRole parent_role = parent->RoleValue(); AccessibilityRole parent_role = parent->RoleValue();
...@@ -1659,13 +1656,9 @@ InvalidState AXNodeObject::GetInvalidState() const { ...@@ -1659,13 +1656,9 @@ InvalidState AXNodeObject::GetInvalidState() const {
int AXNodeObject::PosInSet() const { int AXNodeObject::PosInSet() const {
if (SupportsSetSizeAndPosInSet()) { if (SupportsSetSizeAndPosInSet()) {
String pos_in_set_str = GetAttribute(aria_posinsetAttr); uint32_t pos_in_set;
if (!pos_in_set_str.IsEmpty()) { if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kPosInSet, pos_in_set))
int pos_in_set = pos_in_set_str.ToInt(); return pos_in_set;
if (pos_in_set > 0)
return pos_in_set;
return 1;
}
return AXObjectImpl::IndexInParent() + 1; return AXObjectImpl::IndexInParent() + 1;
} }
...@@ -1675,13 +1668,9 @@ int AXNodeObject::PosInSet() const { ...@@ -1675,13 +1668,9 @@ int AXNodeObject::PosInSet() const {
int AXNodeObject::SetSize() const { int AXNodeObject::SetSize() const {
if (SupportsSetSizeAndPosInSet()) { if (SupportsSetSizeAndPosInSet()) {
String set_size_str = GetAttribute(aria_setsizeAttr); int32_t set_size;
if (!set_size_str.IsEmpty()) { if (HasAOMPropertyOrARIAAttribute(AOMIntProperty::kSetSize, set_size))
int set_size = set_size_str.ToInt(); return set_size;
if (set_size > 0)
return set_size;
return 1;
}
if (ParentObject()) { if (ParentObject()) {
const auto& siblings = ParentObject()->Children(); const auto& siblings = ParentObject()->Children();
...@@ -1708,8 +1697,9 @@ String AXNodeObject::ValueDescription() const { ...@@ -1708,8 +1697,9 @@ String AXNodeObject::ValueDescription() const {
} }
float AXNodeObject::ValueForRange() const { float AXNodeObject::ValueForRange() const {
if (HasAttribute(aria_valuenowAttr)) float value_now;
return GetAttribute(aria_valuenowAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueNow, value_now))
return value_now;
if (IsNativeSlider()) if (IsNativeSlider())
return toHTMLInputElement(*GetNode()).valueAsNumber(); return toHTMLInputElement(*GetNode()).valueAsNumber();
...@@ -1721,8 +1711,9 @@ float AXNodeObject::ValueForRange() const { ...@@ -1721,8 +1711,9 @@ float AXNodeObject::ValueForRange() const {
} }
float AXNodeObject::MaxValueForRange() const { float AXNodeObject::MaxValueForRange() const {
if (HasAttribute(aria_valuemaxAttr)) float value_max;
return GetAttribute(aria_valuemaxAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueMax, value_max))
return value_max;
if (IsNativeSlider()) if (IsNativeSlider())
return toHTMLInputElement(*GetNode()).Maximum(); return toHTMLInputElement(*GetNode()).Maximum();
...@@ -1734,8 +1725,9 @@ float AXNodeObject::MaxValueForRange() const { ...@@ -1734,8 +1725,9 @@ float AXNodeObject::MaxValueForRange() const {
} }
float AXNodeObject::MinValueForRange() const { float AXNodeObject::MinValueForRange() const {
if (HasAttribute(aria_valueminAttr)) float value_min;
return GetAttribute(aria_valueminAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueMin, value_min))
return value_min;
if (IsNativeSlider()) if (IsNativeSlider())
return toHTMLInputElement(*GetNode()).Minimum(); return toHTMLInputElement(*GetNode()).Minimum();
......
...@@ -421,6 +421,42 @@ bool AXObjectImpl::AOMPropertyOrARIAAttributeIsFalse( ...@@ -421,6 +421,42 @@ bool AXObjectImpl::AOMPropertyOrARIAAttributeIsFalse(
return false; return false;
} }
bool AXObjectImpl::HasAOMPropertyOrARIAAttribute(AOMUIntProperty property,
uint32_t& result) const {
Element* element = this->GetElement();
if (!element)
return false;
bool is_null = true;
result =
AccessibleNode::GetPropertyOrARIAAttribute(element, property, is_null);
return !is_null;
}
bool AXObjectImpl::HasAOMPropertyOrARIAAttribute(AOMIntProperty property,
int32_t& result) const {
Element* element = this->GetElement();
if (!element)
return false;
bool is_null = true;
result =
AccessibleNode::GetPropertyOrARIAAttribute(element, property, is_null);
return !is_null;
}
bool AXObjectImpl::HasAOMPropertyOrARIAAttribute(AOMFloatProperty property,
float& result) const {
Element* element = this->GetElement();
if (!element)
return false;
bool is_null = true;
result =
AccessibleNode::GetPropertyOrARIAAttribute(element, property, is_null);
return !is_null;
}
bool AXObjectImpl::IsARIATextControl() const { bool AXObjectImpl::IsARIATextControl() const {
return AriaRoleAttribute() == kTextFieldRole || return AriaRoleAttribute() == kTextFieldRole ||
AriaRoleAttribute() == kSearchBoxRole || AriaRoleAttribute() == kSearchBoxRole ||
......
...@@ -57,6 +57,9 @@ class ScrollableArea; ...@@ -57,6 +57,9 @@ class ScrollableArea;
enum class AOMBooleanProperty; enum class AOMBooleanProperty;
enum class AOMStringProperty; enum class AOMStringProperty;
enum class AOMUIntProperty;
enum class AOMIntProperty;
enum class AOMFloatProperty;
typedef unsigned AXID; typedef unsigned AXID;
...@@ -353,6 +356,9 @@ class MODULES_EXPORT AXObjectImpl ...@@ -353,6 +356,9 @@ class MODULES_EXPORT AXObjectImpl
bool HasAOMPropertyOrARIAAttribute(AOMBooleanProperty, bool& result) const; bool HasAOMPropertyOrARIAAttribute(AOMBooleanProperty, bool& result) const;
bool AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty) const; bool AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty) const;
bool AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty) const; bool AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty) const;
bool HasAOMPropertyOrARIAAttribute(AOMUIntProperty, uint32_t& result) const;
bool HasAOMPropertyOrARIAAttribute(AOMIntProperty, int32_t& result) const;
bool HasAOMPropertyOrARIAAttribute(AOMFloatProperty, float& result) const;
virtual void GetSparseAXAttributes(AXSparseAttributeClient&) const {} virtual void GetSparseAXAttributes(AXSparseAttributeClient&) const {}
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "modules/accessibility/AXProgressIndicator.h" #include "modules/accessibility/AXProgressIndicator.h"
#include "core/dom/AccessibleNode.h"
#include "core/html/HTMLProgressElement.h" #include "core/html/HTMLProgressElement.h"
#include "core/layout/LayoutProgress.h" #include "core/layout/LayoutProgress.h"
#include "modules/accessibility/AXObjectCacheImpl.h" #include "modules/accessibility/AXObjectCacheImpl.h"
...@@ -51,8 +52,9 @@ bool AXProgressIndicator::ComputeAccessibilityIsIgnored( ...@@ -51,8 +52,9 @@ bool AXProgressIndicator::ComputeAccessibilityIsIgnored(
} }
float AXProgressIndicator::ValueForRange() const { float AXProgressIndicator::ValueForRange() const {
if (HasAttribute(aria_valuenowAttr)) float value_now;
return GetAttribute(aria_valuenowAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueNow, value_now))
return value_now;
if (GetProgressElement()->position() >= 0) if (GetProgressElement()->position() >= 0)
return clampTo<float>(GetProgressElement()->value()); return clampTo<float>(GetProgressElement()->value());
...@@ -61,15 +63,17 @@ float AXProgressIndicator::ValueForRange() const { ...@@ -61,15 +63,17 @@ float AXProgressIndicator::ValueForRange() const {
} }
float AXProgressIndicator::MaxValueForRange() const { float AXProgressIndicator::MaxValueForRange() const {
if (HasAttribute(aria_valuemaxAttr)) float value_max;
return GetAttribute(aria_valuemaxAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueMax, value_max))
return value_max;
return clampTo<float>(GetProgressElement()->max()); return clampTo<float>(GetProgressElement()->max());
} }
float AXProgressIndicator::MinValueForRange() const { float AXProgressIndicator::MinValueForRange() const {
if (HasAttribute(aria_valueminAttr)) float value_min;
return GetAttribute(aria_valueminAttr).ToFloat(); if (HasAOMPropertyOrARIAAttribute(AOMFloatProperty::kValueMin, value_min))
return value_min;
return 0.0f; return 0.0f;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "modules/accessibility/AXRadioInput.h" #include "modules/accessibility/AXRadioInput.h"
#include "core/InputTypeNames.h" #include "core/InputTypeNames.h"
#include "core/dom/AccessibleNode.h"
#include "core/html/HTMLInputElement.h" #include "core/html/HTMLInputElement.h"
#include "core/html/forms/RadioInputType.h" #include "core/html/forms/RadioInputType.h"
#include "core/layout/LayoutObject.h" #include "core/layout/LayoutObject.h"
...@@ -65,14 +66,16 @@ HTMLInputElement* AXRadioInput::FindFirstRadioButtonInGroup( ...@@ -65,14 +66,16 @@ HTMLInputElement* AXRadioInput::FindFirstRadioButtonInGroup(
} }
int AXRadioInput::PosInSet() const { int AXRadioInput::PosInSet() const {
if (HasAttribute(aria_posinsetAttr)) uint32_t pos_in_set;
return GetAttribute(aria_posinsetAttr).ToInt(); if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kPosInSet, pos_in_set))
return pos_in_set;
return pos_in_set_; return pos_in_set_;
} }
int AXRadioInput::SetSize() const { int AXRadioInput::SetSize() const {
if (HasAttribute(aria_setsizeAttr)) int32_t set_size;
return GetAttribute(aria_setsizeAttr).ToInt(); if (HasAOMPropertyOrARIAAttribute(AOMIntProperty::kSetSize, set_size))
return set_size;
return set_size_; return set_size_;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "modules/accessibility/AXTable.h" #include "modules/accessibility/AXTable.h"
#include "core/dom/AccessibleNode.h"
#include "core/dom/ElementTraversal.h" #include "core/dom/ElementTraversal.h"
#include "core/editing/EditingUtilities.h" #include "core/editing/EditingUtilities.h"
#include "core/html/HTMLCollection.h" #include "core/html/HTMLCollection.h"
...@@ -496,40 +497,36 @@ void AXTable::RowHeaders(AXObjectVector& headers) { ...@@ -496,40 +497,36 @@ void AXTable::RowHeaders(AXObjectVector& headers) {
} }
int AXTable::AriaColumnCount() { int AXTable::AriaColumnCount() {
if (!HasAttribute(aria_colcountAttr)) int32_t col_count;
if (!HasAOMPropertyOrARIAAttribute(AOMIntProperty::kColCount, col_count))
return 0; return 0;
const AtomicString& col_count_value = GetAttribute(aria_colcountAttr); if (col_count > static_cast<int>(ColumnCount()))
int col_count_int = col_count_value.ToInt(); return col_count;
if (col_count_int > (int)ColumnCount())
return col_count_int;
// Spec says that if all of the columns are present in the DOM, it // Spec says that if all of the columns are present in the DOM, it
// is not necessary to set this attribute as the user agent can // is not necessary to set this attribute as the user agent can
// automatically calculate the total number of columns. // automatically calculate the total number of columns.
// It returns 0 in order not to set this attribute. // It returns 0 in order not to set this attribute.
if (col_count_int == (int)ColumnCount() || col_count_int != -1) if (col_count == static_cast<int>(ColumnCount()) || col_count != -1)
return 0; return 0;
return -1; return -1;
} }
int AXTable::AriaRowCount() { int AXTable::AriaRowCount() {
if (!HasAttribute(aria_rowcountAttr)) int32_t row_count;
if (!HasAOMPropertyOrARIAAttribute(AOMIntProperty::kRowCount, row_count))
return 0; return 0;
const AtomicString& row_count_value = GetAttribute(aria_rowcountAttr); if (row_count > static_cast<int>(RowCount()))
int row_count_int = row_count_value.ToInt(); return row_count;
if (row_count_int > (int)RowCount())
return row_count_int;
// Spec says that if all of the rows are present in the DOM, it is // Spec says that if all of the rows are present in the DOM, it is
// not necessary to set this attribute as the user agent can // not necessary to set this attribute as the user agent can
// automatically calculate the total number of rows. // automatically calculate the total number of rows.
// It returns 0 in order not to set this attribute. // It returns 0 in order not to set this attribute.
if (row_count_int == (int)RowCount() || row_count_int != -1) if (row_count == (int)RowCount() || row_count != -1)
return 0; return 0;
// In the spec, -1 explicitly means an unknown number of rows. // In the spec, -1 explicitly means an unknown number of rows.
......
...@@ -104,9 +104,11 @@ bool AXTableCell::IsTableCell() const { ...@@ -104,9 +104,11 @@ bool AXTableCell::IsTableCell() const {
} }
unsigned AXTableCell::AriaColumnIndex() const { unsigned AXTableCell::AriaColumnIndex() const {
const AtomicString& col_index = GetAttribute(aria_colindexAttr); uint32_t col_index;
if (col_index.ToInt() >= 1) if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, col_index) &&
return col_index.ToInt(); col_index >= 1) {
return col_index;
}
AXObjectImpl* parent = ParentObjectUnignored(); AXObjectImpl* parent = ParentObjectUnignored();
if (!parent || !parent->IsTableRow()) if (!parent || !parent->IsTableRow())
...@@ -116,9 +118,11 @@ unsigned AXTableCell::AriaColumnIndex() const { ...@@ -116,9 +118,11 @@ unsigned AXTableCell::AriaColumnIndex() const {
} }
unsigned AXTableCell::AriaRowIndex() const { unsigned AXTableCell::AriaRowIndex() const {
const AtomicString& row_index = GetAttribute(aria_rowindexAttr); uint32_t row_index;
if (row_index.ToInt() >= 1) if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, row_index) &&
return row_index.ToInt(); row_index >= 1) {
return row_index;
}
AXObjectImpl* parent = ParentObjectUnignored(); AXObjectImpl* parent = ParentObjectUnignored();
if (!parent || !parent->IsTableRow()) if (!parent || !parent->IsTableRow())
......
...@@ -70,7 +70,7 @@ class MODULES_EXPORT AXTableCell : public AXLayoutObject { ...@@ -70,7 +70,7 @@ class MODULES_EXPORT AXTableCell : public AXLayoutObject {
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const final; bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const final;
unsigned aria_col_index_from_row_; unsigned aria_col_index_from_row_ = 0;
}; };
DEFINE_AX_OBJECT_TYPE_CASTS(AXTableCell, IsTableCell()); DEFINE_AX_OBJECT_TYPE_CASTS(AXTableCell, IsTableCell());
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "modules/accessibility/AXTableRow.h" #include "modules/accessibility/AXTableRow.h"
#include "core/dom/AccessibleNode.h"
#include "core/layout/LayoutObject.h" #include "core/layout/LayoutObject.h"
#include "modules/accessibility/AXObjectCacheImpl.h" #include "modules/accessibility/AXObjectCacheImpl.h"
#include "modules/accessibility/AXTableCell.h" #include "modules/accessibility/AXTableCell.h"
...@@ -114,17 +115,21 @@ AXObjectImpl* AXTableRow::HeaderObject() { ...@@ -114,17 +115,21 @@ AXObjectImpl* AXTableRow::HeaderObject() {
} }
unsigned AXTableRow::AriaColumnIndex() const { unsigned AXTableRow::AriaColumnIndex() const {
const AtomicString& col_index_value = GetAttribute(aria_colindexAttr); uint32_t col_index;
if (col_index_value.ToInt() >= 1) if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, col_index) &&
return col_index_value.ToInt(); col_index >= 1) {
return col_index;
}
return 0; return 0;
} }
unsigned AXTableRow::AriaRowIndex() const { unsigned AXTableRow::AriaRowIndex() const {
const AtomicString& row_index_value = GetAttribute(aria_rowindexAttr); uint32_t row_index;
if (row_index_value.ToInt() >= 1) if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, row_index) &&
return row_index_value.ToInt(); row_index >= 1) {
return row_index;
}
return 0; return 0;
} }
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#include "core/dom/AccessibleNode.h" #include "core/dom/AccessibleNode.h"
#include "core/html/HTMLBodyElement.h" #include "core/html/HTMLBodyElement.h"
#include "modules/accessibility/AXObjectCacheImpl.h" #include "modules/accessibility/AXObjectCacheImpl.h"
#include "modules/accessibility/AXTable.h"
#include "modules/accessibility/AXTableCell.h"
#include "modules/accessibility/AXTableRow.h"
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
#include "web/tests/sim/SimRequest.h" #include "web/tests/sim/SimRequest.h"
#include "web/tests/sim/SimTest.h" #include "web/tests/sim/SimTest.h"
...@@ -131,6 +134,104 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) { ...@@ -131,6 +134,104 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
EXPECT_FALSE(axButton->IsEnabled()); EXPECT_FALSE(axButton->IsEnabled());
} }
TEST_F(AccessibilityObjectModelTest, RangeProperties) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<div role=slider id=slider>");
auto* slider = GetDocument().getElementById("slider");
ASSERT_NE(nullptr, slider);
slider->accessibleNode()->setValueMin(-0.5, false);
slider->accessibleNode()->setValueMax(0.5, false);
slider->accessibleNode()->setValueNow(0.1, false);
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* ax_slider = cache->GetOrCreate(slider);
EXPECT_EQ(-0.5f, ax_slider->MinValueForRange());
EXPECT_EQ(0.5f, ax_slider->MaxValueForRange());
EXPECT_EQ(0.1f, ax_slider->ValueForRange());
}
TEST_F(AccessibilityObjectModelTest, Level) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<div role=heading id=heading>");
auto* heading = GetDocument().getElementById("heading");
ASSERT_NE(nullptr, heading);
heading->accessibleNode()->setLevel(5, false);
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* ax_heading = cache->GetOrCreate(heading);
EXPECT_EQ(5, ax_heading->HeadingLevel());
}
TEST_F(AccessibilityObjectModelTest, ListItem) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(
"<div role=list><div role=listitem id=listitem></div></div>");
auto* listitem = GetDocument().getElementById("listitem");
ASSERT_NE(nullptr, listitem);
listitem->accessibleNode()->setPosInSet(9, false);
listitem->accessibleNode()->setSetSize(10, false);
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* ax_listitem = cache->GetOrCreate(listitem);
EXPECT_EQ(9, ax_listitem->PosInSet());
EXPECT_EQ(10, ax_listitem->SetSize());
}
TEST_F(AccessibilityObjectModelTest, Grid) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(
"<div role=grid id=grid>"
" <div role=row id=row>"
" <div role=gridcell id=cell></div>"
" <div role=gridcell id=cell2></div>"
" </div>"
"</div>");
auto* grid = GetDocument().getElementById("grid");
ASSERT_NE(nullptr, grid);
grid->accessibleNode()->setColCount(16, false);
grid->accessibleNode()->setRowCount(9, false);
auto* row = GetDocument().getElementById("row");
ASSERT_NE(nullptr, row);
row->accessibleNode()->setColIndex(8, false);
row->accessibleNode()->setRowIndex(5, false);
auto* cell = GetDocument().getElementById("cell");
auto* cell2 = GetDocument().getElementById("cell2");
ASSERT_NE(nullptr, cell2);
cell2->accessibleNode()->setColIndex(10, false);
cell2->accessibleNode()->setRowIndex(7, false);
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* ax_grid = static_cast<AXTable*>(cache->GetOrCreate(grid));
EXPECT_EQ(16, ax_grid->AriaColumnCount());
EXPECT_EQ(9, ax_grid->AriaRowCount());
auto* ax_cell = static_cast<AXTableCell*>(cache->GetOrCreate(cell));
EXPECT_TRUE(ax_cell->IsTableCell());
EXPECT_EQ(8U, ax_cell->AriaColumnIndex());
EXPECT_EQ(5U, ax_cell->AriaRowIndex());
auto* ax_cell2 = static_cast<AXTableCell*>(cache->GetOrCreate(cell2));
EXPECT_TRUE(ax_cell2->IsTableCell());
EXPECT_EQ(10U, ax_cell2->AriaColumnIndex());
EXPECT_EQ(7U, ax_cell2->AriaRowIndex());
}
} // namespace } // namespace
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment