Bug 1708422: part 14) Extend documentation of `mozInlineSpellChecker::SpellCheckerTim...
[gecko.git] / dom / events / DataTransfer.h
bloba091f2069fd64e040a997fef8044ccc2ec250d54
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/. */
7 #ifndef mozilla_dom_DataTransfer_h
8 #define mozilla_dom_DataTransfer_h
10 #include "nsString.h"
11 #include "nsTArray.h"
12 #include "nsIVariant.h"
13 #include "nsIPrincipal.h"
14 #include "nsIDragService.h"
15 #include "nsITransferable.h"
16 #include "nsCycleCollectionParticipant.h"
18 #include "mozilla/ArrayUtils.h"
19 #include "mozilla/Assertions.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/EventForwards.h"
22 #include "mozilla/dom/BindingDeclarations.h"
23 #include "mozilla/dom/DataTransferItemList.h"
24 #include "mozilla/dom/File.h"
26 class nsINode;
27 class nsITransferable;
28 class nsILoadContext;
30 namespace mozilla {
32 class EventStateManager;
34 namespace dom {
36 class DataTransferItem;
37 class DataTransferItemList;
38 class DOMStringList;
39 class Element;
40 class FileList;
41 class Promise;
42 template <typename T>
43 class Optional;
45 #define NS_DATATRANSFER_IID \
46 { \
47 0x6c5f90d1, 0xa886, 0x42c8, { \
48 0x85, 0x06, 0x10, 0xbe, 0x5c, 0x0d, 0xc6, 0x77 \
49 } \
52 /**
53 * See <https://html.spec.whatwg.org/multipage/dnd.html#datatransfer>.
55 class DataTransfer final : public nsISupports, public nsWrapperCache {
56 public:
57 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID)
59 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
61 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer)
63 friend class mozilla::EventStateManager;
65 /// An enum which represents which "Drag Data Store Mode" the DataTransfer is
66 /// in according to the spec.
67 enum class Mode : uint8_t {
68 ReadWrite,
69 ReadOnly,
70 Protected,
73 protected:
74 // hide the default constructor
75 DataTransfer();
77 // this constructor is used only by the Clone method to copy the fields as
78 // needed to a new data transfer.
79 // NOTE: Do not call this method directly.
80 DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
81 const uint32_t aEffectAllowed, bool aCursorState,
82 bool aIsExternal, bool aUserCancelled,
83 bool aIsCrossDomainSubFrameDrop, int32_t aClipboardType,
84 DataTransferItemList* aItems, Element* aDragImage,
85 uint32_t aDragImageX, uint32_t aDragImageY);
87 ~DataTransfer();
89 static const char sEffects[8][9];
91 public:
92 // Constructor for DataTransfer.
94 // aIsExternal must only be true when used to create a dataTransfer for a
95 // paste, a drag or an input that was started without using a data transfer.
96 // The case of a drag will occur when an external drag occurs, that is, a
97 // drag where the source is another application, or a drag is started by
98 // calling the drag service directly. For clipboard operations,
99 // aClipboardType indicates which clipboard to use, from nsIClipboard, or -1
100 // for non-clipboard operations, or if access to the system clipboard should
101 // not be allowed.
102 DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
103 bool aIsExternal, int32_t aClipboardType);
104 DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
105 nsITransferable* aTransferable);
106 DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
107 const nsAString& aString);
109 virtual JSObject* WrapObject(JSContext* aCx,
110 JS::Handle<JSObject*> aGivenProto) override;
112 nsISupports* GetParentObject() const { return mParent; }
114 void SetParentObject(nsISupports* aNewParent) {
115 MOZ_ASSERT(aNewParent);
116 // Setting the parent after we've been wrapped is pointless, so
117 // make sure we aren't wrapped yet.
118 MOZ_ASSERT(!GetWrapperPreserveColor());
119 mParent = aNewParent;
122 static already_AddRefed<DataTransfer> Constructor(
123 const GlobalObject& aGlobal);
126 * The actual effect that will be used, and should always be one of the
127 * possible values of effectAllowed.
129 * For dragstart, drag and dragleave events, the dropEffect is initialized
130 * to none. Any value assigned to the dropEffect will be set, but the value
131 * isn't used for anything.
133 * For the dragenter and dragover events, the dropEffect will be initialized
134 * based on what action the user is requesting. How this is determined is
135 * platform specific, but typically the user can press modifier keys to
136 * adjust which action is desired. Within an event handler for the dragenter
137 * and dragover events, the dropEffect should be modified if the action the
138 * user is requesting is not the one that is desired.
140 * For the drop and dragend events, the dropEffect will be initialized to
141 * the action that was desired, which will be the value that the dropEffect
142 * had after the last dragenter or dragover event.
144 * Possible values:
145 * copy - a copy of the source item is made at the new location
146 * move - an item is moved to a new location
147 * link - a link is established to the source at the new location
148 * none - the item may not be dropped
150 * Assigning any other value has no effect and retains the old value.
152 void GetDropEffect(nsAString& aDropEffect) {
153 aDropEffect.AssignASCII(sEffects[mDropEffect]);
155 void SetDropEffect(const nsAString& aDropEffect);
158 * Specifies the effects that are allowed for this drag. You may set this in
159 * the dragstart event to set the desired effects for the source, and within
160 * the dragenter and dragover events to set the desired effects for the
161 * target. The value is not used for other events.
163 * Possible values:
164 * copy - a copy of the source item is made at the new location
165 * move - an item is moved to a new location
166 * link - a link is established to the source at the new location
167 * copyLink, copyMove, linkMove, all - combinations of the above
168 * none - the item may not be dropped
169 * uninitialized - the default value when the effect has not been set,
170 * equivalent to all.
172 * Assigning any other value has no effect and retains the old value.
174 void GetEffectAllowed(nsAString& aEffectAllowed) {
175 if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) {
176 aEffectAllowed.AssignLiteral("uninitialized");
177 } else {
178 aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
181 void SetEffectAllowed(const nsAString& aEffectAllowed);
184 * Set the image to be used for dragging if a custom one is desired. Most of
185 * the time, this would not be set, as a default image is created from the
186 * node that was dragged.
188 * If the node is an HTML img element, an HTML canvas element or a XUL image
189 * element, the image data is used. Otherwise, image should be a visible
190 * node and the drag image will be created from this. If image is null, any
191 * custom drag image is cleared and the default is used instead.
193 * The coordinates specify the offset into the image where the mouse cursor
194 * should be. To center the image for instance, use values that are half the
195 * width and height.
197 * @param image a node to use
198 * @param x the horizontal offset
199 * @param y the vertical offset
201 void SetDragImage(Element& aElement, int32_t aX, int32_t aY);
202 void UpdateDragImage(Element& aElement, int32_t aX, int32_t aY);
204 void GetTypes(nsTArray<nsString>& aTypes, CallerType aCallerType) const;
205 bool HasType(const nsAString& aType) const;
206 bool HasFile() const;
208 void GetData(const nsAString& aFormat, nsAString& aData,
209 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) const;
211 void SetData(const nsAString& aFormat, const nsAString& aData,
212 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
214 void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
215 nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aRv);
218 * Holds a list of all the local files available on this data transfer.
219 * A dataTransfer containing no files will return an empty list, and an
220 * invalid index access on the resulting file list will return null.
222 already_AddRefed<FileList> GetFiles(nsIPrincipal& aSubjectPrincipal);
224 already_AddRefed<Promise> GetFilesAndDirectories(
225 nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aRv);
227 already_AddRefed<Promise> GetFiles(bool aRecursiveFlag,
228 nsIPrincipal& aSubjectPrincipal,
229 ErrorResult& aRv);
231 void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
233 uint32_t MozItemCount() const;
235 void GetMozCursor(nsAString& aCursor) {
236 if (mCursorState) {
237 aCursor.AssignLiteral("default");
238 } else {
239 aCursor.AssignLiteral("auto");
242 void SetMozCursor(const nsAString& aCursor);
244 already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex,
245 CallerType aCallerType,
246 mozilla::ErrorResult& aRv) const;
248 void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
249 nsIPrincipal& aSubjectPrincipal,
250 mozilla::ErrorResult& aRv);
252 void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
253 JS::Handle<JS::Value> aData, uint32_t aIndex,
254 nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aRv);
256 void MozGetDataAt(JSContext* aCx, const nsAString& aFormat, uint32_t aIndex,
257 JS::MutableHandle<JS::Value> aRetval,
258 nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aRv);
260 bool MozUserCancelled() const { return mUserCancelled; }
262 already_AddRefed<nsINode> GetMozSourceNode();
265 * Integer version of dropEffect, set to one of the constants in
266 * nsIDragService.
268 uint32_t DropEffectInt() const { return mDropEffect; }
269 void SetDropEffectInt(uint32_t aDropEffectInt) {
270 MOZ_RELEASE_ASSERT(aDropEffectInt < ArrayLength(sEffects),
271 "Bogus drop effect value");
272 mDropEffect = aDropEffectInt;
276 * Integer version of effectAllowed, set to one or a combination of the
277 * constants in nsIDragService.
279 uint32_t EffectAllowedInt() const { return mEffectAllowed; }
281 void GetMozTriggeringPrincipalURISpec(nsAString& aPrincipalURISpec);
283 nsIContentSecurityPolicy* GetMozCSP();
285 mozilla::dom::Element* GetDragTarget() const { return mDragTarget; }
287 nsresult GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex,
288 nsIVariant** aData) const;
290 DataTransferItemList* Items() const { return mItems; }
292 // Returns the current "Drag Data Store Mode" of the DataTransfer. This
293 // determines what modifications may be performed on the DataTransfer, and
294 // what data may be read from it.
295 Mode GetMode() const { return mMode; }
296 void SetMode(Mode aMode);
298 // Helper method. Is true if the DataTransfer's mode is ReadOnly or Protected,
299 // which means that the DataTransfer cannot be modified.
300 bool IsReadOnly() const { return mMode != Mode::ReadWrite; }
301 // Helper method. Is true if the DataTransfer's mode is Protected, which means
302 // that DataTransfer type information may be read, but data may not be.
303 bool IsProtected() const { return mMode == Mode::Protected; }
305 nsITransferable* GetTransferable() const { return mTransferable; }
306 int32_t ClipboardType() const { return mClipboardType; }
307 EventMessage GetEventMessage() const { return mEventMessage; }
308 bool IsCrossDomainSubFrameDrop() const { return mIsCrossDomainSubFrameDrop; }
310 // converts the data into an array of nsITransferable objects to be used for
311 // drag and drop or clipboard operations.
312 already_AddRefed<nsIArray> GetTransferables(nsINode* aDragTarget);
314 already_AddRefed<nsIArray> GetTransferables(nsILoadContext* aLoadContext);
316 // converts the data for a single item at aIndex into an nsITransferable
317 // object.
318 already_AddRefed<nsITransferable> GetTransferable(
319 uint32_t aIndex, nsILoadContext* aLoadContext);
321 // converts the data in the variant to an nsISupportString if possible or
322 // an nsISupports or null otherwise.
323 bool ConvertFromVariant(nsIVariant* aVariant, nsISupports** aSupports,
324 uint32_t* aLength) const;
326 // Disconnects the DataTransfer from the Drag Data Store. If the
327 // dom.dataTransfer.disconnect pref is enabled, this will clear the
328 // DataTransfer and set it to the `Protected` state, otherwise this method is
329 // a no-op.
330 void Disconnect();
332 // clears all of the data
333 void ClearAll();
335 // Similar to SetData except also specifies the principal to store.
336 // aData may be null when called from CacheExternalDragFormats or
337 // CacheExternalClipboardFormats.
338 nsresult SetDataWithPrincipal(const nsAString& aFormat, nsIVariant* aData,
339 uint32_t aIndex, nsIPrincipal* aPrincipal,
340 bool aHidden = false);
342 // Variation of SetDataWithPrincipal with handles extracting
343 // kCustomTypesMime data into separate types.
344 void SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat,
345 nsIVariant* aData, uint32_t aIndex,
346 nsIPrincipal* aPrincipal,
347 bool aHidden);
349 // returns a weak reference to the drag image
350 Element* GetDragImage(int32_t* aX, int32_t* aY) const {
351 *aX = mDragImageX;
352 *aY = mDragImageY;
353 return mDragImage;
356 // This method makes a copy of the DataTransfer object, with a few properties
357 // changed, and the mode updated to reflect the correct mode for the given
358 // event. This method is used during the drag operation to generate the
359 // DataTransfer objects for each event after `dragstart`. Event objects will
360 // lazily clone the DataTransfer stored in the DragSession (which is a clone
361 // of the DataTransfer used in the `dragstart` event) when requested.
362 nsresult Clone(nsISupports* aParent, EventMessage aEventMessage,
363 bool aUserCancelled, bool aIsCrossDomainSubFrameDrop,
364 DataTransfer** aResult);
366 // converts some formats used for compatibility in aInFormat into aOutFormat.
367 // Text and text/unicode become text/plain, and URL becomes text/uri-list
368 void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) const;
370 static bool PrincipalMaySetData(const nsAString& aFormat, nsIVariant* aData,
371 nsIPrincipal* aPrincipal);
373 // Notify the DataTransfer that the list returned from GetTypes may have
374 // changed. This can happen due to items we care about for purposes of
375 // GetTypes being added or removed or changing item kinds.
376 void TypesListMayHaveChanged();
378 // Testing method used to emulate internal DataTransfer management.
379 // NOTE: Please don't use this. See the comments in the webidl for more.
380 already_AddRefed<DataTransfer> MozCloneForEvent(const nsAString& aEvent,
381 ErrorResult& aRv);
383 // Retrieve a list of clipboard formats supported
385 // If kFileMime is supported, then it will be placed either at
386 // index 0 or at index 1 in aResult
387 static void GetExternalClipboardFormats(const int32_t& aWhichClipboard,
388 const bool& aPlainTextOnly,
389 nsTArray<nsCString>* aResult);
391 // Retrieve a list of supporting formats in aTransferable.
393 // If kFileMime is supported, then it will be placed either at
394 // index 0 or at index 1 in aResult
395 static void GetExternalTransferableFormats(nsITransferable* aTransferable,
396 bool aPlainTextOnly,
397 nsTArray<nsCString>* aResult);
399 protected:
400 // caches text and uri-list data formats that exist in the drag service or
401 // clipboard for retrieval later.
402 nsresult CacheExternalData(const char* aFormat, uint32_t aIndex,
403 nsIPrincipal* aPrincipal, bool aHidden);
405 // caches the formats that exist in the drag service that were added by an
406 // external drag
407 void CacheExternalDragFormats();
409 // caches the formats that exist in the clipboard
410 void CacheExternalClipboardFormats(bool aPlainTextOnly);
412 // caches the formats that exist in mTransferable
413 void CacheTransferableFormats();
415 // caches the formats specified by aTypes.
416 void CacheExternalData(const nsTArray<nsCString>& aTypes,
417 nsIPrincipal* aPrincipal);
419 FileList* GetFilesInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal);
420 nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
421 nsIPrincipal* aSubjectPrincipal,
422 nsIVariant** aData) const;
424 nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
425 uint32_t aIndex, nsIPrincipal* aSubjectPrincipal);
427 friend class ContentParent;
428 friend class Clipboard;
430 void FillAllExternalData();
432 void FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal);
434 void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
435 nsIPrincipal* aPrincipal);
437 void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
438 nsIPrincipal& aSubjectPrincipal,
439 mozilla::ErrorResult& aRv);
441 nsCOMPtr<nsISupports> mParent;
443 // If DataTransfer is initialized with an instance of nsITransferable, it's
444 // grabbed with this member **until** the constructor fills all data of all
445 // items.
446 nsCOMPtr<nsITransferable> mTransferable;
448 // the drop effect and effect allowed
449 uint32_t mDropEffect;
450 uint32_t mEffectAllowed;
452 // the event message this data transfer is for. This will correspond to an
453 // event->mMessage value.
454 EventMessage mEventMessage;
456 // Indicates the behavior of the cursor during drag operations
457 bool mCursorState;
459 // The current "Drag Data Store Mode" which the DataTransfer is in.
460 Mode mMode;
462 // true for drags started without a data transfer, for example, those from
463 // another application.
464 bool mIsExternal;
466 // true if the user cancelled the drag. Used only for the dragend event.
467 bool mUserCancelled;
469 // true if this is a cross-domain drop from a subframe where access to the
470 // data should be prevented
471 bool mIsCrossDomainSubFrameDrop;
473 // Indicates which clipboard type to use for clipboard operations. Ignored for
474 // drag and drop.
475 int32_t mClipboardType;
477 // The items contained with the DataTransfer
478 RefPtr<DataTransferItemList> mItems;
480 // the target of the drag. The drag and dragend events will fire at this.
481 nsCOMPtr<mozilla::dom::Element> mDragTarget;
483 // the custom drag image and coordinates within the image. If mDragImage is
484 // null, the default image is created from the drag target.
485 nsCOMPtr<mozilla::dom::Element> mDragImage;
486 uint32_t mDragImageX;
487 uint32_t mDragImageY;
490 NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
492 } // namespace dom
493 } // namespace mozilla
495 #endif /* mozilla_dom_DataTransfer_h */