Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "mozilla/dom/ContentChild.h"
6 : #include "mozilla/Unused.h"
7 : #include "nsArrayUtils.h"
8 : #include "nsClipboardProxy.h"
9 : #include "nsISupportsPrimitives.h"
10 : #include "nsCOMPtr.h"
11 : #include "nsComponentManagerUtils.h"
12 : #include "nsXULAppAPI.h"
13 : #include "nsContentUtils.h"
14 : #include "nsStringStream.h"
15 :
16 : using namespace mozilla;
17 : using namespace mozilla::dom;
18 :
19 18 : NS_IMPL_ISUPPORTS(nsClipboardProxy, nsIClipboard, nsIClipboardProxy)
20 :
21 2 : nsClipboardProxy::nsClipboardProxy()
22 2 : : mClipboardCaps(false, false)
23 : {
24 2 : }
25 :
26 : NS_IMETHODIMP
27 0 : nsClipboardProxy::SetData(nsITransferable *aTransferable,
28 : nsIClipboardOwner *anOwner, int32_t aWhichClipboard)
29 : {
30 0 : ContentChild* child = ContentChild::GetSingleton();
31 :
32 0 : IPCDataTransfer ipcDataTransfer;
33 0 : nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcDataTransfer,
34 0 : false, child, nullptr);
35 :
36 0 : bool isPrivateData = false;
37 0 : aTransferable->GetIsPrivateData(&isPrivateData);
38 0 : nsCOMPtr<nsIPrincipal> requestingPrincipal;
39 0 : aTransferable->GetRequestingPrincipal(getter_AddRefs(requestingPrincipal));
40 0 : child->SendSetClipboard(ipcDataTransfer, isPrivateData,
41 0 : IPC::Principal(requestingPrincipal), aWhichClipboard);
42 :
43 0 : return NS_OK;
44 : }
45 :
46 : NS_IMETHODIMP
47 0 : nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
48 : {
49 0 : nsTArray<nsCString> types;
50 :
51 0 : nsCOMPtr<nsIArray> flavorList;
52 0 : aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
53 0 : if (flavorList) {
54 0 : uint32_t flavorCount = 0;
55 0 : flavorList->GetLength(&flavorCount);
56 0 : for (uint32_t j = 0; j < flavorCount; ++j) {
57 0 : nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
58 0 : if (flavor) {
59 0 : nsAutoCString flavorStr;
60 0 : flavor->GetData(flavorStr);
61 0 : if (flavorStr.Length()) {
62 0 : types.AppendElement(flavorStr);
63 : }
64 : }
65 : }
66 : }
67 :
68 : nsresult rv;
69 0 : IPCDataTransfer dataTransfer;
70 0 : ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard, &dataTransfer);
71 :
72 0 : auto& items = dataTransfer.items();
73 0 : for (uint32_t j = 0; j < items.Length(); ++j) {
74 0 : const IPCDataTransferItem& item = items[j];
75 :
76 0 : if (item.data().type() == IPCDataTransferData::TnsString) {
77 : nsCOMPtr<nsISupportsString> dataWrapper =
78 0 : do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
79 0 : NS_ENSURE_SUCCESS(rv, rv);
80 :
81 0 : nsString data = item.data().get_nsString();
82 0 : rv = dataWrapper->SetData(data);
83 0 : NS_ENSURE_SUCCESS(rv, rv);
84 :
85 0 : rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
86 0 : data.Length() * sizeof(char16_t));
87 0 : NS_ENSURE_SUCCESS(rv, rv);
88 0 : } else if (item.data().type() == IPCDataTransferData::TShmem) {
89 : // If this is an image, convert it into an nsIInputStream.
90 0 : nsCString flavor = item.flavor();
91 0 : mozilla::ipc::Shmem data = item.data().get_Shmem();
92 0 : if (flavor.EqualsLiteral(kJPEGImageMime) ||
93 0 : flavor.EqualsLiteral(kJPGImageMime) ||
94 0 : flavor.EqualsLiteral(kPNGImageMime) ||
95 0 : flavor.EqualsLiteral(kGIFImageMime)) {
96 0 : nsCOMPtr<nsIInputStream> stream;
97 :
98 0 : NS_NewCStringInputStream(getter_AddRefs(stream),
99 0 : nsDependentCString(data.get<char>(), data.Size<char>()));
100 :
101 0 : rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
102 0 : NS_ENSURE_SUCCESS(rv, rv);
103 0 : } else if (flavor.EqualsLiteral(kNativeHTMLMime) ||
104 0 : flavor.EqualsLiteral(kRTFMime) ||
105 0 : flavor.EqualsLiteral(kCustomTypesMime)) {
106 : nsCOMPtr<nsISupportsCString> dataWrapper =
107 0 : do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
108 0 : NS_ENSURE_SUCCESS(rv, rv);
109 :
110 0 : rv = dataWrapper->SetData(nsDependentCString(data.get<char>(), data.Size<char>()));
111 0 : NS_ENSURE_SUCCESS(rv, rv);
112 :
113 0 : rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
114 0 : data.Size<char>());
115 0 : NS_ENSURE_SUCCESS(rv, rv);
116 : }
117 :
118 0 : mozilla::Unused << ContentChild::GetSingleton()->DeallocShmem(data);
119 : }
120 : }
121 :
122 0 : return NS_OK;
123 : }
124 :
125 : NS_IMETHODIMP
126 0 : nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard)
127 : {
128 0 : ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard);
129 0 : return NS_OK;
130 : }
131 :
132 : NS_IMETHODIMP
133 0 : nsClipboardProxy::HasDataMatchingFlavors(const char **aFlavorList,
134 : uint32_t aLength, int32_t aWhichClipboard,
135 : bool *aHasType)
136 : {
137 0 : *aHasType = false;
138 :
139 0 : nsTArray<nsCString> types;
140 0 : nsCString* t = types.AppendElements(aLength);
141 0 : for (uint32_t j = 0; j < aLength; ++j) {
142 0 : t[j].Rebind(aFlavorList[j], nsCharTraits<char>::length(aFlavorList[j]));
143 : }
144 :
145 0 : ContentChild::GetSingleton()->SendClipboardHasType(types, aWhichClipboard, aHasType);
146 :
147 0 : return NS_OK;
148 : }
149 :
150 : NS_IMETHODIMP
151 0 : nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported)
152 : {
153 0 : *aIsSupported = mClipboardCaps.supportsSelectionClipboard();
154 0 : return NS_OK;
155 : }
156 :
157 :
158 : NS_IMETHODIMP
159 0 : nsClipboardProxy::SupportsFindClipboard(bool *aIsSupported)
160 : {
161 0 : *aIsSupported = mClipboardCaps.supportsFindClipboard();
162 0 : return NS_OK;
163 : }
164 :
165 : void
166 2 : nsClipboardProxy::SetCapabilities(const ClipboardCapabilities& aClipboardCaps)
167 : {
168 2 : mClipboardCaps = aClipboardCaps;
169 2 : }
|