summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp b/src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp
new file mode 100644
index 0000000..d9c4c9a
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/AXObjectCache.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AXObjectCache.h"
+
+#include "AccessibilityList.h"
+#include "AccessibilityListBox.h"
+#include "AccessibilityListBoxOption.h"
+#include "AccessibilityImageMapLink.h"
+#include "AccessibilityRenderObject.h"
+#include "AccessibilityTable.h"
+#include "AccessibilityTableCell.h"
+#include "AccessibilityTableColumn.h"
+#include "AccessibilityTableHeaderContainer.h"
+#include "AccessibilityTableRow.h"
+#include "HTMLNames.h"
+#include "RenderObject.h"
+
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+bool AXObjectCache::gAccessibilityEnabled = false;
+bool AXObjectCache::gAccessibilityEnhancedUserInterfaceEnabled = false;
+
+AXObjectCache::~AXObjectCache()
+{
+ HashMap<AXID, RefPtr<AccessibilityObject> >::iterator end = m_objects.end();
+ for (HashMap<AXID, RefPtr<AccessibilityObject> >::iterator it = m_objects.begin(); it != end; ++it) {
+ AccessibilityObject* obj = (*it).second.get();
+ detachWrapper(obj);
+ obj->detach();
+ }
+}
+
+AccessibilityObject* AXObjectCache::get(RenderObject* renderer)
+{
+ if (!renderer)
+ return 0;
+
+ RefPtr<AccessibilityObject> obj = 0;
+ AXID axID = m_renderObjectMapping.get(renderer);
+ ASSERT(!HashTraits<AXID>::isDeletedValue(axID));
+
+ if (axID)
+ obj = m_objects.get(axID).get();
+
+ Node* element = renderer->element();
+ if (!obj) {
+ if (renderer->isListBox())
+ obj = AccessibilityListBox::create(renderer);
+ else if (element && (element->hasTagName(ulTag) || element->hasTagName(olTag) || element->hasTagName(dlTag)))
+ obj = AccessibilityList::create(renderer);
+ else if (renderer->isTable())
+ obj = AccessibilityTable::create(renderer);
+ else if (renderer->isTableRow())
+ obj = AccessibilityTableRow::create(renderer);
+ else if (renderer->isTableCell())
+ obj = AccessibilityTableCell::create(renderer);
+ else
+ obj = AccessibilityRenderObject::create(renderer);
+
+ getAXID(obj.get());
+
+ m_renderObjectMapping.set(renderer, obj.get()->axObjectID());
+ m_objects.set(obj.get()->axObjectID(), obj);
+ attachWrapper(obj.get());
+ }
+
+ return obj.get();
+}
+
+AccessibilityObject* AXObjectCache::get(AccessibilityRole role)
+{
+ RefPtr<AccessibilityObject> obj = 0;
+
+ // will be filled in...
+ switch (role) {
+ case ListBoxOptionRole:
+ obj = AccessibilityListBoxOption::create();
+ break;
+ case ImageMapLinkRole:
+ obj = AccessibilityImageMapLink::create();
+ break;
+ case ColumnRole:
+ obj = AccessibilityTableColumn::create();
+ break;
+ case TableHeaderContainerRole:
+ obj = AccessibilityTableHeaderContainer::create();
+ break;
+ default:
+ obj = 0;
+ }
+
+ if (obj)
+ getAXID(obj.get());
+ else
+ return 0;
+
+ m_objects.set(obj->axObjectID(), obj);
+ attachWrapper(obj.get());
+ return obj.get();
+}
+
+void AXObjectCache::remove(AXID axID)
+{
+ if (!axID)
+ return;
+
+ // first fetch object to operate some cleanup functions on it
+ AccessibilityObject* obj = m_objects.get(axID).get();
+ if (!obj)
+ return;
+
+ detachWrapper(obj);
+ obj->detach();
+ removeAXID(obj);
+
+ // finally remove the object
+ if (!m_objects.take(axID)) {
+ return;
+ }
+
+ ASSERT(m_objects.size() >= m_idsInUse.size());
+}
+
+void AXObjectCache::remove(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+
+ AXID axID = m_renderObjectMapping.get(renderer);
+ remove(axID);
+ m_renderObjectMapping.remove(renderer);
+}
+
+AXID AXObjectCache::getAXID(AccessibilityObject* obj)
+{
+ // check for already-assigned ID
+ AXID objID = obj->axObjectID();
+ if (objID) {
+ ASSERT(m_idsInUse.contains(objID));
+ return objID;
+ }
+
+ // generate a new ID
+ static AXID lastUsedID = 0;
+ objID = lastUsedID;
+ do
+ ++objID;
+ while (objID == 0 || HashTraits<AXID>::isDeletedValue(objID) || m_idsInUse.contains(objID));
+ m_idsInUse.add(objID);
+ lastUsedID = objID;
+ obj->setAXObjectID(objID);
+
+ return objID;
+}
+
+void AXObjectCache::removeAXID(AccessibilityObject* obj)
+{
+ AXID objID = obj->axObjectID();
+ if (objID == 0)
+ return;
+ ASSERT(!HashTraits<AXID>::isDeletedValue(objID));
+ ASSERT(m_idsInUse.contains(objID));
+ obj->setAXObjectID(0);
+ m_idsInUse.remove(objID);
+}
+
+void AXObjectCache::childrenChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+
+ AXID axID = m_renderObjectMapping.get(renderer);
+ if (!axID)
+ return;
+
+ AccessibilityObject* obj = m_objects.get(axID).get();
+ if (obj)
+ obj->childrenChanged();
+}
+
+#if HAVE(ACCESSIBILITY)
+void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
+{
+ postNotificationToElement(renderer, "AXSelectedChildrenChanged");
+}
+#endif
+
+#if HAVE(ACCESSIBILITY)
+void AXObjectCache::handleActiveDescendantChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+ AccessibilityObject* obj = get(renderer);
+ if (obj)
+ obj->handleActiveDescendantChanged();
+}
+
+void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+ AccessibilityObject* obj = get(renderer);
+ if (obj && obj->isAccessibilityRenderObject())
+ static_cast<AccessibilityRenderObject*>(obj)->setAriaRole();
+}
+#endif
+
+} // namespace WebCore