Commit e472e120 authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Ensure that AddChildren() is called with clean layout

Bug: 1091178
Change-Id: Ia6e82b1fcab8f08dbb3dff6186a8ab04e5a4f127
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2376307
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802277}
parent 25e9bd78
...@@ -148,8 +148,11 @@ AXObjectCacheImpl::AXObjectCacheImpl(Document& document) ...@@ -148,8 +148,11 @@ AXObjectCacheImpl::AXObjectCacheImpl(Document& document)
if (document_->LoadEventFinished()) if (document_->LoadEventFinished())
AddPermissionStatusListener(); AddPermissionStatusListener();
documents_.insert(&document); documents_.insert(&document);
relation_cache_->Init();
use_ax_menu_list_ = GetSettings()->GetUseAXMenuList(); use_ax_menu_list_ = GetSettings()->GetUseAXMenuList();
// Perform last, to ensure AXObjectCacheImpl() is fully set up, as
// AXRelationCache() sometimes calls back into AXObjectCacheImpl.
relation_cache_->Init();
} }
AXObjectCacheImpl::~AXObjectCacheImpl() { AXObjectCacheImpl::~AXObjectCacheImpl() {
......
...@@ -679,21 +679,17 @@ TEST_F(AccessibilityTest, CheckNoDuplicateChildren) { ...@@ -679,21 +679,17 @@ TEST_F(AccessibilityTest, CheckNoDuplicateChildren) {
ax_select->FirstChildIncludingIgnored()->ChildCountIncludingIgnored(), 1); ax_select->FirstChildIncludingIgnored()->ChildCountIncludingIgnored(), 1);
} }
TEST_F(AccessibilityTest, InitRelationCache) { TEST_F(AccessibilityTest, InitRelationCacheLabelFor) {
// All of the other tests already have accessibility initialized // Most other tests already have accessibility initialized
// first, but we don't want to in this test. // first, but we don't want to in this test.
// //
// Get rid of the AXContext so the AXObjectCache is destroyed. // Get rid of the AXContext so the AXObjectCache is destroyed.
ax_context_.reset(nullptr); ax_context_.reset(nullptr);
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<ul id="ul" aria-owns="li"></ul>
<label for="a"></label> <label for="a"></label>
<input id="a"> <input id="a">
<input id="b"> <input id="b">
<div role="section" id="div">
<li id="li"></li>
</div>
)HTML"); )HTML");
// Now recreate an AXContext, simulating what happens if accessibility // Now recreate an AXContext, simulating what happens if accessibility
...@@ -706,11 +702,32 @@ TEST_F(AccessibilityTest, InitRelationCache) { ...@@ -706,11 +702,32 @@ TEST_F(AccessibilityTest, InitRelationCache) {
ASSERT_NE(nullptr, input_a); ASSERT_NE(nullptr, input_a);
const AXObject* input_b = GetAXObjectByElementId("b"); const AXObject* input_b = GetAXObjectByElementId("b");
ASSERT_NE(nullptr, input_b); ASSERT_NE(nullptr, input_b);
}
TEST_F(AccessibilityTest, InitRelationCacheAriaOwns) {
// Most other tests already have accessibility initialized
// first, but we don't want to in this test.
//
// Get rid of the AXContext so the AXObjectCache is destroyed.
ax_context_.reset(nullptr);
SetBodyInnerHTML(R"HTML(
<ul id="ul" aria-owns="li"></ul>
<div role="section" id="div">
<li id="li"></li>
</div>
)HTML");
// Now recreate an AXContext, simulating what happens if accessibility
// is enabled after the document is loaded.
ax_context_.reset(new AXContext(GetDocument()));
const AXObject* root = GetAXRootObject();
ASSERT_NE(nullptr, root);
EXPECT_TRUE(GetAXObjectCache().MayHaveHTMLLabel( // Perform deferred processing so that aria-owns children are attached.
To<HTMLElement>(*input_a->GetNode()))); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInAccessibility);
EXPECT_FALSE(GetAXObjectCache().MayHaveHTMLLabel( GetAXObjectCache().ProcessDeferredAccessibilityEvents(GetDocument());
To<HTMLElement>(*input_b->GetNode())));
// Note: retrieve the LI first and check that its parent is not // Note: retrieve the LI first and check that its parent is not
// the paragraph element. If we were to retrieve the UL element, // the paragraph element. If we were to retrieve the UL element,
......
...@@ -24,11 +24,13 @@ void AXRelationCache::Init() { ...@@ -24,11 +24,13 @@ void AXRelationCache::Init() {
if (!id.IsEmpty()) if (!id.IsEmpty())
all_previously_seen_label_target_ids_.insert(id); all_previously_seen_label_target_ids_.insert(id);
// Ensure correct ancestor chains even when not all AXObject's in the
// document are created, e.g. in the devtools accessibility panel.
// Defers adding aria-owns targets as children of their new parents,
// and to the relation cache, until the appropriate document lifecycle.
if (element.FastHasAttribute(html_names::kAriaOwnsAttr)) { if (element.FastHasAttribute(html_names::kAriaOwnsAttr)) {
if (AXObject* obj = object_cache_->GetOrCreate(&element)) { object_cache_->HandleAttributeChanged(html_names::kAriaOwnsAttr,
obj->ClearChildren(); &element);
obj->AddChildren();
}
} }
} }
} }
......
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