Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef mozilla_dom_DataTransfer_h |
michael@0 | 7 | #define mozilla_dom_DataTransfer_h |
michael@0 | 8 | |
michael@0 | 9 | #include "nsString.h" |
michael@0 | 10 | #include "nsTArray.h" |
michael@0 | 11 | #include "nsIVariant.h" |
michael@0 | 12 | #include "nsIPrincipal.h" |
michael@0 | 13 | #include "nsIDOMDataTransfer.h" |
michael@0 | 14 | #include "nsIDOMElement.h" |
michael@0 | 15 | #include "nsIDragService.h" |
michael@0 | 16 | #include "nsCycleCollectionParticipant.h" |
michael@0 | 17 | |
michael@0 | 18 | #include "nsAutoPtr.h" |
michael@0 | 19 | #include "nsDOMFile.h" |
michael@0 | 20 | #include "mozilla/Attributes.h" |
michael@0 | 21 | |
michael@0 | 22 | class nsINode; |
michael@0 | 23 | class nsITransferable; |
michael@0 | 24 | class nsISupportsArray; |
michael@0 | 25 | class nsILoadContext; |
michael@0 | 26 | |
michael@0 | 27 | namespace mozilla { |
michael@0 | 28 | |
michael@0 | 29 | class EventStateManager; |
michael@0 | 30 | |
michael@0 | 31 | namespace dom { |
michael@0 | 32 | |
michael@0 | 33 | class DOMStringList; |
michael@0 | 34 | class Element; |
michael@0 | 35 | template<typename T> class Optional; |
michael@0 | 36 | |
michael@0 | 37 | /** |
michael@0 | 38 | * TransferItem is used to hold data for a particular format. Each piece of |
michael@0 | 39 | * data has a principal set from the caller which added it. This allows a |
michael@0 | 40 | * caller that wishes to retrieve the data to only be able to access the data |
michael@0 | 41 | * it is allowed to, yet still allow a chrome caller to retrieve any of the |
michael@0 | 42 | * data. |
michael@0 | 43 | */ |
michael@0 | 44 | struct TransferItem { |
michael@0 | 45 | nsString mFormat; |
michael@0 | 46 | nsCOMPtr<nsIPrincipal> mPrincipal; |
michael@0 | 47 | nsCOMPtr<nsIVariant> mData; |
michael@0 | 48 | }; |
michael@0 | 49 | |
michael@0 | 50 | #define NS_DATATRANSFER_IID \ |
michael@0 | 51 | { 0x43ee0327, 0xde5d, 0x463d, \ |
michael@0 | 52 | { 0x9b, 0xd0, 0xf1, 0x79, 0x09, 0x69, 0xf2, 0xfb } } |
michael@0 | 53 | |
michael@0 | 54 | class DataTransfer MOZ_FINAL : public nsIDOMDataTransfer, |
michael@0 | 55 | public nsWrapperCache |
michael@0 | 56 | { |
michael@0 | 57 | public: |
michael@0 | 58 | NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID) |
michael@0 | 59 | |
michael@0 | 60 | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
michael@0 | 61 | NS_DECL_NSIDOMDATATRANSFER |
michael@0 | 62 | |
michael@0 | 63 | NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer) |
michael@0 | 64 | |
michael@0 | 65 | friend class mozilla::EventStateManager; |
michael@0 | 66 | |
michael@0 | 67 | protected: |
michael@0 | 68 | |
michael@0 | 69 | // hide the default constructor |
michael@0 | 70 | DataTransfer(); |
michael@0 | 71 | |
michael@0 | 72 | // this constructor is used only by the Clone method to copy the fields as |
michael@0 | 73 | // needed to a new data transfer. |
michael@0 | 74 | DataTransfer(nsISupports* aParent, |
michael@0 | 75 | uint32_t aEventType, |
michael@0 | 76 | const uint32_t aEffectAllowed, |
michael@0 | 77 | bool aCursorState, |
michael@0 | 78 | bool aIsExternal, |
michael@0 | 79 | bool aUserCancelled, |
michael@0 | 80 | bool aIsCrossDomainSubFrameDrop, |
michael@0 | 81 | int32_t aClipboardType, |
michael@0 | 82 | nsTArray<nsTArray<TransferItem> >& aItems, |
michael@0 | 83 | Element* aDragImage, |
michael@0 | 84 | uint32_t aDragImageX, |
michael@0 | 85 | uint32_t aDragImageY); |
michael@0 | 86 | |
michael@0 | 87 | ~DataTransfer(); |
michael@0 | 88 | |
michael@0 | 89 | static const char sEffects[8][9]; |
michael@0 | 90 | |
michael@0 | 91 | public: |
michael@0 | 92 | |
michael@0 | 93 | // Constructor for DataTransfer. |
michael@0 | 94 | // |
michael@0 | 95 | // aEventType is an event constant (such as NS_DRAGDROP_START) |
michael@0 | 96 | // |
michael@0 | 97 | // aIsExternal must only be true when used to create a dataTransfer for a |
michael@0 | 98 | // paste or a drag that was started without using a data transfer. The |
michael@0 | 99 | // latter will occur when an external drag occurs, that is, a drag where the |
michael@0 | 100 | // source is another application, or a drag is started by calling the drag |
michael@0 | 101 | // service directly. For clipboard operations, aClipboardType indicates |
michael@0 | 102 | // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations, |
michael@0 | 103 | // or if access to the system clipboard should not be allowed. |
michael@0 | 104 | DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal, |
michael@0 | 105 | int32_t aClipboardType); |
michael@0 | 106 | |
michael@0 | 107 | virtual JSObject* WrapObject(JSContext* aCx); |
michael@0 | 108 | nsISupports* GetParentObject() |
michael@0 | 109 | { |
michael@0 | 110 | return mParent; |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | void SetParentObject(nsISupports* aNewParent) |
michael@0 | 114 | { |
michael@0 | 115 | MOZ_ASSERT(aNewParent); |
michael@0 | 116 | // Setting the parent after we've been wrapped is pointless, so |
michael@0 | 117 | // make sure we aren't wrapped yet. |
michael@0 | 118 | MOZ_ASSERT(!GetWrapperPreserveColor()); |
michael@0 | 119 | mParent = aNewParent; |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | static already_AddRefed<DataTransfer> |
michael@0 | 123 | Constructor(const GlobalObject& aGlobal, const nsAString& aEventType, |
michael@0 | 124 | bool aIsExternal, ErrorResult& aRv); |
michael@0 | 125 | |
michael@0 | 126 | void GetDropEffect(nsString& aDropEffect) |
michael@0 | 127 | { |
michael@0 | 128 | aDropEffect.AssignASCII(sEffects[mDropEffect]); |
michael@0 | 129 | } |
michael@0 | 130 | void GetEffectAllowed(nsString& aEffectAllowed) |
michael@0 | 131 | { |
michael@0 | 132 | if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) { |
michael@0 | 133 | aEffectAllowed.AssignLiteral("uninitialized"); |
michael@0 | 134 | } else { |
michael@0 | 135 | aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]); |
michael@0 | 136 | } |
michael@0 | 137 | } |
michael@0 | 138 | void SetDragImage(Element& aElement, int32_t aX, int32_t aY, |
michael@0 | 139 | ErrorResult& aRv); |
michael@0 | 140 | already_AddRefed<DOMStringList> Types(); |
michael@0 | 141 | void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv); |
michael@0 | 142 | void SetData(const nsAString& aFormat, const nsAString& aData, |
michael@0 | 143 | ErrorResult& aRv); |
michael@0 | 144 | void ClearData(const mozilla::dom::Optional<nsAString>& aFormat, |
michael@0 | 145 | mozilla::ErrorResult& aRv); |
michael@0 | 146 | nsDOMFileList* GetFiles(mozilla::ErrorResult& aRv); |
michael@0 | 147 | void AddElement(Element& aElement, mozilla::ErrorResult& aRv); |
michael@0 | 148 | uint32_t MozItemCount() |
michael@0 | 149 | { |
michael@0 | 150 | return mItems.Length(); |
michael@0 | 151 | } |
michael@0 | 152 | void GetMozCursor(nsString& aCursor) |
michael@0 | 153 | { |
michael@0 | 154 | if (mCursorState) { |
michael@0 | 155 | aCursor.AssignLiteral("default"); |
michael@0 | 156 | } else { |
michael@0 | 157 | aCursor.AssignLiteral("auto"); |
michael@0 | 158 | } |
michael@0 | 159 | } |
michael@0 | 160 | already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex, |
michael@0 | 161 | mozilla::ErrorResult& aRv); |
michael@0 | 162 | void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex, |
michael@0 | 163 | mozilla::ErrorResult& aRv); |
michael@0 | 164 | void MozSetDataAt(JSContext* aCx, const nsAString& aFormat, |
michael@0 | 165 | JS::Handle<JS::Value> aData, uint32_t aIndex, |
michael@0 | 166 | mozilla::ErrorResult& aRv); |
michael@0 | 167 | void MozGetDataAt(JSContext* aCx, const nsAString& aFormat, |
michael@0 | 168 | uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval, |
michael@0 | 169 | mozilla::ErrorResult& aRv); |
michael@0 | 170 | bool MozUserCancelled() |
michael@0 | 171 | { |
michael@0 | 172 | return mUserCancelled; |
michael@0 | 173 | } |
michael@0 | 174 | already_AddRefed<nsINode> GetMozSourceNode(); |
michael@0 | 175 | |
michael@0 | 176 | mozilla::dom::Element* GetDragTarget() |
michael@0 | 177 | { |
michael@0 | 178 | return mDragTarget; |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | // a readonly dataTransfer cannot have new data added or existing data removed. |
michael@0 | 182 | // Only the dropEffect and effectAllowed may be modified. |
michael@0 | 183 | void SetReadOnly() { mReadOnly = true; } |
michael@0 | 184 | |
michael@0 | 185 | // converts the data into an array of nsITransferable objects to be used for |
michael@0 | 186 | // drag and drop or clipboard operations. |
michael@0 | 187 | already_AddRefed<nsISupportsArray> GetTransferables(nsIDOMNode* aDragTarget); |
michael@0 | 188 | |
michael@0 | 189 | // converts the data for a single item at aIndex into an nsITransferable object. |
michael@0 | 190 | already_AddRefed<nsITransferable> GetTransferable(uint32_t aIndex, |
michael@0 | 191 | nsILoadContext* aLoadContext); |
michael@0 | 192 | |
michael@0 | 193 | // converts the data in the variant to an nsISupportString if possible or |
michael@0 | 194 | // an nsISupports or null otherwise. |
michael@0 | 195 | bool ConvertFromVariant(nsIVariant* aVariant, |
michael@0 | 196 | nsISupports** aSupports, |
michael@0 | 197 | uint32_t* aLength); |
michael@0 | 198 | |
michael@0 | 199 | // clears all of the data |
michael@0 | 200 | void ClearAll(); |
michael@0 | 201 | |
michael@0 | 202 | // Similar to SetData except also specifies the principal to store. |
michael@0 | 203 | // aData may be null when called from CacheExternalDragFormats or |
michael@0 | 204 | // CacheExternalClipboardFormats. |
michael@0 | 205 | nsresult SetDataWithPrincipal(const nsAString& aFormat, |
michael@0 | 206 | nsIVariant* aData, |
michael@0 | 207 | uint32_t aIndex, |
michael@0 | 208 | nsIPrincipal* aPrincipal); |
michael@0 | 209 | |
michael@0 | 210 | // returns a weak reference to the drag image |
michael@0 | 211 | Element* GetDragImage(int32_t* aX, int32_t* aY) |
michael@0 | 212 | { |
michael@0 | 213 | *aX = mDragImageX; |
michael@0 | 214 | *aY = mDragImageY; |
michael@0 | 215 | return mDragImage; |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | nsresult Clone(nsISupports* aParent, uint32_t aEventType, bool aUserCancelled, |
michael@0 | 219 | bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult); |
michael@0 | 220 | |
michael@0 | 221 | protected: |
michael@0 | 222 | |
michael@0 | 223 | // returns a weak reference to the current principal |
michael@0 | 224 | nsIPrincipal* GetCurrentPrincipal(nsresult* rv); |
michael@0 | 225 | |
michael@0 | 226 | // converts some formats used for compatibility in aInFormat into aOutFormat. |
michael@0 | 227 | // Text and text/unicode become text/plain, and URL becomes text/uri-list |
michael@0 | 228 | void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat); |
michael@0 | 229 | |
michael@0 | 230 | // caches text and uri-list data formats that exist in the drag service or |
michael@0 | 231 | // clipboard for retrieval later. |
michael@0 | 232 | void CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal); |
michael@0 | 233 | |
michael@0 | 234 | // caches the formats that exist in the drag service that were added by an |
michael@0 | 235 | // external drag |
michael@0 | 236 | void CacheExternalDragFormats(); |
michael@0 | 237 | |
michael@0 | 238 | // caches the formats that exist in the clipboard |
michael@0 | 239 | void CacheExternalClipboardFormats(); |
michael@0 | 240 | |
michael@0 | 241 | // fills in the data field of aItem with the data from the drag service or |
michael@0 | 242 | // clipboard for a given index. |
michael@0 | 243 | void FillInExternalData(TransferItem& aItem, uint32_t aIndex); |
michael@0 | 244 | |
michael@0 | 245 | void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex, |
michael@0 | 246 | mozilla::ErrorResult& aRv); |
michael@0 | 247 | |
michael@0 | 248 | nsCOMPtr<nsISupports> mParent; |
michael@0 | 249 | |
michael@0 | 250 | // the event type this data transfer is for. This will correspond to an |
michael@0 | 251 | // event->message value. |
michael@0 | 252 | uint32_t mEventType; |
michael@0 | 253 | |
michael@0 | 254 | // the drop effect and effect allowed |
michael@0 | 255 | uint32_t mDropEffect; |
michael@0 | 256 | uint32_t mEffectAllowed; |
michael@0 | 257 | |
michael@0 | 258 | // Indicates the behavior of the cursor during drag operations |
michael@0 | 259 | bool mCursorState; |
michael@0 | 260 | |
michael@0 | 261 | // readonly data transfers may not be modified except the drop effect and |
michael@0 | 262 | // effect allowed. |
michael@0 | 263 | bool mReadOnly; |
michael@0 | 264 | |
michael@0 | 265 | // true for drags started without a data transfer, for example, those from |
michael@0 | 266 | // another application. |
michael@0 | 267 | bool mIsExternal; |
michael@0 | 268 | |
michael@0 | 269 | // true if the user cancelled the drag. Used only for the dragend event. |
michael@0 | 270 | bool mUserCancelled; |
michael@0 | 271 | |
michael@0 | 272 | // true if this is a cross-domain drop from a subframe where access to the |
michael@0 | 273 | // data should be prevented |
michael@0 | 274 | bool mIsCrossDomainSubFrameDrop; |
michael@0 | 275 | |
michael@0 | 276 | // Indicates which clipboard type to use for clipboard operations. Ignored for |
michael@0 | 277 | // drag and drop. |
michael@0 | 278 | int32_t mClipboardType; |
michael@0 | 279 | |
michael@0 | 280 | // array of items, each containing an array of format->data pairs |
michael@0 | 281 | nsTArray<nsTArray<TransferItem> > mItems; |
michael@0 | 282 | |
michael@0 | 283 | // array of files, containing only the files present in the dataTransfer |
michael@0 | 284 | nsRefPtr<nsDOMFileList> mFiles; |
michael@0 | 285 | |
michael@0 | 286 | // the target of the drag. The drag and dragend events will fire at this. |
michael@0 | 287 | nsCOMPtr<mozilla::dom::Element> mDragTarget; |
michael@0 | 288 | |
michael@0 | 289 | // the custom drag image and coordinates within the image. If mDragImage is |
michael@0 | 290 | // null, the default image is created from the drag target. |
michael@0 | 291 | nsCOMPtr<mozilla::dom::Element> mDragImage; |
michael@0 | 292 | uint32_t mDragImageX; |
michael@0 | 293 | uint32_t mDragImageY; |
michael@0 | 294 | }; |
michael@0 | 295 | |
michael@0 | 296 | NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID) |
michael@0 | 297 | |
michael@0 | 298 | } // namespace dom |
michael@0 | 299 | } // namespace mozilla |
michael@0 | 300 | |
michael@0 | 301 | #endif /* mozilla_dom_DataTransfer_h */ |
michael@0 | 302 |