0

Fix AXLayoutObject::IsEditable for selectors (e.g., ::before)

For a specific range, AXPlatformNodeTextRangeProvider::GetAttributeValue
returns the attribute value found in all of its subranges. For example,
if we query the read-only attribute for a range composed of two
subranges, we are going to query the read-only attribute of the two
different subrange. If the value is true in both subranges, true will be
returned. Otherwise, if the value is different, an unknown value will be
returned.

An issue exists with rich text fields. Because the rich text field
accessible node can have children, it can have subranges. That means
that, when we query the read-only attribute for a rich text field, we
look for the read-only value of all of its children. It is thus extra
important that the appropriate properties describing the editable state
of the text field node are propagated to its children node.

Working on this issue, I discovered that the editable properties are not
propagated to its children that are selectors, like the ::before
selector. It works fine for other children however.

This CL fixes this issue by modifying the implementation of
AXLayoutObject::GetNodeOrContainingBlockNode, called by
AXLayoutObject::IsEditable and AXLayoutObject::IsRichlyEditable.

I also took the liberty to fix a test I added in another CL related to
the read-only attribute. The test in itself had no issue for the
moment, but would have as soon as someone else would have modified it.
The error message was not helpful and I spent some time investigating it.
To avoid to waste someone else's time like I did, I fixed it. For more
info, see the changes made to
ax_platform_node_textrangeprovider_win_unittest.cc.

In short:
- We now pass down the editable properties all children of an editable
  node.
- I added a dump test for this scenario.
- I fixed a future issue that would have happened with a unit test.
- I made FindNonAnonymousContainingBlock public and move the
  implementation accordingly.


Bug: 1041305
Change-Id: I3ef0af27f0ef679eb27cf12ce5999c6c11fffccf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1996269
Commit-Queue: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Reviewed-by: Kurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#739533}
This commit is contained in:
Benjamin Beaudry
2020-02-07 20:33:32 +00:00
committed by Commit Bot
parent 56bcbbe34c
commit 087b684a6e
5 changed files with 73 additions and 24 deletions
content/browser/accessibility
third_party/blink/renderer
ui/accessibility/platform

@ -479,6 +479,42 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
value.Reset();
}
// With a rich text field, the read-only attribute should be determined based on
// the editable root node's editable state.
IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
GetAttributeValueIsReadonlyRichTextField) {
LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(
<!DOCTYPE html>
<html>
<style>
.myDiv::before {
content: attr(data-placeholder);
pointer-events: none;
}
</style>
<body>
<div contenteditable="true" data-placeholder="@mention or comment"
role="textbox" aria-readonly="false" aria-label="text_field"
class="myDiv"><p>3.14</p></div>
</body>
</html>
)HTML"));
auto* text_field_node = FindNode(ax::mojom::Role::kTextField, "text_field");
ASSERT_NE(nullptr, text_field_node);
ComPtr<ITextRangeProvider> text_range_provider;
GetTextRangeProviderFromTextNode(*text_field_node, &text_range_provider);
ASSERT_NE(nullptr, text_range_provider.Get());
base::win::ScopedVariant value;
EXPECT_HRESULT_SUCCEEDED(text_range_provider->GetAttributeValue(
UIA_IsReadOnlyAttributeId, value.Receive()));
EXPECT_EQ(value.type(), VT_BOOL);
EXPECT_EQ(V_BOOL(value.ptr()), VARIANT_FALSE);
text_range_provider.Reset();
value.Reset();
}
IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
GetBoundingRectangles) {
LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(