diff options
Diffstat (limited to 'dom/events/DataTransfer.h')
-rw-r--r-- | dom/events/DataTransfer.h | 382 |
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 */ |