Use the new drag code path when dragging links
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 00:08:34 +0000 (00:08 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 00:08:34 +0000 (00:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168612

Reviewed by Tim Horton.

Source/WebCore:

* editing/Editor.cpp:
(WebCore::Editor::copyURL):
Use userVisibleString instead of fillInUserVisibleForm.

(WebCore::Editor::pasteboardWriterURL):
New function that returns a PasteboardWriterData::URL for a given URL + title.

* editing/Editor.h:
Add new members.

* editing/mac/EditorMac.mm:
(WebCore::Editor::userVisibleString):
(WebCore::Editor::fillInUserVisibleForm): Deleted.
Add a getter instead of a function that fills in a struct member.

* page/DragController.cpp:
(WebCore::DragController::startDrag):
Add the new DragItem code path when dragging links.

* platform/PasteboardWriterData.cpp:
(WebCore::PasteboardWriterData::isEmpty):
Check for m_url as well.

(WebCore::PasteboardWriterData::setURL):
Set m_url.

* platform/PasteboardWriterData.h:
Add new members.

* platform/mac/PasteboardWriter.mm:
(WebCore::toUTI):
New helper function that returns an UTI from a pasteboard type.

(WebCore::createPasteboardWriter):
Handle converting URLs to the various pasteboard types.

Tools:

If a type is not dynamic, just use the static UTI.

* DumpRenderTree/mac/DumpRenderTreePasteboard.mm:
(-[LocalPasteboard writeObjects:]):

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

Source/WebCore/ChangeLog
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/page/DragController.cpp
Source/WebCore/platform/PasteboardWriterData.cpp
Source/WebCore/platform/PasteboardWriterData.h
Source/WebCore/platform/mac/PasteboardWriter.mm
Tools/ChangeLog
Tools/DumpRenderTree/mac/DumpRenderTreePasteboard.mm

index eb50e3a..2704078 100644 (file)
@@ -1,3 +1,46 @@
+2017-02-20  Anders Carlsson  <andersca@apple.com>
+
+        Use the new drag code path when dragging links
+        https://bugs.webkit.org/show_bug.cgi?id=168612
+
+        Reviewed by Tim Horton.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::copyURL):
+        Use userVisibleString instead of fillInUserVisibleForm.
+
+        (WebCore::Editor::pasteboardWriterURL):
+        New function that returns a PasteboardWriterData::URL for a given URL + title.
+
+        * editing/Editor.h:
+        Add new members.
+
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::userVisibleString):
+        (WebCore::Editor::fillInUserVisibleForm): Deleted.
+        Add a getter instead of a function that fills in a struct member.
+
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag):
+        Add the new DragItem code path when dragging links.
+
+        * platform/PasteboardWriterData.cpp:
+        (WebCore::PasteboardWriterData::isEmpty):
+        Check for m_url as well.
+
+        (WebCore::PasteboardWriterData::setURL):
+        Set m_url.
+
+        * platform/PasteboardWriterData.h:
+        Add new members.
+
+        * platform/mac/PasteboardWriter.mm:
+        (WebCore::toUTI):
+        New helper function that returns an UTI from a pasteboard type.
+
+        (WebCore::createPasteboardWriter):
+        Handle converting URLs to the various pasteboard types.
+
 2017-02-20  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Add plumbing to the UI process for TextIndicatorData when computing the drag image
index 7b34a53..7e39426 100644 (file)
@@ -1346,12 +1346,25 @@ void Editor::copyURL(const URL& url, const String& title, Pasteboard& pasteboard
     pasteboardURL.title = title;
 
 #if PLATFORM(MAC)
-    fillInUserVisibleForm(pasteboardURL);
+    pasteboardURL.userVisibleForm = userVisibleString(url);
 #endif
 
     pasteboard.write(pasteboardURL);
 }
 
+PasteboardWriterData::URL Editor::pasteboardWriterURL(const URL& url, const String& title)
+{
+    PasteboardWriterData::URL result;
+
+    result.url = url;
+    result.title = title;
+#if PLATFORM(MAC)
+    result.userVisibleForm = userVisibleString(url);
+#endif
+
+    return result;
+}
+
 #if !PLATFORM(IOS)
 
 void Editor::copyImage(const HitTestResult& result)
index 7e512dd..b9b6e06 100644 (file)
@@ -35,6 +35,7 @@
 #include "EditorInsertAction.h"
 #include "FindOptions.h"
 #include "FrameSelection.h"
+#include "PasteboardWriterData.h"
 #include "TextChecking.h"
 #include "TextEventInputType.h"
 #include "TextIteratorBehavior.h"
@@ -147,6 +148,7 @@ public:
 
     WEBCORE_EXPORT void copyURL(const URL&, const String& title);
     void copyURL(const URL&, const String& title, Pasteboard&);
+    PasteboardWriterData::URL pasteboardWriterURL(const URL&, const String& title);
 #if !PLATFORM(IOS)
     WEBCORE_EXPORT void copyImage(const HitTestResult&);
 #endif
@@ -526,7 +528,7 @@ private:
     RefPtr<DocumentFragment> createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&&);
     RefPtr<DocumentFragment> createFragmentAndAddResources(NSAttributedString *);
     FragmentAndResources createFragment(NSAttributedString *);
-    void fillInUserVisibleForm(PasteboardURL&);
+    String userVisibleString(const URL&);
 
     static RefPtr<SharedBuffer> dataInRTFDFormat(NSAttributedString *);
     static RefPtr<SharedBuffer> dataInRTFFormat(NSAttributedString *);
index bd495c2..698d06a 100644 (file)
@@ -251,9 +251,9 @@ static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*&
     cachedImage = tentativeCachedImage;
 }
 
-void Editor::fillInUserVisibleForm(PasteboardURL& pasteboardURL)
+String Editor::userVisibleString(const URL& url)
 {
-    pasteboardURL.userVisibleForm = client()->userVisibleString(pasteboardURL.url);
+    return client()->userVisibleString(url);
 }
 
 void Editor::selectionWillChange()
index a45cfbf..63796df 100644 (file)
@@ -933,10 +933,15 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
     }
 
     if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
+        PasteboardWriterData pasteboardWriterData;
+
         if (!dataTransfer.pasteboard().hasData()) {
             // Simplify whitespace so the title put on the dataTransfer resembles what the user sees
             // on the web page. This includes replacing newlines with spaces.
-            src.editor().copyURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace(), dataTransfer.pasteboard());
+            if (mustUseLegacyDragClient)
+                src.editor().copyURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace(), dataTransfer.pasteboard());
+            else
+                pasteboardWriterData.setURL(src.editor().pasteboardWriterURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace()));
         } else {
             // Make sure the pasteboard also contains trustworthy link data
             // but don't overwrite more general pasteboard types.
@@ -967,8 +972,20 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
             dragImage = DragImage { platformAdjustDragImageForDeviceScaleFactor(dragImage.get(), m_page.deviceScaleFactor()) };
             if (textIndicator.contentImage)
                 dragImage.setIndicatorData(textIndicator);
+            dragImageAnchorPoint = FloatPoint { 0.5, static_cast<float>((size.height() - LinkDragBorderInset) / size.height()) };
+        }
+
+        if (mustUseLegacyDragClient) {
+            doSystemDrag(WTFMove(dragImage), dragLoc, mouseDraggedPoint, { }, dataTransfer, src, DragSourceActionLink);
+            return true;
         }
-        doSystemDrag(WTFMove(dragImage), dragLoc, mouseDraggedPoint, { }, dataTransfer, src, DragSourceActionLink);
+
+        DragItem dragItem;
+        dragItem.image = WTFMove(dragImage);
+        dragItem.imageAnchorPoint = dragImageAnchorPoint;
+        dragItem.data = WTFMove(pasteboardWriterData);
+
+        beginDrag(WTFMove(dragItem), src, dragOrigin, mouseDraggedPoint, dataTransfer, DragSourceActionSelection);
 
         return true;
     }
index 79f10a2..1c84aaa 100644 (file)
@@ -41,6 +41,9 @@ bool PasteboardWriterData::isEmpty() const
     if (m_plainText)
         return false;
 
+    if (m_url)
+        return false;
+
     return true;
 }
 
@@ -51,4 +54,11 @@ void PasteboardWriterData::setPlainText(PlainText plainText)
     m_plainText = WTFMove(plainText);
 }
 
+void PasteboardWriterData::setURL(URL url)
+{
+    ASSERT(!m_url);
+
+    m_url = WTFMove(url);
+}
+
 }
index 9ce46b8..9bc7675 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "URL.h"
 #include <wtf/Optional.h>
 #include <wtf/text/WTFString.h>
 
@@ -35,18 +36,32 @@ public:
     PasteboardWriterData();
     ~PasteboardWriterData();
 
+    WEBCORE_EXPORT bool isEmpty() const;
+
     struct PlainText {
         bool canSmartCopyOrDelete;
         String text;
     };
 
-    WEBCORE_EXPORT bool isEmpty() const;
-
     const std::optional<PlainText>& plainText() const { return m_plainText; }
     void setPlainText(PlainText);
 
+    struct URL {
+        WebCore::URL url;
+        String title;
+#if PLATFORM(MAC)
+        String userVisibleForm;
+#elif PLATFORM(GTK)
+        String markup;
+#endif
+    };
+
+    const std::optional<URL>& url() const { return m_url; }
+    void setURL(URL);
+
 private:
     std::optional<PlainText> m_plainText;
+    std::optional<URL> m_url;
 };
 
 }
index 3a18165..e0c010b 100644 (file)
 
 namespace WebCore {
 
+static RetainPtr<NSString> toUTI(NSString *pasteboardType)
+{
+    return adoptNS((__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, (__bridge CFStringRef)pasteboardType, nullptr));
+}
+
 RetainPtr<id <NSPasteboardWriting>> createPasteboardWriter(const PasteboardWriterData& data)
 {
     auto pasteboardItem = adoptNS([[NSPasteboardItem alloc] init]);
@@ -45,6 +50,39 @@ RetainPtr<id <NSPasteboardWriting>> createPasteboardWriter(const PasteboardWrite
         }
     }
 
+    if (auto& url = data.url()) {
+        NSURL *cocoaURL = url->url;
+        NSString *userVisibleString = url->userVisibleForm;
+        NSString *title = (NSString *)url->title;
+        if (!title.length) {
+            title = cocoaURL.path.lastPathComponent;
+            if (!title.length)
+                title = userVisibleString;
+        }
+
+        // WebURLsWithTitlesPboardType.
+        auto paths = adoptNS([[NSArray alloc] initWithObjects:@[ @[ cocoaURL.absoluteString ] ], @[ url->title.stripWhiteSpace() ], nil]);
+        [pasteboardItem setPropertyList:paths.get() forType:toUTI(@"WebURLsWithTitlesPboardType").get()];
+
+        // NSURLPboardType.
+        if (NSURL *baseCocoaURL = cocoaURL.baseURL)
+            [pasteboardItem setPropertyList:@[ cocoaURL.relativeString, baseCocoaURL.absoluteString ] forType:toUTI(NSURLPboardType).get()];
+        else if (cocoaURL)
+            [pasteboardItem setPropertyList:@[ cocoaURL.absoluteString, @"" ] forType:toUTI(NSURLPboardType).get()];
+        else
+            [pasteboardItem setPropertyList:@[ @"", @"" ] forType:toUTI(NSURLPboardType).get()];
+
+        if (cocoaURL.fileURL)
+            [pasteboardItem setString:cocoaURL.absoluteString forType:(NSString *)kUTTypeFileURL];
+        [pasteboardItem setString:userVisibleString forType:(NSString *)kUTTypeURL];
+
+        // WebURLNamePboardType.
+        [pasteboardItem setString:title forType:@"public.url-name"];
+
+        // NSPasteboardTypeString.
+        [pasteboardItem setString:userVisibleString forType:NSPasteboardTypeString];
+    }
+
     return pasteboardItem;
 }
 
index 5986a46..db92691 100644 (file)
@@ -1,3 +1,15 @@
+2017-02-20  Anders Carlsson  <andersca@apple.com>
+
+        Use the new drag code path when dragging links
+        https://bugs.webkit.org/show_bug.cgi?id=168612
+
+        Reviewed by Tim Horton.
+
+        If a type is not dynamic, just use the static UTI.
+
+        * DumpRenderTree/mac/DumpRenderTreePasteboard.mm:
+        (-[LocalPasteboard writeObjects:]):
+
 2017-02-17  Anders Carlsson  <andersca@apple.com>
 
         Add a new drag code path and use it for dragging plain text
index 057bf5b..76b10f3 100644 (file)
@@ -219,7 +219,12 @@ static NSMutableDictionary *localPasteboards;
 {
     for (id <NSPasteboardWriting> object in objects) {
         for (NSString *type in [object writableTypesForPasteboard:self]) {
-            auto pasteboardType = adoptNS((__bridge NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)type, kUTTagClassNSPboardType));
+            auto pasteboardType = ^{
+                if (UTTypeIsDynamic((__bridge CFStringRef)type))
+                    return adoptNS((__bridge NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)type, kUTTagClassNSPboardType));
+
+                return retainPtr(type);
+            }();
 
             [self addTypes:@[ pasteboardType.get() ] owner:self];