18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AXObjectCache.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AccessibilityObject.h" 31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Document.h" 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Page.h" 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderObject.h" 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockusing namespace std; 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AXObjectCache::detachWrapper(AccessibilityObject* obj) 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // On Windows, AccessibilityObjects are created when get_accChildCount is 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // called, but they are not wrapped until get_accChild is called, so this 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // object may not have a wrapper. 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (AccessibilityObjectWrapper* wrapper = obj->wrapper()) 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project wrapper->detach(); 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AXObjectCache::attachWrapper(AccessibilityObject*) 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // On Windows, AccessibilityObjects are wrapped when the accessibility 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // software requests them via get_accChild. 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid AXObjectCache::handleScrolledToAnchor(const Node* anchorNode) 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // The anchor node may not be accessible. Post the notification for the 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // first accessible object. 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block postPlatformNotification(AccessibilityObject::firstAccessibleObjectFromNode(anchorNode), AXScrolledToAnchor); 60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotification notification) 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!obj) 65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Document* document = obj->document(); 68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!document) 69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Page* page = document->page(); 72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!page || !page->chrome()->platformPageClient()) 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DWORD msaaEvent; 76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (notification) { 77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case AXFocusedUIElementChanged: 78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case AXActiveDescendantChanged: 79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block msaaEvent = EVENT_OBJECT_FOCUS; 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case AXScrolledToAnchor: 83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block msaaEvent = EVENT_SYSTEM_SCROLLINGSTART; 84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 86d0825bca7fe65beaee391d30da42e937db621564Steve Block case AXValueChanged: 87d0825bca7fe65beaee391d30da42e937db621564Steve Block case AXMenuListValueChanged: 88d0825bca7fe65beaee391d30da42e937db621564Steve Block msaaEvent = EVENT_OBJECT_VALUECHANGE; 89d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 90d0825bca7fe65beaee391d30da42e937db621564Steve Block 91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Windows will end up calling get_accChild() on the root accessible 96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // object for the WebView, passing the child ID that we specify below. We 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // negate the AXID so we know that the caller is passing the ID of an 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // element, not the index of a child element. 99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(obj->axObjectID() >= 1); 101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(obj->axObjectID() <= numeric_limits<LONG>::max()); 102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NotifyWinEvent(msaaEvent, page->chrome()->platformPageClient(), OBJID_CLIENT, -static_cast<LONG>(obj->axObjectID())); 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 106bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) 107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 108bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 109bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockAXID AXObjectCache::platformGenerateAXID() const 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static AXID lastUsedID = 0; 113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Generate a new ID. Windows accessibility relies on a positive AXID, 115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // ranging from 1 to LONG_MAX. 116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block AXID objID = lastUsedID; 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block do { 118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ++objID; 119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block objID %= std::numeric_limits<LONG>::max(); 120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } while (objID == 0 || HashTraits<AXID>::isDeletedValue(objID) || m_idsInUse.contains(objID)); 121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(objID >= 1 && objID <= std::numeric_limits<LONG>::max()); 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block lastUsedID = objID; 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return objID; 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject* newFocusedRenderer) 130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!newFocusedRenderer) 132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Page* page = newFocusedRenderer->document()->page(); 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!page || !page->chrome()->platformPageClient()) 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block AccessibilityObject* focusedObject = focusedUIElementForPage(page); 139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!focusedObject) 140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!focusedObject->accessibilityIsIgnored()); 143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block postPlatformNotification(focusedObject, AXFocusedUIElementChanged); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 148