1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "WebAccessibilityObject.h" 33 34 #include "AccessibilityObject.h" 35 #include "CSSPrimitiveValueMappings.h" 36 #include "Document.h" 37 #include "EventHandler.h" 38 #include "FrameView.h" 39 #include "Node.h" 40 #include "PlatformKeyboardEvent.h" 41 #include "RenderStyle.h" 42 #include "UserGestureIndicator.h" 43 #include "WebDocument.h" 44 #include "WebNode.h" 45 #include "WebPoint.h" 46 #include "WebRect.h" 47 #include "WebString.h" 48 #include "WebURL.h" 49 50 using namespace WebCore; 51 52 namespace WebKit { 53 54 class WebAccessibilityObjectPrivate : public WebCore::AccessibilityObject { 55 }; 56 57 void WebAccessibilityObject::reset() 58 { 59 assign(0); 60 } 61 62 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other) 63 { 64 WebAccessibilityObjectPrivate* p = const_cast<WebAccessibilityObjectPrivate*>(other.m_private); 65 if (p) 66 p->ref(); 67 assign(p); 68 } 69 70 bool WebAccessibilityObject::equals(const WebAccessibilityObject& n) const 71 { 72 return (m_private == n.m_private); 73 } 74 75 WebString WebAccessibilityObject::accessibilityDescription() const 76 { 77 if (!m_private) 78 return WebString(); 79 80 m_private->updateBackingStore(); 81 return m_private->accessibilityDescription(); 82 } 83 84 WebString WebAccessibilityObject::actionVerb() const 85 { 86 if (!m_private) 87 return WebString(); 88 89 m_private->updateBackingStore(); 90 return m_private->actionVerb(); 91 } 92 93 bool WebAccessibilityObject::canSetFocusAttribute() const 94 { 95 if (!m_private) 96 return false; 97 98 m_private->updateBackingStore(); 99 return m_private->canSetFocusAttribute(); 100 } 101 102 bool WebAccessibilityObject::canSetValueAttribute() const 103 { 104 if (!m_private) 105 return false; 106 107 m_private->updateBackingStore(); 108 return m_private->canSetValueAttribute(); 109 } 110 111 bool WebAccessibilityObject::isValid() const 112 { 113 if (!m_private) 114 return false; 115 116 m_private->updateBackingStore(); 117 return m_private->axObjectID(); 118 } 119 120 unsigned WebAccessibilityObject::childCount() const 121 { 122 if (!m_private) 123 return 0; 124 125 m_private->updateBackingStore(); 126 return m_private->children().size(); 127 } 128 129 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const 130 { 131 if (!m_private) 132 return WebAccessibilityObject(); 133 134 m_private->updateBackingStore(); 135 if (m_private->children().size() <= index) 136 return WebAccessibilityObject(); 137 138 return WebAccessibilityObject(m_private->children()[index]); 139 } 140 141 WebAccessibilityObject WebAccessibilityObject::firstChild() const 142 { 143 if (!m_private) 144 return WebAccessibilityObject(); 145 146 m_private->updateBackingStore(); 147 return WebAccessibilityObject(m_private->firstChild()); 148 } 149 150 WebAccessibilityObject WebAccessibilityObject::focusedChild() const 151 { 152 if (!m_private) 153 return WebAccessibilityObject(); 154 155 m_private->updateBackingStore(); 156 RefPtr<AccessibilityObject> focused = m_private->focusedUIElement(); 157 if (m_private == focused.get() || focused->parentObject() == m_private) 158 return WebAccessibilityObject(focused); 159 160 return WebAccessibilityObject(); 161 } 162 163 WebAccessibilityObject WebAccessibilityObject::lastChild() const 164 { 165 if (!m_private) 166 return WebAccessibilityObject(); 167 168 m_private->updateBackingStore(); 169 return WebAccessibilityObject(m_private->lastChild()); 170 } 171 172 173 WebAccessibilityObject WebAccessibilityObject::nextSibling() const 174 { 175 if (!m_private) 176 return WebAccessibilityObject(); 177 178 m_private->updateBackingStore(); 179 return WebAccessibilityObject(m_private->nextSibling()); 180 } 181 182 WebAccessibilityObject WebAccessibilityObject::parentObject() const 183 { 184 if (!m_private) 185 return WebAccessibilityObject(); 186 187 m_private->updateBackingStore(); 188 return WebAccessibilityObject(m_private->parentObject()); 189 } 190 191 192 WebAccessibilityObject WebAccessibilityObject::previousSibling() const 193 { 194 if (!m_private) 195 return WebAccessibilityObject(); 196 197 m_private->updateBackingStore(); 198 return WebAccessibilityObject(m_private->previousSibling()); 199 } 200 201 bool WebAccessibilityObject::canSetSelectedAttribute() const 202 { 203 if (!m_private) 204 return 0; 205 206 m_private->updateBackingStore(); 207 return m_private->canSetSelectedAttribute(); 208 } 209 210 bool WebAccessibilityObject::isAnchor() const 211 { 212 if (!m_private) 213 return 0; 214 215 m_private->updateBackingStore(); 216 return m_private->isAnchor(); 217 } 218 219 bool WebAccessibilityObject::isChecked() const 220 { 221 if (!m_private) 222 return 0; 223 224 m_private->updateBackingStore(); 225 return m_private->isChecked(); 226 } 227 228 bool WebAccessibilityObject::isCollapsed() const 229 { 230 if (!m_private) 231 return 0; 232 233 m_private->updateBackingStore(); 234 return m_private->isCollapsed(); 235 } 236 237 238 bool WebAccessibilityObject::isFocused() const 239 { 240 if (!m_private) 241 return 0; 242 243 m_private->updateBackingStore(); 244 return m_private->isFocused(); 245 } 246 247 bool WebAccessibilityObject::isEnabled() const 248 { 249 if (!m_private) 250 return 0; 251 252 m_private->updateBackingStore(); 253 return m_private->isEnabled(); 254 } 255 256 bool WebAccessibilityObject::isHovered() const 257 { 258 if (!m_private) 259 return 0; 260 261 m_private->updateBackingStore(); 262 return m_private->isHovered(); 263 } 264 265 bool WebAccessibilityObject::isIndeterminate() const 266 { 267 if (!m_private) 268 return 0; 269 270 m_private->updateBackingStore(); 271 return m_private->isIndeterminate(); 272 } 273 274 bool WebAccessibilityObject::isLinked() const 275 { 276 if (!m_private) 277 return 0; 278 279 m_private->updateBackingStore(); 280 return m_private->isLinked(); 281 } 282 283 bool WebAccessibilityObject::isMultiSelectable() const 284 { 285 if (!m_private) 286 return 0; 287 288 m_private->updateBackingStore(); 289 return m_private->isMultiSelectable(); 290 } 291 292 bool WebAccessibilityObject::isOffScreen() const 293 { 294 if (!m_private) 295 return 0; 296 297 m_private->updateBackingStore(); 298 return m_private->isOffScreen(); 299 } 300 301 bool WebAccessibilityObject::isPasswordField() const 302 { 303 if (!m_private) 304 return 0; 305 306 m_private->updateBackingStore(); 307 return m_private->isPasswordField(); 308 } 309 310 bool WebAccessibilityObject::isPressed() const 311 { 312 if (!m_private) 313 return 0; 314 315 m_private->updateBackingStore(); 316 return m_private->isPressed(); 317 } 318 319 bool WebAccessibilityObject::isReadOnly() const 320 { 321 if (!m_private) 322 return 0; 323 324 m_private->updateBackingStore(); 325 return m_private->isReadOnly(); 326 } 327 328 bool WebAccessibilityObject::isSelected() const 329 { 330 if (!m_private) 331 return 0; 332 333 m_private->updateBackingStore(); 334 return m_private->isSelected(); 335 } 336 337 bool WebAccessibilityObject::isVisible() const 338 { 339 if (!m_private) 340 return 0; 341 342 m_private->updateBackingStore(); 343 return m_private->isVisible(); 344 } 345 346 bool WebAccessibilityObject::isVisited() const 347 { 348 if (!m_private) 349 return 0; 350 351 m_private->updateBackingStore(); 352 return m_private->isVisited(); 353 } 354 355 WebRect WebAccessibilityObject::boundingBoxRect() const 356 { 357 if (!m_private) 358 return WebRect(); 359 360 m_private->updateBackingStore(); 361 return m_private->boundingBoxRect(); 362 } 363 364 WebString WebAccessibilityObject::helpText() const 365 { 366 if (!m_private) 367 return WebString(); 368 369 m_private->updateBackingStore(); 370 return m_private->helpText(); 371 } 372 373 int WebAccessibilityObject::headingLevel() const 374 { 375 if (!m_private) 376 return 0; 377 378 m_private->updateBackingStore(); 379 return m_private->headingLevel(); 380 } 381 382 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const 383 { 384 if (!m_private) 385 return WebAccessibilityObject(); 386 387 m_private->updateBackingStore(); 388 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point); 389 RefPtr<AccessibilityObject> hit = m_private->accessibilityHitTest(contentsPoint); 390 391 if (hit.get()) 392 return WebAccessibilityObject(hit); 393 394 if (m_private->boundingBoxRect().contains(contentsPoint)) 395 return *this; 396 397 return WebAccessibilityObject(); 398 } 399 400 WebString WebAccessibilityObject::keyboardShortcut() const 401 { 402 if (!m_private) 403 return WebString(); 404 405 m_private->updateBackingStore(); 406 String accessKey = m_private->accessKey(); 407 if (accessKey.isNull()) 408 return WebString(); 409 410 static String modifierString; 411 if (modifierString.isNull()) { 412 unsigned modifiers = EventHandler::accessKeyModifiers(); 413 // Follow the same order as Mozilla MSAA implementation: 414 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings 415 // should not be localized and defines the separator as "+". 416 if (modifiers & PlatformKeyboardEvent::CtrlKey) 417 modifierString += "Ctrl+"; 418 if (modifiers & PlatformKeyboardEvent::AltKey) 419 modifierString += "Alt+"; 420 if (modifiers & PlatformKeyboardEvent::ShiftKey) 421 modifierString += "Shift+"; 422 if (modifiers & PlatformKeyboardEvent::MetaKey) 423 modifierString += "Win+"; 424 } 425 426 return modifierString + accessKey; 427 } 428 429 bool WebAccessibilityObject::performDefaultAction() const 430 { 431 if (!m_private) 432 return false; 433 434 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); 435 436 m_private->updateBackingStore(); 437 return m_private->performDefaultAction(); 438 } 439 440 WebAccessibilityRole WebAccessibilityObject::roleValue() const 441 { 442 if (!m_private) 443 return WebKit::WebAccessibilityRoleUnknown; 444 445 m_private->updateBackingStore(); 446 return static_cast<WebAccessibilityRole>(m_private->roleValue()); 447 } 448 449 void WebAccessibilityObject::setFocused(bool on) const 450 { 451 if (m_private) 452 m_private->setFocused(on); 453 } 454 455 WebString WebAccessibilityObject::stringValue() const 456 { 457 if (!m_private) 458 return WebString(); 459 460 m_private->updateBackingStore(); 461 return m_private->stringValue(); 462 } 463 464 WebString WebAccessibilityObject::title() const 465 { 466 if (!m_private) 467 return WebString(); 468 469 m_private->updateBackingStore(); 470 return m_private->title(); 471 } 472 473 WebURL WebAccessibilityObject::url() const 474 { 475 if (!m_private) 476 return WebURL(); 477 478 m_private->updateBackingStore(); 479 return m_private->url(); 480 } 481 482 WebNode WebAccessibilityObject::node() const 483 { 484 if (!m_private) 485 return WebNode(); 486 487 m_private->updateBackingStore(); 488 489 Node* node = m_private->node(); 490 if (!node) 491 return WebNode(); 492 493 return WebNode(node); 494 } 495 496 WebDocument WebAccessibilityObject::document() const 497 { 498 if (!m_private) 499 return WebDocument(); 500 501 m_private->updateBackingStore(); 502 503 Document* document = m_private->document(); 504 if (!document) 505 return WebDocument(); 506 507 return WebDocument(document); 508 } 509 510 bool WebAccessibilityObject::hasComputedStyle() const 511 { 512 Document* document = m_private->document(); 513 if (document) 514 document->updateStyleIfNeeded(); 515 516 Node* node = m_private->node(); 517 if (!node) 518 return false; 519 520 return node->computedStyle(); 521 } 522 523 WebString WebAccessibilityObject::computedStyleDisplay() const 524 { 525 Document* document = m_private->document(); 526 if (document) 527 document->updateStyleIfNeeded(); 528 529 Node* node = m_private->node(); 530 if (!node) 531 return WebString(); 532 533 RenderStyle* renderStyle = node->computedStyle(); 534 if (!renderStyle) 535 return WebString(); 536 537 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue()); 538 } 539 540 bool WebAccessibilityObject::accessibilityIsIgnored() const 541 { 542 m_private->updateBackingStore(); 543 return m_private->accessibilityIsIgnored(); 544 } 545 546 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 547 : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())) 548 { 549 } 550 551 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 552 { 553 assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())); 554 return *this; 555 } 556 557 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const 558 { 559 return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private)); 560 } 561 562 void WebAccessibilityObject::assign(WebAccessibilityObjectPrivate* p) 563 { 564 // p is already ref'd for us by the caller 565 if (m_private) 566 m_private->deref(); 567 m_private = p; 568 } 569 570 } // namespace WebKit 571