static void AppendBlobImplAsDirectory(nsTArray<OwningFileOrDirectory>& aArray, BlobImpl* aBlobImpl, nsIContent* aContent) { MOZ_ASSERT(aBlobImpl); MOZ_ASSERT(aBlobImpl->IsDirectory()); nsAutoString fullpath; ErrorResult err; aBlobImpl->GetMozFullPath(fullpath, err); if (err.Failed()) { err.SuppressException(); return; } nsCOMPtr<nsIFile> file; NS_ConvertUTF16toUTF8 path(fullpath); nsresult rv = NS_NewNativeLocalFile(path, true, getter_AddRefs(file)); if (NS_WARN_IF(NS_FAILED(rv))) { return; } nsPIDOMWindowInner* inner = aContent->OwnerDoc()->GetInnerWindow(); if (!inner || !inner->IsCurrentInnerWindow()) { return; } RefPtr<Directory> directory = Directory::Create(inner, file); MOZ_ASSERT(directory); OwningFileOrDirectory* element = aArray.AppendElement(); element->SetAsDirectory() = directory; }
void GetDirectoryListingTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue, ErrorResult& aRv) { mFileSystem->AssertIsOnOwningThread(); MOZ_ASSERT(aValue.type() == FileSystemResponseValue::TFileSystemDirectoryListingResponse); FileSystemDirectoryListingResponse r = aValue; for (uint32_t i = 0; i < r.data().Length(); ++i) { const FileSystemDirectoryListingResponseData& data = r.data()[i]; OwningFileOrDirectory* ofd = mTargetData.AppendElement(fallible); if (!ofd) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } if (data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseFile) { const FileSystemDirectoryListingResponseFile& d = data.get_FileSystemDirectoryListingResponseFile(); RefPtr<BlobImpl> blobImpl = static_cast<BlobChild*>(d.blobChild())->GetBlobImpl(); MOZ_ASSERT(blobImpl); RefPtr<File> file = File::Create(mFileSystem->GetParentObject(), blobImpl); MOZ_ASSERT(file); ofd->SetAsFile() = file; } else { MOZ_ASSERT(data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseDirectory); const FileSystemDirectoryListingResponseDirectory& d = data.get_FileSystemDirectoryListingResponseDirectory(); nsCOMPtr<nsIFile> path; aRv = NS_NewLocalFile(d.directoryRealPath(), true, getter_AddRefs(path)); if (NS_WARN_IF(aRv.Failed())) { return; } RefPtr<Directory> directory = Directory::Create(mFileSystem->GetParentObject(), path, mFileSystem); MOZ_ASSERT(directory); ofd->SetAsDirectory() = directory; } } }
bool nsFilePickerProxy::Recv__delete__(const MaybeInputData& aData, const int16_t& aResult) { if (aData.type() == MaybeInputData::TInputBlobs) { const InfallibleTArray<PBlobChild*>& blobs = aData.get_InputBlobs().blobsChild(); for (uint32_t i = 0; i < blobs.Length(); ++i) { BlobChild* actor = static_cast<BlobChild*>(blobs[i]); RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl(); NS_ENSURE_TRUE(blobImpl, true); if (!blobImpl->IsFile()) { return true; } nsPIDOMWindowInner* inner = mParent ? mParent->GetCurrentInnerWindow() : nullptr; RefPtr<File> file = File::Create(inner, blobImpl); MOZ_ASSERT(file); OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement(); element->SetAsFile() = file; } } else if (aData.type() == MaybeInputData::TInputDirectory) { nsCOMPtr<nsIFile> file; NS_ConvertUTF16toUTF8 path(aData.get_InputDirectory().directoryPath()); nsresult rv = NS_NewNativeLocalFile(path, true, getter_AddRefs(file)); if (NS_WARN_IF(NS_FAILED(rv))) { return true; } RefPtr<Directory> directory = Directory::Create(mParent->GetCurrentInnerWindow(), file, Directory::eDOMRootDirectory); MOZ_ASSERT(directory); OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement(); element->SetAsDirectory() = directory; } if (mCallback) { mCallback->Done(aResult); mCallback = nullptr; } return true; }
/** * This is called when we receive a drop or a dragover. */ NS_IMETHODIMP nsFileControlFrame::DnDListener::HandleEvent(nsIDOMEvent* aEvent) { NS_ASSERTION(mFrame, "We should have been unregistered"); bool defaultPrevented = false; aEvent->GetDefaultPrevented(&defaultPrevented); if (defaultPrevented) { return NS_OK; } nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent); if (!dragEvent) { return NS_OK; } nsCOMPtr<nsIDOMDataTransfer> dataTransfer; dragEvent->GetDataTransfer(getter_AddRefs(dataTransfer)); if (!IsValidDropData(dataTransfer)) { return NS_OK; } nsCOMPtr<nsIContent> content = mFrame->GetContent(); bool supportsMultiple = content && content->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple); if (!CanDropTheseFiles(dataTransfer, supportsMultiple)) { dataTransfer->SetDropEffect(NS_LITERAL_STRING("none")); aEvent->StopPropagation(); return NS_OK; } nsAutoString eventType; aEvent->GetType(eventType); if (eventType.EqualsLiteral("dragover")) { // Prevent default if we can accept this drag data aEvent->PreventDefault(); return NS_OK; } if (eventType.EqualsLiteral("drop")) { aEvent->StopPropagation(); aEvent->PreventDefault(); NS_ASSERTION(content, "The frame has no content???"); HTMLInputElement* inputElement = HTMLInputElement::FromContent(content); NS_ASSERTION(inputElement, "No input element for this file upload control frame!"); nsCOMPtr<nsIDOMFileList> fileList; dataTransfer->GetFiles(getter_AddRefs(fileList)); RefPtr<BlobImpl> webkitDir; nsresult rv = GetBlobImplForWebkitDirectory(fileList, getter_AddRefs(webkitDir)); NS_ENSURE_SUCCESS(rv, NS_OK); nsTArray<OwningFileOrDirectory> array; if (webkitDir) { AppendBlobImplAsDirectory(array, webkitDir, content); inputElement->MozSetDndFilesAndDirectories(array); } else { bool blinkFileSystemEnabled = Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false); if (blinkFileSystemEnabled) { FileList* files = static_cast<FileList*>(fileList.get()); if (files) { for (uint32_t i = 0; i < files->Length(); ++i) { File* file = files->Item(i); if (file) { if (file->Impl() && file->Impl()->IsDirectory()) { AppendBlobImplAsDirectory(array, file->Impl(), content); } else { OwningFileOrDirectory* element = array.AppendElement(); element->SetAsFile() = file; } } } } } // This is rather ugly. Pass the directories as Files using SetFiles, // but then if blink filesystem API is enabled, it wants // FileOrDirectory array. inputElement->SetFiles(fileList, true); if (blinkFileSystemEnabled) { inputElement->UpdateEntries(array); } nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, NS_LITERAL_STRING("input"), true, false); nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, NS_LITERAL_STRING("change"), true, false); } } return NS_OK; }