Commit 283a1a3b authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Expose blink accessibility objects hidden via display:none on ancestor

Accessible objects styled with display:none are supposed to be exposed
when they have an id. However, this currently only works if the
display:none style targets the element directly. It also needs to work
if the display:none targets an ancestor.

This is also a necessary precursor to
https://chromium-review.googlesource.com/c/chromium/src/+/2090736

Bug: 651614
Change-Id: I789cda53f303ddfc3304f6109102b71090619aa2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095880
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarAdam Ettenberger <Adam.Ettenberger@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#751439}
parent d268e275
android.webkit.WebView focusable focused scrollable android.webkit.WebView focusable focused scrollable
++android.view.View name='blockDisplay' ++android.view.View name='blockDisplay'
++android.view.View name='blockDisplay Hiddenfalse' ++android.view.View name='blockDisplay Hiddenfalse'
++android.view.View ++android.view.View invisible
++android.view.View focusable invisible name='blockDisplay Hiddentruefocusable' ++android.view.View focusable invisible name='blockDisplay Hiddentruefocusable'
\ No newline at end of file
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
++++[static] name='blockDisplay' ++++[static] name='blockDisplay'
++[section] ++[section]
++++[static] name='blockDisplay Hiddenfalse' ++++[static] name='blockDisplay Hiddenfalse'
++[section] ++[section] hidden:true
++[section] name='blockDisplay Hiddentruefocusable' hidden:true ++[section] name='blockDisplay Hiddentruefocusable' hidden:true
\ No newline at end of file
...@@ -10,6 +10,6 @@ rootWebArea isLineBreakingObject=true ...@@ -10,6 +10,6 @@ rootWebArea isLineBreakingObject=true
++++genericContainer isLineBreakingObject=true ++++genericContainer isLineBreakingObject=true
++++++staticText name='blockDisplay Hiddenfalse' ++++++staticText name='blockDisplay Hiddenfalse'
++++++++inlineTextBox name='blockDisplay Hiddenfalse' ++++++++inlineTextBox name='blockDisplay Hiddenfalse'
++++genericContainer ++++genericContainer invisible
++++genericContainer invisible name='blockDisplay Hiddentruefocusable' isLineBreakingObject=true ++++genericContainer invisible name='blockDisplay Hiddentruefocusable' isLineBreakingObject=true
++++++staticText ignored invisible name='blockDisplay Hiddentruefocusable' ++++++staticText ignored invisible name='blockDisplay Hiddentruefocusable'
\ No newline at end of file
...@@ -3,5 +3,5 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ...@@ -3,5 +3,5 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++ROLE_SYSTEM_STATICTEXT name='blockDisplay' ++++ROLE_SYSTEM_STATICTEXT name='blockDisplay'
++IA2_ROLE_SECTION ++IA2_ROLE_SECTION
++++ROLE_SYSTEM_STATICTEXT name='blockDisplay Hiddenfalse' ++++ROLE_SYSTEM_STATICTEXT name='blockDisplay Hiddenfalse'
++IA2_ROLE_SECTION ++IA2_ROLE_SECTION INVISIBLE hidden:true
++IA2_ROLE_SECTION name='blockDisplay Hiddentruefocusable' INVISIBLE FOCUSABLE hidden:true ++IA2_ROLE_SECTION name='blockDisplay Hiddentruefocusable' INVISIBLE FOCUSABLE hidden:true
\ No newline at end of file
...@@ -5,6 +5,7 @@ rootWebArea ...@@ -5,6 +5,7 @@ rootWebArea
++++++++staticText name='Cats' ++++++++staticText name='Cats'
++++++++++inlineTextBox name='Cats' ++++++++++inlineTextBox name='Cats'
++++++genericContainer ignored invisible name='checkbox' ++++++genericContainer ignored invisible name='checkbox'
++++++++checkBox ignored invisible name='checkbox' checkedState=false
++++++genericContainer ++++++genericContainer
++++++++staticText name='done' ++++++++staticText name='done'
++++++++++inlineTextBox name='done' ++++++++++inlineTextBox name='done'
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div> <div>
<div>Cats</div> <div>Cats</div>
<div id="none"> <div id="none">
<input type="checkbox" aria-label="checkbox"> <input type="checkbox" aria-label="checkbox" id="cbox1">
</div> </div>
<div><code>pending</code></div> <div><code>pending</code></div>
</div> </div>
......
#<skip -- crbug.com/1062697> #<skip -- crbug.com/1062697>
AriaProperties changed on role=menu, name=menu AriaProperties changed on role=menu, name=menu
AriaProperties changed on role=menuitem, name=submenu1
AriaProperties changed on role=menuitem, name=submenu2
MenuOpened on role=menu, name=menu MenuOpened on role=menu, name=menu
MenuOpened on role=region
=== Start Continuation === === Start Continuation ===
AriaProperties changed on role=menu AriaProperties changed on role=menu
AriaProperties changed on role=menuitem, name=option
MenuOpened on role=menu MenuOpened on role=menu
MenuOpened on role=region
=== Start Continuation === === Start Continuation ===
MenuClosed MenuClosed
MenuClosed MenuClosed
......
...@@ -3,14 +3,15 @@ rootWebArea ...@@ -3,14 +3,15 @@ rootWebArea
++++staticText name='some text' ++++staticText name='some text'
++++++inlineTextBox name='some text' ++++++inlineTextBox name='some text'
++++genericContainer ignored ++++genericContainer ignored
++++++genericContainer ignored invisible
=== Start Continuation === === Start Continuation ===
rootWebArea rootWebArea
++genericContainer ignored invisible ++genericContainer ignored invisible
++++genericContainer ignored invisible ++++genericContainer ignored invisible
++++++dialog ++++++dialog
++++++++genericContainer name='Dialog Text' ++++++++genericContainer name='Some Text'
++++++++++staticText name='Dialog Text' ++++++++++staticText name='Some Text'
++++++++++++inlineTextBox name='Dialog Text' ++++++++++++inlineTextBox name='Some Text'
=== Start Continuation === === Start Continuation ===
rootWebArea rootWebArea
++genericContainer ignored invisible ++genericContainer ignored invisible
...@@ -18,4 +19,4 @@ rootWebArea ...@@ -18,4 +19,4 @@ rootWebArea
++++++dialog ++++++dialog
++++++++genericContainer name='Done' ++++++++genericContainer name='Done'
++++++++++staticText name='Done' ++++++++++staticText name='Done'
++++++++++++inlineTextBox name='Done' ++++++++++++inlineTextBox name='Done'
\ No newline at end of file
...@@ -11,7 +11,7 @@ their parent. crbug: 996992 ...@@ -11,7 +11,7 @@ their parent. crbug: 996992
<span>some text</span> <span>some text</span>
<div> <div>
<dialog> <dialog>
<div id="dialog-text" tabindex="0">Dialog Text</div> <div id="dialog-text" tabindex="0">Some Text</div>
</dialog> </dialog>
</div> </div>
...@@ -19,7 +19,7 @@ their parent. crbug: 996992 ...@@ -19,7 +19,7 @@ their parent. crbug: 996992
<script> <script>
function open_modal() { function open_modal() {
document.querySelector("dialog").showModal(); document.querySelector("dialog").showModal();
return "Dialog Text"; return "dialog";
} }
function remove_span() { function remove_span() {
// Cause the root to be updated. // Cause the root to be updated.
...@@ -31,4 +31,4 @@ their parent. crbug: 996992 ...@@ -31,4 +31,4 @@ their parent. crbug: 996992
} }
</script> </script>
</html> </html>
\ No newline at end of file
...@@ -1066,7 +1066,7 @@ bool AXObject::ComputeIsInertOrAriaHidden( ...@@ -1066,7 +1066,7 @@ bool AXObject::ComputeIsInertOrAriaHidden(
} }
bool AXObject::IsVisible() const { bool AXObject::IsVisible() const {
return !IsInertOrAriaHidden() && !IsHiddenForTextAlternativeCalculation(); return !IsInertOrAriaHidden() && !IsHiddenViaStyle();
} }
bool AXObject::IsDescendantOfLeafNode() const { bool AXObject::IsDescendantOfLeafNode() const {
...@@ -1242,7 +1242,7 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const { ...@@ -1242,7 +1242,7 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
if (RuntimeEnabledFeatures::AccessibilityExposeDisplayNoneEnabled()) { if (RuntimeEnabledFeatures::AccessibilityExposeDisplayNoneEnabled()) {
if (Element* element = GetElement()) { if (Element* element = GetElement()) {
if (element->FastHasAttribute(html_names::kIdAttr) && if (element->FastHasAttribute(html_names::kIdAttr) &&
IsHiddenForTextAlternativeCalculation()) { IsHiddenViaStyle()) {
return true; return true;
} }
} }
...@@ -1636,6 +1636,33 @@ String AXObject::RecursiveTextAlternative(const AXObject& ax_obj, ...@@ -1636,6 +1636,33 @@ String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
name_from, nullptr, nullptr); name_from, nullptr, nullptr);
} }
bool AXObject::IsHiddenViaStyle() const {
if (GetLayoutObject())
return GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible;
if (Node* node = GetNode()) {
if (node->isConnected()) {
bool is_first_loop = true;
auto* element = DynamicTo<Element>(node);
while (element && !element->GetLayoutObject()) {
const ComputedStyle* style = element->EnsureComputedStyle();
if (is_first_loop && style->Visibility() != EVisibility::kVisible)
return true;
// CSS Display:
// - does not inherit
// - display: none affects entire subtrees regardless of descendants
// attempting to override it
// - causes elements to have no associated layout object
// Therefore, check each consecutive parent without a layout object.
if (style->Display() == EDisplay::kNone)
return true;
element = element->parentElement();
is_first_loop = false;
}
}
}
return false;
}
bool AXObject::IsHiddenForTextAlternativeCalculation() const { bool AXObject::IsHiddenForTextAlternativeCalculation() const {
if (AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) if (AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden))
return false; return false;
......
...@@ -1147,6 +1147,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { ...@@ -1147,6 +1147,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool HasInternalsAttribute(Element&, const QualifiedName&) const; bool HasInternalsAttribute(Element&, const QualifiedName&) const;
const AtomicString& GetInternalsAttribute(Element&, const AtomicString& GetInternalsAttribute(Element&,
const QualifiedName&) const; const QualifiedName&) const;
bool IsHiddenViaStyle() const;
static unsigned number_of_live_ax_objects_; static unsigned number_of_live_ax_objects_;
......
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