Bug 187225

Summary: [macOS] Text replacements that end with symbols are expanded immediately
Product: WebKit Reporter: Wenson Hsieh <wenson_hsieh>
Component: HTML EditingAssignee: Wenson Hsieh <wenson_hsieh>
Status: RESOLVED FIXED    
Severity: Normal CC: bdakin, commit-queue, darin, dbates, ews-watchlist, rniwa, thorton, webkit-bug-importer, wenson_hsieh
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Fix macOS build
none
Fix the iOS build
none
Win and 32-bit Mac build fix
none
More 32-bit build fixes
none
Patch
darin: review+
Patch for landing
wenson_hsieh: commit-queue-
Patch for landing none

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.