--- /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());
+}