Add support for showing the platform data interaction caret
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Mar 2017 23:21:38 +0000 (23:21 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Mar 2017 23:21:38 +0000 (23:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169898
<rdar://problem/31146295>

Reviewed by Beth Dakin.

Source/WebKit/mac:

Plumb the dataInteractionCaretRect through WebView SPI to WebKit1 clients.

* WebView/WebView.mm:
(-[WebView _dataInteractionCaretRect]):
* WebView/WebViewPrivate.h:

Source/WebKit2:

Add support for showing the caret rect when data interacting over an editable target. To do this, we add
boilerplate plumbing to inform the WKContentView whenever the WebPageProxy's current caret rect changes.

* Platform/spi/ios/UIKitSPI.h:

Define IPI to retrieve the default insertion caret color.

* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didPerformDragControllerAction):
(WebKit::WebPageProxy::dragEnded):
(WebKit::WebPageProxy::didEndDragging):
(WebKit::WebPageProxy::resetCurrentDragInformation):
(WebKit::WebPageProxy::setDragCaretRect):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::didChangeDataInteractionCaretRect):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView cleanupInteraction]):
(-[WKContentView insertionPointColor]):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::dragEnded):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@214284 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewPrivate.h
Source/WebKit2/ChangeLog
Source/WebKit2/Platform/spi/ios/UIKitSPI.h
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index ae3d4a7..cd665d7 100644 (file)
@@ -1,3 +1,17 @@
+2017-03-21  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for showing the platform data interaction caret
+        https://bugs.webkit.org/show_bug.cgi?id=169898
+        <rdar://problem/31146295>
+
+        Reviewed by Beth Dakin.
+
+        Plumb the dataInteractionCaretRect through WebView SPI to WebKit1 clients.
+
+        * WebView/WebView.mm:
+        (-[WebView _dataInteractionCaretRect]):
+        * WebView/WebViewPrivate.h:
+
 2017-03-22  Dan Bernstein  <mitz@apple.com>
 
         [iOS] downloadableBinaryFontsEnabled is set to false in -initSimpleHTMLDocumentWithStyle:frame:preferences:groupName:
index e7c5fb3..3e85e42 100644 (file)
@@ -1819,6 +1819,14 @@ static void WebKitInitializeGamepadProviderIfNecessary()
         _private->textIndicatorData = [[[WebUITextIndicatorData alloc] initWithImage:image scale:_private->page->deviceScaleFactor()] retain];
 }
 
+- (CGRect)_dataInteractionCaretRect
+{
+    if (auto* page = _private->page)
+        return page->dragCaretController().caretPosition().absoluteCaretBounds();
+
+    return { };
+}
+
 - (WebUITextIndicatorData *)_dataOperationTextIndicator
 {
     return _private->dataOperationTextIndicator.get();
@@ -1920,6 +1928,11 @@ static Vector<FloatRect> floatRectsForCGRectArray(NSArray<NSValue *> *rectValues
 {
     return nil;
 }
+
+- (CGRect)_dataInteractionCaretRect
+{
+    return CGRectNull;
+}
 #endif
 
 #endif // ENABLE(DATA_INTERACTION) && defined(__cplusplus)
index 53c8649..52dd703 100644 (file)
@@ -478,6 +478,7 @@ Could be worth adding to the API.
 - (void)_endedDataInteraction:(CGPoint)clientPosition global:(CGPoint)clientPosition;
 
 #if TARGET_OS_IPHONE
+@property (nonatomic, readonly, getter=_dataInteractionCaretRect) CGRect dataInteractionCaretRect;
 - (UIImage *)_createImageWithPlatterForImage:(UIImage *)image boundingRect:(CGRect)boundingRect contentScaleFactor:(CGFloat)contentScaleFactor clippingRects:(NSArray<NSValue *> *)clippingRects;
 // Deprecated. Use -[WebDataSource _quickLookContent] instead.
 - (NSDictionary *)quickLookContentForURL:(NSURL *)url;
index da9f79f..df0f265 100644 (file)
@@ -1,3 +1,37 @@
+2017-03-21  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for showing the platform data interaction caret
+        https://bugs.webkit.org/show_bug.cgi?id=169898
+        <rdar://problem/31146295>
+
+        Reviewed by Beth Dakin.
+
+        Add support for showing the caret rect when data interacting over an editable target. To do this, we add
+        boilerplate plumbing to inform the WKContentView whenever the WebPageProxy's current caret rect changes.
+
+        * Platform/spi/ios/UIKitSPI.h:
+
+        Define IPI to retrieve the default insertion caret color.
+
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didPerformDragControllerAction):
+        (WebKit::WebPageProxy::dragEnded):
+        (WebKit::WebPageProxy::didEndDragging):
+        (WebKit::WebPageProxy::resetCurrentDragInformation):
+        (WebKit::WebPageProxy::setDragCaretRect):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::didChangeDataInteractionCaretRect):
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView cleanupInteraction]):
+        (-[WKContentView insertionPointColor]):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::dragEnded):
+
 2017-03-22  John Wilander  <wilander@apple.com>
 
         Resource Load Statistics: Fix partitioning bug for client-side cookie access
index 0829d1c..40e2843 100644 (file)
@@ -865,6 +865,10 @@ typedef enum {
 
 #endif // USE(APPLE_INTERNAL_SDK)
 
+@interface UIColor (IPI)
++ (UIColor *)insertionPointColor;
+@end
+
 @interface UIView (IPI)
 - (UIScrollView *)_scroller;
 - (CGPoint)accessibilityConvertPointFromSceneReferenceCoordinates:(CGPoint)point;
index e2c51d5..04f7987 100644 (file)
@@ -385,6 +385,7 @@ public:
     virtual void didHandleStartDataInteractionRequest(bool started) = 0;
     virtual void startDataInteractionWithImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& image, std::optional<WebCore::TextIndicatorData>, const WebCore::FloatPoint& anchorPoint, uint64_t action) = 0;
     virtual void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>) = 0;
+    virtual void didChangeDataInteractionCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) = 0;
 #endif
 };
 
index af320a4..04b3ae9 100644 (file)
@@ -1808,7 +1808,7 @@ void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool m
     m_currentDragOperation = static_cast<DragOperation>(dragOperation);
     m_currentDragIsOverFileInput = mouseIsOverFileInput;
     m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
-    m_currentDragCaretRect = insertionRect;
+    setDragCaretRect(insertionRect);
 }
 
 #if PLATFORM(GTK)
@@ -1826,6 +1826,7 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
     if (!isValid())
         return;
     m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
+    setDragCaretRect({ });
 }
     
 void WebPageProxy::dragCancelled()
@@ -1834,13 +1835,28 @@ void WebPageProxy::dragCancelled()
         m_process->send(Messages::WebPage::DragCancelled(), m_pageID);
 }
 
+void WebPageProxy::didEndDragging()
+{
+    resetCurrentDragInformation();
+}
+
 void WebPageProxy::resetCurrentDragInformation()
 {
     m_currentDragOperation = WebCore::DragOperationNone;
     m_currentDragIsOverFileInput = false;
     m_currentDragNumberOfFilesToBeAccepted = 0;
-    m_currentDragCaretRect = { };
+    setDragCaretRect({ });
+}
+
+#if !ENABLE(DATA_INTERACTION)
+
+void WebPageProxy::setDragCaretRect(const IntRect& dragCaretRect)
+{
+    m_currentDragCaretRect = dragCaretRect;
 }
+
+#endif
+
 #endif // ENABLE(DRAG_SUPPORT)
 
 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
index f6f48ab..fb05898 100644 (file)
@@ -835,6 +835,7 @@ public:
     void didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const WebCore::IntRect& insertionRect);
     void dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation);
     void dragCancelled();
+    void setDragCaretRect(const WebCore::IntRect&);
 #if PLATFORM(COCOA)
     void setDragImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& dragImageHandle, std::optional<WebCore::TextIndicatorData>, const WebCore::FloatPoint& dragImageAnchor, uint64_t action);
     void setPromisedDataForImage(const String& pasteboardName, const SharedMemory::Handle& imageHandle, uint64_t imageSize, const String& filename, const String& extension,
@@ -890,6 +891,7 @@ public:
     unsigned currentDragNumberOfFilesToBeAccepted() const { return m_currentDragNumberOfFilesToBeAccepted; }
     WebCore::IntRect currentDragCaretRect() const { return m_currentDragCaretRect; }
     void resetCurrentDragInformation();
+    void didEndDragging();
 #endif
 
     void preferencesDidChange();
index 77fe96f..e92109a 100644 (file)
@@ -296,6 +296,7 @@ messages -> WebPageProxy {
     # Drag and drop messages
 #if ENABLE(DRAG_SUPPORT)
     DidPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, WebCore::IntRect insertionRect)
+    DidEndDragging();
 #endif
 #if PLATFORM(COCOA) && ENABLE(DRAG_SUPPORT)
     SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, std::optional<WebCore::TextIndicatorData> textIndicator, WebCore::FloatPoint dragImageAnchor, uint64_t action)
index e9f8a33..521e1dd 100644 (file)
@@ -207,6 +207,7 @@ private:
     void didHandleStartDataInteractionRequest(bool started) override;
     void startDataInteractionWithImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& image, std::optional<WebCore::TextIndicatorData>, const WebCore::FloatPoint& anchorPoint, uint64_t action) override;
     void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>) override;
+    void didChangeDataInteractionCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) override;
 #endif
 
     WKContentView *m_contentView;
index fa7fb59..b96cd2e 100644 (file)
@@ -790,6 +790,11 @@ void PageClientImpl::didConcludeEditDataInteraction(std::optional<TextIndicatorD
 {
     [m_contentView _didConcludeEditDataInteraction:data];
 }
+
+void PageClientImpl::didChangeDataInteractionCaretRect(const IntRect& previousCaretRect, const IntRect& caretRect)
+{
+    [m_contentView _didChangeDataInteractionCaretRect:previousCaretRect currentRect:caretRect];
+}
 #endif
 
 void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime)
index 13c198a..e21a777 100644 (file)
@@ -74,6 +74,10 @@ class WebPageProxy;
 @class _UIHighlightView;
 @class _UIWebHighlightLongPressGestureRecognizer;
 
+#if ENABLE(DATA_INTERACTION)
+@class WKDataInteractionCaretView;
+#endif
+
 typedef void (^UIWKAutocorrectionCompletionHandler)(UIWKAutocorrectionRects *rectsForInput);
 typedef void (^UIWKAutocorrectionContextHandler)(UIWKAutocorrectionContext *autocorrectionContext);
 typedef void (^UIWKDictationContextHandler)(NSString *selectedText, NSString *beforeText, NSString *afterText);
@@ -193,14 +197,13 @@ struct WKAutoCorrectionData {
 #if ENABLE(DATA_INTERACTION)
     WebKit::WKDataInteractionState _dataInteractionState;
     BOOL _isPerformingDataInteractionOperation;
-#if HAS_DATA_INTERACTION_SPI
     RetainPtr<WKDataInteraction> _dataInteraction;
     RetainPtr<WKDataOperation> _dataOperation;
-#endif
     CGPoint _deferredActionSheetRequestLocation;
     RetainPtr<UIView> _visibleContentViewSnapshot;
     RetainPtr<UIImageView> _dataInteractionUnselectedContentSnapshot;
     BOOL _isRunningConcludeEditDataInteractionAnimation;
+    RetainPtr<WKDataInteractionCaretView> _dataInteractionCaretView;
 #endif
 }
 
@@ -285,6 +288,8 @@ struct WKAutoCorrectionData {
 - (void)_didHandleStartDataInteractionRequest:(BOOL)started;
 - (void)_startDataInteractionWithImage:(RetainPtr<CGImageRef>)image withIndicatorData:(std::optional<WebCore::TextIndicatorData>)indicatorData atClientPosition:(CGPoint)clientPosition anchorPoint:(CGPoint)anchorPoint action:(uint64_t)action;
 - (void)_didConcludeEditDataInteraction:(std::optional<WebCore::TextIndicatorData>)data;
+- (void)_didChangeDataInteractionCaretRect:(CGRect)previousRect currentRect:(CGRect)rect;
+
 - (void)_simulateDataInteractionEntered:(id)info;
 - (void)_simulateDataInteractionUpdated:(id)info;
 - (void)_simulateDataInteractionPerformOperation:(id)info;
index bb173c1..98915e6 100644 (file)
 
 @end
 
+#if ENABLE(DATA_INTERACTION)
+
+@interface WKDataInteractionCaretView : UIView
+
+- (instancetype)initWithTextInputView:(UIView<UITextInput> *)textInputView;
+- (void)insertAtPosition:(UITextPosition *)position;
+- (void)updateToPosition:(UITextPosition *)position;
+- (void)remove;
+
+@end
+
+#endif
+
 using namespace WebCore;
 using namespace WebKit;
 
@@ -641,6 +654,8 @@ static UIWebSelectionMode toUIWebSelectionMode(WKSelectionGranularity granularit
 #if ENABLE(DATA_INTERACTION)
     [self teardownDataInteractionDelegates];
     _isPerformingDataInteractionOperation = NO;
+    [_dataInteractionCaretView remove];
+    _dataInteractionCaretView = nil;
 #endif
 
     _inspectorNodeSearchEnabled = NO;
@@ -1964,6 +1979,11 @@ static void cancelPotentialTapIfNecessary(WKContentView* contentView)
     return result;
 }
 
+- (UIColor *)insertionPointColor
+{
+    return [UIColor insertionPointColor];
+}
+
 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
 {
     return NO;
index 0b538aa..efb074b 100644 (file)
@@ -3593,6 +3593,8 @@ void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint glob
     // FIXME: These are fake modifier keys here, but they should be real ones instead.
     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime(), 0, WebCore::NoTap);
     m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
+
+    send(Messages::WebPageProxy::DidEndDragging());
 }
 
 void WebPage::willPerformLoadDragDestinationAction()