<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[197982] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/197982">197982</a></dd>
<dt>Author</dt> <dd>n_wang@apple.com</dd>
<dt>Date</dt> <dd>2016-03-10 18:37:46 -0800 (Thu, 10 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.

Source/WebCore:

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:

LayoutTests:

* 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:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsaccessibilitymactextmarkerwordnavexpectedtxt">trunk/LayoutTests/accessibility/mac/text-marker-word-nav-expected.txt</a></li>
<li><a href="#trunkLayoutTestsaccessibilitymactextmarkerwordnavhtml">trunk/LayoutTests/accessibility/mac/text-marker-word-nav.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAXObjectCachecpp">trunk/Source/WebCore/accessibility/AXObjectCache.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAXObjectCacheh">trunk/Source/WebCore/accessibility/AXObjectCache.h</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityObjectcpp">trunk/Source/WebCore/accessibility/AccessibilityObject.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityObjecth">trunk/Source/WebCore/accessibility/AccessibilityObject.h</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityRenderObjectcpp">trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityRenderObjecth">trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityiosWebAccessibilityObjectWrapperIOSmm">trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperMacmm">trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm</a></li>
<li><a href="#trunkSourceWebCoreeditinghtmleditingcpp">trunk/Source/WebCore/editing/htmlediting.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditinghtmleditingh">trunk/Source/WebCore/editing/htmlediting.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsaccessibilitymactextmarkerforindexexpectedtxt">trunk/LayoutTests/accessibility/mac/text-marker-for-index-expected.txt</a></li>
<li><a href="#trunkLayoutTestsaccessibilitymactextmarkerforindexhtml">trunk/LayoutTests/accessibility/mac/text-marker-for-index.html</a></li>
</ul>

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

</body>
</html>