Diff
Modified: trunk/Source/WebCore/ChangeLog (235342 => 235343)
--- trunk/Source/WebCore/ChangeLog 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/ChangeLog 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1,3 +1,91 @@
+2018-08-26 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments
+ https://bugs.webkit.org/show_bug.cgi?id=188933
+ <rdar://problem/43699724>
+
+ Reviewed by Darin Adler.
+
+ Support the ability to drop and paste images as image elements, with attachment elements, only if attachment
+ elements are enabled. See changes below for more detail.
+
+ Tests: WKAttachmentTests.CutAndPastePastedImage
+ WKAttachmentTests.MovePastedImageByDragging
+ WKAttachmentTests.RemoveNewlinesBeforePastedImage
+
+ * editing/Editor.h:
+ * editing/cocoa/EditorCocoa.mm:
+ (WebCore::Editor::getPasteboardTypesAndDataForAttachment):
+
+ Adjust this helper to take an Element& rather than an HTMLAttachmentElement&, and address a FIXME by writing the
+ document origin identifier to the pasteboard via custom pasteboard data when dragging an attachment. This allows
+ us to avoid creating extra image and attachment elements when dragging an image backed by an attachment within
+ the same document.
+
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::contentTypeIsSuitableForInlineImageRepresentation):
+
+ Add a helper to determine whether a content type (UTI or MIME type) should be read as an inline image.
+
+ (WebCore::createFragmentForImageAttachment):
+ (WebCore::replaceRichContentWithAttachments):
+ (WebCore::WebContentReader::readFilePaths):
+
+ Teach codepaths where we currently create attachment elements to instead create image elements if the MIME type,
+ is something suitable for display via an inline image element; add the attachment element under the shadow root
+ of the image element.
+
+ * editing/markup.cpp:
+ (WebCore::StyledMarkupAccumulator::appendCustomAttributes):
+ (WebCore::restoreAttachmentElementsInFragment):
+
+ When dragging or copying an image element, we need to make sure that any attachment element backing the image
+ is preserved in the pasted or dropped fragment. To do this, we use a technique similar to what was done for
+ r180785 and r224593 and write a temporary "webkitattachmentid" attribute to the serialized markup on copy. Upon
+ deserializing the markup back to a fragment, we then create an attachment element with the same identifier under
+ the image.
+
+ (WebCore::createFragmentFromMarkup):
+ * html/HTMLAttachmentElement.h:
+ * html/HTMLImageElement.cpp:
+ (WebCore::HTMLImageElement::setAttachmentElement):
+ (WebCore::HTMLImageElement::attachmentElement const):
+
+ Helper methods to get and set an attachment element under an image element. Setting an image's attachment
+ element puts that attachment element under the shadow root of the image, and also hides the attachment element.
+
+ (WebCore::HTMLImageElement::attachmentIdentifier const):
+
+ Returns the identifier of an attachment element associated with the image element, or null.
+
+ * html/HTMLImageElement.h:
+ * html/HTMLImageElement.idl:
+
+ Add HTMLImageElement.webkitAttachmentIdentifier, a readonly attribute guarded by runtime-enabled attachment
+ element feature.
+
+ * page/DragController.cpp:
+ (WebCore::DragController::startDrag):
+
+ In the case of dragging an image, if that image element is backed by an attachment element, don't bother writing
+ the image data to the clipboard; instead, write the attachment data as a promise.
+
+ (WebCore::DragController::doImageDrag):
+
+ Plumb promised attachment information to DragController::doSystemDrag.
+
+ (WebCore::DragController::promisedAttachmentInfo):
+
+ Teach this to handle attachment elements as well as image elements that are backed by attachment elements.
+
+ * page/DragController.h:
+ * platform/PromisedAttachmentInfo.h:
+ (WebCore::PromisedAttachmentInfo::operator bool const):
+
+ A valid PromisedAttachmentInfo no longer requires a contentType to be set; instead, an attachment identifier
+ alone is sufficient, since an up-to-date content type can be requested in the UI process from the API attachment
+ object.
+
2018-08-26 Andy Estes <aes...@apple.com>
[Apple Pay] PaymentRequest.show() should reject when an unsupported ApplePayRequest version is specified
Modified: trunk/Source/WebCore/editing/Editor.h (235342 => 235343)
--- trunk/Source/WebCore/editing/Editor.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/editing/Editor.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -511,7 +511,7 @@
void didRemoveAttachmentElement(HTMLAttachmentElement&);
#if PLATFORM(COCOA)
- void getPasteboardTypesAndDataForAttachment(HTMLAttachmentElement&, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData);
+ void getPasteboardTypesAndDataForAttachment(Element&, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData);
#endif
#endif
Modified: trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm (235342 => 235343)
--- trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -160,26 +160,21 @@
#if ENABLE(ATTACHMENT_ELEMENT)
-void Editor::getPasteboardTypesAndDataForAttachment(HTMLAttachmentElement& attachment, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData)
+void Editor::getPasteboardTypesAndDataForAttachment(Element& element, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData)
{
- auto attachmentRange = Range::create(attachment.document(), { &attachment, Position::PositionIsBeforeAnchor }, { &attachment, Position::PositionIsAfterAnchor });
- client()->getClientPasteboardDataForRange(attachmentRange.ptr(), outTypes, outData);
- // FIXME: We should additionally write the attachment as a web archive here, such that drag and drop within the
- // same page doesn't destroy and recreate attachments unnecessarily. This is also needed to preserve the attachment
- // display mode when dragging and dropping or cutting and pasting. For the time being, this is disabled because
- // inserting attachment elements from web archive data sometimes causes attachment data to be lost; this requires
- // further investigation.
-#if PLATFORM(MAC)
- // On macOS, we currently write the attachment as a web archive; we can't do the same for iOS and remove the platform guard above
- // quite yet without breaking drag moves. This investigation is tracked in <https://bugs.webkit.org/show_bug.cgi?id=181514>.
- // See the above FIXME for more details.
- if (auto archive = LegacyWebArchive::create(attachmentRange.ptr())) {
+ auto& document = element.document();
+ auto elementRange = Range::create(document, { &element, Position::PositionIsBeforeAnchor }, { &element, Position::PositionIsAfterAnchor });
+ client()->getClientPasteboardDataForRange(elementRange.ptr(), outTypes, outData);
+
+ outTypes.append(PasteboardCustomData::cocoaType());
+ outData.append(PasteboardCustomData { document.originIdentifierForPasteboard(), { }, { }, { } }.createSharedBuffer());
+
+ if (auto archive = LegacyWebArchive::create(elementRange.ptr())) {
if (auto webArchiveData = archive->rawDataRepresentation()) {
outTypes.append(WebArchivePboardType);
outData.append(SharedBuffer::create(webArchiveData.get()));
}
}
-#endif
}
#endif
Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (235342 => 235343)
--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -47,6 +47,7 @@
#import "HTMLImageElement.h"
#import "HTMLObjectElement.h"
#import "LegacyWebArchive.h"
+#import "MIMETypeRegistry.h"
#import "Page.h"
#import "PublicURLManager.h"
#import "RuntimeEnabledFeatures.h"
@@ -207,6 +208,11 @@
#if ENABLE(ATTACHMENT_ELEMENT)
+static bool contentTypeIsSuitableForInlineImageRepresentation(const String& contentType)
+{
+ return MIMETypeRegistry::isSupportedImageMIMEType(isDeclaredUTI(contentType) ? MIMETypeFromUTI(contentType) : contentType);
+}
+
static bool supportsClientSideAttachmentData(const Frame& frame)
{
if (auto* client = frame.editor().client())
@@ -224,15 +230,22 @@
// FIXME: This fallback image name needs to be a localized string.
String defaultImageAttachmentName { "image"_s };
+ auto fragment = document.createDocumentFragment();
if (supportsClientSideAttachmentData(frame)) {
- attachment->updateAttributes(buffer->size(), contentType, defaultImageAttachmentName);
frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, defaultImageAttachmentName, WTFMove(buffer));
- } else
+ if (contentTypeIsSuitableForInlineImageRepresentation(contentType)) {
+ auto image = HTMLImageElement::create(document);
+ image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, Blob::create(buffer.get(), contentType)));
+ image->setAttachmentElement(WTFMove(attachment));
+ fragment->appendChild(WTFMove(image));
+ } else {
+ attachment->updateAttributes(buffer->size(), contentType, defaultImageAttachmentName);
+ fragment->appendChild(WTFMove(attachment));
+ }
+ } else {
attachment->setFile(File::create(Blob::create(buffer.get(), contentType), defaultImageAttachmentName), HTMLAttachmentElement::UpdateDisplayAttributes::Yes);
-
- auto fragment = document.createDocumentFragment();
- fragment->appendChild(attachment);
-
+ fragment->appendChild(WTFMove(attachment));
+ }
return fragment;
#else
UNUSED_PARAM(blob);
@@ -243,11 +256,11 @@
static void replaceRichContentWithAttachments(Frame& frame, DocumentFragment& fragment, const Vector<Ref<ArchiveResource>>& subresources)
{
#if ENABLE(ATTACHMENT_ELEMENT)
- struct AttachmentReplacementInfo {
+ struct AttachmentInsertionInfo {
String fileName;
String contentType;
Ref<SharedBuffer> data;
- Ref<Element> elementToReplace;
+ Ref<Element> originalElement;
};
ASSERT(RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled());
@@ -263,7 +276,7 @@
}
Vector<Ref<Element>> elementsToRemove;
- Vector<AttachmentReplacementInfo> attachmentReplacementInfo;
+ Vector<AttachmentInsertionInfo> attachmentInsertionInfo;
for (auto& image : descendantsOfType<HTMLImageElement>(fragment)) {
auto resourceURLString = image.attributeWithoutSynchronization(HTMLNames::srcAttr);
if (resourceURLString.isEmpty())
@@ -277,7 +290,7 @@
if (name.isEmpty())
name = AtomicString("media");
- attachmentReplacementInfo.append({ name, resource->value->mimeType(), resource->value->data(), image });
+ attachmentInsertionInfo.append({ name, resource->value->mimeType(), resource->value->data(), image });
}
for (auto& object : descendantsOfType<HTMLObjectElement>(fragment)) {
@@ -295,23 +308,30 @@
if (name.isEmpty())
name = AtomicString("file");
- attachmentReplacementInfo.append({ name, resource->value->mimeType(), resource->value->data(), object });
+ attachmentInsertionInfo.append({ name, resource->value->mimeType(), resource->value->data(), object });
}
- for (auto& info : attachmentReplacementInfo) {
- auto elementToReplace = WTFMove(info.elementToReplace);
- auto parent = makeRefPtr(elementToReplace->parentNode());
+ for (auto& info : attachmentInsertionInfo) {
+ auto originalElement = WTFMove(info.originalElement);
+ auto parent = makeRefPtr(originalElement->parentNode());
if (!parent)
continue;
auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, fragment.document());
if (supportsClientSideAttachmentData(frame)) {
- attachment->updateAttributes(info.data->size(), info.contentType, info.fileName);
+ if (is<HTMLImageElement>(originalElement.get()) && contentTypeIsSuitableForInlineImageRepresentation(info.contentType)) {
+ auto& image = downcast<HTMLImageElement>(originalElement.get());
+ image.setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(*frame.document(), Blob::create(info.data, info.contentType)));
+ image.setAttachmentElement(WTFMove(attachment));
+ } else {
+ attachment->updateAttributes(info.data->size(), info.contentType, info.fileName);
+ parent->replaceChild(attachment, WTFMove(originalElement));
+ }
frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), WTFMove(info.contentType), WTFMove(info.fileName), WTFMove(info.data));
- } else
- attachment->setFile(File::create(Blob::create(info.data, info.contentType), info.fileName), HTMLAttachmentElement::UpdateDisplayAttributes::Yes);
-
- parent->replaceChild(attachment, elementToReplace);
+ } else {
+ attachment->setFile(File::create(Blob::create(WTFMove(info.data), WTFMove(info.contentType)), WTFMove(info.fileName)), HTMLAttachmentElement::UpdateDisplayAttributes::Yes);
+ parent->replaceChild(WTFMove(attachment), WTFMove(originalElement));
+ }
}
for (auto& elementToRemove : elementsToRemove)
@@ -684,12 +704,20 @@
long long fileSize { 0 };
FileSystem::getFileSize(path, fileSize);
auto contentType = File::contentTypeForFile(path);
- attachment->updateAttributes(fileSize, contentType, FileSystem::pathGetFileName(path));
frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, path);
- } else
+ if (contentTypeIsSuitableForInlineImageRepresentation(contentType)) {
+ auto image = HTMLImageElement::create(document);
+ image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, File::create(path)));
+ image->setAttachmentElement(WTFMove(attachment));
+ fragment->appendChild(image);
+ } else {
+ attachment->updateAttributes(fileSize, contentType, FileSystem::pathGetFileName(path));
+ fragment->appendChild(attachment);
+ }
+ } else {
attachment->setFile(File::create(path), HTMLAttachmentElement::UpdateDisplayAttributes::Yes);
-
- fragment->appendChild(attachment);
+ fragment->appendChild(attachment);
+ }
}
}
#endif
Modified: trunk/Source/WebCore/editing/markup.cpp (235342 => 235343)
--- trunk/Source/WebCore/editing/markup.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/editing/markup.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -67,6 +67,7 @@
#include "PageConfiguration.h"
#include "Range.h"
#include "RenderBlock.h"
+#include "RuntimeEnabledFeatures.h"
#include "Settings.h"
#include "SocketProvider.h"
#include "StyleProperties.h"
@@ -406,16 +407,21 @@
void StyledMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
#if ENABLE(ATTACHMENT_ELEMENT)
- if (!is<HTMLAttachmentElement>(element))
+ if (!RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled())
return;
- const HTMLAttachmentElement& attachment = downcast<HTMLAttachmentElement>(element);
- appendAttribute(out, element, { webkitattachmentidAttr, attachment.uniqueIdentifier() }, namespaces);
- if (auto* file = attachment.file()) {
- // These attributes are only intended for File deserialization, and are removed from the generated attachment
- // element after we've deserialized and set its backing File.
- appendAttribute(out, element, { webkitattachmentpathAttr, file->path() }, namespaces);
- appendAttribute(out, element, { webkitattachmentbloburlAttr, file->url().string() }, namespaces);
+ if (is<HTMLAttachmentElement>(element)) {
+ auto& attachment = downcast<HTMLAttachmentElement>(element);
+ appendAttribute(out, element, { webkitattachmentidAttr, attachment.uniqueIdentifier() }, namespaces);
+ if (auto* file = attachment.file()) {
+ // These attributes are only intended for File deserialization, and are removed from the generated attachment
+ // element after we've deserialized and set its backing File, in restoreAttachmentElementsInFragment.
+ appendAttribute(out, element, { webkitattachmentpathAttr, file->path() }, namespaces);
+ appendAttribute(out, element, { webkitattachmentbloburlAttr, file->url().string() }, namespaces);
+ }
+ } else if (is<HTMLImageElement>(element)) {
+ if (auto attachment = downcast<HTMLImageElement>(element).attachmentElement())
+ appendAttribute(out, element, { webkitattachmentidAttr, attachment->uniqueIdentifier() }, namespaces);
}
#else
UNUSED_PARAM(out);
@@ -881,15 +887,12 @@
return result;
}
-Ref<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
+static void restoreAttachmentElementsInFragment(DocumentFragment& fragment)
{
- // We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
- auto fakeBody = HTMLBodyElement::create(document);
- auto fragment = DocumentFragment::create(document);
+#if ENABLE(ATTACHMENT_ELEMENT)
+ if (!RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled())
+ return;
- fragment->parseHTML(markup, fakeBody.ptr(), parserContentPolicy);
-
-#if ENABLE(ATTACHMENT_ELEMENT)
// When creating a fragment we must strip the webkit-attachment-path attribute after restoring the File object.
Vector<Ref<HTMLAttachmentElement>> attachments;
for (auto& attachment : descendantsOfType<HTMLAttachmentElement>(fragment))
@@ -905,11 +908,39 @@
else if (!blobURL.isEmpty())
attachment->setFile(File::deserialize({ }, blobURL, attachment->attachmentType(), attachment->attachmentTitle()));
+ // Remove temporary attributes that were previously added in StyledMarkupAccumulator::appendCustomAttributes.
attachment->removeAttribute(webkitattachmentidAttr);
attachment->removeAttribute(webkitattachmentpathAttr);
attachment->removeAttribute(webkitattachmentbloburlAttr);
}
+
+ Vector<Ref<HTMLImageElement>> images;
+ for (auto& image : descendantsOfType<HTMLImageElement>(fragment))
+ images.append(image);
+
+ for (auto& image : images) {
+ auto attachmentIdentifier = image->attributeWithoutSynchronization(webkitattachmentidAttr);
+ if (attachmentIdentifier.isEmpty())
+ continue;
+
+ auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, *fragment.ownerDocument());
+ attachment->setUniqueIdentifier(attachmentIdentifier);
+ image->setAttachmentElement(WTFMove(attachment));
+ image->removeAttribute(webkitattachmentidAttr);
+ }
+#else
+ UNUSED_PARAM(fragment);
#endif
+}
+
+Ref<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
+{
+ // We use a fake body element here to trick the HTML parser into using the InBody insertion mode.
+ auto fakeBody = HTMLBodyElement::create(document);
+ auto fragment = DocumentFragment::create(document);
+
+ fragment->parseHTML(markup, fakeBody.ptr(), parserContentPolicy);
+ restoreAttachmentElementsInFragment(fragment);
if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseURL())
completeURLs(fragment.ptr(), baseURL);
Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.h (235342 => 235343)
--- trunk/Source/WebCore/html/HTMLAttachmentElement.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -46,7 +46,7 @@
enum class UpdateDisplayAttributes { No, Yes };
void setFile(RefPtr<File>&&, UpdateDisplayAttributes = UpdateDisplayAttributes::No);
- String uniqueIdentifier() const { return m_uniqueIdentifier; }
+ const String& uniqueIdentifier() const { return m_uniqueIdentifier; }
void setUniqueIdentifier(const String& uniqueIdentifier) { m_uniqueIdentifier = uniqueIdentifier; }
WEBCORE_EXPORT void updateAttributes(uint64_t fileSize, std::optional<String>&& newContentType = std::nullopt, std::optional<String>&& newFilename = std::nullopt);
Modified: trunk/Source/WebCore/html/HTMLImageElement.cpp (235342 => 235343)
--- trunk/Source/WebCore/html/HTMLImageElement.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/html/HTMLImageElement.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -26,8 +26,10 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "CachedImage.h"
+#include "ElementIterator.h"
#include "FrameView.h"
#include "HTMLAnchorElement.h"
+#include "HTMLAttachmentElement.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLParserIdioms.h"
@@ -603,6 +605,35 @@
return parseCORSSettingsAttribute(attributeWithoutSynchronization(crossoriginAttr));
}
+#if ENABLE(ATTACHMENT_ELEMENT)
+
+void HTMLImageElement::setAttachmentElement(Ref<HTMLAttachmentElement>&& attachment)
+{
+ if (auto existingAttachment = attachmentElement())
+ existingAttachment->remove();
+
+ attachment->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone, true);
+ ensureUserAgentShadowRoot().appendChild(WTFMove(attachment));
+}
+
+RefPtr<HTMLAttachmentElement> HTMLImageElement::attachmentElement() const
+{
+ if (auto shadowRoot = userAgentShadowRoot())
+ return childrenOfType<HTMLAttachmentElement>(*shadowRoot).first();
+
+ return nullptr;
+}
+
+const String& HTMLImageElement::attachmentIdentifier() const
+{
+ if (auto attachment = attachmentElement())
+ return attachment->uniqueIdentifier();
+
+ return nullAtom();
+}
+
+#endif // ENABLE(ATTACHMENT_ELEMENT)
+
#if ENABLE(SERVICE_CONTROLS)
void HTMLImageElement::updateImageControls()
{
Modified: trunk/Source/WebCore/html/HTMLImageElement.h (235342 => 235343)
--- trunk/Source/WebCore/html/HTMLImageElement.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/html/HTMLImageElement.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -31,6 +31,7 @@
namespace WebCore {
+class HTMLAttachmentElement;
class HTMLFormElement;
class HTMLMapElement;
@@ -91,6 +92,12 @@
bool willRespondToMouseClickEvents() override;
#endif
+#if ENABLE(ATTACHMENT_ELEMENT)
+ void setAttachmentElement(Ref<HTMLAttachmentElement>&&);
+ RefPtr<HTMLAttachmentElement> attachmentElement() const;
+ const String& attachmentIdentifier() const;
+#endif
+
bool hasPendingActivity() const { return m_imageLoader.hasPendingActivity(); }
bool canContainRangeEndPoint() const override { return false; }
Modified: trunk/Source/WebCore/html/HTMLImageElement.idl (235342 => 235343)
--- trunk/Source/WebCore/html/HTMLImageElement.idl 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/html/HTMLImageElement.idl 2018-08-27 02:37:22 UTC (rev 235343)
@@ -42,6 +42,8 @@
attribute unsigned long width;
[Reflect] attribute DOMString decoding;
+ [Conditional=ATTACHMENT_ELEMENT, EnabledAtRuntime=AttachmentElement, ImplementedAs=attachmentIdentifier] readonly attribute DOMString webkitAttachmentIdentifier;
+
// Extensions
readonly attribute boolean complete;
[Reflect,URL] attribute USVString lowsrc;
Modified: trunk/Source/WebCore/page/DragController.cpp (235342 => 235343)
--- trunk/Source/WebCore/page/DragController.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/page/DragController.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -910,9 +910,6 @@
#if ENABLE(VIDEO)
includeShadowDOM = state.source->isMediaElement();
#endif
-#if ENABLE(ATTACHMENT_ELEMENT)
- includeShadowDOM = includeShadowDOM || is<HTMLAttachmentElement>(state.source.get());
-#endif
#if ENABLE(INPUT_TYPE_COLOR)
bool isColorControl = is<HTMLInputElement>(state.source) && downcast<HTMLInputElement>(*state.source).isColorControl();
includeShadowDOM = includeShadowDOM || isColorControl;
@@ -1048,20 +1045,28 @@
// We shouldn't be starting a drag for an image that can't provide an extension.
// This is an early detection for problems encountered later upon drop.
ASSERT(!image->filenameExtension().isEmpty());
+
+#if ENABLE(ATTACHMENT_ELEMENT)
+ auto attachmentInfo = promisedAttachmentInfo(src, element);
+#else
+ PromisedAttachmentInfo attachmentInfo;
+#endif
+
if (hasData == HasNonDefaultPasteboardData::No) {
m_draggingImageURL = imageURL;
if (element.isContentRichlyEditable())
selectElement(element);
- declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
+ if (!attachmentInfo)
+ declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
}
m_client.willPerformDragSourceAction(DragSourceActionImage, dragOrigin, dataTransfer);
if (!dragImage)
- doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state);
+ doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
else {
// DHTML defined drag image
- doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
+ doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, WTFMove(attachmentInfo));
}
return true;
@@ -1200,7 +1205,7 @@
return false;
}
-void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Frame& frame, IntPoint& dragImageOffset, const DragState& state)
+void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Frame& frame, IntPoint& dragImageOffset, const DragState& state, PromisedAttachmentInfo&& attachmentInfo)
{
IntPoint mouseDownPoint = dragOrigin;
DragImage dragImage;
@@ -1243,7 +1248,7 @@
return;
dragImageOffset = mouseDownPoint + scaledOrigin;
- doSystemDrag(WTFMove(dragImage), dragImageOffset, dragOrigin, frame, state, { });
+ doSystemDrag(WTFMove(dragImage), dragImageOffset, dragOrigin, frame, state, WTFMove(attachmentInfo));
}
void DragController::beginDrag(DragItem dragItem, Frame& frame, const IntPoint& mouseDownPoint, const IntPoint& mouseDraggedPoint, DataTransfer& dataTransfer, DragSourceAction dragSourceAction)
@@ -1367,19 +1372,31 @@
#if ENABLE(ATTACHMENT_ELEMENT)
-PromisedAttachmentInfo DragController::promisedAttachmentInfo(Frame& frame, HTMLAttachmentElement& attachment)
+PromisedAttachmentInfo DragController::promisedAttachmentInfo(Frame& frame, Element& element)
{
+ auto* client = frame.editor().client();
+ if (!client || !client->supportsClientSideAttachmentData())
+ return { };
+
+ RefPtr<HTMLAttachmentElement> attachment;
+ if (is<HTMLAttachmentElement>(element))
+ attachment = &downcast<HTMLAttachmentElement>(element);
+ else if (is<HTMLImageElement>(element))
+ attachment = downcast<HTMLImageElement>(element).attachmentElement();
+
+ if (!attachment)
+ return { };
+
Vector<String> additionalTypes;
Vector<RefPtr<SharedBuffer>> additionalData;
#if PLATFORM(COCOA)
- if (frame.editor().client())
- frame.editor().getPasteboardTypesAndDataForAttachment(attachment, additionalTypes, additionalData);
+ frame.editor().getPasteboardTypesAndDataForAttachment(element, additionalTypes, additionalData);
#endif
- if (auto* file = attachment.file())
- return { file->url(), platformContentTypeForBlobType(file->type()), file->name(), attachment.uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) };
+ if (auto* file = attachment->file())
+ return { file->url(), platformContentTypeForBlobType(file->type()), file->name(), { }, WTFMove(additionalTypes), WTFMove(additionalData) };
- return { { }, platformContentTypeForBlobType(attachment.attachmentType()), attachment.attachmentTitle(), attachment.uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) };
+ return { { }, { }, { }, attachment->uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) };
}
#endif // ENABLE(ATTACHMENT_ELEMENT)
Modified: trunk/Source/WebCore/page/DragController.h (235342 => 235343)
--- trunk/Source/WebCore/page/DragController.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/page/DragController.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -40,7 +40,6 @@
class Element;
class Frame;
class FrameSelection;
-class HTMLAttachmentElement;
class HTMLInputElement;
class IntRect;
class Page;
@@ -115,7 +114,7 @@
void mouseMovedIntoDocument(Document*);
bool shouldUseCachedImageForDragImage(const Image&) const;
- void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState&);
+ void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState&, PromisedAttachmentInfo&&);
void doSystemDrag(DragImage, const IntPoint&, const IntPoint&, Frame&, const DragState&, PromisedAttachmentInfo&&);
void beginDrag(DragItem, Frame&, const IntPoint& mouseDownPoint, const IntPoint& mouseDraggedPoint, DataTransfer&, DragSourceAction);
@@ -135,7 +134,7 @@
void declareAndWriteDragImage(DataTransfer&, Element&, const URL&, const String& label);
#if ENABLE(ATTACHMENT_ELEMENT)
- PromisedAttachmentInfo promisedAttachmentInfo(Frame&, HTMLAttachmentElement&);
+ PromisedAttachmentInfo promisedAttachmentInfo(Frame&, Element&);
#endif
Page& m_page;
DragClient& m_client;
Modified: trunk/Source/WebCore/platform/PromisedAttachmentInfo.h (235342 => 235343)
--- trunk/Source/WebCore/platform/PromisedAttachmentInfo.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebCore/platform/PromisedAttachmentInfo.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -36,7 +36,7 @@
struct PromisedAttachmentInfo {
URL blobURL;
String contentType;
- String filename;
+ String fileName;
#if ENABLE(ATTACHMENT_ELEMENT)
String attachmentIdentifier;
@@ -47,15 +47,12 @@
operator bool() const
{
- if (contentType.isEmpty())
- return false;
-
#if ENABLE(ATTACHMENT_ELEMENT)
if (!attachmentIdentifier.isEmpty())
return true;
#endif
- return !blobURL.isEmpty();
+ return !contentType.isEmpty() && !blobURL.isEmpty();
}
};
Modified: trunk/Source/WebKit/ChangeLog (235342 => 235343)
--- trunk/Source/WebKit/ChangeLog 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/ChangeLog 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1,3 +1,110 @@
+2018-08-26 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments
+ https://bugs.webkit.org/show_bug.cgi?id=188933
+ <rdar://problem/43699724>
+
+ Reviewed by Darin Adler.
+
+ Support the ability to drop and paste images as image elements, with attachment elements, only if attachment
+ elements are enabled. See changes below for more detail.
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<PromisedAttachmentInfo>::encode):
+ (IPC::ArgumentCoder<PromisedAttachmentInfo>::decode):
+
+ Rename "filename" to "fileName", for consistency with WKContentView and WebViewImpl.
+
+ * UIProcess/API/APIAttachment.cpp:
+ (API::Attachment::mimeType const):
+ (API::Attachment::fileName const):
+ * UIProcess/API/APIAttachment.h:
+
+ Push getters for MIME type, UTI, and the file name down from _WKAttachment to API::Attachment. This allows
+ WKContentView and WebViewImpl to ask an API::Attachment questions about its UTI and file name without
+ additionally creating a wrapper object.
+
+ * UIProcess/API/Cocoa/APIAttachmentCocoa.mm: Added.
+ (API::mimeTypeInferredFromFileExtension):
+ (API::isDeclaredOrDynamicTypeIdentifier):
+ (API::Attachment::mimeType const):
+ (API::Attachment::utiType const):
+ (API::Attachment::fileName const):
+ * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+
+ Add a private delegate hook to notify the UI delegate when a drop has been performed. This is used by tests to
+ know when a drop with file promises has been processed by the page.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _web_didPerformDragOperation:]):
+ * UIProcess/API/Cocoa/_WKAttachment.mm:
+ (-[_WKAttachmentInfo initWithFileWrapper:filePath:mimeType:utiType:]):
+ (-[_WKAttachmentInfo fileWrapper]):
+ (-[_WKAttachmentInfo contentType]):
+ (-[_WKAttachment info]):
+ (-[_WKAttachmentInfo initWithFileWrapper:filePath:contentType:]): Deleted.
+ (isDeclaredOrDynamicTypeIdentifier): Deleted.
+ (-[_WKAttachmentInfo _typeIdentifierFromPathExtension]): Deleted.
+ (-[_WKAttachmentInfo mimeType]): Deleted.
+ (-[_WKAttachmentInfo utiType]): Deleted.
+
+ Moved to APIAttachmentCocoa.mm.
+
+ * UIProcess/API/mac/WKView.mm:
+ (-[WKView _web_didPerformDragOperation:]):
+ * UIProcess/Cocoa/WebViewImpl.h:
+ * UIProcess/Cocoa/WebViewImpl.mm:
+ (-[WKPromisedAttachmentContext initWithIdentifier:blobURL:fileName:]):
+
+ Adjust this constructor to take each piece of data separately. This is because, in the case where our
+ PromisedAttachmentInfo contains an attachment identifier, we determine the UTI and file name from the associated
+ file wrapper.
+
+ (-[WKPromisedAttachmentContext fileName]):
+ (WebKit::WebViewImpl::fileNameForFilePromiseProvider):
+ (WebKit::WebViewImpl::didPerformDragOperation):
+ (WebKit::WebViewImpl::startDrag):
+
+ Determine UTI and file name from the attachment element corresponding to the attachment identifier when
+ dragging. This is because the attachment element in the web process shouldn't need to have type and title
+ attributes set when starting a drag if it already has an identifier that maps to attachment data in the UI
+ process. An example of this is in inline images backed by attachments, for which we don't need to bother keeping
+ specifying display attributes, since they are never visible.
+
+ (-[WKPromisedAttachmentContext initWithAttachmentInfo:]): Deleted.
+ (-[WKPromisedAttachmentContext filename]): Deleted.
+ * UIProcess/PageClient.h:
+ (WebKit::PageClient::didPerformDragOperation):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::didPerformDragOperation):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+
+ Rename DidPerformDataInteractionControllerOperation to DidPerformDragOperation, and make it cross-platform (this
+ was previously only sent on iOS). Add plumbing through PageClient and friends on macOS to notify the UI
+ delegate when a drop is handled by the web process.
+
+ * UIProcess/ios/PageClientImplIOS.h:
+ * UIProcess/ios/PageClientImplIOS.mm:
+ (WebKit::PageClientImpl::didPerformDragOperation):
+ (WebKit::PageClientImpl::didPerformDataInteractionControllerOperation): Deleted.
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView _didPerformDragOperation:]):
+ (-[WKContentView _prepareToDragPromisedAttachment:]):
+
+ Just like in WebViewImpl::startDrag, infer content type and file name from the API attachment object.
+
+ (-[WKContentView _didPerformDataInteractionControllerOperation:]): Deleted.
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::didPerformDataInteractionControllerOperation): Deleted.
+ * UIProcess/mac/PageClientImplMac.h:
+ * UIProcess/mac/PageClientImplMac.mm:
+ (WebKit::PageClientImpl::didPerformDragOperation):
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::performDragControllerAction):
+
2018-08-23 Jeff Miller <je...@apple.com>
Remove -[WKNavigationDelegate _webView:decidePolicyForPluginLoadWithCurrentPolicy:pluginInfo:unavailabilityDescription:]
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (235342 => 235343)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -2867,7 +2867,7 @@
{
encoder << info.blobURL;
encoder << info.contentType;
- encoder << info.filename;
+ encoder << info.fileName;
#if ENABLE(ATTACHMENT_ELEMENT)
encoder << info.attachmentIdentifier;
#endif
@@ -2882,7 +2882,7 @@
if (!decoder.decode(info.contentType))
return false;
- if (!decoder.decode(info.filename))
+ if (!decoder.decode(info.fileName))
return false;
#if ENABLE(ATTACHMENT_ELEMENT)
Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -81,6 +81,20 @@
#endif
}
+#if !PLATFORM(COCOA)
+
+WTF::String Attachment::mimeType() const
+{
+ return m_contentType;
}
+WTF::String Attachment::fileName() const
+{
+ return { };
+}
+
+#endif // !PLATFORM(COCOA)
+
+}
+
#endif // ENABLE(ATTACHMENT_ELEMENT)
Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/APIAttachment.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -64,10 +64,13 @@
#if PLATFORM(COCOA)
NSFileWrapper *fileWrapper() const { return m_fileWrapper.get(); }
void setFileWrapper(NSFileWrapper *fileWrapper) { m_fileWrapper = fileWrapper; }
+ WTF::String utiType() const;
#endif
+ WTF::String mimeType() const;
const WTF::String& filePath() const { return m_filePath; }
void setFilePath(const WTF::String& filePath) { m_filePath = filePath; }
+ WTF::String fileName() const;
const WTF::String& contentType() const { return m_contentType; }
void setContentType(const WTF::String& contentType) { m_contentType = contentType; }
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm (0 => 235343)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+#import "APIAttachment.h"
+
+#import <WebCore/MIMETypeRegistry.h>
+#if PLATFORM(IOS)
+#import <MobileCoreServices/MobileCoreServices.h>
+#else
+#import <CoreServices/CoreServices.h>
+#endif
+
+namespace API {
+
+static WTF::String mimeTypeInferredFromFileExtension(const API::Attachment& attachment)
+{
+ if (NSString *fileExtension = [(NSString *)attachment.fileName() pathExtension])
+ return WebCore::MIMETypeRegistry::getMIMETypeForExtension(fileExtension);
+
+ return { };
+}
+
+static BOOL isDeclaredOrDynamicTypeIdentifier(NSString *type)
+{
+ return UTTypeIsDeclared((__bridge CFStringRef)type) || UTTypeIsDynamic((__bridge CFStringRef)type);
+}
+
+WTF::String Attachment::mimeType() const
+{
+ NSString *contentType = m_contentType.isEmpty() ? mimeTypeInferredFromFileExtension(*this) : m_contentType;
+ if (!isDeclaredOrDynamicTypeIdentifier(contentType))
+ return contentType;
+
+ return adoptCF(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)contentType, kUTTagClassMIMEType)).get();
+}
+
+WTF::String Attachment::utiType() const
+{
+ NSString *contentType = m_contentType.isEmpty() ? mimeTypeInferredFromFileExtension(*this) : m_contentType;
+ if (isDeclaredOrDynamicTypeIdentifier(contentType))
+ return contentType;
+
+ return adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)contentType, nullptr)).get();
+}
+
+WTF::String Attachment::fileName() const
+{
+ if ([m_fileWrapper filename].length)
+ return [m_fileWrapper filename];
+
+ return [m_fileWrapper preferredFilename];
+}
+
+} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -191,6 +191,7 @@
- (NSMenu *)_webView:(WKWebView *)webView contextMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element WK_API_DEPRECATED_WITH_REPLACEMENT("_webView:getContextMenuFromProposedMenu:forElement:userInfo:completionHandler:", macosx(10.12, WK_MAC_TBA));
- (NSMenu *)_webView:(WKWebView *)webView contextMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element userInfo:(id <NSSecureCoding>)userInfo WK_API_DEPRECATED_WITH_REPLACEMENT("_webView:getContextMenuFromProposedMenu:forElement:userInfo:completionHandler:", macosx(10.12, WK_MAC_TBA));
- (void)_webView:(WKWebView *)webView getContextMenuFromProposedMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element userInfo:(id <NSSecureCoding>)userInfo completionHandler:(void (^)(NSMenu *))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA));
+- (void)_webView:(WKWebView *)webView didPerformDragOperation:(BOOL)handled WK_API_AVAILABLE(macosx(WK_MAC_TBA));
#endif // TARGET_OS_IPHONE
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -4068,6 +4068,13 @@
return WKDragDestinationActionAny & ~WKDragDestinationActionLoad;
}
+- (void)_web_didPerformDragOperation:(BOOL)handled
+{
+ id <WKUIDelegatePrivate> uiDelegate = (id <WKUIDelegatePrivate>)self.UIDelegate;
+ if ([uiDelegate respondsToSelector:@selector(_webView:didPerformDragOperation:)])
+ [uiDelegate _webView:self didPerformDragOperation:handled];
+}
+
#endif
- (void)_web_dismissContentRelativeChildWindows
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -56,11 +56,12 @@
@implementation _WKAttachmentInfo {
RetainPtr<NSFileWrapper> _fileWrapper;
- RetainPtr<NSString> _contentType;
+ RetainPtr<NSString> _mimeType;
+ RetainPtr<NSString> _utiType;
RetainPtr<NSString> _filePath;
}
-- (instancetype)initWithFileWrapper:(NSFileWrapper *)fileWrapper filePath:(NSString *)filePath contentType:(NSString *)contentType
+- (instancetype)initWithFileWrapper:(NSFileWrapper *)fileWrapper filePath:(NSString *)filePath mimeType:(NSString *)mimeType utiType:(NSString *)utiType
{
if (!(self = [super init]))
return nil;
@@ -67,7 +68,8 @@
_fileWrapper = fileWrapper;
_filePath = filePath;
- _contentType = contentType;
+ _mimeType = mimeType;
+ _utiType = utiType;
return self;
}
@@ -94,50 +96,19 @@
return _filePath.get();
}
-static BOOL isDeclaredOrDynamicTypeIdentifier(NSString *type)
+- (NSFileWrapper *)fileWrapper
{
- return UTTypeIsDeclared((CFStringRef)type) || UTTypeIsDynamic((CFStringRef)type);
+ return _fileWrapper.get();
}
-- (NSString *)_typeIdentifierFromPathExtension
-{
- if (NSString *extension = self.name.pathExtension)
- return WebCore::MIMETypeRegistry::getMIMETypeForExtension(extension);
-
- return nil;
-}
-
- (NSString *)contentType
{
- // A "content type" can refer to either a UTI or a MIME type. We prefer MIME type here to preserve existing behavior.
- return self.mimeType ?: self.utiType;
-}
+ if ([_mimeType length])
+ return _mimeType.get();
-- (NSString *)mimeType
-{
- NSString *contentType = [_contentType length] ? _contentType.get() : [self _typeIdentifierFromPathExtension];
- if (!isDeclaredOrDynamicTypeIdentifier(contentType))
- return contentType;
-
- auto mimeType = adoptCF(UTTypeCopyPreferredTagWithClass((CFStringRef)contentType, kUTTagClassMIMEType));
- return (NSString *)mimeType.autorelease();
+ return _utiType.get();
}
-- (NSString *)utiType
-{
- NSString *contentType = [_contentType length] ? _contentType.get() : [self _typeIdentifierFromPathExtension];
- if (isDeclaredOrDynamicTypeIdentifier(contentType))
- return contentType;
-
- auto utiType = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)contentType, nil));
- return (NSString *)utiType.autorelease();
-}
-
-- (NSFileWrapper *)fileWrapper
-{
- return _fileWrapper.get();
-}
-
@end
@implementation _WKAttachment
@@ -152,7 +123,7 @@
if (!_attachment->isValid())
return nil;
- return [[[_WKAttachmentInfo alloc] initWithFileWrapper:_attachment->fileWrapper() filePath:_attachment->filePath() contentType:_attachment->contentType()] autorelease];
+ return [[[_WKAttachmentInfo alloc] initWithFileWrapper:_attachment->fileWrapper() filePath:_attachment->filePath() mimeType:_attachment->mimeType() utiType:_attachment->utiType()] autorelease];
}
- (void)requestInfo:(void(^)(_WKAttachmentInfo *, NSError *))completionHandler
Modified: trunk/Source/WebKit/UIProcess/API/mac/WKView.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/API/mac/WKView.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/API/mac/WKView.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1031,6 +1031,11 @@
#if ENABLE(DRAG_SUPPORT) && WK_API_ENABLED
+- (void)_web_didPerformDragOperation:(BOOL)handled
+{
+ UNUSED_PARAM(handled);
+}
+
- (WKDragDestinationAction)_web_dragDestinationActionForDraggingInfo:(id <NSDraggingInfo>)draggingInfo
{
return WKDragDestinationActionAny;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -104,6 +104,7 @@
#if ENABLE(DRAG_SUPPORT) && WK_API_ENABLED
- (WKDragDestinationAction)_web_dragDestinationActionForDraggingInfo:(id <NSDraggingInfo>)draggingInfo;
+- (void)_web_didPerformDragOperation:(BOOL)handled;
#endif
@optional
@@ -430,6 +431,8 @@
NSString *fileNameForFilePromiseProvider(NSFilePromiseProvider *, NSString *fileType);
void writeToURLForFilePromiseProvider(NSFilePromiseProvider *, NSURL *, void(^)(NSError *));
+
+ void didPerformDragOperation(bool handled);
#endif
void startWindowDrag();
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -880,14 +880,14 @@
@interface WKPromisedAttachmentContext : NSObject {
@private
RetainPtr<NSURL> _blobURL;
- RetainPtr<NSString> _filename;
+ RetainPtr<NSString> _fileName;
RetainPtr<NSString> _attachmentIdentifier;
}
-- (instancetype)initWithAttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info;
+- (instancetype)initWithIdentifier:(NSString *)identifier blobURL:(NSURL *)url fileName:(NSString *)fileName;
@property (nonatomic, readonly) NSURL *blobURL;
-@property (nonatomic, readonly) NSString *filename;
+@property (nonatomic, readonly) NSString *fileName;
@property (nonatomic, readonly) NSString *attachmentIdentifier;
@end
@@ -894,14 +894,14 @@
@implementation WKPromisedAttachmentContext
-- (instancetype)initWithAttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info
+- (instancetype)initWithIdentifier:(NSString *)identifier blobURL:(NSURL *)blobURL fileName:(NSString *)fileName
{
if (!(self = [super init]))
return nil;
- _blobURL = info.blobURL;
- _filename = info.filename;
- _attachmentIdentifier = info.attachmentIdentifier;
+ _blobURL = blobURL;
+ _fileName = fileName;
+ _attachmentIdentifier = identifier;
return self;
}
@@ -910,9 +910,9 @@
return _blobURL.get();
}
-- (NSString *)filename
+- (NSString *)fileName
{
- return _filename.get();
+ return _fileName.get();
}
- (NSString *)attachmentIdentifier
@@ -3908,7 +3908,7 @@
if (![userInfo isKindOfClass:[WKPromisedAttachmentContext class]])
return nil;
- return [(WKPromisedAttachmentContext *)userInfo filename];
+ return [(WKPromisedAttachmentContext *)userInfo fileName];
}
static NSError *webKitUnknownError()
@@ -3920,6 +3920,15 @@
#endif
}
+void WebViewImpl::didPerformDragOperation(bool handled)
+{
+#if WK_API_ENABLED
+ [m_view _web_didPerformDragOperation:handled];
+#else
+ UNUSED_PARAM(handled);
+#endif
+}
+
void WebViewImpl::writeToURLForFilePromiseProvider(NSFilePromiseProvider *provider, NSURL *fileURL, void(^completionHandler)(NSError *))
{
id userInfo = provider.userInfo;
@@ -3992,18 +4001,26 @@
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
#pragma clang diagnostic pop
- if (auto& attachmentInfo = item.promisedAttachmentInfo) {
- auto provider = adoptNS([[NSFilePromiseProvider alloc] initWithFileType:attachmentInfo.contentType delegate:(id <NSFilePromiseProviderDelegate>)m_view.getAutoreleased()]);
- [provider setUserInfo:[[[WKPromisedAttachmentContext alloc] initWithAttachmentInfo:attachmentInfo] autorelease]];
+ if (auto& info = item.promisedAttachmentInfo) {
+ NSString *utiType = info.contentType;
+ NSString *fileName = info.fileName;
+ if (auto attachment = m_page->attachmentForIdentifier(info.attachmentIdentifier)) {
+ utiType = attachment->utiType();
+ fileName = attachment->fileName();
+ }
+
+ auto provider = adoptNS([[NSFilePromiseProvider alloc] initWithFileType:utiType delegate:(id <NSFilePromiseProviderDelegate>)m_view.getAutoreleased()]);
+ auto context = adoptNS([[WKPromisedAttachmentContext alloc] initWithIdentifier:info.attachmentIdentifier blobURL:info.blobURL fileName:fileName]);
+ [provider setUserInfo:context.get()];
auto draggingItem = adoptNS([[NSDraggingItem alloc] initWithPasteboardWriter:provider.get()]);
[draggingItem setDraggingFrame:NSMakeRect(clientDragLocation.x(), clientDragLocation.y() - size.height(), size.width(), size.height()) contents:dragNSImage.get()];
[m_view beginDraggingSessionWithItems:@[draggingItem.get()] event:m_lastMouseDownEvent.get() source:(id <NSDraggingSource>)m_view.getAutoreleased()];
- ASSERT(attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size());
- if (attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size()) {
- for (size_t index = 0; index < attachmentInfo.additionalTypes.size(); ++index) {
- auto nsData = attachmentInfo.additionalData[index]->createNSData();
- [pasteboard setData:nsData.get() forType:attachmentInfo.additionalTypes[index]];
+ ASSERT(info.additionalTypes.size() == info.additionalData.size());
+ if (info.additionalTypes.size() == info.additionalData.size()) {
+ for (size_t index = 0; index < info.additionalTypes.size(); ++index) {
+ auto nsData = info.additionalData[index]->createNSData();
+ [pasteboard setData:nsData.get() forType:info.additionalTypes[index]];
}
}
m_page->didStartDrag();
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -210,6 +210,7 @@
#else
virtual void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle&) { }
#endif
+ virtual void didPerformDragOperation(bool) { }
#endif // ENABLE(DRAG_SUPPORT)
virtual void setCursor(const WebCore::Cursor&) = 0;
@@ -430,7 +431,6 @@
#endif
#if ENABLE(DATA_INTERACTION)
- virtual void didPerformDataInteractionControllerOperation(bool handled) = 0;
virtual void didHandleStartDataInteractionRequest(bool started) = 0;
virtual void didHandleAdditionalDragItemsRequest(bool added) = 0;
virtual void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>) = 0;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1870,6 +1870,11 @@
setDragCaretRect({ });
}
+void WebPageProxy::didPerformDragOperation(bool handled)
+{
+ m_pageClient.didPerformDragOperation(handled);
+}
+
void WebPageProxy::didStartDrag()
{
if (isValid())
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -628,7 +628,6 @@
void startAutoscrollAtPosition(const WebCore::FloatPoint& positionInWindow);
void cancelAutoscroll();
#if ENABLE(DATA_INTERACTION)
- void didPerformDataInteractionControllerOperation(bool handled);
void didHandleStartDataInteractionRequest(bool started);
void didHandleAdditionalDragItemsRequest(bool added);
void requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
@@ -923,6 +922,7 @@
void dragUpdated(WebCore::DragData&, const String& dragStorageName = String());
void dragExited(WebCore::DragData&, const String& dragStorageName = String());
void performDragOperation(WebCore::DragData&, const String& dragStorageName, SandboxExtension::Handle&&, SandboxExtension::HandleArray&&);
+ void didPerformDragOperation(bool handled);
void didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const WebCore::IntRect& insertionRect);
void dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-08-27 02:37:22 UTC (rev 235343)
@@ -321,8 +321,11 @@
StartDrag(struct WebKit::WebSelectionData selection, uint64_t dragOperation, WebKit::ShareableBitmap::Handle dragImage)
#endif
+#if ENABLE(DRAG_SUPPORT)
+ DidPerformDragOperation(bool handled)
+#endif
+
#if ENABLE(DATA_INTERACTION)
- DidPerformDataInteractionControllerOperation(bool handled)
DidHandleStartDataInteractionRequest(bool started)
DidHandleAdditionalDragItemsRequest(bool added)
DidConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData> textIndicator)
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -210,7 +210,7 @@
#endif
#if ENABLE(DATA_INTERACTION)
- void didPerformDataInteractionControllerOperation(bool handled) override;
+ void didPerformDragOperation(bool handled) override;
void didHandleStartDataInteractionRequest(bool started) override;
void didHandleAdditionalDragItemsRequest(bool added) override;
void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& image) override;
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -778,9 +778,9 @@
#endif
#if ENABLE(DATA_INTERACTION)
-void PageClientImpl::didPerformDataInteractionControllerOperation(bool handled)
+void PageClientImpl::didPerformDragOperation(bool handled)
{
- [m_contentView _didPerformDataInteractionControllerOperation:handled];
+ [m_contentView _didPerformDragOperation:handled];
}
void PageClientImpl::didHandleStartDataInteractionRequest(bool started)
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -341,7 +341,7 @@
#if ENABLE(DATA_INTERACTION)
- (void)_didChangeDragInteractionPolicy;
-- (void)_didPerformDataInteractionControllerOperation:(BOOL)handled;
+- (void)_didPerformDragOperation:(BOOL)handled;
- (void)_didHandleStartDataInteractionRequest:(BOOL)started;
- (void)_didHandleAdditionalDragItemsRequest:(BOOL)added;
- (void)_startDrag:(RetainPtr<CGImageRef>)image item:(const WebCore::DragItem&)item;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -5076,7 +5076,7 @@
}];
}
-- (void)_didPerformDataInteractionControllerOperation:(BOOL)handled
+- (void)_didPerformDragOperation:(BOOL)handled
{
RELEASE_LOG(DragAndDrop, "Finished performing drag controller operation (handled: %d)", handled);
[[WebItemProviderPasteboard sharedInstance] decrementPendingOperationCount];
@@ -5129,10 +5129,17 @@
RELEASE_LOG(DragAndDrop, "Drag session: %p preparing to drag blob: %s with attachment identifier: %s", session.get(), info.blobURL.string().utf8().data(), info.attachmentIdentifier.utf8().data());
+ NSString *utiType = info.contentType;
+ NSString *fileName = info.fileName;
+ if (auto attachment = _page->attachmentForIdentifier(info.attachmentIdentifier)) {
+ utiType = attachment->utiType();
+ fileName = attachment->fileName();
+ }
+
auto registrationList = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
[registrationList setPreferredPresentationStyle:WebPreferredPresentationStyleAttachment];
- if (!info.filename.isEmpty())
- [registrationList setSuggestedName:info.filename];
+ if ([fileName length])
+ [registrationList setSuggestedName:fileName];
if (numberOfAdditionalTypes == info.additionalData.size() && numberOfAdditionalTypes) {
for (size_t index = 0; index < numberOfAdditionalTypes; ++index) {
auto nsData = info.additionalData[index]->createNSData();
@@ -5140,7 +5147,7 @@
}
}
- [registrationList addPromisedType:info.contentType fileCallback:[session = WTFMove(session), weakSelf = WeakObjCPtr<WKContentView>(self), info] (WebItemProviderFileCallback callback) {
+ [registrationList addPromisedType:utiType fileCallback:[session = WTFMove(session), weakSelf = WeakObjCPtr<WKContentView>(self), info] (WebItemProviderFileCallback callback) {
auto strongSelf = weakSelf.get();
if (!strongSelf) {
callback(nil, [NSError errorWithDomain:WKErrorDomain code:WKErrorWebViewInvalidated userInfo:nil]);
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1088,11 +1088,6 @@
#if ENABLE(DATA_INTERACTION)
-void WebPageProxy::didPerformDataInteractionControllerOperation(bool handled)
-{
- m_pageClient.didPerformDataInteractionControllerOperation(handled);
-}
-
void WebPageProxy::didHandleStartDataInteractionRequest(bool started)
{
m_pageClient.didHandleStartDataInteractionRequest(started);
Modified: trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h 2018-08-27 02:37:22 UTC (rev 235343)
@@ -233,6 +233,10 @@
WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override;
bool effectiveAppearanceIsDark() const override;
+#if ENABLE(DRAG_SUPPORT)
+ void didPerformDragOperation(bool handled) final;
+#endif
+
#if WK_API_ENABLED
NSView *inspectorAttachmentView() override;
_WKRemoteObjectRegistry *remoteObjectRegistry() override;
Modified: trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm (235342 => 235343)
--- trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -874,6 +874,15 @@
return m_impl->window();
}
+#if ENABLE(DRAG_SUPPORT)
+
+void PageClientImpl::didPerformDragOperation(bool handled)
+{
+ m_impl->didPerformDragOperation(handled);
+}
+
+#endif
+
#if WK_API_ENABLED
NSView *PageClientImpl::inspectorAttachmentView()
{
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (235342 => 235343)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1811,6 +1811,8 @@
ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
EDCA71B7128DDA8C00201B26 /* WKBundlePageOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A22F1001289FCD90085E74F /* WKBundlePageOverlay.cpp */; };
F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F41056622130699A0092281D /* APIAttachmentCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F41056602130699A0092281D /* APIAttachmentCocoa.h */; };
+ F41056632130699A0092281D /* APIAttachmentCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = F41056612130699A0092281D /* APIAttachmentCocoa.mm */; };
F44291921FA591C9002CC93E /* _WKAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = F44291911FA59107002CC93E /* _WKAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; };
F44291941FA59311002CC93E /* _WKAttachment.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44291931FA59311002CC93E /* _WKAttachment.mm */; };
F44291961FA5942A002CC93E /* _WKAttachmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F44291951FA5942A002CC93E /* _WKAttachmentInternal.h */; };
@@ -4654,6 +4656,8 @@
ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = "<group>"; };
+ F41056602130699A0092281D /* APIAttachmentCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APIAttachmentCocoa.h; sourceTree = "<group>"; };
+ F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; };
F44291911FA59107002CC93E /* _WKAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKAttachment.h; sourceTree = "<group>"; };
F44291931FA59311002CC93E /* _WKAttachment.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKAttachment.mm; sourceTree = "<group>"; };
F44291951FA5942A002CC93E /* _WKAttachmentInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKAttachmentInternal.h; sourceTree = "<group>"; };
@@ -6209,6 +6213,8 @@
5CB237891DF0DD4300117AA3 /* _WKWebsitePolicies.h */,
5CB2378A1DF0DD4300117AA3 /* _WKWebsitePolicies.mm */,
5CB2378D1DF0E0C200117AA3 /* _WKWebsitePoliciesInternal.h */,
+ F41056602130699A0092281D /* APIAttachmentCocoa.h */,
+ F41056612130699A0092281D /* APIAttachmentCocoa.mm */,
7CEFA9601AC0999300B910FD /* APIContentRuleListStoreCocoa.mm */,
FED3C1DA1B447AE800E0EB7F /* APISerializedScriptValueCocoa.mm */,
1A3635AB1A3145E500ED6197 /* APIWebsiteDataStoreCocoa.mm */,
@@ -8998,6 +9004,7 @@
634842511FB26E7100946E3C /* APIApplicationManifest.h in Headers */,
BC64697011DBE603006455B0 /* APIArray.h in Headers */,
2E5C770E1FA7D429005932C3 /* APIAttachment.h in Headers */,
+ F41056622130699A0092281D /* APIAttachmentCocoa.h in Headers */,
99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */,
990D28C01C6553F100986977 /* APIAutomationSessionClient.h in Headers */,
1A3DD206125E5A2F004515E6 /* APIClient.h in Headers */,
@@ -10881,6 +10888,7 @@
2D92A784212B6AB100F493FD /* ActivityAssertion.cpp in Sources */,
BC64696F11DBE603006455B0 /* APIArray.cpp in Sources */,
2E5C770F1FA7D429005932C3 /* APIAttachment.cpp in Sources */,
+ F41056632130699A0092281D /* APIAttachmentCocoa.mm in Sources */,
7C89D2B31A6B068C003A5FDE /* APIContentRuleList.cpp in Sources */,
7C3A06A71AAB903E009D74BA /* APIContentRuleListStore.cpp in Sources */,
7CEFA9621AC0999300B910FD /* APIContentRuleListStoreCocoa.mm in Sources */,
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (235342 => 235343)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-27 02:37:22 UTC (rev 235343)
@@ -3459,11 +3459,7 @@
m_pendingDropSandboxExtension = nullptr;
m_pendingDropExtensionsForFileUpload.clear();
-#if ENABLE(DATA_INTERACTION)
- send(Messages::WebPageProxy::DidPerformDataInteractionControllerOperation(handled));
-#else
- UNUSED_PARAM(handled);
-#endif
+ send(Messages::WebPageProxy::DidPerformDragOperation(handled));
return;
}
}
Modified: trunk/Tools/ChangeLog (235342 => 235343)
--- trunk/Tools/ChangeLog 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Tools/ChangeLog 2018-08-27 02:37:22 UTC (rev 235343)
@@ -1,3 +1,39 @@
+2018-08-26 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments
+ https://bugs.webkit.org/show_bug.cgi?id=188933
+ <rdar://problem/43699724>
+
+ Reviewed by Darin Adler.
+
+ Rebaseline existing API tests that involve dropping or pasting image files, and additionally write some new
+ tests. These new tests exercise the following cases:
+ • Inserting and removing newlines before an inline image with an attachment element does not cause new
+ _WKAttachments to be created and destroyed.
+ • Pasting an image, cutting it, and then pasting it again propagates an attachment update to the UI
+ process with the original _WKAttachment.
+ • A pasted attachment in the document can be moved around by dragging, and doing so does not cause us to
+ lose a _WKAttachment.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+ (-[TestWKWebView expectElementCount:tagName:]):
+ (TestWebKitAPI::TEST):
+
+ Add the new tests described above, and also adjust existing tests to check that images are dropped or pasted
+ as image elements, but still have associated attachment elements whose attachment identifiers (observed via
+ script) match that of the corresponding _WKAttachment's uniqueIdentifier in the UI process.
+
+ * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm:
+ (-[DragAndDropSimulator runFrom:to:]):
+ (-[DragAndDropSimulator continueDragSession]):
+ (-[DragAndDropSimulator performDragInWebView:atLocation:withImage:pasteboard:source:]):
+
+ Teach DragAndDropSimulator on macOS to wait until the drop has been handled by the web process before returning
+ execution to the caller. This ensures that tests which involve dropping promised files as attachments aren't
+ flaky, due to how the promised data is retrieved asynchronously when performing the drop.
+
+ (-[DragAndDropSimulator _webView:didPerformDragOperation:]):
+
2018-08-26 Lucas Forschler <lforsch...@apple.com>
Open svn.webkit.org for commits.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (235342 => 235343)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -225,6 +225,12 @@
NSLog(@"Expected to find ordered tags: %@ in: %@", tagNames, tagsInBody);
}
+- (void)expectElementCount:(NSInteger)count tagName:(NSString *)tagName
+{
+ NSString *script = [NSString stringWithFormat:@"document.querySelectorAll('%@').length", tagName];
+ EXPECT_EQ(count, [self stringByEvaluatingJavaScript:script].integerValue);
+}
+
- (void)expectElementTag:(NSString *)tagName toComeBefore:(NSString *)otherTagName
{
[self expectElementTagsInOrder:@[tagName, otherTagName]];
@@ -779,7 +785,7 @@
[webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
}
-TEST(WKAttachmentTests, InsertPastedImageAsAttachment)
+TEST(WKAttachmentTests, RemoveNewlinesBeforePastedImage)
{
platformCopyPNG();
@@ -795,16 +801,76 @@
auto size = platformImageWithData([attachment info].data).size;
EXPECT_EQ(215., size.width);
EXPECT_EQ(174., size.height);
- EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
+ EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+ [webView stringByEvaluatingJavaScript:@"getSelection().collapse(document.body, 0)"];
{
ObserveAttachmentUpdatesForScope observer(webView.get());
- [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
+ [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
+ [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
+ [webView expectElementTagsInOrder:@[ @"BR", @"BR", @"IMG" ]];
+ }
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[attachment.get()], @[]);
+ [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
+ [webView expectElementCount:0 tagName:@"BR"];
}
}
+TEST(WKAttachmentTests, CutAndPastePastedImage)
+{
+ platformCopyPNG();
+
+ RetainPtr<_WKAttachment> attachment;
+ auto webView = webViewForTestingAttachments();
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+ EXPECT_EQ(1U, observer.observer().inserted.count);
+ attachment = observer.observer().inserted[0];
+ }
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
+ [webView _synchronouslyExecuteEditCommand:@"Cut" argument:nil];
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
+ }
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
+ }
+}
+
+TEST(WKAttachmentTests, MovePastedImageByDragging)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [configuration _setAttachmentElementEnabled:YES];
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
+ TestWKWebView *webView = [simulator webView];
+ [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];
+
+ platformCopyPNG();
+ [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+ [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
+ [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil];
+ [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
+ [webView expectElementTag:@"IMG" toComeBefore:@"STRONG"];
+ [webView expectElementCount:1 tagName:@"IMG"];
+
+ // Drag the attachment element to somewhere below the strong text.
+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 350)];
+
+ [webView expectElementTag:@"STRONG" toComeBefore:@"IMG"];
+ [webView expectElementCount:1 tagName:@"IMG"];
+ EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);
+
+ [simulator endDataTransfer];
+}
+
TEST(WKAttachmentTests, InsertPastedAttributedStringContainingImage)
{
platformCopyRichTextWithImage();
@@ -821,8 +887,7 @@
[attachment expectRequestedDataToBe:testImageData()];
EXPECT_WK_STREQ("Lorem ipsum dolor sit amet.", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
- EXPECT_WK_STREQ("image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
- EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
+ EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
{
ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -857,11 +922,11 @@
}
EXPECT_TRUE(zipAttachment && imageAttachment && pdfAttachment);
- EXPECT_EQ(3, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].integerValue);
- EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
- EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
+ [webView expectElementCount:2 tagName:@"ATTACHMENT"];
+ [webView expectElementCount:1 tagName:@"IMG"];
+ EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
- NSString *zipAttachmentType = [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[2].getAttribute('type')"];
+ NSString *zipAttachmentType = [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"];
#if USES_MODERN_ATTRIBUTED_STRING_CONVERSION
EXPECT_WK_STREQ("application/zip", zipAttachmentType);
#else
@@ -868,9 +933,9 @@
EXPECT_WK_STREQ("application/octet-stream", zipAttachmentType);
#endif
- EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].uniqueIdentifier"]);
- EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].uniqueIdentifier"]);
- EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[2].uniqueIdentifier"]);
+ EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+ EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].uniqueIdentifier"]);
+ EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].uniqueIdentifier"]);
{
ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -992,6 +1057,7 @@
}
[webView expectElementTagsInOrder:@[ @"IMG", @"ATTACHMENT", @"ATTACHMENT" ]];
EXPECT_WK_STREQ("cid:foo-bar", [webView valueOfAttribute:@"src" forQuerySelector:@"img"]);
+ EXPECT_WK_STREQ(@"", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('img')[0].webkitAttachmentIdentifier"]);
}
TEST(WKAttachmentTests, InjectedBundleReplaceURLWhenPastingImage)
@@ -1124,10 +1190,10 @@
// Drag the attachment element to somewhere below the strong text.
[simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(50, 300)];
- EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);
- [attachment expectRequestedDataToBe:data.get()];
EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ [attachment expectRequestedDataToBe:data.get()];
+ EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);
#if PLATFORM(MAC)
EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage));
#endif
@@ -1156,14 +1222,17 @@
EXPECT_EQ(2U, [insertedAttachments count]);
}
- NSArray<NSData *> *expectedAttachmentData = @[ testPDFData(), testImageData() ];
- EXPECT_TRUE([expectedAttachmentData containsObject:[insertedAttachments firstObject].info.data]);
- EXPECT_TRUE([expectedAttachmentData containsObject:[insertedAttachments lastObject].info.data]);
- EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
- EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
- EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
- EXPECT_WK_STREQ("icon.png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
+ [webView expectElementCount:1 tagName:@"ATTACHMENT"];
+ [webView expectElementCount:1 tagName:@"IMG"];
+ EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('type')"]);
+ EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('title')"]);
+ NSString *imageAttachmentIdentifier = [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"];
+ if ([testImageData() isEqualToData:[insertedAttachments firstObject].info.data])
+ EXPECT_WK_STREQ([insertedAttachments firstObject].uniqueIdentifier, imageAttachmentIdentifier);
+ else
+ EXPECT_WK_STREQ([insertedAttachments lastObject].uniqueIdentifier, imageAttachmentIdentifier);
+
for (_WKAttachment *attachment in insertedAttachments.get())
EXPECT_GT(attachment.info.filePath.length, 0U);
@@ -1188,12 +1257,11 @@
[simulator writePromisedFiles:@[ testPDFFileURL(), testImageFileURL() ]];
[simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];
- while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
- if ([simulator insertedAttachments].count == 2)
- break;
- }
- EXPECT_EQ(2, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]);
+ [webView expectElementCount:1 tagName:@"ATTACHMENT"];
+ [webView expectElementCount:1 tagName:@"IMG"];
+ EXPECT_EQ(2U, [simulator insertedAttachments].count);
+
auto insertedAttachments = retainPtr([simulator insertedAttachments]);
NSArray<NSData *> *expectedData = @[ testPDFData(), testImageData() ];
for (_WKAttachment *attachment in insertedAttachments.get()) {
@@ -1201,8 +1269,10 @@
EXPECT_TRUE([expectedData containsObject:attachment.info.data]);
if ([testPDFData() isEqualToData:attachment.info.data])
EXPECT_WK_STREQ("application/pdf", attachment.info.contentType);
- else if ([testImageData() isEqualToData:attachment.info.data])
+ else if ([testImageData() isEqualToData:attachment.info.data]) {
EXPECT_WK_STREQ("image/png", attachment.info.contentType);
+ EXPECT_WK_STREQ(attachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+ }
}
[webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
@@ -1209,7 +1279,8 @@
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
auto removedAttachments = retainPtr([simulator removedAttachments]);
EXPECT_EQ(2U, [removedAttachments count]);
- EXPECT_EQ(0, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]);
+ [webView expectElementCount:0 tagName:@"ATTACHMENT"];
+ [webView expectElementCount:0 tagName:@"IMG"];
EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments firstObject]]);
EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments lastObject]]);
}
@@ -1228,6 +1299,7 @@
NSArray<NSURL *> *urls = [simulator receivePromisedFiles];
EXPECT_EQ(1U, urls.count);
+ EXPECT_WK_STREQ("test.pdf", urls.lastObject.lastPathComponent);
EXPECT_TRUE([[NSData dataWithContentsOfURL:urls.firstObject] isEqualToData:testPDFData()]);
EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage));
}
@@ -1249,7 +1321,7 @@
EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
auto attachment = retainPtr([dragAndDropSimulator insertedAttachments].firstObject);
[attachment expectRequestedDataToBe:testImageData()];
- EXPECT_WK_STREQ("public.png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
{
ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -1277,7 +1349,7 @@
auto size = platformImageWithData([attachment info].data).size;
EXPECT_EQ(215., size.width);
EXPECT_EQ(174., size.height);
- EXPECT_WK_STREQ("image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
{
ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -1315,7 +1387,7 @@
for (_WKAttachment *attachment in [dragAndDropSimulator insertedAttachments])
EXPECT_GT([attachment info].data.length, 0U);
- EXPECT_EQ(2, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].intValue);
+ [webView expectElementCount:2 tagName:@"ATTACHMENT"];
EXPECT_WK_STREQ("hello.rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
EXPECT_WK_STREQ("text/rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
EXPECT_WK_STREQ("world.txt", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
@@ -1340,7 +1412,7 @@
EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
[[dragAndDropSimulator insertedAttachments].firstObject expectRequestedDataToBe:data];
- EXPECT_EQ(1, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].intValue);
+ [webView expectElementCount:1 tagName:@"ATTACHMENT"];
EXPECT_WK_STREQ("archive.zip", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ("application/zip", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
}
Modified: trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm (235342 => 235343)
--- trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-27 01:39:49 UTC (rev 235342)
+++ trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-27 02:37:22 UTC (rev 235343)
@@ -103,6 +103,7 @@
NSPoint _endLocationInWindow;
double _progress;
bool _doneWaitingForDraggingSession;
+ bool _doneWaitingForDrop;
}
@synthesize currentDragOperation=_currentDragOperation;
@@ -155,6 +156,7 @@
_insertedAttachments = adoptNS([NSMutableArray new]);
_removedAttachments = adoptNS([NSMutableArray new]);
_doneWaitingForDraggingSession = true;
+ _doneWaitingForDrop = true;
_startLocationInWindow = [self flipAboutXAxisInHostWindow:flippedStartLocation];
_endLocationInWindow = [self flipAboutXAxisInHostWindow:flippedEndLocation];
_currentDragOperation = NSDragOperationNone;
@@ -167,6 +169,7 @@
NSPoint startLocationInView = [_webView convertPoint:_startLocationInWindow fromView:nil];
NSImage *dragImage = self.externalDragImage ?: defaultExternalDragImage();
[self performDragInWebView:_webView.get() atLocation:startLocationInView withImage:dragImage pasteboard:pasteboard source:nil];
+ TestWebKitAPI::Util::run(&_doneWaitingForDrop);
return;
}
@@ -186,6 +189,8 @@
[_webView mouseUpAtPoint:_endLocationInWindow];
[_webView waitForPendingMouseEvents];
+
+ TestWebKitAPI::Util::run(&_doneWaitingForDrop);
}
- (void)beginDraggingSessionInWebView:(DragAndDropTestWKWebView *)webView withItems:(NSArray<NSDraggingItem *> *)items source:(id<NSDraggingSource>)source
@@ -238,9 +243,10 @@
if (_willEndDraggingHandler)
_willEndDraggingHandler();
- if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()])
+ if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) {
+ _doneWaitingForDrop = false;
[_webView performDragOperation:_draggingInfo.get()];
- else if (_currentDragOperation == NSDragOperationNone)
+ } else if (_currentDragOperation == NSDragOperationNone)
[_webView draggingExited:_draggingInfo.get()];
[_webView waitForNextPresentationUpdate];
[(id <NSDraggingSource>)_webView.get() draggingSession:_draggingSession.get() endedAtPoint:_endLocationInWindow operation:_currentDragOperation];
@@ -268,9 +274,10 @@
if (_willEndDraggingHandler)
_willEndDraggingHandler();
- if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()])
+ if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) {
+ _doneWaitingForDrop = false;
[_webView performDragOperation:_draggingInfo.get()];
- else if (_currentDragOperation == NSDragOperationNone)
+ } else if (_currentDragOperation == NSDragOperationNone)
[_webView draggingExited:_draggingInfo.get()];
[_webView waitForNextPresentationUpdate];
@@ -437,6 +444,8 @@
{
}
+#pragma mark - WKUIDelegatePrivate
+
- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source
{
[_insertedAttachments addObject:attachment];
@@ -447,6 +456,11 @@
[_removedAttachments addObject:attachment];
}
+- (void)_webView:(WKWebView *)webView didPerformDragOperation:(BOOL)handled
+{
+ _doneWaitingForDrop = true;
+}
+
@end
#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC) && WK_API_ENABLED