| Differences between
and this patch
- a/Source/WebCore/ChangeLog +22 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2013-07-19  Mario Sanchez Prada  <mario.prada@samsung.com>
2
3
        [GTK] Reimplement atk_text_get_text_*_offset for SENTENCE boundaries
4
        https://bugs.webkit.org/show_bug.cgi?id=114873
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Re-implement this functions without using GailTextUtil nor Pango.
9
10
        * accessibility/atk/WebKitAccessibleInterfaceText.cpp:
11
        (isSentenceBoundary): Helper function to know when we are either
12
        at the beginning or the end of a sentence.
13
        (isSpaceBetweenRealSentences): It returns true if we are in the
14
        middle of a white space between sentences. Useful for implementing
15
        the SENTENCE_END boundary type.
16
        (sentenceAtPositionForAtkBoundary): New helper function to find the
17
        sentence at a given position considering values of AtkTextBoundary.
18
        (webkitAccessibleTextGetSentenceForBoundary): New function,
19
        implementing atk_text_get_text_*_offset for SENTENCE.
20
        (webkitAccessibleTextGetTextForOffset): Replace usage of Gail for
21
        LINE boundaries with webkitAccessibleTextGetWordForBoundary().
22
1
2013-07-16  Mario Sanchez Prada  <mario.prada@samsung.com>
23
2013-07-16  Mario Sanchez Prada  <mario.prada@samsung.com>
2
24
3
        [GTK] Reimplement atk_text_get_text_*_offset for LINE boundaries
25
        [GTK] Reimplement atk_text_get_text_*_offset for LINE boundaries
- a/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp -1 / +151 lines
Lines 38-43 a/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp_sec1
38
#include "Document.h"
38
#include "Document.h"
39
#include "Font.h"
39
#include "Font.h"
40
#include "FrameView.h"
40
#include "FrameView.h"
41
#include "HTMLParserIdioms.h"
41
#include "HostWindow.h"
42
#include "HostWindow.h"
42
#include "InlineTextBox.h"
43
#include "InlineTextBox.h"
43
#include "NotImplemented.h"
44
#include "NotImplemented.h"
Lines 942-947 static char* webkitAccessibleTextGetLineForBoundary(AtkText* text, int offset, A a/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp_sec2
942
    return webkitAccessibleTextGetText(text, *startOffset, *endOffset);
943
    return webkitAccessibleTextGetText(text, *startOffset, *endOffset);
943
}
944
}
944
945
946
static bool isSentenceBoundary(const VisiblePosition &pos)
947
{
948
    if (pos.isNull())
949
        return false;
950
951
    // It's definitely a sentence boundary if there's nothing before.
952
    if (pos.previous().isNull())
953
        return true;
954
955
    // We go backwards and forward to make sure about this.
956
    VisiblePosition startOfPreviousSentence = startOfSentence(pos);
957
    return startOfPreviousSentence.isNotNull() && pos == endOfSentence(startOfPreviousSentence);
958
}
959
960
static bool isSpaceBetweenRealSentences(const VisiblePosition& position)
961
{
962
    if (position.isNull())
963
        return false;
964
965
    if (!isWhitespace(position.characterAfter()))
966
        return false;
967
968
    VisiblePosition startOfWhiteSpace = startOfWord(position, RightWordIfOnBoundary);
969
    VisiblePosition endOfWhiteSpace = endOfWord(startOfWhiteSpace, RightWordIfOnBoundary);
970
    if (!isSentenceBoundary(startOfWhiteSpace) && !isSentenceBoundary(endOfWhiteSpace))
971
        return false;
972
973
    return comparePositions(startOfWhiteSpace, position) <= 0 && comparePositions(endOfWhiteSpace, position) >= 0;
974
}
975
976
static VisibleSelection sentenceAtPositionForAtkBoundary(const AccessibilityObject* coreObject, const VisiblePosition& position, AtkTextBoundary boundaryType)
977
{
978
    VisiblePosition startPosition;
979
    VisiblePosition endPosition;
980
981
    bool isAtStartOfSentenceForEndBoundary = isSpaceBetweenRealSentences(position) || isSentenceBoundary(position);
982
    if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_START || !isAtStartOfSentenceForEndBoundary) {
983
        startPosition = isSentenceBoundary(position) ? position : startOfSentence(position);
984
        // startOfSentence might stop at a linebreak in the HTML source code,
985
        // but we don't want to stop there yet, so keep going.
986
        while (!isSentenceBoundary(startPosition) && isHTMLLineBreak(startPosition.characterBefore()))
987
            startPosition = startOfSentence(startPosition);
988
989
        endPosition = endOfSentence(startPosition);
990
    }
991
992
    if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_END) {
993
        if (isAtStartOfSentenceForEndBoundary) {
994
            startPosition = position;
995
            endPosition = endOfSentence(endOfWord(position, RightWordIfOnBoundary));
996
        }
997
998
        // startOfSentence returns a position after any white space previous to
999
        // the sentence, so we might need to adjust that offset for this boundary.
1000
        if (isWhitespace(startPosition.characterBefore()))
1001
            startPosition = startOfWord(startPosition, LeftWordIfOnBoundary);
1002
1003
        // endOfSentence returns a position after any white space after the
1004
        // sentence, so we might need to adjust that offset for this boundary.
1005
        if (isWhitespace(endPosition.characterBefore()))
1006
            endPosition = startOfWord(endPosition, LeftWordIfOnBoundary);
1007
1008
        // Finally, do some additional adjustments that might be needed if
1009
        // positions are at the start or the end of a line.
1010
        if (isStartOfLine(startPosition) && !isStartOfBlock(startPosition))
1011
            startPosition = startPosition.previous();
1012
        if (isStartOfLine(endPosition) && !isStartOfBlock(endPosition))
1013
            endPosition = endPosition.previous();
1014
    }
1015
1016
    VisibleSelection selectedSentence(startPosition, endPosition);
1017
1018
    // We mark the selection as 'upstream' so we can use that information later,
1019
    // when finding the actual offsets in getSelectionOffsetsForObject().
1020
    if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_END)
1021
        selectedSentence.setAffinity(UPSTREAM);
1022
1023
    return selectedSentence;
1024
}
1025
1026
static char* webkitAccessibleTextGetSentenceForBoundary(AtkText* text, int offset, AtkTextBoundary boundaryType, GetTextRelativePosition textPosition, int* startOffset, int* endOffset)
1027
{
1028
    AccessibilityObject* coreObject = core(text);
1029
    Document* document = coreObject->document();
1030
    if (!document)
1031
        return emptyTextSelectionAtOffset(0, startOffset, endOffset);
1032
1033
    Node* node = getNodeForAccessibilityObject(coreObject);
1034
    if (!node)
1035
        return emptyTextSelectionAtOffset(0, startOffset, endOffset);
1036
1037
    int actualOffset = atkOffsetToWebCoreOffset(text, offset);
1038
1039
    // Besides of the usual conversion from ATK offsets to WebCore offsets,
1040
    // we need to consider the potential embedded objects that might have been
1041
    // inserted in the text exposed through AtkText when calculating the offset.
1042
    actualOffset -= numberOfReplacedElementsBeforeOffset(text, actualOffset);
1043
1044
    VisiblePosition caretPosition = coreObject->visiblePositionForIndex(actualOffset);
1045
    VisibleSelection currentSentence = sentenceAtPositionForAtkBoundary(coreObject, caretPosition, boundaryType);
1046
1047
    // Take into account other relative positions, if needed, by
1048
    // calculating the new position that we would need to consider.
1049
    VisiblePosition newPosition = caretPosition;
1050
    switch (textPosition) {
1051
    case GetTextPositionAt:
1052
        break;
1053
1054
    case GetTextPositionBefore:
1055
        // Early return if asking for the previous sentence while already at the beginning.
1056
        if (isFirstVisiblePositionInNode(currentSentence.visibleStart(), node))
1057
            return emptyTextSelectionAtOffset(0, startOffset, endOffset);
1058
        newPosition = currentSentence.visibleStart().previous();
1059
        break;
1060
1061
    case GetTextPositionAfter:
1062
        // Early return if asking for the following word while already at the end.
1063
        if (isLastVisiblePositionInNode(currentSentence.visibleEnd(), node))
1064
            return emptyTextSelectionAtOffset(accessibilityObjectLength(coreObject), startOffset, endOffset);
1065
        newPosition = currentSentence.visibleEnd().next();
1066
        break;
1067
1068
    default:
1069
        ASSERT_NOT_REACHED();
1070
    }
1071
1072
    // Determine the relevant sentence we are actually interested in
1073
    // and calculate the ATK offsets for it, then return everything.
1074
    VisibleSelection selectedSentence = newPosition != caretPosition ? sentenceAtPositionForAtkBoundary(coreObject, newPosition, boundaryType) : currentSentence;
1075
    getSelectionOffsetsForObject(coreObject, selectedSentence, *startOffset, *endOffset);
1076
1077
    // We might need to adjust the start or end offset to include the list item marker,
1078
    // if present, when printing the first or the last full sentence for a list item.
1079
    RenderObject* renderer = coreObject->renderer();
1080
    if (renderer->isListItem()) {
1081
        // For Left-to-Right, the list item marker is at the beginning of the exposed text.
1082
        if (renderer->style()->direction() == LTR && isFirstVisiblePositionInNode(selectedSentence.visibleStart(), node))
1083
            *startOffset = 0;
1084
1085
        // For Right-to-Left, the list item marker is at the end of the exposed text.
1086
        if (renderer->style()->direction() == RTL && isLastVisiblePositionInNode(selectedSentence.visibleEnd(), node))
1087
            *endOffset = accessibilityObjectLength(coreObject);
1088
    }
1089
1090
    return webkitAccessibleTextGetText(text, *startOffset, *endOffset);
1091
}
1092
945
static gchar* webkitAccessibleTextGetTextForOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, GetTextRelativePosition textPosition, gint* startOffset, gint* endOffset)
1093
static gchar* webkitAccessibleTextGetTextForOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, GetTextRelativePosition textPosition, gint* startOffset, gint* endOffset)
946
{
1094
{
947
    AccessibilityObject* coreObject = core(text);
1095
    AccessibilityObject* coreObject = core(text);
Lines 957-962 static gchar* webkitAccessibleTextGetTextForOffset(AtkText* text, gint offset, A a/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp_sec3
957
    if (boundaryType == ATK_TEXT_BOUNDARY_LINE_START || boundaryType == ATK_TEXT_BOUNDARY_LINE_END)
1105
    if (boundaryType == ATK_TEXT_BOUNDARY_LINE_START || boundaryType == ATK_TEXT_BOUNDARY_LINE_END)
958
        return webkitAccessibleTextGetLineForBoundary(text, offset, boundaryType, textPosition, startOffset, endOffset);
1106
        return webkitAccessibleTextGetLineForBoundary(text, offset, boundaryType, textPosition, startOffset, endOffset);
959
1107
1108
    if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_START || boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_END)
1109
        return webkitAccessibleTextGetSentenceForBoundary(text, offset, boundaryType, textPosition, startOffset, endOffset);
1110
960
#if PLATFORM(GTK)
1111
#if PLATFORM(GTK)
961
    // FIXME: Get rid of the code below once every single part above
1112
    // FIXME: Get rid of the code below once every single part above
962
    // has been properly implemented without using Pango/Cairo.
1113
    // has been properly implemented without using Pango/Cairo.
963
- 

Return to Bug 114873