<https://bugs.webkit.org/show_bug.cgi?id=119829> Add IAccessibleText and IAccessibleE...
authorroger_fong@apple.com <roger_fong@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Aug 2013 19:01:23 +0000 (19:01 +0000)
committerroger_fong@apple.com <roger_fong@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Aug 2013 19:01:23 +0000 (19:01 +0000)
Reviewed by Chris Fleizach.

* AccessibleBase.cpp:
(AccessibleBase::createInstance): Create an AccessibleText instance when necessary.
(AccessibleBase::QueryService):
* AccessibleBase.h:
* AccessibleTextImpl.cpp: Added.
(AccessibleText::AccessibleText):
(AccessibleText::addSelection):
(AccessibleText::get_attributes): Not Implemented
(AccessibleText::get_caretOffset):
(AccessibleText::get_characterExtents):
(AccessibleText::get_nSelections):
(AccessibleText::get_offsetAtPoint):
(AccessibleText::get_selection):
(AccessibleText::get_text):
(AccessibleText::get_textBeforeOffset): Not Implemented
(AccessibleText::get_textAfterOffset): Not Implemented
(AccessibleText::get_textAtOffset): Not Implemented
(AccessibleText::removeSelection):
(AccessibleText::setCaretOffset):
(AccessibleText::setSelection):
(AccessibleText::get_nCharacters):
(AccessibleText::scrollSubstringTo):
(AccessibleText::scrollSubstringToPoint):
(AccessibleText::get_newText): Not Implemented
(AccessibleText::get_oldText): Not Implemented
(AccessibleText::get_attributeRange): Not Implemented
(AccessibleText::copyText):
(AccessibleText::deleteText):
(AccessibleText::insertText):
(AccessibleText::cutText):
(AccessibleText::pasteText):
(AccessibleText::replaceText):
(AccessibleText::setAttributes): Not Implemented
(AccessibleText::QueryInterface):
(AccessibleText::Release):
(AccessibleText::convertSpecialOffset):
(AccessibleText::initialCheck):
* AccessibleTextImpl.h: Added.
(AccessibleText::~AccessibleText):
(AccessibleText::AddRef):
* WebKit.vcxproj/Interfaces/Interfaces.vcxproj:
* WebKit.vcxproj/Interfaces/Interfaces.vcxproj.filters:
* WebKit.vcxproj/WebKit/WebKit.vcxproj:
* WebKit.vcxproj/WebKit/WebKit.vcxproj.filters:
* WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj:
* WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj.filters:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@154627 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebKit/ChangeLog
Source/WebKit/WebKit.vcxproj/Interfaces/Interfaces.vcxproj
Source/WebKit/WebKit.vcxproj/Interfaces/Interfaces.vcxproj.filters
Source/WebKit/WebKit.vcxproj/WebKit/WebKit.vcxproj
Source/WebKit/WebKit.vcxproj/WebKit/WebKit.vcxproj.filters
Source/WebKit/WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj
Source/WebKit/WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj.filters
Source/WebKit/win/AccessibleBase.cpp
Source/WebKit/win/AccessibleBase.h
Source/WebKit/win/AccessibleTextImpl.cpp [new file with mode: 0644]
Source/WebKit/win/AccessibleTextImpl.h [new file with mode: 0644]
Source/WebKit/win/ChangeLog

index 4d5e4e58b46ce916d439ab5115d22558db9cbd11..d916b97c8f24a524e48cb298c151b3368d2684ca 100644 (file)
@@ -1,3 +1,16 @@
+2013-08-21  Roger Fong  <roger_fong@apple.com>
+
+        <https://bugs.webkit.org/show_bug.cgi?id=119829> IAccessibleText and IAccessibleEditableText implementation for AppleWindows port.
+
+        Reviewed by Chris Fleizach.
+
+        * WebKit.vcxproj/Interfaces/Interfaces.vcxproj:
+        * WebKit.vcxproj/Interfaces/Interfaces.vcxproj.filters:
+        * WebKit.vcxproj/WebKit/WebKit.vcxproj:
+        * WebKit.vcxproj/WebKit/WebKit.vcxproj.filters:
+        * WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj:
+        * WebKit.vcxproj/WebKitGUID/WebKitGUID.vcxproj.filters:
+
 2013-08-26  Brent Fulgham  <bfulgham@apple.com>
 
         [Windows] Build fix after r154541.
index 15616064c92d39207647d7a94541a3b59885e214..417fea7128347bdbbb257b20a7ee3f9c32e06b30 100644 (file)
     <Midl Include="..\..\win\Interfaces\Accessible2\Accessible2.idl" />\r
     <Midl Include="..\..\win\Interfaces\Accessible2\Accessible2_2.idl" />\r
     <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleApplication.idl" />\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleEditableText.idl" />\r
     <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleRelation.idl" />\r
     <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleStates.idl" />\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleText.idl" />\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleText2.idl" />\r
     <Midl Include="..\..\win\Interfaces\AccessibleComparable.idl">\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
index e0043b2a59da21b5d5f7fcfe7e8966692696bf90..ca26898b4b6e0b57cd3eb5d5e5d30ef032f8adac 100644 (file)
     <Midl Include="..\..\win\Interfaces\AccessibilityDelegate.idl">\r
       <Filter>IDL</Filter>\r
     </Midl>\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleText.idl">\r
+      <Filter>IDL\Accessibility2</Filter>\r
+    </Midl>\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleText2.idl">\r
+      <Filter>IDL\Accessibility2</Filter>\r
+    </Midl>\r
+    <Midl Include="..\..\win\Interfaces\Accessible2\AccessibleEditableText.idl">\r
+      <Filter>IDL\Accessibility2</Filter>\r
+    </Midl>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="InterfacesPostBuild.cmd" />\r
index f0ef567b3aa9be3e692006d74e9d59aeedeb6d47..f9364bdf753175713cbc0183c5bb9e6116817a20 100644 (file)
     <ClCompile Include="..\..\win\AccessibleBase.cpp" />\r
     <ClCompile Include="..\..\win\AccessibleDocument.cpp" />\r
     <ClCompile Include="..\..\win\AccessibleImage.cpp" />\r
+    <ClCompile Include="..\..\win\AccessibleTextImpl.cpp" />\r
     <ClCompile Include="..\..\win\CFDictionaryPropertyBag.cpp" />\r
     <ClCompile Include="..\..\win\DefaultDownloadDelegate.cpp" />\r
     <ClCompile Include="..\..\win\DefaultPolicyDelegate.cpp" />\r
     <ClInclude Include="..\..\win\AccessibleBase.h" />\r
     <ClInclude Include="..\..\win\AccessibleDocument.h" />\r
     <ClInclude Include="..\..\win\AccessibleImage.h" />\r
+    <ClInclude Include="..\..\win\AccessibleTextImpl.h" />\r
     <ClInclude Include="..\..\win\CFDictionaryPropertyBag.h" />\r
     <ClInclude Include="..\..\win\CodeAnalysisConfig.h" />\r
     <ClInclude Include="..\..\win\COMEnumVariant.h" />\r
index f2892d69a7c3b7bcc0d4ba00316266b9b1026025..e66424579a8992184826b3d95d907ea73a04d663 100644 (file)
     <ClCompile Include="..\..\cf\WebCoreSupport\WebInspectorClientCF.cpp">\r
       <Filter>WebCoreSupport</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\win\AccessibleTextImpl.cpp">\r
+      <Filter>Sources</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\win\WebCoreSupport\EmbeddedWidget.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\win\WebKitPrefix.h" />\r
+    <ClInclude Include="..\..\win\AccessibleTextImpl.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="WebKitPostBuild.cmd" />\r
       <Filter>Resources</Filter>\r
     </ResourceCompile>\r
   </ItemGroup>\r
-</Project>\r
+</Project>
\ No newline at end of file
index 1ef0c3f05b5cbe35de60f3a183d38c9c206ca09b..7c22997bd5780b414e3f71024577331a749e9f15 100644 (file)
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\Accessible2_2_i.c" />\r
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\AccessibleApplication_i.c" />\r
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\AccessibleRelation_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleEditableText_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleText2_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleText_i.c" />\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
index b5147148c189f3c0784f2c660fae38913716a0b3..1cb8eee09ee5bc2e77e6faa05434186322962eb0 100644 (file)
@@ -10,5 +10,8 @@
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\Accessible2_2_i.c" />\r
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\AccessibleApplication_i.c" />\r
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\WebKit\Interfaces\AccessibleRelation_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleEditableText_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleText_i.c" />\r
+    <ClCompile Include="..\..\..\..\WebKitBuild\Release\obj32\WebKit\Interfaces\AccessibleText2_i.c" />\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 4fc0c6ffc4e35c5d21d7e4dd8aba3cae3a68e5f9..2201c9b1d786873dbc38f8040f85db9285e13376 100644 (file)
@@ -29,6 +29,7 @@
 #include "AccessibleBase.h"
 
 #include "AccessibleImage.h"
+#include "AccessibleTextImpl.h"
 #include "WebView.h"
 #include <WebCore/AccessibilityListBox.h>
 #include <WebCore/AccessibilityMenuListPopup.h>
@@ -78,6 +79,8 @@ AccessibleBase* AccessibleBase::createInstance(AccessibilityObject* obj, HWND wi
 
     if (obj->isImage())
         return new AccessibleImage(obj, window);
+    else if (obj->isStaticText() || obj->isTextControl() || (obj->node() && obj->node()->isTextNode()))
+        return new AccessibleText(obj, window);
 
     return new AccessibleBase(obj, window);
 }
@@ -88,7 +91,10 @@ HRESULT AccessibleBase::QueryService(REFGUID guidService, REFIID riid, void **pp
         && !IsEqualGUID(guidService, IID_IAccessible2_2)
         && !IsEqualGUID(guidService, IID_IAccessible2)
         && !IsEqualGUID(guidService, IID_IAccessibleApplication)
-        && !IsEqualGUID(guidService, IID_IAccessible)) {
+        && !IsEqualGUID(guidService, IID_IAccessible)
+        && !IsEqualGUID(guidService, IID_IAccessibleText)
+        && !IsEqualGUID(guidService, IID_IAccessibleText2)
+        && !IsEqualGUID(guidService, IID_IAccessibleEditableText)) {
         *ppvObject = 0;
         return E_INVALIDARG;
     }
index ed6a4e51b34b40bcce32b6f8b6591d8343916b53..66f74fe626490460214472015ec7c9b5d593ff71 100644 (file)
@@ -26,6 +26,9 @@
 #ifndef AccessibleBase_h
 #define AccessibleBase_h
 
+#include "AccessibleEditableText.h"
+#include "AccessibleText.h"
+#include "AccessibleText2.h"
 #include "WebKit.h"
 #include <WebCore/AccessibilityObject.h>
 #include <WebCore/AccessibilityObjectWrapperWin.h>
diff --git a/Source/WebKit/win/AccessibleTextImpl.cpp b/Source/WebKit/win/AccessibleTextImpl.cpp
new file mode 100644 (file)
index 0000000..fa816cc
--- /dev/null
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2013 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 "AccessibleTextImpl.h"
+
+#include "WebKitDLL.h"
+#include "WebView.h"
+
+#include <WebCore/Document.h>
+#include <WebCore/Editor.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameSelection.h>
+#include <WebCore/HTMLTextFormControlElement.h>
+#include <WebCore/Node.h>
+#include <WebCore/Page.h>
+#include <WebCore/Position.h>
+#include <WebCore/RenderTextControl.h>
+#include <WebCore/VisibleSelection.h>
+#include <WebCore/htmlediting.h>
+
+using namespace WebCore;
+
+AccessibleText::AccessibleText(WebCore::AccessibilityObject* obj, HWND window)
+    : AccessibleBase(obj, window)
+{
+    ASSERT_ARG(obj, obj->isStaticText() || obj->isTextControl() || (obj->node() && obj->node()->isTextNode()));
+    ASSERT_ARG(obj, obj->isAccessibilityRenderObject());
+}
+
+// IAccessibleText
+HRESULT AccessibleText::addSelection(long startOffset, long endOffset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startOffset = convertSpecialOffset(startOffset);
+    endOffset = convertSpecialOffset(endOffset);
+
+    m_object->setSelectedTextRange(PlainTextRange(startOffset, endOffset-startOffset));
+    
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_attributes(long offset, long* startOffset, long* endOffset, BSTR* textAttributes)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    offset = convertSpecialOffset(offset);
+
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::get_caretOffset(long* offset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    VisiblePosition caretPosition = m_object->visiblePositionForPoint(m_object->document()->frame()->selection().absoluteCaretBounds().center());
+
+    int caretOffset = caretPosition.deepEquivalent().offsetInContainerNode();
+    if (caretOffset < 0)
+        return E_FAIL;
+    *offset = caretOffset;
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_characterExtents(long offset, enum IA2CoordinateType coordType, long* x, long* y, long* width, long* height)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    offset = convertSpecialOffset(offset);
+
+    Node* node = m_object->node();
+    if (!node)
+        return E_POINTER;
+
+    IntRect boundingRect = m_object->boundsForVisiblePositionRange(VisiblePositionRange(VisiblePosition(Position(node, offset, Position::PositionIsOffsetInAnchor)), VisiblePosition(Position(node, offset+1, Position::PositionIsOffsetInAnchor))));
+    *width = boundingRect.width();
+    *height = boundingRect.height();
+    switch (coordType) {
+    case IA2_COORDTYPE_SCREEN_RELATIVE:
+        POINT points[1];
+        points[0].x = boundingRect.x();
+        points[0].y = boundingRect.y();
+        MapWindowPoints(m_window, 0, points, 1);
+        *x = points[0].x;
+        *y = points[0].y;
+        break;
+    case IA2_COORDTYPE_PARENT_RELATIVE:
+        *x = boundingRect.x();
+        *y = boundingRect.y();
+        break;
+    default:
+        return E_INVALIDARG;
+    }
+
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_nSelections(long* nSelections)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    if (m_object->document()->frame()->selection().isNone())
+        *nSelections = 0;
+    else
+        *nSelections = 1;
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_offsetAtPoint(long x, long y, enum IA2CoordinateType coordType, long* offset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    Node* node = m_object->node();
+    if (!node)
+        return E_POINTER;
+
+    VisiblePosition vpos;
+    switch (coordType) {
+    case IA2_COORDTYPE_SCREEN_RELATIVE:
+        POINT points[1];
+        points[0].x = x;
+        points[0].y = y;
+        MapWindowPoints(0, m_window, points, 1);
+        vpos = m_object->visiblePositionForPoint(IntPoint(points[0].x, points[0].y));
+        break;
+    case IA2_COORDTYPE_PARENT_RELATIVE:
+        vpos = m_object->visiblePositionForPoint(IntPoint(x, y));
+        break;
+    default:
+        return E_INVALIDARG;
+    }
+
+    int caretPosition = vpos.deepEquivalent().offsetInContainerNode();
+    if (caretPosition < 0 || caretPosition > m_object->stringValue().length())
+        return S_FALSE; 
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_selection(long selectionIndex, long* startOffset, long* endOffset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    long selections;
+    get_nSelections(&selections);
+    if (selectionIndex < 0 || selectionIndex >= selections)
+        return E_INVALIDARG;
+
+    PlainTextRange selectionRange = m_object->selectedTextRange();
+
+    *startOffset = selectionRange.start;
+    *endOffset = selectionRange.length;
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_text(long startOffset, long endOffset, BSTR* text)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startOffset = convertSpecialOffset(startOffset);
+    endOffset = convertSpecialOffset(endOffset);
+    WTF::String substringText = m_object->stringValue().substring(startOffset, endOffset - startOffset);
+
+    *text = SysAllocStringLen(substringText.characters(), substringText.length());
+    if (substringText.length() && !*text)
+        return E_OUTOFMEMORY;
+
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_textBeforeOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+    
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::get_textAfterOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+    
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::get_textAtOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+    
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::removeSelection(long selectionIndex)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    long selections;
+    get_nSelections(&selections);
+    if (selectionIndex < 0 || selectionIndex >= selections)
+        return E_INVALIDARG;
+
+    m_object->document()->frame()->selection().clear();
+    return S_OK;
+}
+
+HRESULT AccessibleText::setCaretOffset(long offset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+        
+    offset = convertSpecialOffset(offset);
+
+    Node* node = m_object->node();
+    if (!node)
+        return E_POINTER;
+
+    m_object->document()->frame()->selection().setSelection(VisibleSelection(VisiblePosition(Position(node, offset, Position::PositionIsOffsetInAnchor))));
+    return S_OK;
+}
+
+HRESULT AccessibleText::setSelection(long selectionIndex, long startOffset, long endOffset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    long selections;
+    get_nSelections(&selections);
+    if (selectionIndex < 0 || selectionIndex >= selections)
+        return E_INVALIDARG;
+
+    m_object->setSelectedTextRange(PlainTextRange(startOffset, endOffset - startOffset));
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_nCharacters(long* characters)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    int length = m_object->stringValue().length();
+    if (length < 0)
+        return E_FAIL;
+
+    *characters = length;
+    return S_OK;
+}
+
+HRESULT AccessibleText::scrollSubstringTo(long startIndex, long endIndex, enum IA2ScrollType scrollType)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startIndex = convertSpecialOffset(startIndex);
+    endIndex = convertSpecialOffset(endIndex);
+
+    VisiblePositionRange textRange = m_object->visiblePositionRangeForRange(PlainTextRange(startIndex, endIndex-startIndex));
+    if (textRange.start.isNull() || textRange.end.isNull())
+        return S_FALSE;
+
+    IntRect boundingBox = makeRange(textRange.start, textRange.end)->boundingBox();
+    switch (scrollType) {
+    case IA2_SCROLL_TYPE_TOP_LEFT:
+        m_object->scrollToGlobalPoint(boundingBox.minXMinYCorner());
+        break;
+    case IA2_SCROLL_TYPE_BOTTOM_RIGHT:
+        m_object->scrollToGlobalPoint(boundingBox.maxXMaxYCorner());
+        break;
+    case IA2_SCROLL_TYPE_TOP_EDGE:
+        m_object->scrollToGlobalPoint(IntPoint((boundingBox.x() + boundingBox.maxX()) / 2, boundingBox.y()));
+        break;
+    case IA2_SCROLL_TYPE_BOTTOM_EDGE:
+        m_object->scrollToGlobalPoint(IntPoint((boundingBox.x() + boundingBox.maxX()) / 2, boundingBox.maxY()));
+        break;
+    case IA2_SCROLL_TYPE_LEFT_EDGE:
+        m_object->scrollToGlobalPoint(IntPoint(boundingBox.x(), (boundingBox.y() + boundingBox.maxY()) / 2));
+        break;
+    case IA2_SCROLL_TYPE_RIGHT_EDGE:
+        m_object->scrollToGlobalPoint(IntPoint(boundingBox.maxX(), (boundingBox.y() + boundingBox.maxY()) / 2));
+        break;
+    case IA2_SCROLL_TYPE_ANYWHERE:
+        m_object->scrollToGlobalPoint(boundingBox.center());
+        break;
+    default:
+        return E_INVALIDARG;
+    }
+    return S_OK;
+}
+
+HRESULT AccessibleText::scrollSubstringToPoint(long startIndex, long endIndex, enum IA2CoordinateType coordinateType, long x, long y)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startIndex = convertSpecialOffset(startIndex);
+    endIndex = convertSpecialOffset(endIndex);
+
+    switch (coordinateType) {
+    case IA2_COORDTYPE_SCREEN_RELATIVE:
+        POINT points[1];
+        points[0].x = x;
+        points[0].y = y;
+        MapWindowPoints(0, m_window, points, 1);
+        m_object->scrollToGlobalPoint(IntPoint(points[0].x, points[0].y));
+        break;
+    case IA2_COORDTYPE_PARENT_RELATIVE:
+        m_object->scrollToGlobalPoint(IntPoint(x, y));
+        break;
+    default:
+        return E_INVALIDARG;
+    }
+
+    return S_OK;
+}
+
+HRESULT AccessibleText::get_newText(IA2TextSegment* newText)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+    
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::get_oldText(IA2TextSegment* oldText)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    return E_NOTIMPL;
+}
+
+
+// IAccessibleText2
+HRESULT AccessibleText::get_attributeRange(long offset, BSTR filter, long* startOffset, long* endOffset, BSTR* attributeValues)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    return E_NOTIMPL;
+}
+
+HRESULT AccessibleText::copyText(long startOffset, long endOffset)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startOffset = convertSpecialOffset(startOffset);
+    endOffset = convertSpecialOffset(endOffset);
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+
+    addSelection(startOffset, endOffset);
+
+    frame->editor().copy();
+    return S_OK;
+}
+
+HRESULT AccessibleText::deleteText(long startOffset, long endOffset)
+{
+    if (m_object->isReadOnly())
+        return S_FALSE;
+
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+
+    addSelection(startOffset, endOffset);
+
+    frame->editor().deleteSelectionWithSmartDelete(false);
+    return S_OK;
+}
+
+HRESULT AccessibleText::insertText(long offset, BSTR* text)
+{
+    if (m_object->isReadOnly())
+        return S_FALSE;
+
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    offset = convertSpecialOffset(offset);
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+    
+    addSelection(offset, offset);
+
+    frame->editor().insertText(*text, 0);
+    return S_OK;
+}
+
+HRESULT AccessibleText::cutText(long startOffset, long endOffset)
+{
+    if (m_object->isReadOnly())
+        return S_FALSE;
+
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startOffset = convertSpecialOffset(startOffset);
+    endOffset = convertSpecialOffset(endOffset);
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+
+    addSelection(startOffset, endOffset);
+
+    frame->editor().cut();
+    return S_OK;
+}
+
+HRESULT AccessibleText::pasteText(long offset)
+{
+    if (m_object->isReadOnly())
+        return S_FALSE;
+
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    offset = convertSpecialOffset(offset);
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+
+    addSelection(offset, offset);
+
+    frame->editor().paste();
+    return S_OK;
+}
+
+HRESULT AccessibleText::replaceText(long startOffset, long endOffset, BSTR* text)
+{
+    if (m_object->isReadOnly())
+        return S_FALSE;
+
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    startOffset = convertSpecialOffset(startOffset);
+    endOffset = convertSpecialOffset(endOffset);
+
+    Frame* frame = m_object->document()->frame();
+    if (!frame)
+        return E_POINTER;
+
+    addSelection(startOffset, endOffset);
+
+    frame->editor().replaceSelectionWithText(*text, true, false);
+    return S_OK;
+}
+
+HRESULT AccessibleText::setAttributes(long startOffset, long endOffset, BSTR* attributes)
+{
+    if (initialCheck() == E_POINTER)
+        return E_POINTER;
+
+    return E_NOTIMPL;
+}
+
+// IAccessible2
+HRESULT AccessibleText::get_attributes(BSTR* attributes)
+{
+    WTF::String text("text-model:a1");
+    *attributes = SysAllocStringLen(text.characters(), text.length());
+    return S_OK;
+}
+
+// IUnknown
+HRESULT STDMETHODCALLTYPE AccessibleText::QueryInterface(REFIID riid, void** ppvObject)
+{
+    if (IsEqualGUID(riid, __uuidof(IAccessibleText)))
+        *ppvObject = static_cast<IAccessibleText*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessibleEditableText)))
+        *ppvObject = static_cast<IAccessibleEditableText*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessible)))
+        *ppvObject = static_cast<IAccessible*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IDispatch)))
+        *ppvObject = static_cast<IAccessible*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IUnknown)))
+        *ppvObject = static_cast<IAccessible*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessible2_2)))
+        *ppvObject = static_cast<IAccessible2_2*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessible2)))
+        *ppvObject = static_cast<IAccessible2*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessibleComparable)))
+        *ppvObject = static_cast<IAccessibleComparable*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IServiceProvider)))
+        *ppvObject = static_cast<IServiceProvider*>(this);
+    else if (IsEqualGUID(riid, __uuidof(AccessibleBase)))
+        *ppvObject = static_cast<AccessibleBase*>(this);
+    else {
+        *ppvObject = 0;
+        return E_NOINTERFACE;
+    }
+    AddRef();
+    return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE AccessibleText::Release(void)
+{
+    ASSERT(m_refCount > 0);
+    if (--m_refCount)
+        return m_refCount;
+    delete this;
+    return 0;
+}
+
+int AccessibleText::convertSpecialOffset(int offset)
+{
+    ASSERT(m_object);
+    
+    if (offset == IA2_TEXT_OFFSET_LENGTH) 
+        return m_object->stringValue().length();
+    if (offset == IA2_TEXT_OFFSET_CARET) {
+        long caretOffset;
+        get_caretOffset(&caretOffset);
+        return caretOffset;
+    }
+    return offset;
+}
+
+HRESULT AccessibleText::initialCheck()
+{
+    if (!m_object)
+        return E_FAIL;
+
+    Document* document = m_object->document();
+    if (!document)
+        return E_FAIL;
+
+    Frame* frame = document->frame();
+    if (!frame)
+        return E_FAIL;
+
+    return S_OK;
+}
diff --git a/Source/WebKit/win/AccessibleTextImpl.h b/Source/WebKit/win/AccessibleTextImpl.h
new file mode 100644 (file)
index 0000000..2f0c103
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013 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. 
+ */
+
+#ifndef AccessibleTextImpl_h
+#define AccessibleTextImpl_h
+
+#include "AccessibleBase.h"
+
+class AccessibleText : public AccessibleBase, public IAccessibleText2, public IAccessibleEditableText {
+public:
+    AccessibleText(WebCore::AccessibilityObject*, HWND);
+    virtual ~AccessibleText() { }
+
+    // IAccessibleText
+    virtual HRESULT STDMETHODCALLTYPE addSelection(long startOffset, long endOffset);
+    virtual HRESULT STDMETHODCALLTYPE get_attributes(long offset, long* startOffset, long* endOffset, BSTR* textAttributes);
+    virtual HRESULT STDMETHODCALLTYPE get_caretOffset(long* offset);
+    virtual HRESULT STDMETHODCALLTYPE get_characterExtents(long offset, enum IA2CoordinateType coordType, long* x, long* y, long* width, long* height);
+    virtual HRESULT STDMETHODCALLTYPE get_nSelections(long* nSelections);
+    virtual HRESULT STDMETHODCALLTYPE get_offsetAtPoint(long x, long y, enum IA2CoordinateType coordType, long* offset);
+    virtual HRESULT STDMETHODCALLTYPE get_selection(long selectionIndex, long* startOffset, long* endOffset);
+    virtual HRESULT STDMETHODCALLTYPE get_text(long startOffset, long endOffset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE get_textBeforeOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE get_textAfterOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE get_textAtOffset(long offset, enum IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE removeSelection(long selectionIndex);
+    virtual HRESULT STDMETHODCALLTYPE setCaretOffset(long offset);
+    virtual HRESULT STDMETHODCALLTYPE setSelection(long selectionIndex, long startOffset, long endOffset);
+    virtual HRESULT STDMETHODCALLTYPE get_nCharacters(long* characters);
+    virtual HRESULT STDMETHODCALLTYPE scrollSubstringTo(long startIndex, long endIndex, enum IA2ScrollType scrollType);
+    virtual HRESULT STDMETHODCALLTYPE scrollSubstringToPoint(long startIndex, long endIndex, enum IA2CoordinateType coordinateType, long x, long y);
+    virtual HRESULT STDMETHODCALLTYPE get_newText(IA2TextSegment* newText);
+    virtual HRESULT STDMETHODCALLTYPE get_oldText(IA2TextSegment* oldText);
+    
+    // IAccessibleText2
+    virtual HRESULT STDMETHODCALLTYPE get_attributeRange(long offset, BSTR filter, long* startOffset, long* endOffset, BSTR* attributeValues);
+
+    // IAccessibleEditableText
+    virtual HRESULT STDMETHODCALLTYPE copyText(long startOffset, long endOffset);
+    virtual HRESULT STDMETHODCALLTYPE deleteText(long startOffset, long endOffset);
+    virtual HRESULT STDMETHODCALLTYPE insertText(long offset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE cutText(long startOffset, long endOffset);
+    virtual HRESULT STDMETHODCALLTYPE pasteText(long offset);
+    virtual HRESULT STDMETHODCALLTYPE replaceText(long startOffset, long endOffset, BSTR* text);
+    virtual HRESULT STDMETHODCALLTYPE setAttributes(long startOffset, long endOffset, BSTR* attributes);
+
+    // IUnknown
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+    virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++m_refCount; }
+    virtual ULONG STDMETHODCALLTYPE Release(void);
+
+    // IAccessibleBase
+    virtual HRESULT STDMETHODCALLTYPE get_attributes(BSTR* attributes);
+
+private:
+    int convertSpecialOffset(int specialOffset);
+    HRESULT initialCheck();
+};
+
+#endif // AccessibleText_h
index 94a914f18df944549cf3d395ce506de0b56ad810..4f20f752486d2a2ba111b4e2370751efac286a20 100644 (file)
@@ -1,3 +1,52 @@
+2013-08-23  Roger Fong  <roger_fong@apple.com>
+
+        <https://bugs.webkit.org/show_bug.cgi?id=119829> Add IAccessibleText and IAccessibleEditableText implementation.
+
+        Reviewed by Chris Fleizach.
+
+        Add IAccessibleText and IAccessibleEditableText interfaces and implementation to AppleWin port.
+
+        * AccessibleBase.cpp:
+        (AccessibleBase::createInstance): Create an AccessibleText instance when necessary.
+        (AccessibleBase::QueryService):
+        * AccessibleBase.h:
+        * AccessibleTextImpl.cpp: Added.
+        (AccessibleText::AccessibleText):
+        (AccessibleText::addSelection):
+        (AccessibleText::get_attributes): Not Implemented
+        (AccessibleText::get_caretOffset):
+        (AccessibleText::get_characterExtents):
+        (AccessibleText::get_nSelections):
+        (AccessibleText::get_offsetAtPoint):
+        (AccessibleText::get_selection):
+        (AccessibleText::get_text):
+        (AccessibleText::get_textBeforeOffset): Not Implemented
+        (AccessibleText::get_textAfterOffset): Not Implemented
+        (AccessibleText::get_textAtOffset): Not Implemented
+        (AccessibleText::removeSelection):
+        (AccessibleText::setCaretOffset):
+        (AccessibleText::setSelection):
+        (AccessibleText::get_nCharacters):
+        (AccessibleText::scrollSubstringTo):
+        (AccessibleText::scrollSubstringToPoint):
+        (AccessibleText::get_newText): Not Implemented
+        (AccessibleText::get_oldText): Not Implemented
+        (AccessibleText::get_attributeRange): Not Implemented
+        (AccessibleText::copyText):
+        (AccessibleText::deleteText):
+        (AccessibleText::insertText):
+        (AccessibleText::cutText):
+        (AccessibleText::pasteText):
+        (AccessibleText::replaceText):
+        (AccessibleText::setAttributes): Not Implemented
+        (AccessibleText::QueryInterface):
+        (AccessibleText::Release):
+        (AccessibleText::convertSpecialOffset):
+        (AccessibleText::initialCheck):
+        * AccessibleTextImpl.h: Added.
+        (AccessibleText::~AccessibleText):
+        (AccessibleText::AddRef):
+
 2013-08-24  Darin Adler  <darin@apple.com>
 
         Frame::tree should return a reference instead of a pointer