michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_DataTransfer_h michael@0: #define mozilla_dom_DataTransfer_h michael@0: michael@0: #include "nsString.h" michael@0: #include "nsTArray.h" michael@0: #include "nsIVariant.h" michael@0: #include "nsIPrincipal.h" michael@0: #include "nsIDOMDataTransfer.h" michael@0: #include "nsIDOMElement.h" michael@0: #include "nsIDragService.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsDOMFile.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: class nsINode; michael@0: class nsITransferable; michael@0: class nsISupportsArray; michael@0: class nsILoadContext; michael@0: michael@0: namespace mozilla { michael@0: michael@0: class EventStateManager; michael@0: michael@0: namespace dom { michael@0: michael@0: class DOMStringList; michael@0: class Element; michael@0: template class Optional; michael@0: michael@0: /** michael@0: * TransferItem is used to hold data for a particular format. Each piece of michael@0: * data has a principal set from the caller which added it. This allows a michael@0: * caller that wishes to retrieve the data to only be able to access the data michael@0: * it is allowed to, yet still allow a chrome caller to retrieve any of the michael@0: * data. michael@0: */ michael@0: struct TransferItem { michael@0: nsString mFormat; michael@0: nsCOMPtr mPrincipal; michael@0: nsCOMPtr mData; michael@0: }; michael@0: michael@0: #define NS_DATATRANSFER_IID \ michael@0: { 0x43ee0327, 0xde5d, 0x463d, \ michael@0: { 0x9b, 0xd0, 0xf1, 0x79, 0x09, 0x69, 0xf2, 0xfb } } michael@0: michael@0: class DataTransfer MOZ_FINAL : public nsIDOMDataTransfer, michael@0: public nsWrapperCache michael@0: { michael@0: public: michael@0: NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID) michael@0: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_NSIDOMDATATRANSFER michael@0: michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer) michael@0: michael@0: friend class mozilla::EventStateManager; michael@0: michael@0: protected: michael@0: michael@0: // hide the default constructor michael@0: DataTransfer(); michael@0: michael@0: // this constructor is used only by the Clone method to copy the fields as michael@0: // needed to a new data transfer. michael@0: DataTransfer(nsISupports* aParent, michael@0: uint32_t aEventType, michael@0: const uint32_t aEffectAllowed, michael@0: bool aCursorState, michael@0: bool aIsExternal, michael@0: bool aUserCancelled, michael@0: bool aIsCrossDomainSubFrameDrop, michael@0: int32_t aClipboardType, michael@0: nsTArray >& aItems, michael@0: Element* aDragImage, michael@0: uint32_t aDragImageX, michael@0: uint32_t aDragImageY); michael@0: michael@0: ~DataTransfer(); michael@0: michael@0: static const char sEffects[8][9]; michael@0: michael@0: public: michael@0: michael@0: // Constructor for DataTransfer. michael@0: // michael@0: // aEventType is an event constant (such as NS_DRAGDROP_START) michael@0: // michael@0: // aIsExternal must only be true when used to create a dataTransfer for a michael@0: // paste or a drag that was started without using a data transfer. The michael@0: // latter will occur when an external drag occurs, that is, a drag where the michael@0: // source is another application, or a drag is started by calling the drag michael@0: // service directly. For clipboard operations, aClipboardType indicates michael@0: // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations, michael@0: // or if access to the system clipboard should not be allowed. michael@0: DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal, michael@0: int32_t aClipboardType); michael@0: michael@0: virtual JSObject* WrapObject(JSContext* aCx); michael@0: nsISupports* GetParentObject() michael@0: { michael@0: return mParent; michael@0: } michael@0: michael@0: void SetParentObject(nsISupports* aNewParent) michael@0: { michael@0: MOZ_ASSERT(aNewParent); michael@0: // Setting the parent after we've been wrapped is pointless, so michael@0: // make sure we aren't wrapped yet. michael@0: MOZ_ASSERT(!GetWrapperPreserveColor()); michael@0: mParent = aNewParent; michael@0: } michael@0: michael@0: static already_AddRefed michael@0: Constructor(const GlobalObject& aGlobal, const nsAString& aEventType, michael@0: bool aIsExternal, ErrorResult& aRv); michael@0: michael@0: void GetDropEffect(nsString& aDropEffect) michael@0: { michael@0: aDropEffect.AssignASCII(sEffects[mDropEffect]); michael@0: } michael@0: void GetEffectAllowed(nsString& aEffectAllowed) michael@0: { michael@0: if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) { michael@0: aEffectAllowed.AssignLiteral("uninitialized"); michael@0: } else { michael@0: aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]); michael@0: } michael@0: } michael@0: void SetDragImage(Element& aElement, int32_t aX, int32_t aY, michael@0: ErrorResult& aRv); michael@0: already_AddRefed Types(); michael@0: void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv); michael@0: void SetData(const nsAString& aFormat, const nsAString& aData, michael@0: ErrorResult& aRv); michael@0: void ClearData(const mozilla::dom::Optional& aFormat, michael@0: mozilla::ErrorResult& aRv); michael@0: nsDOMFileList* GetFiles(mozilla::ErrorResult& aRv); michael@0: void AddElement(Element& aElement, mozilla::ErrorResult& aRv); michael@0: uint32_t MozItemCount() michael@0: { michael@0: return mItems.Length(); michael@0: } michael@0: void GetMozCursor(nsString& aCursor) michael@0: { michael@0: if (mCursorState) { michael@0: aCursor.AssignLiteral("default"); michael@0: } else { michael@0: aCursor.AssignLiteral("auto"); michael@0: } michael@0: } michael@0: already_AddRefed MozTypesAt(uint32_t aIndex, michael@0: mozilla::ErrorResult& aRv); michael@0: void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex, michael@0: mozilla::ErrorResult& aRv); michael@0: void MozSetDataAt(JSContext* aCx, const nsAString& aFormat, michael@0: JS::Handle aData, uint32_t aIndex, michael@0: mozilla::ErrorResult& aRv); michael@0: void MozGetDataAt(JSContext* aCx, const nsAString& aFormat, michael@0: uint32_t aIndex, JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aRv); michael@0: bool MozUserCancelled() michael@0: { michael@0: return mUserCancelled; michael@0: } michael@0: already_AddRefed GetMozSourceNode(); michael@0: michael@0: mozilla::dom::Element* GetDragTarget() michael@0: { michael@0: return mDragTarget; michael@0: } michael@0: michael@0: // a readonly dataTransfer cannot have new data added or existing data removed. michael@0: // Only the dropEffect and effectAllowed may be modified. michael@0: void SetReadOnly() { mReadOnly = true; } michael@0: michael@0: // converts the data into an array of nsITransferable objects to be used for michael@0: // drag and drop or clipboard operations. michael@0: already_AddRefed GetTransferables(nsIDOMNode* aDragTarget); michael@0: michael@0: // converts the data for a single item at aIndex into an nsITransferable object. michael@0: already_AddRefed GetTransferable(uint32_t aIndex, michael@0: nsILoadContext* aLoadContext); michael@0: michael@0: // converts the data in the variant to an nsISupportString if possible or michael@0: // an nsISupports or null otherwise. michael@0: bool ConvertFromVariant(nsIVariant* aVariant, michael@0: nsISupports** aSupports, michael@0: uint32_t* aLength); michael@0: michael@0: // clears all of the data michael@0: void ClearAll(); michael@0: michael@0: // Similar to SetData except also specifies the principal to store. michael@0: // aData may be null when called from CacheExternalDragFormats or michael@0: // CacheExternalClipboardFormats. michael@0: nsresult SetDataWithPrincipal(const nsAString& aFormat, michael@0: nsIVariant* aData, michael@0: uint32_t aIndex, michael@0: nsIPrincipal* aPrincipal); michael@0: michael@0: // returns a weak reference to the drag image michael@0: Element* GetDragImage(int32_t* aX, int32_t* aY) michael@0: { michael@0: *aX = mDragImageX; michael@0: *aY = mDragImageY; michael@0: return mDragImage; michael@0: } michael@0: michael@0: nsresult Clone(nsISupports* aParent, uint32_t aEventType, bool aUserCancelled, michael@0: bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult); michael@0: michael@0: protected: michael@0: michael@0: // returns a weak reference to the current principal michael@0: nsIPrincipal* GetCurrentPrincipal(nsresult* rv); michael@0: michael@0: // converts some formats used for compatibility in aInFormat into aOutFormat. michael@0: // Text and text/unicode become text/plain, and URL becomes text/uri-list michael@0: void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat); michael@0: michael@0: // caches text and uri-list data formats that exist in the drag service or michael@0: // clipboard for retrieval later. michael@0: void CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal); michael@0: michael@0: // caches the formats that exist in the drag service that were added by an michael@0: // external drag michael@0: void CacheExternalDragFormats(); michael@0: michael@0: // caches the formats that exist in the clipboard michael@0: void CacheExternalClipboardFormats(); michael@0: michael@0: // fills in the data field of aItem with the data from the drag service or michael@0: // clipboard for a given index. michael@0: void FillInExternalData(TransferItem& aItem, uint32_t aIndex); michael@0: michael@0: void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex, michael@0: mozilla::ErrorResult& aRv); michael@0: michael@0: nsCOMPtr mParent; michael@0: michael@0: // the event type this data transfer is for. This will correspond to an michael@0: // event->message value. michael@0: uint32_t mEventType; michael@0: michael@0: // the drop effect and effect allowed michael@0: uint32_t mDropEffect; michael@0: uint32_t mEffectAllowed; michael@0: michael@0: // Indicates the behavior of the cursor during drag operations michael@0: bool mCursorState; michael@0: michael@0: // readonly data transfers may not be modified except the drop effect and michael@0: // effect allowed. michael@0: bool mReadOnly; michael@0: michael@0: // true for drags started without a data transfer, for example, those from michael@0: // another application. michael@0: bool mIsExternal; michael@0: michael@0: // true if the user cancelled the drag. Used only for the dragend event. michael@0: bool mUserCancelled; michael@0: michael@0: // true if this is a cross-domain drop from a subframe where access to the michael@0: // data should be prevented michael@0: bool mIsCrossDomainSubFrameDrop; michael@0: michael@0: // Indicates which clipboard type to use for clipboard operations. Ignored for michael@0: // drag and drop. michael@0: int32_t mClipboardType; michael@0: michael@0: // array of items, each containing an array of format->data pairs michael@0: nsTArray > mItems; michael@0: michael@0: // array of files, containing only the files present in the dataTransfer michael@0: nsRefPtr mFiles; michael@0: michael@0: // the target of the drag. The drag and dragend events will fire at this. michael@0: nsCOMPtr mDragTarget; michael@0: michael@0: // the custom drag image and coordinates within the image. If mDragImage is michael@0: // null, the default image is created from the drag target. michael@0: nsCOMPtr mDragImage; michael@0: uint32_t mDragImageX; michael@0: uint32_t mDragImageY; michael@0: }; michael@0: michael@0: NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID) michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: #endif /* mozilla_dom_DataTransfer_h */ michael@0: