Skip to content
Permalink
Browse files
<attachment> should put URLs on the pasteboard so that Finder can acc…
…ept drops.

https://bugs.webkit.org/show_bug.cgi?id=142801
rdar://problem/19982527

Reviewed by Tim Horton.

Source/WebCore:

Test: editing/pasteboard/drag-and-drop-attachment-contenteditable.html

This patch adds all the necessary support to write attachment elements into
the pasteboard, including the promised type.

* WebCore.xcodeproj/project.pbxproj:
* page/DragActions.h:
* page/DragClient.h:
(WebCore::DragClient::declareAndWriteAttachment):
* page/DragController.cpp:
(WebCore::DragController::draggableElement):
(WebCore::DragController::startDrag):
* page/DragController.h:
(WebCore::DragController::draggingAttachmentURL):
* page/EventHandler.cpp:
(WebCore::EventHandler::dragHysteresisExceeded):
(WebCore::EventHandler::handleDrag):
* page/mac/DragControllerMac.mm:
(WebCore::DragController::declareAndWriteAttachment):
* page/win/DragControllerWin.cpp:
(WebCore::DragController::declareAndWriteAttachment):
* platform/URL.cpp:
(WebCore::URL::fileURLWithFileSystemPath):
* platform/URL.h:
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::absoluteAttachmentURL):
* rendering/HitTestResult.h:

Source/WebKit/mac:

This patch adds all the necessary support to write attachment elements into
the pasteboard, including the promised type in WK1.

* Misc/WebNSPasteboardExtras.mm:
(-[NSPasteboard _web_declareAndWriteDragImageForElement:URL:title:archive:source:]):
* WebCoreSupport/WebDragClient.h:
* WebCoreSupport/WebDragClient.mm:
(WebDragClient::declareAndWriteAttachment):
* WebView/WebHTMLView.mm:
(-[WebHTMLView namesOfPromisedFilesDroppedAtDestination:]):
* WebView/WebUIDelegate.h:

Source/WebKit2:

This patch adds all the necessary support to write attachment elements into
the pasteboard, including the promised type in WK2.

* UIProcess/API/mac/WKView.mm:
(-[WKView _setPromisedDataForImage:withFileName:withExtension:withTitle:withURL:withVisibleURL:withArchive:forPasteboard:]):
(-[WKView _setPromisedDataForAttachment:withExtension:withTitle:withURL:withVisibleURL:forPasteboard:]):
(-[WKView namesOfPromisedFilesDroppedAtDestination:]):
(-[WKView _setPromisedData:withFileName:withExtension:withTitle:withURL:withVisibleURL:withArchive:forPasteboard:]): Deleted.
* UIProcess/API/mac/WKViewInternal.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::setPromisedDataForImage):
(WebKit::PageClientImpl::setPromisedDataForAttachment):
(WebKit::PageClientImpl::setPromisedData): Deleted.
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::setPromisedDataForImage):
(WebKit::WebPageProxy::setPromisedDataForAttachment):
(WebKit::WebPageProxy::setPromisedData): Deleted.
* WebProcess/WebCoreSupport/WebDragClient.h:
* WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
(WebKit::WebDragClient::declareAndWriteAttachment):
(WebKit::WebDragClient::declareAndWriteDragImage):

LayoutTests:

* editing/pasteboard/drag-and-drop-attachment-contenteditable-expected.txt: Added.
* editing/pasteboard/drag-and-drop-attachment-contenteditable.html: Added.
* platform/mac-wk2/TestExpectations: Skipping new test on WK2 since it uses eventSender.



Canonical link: https://commits.webkit.org/160897@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Enrica Casucci committed Mar 19, 2015
1 parent 0fa7e4a commit b6770120edd853ecc78d553cf1e77a90b15b146f
Showing with 419 additions and 40 deletions.
  1. +13 −0 LayoutTests/ChangeLog
  2. +11 −0 LayoutTests/editing/pasteboard/drag-and-drop-attachment-contenteditable-expected.txt
  3. +62 −0 LayoutTests/editing/pasteboard/drag-and-drop-attachment-contenteditable.html
  4. +1 −0 LayoutTests/platform/mac-wk2/TestExpectations
  5. +36 −0 Source/WebCore/ChangeLog
  6. +1 −1 Source/WebCore/WebCore.xcodeproj/project.pbxproj
  7. +3 −0 Source/WebCore/page/DragActions.h
  8. +3 −0 Source/WebCore/page/DragClient.h
  9. +38 −0 Source/WebCore/page/DragController.cpp
  10. +9 −1 Source/WebCore/page/DragController.h
  11. +6 −0 Source/WebCore/page/EventHandler.cpp
  12. +10 −0 Source/WebCore/page/mac/DragControllerMac.mm
  13. +6 −0 Source/WebCore/page/win/DragControllerWin.cpp
  14. +5 −0 Source/WebCore/platform/URL.cpp
  15. +1 −0 Source/WebCore/platform/URL.h
  16. +21 −0 Source/WebCore/rendering/HitTestResult.cpp
  17. +3 −0 Source/WebCore/rendering/HitTestResult.h
  18. +20 −0 Source/WebKit/mac/ChangeLog
  19. +15 −5 Source/WebKit/mac/Misc/WebNSPasteboardExtras.mm
  20. +3 −0 Source/WebKit/mac/WebCoreSupport/WebDragClient.h
  21. +9 −3 Source/WebKit/mac/WebCoreSupport/WebDragClient.mm
  22. +11 −7 Source/WebKit/mac/WebView/WebHTMLView.mm
  23. +1 −0 Source/WebKit/mac/WebView/WebUIDelegate.h
  24. +34 −0 Source/WebKit2/ChangeLog
  25. +38 −13 Source/WebKit2/UIProcess/API/mac/WKView.mm
  26. +4 −1 Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
  27. +6 −1 Source/WebKit2/UIProcess/PageClient.h
  28. +4 −1 Source/WebKit2/UIProcess/WebPageProxy.h
  29. +4 −1 Source/WebKit2/UIProcess/WebPageProxy.messages.in
  30. +4 −1 Source/WebKit2/UIProcess/mac/PageClientImpl.h
  31. +9 −2 Source/WebKit2/UIProcess/mac/PageClientImpl.mm
  32. +14 −2 Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm
  33. +3 −0 Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.h
  34. +11 −1 Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
@@ -1,3 +1,15 @@
2015-03-19 Enrica Casucci <enrica@apple.com>

<attachment> should put URLs on the pasteboard so that Finder can accept drops.
https://bugs.webkit.org/show_bug.cgi?id=142801
rdar://problem/19982527

Reviewed by Tim Horton.

* editing/pasteboard/drag-and-drop-attachment-contenteditable-expected.txt: Added.
* editing/pasteboard/drag-and-drop-attachment-contenteditable.html: Added.
* platform/mac-wk2/TestExpectations: Skipping new test on WK2 since it uses eventSender.

2015-03-19 Dean Jackson <dino@apple.com>

http://webkit.org/b/142790
@@ -122,6 +134,7 @@
* fast/repaint/multiple-backgrounds-style-change-expected.txt: Added.
* fast/repaint/multiple-backgrounds-style-change.html: Added.

>>>>>>> .r181712
2015-03-18 Marcos Chavarría Teijeiro <chavarria1991@gmail.com>

Unreviewed GTK Gardening 18th March
@@ -0,0 +1,11 @@
These tests dragging an attachment element into contenteditable

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS target.getElementsByTagName("attachment").length is 1
PASS target.getElementsByTagName("attachment")[0].file.name is "apple.gif"
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<style>
#target {
height: 200px;
width: 220px;
border: 5px solid blue;
}
</style>
</head>
<body onload="runTest()">
<p id="description"></p>
<div id="test1"><attachment id='attachment'></attachment></div>
<div contenteditable=true id="target"></div>
<div id="console"></div>

<script>
description('These tests dragging an attachment element into contenteditable');
var jsTestIsAsync = true;
var target = document.getElementById('target');

function contentInserted() {
shouldBe('target.getElementsByTagName("attachment").length', '1');
shouldBeEqualToString('target.getElementsByTagName("attachment")[0].file.name', 'apple.gif');
finishJSTest();
}

function setupAttachment() {
if (window.internals) {
var attachment = document.getElementById('attachment');
attachment.file = window.internals.createFile("resources/apple.gif");
}
}

function runTest() {
setupAttachment();
target.addEventListener('DOMNodeInserted', contentInserted, false);
if (!window.testRunner)
return;

testRunner.waitUntilDone();

e = document.getElementById("attachment");
x = e.offsetLeft + e.offsetWidth / 2;
y = e.offsetTop + e.offsetHeight / 2;

eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.leapForward(100);
e = document.getElementById("target");
x = e.offsetLeft + e.offsetWidth / 2;
y = e.offsetTop + e.offsetHeight / 2;

eventSender.mouseMoveTo(x, y);
eventSender.mouseUp();
}
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -23,6 +23,7 @@ editing/pasteboard/copy-standalone-image-crash.html
editing/pasteboard/drag-and-drop-image-contenteditable.html
editing/pasteboard/drag-and-drop-inputimage-contenteditable.html
editing/pasteboard/drag-and-drop-objectimage-contenteditable.html
editing/pasteboard/drag-and-drop-attachment-contenteditable.html
editing/pasteboard/drag-drop-dead-frame.html
editing/pasteboard/drag-drop-input-textarea.html
editing/pasteboard/drag-drop-list.html
@@ -1,3 +1,39 @@
2015-03-19 Enrica Casucci <enrica@apple.com>

<attachment> should put URLs on the pasteboard so that Finder can accept drops.
https://bugs.webkit.org/show_bug.cgi?id=142801
rdar://problem/19982527

Reviewed by Tim Horton.

Test: editing/pasteboard/drag-and-drop-attachment-contenteditable.html

This patch adds all the necessary support to write attachment elements into
the pasteboard, including the promised type.

* WebCore.xcodeproj/project.pbxproj:
* page/DragActions.h:
* page/DragClient.h:
(WebCore::DragClient::declareAndWriteAttachment):
* page/DragController.cpp:
(WebCore::DragController::draggableElement):
(WebCore::DragController::startDrag):
* page/DragController.h:
(WebCore::DragController::draggingAttachmentURL):
* page/EventHandler.cpp:
(WebCore::EventHandler::dragHysteresisExceeded):
(WebCore::EventHandler::handleDrag):
* page/mac/DragControllerMac.mm:
(WebCore::DragController::declareAndWriteAttachment):
* page/win/DragControllerWin.cpp:
(WebCore::DragController::declareAndWriteAttachment):
* platform/URL.cpp:
(WebCore::URL::fileURLWithFileSystemPath):
* platform/URL.h:
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::absoluteAttachmentURL):
* rendering/HitTestResult.h:

2015-03-19 Chris Dumez <cdumez@apple.com>

Unreviewed, fix linking error after r181753.
@@ -2527,7 +2527,7 @@
7CC69941191EC5F500AF2270 /* JSWebKitNamespace.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CC6993F191EC5F500AF2270 /* JSWebKitNamespace.h */; };
7CC7E3D717208C0F003C5277 /* IDNScriptWhiteList.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7CC7E3D617208C0F003C5277 /* IDNScriptWhiteList.txt */; };
7CD494CC1A86EB1D000A87EC /* RenderAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD494CA1A86EB1D000A87EC /* RenderAttachment.cpp */; };
7CD494CD1A86EB1D000A87EC /* RenderAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */; };
7CD494CD1A86EB1D000A87EC /* RenderAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; };
7CDEEE1E197610D700E352CD /* ViewStateChangeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CDEEE1D197610D700E352CD /* ViewStateChangeObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
7CE68344192143A800F4D928 /* UserMessageHandlerDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CE68342192143A800F4D928 /* UserMessageHandlerDescriptor.cpp */; };
7CE68345192143A800F4D928 /* UserMessageHandlerDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE68343192143A800F4D928 /* UserMessageHandlerDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -46,6 +46,9 @@ namespace WebCore {
DragSourceActionImage = 2,
DragSourceActionLink = 4,
DragSourceActionSelection = 8,
#if ENABLE(ATTACHMENT_ELEMENT)
DragSourceActionAttachment = 16,
#endif
DragSourceActionAny = UINT_MAX
} DragSourceAction;

@@ -55,6 +55,9 @@ class DragClient {
// Mac-specific helper function to allow access to web archives and NSPasteboard extras in WebKit.
// This is not abstract as that would require another #if PLATFORM(COCOA) for the SVGImage client empty implentation.
virtual void declareAndWriteDragImage(const String&, Element&, const URL&, const String&, Frame*) { }
#if ENABLE(ATTACHMENT_ELEMENT)
virtual void declareAndWriteAttachment(const String&, Element&, const URL&, const String&, Frame*) { }
#endif
#endif

virtual ~DragClient() { }
@@ -49,6 +49,7 @@
#include "FrameSelection.h"
#include "FrameView.h"
#include "HTMLAnchorElement.h"
#include "HTMLAttachmentElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
@@ -623,6 +624,14 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta
state.type = (sourceFrame->selection().contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
if (!startElement)
return nullptr;
#if ENABLE(ATTACHMENT_ELEMENT)
// Unlike image elements, attachment elements are immediately selected upon mouse down,
// but for those elements we still want to use the single element drag behavior as long as
// the element is the only content of the selection.
const VisibleSelection& selection = sourceFrame->selection().selection();
if (selection.isRange() && is<HTMLAttachmentElement>(selection.start().anchorNode()) && selection.start().anchorNode() == selection.end().anchorNode())
state.type = DragSourceActionNone;
#endif

for (auto renderer = startElement->renderer(); renderer; renderer = renderer->parent()) {
Element* element = renderer->nonPseudoElement();
@@ -649,6 +658,14 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionLink);
return element;
}
#if ENABLE(ATTACHMENT_ELEMENT)
if ((m_dragSourceAction & DragSourceActionAttachment)
&& is<HTMLAttachmentElement>(*element)
&& downcast<HTMLAttachmentElement>(*element).file()) {
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionAttachment);
return element;
}
#endif
}
}

@@ -738,6 +755,10 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
return false;
URL linkURL = hitTestResult.absoluteLinkURL();
URL imageURL = hitTestResult.absoluteImageURL();
#if ENABLE(ATTACHMENT_ELEMENT)
URL attachmentURL = hitTestResult.absoluteAttachmentURL();
m_draggingAttachmentURL = URL();
#endif

IntPoint mouseDraggedPoint = src.view()->windowToContents(dragEvent.position());

@@ -853,6 +874,23 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
dragImage = scaleDragImage(dragImage, FloatSize(m_page.deviceScaleFactor(), m_page.deviceScaleFactor()));
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, dataTransfer, src, true);
#if ENABLE(ATTACHMENT_ELEMENT)
} else if (!attachmentURL.isEmpty() && (m_dragSourceAction & DragSourceActionAttachment)) {
if (!dataTransfer.pasteboard().hasData()) {
m_draggingAttachmentURL = attachmentURL;
selectElement(element);
declareAndWriteAttachment(dataTransfer, element, attachmentURL);
}

m_client.willPerformDragSourceAction(DragSourceActionAttachment, dragOrigin, dataTransfer);

if (!dragImage) {
dragImage = dissolveDragImageToFraction(createDragImageForSelection(src), DragImageAlpha);
dragLoc = dragLocForSelectionDrag(src);
m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
}
doSystemDrag(dragImage, dragLoc, dragOrigin, dataTransfer, src, false);
#endif
} else if (state.type == DragSourceActionDHTML) {
if (dragImage) {
ASSERT(m_dragSourceAction & DragSourceActionDHTML);
@@ -73,6 +73,9 @@ namespace WebCore {
bool didInitiateDrag() const { return m_didInitiateDrag; }
DragOperation sourceDragOperation() const { return m_sourceDragOperation; }
const URL& draggingImageURL() const { return m_draggingImageURL; }
#if ENABLE(ATTACHMENT_ELEMENT)
const URL& draggingAttachmentURL() const { return m_draggingAttachmentURL; }
#endif
void setDragOffset(const IntPoint& offset) { m_dragOffset = offset; }
const IntPoint& dragOffset() const { return m_dragOffset; }
DragSourceAction dragSourceAction() const { return m_dragSourceAction; }
@@ -114,7 +117,9 @@ namespace WebCore {
void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, DataTransfer&, Frame&, bool forLink);
void cleanupAfterSystemDrag();
void declareAndWriteDragImage(DataTransfer&, Element&, const URL&, const String& label);

#if ENABLE(ATTACHMENT_ELEMENT)
void declareAndWriteAttachment(DataTransfer&, Element&, const URL&);
#endif
Page& m_page;
DragClient& m_client;

@@ -130,6 +135,9 @@ namespace WebCore {
DragOperation m_sourceDragOperation; // Set in startDrag when a drag starts from a mouse down within WebKit
IntPoint m_dragOffset;
URL m_draggingImageURL;
#if ENABLE(ATTACHMENT_ELEMENT)
URL m_draggingAttachmentURL;
#endif
};

}
@@ -3308,6 +3308,9 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
threshold = TextDragHysteresis;
break;
case DragSourceActionImage:
#if ENABLE(ATTACHMENT_ELEMENT)
case DragSourceActionAttachment:
#endif
threshold = ImageDragHysteresis;
break;
case DragSourceActionLink:
@@ -3430,6 +3433,9 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
ASSERT((dragState().type & DragSourceActionSelection));
ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
#if ENABLE(ATTACHMENT_ELEMENT)
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionAttachment
#endif
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
dragState().type = DragSourceActionSelection;
}
@@ -36,7 +36,9 @@
#import "Editor.h"
#import "EditorClient.h"
#import "Element.h"
#import "File.h"
#import "FrameView.h"
#import "HTMLAttachmentElement.h"
#import "MainFrame.h"
#import "Page.h"
#import "Pasteboard.h"
@@ -87,6 +89,14 @@
dragEnded();
}

#if ENABLE(ATTACHMENT_ELEMENT)
void DragController::declareAndWriteAttachment(DataTransfer& dataTransfer, Element& element, const URL& url)
{
const HTMLAttachmentElement& attachment = downcast<HTMLAttachmentElement>(element);
m_client.declareAndWriteAttachment(dataTransfer.pasteboard().name(), element, url, attachment.file()->path(), element.document().frame());
}
#endif

void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
{
m_client.declareAndWriteDragImage(dataTransfer.pasteboard().name(), element, url, label, element.document().frame());
@@ -69,6 +69,12 @@ void DragController::cleanupAfterSystemDrag()
{
}

#if ENABLE(ATTACHMENT_ELEMENT)
void DragController::declareAndWriteAttachment(DataTransfer&, Element&, const URL&)
{
}
#endif

void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
{
Pasteboard& pasteboard = dataTransfer.pasteboard();
@@ -2119,4 +2119,9 @@ URL URL::fakeURLWithRelativePart(const String& relativePart)
return URL(URL(), "webkit-fake-url://" + createCanonicalUUIDString() + '/' + relativePart);
}

URL URL::fileURLWithFileSystemPath(const String& filePath)
{
return URL(URL(), "file:///" + filePath);
}

}
@@ -73,6 +73,7 @@ class URL {
URL(const URL& base, const String& relative, const TextEncoding&);

static URL fakeURLWithRelativePart(const String&);
static URL fileURLWithFileSystemPath(const String&);

String strippedForUseAsReferrer() const;

@@ -25,11 +25,13 @@
#include "CachedImage.h"
#include "DocumentMarkerController.h"
#include "Editor.h"
#include "File.h"
#include "Frame.h"
#include "FrameSelection.h"
#include "FrameTree.h"
#include "HTMLAnchorElement.h"
#include "HTMLAreaElement.h"
#include "HTMLAttachmentElement.h"
#include "HTMLAudioElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
@@ -310,6 +312,25 @@ IntRect HitTestResult::imageRect() const
return m_innerNonSharedNode->renderBox()->absoluteContentQuad().enclosingBoundingBox();
}

#if ENABLE(ATTACHMENT_ELEMENT)
URL HitTestResult::absoluteAttachmentURL() const
{
if (!m_innerNonSharedNode)
return URL();

if (!(m_innerNonSharedNode->renderer() && m_innerNonSharedNode->renderer()->isAttachment()))
return URL();

if (!is<HTMLAttachmentElement>(*m_innerNonSharedNode))
return URL();
File* attachmentFile = downcast<HTMLAttachmentElement>(*m_innerNonSharedNode).file();
if (!attachmentFile)
return URL();

return URL::fileURLWithFileSystemPath(attachmentFile->path());
}
#endif

URL HitTestResult::absoluteImageURL() const
{
if (!m_innerNonSharedNode)

0 comments on commit b677012

Please sign in to comment.