Diff
Modified: trunk/LayoutTests/ChangeLog (196545 => 196546)
--- trunk/LayoutTests/ChangeLog 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/LayoutTests/ChangeLog 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1,3 +1,16 @@
+2016-02-12 Nan Wang <n_w...@apple.com>
+
+ AX: Implement paragraph related text marker functions using TextIterator
+ https://bugs.webkit.org/show_bug.cgi?id=154098
+ <rdar://problem/24269675>
+
+ Reviewed by Chris Fleizach.
+
+ * accessibility/mac/text-marker-paragraph-nav-expected.txt: Added.
+ * accessibility/mac/text-marker-paragraph-nav.html: Added.
+ * accessibility/text-marker/text-marker-previous-next-expected.txt:
+ * accessibility/text-marker/text-marker-previous-next.html:
+
2016-02-12 Saam barati <sbar...@apple.com>
[ES6] we have an incorrect syntax error when a callee of a function _expression_ has the same name as a top-level lexical declaration
Added: trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav-expected.txt (0 => 196546)
--- trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav-expected.txt 2016-02-13 05:24:24 UTC (rev 196546)
@@ -0,0 +1,84 @@
+paragraph test
+Test Contenteditable is working.
+c d
+test audio file
+can't select
+巧克力 是食物吗?
+كيف حالك؟
+both spaces
+line breaks
+some
+text
+this is my first paragraph. Of text. it has some text.
+this is my second paragraph. Of text. it has some text.
+this is my third paragraph. Of text. it has some text.
+
+This tests that paragraph navigation is working correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Current character is: p
+Current paragraph is: paragraph test
+Pre paragraph start to next paragraph end: paragraph test
+
+Current character is: T
+Current paragraph is: Test Content
+Pre paragraph start to next paragraph end: Test Content
+
+Current character is: c
+Current paragraph is: c [ATTACHMENT]d
+Pre paragraph start to next paragraph end: c [ATTACHMENT]d
+
+Current character is: d
+Current paragraph is: c [ATTACHMENT]d
+Pre paragraph start to next paragraph end: c [ATTACHMENT]d
+test audio file
+
+Current character is: t
+Current paragraph is: test audio [ATTACHMENT]file
+Pre paragraph start to next paragraph end: test audio [ATTACHMENT]file
+
+Current character is: c
+Current paragraph is: can't select
+Pre paragraph start to next paragraph end: can't select
+
+Current character is: 巧
+Current paragraph is: 巧克力 是食物吗?
+Pre paragraph start to next paragraph end: 巧克力 是食物吗?
+
+Current character is: ك
+Current paragraph is: كيف حالك؟
+Pre paragraph start to next paragraph end: كيف حالك؟
+
+Current character is: b
+Current paragraph is: both spaces
+Pre paragraph start to next paragraph end: both spaces
+
+Current character is: i
+Current paragraph is: line breaks
+Pre paragraph start to next paragraph end: line breaks
+
+Current character is: s
+Current paragraph is: some
+Pre paragraph start to next paragraph end: some
+
+Current character is: t
+Current paragraph is: text
+Pre paragraph start to next paragraph end: text
+
+Paragraph: this is my first paragraph. Of text. it has some text.
+Paragraph: this is my second paragraph. Of text. it has some text.
+Paragraph: this is my third paragraph. Of text. it has some text.
+Paragraph: this is my third paragraph. Of text. it has some text.
+Paragraph: this is my second paragraph. Of text. it has some text.
+Paragraph: this is my first paragraph. Of text. it has some text.
+Test going forward.
+End paragraph: text
+
+Test going backwards.
+Start paragraph: paragraph test
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav.html (0 => 196546)
--- trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav.html (rev 0)
+++ trunk/LayoutTests/accessibility/mac/text-marker-paragraph-nav.html 2016-02-13 05:24:24 UTC (rev 196546)
@@ -0,0 +1,219 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<style>
+.userselect { user-select: none; -webkit-user-select: none; }
+</style>
+<body id="body">
+
+<div id="text1" tabindex="0">
+para<span>graph</span>
+test
+</div>
+
+<div id="text2">
+Test Content<span contenteditable="true">editable is working.</span>
+</div>
+
+<div id="text3">
+c <img src="" aria-label="blah" style="background-color: #aaaaaa; width: 100px; height: 100px;">d
+</div>
+
+<div id="text4">
+test audio <audio controls><source src="" type="audio/mpeg"></audio>file
+</div>
+
+<div class="" id="text5">can't select</div>
+
+<div id="text6">
+巧克力
+是食物吗?
+</div>
+
+<div id="text6a">
+كيف حالك؟
+</div>
+
+<pre id="text7">
+both spaces
+line breaks
+</pre>
+
+<div id="text8">
+some<br>text
+</div>
+
+<div id="text9">this is my first paragraph. Of text. it has some text.<br>
+this is my second paragraph. Of text. it has some text.<br>
+this is my third paragraph. Of text. it has some text.<br><br>
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+ description("This tests that paragraph navigation is working correctly.");
+
+ if (window.accessibilityController) {
+
+ // Check that we can get the paragraph range with span tag.
+ var text = accessibilityController.accessibleElementById("text1");
+ var textMarkerRange = text.textMarkerRangeForElement(text);
+ var startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ var currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ // Check with contenteditable.
+ text = accessibilityController.accessibleElementById("text2");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ // Check with replaced elements.
+ text = accessibilityController.accessibleElementById("text3");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+ currentMarker = advanceAndVerify(currentMarker, 3, text);
+ // Audio tag.
+ text = accessibilityController.accessibleElementById("text4");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ // Check with user-select:none.
+ text = accessibilityController.accessibleElementById("text5");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ // Multi-languages.
+ text = accessibilityController.accessibleElementById("text6");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ text = accessibilityController.accessibleElementById("text6a");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+
+ // Check the case with pre tag.
+ text = accessibilityController.accessibleElementById("text7");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+ currentMarker = advanceAndVerify(currentMarker, 15, text);
+
+ // Check the case with br tag.
+ text = accessibilityController.accessibleElementById("text8");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = advanceAndVerify(startMarker, 1, text);
+ currentMarker = advanceAndVerify(currentMarker, 5, text);
+
+ // Check getting the correct paragraphs
+ text = accessibilityController.accessibleElementById("text9");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ startMarker = text.nextTextMarker(startMarker);
+ var endMarker = text.endTextMarkerForTextMarkerRange(textMarkerRange);
+ verifyParagraphs(text, startMarker, 3);
+
+ // Check the paragraph marker runs from start to end, and backwards.
+ // Make sure it won't hang.
+ verifyDocument(text);
+
+
+ function advanceAndVerify(currentMarker, offset, obj) {
+ var previousMarker = currentMarker;
+ for (var i = 0; i < offset; i++) {
+ previousMarker = currentMarker;
+ currentMarker = obj.nextTextMarker(previousMarker);
+ }
+ verifyParagraphRangeForTextMarker(previousMarker, currentMarker, obj);
+ return currentMarker;
+ }
+
+ function replaceAttachmentInString(str) {
+ str = str.replace(String.fromCharCode(65532), "[ATTACHMENT]");
+ return str;
+ }
+
+ function verifyParagraphRangeForTextMarker(preMarker, textMarker, obj) {
+ var markerRange = obj.textMarkerRangeForMarkers(preMarker, textMarker);
+ var currentCharacter = replaceAttachmentInString(obj.stringForTextMarkerRange(markerRange));
+ debug("Current character is: " + currentCharacter);
+
+ var paragraphRange = obj.paragraphTextMarkerRangeForTextMarker(textMarker);
+ var paragraph = replaceAttachmentInString(obj.stringForTextMarkerRange(paragraphRange));
+ debug("Current paragraph is: " + paragraph);
+
+ var preStart = obj.previousParagraphStartTextMarkerForTextMarker(textMarker);
+ var nextEnd = obj.nextParagraphEndTextMarkerForTextMarker(textMarker);
+ var preAndNextParagraphRange = obj.textMarkerRangeForMarkers(preStart, nextEnd);
+ var preAndNextParagraph = replaceAttachmentInString(obj.stringForTextMarkerRange(preAndNextParagraphRange));
+ debug("Pre paragraph start to next paragraph end: " + preAndNextParagraph + "\n");
+ }
+
+ function verifyParagraphs(obj, startMarker, paragraphCount) {
+ // Move to the end of first paragraph, so the first paragraph
+ // won't print twice.
+ var current = obj.nextParagraphEndTextMarkerForTextMarker(startMarker);
+ var i = 0;
+ while(i < paragraphCount) {
+ var currRange = obj.paragraphTextMarkerRangeForTextMarker(current);
+ var currParagraph = obj.stringForTextMarkerRange(currRange);
+ debug("Paragraph: " + currParagraph);
+ current = obj.nextParagraphEndTextMarkerForTextMarker(current);
+ i++;
+ }
+
+ // Backwards.
+ current = obj.previousParagraphStartTextMarkerForTextMarker(current);
+ i = 0;
+ while(i < paragraphCount) {
+ var currRange = obj.paragraphTextMarkerRangeForTextMarker(current);
+ var currParagraph = obj.stringForTextMarkerRange(currRange);
+ debug("Paragraph: " + currParagraph);
+ current = obj.previousParagraphStartTextMarkerForTextMarker(current);
+ i++;
+ }
+ }
+
+ function verifyDocument(obj) {
+ var start = obj.startTextMarker;
+
+ // Going forward.
+ debug("Test going forward.");
+ var current = start;
+ var end = "text";
+ var currParagraph = "";
+ while(currParagraph != end) {
+ var currRange = obj.paragraphTextMarkerRangeForTextMarker(current);
+ currParagraph = obj.stringForTextMarkerRange(currRange);
+ current = obj.nextParagraphEndTextMarkerForTextMarker(current);
+ }
+ debug("End paragraph: " + replaceAttachmentInString(currParagraph));
+
+ // Going backwards.
+ debug("\nTest going backwards.");
+ var start = "paragraph test";
+ currParagraph = "";
+ while(currParagraph != start) {
+ var currentRange = obj.paragraphTextMarkerRangeForTextMarker(current);
+ currParagraph = obj.stringForTextMarkerRange(currentRange);
+ current = obj.previousParagraphStartTextMarkerForTextMarker(current);
+ }
+ debug("Start paragraph: " + replaceAttachmentInString(currParagraph));
+ }
+ }
+
+</script>
+
+<script src=""
+</body>
+</html>
\ No newline at end of file
Modified: trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next-expected.txt (196545 => 196546)
--- trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next-expected.txt 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next-expected.txt 2016-02-13 05:24:24 UTC (rev 196546)
@@ -4,6 +4,7 @@
c d
can't select
+abc de f
This tests the next/previous text marker functions are implemented correctly.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -25,6 +26,8 @@
PASS !psw.accessibilityElementForTextMarker(start) is true
PASS text2.accessibilityElementForTextMarker(currentMarker).isEqual(text3) is true
PASS text2.accessibilityElementForTextMarker(currentMarker).isEqual(text2.childAtIndex(2)) is true
+PASS text.stringForTextMarkerRange(markerRange) is 'f'
+PASS text.stringForTextMarkerRange(markerRange) is 'a'
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next.html (196545 => 196546)
--- trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next.html 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/LayoutTests/accessibility/text-marker/text-marker-previous-next.html 2016-02-13 05:24:24 UTC (rev 196546)
@@ -20,6 +20,12 @@
<div class="userselect" id="text3">can't select</div>
+<div id="text4">
+abc
+de
+f
+</div>
+
<p id="description"></p>
<div id="console"></div>
@@ -135,6 +141,27 @@
currentMarker = text2.previousTextMarker(currentMarker);
shouldBeTrue("text2.accessibilityElementForTextMarker(currentMarker).isEqual(text2.childAtIndex(2))");
+
+ // Make sure that text node with line breaks, we can go through it with next/previous call.
+ text = accessibilityController.accessibleElementById("text4");
+ textMarkerRange = text.textMarkerRangeForElement(text);
+ startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = startMarker;
+ for (var i = 0; i < 8; i++) {
+ previousMarker = currentMarker;
+ currentMarker = text.nextTextMarker(currentMarker);
+ }
+ markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker)
+ shouldBe("text.stringForTextMarkerRange(markerRange)", "'f'");
+
+ endMarker = text.endTextMarkerForTextMarkerRange(textMarkerRange);
+ currentMarker = endMarker;
+ for (var i = 0; i < 7; i++) {
+ currentMarker = text.previousTextMarker(currentMarker);
+ }
+ markerRange = text.textMarkerRangeForMarkers(startMarker, currentMarker)
+ shouldBe("text.stringForTextMarkerRange(markerRange)", "'a'");
+
}
</script>
Modified: trunk/Source/WebCore/ChangeLog (196545 => 196546)
--- trunk/Source/WebCore/ChangeLog 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/ChangeLog 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1,3 +1,71 @@
+2016-02-12 Nan Wang <n_w...@apple.com>
+
+ AX: Implement paragraph related text marker functions using TextIterator
+ https://bugs.webkit.org/show_bug.cgi?id=154098
+ <rdar://problem/24269675>
+
+ Reviewed by Chris Fleizach.
+
+ Using CharacterOffset to implement paragraph related text marker calls. Reused
+ logic from VisibleUnits class. And refactored textMarkerForCharacterOffset method
+ to get better performance. Also fixed an issue where we can't navigate through a text
+ node with line breaks in it using next/previousCharacterOffset call.
+
+ Test: accessibility/mac/text-marker-paragraph-nav.html
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::traverseToOffsetInRange):
+ (WebCore::AXObjectCache::startOrEndTextMarkerDataForRange):
+ (WebCore::AXObjectCache::characterOffsetForNodeAndOffset):
+ (WebCore::AXObjectCache::textMarkerDataForCharacterOffset):
+ (WebCore::AXObjectCache::textMarkerDataForNextCharacterOffset):
+ (WebCore::AXObjectCache::textMarkerDataForPreviousCharacterOffset):
+ (WebCore::AXObjectCache::nextNode):
+ (WebCore::AXObjectCache::textMarkerDataForVisiblePosition):
+ (WebCore::AXObjectCache::nextCharacterOffset):
+ (WebCore::AXObjectCache::previousCharacterOffset):
+ (WebCore::startWordBoundary):
+ (WebCore::AXObjectCache::startCharacterOffsetOfWord):
+ (WebCore::AXObjectCache::endCharacterOffsetOfWord):
+ (WebCore::AXObjectCache::previousWordStartCharacterOffset):
+ (WebCore::AXObjectCache::previousWordBoundary):
+ (WebCore::AXObjectCache::startCharacterOffsetOfParagraph):
+ (WebCore::AXObjectCache::endCharacterOffsetOfParagraph):
+ (WebCore::AXObjectCache::paragraphForCharacterOffset):
+ (WebCore::AXObjectCache::nextParagraphEndCharacterOffset):
+ (WebCore::AXObjectCache::previousParagraphStartCharacterOffset):
+ (WebCore::AXObjectCache::rootAXEditableElement):
+ * accessibility/AXObjectCache.h:
+ (WebCore::CharacterOffset::remaining):
+ (WebCore::CharacterOffset::isNull):
+ (WebCore::CharacterOffset::isEqual):
+ (WebCore::AXObjectCache::isNodeInUse):
+ * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+ (+[WebAccessibilityTextMarker textMarkerWithCharacterOffset:cache:]):
+ (-[WebAccessibilityObjectWrapper nextMarkerForCharacterOffset:]):
+ (-[WebAccessibilityObjectWrapper previousMarkerForCharacterOffset:]):
+ (-[WebAccessibilityObjectWrapper rangeForTextMarkers:]):
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (startOrEndTextmarkerForRange):
+ (nextTextMarkerForCharacterOffset):
+ (previousTextMarkerForCharacterOffset):
+ (-[WebAccessibilityObjectWrapper nextTextMarkerForCharacterOffset:]):
+ (-[WebAccessibilityObjectWrapper previousTextMarkerForCharacterOffset:]):
+ (-[WebAccessibilityObjectWrapper textMarkerForCharacterOffset:]):
+ (textMarkerForCharacterOffset):
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+ (-[WebAccessibilityObjectWrapper nextTextMarkerForNode:offset:]): Deleted.
+ (-[WebAccessibilityObjectWrapper previousTextMarkerForNode:offset:]): Deleted.
+ (-[WebAccessibilityObjectWrapper textMarkerForNode:offset:ignoreStart:]): Deleted.
+ (-[WebAccessibilityObjectWrapper textMarkerForNode:offset:]): Deleted.
+ * editing/VisibleUnits.cpp:
+ (WebCore::nextSentencePosition):
+ (WebCore::findStartOfParagraph):
+ (WebCore::findEndOfParagraph):
+ (WebCore::startOfParagraph):
+ (WebCore::endOfParagraph):
+ * editing/VisibleUnits.h:
+
2016-02-12 Ryan Haddad <ryanhad...@apple.com>
Reset results for bindings tests after r196520
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (196545 => 196546)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2016-02-13 05:24:24 UTC (rev 196546)
@@ -83,6 +83,7 @@
#include "ScrollView.h"
#include "TextBoundaries.h"
#include "TextIterator.h"
+#include "htmlediting.h"
#include <wtf/DataLog.h>
#if ENABLE(VIDEO)
@@ -1469,6 +1470,9 @@
}
}
+ // Sometimes text contents in a node are splitted into several iterations, so that iterator.range()->startOffset()
+ // might not be the correct character count. Here we use a previousNode object to keep track of that.
+ Node* previousNode = nullptr;
for (; !iterator.atEnd(); iterator.advance()) {
int currentLength = iterator.text().length();
bool hasReplacedNodeOrBR = false;
@@ -1497,22 +1501,27 @@
if (childNode && childNode->renderer() && childNode->renderer()->isBR()) {
currentNode = childNode;
hasReplacedNodeOrBR = true;
- } else
+ } else if (currentNode != previousNode)
continue;
}
}
offsetSoFar += currentLength;
}
- lastLength = currentLength;
- lastStartOffset = hasReplacedNodeOrBR ? 0 : iterator.range()->startOffset();
+ if (currentNode == previousNode)
+ lastLength += currentLength;
+ else {
+ lastLength = currentLength;
+ lastStartOffset = hasReplacedNodeOrBR ? 0 : iterator.range()->startOffset();
+ }
// Break early if we have advanced enough characters.
if (!toNodeEnd && offsetSoFar >= offset) {
- offsetInCharacter = offset - (offsetSoFar - currentLength);
+ offsetInCharacter = offset - (offsetSoFar - lastLength);
finished = true;
break;
}
+ previousNode = currentNode;
}
if (!finished) {
@@ -1707,15 +1716,18 @@
setTextMarkerDataWithCharacterOffset(textMarkerData, characterOffset);
}
-CharacterOffset AXObjectCache::characterOffsetForNodeAndOffset(Node& node, int offset, bool toNodeEnd, bool ignoreStart)
+CharacterOffset AXObjectCache::characterOffsetForNodeAndOffset(Node& node, int offset, TraverseOption option)
{
Node* domNode = &node;
if (!domNode)
return CharacterOffset();
+ bool toNodeEnd = option & TraverseOptionToNodeEnd;
+ bool includeStart = option & TraverseOptionIncludeStart;
+
// ignoreStart is used to determine if we should go to previous node or
// stay in current node when offset is 0.
- if (!toNodeEnd && (offset < 0 || (!offset && ignoreStart))) {
+ if (!toNodeEnd && (offset < 0 || (!offset && !includeStart))) {
// Set the offset to the amount of characters we need to go backwards.
offset = - offset;
CharacterOffset charOffset = CharacterOffset();
@@ -1723,14 +1735,14 @@
offset -= charOffset.offset;
domNode = previousNode(domNode);
if (domNode) {
- charOffset = characterOffsetForNodeAndOffset(*domNode, 0, true);
+ charOffset = characterOffsetForNodeAndOffset(*domNode, 0, TraverseOptionToNodeEnd);
} else
return CharacterOffset();
if (!offset)
break;
}
if (offset > 0)
- charOffset = characterOffsetForNodeAndOffset(*charOffset.node, charOffset.offset - offset, false);
+ charOffset = characterOffsetForNodeAndOffset(*charOffset.node, charOffset.offset - offset);
return charOffset;
}
@@ -1750,14 +1762,30 @@
return characterOffset;
}
-void AXObjectCache::textMarkerDataForCharacterOffset(TextMarkerData& textMarkerData, Node& node, int offset, bool toNodeEnd, bool ignoreStart)
+void AXObjectCache::textMarkerDataForCharacterOffset(TextMarkerData& textMarkerData, const CharacterOffset& characterOffset)
{
memset(&textMarkerData, 0, sizeof(TextMarkerData));
-
- CharacterOffset characterOffset = characterOffsetForNodeAndOffset(node, offset, toNodeEnd, ignoreStart);
setTextMarkerDataWithCharacterOffset(textMarkerData, characterOffset);
}
+void AXObjectCache::textMarkerDataForNextCharacterOffset(TextMarkerData& textMarkerData, const CharacterOffset& characterOffset)
+{
+ CharacterOffset next = characterOffset;
+ do {
+ next = nextCharacterOffset(next);
+ textMarkerDataForCharacterOffset(textMarkerData, next);
+ } while (textMarkerData.ignored);
+}
+
+void AXObjectCache::textMarkerDataForPreviousCharacterOffset(TextMarkerData& textMarkerData, const CharacterOffset& characterOffset)
+{
+ CharacterOffset previous = characterOffset;
+ do {
+ previous = previousCharacterOffset(previous);
+ textMarkerDataForCharacterOffset(textMarkerData, previous);
+ } while (textMarkerData.ignored);
+}
+
Node* AXObjectCache::nextNode(Node* node) const
{
if (!node)
@@ -1875,20 +1903,20 @@
cache->setNodeInUse(domNode);
}
-CharacterOffset AXObjectCache::nextCharacterOffset(const CharacterOffset& characterOffset)
+CharacterOffset AXObjectCache::nextCharacterOffset(const CharacterOffset& characterOffset, bool ignoreStart)
{
if (characterOffset.isNull())
return CharacterOffset();
- return characterOffsetForNodeAndOffset(*characterOffset.node, characterOffset.offset + 1);
+ return characterOffsetForNodeAndOffset(*characterOffset.node, characterOffset.offset + 1, ignoreStart ? TraverseOptionDefault : TraverseOptionIncludeStart);
}
-CharacterOffset AXObjectCache::previousCharacterOffset(const CharacterOffset& characterOffset)
+CharacterOffset AXObjectCache::previousCharacterOffset(const CharacterOffset& characterOffset, bool ignoreStart)
{
if (characterOffset.isNull())
return CharacterOffset();
- return characterOffsetForNodeAndOffset(*characterOffset.node, characterOffset.offset - 1, false, false);
+ return characterOffsetForNodeAndOffset(*characterOffset.node, characterOffset.offset - 1, ignoreStart ? TraverseOptionDefault : TraverseOptionIncludeStart);
}
static unsigned startWordBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
@@ -1925,9 +1953,8 @@
CharacterOffset c = characterOffset;
if (side == RightWordIfOnBoundary) {
- // FIXME: need to remove this when isEndOfParagraph is implemented for CharacterOffset.
- VisiblePosition vp = visiblePositionFromCharacterOffset(c);
- if (isEndOfParagraph(vp))
+ CharacterOffset endOfParagraph = endCharacterOffsetOfParagraph(c);
+ if (c.isEqual(endOfParagraph))
return c;
c = nextCharacterOffset(characterOffset);
@@ -1945,12 +1972,11 @@
CharacterOffset c = characterOffset;
if (side == LeftWordIfOnBoundary) {
- // FIXME: need to remove this when isStartOfParagraph is implemented for CharacterOffset.
- VisiblePosition vp = visiblePositionFromCharacterOffset(c);
- if (isStartOfParagraph(vp))
+ CharacterOffset startOfParagraph = startCharacterOffsetOfParagraph(c);
+ if (c.isEqual(startOfParagraph))
return c;
- c = previousCharacterOffset(characterOffset);
+ c = previousCharacterOffset(characterOffset, false);
if (c.isNull())
return characterOffset;
}
@@ -1963,7 +1989,7 @@
if (characterOffset.isNull())
return CharacterOffset();
- CharacterOffset previousOffset = previousCharacterOffset(characterOffset);
+ CharacterOffset previousOffset = previousCharacterOffset(characterOffset, false);
if (previousOffset.isNull())
return CharacterOffset();
@@ -2111,13 +2137,84 @@
// The next variable contains a usable index into a text node
if (&node == characterOffset.node)
next -= characterOffset.startIndex;
- return characterOffsetForNodeAndOffset(node, next, false);
+ return characterOffsetForNodeAndOffset(node, next, TraverseOptionIncludeStart);
}
int characterCount = characterOffset.offset - (string.size() - suffixLength - next);
- return characterOffsetForNodeAndOffset(*characterOffset.node, characterCount, false, false);
+ return characterOffsetForNodeAndOffset(*characterOffset.node, characterCount, TraverseOptionIncludeStart);
}
+CharacterOffset AXObjectCache::startCharacterOffsetOfParagraph(const CharacterOffset& characterOffset, EditingBoundaryCrossingRule boundaryCrossingRule)
+{
+ if (characterOffset.isNull())
+ return CharacterOffset();
+
+ Node* startNode = characterOffset.node;
+
+ if (isRenderedAsNonInlineTableImageOrHR(startNode))
+ return startOrEndCharacterOffsetForRange(rangeForNodeContents(startNode), true);
+
+ Node* startBlock = enclosingBlock(startNode);
+ int offset = characterOffset.startIndex + characterOffset.offset;
+ Position p(startNode, offset, Position::PositionIsOffsetInAnchor);
+ Node* highestRoot = highestEditableRoot(p);
+ Position::AnchorType type = Position::PositionIsOffsetInAnchor;
+
+ Node* node = findStartOfParagraph(startNode, highestRoot, startBlock, offset, type, boundaryCrossingRule);
+
+ if (type == Position::PositionIsOffsetInAnchor)
+ return characterOffsetForNodeAndOffset(*node, offset, TraverseOptionIncludeStart);
+
+ return startOrEndCharacterOffsetForRange(rangeForNodeContents(node), true);
+}
+
+CharacterOffset AXObjectCache::endCharacterOffsetOfParagraph(const CharacterOffset& characterOffset, EditingBoundaryCrossingRule boundaryCrossingRule)
+{
+ if (characterOffset.isNull())
+ return CharacterOffset();
+
+ Node* startNode = characterOffset.node;
+ if (isRenderedAsNonInlineTableImageOrHR(startNode))
+ return startOrEndCharacterOffsetForRange(rangeForNodeContents(startNode), false);
+
+ Node* stayInsideBlock = enclosingBlock(startNode);
+ int offset = characterOffset.startIndex + characterOffset.offset;
+ Position p(startNode, offset, Position::PositionIsOffsetInAnchor);
+ Node* highestRoot = highestEditableRoot(p);
+ Position::AnchorType type = Position::PositionIsOffsetInAnchor;
+
+ Node* node = findEndOfParagraph(startNode, highestRoot, stayInsideBlock, offset, type, boundaryCrossingRule);
+ if (type == Position::PositionIsOffsetInAnchor) {
+ if (node->isTextNode()) {
+ CharacterOffset startOffset = startOrEndCharacterOffsetForRange(rangeForNodeContents(node), true);
+ offset -= startOffset.startIndex;
+ }
+ return characterOffsetForNodeAndOffset(*node, offset, TraverseOptionIncludeStart);
+ }
+
+ return startOrEndCharacterOffsetForRange(rangeForNodeContents(node), false);
+}
+
+RefPtr<Range> AXObjectCache::paragraphForCharacterOffset(const CharacterOffset& characterOffset)
+{
+ CharacterOffset start = startCharacterOffsetOfParagraph(characterOffset);
+ CharacterOffset end = endCharacterOffsetOfParagraph(characterOffset);
+
+ return rangeForUnorderedCharacterOffsets(start, end);
+}
+
+CharacterOffset AXObjectCache::nextParagraphEndCharacterOffset(const CharacterOffset& characterOffset)
+{
+ // make sure we move off of a paragraph end
+ return endCharacterOffsetOfParagraph(nextCharacterOffset(characterOffset));
+}
+
+CharacterOffset AXObjectCache::previousParagraphStartCharacterOffset(const CharacterOffset& characterOffset)
+{
+ // make sure we move off of a paragraph start
+ return startCharacterOffsetOfParagraph(previousCharacterOffset(characterOffset, false));
+}
+
const Element* AXObjectCache::rootAXEditableElement(const Node* node)
{
const Element* result = node->rootEditableElement();
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (196545 => 196546)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2016-02-13 05:24:24 UTC (rev 196546)
@@ -74,6 +74,12 @@
int remaining() const { return remainingOffset; }
bool isNull() const { return !node; }
+ bool isEqual(CharacterOffset& other) const
+ {
+ if (isNull() || other.isNull())
+ return false;
+ return node == other.node && startIndex == other.startIndex && offset == other.offset;
+ }
};
class AXComputedObjectAttributeCache {
@@ -185,9 +191,13 @@
// Text marker utilities.
void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
+ void textMarkerDataForCharacterOffset(TextMarkerData&, const CharacterOffset&);
+ void textMarkerDataForNextCharacterOffset(TextMarkerData&, const CharacterOffset&);
+ void textMarkerDataForPreviousCharacterOffset(TextMarkerData&, const CharacterOffset&);
VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
CharacterOffset characterOffsetForTextMarkerData(TextMarkerData&);
- void textMarkerDataForCharacterOffset(TextMarkerData&, Node&, int, bool toNodeEnd = false, bool ignoreStart = true);
+ CharacterOffset nextCharacterOffset(const CharacterOffset&, bool ignoreStart = true);
+ CharacterOffset previousCharacterOffset(const CharacterOffset&, bool ignoreStart = true);
void startOrEndTextMarkerDataForRange(TextMarkerData&, RefPtr<Range>, bool);
AccessibilityObject* accessibilityObjectForTextMarkerData(TextMarkerData&);
RefPtr<Range> rangeForUnorderedCharacterOffsets(const CharacterOffset&, const CharacterOffset&);
@@ -195,12 +205,15 @@
static int lengthForRange(Range*);
// Word boundary
- CharacterOffset startCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
- CharacterOffset endCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
CharacterOffset nextWordEndCharacterOffset(const CharacterOffset&);
CharacterOffset previousWordStartCharacterOffset(const CharacterOffset&);
RefPtr<Range> leftWordRange(const CharacterOffset&);
RefPtr<Range> rightWordRange(const CharacterOffset&);
+
+ // Paragraph
+ RefPtr<Range> paragraphForCharacterOffset(const CharacterOffset&);
+ CharacterOffset nextParagraphEndCharacterOffset(const CharacterOffset&);
+ CharacterOffset previousParagraphStartCharacterOffset(const CharacterOffset&);
enum AXNotification {
AXActiveDescendantChanged,
@@ -293,6 +306,7 @@
bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
// CharacterOffset functions.
+ enum TraverseOption { TraverseOptionDefault = 1 << 0, TraverseOptionToNodeEnd = 1 << 1, TraverseOptionIncludeStart = 1 << 2 };
Node* nextNode(Node*) const;
Node* previousNode(Node*) const;
CharacterOffset traverseToOffsetInRange(RefPtr<Range>, int, bool, bool stayWithinRange = false);
@@ -302,11 +316,13 @@
UChar32 characterAfter(const CharacterOffset&);
UChar32 characterBefore(const CharacterOffset&);
CharacterOffset startOrEndCharacterOffsetForRange(RefPtr<Range>, bool);
- CharacterOffset characterOffsetForNodeAndOffset(Node&, int, bool toNodeEnd = false, bool ignoreStart = true);
- CharacterOffset nextCharacterOffset(const CharacterOffset&);
- CharacterOffset previousCharacterOffset(const CharacterOffset&);
+ CharacterOffset characterOffsetForNodeAndOffset(Node&, int, TraverseOption = TraverseOptionDefault);
CharacterOffset previousWordBoundary(CharacterOffset&, BoundarySearchFunction);
CharacterOffset nextWordBoundary(CharacterOffset&, BoundarySearchFunction);
+ CharacterOffset startCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
+ CharacterOffset endCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
+ CharacterOffset startCharacterOffsetOfParagraph(const CharacterOffset&, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
+ CharacterOffset endCharacterOffsetOfParagraph(const CharacterOffset&, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
private:
AccessibilityObject* rootWebArea();
Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (196545 => 196546)
--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -189,7 +189,7 @@
return nil;
TextMarkerData textMarkerData;
- cache->textMarkerDataForCharacterOffset(textMarkerData, *characterOffset.node, characterOffset.offset, false);
+ cache->textMarkerDataForCharacterOffset(textMarkerData, characterOffset);
if (!textMarkerData.axID && !textMarkerData.ignored)
return nil;
return [[[WebAccessibilityTextMarker alloc] initWithTextMarker:&textMarkerData cache:cache] autorelease];
@@ -2425,20 +2425,28 @@
- (WebAccessibilityTextMarker *)nextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
- characterOffset.offset = characterOffset.offset + 1;
- WebAccessibilityTextMarker *textMarker = [WebAccessibilityTextMarker textMarkerWithCharacterOffset:characterOffset cache:m_object->axObjectCache()];
- if (textMarker && textMarker.isIgnored)
- textMarker = [self nextMarkerForCharacterOffset:characterOffset];
- return textMarker;
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+
+ TextMarkerData textMarkerData;
+ cache->textMarkerDataForNextCharacterOffset(textMarkerData, characterOffset);
+ if (!textMarkerData.axID)
+ return nil;
+ return [[[WebAccessibilityTextMarker alloc] initWithTextMarker:&textMarkerData cache:cache] autorelease];
}
- (WebAccessibilityTextMarker *)previousMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
- characterOffset.offset = characterOffset.offset - 1;
- WebAccessibilityTextMarker *textMarker = [WebAccessibilityTextMarker textMarkerWithCharacterOffset:characterOffset cache:m_object->axObjectCache()];
- if (textMarker && textMarker.isIgnored)
- textMarker = [self previousMarkerForCharacterOffset:characterOffset];
- return textMarker;
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+
+ TextMarkerData textMarkerData;
+ cache->textMarkerDataForPreviousCharacterOffset(textMarkerData, characterOffset);
+ if (!textMarkerData.axID)
+ return nil;
+ return [[[WebAccessibilityTextMarker alloc] initWithTextMarker:&textMarkerData cache:cache] autorelease];
}
- (RefPtr<Range>)rangeForTextMarkers:(NSArray *)textMarkers
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (196545 => 196546)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -840,45 +840,52 @@
return CFBridgingRelease(wkCreateAXTextMarker(&textMarkerData, sizeof(textMarkerData)));
}
-- (id)nextTextMarkerForNode:(Node&)node offset:(int)offset
+static id nextTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
{
- int nextOffset = offset + 1;
- id textMarker = [self textMarkerForNode:node offset:nextOffset];
- if (isTextMarkerIgnored(textMarker))
- textMarker = [self nextTextMarkerForNode:node offset:nextOffset];
- return textMarker;
+ if (!cache)
+ return nil;
+
+ TextMarkerData textMarkerData;
+ cache->textMarkerDataForNextCharacterOffset(textMarkerData, characterOffset);
+ if (!textMarkerData.axID)
+ return nil;
+ return CFBridgingRelease(wkCreateAXTextMarker(&textMarkerData, sizeof(textMarkerData)));
}
-- (id)previousTextMarkerForNode:(Node&)node offset:(int)offset
+static id previousTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
{
- int previousOffset = offset - 1;
- id textMarker = [self textMarkerForNode:node offset:previousOffset];
- if (isTextMarkerIgnored(textMarker))
- textMarker = [self previousTextMarkerForNode:node offset:previousOffset];
- return textMarker;
+ if (!cache)
+ return nil;
+
+ TextMarkerData textMarkerData;
+ cache->textMarkerDataForPreviousCharacterOffset(textMarkerData, characterOffset);
+ if (!textMarkerData.axID)
+ return nil;
+ return CFBridgingRelease(wkCreateAXTextMarker(&textMarkerData, sizeof(textMarkerData)));
}
-- (id)textMarkerForNode:(Node&)node offset:(int)offset ignoreStart:(BOOL)ignoreStart
+- (id)nextTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
- return textMarkerForCharacterOffset(m_object->axObjectCache(), node, offset, false, ignoreStart);
+ return nextTextMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
}
-- (id)textMarkerForNode:(Node&)node offset:(int)offset
+- (id)previousTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
- return [self textMarkerForNode:node offset:offset ignoreStart:YES];
+ return previousTextMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
}
-static id textMarkerForCharacterOffset(AXObjectCache* cache, Node& node, int offset, bool toNodeEnd, bool ignoreStart)
+- (id)textMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
+ return textMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
+}
+
+static id textMarkerForCharacterOffset(AXObjectCache* cache, const CharacterOffset& characterOffset)
+{
if (!cache)
return nil;
- Node* domNode = &node;
- if (!domNode)
- return nil;
-
TextMarkerData textMarkerData;
- cache->textMarkerDataForCharacterOffset(textMarkerData, node, offset, toNodeEnd, ignoreStart);
+ cache->textMarkerDataForCharacterOffset(textMarkerData, characterOffset);
if (!textMarkerData.axID && !textMarkerData.ignored)
return nil;
@@ -4066,12 +4073,12 @@
if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
- return [self nextTextMarkerForNode:*characterOffset.node offset:characterOffset.offset];
+ return [self nextTextMarkerForCharacterOffset:characterOffset];
}
if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
- return [self previousTextMarkerForNode:*characterOffset.node offset:characterOffset.offset];
+ return [self previousTextMarkerForCharacterOffset:characterOffset];
}
if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
@@ -4111,9 +4118,12 @@
}
if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
- VisiblePositionRange vpRange = m_object->paragraphForPosition(visiblePos);
- return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
+ 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"]) {
@@ -4122,7 +4132,7 @@
return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset nextEnd = cache->nextWordEndCharacterOffset(characterOffset);
- return [self textMarkerForNode:*nextEnd.node offset:nextEnd.offset];
+ return [self textMarkerForCharacterOffset:nextEnd];
}
if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
@@ -4131,7 +4141,7 @@
return nil;
CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
CharacterOffset previousStart = cache->previousWordStartCharacterOffset(characterOffset);
- return [self textMarkerForNode:*previousStart.node offset:previousStart.offset ignoreStart:NO];
+ return [self textMarkerForCharacterOffset:previousStart];
}
if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
@@ -4160,8 +4170,12 @@
}
if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
- return [self textMarkerForVisiblePosition:m_object->previousParagraphStartPosition(visiblePos)];
+ AXObjectCache* cache = m_object->axObjectCache();
+ if (!cache)
+ return nil;
+ CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
+ CharacterOffset previousStart = cache->previousParagraphStartCharacterOffset(characterOffset);
+ return [self textMarkerForCharacterOffset:previousStart];
}
if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
Modified: trunk/Source/WebCore/editing/VisibleUnits.cpp (196545 => 196546)
--- trunk/Source/WebCore/editing/VisibleUnits.cpp 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/editing/VisibleUnits.cpp 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1142,24 +1142,9 @@
return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextSentencePositionBoundary));
}
-VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
+Node* findStartOfParagraph(Node* startNode, Node* highestRoot, Node* startBlock, int& offset, Position::AnchorType& type, EditingBoundaryCrossingRule boundaryCrossingRule)
{
- Position p = c.deepEquivalent();
- Node* startNode = p.deprecatedNode();
-
- if (!startNode)
- return VisiblePosition();
-
- if (isRenderedAsNonInlineTableImageOrHR(startNode))
- return positionBeforeNode(startNode);
-
- Node* startBlock = enclosingBlock(startNode);
-
Node* node = startNode;
- Node* highestRoot = highestEditableRoot(p);
- int offset = p.deprecatedEditingOffset();
- Position::AnchorType type = p.anchorType();
-
Node* n = startNode;
while (n) {
#if ENABLE(USERSELECT_ALL)
@@ -1198,8 +1183,10 @@
if (n == startNode && o < i)
i = std::max(0, o);
while (--i >= 0) {
- if (text[i] == '\n')
- return VisiblePosition(Position(downcast<Text>(n), i + 1), DOWNSTREAM);
+ if (text[i] == '\n') {
+ offset = i + 1;
+ return n;
+ }
}
}
node = n;
@@ -1213,33 +1200,12 @@
n = NodeTraversal::previousPostOrder(*n, startBlock);
}
- if (type == Position::PositionIsOffsetInAnchor) {
- ASSERT(type == Position::PositionIsOffsetInAnchor || !offset);
- return VisiblePosition(Position(node, offset, type), DOWNSTREAM);
- }
-
- return VisiblePosition(Position(node, type), DOWNSTREAM);
+ return node;
}
-VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
-{
- if (c.isNull())
- return VisiblePosition();
-
- Position p = c.deepEquivalent();
- Node* startNode = p.deprecatedNode();
-
- if (isRenderedAsNonInlineTableImageOrHR(startNode))
- return positionAfterNode(startNode);
-
- Node* startBlock = enclosingBlock(startNode);
- Node* stayInsideBlock = startBlock;
-
+Node* findEndOfParagraph(Node* startNode, Node* highestRoot, Node* stayInsideBlock, int& offset, Position::AnchorType& type, EditingBoundaryCrossingRule boundaryCrossingRule)
+{
Node* node = startNode;
- Node* highestRoot = highestEditableRoot(p);
- int offset = p.deprecatedEditingOffset();
- Position::AnchorType type = p.anchorType();
-
Node* n = startNode;
while (n) {
#if ENABLE(USERSELECT_ALL)
@@ -1279,8 +1245,10 @@
int o = n == startNode ? offset : 0;
int length = text.length();
for (int i = o; i < length; ++i) {
- if (text[i] == '\n')
- return VisiblePosition(Position(downcast<Text>(n), i), DOWNSTREAM);
+ if (text[i] == '\n') {
+ offset = i;
+ return n;
+ }
}
}
node = n;
@@ -1293,7 +1261,62 @@
} else
n = NodeTraversal::next(*n, stayInsideBlock);
}
+ return node;
+}
+VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
+{
+ Position p = c.deepEquivalent();
+ Node* startNode = p.deprecatedNode();
+
+ if (!startNode)
+ return VisiblePosition();
+
+ if (isRenderedAsNonInlineTableImageOrHR(startNode))
+ return positionBeforeNode(startNode);
+
+ Node* startBlock = enclosingBlock(startNode);
+
+ Node* highestRoot = highestEditableRoot(p);
+ int offset = p.deprecatedEditingOffset();
+ Position::AnchorType type = p.anchorType();
+
+ Node* node = findStartOfParagraph(startNode, highestRoot, startBlock, offset, type, boundaryCrossingRule);
+
+ if (is<Text>(node))
+ return VisiblePosition(Position(downcast<Text>(node), offset), DOWNSTREAM);
+
+ if (type == Position::PositionIsOffsetInAnchor) {
+ ASSERT(type == Position::PositionIsOffsetInAnchor || !offset);
+ return VisiblePosition(Position(node, offset, type), DOWNSTREAM);
+ }
+
+ return VisiblePosition(Position(node, type), DOWNSTREAM);
+}
+
+VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
+{
+ if (c.isNull())
+ return VisiblePosition();
+
+ Position p = c.deepEquivalent();
+ Node* startNode = p.deprecatedNode();
+
+ if (isRenderedAsNonInlineTableImageOrHR(startNode))
+ return positionAfterNode(startNode);
+
+ Node* startBlock = enclosingBlock(startNode);
+ Node* stayInsideBlock = startBlock;
+
+ Node* highestRoot = highestEditableRoot(p);
+ int offset = p.deprecatedEditingOffset();
+ Position::AnchorType type = p.anchorType();
+
+ Node* node = findEndOfParagraph(startNode, highestRoot, stayInsideBlock, offset, type, boundaryCrossingRule);
+
+ if (is<Text>(node))
+ return VisiblePosition(Position(downcast<Text>(node), offset), DOWNSTREAM);
+
if (type == Position::PositionIsOffsetInAnchor)
return VisiblePosition(Position(node, offset, type), DOWNSTREAM);
Modified: trunk/Source/WebCore/editing/VisibleUnits.h (196545 => 196546)
--- trunk/Source/WebCore/editing/VisibleUnits.h 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Source/WebCore/editing/VisibleUnits.h 2016-02-13 05:24:24 UTC (rev 196546)
@@ -116,6 +116,8 @@
unsigned prefixLengthForRange(RefPtr<Range>, Vector<UChar, 1024>&);
unsigned backwardSearchForBoundaryWithTextIterator(SimplifiedBackwardsTextIterator&, Vector<UChar, 1024>&, unsigned, BoundarySearchFunction);
unsigned forwardSearchForBoundaryWithTextIterator(TextIterator&, Vector<UChar, 1024>&, unsigned, BoundarySearchFunction);
+Node* findStartOfParagraph(Node*, Node*, Node*, int&, Position::AnchorType&, EditingBoundaryCrossingRule);
+Node* findEndOfParagraph(Node*, Node*, Node*, int&, Position::AnchorType&, EditingBoundaryCrossingRule);
} // namespace WebCore
Modified: trunk/Tools/ChangeLog (196545 => 196546)
--- trunk/Tools/ChangeLog 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/ChangeLog 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1,3 +1,56 @@
+2016-02-12 Nan Wang <n_w...@apple.com>
+
+ AX: Implement paragraph related text marker functions using TextIterator
+ https://bugs.webkit.org/show_bug.cgi?id=154098
+ <rdar://problem/24269675>
+
+ Reviewed by Chris Fleizach.
+
+ * DumpRenderTree/AccessibilityUIElement.cpp:
+ (nextWordEndTextMarkerForTextMarkerCallback):
+ (paragraphTextMarkerRangeForTextMarkerCallback):
+ (previousParagraphStartTextMarkerForTextMarkerCallback):
+ (nextParagraphEndTextMarkerForTextMarkerCallback):
+ (setSelectedVisibleTextRangeCallback):
+ (AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ (AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ (AccessibilityUIElement::getJSClass):
+ * DumpRenderTree/AccessibilityUIElement.h:
+ * DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
+ (AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ (AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+ (AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ (AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ (AccessibilityUIElement::supportedActions):
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
+ (WTR::AccessibilityUIElement::rightWordTextMarkerRangeForTextMarker):
+ (WTR::AccessibilityUIElement::previousWordStartTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (WTR::AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+ * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+ * WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
+ (WTR::AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (WTR::AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::mathPostscriptsDescription):
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+ (WTR::AccessibilityUIElement::nextWordEndTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker):
+ (WTR::AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker):
+ (WTR::AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker):
+ (WTR::_convertMathMultiscriptPairsToString):
+
2016-02-12 Jason Marcell <jmarc...@apple.com>
Open source bot watcher's dashboard fails assertion in BuildbotQueue.prototype.compareIterationsByRevisions
Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp (196545 => 196546)
--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1010,6 +1010,33 @@
return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->nextWordEndTextMarkerForTextMarker(marker));
}
+static JSValueRef paragraphTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarker* marker = nullptr;
+ if (argumentCount == 1)
+ marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->paragraphTextMarkerRangeForTextMarker(marker));
+}
+
+static JSValueRef previousParagraphStartTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarker* marker = nullptr;
+ if (argumentCount == 1)
+ marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->previousParagraphStartTextMarkerForTextMarker(marker));
+}
+
+static JSValueRef nextParagraphEndTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarker* marker = nullptr;
+ if (argumentCount == 1)
+ marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->nextParagraphEndTextMarkerForTextMarker(marker));
+}
+
static JSValueRef setSelectedVisibleTextRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityUIElement* uiElement = toAXElement(thisObject);
@@ -1620,6 +1647,21 @@
return nullptr;
}
+AccessibilityTextMarkerRange AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
#endif
// Destruction
@@ -1804,6 +1846,9 @@
{ "rightWordTextMarkerRangeForTextMarker", rightWordTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "previousWordStartTextMarkerForTextMarker", previousWordStartTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "nextWordEndTextMarkerForTextMarker", nextWordEndTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "paragraphTextMarkerRangeForTextMarker", paragraphTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "previousParagraphStartTextMarkerForTextMarker", previousParagraphStartTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "nextParagraphEndTextMarkerForTextMarker", nextParagraphEndTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setSelectedChild", setSelectedChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setSelectedChildAtIndex", setSelectedChildAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeSelectionAtIndex", removeSelectionAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.h (196545 => 196546)
--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.h 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.h 2016-02-13 05:24:24 UTC (rev 196546)
@@ -264,6 +264,9 @@
AccessibilityTextMarkerRange rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
AccessibilityTextMarker previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*);
AccessibilityTextMarker nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ AccessibilityTextMarkerRange paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ AccessibilityTextMarker previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*);
+ AccessibilityTextMarker nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*);
AccessibilityTextMarkerRange selectedTextMarkerRange();
void resetSelectedTextMarkerRange();
bool setSelectedVisibleTextRange(AccessibilityTextMarkerRange*);
Modified: trunk/Tools/DumpRenderTree/ios/AccessibilityUIElementIOS.mm (196545 => 196546)
--- trunk/Tools/DumpRenderTree/ios/AccessibilityUIElementIOS.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/DumpRenderTree/ios/AccessibilityUIElementIOS.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -570,6 +570,21 @@
return nullptr;
}
+AccessibilityTextMarkerRange AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*)
+{
+ return nullptr;
+}
+
#endif // SUPPORTS_AX_TEXTMARKERS && PLATFORM(IOS)
#pragma mark Unused
Modified: trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm (196545 => 196546)
--- trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1886,6 +1886,36 @@
return nullptr;
}
+AccessibilityTextMarkerRange AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id textMarkerRange = [m_element accessibilityAttributeValue:@"AXParagraphTextMarkerRangeForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarkerRange(textMarkerRange);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id previousTextMarker = [m_element accessibilityAttributeValue:@"AXPreviousParagraphStartTextMarkerForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarker(previousTextMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id nextTextMarker = [m_element accessibilityAttributeValue:@"AXNextParagraphEndTextMarkerForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarker(nextTextMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
#endif // SUPPORTS_AX_TEXTMARKERS && PLATFORM(MAC)
JSStringRef AccessibilityUIElement::supportedActions()
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp (196545 => 196546)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp 2016-02-13 05:24:24 UTC (rev 196546)
@@ -249,6 +249,9 @@
PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
#endif
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (196545 => 196546)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2016-02-13 05:24:24 UTC (rev 196546)
@@ -255,6 +255,9 @@
PassRefPtr<AccessibilityTextMarkerRange> rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
PassRefPtr<AccessibilityTextMarker> previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*);
PassRefPtr<AccessibilityTextMarker> nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ PassRefPtr<AccessibilityTextMarkerRange> paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ PassRefPtr<AccessibilityTextMarker> nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ PassRefPtr<AccessibilityTextMarker> previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*);
// Returns an ordered list of supported actions for an element.
JSRetainPtr<JSStringRef> supportedActions() const;
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (196545 => 196546)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2016-02-13 05:24:24 UTC (rev 196546)
@@ -205,6 +205,9 @@
AccessibilityTextMarkerRange rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
AccessibilityTextMarker previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
AccessibilityTextMarker nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarkerRange paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
// Returns an ordered list of supported actions for an element.
readonly attribute DOMString supportedActions;
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm (196545 => 196546)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1116,6 +1116,21 @@
return nullptr;
}
+PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ return nullptr;
+}
+
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ return nullptr;
+}
+
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ return nullptr;
+}
+
JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
{
return 0;
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (196545 => 196546)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2016-02-13 04:52:01 UTC (rev 196545)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2016-02-13 05:24:24 UTC (rev 196546)
@@ -1913,6 +1913,36 @@
return nullptr;
}
+PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id textMarkerRange = [m_element accessibilityAttributeValue:@"AXParagraphTextMarkerRangeForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarkerRange::create(textMarkerRange);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id previousParagraphStartMarker = [m_element accessibilityAttributeValue:@"AXPreviousParagraphStartTextMarkerForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarker::create(previousParagraphStartMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
+PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id nextParagraphEndMarker = [m_element accessibilityAttributeValue:@"AXNextParagraphEndTextMarkerForTextMarker" forParameter:(id)textMarker->platformTextMarker()];
+ return AccessibilityTextMarker::create(nextParagraphEndMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return nullptr;
+}
+
static NSString *_convertMathMultiscriptPairsToString(NSArray *pairs)
{
__block NSMutableString *result = [NSMutableString string];