toolkit/components/jsdownloads/src/Downloads.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial