[PALEMOON] Bug 1129896 - Part 2 of 2 - Convert the shared front-end code to a JavaScript code module

This commit is contained in:
janekptacijarabaci 2018-07-29 13:12:21 +02:00 • committed by Roy Tam
commit 83ba13fdac
8 changed files with 94 additions and 64 deletions

View file

@ -7,7 +7,6 @@
<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/> <script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
<script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/> <script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
<script type="application/javascript" src="chrome://browser/content/browser.js"/> <script type="application/javascript" src="chrome://browser/content/browser.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloadsViewCommon.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/> <script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/> <script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/> <script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>

View file

@ -372,6 +372,17 @@ this.DownloadsCommon = {
return nsIDM.DOWNLOAD_NOTSTARTED; return nsIDM.DOWNLOAD_NOTSTARTED;
}, },
/**
* Helper function required because the Downloads Panel and the Downloads View
* don't share the controller yet.
*/
removeAndFinalizeDownload(download) {
Downloads.getList(Downloads.ALL)
.then(list => list.remove(download))
.then(() => download.finalize(true))
.catch(Cu.reportError);
},
/** /**
* Given an iterable collection of Download objects, generates and returns * Given an iterable collection of Download objects, generates and returns
* statistics about that collection. * statistics about that collection.
@ -383,7 +394,6 @@ this.DownloadsCommon = {
* *
* numActive : The total number of downloads. * numActive : The total number of downloads.
* numPaused : The total number of paused downloads. * numPaused : The total number of paused downloads.
* numScanning : The total number of downloads being scanned.
* numDownloading : The total number of downloads being downloaded. * numDownloading : The total number of downloads being downloaded.
* totalSize : The total size of all downloads once completed. * totalSize : The total size of all downloads once completed.
* totalTransferred: The total amount of transferred data for these * totalTransferred: The total amount of transferred data for these
@ -397,7 +407,6 @@ this.DownloadsCommon = {
let summary = { let summary = {
numActive: 0, numActive: 0,
numPaused: 0, numPaused: 0,
numScanning: 0,
numDownloading: 0, numDownloading: 0,
totalSize: 0, totalSize: 0,
totalTransferred: 0, totalTransferred: 0,
@ -677,7 +686,7 @@ DownloadsDataCtor.prototype = {
*/ */
get canRemoveFinished() get canRemoveFinished()
{ {
for (let download of this.oldDownloadStates.keys()) { for (let download of this.downloads) {
// Stopped, paused, and failed downloads with partial data are removed. // Stopped, paused, and failed downloads with partial data are removed.
if (download.stopped && !(download.canceled && download.hasPartialData)) { if (download.stopped && !(download.canceled && download.hasPartialData)) {
return true; return true;
@ -832,7 +841,7 @@ DownloadsDataCtor.prototype = {
//let loadedItemsArray = [dataItem //let loadedItemsArray = [dataItem
// for each (dataItem in this.dataItems) // for each (dataItem in this.dataItems)
// if (dataItem)]; // if (dataItem)];
let downloadsArray = [...this.oldDownloadStates.keys()]; let downloadsArray = [...this.downloads];
downloadsArray.sort((a, b) => b.startTime - a.startTime); downloadsArray.sort((a, b) => b.startTime - a.startTime);
downloadsArray.forEach(download => aView.onDownloadAdded(download, false)); downloadsArray.forEach(download => aView.onDownloadAdded(download, false));
@ -1659,7 +1668,7 @@ DownloadsIndicatorDataCtor.prototype = {
* to generate statistics about the downloads we care about - in this case, * to generate statistics about the downloads we care about - in this case,
* it's all active downloads. * it's all active downloads.
*/ */
_activeDownloads: function* () { * _activeDownloads() {
let downloads = this._isPrivate ? PrivateDownloadsData.downloads let downloads = this._isPrivate ? PrivateDownloadsData.downloads
: DownloadsData.downloads; : DownloadsData.downloads;
for (let download of downloads) { for (let download of downloads) {
@ -1865,7 +1874,7 @@ DownloadsSummaryData.prototype = {
* it's the downloads in this._downloads after the first few to exclude, * it's the downloads in this._downloads after the first few to exclude,
* which was set when constructing this DownloadsSummaryData instance. * which was set when constructing this DownloadsSummaryData instance.
*/ */
_downloadsForSummary: function* () { * _downloadsForSummary() {
if (this._downloads.length > 0) { if (this._downloads.length > 0) {
for (let i = this._numToExclude; i < this._downloads.length; ++i) { for (let i = this._numToExclude; i < this._downloads.length; ++i) {
yield this._downloads[i]; yield this._downloads[i];

View file

@ -3,16 +3,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * 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 * This module is imported by code that uses the "download.xml" binding, and
* provides prototypes for objects that handle input and display information. * 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"; "use strict";
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; this.EXPORTED_SYMBOLS = [
"DownloadsViewUI",
];
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -20,22 +21,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
"resource://gre/modules/DownloadUtils.jsm"); "resource://gre/modules/DownloadUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon", XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
"resource:///modules/DownloadsCommon.jsm"); "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", XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm"); "resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"); this.DownloadsViewUI = {};
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 * A download element shell is responsible for handling the commands and the
@ -50,9 +39,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
* HistoryDownloadElementShell and the DownloadsViewItem for the panel. The * HistoryDownloadElementShell and the DownloadsViewItem for the panel. The
* history view may use a HistoryDownload object in place of a Download object. * history view may use a HistoryDownload object in place of a Download object.
*/ */
function DownloadElementShell() {} this.DownloadsViewUI.DownloadElementShell = function () {}
DownloadElementShell.prototype = { this.DownloadsViewUI.DownloadElementShell.prototype = {
/** /**
* The richlistitem for the download, initialized by the derived object. * The richlistitem for the download, initialized by the derived object.
*/ */
@ -112,8 +101,10 @@ DownloadElementShell.prototype = {
get _progressElement() { get _progressElement() {
if (!this.__progressElement) { if (!this.__progressElement) {
// If the element is not available now, we will try again the next time. // If the element is not available now, we will try again the next time.
this.__progressElement = document.getAnonymousElementByAttribute( this.__progressElement =
this.element, "anonid", "progressmeter"); this.element.ownerDocument.getAnonymousElementByAttribute(
this.element, "anonid",
"progressmeter");
} }
return this.__progressElement; return this.__progressElement;
}, },
@ -161,7 +152,7 @@ DownloadElementShell.prototype = {
// Dispatch the ValueChange event for accessibility, if possible. // Dispatch the ValueChange event for accessibility, if possible.
if (this._progressElement) { if (this._progressElement) {
let event = document.createEvent("Events"); let event = this.element.ownerDocument.createEvent("Events");
event.initEvent("ValueChange", true, true); event.initEvent("ValueChange", true, true);
this._progressElement.dispatchEvent(event); this._progressElement.dispatchEvent(event);
} }
@ -191,26 +182,28 @@ DownloadElementShell.prototype = {
let tip = ""; let tip = "";
if (!this.download.stopped) { if (!this.download.stopped) {
let total = this.download.hasProgress ? this.download.totalBytes : -1; let totalBytes = this.download.hasProgress ? this.download.totalBytes
: -1;
// By default, extended status information including the individual // By default, extended status information including the individual
// download rate is displayed in the tooltip. The history view overrides // download rate is displayed in the tooltip. The history view overrides
// the getter and displays the detials in the main area instead. // the getter and displays the datails in the main area instead.
[text] = DownloadUtils.getDownloadStatusNoRate( [text] = DownloadUtils.getDownloadStatusNoRate(
this.download.currentBytes, this.download.currentBytes,
total, totalBytes,
this.download.speed, this.download.speed,
this.lastEstimatedSecondsLeft); this.lastEstimatedSecondsLeft);
let newEstimatedSecondsLeft; let newEstimatedSecondsLeft;
[tip, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus( [tip, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus(
this.download.currentBytes, this.download.currentBytes,
total, totalBytes,
this.download.speed, this.download.speed,
this.lastEstimatedSecondsLeft); this.lastEstimatedSecondsLeft);
this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft; this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft;
} else if (this.download.canceled && this.download.hasPartialData) { } else if (this.download.canceled && this.download.hasPartialData) {
let total = this.download.hasProgress ? this.download.totalBytes : -1; let totalBytes = this.download.hasProgress ? this.download.totalBytes
: -1;
let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes, let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes,
total); totalBytes);
// We use the same XUL label to display both the state and the amount // We use the same XUL label to display both the state and the amount
// transferred, for example "Paused - 1.1 MB". // transferred, for example "Paused - 1.1 MB".
@ -224,8 +217,8 @@ DownloadElementShell.prototype = {
if (this.download.succeeded) { if (this.download.succeeded) {
// For completed downloads, show the file size (e.g. "1.5 MB"). // For completed downloads, show the file size (e.g. "1.5 MB").
if (this.download.target.size !== undefined) { if (this.download.target.size !== undefined) {
let [size, unit] = DownloadUtils.convertByteUnits( let [size, unit] =
this.download.target.size); DownloadUtils.convertByteUnits(this.download.target.size);
stateLabel = s.sizeWithUnits(size, unit); stateLabel = s.sizeWithUnits(size, unit);
} else { } else {
// History downloads may not have a size defined. // History downloads may not have a size defined.

View file

@ -2,8 +2,30 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * 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", XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm"); "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; 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 * Represents a download from the browser history. It implements part of the
* interface of the Download object. * interface of the Download object.
* *
* @param url * @param aPlacesNode
* URI string for the download source. * The Places node from which the history download should be initialized.
* @param endTime
* Timestamp with the end time for the download, used if there is no
* additional metadata available.
*/ */
function HistoryDownload(aPlacesNode) { function HistoryDownload(aPlacesNode) {
// TODO (bug 829201): history downloads should get the referrer from Places. // 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 * This method mimicks the "start" method of session downloads, and is called
* when the user retries a history download. * 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() { 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 browserWin = RecentWindow.getMostRecentBrowserWindow();
let initiatingDoc = browserWin ? browserWin.document : document; let initiatingDoc = browserWin ? browserWin.document : document;
@ -150,7 +172,7 @@ HistoryDownload.prototype = {
* displayed data for a single download view element. * displayed data for a single download view element.
* *
* The shell may contain a session download, a history download, or both. When * 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. * priority and its information is displayed.
* *
* On construction, a new richlistitem is created, and can be accessed through * On construction, a new richlistitem is created, and can be accessed through
@ -181,7 +203,7 @@ function HistoryDownloadElementShell(aSessionDownload, aHistoryDownload) {
} }
HistoryDownloadElementShell.prototype = { HistoryDownloadElementShell.prototype = {
__proto__: DownloadElementShell.prototype, __proto__: DownloadsViewUI.DownloadElementShell.prototype,
/** /**
* Manages the "active" state of the shell. By default all the shells without * Manages the "active" state of the shell. By default all the shells without
@ -339,10 +361,7 @@ HistoryDownloadElementShell.prototype = {
} }
case "cmd_delete": { case "cmd_delete": {
if (this._sessionDownload) { if (this._sessionDownload) {
Downloads.getList(Downloads.ALL) DownloadsCommon.removeAndFinalizeDownload(this.download);
.then(list => list.remove(this.download))
.then(() => this.download.finalize(true))
.catch(Cu.reportError);
} }
if (this._historyDownload) { if (this._historyDownload) {
let uri = NetUtil.newURI(this.download.source.url); let uri = NetUtil.newURI(this.download.source.url);
@ -402,8 +421,8 @@ HistoryDownloadElementShell.prototype = {
} }
return ""; return "";
} }
let command = getDefaultCommandForState( let state = DownloadsCommon.stateOfDownload(this.download);
DownloadsCommon.stateOfDownload(this.download)); let command = getDefaultCommandForState(state);
if (command && this.isCommandEnabled(command)) if (command && this.isCommandEnabled(command))
this.doCommand(command); this.doCommand(command);
}, },
@ -452,7 +471,7 @@ HistoryDownloadElementShell.prototype = {
/** /**
* A Downloads Places View is a places view designed to show a places query * 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 * As we don't use the places controller, some methods implemented by other
* places views are not implemented by this view. * places views are not implemented by this view.

View file

@ -34,8 +34,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 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" <script type="application/javascript"
src="chrome://browser/content/downloads/allDownloadsViewOverlay.js"/> src="chrome://browser/content/downloads/allDownloadsViewOverlay.js"/>
<script type="application/javascript" <script type="application/javascript"

View file

@ -4,6 +4,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * 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. * Handles the Downloads panel user interface for each browser window.
* *
@ -1066,7 +1081,7 @@ function DownloadsViewItem(download, aElement) {
} }
DownloadsViewItem.prototype = { DownloadsViewItem.prototype = {
__proto__: DownloadElementShell.prototype, __proto__: DownloadsViewUI.DownloadElementShell.prototype,
/** /**
* The XUL element corresponding to the associated richlistbox item. * The XUL element corresponding to the associated richlistbox item.
@ -1253,10 +1268,7 @@ DownloadsViewItemController.prototype = {
commands: { commands: {
cmd_delete: function DVIC_cmd_delete() cmd_delete: function DVIC_cmd_delete()
{ {
Downloads.getList(Downloads.ALL) DownloadsCommon.removeAndFinalizeDownload(this.download);
.then(list => list.remove(this.download))
.then(() => this.download.finalize(true))
.catch(Cu.reportError);
PlacesUtils.bhistory.removePage( PlacesUtils.bhistory.removePage(
NetUtil.newURI(this.download.source.url)); NetUtil.newURI(this.download.source.url));
}, },

View file

@ -7,7 +7,6 @@ browser.jar:
content/browser/downloads/download.css (content/download.css) content/browser/downloads/download.css (content/download.css)
content/browser/downloads/downloads.css (content/downloads.css) content/browser/downloads/downloads.css (content/downloads.css)
* content/browser/downloads/downloads.js (content/downloads.js) * content/browser/downloads/downloads.js (content/downloads.js)
content/browser/downloads/downloadsViewCommon.js (content/downloadsViewCommon.js)
* content/browser/downloads/downloadsOverlay.xul (content/downloadsOverlay.xul) * content/browser/downloads/downloadsOverlay.xul (content/downloadsOverlay.xul)
content/browser/downloads/indicator.js (content/indicator.js) content/browser/downloads/indicator.js (content/indicator.js)
content/browser/downloads/indicatorOverlay.xul (content/indicatorOverlay.xul) content/browser/downloads/indicatorOverlay.xul (content/indicatorOverlay.xul)

View file

@ -15,6 +15,7 @@ EXTRA_COMPONENTS += [
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
'DownloadsLogger.jsm', 'DownloadsLogger.jsm',
'DownloadsTaskbar.jsm', 'DownloadsTaskbar.jsm',
'DownloadsViewUI.jsm',
] ]
EXTRA_PP_JS_MODULES += [ EXTRA_PP_JS_MODULES += [