mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-07 07:47:30 +09:00
[PALEMOON] Bug 1129896 - Part 2 of 2 - Convert the shared front-end code to a JavaScript code module
This commit is contained in:
parent
b5c90dfea0
commit
83ba13fdac
8 changed files with 94 additions and 64 deletions
|
|
@ -2,8 +2,30 @@
|
|||
* 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/. */
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
|
||||
"resource://gre/modules/DownloadUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
|
||||
"resource:///modules/DownloadsCommon.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsViewUI",
|
||||
"resource:///modules/DownloadsViewUI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
const nsIDM = Ci.nsIDownloadManager;
|
||||
|
||||
|
|
@ -20,11 +42,8 @@ const DOWNLOAD_VIEW_SUPPORTED_COMMANDS =
|
|||
* Represents a download from the browser history. It implements part of the
|
||||
* interface of the Download object.
|
||||
*
|
||||
* @param url
|
||||
* URI string for the download source.
|
||||
* @param endTime
|
||||
* Timestamp with the end time for the download, used if there is no
|
||||
* additional metadata available.
|
||||
* @param aPlacesNode
|
||||
* The Places node from which the history download should be initialized.
|
||||
*/
|
||||
function HistoryDownload(aPlacesNode) {
|
||||
// TODO (bug 829201): history downloads should get the referrer from Places.
|
||||
|
|
@ -115,11 +134,14 @@ HistoryDownload.prototype = {
|
|||
/**
|
||||
* This method mimicks the "start" method of session downloads, and is called
|
||||
* when the user retries a history download.
|
||||
*
|
||||
* At present, we always ask the user for a new target path when retrying a
|
||||
* history download. In the future we may consider reusing the known target
|
||||
* path if the folder still exists and the file name is not already used,
|
||||
* except when the user preferences indicate that the target path should be
|
||||
* requested every time a new download is started.
|
||||
*/
|
||||
start() {
|
||||
// In future we may try to download into the same original target uri, when
|
||||
// we have it. Though that requires verifying the path is still valid and
|
||||
// may surprise the user if he wants to be requested every time.
|
||||
let browserWin = RecentWindow.getMostRecentBrowserWindow();
|
||||
let initiatingDoc = browserWin ? browserWin.document : document;
|
||||
|
||||
|
|
@ -150,7 +172,7 @@ HistoryDownload.prototype = {
|
|||
* displayed data for a single download view element.
|
||||
*
|
||||
* The shell may contain a session download, a history download, or both. When
|
||||
* both a history and a current download are present, the current download gets
|
||||
* both a history and a session download are present, the session download gets
|
||||
* priority and its information is displayed.
|
||||
*
|
||||
* On construction, a new richlistitem is created, and can be accessed through
|
||||
|
|
@ -181,7 +203,7 @@ function HistoryDownloadElementShell(aSessionDownload, aHistoryDownload) {
|
|||
}
|
||||
|
||||
HistoryDownloadElementShell.prototype = {
|
||||
__proto__: DownloadElementShell.prototype,
|
||||
__proto__: DownloadsViewUI.DownloadElementShell.prototype,
|
||||
|
||||
/**
|
||||
* Manages the "active" state of the shell. By default all the shells without
|
||||
|
|
@ -339,10 +361,7 @@ HistoryDownloadElementShell.prototype = {
|
|||
}
|
||||
case "cmd_delete": {
|
||||
if (this._sessionDownload) {
|
||||
Downloads.getList(Downloads.ALL)
|
||||
.then(list => list.remove(this.download))
|
||||
.then(() => this.download.finalize(true))
|
||||
.catch(Cu.reportError);
|
||||
DownloadsCommon.removeAndFinalizeDownload(this.download);
|
||||
}
|
||||
if (this._historyDownload) {
|
||||
let uri = NetUtil.newURI(this.download.source.url);
|
||||
|
|
@ -402,8 +421,8 @@ HistoryDownloadElementShell.prototype = {
|
|||
}
|
||||
return "";
|
||||
}
|
||||
let command = getDefaultCommandForState(
|
||||
DownloadsCommon.stateOfDownload(this.download));
|
||||
let state = DownloadsCommon.stateOfDownload(this.download);
|
||||
let command = getDefaultCommandForState(state);
|
||||
if (command && this.isCommandEnabled(command))
|
||||
this.doCommand(command);
|
||||
},
|
||||
|
|
@ -452,7 +471,7 @@ HistoryDownloadElementShell.prototype = {
|
|||
|
||||
/**
|
||||
* A Downloads Places View is a places view designed to show a places query
|
||||
* for history downloads alongside the current "session"-downloads.
|
||||
* for history downloads alongside the session downloads.
|
||||
*
|
||||
* As we don't use the places controller, some methods implemented by other
|
||||
* places views are not implemented by this view.
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/downloads/downloadsViewCommon.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/downloads/allDownloadsViewOverlay.js"/>
|
||||
<script type="application/javascript"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,21 @@
|
|||
* 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/. */
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
|
||||
"resource:///modules/DownloadsCommon.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsViewUI",
|
||||
"resource:///modules/DownloadsViewUI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* Handles the Downloads panel user interface for each browser window.
|
||||
*
|
||||
|
|
@ -1066,7 +1081,7 @@ function DownloadsViewItem(download, aElement) {
|
|||
}
|
||||
|
||||
DownloadsViewItem.prototype = {
|
||||
__proto__: DownloadElementShell.prototype,
|
||||
__proto__: DownloadsViewUI.DownloadElementShell.prototype,
|
||||
|
||||
/**
|
||||
* The XUL element corresponding to the associated richlistbox item.
|
||||
|
|
@ -1253,10 +1268,7 @@ DownloadsViewItemController.prototype = {
|
|||
commands: {
|
||||
cmd_delete: function DVIC_cmd_delete()
|
||||
{
|
||||
Downloads.getList(Downloads.ALL)
|
||||
.then(list => list.remove(this.download))
|
||||
.then(() => this.download.finalize(true))
|
||||
.catch(Cu.reportError);
|
||||
DownloadsCommon.removeAndFinalizeDownload(this.download);
|
||||
PlacesUtils.bhistory.removePage(
|
||||
NetUtil.newURI(this.download.source.url));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,257 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/*
|
||||
* This file is loaded in every window that uses the "download.xml" binding, and
|
||||
* provides prototypes for objects that handle input and display information.
|
||||
*
|
||||
* This file lazily imports common JavaScript modules in the window scope. Most
|
||||
* of these modules are generally already declared before this file is included.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
|
||||
"resource://gre/modules/DownloadUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
|
||||
"resource:///modules/DownloadsCommon.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
/**
|
||||
* A download element shell is responsible for handling the commands and the
|
||||
* displayed data for a single element that uses the "download.xml" binding.
|
||||
*
|
||||
* The information to display is obtained through the associated Download object
|
||||
* from the JavaScript API for downloads, and commands are executed using a
|
||||
* combination of Download methods and DownloadsCommon.jsm helper functions.
|
||||
*
|
||||
* Specialized versions of this shell must be defined, and they are required to
|
||||
* implement the "download" property or getter. Currently these objects are the
|
||||
* HistoryDownloadElementShell and the DownloadsViewItem for the panel. The
|
||||
* history view may use a HistoryDownload object in place of a Download object.
|
||||
*/
|
||||
function DownloadElementShell() {}
|
||||
|
||||
DownloadElementShell.prototype = {
|
||||
/**
|
||||
* The richlistitem for the download, initialized by the derived object.
|
||||
*/
|
||||
element: null,
|
||||
|
||||
/**
|
||||
* URI string for the file type icon displayed in the download element.
|
||||
*/
|
||||
get image() {
|
||||
if (!this.download.target.path) {
|
||||
// Old history downloads may not have a target path.
|
||||
return "moz-icon://.unknown?size=32";
|
||||
}
|
||||
|
||||
// When a download that was previously in progress finishes successfully, it
|
||||
// means that the target file now exists and we can extract its specific
|
||||
// icon, for example from a Windows executable. To ensure that the icon is
|
||||
// reloaded, however, we must change the URI used by the XUL image element,
|
||||
// for example by adding a query parameter. This only works if we add one of
|
||||
// the parameters explicitly supported by the nsIMozIconURI interface.
|
||||
return "moz-icon://" + this.download.target.path + "?size=32" +
|
||||
(this.download.succeeded ? "&state=normal" : "");
|
||||
},
|
||||
|
||||
/**
|
||||
* The user-facing label for the download. This is normally the leaf name of
|
||||
* the download target file. In case this is a very old history download for
|
||||
* which the target file is unknown, the download source URI is displayed.
|
||||
*/
|
||||
get displayName() {
|
||||
if (!this.download.target.path) {
|
||||
return this.download.source.url;
|
||||
}
|
||||
return OS.Path.basename(this.download.target.path);
|
||||
},
|
||||
|
||||
get extendedDisplayName() {
|
||||
let s = DownloadsCommon.strings;
|
||||
let referrer = this.download.source.referrer ||
|
||||
this.download.source.url;
|
||||
let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
|
||||
return s.statusSeparator(this.displayName, displayHost);
|
||||
},
|
||||
|
||||
get extendedDisplayNameTip() {
|
||||
let s = DownloadsCommon.strings;
|
||||
let referrer = this.download.source.referrer ||
|
||||
this.download.source.url;
|
||||
let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
|
||||
return s.statusSeparator(this.displayName, fullHost);
|
||||
},
|
||||
|
||||
/**
|
||||
* The progress element for the download, or undefined in case the XBL binding
|
||||
* has not been applied yet.
|
||||
*/
|
||||
get _progressElement() {
|
||||
if (!this.__progressElement) {
|
||||
// If the element is not available now, we will try again the next time.
|
||||
this.__progressElement = document.getAnonymousElementByAttribute(
|
||||
this.element, "anonid", "progressmeter");
|
||||
}
|
||||
return this.__progressElement;
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes a major state change in the user interface, then proceeds with
|
||||
* the normal progress update. This function is not called for every progress
|
||||
* update in order to improve performance.
|
||||
*/
|
||||
_updateState() {
|
||||
this.element.setAttribute("displayName", this.displayName);
|
||||
this.element.setAttribute("extendedDisplayName", this.extendedDisplayName);
|
||||
this.element.setAttribute("extendedDisplayNameTip", this.extendedDisplayNameTip);
|
||||
this.element.setAttribute("image", this.image);
|
||||
this.element.setAttribute("state",
|
||||
DownloadsCommon.stateOfDownload(this.download));
|
||||
|
||||
// Since state changed, reset the time left estimation.
|
||||
this.lastEstimatedSecondsLeft = Infinity;
|
||||
|
||||
this._updateProgress();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the elements that change regularly for in-progress downloads,
|
||||
* namely the progress bar and the status line.
|
||||
*/
|
||||
_updateProgress() {
|
||||
if (this.download.succeeded) {
|
||||
// We only need to add or remove this attribute for succeeded downloads.
|
||||
if (this.download.target.exists) {
|
||||
this.element.setAttribute("exists", "true");
|
||||
} else {
|
||||
this.element.removeAttribute("exists");
|
||||
}
|
||||
}
|
||||
|
||||
// The progress bar is only displayed for in-progress downloads.
|
||||
if (this.download.hasProgress) {
|
||||
this.element.setAttribute("progressmode", "normal");
|
||||
this.element.setAttribute("progress", this.download.progress);
|
||||
} else {
|
||||
this.element.setAttribute("progressmode", "undetermined");
|
||||
}
|
||||
|
||||
// Dispatch the ValueChange event for accessibility, if possible.
|
||||
if (this._progressElement) {
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("ValueChange", true, true);
|
||||
this._progressElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
let status = this.statusTextAndTip;
|
||||
this.element.setAttribute("status", status.text);
|
||||
this.element.setAttribute("statusTip", status.tip);
|
||||
},
|
||||
|
||||
lastEstimatedSecondsLeft: Infinity,
|
||||
|
||||
/**
|
||||
* Returns the text for the status line and the associated tooltip. These are
|
||||
* returned by a single property because they are computed together. The
|
||||
* result may be overridden by derived objects.
|
||||
*/
|
||||
get statusTextAndTip() this.rawStatusTextAndTip,
|
||||
|
||||
/**
|
||||
* Derived objects may call this to get the status text.
|
||||
*/
|
||||
get rawStatusTextAndTip() {
|
||||
const nsIDM = Ci.nsIDownloadManager;
|
||||
let s = DownloadsCommon.strings;
|
||||
|
||||
let text = "";
|
||||
let tip = "";
|
||||
|
||||
if (!this.download.stopped) {
|
||||
let total = this.download.hasProgress ? this.download.totalBytes : -1;
|
||||
// By default, extended status information including the individual
|
||||
// download rate is displayed in the tooltip. The history view overrides
|
||||
// the getter and displays the detials in the main area instead.
|
||||
[text] = DownloadUtils.getDownloadStatusNoRate(
|
||||
this.download.currentBytes,
|
||||
total,
|
||||
this.download.speed,
|
||||
this.lastEstimatedSecondsLeft);
|
||||
let newEstimatedSecondsLeft;
|
||||
[tip, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus(
|
||||
this.download.currentBytes,
|
||||
total,
|
||||
this.download.speed,
|
||||
this.lastEstimatedSecondsLeft);
|
||||
this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft;
|
||||
} else if (this.download.canceled && this.download.hasPartialData) {
|
||||
let total = this.download.hasProgress ? this.download.totalBytes : -1;
|
||||
let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes,
|
||||
total);
|
||||
|
||||
// We use the same XUL label to display both the state and the amount
|
||||
// transferred, for example "Paused - 1.1 MB".
|
||||
text = s.statusSeparatorBeforeNumber(s.statePaused, transfer);
|
||||
} else if (!this.download.succeeded && !this.download.canceled &&
|
||||
!this.download.error) {
|
||||
text = s.stateStarting;
|
||||
} else {
|
||||
let stateLabel;
|
||||
|
||||
if (this.download.succeeded) {
|
||||
// For completed downloads, show the file size (e.g. "1.5 MB").
|
||||
if (this.download.target.size !== undefined) {
|
||||
let [size, unit] = DownloadUtils.convertByteUnits(
|
||||
this.download.target.size);
|
||||
stateLabel = s.sizeWithUnits(size, unit);
|
||||
} else {
|
||||
// History downloads may not have a size defined.
|
||||
stateLabel = s.sizeUnknown;
|
||||
}
|
||||
} else if (this.download.canceled) {
|
||||
stateLabel = s.stateCanceled;
|
||||
} else if (this.download.error.becauseBlockedByParentalControls) {
|
||||
stateLabel = s.stateBlockedParentalControls;
|
||||
} else if (this.download.error.becauseBlockedByReputationCheck) {
|
||||
stateLabel = s.stateDirty;
|
||||
} else {
|
||||
stateLabel = s.stateFailed;
|
||||
}
|
||||
|
||||
let referrer = this.download.source.referrer || this.download.source.url;
|
||||
let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
|
||||
|
||||
let date = new Date(this.download.endTime);
|
||||
let [displayDate, fullDate] = DownloadUtils.getReadableDates(date);
|
||||
|
||||
let firstPart = s.statusSeparator(stateLabel, displayHost);
|
||||
text = s.statusSeparator(firstPart, displayDate);
|
||||
tip = s.statusSeparator(fullHost, fullDate);
|
||||
}
|
||||
|
||||
return { text, tip: tip || text };
|
||||
},
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue