Diff
Modified: trunk/Source/WebCore/ChangeLog (275071 => 275072)
--- trunk/Source/WebCore/ChangeLog 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/ChangeLog 2021-03-26 02:27:29 UTC (rev 275072)
@@ -1,3 +1,45 @@
+2021-03-25 Wenson Hsieh <[email protected]>
+
+ It should be possible to drag images with overlay content
+ https://bugs.webkit.org/show_bug.cgi?id=223766
+ <rdar://problem/75856030>
+
+ Reviewed by Tim Horton.
+
+ Make a few minor adjustments to make drag and drop play well with images with overlay content. See below for
+ more details.
+
+ Test: DragAndDropTests.DragElementWithImageOverlay
+
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::isInsideImageOverlay):
+
+ Add a helper method to return whether an individual DOM node is inside an image overlay. Use this in the
+ existing version of this method that takes a `SimpleRange`.
+
+ * html/HTMLElement.h:
+ * page/DragController.cpp:
+ (WebCore::DragController::draggableElement const):
+
+ Skip all drag source actions except for `Selection` in the case where we're hit-testing to text inside of an
+ image overlay.
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleMousePressEvent):
+
+ Make `isMouseDownOnLinkOrImage` `false` in the case where we're over image overlay text.
+
+ * rendering/HitTestResult.cpp:
+ (WebCore::HitTestResult::nodeForImageData const):
+ (WebCore::HitTestResult::image const):
+ (WebCore::HitTestResult::imageRect const):
+ (WebCore::HitTestResult::absoluteImageURL const):
+
+ Teach `HitTestResult` to skip out of image overlay content and find the actual image element when determining
+ the image URL, image, or image rect.
+
+ * rendering/HitTestResult.h:
+
2021-03-25 Jessie Berlin <[email protected]>
Remove 10.13 DEPLOYMENT_TARGETs and SYSTEM_VERSION_PREFIXs
Modified: trunk/Source/WebCore/html/HTMLElement.cpp (275071 => 275072)
--- trunk/Source/WebCore/html/HTMLElement.cpp 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/html/HTMLElement.cpp 2021-03-26 02:27:29 UTC (rev 275072)
@@ -1250,11 +1250,16 @@
if (!commonAncestor)
return false;
- auto host = imageOverlayHost(*commonAncestor);
+ return isInsideImageOverlay(*commonAncestor);
+}
+
+bool HTMLElement::isInsideImageOverlay(const Node& node)
+{
+ auto host = imageOverlayHost(node);
if (!host)
return false;
- return host->userAgentShadowRoot()->contains(*commonAncestor);
+ return host->userAgentShadowRoot()->contains(node);
}
bool HTMLElement::isImageOverlayText(const Node& node)
Modified: trunk/Source/WebCore/html/HTMLElement.h (275071 => 275072)
--- trunk/Source/WebCore/html/HTMLElement.h 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/html/HTMLElement.h 2021-03-26 02:27:29 UTC (rev 275072)
@@ -130,6 +130,7 @@
WEBCORE_EXPORT static bool shouldExtendSelectionToTargetNode(const Node& targetNode, const VisibleSelection& selectionBeforeUpdate);
bool hasImageOverlay() const;
static bool isInsideImageOverlay(const SimpleRange&);
+ static bool isInsideImageOverlay(const Node&);
WEBCORE_EXPORT static bool isImageOverlayText(const Node&);
#if ENABLE(IMAGE_EXTRACTION)
Modified: trunk/Source/WebCore/page/DragController.cpp (275071 => 275072)
--- trunk/Source/WebCore/page/DragController.cpp 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/page/DragController.cpp 2021-03-26 02:27:29 UTC (rev 275072)
@@ -785,6 +785,10 @@
}
#endif
+ auto selectionDragElement = state.type.contains(DragSourceAction::Selection) && m_dragSourceAction.contains(DragSourceAction::Selection) ? startElement : nullptr;
+ if (startElement && HTMLElement::isImageOverlayText(*startElement))
+ return selectionDragElement;
+
for (auto* element = startElement; element; element = element->parentOrShadowHostElement()) {
auto* renderer = element->renderer();
if (!renderer)
@@ -798,7 +802,6 @@
if (dragMode == UserDrag::Auto) {
if ((m_dragSourceAction.contains(DragSourceAction::Image))
&& is<HTMLImageElement>(*element)
- && !HTMLElement::isImageOverlayText(*startElement)
&& imageElementIsDraggable(downcast<HTMLImageElement>(*element), *sourceFrame)) {
state.type.add(DragSourceAction::Image);
return element;
@@ -825,10 +828,7 @@
}
// We either have nothing to drag or we have a selection and we're not over a draggable element.
- if (state.type.contains(DragSourceAction::Selection) && m_dragSourceAction.contains(DragSourceAction::Selection))
- return startElement;
-
- return nullptr;
+ return selectionDragElement;
}
static CachedImage* getCachedImage(Element& element)
Modified: trunk/Source/WebCore/page/EventHandler.cpp (275071 => 275072)
--- trunk/Source/WebCore/page/EventHandler.cpp 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2021-03-26 02:27:29 UTC (rev 275072)
@@ -746,7 +746,8 @@
// Bug: https://bugs.webkit.org/show_bug.cgi?id=155390
// Single mouse down on links or images can always trigger drag-n-drop.
- bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().image();
+ bool isImageOverlayText = event.targetNode() && HTMLElement::isImageOverlayText(*event.targetNode());
+ bool isMouseDownOnLinkOrImage = event.isOverLink() || (event.hitTestResult().image() && !isImageOverlayText);
m_mouseDownMayStartDrag = singleClick && (!event.event().shiftKey() || isMouseDownOnLinkOrImage) && shouldAllowMouseDownToStartDrag();
#endif
Modified: trunk/Source/WebCore/rendering/HitTestResult.cpp (275071 => 275072)
--- trunk/Source/WebCore/rendering/HitTestResult.cpp 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/rendering/HitTestResult.cpp 2021-03-26 02:27:29 UTC (rev 275072)
@@ -331,13 +331,24 @@
return String();
}
-Image* HitTestResult::image() const
+RefPtr<Node> HitTestResult::nodeForImageData() const
{
if (!m_innerNonSharedNode)
return nullptr;
-
- auto* renderer = m_innerNonSharedNode->renderer();
- if (is<RenderImage>(renderer)) {
+
+ if (HTMLElement::isInsideImageOverlay(*m_innerNonSharedNode))
+ return m_innerNonSharedNode->shadowHost();
+
+ return m_innerNonSharedNode;
+}
+
+Image* HitTestResult::image() const
+{
+ auto imageNode = nodeForImageData();
+ if (!imageNode)
+ return nullptr;
+
+ if (auto renderer = imageNode->renderer(); is<RenderImage>(renderer)) {
auto& image = downcast<RenderImage>(*renderer);
if (image.cachedImage() && !image.cachedImage()->errorOccurred())
return image.cachedImage()->imageForRenderer(&image);
@@ -350,28 +361,32 @@
{
if (!image())
return IntRect();
- return m_innerNonSharedNode->renderBox()->absoluteContentQuad().enclosingBoundingBox();
+
+ auto imageNode = nodeForImageData();
+ if (!imageNode)
+ return { };
+
+ return imageNode->renderBox()->absoluteContentQuad().enclosingBoundingBox();
}
URL HitTestResult::absoluteImageURL() const
{
- if (!m_innerNonSharedNode)
- return URL();
+ auto imageNode = nodeForImageData();
+ if (!imageNode)
+ return { };
- if (!(m_innerNonSharedNode->renderer() && m_innerNonSharedNode->renderer()->isImage()))
- return URL();
+ auto renderer = imageNode->renderer();
+ if (!renderer || !renderer->isImage())
+ return { };
- AtomString urlString;
- if (is<HTMLEmbedElement>(*m_innerNonSharedNode)
- || is<HTMLImageElement>(*m_innerNonSharedNode)
- || is<HTMLInputElement>(*m_innerNonSharedNode)
- || is<HTMLObjectElement>(*m_innerNonSharedNode)
- || is<SVGImageElement>(*m_innerNonSharedNode)) {
- urlString = downcast<Element>(*m_innerNonSharedNode).imageSourceURL();
- } else
- return URL();
+ if (is<HTMLEmbedElement>(*imageNode)
+ || is<HTMLImageElement>(*imageNode)
+ || is<HTMLInputElement>(*imageNode)
+ || is<HTMLObjectElement>(*imageNode)
+ || is<SVGImageElement>(*imageNode))
+ return imageNode->document().completeURL(downcast<Element>(*imageNode).imageSourceURL());
- return m_innerNonSharedNode->document().completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
+ return { };
}
URL HitTestResult::absolutePDFURL() const
Modified: trunk/Source/WebCore/rendering/HitTestResult.h (275071 => 275072)
--- trunk/Source/WebCore/rendering/HitTestResult.h 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Source/WebCore/rendering/HitTestResult.h 2021-03-26 02:27:29 UTC (rev 275072)
@@ -151,6 +151,8 @@
template<typename RectType> HitTestProgress addNodeToListBasedTestResultCommon(Node*, const HitTestRequest&, const HitTestLocation&, const RectType&);
+ RefPtr<Node> nodeForImageData() const;
+
#if ENABLE(VIDEO)
HTMLMediaElement* mediaElement() const;
#endif
Modified: trunk/Tools/ChangeLog (275071 => 275072)
--- trunk/Tools/ChangeLog 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/ChangeLog 2021-03-26 02:27:29 UTC (rev 275072)
@@ -1,3 +1,36 @@
+2021-03-25 Wenson Hsieh <[email protected]>
+
+ It should be possible to drag images with overlay content
+ https://bugs.webkit.org/show_bug.cgi?id=223766
+ <rdar://problem/75856030>
+
+ Reviewed by Tim Horton.
+
+ Add an API test to verify that the top part of the image (with an overlay) doesn't trigger a `dragstart` when
+ dragged, but the bottom part of the image does.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKit/simple-image-overlay.html: Added.
+
+ Add a test page that installs an image overlay for testing purposes (assuming that the web view injects the
+ global `internals` object).
+
+ * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
+ * TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm:
+ * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+ * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+ (-[DragAndDropSimulator containsDraggedType:]):
+
+ Add a helper method to return whether or not the simulated drag resulted in the given type being written to the
+ "drag pasteboard" (in the case of iOS, this just means any of the source item providers).
+
+ * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm:
+ (-[DragAndDropSimulator initWithWebViewFrame:configuration:]):
+
+ Make a minor adjustment to ensure that the drag pasteboard is cleared out before starting a simulated drag.
+
+ (-[DragAndDropSimulator containsDraggedType:]):
+
2021-03-25 Andres Gonzalez <[email protected]>
AX: Consider implementing @aria-details.
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-03-26 02:27:29 UTC (rev 275072)
@@ -1227,6 +1227,7 @@
F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */; };
F4E3D80820F70BB9007B58C5 /* significant-text-milestone-article.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */; };
F4EB4E912328AC3000574DAB /* NSItemProviderAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4EB4E902328AC3000574DAB /* NSItemProviderAdditions.mm */; };
+ F4EC8094260D30540010311D /* simple-image-overlay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4EC8093260D2E620010311D /* simple-image-overlay.html */; };
F4F137921D9B683E002BEC57 /* large-video-test-now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */; };
F4F405BC1D4C0D1C007A9707 /* full-size-autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F405BA1D4C0CF8007A9707 /* full-size-autoplaying-video-with-audio.html */; };
F4F405BD1D4C0D1C007A9707 /* skinny-autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F405BB1D4C0CF8007A9707 /* skinny-autoplaying-video-with-audio.html */; };
@@ -1638,6 +1639,7 @@
1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */,
C0ADBE9612FCA79B00D2C129 /* simple-form.html in Copy Resources */,
33DC8912141955FE00747EF7 /* simple-iframe.html in Copy Resources */,
+ F4EC8094260D30540010311D /* simple-image-overlay.html in Copy Resources */,
BCAA485614A0444C0088FAC4 /* simple-tall.html in Copy Resources */,
BC909784125571CF00083756 /* simple.html in Copy Resources */,
51E5C7021919C3B200D8B3E1 /* simple2.html in Copy Resources */,
@@ -3025,6 +3027,7 @@
F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "significant-text-milestone-article.html"; sourceTree = "<group>"; };
F4EB4E8F2328AC3000574DAB /* NSItemProviderAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSItemProviderAdditions.h; path = cocoa/NSItemProviderAdditions.h; sourceTree = SOURCE_ROOT; };
F4EB4E902328AC3000574DAB /* NSItemProviderAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = NSItemProviderAdditions.mm; path = cocoa/NSItemProviderAdditions.mm; sourceTree = SOURCE_ROOT; };
+ F4EC8093260D2E620010311D /* simple-image-overlay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-image-overlay.html"; sourceTree = "<group>"; };
F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-test-now-playing.html"; sourceTree = "<group>"; };
F4F405BA1D4C0CF8007A9707 /* full-size-autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "full-size-autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
F4F405BB1D4C0CF8007A9707 /* skinny-autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "skinny-autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
@@ -4484,6 +4487,7 @@
1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */,
C0ADBE8412FCA6B600D2C129 /* simple-form.html */,
33DC890E1419539300747EF7 /* simple-iframe.html */,
+ F4EC8093260D2E620010311D /* simple-image-overlay.html */,
BCAA485514A021640088FAC4 /* simple-tall.html */,
BC909778125571AB00083756 /* simple.html */,
51E780361919AFF8001829A2 /* simple2.html */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html (0 => 275072)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html 2021-03-26 02:27:29 UTC (rev 275072)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<style>
+img {
+ width: 300px;
+ height: 225px;
+}
+
+body, html {
+ margin: 0;
+}
+</style>
+<script>
+addEventListener("load", () => {
+ if (!window.internals)
+ return;
+
+ internals.installImageOverlay(document.querySelector("img"), [{
+ text : "foobar",
+ topLeft : new DOMPointReadOnly(0, 0),
+ topRight : new DOMPointReadOnly(1, 0),
+ bottomRight : new DOMPointReadOnly(1, 0.5),
+ bottomLeft : new DOMPointReadOnly(0, 0.5),
+ }]);
+});
+</script>
+</head>
+<body><img src=''></img></body>
+</html>
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2021-03-26 02:27:29 UTC (rev 275072)
@@ -30,6 +30,7 @@
#import "DragAndDropSimulator.h"
#import "PlatformUtilities.h"
+#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WebArchive.h>
@@ -383,4 +384,23 @@
#endif // ENABLE(INPUT_TYPE_COLOR)
+#if ENABLE(IMAGE_EXTRACTION)
+
+TEST(DragAndDropTests, DragElementWithImageOverlay)
+{
+ auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]);
+ [[configuration preferences] _setLargeImageAsyncDecodingEnabled:NO];
+
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
+ [[simulator webView] synchronouslyLoadTestPageNamed:@"simple-image-overlay"];
+
+ [simulator runFrom:NSMakePoint(150, 40) to:NSMakePoint(300, 40)];
+ EXPECT_FALSE([simulator containsDraggedType:(__bridge NSString *)kUTTypeJPEG]);
+
+ [simulator runFrom:NSMakePoint(150, 200) to:NSMakePoint(300, 200)];
+ EXPECT_TRUE([simulator containsDraggedType:(__bridge NSString *)kUTTypeJPEG]);
+}
+
+#endif // ENABLE(IMAGE_EXTRACTION)
+
#endif // ENABLE(DRAG_SUPPORT) && !PLATFORM(MACCATALYST)
Modified: trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm 2021-03-26 02:27:29 UTC (rev 275072)
@@ -148,7 +148,6 @@
EXPECT_EQ(pid, [webView _webProcessIdentifier]);
}
-
TEST(DragAndDropTests, ProvideImageDataForMultiplePasteboards)
{
auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]);
Modified: trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2021-03-26 02:27:29 UTC (rev 275072)
@@ -139,6 +139,8 @@
#endif // PLATFORM(MAC)
+- (BOOL)containsDraggedType:(NSString *)type;
+
@end
#endif // ENABLE(DRAG_SUPPORT)
Modified: trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2021-03-26 02:27:29 UTC (rev 275072)
@@ -863,6 +863,17 @@
[[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()];
}
+- (BOOL)containsDraggedType:(NSString *)expectedType
+{
+ for (NSItemProvider *itemProvider in self.sourceItemProviders) {
+ for (NSString *type in itemProvider.registeredTypeIdentifiers) {
+ if ([type isEqualToString:expectedType])
+ return YES;
+ }
+ }
+ return NO;
+}
+
#pragma mark - WKUIDelegatePrivate
- (void)_webView:(WKWebView *)webView dataInteraction:(UIDragInteraction *)interaction sessionWillBegin:(id <UIDragSession>)session
Modified: trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm (275071 => 275072)
--- trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2021-03-26 01:29:28 UTC (rev 275071)
+++ trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2021-03-26 02:27:29 UTC (rev 275072)
@@ -115,6 +115,8 @@
_filePromiseDestinationURLs = adoptNS([NSMutableArray new]);
[_webView setUIDelegate:self];
self.dragDestinationAction = WKDragDestinationActionAny & ~WKDragDestinationActionLoad;
+
+ [[NSPasteboard pasteboardWithName:NSPasteboardNameDrag] clearContents];
}
return self;
}
@@ -449,6 +451,15 @@
{
}
+- (BOOL)containsDraggedType:(NSString *)expectedType
+{
+ for (NSPasteboardType type in [NSPasteboard pasteboardWithName:NSPasteboardNameDrag].types) {
+ if ([type isEqualToString:expectedType])
+ return YES;
+ }
+ return NO;
+}
+
#pragma mark - WKUIDelegatePrivate
- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source