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/public/browser/render_view_host.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 RenderViewHost
* rvh
) {
34 RenderWidgetHostViewBase
* host_view
= static_cast<RenderWidgetHostViewBase
*>(
35 WebContents::FromRenderViewHost(rvh
)->GetRenderWidgetHostView());
37 BrowserAccessibilityManager
* manager
=
38 host_view
->GetBrowserAccessibilityManager();
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
.InternalGetChild(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
) {
81 ToString(dict
, base::string16(depth
* kIndentSpaces
, ' '));
82 if (line
.find(base::ASCIIToUTF16(kSkipString
)) != base::string16::npos
)
86 const base::ListValue
* children
;
87 dict
.GetList(kChildrenDictAttr
, &children
);
88 const base::DictionaryValue
* child_dict
;
89 for (size_t i
= 0; i
< children
->GetSize(); i
++) {
90 children
->GetDictionary(i
, &child_dict
);
91 RecursiveFormatAccessibilityTree(*child_dict
, contents
, depth
+ 1);
95 #if (!defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_ANDROID))
96 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility
& node
,
97 base::DictionaryValue
* dict
) {
98 dict
->SetInteger("id", node
.GetId());
101 base::string16
AccessibilityTreeFormatter::ToString(
102 const base::DictionaryValue
& node
,
103 const base::string16
& indent
) {
105 node
.GetInteger("id", &id_value
);
106 return indent
+ base::IntToString16(id_value
) +
107 base::ASCIIToUTF16("\n");
110 void AccessibilityTreeFormatter::Initialize() {}
113 const base::FilePath::StringType
114 AccessibilityTreeFormatter::GetActualFileSuffix() {
115 return base::FilePath::StringType();
119 const base::FilePath::StringType
120 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
121 return base::FilePath::StringType();
125 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
126 return std::string();
130 const std::string
AccessibilityTreeFormatter::GetAllowString() {
131 return std::string();
135 const std::string
AccessibilityTreeFormatter::GetDenyString() {
136 return std::string();
140 void AccessibilityTreeFormatter::SetFilters(
141 const std::vector
<Filter
>& filters
) {
145 bool AccessibilityTreeFormatter::MatchesFilters(
146 const base::string16
& text
, bool default_result
) const {
147 std::vector
<Filter
>::const_iterator iter
= filters_
.begin();
148 bool allow
= default_result
;
149 for (iter
= filters_
.begin(); iter
!= filters_
.end(); ++iter
) {
150 if (MatchPattern(text
, iter
->match_str
)) {
151 if (iter
->type
== Filter::ALLOW_EMPTY
)
153 else if (iter
->type
== Filter::ALLOW
)
154 allow
= (!MatchPattern(text
, base::UTF8ToUTF16("*=''")));
162 base::string16
AccessibilityTreeFormatter::FormatCoordinates(
163 const char* name
, const char* x_name
, const char* y_name
,
164 const base::DictionaryValue
& value
) {
166 value
.GetInteger(x_name
, &x
);
167 value
.GetInteger(y_name
, &y
);
168 std::string
xy_str(base::StringPrintf("%s=(%d, %d)", name
, x
, y
));
170 return base::UTF8ToUTF16(xy_str
);
173 void AccessibilityTreeFormatter::WriteAttribute(
174 bool include_by_default
, const std::string
& attr
, base::string16
* line
) {
175 WriteAttribute(include_by_default
, base::UTF8ToUTF16(attr
), line
);
178 void AccessibilityTreeFormatter::WriteAttribute(
179 bool include_by_default
, const base::string16
& attr
, base::string16
* line
) {
182 if (!MatchesFilters(attr
, include_by_default
))
185 *line
+= base::ASCIIToUTF16(" ");
189 } // namespace content