toolkit/components/jsdownloads/src/Downloads.jsm

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:f5ed2f655500
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /**
8 * Main entry point to get references to all the back-end objects.
9 */
10
11 "use strict";
12
13 this.EXPORTED_SYMBOLS = [
14 "Downloads",
15 ];
16
17 ////////////////////////////////////////////////////////////////////////////////
18 //// Globals
19
20 const Cc = Components.classes;
21 const Ci = Components.interfaces;
22 const Cu = Components.utils;
23 const Cr = Components.results;
24
25 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
26 Cu.import("resource://gre/modules/DownloadCore.jsm");
27
28 XPCOMUtils.defineLazyModuleGetter(this, "DownloadCombinedList",
29 "resource://gre/modules/DownloadList.jsm");
30 XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
31 "resource://gre/modules/DownloadIntegration.jsm");
32 XPCOMUtils.defineLazyModuleGetter(this, "DownloadList",
33 "resource://gre/modules/DownloadList.jsm");
34 XPCOMUtils.defineLazyModuleGetter(this, "DownloadSummary",
35 "resource://gre/modules/DownloadList.jsm");
36 XPCOMUtils.defineLazyModuleGetter(this, "DownloadUIHelper",
37 "resource://gre/modules/DownloadUIHelper.jsm");
38 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
39 "resource://gre/modules/Promise.jsm");
40 XPCOMUtils.defineLazyModuleGetter(this, "Task",
41 "resource://gre/modules/Task.jsm");
42
43 ////////////////////////////////////////////////////////////////////////////////
44 //// Downloads
45
46 /**
47 * This object is exposed directly to the consumers of this JavaScript module,
48 * and provides the only entry point to get references to back-end objects.
49 */
50 this.Downloads = {
51 /**
52 * Work on downloads that were not started from a private browsing window.
53 */
54 get PUBLIC() "{Downloads.PUBLIC}",
55 /**
56 * Work on downloads that were started from a private browsing window.
57 */
58 get PRIVATE() "{Downloads.PRIVATE}",
59 /**
60 * Work on both Downloads.PRIVATE and Downloads.PUBLIC downloads.
61 */
62 get ALL() "{Downloads.ALL}",
63
64 /**
65 * Creates a new Download object.
66 *
67 * @param aProperties
68 * Provides the initial properties for the newly created download.
69 * This matches the serializable representation of a Download object.
70 * Some of the most common properties in this object include:
71 * {
72 * source: String containing the URI for the download source.
73 * Alternatively, may be an nsIURI, a DownloadSource object,
74 * or an object with the following properties:
75 * {
76 * url: String containing the URI for the download source.
77 * isPrivate: Indicates whether the download originated from a
78 * private window. If omitted, the download is public.
79 * referrer: String containing the referrer URI of the download
80 * source. Can be omitted or null if no referrer should
81 * be sent or the download source is not HTTP.
82 * },
83 * target: String containing the path of the target file.
84 * Alternatively, may be an nsIFile, a DownloadTarget object,
85 * or an object with the following properties:
86 * {
87 * path: String containing the path of the target file.
88 * },
89 * saver: String representing the class of the download operation.
90 * If omitted, defaults to "copy". Alternatively, may be the
91 * serializable representation of a DownloadSaver object.
92 * }
93 *
94 * @return {Promise}
95 * @resolves The newly created Download object.
96 * @rejects JavaScript exception.
97 */
98 createDownload: function D_createDownload(aProperties)
99 {
100 try {
101 return Promise.resolve(Download.fromSerializable(aProperties));
102 } catch (ex) {
103 return Promise.reject(ex);
104 }
105 },
106
107 /**
108 * Downloads data from a remote network location to a local file.
109 *
110 * This download method does not provide user interface, or the ability to
111 * cancel or restart the download programmatically. For that, you should
112 * obtain a reference to a Download object using the createDownload function.
113 *
114 * Since the download cannot be restarted, any partially downloaded data will
115 * not be kept in case the download fails.
116 *
117 * @param aSource
118 * String containing the URI for the download source. Alternatively,
119 * may be an nsIURI or a DownloadSource object.
120 * @param aTarget
121 * String containing the path of the target file. Alternatively, may
122 * be an nsIFile or a DownloadTarget object.
123 * @param aOptions
124 * An optional object used to control the behavior of this function.
125 * You may pass an object with a subset of the following fields:
126 * {
127 * isPrivate: Indicates whether the download originated from a
128 * private window.
129 * }
130 *
131 * @return {Promise}
132 * @resolves When the download has finished successfully.
133 * @rejects JavaScript exception if the download failed.
134 */
135 fetch: function (aSource, aTarget, aOptions) {
136 return this.createDownload({
137 source: aSource,
138 target: aTarget,
139 }).then(function D_SD_onSuccess(aDownload) {
140 if (aOptions && ("isPrivate" in aOptions)) {
141 aDownload.source.isPrivate = aOptions.isPrivate;
142 }
143 return aDownload.start();
144 });
145 },
146
147 /**
148 * Retrieves the specified type of DownloadList object. There is one download
149 * list for each type, and this method always retrieves a reference to the
150 * same download list when called with the same argument.
151 *
152 * Calling this function may cause the list of public downloads to be reloaded
153 * from the previous session, if it wasn't loaded already.
154 *
155 * @param aType
156 * This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
157 * Downloads added to the Downloads.PUBLIC and Downloads.PRIVATE lists
158 * are reflected in the Downloads.ALL list, and downloads added to the
159 * Downloads.ALL list are also added to either the Downloads.PUBLIC or
160 * the Downloads.PRIVATE list based on their properties.
161 *
162 * @return {Promise}
163 * @resolves The requested DownloadList or DownloadCombinedList object.
164 * @rejects JavaScript exception.
165 */
166 getList: function (aType)
167 {
168 if (!this._promiseListsInitialized) {
169 this._promiseListsInitialized = Task.spawn(function () {
170 let publicList = new DownloadList();
171 let privateList = new DownloadList();
172 let combinedList = new DownloadCombinedList(publicList, privateList);
173
174 try {
175 yield DownloadIntegration.addListObservers(publicList, false);
176 yield DownloadIntegration.addListObservers(privateList, true);
177 yield DownloadIntegration.initializePublicDownloadList(publicList);
178 } catch (ex) {
179 Cu.reportError(ex);
180 }
181
182 let publicSummary = yield this.getSummary(Downloads.PUBLIC);
183 let privateSummary = yield this.getSummary(Downloads.PRIVATE);
184 let combinedSummary = yield this.getSummary(Downloads.ALL);
185
186 yield publicSummary.bindToList(publicList);
187 yield privateSummary.bindToList(privateList);
188 yield combinedSummary.bindToList(combinedList);
189
190 this._lists[Downloads.PUBLIC] = publicList;
191 this._lists[Downloads.PRIVATE] = privateList;
192 this._lists[Downloads.ALL] = combinedList;
193 }.bind(this));
194 }
195
196 return this._promiseListsInitialized.then(() => this._lists[aType]);
197 },
198
199 /**
200 * Promise resolved when the initialization of the download lists has
201 * completed, or null if initialization has never been requested.
202 */
203 _promiseListsInitialized: null,
204
205 /**
206 * After initialization, this object is populated with one key for each type
207 * of download list that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
208 * or Downloads.ALL). The values are the DownloadList objects.
209 */
210 _lists: {},
211
212 /**
213 * Retrieves the specified type of DownloadSummary object. There is one
214 * download summary for each type, and this method always retrieves a
215 * reference to the same download summary when called with the same argument.
216 *
217 * Calling this function does not cause the list of public downloads to be
218 * reloaded from the previous session. The summary will behave as if no
219 * downloads are present until the getList method is called.
220 *
221 * @param aType
222 * This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
223 *
224 * @return {Promise}
225 * @resolves The requested DownloadList or DownloadCombinedList object.
226 * @rejects JavaScript exception.
227 */
228 getSummary: function (aType)
229 {
230 if (aType != Downloads.PUBLIC && aType != Downloads.PRIVATE &&
231 aType != Downloads.ALL) {
232 throw new Error("Invalid aType argument.");
233 }
234
235 if (!(aType in this._summaries)) {
236 this._summaries[aType] = new DownloadSummary();
237 }
238
239 return Promise.resolve(this._summaries[aType]);
240 },
241
242 /**
243 * This object is populated by the getSummary method with one key for each
244 * type of object that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
245 * or Downloads.ALL). The values are the DownloadSummary objects.
246 */
247 _summaries: {},
248
249 /**
250 * Returns the system downloads directory asynchronously.
251 * Mac OSX:
252 * User downloads directory
253 * XP/2K:
254 * My Documents/Downloads
255 * Vista and others:
256 * User downloads directory
257 * Linux:
258 * XDG user dir spec, with a fallback to Home/Downloads
259 * Android:
260 * standard downloads directory i.e. /sdcard
261 *
262 * @return {Promise}
263 * @resolves The downloads directory string path.
264 */
265 getSystemDownloadsDirectory: function D_getSystemDownloadsDirectory() {
266 return DownloadIntegration.getSystemDownloadsDirectory();
267 },
268
269 /**
270 * Returns the preferred downloads directory based on the user preferences
271 * in the current profile asynchronously.
272 *
273 * @return {Promise}
274 * @resolves The downloads directory string path.
275 */
276 getPreferredDownloadsDirectory: function D_getPreferredDownloadsDirectory() {
277 return DownloadIntegration.getPreferredDownloadsDirectory();
278 },
279
280 /**
281 * Returns the temporary directory where downloads are placed before the
282 * final location is chosen, or while the document is opened temporarily
283 * with an external application. This may or may not be the system temporary
284 * directory, based on the platform asynchronously.
285 *
286 * @return {Promise}
287 * @resolves The downloads directory string path.
288 */
289 getTemporaryDownloadsDirectory: function D_getTemporaryDownloadsDirectory() {
290 return DownloadIntegration.getTemporaryDownloadsDirectory();
291 },
292
293 /**
294 * Constructor for a DownloadError object. When you catch an exception during
295 * a download, you can use this to verify if "ex instanceof Downloads.Error",
296 * before reading the exception properties with the error details.
297 */
298 Error: DownloadError,
299 };

mercurial