toolkit/components/jsdownloads/src/Downloads.jsm

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/jsdownloads/src/Downloads.jsm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,299 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/**
    1.11 + * Main entry point to get references to all the back-end objects.
    1.12 + */
    1.13 +
    1.14 +"use strict";
    1.15 +
    1.16 +this.EXPORTED_SYMBOLS = [
    1.17 +  "Downloads",
    1.18 +];
    1.19 +
    1.20 +////////////////////////////////////////////////////////////////////////////////
    1.21 +//// Globals
    1.22 +
    1.23 +const Cc = Components.classes;
    1.24 +const Ci = Components.interfaces;
    1.25 +const Cu = Components.utils;
    1.26 +const Cr = Components.results;
    1.27 +
    1.28 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.29 +Cu.import("resource://gre/modules/DownloadCore.jsm");
    1.30 +
    1.31 +XPCOMUtils.defineLazyModuleGetter(this, "DownloadCombinedList",
    1.32 +                                  "resource://gre/modules/DownloadList.jsm");
    1.33 +XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
    1.34 +                                  "resource://gre/modules/DownloadIntegration.jsm");
    1.35 +XPCOMUtils.defineLazyModuleGetter(this, "DownloadList",
    1.36 +                                  "resource://gre/modules/DownloadList.jsm");
    1.37 +XPCOMUtils.defineLazyModuleGetter(this, "DownloadSummary",
    1.38 +                                  "resource://gre/modules/DownloadList.jsm");
    1.39 +XPCOMUtils.defineLazyModuleGetter(this, "DownloadUIHelper",
    1.40 +                                  "resource://gre/modules/DownloadUIHelper.jsm");
    1.41 +XPCOMUtils.defineLazyModuleGetter(this, "Promise",
    1.42 +                                  "resource://gre/modules/Promise.jsm");
    1.43 +XPCOMUtils.defineLazyModuleGetter(this, "Task",
    1.44 +                                  "resource://gre/modules/Task.jsm");
    1.45 +
    1.46 +////////////////////////////////////////////////////////////////////////////////
    1.47 +//// Downloads
    1.48 +
    1.49 +/**
    1.50 + * This object is exposed directly to the consumers of this JavaScript module,
    1.51 + * and provides the only entry point to get references to back-end objects.
    1.52 + */
    1.53 +this.Downloads = {
    1.54 +  /**
    1.55 +   * Work on downloads that were not started from a private browsing window.
    1.56 +   */
    1.57 +  get PUBLIC() "{Downloads.PUBLIC}",
    1.58 +  /**
    1.59 +   * Work on downloads that were started from a private browsing window.
    1.60 +   */
    1.61 +  get PRIVATE() "{Downloads.PRIVATE}",
    1.62 +  /**
    1.63 +   * Work on both Downloads.PRIVATE and Downloads.PUBLIC downloads.
    1.64 +   */
    1.65 +  get ALL() "{Downloads.ALL}",
    1.66 +
    1.67 +  /**
    1.68 +   * Creates a new Download object.
    1.69 +   *
    1.70 +   * @param aProperties
    1.71 +   *        Provides the initial properties for the newly created download.
    1.72 +   *        This matches the serializable representation of a Download object.
    1.73 +   *        Some of the most common properties in this object include:
    1.74 +   *        {
    1.75 +   *          source: String containing the URI for the download source.
    1.76 +   *                  Alternatively, may be an nsIURI, a DownloadSource object,
    1.77 +   *                  or an object with the following properties:
    1.78 +   *          {
    1.79 +   *            url: String containing the URI for the download source.
    1.80 +   *            isPrivate: Indicates whether the download originated from a
    1.81 +   *                       private window.  If omitted, the download is public.
    1.82 +   *            referrer: String containing the referrer URI of the download
    1.83 +   *                      source.  Can be omitted or null if no referrer should
    1.84 +   *                      be sent or the download source is not HTTP.
    1.85 +   *          },
    1.86 +   *          target: String containing the path of the target file.
    1.87 +   *                  Alternatively, may be an nsIFile, a DownloadTarget object,
    1.88 +   *                  or an object with the following properties:
    1.89 +   *          {
    1.90 +   *            path: String containing the path of the target file.
    1.91 +   *          },
    1.92 +   *          saver: String representing the class of the download operation.
    1.93 +   *                 If omitted, defaults to "copy".  Alternatively, may be the
    1.94 +   *                 serializable representation of a DownloadSaver object.
    1.95 +   *        }
    1.96 +   *
    1.97 +   * @return {Promise}
    1.98 +   * @resolves The newly created Download object.
    1.99 +   * @rejects JavaScript exception.
   1.100 +   */
   1.101 +  createDownload: function D_createDownload(aProperties)
   1.102 +  {
   1.103 +    try {
   1.104 +      return Promise.resolve(Download.fromSerializable(aProperties));
   1.105 +    } catch (ex) {
   1.106 +      return Promise.reject(ex);
   1.107 +    }
   1.108 +  },
   1.109 +
   1.110 +  /**
   1.111 +   * Downloads data from a remote network location to a local file.
   1.112 +   *
   1.113 +   * This download method does not provide user interface, or the ability to
   1.114 +   * cancel or restart the download programmatically.  For that, you should
   1.115 +   * obtain a reference to a Download object using the createDownload function.
   1.116 +   *
   1.117 +   * Since the download cannot be restarted, any partially downloaded data will
   1.118 +   * not be kept in case the download fails.
   1.119 +   *
   1.120 +   * @param aSource
   1.121 +   *        String containing the URI for the download source.  Alternatively,
   1.122 +   *        may be an nsIURI or a DownloadSource object.
   1.123 +   * @param aTarget
   1.124 +   *        String containing the path of the target file.  Alternatively, may
   1.125 +   *        be an nsIFile or a DownloadTarget object.
   1.126 +   * @param aOptions
   1.127 +   *        An optional object used to control the behavior of this function.
   1.128 +   *        You may pass an object with a subset of the following fields:
   1.129 +   *        {
   1.130 +   *          isPrivate: Indicates whether the download originated from a
   1.131 +   *                     private window.
   1.132 +   *        }
   1.133 +   *
   1.134 +   * @return {Promise}
   1.135 +   * @resolves When the download has finished successfully.
   1.136 +   * @rejects JavaScript exception if the download failed.
   1.137 +   */
   1.138 +  fetch: function (aSource, aTarget, aOptions) {
   1.139 +    return this.createDownload({
   1.140 +      source: aSource,
   1.141 +      target: aTarget,
   1.142 +    }).then(function D_SD_onSuccess(aDownload) {
   1.143 +      if (aOptions && ("isPrivate" in aOptions)) {
   1.144 +        aDownload.source.isPrivate = aOptions.isPrivate;
   1.145 +      }
   1.146 +      return aDownload.start();
   1.147 +    });
   1.148 +  },
   1.149 +
   1.150 +  /**
   1.151 +   * Retrieves the specified type of DownloadList object.  There is one download
   1.152 +   * list for each type, and this method always retrieves a reference to the
   1.153 +   * same download list when called with the same argument.
   1.154 +   *
   1.155 +   * Calling this function may cause the list of public downloads to be reloaded
   1.156 +   * from the previous session, if it wasn't loaded already.
   1.157 +   *
   1.158 +   * @param aType
   1.159 +   *        This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
   1.160 +   *        Downloads added to the Downloads.PUBLIC and Downloads.PRIVATE lists
   1.161 +   *        are reflected in the Downloads.ALL list, and downloads added to the
   1.162 +   *        Downloads.ALL list are also added to either the Downloads.PUBLIC or
   1.163 +   *        the Downloads.PRIVATE list based on their properties.
   1.164 +   *
   1.165 +   * @return {Promise}
   1.166 +   * @resolves The requested DownloadList or DownloadCombinedList object.
   1.167 +   * @rejects JavaScript exception.
   1.168 +   */
   1.169 +  getList: function (aType)
   1.170 +  {
   1.171 +    if (!this._promiseListsInitialized) {
   1.172 +      this._promiseListsInitialized = Task.spawn(function () {
   1.173 +        let publicList = new DownloadList();
   1.174 +        let privateList = new DownloadList();
   1.175 +        let combinedList = new DownloadCombinedList(publicList, privateList);
   1.176 +
   1.177 +        try {
   1.178 +          yield DownloadIntegration.addListObservers(publicList, false);
   1.179 +          yield DownloadIntegration.addListObservers(privateList, true);
   1.180 +          yield DownloadIntegration.initializePublicDownloadList(publicList);
   1.181 +        } catch (ex) {
   1.182 +          Cu.reportError(ex);
   1.183 +        }
   1.184 +
   1.185 +        let publicSummary = yield this.getSummary(Downloads.PUBLIC);
   1.186 +        let privateSummary = yield this.getSummary(Downloads.PRIVATE);
   1.187 +        let combinedSummary = yield this.getSummary(Downloads.ALL);
   1.188 +
   1.189 +        yield publicSummary.bindToList(publicList);
   1.190 +        yield privateSummary.bindToList(privateList);
   1.191 +        yield combinedSummary.bindToList(combinedList);
   1.192 +
   1.193 +        this._lists[Downloads.PUBLIC] = publicList;
   1.194 +        this._lists[Downloads.PRIVATE] = privateList;
   1.195 +        this._lists[Downloads.ALL] = combinedList;
   1.196 +      }.bind(this));
   1.197 +    }
   1.198 +
   1.199 +    return this._promiseListsInitialized.then(() => this._lists[aType]);
   1.200 +  },
   1.201 +
   1.202 +  /**
   1.203 +   * Promise resolved when the initialization of the download lists has
   1.204 +   * completed, or null if initialization has never been requested.
   1.205 +   */
   1.206 +  _promiseListsInitialized: null,
   1.207 +
   1.208 +  /**
   1.209 +   * After initialization, this object is populated with one key for each type
   1.210 +   * of download list that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
   1.211 +   * or Downloads.ALL).  The values are the DownloadList objects.
   1.212 +   */
   1.213 +  _lists: {},
   1.214 +
   1.215 +  /**
   1.216 +   * Retrieves the specified type of DownloadSummary object.  There is one
   1.217 +   * download summary for each type, and this method always retrieves a
   1.218 +   * reference to the same download summary when called with the same argument.
   1.219 +   *
   1.220 +   * Calling this function does not cause the list of public downloads to be
   1.221 +   * reloaded from the previous session.  The summary will behave as if no
   1.222 +   * downloads are present until the getList method is called.
   1.223 +   *
   1.224 +   * @param aType
   1.225 +   *        This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
   1.226 +   *
   1.227 +   * @return {Promise}
   1.228 +   * @resolves The requested DownloadList or DownloadCombinedList object.
   1.229 +   * @rejects JavaScript exception.
   1.230 +   */
   1.231 +  getSummary: function (aType)
   1.232 +  {
   1.233 +    if (aType != Downloads.PUBLIC && aType != Downloads.PRIVATE &&
   1.234 +        aType != Downloads.ALL) {
   1.235 +      throw new Error("Invalid aType argument.");
   1.236 +    }
   1.237 +
   1.238 +    if (!(aType in this._summaries)) {
   1.239 +      this._summaries[aType] = new DownloadSummary();
   1.240 +    }
   1.241 +
   1.242 +    return Promise.resolve(this._summaries[aType]);
   1.243 +  },
   1.244 +
   1.245 +  /**
   1.246 +   * This object is populated by the getSummary method with one key for each
   1.247 +   * type of object that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
   1.248 +   * or Downloads.ALL).  The values are the DownloadSummary objects.
   1.249 +   */
   1.250 +  _summaries: {},
   1.251 +
   1.252 +  /**
   1.253 +   * Returns the system downloads directory asynchronously.
   1.254 +   *   Mac OSX:
   1.255 +   *     User downloads directory
   1.256 +   *   XP/2K:
   1.257 +   *     My Documents/Downloads
   1.258 +   *   Vista and others:
   1.259 +   *     User downloads directory
   1.260 +   *   Linux:
   1.261 +   *     XDG user dir spec, with a fallback to Home/Downloads
   1.262 +   *   Android:
   1.263 +   *     standard downloads directory i.e. /sdcard
   1.264 +   *
   1.265 +   * @return {Promise}
   1.266 +   * @resolves The downloads directory string path.
   1.267 +   */
   1.268 +  getSystemDownloadsDirectory: function D_getSystemDownloadsDirectory() {
   1.269 +    return DownloadIntegration.getSystemDownloadsDirectory();
   1.270 +  },
   1.271 +
   1.272 +  /**
   1.273 +   * Returns the preferred downloads directory based on the user preferences
   1.274 +   * in the current profile asynchronously.
   1.275 +   *
   1.276 +   * @return {Promise}
   1.277 +   * @resolves The downloads directory string path.
   1.278 +   */
   1.279 +  getPreferredDownloadsDirectory: function D_getPreferredDownloadsDirectory() {
   1.280 +    return DownloadIntegration.getPreferredDownloadsDirectory();
   1.281 +  },
   1.282 +
   1.283 +  /**
   1.284 +   * Returns the temporary directory where downloads are placed before the
   1.285 +   * final location is chosen, or while the document is opened temporarily
   1.286 +   * with an external application. This may or may not be the system temporary
   1.287 +   * directory, based on the platform asynchronously.
   1.288 +   *
   1.289 +   * @return {Promise}
   1.290 +   * @resolves The downloads directory string path.
   1.291 +   */
   1.292 +  getTemporaryDownloadsDirectory: function D_getTemporaryDownloadsDirectory() {
   1.293 +    return DownloadIntegration.getTemporaryDownloadsDirectory();
   1.294 +  },
   1.295 +
   1.296 +  /**
   1.297 +   * Constructor for a DownloadError object.  When you catch an exception during
   1.298 +   * a download, you can use this to verify if "ex instanceof Downloads.Error",
   1.299 +   * before reading the exception properties with the error details.
   1.300 +   */
   1.301 +  Error: DownloadError,
   1.302 +};

mercurial