summaryrefslogtreecommitdiffstats
path: root/widget/nsClipboardProxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/nsClipboardProxy.cpp')
-rw-r--r--widget/nsClipboardProxy.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp
new file mode 100644
index 000000000..f7d863475
--- /dev/null
+++ b/widget/nsClipboardProxy.cpp
@@ -0,0 +1,169 @@
+/* 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/dom/ContentChild.h"
+#include "mozilla/Unused.h"
+#include "nsArrayUtils.h"
+#include "nsClipboardProxy.h"
+#include "nsISupportsPrimitives.h"
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsXULAppAPI.h"
+#include "nsContentUtils.h"
+#include "nsStringStream.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS(nsClipboardProxy, nsIClipboard, nsIClipboardProxy)
+
+nsClipboardProxy::nsClipboardProxy()
+ : mClipboardCaps(false, false)
+{
+}
+
+NS_IMETHODIMP
+nsClipboardProxy::SetData(nsITransferable *aTransferable,
+ nsIClipboardOwner *anOwner, int32_t aWhichClipboard)
+{
+ ContentChild* child = ContentChild::GetSingleton();
+
+ IPCDataTransfer ipcDataTransfer;
+ nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcDataTransfer,
+ false, child, nullptr);
+
+ bool isPrivateData = false;
+ aTransferable->GetIsPrivateData(&isPrivateData);
+ nsCOMPtr<nsIPrincipal> requestingPrincipal;
+ aTransferable->GetRequestingPrincipal(getter_AddRefs(requestingPrincipal));
+ child->SendSetClipboard(ipcDataTransfer, isPrivateData,
+ IPC::Principal(requestingPrincipal), aWhichClipboard);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
+{
+ nsTArray<nsCString> types;
+
+ nsCOMPtr<nsIArray> flavorList;
+ aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
+ if (flavorList) {
+ uint32_t flavorCount = 0;
+ flavorList->GetLength(&flavorCount);
+ for (uint32_t j = 0; j < flavorCount; ++j) {
+ nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
+ if (flavor) {
+ nsAutoCString flavorStr;
+ flavor->GetData(flavorStr);
+ if (flavorStr.Length()) {
+ types.AppendElement(flavorStr);
+ }
+ }
+ }
+ }
+
+ nsresult rv;
+ IPCDataTransfer dataTransfer;
+ ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard, &dataTransfer);
+
+ auto& items = dataTransfer.items();
+ for (uint32_t j = 0; j < items.Length(); ++j) {
+ const IPCDataTransferItem& item = items[j];
+
+ if (item.data().type() == IPCDataTransferData::TnsString) {
+ nsCOMPtr<nsISupportsString> dataWrapper =
+ do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsString data = item.data().get_nsString();
+ rv = dataWrapper->SetData(data);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
+ data.Length() * sizeof(char16_t));
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else if (item.data().type() == IPCDataTransferData::TShmem) {
+ // If this is an image, convert it into an nsIInputStream.
+ nsCString flavor = item.flavor();
+ mozilla::ipc::Shmem data = item.data().get_Shmem();
+ if (flavor.EqualsLiteral(kJPEGImageMime) ||
+ flavor.EqualsLiteral(kJPGImageMime) ||
+ flavor.EqualsLiteral(kPNGImageMime) ||
+ flavor.EqualsLiteral(kGIFImageMime)) {
+ nsCOMPtr<nsIInputStream> stream;
+
+ NS_NewCStringInputStream(getter_AddRefs(stream),
+ nsDependentCString(data.get<char>(), data.Size<char>()));
+
+ rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else if (flavor.EqualsLiteral(kNativeHTMLMime) ||
+ flavor.EqualsLiteral(kRTFMime) ||
+ flavor.EqualsLiteral(kCustomTypesMime)) {
+ nsCOMPtr<nsISupportsCString> dataWrapper =
+ do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = dataWrapper->SetData(nsDependentCString(data.get<char>(), data.Size<char>()));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
+ data.Size<char>());
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ mozilla::Unused << ContentChild::GetSingleton()->DeallocShmem(data);
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard)
+{
+ ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboardProxy::HasDataMatchingFlavors(const char **aFlavorList,
+ uint32_t aLength, int32_t aWhichClipboard,
+ bool *aHasType)
+{
+ *aHasType = false;
+
+ nsTArray<nsCString> types;
+ nsCString* t = types.AppendElements(aLength);
+ for (uint32_t j = 0; j < aLength; ++j) {
+ t[j].Rebind(aFlavorList[j], nsCharTraits<char>::length(aFlavorList[j]));
+ }
+
+ ContentChild::GetSingleton()->SendClipboardHasType(types, aWhichClipboard, aHasType);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported)
+{
+ *aIsSupported = mClipboardCaps.supportsSelectionClipboard();
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsClipboardProxy::SupportsFindClipboard(bool *aIsSupported)
+{
+ *aIsSupported = mClipboardCaps.supportsFindClipboard();
+ return NS_OK;
+}
+
+void
+nsClipboardProxy::SetCapabilities(const ClipboardCapabilities& aClipboardCaps)
+{
+ mClipboardCaps = aClipboardCaps;
+}