Title: [258182] trunk/Source
Revision
258182
Author
[email protected]
Date
2020-03-09 19:54:03 -0700 (Mon, 09 Mar 2020)

Log Message

ASSERT(!m_textCheckingRequest) on editing/spelling/spellcheck-async-remove-frame.html
https://bugs.webkit.org/show_bug.cgi?id=126606

Reviewed by Wenson Hsieh.

SpellChecker's sequence numbers need to be unique between frames, because they are sent out
Source/WebCore:

to EditorClient which may be one per web view, move from a per-SpellChecker int to
TextCheckingRequestIdentifier.

Change terminology from "sequence" to "identifier" and use Optional in
TextCheckingRequestData to represent the unset state.

Tested by existing tests.

* editing/SpellChecker.cpp:
(WebCore::SpellCheckRequest::SpellCheckRequest):
(WebCore::SpellCheckRequest::didSucceed):
(WebCore::SpellCheckRequest::didCancel):
(WebCore::SpellCheckRequest::setCheckerAndIdentifier):
(WebCore::SpellChecker::SpellChecker):
(WebCore::SpellChecker::requestCheckingFor):
(WebCore::SpellChecker::didCheck):
(WebCore::SpellChecker::didCheckSucceed):
(WebCore::SpellChecker::didCheckCancel):
(WebCore::SpellCheckRequest::setCheckerAndSequence): Deleted.
* editing/SpellChecker.h:
(WebCore::SpellChecker::lastRequestIdentifier const):
(WebCore::SpellChecker::lastProcessedIdentifier const):
(WebCore::SpellChecker::lastRequestSequence const): Deleted.
(WebCore::SpellChecker::lastProcessedSequence const): Deleted.
* platform/text/TextChecking.h:
(WebCore::TextCheckingRequestData::TextCheckingRequestData):
(WebCore::TextCheckingRequestData::identifier const):
(WebCore::TextCheckingRequestData::sequence const): Deleted.
* testing/Internals.cpp:
(WebCore::Internals::lastSpellCheckRequestSequence):
(WebCore::Internals::lastSpellCheckProcessedSequence):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

to EditorClient which may be one per web view, so use a static to hold the current
sequence number.

Also convert from int to TextCheckingSequence to make them easier to find, and use
Markable and Optional in TextCheckingRequestData to represent the unset state.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<TextCheckingRequestData>::encode):
(IPC::ArgumentCoder<TextCheckingRequestData>::decode):

Source/WebKitLegacy/mac:

to EditorClient which may be one per web view, so use a static to hold the current
sequence number.

Also convert from int to TextCheckingSequence to make them easier to find, and use
Markable and Optional in TextCheckingRequestData to represent the unset state.

* WebCoreSupport/WebEditorClient.h:
* WebCoreSupport/WebEditorClient.mm:
(-[WebEditorSpellCheckResponder initWithClient:identifier:results:]):
(-[WebEditorSpellCheckResponder perform]):
(WebEditorClient::didCheckSucceed):
(WebEditorClient::requestCheckingOfString):
(-[WebEditorSpellCheckResponder initWithClient:sequence:results:]): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (258181 => 258182)


--- trunk/Source/WebCore/ChangeLog	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/ChangeLog	2020-03-10 02:54:03 UTC (rev 258182)
@@ -1,3 +1,45 @@
+2020-03-09  Simon Fraser  <[email protected]>
+
+        ASSERT(!m_textCheckingRequest) on editing/spelling/spellcheck-async-remove-frame.html
+        https://bugs.webkit.org/show_bug.cgi?id=126606
+
+        Reviewed by Wenson Hsieh.
+
+        SpellChecker's sequence numbers need to be unique between frames, because they are sent out
+        to EditorClient which may be one per web view, move from a per-SpellChecker int to
+        TextCheckingRequestIdentifier.
+
+        Change terminology from "sequence" to "identifier" and use Optional in
+        TextCheckingRequestData to represent the unset state.
+
+        Tested by existing tests.
+
+        * editing/SpellChecker.cpp:
+        (WebCore::SpellCheckRequest::SpellCheckRequest):
+        (WebCore::SpellCheckRequest::didSucceed):
+        (WebCore::SpellCheckRequest::didCancel):
+        (WebCore::SpellCheckRequest::setCheckerAndIdentifier):
+        (WebCore::SpellChecker::SpellChecker):
+        (WebCore::SpellChecker::requestCheckingFor):
+        (WebCore::SpellChecker::didCheck):
+        (WebCore::SpellChecker::didCheckSucceed):
+        (WebCore::SpellChecker::didCheckCancel):
+        (WebCore::SpellCheckRequest::setCheckerAndSequence): Deleted.
+        * editing/SpellChecker.h:
+        (WebCore::SpellChecker::lastRequestIdentifier const):
+        (WebCore::SpellChecker::lastProcessedIdentifier const):
+        (WebCore::SpellChecker::lastRequestSequence const): Deleted.
+        (WebCore::SpellChecker::lastProcessedSequence const): Deleted.
+        * platform/text/TextChecking.h:
+        (WebCore::TextCheckingRequestData::TextCheckingRequestData):
+        (WebCore::TextCheckingRequestData::identifier const):
+        (WebCore::TextCheckingRequestData::sequence const): Deleted.
+        * testing/Internals.cpp:
+        (WebCore::Internals::lastSpellCheckRequestSequence):
+        (WebCore::Internals::lastSpellCheckProcessedSequence):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2020-03-09  Don Olmstead  <[email protected]>
 
         Remove obsolete feature flags

Modified: trunk/Source/WebCore/editing/SpellChecker.cpp (258181 => 258182)


--- trunk/Source/WebCore/editing/SpellChecker.cpp	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/editing/SpellChecker.cpp	2020-03-10 02:54:03 UTC (rev 258182)
@@ -45,7 +45,7 @@
     , m_automaticReplacementRange(WTFMove(automaticReplacementRange))
     , m_paragraphRange(WTFMove(paragraphRange))
     , m_rootEditableElement(m_checkingRange->startContainer().rootEditableElement())
-    , m_requestData(unrequestedTextCheckingSequence, text, mask, processType)
+    , m_requestData(WTF::nullopt, text, mask, processType)
 {
 }
 
@@ -71,7 +71,7 @@
         return;
 
     Ref<SpellCheckRequest> protectedThis(*this);
-    m_checker->didCheckSucceed(m_requestData.sequence(), results);
+    m_checker->didCheckSucceed(m_requestData.identifier().value(), results);
     m_checker = nullptr;
 }
 
@@ -81,16 +81,16 @@
         return;
 
     Ref<SpellCheckRequest> protectedThis(*this);
-    m_checker->didCheckCancel(m_requestData.sequence());
+    m_checker->didCheckCancel(m_requestData.identifier().value());
     m_checker = nullptr;
 }
 
-void SpellCheckRequest::setCheckerAndSequence(SpellChecker* requester, int sequence)
+void SpellCheckRequest::setCheckerAndIdentifier(SpellChecker* requester, TextCheckingRequestIdentifier identifier)
 {
     ASSERT(!m_checker);
-    ASSERT(m_requestData.sequence() == unrequestedTextCheckingSequence);
+    ASSERT(!m_requestData.identifier());
     m_checker = requester;
-    m_requestData.m_sequence = sequence;
+    m_requestData.m_identifier = identifier;
 }
 
 void SpellCheckRequest::requesterDestroyed()
@@ -100,8 +100,6 @@
 
 SpellChecker::SpellChecker(Frame& frame)
     : m_frame(frame)
-    , m_lastRequestSequence(0)
-    , m_lastProcessedSequence(0)
     , m_timerToProcessQueuedRequest(*this, &SpellChecker::timerFiredToProcessQueuedRequest)
 {
 }
@@ -156,12 +154,11 @@
     if (!canCheckAsynchronously(request->paragraphRange()))
         return;
 
-    ASSERT(request->data().sequence() == unrequestedTextCheckingSequence);
-    int sequence = ++m_lastRequestSequence;
-    if (sequence == unrequestedTextCheckingSequence)
-        sequence = ++m_lastRequestSequence;
+    ASSERT(!request->data().identifier());
+    auto identifier = TextCheckingRequestIdentifier::generate();
 
-    request->setCheckerAndSequence(this, sequence);
+    m_lastRequestIdentifier = identifier;
+    request->setCheckerAndIdentifier(this, identifier);
 
     if (m_timerToProcessQueuedRequest.isActive() || m_processingRequest) {
         enqueueRequest(WTFMove(request));
@@ -193,11 +190,11 @@
     m_requestQueue.append(WTFMove(request));
 }
 
-void SpellChecker::didCheck(int sequence, const Vector<TextCheckingResult>& results)
+void SpellChecker::didCheck(TextCheckingRequestIdentifier identifier, const Vector<TextCheckingResult>& results)
 {
     ASSERT(m_processingRequest);
-    ASSERT(m_processingRequest->data().sequence() == sequence);
-    if (m_processingRequest->data().sequence() != sequence) {
+    ASSERT(m_processingRequest->data().identifier() == identifier);
+    if (m_processingRequest->data().identifier() != identifier) {
         m_requestQueue.clear();
         return;
     }
@@ -204,8 +201,8 @@
 
     m_frame.editor().markAndReplaceFor(*m_processingRequest, results);
 
-    if (m_lastProcessedSequence < sequence)
-        m_lastProcessedSequence = sequence;
+    if (m_lastProcessedIdentifier.toUInt64() < identifier.toUInt64())
+        m_lastProcessedIdentifier = identifier;
 
     m_processingRequest = nullptr;
     if (!m_requestQueue.isEmpty())
@@ -212,10 +209,10 @@
         m_timerToProcessQueuedRequest.startOneShot(0_s);
 }
 
-void SpellChecker::didCheckSucceed(int sequence, const Vector<TextCheckingResult>& results)
+void SpellChecker::didCheckSucceed(TextCheckingRequestIdentifier identifier, const Vector<TextCheckingResult>& results)
 {
     TextCheckingRequestData requestData = m_processingRequest->data();
-    if (requestData.sequence() == sequence) {
+    if (requestData.identifier() == identifier) {
         OptionSet<DocumentMarker::MarkerType> markerTypes;
         if (requestData.checkingTypes().contains(TextCheckingType::Spelling))
             markerTypes.add(DocumentMarker::Spelling);
@@ -224,12 +221,12 @@
         if (!markerTypes.isEmpty())
             m_frame.document()->markers().removeMarkers(m_processingRequest->checkingRange(), markerTypes);
     }
-    didCheck(sequence, results);
+    didCheck(identifier, results);
 }
 
-void SpellChecker::didCheckCancel(int sequence)
+void SpellChecker::didCheckCancel(TextCheckingRequestIdentifier identifier)
 {
-    didCheck(sequence, Vector<TextCheckingResult>());
+    didCheck(identifier, Vector<TextCheckingResult>());
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/editing/SpellChecker.h (258181 => 258182)


--- trunk/Source/WebCore/editing/SpellChecker.h	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/editing/SpellChecker.h	2020-03-10 02:54:03 UTC (rev 258182)
@@ -52,7 +52,7 @@
     Range& automaticReplacementRange() const { return m_automaticReplacementRange.get(); }
     Element* rootEditableElement() const { return m_rootEditableElement.get(); }
 
-    void setCheckerAndSequence(SpellChecker*, int sequence);
+    void setCheckerAndIdentifier(SpellChecker*, TextCheckingRequestIdentifier);
     void requesterDestroyed();
     bool isStarted() const { return m_checker; }
 
@@ -84,14 +84,14 @@
 
     void requestCheckingFor(Ref<SpellCheckRequest>&&);
 
-    int lastRequestSequence() const
+    TextCheckingRequestIdentifier lastRequestIdentifier() const
     {
-        return m_lastRequestSequence;
+        return m_lastRequestIdentifier;
     }
 
-    int lastProcessedSequence() const
+    TextCheckingRequestIdentifier lastProcessedIdentifier() const
     {
-        return m_lastProcessedSequence;
+        return m_lastProcessedIdentifier;
     }
 
 private:
@@ -102,13 +102,13 @@
     void timerFiredToProcessQueuedRequest();
     void invokeRequest(Ref<SpellCheckRequest>&&);
     void enqueueRequest(Ref<SpellCheckRequest>&&);
-    void didCheckSucceed(int sequence, const Vector<TextCheckingResult>&);
-    void didCheckCancel(int sequence);
-    void didCheck(int sequence, const Vector<TextCheckingResult>&);
+    void didCheckSucceed(TextCheckingRequestIdentifier, const Vector<TextCheckingResult>&);
+    void didCheckCancel(TextCheckingRequestIdentifier);
+    void didCheck(TextCheckingRequestIdentifier, const Vector<TextCheckingResult>&);
 
     Frame& m_frame;
-    int m_lastRequestSequence;
-    int m_lastProcessedSequence;
+    TextCheckingRequestIdentifier m_lastRequestIdentifier;
+    TextCheckingRequestIdentifier m_lastProcessedIdentifier;
 
     Timer m_timerToProcessQueuedRequest;
 

Modified: trunk/Source/WebCore/platform/text/TextChecking.h (258181 => 258182)


--- trunk/Source/WebCore/platform/text/TextChecking.h	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/platform/text/TextChecking.h	2020-03-10 02:54:03 UTC (rev 258182)
@@ -31,7 +31,9 @@
 
 #pragma once
 
+#include <wtf/ObjectIdentifier.h>
 #include <wtf/OptionSet.h>
+#include <wtf/Optional.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
@@ -39,15 +41,15 @@
 namespace WebCore {
 
 enum class TextCheckingType : uint8_t {
-    None = 0,
-    Spelling = 1 << 0,
-    Grammar = 1 << 1,
-    Link = 1 << 2,
-    Quote = 1 << 3,
-    Dash = 1 << 4,
-    Replacement = 1 << 5,
-    Correction = 1 << 6,
-    ShowCorrectionPanel = 1 << 7,
+    None                    = 0,
+    Spelling                = 1 << 0,
+    Grammar                 = 1 << 1,
+    Link                    = 1 << 2,
+    Quote                   = 1 << 3,
+    Dash                    = 1 << 4,
+    Replacement             = 1 << 5,
+    Correction              = 1 << 6,
+    ShowCorrectionPanel     = 1 << 7,
 };
 
 #if PLATFORM(MAC)
@@ -75,21 +77,22 @@
     String replacement;
 };
 
-const int unrequestedTextCheckingSequence = -1;
+enum TextCheckingRequestIdentifierType { };
+using TextCheckingRequestIdentifier = ObjectIdentifier<TextCheckingRequestIdentifierType>;
 
 class TextCheckingRequestData {
-    friend class SpellCheckRequest; // For access to m_sequence.
+    friend class SpellCheckRequest; // For access to m_identifier.
 public:
     TextCheckingRequestData() = default;
-    TextCheckingRequestData(int sequence, const String& text, OptionSet<TextCheckingType> checkingTypes, TextCheckingProcessType processType)
+    TextCheckingRequestData(Optional<TextCheckingRequestIdentifier> identifier, const String& text, OptionSet<TextCheckingType> checkingTypes, TextCheckingProcessType processType)
         : m_text { text }
-        , m_sequence { sequence }
+        , m_identifier { identifier }
         , m_processType { processType }
         , m_checkingTypes { checkingTypes }
     {
     }
 
-    int sequence() const { return m_sequence; }
+    Optional<TextCheckingRequestIdentifier> identifier() const { return m_identifier; }
     const String& text() const { return m_text; }
     OptionSet<TextCheckingType> checkingTypes() const { return m_checkingTypes; }
     TextCheckingProcessType processType() const { return m_processType; }
@@ -96,7 +99,7 @@
 
 private:
     String m_text;
-    int m_sequence { unrequestedTextCheckingSequence };
+    Optional<TextCheckingRequestIdentifier> m_identifier;
     TextCheckingProcessType m_processType { TextCheckingProcessIncremental };
     OptionSet<TextCheckingType> m_checkingTypes;
 };

Modified: trunk/Source/WebCore/testing/Internals.cpp (258181 => 258182)


--- trunk/Source/WebCore/testing/Internals.cpp	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/testing/Internals.cpp	2020-03-10 02:54:03 UTC (rev 258182)
@@ -2074,22 +2074,22 @@
     return { };
 }
 
-ExceptionOr<int> Internals::lastSpellCheckRequestSequence()
+ExceptionOr<uint64_t> Internals::lastSpellCheckRequestSequence()
 {
     Document* document = contextDocument();
     if (!document || !document->frame())
         return Exception { InvalidAccessError };
 
-    return document->frame()->editor().spellChecker().lastRequestSequence();
+    return document->frame()->editor().spellChecker().lastRequestIdentifier().toUInt64();
 }
 
-ExceptionOr<int> Internals::lastSpellCheckProcessedSequence()
+ExceptionOr<uint64_t> Internals::lastSpellCheckProcessedSequence()
 {
     Document* document = contextDocument();
     if (!document || !document->frame())
         return Exception { InvalidAccessError };
 
-    return document->frame()->editor().spellChecker().lastProcessedSequence();
+    return document->frame()->editor().spellChecker().lastProcessedIdentifier().toUInt64();
 }
 
 Vector<String> Internals::userPreferredLanguages() const

Modified: trunk/Source/WebCore/testing/Internals.h (258181 => 258182)


--- trunk/Source/WebCore/testing/Internals.h	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/testing/Internals.h	2020-03-10 02:54:03 UTC (rev 258182)
@@ -304,8 +304,8 @@
 
     ExceptionOr<void> setDelegatesScrolling(bool enabled);
 
-    ExceptionOr<int> lastSpellCheckRequestSequence();
-    ExceptionOr<int> lastSpellCheckProcessedSequence();
+    ExceptionOr<uint64_t> lastSpellCheckRequestSequence();
+    ExceptionOr<uint64_t> lastSpellCheckProcessedSequence();
 
     Vector<String> userPreferredLanguages() const;
     void setUserPreferredLanguages(const Vector<String>&);

Modified: trunk/Source/WebCore/testing/Internals.idl (258181 => 258182)


--- trunk/Source/WebCore/testing/Internals.idl	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebCore/testing/Internals.idl	2020-03-10 02:54:03 UTC (rev 258182)
@@ -333,8 +333,8 @@
 
     [MayThrowException] void setDelegatesScrolling(boolean enabled);
 
-    [MayThrowException] long lastSpellCheckRequestSequence();
-    [MayThrowException] long lastSpellCheckProcessedSequence();
+    [MayThrowException] unsigned long long lastSpellCheckRequestSequence();
+    [MayThrowException] unsigned long long lastSpellCheckProcessedSequence();
 
     sequence<DOMString> userPreferredLanguages();
     void setUserPreferredLanguages(sequence<DOMString> languages);

Modified: trunk/Source/WebKit/ChangeLog (258181 => 258182)


--- trunk/Source/WebKit/ChangeLog	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebKit/ChangeLog	2020-03-10 02:54:03 UTC (rev 258182)
@@ -1,3 +1,21 @@
+2020-03-09  Simon Fraser  <[email protected]>
+
+        ASSERT(!m_textCheckingRequest) on editing/spelling/spellcheck-async-remove-frame.html
+        https://bugs.webkit.org/show_bug.cgi?id=126606
+
+        Reviewed by Wenson Hsieh.
+
+        SpellChecker's sequence numbers need to be unique between frames, because they are sent out
+        to EditorClient which may be one per web view, so use a static to hold the current
+        sequence number.
+
+        Also convert from int to TextCheckingSequence to make them easier to find, and use
+        Markable and Optional in TextCheckingRequestData to represent the unset state.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<TextCheckingRequestData>::encode):
+        (IPC::ArgumentCoder<TextCheckingRequestData>::decode):
+
 2020-03-09  Don Olmstead  <[email protected]>
 
         Remove obsolete feature flags

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (258181 => 258182)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2020-03-10 02:54:03 UTC (rev 258182)
@@ -2076,7 +2076,7 @@
 
 void ArgumentCoder<TextCheckingRequestData>::encode(Encoder& encoder, const TextCheckingRequestData& request)
 {
-    encoder << request.sequence();
+    encoder << request.identifier();
     encoder << request.text();
     encoder << request.checkingTypes();
     encoder.encodeEnum(request.processType());
@@ -2084,8 +2084,8 @@
 
 bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextCheckingRequestData& request)
 {
-    int sequence;
-    if (!decoder.decode(sequence))
+    Optional<TextCheckingRequestIdentifier> identifier;
+    if (!decoder.decode(identifier))
         return false;
 
     String text;
@@ -2100,7 +2100,7 @@
     if (!decoder.decodeEnum(processType))
         return false;
 
-    request = TextCheckingRequestData { sequence, text, checkingTypes, processType };
+    request = TextCheckingRequestData { identifier, text, checkingTypes, processType };
     return true;
 }
 

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (258181 => 258182)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2020-03-10 02:54:03 UTC (rev 258182)
@@ -1,3 +1,25 @@
+2020-03-09  Simon Fraser  <[email protected]>
+
+        ASSERT(!m_textCheckingRequest) on editing/spelling/spellcheck-async-remove-frame.html
+        https://bugs.webkit.org/show_bug.cgi?id=126606
+
+        Reviewed by Wenson Hsieh.
+
+        SpellChecker's sequence numbers need to be unique between frames, because they are sent out
+        to EditorClient which may be one per web view, so use a static to hold the current
+        sequence number.
+
+        Also convert from int to TextCheckingSequence to make them easier to find, and use
+        Markable and Optional in TextCheckingRequestData to represent the unset state.
+
+        * WebCoreSupport/WebEditorClient.h:
+        * WebCoreSupport/WebEditorClient.mm:
+        (-[WebEditorSpellCheckResponder initWithClient:identifier:results:]):
+        (-[WebEditorSpellCheckResponder perform]):
+        (WebEditorClient::didCheckSucceed):
+        (WebEditorClient::requestCheckingOfString):
+        (-[WebEditorSpellCheckResponder initWithClient:sequence:results:]): Deleted.
+
 2020-03-09  Don Olmstead  <[email protected]>
 
         Remove obsolete feature flags

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h (258181 => 258182)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h	2020-03-10 02:54:03 UTC (rev 258182)
@@ -32,6 +32,7 @@
 #import <WebCore/TextCheckerClient.h>
 #import <WebCore/VisibleSelection.h>
 #import <wtf/Forward.h>
+#import <wtf/Ref.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/Vector.h>
 #import <wtf/WeakPtr.h>
@@ -50,7 +51,7 @@
     WebEditorClient(WebView *);
     virtual ~WebEditorClient();
 
-    void didCheckSucceed(int sequence, NSArray *results);
+    void didCheckSucceed(WebCore::TextCheckingRequestIdentifier, NSArray *results);
 
 private:
     bool isGrammarCheckingEnabled() final;
@@ -195,7 +196,8 @@
     WebView *m_webView;
     RetainPtr<WebEditorUndoTarget> m_undoTarget;
     bool m_haveUndoRedoOperations { false };
-    RefPtr<WebCore::TextCheckingRequest> m_textCheckingRequest;
+    
+    HashMap<WebCore::TextCheckingRequestIdentifier, Ref<WebCore::TextCheckingRequest>> m_requestsInFlight;
 
 #if PLATFORM(IOS_FAMILY)
     bool m_delayingContentChangeNotifications { false };

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm (258181 => 258182)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm	2020-03-10 02:10:50 UTC (rev 258181)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm	2020-03-10 02:54:03 UTC (rev 258182)
@@ -1080,7 +1080,7 @@
 void WebEditorClient::getGuessesForWord(const String& word, const String& context, const WebCore::VisibleSelection& currentSelection, Vector<String>& guesses)
 {
     guesses.clear();
-    NSString* language = nil;
+    NSString *language = nil;
     NSOrthography* orthography = nil;
     NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
     NSDictionary *options = @{ NSTextCheckingInsertionPointKey :  [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
@@ -1092,8 +1092,8 @@
     unsigned count = [stringsArray count];
 
     if (count > 0) {
-        NSEnumerator* enumerator = [stringsArray objectEnumerator];
-        NSString* string;
+        NSEnumerator *enumerator = [stringsArray objectEnumerator];
+        NSString *string;
         while ((string = [enumerator nextObject]) != nil)
             guesses.append(string);
     }
@@ -1212,21 +1212,21 @@
 @interface WebEditorSpellCheckResponder : NSObject
 {
     WeakPtr<WebEditorClient> _client;
-    int _sequence;
+    TextCheckingRequestIdentifier _identifier;
     RetainPtr<NSArray> _results;
 }
-- (id)initWithClient:(WeakPtr<WebEditorClient>)client sequence:(int)sequence results:(NSArray*)results;
+- (id)initWithClient:(WeakPtr<WebEditorClient>)client identifier:(TextCheckingRequestIdentifier)identifier results:(NSArray *)results;
 - (void)perform;
 @end
 
 @implementation WebEditorSpellCheckResponder
-- (id)initWithClient:(WeakPtr<WebEditorClient>)client sequence:(int)sequence results:(NSArray*)results
+- (id)initWithClient:(WeakPtr<WebEditorClient>)client identifier:(TextCheckingRequestIdentifier)identifier results:(NSArray *)results
 {
     self = [super init];
     if (!self)
         return nil;
     _client = client;
-    _sequence = sequence;
+    _identifier = identifier;
     _results = results;
     return self;
 }
@@ -1234,33 +1234,40 @@
 - (void)perform
 {
     if (_client)
-        _client->didCheckSucceed(_sequence, _results.get());
+        _client->didCheckSucceed(_identifier, _results.get());
 }
 
 @end
 
-void WebEditorClient::didCheckSucceed(int sequence, NSArray* results)
+void WebEditorClient::didCheckSucceed(TextCheckingRequestIdentifier identifier, NSArray *results)
 {
-    ASSERT_UNUSED(sequence, sequence == m_textCheckingRequest->data().sequence());
-    m_textCheckingRequest->didSucceed(core(results, m_textCheckingRequest->data().checkingTypes()));
-    m_textCheckingRequest = nullptr;
+    auto requestOptional = m_requestsInFlight.take(identifier);
+    ASSERT(requestOptional);
+    if (!requestOptional)
+        return;
+    
+    auto request = WTFMove(requestOptional.value());
+    ASSERT(identifier == request->data().identifier().value());
+    request->didSucceed(core(results, request->data().checkingTypes()));
 }
 
 #endif
 
-void WebEditorClient::requestCheckingOfString(WebCore::TextCheckingRequest& request, const VisibleSelection& currentSelection)
+void WebEditorClient::requestCheckingOfString(TextCheckingRequest& request, const VisibleSelection& currentSelection)
 {
 #if !PLATFORM(IOS_FAMILY)
-    ASSERT(!m_textCheckingRequest);
-    m_textCheckingRequest = &request;
+    ASSERT(request.data().identifier());
+    auto identifier = request.data().identifier().value();
 
-    int sequence = m_textCheckingRequest->data().sequence();
-    NSRange range = NSMakeRange(0, m_textCheckingRequest->data().text().length());
-    NSRunLoop* currentLoop = [NSRunLoop currentRunLoop];
+    ASSERT(!m_requestsInFlight.contains(identifier));
+    m_requestsInFlight.add(identifier, makeRef(request));
+
+    NSRange range = NSMakeRange(0, request.data().text().length());
+    NSRunLoop *currentLoop = [NSRunLoop currentRunLoop];
     WeakPtr<WebEditorClient> weakThis = makeWeakPtr(*this);
-    NSDictionary *options = @{ NSTextCheckingInsertionPointKey :  [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
-    [[NSSpellChecker sharedSpellChecker] requestCheckingOfString:m_textCheckingRequest->data().text() range:range types:NSTextCheckingAllSystemTypes options:options inSpellDocumentWithTag:0 completionHandler:^(NSInteger, NSArray* results, NSOrthography*, NSInteger) {
-        RetainPtr<WebEditorSpellCheckResponder> responder = adoptNS([[WebEditorSpellCheckResponder alloc] initWithClient:weakThis sequence:sequence results:results]);
+    NSDictionary *options = @{ NSTextCheckingInsertionPointKey : [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
+    [[NSSpellChecker sharedSpellChecker] requestCheckingOfString:request.data().text() range:range types:NSTextCheckingAllSystemTypes options:options inSpellDocumentWithTag:0 completionHandler:^(NSInteger, NSArray *results, NSOrthography *, NSInteger) {
+        RetainPtr<WebEditorSpellCheckResponder> responder = adoptNS([[WebEditorSpellCheckResponder alloc] initWithClient:weakThis identifier:identifier results:results]);
         [currentLoop performBlock:^{
             [responder perform];
         }];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to