Commit 700f882c authored by Kevin Babbitt's avatar Kevin Babbitt Committed by Commit Bot

a11y: Add popup children for nodes walked via layout tree

Call AddPopupChildren() when walking the layout tree in order to ensure
that popup contents for controls such as <input type="date"> are added
to the accessibility tree.

For testing, I wanted a tree dump that would show the contents of the
popup. I tried a couple of different techniques to simulate a click on
the popup button from script but none of them worked. Instead I added
the ability for the tree dumper to synthesize clicks on elements after
the document is loaded.

Bug: 964154
Change-Id: I75b6169bfd336bd98c70e93960f4f56a6413424f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1616387Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarIan Prest <iapres@microsoft.com>
Commit-Queue: Kevin Babbitt <kbabbitt@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#664435}
parent 95283079
...@@ -163,7 +163,8 @@ std::vector<int> DumpAccessibilityTestBase::DiffLines( ...@@ -163,7 +163,8 @@ std::vector<int> DumpAccessibilityTestBase::DiffLines(
void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives( void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
const std::string& test_html, const std::string& test_html,
std::vector<std::string>* wait_for, std::vector<std::string>* wait_for,
std::vector<std::string>* run_until) { std::vector<std::string>* run_until,
std::vector<std::string>* default_action_on) {
for (const std::string& line : base::SplitString( for (const std::string& line : base::SplitString(
test_html, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { test_html, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
const std::string& allow_empty_str = formatter_->GetAllowEmptyString(); const std::string& allow_empty_str = formatter_->GetAllowEmptyString();
...@@ -172,6 +173,7 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives( ...@@ -172,6 +173,7 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
const std::string& deny_node_str = formatter_->GetDenyNodeString(); const std::string& deny_node_str = formatter_->GetDenyNodeString();
const std::string& wait_str = "@WAIT-FOR:"; const std::string& wait_str = "@WAIT-FOR:";
const std::string& until_str = "@RUN-UNTIL-EVENT:"; const std::string& until_str = "@RUN-UNTIL-EVENT:";
const std::string& default_action_on_str = "@DEFAULT-ACTION-ON:";
if (base::StartsWith(line, allow_empty_str, base::CompareCase::SENSITIVE)) { if (base::StartsWith(line, allow_empty_str, base::CompareCase::SENSITIVE)) {
property_filters_.push_back( property_filters_.push_back(
PropertyFilter(base::UTF8ToUTF16(line.substr(allow_empty_str.size())), PropertyFilter(base::UTF8ToUTF16(line.substr(allow_empty_str.size())),
...@@ -200,6 +202,9 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives( ...@@ -200,6 +202,9 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
} else if (base::StartsWith(line, until_str, } else if (base::StartsWith(line, until_str,
base::CompareCase::SENSITIVE)) { base::CompareCase::SENSITIVE)) {
run_until->push_back(line.substr(until_str.size())); run_until->push_back(line.substr(until_str.size()));
} else if (base::StartsWith(line, default_action_on_str,
base::CompareCase::SENSITIVE)) {
default_action_on->push_back(line.substr(default_action_on_str.size()));
} }
} }
} }
...@@ -304,11 +309,13 @@ void DumpAccessibilityTestBase::RunTestForPlatform( ...@@ -304,11 +309,13 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
// Parse filters and other directives in the test file. // Parse filters and other directives in the test file.
std::vector<std::string> wait_for; std::vector<std::string> wait_for;
std::vector<std::string> run_until; std::vector<std::string> run_until;
std::vector<std::string> default_action_on;
property_filters_.clear(); property_filters_.clear();
node_filters_.clear(); node_filters_.clear();
formatter_->AddDefaultFilters(&property_filters_); formatter_->AddDefaultFilters(&property_filters_);
AddDefaultFilters(&property_filters_); AddDefaultFilters(&property_filters_);
ParseHtmlForExtraDirectives(html_contents, &wait_for, &run_until); ParseHtmlForExtraDirectives(html_contents, &wait_for, &run_until,
&default_action_on);
// Get the test URL. // Get the test URL.
GURL url(embedded_test_server()->GetURL("/" + std::string(file_dir) + "/" + GURL url(embedded_test_server()->GetURL("/" + std::string(file_dir) + "/" +
...@@ -332,6 +339,21 @@ void DumpAccessibilityTestBase::RunTestForPlatform( ...@@ -332,6 +339,21 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
accessibility_waiter.WaitForNotification(); accessibility_waiter.WaitForNotification();
} }
// Perform default action on any elements specified by the test.
for (const auto& str : default_action_on) {
AccessibilityNotificationWaiter waiter(shell()->web_contents(),
ui::kAXModeComplete,
ax::mojom::Event::kClicked);
BrowserAccessibility* action_element = FindNode(str);
ui::AXActionData action_data;
action_data.action = ax::mojom::Action::kDoDefault;
action_element->AccessibilityPerformAction(action_data);
waiter.WaitForNotification();
}
// Get the url of every frame in the frame tree. // Get the url of every frame in the frame tree.
FrameTree* frame_tree = web_contents->GetFrameTree(); FrameTree* frame_tree = web_contents->GetFrameTree();
std::vector<std::string> all_frame_urls; std::vector<std::string> all_frame_urls;
...@@ -457,4 +479,33 @@ void DumpAccessibilityTestBase::RunTestForPlatform( ...@@ -457,4 +479,33 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
} }
} }
BrowserAccessibility* DumpAccessibilityTestBase::FindNode(
const std::string& name) {
BrowserAccessibility* root = GetManager()->GetRoot();
CHECK(root);
return FindNodeInSubtree(*root, name);
}
BrowserAccessibilityManager* DumpAccessibilityTestBase::GetManager() {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
return web_contents->GetRootBrowserAccessibilityManager();
}
BrowserAccessibility* DumpAccessibilityTestBase::FindNodeInSubtree(
BrowserAccessibility& node,
const std::string& name) {
if (node.GetStringAttribute(ax::mojom::StringAttribute::kName) == name) {
return &node;
}
for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) {
BrowserAccessibility* result =
FindNodeInSubtree(*node.PlatformGetChild(i), name);
if (result)
return result;
}
return nullptr;
}
} // namespace content } // namespace content
...@@ -97,10 +97,19 @@ class DumpAccessibilityTestBase : public ContentBrowserTest, ...@@ -97,10 +97,19 @@ class DumpAccessibilityTestBase : public ContentBrowserTest,
// @WAIT-FOR: directives. // @WAIT-FOR: directives.
void ParseHtmlForExtraDirectives(const std::string& test_html, void ParseHtmlForExtraDirectives(const std::string& test_html,
std::vector<std::string>* wait_for, std::vector<std::string>* wait_for,
std::vector<std::string>* run_until); std::vector<std::string>* run_until,
std::vector<std::string>* default_action_on);
void RunTestForPlatform(const base::FilePath file_path, const char* file_dir); void RunTestForPlatform(const base::FilePath file_path, const char* file_dir);
// Retrieve the accessibility node, starting from the root node, that matches
// the accessibility name.
BrowserAccessibility* FindNode(const std::string& name);
// Retrieve the browser accessibility manager object for the current web
// contents.
BrowserAccessibilityManager* GetManager();
// The default property filters plus the property filters loaded from the test // The default property filters plus the property filters loaded from the test
// file. // file.
std::vector<AccessibilityTreeFormatter::PropertyFilter> property_filters_; std::vector<AccessibilityTreeFormatter::PropertyFilter> property_filters_;
...@@ -125,6 +134,10 @@ class DumpAccessibilityTestBase : public ContentBrowserTest, ...@@ -125,6 +134,10 @@ class DumpAccessibilityTestBase : public ContentBrowserTest,
bool enable_accessibility_after_navigating_; bool enable_accessibility_after_navigating_;
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
private:
BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
const std::string& name);
}; };
} // namespace content } // namespace content
......
...@@ -1408,6 +1408,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDate) { ...@@ -1408,6 +1408,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDate) {
RunHtmlTest(FILE_PATH_LITERAL("input-date.html")); RunHtmlTest(FILE_PATH_LITERAL("input-date.html"));
} }
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
AccessibilityInputDateWithPopupOpen) {
RunHtmlTest(FILE_PATH_LITERAL("input-date-with-popup-open.html"));
}
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDateTime) { IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDateTime) {
RunHtmlTest(FILE_PATH_LITERAL("input-datetime.html")); RunHtmlTest(FILE_PATH_LITERAL("input-datetime.html"));
} }
......
...@@ -550,6 +550,21 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() { ...@@ -550,6 +550,21 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
dirty_objects.push_back(dirty_object); dirty_objects.push_back(dirty_object);
} }
// Popups have a document lifecycle managed separately from the main document
// but we need to return a combined accessibility tree for both.
// We ensured layout validity for the main document in the loop above; if a
// popup is open, do the same for it.
WebDocument popup_document = GetPopupDocument();
if (!popup_document.IsNull()) {
WebAXObject popup_root_obj = WebAXObject::FromWebDocument(popup_document);
if (!popup_root_obj.UpdateLayoutAndCheckValidity()) {
// If a popup is open but we can't ensure its validity, return without
// sending an update bundle, the same as we would for a node in the main
// document.
return;
}
}
// Keep track of if the host node for a plugin has been invalidated, // Keep track of if the host node for a plugin has been invalidated,
// because if so, the plugin subtree will need to be re-serialized. // because if so, the plugin subtree will need to be re-serialized.
bool invalidate_plugin_subtree = false; bool invalidate_plugin_subtree = false;
...@@ -1187,4 +1202,12 @@ void RenderAccessibilityImpl::AddImageAnnotationDebuggingAttributes( ...@@ -1187,4 +1202,12 @@ void RenderAccessibilityImpl::AddImageAnnotationDebuggingAttributes(
} }
} }
blink::WebDocument RenderAccessibilityImpl::GetPopupDocument() {
blink::WebPagePopup* popup =
render_frame_->GetRenderView()->GetWebView()->GetPagePopup();
if (popup)
return popup->GetDocument();
return WebDocument();
}
} // namespace content } // namespace content
...@@ -169,6 +169,9 @@ class CONTENT_EXPORT RenderAccessibilityImpl ...@@ -169,6 +169,9 @@ class CONTENT_EXPORT RenderAccessibilityImpl
void AddImageAnnotationDebuggingAttributes( void AddImageAnnotationDebuggingAttributes(
const std::vector<AXContentTreeUpdate>& updates); const std::vector<AXContentTreeUpdate>& updates);
// Returns the document for the active popup if any.
blink::WebDocument GetPopupDocument();
// The RenderFrameImpl that owns us. // The RenderFrameImpl that owns us.
RenderFrameImpl* render_frame_; RenderFrameImpl* render_frame_;
......
...@@ -161,6 +161,7 @@ class StubWebPagePopup : public blink::WebPagePopup { ...@@ -161,6 +161,7 @@ class StubWebPagePopup : public blink::WebPagePopup {
// WebPagePopup implementation. // WebPagePopup implementation.
blink::WebPoint PositionRelativeToOwner() override { return {}; } blink::WebPoint PositionRelativeToOwner() override { return {}; }
blink::WebDocument GetDocument() override { return {}; }
blink::WebPagePopupClient* GetClientForTesting() const override { blink::WebPagePopupClient* GetClientForTesting() const override {
return nullptr; return nullptr;
} }
......
android.webkit.WebView focusable focused scrollable android.webkit.WebView focusable focused scrollable
++android.view.View ++android.view.View
++++android.widget.Spinner role_description='date picker' clickable focusable name='@NO_CHILDREN_DUMP' input_type=20 ++++android.widget.Spinner role_description='date picker' clickable focusable name='2008-09-01' input_type=20
\ No newline at end of file
[document web] [document web]
++[section] ++[section]
++++[dateeditor] name='@NO_CHILDREN_DUMP' ++++[dateeditor]
++++++[section]
++++++++[section]
++++++++++[spin button] name='Month' current=9.000000 minimum=1.000000 maximum=12.000000
++++++++++++[text] name='09'
++++++++++[text] name='/'
++++++++++[spin button] name='Day' current=1.000000 minimum=1.000000 maximum=31.000000
++++++++++++[text] name='01'
++++++++++[text] name='/'
++++++++++[spin button] name='Year' current=2008.000000 minimum=1.000000 maximum=275760.000000
++++++++++++[text] name='2008'
++++++[push button] name='Show date picker'
rootWebArea rootWebArea
++genericContainer ++genericContainer
++++date name='@NO_CHILDREN_DUMP' value='2008-09-01' ++++date value='2008-09-01'
++++++genericContainer
++++++++genericContainer
++++++++++spinButton name='Month' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
++++++++++++staticText name='09'
++++++++++++++inlineTextBox name='09'
++++++++++staticText name='/'
++++++++++++inlineTextBox name='/'
++++++++++spinButton name='Day' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
++++++++++++staticText name='01'
++++++++++++++inlineTextBox name='01'
++++++++++staticText name='/'
++++++++++++inlineTextBox name='/'
++++++++++spinButton name='Year' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
++++++++++++staticText name='2008'
++++++++++++++inlineTextBox name='2008'
++++++popUpButton name='Show date picker'
AXWebArea AXRoleDescription='HTML content' AXWebArea AXRoleDescription='HTML content'
++AXGroup AXRoleDescription='group' ++AXGroup AXRoleDescription='group'
++++AXDateField AXRoleDescription='date field' AXValue='2008-09-01' AXDescription='@NO_CHILDREN_DUMP' ++++AXDateField AXRoleDescription='date field' AXValue='2008-09-01'
++++++AXGroup AXRoleDescription='group'
++++++++AXGroup AXRoleDescription='group'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='9' AXDescription='Month'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='09'
++++++++++AXStaticText AXRoleDescription='text' AXValue='/'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='1' AXDescription='Day'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='01'
++++++++++AXStaticText AXRoleDescription='text' AXValue='/'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='2008' AXDescription='Year'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='2008'
++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
region region
++document ++document
++++group ++++group
++++++list Name='@NO_CHILDREN_DUMP' ++++++list
++++++++group
++++++++++group
++++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
++++++++++++++description Name='09'
++++++++++++description Name='/'
++++++++++++spinbutton Name='Day' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=31.00 RangeValue.Minimum=1.00 RangeValue.Value=1.00 Value.Value='01'
++++++++++++++description Name='01'
++++++++++++description Name='/'
++++++++++++spinbutton Name='Year' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=275760.00 RangeValue.Minimum=1.00 RangeValue.Value=2008.00 Value.Value='2008'
++++++++++++++description Name='2008'
++++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='LeafNode'
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>' ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>'
++IA2_ROLE_SECTION ia2_hypertext='<obj0>' ++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++IA2_ROLE_DATE_EDITOR name='@NO_CHILDREN_DUMP' value='2008-09-01' FOCUSABLE ia2_hypertext='<obj0><obj1>' ++++IA2_ROLE_DATE_EDITOR value='2008-09-01' FOCUSABLE ia2_hypertext='<obj0><obj1>'
++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>/<obj2>/<obj4>'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Month' value='09' FOCUSABLE ia2_hypertext='09'
++++++++++++ROLE_SYSTEM_STATICTEXT name='09' ia2_hypertext='09'
++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Day' value='01' FOCUSABLE ia2_hypertext='01'
++++++++++++ROLE_SYSTEM_STATICTEXT name='01' ia2_hypertext='01'
++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Year' value='2008' FOCUSABLE ia2_hypertext='2008'
++++++++++++ROLE_SYSTEM_STATICTEXT name='2008' ia2_hypertext='2008'
++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP ia2_hypertext='Show date picker'
#<skip - date and time controls drop their children, including the popup button, on Android>
[document web]
++[section]
++++[dateeditor]
++++++[section]
++++++++[section]
++++++++++[spin button] name='Month' current=9.000000 minimum=1.000000 maximum=12.000000
++++++++++++[text] name='09'
++++++++++[text] name='/'
++++++++++[spin button] name='Day' current=1.000000 minimum=1.000000 maximum=31.000000
++++++++++++[text] name='01'
++++++++++[text] name='/'
++++++++++[spin button] name='Year' current=2008.000000 minimum=1.000000 maximum=275760.000000
++++++++++++[text] name='2008'
++++++[push button] name='Show date picker'
++++++[document web]
++++++++[section]
++++++++++[section]
++++++++++++[section]
++++++++++++++[push button] name='Show month selection panel'
++++++++++++[push button] name='Show previous month'
++++++++++++[push button] name='Today'
++++++++++++[push button] name='Show next month'
++++++++++++[table] cols=0 headers=(NONE); rows=0 headers=(NONE); caption=false; spans=(all: 1x1)
++++++++++++++[section]
++++++++++++++++[section]
++++++++++++++++++[text] name='Sun'
++++++++++++++++[section]
++++++++++++++++++[text] name='Mon'
++++++++++++++++[section]
++++++++++++++++++[text] name='Tue'
++++++++++++++++[section]
++++++++++++++++++[text] name='Wed'
++++++++++++++++[section]
++++++++++++++++++[text] name='Thu'
++++++++++++++++[section]
++++++++++++++++++[text] name='Fri'
++++++++++++++++[section]
++++++++++++++++++[text] name='Sat'
++++++++++++++[section]
++++++++++++++++[section]
rootWebArea
++genericContainer
++++date value='2008-09-01'
++++++genericContainer
++++++++genericContainer
++++++++++spinButton name='Month' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
++++++++++++staticText name='09'
++++++++++++++inlineTextBox name='09'
++++++++++staticText name='/'
++++++++++++inlineTextBox name='/'
++++++++++spinButton name='Day' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
++++++++++++staticText name='01'
++++++++++++++inlineTextBox name='01'
++++++++++staticText name='/'
++++++++++++inlineTextBox name='/'
++++++++++spinButton name='Year' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
++++++++++++staticText name='2008'
++++++++++++++inlineTextBox name='2008'
++++++popUpButton name='Show date picker'
++++++rootWebArea
++++++++genericContainer
++++++++++genericContainer
++++++++++++genericContainer
++++++++++++++button name='Show month selection panel'
++++++++++++button name='Show previous month'
++++++++++++button name='Today'
++++++++++++button name='Show next month'
++++++++++++grid
++++++++++++++genericContainer
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Sun'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Mon'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Tue'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Wed'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Thu'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Fri'
++++++++++++++++genericContainer
++++++++++++++++++staticText name='Sat'
++++++++++++++genericContainer
++++++++++++++++genericContainer
AXWebArea AXRoleDescription='HTML content'
++AXGroup AXRoleDescription='group'
++++AXDateField AXRoleDescription='date field' AXValue='2008-09-01'
++++++AXGroup AXRoleDescription='group'
++++++++AXGroup AXRoleDescription='group'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='9' AXDescription='Month'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='09'
++++++++++AXStaticText AXRoleDescription='text' AXValue='/'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='1' AXDescription='Day'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='01'
++++++++++AXStaticText AXRoleDescription='text' AXValue='/'
++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='2008' AXDescription='Year'
++++++++++++AXStaticText AXRoleDescription='text' AXValue='2008'
++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
++++++AXWebArea AXRoleDescription='HTML content'
++++++++AXGroup AXRoleDescription='group'
++++++++++AXGroup AXRoleDescription='group'
++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++AXButton AXRoleDescription='button' AXDescription='Show month selection panel'
++++++++++++AXButton AXRoleDescription='button' AXDescription='Show previous month'
++++++++++++AXButton AXRoleDescription='button' AXDescription='Today'
++++++++++++AXButton AXRoleDescription='button' AXDescription='Show next month'
++++++++++++AXTable AXRoleDescription='table' AXDescription='Sun Mon Tue Wed Thu Fri Sat'
++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Sun'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Mon'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Tue'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Wed'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Thu'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Fri'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='Sat'
++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++++AXGroup AXRoleDescription='group'
++++++++++++++AXGroup AXRoleDescription='group'
region
++document
++++group
++++++list
++++++++group
++++++++++group
++++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
++++++++++++++description Name='09'
++++++++++++description Name='/'
++++++++++++spinbutton Name='Day' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=31.00 RangeValue.Minimum=1.00 RangeValue.Value=1.00 Value.Value='01'
++++++++++++++description Name='01'
++++++++++++description Name='/'
++++++++++++spinbutton Name='Year' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=275760.00 RangeValue.Minimum=1.00 RangeValue.Value=2008.00 Value.Value='2008'
++++++++++++++description Name='2008'
++++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='LeafNode'
++++++++document
++++++++++group
++++++++++++group
++++++++++++++group
++++++++++++++++button Name='Show month selection panel'
++++++++++++++button Name='Show previous month'
++++++++++++++button Name='Today'
++++++++++++++button Name='Show next month'
++++++++++++++grid Grid.ColumnCount=0 Grid.RowCount=0 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
++++++++++++++++group
++++++++++++++++++group
++++++++++++++++++++description Name='Sun'
++++++++++++++++++group
++++++++++++++++++++description Name='Mon'
++++++++++++++++++group
++++++++++++++++++++description Name='Tue'
++++++++++++++++++group
++++++++++++++++++++description Name='Wed'
++++++++++++++++++group
++++++++++++++++++++description Name='Thu'
++++++++++++++++++group
++++++++++++++++++++description Name='Fri'
++++++++++++++++++group
++++++++++++++++++++description Name='Sat'
++++++++++++++++group
++++++++++++++++++group
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>'
++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++IA2_ROLE_DATE_EDITOR value='2008-09-01' FOCUSABLE ia2_hypertext='<obj0><obj1><obj2>'
++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>/<obj2>/<obj4>'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Month' value='09' FOCUSABLE ia2_hypertext='09'
++++++++++++ROLE_SYSTEM_STATICTEXT name='09' ia2_hypertext='09'
++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Day' value='01' FOCUSABLE ia2_hypertext='01'
++++++++++++ROLE_SYSTEM_STATICTEXT name='01' ia2_hypertext='01'
++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
++++++++++ROLE_SYSTEM_SPINBUTTON name='Year' value='2008' FOCUSABLE ia2_hypertext='2008'
++++++++++++ROLE_SYSTEM_STATICTEXT name='2008' ia2_hypertext='2008'
++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP ia2_hypertext='Show date picker'
++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>'
++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0><obj1><obj2><obj3><obj4>'
++++++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Show month selection panel' FOCUSABLE ia2_hypertext='Show month selection panel'
++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Show previous month' FOCUSABLE ia2_hypertext='Show previous month'
++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Today' FOCUSABLE ia2_hypertext='Today'
++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Show next month' FOCUSABLE ia2_hypertext='Show next month'
++++++++++++ROLE_SYSTEM_TABLE FOCUSABLE ia2_hypertext='<obj0><obj1>'
++++++++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0><obj1><obj2><obj3><obj4><obj5><obj6>'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Sun'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Sun' ia2_hypertext='Sun'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Mon'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Mon' ia2_hypertext='Mon'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Tue'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Tue' ia2_hypertext='Tue'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Wed'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Wed' ia2_hypertext='Wed'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Thu'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Thu' ia2_hypertext='Thu'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Fri'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Fri' ia2_hypertext='Fri'
++++++++++++++++IA2_ROLE_SECTION ia2_hypertext='Sat'
++++++++++++++++++ROLE_SYSTEM_STATICTEXT name='Sat' ia2_hypertext='Sat'
++++++++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
++++++++++++++++IA2_ROLE_SECTION
<!--
@MAC-ALLOW:AXRole*
@WIN-ALLOW:ia2_hypertext=*
@DEFAULT-ACTION-ON:Show date picker
@WAIT-FOR:Today
-->
<!DOCTYPE html>
<html>
<body>
<input type="date" value="2008-09-01">
</body>
</html>
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<body> <body>
<input aria-label="@NO_CHILDREN_DUMP" type="date" value="2008-09-01"> <input type="date" value="2008-09-01">
</body> </body>
</html> </html>
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
namespace blink { namespace blink {
class WebWidgetClient; class WebWidgetClient;
class WebDocument;
class WebPagePopupClient : public WebWidgetClient { class WebPagePopupClient : public WebWidgetClient {
public: public:
...@@ -54,6 +55,11 @@ class WebPagePopup : public WebWidget { ...@@ -54,6 +55,11 @@ class WebPagePopup : public WebWidget {
BLINK_EXPORT static WebPagePopup* Create(WebPagePopupClient*); BLINK_EXPORT static WebPagePopup* Create(WebPagePopupClient*);
virtual WebPoint PositionRelativeToOwner() = 0; virtual WebPoint PositionRelativeToOwner() = 0;
// The popup's accessibility tree is connected to the main document's
// accessibility tree. Access to the popup document is needed to ensure the
// popup's layout is clean before serializing the combined tree.
virtual WebDocument GetDocument() = 0;
// Web tests require access to the client for a WebPagePopup in order // Web tests require access to the client for a WebPagePopup in order
// to synchronously composite. // to synchronously composite.
virtual WebPagePopupClient* GetClientForTesting() const = 0; virtual WebPagePopupClient* GetClientForTesting() const = 0;
......
...@@ -589,6 +589,10 @@ WebPoint WebPagePopupImpl::PositionRelativeToOwner() { ...@@ -589,6 +589,10 @@ WebPoint WebPagePopupImpl::PositionRelativeToOwner() {
window_rect.y - root_window_rect.y); window_rect.y - root_window_rect.y);
} }
WebDocument WebPagePopupImpl::GetDocument() {
return WebDocument(MainFrame().GetDocument());
}
WebPagePopupClient* WebPagePopupImpl::GetClientForTesting() const { WebPagePopupClient* WebPagePopupImpl::GetClientForTesting() const {
return web_page_popup_client_; return web_page_popup_client_;
} }
......
...@@ -97,6 +97,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup, ...@@ -97,6 +97,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
// WebPagePopup implementation. // WebPagePopup implementation.
WebPoint PositionRelativeToOwner() override; WebPoint PositionRelativeToOwner() override;
WebDocument GetDocument() override;
WebPagePopupClient* GetClientForTesting() const override; WebPagePopupClient* GetClientForTesting() const override;
// PagePopup implementation. // PagePopup implementation.
......
...@@ -169,6 +169,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { ...@@ -169,6 +169,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void AddInlineTextBoxChildren(bool force) override; void AddInlineTextBoxChildren(bool force) override;
void AddImageMapChildren() override; void AddImageMapChildren() override;
void AddHiddenChildren() override; void AddHiddenChildren() override;
void AddPopupChildren() override;
bool CanHaveChildren() const override; bool CanHaveChildren() const override;
// Properties of the object's owning document or page. // Properties of the object's owning document or page.
...@@ -219,7 +220,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { ...@@ -219,7 +220,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
AXSVGRoot* RemoteSVGRootElement() const; AXSVGRoot* RemoteSVGRootElement() const;
AXObject* RemoteSVGElementHitTest(const IntPoint&) const; AXObject* RemoteSVGElementHitTest(const IntPoint&) const;
void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const; void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
void AddPopupChildren();
void AddRemoteSVGChildren(); void AddRemoteSVGChildren();
void AddTableChildren(); void AddTableChildren();
void AddValidationMessageChild(); void AddValidationMessageChild();
......
...@@ -2335,6 +2335,7 @@ void AXNodeObject::AddChildren() { ...@@ -2335,6 +2335,7 @@ void AXNodeObject::AddChildren() {
} }
AddHiddenChildren(); AddHiddenChildren();
AddPopupChildren();
AddImageMapChildren(); AddImageMapChildren();
AddInlineTextBoxChildren(false); AddInlineTextBoxChildren(false);
AddAccessibleNodeChildren(); AddAccessibleNodeChildren();
......
...@@ -195,6 +195,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { ...@@ -195,6 +195,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
virtual void AddInlineTextBoxChildren(bool force) {} virtual void AddInlineTextBoxChildren(bool force) {}
virtual void AddImageMapChildren() {} virtual void AddImageMapChildren() {}
virtual void AddHiddenChildren() {} virtual void AddHiddenChildren() {}
virtual void AddPopupChildren() {}
bool CanHaveChildren() const override; bool CanHaveChildren() const override;
void AddChild(AXObject*); void AddChild(AXObject*);
......
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