WebKit Bugzilla
Attachment 347665 Details for
Bug 188800
: [iOS][WK2] Misspelled words are not underlined
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188800-20180821114627.patch (text/plain), 9.45 KB, created by
Daniel Bates
on 2018-08-21 11:46:28 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Daniel Bates
Created:
2018-08-21 11:46:28 PDT
Size:
9.45 KB
patch
obsolete
>Subversion Revision: 234848 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index ddc5c79b741f62d5ede584fef9ace364cdc84b97..ed9b941300d50f8ee1d6bce7ca0c3ca5e5f51846 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,42 @@ >+2018-08-21 Daniel Bates <dabates@apple.com> >+ >+ [iOS][WK2] Misspelled words are not underlined >+ https://bugs.webkit.org/show_bug.cgi?id=188800 >+ <rdar://problem/34811332> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Implement enough of TextChecker for iOS to compute the list of misspelled words in a >+ paragraph and advertise support for continuous spell checking. The WebCore editing >+ machinery queries TextChecker for the list of the misspelled words, creating document >+ markers that demarcate the misspelled words. When we paint a line of text we paint >+ the spelling correction dots under each misspelled word. >+ >+ On iOS we make use of UITextChecker to perform spell checking of a string. We maintain >+ a side table that maps a "spell document tag" to a UITextChecker* to conform to the >+ shape of the TextChecker interface. >+ >+ * Platform/spi/ios/UIKitSPI.h: Forward declare some SPI. >+ * UIProcess/ios/TextCheckerIOS.mm: >+ (WebKit::mutableState): Added. >+ (WebKit::TextChecker::state): Turns around and returns mutableState(). >+ (WebKit::TextChecker::isContinuousSpellCheckingAllowed): Returns true if we are building >+ with USE(UNIFIED_TEXT_CHECKING). Otherwise, do what we do now. >+ (WebKit::TextChecker::setContinuousSpellCheckingEnabled): Update state. >+ (WebKit::TextChecker::continuousSpellCheckingEnabledStateChanged): Ditto. >+ (WebKit::spellDocumentTagMap): Returns HashMap that maps a "spell document tag" (int64_t) to >+ a RetainPtr<UITextChecker>>. >+ (WebKit::TextChecker::uniqueSpellDocumentTag): Generates a unique identifier for the page >+ this text checker is associated with. >+ (WebKit::TextChecker::closeSpellDocumentWithTag): Removes the entry for the specified identifier >+ from the HashMap. >+ (WebKit::textCheckerFor): >+ (WebKit::TextChecker::checkTextOfParagraph): Spell check the specified string and return a list >+ that represents the misspelled words. >+ (WebKit::TextChecker::checkSpellingOfString): Added a comment to explain that iOS does not implement >+ this function and instead implements checkTextOfParagraph(). >+ (WebKit::TextChecker::checkGrammarOfString): Ditto. >+ > 2018-08-17 Daniel Bates <dabates@apple.com> > > Replace TextCheckingTypeMask with OptionSet >diff --git a/Source/WebKit/Platform/spi/ios/UIKitSPI.h b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >index 1404969339fd5d3b447f9cd0907192538fe48e03..339103d339f3239f5050491ea8279339dc129275 100644 >--- a/Source/WebKit/Platform/spi/ios/UIKitSPI.h >+++ b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >@@ -44,6 +44,7 @@ > #import <UIKit/UIImage_Private.h> > #import <UIKit/UIInterface_Private.h> > #import <UIKit/UIKeyboardImpl.h> >+#import <UIKit/UIKeyboardInputModeController.h> > #import <UIKit/UIKeyboardIntl.h> > #import <UIKit/UIKeyboard_Private.h> > #import <UIKit/UILongPressGestureRecognizer_Private.h> >@@ -57,6 +58,7 @@ > #import <UIKit/UIStringDrawing_Private.h> > #import <UIKit/UITableViewCell_Private.h> > #import <UIKit/UITapGestureRecognizer_Private.h> >+#import <UIKit/UITextChecker_Private.h> > #import <UIKit/UITextEffectsWindow.h> > #import <UIKit/UITextInput_Private.h> > #import <UIKit/UITextInteractionAssistant_Private.h> >@@ -886,6 +888,16 @@ typedef enum { > + (instancetype)actionWithTitle:(NSString *)title handler:(void (^)(UIViewControllerPreviewAction *action, UIViewController *previewViewController))handler; > @end > >+@interface UITextChecker () >+- (id)_initWithAsynchronousLoading:(BOOL)asynchronousLoading; >+- (BOOL)_doneLoading; >+@end >+ >+@interface UIKeyboardInputModeController () >++ (UIKeyboardInputModeController *)sharedInputModeController; >+@property (readwrite, retain) UIKeyboardInputMode *currentInputMode; >+@end >+ > #if ENABLE(DRAG_SUPPORT) > > @interface UIItemProvider : NSItemProvider >diff --git a/Source/WebKit/UIProcess/ios/TextCheckerIOS.mm b/Source/WebKit/UIProcess/ios/TextCheckerIOS.mm >index 068db470ff6866de7f76d975047718cc5ae3f983..34d533c7b2a9fe11d52566b59b7599fe70ba0099 100644 >--- a/Source/WebKit/UIProcess/ios/TextCheckerIOS.mm >+++ b/Source/WebKit/UIProcess/ios/TextCheckerIOS.mm >@@ -29,30 +29,46 @@ > #if PLATFORM(IOS) > > #import "TextCheckerState.h" >+#import "UIKitSPI.h" > #import <WebCore/NotImplemented.h> >+#import <wtf/HashMap.h> >+#import <wtf/NeverDestroyed.h> >+#import <wtf/RetainPtr.h> > #import <wtf/text/StringView.h> > > using namespace WebCore; > > namespace WebKit { >- >-TextCheckerState textCheckerState; >+ >+static TextCheckerState& mutableState() >+{ >+ static NeverDestroyed<TextCheckerState> state = makeNeverDestroyed([] { >+ TextCheckerState initialState; >+ initialState.isContinuousSpellCheckingEnabled = TextChecker::isContinuousSpellCheckingAllowed(); >+ initialState.isGrammarCheckingEnabled = false; >+ return initialState; >+ }()); >+ return state; >+} > > const TextCheckerState& TextChecker::state() > { >- notImplemented(); >- return textCheckerState; >+ return mutableState(); > } > > bool TextChecker::isContinuousSpellCheckingAllowed() > { >+#if USE(UNIFIED_TEXT_CHECKING) >+ return true; >+#else > notImplemented(); > return false; >+#endif > } > >-void TextChecker::setContinuousSpellCheckingEnabled(bool) >+void TextChecker::setContinuousSpellCheckingEnabled(bool enabled) > { >- notImplemented(); >+ mutableState().isContinuousSpellCheckingEnabled = enabled; > } > > void TextChecker::setGrammarCheckingEnabled(bool) >@@ -122,9 +138,9 @@ void TextChecker::toggleSubstitutionsPanelIsShowing() > notImplemented(); > } > >-void TextChecker::continuousSpellCheckingEnabledStateChanged(bool) >+void TextChecker::continuousSpellCheckingEnabledStateChanged(bool enabled) > { >- notImplemented(); >+ mutableState().isContinuousSpellCheckingEnabled = enabled; > } > > void TextChecker::grammarCheckingEnabledStateChanged(bool) >@@ -132,34 +148,93 @@ void TextChecker::grammarCheckingEnabledStateChanged(bool) > notImplemented(); > } > >+#if USE(UNIFIED_TEXT_CHECKING) >+ >+static HashMap<int64_t, RetainPtr<UITextChecker>>& spellDocumentTagMap() >+{ >+ static NeverDestroyed<HashMap<int64_t, RetainPtr<UITextChecker>>> tagMap; >+ return tagMap; >+} >+ >+#endif >+ > int64_t TextChecker::uniqueSpellDocumentTag(WebPageProxy*) > { >- notImplemented(); >+#if USE(UNIFIED_TEXT_CHECKING) >+ static int64_t nextSpellDocumentTag; >+ return ++nextSpellDocumentTag; >+#else > return 0; >+#endif > } > >-void TextChecker::closeSpellDocumentWithTag(int64_t) >+void TextChecker::closeSpellDocumentWithTag(int64_t spellDocumentTag) > { >- notImplemented(); >+#if USE(UNIFIED_TEXT_CHECKING) >+ spellDocumentTagMap().remove(spellDocumentTag); >+#else >+ UNUSED_PARAM(spellDocumentTag); >+#endif > } > > #if USE(UNIFIED_TEXT_CHECKING) > >-Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t, StringView, int32_t, OptionSet<TextCheckingType>, bool) >+static RetainPtr<UITextChecker> textCheckerFor(int64_t spellDocumentTag) > { >- notImplemented(); >- return Vector<TextCheckingResult>(); >+ auto addResult = spellDocumentTagMap().add(spellDocumentTag, nullptr); >+ if (addResult.isNewEntry) >+ addResult.iterator->value = adoptNS([[UITextChecker alloc] _initWithAsynchronousLoading:YES]); >+ return addResult.iterator->value; >+} >+ >+Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t spellDocumentTag, StringView text, int32_t /* insertionPoint */, OptionSet<TextCheckingType> checkingTypes, bool /* initialCapitalizationEnabled */) >+{ >+ Vector<TextCheckingResult> results; >+ if (!checkingTypes.contains(TextCheckingType::Spelling)) >+ return results; >+ >+ auto textChecker = textCheckerFor(spellDocumentTag); >+ if (![textChecker _doneLoading]) >+ return results; >+ >+ NSArray<NSString *> *keyboardLanguages = @[ ]; >+ auto *currentInputMode = [UIKeyboardInputModeController sharedInputModeController].currentInputMode; >+ if (currentInputMode.multilingualLanguages.count) >+ keyboardLanguages = currentInputMode.multilingualLanguages; >+ else if (currentInputMode.primaryLanguage) >+ keyboardLanguages = @[ currentInputMode.languageWithRegion ]; >+ >+ auto stringToCheck = text.createNSStringWithoutCopying(); >+ auto length = [stringToCheck length]; >+ auto range = NSMakeRange(0, length); >+ NSUInteger offsetSoFar = 0; >+ do { >+ auto misspelledRange = [textChecker rangeOfMisspelledWordInString:stringToCheck.get() range:range startingAt:offsetSoFar wrap:NO languages:keyboardLanguages]; >+ if (misspelledRange.location == NSNotFound) >+ break; >+ >+ TextCheckingResult result; >+ result.type = TextCheckingType::Spelling; >+ result.location = misspelledRange.location; >+ result.length = misspelledRange.length; >+ results.append(WTFMove(result)); >+ >+ offsetSoFar = misspelledRange.location + misspelledRange.length; >+ } while (offsetSoFar < length); >+ return results; > } > > #endif > > void TextChecker::checkSpellingOfString(int64_t, StringView, int32_t&, int32_t&) > { >+ // iOS uses checkTextOfParagraph() instead. > notImplemented(); > } > > void TextChecker::checkGrammarOfString(int64_t, StringView, Vector<WebCore::GrammarDetail>&, int32_t&, int32_t&) > { >+ // iOS uses checkTextOfParagraph() instead. > notImplemented(); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188800
:
347665
|
347667
|
347668
|
347676
|
347687
|
347697
|
347721