[ATK] Refactor code for translating offsets between WebCore a11y and ATK
authormario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jul 2013 08:36:15 +0000 (08:36 +0000)
committermario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jul 2013 08:36:15 +0000 (08:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118179

Reviewed by Chris Fleizach.

Encapsulate better and make more clear the translation of offsets
between our ATK implementation and WebCore's accessibility layer.

Values for offsets can differ sometimes between those two worlds
due to some extra flattening we need to do in ATK based ports to
properly expose the accessibility hierarchy to ATs, which
sometimes means adding extra text elements in the exposed text
through the AtkText interface (e.g. list items markers).

* accessibility/atk/WebKitAccessibleInterfaceText.cpp:
(offsetAdjustmentForListItem): Helper function to refactor code
needed to translate offsets from WebCore to ATK worlds. Currently
related to considering list item markers in LTR text only.
(webCoreOffsetToAtkOffset): Convenience function for code
readability purposes. It just calls offsetAdjustmentForListItem.
(atkOffsetToWebCoreOffset): Likewise.
(getSelectionOffsetsForObject): Use webCoreOffsetToAtkOffset.
(webkitAccessibleTextGetCaretOffset): Use webCoreOffsetToAtkOffset
to translate an offset from WebCore to ATK before returning it.
(webkitAccessibleTextSetSelection): Use atkOffsetToWebCoreOffset
to translate an offset from WebCore to ATK before using it.
(webkitAccessibleTextSetCaretOffset): Likewise.

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

Source/WebCore/ChangeLog
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp

index b041eb1..21d26dd 100644 (file)
@@ -1,3 +1,33 @@
+2013-07-11  Mario Sanchez Prada  <mario.prada@samsung.com>
+
+        [ATK] Refactor code for translating offsets between WebCore a11y and ATK
+        https://bugs.webkit.org/show_bug.cgi?id=118179
+
+        Reviewed by Chris Fleizach.
+
+        Encapsulate better and make more clear the translation of offsets
+        between our ATK implementation and WebCore's accessibility layer.
+
+        Values for offsets can differ sometimes between those two worlds
+        due to some extra flattening we need to do in ATK based ports to
+        properly expose the accessibility hierarchy to ATs, which
+        sometimes means adding extra text elements in the exposed text
+        through the AtkText interface (e.g. list items markers).
+
+        * accessibility/atk/WebKitAccessibleInterfaceText.cpp:
+        (offsetAdjustmentForListItem): Helper function to refactor code
+        needed to translate offsets from WebCore to ATK worlds. Currently
+        related to considering list item markers in LTR text only.
+        (webCoreOffsetToAtkOffset): Convenience function for code
+        readability purposes. It just calls offsetAdjustmentForListItem.
+        (atkOffsetToWebCoreOffset): Likewise.
+        (getSelectionOffsetsForObject): Use webCoreOffsetToAtkOffset.
+        (webkitAccessibleTextGetCaretOffset): Use webCoreOffsetToAtkOffset
+        to translate an offset from WebCore to ATK before returning it.
+        (webkitAccessibleTextSetSelection): Use atkOffsetToWebCoreOffset
+        to translate an offset from WebCore to ATK before using it.
+        (webkitAccessibleTextSetCaretOffset): Likewise.
+
 2013-07-10  Sam Weinig  <sam@webkit.org>
 
         Range.getClientRects() not working correctly for partially contained vertically styled text nodes
index 3394c84..12e51e3 100644 (file)
@@ -472,6 +472,34 @@ static IntRect textExtents(AtkText* text, gint startOffset, gint length, AtkCoor
     return extents;
 }
 
+static int offsetAdjustmentForListItem(const AccessibilityObject* object)
+{
+    // We need to adjust the offsets for the list item marker in
+    // Left-To-Right text, since we expose it together with the text.
+    RenderObject* renderer = object->renderer();
+    if (renderer && renderer->isListItem() && renderer->style()->direction() == LTR)
+        return toRenderListItem(renderer)->markerTextWithSuffix().length();
+
+    return 0;
+}
+
+static int webCoreOffsetToAtkOffset(const AccessibilityObject* object, int offset)
+{
+    if (!object->isListItem())
+        return offset;
+
+    return offset + offsetAdjustmentForListItem(object);
+}
+
+static int atkOffsetToWebCoreOffset(AtkText* text, int offset)
+{
+    AccessibilityObject* coreObject = core(text);
+    if (!coreObject || !coreObject->isListItem())
+        return offset;
+
+    return offset - offsetAdjustmentForListItem(coreObject);
+}
+
 static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, VisibleSelection& selection, gint& startOffset, gint& endOffset)
 {
     if (!coreObject->isAccessibilityRenderObject())
@@ -513,15 +541,9 @@ static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, Visibl
     Position parentFirstPosition = firstPositionInOrBeforeNode(node);
     RefPtr<Range> rangeInParent = Range::create(node->document(), parentFirstPosition, nodeRangeStart);
 
-    // Set values for start and end offsets.
-    startOffset = TextIterator::rangeLength(rangeInParent.get(), true);
 
-    // We need to adjust the offsets for the list item marker.
-    RenderObject* renderer = coreObject->renderer();
-    if (renderer && renderer->isListItem()) {
-        String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
-        startOffset += markerText.length();
-    }
+    // Set values for start and end offsets.
+    startOffset = webCoreOffsetToAtkOffset(coreObject, TextIterator::rangeLength(rangeInParent.get(), true));
 
     RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
     endOffset = startOffset + TextIterator::rangeLength(nodeRange.get(), true);
@@ -680,16 +702,7 @@ static gint webkitAccessibleTextGetCaretOffset(AtkText* text)
     if (!objectFocusedAndCaretOffsetUnignored(coreObject, offset))
         return 0;
 
-    RenderObject* renderer = coreObject->renderer();
-    if (renderer && renderer->isListItem()) {
-        String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
-
-        // We need to adjust the offset for the list item marker.
-        offset += markerText.length();
-    }
-
-    // TODO: Verify this for RTL text.
-    return offset;
+    return webCoreOffsetToAtkOffset(coreObject, offset);
 }
 
 static AtkAttributeSet* webkitAccessibleTextGetRunAttributes(AtkText* text, gint offset, gint* startOffset, gint* endOffset)
@@ -821,15 +834,13 @@ static gboolean webkitAccessibleTextSetSelection(AtkText* text, gint selectionNu
         endOffset = textCount;
 
     // We need to adjust the offsets for the list item marker.
-    RenderObject* renderer = coreObject->renderer();
-    if (renderer && renderer->isListItem()) {
-        String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
-        int markerLength = markerText.length();
-        if (startOffset < markerLength || endOffset < markerLength)
+    int offsetAdjustment = offsetAdjustmentForListItem(coreObject);
+    if (offsetAdjustment) {
+        if (startOffset < offsetAdjustment || endOffset < offsetAdjustment)
             return FALSE;
 
-        startOffset -= markerLength;
-        endOffset -= markerLength;
+        startOffset = atkOffsetToWebCoreOffset(text, startOffset);
+        endOffset = atkOffsetToWebCoreOffset(text, endOffset);
     }
 
     PlainTextRange textRange(startOffset, endOffset - startOffset);
@@ -864,15 +875,13 @@ static gboolean webkitAccessibleTextSetCaretOffset(AtkText* text, gint offset)
     if (!coreObject->isAccessibilityRenderObject())
         return FALSE;
 
-    RenderObject* renderer = coreObject->renderer();
-    if (renderer && renderer->isListItem()) {
-        String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
-        int markerLength = markerText.length();
-        if (offset < markerLength)
+    // We need to adjust the offsets for the list item marker.
+    int offsetAdjustment = offsetAdjustmentForListItem(coreObject);
+    if (offsetAdjustment) {
+        if (offset < offsetAdjustment)
             return FALSE;
 
-        // We need to adjust the offset for list items.
-        offset -= markerLength;
+        offset = atkOffsetToWebCoreOffset(text, offset);
     }
 
     PlainTextRange textRange(offset, 0);