Diff
Modified: trunk/Source/WebCore/ChangeLog (227067 => 227068)
--- trunk/Source/WebCore/ChangeLog 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/ChangeLog 2018-01-17 17:07:43 UTC (rev 227068)
@@ -1,3 +1,47 @@
+2018-01-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add injected bundle SPI to replace subresource URLs when dropping or pasting rich content
+ https://bugs.webkit.org/show_bug.cgi?id=181637
+ <rdar://problem/36508471>
+
+ Reviewed by Tim Horton.
+
+ Before carrying out blob URL conversion for pasted or dropped rich content, let the editor client replace
+ subresource URLs in WebKit2 by calling out to new injected bundle SPI. See comments below for more detail.
+
+ Tests: WKAttachmentTests.InjectedBundleReplaceURLsWhenPastingAttributedString
+ WKAttachmentTests.InjectedBundleReplaceURLWhenPastingImage
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::clientReplacementURLForResource):
+ * editing/Editor.h:
+
+ Add a new helper to call out to the editor client for a URL string to replace a given ArchiveResource. In
+ WebKit2, this calls out to the injected bundle's new `replacementURLForResource` SPI hook.
+
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::shouldReplaceSubresourceURL):
+ (WebCore::replaceRichContentWithAttachments):
+ (WebCore::replaceSubresourceURLsWithURLsFromClient):
+
+ Add a new static helper to replace subresource URLs in the given DocumentFragment with URLs supplied by the
+ editor client. Additionally builds a list of ArchiveResources that have not been replaced, for use at call sites
+ so that we don't unnecessarily create more Blobs for ArchiveResources that have already been replaced.
+
+ (WebCore::createFragmentAndAddResources):
+ (WebCore::sanitizeMarkupWithArchive):
+
+ Tweak web content reading codepaths to first replace subresource URLs with editor-client-supplied URLs.
+
+ (WebCore::WebContentReader::readImage):
+ (WebCore::shouldConvertToBlob): Deleted.
+
+ Rename this helper to shouldReplaceSubresourceURL, blob URL replacement is no longer the only scenario in which
+ we replace resource URLs, but in both cases, we still want to ignore `http:`-family and `data:` URLs.
+
+ * loader/EmptyClients.cpp:
+ * page/EditorClient.h:
+
2018-01-17 Yacine Bandou <yacine.bandou_...@softathome.com>
[EME][GStreamer] Add the full-sample encryption support in the GStreamer ClearKey decryptor
https://bugs.webkit.org/show_bug.cgi?id=180080
Modified: trunk/Source/WebCore/editing/Editor.cpp (227067 => 227068)
--- trunk/Source/WebCore/editing/Editor.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/editing/Editor.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -3961,4 +3961,12 @@
return font;
}
+String Editor::clientReplacementURLForResource(Ref<SharedBuffer>&& resourceData, const String& mimeType)
+{
+ if (auto* editorClient = client())
+ return editorClient->replacementURLForResource(WTFMove(resourceData), mimeType);
+
+ return { };
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/Editor.h (227067 => 227068)
--- trunk/Source/WebCore/editing/Editor.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/editing/Editor.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -484,6 +484,8 @@
WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
#endif
+ String clientReplacementURLForResource(Ref<SharedBuffer>&& resourceData, const String& mimeType);
+
#if !PLATFORM(WIN)
WEBCORE_EXPORT void writeSelectionToPasteboard(Pasteboard&);
WEBCORE_EXPORT void writeImageToPasteboard(Pasteboard&, Element& imageElement, const URL&, const String& title);
Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (227067 => 227068)
--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-01-17 17:07:43 UTC (rev 227068)
@@ -175,7 +175,7 @@
};
-static bool shouldConvertToBlob(const URL& url)
+static bool shouldReplaceSubresourceURL(const URL& url)
{
return !(url.protocolIsInHTTPFamily() || url.protocolIsData());
}
@@ -223,7 +223,7 @@
HashMap<AtomicString, Ref<Blob>> urlToBlobMap;
for (const Ref<ArchiveResource>& subresource : subresources) {
auto& url = ""
- if (shouldConvertToBlob(url))
+ if (shouldReplaceSubresourceURL(url))
urlToBlobMap.set(url.string(), Blob::create(subresource->data(), subresource->mimeType()));
}
@@ -286,7 +286,31 @@
#endif
}
+static void replaceSubresourceURLsWithURLsFromClient(DocumentFragment& fragment, const Vector<Ref<ArchiveResource>>& subresources, Vector<Ref<ArchiveResource>>& outUnreplacedResources)
+{
+ ASSERT(fragment.document().frame());
+ auto& frame = *fragment.document().frame();
+ HashMap<AtomicString, AtomicString> subresourceURLToClientURLMap;
+ for (auto& subresource : subresources) {
+ auto& originalURL = subresource->url();
+ if (!shouldReplaceSubresourceURL(originalURL)) {
+ outUnreplacedResources.append(subresource.copyRef());
+ continue;
+ }
+ auto replacementURL = frame.editor().clientReplacementURLForResource(subresource->data(), subresource->mimeType());
+ if (replacementURL.isEmpty()) {
+ outUnreplacedResources.append(subresource.copyRef());
+ continue;
+ }
+
+ subresourceURLToClientURLMap.set(originalURL.string(), replacementURL);
+ }
+
+ if (!subresourceURLToClientURLMap.isEmpty())
+ replaceSubresourceURLs(fragment, WTFMove(subresourceURLToClientURLMap));
+}
+
RefPtr<DocumentFragment> createFragmentAndAddResources(Frame& frame, NSAttributedString *string)
{
if (!frame.page() || !frame.document())
@@ -309,13 +333,16 @@
return WTFMove(fragmentAndResources.fragment);
}
+ Vector<Ref<ArchiveResource>> unreplacedResources;
+ replaceSubresourceURLsWithURLsFromClient(*fragmentAndResources.fragment, fragmentAndResources.resources, unreplacedResources);
+
if (shouldReplaceRichContentWithAttachments()) {
- replaceRichContentWithAttachments(*fragmentAndResources.fragment, fragmentAndResources.resources);
+ replaceRichContentWithAttachments(*fragmentAndResources.fragment, unreplacedResources);
return WTFMove(fragmentAndResources.fragment);
}
HashMap<AtomicString, AtomicString> blobURLMap;
- for (const Ref<ArchiveResource>& subresource : fragmentAndResources.resources) {
+ for (const Ref<ArchiveResource>& subresource : unreplacedResources) {
auto blob = Blob::create(subresource->data(), subresource->mimeType());
String blobURL = DOMURL::createObjectURL(document, blob);
blobURLMap.set(subresource->url().string(), blobURL);
@@ -366,15 +393,18 @@
ASSERT(stagingDocument);
auto fragment = createFragmentFromMarkup(*stagingDocument, markupAndArchive.markup, markupAndArchive.mainResource->url(), DisallowScriptingAndPluginContent);
+ Vector<Ref<ArchiveResource>> unreplacedResources;
+ replaceSubresourceURLsWithURLsFromClient(fragment, markupAndArchive.archive->subresources(), unreplacedResources);
+
if (shouldReplaceRichContentWithAttachments()) {
- replaceRichContentWithAttachments(fragment, markupAndArchive.archive->subresources());
+ replaceRichContentWithAttachments(fragment, unreplacedResources);
return markupForFragmentInDocument(WTFMove(fragment), *stagingDocument);
}
HashMap<AtomicString, AtomicString> blobURLMap;
- for (const Ref<ArchiveResource>& subresource : markupAndArchive.archive->subresources()) {
+ for (const Ref<ArchiveResource>& subresource : unreplacedResources) {
auto& subresourceURL = subresource->url();
- if (!shouldConvertToBlob(subresourceURL))
+ if (!shouldReplaceSubresourceURL(subresourceURL))
continue;
auto blob = Blob::create(subresource->data(), subresource->mimeType());
String blobURL = DOMURL::createObjectURL(destinationDocument, blob);
@@ -392,7 +422,7 @@
continue;
auto subframeURL = subframeMainResource->url();
- if (!shouldConvertToBlob(subframeURL))
+ if (!shouldReplaceSubresourceURL(subframeURL))
continue;
MarkupAndArchive subframeContent = { String::fromUTF8(subframeMainResource->data().data(), subframeMainResource->data().size()),
@@ -581,10 +611,16 @@
bool WebContentReader::readImage(Ref<SharedBuffer>&& buffer, const String& type)
{
- auto blob = Blob::create(buffer.get(), type);
ASSERT(frame.document());
auto& document = *frame.document();
+ auto replacementURL = frame.editor().clientReplacementURLForResource(buffer.copyRef(), type);
+ if (!replacementURL.isEmpty()) {
+ addFragment(createFragmentForImageAndURL(document, replacementURL));
+ return true;
+ }
+
+ auto blob = Blob::create(buffer.get(), type);
if (shouldReplaceRichContentWithAttachments())
addFragment(createFragmentForImageAttachment(document, WTFMove(blob)));
else
Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (227067 => 227068)
--- trunk/Source/WebCore/loader/EmptyClients.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -176,6 +176,7 @@
void willWriteSelectionToPasteboard(Range*) final { }
void didWriteSelectionToPasteboard() final { }
void getClientPasteboardDataForRange(Range*, Vector<String>&, Vector<RefPtr<SharedBuffer>>&) final { }
+ String replacementURLForResource(Ref<SharedBuffer>&&, const String&) final { return { }; }
void requestCandidatesForSelection(const VisibleSelection&) final { }
void handleAcceptedCandidateWithSoftSpaces(TextCheckingResult) final { }
Modified: trunk/Source/WebCore/page/EditorClient.h (227067 => 227068)
--- trunk/Source/WebCore/page/EditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebCore/page/EditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -86,6 +86,7 @@
virtual void willWriteSelectionToPasteboard(Range*) = 0;
virtual void didWriteSelectionToPasteboard() = 0;
virtual void getClientPasteboardDataForRange(Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<SharedBuffer>>& pasteboardData) = 0;
+ virtual String replacementURLForResource(Ref<SharedBuffer>&& resourceData, const String& mimeType) = 0;
virtual void requestCandidatesForSelection(const VisibleSelection&) { }
virtual void handleAcceptedCandidateWithSoftSpaces(TextCheckingResult) { }
Modified: trunk/Source/WebKit/ChangeLog (227067 => 227068)
--- trunk/Source/WebKit/ChangeLog 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/ChangeLog 2018-01-17 17:07:43 UTC (rev 227068)
@@ -1,3 +1,30 @@
+2018-01-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add injected bundle SPI to replace subresource URLs when dropping or pasting rich content
+ https://bugs.webkit.org/show_bug.cgi?id=181637
+ <rdar://problem/36508471>
+
+ Reviewed by Tim Horton.
+
+ Add new injected bundle SPI, replacementURLForResource, which clients may use to provide a replacement URL to
+ represent an archive resource, given the resource's data and MIME type.
+
+ * WebProcess/InjectedBundle/API/APIInjectedBundleEditorClient.h:
+ (API::InjectedBundle::EditorClient::replacementURLForResource):
+ * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInEditingDelegate.h:
+ * WebProcess/InjectedBundle/API/c/WKBundlePageEditorClient.h:
+
+ Add replacementURLForResource, and also bump the current injected bundle editor client version to 2.
+
+ * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
+ (-[WKWebProcessPlugInBrowserContextController _setEditingDelegate:]):
+ * WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp:
+ (WebKit::InjectedBundlePageEditorClient::replacementURLForResource):
+ * WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h:
+ * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+ (WebKit::WebEditorClient::replacementURLForResource):
+ * WebProcess/WebCoreSupport/WebEditorClient.h:
+
2018-01-17 Zan Dobersek <zdober...@igalia.com>
[Cairo] Don't mirror global alpha and image interpolation quality state values in PlatformContextCairo
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/APIInjectedBundleEditorClient.h (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/APIInjectedBundleEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/APIInjectedBundleEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -28,6 +28,7 @@
#include <WebCore/EditorInsertAction.h>
#include <WebCore/TextAffinity.h>
#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
class CSSStyleDeclaration;
@@ -64,6 +65,7 @@
virtual void getPasteboardDataForRange(WebKit::WebPage&, WebCore::Range*, Vector<WTF::String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) { }
virtual void didWriteToPasteboard(WebKit::WebPage&) { }
virtual bool performTwoStepDrop(WebKit::WebPage&, WebCore::DocumentFragment&, WebCore::Range&, bool) { return false; }
+ virtual WTF::String replacementURLForResource(WebKit::WebPage&, Ref<WebCore::SharedBuffer>&&, const WTF::String&) { return { }; }
};
} // namespace InjectedBundle
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInEditingDelegate.h (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInEditingDelegate.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInEditingDelegate.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -61,6 +61,7 @@
- (NSDictionary<NSString *, NSData *> *)_webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller pasteboardDataForRange:(WKWebProcessPlugInRangeHandle *)range;
- (void)_webProcessPlugInBrowserContextControllerDidWriteToPasteboard:(WKWebProcessPlugInBrowserContextController *)controller;
- (BOOL)_webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller performTwoStepDrop:(WKWebProcessPlugInNodeHandle *)fragment atDestination:(WKWebProcessPlugInRangeHandle *)destination isMove:(BOOL)isMove WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (NSString *)_webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller replacementURLForResource:(NSData *)resourceData mimeType:(NSString *)mimeType WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
@end
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePageEditorClient.h (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePageEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePageEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -62,6 +62,7 @@
typedef void (*WKBundlePageEditingNotification)(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo);
typedef void (*WKBundlePageWillWriteToPasteboard)(WKBundlePageRef page, WKBundleRangeHandleRef range, const void* clientInfo);
typedef void (*WKBundlePageGetPasteboardDataForRange)(WKBundlePageRef page, WKBundleRangeHandleRef range, WKArrayRef* pasteboardTypes, WKArrayRef* pasteboardData, const void* clientInfo);
+typedef WKStringRef (*WKBundlePageReplacementURLForResource)(WKBundlePageRef, WKDataRef resourceData, WKStringRef mimeType, const void* clientInfo);
typedef void (*WKBundlePageDidWriteToPasteboard)(WKBundlePageRef page, const void* clientInfo);
typedef bool (*WKBundlePagePerformTwoStepDrop)(WKBundlePageRef page, WKBundleNodeHandleRef fragment, WKBundleRangeHandleRef destination, bool isMove, const void* clientInfo);
@@ -110,4 +111,30 @@
WKBundlePagePerformTwoStepDrop performTwoStepDrop;
} WKBundlePageEditorClientV1;
+typedef struct WKBundlePageEditorClientV2 {
+ WKBundlePageEditorClientBase base;
+
+ // Version 0.
+ WKBundlePageShouldBeginEditingCallback shouldBeginEditing;
+ WKBundlePageShouldEndEditingCallback shouldEndEditing;
+ WKBundlePageShouldInsertNodeCallback shouldInsertNode;
+ WKBundlePageShouldInsertTextCallback shouldInsertText;
+ WKBundlePageShouldDeleteRangeCallback shouldDeleteRange;
+ WKBundlePageShouldChangeSelectedRange shouldChangeSelectedRange;
+ WKBundlePageShouldApplyStyle shouldApplyStyle;
+ WKBundlePageEditingNotification didBeginEditing;
+ WKBundlePageEditingNotification didEndEditing;
+ WKBundlePageEditingNotification didChange;
+ WKBundlePageEditingNotification didChangeSelection;
+
+ // Version 1.
+ WKBundlePageWillWriteToPasteboard willWriteToPasteboard;
+ WKBundlePageGetPasteboardDataForRange getPasteboardDataForRange;
+ WKBundlePageDidWriteToPasteboard didWriteToPasteboard;
+ WKBundlePagePerformTwoStepDrop performTwoStepDrop;
+
+ // Version 2.
+ WKBundlePageReplacementURLForResource replacementURLForResource;
+} WKBundlePageEditorClientV2;
+
#endif // WKBundlePageEditorClient_h
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm 2018-01-17 17:07:43 UTC (rev 227068)
@@ -678,6 +678,16 @@
return [m_controller->_editingDelegate.get() _webProcessPlugInBrowserContextController:m_controller performTwoStepDrop:wrapper(*nodeHandle) atDestination:wrapper(*rangeHandle) isMove:isMove];
}
+ WTF::String replacementURLForResource(WebKit::WebPage&, Ref<WebCore::SharedBuffer>&& resourceData, const WTF::String& mimeType)
+ {
+ if (!m_delegateMethods.replacementURLForResource)
+ return { };
+
+ NSString *type = (NSString *)mimeType;
+ auto data = ""
+ return [m_controller->_editingDelegate.get() _webProcessPlugInBrowserContextController:m_controller replacementURLForResource:data.get() mimeType:type];
+ }
+
WKWebProcessPlugInBrowserContextController *m_controller;
const struct DelegateMethods {
DelegateMethods(RetainPtr<id <WKWebProcessPlugInEditingDelegate>> delegate)
@@ -688,6 +698,7 @@
, getPasteboardDataForRange([delegate respondsToSelector:@selector(_webProcessPlugInBrowserContextController:pasteboardDataForRange:)])
, didWriteToPasteboard([delegate respondsToSelector:@selector(_webProcessPlugInBrowserContextControllerDidWriteToPasteboard:)])
, performTwoStepDrop([delegate respondsToSelector:@selector(_webProcessPlugInBrowserContextController:performTwoStepDrop:atDestination:isMove:)])
+ , replacementURLForResource([delegate respondsToSelector:@selector(_webProcessPlugInBrowserContextController:replacementURLForResource:mimeType:)])
{
}
@@ -698,6 +709,7 @@
bool getPasteboardDataForRange;
bool didWriteToPasteboard;
bool performTwoStepDrop;
+ bool replacementURLForResource;
} m_delegateMethods;
};
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -33,6 +33,8 @@
#include "InjectedBundleRangeHandle.h"
#include "WKAPICast.h"
#include "WKBundleAPICast.h"
+#include "WKData.h"
+#include "WKRetainPtr.h"
#include "WKString.h"
#include "WebPage.h"
#include <WebCore/DocumentFragment.h>
@@ -189,4 +191,14 @@
m_client.didWriteToPasteboard(toAPI(&page), m_client.base.clientInfo);
}
+String InjectedBundlePageEditorClient::replacementURLForResource(WebPage& page, Ref<SharedBuffer>&& resourceData, const String& mimeType)
+{
+ if (!m_client.replacementURLForResource)
+ return { };
+
+ auto data = "" unsigned char*>(resourceData->data()), resourceData->size()));
+ auto type = adoptWK(toCopiedAPI(mimeType));
+ return toWTFString(m_client.replacementURLForResource(toAPI(&page), data.get(), type.get(), m_client.base.clientInfo));
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -31,7 +31,7 @@
namespace API {
template<> struct ClientTraits<WKBundlePageEditorClientBase> {
- typedef std::tuple<WKBundlePageEditorClientV0, WKBundlePageEditorClientV1> Versions;
+ typedef std::tuple<WKBundlePageEditorClientV0, WKBundlePageEditorClientV1, WKBundlePageEditorClientV2> Versions;
};
}
@@ -67,6 +67,7 @@
void getPasteboardDataForRange(WebPage&, WebCore::Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) final;
void didWriteToPasteboard(WebPage&) final;
bool performTwoStepDrop(WebPage&, WebCore::DocumentFragment&, WebCore::Range& destination, bool isMove) final;
+ String replacementURLForResource(WebPage&, Ref<WebCore::SharedBuffer>&& resourceData, const String&) final;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -263,6 +263,11 @@
return m_page->injectedBundleEditorClient().performTwoStepDrop(*m_page, fragment, destination, isMove);
}
+String WebEditorClient::replacementURLForResource(Ref<WebCore::SharedBuffer>&& resourceData, const String& mimeType)
+{
+ return m_page->injectedBundleEditorClient().replacementURLForResource(*m_page, WTFMove(resourceData), mimeType);
+}
+
void WebEditorClient::registerUndoStep(UndoStep& step)
{
// FIXME: Add assertion that the command being reapplied is the same command that is
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h (227067 => 227068)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -76,6 +76,7 @@
void willWriteSelectionToPasteboard(WebCore::Range*) final;
void didWriteSelectionToPasteboard() final;
void getClientPasteboardDataForRange(WebCore::Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) final;
+ String replacementURLForResource(Ref<WebCore::SharedBuffer>&& resourceData, const String& mimeType) final;
void registerUndoStep(WebCore::UndoStep&) final;
void registerRedoStep(WebCore::UndoStep&) final;
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (227067 => 227068)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2018-01-17 17:07:43 UTC (rev 227068)
@@ -1,3 +1,17 @@
+2018-01-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add injected bundle SPI to replace subresource URLs when dropping or pasting rich content
+ https://bugs.webkit.org/show_bug.cgi?id=181637
+ <rdar://problem/36508471>
+
+ Reviewed by Tim Horton.
+
+ Add a stub implementation of replacementURLForResource. See WebCore and WebKit ChangeLogs for more detail.
+
+ * WebCoreSupport/WebEditorClient.h:
+ * WebCoreSupport/WebEditorClient.mm:
+ (WebEditorClient::replacementURLForResource):
+
2018-01-11 Keith Miller <keith_mil...@apple.com>
Rename ENABLE_ASYNC_ITERATION to ENABLE_JS_ASYNC_ITERATION
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h (227067 => 227068)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -78,6 +78,7 @@
void willWriteSelectionToPasteboard(WebCore::Range*) final;
void didWriteSelectionToPasteboard() final;
void getClientPasteboardDataForRange(WebCore::Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) final;
+ String replacementURLForResource(Ref<WebCore::SharedBuffer>&& resourceData, const String& mimeType) final;
void setInsertionPasteboard(const String&) final;
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm (227067 => 227068)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2018-01-17 17:07:43 UTC (rev 227068)
@@ -419,6 +419,12 @@
// Not implemented WebKit, only WebKit2.
}
+String WebEditorClient::replacementURLForResource(Ref<SharedBuffer>&&, const String&)
+{
+ // Not implemented in WebKitLegacy.
+ return { };
+}
+
#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300)
// FIXME: Remove both this stub and the real version of this function below once we don't need the real version on any supported platform.
Modified: trunk/Source/WebKitLegacy/win/ChangeLog (227067 => 227068)
--- trunk/Source/WebKitLegacy/win/ChangeLog 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/win/ChangeLog 2018-01-17 17:07:43 UTC (rev 227068)
@@ -1,3 +1,17 @@
+2018-01-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add injected bundle SPI to replace subresource URLs when dropping or pasting rich content
+ https://bugs.webkit.org/show_bug.cgi?id=181637
+ <rdar://problem/36508471>
+
+ Reviewed by Tim Horton.
+
+ Add a stub implementation of replacementURLForResource. See WebCore and WebKit ChangeLogs for more detail.
+
+ * WebCoreSupport/WebEditorClient.cpp:
+ (WebEditorClient::replacementURLForResource):
+ * WebCoreSupport/WebEditorClient.h:
+
2017-12-28 Yusuke Suzuki <utatane....@gmail.com>
Remove std::chrono completely
Modified: trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.cpp (227067 => 227068)
--- trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -269,6 +269,12 @@
notImplemented();
}
+String WebEditorClient::replacementURLForResource(Ref<WebCore::SharedBuffer>&&, const String&)
+{
+ notImplemented();
+ return { };
+}
+
bool WebEditorClient::shouldDeleteRange(Range* range)
{
COMPtr<IWebEditingDelegate> ed;
Modified: trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h (227067 => 227068)
--- trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h 2018-01-17 17:07:43 UTC (rev 227068)
@@ -54,6 +54,7 @@
void willWriteSelectionToPasteboard(WebCore::Range*) final;
void didWriteSelectionToPasteboard() final;
void getClientPasteboardDataForRange(WebCore::Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) final;
+ String replacementURLForResource(Ref<WebCore::SharedBuffer>&&, const String&) final;
void didEndUserTriggeredSelectionChanges() final { }
void respondToChangedContents() final;
Modified: trunk/Tools/ChangeLog (227067 => 227068)
--- trunk/Tools/ChangeLog 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Tools/ChangeLog 2018-01-17 17:07:43 UTC (rev 227068)
@@ -1,3 +1,34 @@
+2018-01-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add injected bundle SPI to replace subresource URLs when dropping or pasting rich content
+ https://bugs.webkit.org/show_bug.cgi?id=181637
+ <rdar://problem/36508471>
+
+ Reviewed by Tim Horton.
+
+ Add 2 new API tests to exercise injected bundle SPI for supplying replacement URLs when pasting an image, and an
+ attributed string containing multiple NSTextAttachments. See WebKit and WebCore ChangeLogs for more detail.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/BundleEditingDelegatePlugIn.mm:
+ (-[BundleEditingDelegatePlugIn webProcessPlugIn:didCreateBrowserContextController:]):
+ (-[BundleEditingDelegatePlugIn _webProcessPlugInBrowserContextController:replacementURLForResource:mimeType:]):
+
+ Implement the new Objective-C bundle SPI to look up the incoming MIME type in the dictionary supplied via the
+ "MIMETypeToReplacementURLMap" bundle initialization parameter, and return it.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+ (webViewForTestingAttachments):
+ (-[TestWKWebView tagsInBody]):
+ (-[TestWKWebView expectElementTagsInOrder:]):
+ (-[TestWKWebView expectElementTag:toComeBefore:]):
+
+ Add a test helper to check that the given list of element tags appears in the document body. Also, reimplement
+ the existing -expectElementTag:toComeBefore: as a special case of -expectElementTagsInOrder:.
+
+ (TestWebKitAPI::TEST):
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::InjectedBundlePage):
+
2018-01-17 Carlos Garcia Campos <cgar...@igalia.com>
WebDriver: add support for test expectations
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BundleEditingDelegatePlugIn.mm (227067 => 227068)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BundleEditingDelegatePlugIn.mm 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BundleEditingDelegatePlugIn.mm 2018-01-17 17:07:43 UTC (rev 227068)
@@ -47,6 +47,7 @@
RetainPtr<id <BundleEditingDelegateProtocol>> _remoteObject;
BOOL _editingDelegateShouldInsertText;
BOOL _shouldOverridePerformTwoStepDrop;
+ RetainPtr<NSDictionary<NSString *, NSString *>> _mimeTypeToReplacementURLMap;
}
- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController
@@ -63,6 +64,7 @@
_editingDelegateShouldInsertText = YES;
_shouldOverridePerformTwoStepDrop = [[plugInController.parameters valueForKey:@"BundleOverridePerformTwoStepDrop"] boolValue];
+ _mimeTypeToReplacementURLMap = [plugInController.parameters valueForKey:@"MIMETypeToReplacementURLMap"];
_WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(BundleEditingDelegateProtocol)];
_remoteObject = [browserContextController._remoteObjectRegistry remoteObjectProxyWithInterface:interface];
@@ -98,6 +100,12 @@
return _shouldOverridePerformTwoStepDrop;
}
+- (NSString *)_webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller replacementURLForResource:(NSData *)resourceData mimeType:(NSString *)mimeType
+{
+ assert(!!resourceData);
+ return [_mimeTypeToReplacementURLMap objectForKey:mimeType];
+}
+
@end
#endif // WK_API_ENABLED
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (227067 => 227068)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-01-17 17:07:43 UTC (rev 227068)
@@ -28,6 +28,7 @@
#import "DataInteractionSimulator.h"
#import "PlatformUtilities.h"
#import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKPreferencesRefPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WebKit.h>
@@ -144,18 +145,23 @@
@interface TestWKWebView (AttachmentTesting)
@end
-static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize)
+static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize, WKWebViewConfiguration *configuration)
{
- auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [configuration _setAttachmentElementEnabled:YES];
+ configuration._attachmentElementEnabled = YES;
WKPreferencesSetCustomPasteboardDataEnabled((WKPreferencesRef)[configuration preferences], YES);
- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, webViewSize.width, webViewSize.height) configuration:configuration.get()]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, webViewSize.width, webViewSize.height) configuration:configuration]);
[webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width, initial-scale=1'><script>focus = () => document.body.focus()</script><body _onload_=focus() contenteditable></body>"];
return webView;
}
+static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ return webViewForTestingAttachments(webViewSize, configuration.get());
+}
+
static RetainPtr<TestWKWebView> webViewForTestingAttachments()
{
return webViewForTestingAttachments(CGSizeMake(500, 500));
@@ -207,22 +213,31 @@
@implementation TestWKWebView (AttachmentTesting)
-- (void)expectElementTag:(NSString *)tagName toComeBefore:(NSString *)otherTagName
+- (NSArray<NSString *> *)tagsInBody
{
- NSArray *tagsInBody = [self objectByEvaluatingJavaScript:@"Array.from(document.body.getElementsByTagName('*')).map(e => e.tagName)"];
- BOOL success = [tagsInBody containsObject:tagName] && [tagsInBody containsObject:otherTagName];
- if (success) {
- NSUInteger index = [tagsInBody indexOfObject:tagName];
- NSUInteger otherIndex = [tagsInBody indexOfObjectWithOptions:NSEnumerationReverse passingTest:[&] (NSString *tag, NSUInteger, BOOL *) {
- return [tag isEqualToString:otherTagName];
- }];
- success = index < otherIndex;
+ return [self objectByEvaluatingJavaScript:@"Array.from(document.body.getElementsByTagName('*')).map(e => e.tagName)"];
+}
+
+- (void)expectElementTagsInOrder:(NSArray<NSString *> *)tagNames
+{
+ auto remainingTags = adoptNS([tagNames mutableCopy]);
+ NSArray<NSString *> *tagsInBody = self.tagsInBody;
+ for (NSString *tag in tagsInBody.reverseObjectEnumerator) {
+ if ([tag isEqualToString:[remainingTags lastObject]])
+ [remainingTags removeLastObject];
+ if (![remainingTags count])
+ break;
}
- EXPECT_TRUE(success);
- if (!success)
- NSLog(@"Expected %@ to come before %@ in tags: %@", tagName, otherTagName, tagsInBody);
+ EXPECT_EQ([remainingTags count], 0U);
+ if ([remainingTags count])
+ NSLog(@"Expected to find ordered tags: %@ in: %@", tagNames, tagsInBody);
}
+- (void)expectElementTag:(NSString *)tagName toComeBefore:(NSString *)otherTagName
+{
+ [self expectElementTagsInOrder:@[tagName, otherTagName]];
+}
+
- (BOOL)_synchronouslyExecuteEditCommand:(NSString *)command argument:(NSString *)argument
{
__block bool done = false;
@@ -1096,6 +1111,38 @@
[pastedAttachment expectRequestedDataToBe:originalData.get()];
}
+TEST(WKAttachmentTests, InjectedBundleReplaceURLsWhenPastingAttributedString)
+{
+ platformCopyRichTextWithMultipleAttachments();
+
+ auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]);
+ [[configuration processPool] _setObject:@{ @"image/png" : @"cid:foo-bar" } forBundleParameter:@"MIMETypeToReplacementURLMap"];
+ auto webView = webViewForTestingAttachments(CGSizeMake(500, 500), configuration.get());
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+ EXPECT_EQ(2U, observer.observer().inserted.count);
+ }
+ [webView expectElementTagsInOrder:@[ @"IMG", @"ATTACHMENT", @"ATTACHMENT" ]];
+ EXPECT_WK_STREQ("cid:foo-bar", [webView valueOfAttribute:@"src" forQuerySelector:@"img"]);
+}
+
+TEST(WKAttachmentTests, InjectedBundleReplaceURLWhenPastingImage)
+{
+ platformCopyPNG();
+
+ NSString *replacementURL = @"cid:foo-bar";
+ auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]);
+ [[configuration processPool] _setObject:@{ @"image/tiff" : replacementURL, @"image/png" : replacementURL } forBundleParameter:@"MIMETypeToReplacementURLMap"];
+ auto webView = webViewForTestingAttachments(CGSizeMake(500, 500), configuration.get());
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+ EXPECT_EQ(0U, observer.observer().inserted.count);
+ }
+ EXPECT_WK_STREQ("cid:foo-bar", [webView valueOfAttribute:@"src" forQuerySelector:@"img"]);
+}
+
#pragma mark - Platform-specific tests
#if PLATFORM(MAC)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (227067 => 227068)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2018-01-17 17:00:07 UTC (rev 227067)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2018-01-17 17:07:43 UTC (rev 227068)
@@ -358,8 +358,8 @@
};
WKBundlePageSetUIClient(m_page, &uiClient.base);
- WKBundlePageEditorClientV1 editorClient = {
- { 1, this },
+ WKBundlePageEditorClientV2 editorClient = {
+ { 2, this },
shouldBeginEditing,
shouldEndEditing,
shouldInsertNode,
@@ -375,6 +375,7 @@
0, /* getPasteboardDataForRange */
0, /* didWriteToPasteboard */
0, /* performTwoStepDrop */
+ 0, /* replacementURLForResource */
};
WKBundlePageSetEditorClient(m_page, &editorClient.base);