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/pattern.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "content/browser/accessibility/browser_accessibility_manager.h"
15 #include "content/browser/renderer_host/render_widget_host_view_base.h"
16 #include "content/browser/web_contents/web_contents_impl.h"
17 #include "content/public/browser/web_contents.h"
21 const char kIndentSymbol
= '+';
22 const int kIndentSymbolCount
= 2;
23 const char* kSkipString
= "@NO_DUMP";
24 const char* kSkipChildren
= "@NO_CHILDREN_DUMP";
25 const char* kChildrenDictAttr
= "children";
28 AccessibilityTreeFormatter::AccessibilityTreeFormatter(
29 BrowserAccessibility
* root
)
36 AccessibilityTreeFormatter
* AccessibilityTreeFormatter::Create(
37 WebContents
* web_contents
) {
38 BrowserAccessibilityManager
* manager
=
39 static_cast<WebContentsImpl
*>(web_contents
)->
40 GetRootBrowserAccessibilityManager();
44 BrowserAccessibility
* root
= manager
->GetRoot();
45 return new AccessibilityTreeFormatter(root
);
49 AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
52 scoped_ptr
<base::DictionaryValue
>
53 AccessibilityTreeFormatter::BuildAccessibilityTree() {
54 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
55 RecursiveBuildAccessibilityTree(*root_
, dict
.get());
59 void AccessibilityTreeFormatter::FormatAccessibilityTree(
60 base::string16
* contents
) {
61 scoped_ptr
<base::DictionaryValue
> dict
= BuildAccessibilityTree();
62 RecursiveFormatAccessibilityTree(*(dict
.get()), contents
);
65 void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
66 const BrowserAccessibility
& node
, base::DictionaryValue
* dict
) {
67 AddProperties(node
, dict
);
69 base::ListValue
* children
= new base::ListValue
;
70 dict
->Set(kChildrenDictAttr
, children
);
72 for (size_t i
= 0; i
< node
.PlatformChildCount(); ++i
) {
73 BrowserAccessibility
* child_node
= node
.PlatformGetChild(i
);
74 base::DictionaryValue
* child_dict
= new base::DictionaryValue
;
75 children
->Append(child_dict
);
76 RecursiveBuildAccessibilityTree(*child_node
, child_dict
);
80 void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
81 const base::DictionaryValue
& dict
, base::string16
* contents
, int depth
) {
82 base::string16 indent
= base::string16(depth
* kIndentSymbolCount
,
84 base::string16 line
= indent
+ ToString(dict
);
85 if (line
.find(base::ASCIIToUTF16(kSkipString
)) != base::string16::npos
)
88 *contents
+= line
+ base::ASCIIToUTF16("\n");
89 if (line
.find(base::ASCIIToUTF16(kSkipChildren
)) != base::string16::npos
)
92 const base::ListValue
* children
;
93 dict
.GetList(kChildrenDictAttr
, &children
);
94 const base::DictionaryValue
* child_dict
;
95 for (size_t i
= 0; i
< children
->GetSize(); i
++) {
96 children
->GetDictionary(i
, &child_dict
);
97 RecursiveFormatAccessibilityTree(*child_dict
, contents
, depth
+ 1);
101 #if !defined(OS_WIN) && \
102 !defined(OS_MACOSX) && \
103 !defined(OS_ANDROID) && \
104 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11))
105 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility
& node
,
106 base::DictionaryValue
* dict
) {
107 dict
->SetInteger("id", node
.GetId());
110 base::string16
AccessibilityTreeFormatter::ToString(
111 const base::DictionaryValue
& node
) {
113 node
.GetInteger("id", &id_value
);
114 return base::IntToString16(id_value
);
117 void AccessibilityTreeFormatter::Initialize() {}
120 const base::FilePath::StringType
121 AccessibilityTreeFormatter::GetActualFileSuffix() {
122 return base::FilePath::StringType();
126 const base::FilePath::StringType
127 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
128 return base::FilePath::StringType();
132 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
133 return std::string();
137 const std::string
AccessibilityTreeFormatter::GetAllowString() {
138 return std::string();
142 const std::string
AccessibilityTreeFormatter::GetDenyString() {
143 return std::string();
147 void AccessibilityTreeFormatter::SetFilters(
148 const std::vector
<Filter
>& filters
) {
153 bool AccessibilityTreeFormatter::MatchesFilters(
154 const std::vector
<Filter
>& filters
,
155 const base::string16
& text
,
156 bool default_result
) {
157 std::vector
<Filter
>::const_iterator iter
= filters
.begin();
158 bool allow
= default_result
;
159 for (iter
= filters
.begin(); iter
!= filters
.end(); ++iter
) {
160 if (base::MatchPattern(text
, iter
->match_str
)) {
161 if (iter
->type
== Filter::ALLOW_EMPTY
)
163 else if (iter
->type
== Filter::ALLOW
)
164 allow
= (!base::MatchPattern(text
, base::UTF8ToUTF16("*=''")));
172 bool AccessibilityTreeFormatter::MatchesFilters(
173 const base::string16
& text
, bool default_result
) const {
174 return MatchesFilters(filters_
, text
, default_result
);
177 base::string16
AccessibilityTreeFormatter::FormatCoordinates(
178 const char* name
, const char* x_name
, const char* y_name
,
179 const base::DictionaryValue
& value
) {
181 value
.GetInteger(x_name
, &x
);
182 value
.GetInteger(y_name
, &y
);
183 std::string
xy_str(base::StringPrintf("%s=(%d, %d)", name
, x
, y
));
185 return base::UTF8ToUTF16(xy_str
);
188 void AccessibilityTreeFormatter::WriteAttribute(
189 bool include_by_default
, const std::string
& attr
, base::string16
* line
) {
190 WriteAttribute(include_by_default
, base::UTF8ToUTF16(attr
), line
);
193 void AccessibilityTreeFormatter::WriteAttribute(
194 bool include_by_default
, const base::string16
& attr
, base::string16
* line
) {
197 if (!MatchesFilters(attr
, include_by_default
))
200 *line
+= base::ASCIIToUTF16(" ");
204 } // namespace content