Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
6 #ifndef mozilla_dom_DataTransfer_h
7 #define mozilla_dom_DataTransfer_h
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"
18 #include "nsAutoPtr.h"
19 #include "nsDOMFile.h"
20 #include "mozilla/Attributes.h"
22 class nsINode;
23 class nsITransferable;
24 class nsISupportsArray;
25 class nsILoadContext;
27 namespace mozilla {
29 class EventStateManager;
31 namespace dom {
33 class DOMStringList;
34 class Element;
35 template<typename T> class Optional;
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 };
50 #define NS_DATATRANSFER_IID \
51 { 0x43ee0327, 0xde5d, 0x463d, \
52 { 0x9b, 0xd0, 0xf1, 0x79, 0x09, 0x69, 0xf2, 0xfb } }
54 class DataTransfer MOZ_FINAL : public nsIDOMDataTransfer,
55 public nsWrapperCache
56 {
57 public:
58 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID)
60 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
61 NS_DECL_NSIDOMDATATRANSFER
63 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer)
65 friend class mozilla::EventStateManager;
67 protected:
69 // hide the default constructor
70 DataTransfer();
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);
87 ~DataTransfer();
89 static const char sEffects[8][9];
91 public:
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);
107 virtual JSObject* WrapObject(JSContext* aCx);
108 nsISupports* GetParentObject()
109 {
110 return mParent;
111 }
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 }
122 static already_AddRefed<DataTransfer>
123 Constructor(const GlobalObject& aGlobal, const nsAString& aEventType,
124 bool aIsExternal, ErrorResult& aRv);
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();
176 mozilla::dom::Element* GetDragTarget()
177 {
178 return mDragTarget;
179 }
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; }
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);
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);
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);
199 // clears all of the data
200 void ClearAll();
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);
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 }
218 nsresult Clone(nsISupports* aParent, uint32_t aEventType, bool aUserCancelled,
219 bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult);
221 protected:
223 // returns a weak reference to the current principal
224 nsIPrincipal* GetCurrentPrincipal(nsresult* rv);
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);
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);
234 // caches the formats that exist in the drag service that were added by an
235 // external drag
236 void CacheExternalDragFormats();
238 // caches the formats that exist in the clipboard
239 void CacheExternalClipboardFormats();
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);
245 void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
246 mozilla::ErrorResult& aRv);
248 nsCOMPtr<nsISupports> mParent;
250 // the event type this data transfer is for. This will correspond to an
251 // event->message value.
252 uint32_t mEventType;
254 // the drop effect and effect allowed
255 uint32_t mDropEffect;
256 uint32_t mEffectAllowed;
258 // Indicates the behavior of the cursor during drag operations
259 bool mCursorState;
261 // readonly data transfers may not be modified except the drop effect and
262 // effect allowed.
263 bool mReadOnly;
265 // true for drags started without a data transfer, for example, those from
266 // another application.
267 bool mIsExternal;
269 // true if the user cancelled the drag. Used only for the dragend event.
270 bool mUserCancelled;
272 // true if this is a cross-domain drop from a subframe where access to the
273 // data should be prevented
274 bool mIsCrossDomainSubFrameDrop;
276 // Indicates which clipboard type to use for clipboard operations. Ignored for
277 // drag and drop.
278 int32_t mClipboardType;
280 // array of items, each containing an array of format->data pairs
281 nsTArray<nsTArray<TransferItem> > mItems;
283 // array of files, containing only the files present in the dataTransfer
284 nsRefPtr<nsDOMFileList> mFiles;
286 // the target of the drag. The drag and dragend events will fire at this.
287 nsCOMPtr<mozilla::dom::Element> mDragTarget;
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 };
296 NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
298 } // namespace dom
299 } // namespace mozilla
301 #endif /* mozilla_dom_DataTransfer_h */