Commit acde38ba authored by Mansi Awasthi's avatar Mansi Awasthi Committed by Commit Bot

Embed element with child tree should not be treated as an empty object

Currently Embed element with children in different tree are treated as
an empty object. It's because IsEmptyObjectReplacedByCharacter() calls
AnchorUnignoredChildCount() to see if an element has any children. This
call doesn't check if the element has a child tree. This results in
incorrect range calculation for PDF documents.

This CL adds a check in IsEmptyObjectReplacedByCharacter() that an Embed
element with non empty children including child tree should not be
treated as an empty object.

Bug: 1131507
Change-Id: I0fb2572a80c304c7cee35f68062321e09b78ed62
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2449670
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817501}
parent d2954428
......@@ -7810,6 +7810,53 @@ TEST_F(AXPositionTest, EmptyObjectReplacedByCharacterTextNavigation) {
EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, text_position->affinity());
}
TEST_F(AXPositionTest, EmptyObjectReplacedByCharacterEmbedObject) {
g_ax_embedded_object_behavior = AXEmbeddedObjectBehavior::kExposeCharacter;
// Parent Tree
// ++1 kRootWebArea
// ++++2 kEmbeddedObject
//
// Child Tree
// ++1 kDocument
ui::AXTreeID child_tree_id = ui::AXTreeID::CreateNewAXTreeID();
// Create tree manager for parent tree.
AXNodeData root;
AXNodeData embed_object;
root.id = 1;
embed_object.id = 2;
root.role = ax::mojom::Role::kRootWebArea;
root.child_ids = {embed_object.id};
embed_object.role = ax::mojom::Role::kEmbeddedObject;
embed_object.AddStringAttribute(ax::mojom::StringAttribute::kChildTreeId,
child_tree_id.ToString());
SetTree(CreateAXTree({root, embed_object}));
// Create tree manager for child tree.
AXNodeData child_root;
child_root.id = 1;
child_root.role = ax::mojom::Role::kDocument;
AXTreeUpdate update;
update.tree_data.tree_id = child_tree_id;
update.tree_data.parent_tree_id = GetTreeID();
update.has_tree_data = true;
update.root_id = child_root.id;
update.nodes.push_back(child_root);
TestAXTreeManager child_tree_manager(std::make_unique<AXTree>(update));
// Verify that kEmbeddedObject node with child tree is not treated as an
// empty object.
TestPositionType tree_position = AXNodePosition::CreateTreePosition(
GetTreeID(), embed_object.id, 0 /* child_index */);
ASSERT_TRUE(tree_position->IsTreePosition());
EXPECT_FALSE(tree_position->IsLeaf());
}
TEST_F(AXPositionTest, TextNavigationWithCollapsedCombobox) {
// On Windows, a <select> element is replaced by a combobox that contains
// an AXMenuListPopup parent of AXMenuListOptions. When the select dropdown is
......
......@@ -3225,6 +3225,13 @@ class AXPosition {
if (AnchorUnignoredChildCount())
return false;
// Embed element with non empty children should not be treated as empty
// objects.
if (GetAnchorRole() == ax::mojom::Role::kEmbeddedObject &&
AnchorChildCount() > 0) {
return false;
}
// All unignored leaf nodes in the AXTree except document and text
// nodes should be replaced by the embedded object character. Also, nodes
// that only have ignored children (e.g., a button that contains only an
......
......@@ -68,7 +68,7 @@ AXTreeID TestAXTreeManager::GetTreeID() const {
}
AXTreeID TestAXTreeManager::GetParentTreeID() const {
return AXTreeIDUnknown();
return tree_ ? tree_->data().parent_tree_id : AXTreeIDUnknown();
}
AXNode* TestAXTreeManager::GetRootAsAXNode() const {
......@@ -76,6 +76,22 @@ AXNode* TestAXTreeManager::GetRootAsAXNode() const {
}
AXNode* TestAXTreeManager::GetParentNodeFromParentTreeAsAXNode() const {
ui::AXTreeID parent_tree_id = GetParentTreeID();
TestAXTreeManager* parent_manager = static_cast<TestAXTreeManager*>(
ui::AXTreeManagerMap::GetInstance().GetManager(parent_tree_id));
if (!parent_manager)
return nullptr;
std::set<int32_t> host_node_ids =
parent_manager->GetTree()->GetNodeIdsForChildTreeId(GetTreeID());
for (int32_t host_node_id : host_node_ids) {
ui::AXNode* parent_node =
parent_manager->GetNodeFromTree(parent_tree_id, host_node_id);
if (parent_node)
return parent_node;
}
return nullptr;
}
......
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