⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 249074 in webkit


Ignore:
Timestamp:
Aug 23, 2019, 4:00:38 PM (7 years ago)
Author:
Wenson Hsieh
Message:

[iOS] [WebKit2] Tapping on the “I’m” text suggestion after typing “i’” does nothing
https://bugs.webkit.org/show_bug.cgi?id=201085
<rdar://problem/53056118>

Reviewed by Tim Horton.

Source/WebCore:

Exposes an existing quote folding function as a helper on TextIterator, and also adjusts foldQuoteMarks to take
a const String& rather than a String. See WebKit ChangeLog for more details.

  • editing/TextIterator.cpp:

(WebCore::foldQuoteMarks):
(WebCore::SearchBuffer::SearchBuffer):

  • editing/TextIterator.h:

Source/WebKit:

Currently, logic in applyAutocorrectionInternal only selects the range to autocorrect if the text of the range
matches the string to replace (delivered to us from UIKit). In the case of changing "I’" to "I’m", the string to
replace is "I'" (with a straight quote rather than an apostrophe), even though the DOM contains an apostrophe.

This is because kbd believes that the document context contains straight quotes (rather than apostrophes). For
native text views, this works out because UIKit uses relative UITextPositions to determine the replacement
range rather than by checking against the contents of the document. However, WKWebView does not have the ability
to synchronously compute and reason about arbitrary UITextPositions relative to the selection, so we instead
search for the string near the current selection when applying autocorrections.

Of course, this doesn't work in this scenario because the replacement string contains a straight quote, yet the
text node contains an apostrophe, so we bail and don't end up replacing any text. To address this, we repurpose
TextIterator helpers currently used to allow find-in-page to match straight quotes against apostrophes; instead
of matching the replacement string exactly, we instead match the quote-folded versions of these strings when
finding the range to replace.

Test: fast/events/ios/autocorrect-with-apostrophe.html

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::applyAutocorrectionInternal):

LayoutTests:

Add a new layout test to verify that "I’" can be autocorrected to "I’m".

  • fast/events/ios/autocorrect-with-apostrophe-expected.txt: Added.
  • fast/events/ios/autocorrect-with-apostrophe.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r249072 r249074  
     12019-08-23  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] [WebKit2] Tapping on the “I’m” text suggestion after typing “i’” does nothing
     4        https://bugs.webkit.org/show_bug.cgi?id=201085
     5        <rdar://problem/53056118>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a new layout test to verify that "I’" can be autocorrected to "I’m".
     10
     11        * fast/events/ios/autocorrect-with-apostrophe-expected.txt: Added.
     12        * fast/events/ios/autocorrect-with-apostrophe.html: Added.
     13
    1142019-08-23  Tim Horton  <timothy_horton@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r249070 r249074  
     12019-08-23  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] [WebKit2] Tapping on the “I’m” text suggestion after typing “i’” does nothing
     4        https://bugs.webkit.org/show_bug.cgi?id=201085
     5        <rdar://problem/53056118>
     6
     7        Reviewed by Tim Horton.
     8
     9        Exposes an existing quote folding function as a helper on TextIterator, and also adjusts foldQuoteMarks to take
     10        a const String& rather than a String. See WebKit ChangeLog for more details.
     11
     12        * editing/TextIterator.cpp:
     13        (WebCore::foldQuoteMarks):
     14        (WebCore::SearchBuffer::SearchBuffer):
     15        * editing/TextIterator.h:
     16
    1172019-08-23  Youenn Fablet  <youenn@apple.com>
    218
  • trunk/Source/WebCore/editing/TextIterator.cpp

    r248846 r249074  
    17831783// of doing it in a separate replacement pass here, but ICU doesn't offer a way
    17841784// to add tailoring on top of the locale-specific tailoring as of this writing.
    1785 static inline String foldQuoteMarks(String string)
    1786 {
    1787     string.replace(hebrewPunctuationGeresh, '\'');
    1788     string.replace(hebrewPunctuationGershayim, '"');
    1789     string.replace(leftDoubleQuotationMark, '"');
    1790     string.replace(leftLowDoubleQuotationMark, '"');
    1791     string.replace(leftSingleQuotationMark, '\'');
    1792     string.replace(leftLowSingleQuotationMark, '\'');
    1793     string.replace(rightDoubleQuotationMark, '"');
    1794     string.replace(rightSingleQuotationMark, '\'');
    1795 
    1796     return string;
     1785String foldQuoteMarks(const String& stringToFold)
     1786{
     1787    String result(stringToFold);
     1788    result.replace(hebrewPunctuationGeresh, '\'');
     1789    result.replace(hebrewPunctuationGershayim, '"');
     1790    result.replace(leftDoubleQuotationMark, '"');
     1791    result.replace(leftLowDoubleQuotationMark, '"');
     1792    result.replace(leftSingleQuotationMark, '\'');
     1793    result.replace(leftLowSingleQuotationMark, '\'');
     1794    result.replace(rightDoubleQuotationMark, '"');
     1795    result.replace(rightSingleQuotationMark, '\'');
     1796
     1797    return result;
    17971798}
    17981799
     
    24112412
    24122413inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
    2413     : m_target(options & CaseInsensitive ? target.foldCase() : target)
     2414    : m_target(foldQuoteMarks(options & CaseInsensitive ? target.foldCase() : target))
    24142415    , m_options(options)
    24152416    , m_buffer(m_target.length())
     
    24202421    ASSERT(!m_target.isEmpty());
    24212422    m_target.replace(noBreakSpace, ' ');
    2422     foldQuoteMarks(m_target);
    24232423}
    24242424
  • trunk/Source/WebCore/editing/TextIterator.h

    r244200 r249074  
    5555WEBCORE_EXPORT bool hasAnyPlainText(const Range&, TextIteratorBehavior = TextIteratorDefaultBehavior);
    5656bool findPlainText(const String& document, const String&, FindOptions); // Lets us use the search algorithm on a string.
     57WEBCORE_EXPORT String foldQuoteMarks(const String&);
    5758
    5859// FIXME: Move this somewhere else in the editing directory. It doesn't belong here.
  • trunk/Source/WebKit/ChangeLog

    r249068 r249074  
     12019-08-23  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] [WebKit2] Tapping on the “I’m” text suggestion after typing “i’” does nothing
     4        https://bugs.webkit.org/show_bug.cgi?id=201085
     5        <rdar://problem/53056118>
     6
     7        Reviewed by Tim Horton.
     8
     9        Currently, logic in applyAutocorrectionInternal only selects the range to autocorrect if the text of the range
     10        matches the string to replace (delivered to us from UIKit). In the case of changing "I’" to "I’m", the string to
     11        replace is "I'" (with a straight quote rather than an apostrophe), even though the DOM contains an apostrophe.
     12
     13        This is because kbd believes that the document context contains straight quotes (rather than apostrophes). For
     14        native text views, this works out because UIKit uses relative UITextPositions to determine the replacement
     15        range rather than by checking against the contents of the document. However, WKWebView does not have the ability
     16        to synchronously compute and reason about arbitrary UITextPositions relative to the selection, so we instead
     17        search for the string near the current selection when applying autocorrections.
     18
     19        Of course, this doesn't work in this scenario because the replacement string contains a straight quote, yet the
     20        text node contains an apostrophe, so we bail and don't end up replacing any text. To address this, we repurpose
     21        TextIterator helpers currently used to allow find-in-page to match straight quotes against apostrophes; instead
     22        of matching the replacement string exactly, we instead match the quote-folded versions of these strings when
     23        finding the range to replace.
     24
     25        Test: fast/events/ios/autocorrect-with-apostrophe.html
     26
     27        * WebProcess/WebPage/ios/WebPageIOS.mm:
     28        (WebKit::WebPage::applyAutocorrectionInternal):
     29
    1302019-08-23  Jiewen Tan  <jiewen_tan@apple.com>
    231
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r249006 r249074  
    23352335    RefPtr<Range> range;
    23362336    String textForRange;
     2337    auto originalTextWithFoldedQuoteMarks = foldQuoteMarks(originalText);
    23372338
    23382339    if (frame.selection().isCaret()) {
     
    23402341        range = wordRangeFromPosition(position);
    23412342        textForRange = plainTextReplacingNoBreakSpace(range.get());
    2342         if (textForRange != originalText) {
     2343        if (foldQuoteMarks(textForRange) != originalTextWithFoldedQuoteMarks) {
    23432344            // Search for the original text before the selection caret.
    23442345            for (size_t i = 0; i < originalText.length(); ++i)
     
    23702371    }
    23712372
    2372     if (textForRange != originalText)
     2373    if (foldQuoteMarks(textForRange) != originalTextWithFoldedQuoteMarks)
    23732374        return false;
    23742375   
Note: See TracChangeset for help on using the changeset viewer.