| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/browser_accessibility.h" | 5 #include "chrome/browser/browser_accessibility.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/browser_accessibility_manager.h" | 8 #include "chrome/browser/browser_accessibility_manager.h" |
| 9 | 9 |
| 10 using webkit_glue::WebAccessibility; | 10 using webkit_glue::WebAccessibility; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 LONG index_in_parent, | 29 LONG index_in_parent, |
| 30 const webkit_glue::WebAccessibility& src) { | 30 const webkit_glue::WebAccessibility& src) { |
| 31 manager_ = manager; | 31 manager_ = manager; |
| 32 parent_ = parent; | 32 parent_ = parent; |
| 33 child_id_ = child_id; | 33 child_id_ = child_id; |
| 34 index_in_parent_ = index_in_parent; | 34 index_in_parent_ = index_in_parent; |
| 35 | 35 |
| 36 renderer_id_ = src.id; | 36 renderer_id_ = src.id; |
| 37 name_ = src.name; | 37 name_ = src.name; |
| 38 value_ = src.value; | 38 value_ = src.value; |
| 39 action_ = src.action; | 39 attributes_ = src.attributes; |
| 40 description_ = src.description; | |
| 41 help_ = src.help; | |
| 42 shortcut_ = src.shortcut; | |
| 43 role_ = MSAARole(src.role); | |
| 44 state_ = MSAAState(src.state); | |
| 45 location_ = src.location; | 40 location_ = src.location; |
| 41 InitRoleAndState(src.role, src.state); |
| 42 |
| 43 // If this object doesn't have a name but it does have a description, |
| 44 // use the description as its name - because some screen readers only |
| 45 // announce the name. |
| 46 if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { |
| 47 GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); |
| 48 } |
| 46 | 49 |
| 47 instance_active_ = true; | 50 instance_active_ = true; |
| 48 | |
| 49 // Focused is a dynamic state, only one node will be focused at a time. | |
| 50 state_ &= ~STATE_SYSTEM_FOCUSED; | |
| 51 } | 51 } |
| 52 | 52 |
| 53 void BrowserAccessibility::AddChild(BrowserAccessibility* child) { | 53 void BrowserAccessibility::AddChild(BrowserAccessibility* child) { |
| 54 children_.push_back(child); | 54 children_.push_back(child); |
| 55 } | 55 } |
| 56 | 56 |
| 57 void BrowserAccessibility::InactivateTree() { | 57 void BrowserAccessibility::InactivateTree() { |
| 58 // Mark this object as inactive, so calls to all COM methods will return | 58 // Mark this object as inactive, so calls to all COM methods will return |
| 59 // failure. | 59 // failure. |
| 60 instance_active_ = false; | 60 instance_active_ = false; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 } | 99 } |
| 100 | 100 |
| 101 BrowserAccessibility* BrowserAccessibility::NewReference() { | 101 BrowserAccessibility* BrowserAccessibility::NewReference() { |
| 102 AddRef(); | 102 AddRef(); |
| 103 return this; | 103 return this; |
| 104 } | 104 } |
| 105 | 105 |
| 106 // | 106 // |
| 107 // IAccessible methods. | 107 // IAccessible methods. |
| 108 // | 108 // |
| 109 // Conventions: |
| 110 // * Always test for instance_active_ first and return E_FAIL if it's false. |
| 111 // * Always check for invalid arguments first, even if they're unused. |
| 112 // * Return S_FALSE if the only output is a string argument and it's empty. |
| 113 // |
| 109 | 114 |
| 110 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { | 115 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { |
| 111 if (!instance_active_) { | 116 if (!instance_active_) |
| 112 // Instance no longer active, fail gracefully. | |
| 113 return E_FAIL; | 117 return E_FAIL; |
| 114 } | |
| 115 | 118 |
| 116 return E_NOTIMPL; | 119 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 120 if (!target) |
| 121 return E_INVALIDARG; |
| 122 |
| 123 manager_->DoDefaultAction(*target); |
| 124 return S_OK; |
| 117 } | 125 } |
| 118 | 126 |
| 119 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, | 127 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, |
| 120 VARIANT* child) { | 128 VARIANT* child) { |
| 121 if (!instance_active_) { | 129 if (!instance_active_) |
| 122 // Instance no longer active, fail gracefully. | |
| 123 return E_FAIL; | 130 return E_FAIL; |
| 124 } | |
| 125 | 131 |
| 126 if (!child) | 132 if (!child) |
| 127 return E_INVALIDARG; | 133 return E_INVALIDARG; |
| 128 | 134 |
| 129 return E_NOTIMPL; | 135 return E_NOTIMPL; |
| 130 } | 136 } |
| 131 | 137 |
| 132 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, | 138 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, |
| 133 LONG* width, LONG* height, | 139 LONG* width, LONG* height, |
| 134 VARIANT var_id) { | 140 VARIANT var_id) { |
| 135 if (!instance_active_) { | 141 if (!instance_active_) |
| 136 // Instance no longer active, fail gracefully. | |
| 137 return E_FAIL; | 142 return E_FAIL; |
| 138 } | |
| 139 | 143 |
| 140 if (!x_left || !y_top || !width || !height) | 144 if (!x_left || !y_top || !width || !height) |
| 141 return E_INVALIDARG; | 145 return E_INVALIDARG; |
| 142 | 146 |
| 143 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 147 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 144 if (!target) | 148 if (!target) |
| 145 return E_INVALIDARG; | 149 return E_INVALIDARG; |
| 146 | 150 |
| 147 // Find the top left corner of the containing window in screen coords, and | 151 // Find the top left corner of the containing window in screen coords, and |
| 148 // adjust the output position by this amount. | 152 // adjust the output position by this amount. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 163 BrowserAccessibility* target = GetTargetFromChildID(start); | 167 BrowserAccessibility* target = GetTargetFromChildID(start); |
| 164 if (!target) | 168 if (!target) |
| 165 return E_INVALIDARG; | 169 return E_INVALIDARG; |
| 166 | 170 |
| 167 if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && | 171 if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && |
| 168 start.lVal != CHILDID_SELF) { | 172 start.lVal != CHILDID_SELF) { |
| 169 // MSAA states that navigating to first/last child can only be from self. | 173 // MSAA states that navigating to first/last child can only be from self. |
| 170 return E_INVALIDARG; | 174 return E_INVALIDARG; |
| 171 } | 175 } |
| 172 | 176 |
| 173 BrowserAccessibility* result; | 177 BrowserAccessibility* result = NULL; |
| 174 switch (nav_dir) { | 178 switch (nav_dir) { |
| 175 case NAVDIR_DOWN: | 179 case NAVDIR_DOWN: |
| 176 case NAVDIR_UP: | 180 case NAVDIR_UP: |
| 177 case NAVDIR_LEFT: | 181 case NAVDIR_LEFT: |
| 178 case NAVDIR_RIGHT: | 182 case NAVDIR_RIGHT: |
| 179 // These directions are not implemented, matching Mozilla and IE. | 183 // These directions are not implemented, matching Mozilla and IE. |
| 180 return E_NOTIMPL; | 184 return E_NOTIMPL; |
| 181 case NAVDIR_FIRSTCHILD: | 185 case NAVDIR_FIRSTCHILD: |
| 182 if (target->children_.size() > 0) | 186 if (target->children_.size() > 0) |
| 183 result = target->children_[0]; | 187 result = target->children_[0]; |
| 184 break; | 188 break; |
| 185 case NAVDIR_LASTCHILD: | 189 case NAVDIR_LASTCHILD: |
| 186 if (target->children_.size() > 0) | 190 if (target->children_.size() > 0) |
| 187 result = target->children_[target->children_.size() - 1]; | 191 result = target->children_[target->children_.size() - 1]; |
| 188 break; | 192 break; |
| 189 case NAVDIR_NEXT: | 193 case NAVDIR_NEXT: |
| 190 result = target->GetNextSibling(); | 194 result = target->GetNextSibling(); |
| 191 break; | 195 break; |
| 192 case NAVDIR_PREVIOUS: | 196 case NAVDIR_PREVIOUS: |
| 193 result = target->GetPreviousSibling(); | 197 result = target->GetPreviousSibling(); |
| 194 break; | 198 break; |
| 195 } | 199 } |
| 196 | 200 |
| 197 if (!result) { | 201 if (!result) { |
| 198 end->vt = VT_EMPTY; | 202 end->vt = VT_EMPTY; |
| 199 return S_FALSE; | 203 return S_FALSE; |
| 200 } | 204 } |
| 201 | 205 |
| 202 end->vt = VT_DISPATCH; | 206 end->vt = VT_DISPATCH; |
| 203 end->pdispVal = result->NewReference(); | 207 end->pdispVal = result->NewReference(); |
| 204 return S_OK; | 208 return S_OK; |
| 205 } | 209 } |
| 206 | 210 |
| 207 STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, | 211 STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, |
| 208 IDispatch** disp_child) { | 212 IDispatch** disp_child) { |
| 209 if (!instance_active_) { | 213 if (!instance_active_) |
| 210 // Instance no longer active, fail gracefully. | |
| 211 return E_FAIL; | 214 return E_FAIL; |
| 212 } | |
| 213 | 215 |
| 214 if (!disp_child) | 216 if (!disp_child) |
| 215 return E_INVALIDARG; | 217 return E_INVALIDARG; |
| 216 | 218 |
| 217 *disp_child = NULL; | 219 *disp_child = NULL; |
| 218 | 220 |
| 219 BrowserAccessibility* target = GetTargetFromChildID(var_child); | 221 BrowserAccessibility* target = GetTargetFromChildID(var_child); |
| 220 if (!target) | 222 if (!target) |
| 221 return E_INVALIDARG; | 223 return E_INVALIDARG; |
| 222 | 224 |
| 223 (*disp_child) = target->NewReference(); | 225 (*disp_child) = target->NewReference(); |
| 224 return S_OK; | 226 return S_OK; |
| 225 } | 227 } |
| 226 | 228 |
| 227 STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { | 229 STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { |
| 228 if (!instance_active_) { | 230 if (!instance_active_) |
| 229 // Instance no longer active, fail gracefully. | |
| 230 return E_FAIL; | 231 return E_FAIL; |
| 231 } | |
| 232 | 232 |
| 233 if (!child_count) | 233 if (!child_count) |
| 234 return E_INVALIDARG; | 234 return E_INVALIDARG; |
| 235 | 235 |
| 236 *child_count = children_.size(); | 236 *child_count = children_.size(); |
| 237 return S_OK; | 237 return S_OK; |
| 238 } | 238 } |
| 239 | 239 |
| 240 STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, | 240 STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, |
| 241 BSTR* def_action) { | 241 BSTR* def_action) { |
| 242 if (!instance_active_) { | 242 if (!instance_active_) |
| 243 // Instance no longer active, fail gracefully. | |
| 244 return E_FAIL; | 243 return E_FAIL; |
| 245 } | |
| 246 | 244 |
| 247 if (!def_action) | 245 if (!def_action) |
| 248 return E_INVALIDARG; | 246 return E_INVALIDARG; |
| 249 | 247 |
| 250 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 248 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 251 if (!target) | 249 if (!target) |
| 252 return E_INVALIDARG; | 250 return E_INVALIDARG; |
| 253 | 251 |
| 254 // Return false if the string is empty. | 252 string16 action; |
| 255 if (target->action_.size() == 0) | 253 if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &action)) |
| 256 return S_FALSE; | 254 return S_FALSE; |
| 257 | 255 |
| 258 *def_action = SysAllocString(target->action_.c_str()); | 256 if (action.empty()) |
| 257 return S_FALSE; |
| 258 |
| 259 *def_action = SysAllocString(action.c_str()); |
| 259 | 260 |
| 260 DCHECK(*def_action); | 261 DCHECK(*def_action); |
| 261 return S_OK; | 262 return S_OK; |
| 262 } | 263 } |
| 263 | 264 |
| 264 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, | 265 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, |
| 265 BSTR* desc) { | 266 BSTR* desc) { |
| 266 if (!instance_active_) { | 267 if (!instance_active_) |
| 267 // Instance no longer active, fail gracefully. | |
| 268 return E_FAIL; | 268 return E_FAIL; |
| 269 } | |
| 270 | 269 |
| 271 if (!desc) | 270 if (!desc) |
| 272 return E_INVALIDARG; | 271 return E_INVALIDARG; |
| 273 | 272 |
| 274 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 273 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 275 if (!target) | 274 if (!target) |
| 276 return E_INVALIDARG; | 275 return E_INVALIDARG; |
| 277 | 276 |
| 278 // Return false if the string is empty. | 277 string16 description; |
| 279 if (target->description_.size() == 0) | 278 if (!target->GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) |
| 280 return S_FALSE; | 279 return S_FALSE; |
| 281 | 280 |
| 282 *desc = SysAllocString(target->description_.c_str()); | 281 if (description.empty()) |
| 282 return S_FALSE; |
| 283 |
| 284 *desc = SysAllocString(description.c_str()); |
| 283 | 285 |
| 284 DCHECK(*desc); | 286 DCHECK(*desc); |
| 285 return S_OK; | 287 return S_OK; |
| 286 } | 288 } |
| 287 | 289 |
| 288 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { | 290 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { |
| 289 if (!instance_active_) { | 291 if (!instance_active_) |
| 290 // Instance no longer active, fail gracefully. | |
| 291 return E_FAIL; | 292 return E_FAIL; |
| 292 } | |
| 293 | 293 |
| 294 if (!focus_child) | 294 if (!focus_child) |
| 295 return E_INVALIDARG; | 295 return E_INVALIDARG; |
| 296 | 296 |
| 297 BrowserAccessibility* focus = manager_->GetFocus(this); | 297 BrowserAccessibility* focus = manager_->GetFocus(this); |
| 298 if (focus == this) { | 298 if (focus == this) { |
| 299 focus_child->vt = VT_I4; | 299 focus_child->vt = VT_I4; |
| 300 focus_child->lVal = CHILDID_SELF; | 300 focus_child->lVal = CHILDID_SELF; |
| 301 } else if (focus == NULL) { | 301 } else if (focus == NULL) { |
| 302 focus_child->vt = VT_EMPTY; | 302 focus_child->vt = VT_EMPTY; |
| 303 } else { | 303 } else { |
| 304 focus_child->vt = VT_DISPATCH; | 304 focus_child->vt = VT_DISPATCH; |
| 305 focus_child->pdispVal = focus->NewReference(); | 305 focus_child->pdispVal = focus->NewReference(); |
| 306 } | 306 } |
| 307 | 307 |
| 308 return S_OK; | 308 return S_OK; |
| 309 } | 309 } |
| 310 | 310 |
| 311 STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { | 311 STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { |
| 312 if (!instance_active_) { | 312 if (!instance_active_) |
| 313 // Instance no longer active, fail gracefully. | |
| 314 return E_FAIL; | 313 return E_FAIL; |
| 315 } | |
| 316 | 314 |
| 317 if (!help) | 315 if (!help) |
| 318 return E_INVALIDARG; | 316 return E_INVALIDARG; |
| 319 | 317 |
| 320 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 318 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 321 if (!target) | 319 if (!target) |
| 322 return E_INVALIDARG; | 320 return E_INVALIDARG; |
| 323 | 321 |
| 324 // Return false if the string is empty. | 322 string16 help_str; |
| 325 if (target->help_.size() == 0) | 323 if (!target->GetAttribute(WebAccessibility::ATTR_HELP, &help_str)) |
| 326 return S_FALSE; | 324 return S_FALSE; |
| 327 | 325 |
| 328 *help = SysAllocString(target->help_.c_str()); | 326 if (help_str.empty()) |
| 327 return S_FALSE; |
| 328 |
| 329 *help = SysAllocString(help_str.c_str()); |
| 329 | 330 |
| 330 DCHECK(*help); | 331 DCHECK(*help); |
| 331 return S_OK; | 332 return S_OK; |
| 332 } | 333 } |
| 333 | 334 |
| 334 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, | 335 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, |
| 335 BSTR* acc_key) { | 336 BSTR* acc_key) { |
| 336 if (!instance_active_) { | 337 if (!instance_active_) |
| 337 // Instance no longer active, fail gracefully. | |
| 338 return E_FAIL; | 338 return E_FAIL; |
| 339 } | |
| 340 | 339 |
| 341 if (!acc_key) | 340 if (!acc_key) |
| 342 return E_INVALIDARG; | 341 return E_INVALIDARG; |
| 343 | 342 |
| 344 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 343 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 345 if (!target) | 344 if (!target) |
| 346 return E_INVALIDARG; | 345 return E_INVALIDARG; |
| 347 | 346 |
| 348 // Return false if the string is empty. | 347 string16 shortcut; |
| 349 if (target->shortcut_.size() == 0) | 348 if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &shortcut)) |
| 350 return S_FALSE; | 349 return S_FALSE; |
| 351 | 350 |
| 352 *acc_key = SysAllocString(target->shortcut_.c_str()); | 351 if (shortcut.empty()) |
| 352 return S_FALSE; |
| 353 |
| 354 *acc_key = SysAllocString(shortcut.c_str()); |
| 353 | 355 |
| 354 DCHECK(*acc_key); | 356 DCHECK(*acc_key); |
| 355 return S_OK; | 357 return S_OK; |
| 356 } | 358 } |
| 357 | 359 |
| 358 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { | 360 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { |
| 359 if (!instance_active_) { | 361 if (!instance_active_) |
| 360 // Instance no longer active, fail gracefully. | |
| 361 return E_FAIL; | 362 return E_FAIL; |
| 362 } | |
| 363 | 363 |
| 364 if (!name) | 364 if (!name) |
| 365 return E_INVALIDARG; | 365 return E_INVALIDARG; |
| 366 | 366 |
| 367 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 367 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 368 if (!target) | 368 if (!target) |
| 369 return E_INVALIDARG; | 369 return E_INVALIDARG; |
| 370 | 370 |
| 371 // Return false if the string is empty. | 371 if (target->name_.empty()) |
| 372 if (target->name_.size() == 0) | |
| 373 return S_FALSE; | 372 return S_FALSE; |
| 374 | 373 |
| 375 *name = SysAllocString(target->name_.c_str()); | 374 *name = SysAllocString(target->name_.c_str()); |
| 376 | 375 |
| 377 DCHECK(*name); | 376 DCHECK(*name); |
| 378 return S_OK; | 377 return S_OK; |
| 379 } | 378 } |
| 380 | 379 |
| 381 STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { | 380 STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { |
| 382 if (!instance_active_) { | 381 if (!instance_active_) |
| 383 // Instance no longer active, fail gracefully. | |
| 384 return E_FAIL; | 382 return E_FAIL; |
| 385 } | |
| 386 | 383 |
| 387 if (!disp_parent) | 384 if (!disp_parent) |
| 388 return E_INVALIDARG; | 385 return E_INVALIDARG; |
| 389 | 386 |
| 390 IAccessible* parent = parent_; | 387 IAccessible* parent = parent_; |
| 391 if (parent == NULL) { | 388 if (parent == NULL) { |
| 392 // This happens if we're the root of the tree; | 389 // This happens if we're the root of the tree; |
| 393 // return the IAccessible for the window. | 390 // return the IAccessible for the window. |
| 394 parent = manager_->GetParentWindowIAccessible(); | 391 parent = manager_->GetParentWindowIAccessible(); |
| 395 } | 392 } |
| 396 | 393 |
| 397 parent->AddRef(); | 394 parent->AddRef(); |
| 398 *disp_parent = parent; | 395 *disp_parent = parent; |
| 399 return S_OK; | 396 return S_OK; |
| 400 } | 397 } |
| 401 | 398 |
| 402 STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { | 399 STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { |
| 403 if (!instance_active_) { | 400 if (!instance_active_) |
| 404 // Instance no longer active, fail gracefully. | |
| 405 return E_FAIL; | 401 return E_FAIL; |
| 406 } | |
| 407 | 402 |
| 408 if (!role) | 403 if (!role) |
| 409 return E_INVALIDARG; | 404 return E_INVALIDARG; |
| 410 | 405 |
| 411 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 406 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 412 if (!target) | 407 if (!target) |
| 413 return E_INVALIDARG; | 408 return E_INVALIDARG; |
| 414 | 409 |
| 415 role->vt = VT_I4; | 410 if (!target->role_name_.empty()) { |
| 416 role->lVal = target->role_; | 411 role->vt = VT_BSTR; |
| 412 role->bstrVal = SysAllocString(target->role_name_.c_str()); |
| 413 } else { |
| 414 role->vt = VT_I4; |
| 415 role->lVal = target->role_; |
| 416 } |
| 417 return S_OK; | 417 return S_OK; |
| 418 } | 418 } |
| 419 | 419 |
| 420 STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, | 420 STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, |
| 421 VARIANT* state) { | 421 VARIANT* state) { |
| 422 if (!instance_active_) { | 422 if (!instance_active_) |
| 423 // Instance no longer active, fail gracefully. | |
| 424 return E_FAIL; | 423 return E_FAIL; |
| 425 } | |
| 426 | 424 |
| 427 if (!state) | 425 if (!state) |
| 428 return E_INVALIDARG; | 426 return E_INVALIDARG; |
| 429 | 427 |
| 430 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 428 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 431 if (!target) | 429 if (!target) |
| 432 return E_INVALIDARG; | 430 return E_INVALIDARG; |
| 433 | 431 |
| 434 state->vt = VT_I4; | 432 state->vt = VT_I4; |
| 435 state->lVal = target->state_; | 433 state->lVal = target->state_; |
| 436 if (manager_->GetFocus(NULL) == this) | 434 if (manager_->GetFocus(NULL) == this) |
| 437 state->lVal |= STATE_SYSTEM_FOCUSED; | 435 state->lVal |= STATE_SYSTEM_FOCUSED; |
| 438 | 436 |
| 439 return S_OK; | 437 return S_OK; |
| 440 } | 438 } |
| 441 | 439 |
| 442 STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { | 440 STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { |
| 443 if (!instance_active_) { | 441 if (!instance_active_) |
| 444 // Instance no longer active, fail gracefully. | |
| 445 return E_FAIL; | 442 return E_FAIL; |
| 446 } | |
| 447 | 443 |
| 448 if (!value) | 444 if (!value) |
| 449 return E_INVALIDARG; | 445 return E_INVALIDARG; |
| 450 | 446 |
| 451 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 447 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
| 452 if (!target) | 448 if (!target) |
| 453 return E_INVALIDARG; | 449 return E_INVALIDARG; |
| 454 | 450 |
| 455 *value = SysAllocString(target->value_.c_str()); | 451 *value = SysAllocString(target->value_.c_str()); |
| 456 | 452 |
| 457 DCHECK(*value); | 453 DCHECK(*value); |
| 458 return S_OK; | 454 return S_OK; |
| 459 } | 455 } |
| 460 | 456 |
| 461 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, | 457 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, |
| 462 VARIANT var_id, | 458 VARIANT var_id, |
| 463 LONG* topic_id) { | 459 LONG* topic_id) { |
| 464 return E_NOTIMPL; | 460 return E_NOTIMPL; |
| 465 } | 461 } |
| 466 | 462 |
| 467 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { | 463 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { |
| 468 if (!instance_active_) { | 464 if (!instance_active_) |
| 469 // Instance no longer active, fail gracefully. | |
| 470 return E_FAIL; | 465 return E_FAIL; |
| 471 } | |
| 472 | 466 |
| 473 return E_NOTIMPL; | 467 return E_NOTIMPL; |
| 474 } | 468 } |
| 475 | 469 |
| 476 STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_sel, VARIANT var_id) { | 470 STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_sel, VARIANT var_id) { |
| 477 if (!instance_active_) { | 471 if (!instance_active_) |
| 478 // Instance no longer active, fail gracefully. | |
| 479 return E_FAIL; | 472 return E_FAIL; |
| 473 |
| 474 if (flags_sel & SELFLAG_TAKEFOCUS) { |
| 475 manager_->SetFocus(*this); |
| 476 return S_OK; |
| 480 } | 477 } |
| 481 | 478 |
| 482 return E_NOTIMPL; | 479 return S_FALSE; |
| 483 } | 480 } |
| 484 | 481 |
| 485 // | 482 // |
| 486 // IAccessible2 methods. | 483 // IAccessible2 methods. |
| 487 // | 484 // |
| 488 | 485 |
| 489 STDMETHODIMP BrowserAccessibility::role(LONG* role) { | 486 STDMETHODIMP BrowserAccessibility::role(LONG* role) { |
| 490 if (!instance_active_) { | 487 if (!instance_active_) |
| 491 // Instance no longer active, fail gracefully. | |
| 492 return E_FAIL; | 488 return E_FAIL; |
| 493 } | |
| 494 | 489 |
| 495 if (!role) | 490 if (!role) |
| 496 return E_INVALIDARG; | 491 return E_INVALIDARG; |
| 497 | 492 |
| 498 *role = role_; | 493 *role = ia2_role_; |
| 499 | 494 |
| 500 return S_OK; | 495 return S_OK; |
| 501 } | 496 } |
| 502 | 497 |
| 498 STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { |
| 499 if (!instance_active_) |
| 500 return E_FAIL; |
| 501 |
| 502 if (!attributes) |
| 503 return E_INVALIDARG; |
| 504 |
| 505 return S_FALSE; |
| 506 } |
| 507 |
| 503 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { | 508 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { |
| 504 if (!instance_active_) { | 509 if (!instance_active_) |
| 505 // Instance no longer active, fail gracefully. | |
| 506 return E_FAIL; | 510 return E_FAIL; |
| 507 } | |
| 508 | 511 |
| 509 if (!states) | 512 if (!states) |
| 510 return E_INVALIDARG; | 513 return E_INVALIDARG; |
| 511 | 514 |
| 512 *states = state_; | 515 *states = ia2_state_; |
| 513 | 516 |
| 514 return S_OK; | 517 return S_OK; |
| 515 } | 518 } |
| 516 | 519 |
| 517 STDMETHODIMP BrowserAccessibility::get_uniqueID(LONG* unique_id) { | 520 STDMETHODIMP BrowserAccessibility::get_uniqueID(LONG* unique_id) { |
| 518 if (!instance_active_) { | 521 if (!instance_active_) |
| 519 // Instance no longer active, fail gracefully. | |
| 520 return E_FAIL; | 522 return E_FAIL; |
| 521 } | |
| 522 | 523 |
| 523 if (!unique_id) | 524 if (!unique_id) |
| 524 return E_INVALIDARG; | 525 return E_INVALIDARG; |
| 525 | 526 |
| 526 *unique_id = child_id_; | 527 *unique_id = child_id_; |
| 527 return S_OK; | 528 return S_OK; |
| 528 } | 529 } |
| 529 | 530 |
| 530 STDMETHODIMP BrowserAccessibility::get_windowHandle(HWND* window_handle) { | 531 STDMETHODIMP BrowserAccessibility::get_windowHandle(HWND* window_handle) { |
| 531 if (!instance_active_) { | 532 if (!instance_active_) |
| 532 // Instance no longer active, fail gracefully. | |
| 533 return E_FAIL; | 533 return E_FAIL; |
| 534 } | |
| 535 | 534 |
| 536 if (!window_handle) | 535 if (!window_handle) |
| 537 return E_INVALIDARG; | 536 return E_INVALIDARG; |
| 538 | 537 |
| 539 *window_handle = manager_->GetParentHWND(); | 538 *window_handle = manager_->GetParentHWND(); |
| 540 return S_OK; | 539 return S_OK; |
| 541 } | 540 } |
| 542 | 541 |
| 543 STDMETHODIMP BrowserAccessibility::get_indexInParent(LONG* index_in_parent) { | 542 STDMETHODIMP BrowserAccessibility::get_indexInParent(LONG* index_in_parent) { |
| 544 if (!instance_active_) { | 543 if (!instance_active_) |
| 545 // Instance no longer active, fail gracefully. | |
| 546 return E_FAIL; | 544 return E_FAIL; |
| 547 } | |
| 548 | 545 |
| 549 if (!index_in_parent) | 546 if (!index_in_parent) |
| 550 return E_INVALIDARG; | 547 return E_INVALIDARG; |
| 551 | 548 |
| 552 *index_in_parent = index_in_parent_; | 549 *index_in_parent = index_in_parent_; |
| 553 return S_OK; | 550 return S_OK; |
| 554 } | 551 } |
| 555 | 552 |
| 556 // | 553 // |
| 554 // IAccessibleImage methods. |
| 555 // |
| 556 |
| 557 STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { |
| 558 if (!instance_active_) |
| 559 return E_FAIL; |
| 560 |
| 561 if (!desc) |
| 562 return E_INVALIDARG; |
| 563 |
| 564 string16 description; |
| 565 if (!GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) |
| 566 return S_FALSE; |
| 567 |
| 568 if (description.empty()) |
| 569 return S_FALSE; |
| 570 |
| 571 *desc = SysAllocString(description.c_str()); |
| 572 |
| 573 DCHECK(*desc); |
| 574 return S_OK; |
| 575 } |
| 576 |
| 577 STDMETHODIMP BrowserAccessibility::get_imagePosition( |
| 578 enum IA2CoordinateType coordinate_type, long* x, long* y) { |
| 579 if (!instance_active_) |
| 580 return E_FAIL; |
| 581 |
| 582 if (!x || !y) |
| 583 return E_INVALIDARG; |
| 584 |
| 585 if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { |
| 586 HWND parent_hwnd = manager_->GetParentHWND(); |
| 587 POINT top_left = {0, 0}; |
| 588 ::ClientToScreen(parent_hwnd, &top_left); |
| 589 *x = location_.x + top_left.x; |
| 590 *y = location_.y + top_left.y; |
| 591 } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { |
| 592 *x = location_.x; |
| 593 *y = location_.y; |
| 594 if (parent_) { |
| 595 *x -= parent_->location_.x; |
| 596 *y -= parent_->location_.y; |
| 597 } |
| 598 } else { |
| 599 return E_INVALIDARG; |
| 600 } |
| 601 |
| 602 return S_OK; |
| 603 } |
| 604 |
| 605 STDMETHODIMP BrowserAccessibility::get_imageSize(long* height, long* width) { |
| 606 if (!instance_active_) |
| 607 return E_FAIL; |
| 608 |
| 609 if (!height || !width) |
| 610 return E_INVALIDARG; |
| 611 |
| 612 *height = location_.height; |
| 613 *width = location_.width; |
| 614 return S_OK; |
| 615 } |
| 616 |
| 617 // |
| 618 // IAccessibleText methods. |
| 619 // |
| 620 |
| 621 STDMETHODIMP BrowserAccessibility::get_nCharacters(long* n_characters) { |
| 622 if (!instance_active_) |
| 623 return E_FAIL; |
| 624 |
| 625 if (!n_characters) |
| 626 return E_INVALIDARG; |
| 627 |
| 628 *n_characters = name_.length(); |
| 629 return S_OK; |
| 630 } |
| 631 |
| 632 STDMETHODIMP BrowserAccessibility::get_text( |
| 633 long start_offset, long end_offset, BSTR* text) { |
| 634 if (!instance_active_) |
| 635 return E_FAIL; |
| 636 |
| 637 if (!text) |
| 638 return E_INVALIDARG; |
| 639 |
| 640 long len = name_.length(); |
| 641 if (start_offset < 0) |
| 642 start_offset = 0; |
| 643 if (end_offset > len) |
| 644 end_offset = len; |
| 645 |
| 646 *text = SysAllocString( |
| 647 name_.substr(start_offset, end_offset - start_offset).c_str()); |
| 648 return S_OK; |
| 649 } |
| 650 |
| 651 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { |
| 652 *offset = 0; |
| 653 return S_OK; |
| 654 } |
| 655 |
| 656 // |
| 557 // IServiceProvider methods. | 657 // IServiceProvider methods. |
| 558 // | 658 // |
| 559 | 659 |
| 560 STDMETHODIMP BrowserAccessibility::QueryService( | 660 STDMETHODIMP BrowserAccessibility::QueryService( |
| 561 REFGUID guidService, REFIID riid, void** object) { | 661 REFGUID guidService, REFIID riid, void** object) { |
| 562 if (!instance_active_) { | 662 if (!instance_active_) |
| 563 // Instance no longer active, fail gracefully. | |
| 564 return E_FAIL; | 663 return E_FAIL; |
| 565 } | |
| 566 | 664 |
| 567 if (guidService == IID_IAccessible || guidService == IID_IAccessible2) | 665 if (guidService == IID_IAccessible || guidService == IID_IAccessible2) |
| 568 return QueryInterface(riid, object); | 666 return QueryInterface(riid, object); |
| 569 | 667 |
| 570 *object = NULL; | 668 *object = NULL; |
| 571 return E_FAIL; | 669 return E_FAIL; |
| 572 } | 670 } |
| 573 | 671 |
| 574 // | 672 // |
| 673 // CComObjectRootEx methods. |
| 674 // |
| 675 |
| 676 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( |
| 677 void* this_ptr, |
| 678 const _ATL_INTMAP_ENTRY* entries, |
| 679 REFIID iid, |
| 680 void** object) { |
| 681 if (iid == IID_IAccessibleText) { |
| 682 if (role_ != ROLE_SYSTEM_LINK) { |
| 683 *object = NULL; |
| 684 return E_NOINTERFACE; |
| 685 } |
| 686 } else if (iid == IID_IAccessibleImage) { |
| 687 if (role_ != ROLE_SYSTEM_GRAPHIC) { |
| 688 *object = NULL; |
| 689 return E_NOINTERFACE; |
| 690 } |
| 691 } |
| 692 |
| 693 return CComObjectRootBase::InternalQueryInterface( |
| 694 this_ptr, entries, iid, object); |
| 695 } |
| 696 |
| 697 // |
| 575 // Private methods. | 698 // Private methods. |
| 576 // | 699 // |
| 577 | 700 |
| 578 BrowserAccessibility* BrowserAccessibility::GetTargetFromChildID( | 701 BrowserAccessibility* BrowserAccessibility::GetTargetFromChildID( |
| 579 const VARIANT& var_id) { | 702 const VARIANT& var_id) { |
| 580 if (var_id.vt != VT_I4) | 703 if (var_id.vt != VT_I4) |
| 581 return NULL; | 704 return NULL; |
| 582 | 705 |
| 583 LONG child_id = var_id.lVal; | 706 LONG child_id = var_id.lVal; |
| 584 if (child_id == CHILDID_SELF) | 707 if (child_id == CHILDID_SELF) |
| 585 return this; | 708 return this; |
| 586 | 709 |
| 587 if (child_id >= 1 && child_id <= static_cast<LONG>(children_.size())) | 710 if (child_id >= 1 && child_id <= static_cast<LONG>(children_.size())) |
| 588 return children_[child_id - 1]; | 711 return children_[child_id - 1]; |
| 589 | 712 |
| 590 return manager_->GetFromChildID(child_id); | 713 return manager_->GetFromChildID(child_id); |
| 591 } | 714 } |
| 592 | 715 |
| 593 LONG BrowserAccessibility::MSAARole(LONG browser_accessibility_role) { | 716 bool BrowserAccessibility::HasAttribute(WebAccessibility::Attribute attribute) { |
| 594 switch (browser_accessibility_role) { | 717 return (attributes_.find(attribute) != attributes_.end()); |
| 718 } |
| 719 |
| 720 bool BrowserAccessibility::GetAttribute( |
| 721 WebAccessibility::Attribute attribute, string16* value) { |
| 722 std::map<int32, string16>::iterator iter = attributes_.find(attribute); |
| 723 if (iter != attributes_.end()) { |
| 724 *value = iter->second; |
| 725 return true; |
| 726 } |
| 727 |
| 728 return false; |
| 729 } |
| 730 |
| 731 void BrowserAccessibility::InitRoleAndState(LONG web_role, |
| 732 LONG web_state) { |
| 733 state_ = 0; |
| 734 ia2_state_ = IA2_STATE_OPAQUE; |
| 735 |
| 736 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) |
| 737 state_ |= STATE_SYSTEM_CHECKED; |
| 738 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) |
| 739 state_ |= STATE_SYSTEM_FOCUSABLE; |
| 740 if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) |
| 741 state_ |= STATE_SYSTEM_HOTTRACKED; |
| 742 if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) |
| 743 state_ |= STATE_SYSTEM_INDETERMINATE; |
| 744 if ((web_state >> WebAccessibility::STATE_LINKED) & 1) |
| 745 state_ |= STATE_SYSTEM_LINKED; |
| 746 if ((web_state >> WebAccessibility::STATE_MULTISELECTABLE) & 1) |
| 747 state_ |= STATE_SYSTEM_MULTISELECTABLE; |
| 748 if ((web_state >> WebAccessibility::STATE_OFFSCREEN) & 1) |
| 749 state_ |= STATE_SYSTEM_OFFSCREEN; |
| 750 if ((web_state >> WebAccessibility::STATE_PRESSED) & 1) |
| 751 state_ |= STATE_SYSTEM_PRESSED; |
| 752 if ((web_state >> WebAccessibility::STATE_PROTECTED) & 1) |
| 753 state_ |= STATE_SYSTEM_PROTECTED; |
| 754 if ((web_state >> WebAccessibility::STATE_READONLY) & 1) |
| 755 state_ |= STATE_SYSTEM_READONLY; |
| 756 if ((web_state >> WebAccessibility::STATE_TRAVERSED) & 1) |
| 757 state_ |= STATE_SYSTEM_TRAVERSED; |
| 758 if ((web_state >> WebAccessibility::STATE_UNAVAILABLE) & 1) |
| 759 state_ |= STATE_SYSTEM_UNAVAILABLE; |
| 760 |
| 761 role_ = 0; |
| 762 ia2_role_ = 0; |
| 763 switch (web_role) { |
| 764 case WebAccessibility::ROLE_ALERT: |
| 765 case WebAccessibility::ROLE_ALERT_DIALOG: |
| 766 role_ = ROLE_SYSTEM_ALERT; |
| 767 break; |
| 595 case WebAccessibility::ROLE_APPLICATION: | 768 case WebAccessibility::ROLE_APPLICATION: |
| 596 return ROLE_SYSTEM_APPLICATION; | 769 role_ = ROLE_SYSTEM_APPLICATION; |
| 770 break; |
| 771 case WebAccessibility::ROLE_ARTICLE: |
| 772 role_ = ROLE_SYSTEM_GROUPING; |
| 773 ia2_role_ = IA2_ROLE_SECTION; |
| 774 break; |
| 775 case WebAccessibility::ROLE_BUTTON: |
| 776 role_ = ROLE_SYSTEM_PUSHBUTTON; |
| 777 break; |
| 597 case WebAccessibility::ROLE_CELL: | 778 case WebAccessibility::ROLE_CELL: |
| 598 return ROLE_SYSTEM_CELL; | 779 role_ = ROLE_SYSTEM_CELL; |
| 599 case WebAccessibility::ROLE_CHECKBUTTON: | 780 break; |
| 600 return ROLE_SYSTEM_CHECKBUTTON; | 781 case WebAccessibility::ROLE_CHECKBOX: |
| 782 role_ = ROLE_SYSTEM_CHECKBUTTON; |
| 783 break; |
| 784 case WebAccessibility::ROLE_COLOR_WELL: |
| 785 role_ = ROLE_SYSTEM_CLIENT; |
| 786 ia2_role_ = IA2_ROLE_COLOR_CHOOSER; |
| 787 break; |
| 601 case WebAccessibility::ROLE_COLUMN: | 788 case WebAccessibility::ROLE_COLUMN: |
| 602 return ROLE_SYSTEM_COLUMN; | 789 role_ = ROLE_SYSTEM_COLUMN; |
| 603 case WebAccessibility::ROLE_COLUMNHEADER: | 790 break; |
| 604 return ROLE_SYSTEM_COLUMNHEADER; | 791 case WebAccessibility::ROLE_COLUMN_HEADER: |
| 792 role_ = ROLE_SYSTEM_COLUMNHEADER; |
| 793 break; |
| 794 case WebAccessibility::ROLE_COMBO_BOX: |
| 795 role_ = ROLE_SYSTEM_COMBOBOX; |
| 796 break; |
| 797 case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: |
| 798 role_name_ = L"dd"; |
| 799 ia2_role_ = IA2_ROLE_PARAGRAPH; |
| 800 break; |
| 801 case WebAccessibility::ROLE_DEFINITION_LIST_TERM: |
| 802 role_ = ROLE_SYSTEM_LISTITEM; |
| 803 break; |
| 804 case WebAccessibility::ROLE_DIALOG: |
| 805 role_ = ROLE_SYSTEM_DIALOG; |
| 806 break; |
| 605 case WebAccessibility::ROLE_DOCUMENT: | 807 case WebAccessibility::ROLE_DOCUMENT: |
| 606 return ROLE_SYSTEM_DOCUMENT; | 808 case WebAccessibility::ROLE_WEB_AREA: |
| 607 case WebAccessibility::ROLE_GRAPHIC: | 809 role_ = ROLE_SYSTEM_DOCUMENT; |
| 608 return ROLE_SYSTEM_GRAPHIC; | 810 state_ |= STATE_SYSTEM_READONLY; |
| 609 case WebAccessibility::ROLE_GROUPING: | 811 state_ |= STATE_SYSTEM_FOCUSABLE; |
| 610 return ROLE_SYSTEM_GROUPING; | 812 break; |
| 813 case WebAccessibility::ROLE_EDITABLE_TEXT: |
| 814 role_ = ROLE_SYSTEM_TEXT; |
| 815 ia2_state_ |= IA2_STATE_SINGLE_LINE; |
| 816 ia2_state_ |= IA2_STATE_EDITABLE; |
| 817 break; |
| 818 case WebAccessibility::ROLE_GRID: |
| 819 role_ = ROLE_SYSTEM_TABLE; |
| 820 break; |
| 821 case WebAccessibility::ROLE_GROUP: |
| 822 role_name_ = L"div"; |
| 823 ia2_role_ = IA2_ROLE_SECTION; |
| 824 break; |
| 825 case WebAccessibility::ROLE_HEADING: |
| 826 // TODO(dmazzoni): support all heading levels |
| 827 role_name_ = L"h1"; |
| 828 ia2_role_ = IA2_ROLE_HEADING; |
| 829 break; |
| 830 case WebAccessibility::ROLE_IMAGE: |
| 831 role_ = ROLE_SYSTEM_GRAPHIC; |
| 832 break; |
| 833 case WebAccessibility::ROLE_IMAGE_MAP: |
| 834 role_name_ = L"map"; |
| 835 ia2_role_ = IA2_ROLE_IMAGE_MAP; |
| 836 break; |
| 837 case WebAccessibility::ROLE_IMAGE_MAP_LINK: |
| 838 role_ = ROLE_SYSTEM_LINK; |
| 839 state_ |= STATE_SYSTEM_LINKED; |
| 840 break; |
| 841 case WebAccessibility::ROLE_LANDMARK_APPLICATION: |
| 842 case WebAccessibility::ROLE_LANDMARK_BANNER: |
| 843 case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: |
| 844 case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: |
| 845 case WebAccessibility::ROLE_LANDMARK_MAIN: |
| 846 case WebAccessibility::ROLE_LANDMARK_NAVIGATION: |
| 847 case WebAccessibility::ROLE_LANDMARK_SEARCH: |
| 848 role_ = ROLE_SYSTEM_GROUPING; |
| 849 ia2_role_ = IA2_ROLE_SECTION; |
| 850 break; |
| 611 case WebAccessibility::ROLE_LINK: | 851 case WebAccessibility::ROLE_LINK: |
| 612 return ROLE_SYSTEM_LINK; | 852 case WebAccessibility::ROLE_WEBCORE_LINK: |
| 853 role_ = ROLE_SYSTEM_LINK; |
| 854 state_ |= STATE_SYSTEM_LINKED; |
| 855 break; |
| 613 case WebAccessibility::ROLE_LIST: | 856 case WebAccessibility::ROLE_LIST: |
| 857 role_ = ROLE_SYSTEM_LIST; |
| 858 break; |
| 614 case WebAccessibility::ROLE_LISTBOX: | 859 case WebAccessibility::ROLE_LISTBOX: |
| 615 return ROLE_SYSTEM_LIST; | 860 role_ = ROLE_SYSTEM_LIST; |
| 616 case WebAccessibility::ROLE_LISTITEM: | 861 break; |
| 617 return ROLE_SYSTEM_LISTITEM; | 862 case WebAccessibility::ROLE_LISTBOX_OPTION: |
| 618 case WebAccessibility::ROLE_MENUBAR: | 863 case WebAccessibility::ROLE_LIST_ITEM: |
| 619 return ROLE_SYSTEM_MENUBAR; | 864 case WebAccessibility::ROLE_LIST_MARKER: |
| 620 case WebAccessibility::ROLE_MENUITEM: | 865 role_ = ROLE_SYSTEM_LISTITEM; |
| 621 return ROLE_SYSTEM_MENUITEM; | 866 break; |
| 622 case WebAccessibility::ROLE_MENUPOPUP: | 867 case WebAccessibility::ROLE_MENU: |
| 623 return ROLE_SYSTEM_MENUPOPUP; | 868 case WebAccessibility::ROLE_MENU_BUTTON: |
| 869 role_ = ROLE_SYSTEM_MENUPOPUP; |
| 870 break; |
| 871 case WebAccessibility::ROLE_MENU_BAR: |
| 872 role_ = ROLE_SYSTEM_MENUBAR; |
| 873 break; |
| 874 case WebAccessibility::ROLE_MENU_ITEM: |
| 875 case WebAccessibility::ROLE_MENU_LIST_OPTION: |
| 876 role_ = ROLE_SYSTEM_MENUITEM; |
| 877 break; |
| 878 case WebAccessibility::ROLE_MENU_LIST_POPUP: |
| 879 role_ = ROLE_SYSTEM_MENUPOPUP; |
| 880 break; |
| 881 case WebAccessibility::ROLE_NOTE: |
| 882 role_ = ROLE_SYSTEM_GROUPING; |
| 883 ia2_role_ = IA2_ROLE_NOTE; |
| 884 break; |
| 624 case WebAccessibility::ROLE_OUTLINE: | 885 case WebAccessibility::ROLE_OUTLINE: |
| 625 return ROLE_SYSTEM_OUTLINE; | 886 role_ = ROLE_SYSTEM_OUTLINE; |
| 626 case WebAccessibility::ROLE_PAGETABLIST: | 887 break; |
| 627 return ROLE_SYSTEM_PAGETABLIST; | 888 case WebAccessibility::ROLE_POPUP_BUTTON: |
| 628 case WebAccessibility::ROLE_PROGRESSBAR: | 889 role_ = ROLE_SYSTEM_COMBOBOX; |
| 629 return ROLE_SYSTEM_PROGRESSBAR; | 890 break; |
| 630 case WebAccessibility::ROLE_PUSHBUTTON: | 891 case WebAccessibility::ROLE_PROGRESS_INDICATOR: |
| 631 return ROLE_SYSTEM_PUSHBUTTON; | 892 role_ = ROLE_SYSTEM_PROGRESSBAR; |
| 632 case WebAccessibility::ROLE_RADIOBUTTON: | 893 break; |
| 633 return ROLE_SYSTEM_RADIOBUTTON; | 894 case WebAccessibility::ROLE_RADIO_BUTTON: |
| 895 role_ = ROLE_SYSTEM_RADIOBUTTON; |
| 896 break; |
| 897 case WebAccessibility::ROLE_RADIO_GROUP: |
| 898 role_ = ROLE_SYSTEM_GROUPING; |
| 899 ia2_role_ = IA2_ROLE_SECTION; |
| 900 break; |
| 901 case WebAccessibility::ROLE_REGION: |
| 902 role_ = ROLE_SYSTEM_GROUPING; |
| 903 ia2_role_ = IA2_ROLE_SECTION; |
| 904 break; |
| 634 case WebAccessibility::ROLE_ROW: | 905 case WebAccessibility::ROLE_ROW: |
| 635 return ROLE_SYSTEM_ROW; | 906 role_ = ROLE_SYSTEM_ROW; |
| 636 case WebAccessibility::ROLE_ROWHEADER: | 907 break; |
| 637 return ROLE_SYSTEM_ROWHEADER; | 908 case WebAccessibility::ROLE_ROW_HEADER: |
| 638 case WebAccessibility::ROLE_SEPARATOR: | 909 role_ = ROLE_SYSTEM_ROWHEADER; |
| 639 return ROLE_SYSTEM_SEPARATOR; | 910 break; |
| 911 case WebAccessibility::ROLE_RULER: |
| 912 role_ = ROLE_SYSTEM_CLIENT; |
| 913 ia2_role_ = IA2_ROLE_RULER; |
| 914 break; |
| 915 case WebAccessibility::ROLE_SCROLLAREA: |
| 916 role_ = ROLE_SYSTEM_CLIENT; |
| 917 ia2_role_ = IA2_ROLE_SCROLL_PANE; |
| 918 break; |
| 919 case WebAccessibility::ROLE_SCROLLBAR: |
| 920 role_ = ROLE_SYSTEM_SCROLLBAR; |
| 921 break; |
| 640 case WebAccessibility::ROLE_SLIDER: | 922 case WebAccessibility::ROLE_SLIDER: |
| 641 return ROLE_SYSTEM_SLIDER; | 923 role_ = ROLE_SYSTEM_SLIDER; |
| 642 case WebAccessibility::ROLE_STATICTEXT: | 924 break; |
| 643 return ROLE_SYSTEM_STATICTEXT; | 925 case WebAccessibility::ROLE_SPLIT_GROUP: |
| 644 case WebAccessibility::ROLE_STATUSBAR: | 926 role_ = ROLE_SYSTEM_CLIENT; |
| 645 return ROLE_SYSTEM_STATUSBAR; | 927 ia2_role_ = IA2_ROLE_SPLIT_PANE; |
| 928 break; |
| 929 case WebAccessibility::ROLE_ANNOTATION: |
| 930 case WebAccessibility::ROLE_STATIC_TEXT: |
| 931 role_ = ROLE_SYSTEM_TEXT; |
| 932 break; |
| 933 case WebAccessibility::ROLE_STATUS: |
| 934 role_ = ROLE_SYSTEM_STATUSBAR; |
| 935 break; |
| 936 case WebAccessibility::ROLE_TAB: |
| 937 role_ = ROLE_SYSTEM_PAGETAB; |
| 938 break; |
| 646 case WebAccessibility::ROLE_TABLE: | 939 case WebAccessibility::ROLE_TABLE: |
| 647 return ROLE_SYSTEM_TABLE; | 940 role_ = ROLE_SYSTEM_TABLE; |
| 648 case WebAccessibility::ROLE_TEXT: | 941 break; |
| 649 return ROLE_SYSTEM_TEXT; | 942 case WebAccessibility::ROLE_TABLE_HEADER_CONTAINER: |
| 943 role_ = ROLE_SYSTEM_GROUPING; |
| 944 ia2_role_ = IA2_ROLE_SECTION; |
| 945 break; |
| 946 case WebAccessibility::ROLE_TAB_GROUP: |
| 947 case WebAccessibility::ROLE_TAB_LIST: |
| 948 case WebAccessibility::ROLE_TAB_PANEL: |
| 949 role_ = ROLE_SYSTEM_PAGETABLIST; |
| 950 break; |
| 951 case WebAccessibility::ROLE_TEXTAREA: |
| 952 role_ = ROLE_SYSTEM_TEXT; |
| 953 ia2_state_ |= IA2_STATE_MULTI_LINE; |
| 954 ia2_state_ |= IA2_STATE_EDITABLE; |
| 955 break; |
| 956 case WebAccessibility::ROLE_TEXT_FIELD: |
| 957 role_ = ROLE_SYSTEM_TEXT; |
| 958 ia2_state_ |= IA2_STATE_SINGLE_LINE; |
| 959 ia2_state_ |= IA2_STATE_EDITABLE; |
| 960 break; |
| 650 case WebAccessibility::ROLE_TOOLBAR: | 961 case WebAccessibility::ROLE_TOOLBAR: |
| 651 return ROLE_SYSTEM_TOOLBAR; | 962 role_ = ROLE_SYSTEM_TOOLBAR; |
| 963 break; |
| 652 case WebAccessibility::ROLE_TOOLTIP: | 964 case WebAccessibility::ROLE_TOOLTIP: |
| 653 return ROLE_SYSTEM_TOOLTIP; | 965 role_ = ROLE_SYSTEM_TOOLTIP; |
| 654 case WebAccessibility::ROLE_CLIENT: | 966 break; |
| 967 case WebAccessibility::ROLE_TREE: |
| 968 role_ = ROLE_SYSTEM_OUTLINE; |
| 969 break; |
| 970 case WebAccessibility::ROLE_TREE_GRID: |
| 971 role_ = ROLE_SYSTEM_OUTLINE; |
| 972 break; |
| 973 case WebAccessibility::ROLE_TREE_ITEM: |
| 974 role_ = ROLE_SYSTEM_OUTLINEITEM; |
| 975 break; |
| 976 case WebAccessibility::ROLE_WINDOW: |
| 977 role_ = ROLE_SYSTEM_WINDOW; |
| 978 break; |
| 979 |
| 980 // TODO(dmazzoni): figure out the proper MSAA role for all of these. |
| 981 case WebAccessibility::ROLE_BROWSER: |
| 982 case WebAccessibility::ROLE_BUSY_INDICATOR: |
| 983 case WebAccessibility::ROLE_DIRECTORY: |
| 984 case WebAccessibility::ROLE_DISCLOSURE_TRIANGLE: |
| 985 case WebAccessibility::ROLE_DRAWER: |
| 986 case WebAccessibility::ROLE_GROW_AREA: |
| 987 case WebAccessibility::ROLE_HELP_TAG: |
| 988 case WebAccessibility::ROLE_IGNORED: |
| 989 case WebAccessibility::ROLE_INCREMENTOR: |
| 990 case WebAccessibility::ROLE_LOG: |
| 991 case WebAccessibility::ROLE_MARQUEE: |
| 992 case WebAccessibility::ROLE_MATH: |
| 993 case WebAccessibility::ROLE_MATTE: |
| 994 case WebAccessibility::ROLE_RULER_MARKER: |
| 995 case WebAccessibility::ROLE_SHEET: |
| 996 case WebAccessibility::ROLE_SLIDER_THUMB: |
| 997 case WebAccessibility::ROLE_SPLITTER: |
| 998 case WebAccessibility::ROLE_SYSTEM_WIDE: |
| 999 case WebAccessibility::ROLE_TIMER: |
| 1000 case WebAccessibility::ROLE_VALUE_INDICATOR: |
| 655 default: | 1001 default: |
| 656 // This is the default role for MSAA. | 1002 role_ = ROLE_SYSTEM_CLIENT; |
| 657 return ROLE_SYSTEM_CLIENT; | 1003 break; |
| 658 } | 1004 } |
| 1005 |
| 1006 // The role should always be set. |
| 1007 DCHECK(!role_name_.empty() || role_); |
| 1008 |
| 1009 // If we didn't explicitly set the IAccessible2 role, make it the same |
| 1010 // as the MSAA role. |
| 1011 if (!ia2_role_) |
| 1012 ia2_role_ = role_; |
| 659 } | 1013 } |
| 660 | |
| 661 LONG BrowserAccessibility::MSAAState(LONG browser_accessibility_state) { | |
| 662 LONG state = 0; | |
| 663 | |
| 664 if ((browser_accessibility_state >> WebAccessibility::STATE_CHECKED) & 1) | |
| 665 state |= STATE_SYSTEM_CHECKED; | |
| 666 | |
| 667 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSABLE) & 1) | |
| 668 state |= STATE_SYSTEM_FOCUSABLE; | |
| 669 | |
| 670 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSED) & 1) | |
| 671 state |= STATE_SYSTEM_FOCUSED; | |
| 672 | |
| 673 if ((browser_accessibility_state >> WebAccessibility::STATE_HOTTRACKED) & 1) | |
| 674 state |= STATE_SYSTEM_HOTTRACKED; | |
| 675 | |
| 676 if ((browser_accessibility_state >> | |
| 677 WebAccessibility::STATE_INDETERMINATE) & 1) { | |
| 678 state |= STATE_SYSTEM_INDETERMINATE; | |
| 679 } | |
| 680 | |
| 681 if ((browser_accessibility_state >> WebAccessibility::STATE_LINKED) & 1) | |
| 682 state |= STATE_SYSTEM_LINKED; | |
| 683 | |
| 684 if ((browser_accessibility_state >> | |
| 685 WebAccessibility::STATE_MULTISELECTABLE) & 1) { | |
| 686 state |= STATE_SYSTEM_MULTISELECTABLE; | |
| 687 } | |
| 688 | |
| 689 if ((browser_accessibility_state >> WebAccessibility::STATE_OFFSCREEN) & 1) | |
| 690 state |= STATE_SYSTEM_OFFSCREEN; | |
| 691 | |
| 692 if ((browser_accessibility_state >> WebAccessibility::STATE_PRESSED) & 1) | |
| 693 state |= STATE_SYSTEM_PRESSED; | |
| 694 | |
| 695 if ((browser_accessibility_state >> WebAccessibility::STATE_PROTECTED) & 1) | |
| 696 state |= STATE_SYSTEM_PROTECTED; | |
| 697 | |
| 698 if ((browser_accessibility_state >> WebAccessibility::STATE_READONLY) & 1) | |
| 699 state |= STATE_SYSTEM_READONLY; | |
| 700 | |
| 701 if ((browser_accessibility_state >> WebAccessibility::STATE_TRAVERSED) & 1) | |
| 702 state |= STATE_SYSTEM_TRAVERSED; | |
| 703 | |
| 704 if ((browser_accessibility_state >> WebAccessibility::STATE_UNAVAILABLE) & 1) | |
| 705 state |= STATE_SYSTEM_UNAVAILABLE; | |
| 706 | |
| 707 return state; | |
| 708 } | |
| OLD | NEW |