diff -r 000000000000 -r 4f2f89ce4247 WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp --- /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 +#include +#include + +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&) +{ +} + +void AccessibilityUIElement::getDocumentLinks(Vector&) +{ +} + +void AccessibilityUIElement::getChildren(Vector& 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& 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 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(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 parent; + m_element->get_accParent(&parent); + + COMPtr 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 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 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()); +}