Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebCore / platform / mac / DragDataMac.mm
index ac3c5b0..64e4894 100644 (file)
 #import "DragData.h"
 
 #if ENABLE(DRAG_SUPPORT)
+#import "LegacyNSPasteboardTypes.h"
 #import "MIMETypeRegistry.h"
+#import "NotImplemented.h"
 #import "Pasteboard.h"
 #import "PasteboardStrategy.h"
+#import "PlatformPasteboard.h"
 #import "PlatformStrategies.h"
+#import "RuntimeEnabledFeatures.h"
 #import "WebCoreNSURLExtras.h"
+#import <wtf/cocoa/NSURLExtras.h>
 
-#if USE(APPLE_INTERNAL_SDK)
-
-#import <WebKitAdditions/DragDataAdditions.mm>
+#if PLATFORM(IOS_FAMILY)
+#import <MobileCoreServices/MobileCoreServices.h>
+#endif
 
-#else
+namespace WebCore {
 
 static inline String rtfPasteboardType()
 {
-    return String(NSRTFPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeRTF);
+#else
+    return String(legacyRTFPasteboardType());
+#endif
 }
 
 static inline String rtfdPasteboardType()
 {
-    return String(NSRTFDPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeFlatRTFD);
+#else
+    return String(legacyRTFDPasteboardType());
+#endif
 }
 
 static inline String stringPasteboardType()
 {
-    return String(NSStringPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeText);
+#else
+    return String(legacyStringPasteboardType());
+#endif
 }
 
 static inline String urlPasteboardType()
 {
-    return String(NSURLPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeURL);
+#else
+    return String(legacyURLPasteboardType());
+#endif
 }
 
 static inline String htmlPasteboardType()
 {
-    return String(NSHTMLPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeHTML);
+#else
+    return String(legacyHTMLPasteboardType());
+#endif
 }
 
 static inline String colorPasteboardType()
 {
-    return String(NSColorPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String { UIColorPboardType };
+#else
+    return String(legacyColorPasteboardType());
+#endif
 }
 
 static inline String pdfPasteboardType()
 {
-    return String(NSPDFPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypePDF);
+#else
+    return String(legacyPDFPasteboardType());
+#endif
 }
 
 static inline String tiffPasteboardType()
 {
-    return String(NSTIFFPboardType);
+#if PLATFORM(IOS_FAMILY)
+    return String(kUTTypeTIFF);
+#else
+    return String(legacyTIFFPasteboardType());
+#endif
 }
 
-#endif // USE(APPLE_INTERNAL_SDK)
-
-namespace WebCore {
-
-DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, 
-    DragOperation sourceOperationMask, DragApplicationFlags flags)
+DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation sourceOperationMask, DragApplicationFlags flags, DragDestinationAction destinationAction)
     : m_clientPosition(clientPosition)
     , m_globalPosition(globalPosition)
     , m_platformDragData(data)
     , m_draggingSourceOperationMask(sourceOperationMask)
     , m_applicationFlags(flags)
+    , m_dragDestinationAction(destinationAction)
 #if PLATFORM(MAC)
     , m_pasteboardName([[m_platformDragData draggingPasteboard] name])
 #else
@@ -98,16 +131,23 @@ DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPo
 {
 }
 
-DragData::DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition,
-    DragOperation sourceOperationMask, DragApplicationFlags flags)
+DragData::DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation sourceOperationMask, DragApplicationFlags flags, DragDestinationAction destinationAction)
     : m_clientPosition(clientPosition)
     , m_globalPosition(globalPosition)
     , m_platformDragData(0)
     , m_draggingSourceOperationMask(sourceOperationMask)
     , m_applicationFlags(flags)
+    , m_dragDestinationAction(destinationAction)
     , m_pasteboardName(dragStorageName)
 {
 }
+
+bool DragData::containsURLTypeIdentifier() const
+{
+    Vector<String> types;
+    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
+    return types.contains(urlPasteboardType());
+}
     
 bool DragData::canSmartReplace() const
 {
@@ -123,34 +163,27 @@ bool DragData::containsColor() const
 
 bool DragData::containsFiles() const
 {
-#if PLATFORM(MAC)
-    Vector<String> types;
-    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
-    return types.contains(String(NSFilenamesPboardType)) || types.contains(String(NSFilesPromisePboardType));
-#else
-    return false;
-#endif
+    return numberOfFiles();
 }
 
 unsigned DragData::numberOfFiles() const
 {
-    Vector<String> files;
-#if PLATFORM(MAC)
-    platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilenamesPboardType), m_pasteboardName);
-    if (!files.size())
-        platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilesPromisePboardType), m_pasteboardName);
-#endif
-    return files.size();
+    return platformStrategies()->pasteboardStrategy()->getNumberOfFiles(m_pasteboardName);
 }
 
-void DragData::asFilenames(Vector<String>& result) const
+Vector<String> DragData::asFilenames() const
 {
 #if PLATFORM(MAC)
-    platformStrategies()->pasteboardStrategy()->getPathnamesForType(result, String(NSFilenamesPboardType), m_pasteboardName);
-    if (!result.size())
-        result = fileNames();
+    Vector<String> types;
+    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
+    if (types.contains(String(legacyFilesPromisePasteboardType())))
+        return fileNames();
+
+    Vector<String> results;
+    platformStrategies()->pasteboardStrategy()->getPathnamesForType(results, String(legacyFilenamesPasteboardType()), m_pasteboardName);
+    return results;
 #else
-    UNUSED_PARAM(result);
+    return fileNames();
 #endif
 }
 
@@ -163,7 +196,7 @@ bool DragData::containsPlainText() const
         || types.contains(rtfdPasteboardType())
         || types.contains(rtfPasteboardType())
 #if PLATFORM(MAC)
-        || types.contains(String(NSFilenamesPboardType))
+        || types.contains(String(legacyFilenamesPasteboardType()))
 #endif
         || platformStrategies()->pasteboardStrategy()->stringForType(urlPasteboardType(), m_pasteboardName).length();
 }
@@ -178,7 +211,7 @@ String DragData::asPlainText() const
     // FIXME: It's not clear this is 100% correct since we know -[NSURL URLWithString:] does not handle
     // all the same cases we handle well in the URL code for creating an NSURL.
     if (text.isURL)
-        return userVisibleString([NSURL URLWithString:string]);
+        return WTF::userVisibleString([NSURL URLWithString:string]);
 
     // FIXME: WTF should offer a non-Mac-specific way to convert string to precomposed form so we can do it for all platforms.
     return [(NSString *)string precomposedStringWithCanonicalMapping];
@@ -189,38 +222,71 @@ Color DragData::asColor() const
     return platformStrategies()->pasteboardStrategy()->color(m_pasteboardName);
 }
 
-bool DragData::containsCompatibleContent() const
+bool DragData::containsCompatibleContent(DraggingPurpose purpose) const
 {
+    if (purpose == DraggingPurpose::ForFileUpload)
+        return containsFiles();
+
+    if (purpose == DraggingPurpose::ForColorControl)
+        return containsColor();
+
+    if (purpose == DraggingPurpose::ForEditing && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && containsFiles())
+        return true;
+
     Vector<String> types;
     platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
     return types.contains(String(WebArchivePboardType))
         || types.contains(htmlPasteboardType())
 #if PLATFORM(MAC)
-        || types.contains(String(NSFilenamesPboardType))
-        || types.contains(String(NSFilesPromisePboardType))
+        || types.contains(String(legacyFilenamesPasteboardType()))
+        || types.contains(String(legacyFilesPromisePasteboardType()))
 #endif
         || types.contains(tiffPasteboardType())
         || types.contains(pdfPasteboardType())
         || types.contains(urlPasteboardType())
         || types.contains(rtfdPasteboardType())
         || types.contains(rtfPasteboardType())
+        || types.contains(String(kUTTypeUTF8PlainText))
         || types.contains(stringPasteboardType())
         || types.contains(colorPasteboardType())
+        || types.contains(String(kUTTypeJPEG))
         || types.contains(String(kUTTypePNG));
 }
 
 bool DragData::containsPromise() const
 {
+    // FIXME: legacyFilesPromisePasteboardType() contains UTIs, not path names. Also, why do we
+    // think promises should only contain one file (or UTI)?
     Vector<String> files;
 #if PLATFORM(MAC)
-    platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilesPromisePboardType), m_pasteboardName);
+    platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(legacyFilesPromisePasteboardType()), m_pasteboardName);
 #endif
     return files.size() == 1;
 }
 
 bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
 {
+#if PLATFORM(IOS_FAMILY)
+    UNUSED_PARAM(filenamePolicy);
+    Vector<String> types;
+    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
+    if (!types.contains(urlPasteboardType()))
+        return false;
+
+    auto urlString = platformStrategies()->pasteboardStrategy()->stringForType(urlPasteboardType(), m_pasteboardName);
+    if (urlString.isEmpty()) {
+        // On iOS, we don't get access to the contents of NSItemProviders until we perform the drag operation.
+        // Thus, we consider DragData to contain an URL if it contains the `public.url` UTI type. Later down the
+        // road, when we perform the drag operation, we can then check if the URL's protocol is http or https,
+        // and if it isn't, we bail out of page navigation.
+        return true;
+    }
+
+    URL webcoreURL = [NSURL URLWithString:urlString];
+    return webcoreURL.protocolIs("http") || webcoreURL.protocolIs("https");
+#else
     return !asURL(filenamePolicy).isEmpty();
+#endif
 }
 
 String DragData::asURL(FilenameConversionPolicy, String* title) const
@@ -257,9 +323,9 @@ String DragData::asURL(FilenameConversionPolicy, String* title) const
     }
     
 #if PLATFORM(MAC)
-    if (types.contains(String(NSFilenamesPboardType))) {
+    if (types.contains(String(legacyFilenamesPasteboardType()))) {
         Vector<String> files;
-        platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilenamesPboardType), m_pasteboardName);
+        platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(legacyFilenamesPasteboardType()), m_pasteboardName);
         if (files.size() == 1) {
             BOOL isDirectory;
             if ([[NSFileManager defaultManager] fileExistsAtPath:files[0] isDirectory:&isDirectory] && isDirectory)
@@ -268,7 +334,7 @@ String DragData::asURL(FilenameConversionPolicy, String* title) const
         }
     }
 
-    if (types.contains(String(NSFilesPromisePboardType)) && fileNames().size() == 1)
+    if (types.contains(String(legacyFilesPromisePasteboardType())) && fileNames().size() == 1)
         return [URLByCanonicalizingURL([NSURL fileURLWithPath:fileNames()[0]]) absoluteString];
 #endif