Changeset 153652 in webkit


Ignore:
Timestamp:
Aug 2, 2013 9:02:11 AM (11 years ago)
Author:
mario@webkit.org
Message:

Implement atk_text_get_text_*_offset for WORD
https://bugs.webkit.org/show_bug.cgi?id=114871

Reviewed by Martin Robinson.

Source/WebCore:

Re-implement this functions without using GailTextUtil nor Pango.

  • accessibility/atk/WebKitAccessibleInterfaceText.cpp:

(textForObject): Made the parameter a const, to avoid warnings.
(getSelectionOffsetsForObject): Add special cases for END boundaries.
(emptyTextSelectionAtOffset): Convenience function to be used in
early returns from functions returning both text and offsets.
(webkitAccessibleTextGetChar): Use emptyTextSelectionAtOffset(),
and remove checks that are now done outside of this function, in
webkitAccessibleTextGetTextForOffset().
(nextWordStartPosition): Helper function to reliably find the
start of the next word as and user would do it by navigating with
Ctrl and the arrows (considering spaces and punctuation).
(previousWordEndPosition): Similar to nextWordStartPosition, but
written to help find the end of the previous one.
(wordAtPositionForAtkBoundary): Helper function to find the word
at a given position considering values of AtkTextBoundary.
(numberOfReplacedElementsBeforeOffset): Helper function to help
figure out how many embedded objects we have exposed for an
AtkText object, used to adjust offsets coming from outside.
(webkitAccessibleTextGetWordForBoundary): New function,
implementing atk_text_get_text_*_offset for WORD.
(webkitAccessibleTextGetTextForOffset): Replace usage of Gail for
WORD boundaries with webkitAccessibleTextGetWordForBoundary().
Also, moved the initialization of the start and end offsets to the
bottom, into the gail/pango section, since those values will be
from now on initialized in getSelectionOffsetsForObject().
(webkitAccessibleTextGetSelection): Removed the initialization of
the start and end offsets, since those values will be from now on
initialized in getSelectionOffsetsForObject().

Source/WebKit/gtk:

Updated current unit tests and add a new one specific for embedded
objects, to ensure we are covering even more cases than before.

  • tests/testatk.c:

(testWebkitAtkGetTextAtOffsetWithEmbeddedObjects): New.
(main): Added new test to the test suite.

Location:
trunk/Source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r153650 r153652  
     12013-08-02  Mario Sanchez Prada  <mario.prada@samsung.com>
     2
     3        Implement atk_text_get_text_*_offset for WORD
     4        https://bugs.webkit.org/show_bug.cgi?id=114871
     5
     6        Reviewed by Martin Robinson.
     7
     8        Re-implement this functions without using GailTextUtil nor Pango.
     9
     10        * accessibility/atk/WebKitAccessibleInterfaceText.cpp:
     11        (textForObject): Made the parameter a const, to avoid warnings.
     12        (getSelectionOffsetsForObject): Add special cases for END boundaries.
     13        (emptyTextSelectionAtOffset): Convenience function to be used in
     14        early returns from functions returning both text and offsets.
     15        (webkitAccessibleTextGetChar): Use emptyTextSelectionAtOffset(),
     16        and remove checks that are now done outside of this function, in
     17        webkitAccessibleTextGetTextForOffset().
     18        (nextWordStartPosition): Helper function to reliably find the
     19        start of the next word as and user would do it by navigating with
     20        Ctrl and the arrows (considering spaces and punctuation).
     21        (previousWordEndPosition): Similar to nextWordStartPosition, but
     22        written to help find the end of the previous one.
     23        (wordAtPositionForAtkBoundary): Helper function to find the word
     24        at a given position considering values of AtkTextBoundary.
     25        (numberOfReplacedElementsBeforeOffset): Helper function to help
     26        figure out how many embedded objects we have exposed for an
     27        AtkText object, used to adjust offsets coming from outside.
     28        (webkitAccessibleTextGetWordForBoundary): New function,
     29        implementing atk_text_get_text_*_offset for WORD.
     30        (webkitAccessibleTextGetTextForOffset): Replace usage of Gail for
     31        WORD boundaries with webkitAccessibleTextGetWordForBoundary().
     32        Also, moved the initialization of the start and end offsets to the
     33        bottom, into the gail/pango section, since those values will be
     34        from now on initialized in getSelectionOffsetsForObject().
     35        (webkitAccessibleTextGetSelection): Removed the initialization of
     36        the start and end offsets, since those values will be from now on
     37        initialized in getSelectionOffsetsForObject().
     38
    1392013-08-02  Zoltan Arvai  <zarvai@inf.u-szeged.hu>
    240
  • trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp

    r153427 r153652  
    33 * Copyright (C) 2009 Jan Alonzo
    44 * Copyright (C) 2009, 2010, 2011, 2012 Igalia S.L.
     5 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    56 *
    67 * Portions from Mozilla a11y, copyright as follows:
     
    5051#include "WebKitAccessibleWrapperAtk.h"
    5152#include "htmlediting.h"
     53#include <wtf/NotFound.h>
    5254#include <wtf/gobject/GOwnPtr.h>
    5355#include <wtf/text/CString.h>
     
    137139}
    138140
    139 static gchar* textForObject(AccessibilityObject* coreObject)
     141static gchar* textForObject(const AccessibilityObject* coreObject)
    140142{
    141143    GString* str = g_string_new(0);
     
    560562    RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
    561563    int rangeLength = TextIterator::rangeLength(nodeRange.get(), true);
     564
     565    // Special cases that are only relevant when working with *_END boundaries.
     566    if (selection.affinity() == UPSTREAM) {
     567        VisiblePosition visibleStart(nodeRangeStart, UPSTREAM);
     568        VisiblePosition visibleEnd(nodeRangeEnd, UPSTREAM);
     569
     570        // We need to adjust offsets when finding wrapped lines so the position at the end
     571        // of the line is properly taking into account when calculating the offsets.
     572        if (isEndOfLine(visibleStart) && !lineBreakExistsAtVisiblePosition(visibleStart)) {
     573            if (isStartOfLine(visibleStart.next()))
     574                rangeLength++;
     575
     576            if (!isEndOfBlock(visibleStart))
     577                startOffset = std::max(startOffset - 1, 0);
     578        }
     579
     580        if (isEndOfLine(visibleEnd) && !lineBreakExistsAtVisiblePosition(visibleEnd) && !isEndOfBlock(visibleEnd))
     581            rangeLength--;
     582    }
     583
    562584    endOffset = std::min(startOffset + rangeLength, static_cast<int>(accessibilityObjectLength(coreObject)));
    563585}
     
    614636};
    615637
    616 static gchar* webkitAccessibleTextGetChar(AtkText* text, gint offset, GetTextRelativePosition textPosition, gint* startOffset, gint* endOffset)
    617 {
    618     AccessibilityObject* coreObject = core(text);
    619     if (!coreObject || !coreObject->isAccessibilityRenderObject())
    620         return g_strdup("");
    621 
     638// Convenience function to be used in early returns.
     639static char* emptyTextSelectionAtOffset(int offset, int* startOffset, int* endOffset)
     640{
     641    *startOffset = offset;
     642    *endOffset = offset;
     643    return g_strdup("");
     644}
     645
     646static char* webkitAccessibleTextGetChar(AtkText* text, int offset, GetTextRelativePosition textPosition, int* startOffset, int* endOffset)
     647{
    622648    int actualOffset = offset;
    623649    if (textPosition == GetTextPositionBefore)
     
    641667}
    642668
     669static VisiblePosition nextWordStartPosition(const VisiblePosition &position)
     670{
     671    VisiblePosition positionAfterCurrentWord = nextWordPosition(position);
     672
     673    // In order to skip spaces when moving right, we advance one word further
     674    // and then move one word back. This will put us at the beginning of the
     675    // word following.
     676    VisiblePosition positionAfterSpacingAndFollowingWord = nextWordPosition(positionAfterCurrentWord);
     677
     678    if (positionAfterSpacingAndFollowingWord != positionAfterCurrentWord)
     679        positionAfterCurrentWord = previousWordPosition(positionAfterSpacingAndFollowingWord);
     680
     681    bool movingBackwardsMovedPositionToStartOfCurrentWord = positionAfterCurrentWord == previousWordPosition(nextWordPosition(position));
     682    if (movingBackwardsMovedPositionToStartOfCurrentWord)
     683        positionAfterCurrentWord = positionAfterSpacingAndFollowingWord;
     684
     685    return positionAfterCurrentWord;
     686}
     687
     688static VisiblePosition previousWordEndPosition(const VisiblePosition &position)
     689{
     690    // We move forward and then backward to position ourselves at the beginning
     691    // of the current word for this boundary, making the most of the semantics
     692    // of previousWordPosition() and nextWordPosition().
     693    VisiblePosition positionAtStartOfCurrentWord = previousWordPosition(nextWordPosition(position));
     694    VisiblePosition positionAtPreviousWord = previousWordPosition(position);
     695
     696    // Need to consider special cases (punctuation) when we are in the last word of a sentence.
     697    if (isStartOfWord(position) && positionAtPreviousWord != position && positionAtPreviousWord == positionAtStartOfCurrentWord)
     698        return nextWordPosition(positionAtStartOfCurrentWord);
     699
     700    // In order to skip spaces when moving left, we advance one word backwards
     701    // and then move one word forward. This will put us at the beginning of
     702    // the word following.
     703    VisiblePosition positionBeforeSpacingAndPreceedingWord = previousWordPosition(positionAtStartOfCurrentWord);
     704
     705    if (positionBeforeSpacingAndPreceedingWord != positionAtStartOfCurrentWord)
     706        positionAtStartOfCurrentWord = nextWordPosition(positionBeforeSpacingAndPreceedingWord);
     707
     708    bool movingForwardMovedPositionToEndOfCurrentWord = nextWordPosition(positionAtStartOfCurrentWord) == previousWordPosition(nextWordPosition(position));
     709    if (movingForwardMovedPositionToEndOfCurrentWord)
     710        positionAtStartOfCurrentWord = positionBeforeSpacingAndPreceedingWord;
     711
     712    return positionAtStartOfCurrentWord;
     713}
     714
     715static VisibleSelection wordAtPositionForAtkBoundary(const AccessibilityObject* coreObject, const VisiblePosition& position, AtkTextBoundary boundaryType)
     716{
     717    VisiblePosition startPosition;
     718    VisiblePosition endPosition;
     719
     720    switch (boundaryType) {
     721    case ATK_TEXT_BOUNDARY_WORD_START:
     722        // isStartOfWord() returns true both when at the beginning of a "real" word
     723        // as when at the beginning of a whitespace range between two "real" words,
     724        // since that whitespace is considered a "word" as well. And in case we are
     725        // already at the beginning of a "real" word we do not need to look backwards.
     726        if (isStartOfWord(position) && isWhitespace(position.characterBefore()))
     727            startPosition = position;
     728        else
     729            startPosition = previousWordPosition(position);
     730        endPosition = nextWordStartPosition(startPosition);
     731
     732        // We need to make sure that we look for the word in the current line when
     733        // we are at the beginning of a new line, and not look into the previous one
     734        // at all, which might happen when lines belong to different nodes.
     735        if (isStartOfLine(position) && isStartOfLine(endPosition)) {
     736            startPosition = endPosition;
     737            endPosition = nextWordStartPosition(startPosition);
     738        }
     739        break;
     740
     741    case ATK_TEXT_BOUNDARY_WORD_END:
     742        startPosition = previousWordEndPosition(position);
     743        endPosition = nextWordPosition(startPosition);
     744        break;
     745
     746    default:
     747        ASSERT_NOT_REACHED();
     748    }
     749
     750    VisibleSelection selectedWord(startPosition, endPosition);
     751
     752    // We mark the selection as 'upstream' so we can use that information later,
     753    // when finding the actual offsets in getSelectionOffsetsForObject().
     754    if (boundaryType == ATK_TEXT_BOUNDARY_WORD_END)
     755        selectedWord.setAffinity(UPSTREAM);
     756
     757    return selectedWord;
     758}
     759
     760static int numberOfReplacedElementsBeforeOffset(AtkText* text, unsigned offset)
     761{
     762    GOwnPtr<char> textForObject(webkitAccessibleTextGetText(text, 0, offset));
     763    String textBeforeOffset = String::fromUTF8(textForObject.get());
     764
     765    int count = 0;
     766    size_t index = textBeforeOffset.find(objectReplacementCharacter, 0);
     767    while (index < offset && index != WTF::notFound) {
     768        index = textBeforeOffset.find(objectReplacementCharacter, index + 1);
     769        count++;
     770    }
     771    return count;
     772}
     773
     774static char* webkitAccessibleTextGetWordForBoundary(AtkText* text, int offset, AtkTextBoundary boundaryType, GetTextRelativePosition textPosition, int* startOffset, int* endOffset)
     775{
     776    AccessibilityObject* coreObject = core(text);
     777    Document* document = coreObject->document();
     778    if (!document)
     779        return emptyTextSelectionAtOffset(0, startOffset, endOffset);
     780
     781    Node* node = getNodeForAccessibilityObject(coreObject);
     782    if (!node)
     783        return emptyTextSelectionAtOffset(0, startOffset, endOffset);
     784
     785    int actualOffset = atkOffsetToWebCoreOffset(text, offset);
     786
     787    // Besides of the usual conversion from ATK offsets to WebCore offsets,
     788    // we need to consider the potential embedded objects that might have been
     789    // inserted in the text exposed through AtkText when calculating the offset.
     790    actualOffset -= numberOfReplacedElementsBeforeOffset(text, actualOffset);
     791
     792    VisiblePosition caretPosition = coreObject->visiblePositionForIndex(actualOffset);
     793    VisibleSelection currentWord = wordAtPositionForAtkBoundary(coreObject, caretPosition, boundaryType);
     794
     795    // Take into account other relative positions, if needed, by
     796    // calculating the new position that we would need to consider.
     797    VisiblePosition newPosition = caretPosition;
     798    switch (textPosition) {
     799    case GetTextPositionAt:
     800        break;
     801
     802    case GetTextPositionBefore:
     803        // Early return if asking for the previous word while already at the beginning.
     804        if (isFirstVisiblePositionInNode(currentWord.visibleStart(), node))
     805            return emptyTextSelectionAtOffset(0, startOffset, endOffset);
     806
     807        if (isStartOfLine(currentWord.end()))
     808            newPosition = currentWord.visibleStart().previous();
     809        else
     810            newPosition = startOfWord(currentWord.start(), LeftWordIfOnBoundary);
     811        break;
     812
     813    case GetTextPositionAfter:
     814        // Early return if asking for the following word while already at the end.
     815        if (isLastVisiblePositionInNode(currentWord.visibleEnd(), node))
     816            return emptyTextSelectionAtOffset(accessibilityObjectLength(coreObject), startOffset, endOffset);
     817
     818        if (isEndOfLine(currentWord.end()))
     819            newPosition = currentWord.visibleEnd().next();
     820        else
     821            newPosition = endOfWord(currentWord.end(), RightWordIfOnBoundary);
     822        break;
     823
     824    default:
     825        ASSERT_NOT_REACHED();
     826    }
     827
     828    // Determine the relevant word we are actually interested in
     829    // and calculate the ATK offsets for it, then return everything.
     830    VisibleSelection selectedWord = newPosition != caretPosition ? wordAtPositionForAtkBoundary(coreObject, newPosition, boundaryType) : currentWord;
     831    getSelectionOffsetsForObject(coreObject, selectedWord, *startOffset, *endOffset);
     832    return webkitAccessibleTextGetText(text, *startOffset, *endOffset);
     833}
     834
    643835static gchar* webkitAccessibleTextGetTextForOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, GetTextRelativePosition textPosition, gint* startOffset, gint* endOffset)
    644836{
    645     // Make sure we always return valid valid values for offsets.
    646     *startOffset = 0;
    647     *endOffset = 0;
     837    AccessibilityObject* coreObject = core(text);
     838    if (!coreObject || !coreObject->isAccessibilityRenderObject())
     839        return emptyTextSelectionAtOffset(0, startOffset, endOffset);
    648840
    649841    if (boundaryType == ATK_TEXT_BOUNDARY_CHAR)
    650842        return webkitAccessibleTextGetChar(text, offset, textPosition, startOffset, endOffset);
    651843
     844    if (boundaryType == ATK_TEXT_BOUNDARY_WORD_START || boundaryType == ATK_TEXT_BOUNDARY_WORD_END)
     845        return webkitAccessibleTextGetWordForBoundary(text, offset, boundaryType, textPosition, startOffset, endOffset);
     846
    652847#if PLATFORM(GTK)
    653     // FIXME: Get rid of the code below once every single get_text_*_offset
    654     // function has been properly implemented without using Pango/Cairo.
     848    // FIXME: Get rid of the code below once every single part above
     849    // has been properly implemented without using Pango/Cairo.
    655850    GailOffsetType offsetType = GAIL_AT_OFFSET;
    656851    switch (textPosition) {
     
    669864        ASSERT_NOT_REACHED();
    670865    }
     866
     867    // Make sure we always return valid valid values for offsets.
     868    *startOffset = 0;
     869    *endOffset = 0;
    671870
    672871    return gail_text_util_get_text(getGailTextUtilForAtk(text), getPangoLayoutForAtk(text), offsetType, boundaryType, offset, startOffset, endOffset);
     
    8041003static gchar* webkitAccessibleTextGetSelection(AtkText* text, gint selectionNum, gint* startOffset, gint* endOffset)
    8051004{
    806     // Default values, unless the contrary is proved
    807     *startOffset = *endOffset = 0;
    808 
    8091005    // WebCore does not support multiple selection, so anything but 0 does not make sense for now.
    8101006    if (selectionNum)
  • trunk/Source/WebKit/gtk/ChangeLog

    r153466 r153652  
     12013-08-02  Mario Sanchez Prada  <mario.prada@samsung.com>
     2
     3        Implement atk_text_get_text_*_offset for WORD
     4        https://bugs.webkit.org/show_bug.cgi?id=114871
     5
     6        Reviewed by Martin Robinson.
     7
     8        Updated current unit tests and add a new one specific for embedded
     9        objects, to ensure we are covering even more cases than before.
     10
     11        * tests/testatk.c:
     12        (testWebkitAtkGetTextAtOffsetWithEmbeddedObjects): New.
     13        (main): Added new test to the test suite.
     14
    1152013-07-30  Carlos Garcia Campos  <cgarcia@igalia.com>
    216
  • trunk/Source/WebKit/gtk/tests/testatk.c

    r153427 r153652  
    11/*
    22 * Copyright (C) 2009 Igalia S.L.
     3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
     
    5354static const char* contentsWithWrappedLines = "<html><body><p style='max-width:150px;'>This is one line wrapped because of the maximum width of its container.</p><p>This is another line wrapped<br>because of one forced<br>line break in the middle.</body></html>";
    5455
     56static const char* contentsWithEmbeddedObjects = "<html><body>This is one line containing two <img> embedded objects <img> in the middle.</body></html>";
     57
    5558static const char* comboBoxSelector = "<html><body><select><option selected value='foo'>foo</option><option value='bar'>bar</option></select></body></html>";
    5659
     
    10521055    g_object_unref(paragraph2);
    10531056
     1057    g_object_unref(webView);
     1058}
     1059
     1060static void testWebkitAtkGetTextAtOffsetWithEmbeddedObjects()
     1061{
     1062    WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
     1063    g_object_ref_sink(webView);
     1064    GtkAllocation allocation = { 0, 0, 800, 600 };
     1065    gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
     1066    webkit_web_view_load_string(webView, contentsWithEmbeddedObjects, 0, 0, 0);
     1067
     1068    /* Enable caret browsing. */
     1069    WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
     1070    g_object_set(settings, "enable-caret-browsing", TRUE, NULL);
     1071    webkit_web_view_set_settings(webView, settings);
     1072
     1073    /* Get to the inner AtkText object. */
     1074    AtkObject* object = getWebAreaObject(webView);
     1075    g_assert(object);
     1076
     1077    /* Check the paragraph with the text wrapped because of max-width. */
     1078    AtkText* paragraph = ATK_TEXT(atk_object_ref_accessible_child(object, 0));
     1079    g_assert(ATK_IS_TEXT(paragraph));
     1080
     1081    gchar* text = atk_text_get_text(paragraph, 0, -1);
     1082    g_assert_cmpstr(text, ==, "This is one line containing two \357\277\274 embedded objects \357\277\274 in the middle.");
     1083    g_free(text);
     1084
     1085    /* Check right before the first embedded object */
     1086    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 32, "\357\277\274", 32, 33);
     1087    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 32, "two \357\277\274 ", 28, 34);
     1088    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 32, " \357\277\274 embedded", 31, 42);
     1089
     1090    /* Check right after the first embedded object (and before the first word after it) */
     1091    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 33, " ", 33, 34);
     1092    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 33, "two \357\277\274 ", 28, 34);
     1093    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 33, " \357\277\274 embedded", 31, 42);
     1094
     1095    /* Check at the beginning of the first word between the two embedded objects */
     1096    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 34, "e", 34, 35);
     1097    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 34, "embedded ", 34, 43);
     1098    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 34, " \357\277\274 embedded", 31, 42);
     1099
     1100    /* Check at the end of the first word between the two embedded objects */
     1101    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 42, " ", 42, 43);
     1102    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 42, "embedded ", 34, 43);
     1103    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 42, " objects", 42, 50);
     1104
     1105    /* Check right before the second embedded object */
     1106    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 51, "\357\277\274", 51, 52);
     1107    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 51, "objects \357\277\274 ", 43, 53);
     1108    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 51, " \357\277\274 in", 50, 55);
     1109
     1110    /* Check right after the second embedded object (and before the first word after it) */
     1111    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 52, " ", 52, 53);
     1112    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 52, "objects \357\277\274 ", 43, 53);
     1113    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 52, " \357\277\274 in", 50, 55);
     1114
     1115    /* Check at the beginning of the first word after the two embedded objects */
     1116    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 53, "i", 53, 54);
     1117    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 53, "in ", 53, 56);
     1118    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 53, " \357\277\274 in", 50, 55);
     1119
     1120    /* Check at the end of the first word after the two embedded objects */
     1121    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, 55, " ", 55, 56);
     1122    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, 55, "in ", 53, 56);
     1123    testGetTextFunction(paragraph, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, 55, " the", 55, 59);
     1124
     1125    g_object_unref(paragraph);
    10541126    g_object_unref(webView);
    10551127}
     
    21262198    g_test_add_func("/webkit/atk/getTextAtOffsetWithSpecialCharacters", testWebkitAtkGetTextAtOffsetWithSpecialCharacters);
    21272199    g_test_add_func("/webkit/atk/getTextAtOffsetWithWrappedLines", testWebkitAtkGetTextAtOffsetWithWrappedLines);
     2200    g_test_add_func("/webkit/atk/getTextAtOffsetWithEmbeddedObjects", testWebkitAtkGetTextAtOffsetWithEmbeddedObjects);
    21282201    g_test_add_func("/webkit/atk/getTextInParagraphAndBodySimple", testWebkitAtkGetTextInParagraphAndBodySimple);
    21292202    g_test_add_func("/webkit/atk/getTextInParagraphAndBodyModerate", testWebkitAtkGetTextInParagraphAndBodyModerate);
Note: See TracChangeset for help on using the changeset viewer.