Diff
Modified: trunk/LayoutTests/ChangeLog (197981 => 197982)
--- trunk/LayoutTests/ChangeLog 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/LayoutTests/ChangeLog 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1,3 +1,15 @@
+2016-03-10 Nan Wang <n_w...@apple.com>
+
+ AX: Implement bounds/position and index related text marker functions using TextIterator
+ https://bugs.webkit.org/show_bug.cgi?id=154976
+
+ Reviewed by Chris Fleizach.
+
+ * accessibility/mac/text-marker-for-index-expected.txt: Added.
+ * accessibility/mac/text-marker-for-index.html: Added.
+ * accessibility/mac/text-marker-word-nav-expected.txt:
+ * accessibility/mac/text-marker-word-nav.html:
+
2016-03-10 Myles C. Maxfield <mmaxfi...@apple.com>
[Cocoa] Test gardening after r197933
Added: trunk/LayoutTests/accessibility/mac/text-marker-for-index-expected.txt (0 => 197982)
--- trunk/LayoutTests/accessibility/mac/text-marker-for-index-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/mac/text-marker-for-index-expected.txt 2016-03-11 02:37:46 UTC (rev 197982)
@@ -0,0 +1,25 @@
+text
+
+text
+audio file.
+This verifies that textMarkerForIndex and indexForTextMarker are working correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Original marker string: x
+Index is: 3
+New marker string: x
+
+Original marker string: 'line break'
+Index is: 6
+New marker string: 'line break'
+
+Original marker string: f
+Index is: 18
+New marker string: f
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/accessibility/mac/text-marker-for-index.html (0 => 197982)
--- trunk/LayoutTests/accessibility/mac/text-marker-for-index.html (rev 0)
+++ trunk/LayoutTests/accessibility/mac/text-marker-for-index.html 2016-03-11 02:37:46 UTC (rev 197982)
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<script src=""
+<body id="body" tabindex="0">
+
+<div tabindex="0" id="text1">text</div>
+<br>
+text
+
+<div id="text2">
+audio <audio controls><source src="" type="audio/mpeg"></audio>file.
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+ description("This verifies that textMarkerForIndex and indexForTextMarker are working correctly.");
+
+ if (window.accessibilityController) {
+ var text = accessibilityController.accessibleElementById("text1");
+ // Get the actual text node.
+ text = text.childAtIndex(0);
+
+ var previous, current;
+ var textMarkerRange = text.textMarkerRangeForElement(text);
+ var startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ var result = forward(3, previous, startMarker, text);
+ previous = result.previous;
+ current = result.current;
+ verifyMarkerIndex(previous, current, text);
+
+ // BR
+ result = forward(2, previous, current, text);
+ previous = result.previous;
+ current = result.current;
+ verifyMarkerIndex(previous, current, text);
+
+ // Attachment
+ text = accessibilityController.accessibleElementById("text2");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ result = forward(8, previous, startMarker, text);
+ previous = result.previous;
+ current = result.current;
+ verifyMarkerIndex(previous, current, text);
+ }
+
+
+ function forward(count, previousMarker, currentMarker, obj) {
+ for (var i = 0; i < count; i++) {
+ previousMarker = currentMarker;
+ currentMarker = obj.nextTextMarker(currentMarker);
+ }
+ return {
+ previous: previousMarker,
+ current: currentMarker
+ };
+ }
+
+ function replaceLinebreakInString(str) {
+ var newline = '\n';
+ str = str.replace(newline, "'line break'");
+ return str;
+ }
+
+ function verifyMarkerIndex(previousMarker, textMarker, obj) {
+ var markerRange = obj.textMarkerRangeForMarkers(previousMarker, textMarker);
+ var originalString = replaceLinebreakInString(obj.stringForTextMarkerRange(markerRange));
+ debug("Original marker string: " + originalString);
+
+ var index = obj.indexForTextMarker(textMarker);
+ var newMarker = obj.textMarkerForIndex(index);
+ markerRange = obj.textMarkerRangeForMarkers(previousMarker, newMarker);
+ var newString = replaceLinebreakInString(obj.stringForTextMarkerRange(markerRange));
+ debug("Index is: " + index + "\nNew marker string: " + newString + "\n");
+ }
+
+</script>
+
+<script src=""
+
+</body>
+</html>
\ No newline at end of file
Modified: trunk/LayoutTests/accessibility/mac/text-marker-word-nav-expected.txt (197981 => 197982)
--- trunk/LayoutTests/accessibility/mac/text-marker-word-nav-expected.txt 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/LayoutTests/accessibility/mac/text-marker-word-nav-expected.txt 2016-03-11 02:37:46 UTC (rev 197982)
@@ -9,6 +9,8 @@
some
text
test audio file
+Edit text
+
This tests that word navigation is working correctly.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -59,6 +61,11 @@
Right word is: can't
Pre word start to next word end: can't
+Current character is:
+Left word is: 巧克力
+Right word is: 巧克力
+Pre word start to next word end: select'line break'巧克力
+
Current character is: 克
Left word is: 巧克力
Right word is: 巧克力
@@ -119,6 +126,11 @@
Right word is: file
Pre word start to next word end: file
+Current character is: t
+Left word is: Edit
+Right word is:
+Pre word start to next word end: Edit text
+
Test going forward.
End word: file
Modified: trunk/LayoutTests/accessibility/mac/text-marker-word-nav.html (197981 => 197982)
--- trunk/LayoutTests/accessibility/mac/text-marker-word-nav.html 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/LayoutTests/accessibility/mac/text-marker-word-nav.html 2016-03-11 02:37:46 UTC (rev 197982)
@@ -39,6 +39,11 @@
test audio <audio controls><source src="" type="audio/mpeg"></audio>file
</div>
+<p id="text8">
+<strong>Edit</strong>
+text
+</p>
+
<p id="description"></p>
<div id="console"></div>
@@ -64,13 +69,13 @@
// At "T" in "Thisis", should return the word as "Thisislongword".
currentMarker = advanceAndVerify(currentMarker, 2, text);
// At " " before "I", the word should be "I'll".
- currentMarker = advanceAndVerify(currentMarker, 15, text);
+ currentMarker = advanceAndVerify(currentMarker, 14, text);
// At " " before "try", the word should excludes "."
- currentMarker = advanceAndVerify(currentMarker, 6, text);
+ currentMarker = advanceAndVerify(currentMarker, 5, text);
// Check the case with contenteditable
// At "e" in "editable", the word should NOT include "Content" before it.
- currentMarker = advanceAndVerify(currentMarker, 19, text);
+ currentMarker = advanceAndVerify(currentMarker, 18, text);
// Check the case with replaced node, the replaced node should be considered a word.
var text2 = accessibilityController.accessibleElementById("text2");
@@ -89,6 +94,8 @@
var text4 = accessibilityController.accessibleElementById("text4");
textMarkerRange = text4.textMarkerRangeForElement(text4);
currentMarker = text4.startTextMarkerForTextMarkerRange(textMarkerRange);
+ // Make sure when we are at the beginning of line, it won't go to previous node.
+ currentMarker = advanceAndVerify(currentMarker, 0, text4);
currentMarker = advanceAndVerify(currentMarker, 2, text4);
currentMarker = advanceAndVerify(currentMarker, 1, text4);
currentMarker = advanceAndVerify(currentMarker, 1, text4);
@@ -123,12 +130,18 @@
currentMarker = advanceAndVerify(currentMarker, 1, text7);
currentMarker = advanceAndVerify(currentMarker, 1, text7);
+ // For node with text node children, we should treat the visual space as word boundary.
+ var text8 = accessibilityController.accessibleElementById("text8");
+ textMarkerRange = text8.textMarkerRangeForElement(text8);
+ currentMarker = text8.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(currentMarker, 4, text8);
+
// Check the word marker runs from start to end, and backwards.
// Make sure it won't hang.
verifyDocument(text);
function advanceAndVerify(currentMarker, offset, obj) {
- var previousMarker;
+ var previousMarker = currentMarker;
for (var i = 0; i < offset; i++) {
previousMarker = currentMarker;
currentMarker = obj.nextTextMarker(previousMarker);
Modified: trunk/Source/WebCore/ChangeLog (197981 => 197982)
--- trunk/Source/WebCore/ChangeLog 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/ChangeLog 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1,3 +1,76 @@
+2016-03-10 Nan Wang <n_w...@apple.com>
+
+ AX: Implement bounds/position and index related text marker functions using TextIterator
+ https://bugs.webkit.org/show_bug.cgi?id=154976
+
+ Reviewed by Chris Fleizach.
+
+ Implemented position and index related text marker calls with TextIterator. Also fixed some
+ VoiceOver navigation issues.
+
+ Test: accessibility/mac/text-marker-for-index.html
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::traverseToOffsetInRange):
+ (WebCore::AXObjectCache::startOrEndCharacterOffsetForRange):
+ (WebCore::AXObjectCache::textMarkerDataForCharacterOffset):
+ (WebCore::AXObjectCache::shouldSkipBoundary):
+ (WebCore::AXObjectCache::textMarkerDataForNextCharacterOffset):
+ (WebCore::AXObjectCache::startCharacterOffsetOfWord):
+ (WebCore::AXObjectCache::nextBoundary):
+ (WebCore::AXObjectCache::previousBoundary):
+ (WebCore::AXObjectCache::previousSentenceStartCharacterOffset):
+ (WebCore::AXObjectCache::localCaretRectForCharacterOffset):
+ (WebCore::AXObjectCache::absoluteCaretBoundsForCharacterOffset):
+ (WebCore::AXObjectCache::characterOffsetForPoint):
+ (WebCore::AXObjectCache::characterOffsetForBounds):
+ (WebCore::AXObjectCache::endCharacterOffsetOfLine):
+ (WebCore::AXObjectCache::startCharacterOffsetOfLine):
+ (WebCore::AXObjectCache::characterOffsetForIndex):
+ (WebCore::AXObjectCache::indexForCharacterOffset):
+ (WebCore::AXObjectCache::rootAXEditableElement):
+ * accessibility/AXObjectCache.h:
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::visiblePositionRangeForRange):
+ (WebCore::AccessibilityObject::rangeForPlainTextRange):
+ (WebCore::AccessibilityObject::lineRangeForPosition):
+ * accessibility/AccessibilityObject.h:
+ (WebCore::AccessibilityObject::boundsForVisiblePositionRange):
+ (WebCore::AccessibilityObject::boundsForRange):
+ (WebCore::AccessibilityObject::setSelectedVisiblePositionRange):
+ (WebCore::AccessibilityObject::doAXStringForRange):
+ (WebCore::AccessibilityObject::doAXBoundsForRange):
+ (WebCore::AccessibilityObject::doAXBoundsForRangeUsingCharacterOffset):
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::nodeIsTextControl):
+ (WebCore::AccessibilityRenderObject::boundsForRects):
+ (WebCore::AccessibilityRenderObject::boundsForVisiblePositionRange):
+ (WebCore::AccessibilityRenderObject::boundsForRange):
+ (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange):
+ (WebCore::AccessibilityRenderObject::doAXBoundsForRange):
+ (WebCore::AccessibilityRenderObject::doAXBoundsForRangeUsingCharacterOffset):
+ (WebCore::AccessibilityRenderObject::accessibilityImageMapHitTest):
+ * accessibility/AccessibilityRenderObject.h:
+ * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+ (-[WebAccessibilityObjectWrapper positionForTextMarker:]):
+ (-[WebAccessibilityObjectWrapper textMarkerRange]):
+ (-[WebAccessibilityObjectWrapper textMarkerRangeForSelection]):
+ (-[WebAccessibilityObjectWrapper textMarkerForPosition:]):
+ (-[WebAccessibilityObjectWrapper _stringForRange:attributed:]):
+ (-[WebAccessibilityObjectWrapper frameForTextMarkers:]):
+ (-[WebAccessibilityObjectWrapper textMarkerForPoint:]):
+ (-[WebAccessibilityObjectWrapper nextMarkerForCharacterOffset:]):
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper doAXAttributedStringForRange:]):
+ (-[WebAccessibilityObjectWrapper _convertToNSRange:]):
+ (-[WebAccessibilityObjectWrapper _indexForTextMarker:]):
+ (-[WebAccessibilityObjectWrapper _textMarkerForIndex:]):
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+ * editing/htmlediting.cpp:
+ (WebCore::localCaretRectInRendererForCaretPainting):
+ (WebCore::localCaretRectInRendererForRect):
+ * editing/htmlediting.h:
+
2016-03-10 Simon Fraser <simon.fra...@apple.com>
Font antialiasing (smoothing) changes when elements are rendered into compositing layers
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1506,8 +1506,9 @@
currentNode = childNode;
hasReplacedNodeOrBR = true;
} else if (currentNode != previousNode) {
- // We should set the currentNode to previous one in case this is the last iteration.
- currentNode = previousNode;
+ // We should set the start offset and length for the current node in case this is the last iteration.
+ lastStartOffset = 1;
+ lastLength = 0;
continue;
}
}
@@ -1695,6 +1696,10 @@
if (!range)
return CharacterOffset();
+ // When getting the end CharacterOffset at node boundary, we don't want to collapse to the previous node.
+ if (!isStart && !range->endOffset())
+ return characterOffsetForNodeAndOffset(range->endContainer(), 0, TraverseOptionIncludeStart);
+
// If it's end text marker, we want to go to the end of the range, and stay within the range.
bool stayWithinRange = !isStart;
@@ -1775,12 +1780,35 @@
setTextMarkerDataWithCharacterOffset(textMarkerData, characterOffset);
}
+bool AXObjectCache::shouldSkipBoundary(const CharacterOffset& previous, const CharacterOffset& next)
+{
+ // Match the behavior of VisiblePosition, we should skip the node boundary when there's no visual space or new line character.
+ if (previous.isNull() || next.isNull())
+ return false;
+
+ if (previous.node == next.node)
+ return false;
+
+ if (next.startIndex > 0 || next.offset > 0)
+ return false;
+
+ CharacterOffset newLine = startCharacterOffsetOfLine(next);
+ if (next.isEqual(newLine))
+ return false;
+
+ return true;
+}
+
void AXObjectCache::textMarkerDataForNextCharacterOffset(TextMarkerData& textMarkerData, const CharacterOffset& characterOffset)
{
CharacterOffset next = characterOffset;
+ CharacterOffset previous = characterOffset;
do {
next = nextCharacterOffset(next, false);
+ if (shouldSkipBoundary(previous, next))
+ next = nextCharacterOffset(next, false);
textMarkerDataForCharacterOffset(textMarkerData, next);
+ previous = next;
} while (textMarkerData.ignored);
}
@@ -1958,7 +1986,10 @@
if (c.isEqual(endOfParagraph))
return c;
- c = nextCharacterOffset(characterOffset);
+ // We should consider the node boundary that splits words. Otherwise VoiceOver won't see it as space.
+ c = nextCharacterOffset(characterOffset, false);
+ if (shouldSkipBoundary(characterOffset, c))
+ c = nextCharacterOffset(c, false);
if (c.isNull())
return characterOffset;
}
@@ -2106,6 +2137,10 @@
if (it.atEnd() && next == string.size())
return end;
+ // We should consider the node boundary that splits words.
+ if (searchFunction == endWordBoundary && next - prefixLength == 1)
+ return nextCharacterOffset(characterOffset, false);
+
// The endSentenceBoundary function will include a line break at the end of the sentence.
if (searchFunction == endSentenceBoundary && string[next - 1] == '\n')
next--;
@@ -2160,7 +2195,7 @@
int characterCount = characterOffset.offset - (string.size() - suffixLength - next);
// We don't want to go to the previous node if the node is at the start of a new line.
- if (characterCount < 0 && (characterOffsetNodeIsBR(characterOffset) || string[string.size() - 1] == '\n'))
+ if (characterCount < 0 && (characterOffsetNodeIsBR(characterOffset) || string[string.size() - suffixLength - 1] == '\n'))
characterCount = 0;
return characterOffsetForNodeAndOffset(*characterOffset.node, characterCount, TraverseOptionIncludeStart);
}
@@ -2283,6 +2318,133 @@
return startCharacterOffsetOfSentence(previous);
}
+LayoutRect AXObjectCache::localCaretRectForCharacterOffset(RenderObject*& renderer, const CharacterOffset& characterOffset)
+{
+ if (characterOffset.isNull()) {
+ renderer = nullptr;
+ return IntRect();
+ }
+
+ Node* node = characterOffset.node;
+
+ renderer = node->renderer();
+ if (!renderer)
+ return LayoutRect();
+
+ InlineBox* inlineBox = nullptr;
+ int caretOffset;
+ // Use a collapsed range to get the position.
+ RefPtr<Range> range = rangeForUnorderedCharacterOffsets(characterOffset, characterOffset);
+ Position startPosition = range->startPosition();
+ startPosition.getInlineBoxAndOffset(DOWNSTREAM, inlineBox, caretOffset);
+
+ if (inlineBox)
+ renderer = &inlineBox->renderer();
+
+ return renderer->localCaretRect(inlineBox, caretOffset);
+}
+
+IntRect AXObjectCache::absoluteCaretBoundsForCharacterOffset(const CharacterOffset& characterOffset)
+{
+ RenderBlock* caretPainter = nullptr;
+
+ // First compute a rect local to the renderer at the selection start.
+ RenderObject* renderer = nullptr;
+ LayoutRect localRect = localCaretRectForCharacterOffset(renderer, characterOffset);
+
+ localRect = localCaretRectInRendererForRect(localRect, characterOffset.node, renderer, caretPainter);
+ return absoluteBoundsForLocalCaretRect(caretPainter, localRect);
+}
+
+CharacterOffset AXObjectCache::characterOffsetForPoint(const IntPoint &point, AccessibilityObject* obj)
+{
+ if (!obj)
+ return CharacterOffset();
+
+ VisiblePosition vp = obj->visiblePositionForPoint(point);
+ RefPtr<Range> range = makeRange(vp, vp);
+ return startOrEndCharacterOffsetForRange(range, true);
+}
+
+CharacterOffset AXObjectCache::characterOffsetForPoint(const IntPoint &point)
+{
+ RefPtr<Range> caretRange = m_document.caretRangeFromPoint(LayoutPoint(point));
+ return startOrEndCharacterOffsetForRange(caretRange, true);
+}
+
+CharacterOffset AXObjectCache::characterOffsetForBounds(const IntRect& rect, bool first)
+{
+ if (rect.isEmpty())
+ return CharacterOffset();
+
+ IntPoint corner = first ? rect.minXMinYCorner() : rect.maxXMaxYCorner();
+ CharacterOffset characterOffset = characterOffsetForPoint(corner);
+
+ if (rect.contains(absoluteCaretBoundsForCharacterOffset(characterOffset).center()))
+ return characterOffset;
+
+ // If the initial position is located outside the bounds adjust it incrementally as needed.
+ CharacterOffset nextCharOffset = nextCharacterOffset(characterOffset, false);
+ CharacterOffset previousCharOffset = previousCharacterOffset(characterOffset, false);
+ while (!nextCharOffset.isNull() || !previousCharOffset.isNull()) {
+ if (rect.contains(absoluteCaretBoundsForCharacterOffset(nextCharOffset).center()))
+ return nextCharOffset;
+ if (rect.contains(absoluteCaretBoundsForCharacterOffset(previousCharOffset).center()))
+ return previousCharOffset;
+
+ nextCharOffset = nextCharacterOffset(nextCharOffset, false);
+ previousCharOffset = previousCharacterOffset(previousCharOffset, false);
+ }
+
+ return CharacterOffset();
+}
+
+// FIXME: Remove VisiblePosition code after implementing this using CharacterOffset.
+CharacterOffset AXObjectCache::endCharacterOffsetOfLine(const CharacterOffset& characterOffset)
+{
+ if (characterOffset.isNull())
+ return CharacterOffset();
+
+ VisiblePosition vp = visiblePositionFromCharacterOffset(characterOffset);
+ VisiblePosition endLine = endOfLine(vp);
+
+ return characterOffsetFromVisiblePosition(endLine);
+}
+
+CharacterOffset AXObjectCache::startCharacterOffsetOfLine(const CharacterOffset& characterOffset)
+{
+ if (characterOffset.isNull())
+ return CharacterOffset();
+
+ VisiblePosition vp = visiblePositionFromCharacterOffset(characterOffset);
+ VisiblePosition startLine = startOfLine(vp);
+
+ return characterOffsetFromVisiblePosition(startLine);
+}
+
+CharacterOffset AXObjectCache::characterOffsetForIndex(int index, const AccessibilityObject* obj)
+{
+ if (!obj)
+ return CharacterOffset();
+
+ // Since this would only work on rendered nodes, using VisiblePosition to create a collapsed
+ // range should be fine.
+ VisiblePosition vp = obj->visiblePositionForIndex(index);
+ RefPtr<Range> range = makeRange(vp, vp);
+
+ return startOrEndCharacterOffsetForRange(range, true);
+}
+
+int AXObjectCache::indexForCharacterOffset(const CharacterOffset& characterOffset, AccessibilityObject* obj)
+{
+ // Create a collapsed range so that we can get the VisiblePosition from it.
+ RefPtr<Range> range = rangeForUnorderedCharacterOffsets(characterOffset, characterOffset);
+ if (!range)
+ return 0;
+ VisiblePosition vp = range->startPosition();
+ return obj->indexForVisiblePosition(vp);
+}
+
const Element* AXObjectCache::rootAXEditableElement(const Node* node)
{
const Element* result = node->rootEditableElement();
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2016-03-11 02:37:46 UTC (rev 197982)
@@ -200,6 +200,7 @@
CharacterOffset nextCharacterOffset(const CharacterOffset&, bool ignoreNextNodeStart = true);
CharacterOffset previousCharacterOffset(const CharacterOffset&, bool ignorePreviousNodeEnd = true);
void startOrEndTextMarkerDataForRange(TextMarkerData&, RefPtr<Range>, bool);
+ CharacterOffset startOrEndCharacterOffsetForRange(RefPtr<Range>, bool);
AccessibilityObject* accessibilityObjectForTextMarkerData(TextMarkerData&);
RefPtr<Range> rangeForUnorderedCharacterOffsets(const CharacterOffset&, const CharacterOffset&);
static RefPtr<Range> rangeForNodeContents(Node*);
@@ -220,6 +221,19 @@
RefPtr<Range> sentenceForCharacterOffset(const CharacterOffset&);
CharacterOffset nextSentenceEndCharacterOffset(const CharacterOffset&);
CharacterOffset previousSentenceStartCharacterOffset(const CharacterOffset&);
+
+ // Bounds
+ CharacterOffset characterOffsetForPoint(const IntPoint&, AccessibilityObject*);
+ IntRect absoluteCaretBoundsForCharacterOffset(const CharacterOffset&);
+ CharacterOffset characterOffsetForBounds(const IntRect&, bool);
+
+ // Lines
+ CharacterOffset endCharacterOffsetOfLine(const CharacterOffset&);
+ CharacterOffset startCharacterOffsetOfLine(const CharacterOffset&);
+
+ // Index
+ CharacterOffset characterOffsetForIndex(int, const AccessibilityObject*);
+ int indexForCharacterOffset(const CharacterOffset&, AccessibilityObject*);
enum AXNotification {
AXActiveDescendantChanged,
@@ -321,7 +335,6 @@
void setTextMarkerDataWithCharacterOffset(TextMarkerData&, const CharacterOffset&);
UChar32 characterAfter(const CharacterOffset&);
UChar32 characterBefore(const CharacterOffset&);
- CharacterOffset startOrEndCharacterOffsetForRange(RefPtr<Range>, bool);
CharacterOffset characterOffsetForNodeAndOffset(Node&, int, TraverseOption = TraverseOptionDefault);
CharacterOffset previousBoundary(const CharacterOffset&, BoundarySearchFunction);
CharacterOffset nextBoundary(const CharacterOffset&, BoundarySearchFunction);
@@ -331,6 +344,9 @@
CharacterOffset endCharacterOffsetOfParagraph(const CharacterOffset&, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
CharacterOffset startCharacterOffsetOfSentence(const CharacterOffset&);
CharacterOffset endCharacterOffsetOfSentence(const CharacterOffset&);
+ CharacterOffset characterOffsetForPoint(const IntPoint&);
+ LayoutRect localCaretRectForCharacterOffset(RenderObject*&, const CharacterOffset&);
+ bool shouldSkipBoundary(const CharacterOffset&, const CharacterOffset&);
private:
AccessibilityObject* rootWebArea();
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1198,6 +1198,20 @@
return VisiblePositionRange(startPosition, endPosition);
}
+RefPtr<Range> AccessibilityObject::rangeForPlainTextRange(const PlainTextRange& range) const
+{
+ unsigned textLength = getLengthForTextRange();
+ if (range.start + range.length > textLength)
+ return nullptr;
+
+ if (AXObjectCache* cache = axObjectCache()) {
+ CharacterOffset start = cache->characterOffsetForIndex(range.start, this);
+ CharacterOffset end = cache->characterOffsetForIndex(range.start + range.length, this);
+ return cache->rangeForUnorderedCharacterOffsets(start, end);
+ }
+ return nullptr;
+}
+
VisiblePositionRange AccessibilityObject::lineRangeForPosition(const VisiblePosition& visiblePosition) const
{
VisiblePosition startPosition = startOfLine(visiblePosition);
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2016-03-11 02:37:46 UTC (rev 197982)
@@ -835,10 +835,13 @@
VisiblePositionRange styleRangeForPosition(const VisiblePosition&) const;
VisiblePositionRange visiblePositionRangeForRange(const PlainTextRange&) const;
VisiblePositionRange lineRangeForPosition(const VisiblePosition&) const;
+
+ RefPtr<Range> rangeForPlainTextRange(const PlainTextRange&) const;
String stringForVisiblePositionRange(const VisiblePositionRange&) const;
String stringForRange(RefPtr<Range>) const;
virtual IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const { return IntRect(); }
+ virtual IntRect boundsForRange(const RefPtr<Range>) const { return IntRect(); }
int lengthForVisiblePositionRange(const VisiblePositionRange&) const;
virtual void setSelectedVisiblePositionRange(const VisiblePositionRange&) const { }
@@ -872,6 +875,7 @@
virtual String doAXStringForRange(const PlainTextRange&) const { return String(); }
virtual IntRect doAXBoundsForRange(const PlainTextRange&) const { return IntRect(); }
+ virtual IntRect doAXBoundsForRangeUsingCharacterOffset(const PlainTextRange&) const { return IntRect(); }
String listMarkerTextForNodeAndPosition(Node*, const VisiblePosition&) const;
unsigned doAXLineForIndex(unsigned);
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1962,6 +1962,26 @@
return false;
}
+IntRect AccessibilityRenderObject::boundsForRects(LayoutRect& rect1, LayoutRect& rect2, RefPtr<Range> dataRange) const
+{
+ LayoutRect ourRect = rect1;
+ ourRect.unite(rect2);
+
+ // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead
+ if (rect1.maxY() != rect2.maxY()) {
+ LayoutRect boundingBox = dataRange->absoluteBoundingBox();
+ String rangeString = plainText(dataRange.get());
+ if (rangeString.length() > 1 && !boundingBox.isEmpty())
+ ourRect = boundingBox;
+ }
+
+#if PLATFORM(MAC)
+ return m_renderer->view().frameView().contentsToScreen(snappedIntRect(ourRect));
+#else
+ return snappedIntRect(ourRect);
+#endif
+}
+
IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
{
if (visiblePositionRange.isNull())
@@ -1985,23 +2005,39 @@
}
}
- LayoutRect ourrect = rect1;
- ourrect.unite(rect2);
+ RefPtr<Range> dataRange = makeRange(range.start, range.end);
+ return boundsForRects(rect1, rect2, dataRange);
+}
+
+IntRect AccessibilityRenderObject::boundsForRange(const RefPtr<Range> range) const
+{
+ if (!range)
+ return IntRect();
- // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead
- if (rect1.maxY() != rect2.maxY()) {
- RefPtr<Range> dataRange = makeRange(range.start, range.end);
- LayoutRect boundingBox = dataRange->absoluteBoundingBox();
- String rangeString = plainText(dataRange.get());
- if (rangeString.length() > 1 && !boundingBox.isEmpty())
- ourrect = boundingBox;
+ AXObjectCache* cache = this->axObjectCache();
+ if (!cache)
+ return IntRect();
+
+ CharacterOffset start = cache->startOrEndCharacterOffsetForRange(range, true);
+ CharacterOffset end = cache->startOrEndCharacterOffsetForRange(range, false);
+
+ LayoutRect rect1 = cache->absoluteCaretBoundsForCharacterOffset(start);
+ LayoutRect rect2 = cache->absoluteCaretBoundsForCharacterOffset(end);
+
+ // readjust for position at the edge of a line. This is to exclude line rect that doesn't need to be accounted in the range bounds.
+ if (rect2.y() != rect1.y()) {
+ CharacterOffset endOfFirstLine = cache->endCharacterOffsetOfLine(start);
+ if (start.isEqual(endOfFirstLine)) {
+ start = cache->nextCharacterOffset(start, false);
+ rect1 = cache->absoluteCaretBoundsForCharacterOffset(start);
+ }
+ if (end.isEqual(endOfFirstLine)) {
+ end = cache->previousCharacterOffset(end, false);
+ rect2 = cache->absoluteCaretBoundsForCharacterOffset(end);
+ }
}
-#if PLATFORM(MAC)
- return m_renderer->view().frameView().contentsToScreen(snappedIntRect(ourrect));
-#else
- return snappedIntRect(ourrect);
-#endif
+ return boundsForRects(rect1, rect2, range);
}
void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
@@ -2196,6 +2232,13 @@
return IntRect();
}
+IntRect AccessibilityRenderObject::doAXBoundsForRangeUsingCharacterOffset(const PlainTextRange& range) const
+{
+ if (allowsTextRanges())
+ return boundsForRange(rangeForPlainTextRange(range));
+ return IntRect();
+}
+
AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
{
if (!area)
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (197981 => 197982)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2016-03-11 02:37:46 UTC (rev 197982)
@@ -173,6 +173,8 @@
VisiblePositionRange visiblePositionRange() const override;
VisiblePositionRange visiblePositionRangeForLine(unsigned) const override;
IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const override;
+ IntRect boundsForRange(const RefPtr<Range>) const override;
+ IntRect boundsForRects(LayoutRect&, LayoutRect&, RefPtr<Range>) const;
void setSelectedVisiblePositionRange(const VisiblePositionRange&) const override;
bool supportsARIAFlowTo() const override;
void ariaFlowToElements(AccessibilityChildrenVector&) const override;
@@ -200,6 +202,7 @@
String doAXStringForRange(const PlainTextRange&) const override;
IntRect doAXBoundsForRange(const PlainTextRange&) const override;
+ IntRect doAXBoundsForRangeUsingCharacterOffset(const PlainTextRange&) const override;
String stringValueForMSAA() const override;
String stringRoleForMSAA() const override;
Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (197981 => 197982)
--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-03-11 02:37:46 UTC (rev 197982)
@@ -2148,10 +2148,14 @@
if (!marker)
return NSNotFound;
- VisibleSelection selection([marker visiblePosition]);
- RefPtr<Range> range = selection.toNormalizedRange();
- NSRange nsRange = [self _convertToNSRange:range.get()];
- return nsRange.location;
+ if (AXObjectCache* cache = m_object->axObjectCache()) {
+ CharacterOffset characterOffset = [marker characterOffset];
+ // Create a collapsed range from the CharacterOffset object.
+ RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(characterOffset, characterOffset);
+ NSRange nsRange = [self _convertToNSRange:range.get()];
+ return nsRange.location;
+ }
+ return NSNotFound;
}
- (NSArray *)textMarkerRange
@@ -2205,11 +2209,17 @@
VisibleSelection selection = m_object->selection();
if (selection.isNone())
return nil;
- VisiblePosition startPosition = selection.visibleStart();
- VisiblePosition endPosition = selection.visibleEnd();
+
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+
+ RefPtr<Range> range = selection.toNormalizedRange();
+ CharacterOffset start = cache->startOrEndCharacterOffsetForRange(range, true);
+ CharacterOffset end = cache->startOrEndCharacterOffsetForRange(range, false);
- WebAccessibilityTextMarker* startMarker = [WebAccessibilityTextMarker textMarkerWithVisiblePosition:startPosition cache:m_object->axObjectCache()];
- WebAccessibilityTextMarker* endMarker = [WebAccessibilityTextMarker textMarkerWithVisiblePosition:endPosition cache:m_object->axObjectCache()];
+ WebAccessibilityTextMarker* startMarker = [WebAccessibilityTextMarker textMarkerWithCharacterOffset:start cache:cache];
+ WebAccessibilityTextMarker* endMarker = [WebAccessibilityTextMarker textMarkerWithCharacterOffset:end cache:cache];
if (!startMarker || !endMarker)
return nil;
@@ -2224,11 +2234,13 @@
RefPtr<Range> range = [self _convertToDOMRange:NSMakeRange(position, 0)];
if (!range)
return nil;
+
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
- VisibleSelection selection = VisibleSelection(*range, DOWNSTREAM);
-
- VisiblePosition visiblePosition = selection.visibleStart();
- return [WebAccessibilityTextMarker textMarkerWithVisiblePosition:visiblePosition cache:m_object->axObjectCache()];
+ CharacterOffset characterOffset = cache->startOrEndCharacterOffsetForRange(range, true);
+ return [WebAccessibilityTextMarker textMarkerWithCharacterOffset:characterOffset cache:cache];
}
- (id)_stringForRange:(NSRange)range attributed:(BOOL)attributed
@@ -2405,15 +2417,14 @@
if (![self _prepareAccessibilityCall])
return CGRectZero;
- if ([array count] != 2)
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
return CGRectZero;
+ RefPtr<Range> range = [self rangeForTextMarkers:array];
+ if (!range)
+ return CGRectZero;
- WebAccessibilityTextMarker* startMarker = [array objectAtIndex:0];
- WebAccessibilityTextMarker* endMarker = [array objectAtIndex:1];
- if (![startMarker isKindOfClass:[WebAccessibilityTextMarker class]] || ![endMarker isKindOfClass:[WebAccessibilityTextMarker class]])
- return CGRectZero;
-
- IntRect rect = m_object->boundsForVisiblePositionRange(VisiblePositionRange([startMarker visiblePosition], [endMarker visiblePosition]));
+ IntRect rect = m_object->boundsForRange(range);
return [self convertRectToScreenSpace:rect];
}
@@ -2422,8 +2433,11 @@
if (![self _prepareAccessibilityCall])
return nil;
- VisiblePosition pos = m_object->visiblePositionForPoint(IntPoint(point));
- return [WebAccessibilityTextMarker textMarkerWithVisiblePosition:pos cache:m_object->axObjectCache()];
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+ CharacterOffset characterOffset = cache->characterOffsetForPoint(IntPoint(point), m_object);
+ return [WebAccessibilityTextMarker textMarkerWithCharacterOffset:characterOffset cache:cache];
}
- (WebAccessibilityTextMarker *)nextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (197981 => 197982)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-03-11 02:37:46 UTC (rev 197982)
@@ -3776,8 +3776,8 @@
- (NSAttributedString*)doAXAttributedStringForRange:(NSRange)range
{
PlainTextRange textRange = PlainTextRange(range.location, range.length);
- VisiblePositionRange visiblePosRange = m_object->visiblePositionRangeForRange(textRange);
- return [self doAXAttributedStringForTextMarkerRange:[self textMarkerRangeFromVisiblePositions:visiblePosRange.start endPosition:visiblePosRange.end]];
+ RefPtr<Range> webRange = m_object->rangeForPlainTextRange(textRange);
+ return [self doAXAttributedStringForTextMarkerRange:[self textMarkerRangeFromRange:webRange]];
}
- (NSRange)_convertToNSRange:(Range*)range
@@ -3804,8 +3804,13 @@
if (!marker)
return NSNotFound;
- VisibleSelection selection([self visiblePositionForTextMarker:marker]);
- return [self _convertToNSRange:selection.toNormalizedRange().get()].location;
+ if (AXObjectCache* cache = m_object->axObjectCache()) {
+ CharacterOffset characterOffset = [self characterOffsetForTextMarker:marker];
+ // Create a collapsed range from the CharacterOffset object.
+ RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(characterOffset, characterOffset);
+ return [self _convertToNSRange:range.get()].location;
+ }
+ return NSNotFound;
}
- (id)_textMarkerForIndex:(NSInteger)textIndex
@@ -3818,8 +3823,11 @@
if (!textRange || !textRange->boundaryPointsValid())
return nil;
- VisiblePosition position(textRange->startPosition());
- return [self textMarkerForVisiblePosition:position];
+ if (AXObjectCache* cache = m_object->axObjectCache()) {
+ CharacterOffset characterOffset = cache->startOrEndCharacterOffsetForRange(textRange, true);
+ return [self textMarkerForCharacterOffset:characterOffset];
+ }
+ return nil;
}
// The RTF representation of the text associated with this accessibility object that is
@@ -3907,6 +3915,10 @@
if (![self updateObjectBackingStore])
return nil;
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+
// common parameter type check/casting. Nil checks in handlers catch wrong type case.
// NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from
// a parameter of the wrong type.
@@ -3964,11 +3976,13 @@
if ([attribute isEqualToString:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute]) {
IntRect webCoreRect = [self screenToContents:enclosingIntRect(rect)];
- return [self textMarkerForVisiblePosition:m_object->visiblePositionForBounds(webCoreRect, LastVisiblePositionForBounds)];
+ CharacterOffset characterOffset = cache->characterOffsetForBounds(webCoreRect, false);
+ return [self textMarkerForCharacterOffset:characterOffset];
}
if ([attribute isEqualToString:NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute]) {
IntRect webCoreRect = [self screenToContents:enclosingIntRect(rect)];
- return [self textMarkerForVisiblePosition:m_object->visiblePositionForBounds(webCoreRect, FirstVisiblePositionForBounds)];
+ CharacterOffset characterOffset = cache->characterOffsetForBounds(webCoreRect, true);
+ return [self textMarkerForCharacterOffset:characterOffset];
}
if ([attribute isEqualToString:NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
@@ -4017,30 +4031,35 @@
if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) {
IntPoint webCorePoint = IntPoint(point);
- return pointSet ? [self textMarkerForVisiblePosition:m_object->visiblePositionForPoint(webCorePoint)] : nil;
+ if (!pointSet)
+ return nil;
+ CharacterOffset characterOffset = cache->characterOffsetForPoint(webCorePoint, m_object);
+ return [self textMarkerForCharacterOffset:characterOffset];
}
if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
- VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
- NSRect rect = m_object->boundsForVisiblePositionRange(visiblePosRange);
+ RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
+ NSRect rect = m_object->boundsForRange(range);
return [NSValue valueWithRect:rect];
}
if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
- VisiblePosition start = m_object->visiblePositionForIndex(range.location);
- VisiblePosition end = m_object->visiblePositionForIndex(range.location+range.length);
+ CharacterOffset start = cache->characterOffsetForIndex(range.location, m_object);
+ CharacterOffset end = cache->characterOffsetForIndex(range.location+range.length, m_object);
if (start.isNull() || end.isNull())
return nil;
- NSRect rect = m_object->boundsForVisiblePositionRange(VisiblePositionRange(start, end));
+ RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(start, end);
+ NSRect rect = m_object->boundsForRange(range);
return [NSValue valueWithRect:rect];
}
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
- VisiblePosition start = m_object->visiblePositionForIndex(range.location);
- VisiblePosition end = m_object->visiblePositionForIndex(range.location+range.length);
+ CharacterOffset start = cache->characterOffsetForIndex(range.location, m_object);
+ CharacterOffset end = cache->characterOffsetForIndex(range.location + range.length, m_object);
if (start.isNull() || end.isNull())
return nil;
- return m_object->stringForVisiblePositionRange(VisiblePositionRange(start, end));
+ RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(start, end);
+ return m_object->stringForRange(range);
}
if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"])
@@ -4055,9 +4074,6 @@
if (!AXObjectIsTextMarker(textMarker1) || !AXObjectIsTextMarker(textMarker2))
return nil;
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset1 = [self characterOffsetForTextMarker:textMarker1];
CharacterOffset characterOffset2 = [self characterOffsetForTextMarker:textMarker2];
RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(characterOffset1, characterOffset2);
@@ -4075,18 +4091,12 @@
}
if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
RefPtr<Range> range = cache->leftWordRange(characterOffset);
return [self textMarkerRangeFromRange:range];
}
if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
RefPtr<Range> range = cache->rightWordRange(characterOffset);
return [self textMarkerRangeFromRange:range];
@@ -4105,36 +4115,24 @@
}
if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
RefPtr<Range> range = cache->sentenceForCharacterOffset(characterOffset);
return [self textMarkerRangeFromRange:range];
}
if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
RefPtr<Range> range = cache->paragraphForCharacterOffset(characterOffset);
return [self textMarkerRangeFromRange:range];
}
if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset nextEnd = cache->nextWordEndCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:nextEnd];
}
if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset previousStart = cache->previousWordStartCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:previousStart];
@@ -4151,36 +4149,24 @@
}
if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset nextEnd = cache->nextSentenceEndCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:nextEnd];
}
if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset previousStart = cache->previousSentenceStartCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:previousStart];
}
if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset nextEnd = cache->nextParagraphEndCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:nextEnd];
}
if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
- AXObjectCache* cache = m_object->axObjectCache();
- if (!cache)
- return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset previousStart = cache->previousParagraphStartCharacterOffset(characterOffset);
return [self textMarkerForCharacterOffset:previousStart];
@@ -4276,7 +4262,7 @@
if (!rangeSet)
return nil;
PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
- NSRect rect = m_object->doAXBoundsForRange(plainTextRange);
+ NSRect rect = m_object->doAXBoundsForRangeUsingCharacterOffset(plainTextRange);
return [NSValue valueWithRect:rect];
}
Modified: trunk/Source/WebCore/editing/htmlediting.cpp (197981 => 197982)
--- trunk/Source/WebCore/editing/htmlediting.cpp 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/editing/htmlediting.cpp 2016-03-11 02:37:46 UTC (rev 197982)
@@ -1320,9 +1320,14 @@
RenderObject* renderer;
LayoutRect localRect = caretPosition.localCaretRect(renderer);
+ return localCaretRectInRendererForRect(localRect, caretPosition.deepEquivalent().deprecatedNode(), renderer, caretPainter);
+}
+
+LayoutRect localCaretRectInRendererForRect(LayoutRect& localRect, Node* node, RenderObject* renderer, RenderBlock*& caretPainter)
+{
// Get the renderer that will be responsible for painting the caret
// (which is either the renderer we just found, or one of its containers).
- caretPainter = rendererForCaretPainting(caretPosition.deepEquivalent().deprecatedNode());
+ caretPainter = rendererForCaretPainting(node);
// Compute an offset between the renderer and the caretPainter.
while (renderer != caretPainter) {
Modified: trunk/Source/WebCore/editing/htmlediting.h (197981 => 197982)
--- trunk/Source/WebCore/editing/htmlediting.h 2016-03-11 01:49:22 UTC (rev 197981)
+++ trunk/Source/WebCore/editing/htmlediting.h 2016-03-11 02:37:46 UTC (rev 197982)
@@ -269,6 +269,7 @@
RenderBlock* rendererForCaretPainting(Node*);
LayoutRect localCaretRectInRendererForCaretPainting(const VisiblePosition&, RenderBlock*&);
+LayoutRect localCaretRectInRendererForRect(LayoutRect&, Node*, RenderObject*, RenderBlock*&);
IntRect absoluteBoundsForLocalCaretRect(RenderBlock* rendererForCaretPainting, const LayoutRect&);
}