|
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 |
- |
|
|