Diff
Modified: trunk/Source/WebCore/ChangeLog (244055 => 244056)
--- trunk/Source/WebCore/ChangeLog 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebCore/ChangeLog 2019-04-08 22:49:20 UTC (rev 244056)
@@ -1,3 +1,22 @@
+2019-04-08 Wenson Hsieh <[email protected]>
+
+ [iOS] Do not allow starting selection drags when selection views are not visible
+ https://bugs.webkit.org/show_bug.cgi?id=196686
+ <rdar://problem/49399192>
+
+ Reviewed by Tim Horton.
+
+ See WebKit ChangeLog for more details.
+
+ Tests: DragAndDropTests.CanDragImageWhenNotFirstResponder
+ DragAndDropTests.DoNotPerformSelectionDragWhenNotFirstResponder
+
+ * page/DragController.cpp:
+ (WebCore::DragController::draggableElement const):
+
+ Make this respect the case where m_dragSourceAction does not include DragSourceActionSelection. All the other
+ drag source types are currently consulted in this method, with the exception of DragSourceActionSelection.
+
2019-04-08 Youenn Fablet <[email protected]>
Add a test to check for the service worker process name
Modified: trunk/Source/WebCore/page/DragController.cpp (244055 => 244056)
--- trunk/Source/WebCore/page/DragController.cpp 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebCore/page/DragController.cpp 2019-04-08 22:49:20 UTC (rev 244056)
@@ -826,7 +826,10 @@
}
// We either have nothing to drag or we have a selection and we're not over a draggable element.
- return (state.type & DragSourceActionSelection) ? startElement : nullptr;
+ if (state.type & DragSourceActionSelection && m_dragSourceAction & DragSourceActionSelection)
+ return startElement;
+
+ return nullptr;
}
static CachedImage* getCachedImage(Element& element)
Modified: trunk/Source/WebKit/ChangeLog (244055 => 244056)
--- trunk/Source/WebKit/ChangeLog 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/ChangeLog 2019-04-08 22:49:20 UTC (rev 244056)
@@ -1,3 +1,56 @@
+2019-04-08 Wenson Hsieh <[email protected]>
+
+ [iOS] Do not allow starting selection drags when selection views are not visible
+ https://bugs.webkit.org/show_bug.cgi?id=196686
+ <rdar://problem/49399192>
+
+ Reviewed by Tim Horton.
+
+ Currently, on iOS, it's possible to start dragging selected text in a web view even if the selection itself is
+ not visible. This can happen if the user selects some text, focuses a native text field, and then long presses
+ the previously selected text. This is because the text is still selected in the document since we don't clear
+ the selection when resigning first responder on iOS, despite the fact that the native selection view is no
+ longer present.
+
+ To fix this, we add plumbing to specify the set of allowed drag source actions when requesting drag start; this
+ set of allowed drag source actions only includes DragSourceActionSelection if the selection view can be visible
+ (i.e. the content view is first responder, and isn't suppressing text interactions). We then update WebPage's
+ allowed drag source actions with this given set of actions, while sending "dragstart" to the page.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView hasSelectablePositionAtPoint:]):
+ (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
+
+ Only bail out of text selection in text that is already selected if the web view allows dragging text selections
+ (i.e. the web view is first responder, and is not suppressing text interactions).
+
+ (-[WKContentView _allowedDragSourceActions]):
+ (-[WKContentView _dragInteraction:itemsForAddingToSession:withTouchAtPoint:completion:]):
+ (-[WKContentView _dragInteraction:prepareForSession:completion:]):
+
+ Pass the set of allowed drag source actions when requesting a drag start or adding items to an existing session.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::requestDragStart):
+ (WebKit::WebPageProxy::requestAdditionalItemsForDragSession):
+
+ Plumb the allowed drag source actions from the UI process (WKContentView) over to the web process (WebPage).
+
+ * WebProcess/WebCoreSupport/WebDragClient.cpp:
+ (WebKit::WebDragClient::dragSourceActionMaskForPoint):
+
+ Instead of always returning Any, consult WebPage's allowed drag source actions.
+
+ * WebProcess/WebPage/WebPage.h:
+ (WebKit::WebPage::allowedDragSourceActions const):
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::requestDragStart):
+ (WebKit::WebPage::requestAdditionalItemsForDragSession):
+
+ Set WebPage's allowed drag source actions to the given set of actions when sending a drag start to the page.
+
2019-04-08 Justin Fan <[email protected]>
[Web GPU] Fix Web GPU experimental feature on iOS
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (244055 => 244056)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-04-08 22:49:20 UTC (rev 244056)
@@ -716,8 +716,8 @@
#if ENABLE(DATA_INTERACTION)
void didHandleDragStartRequest(bool started);
void didHandleAdditionalDragItemsRequest(bool added);
- void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
- void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
+ void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions);
+ void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions);
void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>);
#endif
#endif
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (244055 => 244056)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-04-08 22:49:20 UTC (rev 244056)
@@ -2053,9 +2053,9 @@
if (![self ensurePositionInformationIsUpToDate:request])
return NO;
-#if ENABLE(DATA_INTERACTION)
- if (_positionInformation.hasSelectionAtPosition) {
- // If the position might initiate a data interaction, we don't want to consider the content at this position to be selectable.
+#if ENABLE(DRAG_SUPPORT)
+ if (_positionInformation.hasSelectionAtPosition && self._allowedDragSourceActions & WebCore::DragSourceActionSelection) {
+ // If the position might initiate a drag, we don't want to consider the content at this position to be selectable.
// FIXME: This should be renamed to something more precise, such as textSelectionShouldRecognizeGestureAtPoint:
return NO;
}
@@ -2093,9 +2093,9 @@
if (![self ensurePositionInformationIsUpToDate:request])
return NO;
-#if ENABLE(DATA_INTERACTION)
- if (_positionInformation.hasSelectionAtPosition && gesture == UIWKGestureLoupe) {
- // If the position might initiate data interaction, we don't want to change the selection.
+#if ENABLE(DRAG_SUPPORT)
+ if (_positionInformation.hasSelectionAtPosition && gesture == UIWKGestureLoupe && self._allowedDragSourceActions & WebCore::DragSourceActionSelection) {
+ // If the position might initiate a drag, we don't want to change the selection.
return NO;
}
#endif
@@ -6289,6 +6289,16 @@
return WKDragDestinationActionAny & ~WKDragDestinationActionLoad;
}
+- (WebCore::DragSourceAction)_allowedDragSourceActions
+{
+ auto allowedActions = WebCore::DragSourceActionAny;
+ if (!self.isFirstResponder || !_suppressSelectionAssistantReasons.isEmpty()) {
+ // Don't allow starting a drag on a selection when selection views are not visible.
+ allowedActions = static_cast<WebCore::DragSourceAction>(allowedActions & ~WebCore::DragSourceActionSelection);
+ }
+ return allowedActions;
+}
+
- (id <UIDragDropSession>)currentDragOrDropSession
{
if (_dragDropInteractionState.dropSession())
@@ -6448,7 +6458,7 @@
}
_dragDropInteractionState.dragSessionWillRequestAdditionalItem(completion);
- _page->requestAdditionalItemsForDragSession(WebCore::roundedIntPoint(point), WebCore::roundedIntPoint(point));
+ _page->requestAdditionalItemsForDragSession(WebCore::roundedIntPoint(point), WebCore::roundedIntPoint(point), self._allowedDragSourceActions);
}
- (void)_dragInteraction:(UIDragInteraction *)interaction prepareForSession:(id <UIDragSession>)session completion:(dispatch_block_t)completion
@@ -6468,7 +6478,7 @@
_dragDropInteractionState.prepareForDragSession(session, completion);
auto dragOrigin = WebCore::roundedIntPoint([session locationInView:self]);
- _page->requestDragStart(dragOrigin, WebCore::roundedIntPoint([self convertPoint:dragOrigin toView:self.window]));
+ _page->requestDragStart(dragOrigin, WebCore::roundedIntPoint([self convertPoint:dragOrigin toView:self.window]), self._allowedDragSourceActions);
RELEASE_LOG(DragAndDrop, "Drag session requested: %p at origin: {%d, %d}", session, dragOrigin.x(), dragOrigin.y());
}
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (244055 => 244056)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2019-04-08 22:49:20 UTC (rev 244056)
@@ -1177,16 +1177,16 @@
pageClient().didHandleAdditionalDragItemsRequest(added);
}
-void WebPageProxy::requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition)
+void WebPageProxy::requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions)
{
if (hasRunningProcess())
- m_process->send(Messages::WebPage::RequestDragStart(clientPosition, globalPosition), m_pageID);
+ m_process->send(Messages::WebPage::RequestDragStart(clientPosition, globalPosition, allowedActions), m_pageID);
}
-void WebPageProxy::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition)
+void WebPageProxy::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition, WebCore::DragSourceAction allowedActions)
{
if (hasRunningProcess())
- m_process->send(Messages::WebPage::RequestAdditionalItemsForDragSession(clientPosition, globalPosition), m_pageID);
+ m_process->send(Messages::WebPage::RequestAdditionalItemsForDragSession(clientPosition, globalPosition, allowedActions), m_pageID);
}
void WebPageProxy::didConcludeEditDrag(Optional<TextIndicatorData> data)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp (244055 => 244056)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp 2019-04-08 22:49:20 UTC (rev 244056)
@@ -47,7 +47,7 @@
DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint&)
{
- return DragSourceActionAny;
+ return m_page->allowedDragSourceActions();
}
#if !PLATFORM(COCOA) && !PLATFORM(GTK)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (244055 => 244056)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-04-08 22:49:20 UTC (rev 244056)
@@ -57,6 +57,7 @@
#include <WebCore/ActivityState.h>
#include <WebCore/DictionaryPopupInfo.h>
#include <WebCore/DisabledAdaptations.h>
+#include <WebCore/DragActions.h>
#include <WebCore/FrameLoaderTypes.h>
#include <WebCore/HTMLMenuElement.h>
#include <WebCore/HTMLMenuItemElement.h>
@@ -846,6 +847,7 @@
void willStartDrag() { ASSERT(!m_isStartingDrag); m_isStartingDrag = true; }
void didStartDrag();
void dragCancelled();
+ WebCore::DragSourceAction allowedDragSourceActions() const { return m_allowedDragSourceActions; }
#endif
void beginPrinting(uint64_t frameID, const PrintInfo&);
@@ -1229,8 +1231,8 @@
#endif
#if PLATFORM(IOS_FAMILY) && ENABLE(DATA_INTERACTION)
- void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
- void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
+ void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions);
+ void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions);
#endif
#if !PLATFORM(COCOA) && !PLATFORM(WPE)
@@ -1732,6 +1734,7 @@
#if ENABLE(DRAG_SUPPORT)
bool m_isStartingDrag { false };
+ WebCore::DragSourceAction m_allowedDragSourceActions { WebCore::DragSourceActionAny };
#endif
bool m_cachedMainFrameIsPinnedToLeftSide { true };
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (244055 => 244056)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-04-08 22:49:20 UTC (rev 244056)
@@ -301,8 +301,8 @@
#endif
#if ENABLE(DATA_INTERACTION)
- RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition)
- RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition)
+ RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions)
+ RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions)
#endif
# Popup menu.
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (244055 => 244056)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-04-08 22:49:20 UTC (rev 244056)
@@ -714,14 +714,16 @@
}
#if ENABLE(DATA_INTERACTION)
-void WebPage::requestDragStart(const IntPoint& clientPosition, const IntPoint& globalPosition)
+void WebPage::requestDragStart(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t allowedActions)
{
+ SetForScope<WebCore::DragSourceAction> allowedActionsForScope(m_allowedDragSourceActions, static_cast<WebCore::DragSourceAction>(allowedActions));
bool didStart = m_page->mainFrame().eventHandler().tryToBeginDragAtPoint(clientPosition, globalPosition);
send(Messages::WebPageProxy::DidHandleDragStartRequest(didStart));
}
-void WebPage::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition)
+void WebPage::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t allowedActions)
{
+ SetForScope<WebCore::DragSourceAction> allowedActionsForScope(m_allowedDragSourceActions, static_cast<WebCore::DragSourceAction>(allowedActions));
// To augment the platform drag session with additional items, end the current drag session and begin a new drag session with the new drag item.
// This process is opaque to the UI process, which still maintains the old drag item in its drag session. Similarly, this persistent drag session
// is opaque to the web process, which only sees that the current drag has ended, and that a new one is beginning.
Modified: trunk/Tools/ChangeLog (244055 => 244056)
--- trunk/Tools/ChangeLog 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Tools/ChangeLog 2019-04-08 22:49:20 UTC (rev 244056)
@@ -1,3 +1,24 @@
+2019-04-08 Wenson Hsieh <[email protected]>
+
+ [iOS] Do not allow starting selection drags when selection views are not visible
+ https://bugs.webkit.org/show_bug.cgi?id=196686
+ <rdar://problem/49399192>
+
+ Reviewed by Tim Horton.
+
+ Adjust some existing API tests to make the web view become first responder before trying to begin dragging, and
+ also add some new API tests to cover scenarios where the web view is not first responder.
+
+ * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+
+ Add a switch to optionally make the web view first responder when starting the simulated drag.
+
+ * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+ (-[DragAndDropSimulator initWithWebView:]):
+ (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+
2019-04-08 Justin Fan <[email protected]>
[Web GPU] Fix Web GPU experimental feature on iOS
Modified: trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm (244055 => 244056)
--- trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm 2019-04-08 22:49:20 UTC (rev 244056)
@@ -430,6 +430,31 @@
EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"destination.value"]);
}
+TEST(DragAndDropTests, DoNotPerformSelectionDragWhenNotFirstResponder)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
+ [simulator setShouldBecomeFirstResponder:NO];
+
+ [webView synchronouslyLoadTestPageNamed:@"selected-text-and-textarea"];
+ [simulator runFrom:CGPointMake(160, 100) to:CGPointMake(160, 300)];
+
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"destination.value"]);
+}
+
+TEST(DragAndDropTests, CanDragImageWhenNotFirstResponder)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
+ [simulator setShouldBecomeFirstResponder:NO];
+
+ [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)];
+
+ NSURL *droppedImageURL = [NSURL URLWithString:[webView stringByEvaluatingJavaScript:@"editor.querySelector('img').src"]];
+ EXPECT_WK_STREQ("blob", droppedImageURL.scheme);
+}
+
TEST(DragAndDropTests, ContentEditableMoveParagraphs)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
Modified: trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h (244055 => 244056)
--- trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2019-04-08 22:49:20 UTC (rev 244056)
@@ -95,6 +95,7 @@
@property (nonatomic, readonly) DragAndDropPhase phase;
@property (nonatomic) BOOL allowsFocusToStartInputSession;
@property (nonatomic) BOOL shouldEnsureUIApplication;
+@property (nonatomic) BOOL shouldBecomeFirstResponder;
@property (nonatomic) BOOL shouldAllowMoveOperation;
@property (nonatomic, strong) NSArray *externalItemProviders;
@property (nonatomic, readonly) UIDropProposal *lastKnownDropProposal;
Modified: trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm (244055 => 244056)
--- trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2019-04-08 22:45:01 UTC (rev 244055)
+++ trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2019-04-08 22:49:20 UTC (rev 244056)
@@ -343,6 +343,7 @@
if (self = [super init]) {
_webView = webView;
_shouldEnsureUIApplication = NO;
+ _shouldBecomeFirstResponder = YES;
_shouldAllowMoveOperation = YES;
[_webView setUIDelegate:self];
[_webView _setInputDelegate:self];
@@ -415,6 +416,9 @@
if (_shouldEnsureUIApplication)
UIApplicationInstantiateSingleton([DragAndDropSimulatorApplication class]);
+ if (_shouldBecomeFirstResponder)
+ [_webView becomeFirstResponder];
+
[self _resetSimulatedState];
if (additionalItemRequestLocations)