WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,631 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "AccessibilityUIElement.h"
+
+#include "AccessibilityController.h"
+#include "DumpRenderTree.h"
+#include "FrameLoadDelegate.h"
+#include <JavaScriptCore/JSStringRef.h>
+#include <tchar.h>
+#include <string>
+
+using std::wstring;
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+    : m_element(element)
+{
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+    : m_element(other.m_element)
+{
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+}
+
+void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>&)
+{
+}
+
+void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&)
+{
+}
+
+void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children)
+{
+    long childCount;
+    if (FAILED(m_element->get_accChildCount(&childCount)))
+        return;
+    for (long i = 0; i < childCount; ++i)
+        children.append(getChildAtIndex(i));
+}
+
+void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length)
+{
+    long childCount;
+    unsigned appendedCount = 0;
+    if (FAILED(m_element->get_accChildCount(&childCount)))
+        return;
+    for (long i = location; i < childCount && appendedCount < length; ++i, ++appendedCount)
+        elementVector.append(getChildAtIndex(i));
+}
+
+int AccessibilityUIElement::childrenCount()
+{
+    long childCount;
+    m_element->get_accChildCount(&childCount);
+    return childCount;
+}
+
+int AccessibilityUIElement::rowCount()
+{
+    // FIXME: implement
+    return 0;
+}
+ 
+int AccessibilityUIElement::columnCount()
+{
+    // FIXME: implement
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
+{
+    // FIXME: implement
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
+{
+    COMPtr<IDispatch> child;
+    VARIANT vChild;
+    ::VariantInit(&vChild);
+    V_VT(&vChild) = VT_I4;
+    // In MSAA, index 0 is the object itself.
+    V_I4(&vChild) = index + 1;
+    if (FAILED(m_element->get_accChild(vChild, &child)))
+        return 0;
+    return COMPtr<IAccessible>(Query, child);
+}
+
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
+{ 
+    // FIXME: implement
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::allAttributes()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+AccessibilityUIElement AccessibilityUIElement::titleUIElement()
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::parentElement()
+{
+    COMPtr<IDispatch> parent;
+    m_element->get_accParent(&parent);
+
+    COMPtr<IAccessible> parentAccessible(Query, parent);
+    return parentAccessible;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfChildren()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+static VARIANT& self()
+{
+    static VARIANT vSelf;
+    static bool haveInitialized;
+
+    if (!haveInitialized) {
+        ::VariantInit(&vSelf);
+        V_VT(&vSelf) = VT_I4;
+        V_I4(&vSelf) = CHILDID_SELF;
+    }
+    return vSelf;
+}
+
+JSStringRef AccessibilityUIElement::role()
+{
+    VARIANT vRole;
+    if (FAILED(m_element->get_accRole(self(), &vRole)))
+        return JSStringCreateWithCharacters(0, 0);
+
+    ASSERT(V_VT(&vRole) == VT_I4 || V_VT(&vRole) == VT_BSTR);
+
+    wstring result;
+    if (V_VT(&vRole) == VT_I4) {
+        unsigned roleTextLength = ::GetRoleText(V_I4(&vRole), 0, 0) + 1;
+
+        Vector<TCHAR> roleText(roleTextLength);
+
+        ::GetRoleText(V_I4(&vRole), roleText.data(), roleTextLength);
+
+        result = roleText.data();
+    } else if (V_VT(&vRole) == VT_BSTR)
+        result = wstring(V_BSTR(&vRole), ::SysStringLen(V_BSTR(&vRole)));
+
+    ::VariantClear(&vRole);
+
+    return JSStringCreateWithCharacters(result.data(), result.length());
+}
+
+JSStringRef AccessibilityUIElement::subrole()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::roleDescription()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::title()
+{
+    BSTR titleBSTR;
+    if (FAILED(m_element->get_accName(self(), &titleBSTR)) || !titleBSTR)
+        return JSStringCreateWithCharacters(0, 0);
+    wstring title(titleBSTR, SysStringLen(titleBSTR));
+    ::SysFreeString(titleBSTR);
+    return JSStringCreateWithCharacters(title.data(), title.length());
+}
+
+JSStringRef AccessibilityUIElement::description()
+{
+    BSTR descriptionBSTR;
+    if (FAILED(m_element->get_accDescription(self(), &descriptionBSTR)) || !descriptionBSTR)
+        return JSStringCreateWithCharacters(0, 0);
+    wstring description(descriptionBSTR, SysStringLen(descriptionBSTR));
+    ::SysFreeString(descriptionBSTR);
+    return JSStringCreateWithCharacters(description.data(), description.length());
+}
+
+JSStringRef AccessibilityUIElement::stringValue()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::language()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::helpText() const
+{
+    return 0;
+}
+
+double AccessibilityUIElement::x()
+{
+    long x, y, width, height;
+    if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+        return 0;
+    return x;
+}
+
+double AccessibilityUIElement::y()
+{
+    long x, y, width, height;
+    if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+        return 0;
+    return y;
+}
+
+double AccessibilityUIElement::width()
+{
+    long x, y, width, height;
+    if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+        return 0;
+    return width;
+}
+
+double AccessibilityUIElement::height()
+{
+    long x, y, width, height;
+    if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+        return 0;
+    return height;
+}
+
+double AccessibilityUIElement::clickPointX()
+{
+    return 0;
+}
+
+double AccessibilityUIElement::clickPointY()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::valueDescription()
+{
+    return 0;
+}
+
+static DWORD accessibilityState(COMPtr<IAccessible> element)
+{
+    VARIANT state;
+    element->get_accState(self(), &state);
+
+    ASSERT(V_VT(&state) == VT_I4);
+
+    DWORD result = state.lVal;
+    VariantClear(&state);
+
+    return result;
+}
+
+bool AccessibilityUIElement::isSelected() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_SELECTED) == STATE_SYSTEM_SELECTED;
+}
+
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+    return 0;
+}
+
+bool AccessibilityUIElement::ariaIsGrabbed() const
+{
+    return false;
+}
+ 
+JSStringRef AccessibilityUIElement::ariaDropEffects() const
+{
+    return 0;
+}
+
+bool AccessibilityUIElement::isExpanded() const
+{
+    return false;
+}
+
+bool AccessibilityUIElement::isChecked() const
+{
+    VARIANT vState;
+    if (FAILED(m_element->get_accState(self(), &vState)))
+        return false;
+
+    return vState.lVal & STATE_SYSTEM_CHECKED;
+}
+
+JSStringRef AccessibilityUIElement::orientation() const
+{
+    return 0;
+}
+
+double AccessibilityUIElement::intValue() const
+{
+    BSTR valueBSTR;
+    if (FAILED(m_element->get_accValue(self(), &valueBSTR)) || !valueBSTR)
+        return 0;
+    wstring value(valueBSTR, SysStringLen(valueBSTR));
+    ::SysFreeString(valueBSTR);
+    TCHAR* ignored;
+    return _tcstod(value.data(), &ignored);
+}
+
+double AccessibilityUIElement::minValue()
+{
+    return 0;
+}
+
+double AccessibilityUIElement::maxValue()
+{
+    return 0;
+}
+
+bool AccessibilityUIElement::isActionSupported(JSStringRef action)
+{
+    return false;
+}
+
+bool AccessibilityUIElement::isEnabled()
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_UNAVAILABLE) != STATE_SYSTEM_UNAVAILABLE;
+}
+
+bool AccessibilityUIElement::isRequired() const
+{
+    return false;
+}
+
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+int AccessibilityUIElement::lineForIndex(int)
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned)
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::selectedTextRange()
+{
+    return JSStringCreateWithCharacters(0, 0);    
+}
+
+void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
+{
+}
+
+JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
+{
+    // FIXME: implement
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+    // FIXME: implement
+    return false;
+}
+
+bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
+{
+    return false;
+}
+
+bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
+{
+    return false;
+}
+
+void AccessibilityUIElement::increment()
+{
+}
+
+void AccessibilityUIElement::decrement()
+{
+}
+
+void AccessibilityUIElement::showMenu()
+{
+    ASSERT(hasPopup());
+    m_element->accDoDefaultAction(self());
+}
+
+void AccessibilityUIElement::press()
+{
+    // FIXME: implement
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
+{
+    return 0;
+}
+
+JSStringRef AccessibilityUIElement::accessibilityValue() const
+{
+    BSTR valueBSTR;
+    if (FAILED(m_element->get_accValue(self(), &valueBSTR)) || !valueBSTR)
+        return JSStringCreateWithCharacters(0, 0);
+
+    wstring value(valueBSTR, SysStringLen(valueBSTR));
+    ::SysFreeString(valueBSTR);
+
+    return JSStringCreateWithCharacters(value.data(), value.length());
+}
+
+
+JSStringRef AccessibilityUIElement::documentEncoding()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::documentURI()
+{
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::url()
+{
+    // FIXME: implement
+    return JSStringCreateWithCharacters(0, 0);
+}
+
+bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
+{
+    if (!functionCallback)
+        return false;
+
+    sharedFrameLoadDelegate->accessibilityController()->addNotificationListener(m_element, functionCallback);
+    return true;
+}
+
+void AccessibilityUIElement::removeNotificationListener()
+{
+    // FIXME: implement
+}
+
+bool AccessibilityUIElement::isSelectable() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_SELECTABLE) == STATE_SYSTEM_SELECTABLE;
+}
+
+bool AccessibilityUIElement::isMultiSelectable() const
+{
+    DWORD multiSelectable = STATE_SYSTEM_EXTSELECTABLE | STATE_SYSTEM_MULTISELECTABLE;
+    DWORD state = accessibilityState(m_element);
+    return (state & multiSelectable) == multiSelectable;
+}
+
+bool AccessibilityUIElement::isVisible() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_INVISIBLE) != STATE_SYSTEM_INVISIBLE;
+}
+
+bool AccessibilityUIElement::isOffScreen() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_OFFSCREEN) == STATE_SYSTEM_OFFSCREEN;
+}
+
+bool AccessibilityUIElement::isCollapsed() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_COLLAPSED) == STATE_SYSTEM_COLLAPSED;
+}
+
+bool AccessibilityUIElement::hasPopup() const
+{
+    DWORD state = accessibilityState(m_element);
+    return (state & STATE_SYSTEM_HASPOPUP) == STATE_SYSTEM_HASPOPUP;
+}
+
+void AccessibilityUIElement::takeFocus()
+{
+    m_element->accSelect(SELFLAG_TAKEFOCUS, self());
+}
+
+void AccessibilityUIElement::takeSelection()
+{
+    m_element->accSelect(SELFLAG_TAKESELECTION, self());
+}
+
+void AccessibilityUIElement::addSelection()
+{
+    m_element->accSelect(SELFLAG_ADDSELECTION, self());
+}
+
+void AccessibilityUIElement::removeSelection()
+{
+    m_element->accSelect(SELFLAG_REMOVESELECTION, self());
+}