<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - AX: WKContentView needs to implement UITextInput methods to make speak selection highlighting work"
   href="https://bugs.webkit.org/show_bug.cgi?id=166955#c25">Comment # 25</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - AX: WKContentView needs to implement UITextInput methods to make speak selection highlighting work"
   href="https://bugs.webkit.org/show_bug.cgi?id=166955">bug 166955</a>
              from <span class="vcard"><a class="email" href="mailto:rniwa&#64;webkit.org" title="Ryosuke Niwa &lt;rniwa&#64;webkit.org&gt;"> <span class="fn">Ryosuke Niwa</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=299952&amp;action=diff" name="attach_299952" title="patch">attachment 299952</a> <a href="attachment.cgi?id=299952&amp;action=edit" title="patch">[details]</a></span>
patch

View in context: <a href="https://bugs.webkit.org/attachment.cgi?id=299952&amp;action=review">https://bugs.webkit.org/attachment.cgi?id=299952&amp;action=review</a>

Wow, the code looks much nicer! &amp; great test cases!
Please address the comments below and we're good to go!

<span class="quote">&gt; Source/WebCore/editing/TextIterator.cpp:2659
&gt; -static std::optional&lt;std::pair&lt;size_t, size_t&gt;&gt; findPlainTextOffset(SearchBuffer&amp; buffer, CharacterIterator&amp; findIterator, bool searchForward)
&gt; +static std::optional&lt;std::pair&lt;size_t, size_t&gt;&gt; findPlainTextOffset(SearchBuffer&amp; buffer, CharacterIterator&amp; findIterator, const std::function&lt;bool(size_t&amp;, size_t&amp;, size_t, size_t)&gt;&amp; found)</span >

It's cleaner if this function just returned void and instead each lambda kept matchStart, matchEnd themselves.
We should probably rename this function to findPlainTextMatches() to signify the fact we just calls the callback.

Once we did that, this function's lambda can just be std::function&lt;bool(size_t, size_t)&gt;.

<span class="quote">&gt; Source/WebCore/editing/TextIterator.cpp:2677
&gt; -            if (searchForward) // Look for the last match when searching backwards instead.
&gt; +            if (found(matchStart, matchLength, lastCharacterInBufferOffset - matchStartOffset, newMatchLength))</span >

Once we made the change above, we should just call this function callback.
Basically, for backwards searching and your function, this function will always return false.
For forward searching, it always returns true (since the first match should be returned).

<span class="quote">&gt; Source/WebCore/editing/TextIterator.cpp:2688
&gt; -Ref&lt;Range&gt; findPlainText(const Range&amp; range, const String&amp; target, FindOptions options)
&gt; +static Ref&lt;Range&gt; findPlainTextWithFunc(const Range&amp; range, const String&amp; target, FindOptions options, const std::function&lt;bool(size_t&amp;, size_t&amp;, size_t, size_t)&gt;&amp; func)</span >

Please don't use abbreviations like &quot;func&quot;.
I'd call this function findPlainTextMatchesInRange or something instead of suffixing it with the last argument's type.

<span class="quote">&gt; Source/WebCore/editing/TextIterator.cpp:2720
&gt; +        size_t newDistance = std::min(abs((signed)(start - targetOffset)), abs((signed)(start + length - targetOffset)));</span >

Please don't use C-style casing like (signed).

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1829
&gt; +static VisiblePosition visiblePositionForPositionWithOffset(const VisiblePosition&amp; position, int32_t offset)
&gt; +{
&gt; +    SelectionDirection direction = offset &lt; 0 ? DirectionBackward : DirectionForward;
&gt; +    VisiblePosition result = position;
&gt; +    result.setAffinity(DOWNSTREAM);
&gt; +    for (int i = 0; i &lt; abs(offset); ++i) {
&gt; +        result = direction == DirectionForward ? result.next() : result.previous();
&gt; +        if (result.isNull())
&gt; +            break;
&gt; +    }
&gt; +    return result;
&gt; +}</span >

Please use visiblePositionForIndex(root, indexForVisiblePosition(position, root) + offset) instead
where root is commonAncestorContainer() of the range or its rootEditableElement().

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1830
&gt; +    </span >

There's a whitespace here.

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1835
&gt; +    </span >

All these functions have whitespace in blank lines. Please remove them all.

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1841
&gt; +    VisiblePosition position = visiblePositionForPositionWithOffset(selectionStart, offset);</span >

Use auto.

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1844
&gt; +    RefPtr&lt;Range&gt; range = enclosingTextUnitOfGranularity(position, static_cast&lt;WebCore::TextGranularity&gt;(granularity), direction);</span >

Use auto.

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1869
&gt; +    RefPtr&lt;Range&gt; selectionRange = frame.selection().selection().toNormalizedRange();</span >

Normalizing Range is expensive. Why don't we call it in inside the if (rangeText != text) below?

<span class="quote">&gt; Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:1878
&gt; +    VisiblePosition startPosition = visiblePositionForPositionWithOffset(selectionStart, offset);
&gt; +    VisiblePosition endPosition = visiblePositionForPositionWithOffset(startPosition, length);
&gt; +    RefPtr&lt;Range&gt; range = Range::create(*frame.document(), startPosition, endPosition);</span >

Use auto.

<span class="quote">&gt; LayoutTests/editing/text-iterator/range-of-string-closest-to-position.html:27
&gt; +    </span >

Please remove these whitespace in blank lines.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>