1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/accessibility/accessibility_tree_formatter.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "content/browser/accessibility/browser_accessibility_manager.h"
14 #include "content/browser/renderer_host/render_widget_host_view_base.h"
15 #include "content/browser/web_contents/web_contents_impl.h"
16 #include "content/public/browser/web_contents.h"
20 const int kIndentSpaces
= 4;
21 const char* kSkipString
= "@NO_DUMP";
22 const char* kChildrenDictAttr
= "children";
25 AccessibilityTreeFormatter::AccessibilityTreeFormatter(
26 BrowserAccessibility
* root
)
32 AccessibilityTreeFormatter
* AccessibilityTreeFormatter::Create(
33 WebContents
* web_contents
) {
34 BrowserAccessibilityManager
* manager
=
35 static_cast<WebContentsImpl
*>(web_contents
)->
36 GetRootBrowserAccessibilityManager();
40 BrowserAccessibility
* root
= manager
->GetRoot();
41 return new AccessibilityTreeFormatter(root
);
45 AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
48 scoped_ptr
<base::DictionaryValue
>
49 AccessibilityTreeFormatter::BuildAccessibilityTree() {
50 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
51 RecursiveBuildAccessibilityTree(*root_
, dict
.get());
55 void AccessibilityTreeFormatter::FormatAccessibilityTree(
56 base::string16
* contents
) {
57 scoped_ptr
<base::DictionaryValue
> dict
= BuildAccessibilityTree();
58 RecursiveFormatAccessibilityTree(*(dict
.get()), contents
);
61 void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
62 const BrowserAccessibility
& node
, base::DictionaryValue
* dict
) {
63 AddProperties(node
, dict
);
65 base::ListValue
* children
= new base::ListValue
;
66 dict
->Set(kChildrenDictAttr
, children
);
68 for (size_t i
= 0; i
< node
.PlatformChildCount(); ++i
) {
69 BrowserAccessibility
* child_node
= node
.PlatformGetChild(i
);
70 base::DictionaryValue
* child_dict
= new base::DictionaryValue
;
71 children
->Append(child_dict
);
72 RecursiveBuildAccessibilityTree(*child_node
, child_dict
);
76 void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
77 const base::DictionaryValue
& dict
, base::string16
* contents
, int depth
) {
79 ToString(dict
, base::string16(depth
* kIndentSpaces
, ' '));
80 if (line
.find(base::ASCIIToUTF16(kSkipString
)) != base::string16::npos
)
84 const base::ListValue
* children
;
85 dict
.GetList(kChildrenDictAttr
, &children
);
86 const base::DictionaryValue
* child_dict
;
87 for (size_t i
= 0; i
< children
->GetSize(); i
++) {
88 children
->GetDictionary(i
, &child_dict
);
89 RecursiveFormatAccessibilityTree(*child_dict
, contents
, depth
+ 1);
93 #if (!defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_ANDROID))
94 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility
& node
,
95 base::DictionaryValue
* dict
) {
96 dict
->SetInteger("id", node
.GetId());
99 base::string16
AccessibilityTreeFormatter::ToString(
100 const base::DictionaryValue
& node
,
101 const base::string16
& indent
) {
103 node
.GetInteger("id", &id_value
);
104 return indent
+ base::IntToString16(id_value
) +
105 base::ASCIIToUTF16("\n");
108 void AccessibilityTreeFormatter::Initialize() {}
111 const base::FilePath::StringType
112 AccessibilityTreeFormatter::GetActualFileSuffix() {
113 return base::FilePath::StringType();
117 const base::FilePath::StringType
118 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
119 return base::FilePath::StringType();
123 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
124 return std::string();
128 const std::string
AccessibilityTreeFormatter::GetAllowString() {
129 return std::string();
133 const std::string
AccessibilityTreeFormatter::GetDenyString() {
134 return std::string();
138 void AccessibilityTreeFormatter::SetFilters(
139 const std::vector
<Filter
>& filters
) {
143 bool AccessibilityTreeFormatter::MatchesFilters(
144 const base::string16
& text
, bool default_result
) const {
145 std::vector
<Filter
>::const_iterator iter
= filters_
.begin();
146 bool allow
= default_result
;
147 for (iter
= filters_
.begin(); iter
!= filters_
.end(); ++iter
) {
148 if (MatchPattern(text
, iter
->match_str
)) {
149 if (iter
->type
== Filter::ALLOW_EMPTY
)
151 else if (iter
->type
== Filter::ALLOW
)
152 allow
= (!MatchPattern(text
, base::UTF8ToUTF16("*=''")));
160 base::string16
AccessibilityTreeFormatter::FormatCoordinates(
161 const char* name
, const char* x_name
, const char* y_name
,
162 const base::DictionaryValue
& value
) {
164 value
.GetInteger(x_name
, &x
);
165 value
.GetInteger(y_name
, &y
);
166 std::string
xy_str(base::StringPrintf("%s=(%d, %d)", name
, x
, y
));
168 return base::UTF8ToUTF16(xy_str
);
171 void AccessibilityTreeFormatter::WriteAttribute(
172 bool include_by_default
, const std::string
& attr
, base::string16
* line
) {
173 WriteAttribute(include_by_default
, base::UTF8ToUTF16(attr
), line
);
176 void AccessibilityTreeFormatter::WriteAttribute(
177 bool include_by_default
, const base::string16
& attr
, base::string16
* line
) {
180 if (!MatchesFilters(attr
, include_by_default
))
183 *line
+= base::ASCIIToUTF16(" ");
187 } // namespace content