Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla_dom_DataTransfer_h
8 : #define mozilla_dom_DataTransfer_h
9 :
10 : #include "nsString.h"
11 : #include "nsTArray.h"
12 : #include "nsIVariant.h"
13 : #include "nsIPrincipal.h"
14 : #include "nsIDOMDataTransfer.h"
15 : #include "nsIDOMElement.h"
16 : #include "nsIDragService.h"
17 : #include "nsCycleCollectionParticipant.h"
18 :
19 : #include "mozilla/Attributes.h"
20 : #include "mozilla/EventForwards.h"
21 : #include "mozilla/dom/BindingDeclarations.h"
22 : #include "mozilla/dom/File.h"
23 :
24 : class nsINode;
25 : class nsITransferable;
26 : class nsILoadContext;
27 :
28 : namespace mozilla {
29 :
30 : class EventStateManager;
31 :
32 : namespace dom {
33 :
34 : class DataTransferItem;
35 : class DataTransferItemList;
36 : class DOMStringList;
37 : class Element;
38 : class FileList;
39 : class Promise;
40 : template<typename T> class Optional;
41 :
42 : #define NS_DATATRANSFER_IID \
43 : { 0x6c5f90d1, 0xa886, 0x42c8, \
44 : { 0x85, 0x06, 0x10, 0xbe, 0x5c, 0x0d, 0xc6, 0x77 } }
45 :
46 : class DataTransfer final : public nsIDOMDataTransfer,
47 : public nsWrapperCache
48 : {
49 : public:
50 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID)
51 :
52 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
53 : NS_DECL_NSIDOMDATATRANSFER
54 :
55 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer)
56 :
57 : friend class mozilla::EventStateManager;
58 :
59 0 : static DataTransfer* Cast(nsIDOMDataTransfer* aArg)
60 : {
61 0 : return static_cast<DataTransfer*>(aArg);
62 : }
63 :
64 : protected:
65 :
66 : // hide the default constructor
67 : DataTransfer();
68 :
69 : // this constructor is used only by the Clone method to copy the fields as
70 : // needed to a new data transfer.
71 : DataTransfer(nsISupports* aParent,
72 : EventMessage aEventMessage,
73 : const uint32_t aEffectAllowed,
74 : bool aCursorState,
75 : bool aIsExternal,
76 : bool aUserCancelled,
77 : bool aIsCrossDomainSubFrameDrop,
78 : int32_t aClipboardType,
79 : DataTransferItemList* aItems,
80 : Element* aDragImage,
81 : uint32_t aDragImageX,
82 : uint32_t aDragImageY);
83 :
84 : ~DataTransfer();
85 :
86 : static const char sEffects[8][9];
87 :
88 : public:
89 : // Constructor for DataTransfer.
90 : //
91 : // aIsExternal must only be true when used to create a dataTransfer for a
92 : // paste or a drag that was started without using a data transfer. The
93 : // latter will occur when an external drag occurs, that is, a drag where the
94 : // source is another application, or a drag is started by calling the drag
95 : // service directly. For clipboard operations, aClipboardType indicates
96 : // which clipboard to use, from nsIClipboard, or -1 for non-clipboard
97 : // operations, or if access to the system clipboard should not be allowed.
98 : DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
99 : bool aIsExternal, int32_t aClipboardType);
100 :
101 : virtual JSObject*
102 : WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
103 :
104 0 : nsISupports* GetParentObject() const
105 : {
106 0 : return mParent;
107 : }
108 :
109 0 : void SetParentObject(nsISupports* aNewParent)
110 : {
111 0 : MOZ_ASSERT(aNewParent);
112 : // Setting the parent after we've been wrapped is pointless, so
113 : // make sure we aren't wrapped yet.
114 0 : MOZ_ASSERT(!GetWrapperPreserveColor());
115 0 : mParent = aNewParent;
116 0 : }
117 :
118 : static already_AddRefed<DataTransfer>
119 : Constructor(const GlobalObject& aGlobal, const nsAString& aEventType,
120 : bool aIsExternal, ErrorResult& aRv);
121 :
122 0 : void GetDropEffect(nsString& aDropEffect)
123 : {
124 0 : aDropEffect.AssignASCII(sEffects[mDropEffect]);
125 0 : }
126 :
127 0 : void GetEffectAllowed(nsString& aEffectAllowed)
128 : {
129 0 : if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) {
130 0 : aEffectAllowed.AssignLiteral("uninitialized");
131 : } else {
132 0 : aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
133 : }
134 0 : }
135 :
136 : void SetDragImage(Element& aElement, int32_t aX, int32_t aY);
137 : void UpdateDragImage(Element& aElement, int32_t aX, int32_t aY);
138 :
139 : void GetTypes(nsTArray<nsString>& aTypes, CallerType aCallerType) const;
140 :
141 : void GetData(const nsAString& aFormat, nsAString& aData,
142 : nsIPrincipal& aSubjectPrincipal,
143 : ErrorResult& aRv);
144 :
145 : void SetData(const nsAString& aFormat, const nsAString& aData,
146 : nsIPrincipal& aSubjectPrincipal,
147 : ErrorResult& aRv);
148 :
149 : void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
150 : nsIPrincipal& aSubjectPrincipal,
151 : mozilla::ErrorResult& aRv);
152 :
153 : already_AddRefed<FileList>
154 : GetFiles(nsIPrincipal& aSubjectPrincipal,
155 : mozilla::ErrorResult& aRv);
156 :
157 : already_AddRefed<Promise>
158 : GetFilesAndDirectories(nsIPrincipal& aSubjectPrincipal,
159 : mozilla::ErrorResult& aRv);
160 :
161 : already_AddRefed<Promise>
162 : GetFiles(bool aRecursiveFlag,
163 : nsIPrincipal& aSubjectPrincipal,
164 : ErrorResult& aRv);
165 :
166 :
167 : void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
168 :
169 : uint32_t MozItemCount() const;
170 :
171 0 : void GetMozCursor(nsString& aCursor)
172 : {
173 0 : if (mCursorState) {
174 0 : aCursor.AssignLiteral("default");
175 : } else {
176 0 : aCursor.AssignLiteral("auto");
177 : }
178 0 : }
179 :
180 : already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex,
181 : CallerType aCallerType,
182 : mozilla::ErrorResult& aRv) const;
183 :
184 : void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
185 : nsIPrincipal& aSubjectPrincipal,
186 : mozilla::ErrorResult& aRv);
187 :
188 : void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
189 : JS::Handle<JS::Value> aData, uint32_t aIndex,
190 : nsIPrincipal& aSubjectPrincipal,
191 : mozilla::ErrorResult& aRv);
192 :
193 : void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
194 : uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
195 : nsIPrincipal& aSubjectPrincipal,
196 : mozilla::ErrorResult& aRv);
197 :
198 0 : bool MozUserCancelled() const
199 : {
200 0 : return mUserCancelled;
201 : }
202 :
203 : already_AddRefed<nsINode> GetMozSourceNode();
204 :
205 0 : mozilla::dom::Element* GetDragTarget() const
206 : {
207 0 : return mDragTarget;
208 : }
209 :
210 : nsresult GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex,
211 : nsIVariant** aData);
212 :
213 0 : DataTransferItemList* Items() const {
214 0 : return mItems;
215 : }
216 :
217 : // a readonly dataTransfer cannot have new data added or existing data
218 : // removed. Only the dropEffect and effectAllowed may be modified.
219 0 : bool IsReadOnly() const {
220 0 : return mReadOnly;
221 : }
222 0 : void SetReadOnly() {
223 0 : mReadOnly = true;
224 0 : }
225 :
226 0 : int32_t ClipboardType() const {
227 0 : return mClipboardType;
228 : }
229 0 : EventMessage GetEventMessage() const {
230 0 : return mEventMessage;
231 : }
232 0 : bool IsCrossDomainSubFrameDrop() const {
233 0 : return mIsCrossDomainSubFrameDrop;
234 : }
235 :
236 : // converts the data into an array of nsITransferable objects to be used for
237 : // drag and drop or clipboard operations.
238 : already_AddRefed<nsIArray> GetTransferables(nsIDOMNode* aDragTarget);
239 :
240 : already_AddRefed<nsIArray>
241 : GetTransferables(nsILoadContext* aLoadContext);
242 :
243 : // converts the data for a single item at aIndex into an nsITransferable
244 : // object.
245 : already_AddRefed<nsITransferable>
246 : GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext);
247 :
248 : // converts the data in the variant to an nsISupportString if possible or
249 : // an nsISupports or null otherwise.
250 : bool ConvertFromVariant(nsIVariant* aVariant,
251 : nsISupports** aSupports,
252 : uint32_t* aLength) const;
253 :
254 : // clears all of the data
255 : void ClearAll();
256 :
257 : // Similar to SetData except also specifies the principal to store.
258 : // aData may be null when called from CacheExternalDragFormats or
259 : // CacheExternalClipboardFormats.
260 : nsresult SetDataWithPrincipal(const nsAString& aFormat,
261 : nsIVariant* aData,
262 : uint32_t aIndex,
263 : nsIPrincipal* aPrincipal);
264 :
265 : // Variation of SetDataWithPrincipal with handles extracting
266 : // kCustomTypesMime data into separate types.
267 : void SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat,
268 : nsIVariant* aData,
269 : uint32_t aIndex,
270 : nsIPrincipal* aPrincipal,
271 : bool aHidden);
272 :
273 : // returns a weak reference to the drag image
274 0 : Element* GetDragImage(int32_t* aX, int32_t* aY) const
275 : {
276 0 : *aX = mDragImageX;
277 0 : *aY = mDragImageY;
278 0 : return mDragImage;
279 : }
280 :
281 : nsresult Clone(nsISupports* aParent, EventMessage aEventMessage,
282 : bool aUserCancelled, bool aIsCrossDomainSubFrameDrop,
283 : DataTransfer** aResult);
284 :
285 : // converts some formats used for compatibility in aInFormat into aOutFormat.
286 : // Text and text/unicode become text/plain, and URL becomes text/uri-list
287 : void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) const;
288 :
289 : static bool PrincipalMaySetData(const nsAString& aFormat,
290 : nsIVariant* aData,
291 : nsIPrincipal* aPrincipal);
292 :
293 : // Notify the DataTransfer that the list returned from GetTypes may have
294 : // changed. This can happen due to items we care about for purposes of
295 : // GetTypes being added or removed or changing item kinds.
296 : void TypesListMayHaveChanged();
297 :
298 : protected:
299 :
300 : // caches text and uri-list data formats that exist in the drag service or
301 : // clipboard for retrieval later.
302 : nsresult CacheExternalData(const char* aFormat, uint32_t aIndex,
303 : nsIPrincipal* aPrincipal, bool aHidden);
304 :
305 : // caches the formats that exist in the drag service that were added by an
306 : // external drag
307 : void CacheExternalDragFormats();
308 :
309 : // caches the formats that exist in the clipboard
310 : void CacheExternalClipboardFormats(bool aPlainTextOnly);
311 :
312 : FileList* GetFilesInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal);
313 : nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
314 : nsIPrincipal* aSubjectPrincipal,
315 : nsIVariant** aData);
316 :
317 : nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
318 : uint32_t aIndex, nsIPrincipal* aSubjectPrincipal);
319 :
320 : friend class ContentParent;
321 :
322 : void FillAllExternalData();
323 :
324 : void FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal);
325 :
326 : void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
327 : nsIPrincipal* aPrincipal);
328 :
329 : void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
330 : nsIPrincipal& aSubjectPrincipal,
331 : mozilla::ErrorResult& aRv);
332 :
333 : nsCOMPtr<nsISupports> mParent;
334 :
335 : // the drop effect and effect allowed
336 : uint32_t mDropEffect;
337 : uint32_t mEffectAllowed;
338 :
339 : // the event message this data transfer is for. This will correspond to an
340 : // event->mMessage value.
341 : EventMessage mEventMessage;
342 :
343 : // Indicates the behavior of the cursor during drag operations
344 : bool mCursorState;
345 :
346 : // readonly data transfers may not be modified except the drop effect and
347 : // effect allowed.
348 : bool mReadOnly;
349 :
350 : // true for drags started without a data transfer, for example, those from
351 : // another application.
352 : bool mIsExternal;
353 :
354 : // true if the user cancelled the drag. Used only for the dragend event.
355 : bool mUserCancelled;
356 :
357 : // true if this is a cross-domain drop from a subframe where access to the
358 : // data should be prevented
359 : bool mIsCrossDomainSubFrameDrop;
360 :
361 : // Indicates which clipboard type to use for clipboard operations. Ignored for
362 : // drag and drop.
363 : int32_t mClipboardType;
364 :
365 : // The items contained with the DataTransfer
366 : RefPtr<DataTransferItemList> mItems;
367 :
368 : // the target of the drag. The drag and dragend events will fire at this.
369 : nsCOMPtr<mozilla::dom::Element> mDragTarget;
370 :
371 : // the custom drag image and coordinates within the image. If mDragImage is
372 : // null, the default image is created from the drag target.
373 : nsCOMPtr<mozilla::dom::Element> mDragImage;
374 : uint32_t mDragImageX;
375 : uint32_t mDragImageY;
376 : };
377 :
378 : NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
379 :
380 : } // namespace dom
381 : } // namespace mozilla
382 :
383 : #endif /* mozilla_dom_DataTransfer_h */
|