diff options
Diffstat (limited to '')
-rw-r--r-- | widget/nsClipboardProxy.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp new file mode 100644 index 0000000000..04e5cdc7d5 --- /dev/null +++ b/widget/nsClipboardProxy.cpp @@ -0,0 +1,181 @@ +/* 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 "nsClipboardProxy.h" + +#if defined(ACCESSIBILITY) && defined(XP_WIN) +# include "mozilla/a11y/Compatibility.h" +#endif +#include "mozilla/ClipboardWriteRequestChild.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/net/CookieJarSettings.h" +#include "mozilla/Maybe.h" +#include "mozilla/Unused.h" +#include "nsArrayUtils.h" +#include "nsISupportsPrimitives.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsXULAppAPI.h" +#include "nsContentUtils.h" +#include "PermissionMessageUtils.h" + +using namespace mozilla; +using namespace mozilla::dom; + +NS_IMPL_ISUPPORTS(nsClipboardProxy, nsIClipboard, nsIClipboardProxy) + +nsClipboardProxy::nsClipboardProxy() : mClipboardCaps(false, false, false) {} + +NS_IMETHODIMP +nsClipboardProxy::SetData(nsITransferable* aTransferable, + nsIClipboardOwner* anOwner, int32_t aWhichClipboard) { +#if defined(ACCESSIBILITY) && defined(XP_WIN) + a11y::Compatibility::SuppressA11yForClipboardCopy(); +#endif + + ContentChild* child = ContentChild::GetSingleton(); + IPCTransferable ipcTransferable; + nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable, + false, nullptr); + child->SendSetClipboard(std::move(ipcTransferable), aWhichClipboard); + return NS_OK; +} + +NS_IMETHODIMP nsClipboardProxy::AsyncSetData( + int32_t aWhichClipboard, nsIAsyncSetClipboardDataCallback* aCallback, + nsIAsyncSetClipboardData** _retval) { + RefPtr<ClipboardWriteRequestChild> request = + MakeRefPtr<ClipboardWriteRequestChild>(aCallback); + ContentChild::GetSingleton()->SendPClipboardWriteRequestConstructor( + request, aWhichClipboard); + request.forget(_retval); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboardProxy::GetData(nsITransferable* aTransferable, + int32_t aWhichClipboard) { + nsTArray<nsCString> types; + aTransferable->FlavorsTransferableCanImport(types); + + IPCTransferableData transferable; + ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard, + &transferable); + return nsContentUtils::IPCTransferableDataToTransferable( + transferable, false /* aAddDataFlavor */, aTransferable, + false /* aFilterUnknownFlavors */); +} + +NS_IMETHODIMP +nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard) { + ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboardProxy::HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList, + int32_t aWhichClipboard, + bool* aHasType) { + *aHasType = false; + + ContentChild::GetSingleton()->SendClipboardHasType(aFlavorList, + aWhichClipboard, aHasType); + + return NS_OK; +} + +NS_IMETHODIMP +nsClipboardProxy::IsClipboardTypeSupported(int32_t aWhichClipboard, + bool* aIsSupported) { + switch (aWhichClipboard) { + case kGlobalClipboard: + // We always support the global clipboard. + *aIsSupported = true; + return NS_OK; + case kSelectionClipboard: + *aIsSupported = mClipboardCaps.supportsSelectionClipboard(); + return NS_OK; + case kFindClipboard: + *aIsSupported = mClipboardCaps.supportsFindClipboard(); + return NS_OK; + case kSelectionCache: + *aIsSupported = mClipboardCaps.supportsSelectionCache(); + return NS_OK; + } + + *aIsSupported = false; + return NS_OK; +} + +void nsClipboardProxy::SetCapabilities( + const ClipboardCapabilities& aClipboardCaps) { + mClipboardCaps = aClipboardCaps; +} + +RefPtr<DataFlavorsPromise> nsClipboardProxy::AsyncHasDataMatchingFlavors( + const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) { + auto promise = MakeRefPtr<DataFlavorsPromise::Private>(__func__); + ContentChild::GetSingleton() + ->SendClipboardHasTypesAsync(aFlavorList, aWhichClipboard) + ->Then( + GetMainThreadSerialEventTarget(), __func__, + /* resolve */ + [promise](nsTArray<nsCString> types) { + promise->Resolve(std::move(types), __func__); + }, + /* reject */ + [promise](mozilla::ipc::ResponseRejectReason aReason) { + promise->Reject(NS_ERROR_FAILURE, __func__); + }); + + return promise.forget(); +} + +RefPtr<GenericPromise> nsClipboardProxy::AsyncGetData( + nsITransferable* aTransferable, int32_t aWhichClipboard) { + if (!aTransferable) { + return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + } + + // Get a list of flavors this transferable can import + nsTArray<nsCString> flavors; + nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors); + if (NS_FAILED(rv)) { + return GenericPromise::CreateAndReject(rv, __func__); + } + + nsCOMPtr<nsITransferable> transferable(aTransferable); + auto promise = MakeRefPtr<GenericPromise::Private>(__func__); + ContentChild::GetSingleton() + ->SendGetClipboardAsync(flavors, aWhichClipboard) + ->Then( + GetMainThreadSerialEventTarget(), __func__, + /* resolve */ + [promise, transferable]( + const IPCTransferableDataOrError& ipcTransferableDataOrError) { + if (ipcTransferableDataOrError.type() == + IPCTransferableDataOrError::Tnsresult) { + promise->Reject(ipcTransferableDataOrError.get_nsresult(), + __func__); + return; + } + + nsresult rv = nsContentUtils::IPCTransferableDataToTransferable( + ipcTransferableDataOrError.get_IPCTransferableData(), + false /* aAddDataFlavor */, transferable, + false /* aFilterUnknownFlavors */); + if (NS_FAILED(rv)) { + promise->Reject(rv, __func__); + return; + } + + promise->Resolve(true, __func__); + }, + /* reject */ + [promise](mozilla::ipc::ResponseRejectReason aReason) { + promise->Reject(NS_ERROR_FAILURE, __func__); + }); + + return promise.forget(); +} |