[A11y] More const improvements for AXObject
Updating the parent, children, cached values or any other properties
should not be const, and cached properties of an object should not
require the mutable keyword -- that is a bad "code smell".
Having the right methods be const helps ensure at compile time that
we aren't calling methods that will alter the tree or its objects
at the wrong time.
Bug: none
Change-Id: I26d3a9926d07ce4824fb44f721cbfb39ba4b27d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5462029
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Auto-Submit: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1289659}
diff --git a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
index c6a64870..280f054 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
@@ -416,7 +416,7 @@
return static_cast<int>(inline_text_box_->Len());
}
-void AXInlineTextBox::ClearChildren() const {
+void AXInlineTextBox::ClearChildren() {
// An AXInlineTextBox has no children to clear.
}
diff --git a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
index d599c9c4..1936b5eb 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
@@ -72,7 +72,7 @@
NOTREACHED();
return ax::mojom::blink::Role::kInlineTextBox;
}
- void ClearChildren() const override;
+ void ClearChildren() override;
AbstractInlineTextBox* GetInlineTextBox() const override;
protected:
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index f419159..b5564799 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -109,7 +109,7 @@
AXNodeObject::ChildrenChangedWithCleanLayout();
}
-void AXMenuList::SetNeedsToUpdateChildren(bool update) const {
+void AXMenuList::SetNeedsToUpdateChildren(bool update) {
if (!update) {
AXNodeObject::SetNeedsToUpdateChildren(false);
return;
@@ -125,7 +125,7 @@
AXNodeObject::SetNeedsToUpdateChildren();
}
-void AXMenuList::ClearChildren() const {
+void AXMenuList::ClearChildren() {
if (popup_) {
popup_->ClearChildren();
}
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.h b/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
index 850a719..46f25fbc 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
@@ -46,8 +46,8 @@
AccessibilityExpanded IsExpanded() const final;
bool OnNativeClickAction() override;
void ChildrenChangedWithCleanLayout() override;
- void SetNeedsToUpdateChildren(bool update = true) const override;
- void ClearChildren() const override;
+ void SetNeedsToUpdateChildren(bool update = true) override;
+ void ClearChildren() override;
void Detach() override;
void DidUpdateActiveOption();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 171717b..fa2efa5 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1051,7 +1051,7 @@
ContainerListMarkerIncludingIgnored();
if (list_marker_object &&
(list_marker_object->GetLayoutObject()->IsListMarkerForSummary() ||
- !list_marker_object->AccessibilityIsIgnored())) {
+ !list_marker_object->LastKnownIsIgnoredValue())) {
if (ignored_reasons) {
ignored_reasons->push_back(IgnoredReason(kAXPresentational));
}
@@ -1064,8 +1064,8 @@
// This means that other interesting objects inside the <label> will
// cause the text to be unignored.
if (IsUsedForLabelOrDescription()) {
- AXObject* ancestor = ParentObject();
- while (ancestor && ancestor->AccessibilityIsIgnored()) {
+ const AXObject* ancestor = ParentObject();
+ while (ancestor && ancestor->LastKnownIsIgnoredValue()) {
if (ancestor->RoleValue() == ax::mojom::blink::Role::kLabelText) {
if (ignored_reasons) {
ignored_reasons->push_back(IgnoredReason(kAXPresentational));
@@ -4816,10 +4816,7 @@
ax::mojom::blink::NameFrom last_used_name_from =
ax::mojom::blink::NameFrom::kNone;
- // Ensure that if this node needs to invalidate its children (e.g. due to
- // included in tree status change), that we do it now, rather than while
- // traversing the children.
- UpdateCachedAttributeValuesIfNeeded();
+ CHECK(!NeedsToUpdateCachedValues());
const AXObjectVector& children = ChildrenIncludingIgnored();
#if defined(AX_FAIL_FAST_BUILD)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index b384041..eaddd72 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -609,14 +609,14 @@
--number_of_live_ax_objects_;
}
-void AXObject::SetHasDirtyDescendants(bool dirty) const {
+void AXObject::SetHasDirtyDescendants(bool dirty) {
CHECK(!dirty || LastKnownIsIncludedInTreeValue())
<< "Only included nodes can be marked as having dirty descendants: "
<< this;
has_dirty_descendants_ = dirty;
}
-void AXObject::SetAncestorsHaveDirtyDescendants() const {
+void AXObject::SetAncestorsHaveDirtyDescendants() {
CHECK(!IsDetached());
CHECK(!AXObjectCache().HasBeenDisposed());
if (AXObjectCache().IsFrozen()) {
@@ -653,7 +653,7 @@
return;
}
- const AXObject* ancestor = this;
+ AXObject* ancestor = this;
while (true) {
ancestor = ancestor->CachedParentObject();
@@ -804,7 +804,8 @@
return GetNode() && GetNode() == &AXObjectCache().GetDocument();
}
-void AXObject::SetParent(AXObject* new_parent) const {
+void AXObject::SetParent(AXObject* new_parent) {
+ CHECK(!AXObjectCache().IsFrozen());
#if DCHECK_IS_ON()
if (!new_parent && !IsRoot()) {
std::ostringstream message;
@@ -1353,15 +1354,15 @@
PreSerializationConsistencyCheck();
// Serialize a few things that we need even for ignored nodes.
- bool is_focusable = CanSetFocusAttribute();
- if (is_focusable)
+ if (CanSetFocusAttribute()) {
node_data->AddState(ax::mojom::blink::State::kFocusable);
+ }
bool is_visible = IsVisible();
if (!is_visible)
node_data->AddState(ax::mojom::blink::State::kInvisible);
- if (is_visible || is_focusable) {
+ if (is_visible || CanSetFocusAttribute()) {
// If the author applied the ARIA "textbox" role on something that is not
// (currently) editable, this may be a read-only rich-text object. Or it
// might just be bad authoring. Either way, we want to expose its
@@ -1405,10 +1406,10 @@
// Return early. The following attributes are unnecessary for ignored nodes.
// Exception: focusable ignored nodes are fully serialized, so that reasonable
// verbalizations can be made if they actually receive focus.
- if (AccessibilityIsIgnored()) {
+ if (LastKnownIsIgnoredValue()) {
node_data->AddState(ax::mojom::blink::State::kIgnored);
// Early return for ignored, unfocusable nodes, avoiding unnecessary work.
- if (!is_focusable) {
+ if (!CanSetFocusAttribute()) {
// The name is important for exposing the selection around ignored nodes.
// TODO(accessibility) Remove this and still pass this
// content_browsertest:
@@ -1446,7 +1447,7 @@
// Return early. The following attributes are unnecessary for ignored nodes.
// Exception: focusable ignored nodes are fully serialized, so that reasonable
// verbalizations can be made if they actually receive focus.
- if (AccessibilityIsIgnored() &&
+ if (LastKnownIsIgnoredValue() &&
!node_data->HasState(ax::mojom::blink::State::kFocusable)) {
return;
}
@@ -3083,7 +3084,7 @@
return false;
}
-bool AXObject::AccessibilityIsIgnored() const {
+bool AXObject::AccessibilityIsIgnored() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
#if defined(AX_FAIL_FAST_BUILD)
@@ -3102,6 +3103,10 @@
}
bool AXObject::AccessibilityIsIgnoredButIncludedInTree() const {
+ return cached_is_ignored_but_included_in_tree_;
+}
+
+bool AXObject::AccessibilityIsIgnoredButIncludedInTree() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
@@ -3134,7 +3139,7 @@
}
void AXObject::UpdateCachedAttributeValuesIfNeeded(
- bool notify_parent_of_ignored_changes) const {
+ bool notify_parent_of_ignored_changes) {
if (IsDetached()) {
cached_is_ignored_ = true;
cached_is_ignored_but_included_in_tree_ = false;
@@ -3304,8 +3309,7 @@
// Must defer it, otherwise it can cause reentry into
// UpdateCachedAttributeValuesIfNeeded() on |this|.
// ParentObjectUnignored()->SetNeedsToUpdateChildren();
- AXObjectCache().ChildrenChangedOnAncestorOf(
- const_cast<AXObject*>(this));
+ AXObjectCache().ChildrenChangedOnAncestorOf(this);
}
} else if (included_in_tree_changed && AXObjectCache().UpdatingTree()) {
// In some cases changes to inherited properties can cause an object
@@ -3324,7 +3328,6 @@
// Compute live region root, which can be from any ARIA live value, including
// "off", or from an automatic ARIA live value, e.g. from role="status".
- // TODO(dmazzoni): remove this const_cast.
AXObject* previous_live_region_root = cached_live_region_root_;
if (GetNode() && IsA<Document>(GetNode())) {
// The document root is never a live region root.
@@ -3334,8 +3337,8 @@
cached_live_region_root_ = nullptr;
} else if (parent_) {
// Is a live region root if this or an ancestor is a live region.
- cached_live_region_root_ = IsLiveRegionRoot() ? const_cast<AXObject*>(this)
- : parent_->LiveRegionRoot();
+ cached_live_region_root_ =
+ IsLiveRegionRoot() ? this : parent_->LiveRegionRoot();
}
if (cached_live_region_root_ != previous_live_region_root) {
is_changing_inherited_values = true;
@@ -3360,7 +3363,7 @@
#endif
}
-void AXObject::OnInheritedCachedValuesChanged() const {
+void AXObject::OnInheritedCachedValuesChanged() {
// When a cached value that can inherit its value changes, it means that
// all descendants need to recompute its value. We do this by ensuring
// that UpdateTreeIfNeeded() will visit all descendants and recompute
@@ -3397,7 +3400,7 @@
if (!AccessibilityIsIncludedInTree()) {
// Make sure that, starting at an included node, children will
// recursively be updated until we reach |this|.
- AXObjectCache().ChildrenChangedOnAncestorOf(const_cast<AXObject*>(this));
+ AXObjectCache().ChildrenChangedOnAncestorOf(this);
}
}
}
@@ -3409,9 +3412,6 @@
bool AXObject::ShouldIgnoreForHiddenOrInert(
IgnoredReasons* ignored_reasons) const {
- // TODO(crbug.com/1522716): Figure out how this can happen:
- // "Check failed: !cached_values_need_update_. Tried to compute ignored value
- // without up-to-date hidden/inert values on SELECT".
DUMP_WILL_BE_CHECK(!cached_values_need_update_)
<< "Tried to compute ignored value without up-to-date hidden/inert "
"values on "
@@ -3471,7 +3471,7 @@
// Note: do not rely on the value of this inside of display:none.
// In practice, it does not matter because nodes in display:none subtrees are
// marked ignored either way.
-bool AXObject::IsInert() const {
+bool AXObject::IsInert() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
@@ -3573,7 +3573,7 @@
return ComputeIsInertViaStyle(GetComputedStyle(), ignored_reasons);
}
-bool AXObject::IsAriaHidden() const {
+bool AXObject::IsAriaHidden() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
@@ -3612,14 +3612,13 @@
return false;
}
-bool AXObject::IsHiddenByChildTree() const {
+bool AXObject::IsHiddenByChildTree() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
return cached_is_hidden_by_child_tree_;
}
-bool AXObject::ComputeIsHiddenByChildTree(
- IgnoredReasons* ignored_reasons) const {
+bool AXObject::ComputeIsHiddenByChildTree(IgnoredReasons* ignored_reasons) {
const AXObject* parent = ParentObject();
if (!parent) {
return false;
@@ -3796,14 +3795,14 @@
return false;
}
-bool AXObject::IsDescendantOfDisabledNode() const {
+bool AXObject::IsDescendantOfDisabledNode() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
return cached_is_descendant_of_disabled_node_;
}
-bool AXObject::ComputeIsDescendantOfDisabledNode() const {
+bool AXObject::ComputeIsDescendantOfDisabledNode() {
if (IsA<Document>(GetNode()))
return false;
@@ -3884,7 +3883,7 @@
return true;
}
-bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
+bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() {
// If an inline text box is ignored, it is never included in the tree.
if (IsAXInlineTextBox()) {
return false;
@@ -4223,7 +4222,7 @@
}
}
-bool AXObject::CanSetFocusAttribute() const {
+bool AXObject::CanSetFocusAttribute() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
@@ -4235,7 +4234,7 @@
// returning early if IsHiddenViaStyle() is true, we can call
// Element::IsKeyboardFocusable(), which would otherwise recalculate style at an
// awkward time.
-bool AXObject::ComputeCanSetFocusAttribute() const {
+bool AXObject::ComputeCanSetFocusAttribute() {
DCHECK(!IsDetached());
DCHECK(GetDocument());
@@ -4535,7 +4534,7 @@
// work, but don't destroy the work that was already there"
// * "content-visibility: auto" is "paint when it's scrolled into the viewport,
// but its layout information is not updated when it isn't"
-bool AXObject::ComputeIsHiddenViaStyle(const ComputedStyle* style) const {
+bool AXObject::ComputeIsHiddenViaStyle(const ComputedStyle* style) {
// The the parent element of text is hidden, then the text is hidden too.
// This helps provide more consistent results in edge cases, e.g. text inside
// of a <canvas> or display:none content.
@@ -4583,7 +4582,7 @@
return node->IsElementNode();
}
-bool AXObject::IsHiddenViaStyle() const {
+bool AXObject::IsHiddenViaStyle() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
@@ -4662,12 +4661,12 @@
return IsHiddenViaStyle();
}
-bool AXObject::IsUsedForLabelOrDescription() const {
+bool AXObject::IsUsedForLabelOrDescription() {
UpdateCachedAttributeValuesIfNeeded();
return cached_is_used_for_label_or_description_;
}
-bool AXObject::ComputeIsUsedForLabelOrDescription() const {
+bool AXObject::ComputeIsUsedForLabelOrDescription() {
if (GetElement()) {
// Return true if a <label> or the target of a naming/description
// relation (<aria-labelledby or aria-describedby).
@@ -5484,11 +5483,11 @@
return node->IsRichlyEditableForAccessibility();
}
-AXObject* AXObject::LiveRegionRoot() const {
+AXObject* AXObject::LiveRegionRoot() {
CheckCanAccessCachedValues();
UpdateCachedAttributeValuesIfNeeded();
- return cached_live_region_root_.Get();
+ return cached_live_region_root_;
}
bool AXObject::LiveRegionAtomic() const {
@@ -5503,34 +5502,22 @@
}
const AtomicString& AXObject::ContainerLiveRegionStatus() const {
- CheckCanAccessCachedValues();
-
- UpdateCachedAttributeValuesIfNeeded();
return cached_live_region_root_ ? cached_live_region_root_->LiveRegionStatus()
: g_null_atom;
}
const AtomicString& AXObject::ContainerLiveRegionRelevant() const {
- CheckCanAccessCachedValues();
-
- UpdateCachedAttributeValuesIfNeeded();
return cached_live_region_root_
? cached_live_region_root_->LiveRegionRelevant()
: g_null_atom;
}
bool AXObject::ContainerLiveRegionAtomic() const {
- CheckCanAccessCachedValues();
-
- UpdateCachedAttributeValuesIfNeeded();
return cached_live_region_root_ &&
cached_live_region_root_->LiveRegionAtomic();
}
bool AXObject::ContainerLiveRegionBusy() const {
- CheckCanAccessCachedValues();
-
- UpdateCachedAttributeValuesIfNeeded();
return cached_live_region_root_ &&
cached_live_region_root_->AOMPropertyOrARIAAttributeIsTrue(
AOMBooleanProperty::kBusy);
@@ -5574,7 +5561,7 @@
const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() const {
DCHECK(!IsDetached());
- return const_cast<AXObject*>(this)->ChildrenIncludingIgnored();
+ return children_;
}
const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() {
@@ -5925,13 +5912,9 @@
}
AXObject* AXObject::ParentObject() const {
- if (IsDetached()) {
- return nullptr;
- }
-
+ DUMP_WILL_BE_CHECK(!IsDetached());
DUMP_WILL_BE_CHECK(!IsMissingParent()) << "Missing parent: " << this;
-
- return parent_.Get();
+ return parent_;
}
AXObject* AXObject::ParentObjectUnignored() const {
@@ -6104,7 +6087,7 @@
}
#endif
-void AXObject::SetNeedsToUpdateChildren(bool update) const {
+void AXObject::SetNeedsToUpdateChildren(bool update) {
CHECK(!IsDetached()) << "Cannot update children on a detached node: " << this;
CHECK(!AXObjectCache().IsFrozen());
CHECK(!AXObjectCache().HasBeenDisposed());
@@ -6213,7 +6196,7 @@
AXObjectCache().UpdateAXForAllDocuments();
}
-void AXObject::ClearChildren() const {
+void AXObject::ClearChildren() {
CHECK(!IsDetached());
CHECK(!AXObjectCache().IsFrozen())
<< "Do not clear children while tree is frozen: " << this;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index cac6edfc..0625af88 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -267,7 +267,7 @@
#if DCHECK_IS_ON()
bool is_initializing_ = false;
bool is_computing_role_ = false;
- mutable bool is_updating_cached_values_ = false;
+ bool is_updating_cached_values_ = false;
#endif
#if !defined(NDEBUG)
// Keep track of what the object used to be, to make it easier to debug
@@ -306,8 +306,8 @@
// AXObjectCacheImpl::UpdateTreeIfNeeded. It does not directly indicate
// whether children, parent or other pointers are actually out of date; there
// are other dirty bits such as children_dirty_ for that.
- void SetAncestorsHaveDirtyDescendants() const;
- void SetHasDirtyDescendants(bool dirty) const;
+ void SetAncestorsHaveDirtyDescendants();
+ void SetHasDirtyDescendants(bool dirty);
bool HasDirtyDescendants() const { return has_dirty_descendants_; }
// When the corresponding WebCore object that this AXObject
@@ -322,7 +322,7 @@
// tree status changes. Use |notify_parent_of_ignored_changes = false| to
// prevent this.
void UpdateCachedAttributeValuesIfNeeded(
- bool notify_parent_of_ignored_changes = true) const;
+ bool notify_parent_of_ignored_changes = true);
// Invalidates cached_* members on this object only by resetting the
// modification count.
@@ -500,16 +500,20 @@
bool CanSetValueAttribute() const;
// Is the element focusable?
- bool CanSetFocusAttribute() const;
+ bool CanSetFocusAttribute() const { return cached_can_set_focus_attribute_; }
+ bool CanSetFocusAttribute();
// Is the element in the tab order?
bool IsKeyboardFocusable() const;
// Whether objects are ignored, i.e. hidden from the AT.
- bool AccessibilityIsIgnored() const;
+ bool AccessibilityIsIgnored() const { return cached_is_ignored_; }
+ bool AccessibilityIsIgnored();
// Whether objects are ignored but included in the tree.
bool AccessibilityIsIgnoredButIncludedInTree() const;
+ bool AccessibilityIsIgnoredButIncludedInTree();
// Is visibility:hidden or display:none being used to hide this element.
- bool IsHiddenViaStyle() const;
+ bool IsHiddenViaStyle() const { return cached_is_hidden_via_style_; }
+ bool IsHiddenViaStyle();
// Whether this is part of the label or description for another element.
// This is used to ensure hidden objects are included in the tree, and the
// implementation currently only ensures that an element's ancestor was part
@@ -517,10 +521,10 @@
// the relation cache does not bother clear old aria-labelledby/describedby
// ids. However, for purposes of preventing too many hidden objects from being
// serialized, it works well.
- bool IsUsedForLabelOrDescription() const;
- bool CachedIsUsedForLabelOrDescription() const {
+ bool IsUsedForLabelOrDescription() const {
return cached_is_used_for_label_or_description_;
}
+ bool IsUsedForLabelOrDescription();
// Whether objects are included in the tree. Nodes that are included in the
// tree are serialized, even if they are ignored. This allows browser-side
@@ -531,22 +535,28 @@
typedef HeapVector<IgnoredReason> IgnoredReasons;
virtual bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const;
bool ShouldIgnoreForHiddenOrInert(IgnoredReasons* = nullptr) const;
- bool IsInert() const;
- bool IsAriaHidden() const;
- bool IsHiddenByChildTree() const;
- bool CachedIsAriaHidden() { return cached_is_aria_hidden_; }
+ bool IsInert() const { return cached_is_inert_; }
+ bool IsInert();
+ bool IsAriaHidden() const { return cached_is_aria_hidden_; }
+ bool IsAriaHidden();
+ bool IsHiddenByChildTree() const { return cached_is_hidden_by_child_tree_; }
+ bool IsHiddenByChildTree();
const AXObject* AriaHiddenRoot() const;
bool ComputeIsInert(IgnoredReasons* = nullptr) const;
bool ComputeIsAriaHidden(IgnoredReasons* = nullptr) const;
// Determines if the object is hidden because a child tree has been stitched
// into one of its ancestor objects.
- bool ComputeIsHiddenByChildTree(IgnoredReasons* = nullptr) const;
+ bool ComputeIsHiddenByChildTree(IgnoredReasons* = nullptr);
bool IsBlockedByAriaModalDialog(IgnoredReasons* = nullptr) const;
- bool IsDescendantOfDisabledNode() const;
- bool ComputeAccessibilityIsIgnoredButIncludedInTree() const;
+ bool IsDescendantOfDisabledNode() const {
+ return cached_is_descendant_of_disabled_node_;
+ }
+ bool IsDescendantOfDisabledNode();
+ bool ComputeAccessibilityIsIgnoredButIncludedInTree();
const AXObject* GetAtomicTextFieldAncestor(int max_levels_to_check = 3) const;
const AXObject* DatetimeAncestor() const;
- bool ComputeIsDescendantOfDisabledNode() const;
+ bool ComputeIsDescendantOfDisabledNode();
+ // TODO(accessibility): Remove these.
bool LastKnownIsIgnoredValue() const;
bool LastKnownIsIgnoredButIncludedInTreeValue() const;
bool LastKnownIsIncludedInTreeValue() const;
@@ -967,7 +977,9 @@
// ARIA live-region features.
bool IsLiveRegionRoot() const; // Any live region, including polite="off".
bool IsActiveLiveRegionRoot() const; // Live region that is not polite="off".
- AXObject* LiveRegionRoot() const; // Container that controls live politeness.
+ // Containing element that controls aria-live properties.
+ AXObject* LiveRegionRoot() const { return cached_live_region_root_; }
+ AXObject* LiveRegionRoot();
virtual const AtomicString& LiveRegionStatus() const;
virtual const AtomicString& LiveRegionRelevant() const;
bool LiveRegionAtomic() const;
@@ -1184,7 +1196,7 @@
// Sets the parent AXObject directly. If the parent of this object is known,
// this can be faster than using ComputeParent().
- void SetParent(AXObject* new_parent) const;
+ void SetParent(AXObject* new_parent);
// If parent was not initialized during AddChildren() it can be computed by
// walking the DOM (or layout for nodeless aka anonymous layout object).
@@ -1294,8 +1306,8 @@
virtual bool CanHaveChildren() const { return true; }
void UpdateChildrenIfNecessary();
bool NeedsToUpdateChildren() const;
- virtual void SetNeedsToUpdateChildren(bool update = true) const;
- virtual void ClearChildren() const;
+ virtual void SetNeedsToUpdateChildren(bool update = true);
+ virtual void ClearChildren();
void DetachFromParent();
virtual void SelectedOptions(AXObjectVector&) const {}
@@ -1458,10 +1470,10 @@
protected:
AXID id_;
// Any parent, regardless of whether it's ignored or not included in the tree.
- mutable Member<AXObject> parent_;
+ Member<AXObject> parent_;
// Only children that are included in tree, maybe rename to children_in_tree_.
- mutable AXObjectVector children_;
- mutable bool has_dirty_descendants_ = false;
+ AXObjectVector children_;
+ bool has_dirty_descendants_ = false;
// The final role, taking into account the ARIA role and native role.
ax::mojom::blink::Role role_;
@@ -1552,17 +1564,17 @@
ui::AXNodeData* node_data) const;
private:
- bool ComputeCanSetFocusAttribute() const;
+ bool ComputeCanSetFocusAttribute();
String KeyboardShortcut() const;
void UpdateStyleAndLayoutTreeForNode(Node& node);
- void OnInheritedCachedValuesChanged() const;
+ void OnInheritedCachedValuesChanged();
- mutable bool children_dirty_ : 1 = false;
+ bool children_dirty_ : 1 = false;
// Do the rest of the cached_* member variables need to be recomputed?
- mutable bool cached_values_need_update_ : 1 = true;
+ bool cached_values_need_update_ : 1 = true;
// Do children need to recompute their cached values?
- mutable bool child_cached_values_need_update_ : 1 = false;
+ bool child_cached_values_need_update_ : 1 = false;
// The following cached attribute values (the ones starting with cached_**)
// are only valid if cached_values_need_update_ is false.
@@ -1570,18 +1582,18 @@
// not included in the tree), so that if object becomes included in Init()
// or in a future page update, the included node count will be incremented via
// AXObjectCacheImpl::UpdateIncludedNodeCount().
- mutable bool cached_is_ignored_ : 1 = true;
- mutable bool cached_is_ignored_but_included_in_tree_ : 1 = false;
- mutable bool cached_is_inert_ : 1 = false;
- mutable bool cached_is_aria_hidden_ : 1 = false;
- mutable bool cached_is_hidden_by_child_tree_ : 1 = false;
- mutable bool cached_is_hidden_via_style_ : 1 = false;
- mutable bool cached_is_used_for_label_or_description_ : 1;
- mutable bool cached_is_descendant_of_disabled_node_ : 1 = false;
- mutable bool cached_can_set_focus_attribute_ : 1 = false;
+ bool cached_is_ignored_ : 1 = true;
+ bool cached_is_ignored_but_included_in_tree_ : 1 = false;
+ bool cached_is_inert_ : 1 = false;
+ bool cached_is_aria_hidden_ : 1 = false;
+ bool cached_is_hidden_by_child_tree_ : 1 = false;
+ bool cached_is_hidden_via_style_ : 1 = false;
+ bool cached_is_used_for_label_or_description_ : 1;
+ bool cached_is_descendant_of_disabled_node_ : 1 = false;
+ bool cached_can_set_focus_attribute_ : 1 = false;
- mutable Member<AXObject> cached_live_region_root_;
- mutable gfx::RectF cached_local_bounding_box_rect_for_accessibility_;
+ Member<AXObject> cached_live_region_root_;
+ gfx::RectF cached_local_bounding_box_rect_for_accessibility_;
Member<AXObjectCacheImpl> ax_object_cache_;
@@ -1593,8 +1605,8 @@
unsigned ComputeAriaColumnIndex() const;
unsigned ComputeAriaRowIndex() const;
const ComputedStyle* GetComputedStyle() const;
- bool ComputeIsHiddenViaStyle(const ComputedStyle*) const;
- bool ComputeIsUsedForLabelOrDescription() const;
+ bool ComputeIsHiddenViaStyle(const ComputedStyle*);
+ bool ComputeIsUsedForLabelOrDescription();
bool ComputeIsInertViaStyle(const ComputedStyle*,
IgnoredReasons* = nullptr) const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
index ad1f51a..4de2d74 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
@@ -1661,32 +1661,6 @@
GetAXObjectByElementId("a-hidden-inert")->CanSetFocusAttribute());
}
-TEST_F(AccessibilityTest, GetParentNodeForComputeParent) {
- SetBodyInnerHTML(
- R"HTML(<img usemap="#map"><map name="map"><area id="area"
- shape="rect" coords="0,0,5,5" href="about:blank" alt="Area">)HTML");
-
- AXObjectCacheImpl& cache = GetAXObjectCache();
-
- // The parent of the area isn't the DOM parent, but the image because that
- // mirrors the structure of the ax tree.
- Element* area = GetElementById("area");
- AXObject* parent = AXObject::ComputeNonARIAParent(cache, area);
- EXPECT_TRUE(IsA<HTMLImageElement>(parent->GetNode()));
-
- parent = AXObject::ComputeNonARIAParent(cache, parent->GetNode());
- EXPECT_TRUE(IsA<HTMLBodyElement>(parent->GetNode()));
-
- parent = AXObject::ComputeNonARIAParent(cache, parent->GetNode());
- EXPECT_TRUE(IsA<HTMLHtmlElement>(parent->GetNode()));
-
- parent = AXObject::ComputeNonARIAParent(cache, parent->GetNode());
- EXPECT_TRUE(IsA<Document>(parent->GetNode()));
-
- parent = AXObject::ComputeNonARIAParent(cache, parent->GetNode());
- EXPECT_EQ(parent, nullptr);
-}
-
TEST_F(AccessibilityTest, CanComputeAsNaturalParent) {
SetBodyInnerHTML(R"HTML(M<img usemap="#map"><map name="map"><hr><progress>
<div><input type="range">M)HTML");