mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
d88b0348e7
This implementation supports - HTML drag & drop API. - Drop and drop for text/plain or text/html from/to external application. Differential Revision: https://phabricator.services.mozilla.com/D197330
215 lines
6.3 KiB
C++
215 lines
6.3 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "mozilla/java/ClipboardWrappers.h"
|
|
#include "mozilla/java/GeckoAppShellWrappers.h"
|
|
#include "nsClipboard.h"
|
|
#include "nsISupportsPrimitives.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsMemory.h"
|
|
#include "nsStringStream.h"
|
|
#include "nsPrimitiveHelpers.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(nsClipboard, nsBaseClipboard)
|
|
|
|
/* The Android clipboard only supports text and doesn't support mime types
|
|
* so we assume all clipboard data is text/plain for now. Documentation
|
|
* indicates that support for other data types is planned for future
|
|
* releases.
|
|
*/
|
|
|
|
nsClipboard::nsClipboard()
|
|
: nsBaseClipboard(mozilla::dom::ClipboardCapabilities(
|
|
false /* supportsSelectionClipboard */,
|
|
false /* supportsFindClipboard */,
|
|
false /* supportsSelectionCache */)) {
|
|
java::Clipboard::StartTrackingClipboardData(
|
|
java::GeckoAppShell::GetApplicationContext());
|
|
}
|
|
|
|
nsClipboard::~nsClipboard() {
|
|
java::Clipboard::StopTrackingClipboardData(
|
|
java::GeckoAppShell::GetApplicationContext());
|
|
}
|
|
|
|
// static
|
|
nsresult nsClipboard::GetTextFromTransferable(nsITransferable* aTransferable,
|
|
nsString& aText,
|
|
nsString& aHTML) {
|
|
nsTArray<nsCString> flavors;
|
|
nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
for (auto& flavorStr : flavors) {
|
|
if (flavorStr.EqualsLiteral(kTextMime)) {
|
|
nsCOMPtr<nsISupports> item;
|
|
nsresult rv =
|
|
aTransferable->GetTransferData(kTextMime, getter_AddRefs(item));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
continue;
|
|
}
|
|
nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(item);
|
|
if (supportsString) {
|
|
supportsString->GetData(aText);
|
|
}
|
|
} else if (flavorStr.EqualsLiteral(kHTMLMime)) {
|
|
nsCOMPtr<nsISupports> item;
|
|
nsresult rv =
|
|
aTransferable->GetTransferData(kHTMLMime, getter_AddRefs(item));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
continue;
|
|
}
|
|
nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(item);
|
|
if (supportsString) {
|
|
supportsString->GetData(aHTML);
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable,
|
|
int32_t aWhichClipboard) {
|
|
MOZ_DIAGNOSTIC_ASSERT(aTransferable);
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
|
|
|
|
if (!jni::IsAvailable()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
nsString text;
|
|
nsString html;
|
|
nsresult rv = GetTextFromTransferable(aTransferable, text, html);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (!html.IsEmpty() &&
|
|
java::Clipboard::SetHTML(java::GeckoAppShell::GetApplicationContext(),
|
|
text, html)) {
|
|
return NS_OK;
|
|
}
|
|
if (!text.IsEmpty() &&
|
|
java::Clipboard::SetText(java::GeckoAppShell::GetApplicationContext(),
|
|
text)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable,
|
|
int32_t aWhichClipboard) {
|
|
MOZ_DIAGNOSTIC_ASSERT(aTransferable);
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
|
|
|
|
if (!jni::IsAvailable()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
nsTArray<nsCString> flavors;
|
|
aTransferable->FlavorsTransferableCanImport(flavors);
|
|
|
|
for (auto& flavorStr : flavors) {
|
|
if (flavorStr.EqualsLiteral(kTextMime) ||
|
|
flavorStr.EqualsLiteral(kHTMLMime)) {
|
|
auto text = java::Clipboard::GetTextData(
|
|
java::GeckoAppShell::GetApplicationContext(), flavorStr);
|
|
if (!text) {
|
|
continue;
|
|
}
|
|
nsString buffer = text->ToString();
|
|
if (buffer.IsEmpty()) {
|
|
continue;
|
|
}
|
|
nsCOMPtr<nsISupports> wrapper;
|
|
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, buffer.get(),
|
|
buffer.Length() * 2,
|
|
getter_AddRefs(wrapper));
|
|
if (wrapper) {
|
|
aTransferable->SetTransferData(flavorStr.get(), wrapper);
|
|
return NS_OK;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
mozilla::jni::ByteArray::LocalRef bytes;
|
|
nsresult rv = java::Clipboard::GetRawData(flavorStr, &bytes);
|
|
if (NS_FAILED(rv) || !bytes) {
|
|
continue;
|
|
}
|
|
nsCOMPtr<nsIInputStream> byteStream;
|
|
rv = NS_NewByteInputStream(
|
|
getter_AddRefs(byteStream),
|
|
mozilla::Span(
|
|
reinterpret_cast<const char*>(bytes->GetElements().Elements()),
|
|
bytes->Length()),
|
|
NS_ASSIGNMENT_COPY);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
continue;
|
|
}
|
|
rv = aTransferable->SetTransferData(flavorStr.get(), byteStream);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsClipboard::EmptyNativeClipboardData(int32_t aWhichClipboard) {
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
|
|
|
|
if (!jni::IsAvailable()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
java::Clipboard::Clear(java::GeckoAppShell::GetApplicationContext());
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
mozilla::Result<int32_t, nsresult>
|
|
nsClipboard::GetNativeClipboardSequenceNumber(int32_t aWhichClipboard) {
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
|
|
|
|
if (!jni::IsAvailable()) {
|
|
return Err(NS_ERROR_NOT_AVAILABLE);
|
|
}
|
|
|
|
return java::Clipboard::GetSequenceNumber(
|
|
java::GeckoAppShell::GetApplicationContext());
|
|
}
|
|
|
|
mozilla::Result<bool, nsresult>
|
|
nsClipboard::HasNativeClipboardDataMatchingFlavors(
|
|
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) {
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
|
|
|
|
if (!jni::IsAvailable()) {
|
|
return Err(NS_ERROR_NOT_AVAILABLE);
|
|
}
|
|
|
|
for (auto& flavor : aFlavorList) {
|
|
if (java::Clipboard::HasData(java::GeckoAppShell::GetApplicationContext(),
|
|
NS_ConvertASCIItoUTF16(flavor))) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|