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 char kIndentSymbol
= '+';
21 const int kIndentSymbolCount
= 2;
22 const char* kSkipString
= "@NO_DUMP";
23 const char* kSkipChildren
= "@NO_CHILDREN_DUMP";
24 const char* kChildrenDictAttr
= "children";
27 AccessibilityTreeFormatter::AccessibilityTreeFormatter(
28 BrowserAccessibility
* root
)
35 AccessibilityTreeFormatter
* AccessibilityTreeFormatter::Create(
36 WebContents
* web_contents
) {
37 BrowserAccessibilityManager
* manager
=
38 static_cast<WebContentsImpl
*>(web_contents
)->
39 GetRootBrowserAccessibilityManager();
43 BrowserAccessibility
* root
= manager
->GetRoot();
44 return new AccessibilityTreeFormatter(root
);
48 AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
51 scoped_ptr
<base::DictionaryValue
>
52 AccessibilityTreeFormatter::BuildAccessibilityTree() {
53 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
54 RecursiveBuildAccessibilityTree(*root_
, dict
.get());
58 void AccessibilityTreeFormatter::FormatAccessibilityTree(
59 base::string16
* contents
) {
60 scoped_ptr
<base::DictionaryValue
> dict
= BuildAccessibilityTree();
61 RecursiveFormatAccessibilityTree(*(dict
.get()), contents
);
64 void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
65 const BrowserAccessibility
& node
, base::DictionaryValue
* dict
) {
66 AddProperties(node
, dict
);
68 base::ListValue
* children
= new base::ListValue
;
69 dict
->Set(kChildrenDictAttr
, children
);
71 for (size_t i
= 0; i
< node
.PlatformChildCount(); ++i
) {
72 BrowserAccessibility
* child_node
= node
.PlatformGetChild(i
);
73 base::DictionaryValue
* child_dict
= new base::DictionaryValue
;
74 children
->Append(child_dict
);
75 RecursiveBuildAccessibilityTree(*child_node
, child_dict
);
79 void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
80 const base::DictionaryValue
& dict
, base::string16
* contents
, int depth
) {
81 base::string16 indent
= base::string16(depth
* kIndentSymbolCount
,
83 base::string16 line
= indent
+ ToString(dict
);
84 if (line
.find(base::ASCIIToUTF16(kSkipString
)) != base::string16::npos
)
87 *contents
+= line
+ base::ASCIIToUTF16("\n");
88 if (line
.find(base::ASCIIToUTF16(kSkipChildren
)) != base::string16::npos
)
91 const base::ListValue
* children
;
92 dict
.GetList(kChildrenDictAttr
, &children
);
93 const base::DictionaryValue
* child_dict
;
94 for (size_t i
= 0; i
< children
->GetSize(); i
++) {
95 children
->GetDictionary(i
, &child_dict
);
96 RecursiveFormatAccessibilityTree(*child_dict
, contents
, depth
+ 1);
100 #if (!defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_ANDROID))
101 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility
& node
,
102 base::DictionaryValue
* dict
) {
103 dict
->SetInteger("id", node
.GetId());
106 base::string16
AccessibilityTreeFormatter::ToString(
107 const base::DictionaryValue
& node
) {
109 node
.GetInteger("id", &id_value
);
110 return base::IntToString16(id_value
);
113 void AccessibilityTreeFormatter::Initialize() {}
116 const base::FilePath::StringType
117 AccessibilityTreeFormatter::GetActualFileSuffix() {
118 return base::FilePath::StringType();
122 const base::FilePath::StringType
123 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
124 return base::FilePath::StringType();
128 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
129 return std::string();
133 const std::string
AccessibilityTreeFormatter::GetAllowString() {
134 return std::string();
138 const std::string
AccessibilityTreeFormatter::GetDenyString() {
139 return std::string();
143 void AccessibilityTreeFormatter::SetFilters(
144 const std::vector
<Filter
>& filters
) {
149 bool AccessibilityTreeFormatter::MatchesFilters(
150 const std::vector
<Filter
>& filters
,
151 const base::string16
& text
,
152 bool default_result
) {
153 std::vector
<Filter
>::const_iterator iter
= filters
.begin();
154 bool allow
= default_result
;
155 for (iter
= filters
.begin(); iter
!= filters
.end(); ++iter
) {
156 if (MatchPattern(text
, iter
->match_str
)) {
157 if (iter
->type
== Filter::ALLOW_EMPTY
)
159 else if (iter
->type
== Filter::ALLOW
)
160 allow
= (!MatchPattern(text
, base::UTF8ToUTF16("*=''")));
168 bool AccessibilityTreeFormatter::MatchesFilters(
169 const base::string16
& text
, bool default_result
) const {
170 return MatchesFilters(filters_
, text
, default_result
);
173 base::string16
AccessibilityTreeFormatter::FormatCoordinates(
174 const char* name
, const char* x_name
, const char* y_name
,
175 const base::DictionaryValue
& value
) {
177 value
.GetInteger(x_name
, &x
);
178 value
.GetInteger(y_name
, &y
);
179 std::string
xy_str(base::StringPrintf("%s=(%d, %d)", name
, x
, y
));
181 return base::UTF8ToUTF16(xy_str
);
184 void AccessibilityTreeFormatter::WriteAttribute(
185 bool include_by_default
, const std::string
& attr
, base::string16
* line
) {
186 WriteAttribute(include_by_default
, base::UTF8ToUTF16(attr
), line
);
189 void AccessibilityTreeFormatter::WriteAttribute(
190 bool include_by_default
, const base::string16
& attr
, base::string16
* line
) {
193 if (!MatchesFilters(attr
, include_by_default
))
196 *line
+= base::ASCIIToUTF16(" ");
200 } // namespace content