RESOLVED FIXED 187225
[macOS] Text replacements that end with symbols are expanded immediately
https://bugs.webkit.org/show_bug.cgi?id=187225
Summary [macOS] Text replacements that end with symbols are expanded immediately
Wenson Hsieh
Reported 2018-06-30 17:04:01 PDT
Attachments
Patch (68.90 KB, patch)
2018-06-30 18:36 PDT, Wenson Hsieh
no flags
Fix macOS build (68.90 KB, patch)
2018-06-30 18:52 PDT, Wenson Hsieh
no flags
Fix the iOS build (68.89 KB, patch)
2018-06-30 19:33 PDT, Wenson Hsieh
no flags
Win and 32-bit Mac build fix (69.65 KB, patch)
2018-06-30 20:45 PDT, Wenson Hsieh
no flags
More 32-bit build fixes (69.78 KB, patch)
2018-06-30 21:20 PDT, Wenson Hsieh
no flags
Patch (69.77 KB, patch)
2018-06-30 21:26 PDT, Wenson Hsieh
darin: review+
Patch for landing (69.40 KB, patch)
2018-07-01 16:59 PDT, Wenson Hsieh
wenson_hsieh: commit-queue-
Patch for landing (69.78 KB, patch)
2018-07-01 17:08 PDT, Wenson Hsieh
no flags
Wenson Hsieh
Comment 1 2018-06-30 17:12:11 PDT
To reproduce: - Go to System Preferences > Keyboard > Text. - Add a text replacement from "yt?" to "you there?". - In Safari (or any other WebKit-based app), focus an editable area. - Type "yt?", and don't press space or enter. Expected: The editable area should contain "yt?". Subsequently inserting a space or newline should then replace "yt?" with "you there?". Observed: Autocorrection kicks in and changes "yt?" to "you there?" immediately.
Wenson Hsieh
Comment 2 2018-06-30 17:12:47 PDT
This also reproduces on shipping macOS, but only if grammar checking is enabled.
Wenson Hsieh
Comment 3 2018-06-30 18:36:44 PDT Comment hidden (obsolete)
Wenson Hsieh
Comment 4 2018-06-30 18:52:50 PDT Comment hidden (obsolete)
Wenson Hsieh
Comment 5 2018-06-30 19:33:34 PDT Comment hidden (obsolete)
Wenson Hsieh
Comment 6 2018-06-30 20:45:50 PDT Comment hidden (obsolete)
Wenson Hsieh
Comment 7 2018-06-30 21:20:50 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 8 2018-06-30 21:23:31 PDT Comment hidden (obsolete)
Wenson Hsieh
Comment 9 2018-06-30 21:26:41 PDT
Darin Adler
Comment 10 2018-07-01 14:40:33 PDT
Comment on attachment 344042 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=344042&action=review > Source/WebCore/editing/Editor.h:296 > + void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* automaticReplacementRange, Range* grammarRange); Why are these Range* instead of Range& or const Range&? Can all three be null? > Source/WebCore/editing/TextCheckingHelper.h:82 > + mutable int m_checkingStart { -1 }; > + mutable int m_checkingEnd { -1 }; > + mutable int m_checkingLength { -1 }; > + mutable int m_automaticReplacementStart { -1 }; > + mutable int m_automaticReplacementLength { -1 }; At some point we should consider using std::optional here instead of a magic number of -1. > Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.h:35 > +@interface LayoutTestTextCheckingResult : NSTextCheckingResult { I think this class should be private and not mentioned in the header. The data structures could just hold NSTextCheckingResult; no need to remember that our special type was used once the object is created. > Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.h:51 > ++ (instancetype)installIfNecessary; Seems slightly unnecessarily wordy. Such methods often have simpler names like "checker", with the "set this up so I can use it" part treated as implicit. > Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.mm:36 > +typedef void (^TextCheckingCompletionHandler)(NSInteger sequenceNumber, NSArray<NSTextCheckingResult *> *results, NSOrthography *orthography, NSInteger wordCount); New code should typically use "using" instead of "typedef". > Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.mm:38 > +static NeverDestroyed<RetainPtr<LayoutTestSpellChecker>> globalSpellChecker; Typically it’s overkill to use NeverDestroyed<RetainPtr>. Instead we just do a leakRef when initializing the global or just skip the adoptNS.
Wenson Hsieh
Comment 11 2018-07-01 15:30:27 PDT
Comment on attachment 344042 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=344042&action=review >> Source/WebCore/editing/Editor.h:296 >> + void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* automaticReplacementRange, Range* grammarRange); > > Why are these Range* instead of Range& or const Range&? Can all three be null? It does look like all three may be null (at least one call site passes a null grammarRange, and additionally, there's logic in markAllMisspellingsAndBadGrammarInRanges to bail when !spellingRange). I think the modern idiom for this would be to make these three ranges RefPtr<Range>&& instead — I can do this in a followup (along with refactoring the cached offsets in TextCheckingParagraph to be `std::optional`s). >> Source/WebCore/editing/TextCheckingHelper.h:82 >> + mutable int m_automaticReplacementLength { -1 }; > > At some point we should consider using std::optional here instead of a magic number of -1. Definitely agree! I'll do this in a followup. >> Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.h:35 >> +@interface LayoutTestTextCheckingResult : NSTextCheckingResult { > > I think this class should be private and not mentioned in the header. The data structures could just hold NSTextCheckingResult; no need to remember that our special type was used once the object is created. Good catch — moved to the implementation file. >> Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.h:51 >> ++ (instancetype)installIfNecessary; > > Seems slightly unnecessarily wordy. Such methods often have simpler names like "checker", with the "set this up so I can use it" part treated as implicit. Ok! Renamed to "checker". >> Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.mm:36 >> +typedef void (^TextCheckingCompletionHandler)(NSInteger sequenceNumber, NSArray<NSTextCheckingResult *> *results, NSOrthography *orthography, NSInteger wordCount); > > New code should typically use "using" instead of "typedef". Ah, I just realized that I don't actually need this typedef, so I just removed this. >> Tools/TestRunnerShared/cocoa/LayoutTestSpellChecker.mm:38 >> +static NeverDestroyed<RetainPtr<LayoutTestSpellChecker>> globalSpellChecker; > > Typically it’s overkill to use NeverDestroyed<RetainPtr>. Instead we just do a leakRef when initializing the global or just skip the adoptNS. Got it — removed the NeverDestroyed<> and adoptNS() here.
Wenson Hsieh
Comment 12 2018-07-01 16:59:35 PDT
Created attachment 344064 [details] Patch for landing
Wenson Hsieh
Comment 13 2018-07-01 17:08:54 PDT
Created attachment 344065 [details] Patch for landing
WebKit Commit Bot
Comment 14 2018-07-01 17:47:55 PDT
Comment on attachment 344065 [details] Patch for landing Clearing flags on attachment: 344065 Committed r233412: <https://trac.webkit.org/changeset/233412>
Note You need to log in before you can comment on or make changes to this bug.