Changeset 235343 in webkit
- Timestamp:
- Aug 26, 2018 7:37:22 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r235342 r235343 1 2018-08-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments 4 https://bugs.webkit.org/show_bug.cgi?id=188933 5 <rdar://problem/43699724> 6 7 Reviewed by Darin Adler. 8 9 Support the ability to drop and paste images as image elements, with attachment elements, only if attachment 10 elements are enabled. See changes below for more detail. 11 12 Tests: WKAttachmentTests.CutAndPastePastedImage 13 WKAttachmentTests.MovePastedImageByDragging 14 WKAttachmentTests.RemoveNewlinesBeforePastedImage 15 16 * editing/Editor.h: 17 * editing/cocoa/EditorCocoa.mm: 18 (WebCore::Editor::getPasteboardTypesAndDataForAttachment): 19 20 Adjust this helper to take an Element& rather than an HTMLAttachmentElement&, and address a FIXME by writing the 21 document origin identifier to the pasteboard via custom pasteboard data when dragging an attachment. This allows 22 us to avoid creating extra image and attachment elements when dragging an image backed by an attachment within 23 the same document. 24 25 * editing/cocoa/WebContentReaderCocoa.mm: 26 (WebCore::contentTypeIsSuitableForInlineImageRepresentation): 27 28 Add a helper to determine whether a content type (UTI or MIME type) should be read as an inline image. 29 30 (WebCore::createFragmentForImageAttachment): 31 (WebCore::replaceRichContentWithAttachments): 32 (WebCore::WebContentReader::readFilePaths): 33 34 Teach codepaths where we currently create attachment elements to instead create image elements if the MIME type, 35 is something suitable for display via an inline image element; add the attachment element under the shadow root 36 of the image element. 37 38 * editing/markup.cpp: 39 (WebCore::StyledMarkupAccumulator::appendCustomAttributes): 40 (WebCore::restoreAttachmentElementsInFragment): 41 42 When dragging or copying an image element, we need to make sure that any attachment element backing the image 43 is preserved in the pasted or dropped fragment. To do this, we use a technique similar to what was done for 44 r180785 and r224593 and write a temporary "webkitattachmentid" attribute to the serialized markup on copy. Upon 45 deserializing the markup back to a fragment, we then create an attachment element with the same identifier under 46 the image. 47 48 (WebCore::createFragmentFromMarkup): 49 * html/HTMLAttachmentElement.h: 50 * html/HTMLImageElement.cpp: 51 (WebCore::HTMLImageElement::setAttachmentElement): 52 (WebCore::HTMLImageElement::attachmentElement const): 53 54 Helper methods to get and set an attachment element under an image element. Setting an image's attachment 55 element puts that attachment element under the shadow root of the image, and also hides the attachment element. 56 57 (WebCore::HTMLImageElement::attachmentIdentifier const): 58 59 Returns the identifier of an attachment element associated with the image element, or null. 60 61 * html/HTMLImageElement.h: 62 * html/HTMLImageElement.idl: 63 64 Add HTMLImageElement.webkitAttachmentIdentifier, a readonly attribute guarded by runtime-enabled attachment 65 element feature. 66 67 * page/DragController.cpp: 68 (WebCore::DragController::startDrag): 69 70 In the case of dragging an image, if that image element is backed by an attachment element, don't bother writing 71 the image data to the clipboard; instead, write the attachment data as a promise. 72 73 (WebCore::DragController::doImageDrag): 74 75 Plumb promised attachment information to DragController::doSystemDrag. 76 77 (WebCore::DragController::promisedAttachmentInfo): 78 79 Teach this to handle attachment elements as well as image elements that are backed by attachment elements. 80 81 * page/DragController.h: 82 * platform/PromisedAttachmentInfo.h: 83 (WebCore::PromisedAttachmentInfo::operator bool const): 84 85 A valid PromisedAttachmentInfo no longer requires a contentType to be set; instead, an attachment identifier 86 alone is sufficient, since an up-to-date content type can be requested in the UI process from the API attachment 87 object. 88 1 89 2018-08-26 Andy Estes <aestes@apple.com> 2 90 -
trunk/Source/WebCore/editing/Editor.h
r235137 r235343 512 512 513 513 #if PLATFORM(COCOA) 514 void getPasteboardTypesAndDataForAttachment( HTMLAttachmentElement&, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData);514 void getPasteboardTypesAndDataForAttachment(Element&, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData); 515 515 #endif 516 516 #endif -
trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm
r235202 r235343 161 161 #if ENABLE(ATTACHMENT_ELEMENT) 162 162 163 void Editor::getPasteboardTypesAndDataForAttachment(HTMLAttachmentElement& attachment, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData) 164 { 165 auto attachmentRange = Range::create(attachment.document(), { &attachment, Position::PositionIsBeforeAnchor }, { &attachment, Position::PositionIsAfterAnchor }); 166 client()->getClientPasteboardDataForRange(attachmentRange.ptr(), outTypes, outData); 167 // FIXME: We should additionally write the attachment as a web archive here, such that drag and drop within the 168 // same page doesn't destroy and recreate attachments unnecessarily. This is also needed to preserve the attachment 169 // display mode when dragging and dropping or cutting and pasting. For the time being, this is disabled because 170 // inserting attachment elements from web archive data sometimes causes attachment data to be lost; this requires 171 // further investigation. 172 #if PLATFORM(MAC) 173 // 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 174 // quite yet without breaking drag moves. This investigation is tracked in <https://bugs.webkit.org/show_bug.cgi?id=181514>. 175 // See the above FIXME for more details. 176 if (auto archive = LegacyWebArchive::create(attachmentRange.ptr())) { 163 void Editor::getPasteboardTypesAndDataForAttachment(Element& element, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData) 164 { 165 auto& document = element.document(); 166 auto elementRange = Range::create(document, { &element, Position::PositionIsBeforeAnchor }, { &element, Position::PositionIsAfterAnchor }); 167 client()->getClientPasteboardDataForRange(elementRange.ptr(), outTypes, outData); 168 169 outTypes.append(PasteboardCustomData::cocoaType()); 170 outData.append(PasteboardCustomData { document.originIdentifierForPasteboard(), { }, { }, { } }.createSharedBuffer()); 171 172 if (auto archive = LegacyWebArchive::create(elementRange.ptr())) { 177 173 if (auto webArchiveData = archive->rawDataRepresentation()) { 178 174 outTypes.append(WebArchivePboardType); … … 180 176 } 181 177 } 182 #endif183 178 } 184 179 -
trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
r235137 r235343 48 48 #import "HTMLObjectElement.h" 49 49 #import "LegacyWebArchive.h" 50 #import "MIMETypeRegistry.h" 50 51 #import "Page.h" 51 52 #import "PublicURLManager.h" … … 208 209 #if ENABLE(ATTACHMENT_ELEMENT) 209 210 211 static bool contentTypeIsSuitableForInlineImageRepresentation(const String& contentType) 212 { 213 return MIMETypeRegistry::isSupportedImageMIMEType(isDeclaredUTI(contentType) ? MIMETypeFromUTI(contentType) : contentType); 214 } 215 210 216 static bool supportsClientSideAttachmentData(const Frame& frame) 211 217 { … … 225 231 String defaultImageAttachmentName { "image"_s }; 226 232 233 auto fragment = document.createDocumentFragment(); 227 234 if (supportsClientSideAttachmentData(frame)) { 228 attachment->updateAttributes(buffer->size(), contentType, defaultImageAttachmentName);229 235 frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, defaultImageAttachmentName, WTFMove(buffer)); 230 } else 236 if (contentTypeIsSuitableForInlineImageRepresentation(contentType)) { 237 auto image = HTMLImageElement::create(document); 238 image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, Blob::create(buffer.get(), contentType))); 239 image->setAttachmentElement(WTFMove(attachment)); 240 fragment->appendChild(WTFMove(image)); 241 } else { 242 attachment->updateAttributes(buffer->size(), contentType, defaultImageAttachmentName); 243 fragment->appendChild(WTFMove(attachment)); 244 } 245 } else { 231 246 attachment->setFile(File::create(Blob::create(buffer.get(), contentType), defaultImageAttachmentName), HTMLAttachmentElement::UpdateDisplayAttributes::Yes); 232 233 auto fragment = document.createDocumentFragment(); 234 fragment->appendChild(attachment); 235 247 fragment->appendChild(WTFMove(attachment)); 248 } 236 249 return fragment; 237 250 #else … … 244 257 { 245 258 #if ENABLE(ATTACHMENT_ELEMENT) 246 struct Attachment ReplacementInfo {259 struct AttachmentInsertionInfo { 247 260 String fileName; 248 261 String contentType; 249 262 Ref<SharedBuffer> data; 250 Ref<Element> elementToReplace;263 Ref<Element> originalElement; 251 264 }; 252 265 … … 264 277 265 278 Vector<Ref<Element>> elementsToRemove; 266 Vector<Attachment ReplacementInfo> attachmentReplacementInfo;279 Vector<AttachmentInsertionInfo> attachmentInsertionInfo; 267 280 for (auto& image : descendantsOfType<HTMLImageElement>(fragment)) { 268 281 auto resourceURLString = image.attributeWithoutSynchronization(HTMLNames::srcAttr); … … 278 291 name = AtomicString("media"); 279 292 280 attachment ReplacementInfo.append({ name, resource->value->mimeType(), resource->value->data(), image });293 attachmentInsertionInfo.append({ name, resource->value->mimeType(), resource->value->data(), image }); 281 294 } 282 295 … … 296 309 name = AtomicString("file"); 297 310 298 attachment ReplacementInfo.append({ name, resource->value->mimeType(), resource->value->data(), object });299 } 300 301 for (auto& info : attachment ReplacementInfo) {302 auto elementToReplace = WTFMove(info.elementToReplace);303 auto parent = makeRefPtr( elementToReplace->parentNode());311 attachmentInsertionInfo.append({ name, resource->value->mimeType(), resource->value->data(), object }); 312 } 313 314 for (auto& info : attachmentInsertionInfo) { 315 auto originalElement = WTFMove(info.originalElement); 316 auto parent = makeRefPtr(originalElement->parentNode()); 304 317 if (!parent) 305 318 continue; … … 307 320 auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, fragment.document()); 308 321 if (supportsClientSideAttachmentData(frame)) { 309 attachment->updateAttributes(info.data->size(), info.contentType, info.fileName); 322 if (is<HTMLImageElement>(originalElement.get()) && contentTypeIsSuitableForInlineImageRepresentation(info.contentType)) { 323 auto& image = downcast<HTMLImageElement>(originalElement.get()); 324 image.setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(*frame.document(), Blob::create(info.data, info.contentType))); 325 image.setAttachmentElement(WTFMove(attachment)); 326 } else { 327 attachment->updateAttributes(info.data->size(), info.contentType, info.fileName); 328 parent->replaceChild(attachment, WTFMove(originalElement)); 329 } 310 330 frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), WTFMove(info.contentType), WTFMove(info.fileName), WTFMove(info.data)); 311 } else 312 attachment->setFile(File::create(Blob::create( info.data, info.contentType), info.fileName), HTMLAttachmentElement::UpdateDisplayAttributes::Yes);313 314 parent->replaceChild(attachment, elementToReplace);331 } else { 332 attachment->setFile(File::create(Blob::create(WTFMove(info.data), WTFMove(info.contentType)), WTFMove(info.fileName)), HTMLAttachmentElement::UpdateDisplayAttributes::Yes); 333 parent->replaceChild(WTFMove(attachment), WTFMove(originalElement)); 334 } 315 335 } 316 336 … … 685 705 FileSystem::getFileSize(path, fileSize); 686 706 auto contentType = File::contentTypeForFile(path); 687 attachment->updateAttributes(fileSize, contentType, FileSystem::pathGetFileName(path));688 707 frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, path); 689 } else 708 if (contentTypeIsSuitableForInlineImageRepresentation(contentType)) { 709 auto image = HTMLImageElement::create(document); 710 image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, File::create(path))); 711 image->setAttachmentElement(WTFMove(attachment)); 712 fragment->appendChild(image); 713 } else { 714 attachment->updateAttributes(fileSize, contentType, FileSystem::pathGetFileName(path)); 715 fragment->appendChild(attachment); 716 } 717 } else { 690 718 attachment->setFile(File::create(path), HTMLAttachmentElement::UpdateDisplayAttributes::Yes); 691 692 fragment->appendChild(attachment);719 fragment->appendChild(attachment); 720 } 693 721 } 694 722 } -
trunk/Source/WebCore/editing/markup.cpp
r234278 r235343 68 68 #include "Range.h" 69 69 #include "RenderBlock.h" 70 #include "RuntimeEnabledFeatures.h" 70 71 #include "Settings.h" 71 72 #include "SocketProvider.h" … … 407 408 { 408 409 #if ENABLE(ATTACHMENT_ELEMENT) 409 if (! is<HTMLAttachmentElement>(element))410 if (!RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled()) 410 411 return; 411 412 412 const HTMLAttachmentElement& attachment = downcast<HTMLAttachmentElement>(element); 413 appendAttribute(out, element, { webkitattachmentidAttr, attachment.uniqueIdentifier() }, namespaces); 414 if (auto* file = attachment.file()) { 415 // These attributes are only intended for File deserialization, and are removed from the generated attachment 416 // element after we've deserialized and set its backing File. 417 appendAttribute(out, element, { webkitattachmentpathAttr, file->path() }, namespaces); 418 appendAttribute(out, element, { webkitattachmentbloburlAttr, file->url().string() }, namespaces); 413 if (is<HTMLAttachmentElement>(element)) { 414 auto& attachment = downcast<HTMLAttachmentElement>(element); 415 appendAttribute(out, element, { webkitattachmentidAttr, attachment.uniqueIdentifier() }, namespaces); 416 if (auto* file = attachment.file()) { 417 // These attributes are only intended for File deserialization, and are removed from the generated attachment 418 // element after we've deserialized and set its backing File, in restoreAttachmentElementsInFragment. 419 appendAttribute(out, element, { webkitattachmentpathAttr, file->path() }, namespaces); 420 appendAttribute(out, element, { webkitattachmentbloburlAttr, file->url().string() }, namespaces); 421 } 422 } else if (is<HTMLImageElement>(element)) { 423 if (auto attachment = downcast<HTMLImageElement>(element).attachmentElement()) 424 appendAttribute(out, element, { webkitattachmentidAttr, attachment->uniqueIdentifier() }, namespaces); 419 425 } 420 426 #else … … 882 888 } 883 889 884 Ref<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy) 885 { 886 // We use a fake body element here to trick the HTML parser to using the InBody insertion mode. 887 auto fakeBody = HTMLBodyElement::create(document); 888 auto fragment = DocumentFragment::create(document); 889 890 fragment->parseHTML(markup, fakeBody.ptr(), parserContentPolicy); 891 890 static void restoreAttachmentElementsInFragment(DocumentFragment& fragment) 891 { 892 892 #if ENABLE(ATTACHMENT_ELEMENT) 893 if (!RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled()) 894 return; 895 893 896 // When creating a fragment we must strip the webkit-attachment-path attribute after restoring the File object. 894 897 Vector<Ref<HTMLAttachmentElement>> attachments; … … 906 909 attachment->setFile(File::deserialize({ }, blobURL, attachment->attachmentType(), attachment->attachmentTitle())); 907 910 911 // Remove temporary attributes that were previously added in StyledMarkupAccumulator::appendCustomAttributes. 908 912 attachment->removeAttribute(webkitattachmentidAttr); 909 913 attachment->removeAttribute(webkitattachmentpathAttr); 910 914 attachment->removeAttribute(webkitattachmentbloburlAttr); 911 915 } 916 917 Vector<Ref<HTMLImageElement>> images; 918 for (auto& image : descendantsOfType<HTMLImageElement>(fragment)) 919 images.append(image); 920 921 for (auto& image : images) { 922 auto attachmentIdentifier = image->attributeWithoutSynchronization(webkitattachmentidAttr); 923 if (attachmentIdentifier.isEmpty()) 924 continue; 925 926 auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, *fragment.ownerDocument()); 927 attachment->setUniqueIdentifier(attachmentIdentifier); 928 image->setAttachmentElement(WTFMove(attachment)); 929 image->removeAttribute(webkitattachmentidAttr); 930 } 931 #else 932 UNUSED_PARAM(fragment); 912 933 #endif 934 } 935 936 Ref<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy) 937 { 938 // We use a fake body element here to trick the HTML parser into using the InBody insertion mode. 939 auto fakeBody = HTMLBodyElement::create(document); 940 auto fragment = DocumentFragment::create(document); 941 942 fragment->parseHTML(markup, fakeBody.ptr(), parserContentPolicy); 943 restoreAttachmentElementsInFragment(fragment); 913 944 if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseURL()) 914 945 completeURLs(fragment.ptr(), baseURL); -
trunk/Source/WebCore/html/HTMLAttachmentElement.h
r235137 r235343 47 47 void setFile(RefPtr<File>&&, UpdateDisplayAttributes = UpdateDisplayAttributes::No); 48 48 49 StringuniqueIdentifier() const { return m_uniqueIdentifier; }49 const String& uniqueIdentifier() const { return m_uniqueIdentifier; } 50 50 void setUniqueIdentifier(const String& uniqueIdentifier) { m_uniqueIdentifier = uniqueIdentifier; } 51 51 -
trunk/Source/WebCore/html/HTMLImageElement.cpp
r234610 r235343 27 27 #include "CSSValueKeywords.h" 28 28 #include "CachedImage.h" 29 #include "ElementIterator.h" 29 30 #include "FrameView.h" 30 31 #include "HTMLAnchorElement.h" 32 #include "HTMLAttachmentElement.h" 31 33 #include "HTMLDocument.h" 32 34 #include "HTMLFormElement.h" … … 604 606 } 605 607 608 #if ENABLE(ATTACHMENT_ELEMENT) 609 610 void HTMLImageElement::setAttachmentElement(Ref<HTMLAttachmentElement>&& attachment) 611 { 612 if (auto existingAttachment = attachmentElement()) 613 existingAttachment->remove(); 614 615 attachment->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone, true); 616 ensureUserAgentShadowRoot().appendChild(WTFMove(attachment)); 617 } 618 619 RefPtr<HTMLAttachmentElement> HTMLImageElement::attachmentElement() const 620 { 621 if (auto shadowRoot = userAgentShadowRoot()) 622 return childrenOfType<HTMLAttachmentElement>(*shadowRoot).first(); 623 624 return nullptr; 625 } 626 627 const String& HTMLImageElement::attachmentIdentifier() const 628 { 629 if (auto attachment = attachmentElement()) 630 return attachment->uniqueIdentifier(); 631 632 return nullAtom(); 633 } 634 635 #endif // ENABLE(ATTACHMENT_ELEMENT) 636 606 637 #if ENABLE(SERVICE_CONTROLS) 607 638 void HTMLImageElement::updateImageControls() -
trunk/Source/WebCore/html/HTMLImageElement.h
r231329 r235343 32 32 namespace WebCore { 33 33 34 class HTMLAttachmentElement; 34 35 class HTMLFormElement; 35 36 class HTMLMapElement; … … 90 91 #if PLATFORM(IOS) 91 92 bool willRespondToMouseClickEvents() override; 93 #endif 94 95 #if ENABLE(ATTACHMENT_ELEMENT) 96 void setAttachmentElement(Ref<HTMLAttachmentElement>&&); 97 RefPtr<HTMLAttachmentElement> attachmentElement() const; 98 const String& attachmentIdentifier() const; 92 99 #endif 93 100 -
trunk/Source/WebCore/html/HTMLImageElement.idl
r225616 r235343 43 43 [Reflect] attribute DOMString decoding; 44 44 45 [Conditional=ATTACHMENT_ELEMENT, EnabledAtRuntime=AttachmentElement, ImplementedAs=attachmentIdentifier] readonly attribute DOMString webkitAttachmentIdentifier; 46 45 47 // Extensions 46 48 readonly attribute boolean complete; -
trunk/Source/WebCore/page/DragController.cpp
r235137 r235343 911 911 includeShadowDOM = state.source->isMediaElement(); 912 912 #endif 913 #if ENABLE(ATTACHMENT_ELEMENT)914 includeShadowDOM = includeShadowDOM || is<HTMLAttachmentElement>(state.source.get());915 #endif916 913 #if ENABLE(INPUT_TYPE_COLOR) 917 914 bool isColorControl = is<HTMLInputElement>(state.source) && downcast<HTMLInputElement>(*state.source).isColorControl(); … … 1049 1046 // This is an early detection for problems encountered later upon drop. 1050 1047 ASSERT(!image->filenameExtension().isEmpty()); 1048 1049 #if ENABLE(ATTACHMENT_ELEMENT) 1050 auto attachmentInfo = promisedAttachmentInfo(src, element); 1051 #else 1052 PromisedAttachmentInfo attachmentInfo; 1053 #endif 1054 1051 1055 if (hasData == HasNonDefaultPasteboardData::No) { 1052 1056 m_draggingImageURL = imageURL; 1053 1057 if (element.isContentRichlyEditable()) 1054 1058 selectElement(element); 1055 declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString()); 1059 if (!attachmentInfo) 1060 declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString()); 1056 1061 } 1057 1062 … … 1059 1064 1060 1065 if (!dragImage) 1061 doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state );1066 doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo)); 1062 1067 else { 1063 1068 // DHTML defined drag image 1064 doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });1069 doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, WTFMove(attachmentInfo)); 1065 1070 } 1066 1071 … … 1201 1206 } 1202 1207 1203 void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Frame& frame, IntPoint& dragImageOffset, const DragState& state )1208 void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Frame& frame, IntPoint& dragImageOffset, const DragState& state, PromisedAttachmentInfo&& attachmentInfo) 1204 1209 { 1205 1210 IntPoint mouseDownPoint = dragOrigin; … … 1244 1249 1245 1250 dragImageOffset = mouseDownPoint + scaledOrigin; 1246 doSystemDrag(WTFMove(dragImage), dragImageOffset, dragOrigin, frame, state, { });1251 doSystemDrag(WTFMove(dragImage), dragImageOffset, dragOrigin, frame, state, WTFMove(attachmentInfo)); 1247 1252 } 1248 1253 … … 1368 1373 #if ENABLE(ATTACHMENT_ELEMENT) 1369 1374 1370 PromisedAttachmentInfo DragController::promisedAttachmentInfo(Frame& frame, HTMLAttachmentElement& attachment) 1371 { 1375 PromisedAttachmentInfo DragController::promisedAttachmentInfo(Frame& frame, Element& element) 1376 { 1377 auto* client = frame.editor().client(); 1378 if (!client || !client->supportsClientSideAttachmentData()) 1379 return { }; 1380 1381 RefPtr<HTMLAttachmentElement> attachment; 1382 if (is<HTMLAttachmentElement>(element)) 1383 attachment = &downcast<HTMLAttachmentElement>(element); 1384 else if (is<HTMLImageElement>(element)) 1385 attachment = downcast<HTMLImageElement>(element).attachmentElement(); 1386 1387 if (!attachment) 1388 return { }; 1389 1372 1390 Vector<String> additionalTypes; 1373 1391 Vector<RefPtr<SharedBuffer>> additionalData; 1374 1392 #if PLATFORM(COCOA) 1375 if (frame.editor().client()) 1376 frame.editor().getPasteboardTypesAndDataForAttachment(attachment, additionalTypes, additionalData); 1377 #endif 1378 1379 if (auto* file = attachment.file()) 1380 return { file->url(), platformContentTypeForBlobType(file->type()), file->name(), attachment.uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) }; 1381 1382 return { { }, platformContentTypeForBlobType(attachment.attachmentType()), attachment.attachmentTitle(), attachment.uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) }; 1393 frame.editor().getPasteboardTypesAndDataForAttachment(element, additionalTypes, additionalData); 1394 #endif 1395 1396 if (auto* file = attachment->file()) 1397 return { file->url(), platformContentTypeForBlobType(file->type()), file->name(), { }, WTFMove(additionalTypes), WTFMove(additionalData) }; 1398 1399 return { { }, { }, { }, attachment->uniqueIdentifier(), WTFMove(additionalTypes), WTFMove(additionalData) }; 1383 1400 } 1384 1401 -
trunk/Source/WebCore/page/DragController.h
r235137 r235343 41 41 class Frame; 42 42 class FrameSelection; 43 class HTMLAttachmentElement;44 43 class HTMLInputElement; 45 44 class IntRect; … … 116 115 bool shouldUseCachedImageForDragImage(const Image&) const; 117 116 118 void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState& );117 void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState&, PromisedAttachmentInfo&&); 119 118 void doSystemDrag(DragImage, const IntPoint&, const IntPoint&, Frame&, const DragState&, PromisedAttachmentInfo&&); 120 119 … … 136 135 137 136 #if ENABLE(ATTACHMENT_ELEMENT) 138 PromisedAttachmentInfo promisedAttachmentInfo(Frame&, HTMLAttachmentElement&);137 PromisedAttachmentInfo promisedAttachmentInfo(Frame&, Element&); 139 138 #endif 140 139 Page& m_page; -
trunk/Source/WebCore/platform/PromisedAttachmentInfo.h
r235137 r235343 37 37 URL blobURL; 38 38 String contentType; 39 String file name;39 String fileName; 40 40 41 41 #if ENABLE(ATTACHMENT_ELEMENT) … … 48 48 operator bool() const 49 49 { 50 if (contentType.isEmpty())51 return false;52 53 50 #if ENABLE(ATTACHMENT_ELEMENT) 54 51 if (!attachmentIdentifier.isEmpty()) … … 56 53 #endif 57 54 58 return ! blobURL.isEmpty();55 return !contentType.isEmpty() && !blobURL.isEmpty(); 59 56 } 60 57 }; -
trunk/Source/WebKit/ChangeLog
r235332 r235343 1 2018-08-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments 4 https://bugs.webkit.org/show_bug.cgi?id=188933 5 <rdar://problem/43699724> 6 7 Reviewed by Darin Adler. 8 9 Support the ability to drop and paste images as image elements, with attachment elements, only if attachment 10 elements are enabled. See changes below for more detail. 11 12 * Shared/WebCoreArgumentCoders.cpp: 13 (IPC::ArgumentCoder<PromisedAttachmentInfo>::encode): 14 (IPC::ArgumentCoder<PromisedAttachmentInfo>::decode): 15 16 Rename "filename" to "fileName", for consistency with WKContentView and WebViewImpl. 17 18 * UIProcess/API/APIAttachment.cpp: 19 (API::Attachment::mimeType const): 20 (API::Attachment::fileName const): 21 * UIProcess/API/APIAttachment.h: 22 23 Push getters for MIME type, UTI, and the file name down from _WKAttachment to API::Attachment. This allows 24 WKContentView and WebViewImpl to ask an API::Attachment questions about its UTI and file name without 25 additionally creating a wrapper object. 26 27 * UIProcess/API/Cocoa/APIAttachmentCocoa.mm: Added. 28 (API::mimeTypeInferredFromFileExtension): 29 (API::isDeclaredOrDynamicTypeIdentifier): 30 (API::Attachment::mimeType const): 31 (API::Attachment::utiType const): 32 (API::Attachment::fileName const): 33 * UIProcess/API/Cocoa/WKUIDelegatePrivate.h: 34 35 Add a private delegate hook to notify the UI delegate when a drop has been performed. This is used by tests to 36 know when a drop with file promises has been processed by the page. 37 38 * UIProcess/API/Cocoa/WKWebView.mm: 39 (-[WKWebView _web_didPerformDragOperation:]): 40 * UIProcess/API/Cocoa/_WKAttachment.mm: 41 (-[_WKAttachmentInfo initWithFileWrapper:filePath:mimeType:utiType:]): 42 (-[_WKAttachmentInfo fileWrapper]): 43 (-[_WKAttachmentInfo contentType]): 44 (-[_WKAttachment info]): 45 (-[_WKAttachmentInfo initWithFileWrapper:filePath:contentType:]): Deleted. 46 (isDeclaredOrDynamicTypeIdentifier): Deleted. 47 (-[_WKAttachmentInfo _typeIdentifierFromPathExtension]): Deleted. 48 (-[_WKAttachmentInfo mimeType]): Deleted. 49 (-[_WKAttachmentInfo utiType]): Deleted. 50 51 Moved to APIAttachmentCocoa.mm. 52 53 * UIProcess/API/mac/WKView.mm: 54 (-[WKView _web_didPerformDragOperation:]): 55 * UIProcess/Cocoa/WebViewImpl.h: 56 * UIProcess/Cocoa/WebViewImpl.mm: 57 (-[WKPromisedAttachmentContext initWithIdentifier:blobURL:fileName:]): 58 59 Adjust this constructor to take each piece of data separately. This is because, in the case where our 60 PromisedAttachmentInfo contains an attachment identifier, we determine the UTI and file name from the associated 61 file wrapper. 62 63 (-[WKPromisedAttachmentContext fileName]): 64 (WebKit::WebViewImpl::fileNameForFilePromiseProvider): 65 (WebKit::WebViewImpl::didPerformDragOperation): 66 (WebKit::WebViewImpl::startDrag): 67 68 Determine UTI and file name from the attachment element corresponding to the attachment identifier when 69 dragging. This is because the attachment element in the web process shouldn't need to have type and title 70 attributes set when starting a drag if it already has an identifier that maps to attachment data in the UI 71 process. An example of this is in inline images backed by attachments, for which we don't need to bother keeping 72 specifying display attributes, since they are never visible. 73 74 (-[WKPromisedAttachmentContext initWithAttachmentInfo:]): Deleted. 75 (-[WKPromisedAttachmentContext filename]): Deleted. 76 * UIProcess/PageClient.h: 77 (WebKit::PageClient::didPerformDragOperation): 78 * UIProcess/WebPageProxy.cpp: 79 (WebKit::WebPageProxy::didPerformDragOperation): 80 * UIProcess/WebPageProxy.h: 81 * UIProcess/WebPageProxy.messages.in: 82 83 Rename DidPerformDataInteractionControllerOperation to DidPerformDragOperation, and make it cross-platform (this 84 was previously only sent on iOS). Add plumbing through PageClient and friends on macOS to notify the UI 85 delegate when a drop is handled by the web process. 86 87 * UIProcess/ios/PageClientImplIOS.h: 88 * UIProcess/ios/PageClientImplIOS.mm: 89 (WebKit::PageClientImpl::didPerformDragOperation): 90 (WebKit::PageClientImpl::didPerformDataInteractionControllerOperation): Deleted. 91 * UIProcess/ios/WKContentViewInteraction.h: 92 * UIProcess/ios/WKContentViewInteraction.mm: 93 (-[WKContentView _didPerformDragOperation:]): 94 (-[WKContentView _prepareToDragPromisedAttachment:]): 95 96 Just like in WebViewImpl::startDrag, infer content type and file name from the API attachment object. 97 98 (-[WKContentView _didPerformDataInteractionControllerOperation:]): Deleted. 99 * UIProcess/ios/WebPageProxyIOS.mm: 100 (WebKit::WebPageProxy::didPerformDataInteractionControllerOperation): Deleted. 101 * UIProcess/mac/PageClientImplMac.h: 102 * UIProcess/mac/PageClientImplMac.mm: 103 (WebKit::PageClientImpl::didPerformDragOperation): 104 * WebKit.xcodeproj/project.pbxproj: 105 * WebProcess/WebPage/WebPage.cpp: 106 (WebKit::WebPage::performDragControllerAction): 107 1 108 2018-08-23 Jeff Miller <jeffm@apple.com> 2 109 -
trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
r235137 r235343 2868 2868 encoder << info.blobURL; 2869 2869 encoder << info.contentType; 2870 encoder << info.file name;2870 encoder << info.fileName; 2871 2871 #if ENABLE(ATTACHMENT_ELEMENT) 2872 2872 encoder << info.attachmentIdentifier; … … 2883 2883 return false; 2884 2884 2885 if (!decoder.decode(info.file name))2885 if (!decoder.decode(info.fileName)) 2886 2886 return false; 2887 2887 -
trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp
r235156 r235343 82 82 } 83 83 84 #if !PLATFORM(COCOA) 85 86 WTF::String Attachment::mimeType() const 87 { 88 return m_contentType; 89 } 90 91 WTF::String Attachment::fileName() const 92 { 93 return { }; 94 } 95 96 #endif // !PLATFORM(COCOA) 97 84 98 } 85 99 -
trunk/Source/WebKit/UIProcess/API/APIAttachment.h
r235156 r235343 65 65 NSFileWrapper *fileWrapper() const { return m_fileWrapper.get(); } 66 66 void setFileWrapper(NSFileWrapper *fileWrapper) { m_fileWrapper = fileWrapper; } 67 WTF::String utiType() const; 67 68 #endif 69 WTF::String mimeType() const; 68 70 69 71 const WTF::String& filePath() const { return m_filePath; } 70 72 void setFilePath(const WTF::String& filePath) { m_filePath = filePath; } 73 WTF::String fileName() const; 71 74 72 75 const WTF::String& contentType() const { return m_contentType; } -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h
r235259 r235343 192 192 - (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)); 193 193 - (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)); 194 - (void)_webView:(WKWebView *)webView didPerformDragOperation:(BOOL)handled WK_API_AVAILABLE(macosx(WK_MAC_TBA)); 194 195 #endif // TARGET_OS_IPHONE 195 196 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r235328 r235343 4069 4069 } 4070 4070 4071 - (void)_web_didPerformDragOperation:(BOOL)handled 4072 { 4073 id <WKUIDelegatePrivate> uiDelegate = (id <WKUIDelegatePrivate>)self.UIDelegate; 4074 if ([uiDelegate respondsToSelector:@selector(_webView:didPerformDragOperation:)]) 4075 [uiDelegate _webView:self didPerformDragOperation:handled]; 4076 } 4077 4071 4078 #endif 4072 4079 -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm
r235156 r235343 57 57 @implementation _WKAttachmentInfo { 58 58 RetainPtr<NSFileWrapper> _fileWrapper; 59 RetainPtr<NSString> _contentType; 59 RetainPtr<NSString> _mimeType; 60 RetainPtr<NSString> _utiType; 60 61 RetainPtr<NSString> _filePath; 61 62 } 62 63 63 - (instancetype)initWithFileWrapper:(NSFileWrapper *)fileWrapper filePath:(NSString *)filePath contentType:(NSString *)contentType64 - (instancetype)initWithFileWrapper:(NSFileWrapper *)fileWrapper filePath:(NSString *)filePath mimeType:(NSString *)mimeType utiType:(NSString *)utiType 64 65 { 65 66 if (!(self = [super init])) … … 68 69 _fileWrapper = fileWrapper; 69 70 _filePath = filePath; 70 _contentType = contentType; 71 _mimeType = mimeType; 72 _utiType = utiType; 71 73 return self; 72 74 } … … 95 97 } 96 98 97 static BOOL isDeclaredOrDynamicTypeIdentifier(NSString *type) 98 { 99 return UTTypeIsDeclared((CFStringRef)type) || UTTypeIsDynamic((CFStringRef)type); 100 } 101 102 - (NSString *)_typeIdentifierFromPathExtension 103 { 104 if (NSString *extension = self.name.pathExtension) 105 return WebCore::MIMETypeRegistry::getMIMETypeForExtension(extension); 106 107 return nil; 99 - (NSFileWrapper *)fileWrapper 100 { 101 return _fileWrapper.get(); 108 102 } 109 103 110 104 - (NSString *)contentType 111 105 { 112 // A "content type" can refer to either a UTI or a MIME type. We prefer MIME type here to preserve existing behavior. 113 return self.mimeType ?: self.utiType; 114 } 115 116 - (NSString *)mimeType 117 { 118 NSString *contentType = [_contentType length] ? _contentType.get() : [self _typeIdentifierFromPathExtension]; 119 if (!isDeclaredOrDynamicTypeIdentifier(contentType)) 120 return contentType; 121 122 auto mimeType = adoptCF(UTTypeCopyPreferredTagWithClass((CFStringRef)contentType, kUTTagClassMIMEType)); 123 return (NSString *)mimeType.autorelease(); 124 } 125 126 - (NSString *)utiType 127 { 128 NSString *contentType = [_contentType length] ? _contentType.get() : [self _typeIdentifierFromPathExtension]; 129 if (isDeclaredOrDynamicTypeIdentifier(contentType)) 130 return contentType; 131 132 auto utiType = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)contentType, nil)); 133 return (NSString *)utiType.autorelease(); 134 } 135 136 - (NSFileWrapper *)fileWrapper 137 { 138 return _fileWrapper.get(); 106 if ([_mimeType length]) 107 return _mimeType.get(); 108 109 return _utiType.get(); 139 110 } 140 111 … … 153 124 return nil; 154 125 155 return [[[_WKAttachmentInfo alloc] initWithFileWrapper:_attachment->fileWrapper() filePath:_attachment->filePath() contentType:_attachment->contentType()] autorelease];126 return [[[_WKAttachmentInfo alloc] initWithFileWrapper:_attachment->fileWrapper() filePath:_attachment->filePath() mimeType:_attachment->mimeType() utiType:_attachment->utiType()] autorelease]; 156 127 } 157 128 -
trunk/Source/WebKit/UIProcess/API/mac/WKView.mm
r235202 r235343 1032 1032 #if ENABLE(DRAG_SUPPORT) && WK_API_ENABLED 1033 1033 1034 - (void)_web_didPerformDragOperation:(BOOL)handled 1035 { 1036 UNUSED_PARAM(handled); 1037 } 1038 1034 1039 - (WKDragDestinationAction)_web_dragDestinationActionForDraggingInfo:(id <NSDraggingInfo>)draggingInfo 1035 1040 { -
trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
r235202 r235343 105 105 #if ENABLE(DRAG_SUPPORT) && WK_API_ENABLED 106 106 - (WKDragDestinationAction)_web_dragDestinationActionForDraggingInfo:(id <NSDraggingInfo>)draggingInfo; 107 - (void)_web_didPerformDragOperation:(BOOL)handled; 107 108 #endif 108 109 … … 431 432 NSString *fileNameForFilePromiseProvider(NSFilePromiseProvider *, NSString *fileType); 432 433 void writeToURLForFilePromiseProvider(NSFilePromiseProvider *, NSURL *, void(^)(NSError *)); 434 435 void didPerformDragOperation(bool handled); 433 436 #endif 434 437 -
trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
r235265 r235343 881 881 @private 882 882 RetainPtr<NSURL> _blobURL; 883 RetainPtr<NSString> _file name;883 RetainPtr<NSString> _fileName; 884 884 RetainPtr<NSString> _attachmentIdentifier; 885 885 } 886 886 887 - (instancetype)initWith AttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info;887 - (instancetype)initWithIdentifier:(NSString *)identifier blobURL:(NSURL *)url fileName:(NSString *)fileName; 888 888 889 889 @property (nonatomic, readonly) NSURL *blobURL; 890 @property (nonatomic, readonly) NSString *file name;890 @property (nonatomic, readonly) NSString *fileName; 891 891 @property (nonatomic, readonly) NSString *attachmentIdentifier; 892 892 … … 895 895 @implementation WKPromisedAttachmentContext 896 896 897 - (instancetype)initWith AttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info897 - (instancetype)initWithIdentifier:(NSString *)identifier blobURL:(NSURL *)blobURL fileName:(NSString *)fileName 898 898 { 899 899 if (!(self = [super init])) 900 900 return nil; 901 901 902 _blobURL = info.blobURL;903 _file name = info.filename;904 _attachmentIdentifier = i nfo.attachmentIdentifier;902 _blobURL = blobURL; 903 _fileName = fileName; 904 _attachmentIdentifier = identifier; 905 905 return self; 906 906 } … … 911 911 } 912 912 913 - (NSString *)file name914 { 915 return _file name.get();913 - (NSString *)fileName 914 { 915 return _fileName.get(); 916 916 } 917 917 … … 3909 3909 return nil; 3910 3910 3911 return [(WKPromisedAttachmentContext *)userInfo file name];3911 return [(WKPromisedAttachmentContext *)userInfo fileName]; 3912 3912 } 3913 3913 … … 3918 3918 #else 3919 3919 return [NSError errorWithDomain:@"WKErrorDomain" code:1 userInfo:nil]; 3920 #endif 3921 } 3922 3923 void WebViewImpl::didPerformDragOperation(bool handled) 3924 { 3925 #if WK_API_ENABLED 3926 [m_view _web_didPerformDragOperation:handled]; 3927 #else 3928 UNUSED_PARAM(handled); 3920 3929 #endif 3921 3930 } … … 3993 4002 #pragma clang diagnostic pop 3994 4003 3995 if (auto& attachmentInfo = item.promisedAttachmentInfo) { 3996 auto provider = adoptNS([[NSFilePromiseProvider alloc] initWithFileType:attachmentInfo.contentType delegate:(id <NSFilePromiseProviderDelegate>)m_view.getAutoreleased()]); 3997 [provider setUserInfo:[[[WKPromisedAttachmentContext alloc] initWithAttachmentInfo:attachmentInfo] autorelease]]; 4004 if (auto& info = item.promisedAttachmentInfo) { 4005 NSString *utiType = info.contentType; 4006 NSString *fileName = info.fileName; 4007 if (auto attachment = m_page->attachmentForIdentifier(info.attachmentIdentifier)) { 4008 utiType = attachment->utiType(); 4009 fileName = attachment->fileName(); 4010 } 4011 4012 auto provider = adoptNS([[NSFilePromiseProvider alloc] initWithFileType:utiType delegate:(id <NSFilePromiseProviderDelegate>)m_view.getAutoreleased()]); 4013 auto context = adoptNS([[WKPromisedAttachmentContext alloc] initWithIdentifier:info.attachmentIdentifier blobURL:info.blobURL fileName:fileName]); 4014 [provider setUserInfo:context.get()]; 3998 4015 auto draggingItem = adoptNS([[NSDraggingItem alloc] initWithPasteboardWriter:provider.get()]); 3999 4016 [draggingItem setDraggingFrame:NSMakeRect(clientDragLocation.x(), clientDragLocation.y() - size.height(), size.width(), size.height()) contents:dragNSImage.get()]; 4000 4017 [m_view beginDraggingSessionWithItems:@[draggingItem.get()] event:m_lastMouseDownEvent.get() source:(id <NSDraggingSource>)m_view.getAutoreleased()]; 4001 4018 4002 ASSERT( attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size());4003 if ( attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size()) {4004 for (size_t index = 0; index < attachmentInfo.additionalTypes.size(); ++index) {4005 auto nsData = attachmentInfo.additionalData[index]->createNSData();4006 [pasteboard setData:nsData.get() forType: attachmentInfo.additionalTypes[index]];4019 ASSERT(info.additionalTypes.size() == info.additionalData.size()); 4020 if (info.additionalTypes.size() == info.additionalData.size()) { 4021 for (size_t index = 0; index < info.additionalTypes.size(); ++index) { 4022 auto nsData = info.additionalData[index]->createNSData(); 4023 [pasteboard setData:nsData.get() forType:info.additionalTypes[index]]; 4007 4024 } 4008 4025 } -
trunk/Source/WebKit/UIProcess/PageClient.h
r235156 r235343 211 211 virtual void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle&) { } 212 212 #endif 213 virtual void didPerformDragOperation(bool) { } 213 214 #endif // ENABLE(DRAG_SUPPORT) 214 215 … … 431 432 432 433 #if ENABLE(DATA_INTERACTION) 433 virtual void didPerformDataInteractionControllerOperation(bool handled) = 0;434 434 virtual void didHandleStartDataInteractionRequest(bool started) = 0; 435 435 virtual void didHandleAdditionalDragItemsRequest(bool added) = 0; -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r235265 r235343 1871 1871 } 1872 1872 1873 void WebPageProxy::didPerformDragOperation(bool handled) 1874 { 1875 m_pageClient.didPerformDragOperation(handled); 1876 } 1877 1873 1878 void WebPageProxy::didStartDrag() 1874 1879 { -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r235205 r235343 629 629 void cancelAutoscroll(); 630 630 #if ENABLE(DATA_INTERACTION) 631 void didPerformDataInteractionControllerOperation(bool handled);632 631 void didHandleStartDataInteractionRequest(bool started); 633 632 void didHandleAdditionalDragItemsRequest(bool added); … … 924 923 void dragExited(WebCore::DragData&, const String& dragStorageName = String()); 925 924 void performDragOperation(WebCore::DragData&, const String& dragStorageName, SandboxExtension::Handle&&, SandboxExtension::HandleArray&&); 925 void didPerformDragOperation(bool handled); 926 926 927 927 void didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const WebCore::IntRect& insertionRect); -
trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in
r235200 r235343 322 322 #endif 323 323 324 #if ENABLE(DRAG_SUPPORT) 325 DidPerformDragOperation(bool handled) 326 #endif 327 324 328 #if ENABLE(DATA_INTERACTION) 325 DidPerformDataInteractionControllerOperation(bool handled)326 329 DidHandleStartDataInteractionRequest(bool started) 327 330 DidHandleAdditionalDragItemsRequest(bool added) -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h
r235137 r235343 211 211 212 212 #if ENABLE(DATA_INTERACTION) 213 void didPerformD ataInteractionControllerOperation(bool handled) override;213 void didPerformDragOperation(bool handled) override; 214 214 void didHandleStartDataInteractionRequest(bool started) override; 215 215 void didHandleAdditionalDragItemsRequest(bool added) override; -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
r235265 r235343 779 779 780 780 #if ENABLE(DATA_INTERACTION) 781 void PageClientImpl::didPerformD ataInteractionControllerOperation(bool handled)782 { 783 [m_contentView _didPerformD ataInteractionControllerOperation:handled];781 void PageClientImpl::didPerformDragOperation(bool handled) 782 { 783 [m_contentView _didPerformDragOperation:handled]; 784 784 } 785 785 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r235137 r235343 342 342 #if ENABLE(DATA_INTERACTION) 343 343 - (void)_didChangeDragInteractionPolicy; 344 - (void)_didPerformD ataInteractionControllerOperation:(BOOL)handled;344 - (void)_didPerformDragOperation:(BOOL)handled; 345 345 - (void)_didHandleStartDataInteractionRequest:(BOOL)started; 346 346 - (void)_didHandleAdditionalDragItemsRequest:(BOOL)added; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r235245 r235343 5077 5077 } 5078 5078 5079 - (void)_didPerformD ataInteractionControllerOperation:(BOOL)handled5079 - (void)_didPerformDragOperation:(BOOL)handled 5080 5080 { 5081 5081 RELEASE_LOG(DragAndDrop, "Finished performing drag controller operation (handled: %d)", handled); … … 5130 5130 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()); 5131 5131 5132 NSString *utiType = info.contentType; 5133 NSString *fileName = info.fileName; 5134 if (auto attachment = _page->attachmentForIdentifier(info.attachmentIdentifier)) { 5135 utiType = attachment->utiType(); 5136 fileName = attachment->fileName(); 5137 } 5138 5132 5139 auto registrationList = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]); 5133 5140 [registrationList setPreferredPresentationStyle:WebPreferredPresentationStyleAttachment]; 5134 if ( !info.filename.isEmpty())5135 [registrationList setSuggestedName: info.filename];5141 if ([fileName length]) 5142 [registrationList setSuggestedName:fileName]; 5136 5143 if (numberOfAdditionalTypes == info.additionalData.size() && numberOfAdditionalTypes) { 5137 5144 for (size_t index = 0; index < numberOfAdditionalTypes; ++index) { … … 5141 5148 } 5142 5149 5143 [registrationList addPromisedType: info.contentType fileCallback:[session = WTFMove(session), weakSelf = WeakObjCPtr<WKContentView>(self), info] (WebItemProviderFileCallback callback) {5150 [registrationList addPromisedType:utiType fileCallback:[session = WTFMove(session), weakSelf = WeakObjCPtr<WKContentView>(self), info] (WebItemProviderFileCallback callback) { 5144 5151 auto strongSelf = weakSelf.get(); 5145 5152 if (!strongSelf) { -
trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
r235265 r235343 1089 1089 #if ENABLE(DATA_INTERACTION) 1090 1090 1091 void WebPageProxy::didPerformDataInteractionControllerOperation(bool handled)1092 {1093 m_pageClient.didPerformDataInteractionControllerOperation(handled);1094 }1095 1096 1091 void WebPageProxy::didHandleStartDataInteractionRequest(bool started) 1097 1092 { -
trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h
r235137 r235343 234 234 bool effectiveAppearanceIsDark() const override; 235 235 236 #if ENABLE(DRAG_SUPPORT) 237 void didPerformDragOperation(bool handled) final; 238 #endif 239 236 240 #if WK_API_ENABLED 237 241 NSView *inspectorAttachmentView() override; -
trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
r235265 r235343 875 875 } 876 876 877 #if ENABLE(DRAG_SUPPORT) 878 879 void PageClientImpl::didPerformDragOperation(bool handled) 880 { 881 m_impl->didPerformDragOperation(handled); 882 } 883 884 #endif 885 877 886 #if WK_API_ENABLED 878 887 NSView *PageClientImpl::inspectorAttachmentView() -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r235323 r235343 1812 1812 EDCA71B7128DDA8C00201B26 /* WKBundlePageOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A22F1001289FCD90085E74F /* WKBundlePageOverlay.cpp */; }; 1813 1813 F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1814 F41056622130699A0092281D /* APIAttachmentCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F41056602130699A0092281D /* APIAttachmentCocoa.h */; }; 1815 F41056632130699A0092281D /* APIAttachmentCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = F41056612130699A0092281D /* APIAttachmentCocoa.mm */; }; 1814 1816 F44291921FA591C9002CC93E /* _WKAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = F44291911FA59107002CC93E /* _WKAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1815 1817 F44291941FA59311002CC93E /* _WKAttachment.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44291931FA59311002CC93E /* _WKAttachment.mm */; }; … … 4655 4657 F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; }; 4656 4658 F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = "<group>"; }; 4659 F41056602130699A0092281D /* APIAttachmentCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APIAttachmentCocoa.h; sourceTree = "<group>"; }; 4660 F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; }; 4657 4661 F44291911FA59107002CC93E /* _WKAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKAttachment.h; sourceTree = "<group>"; }; 4658 4662 F44291931FA59311002CC93E /* _WKAttachment.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKAttachment.mm; sourceTree = "<group>"; }; … … 6210 6214 5CB2378A1DF0DD4300117AA3 /* _WKWebsitePolicies.mm */, 6211 6215 5CB2378D1DF0E0C200117AA3 /* _WKWebsitePoliciesInternal.h */, 6216 F41056602130699A0092281D /* APIAttachmentCocoa.h */, 6217 F41056612130699A0092281D /* APIAttachmentCocoa.mm */, 6212 6218 7CEFA9601AC0999300B910FD /* APIContentRuleListStoreCocoa.mm */, 6213 6219 FED3C1DA1B447AE800E0EB7F /* APISerializedScriptValueCocoa.mm */, … … 8999 9005 BC64697011DBE603006455B0 /* APIArray.h in Headers */, 9000 9006 2E5C770E1FA7D429005932C3 /* APIAttachment.h in Headers */, 9007 F41056622130699A0092281D /* APIAttachmentCocoa.h in Headers */, 9001 9008 99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */, 9002 9009 990D28C01C6553F100986977 /* APIAutomationSessionClient.h in Headers */, … … 10882 10889 BC64696F11DBE603006455B0 /* APIArray.cpp in Sources */, 10883 10890 2E5C770F1FA7D429005932C3 /* APIAttachment.cpp in Sources */, 10891 F41056632130699A0092281D /* APIAttachmentCocoa.mm in Sources */, 10884 10892 7C89D2B31A6B068C003A5FDE /* APIContentRuleList.cpp in Sources */, 10885 10893 7C3A06A71AAB903E009D74BA /* APIContentRuleListStore.cpp in Sources */, -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r235331 r235343 3460 3460 3461 3461 m_pendingDropExtensionsForFileUpload.clear(); 3462 #if ENABLE(DATA_INTERACTION) 3463 send(Messages::WebPageProxy::DidPerformDataInteractionControllerOperation(handled)); 3464 #else 3465 UNUSED_PARAM(handled); 3466 #endif 3462 send(Messages::WebPageProxy::DidPerformDragOperation(handled)); 3467 3463 return; 3468 3464 } -
trunk/Tools/ChangeLog
r235339 r235343 1 2018-08-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Dropping and pasting images should insert inline image elements with _WKAttachments 4 https://bugs.webkit.org/show_bug.cgi?id=188933 5 <rdar://problem/43699724> 6 7 Reviewed by Darin Adler. 8 9 Rebaseline existing API tests that involve dropping or pasting image files, and additionally write some new 10 tests. These new tests exercise the following cases: 11 • Inserting and removing newlines before an inline image with an attachment element does not cause new 12 _WKAttachments to be created and destroyed. 13 • Pasting an image, cutting it, and then pasting it again propagates an attachment update to the UI 14 process with the original _WKAttachment. 15 • A pasted attachment in the document can be moved around by dragging, and doing so does not cause us to 16 lose a _WKAttachment. 17 18 * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm: 19 (-[TestWKWebView expectElementCount:tagName:]): 20 (TestWebKitAPI::TEST): 21 22 Add the new tests described above, and also adjust existing tests to check that images are dropped or pasted 23 as image elements, but still have associated attachment elements whose attachment identifiers (observed via 24 script) match that of the corresponding _WKAttachment's uniqueIdentifier in the UI process. 25 26 * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: 27 (-[DragAndDropSimulator runFrom:to:]): 28 (-[DragAndDropSimulator continueDragSession]): 29 (-[DragAndDropSimulator performDragInWebView:atLocation:withImage:pasteboard:source:]): 30 31 Teach DragAndDropSimulator on macOS to wait until the drop has been handled by the web process before returning 32 execution to the caller. This ensures that tests which involve dropping promised files as attachments aren't 33 flaky, due to how the promised data is retrieved asynchronously when performing the drop. 34 35 (-[DragAndDropSimulator _webView:didPerformDragOperation:]): 36 1 37 2018-08-26 Lucas Forschler <lforschler@apple.com> 2 38 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm
r235229 r235343 226 226 } 227 227 228 - (void)expectElementCount:(NSInteger)count tagName:(NSString *)tagName 229 { 230 NSString *script = [NSString stringWithFormat:@"document.querySelectorAll('%@').length", tagName]; 231 EXPECT_EQ(count, [self stringByEvaluatingJavaScript:script].integerValue); 232 } 233 228 234 - (void)expectElementTag:(NSString *)tagName toComeBefore:(NSString *)otherTagName 229 235 { … … 780 786 } 781 787 782 TEST(WKAttachmentTests, InsertPastedImageAsAttachment)788 TEST(WKAttachmentTests, RemoveNewlinesBeforePastedImage) 783 789 { 784 790 platformCopyPNG(); … … 796 802 EXPECT_EQ(215., size.width); 797 803 EXPECT_EQ(174., size.height); 798 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]); 799 804 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 805 806 [webView stringByEvaluatingJavaScript:@"getSelection().collapse(document.body, 0)"]; 807 { 808 ObserveAttachmentUpdatesForScope observer(webView.get()); 809 [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; 810 [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; 811 observer.expectAttachmentUpdates(@[ ], @[ ]); 812 [webView expectElementTagsInOrder:@[ @"BR", @"BR", @"IMG" ]]; 813 } 814 { 815 ObserveAttachmentUpdatesForScope observer(webView.get()); 816 [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil]; 817 [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil]; 818 observer.expectAttachmentUpdates(@[ ], @[ ]); 819 [webView expectElementCount:0 tagName:@"BR"]; 820 } 821 } 822 823 TEST(WKAttachmentTests, CutAndPastePastedImage) 824 { 825 platformCopyPNG(); 826 827 RetainPtr<_WKAttachment> attachment; 828 auto webView = webViewForTestingAttachments(); 829 { 830 ObserveAttachmentUpdatesForScope observer(webView.get()); 831 [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil]; 832 EXPECT_EQ(1U, observer.observer().inserted.count); 833 attachment = observer.observer().inserted[0]; 834 } 800 835 { 801 836 ObserveAttachmentUpdatesForScope observer(webView.get()); 802 837 [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil]; 803 [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil]; 804 observer.expectAttachmentUpdates(@[attachment.get()], @[]); 805 } 838 [webView _synchronouslyExecuteEditCommand:@"Cut" argument:nil]; 839 observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]); 840 } 841 { 842 ObserveAttachmentUpdatesForScope observer(webView.get()); 843 [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil]; 844 observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]); 845 } 846 } 847 848 TEST(WKAttachmentTests, MovePastedImageByDragging) 849 { 850 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 851 [configuration _setAttachmentElementEnabled:YES]; 852 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]); 853 TestWKWebView *webView = [simulator webView]; 854 [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup]; 855 856 platformCopyPNG(); 857 [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil]; 858 [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil]; 859 [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil]; 860 [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; 861 [webView expectElementTag:@"IMG" toComeBefore:@"STRONG"]; 862 [webView expectElementCount:1 tagName:@"IMG"]; 863 864 // Drag the attachment element to somewhere below the strong text. 865 [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 350)]; 866 867 [webView expectElementTag:@"STRONG" toComeBefore:@"IMG"]; 868 [webView expectElementCount:1 tagName:@"IMG"]; 869 EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count); 870 871 [simulator endDataTransfer]; 806 872 } 807 873 … … 822 888 [attachment expectRequestedDataToBe:testImageData()]; 823 889 EXPECT_WK_STREQ("Lorem ipsum dolor sit amet.", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]); 824 EXPECT_WK_STREQ("image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); 825 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]); 890 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 826 891 827 892 { … … 858 923 859 924 EXPECT_TRUE(zipAttachment && imageAttachment && pdfAttachment); 860 EXPECT_EQ(3, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].integerValue);861 EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);862 EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[ 1].getAttribute('type')"]);863 864 NSString *zipAttachmentType = [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[ 2].getAttribute('type')"];925 [webView expectElementCount:2 tagName:@"ATTACHMENT"]; 926 [webView expectElementCount:1 tagName:@"IMG"]; 927 EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]); 928 929 NSString *zipAttachmentType = [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]; 865 930 #if USES_MODERN_ATTRIBUTED_STRING_CONVERSION 866 931 EXPECT_WK_STREQ("application/zip", zipAttachmentType); … … 869 934 #endif 870 935 871 EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector All('attachment')[0].uniqueIdentifier"]);872 EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[ 1].uniqueIdentifier"]);873 EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[ 2].uniqueIdentifier"]);936 EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 937 EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].uniqueIdentifier"]); 938 EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].uniqueIdentifier"]); 874 939 875 940 { … … 993 1058 [webView expectElementTagsInOrder:@[ @"IMG", @"ATTACHMENT", @"ATTACHMENT" ]]; 994 1059 EXPECT_WK_STREQ("cid:foo-bar", [webView valueOfAttribute:@"src" forQuerySelector:@"img"]); 1060 EXPECT_WK_STREQ(@"", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('img')[0].webkitAttachmentIdentifier"]); 995 1061 } 996 1062 … … 1125 1191 [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(50, 300)]; 1126 1192 1127 EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);1128 [attachment expectRequestedDataToBe:data.get()];1129 1193 EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]); 1130 1194 EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); 1195 [attachment expectRequestedDataToBe:data.get()]; 1196 EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count); 1131 1197 #if PLATFORM(MAC) 1132 1198 EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage)); … … 1157 1223 } 1158 1224 1159 NSArray<NSData *> *expectedAttachmentData = @[ testPDFData(), testImageData() ]; 1160 EXPECT_TRUE([expectedAttachmentData containsObject:[insertedAttachments firstObject].info.data]); 1161 EXPECT_TRUE([expectedAttachmentData containsObject:[insertedAttachments lastObject].info.data]); 1162 EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]); 1163 EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]); 1164 EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]); 1165 EXPECT_WK_STREQ("icon.png", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]); 1225 [webView expectElementCount:1 tagName:@"ATTACHMENT"]; 1226 [webView expectElementCount:1 tagName:@"IMG"]; 1227 EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('type')"]); 1228 EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('title')"]); 1229 1230 NSString *imageAttachmentIdentifier = [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]; 1231 if ([testImageData() isEqualToData:[insertedAttachments firstObject].info.data]) 1232 EXPECT_WK_STREQ([insertedAttachments firstObject].uniqueIdentifier, imageAttachmentIdentifier); 1233 else 1234 EXPECT_WK_STREQ([insertedAttachments lastObject].uniqueIdentifier, imageAttachmentIdentifier); 1166 1235 1167 1236 for (_WKAttachment *attachment in insertedAttachments.get()) … … 1189 1258 1190 1259 [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)]; 1191 while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) { 1192 if ([simulator insertedAttachments].count == 2) 1193 break; 1194 } 1195 EXPECT_EQ(2, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]); 1260 1261 [webView expectElementCount:1 tagName:@"ATTACHMENT"]; 1262 [webView expectElementCount:1 tagName:@"IMG"]; 1263 EXPECT_EQ(2U, [simulator insertedAttachments].count); 1196 1264 1197 1265 auto insertedAttachments = retainPtr([simulator insertedAttachments]); … … 1202 1270 if ([testPDFData() isEqualToData:attachment.info.data]) 1203 1271 EXPECT_WK_STREQ("application/pdf", attachment.info.contentType); 1204 else if ([testImageData() isEqualToData:attachment.info.data]) 1272 else if ([testImageData() isEqualToData:attachment.info.data]) { 1205 1273 EXPECT_WK_STREQ("image/png", attachment.info.contentType); 1274 EXPECT_WK_STREQ(attachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 1275 } 1206 1276 } 1207 1277 … … 1210 1280 auto removedAttachments = retainPtr([simulator removedAttachments]); 1211 1281 EXPECT_EQ(2U, [removedAttachments count]); 1212 EXPECT_EQ(0, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]); 1282 [webView expectElementCount:0 tagName:@"ATTACHMENT"]; 1283 [webView expectElementCount:0 tagName:@"IMG"]; 1213 1284 EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments firstObject]]); 1214 1285 EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments lastObject]]); … … 1229 1300 NSArray<NSURL *> *urls = [simulator receivePromisedFiles]; 1230 1301 EXPECT_EQ(1U, urls.count); 1302 EXPECT_WK_STREQ("test.pdf", urls.lastObject.lastPathComponent); 1231 1303 EXPECT_TRUE([[NSData dataWithContentsOfURL:urls.firstObject] isEqualToData:testPDFData()]); 1232 1304 EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage)); … … 1250 1322 auto attachment = retainPtr([dragAndDropSimulator insertedAttachments].firstObject); 1251 1323 [attachment expectRequestedDataToBe:testImageData()]; 1252 EXPECT_WK_STREQ( "public.png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);1324 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 1253 1325 1254 1326 { … … 1278 1350 EXPECT_EQ(215., size.width); 1279 1351 EXPECT_EQ(174., size.height); 1280 EXPECT_WK_STREQ( "image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);1352 EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]); 1281 1353 1282 1354 { … … 1316 1388 EXPECT_GT([attachment info].data.length, 0U); 1317 1389 1318 EXPECT_EQ(2, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].intValue);1390 [webView expectElementCount:2 tagName:@"ATTACHMENT"]; 1319 1391 EXPECT_WK_STREQ("hello.rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]); 1320 1392 EXPECT_WK_STREQ("text/rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]); … … 1341 1413 EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count); 1342 1414 [[dragAndDropSimulator insertedAttachments].firstObject expectRequestedDataToBe:data]; 1343 EXPECT_EQ(1, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"].intValue);1415 [webView expectElementCount:1 tagName:@"ATTACHMENT"]; 1344 1416 EXPECT_WK_STREQ("archive.zip", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]); 1345 1417 EXPECT_WK_STREQ("application/zip", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); -
trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm
r235202 r235343 104 104 double _progress; 105 105 bool _doneWaitingForDraggingSession; 106 bool _doneWaitingForDrop; 106 107 } 107 108 … … 156 157 _removedAttachments = adoptNS([NSMutableArray new]); 157 158 _doneWaitingForDraggingSession = true; 159 _doneWaitingForDrop = true; 158 160 _startLocationInWindow = [self flipAboutXAxisInHostWindow:flippedStartLocation]; 159 161 _endLocationInWindow = [self flipAboutXAxisInHostWindow:flippedEndLocation]; … … 168 170 NSImage *dragImage = self.externalDragImage ?: defaultExternalDragImage(); 169 171 [self performDragInWebView:_webView.get() atLocation:startLocationInView withImage:dragImage pasteboard:pasteboard source:nil]; 172 TestWebKitAPI::Util::run(&_doneWaitingForDrop); 170 173 return; 171 174 } … … 187 190 [_webView mouseUpAtPoint:_endLocationInWindow]; 188 191 [_webView waitForPendingMouseEvents]; 192 193 TestWebKitAPI::Util::run(&_doneWaitingForDrop); 189 194 } 190 195 … … 239 244 _willEndDraggingHandler(); 240 245 241 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) 246 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) { 247 _doneWaitingForDrop = false; 242 248 [_webView performDragOperation:_draggingInfo.get()]; 243 else if (_currentDragOperation == NSDragOperationNone)249 } else if (_currentDragOperation == NSDragOperationNone) 244 250 [_webView draggingExited:_draggingInfo.get()]; 245 251 [_webView waitForNextPresentationUpdate]; … … 269 275 _willEndDraggingHandler(); 270 276 271 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) 277 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) { 278 _doneWaitingForDrop = false; 272 279 [_webView performDragOperation:_draggingInfo.get()]; 273 else if (_currentDragOperation == NSDragOperationNone)280 } else if (_currentDragOperation == NSDragOperationNone) 274 281 [_webView draggingExited:_draggingInfo.get()]; 275 282 [_webView waitForNextPresentationUpdate]; … … 438 445 } 439 446 447 #pragma mark - WKUIDelegatePrivate 448 440 449 - (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source 441 450 { … … 448 457 } 449 458 459 - (void)_webView:(WKWebView *)webView didPerformDragOperation:(BOOL)handled 460 { 461 _doneWaitingForDrop = true; 462 } 463 450 464 @end 451 465
Note: See TracChangeset
for help on using the changeset viewer.