Diff
Modified: trunk/Source/WebCore/ChangeLog (235391 => 235392)
--- trunk/Source/WebCore/ChangeLog 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/ChangeLog 2018-08-27 20:14:21 UTC (rev 235392)
@@ -1,3 +1,45 @@
+2018-08-27 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Cocoa] Exception (fileType 'dyn.agq8u' is not a valid UTI) raised when dragging an attachment whose file wrapper is a directory
+ https://bugs.webkit.org/show_bug.cgi?id=188903
+ <rdar://problem/43702993>
+
+ Reviewed by Tim Horton.
+
+ Fixes the exception for attachments that are created when dropping files with extensions that don't map to any
+ known UTIs, and when dropping folders. See below for more detail.
+
+ Tests: WKAttachmentTests.InsertFolderAndFileWithUnknownExtension
+ WKAttachmentTests.DropFolderAsAttachmentAndMoveByDragging
+ WKAttachmentTests.ChangeAttachmentDataAndFileInformation
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertAttachment):
+ * editing/Editor.h:
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::WebContentReader::readFilePaths):
+
+ When creating an attachment by dropping or pasting a file backed by a file path, handle the cases where…
+ (1) the dropped path is a directory, by setting the UTI to "public.directory". This allows us to show a
+ folder icon for the dropped attachment element on macOS.
+ (2) the dropped path is a file whose UTI is unknown, by defaulting to "public.data".
+
+ By ensuring that the UTI of a dropped file-backed attachment is set to a concrete type in any case, we avoid an
+ exception when dragging the attachment on macOS, and on iOS, avoid silently failing to drag an attachment.
+
+ * html/HTMLAttachmentElement.cpp:
+ (WebCore::HTMLAttachmentElement::updateAttributes):
+
+ Change this method to take an optional file size (the subtitle attribute will only be set if the file size is
+ not `std::nullopt`). Furthermore, allow callers of this method to clear attributes on the attachment element by
+ passing in `std::nullopt` for any of the three arguments. This allows us to handle the case where an
+ attachment's file wrapper is changed from a regular file to a folder whose total size is currently unknown.
+ Instead of showing "0 bytes", we'll simply refrain from showing a subtitle at all (in the future, this should
+ be improved by implementing a way to estimate the size of the files in the folder, or perhaps show the number of
+ items in the folder as the subtitle).
+
+ * html/HTMLAttachmentElement.h:
+
2018-08-27 Devin Rousso <drou...@apple.com>
Web Inspector: provide autocompletion for event breakpoints
Modified: trunk/Source/WebCore/editing/Editor.cpp (235391 => 235392)
--- trunk/Source/WebCore/editing/Editor.cpp 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/editing/Editor.cpp 2018-08-27 20:14:21 UTC (rev 235392)
@@ -3876,11 +3876,11 @@
}
}
-void Editor::insertAttachment(const String& identifier, const AttachmentDisplayOptions&, uint64_t fileSize, const String& fileName, std::optional<String>&& explicitContentType)
+void Editor::insertAttachment(const String& identifier, const AttachmentDisplayOptions&, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType)
{
auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, document());
attachment->setUniqueIdentifier(identifier);
- attachment->updateAttributes(fileSize, WTFMove(explicitContentType), fileName);
+ attachment->updateAttributes(WTFMove(fileSize), contentType, fileName);
auto fragmentToInsert = document().createDocumentFragment();
fragmentToInsert->appendChild(attachment.get());
Modified: trunk/Source/WebCore/editing/Editor.h (235391 => 235392)
--- trunk/Source/WebCore/editing/Editor.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/editing/Editor.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -503,7 +503,7 @@
bool isGettingDictionaryPopupInfo() const { return m_isGettingDictionaryPopupInfo; }
#if ENABLE(ATTACHMENT_ELEMENT)
- WEBCORE_EXPORT void insertAttachment(const String& identifier, const AttachmentDisplayOptions&, uint64_t fileSize, const String& fileName, std::optional<String>&& explicitContentType = std::nullopt);
+ WEBCORE_EXPORT void insertAttachment(const String& identifier, const AttachmentDisplayOptions&, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType);
void registerAttachmentIdentifier(const String&, const String& /* contentType */, const String& /* preferredFileName */, Ref<SharedBuffer>&&);
void registerAttachmentIdentifier(const String&, const String& /* contentType */, const String& /* filePath */);
void cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier);
Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (235391 => 235392)
--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -703,9 +703,18 @@
for (auto& path : paths) {
auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, document);
if (supportsClientSideAttachmentData(frame)) {
- long long fileSize { 0 };
- FileSystem::getFileSize(path, fileSize);
- auto contentType = File::contentTypeForFile(path);
+ String contentType;
+ std::optional<uint64_t> fileSizeForDisplay;
+ if (FileSystem::fileIsDirectory(path, FileSystem::ShouldFollowSymbolicLinks::Yes))
+ contentType = kUTTypeDirectory;
+ else {
+ long long fileSize;
+ FileSystem::getFileSize(path, fileSize);
+ fileSizeForDisplay = fileSize;
+ contentType = File::contentTypeForFile(path);
+ if (contentType.isEmpty())
+ contentType = kUTTypeData;
+ }
frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, path);
if (contentTypeIsSuitableForInlineImageRepresentation(contentType)) {
auto image = HTMLImageElement::create(document);
@@ -713,7 +722,7 @@
image->setAttachmentElement(WTFMove(attachment));
fragment->appendChild(image);
} else {
- attachment->updateAttributes(fileSize, contentType, FileSystem::pathGetFileName(path));
+ attachment->updateAttributes(WTFMove(fileSizeForDisplay), contentType, FileSystem::pathGetFileName(path));
fragment->appendChild(attachment);
}
} else {
Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.cpp (235391 => 235392)
--- trunk/Source/WebCore/html/HTMLAttachmentElement.cpp 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.cpp 2018-08-27 20:14:21 UTC (rev 235392)
@@ -144,15 +144,23 @@
return attributeWithoutSynchronization(webkitattachmentpathAttr);
}
-void HTMLAttachmentElement::updateAttributes(uint64_t fileSize, std::optional<String>&& newContentType, std::optional<String>&& newFilename)
+void HTMLAttachmentElement::updateAttributes(std::optional<uint64_t>&& newFileSize, std::optional<String>&& newContentType, std::optional<String>&& newFilename)
{
if (newFilename)
setAttributeWithoutSynchronization(HTMLNames::titleAttr, *newFilename);
+ else
+ removeAttribute(HTMLNames::titleAttr);
if (newContentType)
setAttributeWithoutSynchronization(HTMLNames::typeAttr, *newContentType);
+ else
+ removeAttribute(HTMLNames::typeAttr);
- setAttributeWithoutSynchronization(HTMLNames::subtitleAttr, fileSizeDescription(fileSize));
+ if (newFileSize)
+ setAttributeWithoutSynchronization(HTMLNames::subtitleAttr, fileSizeDescription(*newFileSize));
+ else
+ removeAttribute(HTMLNames::subtitleAttr);
+
if (auto* renderer = this->renderer())
renderer->invalidate();
}
Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.h (235391 => 235392)
--- trunk/Source/WebCore/html/HTMLAttachmentElement.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -49,7 +49,7 @@
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);
+ WEBCORE_EXPORT void updateAttributes(std::optional<uint64_t>&& newFileSize = std::nullopt, std::optional<String>&& newContentType = std::nullopt, std::optional<String>&& newFilename = std::nullopt);
InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
void removedFromAncestor(RemovalType, ContainerNode&) final;
Modified: trunk/Source/WebKit/ChangeLog (235391 => 235392)
--- trunk/Source/WebKit/ChangeLog 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/ChangeLog 2018-08-27 20:14:21 UTC (rev 235392)
@@ -1,3 +1,71 @@
+2018-08-27 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Cocoa] Exception (fileType 'dyn.agq8u' is not a valid UTI) raised when dragging an attachment whose file wrapper is a directory
+ https://bugs.webkit.org/show_bug.cgi?id=188903
+ <rdar://problem/43702993>
+
+ Reviewed by Tim Horton.
+
+ Fixes the bug by supporting NSFileWrappers of type directory, as well as NSFileWrappers with file that do not
+ map to concrete type identifiers. Among other things, this patch ensures that:
+ - Inserting a directory file wrapper (or using -setFileWrapper:…: to change an existing _WKAttachment's
+ file wrapper to a directory) does not cause the attachment element to show "0 bytes" as the subtitle.
+ - In the above scenario, we also won't end up with a missing "type" attribute for the attachment element,
+ as well as a corresponding API::Attachment::contentType() that's an empty string.
+ - Dropping or pasting attachments backed by paths on disk also doesn't trigger these problems, if the path
+ is a directory or of unknown file type.
+
+ Changes are verified by 2 new API tests.
+
+ * UIProcess/API/APIAttachment.cpp:
+ (API::Attachment::updateAttributes):
+ (API::Attachment::fileSizeForDisplay const):
+ * UIProcess/API/APIAttachment.h:
+ * UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
+ (API::Attachment::setFileWrapperAndUpdateContentType):
+
+ Add a helper that sets the file wrapper to the given NSFileWrapper, and either sets the content type to the
+ given content type if it's specified, or infers it from the file extension of the new NSFileWrapper. Invoked
+ whenever an NSFileWrapper and content type combination is set on an API attachment via WebKit SPI.
+
+ (API::Attachment::fileSizeForDisplay const):
+
+ Returns a file size to be displayed in the attachment element's subtitle. This returns an optional file size,
+ where `std::nullopt` indicates that there should not be a file size shown. For now, this returns `std::nullopt`
+ for directory file wrappers, though in the future, this should be done only in cases where we don't immediately
+ have a size estimate for the file wrapper.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _insertAttachmentWithFileWrapper:contentType:options:completion:]):
+
+ Use API::Attachment::setFileWrapperAndUpdateContentType() instead of trying to come up with a fallback UTI.
+
+ * UIProcess/API/Cocoa/_WKAttachment.mm:
+ (-[_WKAttachment setFileWrapper:contentType:completion:]):
+
+ Use API::Attachment::setFileWrapperAndUpdateContentType() instead of trying to come up with a fallback UTI.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::insertAttachment):
+
+ Remove the separate arguments for file size, content type, and file name, and instead get them from the given
+ API Attachment object.
+
+ (WebKit::WebPageProxy::updateAttachmentAttributes):
+
+ Remove separate arguments for file size, content type and file name and just take an API::Attachment instead.
+ These separate pieces of information can simply be asked from the Attachment itself.
+
+ * UIProcess/WebPageProxy.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::insertAttachment):
+ (WebKit::WebPage::updateAttachmentAttributes):
+
+ Adjust some interfaces here to allow the displayed file size to be optional.
+
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
2018-08-27 Alex Christensen <achristen...@webkit.org>
Fix internal builds after r235368
Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp 2018-08-27 20:14:21 UTC (rev 235392)
@@ -57,17 +57,14 @@
callback(WebKit::CallbackBase::Error::OwnerWasInvalidated);
}
-void Attachment::updateAttributes(uint64_t fileSize, const WTF::String& newContentType, const WTF::String& newFilename, Function<void(WebKit::CallbackBase::Error)>&& callback)
+void Attachment::updateAttributes(Function<void(WebKit::CallbackBase::Error)>&& callback)
{
- setContentType(newContentType);
- setFilePath({ });
+ if (!m_webPage) {
+ callback(WebKit::CallbackBase::Error::OwnerWasInvalidated);
+ return;
+ }
- auto optionalNewContentType = newContentType.isNull() ? std::nullopt : std::optional<WTF::String> { newContentType };
- auto optionalNewFilename = newFilename.isNull() ? std::nullopt : std::optional<WTF::String> { newFilename };
- if (m_webPage)
- m_webPage->updateAttachmentAttributes(m_identifier, fileSize, WTFMove(optionalNewContentType), WTFMove(optionalNewFilename), WTFMove(callback));
- else
- callback(WebKit::CallbackBase::Error::OwnerWasInvalidated);
+ m_webPage->updateAttachmentAttributes(*this, WTFMove(callback));
}
void Attachment::invalidate()
@@ -93,6 +90,11 @@
return { };
}
+std::optional<uint64_t> Attachment::fileSizeForDisplay() const
+{
+ return std::nullopt;
+}
+
#endif // !PLATFORM(COCOA)
}
Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.h (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/API/APIAttachment.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -56,7 +56,7 @@
const WTF::String& identifier() const { return m_identifier; }
void setDisplayOptions(WebCore::AttachmentDisplayOptions, Function<void(WebKit::CallbackBase::Error)>&&);
- void updateAttributes(uint64_t fileSize, const WTF::String& newContentType, const WTF::String& newFilename, Function<void(WebKit::CallbackBase::Error)>&&);
+ void updateAttributes(Function<void(WebKit::CallbackBase::Error)>&&);
void invalidate();
bool isValid() const { return !!m_webPage; }
@@ -64,6 +64,7 @@
#if PLATFORM(COCOA)
NSFileWrapper *fileWrapper() const { return m_fileWrapper.get(); }
void setFileWrapper(NSFileWrapper *fileWrapper) { m_fileWrapper = fileWrapper; }
+ void setFileWrapperAndUpdateContentType(NSFileWrapper *, NSString *contentType);
WTF::String utiType() const;
#endif
WTF::String mimeType() const;
@@ -78,6 +79,8 @@
InsertionState insertionState() const { return m_insertionState; }
void setInsertionState(InsertionState state) { m_insertionState = state; }
+ std::optional<uint64_t> fileSizeForDisplay() const;
+
private:
explicit Attachment(const WTF::String& identifier, WebKit::WebPageProxy&);
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -74,4 +74,34 @@
return [m_fileWrapper preferredFilename];
}
+void Attachment::setFileWrapperAndUpdateContentType(NSFileWrapper *fileWrapper, NSString *contentType)
+{
+ if (!contentType.length) {
+ if (fileWrapper.directory)
+ contentType = (NSString *)kUTTypeDirectory;
+ else if (fileWrapper.regularFile) {
+ if (NSString *pathExtension = (fileWrapper.filename.length ? fileWrapper.filename : fileWrapper.preferredFilename).pathExtension)
+ contentType = WebCore::MIMETypeRegistry::getMIMETypeForExtension(pathExtension);
+ if (!contentType.length)
+ contentType = (NSString *)kUTTypeData;
+ }
+ }
+
+ setContentType(contentType);
+ setFileWrapper(fileWrapper);
+}
+
+std::optional<uint64_t> Attachment::fileSizeForDisplay() const
+{
+ if (![m_fileWrapper isRegularFile]) {
+ // FIXME: We should display a size estimate for directory-type file wrappers.
+ return std::nullopt;
+ }
+
+ if (auto fileSize = [[m_fileWrapper fileAttributes][NSFileSize] unsignedLongLongValue])
+ return fileSize;
+
+ return [m_fileWrapper regularFileContents].length;
+}
+
} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -4454,18 +4454,8 @@
auto identifier = createCanonicalUUIDString();
auto coreOptions = options ? options.coreDisplayOptions : WebCore::AttachmentDisplayOptions { };
auto attachment = API::Attachment::create(identifier, *_page);
- attachment->setFileWrapper(fileWrapper);
-
- if (!contentType.length) {
- if (NSString *pathExtension = (fileWrapper.filename.length ? fileWrapper.filename : fileWrapper.preferredFilename).pathExtension)
- contentType = WebCore::MIMETypeRegistry::getMIMETypeForExtension(pathExtension);
- }
-
- auto fileSize = [[[fileWrapper fileAttributes] objectForKey:NSFileSize] unsignedLongLongValue];
- if (!fileSize && fileWrapper.regularFile)
- fileSize = fileWrapper.regularFileContents.length;
-
- _page->insertAttachment(attachment.copyRef(), coreOptions, fileSize, [fileWrapper preferredFilename], contentType.length ? std::optional<String> { contentType } : std::nullopt, [capturedHandler = makeBlockPtr(completionHandler)] (WebKit::CallbackBase::Error error) {
+ attachment->setFileWrapperAndUpdateContentType(fileWrapper, contentType);
+ _page->insertAttachment(attachment.copyRef(), coreOptions, [capturedHandler = makeBlockPtr(completionHandler)] (WebKit::CallbackBase::Error error) {
if (capturedHandler)
capturedHandler(error == WebKit::CallbackBase::Error::None);
});
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAttachment.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -157,17 +157,11 @@
return;
}
- auto fileSize = [fileWrapper.fileAttributes[NSFileSize] unsignedLongLongValue];
- if (!fileSize && fileWrapper.regularFile)
- fileSize = fileWrapper.regularFileContents.length;
-
- if (!contentType.length) {
- if (NSString *pathExtension = (fileWrapper.filename.length ? fileWrapper.filename : fileWrapper.preferredFilename).pathExtension)
- contentType = WebCore::MIMETypeRegistry::getMIMETypeForExtension(pathExtension);
- }
-
- _attachment->setFileWrapper(fileWrapper);
- _attachment->updateAttributes(fileSize, contentType, fileWrapper.preferredFilename, [capturedBlock = makeBlockPtr(completionHandler)] (auto error) {
+ // This file path member is only populated when the attachment is generated upon dropping files. When data is specified via NSFileWrapper
+ // from the SPI client, the corresponding file path of the data is unknown, if it even exists at all.
+ _attachment->setFilePath({ });
+ _attachment->setFileWrapperAndUpdateContentType(fileWrapper, contentType);
+ _attachment->updateAttributes([capturedBlock = makeBlockPtr(completionHandler)] (auto error) {
if (!capturedBlock)
return;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-08-27 20:14:21 UTC (rev 235392)
@@ -7751,7 +7751,7 @@
return m_attachmentIdentifierToAttachmentMap.get(identifier);
}
-void WebPageProxy::insertAttachment(Ref<API::Attachment>&& attachment, const AttachmentDisplayOptions& options, uint64_t fileSize, const String& filename, std::optional<String> contentType, Function<void(CallbackBase::Error)>&& callback)
+void WebPageProxy::insertAttachment(Ref<API::Attachment>&& attachment, const AttachmentDisplayOptions& options, Function<void(CallbackBase::Error)>&& callback)
{
if (!isValid()) {
callback(CallbackBase::Error::OwnerWasInvalidated);
@@ -7758,14 +7758,10 @@
return;
}
- if (contentType)
- attachment->setContentType(*contentType);
-
auto attachmentIdentifier = attachment->identifier();
+ auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
+ m_process->send(Messages::WebPage::InsertAttachment(attachmentIdentifier, options, attachment->fileSizeForDisplay(), attachment->fileName(), attachment->contentType(), callbackID), m_pageID);
m_attachmentIdentifierToAttachmentMap.set(attachmentIdentifier, WTFMove(attachment));
-
- auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
- m_process->send(Messages::WebPage::InsertAttachment(attachmentIdentifier, options, fileSize, filename, contentType, callbackID), m_pageID);
}
void WebPageProxy::setAttachmentDisplayOptions(const String& identifier, AttachmentDisplayOptions options, Function<void(CallbackBase::Error)>&& callback)
@@ -7779,7 +7775,7 @@
m_process->send(Messages::WebPage::SetAttachmentDisplayOptions(identifier, options, callbackID), m_pageID);
}
-void WebPageProxy::updateAttachmentAttributes(const String& identifier, uint64_t fileSize, std::optional<String>&& newContentType, std::optional<String>&& newFilename, Function<void(CallbackBase::Error)>&& callback)
+void WebPageProxy::updateAttachmentAttributes(const API::Attachment& attachment, Function<void(CallbackBase::Error)>&& callback)
{
if (!isValid()) {
callback(CallbackBase::Error::OwnerWasInvalidated);
@@ -7787,7 +7783,9 @@
}
auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
- m_process->send(Messages::WebPage::UpdateAttachmentAttributes(identifier, fileSize, WTFMove(newContentType), WTFMove(newFilename), callbackID), m_pageID);
+ auto name = attachment.fileName();
+ auto optionalName = name.isNull() ? std::nullopt : std::optional<WTF::String> { name };
+ m_process->send(Messages::WebPage::UpdateAttachmentAttributes(attachment.identifier(), attachment.fileSizeForDisplay(), attachment.contentType(), WTFMove(optionalName), callbackID), m_pageID);
}
void WebPageProxy::registerAttachmentIdentifierFromData(const String& identifier, const String& contentType, const String& preferredFileName, const IPC::DataReference& data)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (235391 => 235392)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -1319,9 +1319,9 @@
#if ENABLE(ATTACHMENT_ELEMENT)
RefPtr<API::Attachment> attachmentForIdentifier(const String& identifier) const;
- void insertAttachment(Ref<API::Attachment>&&, const WebCore::AttachmentDisplayOptions&, uint64_t fileSize, const String& fileName, std::optional<String> contentType, Function<void(CallbackBase::Error)>&&);
+ void insertAttachment(Ref<API::Attachment>&&, const WebCore::AttachmentDisplayOptions&, Function<void(CallbackBase::Error)>&&);
void setAttachmentDisplayOptions(const String& identifier, WebCore::AttachmentDisplayOptions, Function<void(CallbackBase::Error)>&&);
- void updateAttachmentAttributes(const String& identifier, uint64_t fileSize, std::optional<String>&& newContentType, std::optional<String>&& newFilename, Function<void(CallbackBase::Error)>&&);
+ void updateAttachmentAttributes(const API::Attachment&, Function<void(CallbackBase::Error)>&&);
#endif
#if ENABLE(APPLICATION_MANIFEST)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (235391 => 235392)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-08-27 20:14:21 UTC (rev 235392)
@@ -6066,10 +6066,10 @@
#if ENABLE(ATTACHMENT_ELEMENT)
-void WebPage::insertAttachment(const String& identifier, const AttachmentDisplayOptions& options, uint64_t fileSize, const String& fileName, std::optional<String> contentType, CallbackID callbackID)
+void WebPage::insertAttachment(const String& identifier, const AttachmentDisplayOptions& options, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID callbackID)
{
auto& frame = m_page->focusController().focusedOrMainFrame();
- frame.editor().insertAttachment(identifier, options, fileSize, fileName, WTFMove(contentType));
+ frame.editor().insertAttachment(identifier, options, WTFMove(fileSize), fileName, contentType);
send(Messages::WebPageProxy::VoidCallback(callbackID));
}
@@ -6078,11 +6078,11 @@
send(Messages::WebPageProxy::VoidCallback(callbackID));
}
-void WebPage::updateAttachmentAttributes(const String& identifier, uint64_t fileSize, std::optional<String> newContentType, std::optional<String> newFilename, CallbackID callbackID)
+void WebPage::updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, std::optional<String>&& newFilename, CallbackID callbackID)
{
if (auto attachment = attachmentElementWithIdentifier(identifier)) {
attachment->document().updateLayout();
- attachment->updateAttributes(fileSize, WTFMove(newContentType), WTFMove(newFilename));
+ attachment->updateAttributes(WTFMove(fileSize), contentType, WTFMove(newFilename));
}
send(Messages::WebPageProxy::VoidCallback(callbackID));
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (235391 => 235392)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -1075,9 +1075,9 @@
#endif
#if ENABLE(ATTACHMENT_ELEMENT)
- void insertAttachment(const String& identifier, const WebCore::AttachmentDisplayOptions&, uint64_t fileSize, const String& fileName, std::optional<String> contentType, CallbackID);
+ void insertAttachment(const String& identifier, const WebCore::AttachmentDisplayOptions&, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID);
void setAttachmentDisplayOptions(const String& identifier, const WebCore::AttachmentDisplayOptions&, CallbackID);
- void updateAttachmentAttributes(const String& identifier, uint64_t fileSize, std::optional<String> newContentType, std::optional<String> newFilename, CallbackID);
+ void updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, std::optional<String>&& newFilename, CallbackID);
#endif
#if ENABLE(APPLICATION_MANIFEST)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (235391 => 235392)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-08-27 20:14:21 UTC (rev 235392)
@@ -510,9 +510,9 @@
#endif
#if ENABLE(ATTACHMENT_ELEMENT)
- InsertAttachment(String identifier, struct WebCore::AttachmentDisplayOptions options, uint64_t fileSize, String fileName, std::optional<String> contentType, WebKit::CallbackID callbackID)
+ InsertAttachment(String identifier, struct WebCore::AttachmentDisplayOptions options, std::optional<uint64_t> fileSize, String fileName, String contentType, WebKit::CallbackID callbackID)
SetAttachmentDisplayOptions(String identifier, struct WebCore::AttachmentDisplayOptions options, WebKit::CallbackID callbackID)
- UpdateAttachmentAttributes(String identifier, uint64_t fileSize, std::optional<String> newContentType, std::optional<String> newFilename, WebKit::CallbackID callbackID)
+ UpdateAttachmentAttributes(String identifier, std::optional<uint64_t> fileSize, String newContentType, std::optional<String> newFilename, WebKit::CallbackID callbackID)
#endif
#if ENABLE(APPLICATION_MANIFEST)
Modified: trunk/Tools/ChangeLog (235391 => 235392)
--- trunk/Tools/ChangeLog 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Tools/ChangeLog 2018-08-27 20:14:21 UTC (rev 235392)
@@ -1,3 +1,51 @@
+2018-08-27 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Cocoa] Exception (fileType 'dyn.agq8u' is not a valid UTI) raised when dragging an attachment whose file wrapper is a directory
+ https://bugs.webkit.org/show_bug.cgi?id=188903
+ <rdar://problem/43702993>
+
+ Reviewed by Tim Horton.
+
+ Add two API tests and adjust existing WKAttachment API tests. The new tests exercise the following scenarios, in
+ both iOS and macOS:
+ • Dropping a folder as an attachment element, and then moving that attachment element in the document by
+ dragging and dropping.
+ • Using WKWebView SPI to insert a folder and a file with an unknown extension, and then using more
+ _WKAttachment SPI to swap the attachments' backing file wrappers.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+ (runTestWithTemporaryFolder):
+
+ Add a helper function to run a test with a new folder path, created in the temporary directory and populated
+ with some sample content. This folder is deleted after running the test.
+
+ (simulateFolderDragWithURL):
+
+ Add a helper function to prepare a given DragAndDropSimulator for simulating a dragged folder from a source
+ external to the web view.
+
+ (platformCopyRichTextWithMultipleAttachments):
+ (platformCopyRichTextWithImage):
+ (platformCopyPNG):
+ (TestWebKitAPI::TEST):
+
+ Add new API tests, and adjust existing tests to reflect new -setFileWrapper:…: behavior. Specifically,
+ ChangeAttachmentDataAndFileInformation previously required that changing a _WKAttachment's NSFileWrapper would
+ preserve the previous NSFileWrapper's preferred name if the new file wrapper does not have a preferred name, but
+ this quirk is no longer supported.
+
+ Also add a few bridging casts for the eventual transition of TestWebKitAPI to ARC.
+
+ * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+
+ Add a new hook to clear any external drag information on an existing DragAndDropSimulator. This is convenient
+ when using the same DragAndDropSimulator to perform multiple drags in a single test.
+
+ * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+ (-[DragAndDropSimulator clearExternalDragInformation]):
+ * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm:
+ (-[DragAndDropSimulator clearExternalDragInformation]):
+
2018-08-27 Alex Christensen <achristen...@webkit.org>
Translate 4 tests using WKPageLoaderClient to ObjC
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (235391 => 235392)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -408,6 +408,37 @@
@end
+static void runTestWithTemporaryFolder(void(^runTest)(NSURL *folderURL))
+{
+ NSFileManager *defaultManager = [NSFileManager defaultManager];
+ auto temporaryFolder = retainPtr([NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"folder-%@", NSUUID.UUID]] isDirectory:YES]);
+ [defaultManager removeItemAtURL:temporaryFolder.get() error:nil];
+ [defaultManager createDirectoryAtURL:temporaryFolder.get() withIntermediateDirectories:NO attributes:nil error:nil];
+ [testImageData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"image.png" isDirectory:NO] atomically:YES];
+ [testZIPData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"archive.zip" isDirectory:NO] atomically:YES];
+ @try {
+ runTest(temporaryFolder.get());
+ } @finally {
+ [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil];
+ }
+}
+
+static void simulateFolderDragWithURL(DragAndDropSimulator *simulator, NSURL *folderURL)
+{
+#if PLATFORM(MAC)
+ [simulator writePromisedFiles:@[ folderURL ]];
+#else
+ auto folderProvider = adoptNS([[NSItemProvider alloc] init]);
+ [folderProvider setSuggestedName:folderURL.lastPathComponent];
+ [folderProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
+ [folderProvider registerFileRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeFolder fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void(^completion)(NSURL *, BOOL, NSError *)) -> NSProgress * {
+ completion(folderURL, NO, nil);
+ return nil;
+ }];
+ simulator.externalItemProviders = @[ folderProvider.get() ];
+#endif
+}
+
#pragma mark - Platform testing helper functions
#if PLATFORM(MAC)
@@ -468,9 +499,9 @@
void platformCopyRichTextWithMultipleAttachments()
{
- auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(NSString *)kUTTypePNG]);
- auto pdf = adoptNS([[NSTextAttachment alloc] initWithData:testPDFData() ofType:(NSString *)kUTTypePDF]);
- auto zip = adoptNS([[NSTextAttachment alloc] initWithData:testZIPData() ofType:(NSString *)kUTTypeZipArchive]);
+ auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);
+ auto pdf = adoptNS([[NSTextAttachment alloc] initWithData:testPDFData() ofType:(__bridge NSString *)kUTTypePDF]);
+ auto zip = adoptNS([[NSTextAttachment alloc] initWithData:testZIPData() ofType:(__bridge NSString *)kUTTypeZipArchive]);
auto richText = adoptNS([[NSMutableAttributedString alloc] init]);
[richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:image.get()]];
@@ -491,7 +522,7 @@
void platformCopyRichTextWithImage()
{
auto richText = adoptNS([[NSMutableAttributedString alloc] init]);
- auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(NSString *)kUTTypePNG]);
+ auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);
[richText appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Lorem ipsum "] autorelease]];
[richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:image.get()]];
@@ -518,7 +549,7 @@
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
auto item = adoptNS([[UIItemProvider alloc] init]);
[item setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
- [item registerData:testImageData() type:(NSString *)kUTTypePNG];
+ [item registerData:testImageData() type:(__bridge NSString *)kUTTypePNG];
pasteboard.itemProviders = @[ item.get() ];
#endif
}
@@ -641,7 +672,7 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
- observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
[webView expectUpdatesAfterCommand:@"InsertText" withArgument:@"World" expectedRemovals:@[] expectedInsertions:@[]];
[webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
@@ -665,7 +696,7 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
- observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
[webView expectUpdatesAfterCommand:@"InsertOrderedList" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
// This edit command behaves more like a "toggle", and will actually break us out of the list we just inserted.
@@ -686,7 +717,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"InsertHTML" argument:@"<div><strong><attachment src='' title='a'></attachment></strong></div>"];
attachment = observer.observer().inserted[0];
- observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
observer.expectSourceForIdentifier(@"cid:123-4567", [attachment uniqueIdentifier]);
}
EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
@@ -697,7 +728,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').remove()"];
[webView waitForNextPresentationUpdate];
- observer.expectAttachmentUpdates(@[attachment.get()], @[ ]);
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
[attachment expectRequestedDataToBe:nil];
}
@@ -709,7 +740,7 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
- observer.expectAttachmentUpdates(@[], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
[attachment expectRequestedDataToBe:testHTMLData()];
EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
@@ -717,13 +748,13 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"Cut" argument:nil];
- observer.expectAttachmentUpdates(@[attachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
[attachment expectRequestedDataToBe:testHTMLData()];
{
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
- observer.expectAttachmentUpdates(@[], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
[attachment expectRequestedDataToBe:testHTMLData()];
EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
@@ -738,7 +769,7 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
attachment = [webView synchronouslyInsertAttachmentWithFilename:@"empty.txt" contentType:@"text/plain" data:[NSData data]];
- observer.expectAttachmentUpdates(@[], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
[attachment expectRequestedDataToBe:[NSData data]];
EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
@@ -745,11 +776,92 @@
{
ObserveAttachmentUpdatesForScope scope(webView.get());
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- scope.expectAttachmentUpdates(@[attachment.get()], @[]);
+ scope.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
[attachment expectRequestedDataToBe:[NSData data]];
}
+TEST(WKAttachmentTests, DropFolderAsAttachmentAndMoveByDragging)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [configuration _setAttachmentElementEnabled:YES];
+
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
+ [[simulator webView] synchronouslyLoadHTMLString:attachmentEditingTestMarkup];
+
+ runTestWithTemporaryFolder([simulator] (NSURL *folderURL) {
+ simulateFolderDragWithURL(simulator.get(), folderURL);
+ [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];
+
+ TestWKWebView *webView = [simulator webView];
+ auto attachment = retainPtr([simulator insertedAttachments].firstObject);
+ EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
+ EXPECT_WK_STREQ((__bridge NSString *)kUTTypeDirectory, [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ EXPECT_WK_STREQ(folderURL.lastPathComponent, [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
+
+ NSFileWrapper *image = [attachment info].fileWrapper.fileWrappers[@"image.png"];
+ NSFileWrapper *archive = [attachment info].fileWrapper.fileWrappers[@"archive.zip"];
+ EXPECT_TRUE([image.regularFileContents isEqualToData:testImageData()]);
+ EXPECT_TRUE([archive.regularFileContents isEqualToData:testZIPData()]);
+
+ [webView evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
+ [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
+ [webView _executeEditCommand:@"InsertHTML" argument:@"<em>foo</em>" completion:nil];
+ [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
+
+ [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"EM"];
+ [simulator clearExternalDragInformation];
+ [simulator runFrom:webView.attachmentElementMidPoint to:CGPointMake(300, 300)];
+ [webView expectElementTag:@"EM" toComeBefore:@"ATTACHMENT"];
+ });
+}
+
+TEST(WKAttachmentTests, InsertFolderAndFileWithUnknownExtension)
+{
+ auto webView = webViewForTestingAttachments();
+ auto file = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testHTMLData()]);
+ [file setPreferredFilename:@"test.foobar"];
+ auto image = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testImageData()]);
+ auto document = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testPDFData()]);
+ auto folder = adoptNS([[NSFileWrapper alloc] initDirectoryWithFileWrappers:@{ @"image.png": image.get(), @"document.pdf": document.get() }]);
+ [folder setPreferredFilename:@"folder"];
+
+ RetainPtr<_WKAttachment> firstAttachment;
+ RetainPtr<_WKAttachment> secondAttachment;
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ firstAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:file.get() contentType:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ firstAttachment.get() ]);
+ }
+ {
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ secondAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:folder.get() contentType:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ secondAttachment.get() ]);
+ }
+
+ auto checkAttachmentConsistency = [webView, file, folder] (_WKAttachment *expectedFileAttachment, _WKAttachment *expectedFolderAttachment) {
+ [webView expectElementCount:2 tagName:@"ATTACHMENT"];
+ EXPECT_TRUE(UTTypeConformsTo((__bridge CFStringRef)[webView valueOfAttribute:@"type" forQuerySelector:@"attachment[title=folder]"], kUTTypeDirectory));
+ EXPECT_TRUE(UTTypeConformsTo((__bridge CFStringRef)[webView valueOfAttribute:@"type" forQuerySelector:@"attachment[title^=test]"], kUTTypeData));
+ EXPECT_WK_STREQ(expectedFileAttachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title^=test]').uniqueIdentifier"]);
+ EXPECT_WK_STREQ(expectedFolderAttachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title=folder]').uniqueIdentifier"]);
+ EXPECT_TRUE([expectedFileAttachment.info.fileWrapper isEqual:file.get()]);
+ EXPECT_TRUE([expectedFolderAttachment.info.fileWrapper isEqual:folder.get()]);
+ };
+
+ checkAttachmentConsistency(firstAttachment.get(), secondAttachment.get());
+
+ {
+ // Swap the two attachments' file wrappers without creating or destroying attachment elements.
+ ObserveAttachmentUpdatesForScope observer(webView.get());
+ [firstAttachment synchronouslySetFileWrapper:folder.get() newContentType:nil error:nil];
+ [secondAttachment synchronouslySetFileWrapper:file.get() newContentType:nil error:nil];
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
+ }
+
+ checkAttachmentConsistency(secondAttachment.get(), firstAttachment.get());
+}
+
TEST(WKAttachmentTests, ChangeAttachmentDataAndFileInformation)
{
auto webView = webViewForTestingAttachments();
@@ -761,7 +873,7 @@
[attachment expectRequestedDataToBe:pdfData.get()];
EXPECT_WK_STREQ(@"test.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ(@"application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
- observer.expectAttachmentUpdates(@[], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
}
{
RetainPtr<NSData> imageData = testImageData();
@@ -770,10 +882,10 @@
[attachment expectRequestedDataToBe:imageData.get()];
EXPECT_WK_STREQ(@"icon.png", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ(@"image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
- observer.expectAttachmentUpdates(@[], @[]);
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
}
{
- RetainPtr<NSData> textData = testHTMLData();
+ RetainPtr<NSData> textData = [@"Hello world" dataUsingEncoding:NSUTF8StringEncoding];
ObserveAttachmentUpdatesForScope observer(webView.get());
// The new content type should be inferred from the file name.
[attachment synchronouslySetData:textData.get() newContentType:nil newFilename:@"foo.txt" error:nil];
@@ -780,19 +892,18 @@
[attachment expectRequestedDataToBe:textData.get()];
EXPECT_WK_STREQ(@"foo.txt", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ(@"text/plain", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
- observer.expectAttachmentUpdates(@[], @[]);
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
}
{
- RetainPtr<NSData> secondTextData = [@"Hello world" dataUsingEncoding:NSUTF8StringEncoding];
+ RetainPtr<NSData> htmlData = testHTMLData();
ObserveAttachmentUpdatesForScope observer(webView.get());
- // Both the previous file name and type should be inferred.
- [attachment synchronouslySetData:secondTextData.get() newContentType:nil newFilename:nil error:nil];
- [attachment expectRequestedDataToBe:secondTextData.get()];
- EXPECT_WK_STREQ(@"foo.txt", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
- EXPECT_WK_STREQ(@"text/plain", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
- observer.expectAttachmentUpdates(@[], @[]);
+ [attachment synchronouslySetData:htmlData.get() newContentType:@"text/html" newFilename:@"bar" error:nil];
+ [attachment expectRequestedDataToBe:htmlData.get()];
+ EXPECT_WK_STREQ(@"bar", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
+ EXPECT_WK_STREQ(@"text/html", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ observer.expectAttachmentUpdates(@[ ], @[ ]);
}
- [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
+ [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[ ]];
}
TEST(WKAttachmentTests, RemoveNewlinesBeforePastedImage)
@@ -903,7 +1014,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[attachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
}
@@ -989,7 +1100,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
originalAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:@"text/plain"];
EXPECT_EQ(0U, observer.observer().removed.count);
- observer.expectAttachmentUpdates(@[], @[originalAttachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ originalAttachment.get() ]);
}
[webView selectAll:nil];
[webView _executeEditCommand:@"Copy" argument:nil completion:nil];
@@ -1005,13 +1116,13 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[pastedAttachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ pastedAttachment.get() ], @[ ]);
[originalAttachment expectRequestedDataToBe:data.get()];
}
{
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[originalAttachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ originalAttachment.get() ], @[ ]);
}
EXPECT_FALSE([originalAttachment isEqual:pastedAttachment.get()]);
@@ -1030,7 +1141,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
originalAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:@"text/plain"];
EXPECT_EQ(0U, observer.observer().removed.count);
- observer.expectAttachmentUpdates(@[], @[originalAttachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ originalAttachment.get() ]);
}
[webView selectAll:nil];
[webView _executeEditCommand:@"Copy" argument:nil completion:nil];
@@ -1219,7 +1330,7 @@
auto mainResource = adoptNS([[WebResource alloc] initWithData:markupData URL:[NSURL URLWithString:@"foo.html"] MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
auto pngResource = adoptNS([[WebResource alloc] initWithData:testImageData() URL:[NSURL URLWithString:@"1.png"] MIMEType:@"image/png" textEncodingName:nil frameName:nil]);
auto gifResource = adoptNS([[WebResource alloc] initWithData:testGIFData() URL:[NSURL URLWithString:@"2.gif"] MIMEType:@"image/gif" textEncodingName:nil frameName:nil]);
- auto archive = adoptNS([[WebArchive alloc] initWithMainResource:(__bridge WebResource *)mainResource.get() subresources:@[ (__bridge WebResource *)pngResource.get(), (__bridge WebResource *)gifResource.get() ] subframeArchives:@[ ]]);
+ auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:@[ pngResource.get(), gifResource.get() ] subframeArchives:@[ ]]);
#if PLATFORM(MAC)
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
@@ -1234,7 +1345,7 @@
RetainPtr<_WKAttachment> pngAttachment;
auto webView = webViewForTestingAttachments();
- ObserveAttachmentUpdatesForScope observer((__bridge TestWKWebView *)webView.get());
+ ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
[webView expectElementCount:2 tagName:@"IMG"];
@@ -1249,7 +1360,7 @@
EXPECT_WK_STREQ("bar", [gifAttachment info].name);
[pngAttachment expectRequestedDataToBe:testImageData()];
[gifAttachment expectRequestedDataToBe:testGIFData()];
- observer.expectAttachmentUpdates(@[ ], @[ (__bridge _WKAttachment *)pngAttachment.get(), (__bridge _WKAttachment *)gifAttachment.get() ]);
+ observer.expectAttachmentUpdates(@[ ], @[ pngAttachment.get(), gifAttachment.get() ]);
}
#pragma mark - Platform-specific tests
@@ -1363,7 +1474,7 @@
auto webView = webViewForTestingAttachments();
auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
auto item = adoptNS([[NSItemProvider alloc] init]);
- [item registerData:testImageData() type:(NSString *)kUTTypePNG];
+ [item registerData:testImageData() type:(__bridge NSString *)kUTTypePNG];
[dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
[dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];
@@ -1377,7 +1488,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[attachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
}
@@ -1385,7 +1496,7 @@
{
auto webView = webViewForTestingAttachments();
auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
- auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(NSString *)kUTTypePNG]);
+ auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);
auto item = adoptNS([[NSItemProvider alloc] init]);
[item registerObject:[NSAttributedString attributedStringWithAttachment:image.get()] visibility:NSItemProviderRepresentationVisibilityAll];
@@ -1405,7 +1516,7 @@
ObserveAttachmentUpdatesForScope observer(webView.get());
[webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
[webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
- observer.expectAttachmentUpdates(@[attachment.get()], @[]);
+ observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
}
}
@@ -1451,7 +1562,7 @@
// presentation style (e.g. Notes) into Mail.
auto item = adoptNS([[NSItemProvider alloc] init]);
NSData *data = ""
- [item registerData:data type:(NSString *)kUTTypeZipArchive];
+ [item registerData:data type:(__bridge NSString *)kUTTypeZipArchive];
[item setSuggestedName:@"archive.zip"];
auto webView = webViewForTestingAttachments();
@@ -1481,7 +1592,7 @@
[inlineTextItem registerObject:appleURL.get() visibility:NSItemProviderRepresentationVisibilityAll];
auto secondAttachmentItem = adoptNS([[NSItemProvider alloc] init]);
- [secondAttachmentItem registerData:testPDFData() type:(NSString *)kUTTypePDF];
+ [secondAttachmentItem registerData:testPDFData() type:(__bridge NSString *)kUTTypePDF];
[secondAttachmentItem setSuggestedName:@"second.pdf"];
auto webView = webViewForTestingAttachments();
@@ -1508,7 +1619,7 @@
{
auto item = adoptNS([[NSItemProvider alloc] init]);
auto data = ""
- [item registerData:data.get() type:(NSString *)kUTTypePDF];
+ [item registerData:data.get() type:(__bridge NSString *)kUTTypePDF];
[item setSuggestedName:@"document.pdf"];
auto webView = webViewForTestingAttachments();
@@ -1531,7 +1642,7 @@
EXPECT_EQ(1U, [dragAndDropSimulator sourceItemProviders].count);
NSItemProvider *itemProvider = [dragAndDropSimulator sourceItemProviders].firstObject;
EXPECT_EQ(UIPreferredPresentationStyleAttachment, itemProvider.preferredPresentationStyle);
- [itemProvider expectType:(NSString *)kUTTypePDF withData:data.get()];
+ [itemProvider expectType:(__bridge NSString *)kUTTypePDF withData:data.get()];
EXPECT_WK_STREQ("document.pdf", [itemProvider suggestedName]);
[dragAndDropSimulator endDataTransfer];
}
@@ -1544,7 +1655,7 @@
{
ObserveAttachmentUpdatesForScope observer(webView.get());
attachment = [webView synchronouslyInsertAttachmentWithFilename:@"document.pdf" contentType:@"application/pdf" data:data.get()];
- observer.expectAttachmentUpdates(@[], @[attachment.get()]);
+ observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
}
// First, verify that the attachment was successfully inserted from raw data.
@@ -1560,7 +1671,7 @@
EXPECT_EQ(1U, [dragAndDropSimulator sourceItemProviders].count);
NSItemProvider *itemProvider = [dragAndDropSimulator sourceItemProviders].firstObject;
EXPECT_EQ(UIPreferredPresentationStyleAttachment, itemProvider.preferredPresentationStyle);
- [itemProvider expectType:(NSString *)kUTTypePDF withData:data.get()];
+ [itemProvider expectType:(__bridge NSString *)kUTTypePDF withData:data.get()];
EXPECT_WK_STREQ("document.pdf", [itemProvider suggestedName]);
[dragAndDropSimulator endDataTransfer];
}
Modified: trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h (235391 => 235392)
--- trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2018-08-27 20:14:21 UTC (rev 235392)
@@ -80,6 +80,7 @@
// The start location, end location, and locations of additional item requests are all in window coordinates.
- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation;
- (void)endDataTransfer;
+- (void)clearExternalDragInformation;
@property (nonatomic, readonly) NSArray<_WKAttachment *> *insertedAttachments;
@property (nonatomic, readonly) NSArray<_WKAttachment *> *removedAttachments;
@property (nonatomic, readonly) TestWKWebView *webView;
Modified: trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm (235391 => 235392)
--- trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -568,6 +568,11 @@
[self _scheduleAdvanceProgress];
}
+- (void)clearExternalDragInformation
+{
+ _externalItemProviders = nil;
+}
+
- (CGPoint)_currentLocation
{
CGFloat distanceX = _endLocation.x - _startLocation.x;
Modified: trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm (235391 => 235392)
--- trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-27 19:38:07 UTC (rev 235391)
+++ trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-27 20:14:21 UTC (rev 235392)
@@ -358,6 +358,13 @@
return _externalPromisedFiles.get();
}
+- (void)clearExternalDragInformation
+{
+ _externalPromisedFiles = nil;
+ _externalDragImage = nil;
+ _externalDragPasteboard = nil;
+}
+
static BOOL getFilePathsAndTypeIdentifiers(NSArray<NSURL *> *fileURLs, NSArray<NSString *> **outFilePaths, NSArray<NSString *> **outTypeIdentifiers)
{
NSMutableArray *filePaths = [NSMutableArray arrayWithCapacity:fileURLs.count];