Commit 7996d081 authored by Victor Fei's avatar Victor Fei Committed by Commit Bot

Stand Up IsOffscreen in AXPlatformNodeWin::GetPropertyValue

- Enabled/implemented IsOffscreen property for UIA in
AXPlatformNodeWin::GetPropertyValue and assoicated browser tests.
GetPropertyValue calculates isOffscreen status by utilizing
AXTree::RelativeToTreeBounds, which looks at the bounds of the
node relative to its ancestor and rootWebArea bounds to determine
the isOffscreen status.

- Modified AccessibilityWinBrowserTests::FindNodeInSubtree to take
into account of StringAttribute::kValue when finding the node.

Bug: 844149
Change-Id: Ied62e00814957a6ca97b1849935ec692f1acf03a
Reviewed-on: https://chromium-review.googlesource.com/c/1481800
Commit-Queue: Victor Fei <vicfei@microsoft.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636934}
parent cebbbd26
...@@ -98,7 +98,8 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest { ...@@ -98,7 +98,8 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
void SetUpSampleParagraphInScrollableEditable( void SetUpSampleParagraphInScrollableEditable(
Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text, Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
ui::AXMode accessibility_mode = ui::kAXModeComplete); ui::AXMode accessibility_mode = ui::kAXModeComplete);
BrowserAccessibility* FindNode(ax::mojom::Role role, const std::string& name); BrowserAccessibility* FindNode(ax::mojom::Role role,
const std::string& name_or_value);
BrowserAccessibilityManager* GetManager(); BrowserAccessibilityManager* GetManager();
static Microsoft::WRL::ComPtr<IAccessible> GetAccessibleFromVariant( static Microsoft::WRL::ComPtr<IAccessible> GetAccessibleFromVariant(
IAccessible* parent, IAccessible* parent,
...@@ -126,7 +127,7 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest { ...@@ -126,7 +127,7 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text); Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text);
BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node, BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
ax::mojom::Role role, ax::mojom::Role role,
const std::string& name); const std::string& name_or_value);
DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest); DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
}; };
...@@ -477,30 +478,41 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraphHelper( ...@@ -477,30 +478,41 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraphHelper(
ASSERT_HRESULT_SUCCEEDED(paragraph.CopyTo(accessible_text->GetAddressOf())); ASSERT_HRESULT_SUCCEEDED(paragraph.CopyTo(accessible_text->GetAddressOf()));
} }
// Retrieve the accessibility node, starting from the root node, that matches
// the accessibility role, name or value.
BrowserAccessibility* AccessibilityWinBrowserTest::FindNode( BrowserAccessibility* AccessibilityWinBrowserTest::FindNode(
ax::mojom::Role role, ax::mojom::Role role,
const std::string& name) { const std::string& name_or_value) {
BrowserAccessibility* root = GetManager()->GetRoot(); BrowserAccessibility* root = GetManager()->GetRoot();
CHECK(root); CHECK(root);
return FindNodeInSubtree(*root, role, name); return FindNodeInSubtree(*root, role, name_or_value);
} }
// Retrieve the browser accessibility manager object for the current web
// contents.
BrowserAccessibilityManager* AccessibilityWinBrowserTest::GetManager() { BrowserAccessibilityManager* AccessibilityWinBrowserTest::GetManager() {
WebContentsImpl* web_contents = WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents()); static_cast<WebContentsImpl*>(shell()->web_contents());
return web_contents->GetRootBrowserAccessibilityManager(); return web_contents->GetRootBrowserAccessibilityManager();
} }
// Retrieve the accessibility node in the subtree that matches the accessibility
// role, name or value.
BrowserAccessibility* AccessibilityWinBrowserTest::FindNodeInSubtree( BrowserAccessibility* AccessibilityWinBrowserTest::FindNodeInSubtree(
BrowserAccessibility& node, BrowserAccessibility& node,
ax::mojom::Role role, ax::mojom::Role role,
const std::string& name) { const std::string& name_or_value) {
const auto& name = node.GetStringAttribute(ax::mojom::StringAttribute::kName);
const auto& value =
node.GetStringAttribute(ax::mojom::StringAttribute::kValue);
if (node.GetRole() == role && if (node.GetRole() == role &&
node.GetStringAttribute(ax::mojom::StringAttribute::kName) == name) (name == name_or_value || value == name_or_value)) {
return &node; return &node;
}
for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) { for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) {
BrowserAccessibility* result = BrowserAccessibility* result =
FindNodeInSubtree(*node.PlatformGetChild(i), role, name); FindNodeInSubtree(*node.PlatformGetChild(i), role, name_or_value);
if (result) if (result)
return result; return result;
} }
......
...@@ -1750,11 +1750,21 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOffscreen) { ...@@ -1750,11 +1750,21 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOffscreen) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen.html")); RunHtmlTest(FILE_PATH_LITERAL("offscreen.html"));
} }
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityOffscreenIframe) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen-iframe.html"));
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityOffscreenScroll) { AccessibilityOffscreenScroll) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen-scroll.html")); RunHtmlTest(FILE_PATH_LITERAL("offscreen-scroll.html"));
} }
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityOffscreenSelect) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen-select.html"));
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOptgroup) { IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOptgroup) {
RunHtmlTest(FILE_PATH_LITERAL("optgroup.html")); RunHtmlTest(FILE_PATH_LITERAL("optgroup.html"));
} }
......
<!doctype html>
<html>
<body>
<div aria-label="iframe_onscreen" style="height:300px; background-color: red;"></div>
<div aria-label="iframe_offscreen" style="height:200px; background-color: green"></div>
</body>
</html>
rootWebArea
++genericContainer
++++iframe
++++++rootWebArea
++++++++genericContainer name='iframe_onscreen'
++++++++genericContainer offscreen name='iframe_offscreen'
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_SECTION
++++IA2_ROLE_INTERNAL_FRAME
++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++++++IA2_ROLE_SECTION name='iframe_onscreen'
++++++++IA2_ROLE_SECTION name='iframe_offscreen' OFFSCREEN
<!--
@WIN-ALLOW:OFFSCREEN
@BLINK-ALLOW:offscreen
-->
<html>
<body>
<iframe height="300px" width="200px" src="offscreen-iframe-content.html"></iframe>
</body>
</html>
rootWebArea
++popUpButton collapsed value='Onscreen 1'
++++menuListPopup invisible
++++++menuListOption name='Onscreen 1' selected=true
++++++menuListOption invisible name='Onscreen 2' selected=false
++++++menuListOption invisible name='Onscreen 3' selected=false
++popUpButton collapsed offscreen value='Offscreen 1'
++++menuListPopup invisible
++++++menuListOption offscreen name='Offscreen 1' selected=true
++++++menuListOption invisible offscreen name='Offscreen 2' selected=false
++++++menuListOption invisible offscreen name='Offscreen 3' selected=false
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++ROLE_SYSTEM_COMBOBOX value='Onscreen 1' COLLAPSED FOCUSABLE HASPOPUP
++++ROLE_SYSTEM_LIST INVISIBLE
++++++ROLE_SYSTEM_LISTITEM name='Onscreen 1' SELECTED FOCUSABLE
++++++ROLE_SYSTEM_LISTITEM name='Onscreen 2' INVISIBLE FOCUSABLE
++++++ROLE_SYSTEM_LISTITEM name='Onscreen 3' INVISIBLE FOCUSABLE
++ROLE_SYSTEM_COMBOBOX value='Offscreen 1' COLLAPSED OFFSCREEN FOCUSABLE HASPOPUP
++++ROLE_SYSTEM_LIST INVISIBLE
++++++ROLE_SYSTEM_LISTITEM name='Offscreen 1' SELECTED OFFSCREEN FOCUSABLE
++++++ROLE_SYSTEM_LISTITEM name='Offscreen 2' INVISIBLE OFFSCREEN FOCUSABLE
++++++ROLE_SYSTEM_LISTITEM name='Offscreen 3' INVISIBLE OFFSCREEN FOCUSABLE
<!--
@WIN-ALLOW:OFFSCREEN
@BLINK-ALLOW:offscreen
-->
<html>
<body>
<!-- Test when list box items are onscreen
Currently collapsed <option> elements are treated as onscreen, but this
probably isn't the most correct behavior, we should fix it.
http://crbug.com/937386 -->
<select name="Select onscreen">
<option value="1">Onscreen 1</option>
<option value="2">Onscreen 2</option>
<option value="3">Onscreen 3</option>
</select>
<div style="height:650px"></div>
<!-- Test when list box items are offscreen -->
<select name="Select offscreen">
<option value="1">Offscreen 1</option>
<option value="2">Offscreen 2</option>
<option value="3">Offscreen 3</option>
</select>
</body>
</html>
...@@ -3695,6 +3695,12 @@ IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id, ...@@ -3695,6 +3695,12 @@ IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id,
: VARIANT_FALSE; : VARIANT_FALSE;
break; break;
case UIA_IsOffscreenPropertyId:
result->vt = VT_BOOL;
result->boolVal =
GetDelegate()->IsOffscreen() ? VARIANT_TRUE : VARIANT_FALSE;
break;
case UIA_IsRequiredForFormPropertyId: case UIA_IsRequiredForFormPropertyId:
result->vt = VT_BOOL; result->vt = VT_BOOL;
if (data.HasState(ax::mojom::State::kRequired)) { if (data.HasState(ax::mojom::State::kRequired)) {
...@@ -3847,7 +3853,6 @@ IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id, ...@@ -3847,7 +3853,6 @@ IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id,
// Covered by MSAA. // Covered by MSAA.
case UIA_BoundingRectanglePropertyId: case UIA_BoundingRectanglePropertyId:
case UIA_HelpTextPropertyId: case UIA_HelpTextPropertyId:
case UIA_IsOffscreenPropertyId:
case UIA_NativeWindowHandlePropertyId: case UIA_NativeWindowHandlePropertyId:
case UIA_ProcessIdPropertyId: case UIA_ProcessIdPropertyId:
break; break;
......
...@@ -3219,6 +3219,7 @@ TEST_F(AXPlatformNodeWinTest, TestUIAGetPropertySimple) { ...@@ -3219,6 +3219,7 @@ TEST_F(AXPlatformNodeWinTest, TestUIAGetPropertySimple) {
EXPECT_UIA_BOOL_EQ(root_node, UIA_IsRequiredForFormPropertyId, false); EXPECT_UIA_BOOL_EQ(root_node, UIA_IsRequiredForFormPropertyId, false);
EXPECT_UIA_BOOL_EQ(root_node, UIA_IsDataValidForFormPropertyId, true); EXPECT_UIA_BOOL_EQ(root_node, UIA_IsDataValidForFormPropertyId, true);
EXPECT_UIA_BOOL_EQ(root_node, UIA_IsKeyboardFocusablePropertyId, false); EXPECT_UIA_BOOL_EQ(root_node, UIA_IsKeyboardFocusablePropertyId, false);
EXPECT_UIA_BOOL_EQ(root_node, UIA_IsOffscreenPropertyId, false);
ComPtr<IRawElementProviderSimple> child_node1 = ComPtr<IRawElementProviderSimple> child_node1 =
QueryInterfaceFromNode<IRawElementProviderSimple>( QueryInterfaceFromNode<IRawElementProviderSimple>(
GetRootNode()->children()[0]); GetRootNode()->children()[0]);
......
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