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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 return GetData().state; | 179 return GetData().state; |
180 } | 180 } |
181 | 181 |
182 const BrowserAccessibility::HtmlAttributes& | 182 const BrowserAccessibility::HtmlAttributes& |
183 BrowserAccessibility::GetHtmlAttributes() const { | 183 BrowserAccessibility::GetHtmlAttributes() const { |
184 return GetData().html_attributes; | 184 return GetData().html_attributes; |
185 } | 185 } |
186 | 186 |
187 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { | 187 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { |
188 gfx::Rect bounds = GetLocation(); | 188 gfx::Rect bounds = GetLocation(); |
189 | 189 return ElementBoundsToLocalBounds(bounds); |
190 // Walk up the parent chain. Every time we encounter a Web Area, offset | |
191 // based on the scroll bars and then offset based on the origin of that | |
192 // nested web area. | |
193 BrowserAccessibility* parent = GetParentForBoundsCalculation(); | |
194 bool need_to_offset_web_area = | |
195 (GetRole() == ui::AX_ROLE_WEB_AREA || | |
196 GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); | |
197 while (parent) { | |
198 if (need_to_offset_web_area && | |
199 parent->GetLocation().width() > 0 && | |
200 parent->GetLocation().height() > 0) { | |
201 bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); | |
202 need_to_offset_web_area = false; | |
203 } | |
204 | |
205 // On some platforms, we don't want to take the root scroll offsets | |
206 // into account. | |
207 if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && | |
208 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { | |
209 break; | |
210 } | |
211 | |
212 if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || | |
213 parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { | |
214 int sx = 0; | |
215 int sy = 0; | |
216 if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && | |
217 parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { | |
218 bounds.Offset(-sx, -sy); | |
219 } | |
220 need_to_offset_web_area = true; | |
221 } | |
222 parent = parent->GetParentForBoundsCalculation(); | |
223 } | |
224 | |
225 return bounds; | |
226 } | 190 } |
227 | 191 |
228 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { | 192 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { |
229 gfx::Rect bounds = GetLocalBoundsRect(); | 193 gfx::Rect bounds = GetLocalBoundsRect(); |
230 | 194 |
231 // Adjust the bounds by the top left corner of the containing view's bounds | 195 // Adjust the bounds by the top left corner of the containing view's bounds |
232 // in screen coordinates. | 196 // in screen coordinates. |
233 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 197 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
234 | 198 |
235 return bounds; | 199 return bounds; |
236 } | 200 } |
237 | 201 |
238 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) | 202 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) |
239 const { | 203 const { |
240 if (GetRole() != ui::AX_ROLE_STATIC_TEXT) { | 204 if (GetRole() != ui::AX_ROLE_STATIC_TEXT) { |
241 // Apply recursively to all static text descendants. For example, if | 205 // Apply recursively to all static text descendants. For example, if |
242 // you call it on a div with two text node children, it just calls | 206 // you call it on a div with two text node children, it just calls |
243 // GetLocalBoundsForRange on each of the two children (adjusting | 207 // GetLocalBoundsForRange on each of the two children (adjusting |
244 // |start| for each one) and unions the resulting rects. | 208 // |start| for each one) and unions the resulting rects. |
245 gfx::Rect bounds; | 209 gfx::Rect bounds; |
246 for (size_t i = 0; i < InternalChildCount(); ++i) { | 210 for (size_t i = 0; i < InternalChildCount(); ++i) { |
247 BrowserAccessibility* child = InternalGetChild(i); | 211 BrowserAccessibility* child = InternalGetChild(i); |
248 int child_len = child->GetStaticTextLenRecursive(); | 212 int child_len = child->GetStaticTextLenRecursive(); |
249 if (start < child_len && start + len > 0) { | 213 if (start < child_len && start + len > 0) { |
250 gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len); | 214 gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len); |
251 bounds.Union(child_rect); | 215 bounds.Union(child_rect); |
252 } | 216 } |
253 start -= child_len; | 217 start -= child_len; |
254 } | 218 } |
255 return bounds; | 219 return ElementBoundsToLocalBounds(bounds); |
256 } | 220 } |
257 | 221 |
258 int end = start + len; | 222 int end = start + len; |
259 int child_start = 0; | 223 int child_start = 0; |
260 int child_end = 0; | 224 int child_end = 0; |
261 | 225 |
262 gfx::Rect bounds; | 226 gfx::Rect bounds; |
263 for (size_t i = 0; i < InternalChildCount() && child_end < start + len; ++i) { | 227 for (size_t i = 0; i < InternalChildCount() && child_end < start + len; ++i) { |
264 BrowserAccessibility* child = InternalGetChild(i); | 228 BrowserAccessibility* child = InternalGetChild(i); |
265 DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX); | 229 DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 default: | 286 default: |
323 NOTREACHED(); | 287 NOTREACHED(); |
324 } | 288 } |
325 | 289 |
326 if (bounds.width() == 0 && bounds.height() == 0) | 290 if (bounds.width() == 0 && bounds.height() == 0) |
327 bounds = child_overlap_rect; | 291 bounds = child_overlap_rect; |
328 else | 292 else |
329 bounds.Union(child_overlap_rect); | 293 bounds.Union(child_overlap_rect); |
330 } | 294 } |
331 | 295 |
332 return bounds; | 296 return ElementBoundsToLocalBounds(bounds); |
333 } | 297 } |
334 | 298 |
335 gfx::Rect BrowserAccessibility::GetGlobalBoundsForRange(int start, int len) | 299 gfx::Rect BrowserAccessibility::GetGlobalBoundsForRange(int start, int len) |
336 const { | 300 const { |
337 gfx::Rect bounds = GetLocalBoundsForRange(start, len); | 301 gfx::Rect bounds = GetLocalBoundsForRange(start, len); |
338 | 302 |
339 // Adjust the bounds by the top left corner of the containing view's bounds | 303 // Adjust the bounds by the top left corner of the containing view's bounds |
340 // in screen coordinates. | 304 // in screen coordinates. |
341 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 305 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
342 | 306 |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 ui::AXNode* parent = node_->parent(); | 668 ui::AXNode* parent = node_->parent(); |
705 if (parent) | 669 if (parent) |
706 return manager_->GetFromAXNode(parent); | 670 return manager_->GetFromAXNode(parent); |
707 | 671 |
708 if (!manager_->delegate()) | 672 if (!manager_->delegate()) |
709 return NULL; | 673 return NULL; |
710 | 674 |
711 return manager_->delegate()->AccessibilityGetParentFrame(); | 675 return manager_->delegate()->AccessibilityGetParentFrame(); |
712 } | 676 } |
713 | 677 |
| 678 gfx::Rect BrowserAccessibility::ElementBoundsToLocalBounds(gfx::Rect bounds) |
| 679 const { |
| 680 // Walk up the parent chain. Every time we encounter a Web Area, offset |
| 681 // based on the scroll bars and then offset based on the origin of that |
| 682 // nested web area. |
| 683 BrowserAccessibility* parent = GetParentForBoundsCalculation(); |
| 684 bool need_to_offset_web_area = |
| 685 (GetRole() == ui::AX_ROLE_WEB_AREA || |
| 686 GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); |
| 687 while (parent) { |
| 688 if (need_to_offset_web_area && |
| 689 parent->GetLocation().width() > 0 && |
| 690 parent->GetLocation().height() > 0) { |
| 691 bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); |
| 692 need_to_offset_web_area = false; |
| 693 } |
| 694 |
| 695 // On some platforms, we don't want to take the root scroll offsets |
| 696 // into account. |
| 697 if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && |
| 698 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { |
| 699 break; |
| 700 } |
| 701 |
| 702 if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || |
| 703 parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { |
| 704 int sx = 0; |
| 705 int sy = 0; |
| 706 if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && |
| 707 parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { |
| 708 bounds.Offset(-sx, -sy); |
| 709 } |
| 710 need_to_offset_web_area = true; |
| 711 } |
| 712 parent = parent->GetParentForBoundsCalculation(); |
| 713 } |
| 714 |
| 715 return bounds; |
| 716 } |
| 717 |
714 } // namespace content | 718 } // namespace content |
OLD | NEW |