Diff
Modified: trunk/Source/WebCore/ChangeLog (222838 => 222839)
--- trunk/Source/WebCore/ChangeLog 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/ChangeLog 2017-10-04 11:06:15 UTC (rev 222839)
@@ -1,3 +1,39 @@
+2017-10-04 Ryosuke Niwa <[email protected]>
+
+ Use blob URL when pasting RTFD instead of overriding DocumentLoader
+ https://bugs.webkit.org/show_bug.cgi?id=177801
+ <rdar://problem/34542270>
+
+ Reviewed by Wenson Hsieh.
+
+ Before this patch, pasting RTFD resulted in images and other subresources in RTFD are being placed
+ into the document using WebKit fake URL, and DocumentLoader was overridden to return the appropriate
+ data upon resource requests. This is bad because there is no mechanism for websites to access its content.
+
+ Like r222119 and r208451, this patch fixes thie problem by using a blob URL instead of a WebKit fake URL.
+ This patch also adds a Blob::create variant which takes a SharedBuffer.
+
+ API Tests: PasteRTFD
+
+ * editing/WebCorePasteboardFileReader.cpp:
+ (WebCore::WebCorePasteboardFileReader::readBuffer):
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::DeferredLoadingScope): Extracted out of createFragmentAndAddResources for clarity.
+ (WebCore::DeferredLoadingScope::DeferredLoadingScope):
+ (WebCore::DeferredLoadingScope::~DeferredLoadingScope):
+ (WebCore::createFragmentAndAddResources): Instead of adding resources to document loader, replace each
+ URL in the document by a blob URL.
+ (WebCore::WebContentReader::readImage):
+ * editing/markup.cpp:
+ (WebCore::replaceSubresourceURLs): Added. A helper to replace each URL in the document fragment by a blob
+ URL created for each subresource. This won't work for iframes or srcset but that's okay for now since DOM
+ constructed from RTFD doesn't use either.
+ * editing/markup.h:
+ * fileapi/Blob.cpp:
+ (WebCore::Blob::Blob): Added a variant which takes a SharedBuffer.
+ * fileapi/Blob.h:
+ (WebCore::Blob::create): Ditto.
+
2017-10-04 Michael Catanzaro <[email protected]>
REGRESSION(r222392): [WPE][GTK] Many forms tests are failing due to broken event timestamps
Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp (222838 => 222839)
--- trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp 2017-10-04 11:06:15 UTC (rev 222839)
@@ -108,7 +108,7 @@
void FetchBodyOwner::blob(Ref<DeferredPromise>&& promise)
{
if (isBodyNullOrOpaque()) {
- promise->resolve<IDLInterface<Blob>>(Blob::create({ }, Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType))));
+ promise->resolve<IDLInterface<Blob>>(Blob::create(Vector<uint8_t> { }, Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType))));
return;
}
if (isDisturbedOrLocked()) {
Modified: trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp (222838 => 222839)
--- trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp 2017-10-04 11:06:15 UTC (rev 222839)
@@ -40,9 +40,7 @@
void WebCorePasteboardFileReader::readBuffer(const String& filename, const String& type, Ref<SharedBuffer>&& buffer)
{
- Vector<uint8_t> data;
- data.append(buffer->data(), buffer->size());
- files.append(File::create(Blob::create(WTFMove(data), type), filename));
+ files.append(File::create(Blob::create(buffer.get(), type), filename));
}
}
Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (222838 => 222839)
--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2017-10-04 11:06:15 UTC (rev 222839)
@@ -122,6 +122,38 @@
#endif
+class DeferredLoadingScope {
+public:
+ DeferredLoadingScope(Frame& frame)
+ : m_frame(frame)
+ , m_cachedResourceLoader(frame.document()->cachedResourceLoader())
+ {
+ if (!frame.page()->defersLoading()) {
+ frame.page()->setDefersLoading(true);
+ m_didEnabledDeferredLoading = true;
+ }
+
+ if (m_cachedResourceLoader->imagesEnabled()) {
+ m_cachedResourceLoader->setImagesEnabled(false);
+ m_didDisableImage = true;
+ }
+ }
+
+ ~DeferredLoadingScope()
+ {
+ if (m_didEnabledDeferredLoading)
+ m_cachedResourceLoader->setImagesEnabled(true);
+ if (m_didDisableImage)
+ m_frame->page()->setDefersLoading(false);
+ }
+
+private:
+ Ref<Frame> m_frame;
+ Ref<CachedResourceLoader> m_cachedResourceLoader;
+ bool m_didEnabledDeferredLoading { false };
+ bool m_didDisableImage { false };
+};
+
RefPtr<DocumentFragment> createFragmentAndAddResources(Frame& frame, NSAttributedString *string)
{
if (!frame.page() || !frame.document())
@@ -131,26 +163,19 @@
if (!document.isHTMLDocument() || !string)
return nullptr;
- bool wasDeferringCallbacks = frame.page()->defersLoading();
- if (!wasDeferringCallbacks)
- frame.page()->setDefersLoading(true);
+ DeferredLoadingScope scope(frame);
+ auto fragmentAndResources = createFragment(frame, string);
+ if (!fragmentAndResources.fragment)
+ return nullptr;
- auto& cachedResourceLoader = document.cachedResourceLoader();
- bool wasImagesEnabled = cachedResourceLoader.imagesEnabled();
- if (wasImagesEnabled)
- cachedResourceLoader.setImagesEnabled(false);
-
- auto fragmentAndResources = createFragment(frame, string);
- if (auto* loader = frame.loader().documentLoader()) {
- for (auto& resource : fragmentAndResources.resources)
- loader->addArchiveResource(WTFMove(resource));
+ HashMap<AtomicString, AtomicString> blobURLMap;
+ for (const Ref<ArchiveResource>& subresource : fragmentAndResources.resources) {
+ auto blob = Blob::create(subresource->data(), subresource->mimeType());
+ String blobURL = DOMURL::createObjectURL(document, blob);
+ blobURLMap.set(subresource->url().string(), blobURL);
}
+ replaceSubresourceURLs(*fragmentAndResources.fragment, WTFMove(blobURLMap));
- if (wasImagesEnabled)
- cachedResourceLoader.setImagesEnabled(true);
- if (!wasDeferringCallbacks)
- frame.page()->setDefersLoading(false);
-
return WTFMove(fragmentAndResources.fragment);
}
@@ -225,9 +250,7 @@
bool WebContentReader::readImage(Ref<SharedBuffer>&& buffer, const String& type)
{
- Vector<uint8_t> data;
- data.append(buffer->data(), buffer->size());
- auto blob = Blob::create(WTFMove(data), type);
+ auto blob = Blob::create(buffer.get(), type);
ASSERT(frame.document());
auto& document = *frame.document();
String blobURL = DOMURL::createObjectURL(document, blob);
Modified: trunk/Source/WebCore/editing/markup.cpp (222838 => 222839)
--- trunk/Source/WebCore/editing/markup.cpp 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/editing/markup.cpp 2017-10-04 11:06:15 UTC (rev 222839)
@@ -116,6 +116,25 @@
for (auto& change : changes)
change.apply();
}
+
+void replaceSubresourceURLs(Ref<DocumentFragment>&& fragment, HashMap<AtomicString, AtomicString>&& replacementMap)
+{
+ Vector<AttributeChange> changes;
+ for (auto& element : descendantsOfType<Element>(fragment)) {
+ if (!element.hasAttributes())
+ continue;
+ for (const Attribute& attribute : element.attributesIterator()) {
+ // FIXME: This won't work for srcset.
+ if (element.attributeContainsURL(attribute) && !attribute.value().isEmpty()) {
+ auto replacement = replacementMap.get(attribute.value());
+ if (!replacement.isNull())
+ changes.append({ &element, attribute.name(), replacement });
+ }
+ }
+ }
+ for (auto& change : changes)
+ change.apply();
+}
class StyledMarkupAccumulator final : public MarkupAccumulator {
public:
Modified: trunk/Source/WebCore/editing/markup.h (222838 => 222839)
--- trunk/Source/WebCore/editing/markup.h 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/editing/markup.h 2017-10-04 11:06:15 UTC (rev 222839)
@@ -29,6 +29,7 @@
#include "FragmentScriptingPermission.h"
#include "HTMLInterchange.h"
#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
namespace WebCore {
@@ -44,6 +45,8 @@
class QualifiedName;
class Range;
+void replaceSubresourceURLs(Ref<DocumentFragment>&&, HashMap<AtomicString, AtomicString>&&);
+
enum EChildrenOnly { IncludeNode, ChildrenOnly };
enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
enum EFragmentSerialization { HTMLFragmentSerialization, XMLFragmentSerialization };
Modified: trunk/Source/WebCore/fileapi/Blob.cpp (222838 => 222839)
--- trunk/Source/WebCore/fileapi/Blob.cpp 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/fileapi/Blob.cpp 2017-10-04 11:06:15 UTC (rev 222839)
@@ -36,6 +36,7 @@
#include "BlobURL.h"
#include "File.h"
#include "ScriptExecutionContext.h"
+#include "SharedBuffer.h"
#include "ThreadableBlobRegistry.h"
#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
@@ -96,6 +97,19 @@
ThreadableBlobRegistry::registerBlobURL(m_internalURL, builder.finalize(), m_type);
}
+Blob::Blob(const SharedBuffer& buffer, const String& contentType)
+ : m_type(contentType)
+ , m_size(buffer.size())
+{
+ Vector<uint8_t> data;
+ data.append(buffer.data(), buffer.size());
+
+ Vector<BlobPart> blobParts;
+ blobParts.append(BlobPart(WTFMove(data)));
+ m_internalURL = BlobURL::createInternalURL();
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType);
+}
+
Blob::Blob(Vector<uint8_t>&& data, const String& contentType)
: m_type(contentType)
, m_size(data.size())
Modified: trunk/Source/WebCore/fileapi/Blob.h (222838 => 222839)
--- trunk/Source/WebCore/fileapi/Blob.h 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebCore/fileapi/Blob.h 2017-10-04 11:06:15 UTC (rev 222839)
@@ -45,6 +45,7 @@
class Blob;
class ScriptExecutionContext;
+class SharedBuffer;
using BlobPartVariant = Variant<RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<Blob>, String>;
@@ -60,6 +61,11 @@
return adoptRef(*new Blob(WTFMove(blobPartVariants), propertyBag));
}
+ static Ref<Blob> create(const SharedBuffer& buffer, const String& contentType)
+ {
+ return adoptRef(*new Blob(buffer, contentType));
+ }
+
static Ref<Blob> create(Vector<uint8_t>&& data, const String& contentType)
{
return adoptRef(*new Blob(WTFMove(data), contentType));
@@ -99,6 +105,7 @@
protected:
Blob();
Blob(Vector<BlobPartVariant>&&, const BlobPropertyBag&);
+ Blob(const SharedBuffer&, const String& contentType);
Blob(Vector<uint8_t>&&, const String& contentType);
enum ReferencingExistingBlobConstructor { referencingExistingBlobConstructor };
Modified: trunk/Source/WebKit/ChangeLog (222838 => 222839)
--- trunk/Source/WebKit/ChangeLog 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebKit/ChangeLog 2017-10-04 11:06:15 UTC (rev 222839)
@@ -1,3 +1,16 @@
+2017-10-04 Ryosuke Niwa <[email protected]>
+
+ Use blob URL when pasting RTFD instead of overriding DocumentLoader
+ https://bugs.webkit.org/show_bug.cgi?id=177801
+ <rdar://problem/34542270>
+
+ Reviewed by Wenson Hsieh.
+
+ Fixed the assertion failure when RTFD content is empty.
+
+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+ (WebKit::WebPasteboardProxy::getPasteboardBufferForType):
+
2017-10-04 Michael Catanzaro <[email protected]>
REGRESSION(r222392): [WPE][GTK] Many forms tests are failing due to broken event timestamps
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm (222838 => 222839)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-10-04 11:06:15 UTC (rev 222839)
@@ -75,6 +75,8 @@
if (!buffer)
return;
size = buffer->size();
+ if (!size)
+ return;
RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(size);
if (!sharedMemoryBuffer)
return;
Modified: trunk/Tools/ChangeLog (222838 => 222839)
--- trunk/Tools/ChangeLog 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Tools/ChangeLog 2017-10-04 11:06:15 UTC (rev 222839)
@@ -1,3 +1,19 @@
+2017-10-04 Ryosuke Niwa <[email protected]>
+
+ Use blob URL when pasting RTFD instead of overriding DocumentLoader
+ https://bugs.webkit.org/show_bug.cgi?id=177801
+ <rdar://problem/34542270>
+
+ Reviewed by Wenson Hsieh.
+
+ Added a regression test for an assertion failure when pasting an empty RTFD as well as a test for pasting
+ RTFD with an image, which should result in an image element with a blob URL.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/PasteRTFD.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/paste-rtfd.html:
+
2017-10-03 Gustavo Noronha Silva <[email protected]>
[GLib] Let WebCore know of low power situations
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (222838 => 222839)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-10-04 11:06:15 UTC (rev 222839)
@@ -545,6 +545,7 @@
9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; };
9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */; };
9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
+ 9B7D740F1F8378770006C432 /* paste-rtfd.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B7D740E1F8377E60006C432 /* paste-rtfd.html */; };
9BD4239A1E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */; };
9BD4239C1E04C01C00200395 /* chinese-character-with-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */; };
9BD6D3A21F7B218300BD4962 /* sunset-in-cupertino-100px.tiff in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D3A11F7B202100BD4962 /* sunset-in-cupertino-100px.tiff */; };
@@ -553,6 +554,7 @@
9BD6D3A51F7B218300BD4962 /* sunset-in-cupertino-600px.jpg in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D39E1F7B201E00BD4962 /* sunset-in-cupertino-600px.jpg */; };
9BD6D3A71F7B21DC00BD4962 /* paste-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D3A61F7B21CC00BD4962 /* paste-image.html */; };
9BDCCD871F7D0B0700009A18 /* PasteImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDCCD851F7D0B0700009A18 /* PasteImage.mm */; };
+ 9BDD95581F83683600D20C60 /* PasteRTFD.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDD95561F83683600D20C60 /* PasteRTFD.mm */; };
9C64DC321D76198A004B598E /* YouTubePluginReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C64DC311D76198A004B598E /* YouTubePluginReplacement.cpp */; };
A10F047E1E3AD29C00C95E19 /* NSFileManagerExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = A10F047C1E3AD29C00C95E19 /* NSFileManagerExtras.mm */; };
A1146A8D1D2D7115000FE710 /* ContentFiltering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */; };
@@ -978,6 +980,7 @@
A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */,
A1409AD91E7254D4004949D9 /* password-protected.pages in Copy Resources */,
9BD6D3A71F7B21DC00BD4962 /* paste-image.html in Copy Resources */,
+ 9B7D740F1F8378770006C432 /* paste-rtfd.html in Copy Resources */,
3FCC4FE81EC4E8CA0076E37C /* PictureInPictureDelegate.html in Copy Resources */,
F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */,
F41AB9A81EF4696B0083FA08 /* prevent-operation.html in Copy Resources */,
@@ -1507,6 +1510,7 @@
9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; };
9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; };
9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
+ 9B7D740E1F8377E60006C432 /* paste-rtfd.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-rtfd.html"; sourceTree = "<group>"; };
9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedSubstringForProposedRangeWithImage.mm; sourceTree = "<group>"; };
9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "chinese-character-with-image.html"; sourceTree = "<group>"; };
9BD6D39E1F7B201E00BD4962 /* sunset-in-cupertino-600px.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "sunset-in-cupertino-600px.jpg"; sourceTree = "<group>"; };
@@ -1515,6 +1519,7 @@
9BD6D3A11F7B202100BD4962 /* sunset-in-cupertino-100px.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "sunset-in-cupertino-100px.tiff"; sourceTree = "<group>"; };
9BD6D3A61F7B21CC00BD4962 /* paste-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-image.html"; sourceTree = "<group>"; };
9BDCCD851F7D0B0700009A18 /* PasteImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteImage.mm; sourceTree = "<group>"; };
+ 9BDD95561F83683600D20C60 /* PasteRTFD.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteRTFD.mm; sourceTree = "<group>"; };
9C64DC311D76198A004B598E /* YouTubePluginReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YouTubePluginReplacement.cpp; sourceTree = "<group>"; };
A10F047C1E3AD29C00C95E19 /* NSFileManagerExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NSFileManagerExtras.mm; sourceTree = "<group>"; };
A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentFiltering.mm; sourceTree = "<group>"; };
@@ -2014,6 +2019,7 @@
CEA6CF2219CCF5BD0064F5A7 /* OpenAndCloseWindow.mm */,
CEBCA12E1E3A660100C73293 /* OverrideContentSecurityPolicy.mm */,
9BDCCD851F7D0B0700009A18 /* PasteImage.mm */,
+ 9BDD95561F83683600D20C60 /* PasteRTFD.mm */,
3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
@@ -2308,6 +2314,7 @@
CEBCA1371E3A803400C73293 /* page-without-csp.html */,
A1409AD81E7254AC004949D9 /* password-protected.pages */,
9BD6D3A61F7B21CC00BD4962 /* paste-image.html */,
+ 9B7D740E1F8377E60006C432 /* paste-rtfd.html */,
3FCC4FE61EC4E87E0076E37C /* PictureInPictureDelegate.html */,
F415086C1DA040C10044BE9B /* play-audio-on-click.html */,
F41AB9941EF4692C0083FA08 /* prevent-operation.html */,
@@ -3374,6 +3381,7 @@
7C83E0511D0A641800FEBCF3 /* ParsedContentRange.cpp in Sources */,
7CCE7F0A1A411AE600447C4C /* PasteboardNotifications.mm in Sources */,
9BDCCD871F7D0B0700009A18 /* PasteImage.mm in Sources */,
+ 9BDD95581F83683600D20C60 /* PasteRTFD.mm in Sources */,
7C83E0531D0A643A00FEBCF3 /* PendingAPIRequestURL.cpp in Sources */,
3FCC4FE51EC4E8520076E37C /* PictureInPictureDelegate.mm in Sources */,
7CCE7EAF1A411A3800447C4C /* PlatformUtilities.cpp in Sources */,
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm (222838 => 222839)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm 2017-10-04 10:03:20 UTC (rev 222838)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm 2017-10-04 11:06:15 UTC (rev 222839)
@@ -27,10 +27,8 @@
#if WK_API_ENABLED && PLATFORM(COCOA)
-#import "AppKitSPI.h"
#import "PlatformUtilities.h"
#import "TestWKWebView.h"
-#import <wtf/BlockPtr.h>
#import <wtf/RetainPtr.h>
#import <wtf/text/WTFString.h>
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteRTFD.mm (0 => 222839)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteRTFD.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteRTFD.mm 2017-10-04 11:06:15 UTC (rev 222839)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if WK_API_ENABLED && PLATFORM(COCOA)
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <wtf/RetainPtr.h>
+#import <wtf/text/WTFString.h>
+
+#if PLATFORM(IOS)
+#include <MobileCoreServices/MobileCoreServices.h>
+#endif
+
+@interface WKWebView ()
+- (void)paste:(id)sender;
+@end
+
+#if PLATFORM(MAC)
+void writeRTFDToPasteboard(NSData *data)
+{
+ [[NSPasteboard generalPasteboard] declareTypes:@[NSRTFDPboardType] owner:nil];
+ [[NSPasteboard generalPasteboard] setData:data forType:NSRTFDPboardType];
+}
+#else
+
+@interface NSAttributedString ()
+- (id)initWithRTF:(NSData *)data documentAttributes:(NSDictionary **)dict;
+- (id)initWithRTFD:(NSData *)data documentAttributes:(NSDictionary **)dict;
+- (NSData *)RTFFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
+- (NSData *)RTFDFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
+- (BOOL)containsAttachments;
+@end
+
+void writeRTFDToPasteboard(NSData *data)
+{
+ [[UIPasteboard generalPasteboard] setItems:@[@{ (NSString *)kUTTypeFlatRTFD : data}]];
+}
+#endif
+
+TEST(PasteRTFD, EmptyRTFD)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html><html><body><div id='editor' contenteditable></div></body></html>"];
+
+ writeRTFDToPasteboard([NSData data]);
+ [webView stringByEvaluatingJavaScript:@"document.getElementById('editor').focus()"];
+ [webView paste:nil];
+}
+
+TEST(PasteRTFD, ImageElementsUseBlobURL)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ auto *pngData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-200px" ofType:@"png" inDirectory:@"TestWebKitAPI.resources"]];
+ auto attachment = adoptNS([[NSTextAttachment alloc] initWithData:pngData ofType:(NSString *)kUTTypePNG]);
+ NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attachment.get()];
+ NSData *RTFDData = [string RTFDFromRange:NSMakeRange(0, [string length]) documentAttributes:@{ }];
+
+ writeRTFDToPasteboard(RTFDData);
+ [webView paste:nil];
+
+ [webView waitForMessage:@"loaded"];
+ EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"imageElement = document.querySelector('img'); imageElement.width"]);
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src).protocol"]);
+}
+
+#endif // WK_API_ENABLED && PLATFORM(MAC)
+
+
+
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-rtfd.html (0 => 222839)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-rtfd.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-rtfd.html 2017-10-04 11:06:15 UTC (rev 222839)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="editor" contenteditable></div>
+<script>
+const editor = document.getElementById('editor');
+editor.focus();
+
+editor.addEventListener('paste', (event) => {
+ setTimeout(() => {
+ let img = document.querySelector('img');
+ if (img.complete)
+ notifyLoaded();
+ else
+ img._onload_ = notifyLoaded;
+ }, 0);
+});
+
+function notifyLoaded()
+{
+ webkit.messageHandlers.testHandler.postMessage('loaded');
+}
+
+</script>
+</body>
+</html>