OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/accessibility/browser_accessibility.h" | 5 #include "content/browser/accessibility/browser_accessibility.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 renderer_id_(0), | 37 renderer_id_(0), |
38 role_(0), | 38 role_(0), |
39 state_(0), | 39 state_(0), |
40 instance_active_(false) { | 40 instance_active_(false) { |
41 } | 41 } |
42 | 42 |
43 BrowserAccessibility::~BrowserAccessibility() { | 43 BrowserAccessibility::~BrowserAccessibility() { |
44 } | 44 } |
45 | 45 |
46 bool BrowserAccessibility::PlatformIsLeaf() const { | 46 bool BrowserAccessibility::PlatformIsLeaf() const { |
47 return role_ == WebKit::WebAXRoleStaticText || child_count() == 0; | 47 return role_ == blink::WebAXRoleStaticText || child_count() == 0; |
48 } | 48 } |
49 | 49 |
50 uint32 BrowserAccessibility::PlatformChildCount() const { | 50 uint32 BrowserAccessibility::PlatformChildCount() const { |
51 return PlatformIsLeaf() ? 0 : children_.size(); | 51 return PlatformIsLeaf() ? 0 : children_.size(); |
52 } | 52 } |
53 | 53 |
54 void BrowserAccessibility::DetachTree( | 54 void BrowserAccessibility::DetachTree( |
55 std::vector<BrowserAccessibility*>* nodes) { | 55 std::vector<BrowserAccessibility*>* nodes) { |
56 nodes->push_back(this); | 56 nodes->push_back(this); |
57 for (size_t i = 0; i < children_.size(); ++i) | 57 for (size_t i = 0; i < children_.size(); ++i) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 144 } |
145 | 145 |
146 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { | 146 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { |
147 gfx::Rect bounds = location_; | 147 gfx::Rect bounds = location_; |
148 | 148 |
149 // Walk up the parent chain. Every time we encounter a Web Area, offset | 149 // Walk up the parent chain. Every time we encounter a Web Area, offset |
150 // based on the scroll bars and then offset based on the origin of that | 150 // based on the scroll bars and then offset based on the origin of that |
151 // nested web area. | 151 // nested web area. |
152 BrowserAccessibility* parent = parent_; | 152 BrowserAccessibility* parent = parent_; |
153 bool need_to_offset_web_area = | 153 bool need_to_offset_web_area = |
154 (role_ == WebKit::WebAXRoleWebArea || | 154 (role_ == blink::WebAXRoleWebArea || |
155 role_ == WebKit::WebAXRoleRootWebArea); | 155 role_ == blink::WebAXRoleRootWebArea); |
156 while (parent) { | 156 while (parent) { |
157 if (need_to_offset_web_area && | 157 if (need_to_offset_web_area && |
158 parent->location().width() > 0 && | 158 parent->location().width() > 0 && |
159 parent->location().height() > 0) { | 159 parent->location().height() > 0) { |
160 bounds.Offset(parent->location().x(), parent->location().y()); | 160 bounds.Offset(parent->location().x(), parent->location().y()); |
161 need_to_offset_web_area = false; | 161 need_to_offset_web_area = false; |
162 } | 162 } |
163 | 163 |
164 // On some platforms, we don't want to take the root scroll offsets | 164 // On some platforms, we don't want to take the root scroll offsets |
165 // into account. | 165 // into account. |
166 if (parent->role() == WebKit::WebAXRoleRootWebArea && | 166 if (parent->role() == blink::WebAXRoleRootWebArea && |
167 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { | 167 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { |
168 break; | 168 break; |
169 } | 169 } |
170 | 170 |
171 if (parent->role() == WebKit::WebAXRoleWebArea || | 171 if (parent->role() == blink::WebAXRoleWebArea || |
172 parent->role() == WebKit::WebAXRoleRootWebArea) { | 172 parent->role() == blink::WebAXRoleRootWebArea) { |
173 int sx = 0; | 173 int sx = 0; |
174 int sy = 0; | 174 int sy = 0; |
175 if (parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X, &sx) && | 175 if (parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X, &sx) && |
176 parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y, &sy)) { | 176 parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y, &sy)) { |
177 bounds.Offset(-sx, -sy); | 177 bounds.Offset(-sx, -sy); |
178 } | 178 } |
179 need_to_offset_web_area = true; | 179 need_to_offset_web_area = true; |
180 } | 180 } |
181 parent = parent->parent(); | 181 parent = parent->parent(); |
182 } | 182 } |
183 | 183 |
184 return bounds; | 184 return bounds; |
185 } | 185 } |
186 | 186 |
187 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { | 187 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { |
188 gfx::Rect bounds = GetLocalBoundsRect(); | 188 gfx::Rect bounds = GetLocalBoundsRect(); |
189 | 189 |
190 // Adjust the bounds by the top left corner of the containing view's bounds | 190 // Adjust the bounds by the top left corner of the containing view's bounds |
191 // in screen coordinates. | 191 // in screen coordinates. |
192 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 192 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
193 | 193 |
194 return bounds; | 194 return bounds; |
195 } | 195 } |
196 | 196 |
197 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) | 197 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) |
198 const { | 198 const { |
199 DCHECK_EQ(role_, WebKit::WebAXRoleStaticText); | 199 DCHECK_EQ(role_, blink::WebAXRoleStaticText); |
200 int end = start + len; | 200 int end = start + len; |
201 int child_start = 0; | 201 int child_start = 0; |
202 int child_end = 0; | 202 int child_end = 0; |
203 | 203 |
204 gfx::Rect bounds; | 204 gfx::Rect bounds; |
205 for (size_t i = 0; i < children_.size() && child_end < start + len; ++i) { | 205 for (size_t i = 0; i < children_.size() && child_end < start + len; ++i) { |
206 BrowserAccessibility* child = children_[i]; | 206 BrowserAccessibility* child = children_[i]; |
207 DCHECK_EQ(child->role(), WebKit::WebAXRoleInlineTextBox); | 207 DCHECK_EQ(child->role(), blink::WebAXRoleInlineTextBox); |
208 std::string child_text; | 208 std::string child_text; |
209 child->GetStringAttribute(AccessibilityNodeData::ATTR_VALUE, &child_text); | 209 child->GetStringAttribute(AccessibilityNodeData::ATTR_VALUE, &child_text); |
210 int child_len = static_cast<int>(child_text.size()); | 210 int child_len = static_cast<int>(child_text.size()); |
211 child_start = child_end; | 211 child_start = child_end; |
212 child_end += child_len; | 212 child_end += child_len; |
213 | 213 |
214 if (child_end < start) | 214 if (child_end < start) |
215 continue; | 215 continue; |
216 | 216 |
217 int overlap_start = std::max(start, child_start); | 217 int overlap_start = std::max(start, child_start); |
218 int overlap_end = std::min(end, child_end); | 218 int overlap_end = std::min(end, child_end); |
219 | 219 |
220 int local_start = overlap_start - child_start; | 220 int local_start = overlap_start - child_start; |
221 int local_end = overlap_end - child_start; | 221 int local_end = overlap_end - child_start; |
222 | 222 |
223 gfx::Rect child_rect = child->location(); | 223 gfx::Rect child_rect = child->location(); |
224 int text_direction = child->GetIntAttribute( | 224 int text_direction = child->GetIntAttribute( |
225 AccessibilityNodeData::ATTR_TEXT_DIRECTION); | 225 AccessibilityNodeData::ATTR_TEXT_DIRECTION); |
226 const std::vector<int32>& character_offsets = child->GetIntListAttribute( | 226 const std::vector<int32>& character_offsets = child->GetIntListAttribute( |
227 AccessibilityNodeData::ATTR_CHARACTER_OFFSETS); | 227 AccessibilityNodeData::ATTR_CHARACTER_OFFSETS); |
228 int start_pixel_offset = | 228 int start_pixel_offset = |
229 local_start > 0 ? character_offsets[local_start - 1] : 0; | 229 local_start > 0 ? character_offsets[local_start - 1] : 0; |
230 int end_pixel_offset = | 230 int end_pixel_offset = |
231 local_end > 0 ? character_offsets[local_end - 1] : 0; | 231 local_end > 0 ? character_offsets[local_end - 1] : 0; |
232 | 232 |
233 gfx::Rect child_overlap_rect; | 233 gfx::Rect child_overlap_rect; |
234 switch (text_direction) { | 234 switch (text_direction) { |
235 case WebKit::WebAXTextDirectionLR: { | 235 case blink::WebAXTextDirectionLR: { |
236 int left = child_rect.x() + start_pixel_offset; | 236 int left = child_rect.x() + start_pixel_offset; |
237 int right = child_rect.x() + end_pixel_offset; | 237 int right = child_rect.x() + end_pixel_offset; |
238 child_overlap_rect = gfx::Rect(left, child_rect.y(), | 238 child_overlap_rect = gfx::Rect(left, child_rect.y(), |
239 right - left, child_rect.height()); | 239 right - left, child_rect.height()); |
240 break; | 240 break; |
241 } | 241 } |
242 case WebKit::WebAXTextDirectionRL: { | 242 case blink::WebAXTextDirectionRL: { |
243 int right = child_rect.right() - start_pixel_offset; | 243 int right = child_rect.right() - start_pixel_offset; |
244 int left = child_rect.right() - end_pixel_offset; | 244 int left = child_rect.right() - end_pixel_offset; |
245 child_overlap_rect = gfx::Rect(left, child_rect.y(), | 245 child_overlap_rect = gfx::Rect(left, child_rect.y(), |
246 right - left, child_rect.height()); | 246 right - left, child_rect.height()); |
247 break; | 247 break; |
248 } | 248 } |
249 case WebKit::WebAXTextDirectionTB: { | 249 case blink::WebAXTextDirectionTB: { |
250 int top = child_rect.y() + start_pixel_offset; | 250 int top = child_rect.y() + start_pixel_offset; |
251 int bottom = child_rect.y() + end_pixel_offset; | 251 int bottom = child_rect.y() + end_pixel_offset; |
252 child_overlap_rect = gfx::Rect(child_rect.x(), top, | 252 child_overlap_rect = gfx::Rect(child_rect.x(), top, |
253 child_rect.width(), bottom - top); | 253 child_rect.width(), bottom - top); |
254 break; | 254 break; |
255 } | 255 } |
256 case WebKit::WebAXTextDirectionBT: { | 256 case blink::WebAXTextDirectionBT: { |
257 int bottom = child_rect.bottom() - start_pixel_offset; | 257 int bottom = child_rect.bottom() - start_pixel_offset; |
258 int top = child_rect.bottom() - end_pixel_offset; | 258 int top = child_rect.bottom() - end_pixel_offset; |
259 child_overlap_rect = gfx::Rect(child_rect.x(), top, | 259 child_overlap_rect = gfx::Rect(child_rect.x(), top, |
260 child_rect.width(), bottom - top); | 260 child_rect.width(), bottom - top); |
261 break; | 261 break; |
262 } | 262 } |
263 default: | 263 default: |
264 NOTREACHED(); | 264 NOTREACHED(); |
265 } | 265 } |
266 | 266 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 (*iter)->Destroy(); | 303 (*iter)->Destroy(); |
304 } | 304 } |
305 children_.clear(); | 305 children_.clear(); |
306 | 306 |
307 // Allow the object to fire a TextRemoved notification. | 307 // Allow the object to fire a TextRemoved notification. |
308 name_.clear(); | 308 name_.clear(); |
309 value_.clear(); | 309 value_.clear(); |
310 PostInitialize(); | 310 PostInitialize(); |
311 | 311 |
312 manager_->NotifyAccessibilityEvent( | 312 manager_->NotifyAccessibilityEvent( |
313 WebKit::WebAXEventHide, this); | 313 blink::WebAXEventHide, this); |
314 | 314 |
315 instance_active_ = false; | 315 instance_active_ = false; |
316 manager_->RemoveNode(this); | 316 manager_->RemoveNode(this); |
317 NativeReleaseReference(); | 317 NativeReleaseReference(); |
318 } | 318 } |
319 | 319 |
320 void BrowserAccessibility::NativeReleaseReference() { | 320 void BrowserAccessibility::NativeReleaseReference() { |
321 delete this; | 321 delete this; |
322 } | 322 } |
323 | 323 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 | 548 |
549 if (EqualsASCII(value, "true")) | 549 if (EqualsASCII(value, "true")) |
550 return true; | 550 return true; |
551 | 551 |
552 if (EqualsASCII(value, "mixed")) | 552 if (EqualsASCII(value, "mixed")) |
553 *is_mixed = true; | 553 *is_mixed = true; |
554 | 554 |
555 return false; // Not set | 555 return false; // Not set |
556 } | 556 } |
557 | 557 |
558 bool BrowserAccessibility::HasState(WebKit::WebAXState state_enum) const { | 558 bool BrowserAccessibility::HasState(blink::WebAXState state_enum) const { |
559 return (state_ >> state_enum) & 1; | 559 return (state_ >> state_enum) & 1; |
560 } | 560 } |
561 | 561 |
562 bool BrowserAccessibility::IsEditableText() const { | 562 bool BrowserAccessibility::IsEditableText() const { |
563 // These roles don't have readonly set, but they're not editable text. | 563 // These roles don't have readonly set, but they're not editable text. |
564 if (role_ == WebKit::WebAXRoleScrollArea || | 564 if (role_ == blink::WebAXRoleScrollArea || |
565 role_ == WebKit::WebAXRoleColumn || | 565 role_ == blink::WebAXRoleColumn || |
566 role_ == WebKit::WebAXRoleTableHeaderContainer) { | 566 role_ == blink::WebAXRoleTableHeaderContainer) { |
567 return false; | 567 return false; |
568 } | 568 } |
569 | 569 |
570 // Note: WebAXStateReadonly being false means it's either a text control, | 570 // Note: WebAXStateReadonly being false means it's either a text control, |
571 // or contenteditable. We also check for editable text roles to cover | 571 // or contenteditable. We also check for editable text roles to cover |
572 // another element that has role=textbox set on it. | 572 // another element that has role=textbox set on it. |
573 return (!HasState(WebKit::WebAXStateReadonly) || | 573 return (!HasState(blink::WebAXStateReadonly) || |
574 role_ == WebKit::WebAXRoleTextField || | 574 role_ == blink::WebAXRoleTextField || |
575 role_ == WebKit::WebAXRoleTextArea); | 575 role_ == blink::WebAXRoleTextArea); |
576 } | 576 } |
577 | 577 |
578 std::string BrowserAccessibility::GetTextRecursive() const { | 578 std::string BrowserAccessibility::GetTextRecursive() const { |
579 if (!name_.empty()) { | 579 if (!name_.empty()) { |
580 return name_; | 580 return name_; |
581 } | 581 } |
582 | 582 |
583 std::string result; | 583 std::string result; |
584 for (size_t i = 0; i < children_.size(); ++i) | 584 for (size_t i = 0; i < children_.size(); ++i) |
585 result += children_[i]->GetTextRecursive(); | 585 result += children_[i]->GetTextRecursive(); |
586 return result; | 586 return result; |
587 } | 587 } |
588 | 588 |
589 } // namespace content | 589 } // namespace content |
OLD | NEW |