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