REGRESSION(r198177): Cannot paste an image when the pasteboard format is mime type.
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Jun 2016 00:21:16 +0000 (00:21 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Jun 2016 00:21:16 +0000 (00:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158590
rdar://problem/25471371

Reviewed by Darin Adler.

Source/WebCore:

When creating a fragment from an image resource, the resource needs to
be added to the document loader before setting the src attribute to the
image element, otherwise loading is triggered and the loading fails.
In r198177 the order of the operations was changed causing the bug.
This patch adds support to test the scenario where the image in the pasteboard
is available only as mime type (not WebArchive or RTFD), a situation that occurs
more frequently on iOS.

Test: editing/pasteboard/image-in-iframe.html

* editing/ios/EditorIOS.mm:
(WebCore::Editor::createFragmentForImageResourceAndAddResource):
* editing/mac/EditorMac.mm:
(WebCore::Editor::WebContentReader::readWebArchive):
(WebCore::Editor::WebContentReader::readRTFD):
(WebCore::Editor::WebContentReader::readRTF):
(WebCore::Editor::createFragmentForImageResourceAndAddResource):
* page/Settings.cpp:
(WebCore::Settings::setImagesEnabled):
(WebCore::Settings::setPreferMimeTypeForImages):
(WebCore::Settings::setForcePendingWebGLPolicy):
* page/Settings.h:
(WebCore::Settings::areImagesEnabled):
(WebCore::Settings::preferMimeTypeForImages):
(WebCore::Settings::arePluginsEnabled):
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setLangAttributeAwareFormControlUIEnabled):
(WebCore::InternalSettings::setPreferMimeTypeForImages):
(WebCore::InternalSettings::setImagesEnabled):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:

LayoutTests:

* editing/pasteboard/image-in-iframe-expected.txt: Added.
* editing/pasteboard/image-in-iframe.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/image-in-iframe-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/image-in-iframe.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/editing/ios/EditorIOS.mm
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl

index 4d5937b..4226a7a 100644 (file)
@@ -1,3 +1,14 @@
+2016-06-10  Enrica Casucci  <enrica@apple.com>
+
+        REGRESSION(r198177): Cannot paste an image when the pasteboard format is mime type.
+        https://bugs.webkit.org/show_bug.cgi?id=158590
+        rdar://problem/25471371
+
+        Reviewed by Darin Adler.
+
+        * editing/pasteboard/image-in-iframe-expected.txt: Added.
+        * editing/pasteboard/image-in-iframe.html: Added.
+
 2016-06-10  Ryan Haddad  <ryanhaddad@apple.com>
 
         Marking imported/blink/storage/indexeddb/blob-delete-objectstore-db.html as flaky on Yosemite Release WK2
diff --git a/LayoutTests/editing/pasteboard/image-in-iframe-expected.txt b/LayoutTests/editing/pasteboard/image-in-iframe-expected.txt
new file mode 100644 (file)
index 0000000..a4b136d
--- /dev/null
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x276
+  RenderBlock {HTML} at (0,0) size 800x276
+    RenderBody {BODY} at (8,8) size 784x260
+      RenderBlock {DIV} at (0,0) size 502x102 [border: (1px solid #FF0000)]
+        RenderImage {IMG} at (1,1) size 76x103
+      RenderBlock (anonymous) at (0,102) size 784x158
+        RenderIFrame {IFRAME} at (0,0) size 304x154 [border: (2px inset #000000)]
+          layer at (0,0) size 300x150
+            RenderView at (0,0) size 300x150
+          layer at (0,0) size 300x150
+            RenderBlock {HTML} at (0,0) size 300x150
+              RenderBody {BODY} at (0,0) size 300x150
+                RenderImage {IMG} at (0,0) size 76x103
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+caret: position 1 of child 0 {IMG} of child 1 {DIV} of body
diff --git a/LayoutTests/editing/pasteboard/image-in-iframe.html b/LayoutTests/editing/pasteboard/image-in-iframe.html
new file mode 100644 (file)
index 0000000..a0ad138
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="destination" contenteditable="true" style="width: 500px; height: 100px; border: solid red 1px"></div>
+<iframe id="iframe" src="../resources/abe.png" onload="selectInFrame()"></iframe>
+</body>
+<script>
+    function selectInFrame() {
+        if (window.internals)
+            window.internals.settings.setPreferMIMETypeForImages(true);
+        var iframe = document.getElementById("iframe");
+        var iframeDocument = iframe.contentDocument;
+        var destination = document.getElementById("destination");
+        iframeDocument.body.focus();
+        iframeDocument.execCommand("SelectAll");
+        iframeDocument.execCommand("Copy");
+        destination.focus();
+        document.execCommand("Paste");
+    }
+</script>
+</html>
index bfd2491..e65b730 100644 (file)
@@ -1,3 +1,44 @@
+2016-06-10  Enrica Casucci  <enrica@apple.com>
+
+        REGRESSION(r198177): Cannot paste an image when the pasteboard format is mime type.
+        https://bugs.webkit.org/show_bug.cgi?id=158590
+        rdar://problem/25471371
+
+        Reviewed by Darin Adler.
+
+        When creating a fragment from an image resource, the resource needs to
+        be added to the document loader before setting the src attribute to the
+        image element, otherwise loading is triggered and the loading fails.
+        In r198177 the order of the operations was changed causing the bug.
+        This patch adds support to test the scenario where the image in the pasteboard
+        is available only as mime type (not WebArchive or RTFD), a situation that occurs
+        more frequently on iOS.
+
+        Test: editing/pasteboard/image-in-iframe.html
+
+        * editing/ios/EditorIOS.mm:
+        (WebCore::Editor::createFragmentForImageResourceAndAddResource):
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::WebContentReader::readWebArchive):
+        (WebCore::Editor::WebContentReader::readRTFD):
+        (WebCore::Editor::WebContentReader::readRTF):
+        (WebCore::Editor::createFragmentForImageResourceAndAddResource):
+        * page/Settings.cpp:
+        (WebCore::Settings::setImagesEnabled):
+        (WebCore::Settings::setPreferMimeTypeForImages):
+        (WebCore::Settings::setForcePendingWebGLPolicy):
+        * page/Settings.h:
+        (WebCore::Settings::areImagesEnabled):
+        (WebCore::Settings::preferMimeTypeForImages):
+        (WebCore::Settings::arePluginsEnabled):
+        * testing/InternalSettings.cpp:
+        (WebCore::InternalSettings::Backup::restoreTo):
+        (WebCore::InternalSettings::setLangAttributeAwareFormControlUIEnabled):
+        (WebCore::InternalSettings::setPreferMimeTypeForImages):
+        (WebCore::InternalSettings::setImagesEnabled):
+        * testing/InternalSettings.h:
+        * testing/InternalSettings.idl:
+
 2016-06-10  Alex Christensen  <achristensen@webkit.org>
 
         Fix WinCairo build after r201943
index 9ea8385..e98adce 100644 (file)
@@ -38,6 +38,7 @@
 #include "Frame.h"
 #include "FrameLoaderClient.h"
 #include "HTMLConverter.h"
+#include "HTMLImageElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
 #include "HTMLParserIdioms.h"
@@ -579,15 +580,15 @@ RefPtr<DocumentFragment> Editor::createFragmentForImageResourceAndAddResource(Re
     if (!resource)
         return nullptr;
 
-    Ref<Element> imageElement = m_frame.document()->createElement(HTMLNames::imgTag, false);
-
     NSURL *URL = resource->url();
-    imageElement->setAttribute(HTMLNames::srcAttr, [URL isFileURL] ? [URL absoluteString] : resource->url());
+    String resourceURL = [URL isFileURL] ? [URL absoluteString] : resource->url();
 
-    // FIXME: The code in createFragmentAndAddResources calls setDefersLoading(true). Don't we need that here?
     if (DocumentLoader* loader = m_frame.loader().documentLoader())
         loader->addArchiveResource(resource.releaseNonNull());
 
+    auto imageElement = HTMLImageElement::create(*m_frame.document());
+    imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
+
     auto fragment = m_frame.document()->createDocumentFragment();
     fragment->appendChild(imageElement);
 
index 9e835d7..29b1f63 100644 (file)
@@ -44,6 +44,7 @@
 #import "HTMLAttachmentElement.h"
 #import "HTMLConverter.h"
 #import "HTMLElement.h"
+#include "HTMLImageElement.h"
 #import "HTMLNames.h"
 #import "LegacyWebArchive.h"
 #import "MIMETypeRegistry.h"
@@ -56,6 +57,7 @@
 #import "RenderBlock.h"
 #import "RenderImage.h"
 #import "RuntimeApplicationChecks.h"
+#import "Settings.h"
 #import "Sound.h"
 #import "StyleProperties.h"
 #import "Text.h"
@@ -474,6 +476,9 @@ private:
 
 bool Editor::WebContentReader::readWebArchive(SharedBuffer* buffer)
 {
+    if (frame.settings().preferMIMETypeForImages())
+        return false;
+
     if (!frame.document())
         return false;
 
@@ -560,12 +565,18 @@ bool Editor::WebContentReader::readHTML(const String& string)
 
 bool Editor::WebContentReader::readRTFD(SharedBuffer& buffer)
 {
+    if (frame.settings().preferMIMETypeForImages())
+        return false;
+
     fragment = frame.editor().createFragmentAndAddResources(adoptNS([[NSAttributedString alloc] initWithRTFD:buffer.createNSData().get() documentAttributes:nullptr]).get());
     return fragment;
 }
 
 bool Editor::WebContentReader::readRTF(SharedBuffer& buffer)
 {
+    if (frame.settings().preferMIMETypeForImages())
+        return false;
+
     fragment = frame.editor().createFragmentAndAddResources(adoptNS([[NSAttributedString alloc] initWithRTF:buffer.createNSData().get() documentAttributes:nullptr]).get());
     return fragment;
 }
@@ -623,13 +634,13 @@ RefPtr<DocumentFragment> Editor::createFragmentForImageResourceAndAddResource(Re
     if (!resource)
         return nullptr;
 
-    auto imageElement = document().createElement(HTMLNames::imgTag, false);
-    imageElement->setAttribute(HTMLNames::srcAttr, resource->url().string());
-
-    // FIXME: The code in createFragmentAndAddResources calls setDefersLoading(true). Don't we need that here?
+    String resourceURL = resource->url().string();
     if (DocumentLoader* loader = m_frame.loader().documentLoader())
         loader->addArchiveResource(resource.releaseNonNull());
 
+    auto imageElement = HTMLImageElement::create(*m_frame.document());
+    imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
+
     auto fragment = document().createDocumentFragment();
     fragment->appendChild(imageElement);
 
index 6eb52ba..b415463 100644 (file)
@@ -419,6 +419,11 @@ void Settings::setImagesEnabled(bool areImagesEnabled)
     m_setImageLoadingSettingsTimer.startOneShot(0);
 }
 
+void Settings::setPreferMIMETypeForImages(bool preferMIMETypeForImages)
+{
+    m_preferMIMETypeForImages = preferMIMETypeForImages;
+}
+
 void Settings::setForcePendingWebGLPolicy(bool forced)
 {
     m_forcePendingWebGLPolicy = forced;
index eb97249..5021b5c 100644 (file)
@@ -143,6 +143,9 @@ public:
     WEBCORE_EXPORT void setImagesEnabled(bool);
     bool areImagesEnabled() const { return m_areImagesEnabled; }
 
+    WEBCORE_EXPORT void setPreferMIMETypeForImages(bool);
+    bool preferMIMETypeForImages() const { return m_preferMIMETypeForImages; }
+
     WEBCORE_EXPORT void setPluginsEnabled(bool);
     bool arePluginsEnabled() const { return m_arePluginsEnabled; }
 
@@ -320,6 +323,7 @@ private:
     bool m_isJavaEnabledForLocalFiles : 1;
     bool m_loadsImagesAutomatically : 1;
     bool m_areImagesEnabled : 1;
+    bool m_preferMIMETypeForImages : 1;
     bool m_arePluginsEnabled : 1;
     bool m_isScriptEnabled : 1;
     bool m_needsAdobeFrameReloadingQuirk : 1;
index f557c22..1b29784 100644 (file)
@@ -157,6 +157,7 @@ void InternalSettings::Backup::restoreTo(Settings& settings)
     settings.setCanvasUsesAcceleratedDrawing(m_originalCanvasUsesAcceleratedDrawing);
     RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
     settings.setImagesEnabled(m_imagesEnabled);
+    settings.setPreferMIMETypeForImages(m_preferMIMETypeForImages);
     settings.setMinimumDOMTimerInterval(m_minimumTimerInterval);
 #if ENABLE(VIDEO_TRACK)
     settings.setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
@@ -469,6 +470,12 @@ void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
     RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(enabled);
 }
 
+void InternalSettings::setPreferMIMETypeForImages(bool preferMIMETypeForImages, ExceptionCode &ec)
+{
+    InternalSettingsGuardForSettings();
+    settings()->setPreferMIMETypeForImages(preferMIMETypeForImages);
+}
+
 void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec)
 {
     InternalSettingsGuardForSettings();
index b35cc42..3092fae 100644 (file)
@@ -79,6 +79,7 @@ public:
         bool m_originalUsesOverlayScrollbars;
         bool m_langAttributeAwareFormControlUIEnabled;
         bool m_imagesEnabled;
+        bool m_preferMIMETypeForImages;
         std::chrono::milliseconds m_minimumTimerInterval;
 #if ENABLE(VIDEO_TRACK)
         bool m_shouldDisplaySubtitles;
@@ -139,6 +140,7 @@ public:
     void setCanStartMedia(bool, ExceptionCode&);
     void setWirelessPlaybackDisabled(bool);
     void setEditingBehavior(const String&, ExceptionCode&);
+    void setPreferMIMETypeForImages(bool, ExceptionCode&);
     void setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode&);
     bool shouldDisplayTrackKind(const String& kind, ExceptionCode&);
     void setStorageBlockingPolicy(const String&, ExceptionCode&);
index 4abde2c..a30eabd 100644 (file)
@@ -63,6 +63,7 @@
     [RaisesException] void setEditingBehavior(DOMString behavior);
     [RaisesException] void setShouldConvertPositionStyleOnCopy(boolean convert);
     void setLangAttributeAwareFormControlUIEnabled(boolean enabled);
+    [RaisesException] void setPreferMIMETypeForImages(boolean preferMimeTypeForImage);
 
     // Other switches
     [RaisesException] void setStorageBlockingPolicy(DOMString policy);