Skip to content
Permalink
Browse files
Use Blob URL instead of webkit-fake-url when pasting an image
https://bugs.webkit.org/show_bug.cgi?id=49141

Reviewed by Darin Adler.

Source/WebCore:

Use Blob URL instead of webkit-fake-url when pasting an image.

Tests: editing/pasteboard/paste-image-as-blob-url.html
       editing/pasteboard/paste-image-using-image-data.html

* editing/Editor.h:
* editing/mac/EditorMac.mm:
(WebCore::Editor::WebContentReader::readImage):
(WebCore::Editor::createFragmentForImageAndURL):

LayoutTests:

Add layout test coverage checking that the image shows as expected and that the
resulting URL is indeed a Blob URL.

* editing/pasteboard/paste-image-as-blob-url-expected.txt: Added.
* editing/pasteboard/paste-image-as-blob-url.html: Added.
* editing/pasteboard/paste-image-using-image-data-expected.html: Added.
* editing/pasteboard/paste-image-using-image-data.html: Added.


Canonical link: https://commits.webkit.org/182183@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208451 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
cdumez committed Nov 9, 2016
1 parent d8cc9ec commit 58238d437460d46bdcec14e54945edcf217e7f04
Showing 11 changed files with 137 additions and 9 deletions.
@@ -1,3 +1,18 @@
2016-11-09 Chris Dumez <cdumez@apple.com>

Use Blob URL instead of webkit-fake-url when pasting an image
https://bugs.webkit.org/show_bug.cgi?id=49141

Reviewed by Darin Adler.

Add layout test coverage checking that the image shows as expected and that the
resulting URL is indeed a Blob URL.

* editing/pasteboard/paste-image-as-blob-url-expected.txt: Added.
* editing/pasteboard/paste-image-as-blob-url.html: Added.
* editing/pasteboard/paste-image-using-image-data-expected.html: Added.
* editing/pasteboard/paste-image-using-image-data.html: Added.

2016-11-07 Yusuke Suzuki <utatane.tea@gmail.com>

[JSC] The implementation of 8 bit operation in MacroAssembler should care about uint8_t / int8_t
@@ -0,0 +1,12 @@
Tests that pasted images use blob URL, not webkit fake URLs.

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


PASS pastedImages.length is 1
PASS url.protocol is "blob:"
PASS successfullyParsed is true

TEST COMPLETE


@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<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>
description("Tests that pasted images use blob URL, not webkit fake URLs.");
jsTestIsAsync = true;

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");

pastedImages = destination.getElementsByTagName("img");
shouldBe("pastedImages.length", "1");
img = pastedImages[0];
url = new URL(img.src);
shouldBeEqualToString("url.protocol", "blob:");

finishJSTest();
}
</script>
<script src="../../resources/js-test-post.js"></script>
</html>
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<body>
<div id="destination" contenteditable="true" style="width: 500px; height: 100px; border: solid red 1px">
<img src="../resources/abe.png">
</div>
<iframe id="iframe" src="../resources/abe.png"></iframe>
</body>
</html>
@@ -0,0 +1,22 @@
<!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");
destination.blur();
}
</script>
</html>
@@ -1,3 +1,20 @@
2016-11-09 Chris Dumez <cdumez@apple.com>

Use Blob URL instead of webkit-fake-url when pasting an image
https://bugs.webkit.org/show_bug.cgi?id=49141

Reviewed by Darin Adler.

Use Blob URL instead of webkit-fake-url when pasting an image.

Tests: editing/pasteboard/paste-image-as-blob-url.html
editing/pasteboard/paste-image-using-image-data.html

* editing/Editor.h:
* editing/mac/EditorMac.mm:
(WebCore::Editor::WebContentReader::readImage):
(WebCore::Editor::createFragmentForImageAndURL):

2016-11-09 Michael Catanzaro <mcatanzaro@igalia.com>

Fix error message when SQLite initialization fails
@@ -518,6 +518,7 @@ class Editor {
RefPtr<SharedBuffer> imageInWebArchiveFormat(Element&);
RefPtr<Range> adjustedSelectionRange();
RefPtr<DocumentFragment> createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&&);
Ref<DocumentFragment> createFragmentForImageAndURL(const String&);
RefPtr<DocumentFragment> createFragmentAndAddResources(NSAttributedString *);
FragmentAndResources createFragment(NSAttributedString *);
void fillInUserVisibleForm(PasteboardURL&);
@@ -26,10 +26,12 @@
#import "config.h"
#import "Editor.h"

#import "Blob.h"
#import "CSSPrimitiveValueMappings.h"
#import "CSSValuePool.h"
#import "CachedResourceLoader.h"
#import "ColorMac.h"
#import "DOMURL.h"
#import "DataTransfer.h"
#import "DocumentFragment.h"
#import "DocumentLoader.h"
@@ -610,9 +612,14 @@ static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*&
ASSERT(type.contains('/'));
String typeAsFilenameWithExtension = type;
typeAsFilenameWithExtension.replace('/', '.');
URL imageURL = URL::fakeURLWithRelativePart(typeAsFilenameWithExtension);

fragment = frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(WTFMove(buffer), imageURL, type, emptyString(), emptyString()));
Vector<uint8_t> data;
data.append(buffer->data(), buffer->size());
auto blob = Blob::create(WTFMove(data), type);
ASSERT(frame.document());
String blobURL = DOMURL::createObjectURL(*frame.document(), blob);

fragment = frame.editor().createFragmentForImageAndURL(blobURL);
return fragment;
}

@@ -671,6 +678,17 @@ static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*&
return WTFMove(fragment);
}

Ref<DocumentFragment> Editor::createFragmentForImageAndURL(const String& url)
{
auto imageElement = HTMLImageElement::create(*m_frame.document());
imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, url);

auto fragment = document().createDocumentFragment();
fragment->appendChild(imageElement);

return fragment;
}

RefPtr<DocumentFragment> Editor::createFragmentAndAddResources(NSAttributedString *string)
{
if (!m_frame.page() || !document().isHTMLDocument())
@@ -77,7 +77,7 @@ Blob::Blob()
ThreadableBlobRegistry::registerBlobURL(m_internalURL, Vector<BlobPart>(), String());
}

Blob::Blob(Vector<uint8_t> data, const String& contentType)
Blob::Blob(Vector<uint8_t>&& data, const String& contentType)
: m_type(contentType)
, m_size(data.size())
{
@@ -87,7 +87,7 @@ Blob::Blob(Vector<uint8_t> data, const String& contentType)
ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType);
}

Blob::Blob(Vector<BlobPart> blobParts, const String& contentType)
Blob::Blob(Vector<BlobPart>&& blobParts, const String& contentType)
: m_type(contentType)
, m_size(-1)
{
@@ -48,12 +48,12 @@ class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Bl
return adoptRef(*new Blob);
}

static Ref<Blob> create(Vector<uint8_t> data, const String& contentType)
static Ref<Blob> create(Vector<uint8_t>&& data, const String& contentType)
{
return adoptRef(*new Blob(WTFMove(data), contentType));
}

static Ref<Blob> create(Vector<BlobPart> blobParts, const String& contentType)
static Ref<Blob> create(Vector<BlobPart>&& blobParts, const String& contentType)
{
return adoptRef(*new Blob(WTFMove(blobParts), contentType));
}
@@ -91,8 +91,8 @@ class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Bl

protected:
Blob();
Blob(Vector<uint8_t>, const String& contentType);
Blob(Vector<BlobPart>, const String& contentType);
Blob(Vector<uint8_t>&&, const String& contentType);
Blob(Vector<BlobPart>&&, const String& contentType);

enum UninitializedContructor { uninitializedContructor };
Blob(UninitializedContructor);
@@ -42,7 +42,7 @@ class BlobPart {
{
}

BlobPart(Vector<uint8_t> data)
BlobPart(Vector<uint8_t>&& data)
: m_type(Data)
, m_data(WTFMove(data))
{

0 comments on commit 58238d4

Please sign in to comment.