Diff
Modified: trunk/Source/WTF/ChangeLog (243194 => 243195)
--- trunk/Source/WTF/ChangeLog 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WTF/ChangeLog 2019-03-20 07:32:40 UTC (rev 243195)
@@ -1,3 +1,13 @@
+2019-03-20 Tim Horton <[email protected]>
+
+ Add an platform-driven spell-checking mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=195795
+
+ Reviewed by Ryosuke Niwa.
+
+ * wtf/Platform.h:
+ Add an ENABLE flag.
+
2019-03-19 Michael Catanzaro <[email protected]>
Build cleanly with GCC 9
Modified: trunk/Source/WTF/wtf/Platform.h (243194 => 243195)
--- trunk/Source/WTF/wtf/Platform.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WTF/wtf/Platform.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -1518,3 +1518,7 @@
#if PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000
#define HAVE_UI_WEB_TOUCH_EVENTS_GESTURE_RECOGNIZER_WITH_ACTIVE_TOUCHES_BY_ID 1
#endif
+
+#if PLATFORM(IOSMAC)
+#define ENABLE_PLATFORM_DRIVEN_TEXT_CHECKING 1
+#endif
Modified: trunk/Source/WebCore/ChangeLog (243194 => 243195)
--- trunk/Source/WebCore/ChangeLog 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/ChangeLog 2019-03-20 07:32:40 UTC (rev 243195)
@@ -1,3 +1,51 @@
+2019-03-20 Tim Horton <[email protected]>
+
+ Add an platform-driven spell-checking mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=195795
+
+ Reviewed by Ryosuke Niwa.
+
+ * dom/Document.cpp:
+ (WebCore::Document::textInserted):
+ PlatformTextChecking markers are not expected
+ to propagate to newly inserted text, so remove them.
+
+ * dom/DocumentMarker.h:
+ (WebCore::DocumentMarker::allMarkers):
+ Add a new type of DocumentMarker, PlatformTextChecking,
+ and a new data variant that stores a key value pair of strings.
+
+ * dom/DocumentMarkerController.cpp:
+ (WebCore::DocumentMarkerController::addPlatformTextCheckingMarker):
+ (WebCore::DocumentMarkerController::removeMarkers):
+ (WebCore::DocumentMarkerController::filterMarkers):
+ (WebCore::shouldInsertAsSeparateMarker):
+ * dom/DocumentMarkerController.h:
+ Export some things.
+ Add addPlatformTextCheckingMarker, like the others.
+ Make it possible to filter out markers of a particular type
+ in a range with a predicate function.
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::replaceTextInNodePreservingMarkers):
+ Propagate PlatformTextChecking data.
+ A future change should probably make it possible for
+ any DocumentMarker to copy its data here, instead of
+ special-casing each type that is important.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::markMisspellingsAfterTypingToWord):
+ (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges):
+ (WebCore::Editor::markMisspellingsAndBadGrammar):
+ * editing/TextCheckingHelper.cpp:
+ (WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar):
+ (WebCore::TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange const):
+ (WebCore::platformDrivenTextCheckerEnabled):
+ * editing/TextCheckingHelper.h:
+ Bail from traditional spell checking if this mechanism is
+ enabled. (I wrote it this way to make it runtime switchable
+ in the near future, and to be similar to unifiedTextCheckerEnabled).
+
2019-03-19 Jiewen Tan <[email protected]>
[WebAuthN] Implement FIDO AppID extension
Modified: trunk/Source/WebCore/dom/Document.cpp (243194 => 243195)
--- trunk/Source/WebCore/dom/Document.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/dom/Document.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -4533,6 +4533,11 @@
// Update the markers for spelling and grammar checking.
m_markers->shiftMarkers(text, offset, length);
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ // Freshly inserted text is expected to not inherit PlatformTextChecking markers.
+ m_markers->removeMarkers(text, offset, length, DocumentMarker::PlatformTextChecking);
+#endif
}
void Document::textRemoved(Node& text, unsigned offset, unsigned length)
Modified: trunk/Source/WebCore/dom/DocumentMarker.h (243194 => 243195)
--- trunk/Source/WebCore/dom/DocumentMarker.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/dom/DocumentMarker.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -79,7 +79,11 @@
// This marker indicates that the user has selected a text candidate.
AcceptedCandidate = 1 << 13,
// This marker indicates that the user has initiated a drag with this content.
- DraggedContent = 1 << 14
+ DraggedContent = 1 << 14,
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ // This marker maintains state for the platform text checker.
+ PlatformTextChecking = 1 << 15,
+#endif
};
static constexpr OptionSet<MarkerType> allMarkers();
@@ -99,7 +103,17 @@
struct DraggedContentData {
RefPtr<Node> targetNode;
};
- using Data = "" DescriptionData, DictationData, DictationAlternativesData, DraggedContentData>;
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ struct PlatformTextCheckingData {
+ String key;
+ String value;
+ };
+#endif
+ using Data = "" DescriptionData, DictationData, DictationAlternativesData, DraggedContentData
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ , PlatformTextCheckingData
+#endif
+ >;
DocumentMarker(unsigned startOffset, unsigned endOffset, bool isActiveMatch);
DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, const String& description = String());
@@ -163,6 +177,9 @@
DictationPhraseWithAlternatives,
DictationResult,
#endif
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ PlatformTextChecking
+#endif
};
}
Modified: trunk/Source/WebCore/dom/DocumentMarkerController.cpp (243194 => 243195)
--- trunk/Source/WebCore/dom/DocumentMarkerController.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/dom/DocumentMarkerController.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -142,6 +142,17 @@
}
}
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+void DocumentMarkerController::addPlatformTextCheckingMarker(Range& range, const String& key, const String& value)
+{
+ for (TextIterator markedText(&range); !markedText.atEnd(); markedText.advance()) {
+ auto textPiece = markedText.range();
+ DocumentMarker::PlatformTextCheckingData textCheckingData { key, value };
+ addMarker(textPiece->startContainer(), { DocumentMarker::PlatformTextChecking, textPiece->startOffset(), textPiece->endOffset(), WTFMove(textCheckingData) });
+ }
+}
+#endif
+
void DocumentMarkerController::removeMarkers(Range& range, OptionSet<DocumentMarker::MarkerType> markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
{
for (TextIterator markedText(&range); !markedText.atEnd(); markedText.advance()) {
@@ -152,10 +163,24 @@
auto textPiece = markedText.range();
unsigned startOffset = textPiece->startOffset();
unsigned endOffset = textPiece->endOffset();
- removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker);
+ removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, nullptr, shouldRemovePartiallyOverlappingMarker);
}
}
+void DocumentMarkerController::filterMarkers(Range& range, std::function<bool(DocumentMarker*)> filterFunction, OptionSet<DocumentMarker::MarkerType> markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
+{
+ for (TextIterator markedText(&range); !markedText.atEnd(); markedText.advance()) {
+ if (!possiblyHasMarkers(markerTypes))
+ return;
+ ASSERT(!m_markers.isEmpty());
+
+ auto textPiece = markedText.range();
+ unsigned startOffset = textPiece->startOffset();
+ unsigned endOffset = textPiece->endOffset();
+ removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, filterFunction, shouldRemovePartiallyOverlappingMarker);
+ }
+}
+
static void updateRenderedRectsForMarker(RenderedDocumentMarker& marker, Node& node)
{
ASSERT(!node.document().view() || !node.document().view()->needsLayout());
@@ -300,6 +325,11 @@
static bool shouldInsertAsSeparateMarker(const DocumentMarker& newMarker)
{
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ if (newMarker.type() == DocumentMarker::PlatformTextChecking)
+ return true;
+#endif
+
#if PLATFORM(IOS_FAMILY)
if (newMarker.type() == DocumentMarker::DictationPhraseWithAlternatives || newMarker.type() == DocumentMarker::DictationResult)
return true;
@@ -433,7 +463,7 @@
dstNode.renderer()->repaint();
}
-void DocumentMarkerController::removeMarkers(Node& node, unsigned startOffset, int length, OptionSet<DocumentMarker::MarkerType> markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
+void DocumentMarkerController::removeMarkers(Node& node, unsigned startOffset, int length, OptionSet<DocumentMarker::MarkerType> markerTypes, std::function<bool(DocumentMarker*)> filterFunction, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
{
if (length <= 0)
return;
@@ -461,6 +491,11 @@
continue;
}
+ if (filterFunction && !filterFunction(&marker)) {
+ i++;
+ continue;
+ }
+
// at this point we know that marker and target intersect in some way
docDirty = true;
Modified: trunk/Source/WebCore/dom/DocumentMarkerController.h (243194 => 243195)
--- trunk/Source/WebCore/dom/DocumentMarkerController.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/dom/DocumentMarkerController.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -48,8 +48,8 @@
~DocumentMarkerController();
void detach();
- void addMarker(Range&, DocumentMarker::MarkerType);
- void addMarker(Range&, DocumentMarker::MarkerType, const String& description);
+ WEBCORE_EXPORT void addMarker(Range&, DocumentMarker::MarkerType);
+ WEBCORE_EXPORT void addMarker(Range&, DocumentMarker::MarkerType, const String& description);
void addMarkerToNode(Node&, unsigned startOffset, unsigned length, DocumentMarker::MarkerType);
void addMarkerToNode(Node&, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, DocumentMarker::Data&&);
WEBCORE_EXPORT void addTextMatchMarker(const Range&, bool activeMatch);
@@ -60,6 +60,10 @@
#endif
void addDraggedContentMarker(Range&);
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ WEBCORE_EXPORT void addPlatformTextCheckingMarker(Range&, const String& key, const String& value);
+#endif
+
void copyMarkers(Node& srcNode, unsigned startOffset, int length, Node& dstNode, int delta);
bool hasMarkers() const
{
@@ -72,9 +76,12 @@
// remove the marker. If the argument is false, we will adjust the span of the marker so that it retains
// the portion that is outside of the range.
enum RemovePartiallyOverlappingMarkerOrNot { DoNotRemovePartiallyOverlappingMarker, RemovePartiallyOverlappingMarker };
- void removeMarkers(Range&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
- void removeMarkers(Node&, unsigned startOffset, int length, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
+ WEBCORE_EXPORT void removeMarkers(Range&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
+ void removeMarkers(Node&, unsigned startOffset, int length, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), std::function<bool(DocumentMarker*)> filterFunction = nullptr, RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
+ // Return false from filterFunction to remove the marker.
+ WEBCORE_EXPORT void filterMarkers(Range&, std::function<bool(DocumentMarker*)> filterFunction, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers(), RemovePartiallyOverlappingMarkerOrNot = DoNotRemovePartiallyOverlappingMarker);
+
WEBCORE_EXPORT void removeMarkers(OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
void removeMarkers(Node&, OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
void repaintMarkers(OptionSet<DocumentMarker::MarkerType> = DocumentMarker::allMarkers());
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (243194 => 243195)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -781,6 +781,18 @@
continue;
}
#endif
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ if (marker.type() == DocumentMarker::PlatformTextChecking) {
+ if (!WTF::holds_alternative<DocumentMarker::PlatformTextCheckingData>(marker.data())) {
+ ASSERT_NOT_REACHED();
+ continue;
+ }
+
+ auto& textCheckingData = WTF::get<DocumentMarker::PlatformTextCheckingData>(marker.data());
+ markerController.addPlatformTextCheckingMarker(newRange, textCheckingData.key, textCheckingData.value);
+ continue;
+ }
+#endif
markerController.addMarker(newRange, marker.type(), marker.description());
}
}
Modified: trunk/Source/WebCore/editing/Editor.cpp (243194 => 243195)
--- trunk/Source/WebCore/editing/Editor.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/editing/Editor.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -2408,6 +2408,9 @@
{
Ref<Frame> protection(m_frame);
+ if (platformDrivenTextCheckerEnabled())
+ return;
+
#if PLATFORM(IOS_FAMILY)
UNUSED_PARAM(selectionAfterTyping);
UNUSED_PARAM(doReplacement);
@@ -2630,6 +2633,9 @@
void Editor::markAllMisspellingsAndBadGrammarInRanges(OptionSet<TextCheckingType> textCheckingOptions, RefPtr<Range>&& spellingRange, RefPtr<Range>&& automaticReplacementRange, RefPtr<Range>&& grammarRange)
{
+ if (platformDrivenTextCheckerEnabled())
+ return;
+
ASSERT(unifiedTextCheckerEnabled());
// There shouldn't be pending autocorrection at this moment.
@@ -2693,6 +2699,11 @@
return false;
}
+void Editor::replaceRangeForSpellChecking(Range& rangeToReplace, const String& replacement)
+{
+ SpellingCorrectionCommand::create(rangeToReplace, replacement)->apply();
+}
+
static void correctSpellcheckingPreservingTextCheckingParagraph(TextCheckingParagraph& paragraph, Range& rangeToReplace, const String& replacement, int resultLocation, int resultLength)
{
auto& scope = downcast<ContainerNode>(paragraph.paragraphRange().startContainer().rootNode());
@@ -2905,6 +2916,9 @@
void Editor::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection)
{
+ if (platformDrivenTextCheckerEnabled())
+ return;
+
if (unifiedTextCheckerEnabled()) {
if (!isContinuousSpellCheckingEnabled())
return;
Modified: trunk/Source/WebCore/editing/Editor.h (243194 => 243195)
--- trunk/Source/WebCore/editing/Editor.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/editing/Editor.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -301,6 +301,7 @@
void markBadGrammar(const VisibleSelection&);
void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
void markAndReplaceFor(const SpellCheckRequest&, const Vector<TextCheckingResult>&);
+ WEBCORE_EXPORT void replaceRangeForSpellChecking(Range&, const String&);
bool isOverwriteModeEnabled() const { return m_overwriteModeEnabled; }
WEBCORE_EXPORT void toggleOverwriteModeEnabled();
Modified: trunk/Source/WebCore/editing/TextCheckingHelper.cpp (243194 => 243195)
--- trunk/Source/WebCore/editing/TextCheckingHelper.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/editing/TextCheckingHelper.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -303,6 +303,9 @@
if (!unifiedTextCheckerEnabled())
return emptyString();
+ if (platformDrivenTextCheckerEnabled())
+ return emptyString();
+
String firstFoundItem;
String misspelledWord;
String badGrammarPhrase;
@@ -572,6 +575,9 @@
if (!unifiedTextCheckerEnabled())
return Vector<String>();
+ if (platformDrivenTextCheckerEnabled())
+ return Vector<String>();
+
Vector<String> guesses;
misspelled = false;
ungrammatical = false;
@@ -689,4 +695,13 @@
return frame->settings().unifiedTextCheckerEnabled();
}
+bool platformDrivenTextCheckerEnabled()
+{
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ return true;
+#else
+ return false;
+#endif
}
+
+}
Modified: trunk/Source/WebCore/editing/TextCheckingHelper.h (243194 => 243195)
--- trunk/Source/WebCore/editing/TextCheckingHelper.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebCore/editing/TextCheckingHelper.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -111,5 +111,6 @@
void checkTextOfParagraph(TextCheckerClient&, StringView, OptionSet<TextCheckingType>, Vector<TextCheckingResult>&, const VisibleSelection& currentSelection);
bool unifiedTextCheckerEnabled(const Frame*);
+bool platformDrivenTextCheckerEnabled();
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (243194 => 243195)
--- trunk/Source/WebKit/ChangeLog 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/ChangeLog 2019-03-20 07:32:40 UTC (rev 243195)
@@ -1,3 +1,62 @@
+2019-03-20 Tim Horton <[email protected]>
+
+ Add an platform-driven spell-checking mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=195795
+
+ Reviewed by Ryosuke Niwa.
+
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * SourcesCocoa.txt:
+ * UIProcess/Cocoa/TextCheckingController.h: Added.
+ * UIProcess/Cocoa/TextCheckingController.mm: Added.
+ (WebKit::TextCheckingController::TextCheckingController):
+ (WebKit::TextCheckingController::replaceRelativeToSelection):
+ (WebKit::TextCheckingController::removeAnnotationRelativeToSelection):
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView setupInteraction]):
+ (-[WKContentView replaceSelectionOffset:length:withAnnotatedString:relativeReplacementRange:]):
+ (-[WKContentView removeAnnotation:forSelectionOffset:length:]):
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.cpp:
+ * WebProcess/WebPage/WebPage.h:
+ (WebKit::WebPage::textCheckingController):
+ Plumb two UITextInput methods through to the Web Content process.
+ I added a new object instead of just sticking things on WebPage
+ because there are quite a few more related ones coming down the pipeline,
+ and will also end up being messages going in the opposite direction.
+
+ * WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.h: Added.
+ * WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in: Added.
+ * WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm: Added.
+ (WebKit::TextCheckingControllerProxy::TextCheckingControllerProxy):
+ (WebKit::TextCheckingControllerProxy::~TextCheckingControllerProxy):
+ (WebKit::relevantMarkerTypes):
+ (WebKit::TextCheckingControllerProxy::rangeAndOffsetRelativeToSelection):
+ (WebKit::TextCheckingControllerProxy::replaceRelativeToSelection):
+ (WebKit::TextCheckingControllerProxy::removeAnnotationRelativeToSelection):
+ Make it possible for the platform to maintain arbitrary key-value pairs
+ attached to document ranges, as a way for it to keep track of various
+ text checking context (e.g. if something has been checked, replaced,
+ what language it might be, ...).
+
+ Allow it to replace the text of a range and the annotations in that range,
+ or remove annotations in a range. Ranges are specified relative to
+ the selection.
+
+ One large missing piece is giving the platform the ability to retrieve
+ annotations in a range; that is coming in a future patch.
+
+ We translate certain annotations into traditional WebCore spelling
+ and grammar document markers, for normal display-time treatment.
+
+ * WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm:
+ (-[WKAccessibilityWebPageObject convertScreenPointToRootView:]):
+ (-[WKAccessibilityWebPageObject accessibilityHitTest:]):
+ Unified sources fixes.
+
2019-03-19 Jiewen Tan <[email protected]>
[WebAuthN] Implement FIDO AppID extension
Modified: trunk/Source/WebKit/DerivedSources-input.xcfilelist (243194 => 243195)
--- trunk/Source/WebKit/DerivedSources-input.xcfilelist 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/DerivedSources-input.xcfilelist 2019-03-20 07:32:40 UTC (rev 243195)
@@ -112,6 +112,7 @@
$(PROJECT_DIR)/WebProcess/Storage/WebSWContextManagerConnection.messages.in
$(PROJECT_DIR)/WebProcess/UserContent/WebUserContentController.messages.in
$(PROJECT_DIR)/WebProcess/WebAuthentication/WebAuthenticatorCoordinator.messages.in
+$(PROJECT_DIR)/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in
$(PROJECT_DIR)/WebProcess/WebPage/DrawingArea.messages.in
$(PROJECT_DIR)/WebProcess/WebPage/EventDispatcher.messages.in
$(PROJECT_DIR)/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.messages.in
Modified: trunk/Source/WebKit/DerivedSources-output.xcfilelist (243194 => 243195)
--- trunk/Source/WebKit/DerivedSources-output.xcfilelist 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/DerivedSources-output.xcfilelist 2019-03-20 07:32:40 UTC (rev 243195)
@@ -88,6 +88,8 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageAreaMapMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/TextCheckingControllerProxyMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/TextCheckingControllerProxyMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/UserMediaCaptureManagerMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/UserMediaCaptureManagerMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/UserMediaCaptureManagerProxyMessageReceiver.cpp
Modified: trunk/Source/WebKit/DerivedSources.make (243194 => 243195)
--- trunk/Source/WebKit/DerivedSources.make 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/DerivedSources.make 2019-03-20 07:32:40 UTC (rev 243195)
@@ -59,6 +59,7 @@
$(WebKit2)/WebProcess/WebAuthentication \
$(WebKit2)/WebProcess/WebCoreSupport \
$(WebKit2)/WebProcess/WebPage \
+ $(WebKit2)/WebProcess/WebPage/Cocoa \
$(WebKit2)/WebProcess/WebPage/RemoteLayerTree \
$(WebKit2)/WebProcess/WebStorage \
$(WebKit2)/WebProcess/cocoa \
@@ -135,6 +136,7 @@
SmartMagnificationController \
StorageAreaMap \
StorageManager \
+ TextCheckingControllerProxy \
UserMediaCaptureManager \
UserMediaCaptureManagerProxy \
VideoFullscreenManager \
Modified: trunk/Source/WebKit/SourcesCocoa.txt (243194 => 243195)
--- trunk/Source/WebKit/SourcesCocoa.txt 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/SourcesCocoa.txt 2019-03-20 07:32:40 UTC (rev 243195)
@@ -339,6 +339,7 @@
UIProcess/Cocoa/SafeBrowsingWarningCocoa.mm
UIProcess/Cocoa/SessionStateCoding.mm
UIProcess/Cocoa/SystemPreviewControllerCocoa.mm
+UIProcess/Cocoa/TextCheckingController.mm
UIProcess/Cocoa/UIDelegate.mm
UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp
UIProcess/Cocoa/VersionChecks.mm
@@ -558,6 +559,7 @@
WebProcess/WebPage/ViewUpdateDispatcher.cpp
WebProcess/WebPage/WKAccessibilityWebPageObjectIOS.mm
+WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm
WebProcess/WebPage/Cocoa/WebPageCocoa.mm
WebProcess/WebPage/ios/FindControllerIOS.mm
@@ -584,3 +586,4 @@
// Derived Sources
EditableImageControllerMessageReceiver.cpp
ServiceWorkerFetchTaskMessageReceiver.cpp
+TextCheckingControllerProxyMessageReceiver.cpp
Added: trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.h (0 => 243195)
--- trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+
+#import "EditingRange.h"
+#import "WebPageProxy.h"
+#import <WebCore/FloatRect.h>
+#import <wtf/CompletionHandler.h>
+
+OBJC_CLASS NSAttributedString;
+
+namespace WebKit {
+
+class TextCheckingController final {
+ WTF_MAKE_NONCOPYABLE(TextCheckingController);
+public:
+ explicit TextCheckingController(WebPageProxy&);
+ ~TextCheckingController() = default;
+
+ void replaceRelativeToSelection(NSAttributedString *annotatedString, int64_t selectionOffset, uint64_t length, bool textChanged);
+ void removeAnnotationRelativeToSelection(NSString *annotationName, int64_t selectionOffset, uint64_t length);
+
+private:
+ WebPageProxy& m_page;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
Added: trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.mm (0 => 243195)
--- trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/Cocoa/TextCheckingController.mm 2019-03-20 07:32:40 UTC (rev 243195)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TextCheckingController.h"
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+
+#import "AttributedString.h"
+#import "TextCheckingControllerProxyMessages.h"
+#import "WebProcessProxy.h"
+
+namespace WebKit {
+
+TextCheckingController::TextCheckingController(WebPageProxy& webPageProxy)
+ : m_page(webPageProxy)
+{
+}
+
+void TextCheckingController::replaceRelativeToSelection(NSAttributedString *annotatedString, int64_t selectionOffset, uint64_t length, bool textChanged)
+{
+ if (!m_page.hasRunningProcess())
+ return;
+
+ m_page.process().send(Messages::TextCheckingControllerProxy::ReplaceRelativeToSelection(annotatedString, selectionOffset, length, textChanged), m_page.pageID());
+}
+
+void TextCheckingController::removeAnnotationRelativeToSelection(NSString *annotationName, int64_t selectionOffset, uint64_t length)
+{
+ if (!m_page.hasRunningProcess())
+ return;
+
+ m_page.process().send(Messages::TextCheckingControllerProxy::RemoveAnnotationRelativeToSelection(annotationName, selectionOffset, length), m_page.pageID());
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (243194 => 243195)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-03-20 07:32:40 UTC (rev 243195)
@@ -64,11 +64,6 @@
#import "UIKitSPI.h"
#endif
-#if PLATFORM(IOS)
-#import "UIKitSPI.h"
-#import <wtf/SoftLinking.h>
-#endif
-
NSString *WebServiceWorkerRegistrationDirectoryDefaultsKey = @"WebServiceWorkerRegistrationDirectory";
NSString *WebKitLocalCacheDefaultsKey = @"WebKitLocalCache";
NSString *WebKitJSCJITEnabledDefaultsKey = @"WebKitJSCJITEnabledDefaultsKey";
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (243194 => 243195)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -36,6 +36,7 @@
#import "FocusedElementInformation.h"
#import "GestureTypes.h"
#import "InteractionInformationAtPosition.h"
+#import "TextCheckingController.h"
#import "UIKitSPI.h"
#import "WKActionSheetAssistant.h"
#import "WKAirPlayRoutePicker.h"
@@ -340,6 +341,10 @@
BOOL _shouldRestoreFirstResponderStatusAfterLosingFocus;
BlockPtr<void()> _activeFocusedStateRetainBlock;
#endif
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ std::unique_ptr<WebKit::TextCheckingController> _textCheckingController;
+#endif
}
@end
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (243194 => 243195)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-03-20 07:32:40 UTC (rev 243195)
@@ -782,6 +782,10 @@
_dataListTextSuggestions = nil;
#endif
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ _textCheckingController = std::make_unique<WebKit::TextCheckingController>(*_page);
+#endif
+
_hasSetUpInteractions = YES;
}
@@ -5511,6 +5515,18 @@
_page->extendSelection(WebCore::WordGranularity);
}
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+- (void)replaceSelectionOffset:(NSInteger)selectionOffset length:(NSUInteger)length withAnnotatedString:(NSAttributedString *)annotatedString relativeReplacementRange:(NSRange)relativeReplacementRange
+{
+ _textCheckingController->replaceRelativeToSelection(annotatedString, selectionOffset, length, relativeReplacementRange.location != NSNotFound);
+}
+
+- (void)removeAnnotation:(NSAttributedStringKey)annotationName forSelectionOffset:(NSInteger)selectionOffset length:(NSUInteger)length
+{
+ _textCheckingController->removeAnnotationRelativeToSelection(annotationName, selectionOffset, length);
+}
+#endif
+
- (void)_updateChangedSelection
{
[self _updateChangedSelection:NO];
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (243194 => 243195)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-03-20 07:32:40 UTC (rev 243195)
@@ -2476,6 +2476,8 @@
29D04E2821F7C73D0076741D /* AccessibilityPrivSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilityPrivSPI.h; sourceTree = "<group>"; };
2D0035221BC7414800DA8716 /* PDFPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPlugin.h; path = PDF/PDFPlugin.h; sourceTree = "<group>"; };
2D0035231BC7414800DA8716 /* PDFPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPlugin.mm; path = PDF/PDFPlugin.mm; sourceTree = "<group>"; };
+ 2D0CF64B21F2A80300787566 /* TextCheckingController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TextCheckingController.mm; sourceTree = "<group>"; };
+ 2D0CF64C21F2A80300787566 /* TextCheckingController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextCheckingController.h; sourceTree = "<group>"; };
2D10875E1D2C573E00B85F82 /* LoadParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadParameters.cpp; sourceTree = "<group>"; };
2D10875F1D2C573E00B85F82 /* LoadParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadParameters.h; sourceTree = "<group>"; };
2D1087621D2C641B00B85F82 /* LoadParametersCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadParametersCocoa.mm; sourceTree = "<group>"; };
@@ -2739,6 +2741,9 @@
2D8786221BDB58FF00D02ABB /* APIUserStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIUserStyleSheet.h; sourceTree = "<group>"; };
2D8949EE182044F600E898AA /* PlatformCALayerRemoteTiledBacking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformCALayerRemoteTiledBacking.cpp; sourceTree = "<group>"; };
2D8949EF182044F600E898AA /* PlatformCALayerRemoteTiledBacking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformCALayerRemoteTiledBacking.h; sourceTree = "<group>"; };
+ 2D9CD5EB21FA503F0029ACFA /* TextCheckingControllerProxy.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = TextCheckingControllerProxy.messages.in; sourceTree = "<group>"; };
+ 2D9CD5EC21FA503F0029ACFA /* TextCheckingControllerProxy.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TextCheckingControllerProxy.mm; sourceTree = "<group>"; };
+ 2D9CD5ED21FA503F0029ACFA /* TextCheckingControllerProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextCheckingControllerProxy.h; sourceTree = "<group>"; };
2D9CD5EE21FA75EE0029ACFA /* EditingRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditingRange.cpp; sourceTree = "<group>"; };
2D9EA30C1A96CB59002D2807 /* WKPageInjectedBundleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPageInjectedBundleClient.h; sourceTree = "<group>"; };
2D9EA30E1A96CBFF002D2807 /* WebPageInjectedBundleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInjectedBundleClient.h; sourceTree = "<group>"; };
@@ -5375,6 +5380,8 @@
1A002D47196B345D00B9AD44 /* SessionStateCoding.h */,
1A002D46196B345D00B9AD44 /* SessionStateCoding.mm */,
3157135C2040A9B20084F9CF /* SystemPreviewControllerCocoa.mm */,
+ 2D0CF64C21F2A80300787566 /* TextCheckingController.h */,
+ 2D0CF64B21F2A80300787566 /* TextCheckingController.mm */,
1AFE436418B6C081009C7A48 /* UIDelegate.h */,
1AFE436318B6C081009C7A48 /* UIDelegate.mm */,
E4E8648E1B1673FB00C82F40 /* VersionChecks.h */,
@@ -5613,6 +5620,9 @@
2D29ECCD192F2C2E00984B78 /* Cocoa */ = {
isa = PBXGroup;
children = (
+ 2D9CD5ED21FA503F0029ACFA /* TextCheckingControllerProxy.h */,
+ 2D9CD5EB21FA503F0029ACFA /* TextCheckingControllerProxy.messages.in */,
+ 2D9CD5EC21FA503F0029ACFA /* TextCheckingControllerProxy.mm */,
2DC4CF7A1D2DE24B00ECCC94 /* WebPageCocoa.mm */,
);
path = Cocoa;
Added: trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.h (0 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+
+#include "AttributedString.h"
+#include "Connection.h"
+#include "EditingRange.h"
+#include "MessageReceiver.h"
+#include <wtf/Vector.h>
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class TextCheckingControllerProxy : public IPC::MessageReceiver {
+public:
+ TextCheckingControllerProxy(WebPage&);
+ ~TextCheckingControllerProxy();
+
+private:
+ // IPC::MessageReceiver
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ struct RangeAndOffset {
+ RefPtr<WebCore::Range> range;
+ size_t locationInRoot;
+ };
+ Optional<RangeAndOffset> rangeAndOffsetRelativeToSelection(int64_t offset, uint64_t length);
+
+ // Message handlers.
+ void replaceRelativeToSelection(AttributedString, int64_t selectionOffset, uint64_t length, bool textChanged);
+ void removeAnnotationRelativeToSelection(String annotationName, int64_t selectionOffset, uint64_t length);
+
+ WebPage& m_page;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
Added: trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in (0 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.messages.in 2019-03-20 07:32:40 UTC (rev 243195)
@@ -0,0 +1,31 @@
+# Copyright (C) 2019 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+
+messages -> TextCheckingControllerProxy {
+ ReplaceRelativeToSelection(struct WebKit::AttributedString annotatedString, int64_t selectionOffset, uint64_t length, bool textChanged)
+
+ RemoveAnnotationRelativeToSelection(String annotationName, int64_t selectionOffset, uint64_t length)
+}
+
+#endif
\ No newline at end of file
Added: trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm (0 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm 2019-03-20 07:32:40 UTC (rev 243195)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TextCheckingControllerProxy.h"
+
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+
+#import "ArgumentCoders.h"
+#import "TextCheckingControllerProxyMessages.h"
+#import "WebCoreArgumentCoders.h"
+#import "WebPage.h"
+#import "WebProcess.h"
+#import <WebCore/DocumentMarker.h>
+#import <WebCore/DocumentMarkerController.h>
+#import <WebCore/Editing.h>
+#import <WebCore/Editor.h>
+#import <WebCore/FocusController.h>
+#import <WebCore/RenderObject.h>
+#import <WebCore/RenderedDocumentMarker.h>
+#import <WebCore/TextIterator.h>
+#import <WebCore/VisibleUnits.h>
+
+// FIXME: Remove this after rdar://problem/48914153 is resolved.
+#if PLATFORM(IOSMAC)
+typedef NS_ENUM(NSInteger, NSSpellingState) {
+ NSSpellingStateSpellingFlag = (1 << 0),
+ NSSpellingStateGrammarFlag = (1 << 1)
+};
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+TextCheckingControllerProxy::TextCheckingControllerProxy(WebPage& page)
+ : m_page(page)
+{
+ WebProcess::singleton().addMessageReceiver(Messages::TextCheckingControllerProxy::messageReceiverName(), m_page.pageID(), *this);
+}
+
+TextCheckingControllerProxy::~TextCheckingControllerProxy()
+{
+ WebProcess::singleton().removeMessageReceiver(Messages::TextCheckingControllerProxy::messageReceiverName(), m_page.pageID());
+}
+
+static OptionSet<DocumentMarker::MarkerType> relevantMarkerTypes()
+{
+ return { DocumentMarker::PlatformTextChecking, DocumentMarker::Spelling, DocumentMarker::Grammar };
+}
+
+Optional<TextCheckingControllerProxy::RangeAndOffset> TextCheckingControllerProxy::rangeAndOffsetRelativeToSelection(int64_t offset, uint64_t length)
+{
+ Frame& frame = m_page.corePage()->focusController().focusedOrMainFrame();
+ const FrameSelection& frameSelection = frame.selection();
+ const VisibleSelection& selection = frameSelection.selection();
+ if (selection.isNone())
+ return WTF::nullopt;
+
+ auto root = frameSelection.rootEditableElementOrDocumentElement();
+ auto range = selection.toNormalizedRange();
+ range->collapse(true);
+
+ size_t selectionLocation;
+ size_t selectionLength;
+ TextIterator::getLocationAndLengthFromRange(root, range.get(), selectionLocation, selectionLength);
+ selectionLocation += offset;
+
+ return {{ TextIterator::rangeFromLocationAndLength(root, selectionLocation, length), selectionLocation }};
+}
+
+void TextCheckingControllerProxy::replaceRelativeToSelection(AttributedString annotatedString, int64_t selectionOffset, uint64_t length, bool textChanged)
+{
+ Frame& frame = m_page.corePage()->focusController().focusedOrMainFrame();
+ FrameSelection& frameSelection = frame.selection();
+ auto root = frameSelection.rootEditableElementOrDocumentElement();
+
+ auto rangeAndOffset = rangeAndOffsetRelativeToSelection(selectionOffset, length);
+ if (!rangeAndOffset)
+ return;
+ auto range = rangeAndOffset->range;
+ if (!range)
+ return;
+ auto locationInRoot = rangeAndOffset->locationInRoot;
+
+ auto& markers = frame.document()->markers();
+ markers.removeMarkers(*range, relevantMarkerTypes());
+
+ if (textChanged) {
+ bool restoreSelection = frameSelection.selection().isRange();
+
+ frame.editor().replaceRangeForSpellChecking(*range, [annotatedString.string string]);
+
+ size_t selectionLocationToRestore = locationInRoot - selectionOffset;
+ if (restoreSelection && selectionLocationToRestore > locationInRoot + length) {
+ selectionLocationToRestore -= locationInRoot - length;
+ auto selectionToRestore = TextIterator::rangeFromLocationAndLength(root, selectionLocationToRestore, 0);
+ frameSelection.moveTo(selectionToRestore.get());
+ }
+ }
+
+ [annotatedString.string enumerateAttributesInRange:NSMakeRange(0, [annotatedString.string length]) options:0 usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange attributeRange, BOOL *stop) {
+ auto attributeCoreRange = TextIterator::rangeFromLocationAndLength(root, locationInRoot + attributeRange.location, attributeRange.length);
+ if (!attributeCoreRange)
+ return;
+
+ [attrs enumerateKeysAndObjectsUsingBlock:^(NSAttributedStringKey key, id value, BOOL *stop) {
+ if (![value isKindOfClass:[NSString class]])
+ return;
+ markers.addPlatformTextCheckingMarker(*attributeCoreRange, key, (NSString *)value);
+
+ // FIXME: Switch to constants after rdar://problem/48914153 is resolved.
+ if ([key isEqualToString:@"NSSpellingState"]) {
+ NSSpellingState spellingState = (NSSpellingState)[value integerValue];
+ if (spellingState & NSSpellingStateSpellingFlag)
+ markers.addMarker(*attributeCoreRange, DocumentMarker::Spelling);
+ if (spellingState & NSSpellingStateGrammarFlag) {
+ NSString *userDescription = [attrs objectForKey:@"NSGrammarUserDescription"];
+ markers.addMarker(*attributeCoreRange, DocumentMarker::Grammar, userDescription);
+ }
+ }
+ }];
+ }];
+}
+
+void TextCheckingControllerProxy::removeAnnotationRelativeToSelection(String annotation, int64_t selectionOffset, uint64_t length)
+{
+ Frame& frame = m_page.corePage()->focusController().focusedOrMainFrame();
+ auto rangeAndOffset = rangeAndOffsetRelativeToSelection(selectionOffset, length);
+ if (!rangeAndOffset)
+ return;
+ auto range = rangeAndOffset->range;
+ if (!range)
+ return;
+
+ bool removeCoreSpellingMarkers = (annotation == String(@"NSSpellingState"));
+ frame.document()->markers().filterMarkers(*range, [&] (DocumentMarker* marker) {
+ if (!WTF::holds_alternative<DocumentMarker::PlatformTextCheckingData>(marker->data()))
+ return false;
+ auto& textCheckingData = WTF::get<DocumentMarker::PlatformTextCheckingData>(marker->data());
+ return textCheckingData.key != annotation;
+ }, removeCoreSpellingMarkers ? relevantMarkerTypes() : DocumentMarker::PlatformTextChecking);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (243194 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-03-20 07:32:40 UTC (rev 243195)
@@ -252,6 +252,7 @@
#include "PDFPlugin.h"
#include "PlaybackSessionManager.h"
#include "RemoteLayerTreeTransaction.h"
+#include "TextCheckingControllerProxy.h"
#include "TouchBarMenuData.h"
#include "TouchBarMenuItemData.h"
#include "VideoFullscreenManager.h"
@@ -370,6 +371,9 @@
, m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
#endif
, m_layerHostingMode(parameters.layerHostingMode)
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ , m_textCheckingControllerProxy(makeUniqueRef<TextCheckingControllerProxy>(*this))
+#endif
#if PLATFORM(COCOA) || PLATFORM(GTK)
, m_viewGestureGeometryCollector(std::make_unique<ViewGestureGeometryCollector>(*this))
#elif HAVE(ACCESSIBILITY) && PLATFORM(GTK)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (243194 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-03-20 07:32:40 UTC (rev 243195)
@@ -207,6 +207,7 @@
class PageBanner;
class PluginView;
class RemoteWebInspectorUI;
+class TextCheckingControllerProxy;
class UserMediaPermissionRequestManager;
class ViewGestureGeometryCollector;
class VisibleContentRectUpdateInfo;
@@ -1167,6 +1168,10 @@
WebPaymentCoordinator* paymentCoordinator();
#endif
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ TextCheckingControllerProxy& textCheckingController() { return m_textCheckingControllerProxy.get(); }
+#endif
+
private:
WebPage(uint64_t pageID, WebPageCreationParameters&&);
@@ -1449,8 +1454,6 @@
static PluginView* focusedPluginViewForFrame(WebCore::Frame&);
- static RefPtr<WebCore::Range> rangeFromEditingRange(WebCore::Frame&, const EditingRange&, EditingRangeIsRelativeTo = EditingRangeIsRelativeTo::EditableRoot);
-
void reportUsedFeatures();
void updateWebsitePolicies(WebsitePoliciesData&&);
@@ -1612,6 +1615,10 @@
RetainPtr<WKAccessibilityWebPageObject> m_mockAccessibilityElement;
#endif
+#if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
+ UniqueRef<TextCheckingControllerProxy> m_textCheckingControllerProxy;
+#endif
+
#if PLATFORM(COCOA) || PLATFORM(GTK)
std::unique_ptr<ViewGestureGeometryCollector> m_viewGestureGeometryCollector;
#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm (243194 => 243195)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm 2019-03-20 06:51:19 UTC (rev 243194)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm 2019-03-20 07:32:40 UTC (rev 243195)
@@ -119,7 +119,7 @@
- (NSPoint)convertScreenPointToRootView:(NSPoint)point
{
return retrieveAccessibilityValueFromMainThread<NSPoint>([&self, &point] () -> NSPoint {
- return m_page->screenToRootView(IntPoint(point.x, point.y));
+ return m_page->screenToRootView(WebCore::IntPoint(point.x, point.y));
});
}
@@ -238,11 +238,11 @@
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- (id)accessibilityHitTest:(NSPoint)point
{
- auto convertedPoint = retrieveAccessibilityValueFromMainThread<IntPoint>([&self, &point] () -> IntPoint {
+ auto convertedPoint = retrieveAccessibilityValueFromMainThread<WebCore::IntPoint>([&self, &point] () -> WebCore::IntPoint {
if (!m_page)
- return IntPoint(point);
+ return WebCore::IntPoint(point);
- auto convertedPoint = m_page->screenToRootView(IntPoint(point));
+ auto convertedPoint = m_page->screenToRootView(WebCore::IntPoint(point));
// Some plugins may be able to figure out the scroll position and inset on their own.
bool applyContentOffset = true;