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* kChildrenDictAttr
= "children";
26 AccessibilityTreeFormatter::AccessibilityTreeFormatter(
27 BrowserAccessibility
* root
)
34 AccessibilityTreeFormatter
* AccessibilityTreeFormatter::Create(
35 WebContents
* web_contents
) {
36 BrowserAccessibilityManager
* manager
=
37 static_cast<WebContentsImpl
*>(web_contents
)->
38 GetRootBrowserAccessibilityManager();
42 BrowserAccessibility
* root
= manager
->GetRoot();
43 return new AccessibilityTreeFormatter(root
);
47 AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
50 scoped_ptr
<base::DictionaryValue
>
51 AccessibilityTreeFormatter::BuildAccessibilityTree() {
52 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
53 RecursiveBuildAccessibilityTree(*root_
, dict
.get());
57 void AccessibilityTreeFormatter::FormatAccessibilityTree(
58 base::string16
* contents
) {
59 scoped_ptr
<base::DictionaryValue
> dict
= BuildAccessibilityTree();
60 RecursiveFormatAccessibilityTree(*(dict
.get()), contents
);
63 void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
64 const BrowserAccessibility
& node
, base::DictionaryValue
* dict
) {
65 AddProperties(node
, dict
);
67 base::ListValue
* children
= new base::ListValue
;
68 dict
->Set(kChildrenDictAttr
, children
);
70 for (size_t i
= 0; i
< node
.PlatformChildCount(); ++i
) {
71 BrowserAccessibility
* child_node
= node
.PlatformGetChild(i
);
72 base::DictionaryValue
* child_dict
= new base::DictionaryValue
;
73 children
->Append(child_dict
);
74 RecursiveBuildAccessibilityTree(*child_node
, child_dict
);
78 void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
79 const base::DictionaryValue
& dict
, base::string16
* contents
, int depth
) {
80 base::string16 indent
= base::string16(depth
* kIndentSymbolCount
,
82 base::string16 line
= indent
+ ToString(dict
);
83 if (line
.find(base::ASCIIToUTF16(kSkipString
)) != base::string16::npos
)
86 *contents
+= line
+ base::ASCIIToUTF16("\n");
87 const base::ListValue
* children
;
88 dict
.GetList(kChildrenDictAttr
, &children
);
89 const base::DictionaryValue
* child_dict
;
90 for (size_t i
= 0; i
< children
->GetSize(); i
++) {
91 children
->GetDictionary(i
, &child_dict
);
92 RecursiveFormatAccessibilityTree(*child_dict
, contents
, depth
+ 1);
96 #if (!defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_ANDROID))
97 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility
& node
,
98 base::DictionaryValue
* dict
) {
99 dict
->SetInteger("id", node
.GetId());
102 base::string16
AccessibilityTreeFormatter::ToString(
103 const base::DictionaryValue
& node
) {
105 node
.GetInteger("id", &id_value
);
106 return base::IntToString16(id_value
);
109 void AccessibilityTreeFormatter::Initialize() {}
112 const base::FilePath::StringType
113 AccessibilityTreeFormatter::GetActualFileSuffix() {
114 return base::FilePath::StringType();
118 const base::FilePath::StringType
119 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
120 return base::FilePath::StringType();
124 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
125 return std::string();
129 const std::string
AccessibilityTreeFormatter::GetAllowString() {
130 return std::string();
134 const std::string
AccessibilityTreeFormatter::GetDenyString() {
135 return std::string();
139 void AccessibilityTreeFormatter::SetFilters(
140 const std::vector
<Filter
>& filters
) {
145 bool AccessibilityTreeFormatter::MatchesFilters(
146 const std::vector
<Filter
>& filters
,
147 const base::string16
& text
,
148 bool default_result
) {
149 std::vector
<Filter
>::const_iterator iter
= filters
.begin();
150 bool allow
= default_result
;
151 for (iter
= filters
.begin(); iter
!= filters
.end(); ++iter
) {
152 if (MatchPattern(text
, iter
->match_str
)) {
153 if (iter
->type
== Filter::ALLOW_EMPTY
)
155 else if (iter
->type
== Filter::ALLOW
)
156 allow
= (!MatchPattern(text
, base::UTF8ToUTF16("*=''")));
164 bool AccessibilityTreeFormatter::MatchesFilters(
165 const base::string16
& text
, bool default_result
) const {
166 return MatchesFilters(filters_
, text
, default_result
);
169 base::string16
AccessibilityTreeFormatter::FormatCoordinates(
170 const char* name
, const char* x_name
, const char* y_name
,
171 const base::DictionaryValue
& value
) {
173 value
.GetInteger(x_name
, &x
);
174 value
.GetInteger(y_name
, &y
);
175 std::string
xy_str(base::StringPrintf("%s=(%d, %d)", name
, x
, y
));
177 return base::UTF8ToUTF16(xy_str
);
180 void AccessibilityTreeFormatter::WriteAttribute(
181 bool include_by_default
, const std::string
& attr
, base::string16
* line
) {
182 WriteAttribute(include_by_default
, base::UTF8ToUTF16(attr
), line
);
185 void AccessibilityTreeFormatter::WriteAttribute(
186 bool include_by_default
, const base::string16
& attr
, base::string16
* line
) {
189 if (!MatchesFilters(attr
, include_by_default
))
192 *line
+= base::ASCIIToUTF16(" ");
196 } // namespace content