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/. */
5 #include "mozilla/dom/ContentChild.h"
6 #include "mozilla/Unused.h"
7 #include "nsArrayUtils.h"
8 #include "nsClipboardProxy.h"
9 #include "nsISupportsPrimitives.h"
11 #include "nsComponentManagerUtils.h"
12 #include "nsXULAppAPI.h"
13 #include "nsContentUtils.h"
14 #include "nsStringStream.h"
16 using namespace mozilla
;
17 using namespace mozilla::dom
;
19 NS_IMPL_ISUPPORTS(nsClipboardProxy
, nsIClipboard
, nsIClipboardProxy
)
21 nsClipboardProxy::nsClipboardProxy()
22 : mClipboardCaps(false, false)
27 nsClipboardProxy::SetData(nsITransferable
*aTransferable
,
28 nsIClipboardOwner
*anOwner
, int32_t aWhichClipboard
)
30 ContentChild
* child
= ContentChild::GetSingleton();
32 IPCDataTransfer ipcDataTransfer
;
33 nsContentUtils::TransferableToIPCTransferable(aTransferable
, &ipcDataTransfer
,
34 false, child
, nullptr);
36 bool isPrivateData
= false;
37 aTransferable
->GetIsPrivateData(&isPrivateData
);
38 nsCOMPtr
<nsIPrincipal
> requestingPrincipal
;
39 aTransferable
->GetRequestingPrincipal(getter_AddRefs(requestingPrincipal
));
40 nsContentPolicyType contentPolicyType
= nsIContentPolicy::TYPE_OTHER
;
41 aTransferable
->GetContentPolicyType(&contentPolicyType
);
42 child
->SendSetClipboard(ipcDataTransfer
, isPrivateData
,
43 IPC::Principal(requestingPrincipal
),
44 contentPolicyType
, aWhichClipboard
);
50 nsClipboardProxy::GetData(nsITransferable
*aTransferable
, int32_t aWhichClipboard
)
52 nsTArray
<nsCString
> types
;
54 nsCOMPtr
<nsIArray
> flavorList
;
55 aTransferable
->FlavorsTransferableCanImport(getter_AddRefs(flavorList
));
57 uint32_t flavorCount
= 0;
58 flavorList
->GetLength(&flavorCount
);
59 for (uint32_t j
= 0; j
< flavorCount
; ++j
) {
60 nsCOMPtr
<nsISupportsCString
> flavor
= do_QueryElementAt(flavorList
, j
);
62 nsAutoCString flavorStr
;
63 flavor
->GetData(flavorStr
);
64 if (flavorStr
.Length()) {
65 types
.AppendElement(flavorStr
);
72 IPCDataTransfer dataTransfer
;
73 ContentChild::GetSingleton()->SendGetClipboard(types
, aWhichClipboard
, &dataTransfer
);
75 auto& items
= dataTransfer
.items();
76 for (uint32_t j
= 0; j
< items
.Length(); ++j
) {
77 const IPCDataTransferItem
& item
= items
[j
];
79 if (item
.data().type() == IPCDataTransferData::TnsString
) {
80 nsCOMPtr
<nsISupportsString
> dataWrapper
=
81 do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID
, &rv
);
82 NS_ENSURE_SUCCESS(rv
, rv
);
84 const nsString
& data
= item
.data().get_nsString();
85 rv
= dataWrapper
->SetData(data
);
86 NS_ENSURE_SUCCESS(rv
, rv
);
88 rv
= aTransferable
->SetTransferData(item
.flavor().get(), dataWrapper
,
89 data
.Length() * sizeof(char16_t
));
90 NS_ENSURE_SUCCESS(rv
, rv
);
91 } else if (item
.data().type() == IPCDataTransferData::TShmem
) {
92 // If this is an image, convert it into an nsIInputStream.
93 const nsCString
& flavor
= item
.flavor();
94 mozilla::ipc::Shmem data
= item
.data().get_Shmem();
95 if (flavor
.EqualsLiteral(kJPEGImageMime
) ||
96 flavor
.EqualsLiteral(kJPGImageMime
) ||
97 flavor
.EqualsLiteral(kPNGImageMime
) ||
98 flavor
.EqualsLiteral(kGIFImageMime
)) {
99 nsCOMPtr
<nsIInputStream
> stream
;
101 NS_NewCStringInputStream(getter_AddRefs(stream
),
102 nsDependentCString(data
.get
<char>(), data
.Size
<char>()));
104 rv
= aTransferable
->SetTransferData(flavor
.get(), stream
, sizeof(nsISupports
*));
105 NS_ENSURE_SUCCESS(rv
, rv
);
106 } else if (flavor
.EqualsLiteral(kNativeHTMLMime
) ||
107 flavor
.EqualsLiteral(kRTFMime
) ||
108 flavor
.EqualsLiteral(kCustomTypesMime
)) {
109 nsCOMPtr
<nsISupportsCString
> dataWrapper
=
110 do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID
, &rv
);
111 NS_ENSURE_SUCCESS(rv
, rv
);
113 rv
= dataWrapper
->SetData(nsDependentCString(data
.get
<char>(), data
.Size
<char>()));
114 NS_ENSURE_SUCCESS(rv
, rv
);
116 rv
= aTransferable
->SetTransferData(item
.flavor().get(), dataWrapper
,
118 NS_ENSURE_SUCCESS(rv
, rv
);
121 mozilla::Unused
<< ContentChild::GetSingleton()->DeallocShmem(data
);
129 nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard
)
131 ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard
);
136 nsClipboardProxy::HasDataMatchingFlavors(const char **aFlavorList
,
137 uint32_t aLength
, int32_t aWhichClipboard
,
142 nsTArray
<nsCString
> types
;
143 nsCString
* t
= types
.AppendElements(aLength
);
144 for (uint32_t j
= 0; j
< aLength
; ++j
) {
145 t
[j
].Rebind(aFlavorList
[j
], nsCharTraits
<char>::length(aFlavorList
[j
]));
148 ContentChild::GetSingleton()->SendClipboardHasType(types
, aWhichClipboard
, aHasType
);
154 nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported
)
156 *aIsSupported
= mClipboardCaps
.supportsSelectionClipboard();
162 nsClipboardProxy::SupportsFindClipboard(bool *aIsSupported
)
164 *aIsSupported
= mClipboardCaps
.supportsFindClipboard();
169 nsClipboardProxy::SetCapabilities(const ClipboardCapabilities
& aClipboardCaps
)
171 mClipboardCaps
= aClipboardCaps
;