Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Main entry point to get references to all the back-end objects.
*/
import { Integration } from "resource://gre/modules/Integration.sys.mjs";
import {
Download,
DownloadError,
} from "resource://gre/modules/DownloadCore.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
DownloadCombinedList: "resource://gre/modules/DownloadList.sys.mjs",
DownloadList: "resource://gre/modules/DownloadList.sys.mjs",
DownloadSummary: "resource://gre/modules/DownloadList.sys.mjs",
});
Integration.downloads.defineESModuleGetter(
lazy,
"DownloadIntegration",
"resource://gre/modules/DownloadIntegration.sys.mjs"
);
/**
* This object is exposed directly to the consumers of this JavaScript module,
* and provides the only entry point to get references to back-end objects.
*/
export const Downloads = {
/**
* Work on downloads that were not started from a private browsing window.
*/
get PUBLIC() {
return "{Downloads.PUBLIC}";
},
/**
* Work on downloads that were started from a private browsing window.
*/
get PRIVATE() {
return "{Downloads.PRIVATE}";
},
/**
* Work on both Downloads.PRIVATE and Downloads.PUBLIC downloads.
*/
get ALL() {
return "{Downloads.ALL}";
},
/**
* Creates a new Download object.
*
* @param properties
* Provides the initial properties for the newly created download.
* This matches the serializable representation of a Download object.
* Some of the most common properties in this object include:
* {
* source: String containing the URI for the download source.
* Alternatively, may be an nsIURI, a DownloadSource object,
* or an object with the following properties:
* {
* url: String containing the URI for the download source.
* isPrivate: Indicates whether the download originated from a
* private window. If omitted, the download is public.
* referrerInfo: String or nsIReferrerInfo object represents the
* referrerInfo of the download source. Can be
* omitted or null for example when the download
* source is not HTTP.
* cookieJarSettings: The nsICookieJarSettings object represents
* the cookieJarSetting of the download source.
* Can be omitted or null if the download source
* is not from a document.
* },
* target: String containing the path of the target file.
* Alternatively, may be an nsIFile, a DownloadTarget object,
* or an object with the following properties:
* {
* path: String containing the path of the target file.
* },
* saver: String representing the class of the download operation.
* If omitted, defaults to "copy". Alternatively, may be the
* serializable representation of a DownloadSaver object.
* }
*
* @return {Promise}
* @resolves The newly created Download object.
* @rejects JavaScript exception.
*/
async createDownload(properties) {
return Download.fromSerializable(properties);
},
/**
* Downloads data from a remote network location to a local file.
*
* This download method does not provide user interface, or the ability to
* cancel or restart the download programmatically. For that, you should
* obtain a reference to a Download object using the createDownload function.
*
* Since the download cannot be restarted, any partially downloaded data will
* not be kept in case the download fails.
*
* @param source
* String containing the URI for the download source. Alternatively,
* may be an nsIURI or a DownloadSource object.
* @param target
* String containing the path of the target file. Alternatively, may
* be an nsIFile or a DownloadTarget object.
* @param options
* An optional object used to control the behavior of this function.
* You may pass an object with a subset of the following fields:
* {
* isPrivate: Indicates whether the download originated from a
* private window.
* }
*
* @return {Promise}
* @resolves When the download has finished successfully.
* @rejects JavaScript exception if the download failed.
*/
async fetch(source, target, options) {
const download = await this.createDownload({ source, target });
if (options?.isPrivate) {
download.source.isPrivate = options.isPrivate;
}
return download.start();
},
/**
* Retrieves the specified type of DownloadList object. There is one download
* list for each type, and this method always retrieves a reference to the
* same download list when called with the same argument.
*
* Calling this function may cause the list of public downloads to be reloaded
* from the previous session, if it wasn't loaded already.
*
* @param type
* This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
* Downloads added to the Downloads.PUBLIC and Downloads.PRIVATE lists
* are reflected in the Downloads.ALL list, and downloads added to the
* Downloads.ALL list are also added to either the Downloads.PUBLIC or
* the Downloads.PRIVATE list based on their properties.
*
* @return {Promise}
* @resolves The requested DownloadList or DownloadCombinedList object.
* @rejects JavaScript exception.
*/
async getList(type) {
if (!this._promiseListsInitialized) {
this._promiseListsInitialized = (async () => {
let publicList = new lazy.DownloadList();
let privateList = new lazy.DownloadList();
let combinedList = new lazy.DownloadCombinedList(
publicList,
privateList
);
try {
await lazy.DownloadIntegration.addListObservers(publicList, false);
await lazy.DownloadIntegration.addListObservers(privateList, true);
await lazy.DownloadIntegration.initializePublicDownloadList(
publicList
);
} catch (err) {
console.error(err);
}
let publicSummary = await this.getSummary(Downloads.PUBLIC);
let privateSummary = await this.getSummary(Downloads.PRIVATE);
let combinedSummary = await this.getSummary(Downloads.ALL);
await publicSummary.bindToList(publicList);
await privateSummary.bindToList(privateList);
await combinedSummary.bindToList(combinedList);
this._lists[Downloads.PUBLIC] = publicList;
this._lists[Downloads.PRIVATE] = privateList;
this._lists[Downloads.ALL] = combinedList;
})();
}
await this._promiseListsInitialized;
return this._lists[type];
},
/**
* Promise resolved when the initialization of the download lists has
* completed, or null if initialization has never been requested.
*/
_promiseListsInitialized: null,
/**
* After initialization, this object is populated with one key for each type
* of download list that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
* or Downloads.ALL). The values are the DownloadList objects.
*/
_lists: {},
/**
* Retrieves the specified type of DownloadSummary object. There is one
* download summary for each type, and this method always retrieves a
* reference to the same download summary when called with the same argument.
*
* Calling this function does not cause the list of public downloads to be
* reloaded from the previous session. The summary will behave as if no
* downloads are present until the getList method is called.
*
* @param type
* This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
*
* @return {Promise}
* @resolves The requested DownloadList or DownloadCombinedList object.
* @rejects JavaScript exception.
*/
async getSummary(type) {
if (
type != Downloads.PUBLIC &&
type != Downloads.PRIVATE &&
type != Downloads.ALL
) {
throw new Error("Invalid type argument.");
}
if (!(type in this._summaries)) {
this._summaries[type] = new lazy.DownloadSummary();
}
return this._summaries[type];
},
/**
* This object is populated by the getSummary method with one key for each
* type of object that can be returned (Downloads.PUBLIC, Downloads.PRIVATE,
* or Downloads.ALL). The values are the DownloadSummary objects.
*/
_summaries: {},
/**
* Returns the system downloads directory asynchronously.
* Mac OSX:
* User downloads directory
* XP/2K:
* My Documents/Downloads
* Vista and others:
* User downloads directory
* Linux:
* XDG user dir spec, with a fallback to Home/Downloads
* Android:
* standard downloads directory i.e. /sdcard
*
* @return {Promise}
* @resolves The downloads directory string path.
*/
getSystemDownloadsDirectory() {
return lazy.DownloadIntegration.getSystemDownloadsDirectory();
},
/**
* Returns the preferred downloads directory based on the user preferences
* in the current profile asynchronously.
*
* @return {Promise}
* @resolves The downloads directory string path.
*/
getPreferredDownloadsDirectory() {
return lazy.DownloadIntegration.getPreferredDownloadsDirectory();
},
/**
* Returns the temporary directory where downloads are placed before the
* final location is chosen, or while the document is opened temporarily
* with an external application. This may or may not be the system temporary
* directory, based on the platform asynchronously.
*
* @return {Promise}
* @resolves The downloads directory string path.
*/
getTemporaryDownloadsDirectory() {
return lazy.DownloadIntegration.getTemporaryDownloadsDirectory();
},
/**
* Constructor for a DownloadError object. When you catch an exception during
* a download, you can use this to verify if "ex instanceof Downloads.Error",
* before reading the exception properties with the error details.
*/
Error: DownloadError,
};