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 42using namespace WebCore; 43 44namespace WebKit { 45 46class WebAccessibilityObjectPrivate : public WebCore::AccessibilityObject { 47}; 48 49void WebAccessibilityObject::reset() 50{ 51 assign(0); 52} 53 54void 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 62WebString WebAccessibilityObject::accessibilityDescription() const 63{ 64 if (!m_private) 65 return WebString(); 66 67 m_private->updateBackingStore(); 68 return m_private->accessibilityDescription(); 69} 70 71WebString WebAccessibilityObject::actionVerb() const 72{ 73 if (!m_private) 74 return WebString(); 75 76 m_private->updateBackingStore(); 77 return m_private->actionVerb(); 78} 79 80bool WebAccessibilityObject::canSetFocusAttribute() const 81{ 82 if (!m_private) 83 return false; 84 85 m_private->updateBackingStore(); 86 return m_private->canSetFocusAttribute(); 87} 88 89bool WebAccessibilityObject::canSetValueAttribute() const 90{ 91 if (!m_private) 92 return false; 93 94 m_private->updateBackingStore(); 95 return m_private->canSetValueAttribute(); 96} 97 98unsigned WebAccessibilityObject::childCount() const 99{ 100 if (!m_private) 101 return 0; 102 103 m_private->updateBackingStore(); 104 return m_private->children().size(); 105} 106 107WebAccessibilityObject 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 119WebAccessibilityObject WebAccessibilityObject::firstChild() const 120{ 121 if (!m_private) 122 return WebAccessibilityObject(); 123 124 m_private->updateBackingStore(); 125 return WebAccessibilityObject(m_private->firstChild()); 126} 127 128WebAccessibilityObject 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 141WebAccessibilityObject 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 151WebAccessibilityObject WebAccessibilityObject::nextSibling() const 152{ 153 if (!m_private) 154 return WebAccessibilityObject(); 155 156 m_private->updateBackingStore(); 157 return WebAccessibilityObject(m_private->nextSibling()); 158} 159 160WebAccessibilityObject 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 170WebAccessibilityObject WebAccessibilityObject::previousSibling() const 171{ 172 if (!m_private) 173 return WebAccessibilityObject(); 174 175 m_private->updateBackingStore(); 176 return WebAccessibilityObject(m_private->previousSibling()); 177} 178 179bool WebAccessibilityObject::isAnchor() const 180{ 181 if (!m_private) 182 return 0; 183 184 m_private->updateBackingStore(); 185 return m_private->isAnchor(); 186} 187 188bool WebAccessibilityObject::isChecked() const 189{ 190 if (!m_private) 191 return 0; 192 193 m_private->updateBackingStore(); 194 return m_private->isChecked(); 195} 196 197 198bool WebAccessibilityObject::isFocused() const 199{ 200 if (!m_private) 201 return 0; 202 203 m_private->updateBackingStore(); 204 return m_private->isFocused(); 205} 206 207bool WebAccessibilityObject::isEnabled() const 208{ 209 if (!m_private) 210 return 0; 211 212 m_private->updateBackingStore(); 213 return m_private->isEnabled(); 214} 215 216bool WebAccessibilityObject::isHovered() const 217{ 218 if (!m_private) 219 return 0; 220 221 m_private->updateBackingStore(); 222 return m_private->isHovered(); 223} 224 225bool WebAccessibilityObject::isIndeterminate() const 226{ 227 if (!m_private) 228 return 0; 229 230 m_private->updateBackingStore(); 231 return m_private->isIndeterminate(); 232} 233 234bool WebAccessibilityObject::isMultiSelectable() const 235{ 236 if (!m_private) 237 return 0; 238 239 m_private->updateBackingStore(); 240 return m_private->isMultiSelectable(); 241} 242 243bool WebAccessibilityObject::isOffScreen() const 244{ 245 if (!m_private) 246 return 0; 247 248 m_private->updateBackingStore(); 249 return m_private->isOffScreen(); 250} 251 252bool WebAccessibilityObject::isPasswordField() const 253{ 254 if (!m_private) 255 return 0; 256 257 m_private->updateBackingStore(); 258 return m_private->isPasswordField(); 259} 260 261bool WebAccessibilityObject::isPressed() const 262{ 263 if (!m_private) 264 return 0; 265 266 m_private->updateBackingStore(); 267 return m_private->isPressed(); 268} 269 270bool WebAccessibilityObject::isReadOnly() const 271{ 272 if (!m_private) 273 return 0; 274 275 m_private->updateBackingStore(); 276 return m_private->isReadOnly(); 277} 278 279bool WebAccessibilityObject::isVisited() const 280{ 281 if (!m_private) 282 return 0; 283 284 m_private->updateBackingStore(); 285 return m_private->isVisited(); 286} 287 288WebRect 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 297WebString WebAccessibilityObject::helpText() const 298{ 299 if (!m_private) 300 return WebString(); 301 302 m_private->updateBackingStore(); 303 return m_private->helpText(); 304} 305 306WebAccessibilityObject 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 324WebString 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 353bool WebAccessibilityObject::performDefaultAction() const 354{ 355 if (!m_private) 356 return false; 357 358 m_private->updateBackingStore(); 359 return m_private->performDefaultAction(); 360} 361 362WebAccessibilityRole 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 371WebString WebAccessibilityObject::stringValue() const 372{ 373 if (!m_private) 374 return WebString(); 375 376 m_private->updateBackingStore(); 377 return m_private->stringValue(); 378} 379 380WebString WebAccessibilityObject::title() const 381{ 382 if (!m_private) 383 return WebString(); 384 385 m_private->updateBackingStore(); 386 return m_private->title(); 387} 388 389WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 390 : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())) 391{ 392} 393 394WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) 395{ 396 assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())); 397 return *this; 398} 399 400WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const 401{ 402 return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private)); 403} 404 405void 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