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 "EventHandler.h" 36 #include "FrameView.h" 37 #include "PlatformKeyboardEvent.h" 38 #include "WebPoint.h" 39 #include "WebRect.h" 40 #include "WebString.h" 41 42 using namespace WebCore; 43 44 namespace WebKit { 45 46 class WebAccessibilityObjectPrivate : public WebCore::AccessibilityObject { 47 }; 48 49 void WebAccessibilityObject::reset() 50 { 51 assign(0); 52 } 53 54 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other) 55 { 56 WebAccessibilityObjectPrivate* p = const_cast<WebAccessibilityObjectPrivate*>(other.m_private); 57 if (p) 58 p->ref(); 59 assign(p); 60 } 61 62 WebString WebAccessibilityObject::accessibilityDescription() const 63 { 64 if (!m_private) 65 return WebString(); 66 67 m_private->updateBackingStore(); 68 return m_private->accessibilityDescription(); 69 } 70 71 WebString WebAccessibilityObject::actionVerb() const 72 { 73 if (!m_private) 74 return WebString(); 75 76 m_private->updateBackingStore(); 77 return m_private->actionVerb(); 78 } 79 80 bool WebAccessibilityObject::canSetFocusAttribute() const 81 { 82 if (!m_private) 83 return false; 84 85 m_private->updateBackingStore(); 86 return m_private->canSetFocusAttribute(); 87 } 88 89 bool WebAccessibilityObject::canSetValueAttribute() const 90 { 91 if (!m_private) 92 return false; 93 94 m_private->updateBackingStore(); 95 return m_private->canSetValueAttribute(); 96 } 97 98 unsigned WebAccessibilityObject::childCount() const 99 { 100 if (!m_private) 101 return 0; 102 103 m_private->updateBackingStore(); 104 return m_private->children().size(); 105 } 106 107 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const 108 { 109 if (!m_private) 110 return WebAccessibilityObject(); 111 112 m_private->updateBackingStore(); 113 if (m_private->children().size() <= index) 114 return WebAccessibilityObject(); 115 116 return WebAccessibilityObject(m_private->children()[index]); 117 } 118 119 WebAccessibilityObject WebAccessibilityObject::firstChild() const 120 { 121 if (!m_private) 122 return WebAccessibilityObject(); 123 124 m_private->updateBackingStore(); 125 return WebAccessibilityObject(m_private->firstChild()); 126 } 127 128 WebAccessibilityObject WebAccessibilityObject::focusedChild() const 129 { 130 if (!m_private) 131 return WebAccessibilityObject(); 132 133 m_private->updateBackingStore(); 134 RefPtr<AccessibilityObject> focused = m_private->focusedUIElement(); 135 if (m_private == focused.get() || focused->parentObject() == m_private) 136 return WebAccessibilityObject(focused); 137 138 return WebAccessibilityObject(); 139 } 140 141 WebAccessibilityObject WebAccessibilityObject::lastChild() const 142 { 143 if (!m_private) 144 return WebAccessibilityObject(); 145 146 m_private->updateBackingStore(); 147 return WebAccessibilityObject(m_private->lastChild()); 148 } 149 150 151 WebAccessibilityObject WebAccessibilityObject::nextSibling() const 152 { 153 if (!m_private) 154 return WebAccessibilityObject(); 155 156 m_private->updateBackingStore(); 157 return WebAccessibilityObject(m_private->nextSibling()); 158 } 159 160 WebAccessibilityObject WebAccessibilityObject::parentObject() const 161 { 162 if (!m_private) 163 return WebAccessibilityObject(); 164 165 m_private->updateBackingStore(); 166 return WebAccessibilityObject(m_private->parentObject()); 167 } 168 169 170 WebAccessibilityObject WebAccessibilityObject::previousSibling() const 171 { 172 if (!m_private) 173 return WebAccessibilityObject(); 174 175 m_private->updateBackingStore(); 176 return WebAccessibilityObject(m_private->previousSibling()); 177 } 178 179 bool WebAccessibilityObject::isAnchor() const 180 { 181 if (!m_private) 182 return 0; 183 184 m_private->updateBackingStore(); 185 return m_private->isAnchor(); 186 } 187 188 bool WebAccessibilityObject::isChecked() const 189 { 190 if (!m_private) 191 return 0; 192 193 m_private->updateBackingStore(); 194 return m_private->isChecked(); 195 } 196 197 198 bool WebAccessibilityObject::isFocused() const 199 { 200 if (!m_private) 201 return 0; 202 203 m_private->updateBackingStore(); 204 return m_private->isFocused(); 205 } 206 207 bool WebAccessibilityObject::isEnabled() const 208 { 209 if (!m_private) 210 return 0; 211 212 m_private->updateBackingStore(); 213 return m_private->isEnabled(); 214 } 215 216 bool WebAccessibilityObject::isHovered() const 217 { 218 if (!m_private) 219 return 0; 220 221 m_private->updateBackingStore(); 222 return m_private->isHovered(); 223 } 224 225 bool WebAccessibilityObject::isIndeterminate() const 226 { 227 if (!m_private) 228 return 0; 229 230 m_private->updateBackingStore(); 231 return m_private->isIndeterminate(); 232 } 233 234 bool WebAccessibilityObject::isMultiSelectable() const 235 { 236 if (!m_private) 237 return 0; 238 239 m_private->updateBackingStore(); 240 return m_private->isMultiSelectable(); 241 } 242 243 bool WebAccessibilityObject::isOffScreen() const 244 { 245 if (!m_private) 246 return 0; 247 248 m_private->updateBackingStore(); 249 return m_private->isOffScreen(); 250 } 251 252 bool WebAccessibilityObject::isPasswordField() const 253 { 254 if (!m_private) 255 return 0; 256 257 m_private->updateBackingStore(); 258 return m_private->isPasswordField(); 259 } 260 261 bool WebAccessibilityObject::isPressed() const 262 { 263 if (!m_private) 264 return 0; 265 266 m_private->updateBackingStore(); 267 return m_private->isPressed(); 268 } 269 270 bool WebAccessibilityObject::isReadOnly() const 271 { 272 if (!m_private) 273 return 0; 274 275 m_private->updateBackingStore(); 276 return m_private->isReadOnly(); 277 } 278 279 bool WebAccessibilityObject::isVisited() const 280 { 281 if (!m_private) 282 return 0; 283 284 m_private->updateBackingStore(); 285 return m_private->isVisited(); 286 } 287 288 WebRect WebAccessibilityObject::boundingBoxRect() const 289 { 290 if (!m_private) 291 return WebRect(); 292 293 m_private->updateBackingStore(); 294 return m_private->documentFrameView()->contentsToWindow(m_private->boundingBoxRect()); 295 } 296 297 WebString WebAccessibilityObject::helpText() const 298 { 299 if (!m_private) 300 return WebString(); 301 302 m_private->updateBackingStore(); 303 return m_private->helpText(); 304 } 305 306 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const 307 { 308 if (!m_private) 309 return WebAccessibilityObject(); 310 311 m_private->updateBackingStore(); 312 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point); 313 RefPtr<AccessibilityObject> hit = m_private->doAccessibilityHitTest(contentsPoint); 314 315 if (hit.get()) 316 return WebAccessibilityObject(hit); 317 318 if (m_private->boundingBoxRect().contains(contentsPoint)) 319 return *this; 320 321 return WebAccessibilityObject(); 322 } 323 324 WebString WebAccessibilityObject::keyboardShortcut() const 325 { 326 if (!m_private) 327 return WebString(); 328 329 m_private->updateBackingStore(); 330 String accessKey = m_private->accessKey(); 331 if (accessKey.isNull()) 332 return WebString(); 333 334 static String modifierString; 335 if (modifierString.isNull()) { 336 unsigned modifiers = EventHandler::accessKeyModifiers(); 337 // Follow the same order as Mozilla MSAA implementation: 338 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings 339 // should not be localized and defines the separator as "+". 340 if (modifiers & PlatformKeyboardEvent::CtrlKey) 341 modifierString += "Ctrl+"; 342 if (modifiers & PlatformKeyboardEvent::AltKey) 343 modifierString += "Alt+"; 344 if (modifiers & PlatformKeyboardEvent::ShiftKey) 345 modifierString += "Shift+"; 346 if (modifiers & PlatformKeyboardEvent::MetaKey) 347 modifierString += "Win+"; 348 } 349 350 return modifierString + accessKey; 351 } 352 353 bool WebAccessibilityObject::performDefaultAction() const 354 { 355 if (!m_private) 356 return false; 357 358 m_private->updateBackingStore(); 359 return m_private->performDefaultAction(); 360 } 361 362 WebAccessibilityRole WebAccessibilityObject::roleValue() const 363 { 364 if (!m_private) 365 return WebKit::WebAccessibilityRoleUnknown; 366 367 m_private->updateBackingStore(); 368 return static_cast<WebAccessibilityRole>(m_private->roleValue()); 369 } 370 371 WebString WebAccessibilityObject::stringValue() const 372 { 373 if (!m_private) 374 return WebString(); 375 376 m_private->updateBackingStore(); 377 return m_private->stringValue(); 378 } 379 380 WebString WebAccessibilityObject::title() const 381 { 382 if (!m_private) 383 return WebString(); 384 385 m_private->updateBackingStore(); 386 return m_private->title(); 387 } 388 389 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 390 : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())) 391 { 392 } 393 394 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 395 { 396 assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())); 397 return *this; 398 } 399 400 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const 401 { 402 return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private)); 403 } 404 405 void WebAccessibilityObject::assign(WebAccessibilityObjectPrivate* p) 406 { 407 // p is already ref'd for us by the caller 408 if (m_private) 409 m_private->deref(); 410 m_private = p; 411 } 412 413 } // namespace WebKit 414