/** * 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; } 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)); inputElement->SetFiles(fileList, true); nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, NS_LITERAL_STRING("change"), true, false); } return NS_OK; }
/** * 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; }