summaryrefslogtreecommitdiffstats
path: root/dom/events/DataTransfer.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/events/DataTransfer.h')
-rw-r--r--dom/events/DataTransfer.h382
1 files changed, 382 insertions, 0 deletions
diff --git a/dom/events/DataTransfer.h b/dom/events/DataTransfer.h
new file mode 100644
index 000000000..7c6b0b8c1
--- /dev/null
+++ b/dom/events/DataTransfer.h
@@ -0,0 +1,382 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_DataTransfer_h
+#define mozilla_dom_DataTransfer_h
+
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsIVariant.h"
+#include "nsIPrincipal.h"
+#include "nsIDOMDataTransfer.h"
+#include "nsIDOMElement.h"
+#include "nsIDragService.h"
+#include "nsCycleCollectionParticipant.h"
+
+#include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/dom/File.h"
+
+class nsINode;
+class nsITransferable;
+class nsILoadContext;
+
+namespace mozilla {
+
+class EventStateManager;
+
+namespace dom {
+
+class DataTransferItem;
+class DataTransferItemList;
+class DOMStringList;
+class Element;
+class FileList;
+class Promise;
+template<typename T> class Optional;
+
+#define NS_DATATRANSFER_IID \
+{ 0x6c5f90d1, 0xa886, 0x42c8, \
+ { 0x85, 0x06, 0x10, 0xbe, 0x5c, 0x0d, 0xc6, 0x77 } }
+
+class DataTransfer final : public nsIDOMDataTransfer,
+ public nsWrapperCache
+{
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID)
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_NSIDOMDATATRANSFER
+
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer)
+
+ friend class mozilla::EventStateManager;
+
+ static DataTransfer* Cast(nsIDOMDataTransfer* aArg)
+ {
+ return static_cast<DataTransfer*>(aArg);
+ }
+
+protected:
+
+ // hide the default constructor
+ DataTransfer();
+
+ // this constructor is used only by the Clone method to copy the fields as
+ // needed to a new data transfer.
+ DataTransfer(nsISupports* aParent,
+ EventMessage aEventMessage,
+ const uint32_t aEffectAllowed,
+ bool aCursorState,
+ bool aIsExternal,
+ bool aUserCancelled,
+ bool aIsCrossDomainSubFrameDrop,
+ int32_t aClipboardType,
+ DataTransferItemList* aItems,
+ Element* aDragImage,
+ uint32_t aDragImageX,
+ uint32_t aDragImageY);
+
+ ~DataTransfer();
+
+ static const char sEffects[8][9];
+
+public:
+ // Constructor for DataTransfer.
+ //
+ // aIsExternal must only be true when used to create a dataTransfer for a
+ // paste or a drag that was started without using a data transfer. The
+ // latter will occur when an external drag occurs, that is, a drag where the
+ // source is another application, or a drag is started by calling the drag
+ // service directly. For clipboard operations, aClipboardType indicates
+ // which clipboard to use, from nsIClipboard, or -1 for non-clipboard
+ // operations, or if access to the system clipboard should not be allowed.
+ DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
+ bool aIsExternal, int32_t aClipboardType);
+
+ virtual JSObject*
+ WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+ nsISupports* GetParentObject() const
+ {
+ return mParent;
+ }
+
+ void SetParentObject(nsISupports* aNewParent)
+ {
+ MOZ_ASSERT(aNewParent);
+ // Setting the parent after we've been wrapped is pointless, so
+ // make sure we aren't wrapped yet.
+ MOZ_ASSERT(!GetWrapperPreserveColor());
+ mParent = aNewParent;
+ }
+
+ static already_AddRefed<DataTransfer>
+ Constructor(const GlobalObject& aGlobal, const nsAString& aEventType,
+ bool aIsExternal, ErrorResult& aRv);
+
+ void GetDropEffect(nsString& aDropEffect)
+ {
+ aDropEffect.AssignASCII(sEffects[mDropEffect]);
+ }
+
+ void GetEffectAllowed(nsString& aEffectAllowed)
+ {
+ if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) {
+ aEffectAllowed.AssignLiteral("uninitialized");
+ } else {
+ aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
+ }
+ }
+
+ void SetDragImage(Element& aElement, int32_t aX, int32_t aY,
+ ErrorResult& aRv);
+
+ void GetTypes(nsTArray<nsString>& aTypes,
+ nsIPrincipal& aSubjectPrincipal) const;
+
+ void GetData(const nsAString& aFormat, nsAString& aData,
+ nsIPrincipal& aSubjectPrincipal,
+ ErrorResult& aRv);
+
+ void SetData(const nsAString& aFormat, const nsAString& aData,
+ nsIPrincipal& aSubjectPrincipal,
+ ErrorResult& aRv);
+
+ void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
+ nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ already_AddRefed<FileList>
+ GetFiles(nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ already_AddRefed<Promise>
+ GetFilesAndDirectories(nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ already_AddRefed<Promise>
+ GetFiles(bool aRecursiveFlag,
+ nsIPrincipal& aSubjectPrincipal,
+ ErrorResult& aRv);
+
+
+ void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
+
+ uint32_t MozItemCount() const;
+
+ void GetMozCursor(nsString& aCursor)
+ {
+ if (mCursorState) {
+ aCursor.AssignLiteral("default");
+ } else {
+ aCursor.AssignLiteral("auto");
+ }
+ }
+
+ already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex,
+ mozilla::ErrorResult& aRv) const;
+
+ void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
+ nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
+ JS::Handle<JS::Value> aData, uint32_t aIndex,
+ nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
+ uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
+ nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ bool MozUserCancelled() const
+ {
+ return mUserCancelled;
+ }
+
+ already_AddRefed<nsINode> GetMozSourceNode();
+
+ mozilla::dom::Element* GetDragTarget() const
+ {
+ return mDragTarget;
+ }
+
+ nsresult GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex,
+ nsIVariant** aData);
+
+ DataTransferItemList* Items() const {
+ return mItems;
+ }
+
+ // a readonly dataTransfer cannot have new data added or existing data
+ // removed. Only the dropEffect and effectAllowed may be modified.
+ bool IsReadOnly() const {
+ return mReadOnly;
+ }
+ void SetReadOnly() {
+ mReadOnly = true;
+ }
+
+ int32_t ClipboardType() const {
+ return mClipboardType;
+ }
+ EventMessage GetEventMessage() const {
+ return mEventMessage;
+ }
+ bool IsCrossDomainSubFrameDrop() const {
+ return mIsCrossDomainSubFrameDrop;
+ }
+
+ // converts the data into an array of nsITransferable objects to be used for
+ // drag and drop or clipboard operations.
+ already_AddRefed<nsIArray> GetTransferables(nsIDOMNode* aDragTarget);
+
+ already_AddRefed<nsIArray>
+ GetTransferables(nsILoadContext* aLoadContext);
+
+ // converts the data for a single item at aIndex into an nsITransferable
+ // object.
+ already_AddRefed<nsITransferable>
+ GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext);
+
+ // converts the data in the variant to an nsISupportString if possible or
+ // an nsISupports or null otherwise.
+ bool ConvertFromVariant(nsIVariant* aVariant,
+ nsISupports** aSupports,
+ uint32_t* aLength) const;
+
+ // clears all of the data
+ void ClearAll();
+
+ // Similar to SetData except also specifies the principal to store.
+ // aData may be null when called from CacheExternalDragFormats or
+ // CacheExternalClipboardFormats.
+ nsresult SetDataWithPrincipal(const nsAString& aFormat,
+ nsIVariant* aData,
+ uint32_t aIndex,
+ nsIPrincipal* aPrincipal);
+
+ // Variation of SetDataWithPrincipal with handles extracting
+ // kCustomTypesMime data into separate types.
+ void SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat,
+ nsIVariant* aData,
+ uint32_t aIndex,
+ nsIPrincipal* aPrincipal,
+ bool aHidden);
+
+ // returns a weak reference to the drag image
+ Element* GetDragImage(int32_t* aX, int32_t* aY) const
+ {
+ *aX = mDragImageX;
+ *aY = mDragImageY;
+ return mDragImage;
+ }
+
+ nsresult Clone(nsISupports* aParent, EventMessage aEventMessage,
+ bool aUserCancelled, bool aIsCrossDomainSubFrameDrop,
+ DataTransfer** aResult);
+
+ // converts some formats used for compatibility in aInFormat into aOutFormat.
+ // Text and text/unicode become text/plain, and URL becomes text/uri-list
+ void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) const;
+
+ static bool PrincipalMaySetData(const nsAString& aFormat,
+ nsIVariant* aData,
+ nsIPrincipal* aPrincipal);
+
+ // Notify the DataTransfer that the list returned from GetTypes may have
+ // changed. This can happen due to items we care about for purposes of
+ // GetTypes being added or removed or changing item kinds.
+ void TypesListMayHaveChanged();
+
+protected:
+
+ // caches text and uri-list data formats that exist in the drag service or
+ // clipboard for retrieval later.
+ nsresult CacheExternalData(const char* aFormat, uint32_t aIndex,
+ nsIPrincipal* aPrincipal, bool aHidden);
+
+ // caches the formats that exist in the drag service that were added by an
+ // external drag
+ void CacheExternalDragFormats();
+
+ // caches the formats that exist in the clipboard
+ void CacheExternalClipboardFormats();
+
+ FileList* GetFilesInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal);
+ nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
+ nsIPrincipal* aSubjectPrincipal,
+ nsIVariant** aData);
+
+ nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
+ uint32_t aIndex, nsIPrincipal* aSubjectPrincipal);
+
+ friend class ContentParent;
+
+ void FillAllExternalData();
+
+ void FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal);
+
+ void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
+ nsIPrincipal* aPrincipal);
+
+ void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
+ nsIPrincipal& aSubjectPrincipal,
+ mozilla::ErrorResult& aRv);
+
+ nsCOMPtr<nsISupports> mParent;
+
+ // the drop effect and effect allowed
+ uint32_t mDropEffect;
+ uint32_t mEffectAllowed;
+
+ // the event message this data transfer is for. This will correspond to an
+ // event->mMessage value.
+ EventMessage mEventMessage;
+
+ // Indicates the behavior of the cursor during drag operations
+ bool mCursorState;
+
+ // readonly data transfers may not be modified except the drop effect and
+ // effect allowed.
+ bool mReadOnly;
+
+ // true for drags started without a data transfer, for example, those from
+ // another application.
+ bool mIsExternal;
+
+ // true if the user cancelled the drag. Used only for the dragend event.
+ bool mUserCancelled;
+
+ // true if this is a cross-domain drop from a subframe where access to the
+ // data should be prevented
+ bool mIsCrossDomainSubFrameDrop;
+
+ // Indicates which clipboard type to use for clipboard operations. Ignored for
+ // drag and drop.
+ int32_t mClipboardType;
+
+ // The items contained with the DataTransfer
+ RefPtr<DataTransferItemList> mItems;
+
+ // the target of the drag. The drag and dragend events will fire at this.
+ nsCOMPtr<mozilla::dom::Element> mDragTarget;
+
+ // the custom drag image and coordinates within the image. If mDragImage is
+ // null, the default image is created from the drag target.
+ nsCOMPtr<mozilla::dom::Element> mDragImage;
+ uint32_t mDragImageX;
+ uint32_t mDragImageY;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_DataTransfer_h */