mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
291
mobile/android/modules/DownloadNotifications.jsm
Normal file
291
mobile/android/modules/DownloadNotifications.jsm
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DownloadNotifications"];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Snackbars.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry", "resource://gre/modules/UITelemetry.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ParentalControls",
|
||||
"@mozilla.org/parental-controls-service;1", "nsIParentalControlsService");
|
||||
|
||||
var Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.i.bind(null, "DownloadNotifications");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "strings",
|
||||
() => Services.strings.createBundle("chrome://browser/locale/browser.properties"));
|
||||
|
||||
Object.defineProperty(this, "window",
|
||||
{ get: () => Services.wm.getMostRecentWindow("navigator:browser") });
|
||||
|
||||
const kButtons = {
|
||||
PAUSE: new DownloadNotificationButton("pause",
|
||||
"drawable://pause",
|
||||
"alertDownloadsPause"),
|
||||
RESUME: new DownloadNotificationButton("resume",
|
||||
"drawable://play",
|
||||
"alertDownloadsResume"),
|
||||
CANCEL: new DownloadNotificationButton("cancel",
|
||||
"drawable://close",
|
||||
"alertDownloadsCancel")
|
||||
};
|
||||
|
||||
var notifications = new Map();
|
||||
|
||||
var DownloadNotifications = {
|
||||
_notificationKey: "downloads",
|
||||
|
||||
init: function () {
|
||||
Downloads.getList(Downloads.ALL)
|
||||
.then(list => list.addView(this))
|
||||
.then(() => this._viewAdded = true, Cu.reportError);
|
||||
|
||||
// All click, cancel, and button presses will be handled by this handler as part of the Notifications callback API.
|
||||
Notifications.registerHandler(this._notificationKey, this);
|
||||
},
|
||||
|
||||
onDownloadAdded: function (download) {
|
||||
// Don't create notifications for pre-existing succeeded downloads.
|
||||
// We still add notifications for canceled downloads in case the
|
||||
// user decides to retry the download.
|
||||
if (download.succeeded && !this._viewAdded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ParentalControls.isAllowed(ParentalControls.DOWNLOAD)) {
|
||||
download.cancel().catch(Cu.reportError);
|
||||
download.removePartialData().catch(Cu.reportError);
|
||||
Snackbars.show(strings.GetStringFromName("downloads.disabledInGuest"), Snackbars.LENGTH_LONG);
|
||||
return;
|
||||
}
|
||||
|
||||
let notification = new DownloadNotification(download);
|
||||
notifications.set(download, notification);
|
||||
notification.showOrUpdate();
|
||||
|
||||
// If this is a new download, show a snackbar as well.
|
||||
if (this._viewAdded) {
|
||||
Snackbars.show(strings.GetStringFromName("alertDownloadsToast"), Snackbars.LENGTH_LONG);
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadChanged: function (download) {
|
||||
let notification = notifications.get(download);
|
||||
|
||||
if (download.succeeded) {
|
||||
let file = new FileUtils.File(download.target.path);
|
||||
|
||||
Snackbars.show(strings.formatStringFromName("alertDownloadSucceeded", [file.leafName], 1), Snackbars.LENGTH_LONG, {
|
||||
action: {
|
||||
label: strings.GetStringFromName("helperapps.open"),
|
||||
callback: () => {
|
||||
UITelemetry.addEvent("launch.1", "toast", null, "downloads");
|
||||
try {
|
||||
file.launch();
|
||||
} catch (ex) {
|
||||
this.showInAboutDownloads(download);
|
||||
}
|
||||
if (notification) {
|
||||
notification.hide();
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
if (notification) {
|
||||
notification.showOrUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadRemoved: function (download) {
|
||||
let notification = notifications.get(download);
|
||||
if (!notification) {
|
||||
Cu.reportError("Download doesn't have a notification.");
|
||||
return;
|
||||
}
|
||||
|
||||
notification.hide();
|
||||
notifications.delete(download);
|
||||
},
|
||||
|
||||
_findDownloadForCookie: function(cookie) {
|
||||
return Downloads.getList(Downloads.ALL)
|
||||
.then(list => list.getAll())
|
||||
.then((downloads) => {
|
||||
for (let download of downloads) {
|
||||
let cookie2 = getCookieFromDownload(download);
|
||||
if (cookie2 === cookie) {
|
||||
return download;
|
||||
}
|
||||
}
|
||||
|
||||
throw "Couldn't find download for " + cookie;
|
||||
});
|
||||
},
|
||||
|
||||
onCancel: function(cookie) {
|
||||
// TODO: I'm not sure what we do here...
|
||||
},
|
||||
|
||||
showInAboutDownloads: function (download) {
|
||||
let hash = "#" + window.encodeURIComponent(download.target.path);
|
||||
|
||||
// Force using string equality to find a tab
|
||||
window.BrowserApp.selectOrAddTab("about:downloads" + hash, null, { startsWith: true });
|
||||
},
|
||||
|
||||
onClick: function(cookie) {
|
||||
this._findDownloadForCookie(cookie).then((download) => {
|
||||
if (download.succeeded) {
|
||||
// We don't call Download.launch(), because there's (currently) no way to
|
||||
// tell if the file was actually launched or not, and we want to show
|
||||
// about:downloads if the launch failed.
|
||||
let file = new FileUtils.File(download.target.path);
|
||||
try {
|
||||
file.launch();
|
||||
} catch (ex) {
|
||||
this.showInAboutDownloads(download);
|
||||
}
|
||||
} else {
|
||||
ConfirmCancelPrompt.show(download);
|
||||
}
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
onButtonClick: function(button, cookie) {
|
||||
this._findDownloadForCookie(cookie).then((download) => {
|
||||
if (button === kButtons.PAUSE.buttonId) {
|
||||
download.cancel().catch(Cu.reportError);
|
||||
} else if (button === kButtons.RESUME.buttonId) {
|
||||
download.start().catch(Cu.reportError);
|
||||
} else if (button === kButtons.CANCEL.buttonId) {
|
||||
download.cancel().catch(Cu.reportError);
|
||||
download.removePartialData().catch(Cu.reportError);
|
||||
}
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
};
|
||||
|
||||
function getCookieFromDownload(download) {
|
||||
return download.target.path +
|
||||
download.source.url +
|
||||
download.startTime;
|
||||
}
|
||||
|
||||
function DownloadNotification(download) {
|
||||
this.download = download;
|
||||
this._fileName = OS.Path.basename(download.target.path);
|
||||
|
||||
this.id = null;
|
||||
}
|
||||
|
||||
DownloadNotification.prototype = {
|
||||
_updateFromDownload: function () {
|
||||
this._downloading = !this.download.stopped;
|
||||
this._paused = this.download.canceled && this.download.hasPartialData;
|
||||
this._succeeded = this.download.succeeded;
|
||||
|
||||
this._show = this._downloading || this._paused || this._succeeded;
|
||||
},
|
||||
|
||||
get options() {
|
||||
if (!this._show) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let options = {
|
||||
icon: "drawable://alert_download",
|
||||
cookie: getCookieFromDownload(this.download),
|
||||
handlerKey: DownloadNotifications._notificationKey
|
||||
};
|
||||
|
||||
if (this._downloading) {
|
||||
options.icon = "drawable://alert_download_animation";
|
||||
if (this.download.currentBytes == 0) {
|
||||
this._updateOptionsForStatic(options, "alertDownloadsStart2");
|
||||
} else {
|
||||
let buttons = this.download.hasPartialData ? [kButtons.PAUSE, kButtons.CANCEL] :
|
||||
[kButtons.CANCEL]
|
||||
this._updateOptionsForOngoing(options, buttons);
|
||||
}
|
||||
} else if (this._paused) {
|
||||
this._updateOptionsForOngoing(options, [kButtons.RESUME, kButtons.CANCEL]);
|
||||
} else if (this._succeeded) {
|
||||
options.persistent = false;
|
||||
this._updateOptionsForStatic(options, "alertDownloadsDone2");
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
_updateOptionsForStatic : function (options, titleName) {
|
||||
options.title = strings.GetStringFromName(titleName);
|
||||
options.message = this._fileName;
|
||||
},
|
||||
|
||||
_updateOptionsForOngoing: function (options, buttons) {
|
||||
options.title = this._fileName;
|
||||
options.message = this.download.progress + "%";
|
||||
options.buttons = buttons;
|
||||
options.ongoing = true;
|
||||
options.progress = this.download.progress;
|
||||
options.persistent = true;
|
||||
},
|
||||
|
||||
showOrUpdate: function () {
|
||||
this._updateFromDownload();
|
||||
|
||||
if (this._show) {
|
||||
if (!this.id) {
|
||||
this.id = Notifications.create(this.options);
|
||||
} else if (!this.options.ongoing) {
|
||||
// We need to explictly cancel ongoing notifications,
|
||||
// since updating them to be non-ongoing doesn't seem
|
||||
// to work. See bug 1130834.
|
||||
Notifications.cancel(this.id);
|
||||
this.id = Notifications.create(this.options);
|
||||
} else {
|
||||
Notifications.update(this.id, this.options);
|
||||
}
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
if (this.id) {
|
||||
Notifications.cancel(this.id);
|
||||
this.id = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var ConfirmCancelPrompt = {
|
||||
show: function (download) {
|
||||
// Open a prompt that offers a choice to cancel the download
|
||||
let title = strings.GetStringFromName("downloadCancelPromptTitle1");
|
||||
let message = strings.GetStringFromName("downloadCancelPromptMessage1");
|
||||
|
||||
if (Services.prompt.confirm(null, title, message)) {
|
||||
download.cancel().catch(Cu.reportError);
|
||||
download.removePartialData().catch(Cu.reportError);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function DownloadNotificationButton(buttonId, iconUrl, titleStringName, onClicked) {
|
||||
this.buttonId = buttonId;
|
||||
this.title = strings.GetStringFromName(titleStringName);
|
||||
this.icon = iconUrl;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue