[iOS] Refactor some logic for inserting pasted or dropped virtual card files as attac...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Apr 2019 16:45:25 +0000 (16:45 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Apr 2019 16:45:25 +0000 (16:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196435
Work towards <rdar://problem/48573098>

Reviewed by Darin Adler.

Refactor some existing codepaths on iOS for inserting VCard files as attachment elements. Instead of using a
separate readVirtualContactFile method for converting a vcard file or data into an attachment element (possibly
accompanied by a link), use the existing readFilePaths WebContentReader method.

To handle links which may accompany the attachment element, add a helper method in PasteboardIOS that reads a
titled URL prior to inserting an attachment element, in the case of pasting or dropping a VCF.

This means we no longer need to handle attachment reading in readPasteboardWebContentDataForType, so we can
simply bail before reading "public.vcard" here and defer to reading other data types.

Covered by existing API tests in WKAttachmentTests and DragAndDropTestsIOS.

* editing/WebContentReader.h:
* editing/cocoa/WebContentReaderCocoa.mm:
(WebCore::WebContentReader::readVirtualContactFile): Deleted.
* platform/Pasteboard.h:
* platform/ios/PasteboardIOS.mm:
(WebCore::Pasteboard::readPasteboardWebContentDataForType):
(WebCore::readURLAlongsideAttachmentIfNecessary):
(WebCore::prefersAttachmentRepresentation):
(WebCore::Pasteboard::read):
(WebCore::Pasteboard::readRespectingUTIFidelities):

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

Source/WebCore/ChangeLog
Source/WebCore/editing/WebContentReader.h
Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
Source/WebCore/platform/Pasteboard.h
Source/WebCore/platform/ios/PasteboardIOS.mm

index 9348559..05bc9a2 100644 (file)
@@ -1,3 +1,34 @@
+2019-04-01  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Refactor some logic for inserting pasted or dropped virtual card files as attachment elements
+        https://bugs.webkit.org/show_bug.cgi?id=196435
+        Work towards <rdar://problem/48573098>
+
+        Reviewed by Darin Adler.
+
+        Refactor some existing codepaths on iOS for inserting VCard files as attachment elements. Instead of using a
+        separate readVirtualContactFile method for converting a vcard file or data into an attachment element (possibly
+        accompanied by a link), use the existing readFilePaths WebContentReader method.
+
+        To handle links which may accompany the attachment element, add a helper method in PasteboardIOS that reads a
+        titled URL prior to inserting an attachment element, in the case of pasting or dropping a VCF.
+
+        This means we no longer need to handle attachment reading in readPasteboardWebContentDataForType, so we can
+        simply bail before reading "public.vcard" here and defer to reading other data types.
+
+        Covered by existing API tests in WKAttachmentTests and DragAndDropTestsIOS.
+
+        * editing/WebContentReader.h:
+        * editing/cocoa/WebContentReaderCocoa.mm:
+        (WebCore::WebContentReader::readVirtualContactFile): Deleted.
+        * platform/Pasteboard.h:
+        * platform/ios/PasteboardIOS.mm:
+        (WebCore::Pasteboard::readPasteboardWebContentDataForType):
+        (WebCore::readURLAlongsideAttachmentIfNecessary):
+        (WebCore::prefersAttachmentRepresentation):
+        (WebCore::Pasteboard::read):
+        (WebCore::Pasteboard::readRespectingUTIFidelities):
+
 2019-04-01  Antti Koivisto  <antti@apple.com>
 
         Trying to scroll the compose pane on gmail.com scrolls the message list behind
index 7e78db1..3c31112 100644 (file)
@@ -77,7 +77,6 @@ private:
     bool readRTF(SharedBuffer&) override;
     bool readImage(Ref<SharedBuffer>&&, const String& type) override;
     bool readURL(const URL&, const String& title) override;
-    bool readVirtualContactFile(const String& filePath, const URL&, const String& urlTitle) override;
     bool readDataBuffer(SharedBuffer&, const String& type, const String& name) override;
 #endif
     bool readPlainText(const String&) override;
@@ -96,7 +95,6 @@ private:
 #if PLATFORM(COCOA)
     bool readWebArchive(SharedBuffer&) override;
     bool readFilePaths(const Vector<String>&) override { return false; }
-    bool readVirtualContactFile(const String&, const URL&, const String&) override { return false; }
     bool readHTML(const String&) override;
     bool readRTFD(SharedBuffer&) override;
     bool readRTF(SharedBuffer&) override;
index 9e8e265..8d1f9e7 100644 (file)
@@ -774,28 +774,6 @@ bool WebContentReader::readFilePaths(const Vector<String>& paths)
     return true;
 }
 
-bool WebContentReader::readVirtualContactFile(const String& filePath, const URL& url, const String& urlTitle)
-{
-    if (filePath.isEmpty() || !frame.document())
-        return false;
-
-    auto& document = *frame.document();
-    if (!fragment)
-        fragment = document.createDocumentFragment();
-
-#if ENABLE(ATTACHMENT_ELEMENT)
-    if (!url.isEmpty())
-        readURL(url, urlTitle);
-
-    auto attachmentContainer = HTMLDivElement::create(*frame.document());
-    attachmentContainer->setInlineStyleProperty(CSSPropertyDisplay, CSSValueBlock, true);
-    attachmentContainer->appendChild(attachmentForFilePath(frame, filePath));
-    fragment->appendChild(WTFMove(attachmentContainer));
-#endif
-
-    return true;
-}
-
 bool WebContentReader::readURL(const URL& url, const String& title)
 {
     if (url.isEmpty())
index 35a831d..4a2f364 100644 (file)
@@ -137,7 +137,6 @@ public:
 #if PLATFORM(COCOA)
     virtual bool readWebArchive(SharedBuffer&) = 0;
     virtual bool readFilePaths(const Vector<String>&) = 0;
-    virtual bool readVirtualContactFile(const String& filePath, const URL&, const String& urlTitle) = 0;
     virtual bool readHTML(const String&) = 0;
     virtual bool readRTFD(SharedBuffer&) = 0;
     virtual bool readRTF(SharedBuffer&) = 0;
@@ -289,7 +288,7 @@ private:
         DidNotReadType,
         PasteboardWasChangedExternally
     };
-    ReaderResult readPasteboardWebContentDataForType(PasteboardWebContentReader&, PasteboardStrategy&, NSString *type, int itemIndex, const PasteboardItemInfo&);
+    ReaderResult readPasteboardWebContentDataForType(PasteboardWebContentReader&, PasteboardStrategy&, NSString *type, int itemIndex);
 #endif
 
 #if PLATFORM(WIN)
index 5ef3ce8..41d9056 100644 (file)
@@ -181,7 +181,7 @@ static bool isTypeAllowedByReadingPolicy(NSString *type, WebContentReadingPolicy
         || [type isEqualToString:(__bridge NSString *)kUTTypeFlatRTFD];
 }
 
-Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, NSString *type, int itemIndex, const PasteboardItemInfo& info)
+Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, NSString *type, int itemIndex)
 {
     if ([type isEqualToString:WebArchivePboardType] || [type isEqualToString:(__bridge NSString *)kUTTypeWebArchive]) {
         auto buffer = strategy.readBufferFromPasteboard(itemIndex, type, m_pasteboardName);
@@ -198,24 +198,10 @@ Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(Pastebo
     }
 
     if ([type isEqualToString:(__bridge NSString *)kUTTypeVCard]) {
-        bool canCreateAttachments = false;
-#if ENABLE(ATTACHMENT_ELEMENT)
-        if (RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled())
-            canCreateAttachments = true;
-#endif
-        if (canCreateAttachments) {
-            auto path = info.pathForContentType(kUTTypeVCard);
-            if (path.isEmpty())
-                return ReaderResult::DidNotReadType;
-
-            String title;
-            auto url = strategy.readURLFromPasteboard(itemIndex, m_pasteboardName, title);
-            if (m_changeCount != changeCount())
-                return ReaderResult::PasteboardWasChangedExternally;
-
-            if (reader.readVirtualContactFile(path, url, title))
-                return ReaderResult::ReadType;
-        }
+        // When dropping or pasting a virtual contact file in editable content, there's never a case where we
+        // would want to dump the entire contents of the file as plain text. Instead, fall back on another
+        // appropriate representation, such as a URL or plain text. For instance, in the case of an MKMapItem,
+        // we would prefer to insert an Apple Maps link instead.
         return ReaderResult::DidNotReadType;
     }
 
@@ -267,6 +253,29 @@ Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(Pastebo
     return ReaderResult::DidNotReadType;
 }
 
+static void readURLAlongsideAttachmentIfNecessary(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, const String& typeIdentifier, const String& pasteboardName, int itemIndex)
+{
+    if (!UTTypeConformsTo(typeIdentifier.createCFString().get(), kUTTypeVCard))
+        return;
+
+    String title;
+    auto url = strategy.readURLFromPasteboard(itemIndex, pasteboardName, title);
+    if (!url.isEmpty())
+        reader.readURL(url, title);
+}
+
+static bool prefersAttachmentRepresentation(const PasteboardItemInfo& info)
+{
+    auto contentTypeForHighestFidelityItem = info.contentTypeForHighestFidelityItem();
+    if (contentTypeForHighestFidelityItem.isEmpty())
+        return false;
+
+    if (info.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment)
+        return true;
+
+    return UTTypeConformsTo(contentTypeForHighestFidelityItem.createCFString().get(), kUTTypeVCard);
+}
+
 void Pasteboard::read(PasteboardWebContentReader& reader, WebContentReadingPolicy policy)
 {
     reader.contentOrigin = readOrigin();
@@ -294,12 +303,12 @@ void Pasteboard::read(PasteboardWebContentReader& reader, WebContentReadingPolic
     for (int i = 0; i < numberOfItems; i++) {
         auto info = strategy.informationForItemAtIndex(i, m_pasteboardName);
 #if ENABLE(ATTACHMENT_ELEMENT)
-        if (canReadAttachment) {
+        if (canReadAttachment && prefersAttachmentRepresentation(info)) {
             auto typeForFileUpload = info.contentTypeForHighestFidelityItem();
-            if (!typeForFileUpload.isEmpty() && info.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment) {
-                auto buffer = strategy.readBufferFromPasteboard(i, typeForFileUpload, m_pasteboardName);
-                if (buffer && reader.readDataBuffer(*buffer, typeForFileUpload, info.suggestedFileName))
-                    continue;
+            if (auto buffer = strategy.readBufferFromPasteboard(i, typeForFileUpload, m_pasteboardName)) {
+                readURLAlongsideAttachmentIfNecessary(reader, strategy, typeForFileUpload, m_pasteboardName, i);
+                reader.readDataBuffer(*buffer, typeForFileUpload, info.suggestedFileName);
+                continue;
             }
         }
 #endif
@@ -309,7 +318,7 @@ void Pasteboard::read(PasteboardWebContentReader& reader, WebContentReadingPolic
             if (!isTypeAllowedByReadingPolicy(type, policy))
                 continue;
 
-            auto itemResult = readPasteboardWebContentDataForType(reader, strategy, type, i, info);
+            auto itemResult = readPasteboardWebContentDataForType(reader, strategy, type, i);
             if (itemResult == ReaderResult::PasteboardWasChangedExternally)
                 return;
 
@@ -336,7 +345,8 @@ void Pasteboard::readRespectingUTIFidelities(PasteboardWebContentReader& reader,
         auto info = strategy.informationForItemAtIndex(index, m_pasteboardName);
         auto attachmentFilePath = info.pathForHighestFidelityItem();
         bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !attachmentFilePath.isEmpty();
-        if (canReadAttachment && info.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment) {
+        if (canReadAttachment && prefersAttachmentRepresentation(info)) {
+            readURLAlongsideAttachmentIfNecessary(reader, strategy, info.contentTypeForHighestFidelityItem(), m_pasteboardName, index);
             reader.readFilePaths({ WTFMove(attachmentFilePath) });
             continue;
         }
@@ -348,7 +358,7 @@ void Pasteboard::readRespectingUTIFidelities(PasteboardWebContentReader& reader,
             if (!isTypeAllowedByReadingPolicy(type, policy))
                 continue;
 
-            result = readPasteboardWebContentDataForType(reader, strategy, type, index, info);
+            result = readPasteboardWebContentDataForType(reader, strategy, type, index);
             if (result == ReaderResult::PasteboardWasChangedExternally)
                 return;
             if (result == ReaderResult::ReadType)