Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "content/browser/accessibility/browser_accessibility_manager.h" | 10 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 return NULL; | 126 return NULL; |
| 127 } | 127 } |
| 128 | 128 |
| 129 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() { | 129 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() { |
| 130 gfx::Rect bounds = location_; | 130 gfx::Rect bounds = location_; |
| 131 | 131 |
| 132 // Adjust top left position by the root document's scroll offset. | 132 // Adjust top left position by the root document's scroll offset. |
| 133 BrowserAccessibility* root = manager_->GetRoot(); | 133 BrowserAccessibility* root = manager_->GetRoot(); |
| 134 int scroll_x = 0; | 134 int scroll_x = 0; |
| 135 int scroll_y = 0; | 135 int scroll_y = 0; |
| 136 root->GetIntAttribute(WebAccessibility::ATTR_DOC_SCROLLX, &scroll_x); | 136 root->GetIntAttribute(WebAccessibility::ATTR_SCROLL_X, &scroll_x); |
| 137 root->GetIntAttribute(WebAccessibility::ATTR_DOC_SCROLLY, &scroll_y); | 137 root->GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y, &scroll_y); |
| 138 bounds.Offset(-scroll_x, -scroll_y); | 138 bounds.Offset(-scroll_x, -scroll_y); |
| 139 | 139 |
| 140 return bounds; | 140 return bounds; |
| 141 } | 141 } |
| 142 | 142 |
| 143 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() { | 143 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() { |
| 144 gfx::Rect bounds = GetLocalBoundsRect(); | 144 gfx::Rect bounds = GetLocalBoundsRect(); |
| 145 | 145 |
| 146 // Adjust the bounds by the top left corner of the containing view's bounds | 146 // Adjust the bounds by the top left corner of the containing view's bounds |
| 147 // in screen coordinates. | 147 // in screen coordinates. |
| 148 gfx::Point top_left = manager_->GetViewBounds().origin(); | 148 gfx::Point top_left = manager_->GetViewBounds().origin(); |
| 149 bounds.Offset(top_left); | 149 bounds.Offset(top_left); |
| 150 | 150 |
| 151 return bounds; | 151 return bounds; |
| 152 } | 152 } |
| 153 | 153 |
| 154 BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint( | 154 BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint( |
| 155 const gfx::Point& point) { | 155 const gfx::Point& point) { |
| 156 // Walk the children recursively looking for the BrowserAccessibility that | 156 // Walk the children recursively looking for the BrowserAccessibility that |
| 157 // most tightly encloses the specified point. | 157 // most tightly encloses the specified point. |
| 158 for (int i = children_.size() - 1; i >= 0; --i) { | 158 for (int i = children_.size() - 1; i >= 0; --i) { |
| 159 BrowserAccessibility* child = children_[i]; | 159 BrowserAccessibility* child = children_[i]; |
| 160 if (child->GetGlobalBoundsRect().Contains(point)) | 160 if (child->GetGlobalBoundsRect().Contains(point)) |
| 161 return child->BrowserAccessibilityForPoint(point); | 161 return child->BrowserAccessibilityForPoint(point); |
| 162 } | 162 } |
| 163 return this; | 163 return this; |
| 164 } | 164 } |
| 165 | 165 |
| 166 void BrowserAccessibility::ScrollToMakeVisible(const gfx::Rect& subfocus, | |
| 167 const gfx::Rect& focus, | |
| 168 const gfx::Rect& viewport) { | |
| 169 int scroll_x = 0; | |
| 170 int scroll_x_min = 0; | |
| 171 int scroll_x_max = 0; | |
| 172 int scroll_y = 0; | |
| 173 int scroll_y_min = 0; | |
| 174 int scroll_y_max = 0; | |
| 175 if (!GetIntAttribute(WebAccessibility::ATTR_SCROLL_X, &scroll_x) || | |
| 176 !GetIntAttribute(WebAccessibility::ATTR_SCROLL_X_MIN, &scroll_x_min) || | |
| 177 !GetIntAttribute(WebAccessibility::ATTR_SCROLL_X_MAX, &scroll_x_max) || | |
| 178 !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y, &scroll_y) || | |
| 179 !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y_MIN, &scroll_y_min) || | |
| 180 !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y_MAX, &scroll_y_max)) { | |
| 181 return; | |
| 182 } | |
| 183 | |
| 184 int viewport_left = std::max(viewport.x(), 0); | |
|
David Tseng
2011/12/02 00:02:17
Why isn't this std::max(viewport.x(), location_.x(
dmazzoni
2011/12/03 00:37:10
location_ is in global coordinates. We want things
| |
| 185 int viewport_top = std::max(viewport.y(), 0); | |
|
David Tseng
2011/12/02 00:02:17
ditto.
| |
| 186 int viewport_right = std::min(viewport.right(), location_.right()); | |
| 187 int viewport_bottom = std::min(viewport.bottom(), location_.bottom()); | |
| 188 | |
| 189 int new_scroll_x = ComputeBestScrollOffset( | |
|
David Tseng
2011/12/02 00:02:17
Did you try using Rect's as primitives to perform
dmazzoni
2011/12/03 00:37:10
Used Intersect, above. Good idea.
I don't think t
| |
| 190 scroll_x, | |
| 191 subfocus.x(), subfocus.right(), | |
| 192 focus.x(), focus.right(), | |
| 193 viewport_left, viewport_right); | |
| 194 new_scroll_x = std::max(new_scroll_x, scroll_x_min); | |
| 195 new_scroll_x = std::min(new_scroll_x, scroll_x_max); | |
| 196 | |
| 197 int new_scroll_y = ComputeBestScrollOffset( | |
| 198 scroll_y, | |
| 199 subfocus.y(), subfocus.bottom(), | |
| 200 focus.y(), focus.bottom(), | |
| 201 viewport_top, viewport_bottom); | |
| 202 new_scroll_y = std::max(new_scroll_y, scroll_y_min); | |
| 203 new_scroll_y = std::min(new_scroll_y, scroll_y_max); | |
| 204 | |
| 205 manager_->ChangeScrollPosition(*this, new_scroll_x, new_scroll_y); | |
| 206 } | |
| 207 | |
| 208 // static | |
| 209 int BrowserAccessibility::ComputeBestScrollOffset( | |
| 210 int current_scroll_offset, | |
| 211 int subfocus_min, int subfocus_max, | |
| 212 int focus_min, int focus_max, | |
| 213 int viewport_min, int viewport_max) { | |
| 214 int viewport_size = viewport_max - viewport_min; | |
| 215 | |
| 216 // If the focus size is larger than the viewport size, shrink it in the | |
| 217 // direction of subfocus. | |
| 218 if (focus_max - focus_min > viewport_size) { | |
| 219 // Subfocus must be within focus: | |
| 220 subfocus_min = std::max(subfocus_min, focus_min); | |
| 221 subfocus_max = std::min(subfocus_max, focus_max); | |
| 222 | |
| 223 // Subfocus must be no larger than the viewport size; favor top/left. | |
| 224 if (subfocus_max - subfocus_min > viewport_size) | |
| 225 subfocus_max = subfocus_min + viewport_size; | |
| 226 | |
| 227 if (subfocus_min + viewport_size > focus_max) { | |
| 228 focus_min = focus_max - viewport_size; | |
| 229 } else { | |
| 230 focus_min = subfocus_min; | |
| 231 focus_max = subfocus_min + viewport_size; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 // Exit now if the focus is already within the viewport. | |
| 236 if (focus_min - current_scroll_offset >= viewport_min && | |
| 237 focus_max - current_scroll_offset <= viewport_max) { | |
| 238 return current_scroll_offset; | |
| 239 } | |
| 240 | |
| 241 // Scroll left if we're too far to the right. | |
| 242 if (focus_max - current_scroll_offset > viewport_max) | |
| 243 return focus_max - viewport_max; | |
| 244 | |
| 245 // Scroll right if we're too far to the left. | |
| 246 if (focus_min - current_scroll_offset < viewport_min) | |
| 247 return focus_min - viewport_min; | |
| 248 | |
| 249 // This shouldn't happen. | |
| 250 NOTREACHED(); | |
| 251 return current_scroll_offset; | |
| 252 } | |
| 253 | |
| 166 void BrowserAccessibility::InternalAddReference() { | 254 void BrowserAccessibility::InternalAddReference() { |
| 167 ref_count_++; | 255 ref_count_++; |
| 168 } | 256 } |
| 169 | 257 |
| 170 void BrowserAccessibility::InternalReleaseReference(bool recursive) { | 258 void BrowserAccessibility::InternalReleaseReference(bool recursive) { |
| 171 DCHECK_GT(ref_count_, 0); | 259 DCHECK_GT(ref_count_, 0); |
| 172 | 260 |
| 173 if (recursive || ref_count_ == 1) { | 261 if (recursive || ref_count_ == 1) { |
| 174 for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin(); | 262 for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin(); |
| 175 iter != children_.end(); | 263 iter != children_.end(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 if (!name_.empty()) { | 354 if (!name_.empty()) { |
| 267 return name_; | 355 return name_; |
| 268 } | 356 } |
| 269 | 357 |
| 270 string16 result; | 358 string16 result; |
| 271 for (size_t i = 0; i < children_.size(); ++i) | 359 for (size_t i = 0; i < children_.size(); ++i) |
| 272 result += children_[i]->GetTextRecursive(); | 360 result += children_[i]->GetTextRecursive(); |
| 273 return result; | 361 return result; |
| 274 } | 362 } |
| 275 | 363 |
| OLD | NEW |