diff options
Diffstat (limited to 'application/palemoon/components/downloads')
4 files changed, 46 insertions, 416 deletions
diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js index d756edf23..b85b64c1c 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js @@ -2,31 +2,10 @@ * 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/. */ -/** - * THE PLACES VIEW IMPLEMENTED IN THIS FILE HAS A VERY PARTICULAR USE CASE. - * IT IS HIGHLY RECOMMENDED NOT TO EXTEND IT FOR ANY OTHER USE CASES OR RELY - * ON IT AS AN API. - */ - -var Cu = Components.utils; -var Ci = Components.interfaces; -var Cc = Components.classes; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource://gre/modules/DownloadUtils.jsm"); -Cu.import("resource:///modules/DownloadsCommon.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", - "resource://gre/modules/PrivateBrowsingUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "DownloadsDataItem", + "resource:///modules/DownloadsCommon.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow", "resource:///modules/RecentWindow.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); const nsIDM = Ci.nsIDownloadManager; @@ -153,12 +132,12 @@ DownloadsHistoryDataItem.prototype = { * @param [optional] aHistoryDataItem * The history download, required if aSessionDataItem is not set. */ -function DownloadElementShell(aSessionDataItem, aHistoryDataItem) { - this._element = document.createElement("richlistitem"); - this._element._shell = this; +function HistoryDownloadElementShell(aSessionDataItem, aHistoryDataItem) { + this.element = document.createElement("richlistitem"); + this.element._shell = this; - this._element.classList.add("download"); - this._element.classList.add("download-state"); + this.element.classList.add("download"); + this.element.classList.add("download-state"); if (aSessionDataItem) { this.sessionDataItem = aSessionDataItem; @@ -168,11 +147,8 @@ function DownloadElementShell(aSessionDataItem, aHistoryDataItem) { } } -DownloadElementShell.prototype = { - /** - * The richlistitem for the download. - */ - get element() this._element, +HistoryDownloadElementShell.prototype = { + __proto__: DownloadElementShell.prototype, /** * Manages the "active" state of the shell. By default all the shells without @@ -183,19 +159,13 @@ DownloadElementShell.prototype = { ensureActive: function DES_ensureActive() { if (!this._active) { this._active = true; - this._element.setAttribute("active", true); + this.element.setAttribute("active", true); this._updateUI(); } }, get active() !!this._active, /** - * Download or HistoryDownload object to use for displaying information and - * for executing commands in the user interface. - */ - get download() this.dataItem.download, - - /** * DownloadsDataItem or DownloadsHistoryDataItem object to use for displaying * information and for executing commands in the user interface. */ @@ -236,16 +206,6 @@ DownloadElementShell.prototype = { return aValue; }, - // The progressmeter element for the download - get _progressElement() { - if (!("__progressElement" in this)) { - this.__progressElement = - document.getAnonymousElementByAttribute(this._element, "anonid", - "progressmeter"); - } - return this.__progressElement; - }, - _updateUI() { // There is nothing to do if the item has always been invisible. if (!this.active) { @@ -255,168 +215,20 @@ DownloadElementShell.prototype = { // Since the state changed, we may need to check the target file again. this._targetFileChecked = false; - 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._updateActiveStatusUI(); - }, - - // Updates the download state attribute (and by that hide/unhide the - // appropriate buttons and context menu items), the status text label, - // and the progress meter. - _updateActiveStatusUI() { - if (!this.active) - throw new Error("_updateActiveStatusUI called for an inactive item."); - - this._element.setAttribute("state", this.dataItem.state); - this._element.setAttribute("status", this.statusText); - - // We have update the progress meter only for session downloads. - if (!this._sessionDataItem) { - return; - } - - // Copied from updateProgress in downloads.js. - if (this.dataItem.starting) { - // Before the download starts, the progress meter has its initial value. - this._element.setAttribute("progressmode", "normal"); - this._element.setAttribute("progress", "0"); - } else if (this.dataItem.state == nsIDM.DOWNLOAD_SCANNING || - this.dataItem.percentComplete == -1) { - // We might not know the progress of a running download, and we don't know - // the remaining time during the malware scanning phase. - this._element.setAttribute("progressmode", "undetermined"); - } else { - // This is a running download of which we know the progress. - this._element.setAttribute("progressmode", "normal"); - this._element.setAttribute("progress", this.dataItem.percentComplete); - } - - // 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); - } - }, - - /** - * URI string for the file type icon displayed in the download element. - */ - get image() { - if (this.download.target.path) { - return "moz-icon://" + this.download.target.path + "?size=32"; - } - - // Old history downloads may not have a target path. - return "moz-icon://.unknown?size=32"; - }, - - // The status text for the download - /** - * The user-facing label for the download. This is normally the leaf name of - * 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.dataItem.download.source.referrer || - this.dataItem.download.source.url; - let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer); - return s.statusSeparator(this.displayName, displayHost); + this._updateState(); }, - - get extendedDisplayNameTip() { - let s = DownloadsCommon.strings; - let referrer = this.dataItem.download.source.referrer || - this.dataItem.download.source.url; - let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer); - return s.statusSeparator(this.displayName, fullHost); - }, - - get statusText() { - let s = DownloadsCommon.strings; - if (this.dataItem.inProgress) { - if (this.dataItem.paused) { - let transfer = - DownloadUtils.getTransferTotal(this.download.currentBytes, - this.dataItem.maxBytes); - - // We use the same XUL label to display both the state and the amount - // transferred, for example "Paused - 1.1 MB". - return s.statusSeparatorBeforeNumber(s.statePaused, transfer); - } - if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) { - let [status, newEstimatedSecondsLeft] = - DownloadUtils.getDownloadStatus(this.download.currentBytes, - this.dataItem.maxBytes, - this.download.speed, - this._lastEstimatedSecondsLeft || Infinity); - this._lastEstimatedSecondsLeft = newEstimatedSecondsLeft; - return status; - } - if (this.dataItem.starting) { - return s.stateStarting; - } - if (this.dataItem.state == nsIDM.DOWNLOAD_SCANNING) { - return s.stateScanning; - } - throw new Error("_getStatusText called with a bogus download state"); - } + get statusTextAndTip() { + let status = this.rawStatusTextAndTip; - // This is a not-in-progress or history download. - let stateLabel = ""; - switch (this.dataItem.state) { - case nsIDM.DOWNLOAD_FAILED: - stateLabel = s.stateFailed; - break; - case nsIDM.DOWNLOAD_CANCELED: - stateLabel = s.stateCanceled; - break; - case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: - stateLabel = s.stateBlockedParentalControls; - break; - case nsIDM.DOWNLOAD_BLOCKED_POLICY: - stateLabel = s.stateBlockedPolicy; - break; - case nsIDM.DOWNLOAD_DIRTY: - stateLabel = s.stateDirty; - break; - case nsIDM.DOWNLOAD_FINISHED: - // For completed downloads, show the file size (e.g. "1.5 MB") - if (this.dataItem.maxBytes !== undefined) { - let [size, unit] = - DownloadUtils.convertByteUnits(this.dataItem.maxBytes); - stateLabel = s.sizeWithUnits(size, unit); - break; - } - // Fallback to default unknown state. - default: - stateLabel = s.sizeUnknown; - break; + // The base object would show extended progress information in the tooltip, + // but we move this to the main view and never display a tooltip. + if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) { + status.text = status.tip; } + status.tip = ""; - let referrer = this.download.source.referrer || - this.download.source.url; - let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer); - - let date = new Date(this.dataItem.endTime); - let [displayDate, fullDate] = DownloadUtils.getReadableDates(date); - - // We use the same XUL label to display the state, the host name, and the - // end time. - let firstPart = s.statusSeparator(stateLabel, displayHost); - return s.statusSeparator(firstPart, displayDate); + return status; }, onStateChanged() { @@ -427,17 +239,20 @@ DownloadElementShell.prototype = { // scheme, this only works if we add one of the parameters explicitly // supported by the nsIMozIconURI interface. if (this.dataItem.state == nsIDM.DOWNLOAD_FINISHED) { - this._element.setAttribute("image", this.image + "&state=normal"); + this.element.setAttribute("image", this.image + "&state=normal"); } - if (this._element.selected) + // Update the user interface after switching states. + this.element.setAttribute("state", this.dataItem.state); + + if (this.element.selected) { goUpdateDownloadCommands(); else goUpdateCommand("downloadsCmd_clearDownloads"); }, onChanged() { - this._updateActiveStatusUI(); + this._updateProgress(); }, /* nsIController */ @@ -615,7 +430,7 @@ DownloadElementShell.prototype = { } // Update the commands only if the element is still selected. - if (this._element.selected) { + if (this.element.selected) { goUpdateDownloadCommands(); } }), @@ -861,7 +676,7 @@ DownloadsPlacesView.prototype = { historyDataItem = new DownloadsHistoryDataItem(aPlacesNode); historyDataItem.updateFromMetaData(metaData); } - let shell = new DownloadElementShell(aDataItem, historyDataItem); + let shell = new HistoryDownloadElementShell(aDataItem, historyDataItem); shell.element._placesNode = aPlacesNode; newOrUpdatedShell = shell; shellsForURI.add(shell); diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.xul b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.xul index 4e9bfd15b..d8e797ed1 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.xul +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.xul @@ -35,6 +35,8 @@ 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" src="chrome://global/content/contentAreaUtils.js"/> diff --git a/application/palemoon/components/downloads/content/downloads.js b/application/palemoon/components/downloads/content/downloads.js index a6c716b8c..edc9fc2ec 100644 --- a/application/palemoon/components/downloads/content/downloads.js +++ b/application/palemoon/components/downloads/content/downloads.js @@ -65,22 +65,6 @@ "use strict"; //////////////////////////////////////////////////////////////////////////////// -//// Globals - -XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils", - "resource://gre/modules/DownloadUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon", - "resource:///modules/DownloadsCommon.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", - "resource://gre/modules/PrivateBrowsingUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); - -//////////////////////////////////////////////////////////////////////////////// //// DownloadsPanel /** @@ -932,7 +916,7 @@ const DownloadsView = { _removeViewItem: function DV_removeViewItem(aDataItem) { DownloadsCommon.log("Removing a DownloadsViewItem from the downloads list."); - let element = this._visibleViewItems.get(aDataItem)._element; + let element = this._visibleViewItems.get(aDataItem).element; let previousSelectedIndex = this.richListBox.selectedIndex; this.richListBox.removeChild(element); if (previousSelectedIndex != -1) { @@ -1075,45 +1059,21 @@ XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView); */ function DownloadsViewItem(aDataItem, aElement) { - this._element = aElement; this.dataItem = aDataItem; - this.lastEstimatedSecondsLeft = Infinity; - - // Set the URI that represents the correct icon for the target file. As soon - // as bug 239948 comment 12 is handled, the "file" property will be always a - // file URL rather than a file name. At that point we should remove the "//" - // (double slash) from the icon URI specification (see test_moz_icon_uri.js). - this.image = "moz-icon://" + this.dataItem.download.target.path + "?size=32"; - - let s = DownloadsCommon.strings; - let [displayHost, fullHost] = - DownloadUtils.getURIHost(this.dataItem.download.source.referrer || - this.dataItem.download.source.url); - - let target = OS.Path.basename(this.dataItem.download.target.path); - let attributes = { - "type": "download", - "class": "download-state", - "state": this.dataItem.state, - "progress": this.dataItem.inProgress ? this.dataItem.percentComplete : 100, - "displayName": target, - "extendedDisplayName": s.statusSeparator(target, displayHost), - "extendedDisplayNameTip": s.statusSeparator(target, fullHost), - "image": this.image - }; - - for (let attributeName in attributes) { - this._element.setAttribute(attributeName, attributes[attributeName]); - } + this.element = aElement; + this.element._shell = this; - // Initialize more complex attributes. - this._updateProgress(); - this._updateStatusLine(); + this.element.setAttribute("type", "download"); + this.element.classList.add("download-state"); + + this._updateState(); this.verifyTargetExists(); } DownloadsViewItem.prototype = { + __proto__: DownloadElementShell.prototype, + /** * The DownloadDataItem associated with this view item. */ @@ -1124,19 +1084,6 @@ DownloadsViewItem.prototype = { */ _element: null, - /** - * The inner XUL element for the progress bar, or null if not available. - */ - _progressElement: null, - - ////////////////////////////////////////////////////////////////////////////// - //// Callback functions from DownloadsData - - /** - * Called when the download state might have changed. Sometimes the state of - * the download might be the same as before, if the data layer received - * multiple events for the same download. - */ onStateChanged() { // If a download just finished successfully, it means that the target file // now exists and we can extract its specific icon. To ensure that the icon @@ -1145,158 +1092,23 @@ DownloadsViewItem.prototype = { // scheme, this only works if we add one of the parameters explicitly // supported by the nsIMozIconURI interface. if (this.dataItem.state == Ci.nsIDownloadManager.DOWNLOAD_FINISHED) { - this._element.setAttribute("image", this.image + "&state=normal"); + this.element.setAttribute("image", this.image + "&state=normal"); // We assume the existence of the target of a download that just completed // successfully, without checking the condition in the background. If the // panel is already open, this will take effect immediately. If the panel // is opened later, a new background existence check will be performed. - this._element.setAttribute("exists", "true"); + this.element.setAttribute("exists", "true"); } // Update the user interface after switching states. - this._element.setAttribute("state", this.dataItem.state); + this.element.setAttribute("state", this.dataItem.state); }, - /** - * Called when the download progress has changed. - */ onChanged() { this._updateProgress(); - this._updateStatusLine(); }, - ////////////////////////////////////////////////////////////////////////////// - //// Functions for updating the user interface - - /** - * Updates the progress bar. - */ - _updateProgress: function DVI_updateProgress() { - if (this.dataItem.starting) { - // Before the download starts, the progress meter has its initial value. - this._element.setAttribute("progressmode", "normal"); - this._element.setAttribute("progress", "0"); - } else if (this.dataItem.state == Ci.nsIDownloadManager.DOWNLOAD_SCANNING || - this.dataItem.percentComplete == -1) { - // We might not know the progress of a running download, and we don't know - // the remaining time during the malware scanning phase. - this._element.setAttribute("progressmode", "undetermined"); - } else { - // This is a running download of which we know the progress. - this._element.setAttribute("progressmode", "normal"); - this._element.setAttribute("progress", this.dataItem.percentComplete); - } - - // Find the progress element as soon as the download binding is accessible. - if (!this._progressElement) { - this._progressElement = - document.getAnonymousElementByAttribute(this._element, "anonid", - "progressmeter"); - } - - // 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); - } - }, - - /** - * Updates the main status line, including bytes transferred, bytes total, - * download rate, and time remaining. - */ - _updateStatusLine: function DVI_updateStatusLine() { - const nsIDM = Ci.nsIDownloadManager; - - let status = ""; - let statusTip = ""; - - if (this.dataItem.paused) { - let transfer = DownloadUtils.getTransferTotal(this.dataItem.download.currentBytes, - this.dataItem.maxBytes); - - // We use the same XUL label to display both the state and the amount - // transferred, for example "Paused - 1.1 MB". - status = DownloadsCommon.strings.statusSeparatorBeforeNumber( - DownloadsCommon.strings.statePaused, - transfer); - } else if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) { - // We don't show the rate for each download in order to reduce clutter. - // The remaining time per download is likely enough information for the - // panel. - [status] = - DownloadUtils.getDownloadStatusNoRate(this.dataItem.download.currentBytes, - this.dataItem.maxBytes, - this.dataItem.download.speed, - this.lastEstimatedSecondsLeft); - - // We are, however, OK with displaying the rate in the tooltip. - let newEstimatedSecondsLeft; - [statusTip, newEstimatedSecondsLeft] = - DownloadUtils.getDownloadStatus(this.dataItem.download.currentBytes, - this.dataItem.maxBytes, - this.dataItem.download.speed, - this.lastEstimatedSecondsLeft); - this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft; - } else if (this.dataItem.starting) { - status = DownloadsCommon.strings.stateStarting; - } else if (this.dataItem.state == nsIDM.DOWNLOAD_SCANNING) { - status = DownloadsCommon.strings.stateScanning; - } else if (!this.dataItem.inProgress) { - let stateLabel = function () { - let s = DownloadsCommon.strings; - switch (this.dataItem.state) { - case nsIDM.DOWNLOAD_FAILED: return s.stateFailed; - case nsIDM.DOWNLOAD_CANCELED: return s.stateCanceled; - case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: return s.stateBlockedParentalControls; - case nsIDM.DOWNLOAD_BLOCKED_POLICY: return s.stateBlockedPolicy; - case nsIDM.DOWNLOAD_DIRTY: return s.stateDirty; - case nsIDM.DOWNLOAD_FINISHED: return this._fileSizeText; - } - return null; - }.apply(this); - - let [displayHost, fullHost] = - DownloadUtils.getURIHost(this.dataItem.download.source.referrer || - this.dataItem.download.source.url); - - let end = new Date(this.dataItem.endTime); - let [displayDate, fullDate] = DownloadUtils.getReadableDates(end); - - // We use the same XUL label to display the state, the host name, and the - // end time, for example "Canceled - 222.net - 11:15" or "1.1 MB - - // website2.com - Yesterday". We show the full host and the complete date - // in the tooltip. - let firstPart = DownloadsCommon.strings.statusSeparator(stateLabel, - displayHost); - status = DownloadsCommon.strings.statusSeparator(firstPart, displayDate); - statusTip = DownloadsCommon.strings.statusSeparator(fullHost, fullDate); - } - - this._element.setAttribute("status", status); - this._element.setAttribute("statusTip", statusTip || status); - }, - - /** - * Localized string representing the total size of completed downloads, for - * example "1.5 MB" or "Unknown size". - */ - get _fileSizeText() - { - // Display the file size, but show "Unknown" for negative sizes. - let fileSize = this.dataItem.maxBytes; - if (fileSize < 0) { - return DownloadsCommon.strings.sizeUnknown; - } - let [size, unit] = DownloadUtils.convertByteUnits(fileSize); - return DownloadsCommon.strings.sizeWithUnits(size, unit); - }, - - ////////////////////////////////////////////////////////////////////////////// - //// Functions called by the panel - /** * Starts checking whether the target file of a finished download is still * available on disk, and sets an attribute that controls how the item is @@ -1306,15 +1118,15 @@ DownloadsViewItem.prototype = { */ verifyTargetExists: function DVI_verifyTargetExists() { // We don't need to check if the download is not finished successfully. - if (!this.dataItem.download.succeeded) { + if (!this.download.succeeded) { return; } - OS.File.exists(this.dataItem.download.target.path).then(aExists => { + OS.File.exists(this.download.target.path).then(aExists => { if (aExists) { - this._element.setAttribute("exists", "true"); + this.element.setAttribute("exists", "true"); } else { - this._element.removeAttribute("exists"); + this.element.removeAttribute("exists"); } }).catch(Cu.reportError); }, diff --git a/application/palemoon/components/downloads/jar.mn b/application/palemoon/components/downloads/jar.mn index 8f8c66dd7..5a114ea71 100644 --- a/application/palemoon/components/downloads/jar.mn +++ b/application/palemoon/components/downloads/jar.mn @@ -7,6 +7,7 @@ browser.jar: content/browser/downloads/download.css (content/download.css) content/browser/downloads/downloads.css (content/downloads.css) * 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/indicator.js (content/indicator.js) content/browser/downloads/indicatorOverlay.xul (content/indicatorOverlay.xul) |