diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-29 11:13:36 +0200 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-29 11:13:36 +0200 |
commit | 462332eee018e24d88255c708fa8acb67a717673 (patch) | |
tree | 84b95527aa96af5cc58239a7478d464fad5705b0 /application/palemoon/components/downloads/content | |
parent | df852eca4ed7707d16bc41b83d246fb07d1af3ee (diff) | |
download | UXP-462332eee018e24d88255c708fa8acb67a717673.tar UXP-462332eee018e24d88255c708fa8acb67a717673.tar.gz UXP-462332eee018e24d88255c708fa8acb67a717673.tar.lz UXP-462332eee018e24d88255c708fa8acb67a717673.tar.xz UXP-462332eee018e24d88255c708fa8acb67a717673.zip |
[PALEMOON] Bug 1117141 - Part 1 of 2 - Bypass all the DownloadsDataItem properties
Diffstat (limited to 'application/palemoon/components/downloads/content')
3 files changed, 208 insertions, 180 deletions
diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js index b85b64c1c..59da61c91 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js @@ -24,69 +24,48 @@ const DOWNLOAD_VIEW_SUPPORTED_COMMANDS = * * @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. */ -function HistoryDownload(url) { +function HistoryDownload(aPlacesNode) { // TODO (bug 829201): history downloads should get the referrer from Places. - this.source = { url }; + this.source = { url: aPlacesNode.uri }; this.target = { path: undefined, size: undefined }; -} - -HistoryDownload.prototype = { - /** - * This method mimicks the "start" method of session downloads, and is called - * when the user retries a history download. - */ - 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; - - // Do not suggest a file name if we don't know the original target. - let leafName = this.target.path ? OS.Path.basename(this.target.path) : null; - DownloadURL(this.source.url, leafName, initiatingDoc); - - return Promise.resolve(); - }, -}; - -/** - * Represents a download from the browser history. It uses the same interface as - * the DownloadsDataItem object. - * - * @param aPlacesNode - * The Places node for the history download. - */ -function DownloadsHistoryDataItem(aPlacesNode) { - this.download = new HistoryDownload(aPlacesNode.uri); // In case this download cannot obtain its end time from the Places metadata, // use the time from the Places node, that is the start time of the download. this.endTime = aPlacesNode.time / 1000; } -DownloadsHistoryDataItem.prototype = { - __proto__: DownloadsDataItem.prototype, - +HistoryDownload.prototype = { /** * Pushes information from Places metadata into this object. */ updateFromMetaData(aPlacesMetaData) { try { - let targetFile = Cc["@mozilla.org/network/protocol;1?name=file"] - .getService(Ci.nsIFileProtocolHandler) - .getFileFromURLSpec(aPlacesMetaData.targetFileURISpec); - this.download.target.path = targetFile.path; + this.target.path = Cc["@mozilla.org/network/protocol;1?name=file"] + .getService(Ci.nsIFileProtocolHandler) + .getFileFromURLSpec(aPlacesMetaData. + targetFileURISpec).path; } catch (ex) { - this.download.target.path = undefined; + this.target.path = undefined; } try { let metaData = JSON.parse(aPlacesMetaData.jsonDetails); - this.state = metaData.state; + this.succeeded = metaData.state == nsIDM.DOWNLOAD_FINISHED; + this.error = metaData.state == nsIDM.DOWNLOAD_FAILED + ? { message: "History download failed." } + : metaData.state == nsIDM.DOWNLOAD_BLOCKED_PARENTAL + ? { becauseBlockedByParentalControls: true } + : metaData.state == nsIDM.DOWNLOAD_DIRTY + ? { becauseBlockedByReputationCheck: true } + : null; + this.canceled = metaData.state == nsIDM.DOWNLOAD_CANCELED || + metaData.state == nsIDM.DOWNLOAD_PAUSED; this.endTime = metaData.endTime; - this.download.target.size = metaData.fileSize; + this.target.size = metaData.fileSize; } catch (ex) { // Metadata might be missing from a download that has started but hasn't // stopped already. Normally, this state is overridden with the one from @@ -98,21 +77,72 @@ DownloadsHistoryDataItem.prototype = { // On the other hand, if the download is missing the target file // annotation as well, it is just a very old one, and we can assume it // succeeded. - this.state = this.download.target.path ? nsIDM.DOWNLOAD_FAILED - : nsIDM.DOWNLOAD_FINISHED; - this.download.target.size = undefined; + this.succeeded = !this.target.path; + this.error = this.target.path ? { message: "Unstarted download." } : null; + this.canceled = false; + this.target.size = -1; } // This property is currently used to get the size of downloads, but will be // replaced by download.target.size when available for session downloads. - this.maxBytes = this.download.target.size; + this.totalBytes = this.target.size; + this.currentBytes = this.target.size; + }, + + /** + * History downloads are never in progress. + */ + stopped: true, - // This is not displayed for history downloads, that are never in progress. - this.percentComplete = 100; + /** + * No percentage indication is shown for history downloads. + */ + hasProgress: false, + + /** + * History downloads cannot be restarted using their partial data, even if + * they are indicated as paused in their Places metadata. The only way is to + * use the information from a persisted session download, that will be shown + * instead of the history download. In case this session download is not + * available, we show the history download as canceled, not paused. + */ + hasPartialData: false, + + /** + * This method mimicks the "start" method of session downloads, and is called + * when the user retries a history download. + */ + 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; + + // Do not suggest a file name if we don't know the original target. + let leafName = this.target.path ? OS.Path.basename(this.target.path) : null; + DownloadURL(this.source.url, leafName, initiatingDoc); + + return Promise.resolve(); }, }; /** + * Represents a download from the browser history. It uses the same interface as + * the DownloadsDataItem object. + * + * @param aPlacesNode + * The Places node for the history download. + */ +function DownloadsHistoryDataItem(aPlacesNode) { + this.download = new HistoryDownload(aPlacesNode); +} + +DownloadsHistoryDataItem.prototype = { + __proto__: DownloadsDataItem.prototype, +}; + +/** * A download element shell is responsible for handling the commands and the * displayed data for a single download view element. * @@ -223,7 +253,7 @@ HistoryDownloadElementShell.prototype = { // 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) { + if (!this.download.stopped) { status.text = status.tip; } status.tip = ""; @@ -232,18 +262,9 @@ HistoryDownloadElementShell.prototype = { }, 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 - // is reloaded, we must change the URI used by the XUL image element, for - // example by adding a query parameter. Since this URI has a "moz-icon" - // 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"); - } - - // Update the user interface after switching states. - this.element.setAttribute("state", this.dataItem.state); + this.element.setAttribute("image", this.image); + this.element.setAttribute("state", + DownloadsCommon.stateOfDownload(this.download)); if (this.element.selected) { goUpdateDownloadCommands(); @@ -275,12 +296,14 @@ HistoryDownloadElementShell.prototype = { // If the target file information is not yet fetched, // temporarily assume that the file is in place. - return this.dataItem.state == nsIDM.DOWNLOAD_FINISHED; + return this.download.succeeded; case "downloadsCmd_show": // TODO: Bug 827010 - Handle part-file asynchronously. - if (this._sessionDataItem && - this.dataItem.partFile && this.dataItem.partFile.exists()) { - return true; + if (this._sessionDataItem && this.download.target.partFilePath) { + let partFile = new FileUtils.File(this.download.target.partFilePath); + if (partFile.exists()) { + return true; + } } if (this._targetFileChecked) { @@ -289,17 +312,16 @@ HistoryDownloadElementShell.prototype = { // If the target file information is not yet fetched, // temporarily assume that the file is in place. - return this.dataItem.state == nsIDM.DOWNLOAD_FINISHED; + return this.download.succeeded; case "downloadsCmd_pauseResume": - return this._sessionDataItem && this.dataItem.inProgress && - this.dataItem.download.hasPartialData; + return this.download.hasPartialData && !this.download.error; case "downloadsCmd_retry": - return this.dataItem.canRetry; + return this.download.canceled || this.download.error; case "downloadsCmd_openReferrer": return !!this.download.source.referrer; case "cmd_delete": - // The behavior in this case is somewhat unexpected, so we disallow that. - return !this.dataItem.inProgress; + // We don't want in-progress downloads to be removed accidentally. + return this.download.stopped; case "downloadsCmd_cancel": return !!this._sessionDataItem; } @@ -393,7 +415,8 @@ HistoryDownloadElementShell.prototype = { } return ""; } - let command = getDefaultCommandForState(this.dataItem.state); + let command = getDefaultCommandForState( + DownloadsCommon.stateOfDownload(this.download)); if (command && this.isCommandEnabled(command)) this.doCommand(command); }, @@ -621,8 +644,9 @@ DownloadsPlacesView.prototype = { _addDownloadData: function DPV_addDownloadData(aDataItem, aPlacesNode, aNewest = false, aDocumentFragment = null) { + let sessionDownload = aDataItem && aDataItem.download; let downloadURI = aPlacesNode ? aPlacesNode.uri - : aDataItem.download.source.url; + : sessionDownload.source.url; let shellsForURI = this._downloadElementsShellsForURI.get(downloadURI); if (!shellsForURI) { shellsForURI = new Set(); @@ -674,7 +698,7 @@ DownloadsPlacesView.prototype = { if (aPlacesNode) { let metaData = this._getCachedPlacesMetaDataFor(aPlacesNode.uri); historyDataItem = new DownloadsHistoryDataItem(aPlacesNode); - historyDataItem.updateFromMetaData(metaData); + historyDataItem.download.updateFromMetaData(metaData); } let shell = new HistoryDownloadElementShell(aDataItem, historyDataItem); shell.element._placesNode = aPlacesNode; @@ -782,8 +806,9 @@ DownloadsPlacesView.prototype = { _removeSessionDownloadFromView: function DPV__removeSessionDownloadFromView(aDataItem) { + let download = aDataItem.download; let shells = this._downloadElementsShellsForURI - .get(aDataItem.download.source.url); + .get(download.source.url); if (shells.size == 0) throw new Error("Should have had at leaat one shell for this uri"); @@ -799,7 +824,7 @@ DownloadsPlacesView.prototype = { this._removeElement(shell.element); shells.delete(shell); if (shells.size == 0) - this._downloadElementsShellsForURI.delete(aDataItem.download.source.url); + this._downloadElementsShellsForURI.delete(download.source.url); } else { // We have one download element shell containing both a session download @@ -809,7 +834,7 @@ DownloadsPlacesView.prototype = { // read the latest metadata before removing the session download. let url = shell.historyDataItem.download.source.url; let metaData = this._getPlacesMetaDataFor(url); - shell.historyDataItem.updateFromMetaData(metaData); + shell.historyDataItem.download.updateFromMetaData(metaData); shell.sessionDataItem = null; // Move it below the session-download items; if (this._lastSessionDownloadElement == shell.element) { @@ -1142,7 +1167,9 @@ DownloadsPlacesView.prototype = { // Because history downloads are always removable and are listed after the // session downloads, check from bottom to top. for (let elt = this._richlistbox.lastChild; elt; elt = elt.previousSibling) { - if (!elt._shell.dataItem.inProgress) { + // Stopped, paused, and failed downloads with partial data are removed. + let download = elt._shell.download; + if (download.stopped && !(download.canceled && download.hasPartialData)) { return true; } } @@ -1244,12 +1271,13 @@ DownloadsPlacesView.prototype = { // Set the state attribute so that only the appropriate items are displayed. let contextMenu = document.getElementById("downloadsContextMenu"); - let state = element._shell.dataItem.state; - contextMenu.setAttribute("state", state); + let download = element._shell.download; + contextMenu.setAttribute("state", + DownloadsCommon.stateOfDownload(download)); - if (state == nsIDM.DOWNLOAD_DOWNLOADING) { - // The resumable property of a download may change at any time, so - // ensure we update the related command now. + if (!download.stopped) { + // The hasPartialData property of a download may change at any time after + // it has started, so ensure we update the related command now. goUpdateCommand("downloadsCmd_pauseResume"); } return true; diff --git a/application/palemoon/components/downloads/content/downloads.js b/application/palemoon/components/downloads/content/downloads.js index edc9fc2ec..05233e76d 100644 --- a/application/palemoon/components/downloads/content/downloads.js +++ b/application/palemoon/components/downloads/content/downloads.js @@ -1025,9 +1025,10 @@ const DownloadsView = { return; } - let localFile = DownloadsView.controllerForElement(element) - .dataItem.localFile; - if (!localFile.exists()) { + // We must check for existence synchronously because this is a DOM event. + let file = new FileUtils.File(DownloadsView.controllerForElement(element) + .download.target.path); + if (!file.exists()) { return; } @@ -1085,24 +1086,17 @@ DownloadsViewItem.prototype = { _element: null, 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 - // is reloaded, we must change the URI used by the XUL image element, for - // example by adding a query parameter. Since this URI has a "moz-icon" - // 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); + this.element.setAttribute("state", + DownloadsCommon.stateOfDownload(this.download)); + if (this.download.succeeded) { // 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"); } - - // Update the user interface after switching states. - this.element.setAttribute("state", this.dataItem.state); }, onChanged() { @@ -1252,24 +1246,38 @@ DownloadsViewItemController.prototype = { */ dataItem: null, + get download() this.dataItem.download, + isCommandEnabled: function DVIC_isCommandEnabled(aCommand) { switch (aCommand) { case "downloadsCmd_open": { - return this.dataItem.download.succeeded && - this.dataItem.localFile.exists(); + if (!this.download.succeeded) { + return false; + } + + let file = new FileUtils.File(this.download.target.path); + return file.exists(); } case "downloadsCmd_show": { - return this.dataItem.localFile.exists() || - this.dataItem.partFile.exists(); + let file = new FileUtils.File(this.download.target.path); + if (file.exists()) { + return true; + } + + if (!this.download.target.partFilePath) { + return false; + } + + let partFile = new FileUtils.File(this.download.target.partFilePath); + return partFile.exists(); } case "downloadsCmd_pauseResume": - return this.dataItem.inProgress && - this.dataItem.download.hasPartialData; + return this.download.hasPartialData && !this.download.error; case "downloadsCmd_retry": - return this.dataItem.canRetry; + return this.download.canceled || this.download.error; case "downloadsCmd_openReferrer": - return !!this.dataItem.download.source.referrer; + return !!this.download.source.referrer; case "cmd_delete": case "downloadsCmd_cancel": case "downloadsCmd_copyLocation": @@ -1298,22 +1306,23 @@ DownloadsViewItemController.prototype = { cmd_delete: function DVIC_cmd_delete() { Downloads.getList(Downloads.ALL) - .then(list => list.remove(this.dataItem.download)) - .then(() => this.dataItem.download.finalize(true)) + .then(list => list.remove(this.download)) + .then(() => this.download.finalize(true)) .catch(Cu.reportError); PlacesUtils.bhistory.removePage( - NetUtil.newURI(this.dataItem.download.source.url)); + NetUtil.newURI(this.download.source.url)); }, downloadsCmd_cancel: function DVIC_downloadsCmd_cancel() { - this.dataItem.download.cancel().catch(() => {}); - this.dataItem.download.removePartialData().catch(Cu.reportError); + this.download.cancel().catch(() => {}); + this.download.removePartialData().catch(Cu.reportError); }, downloadsCmd_open: function DVIC_downloadsCmd_open() { - this.dataItem.download.launch().catch(Cu.reportError); + this.download.launch().catch(Cu.reportError); + // We explicitly close the panel here to give the user the feedback that // their click has been received, and we're handling the action. // Otherwise, we'd have to wait for the file-type handler to execute @@ -1324,7 +1333,8 @@ DownloadsViewItemController.prototype = { downloadsCmd_show: function DVIC_downloadsCmd_show() { - DownloadsCommon.showDownloadedFile(this.dataItem.localFile); + let file = new FileUtils.File(this.download.target.path); + DownloadsCommon.showDownloadedFile(file); // We explicitly close the panel here to give the user the feedback that // their click has been received, and we're handling the action. @@ -1336,28 +1346,28 @@ DownloadsViewItemController.prototype = { downloadsCmd_pauseResume: function DVIC_downloadsCmd_pauseResume() { - if (this.dataItem.download.stopped) { - this.dataItem.download.start(); + if (this.download.stopped) { + this.download.start(); } else { - this.dataItem.download.cancel(); + this.download.cancel(); } }, downloadsCmd_retry: function DVIC_downloadsCmd_retry() { - this.dataItem.download.start().catch(() => {}); + this.download.start().catch(() => {}); }, downloadsCmd_openReferrer: function DVIC_downloadsCmd_openReferrer() { - openURL(this.dataItem.download.source.referrer); + openURL(this.download.source.referrer); }, downloadsCmd_copyLocation: function DVIC_downloadsCmd_copyLocation() { let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); - clipboard.copyString(this.dataItem.download.source.url, document); + clipboard.copyString(this.download.source.url, document); }, downloadsCmd_doDefault: function DVIC_downloadsCmd_doDefault() @@ -1366,7 +1376,7 @@ DownloadsViewItemController.prototype = { // Determine the default command for the current item. let defaultCommand = function () { - switch (this.dataItem.state) { + switch (DownloadsCommon.stateOfDownload(this.download)) { case nsIDM.DOWNLOAD_NOTSTARTED: return "downloadsCmd_cancel"; case nsIDM.DOWNLOAD_FINISHED: return "downloadsCmd_open"; case nsIDM.DOWNLOAD_FAILED: return "downloadsCmd_retry"; diff --git a/application/palemoon/components/downloads/content/downloadsViewCommon.js b/application/palemoon/components/downloads/content/downloadsViewCommon.js index 7b763ed07..7d18eadc6 100644 --- a/application/palemoon/components/downloads/content/downloadsViewCommon.js +++ b/application/palemoon/components/downloads/content/downloadsViewCommon.js @@ -72,12 +72,19 @@ DownloadElementShell.prototype = { * 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"; + if (!this.download.target.path) { + // Old history downloads may not have a target path. + return "moz-icon://.unknown?size=32"; } - // 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" : ""); }, /** @@ -127,11 +134,12 @@ DownloadElementShell.prototype = { * update in order to improve performance. */ _updateState() { - this.element.setAttribute("state", this.dataItem.state); 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; @@ -144,19 +152,12 @@ DownloadElementShell.prototype = { * namely the progress bar and the status line. */ _updateProgress() { - if (this.dataItem.starting) { - // Before the download starts, the progress meter has its initial value. + // The progress bar is only displayed for in-progress downloads. + if (this.download.hasProgress) { 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"); + this.element.setAttribute("progress", this.download.progress); } else { - // This is a running download of which we know the progress. - this.element.setAttribute("progressmode", "normal"); - this.element.setAttribute("progress", this.dataItem.percentComplete); + this.element.setAttribute("progressmode", "undetermined"); } // Dispatch the ValueChange event for accessibility, if possible. @@ -190,71 +191,60 @@ DownloadElementShell.prototype = { let text = ""; let tip = ""; - 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". - text = s.statusSeparatorBeforeNumber(s.statePaused, transfer); - } else if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) { + if (!this.download.stopped) { + let maxBytes = DownloadsCommon.maxBytesOfDownload(this.download); // 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, - this.dataItem.maxBytes, + maxBytes, this.download.speed, this.lastEstimatedSecondsLeft); let newEstimatedSecondsLeft; [tip, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus( this.download.currentBytes, - this.dataItem.maxBytes, + maxBytes, this.download.speed, this.lastEstimatedSecondsLeft); this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft; - } else if (this.dataItem.starting) { + } else if (this.download.canceled && this.download.hasPartialData) { + let maxBytes = DownloadsCommon.maxBytesOfDownload(this.download); + let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes, + maxBytes); + + // 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 if (this.dataItem.state == nsIDM.DOWNLOAD_SCANNING) { - text = s.stateScanning; } else { 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 && - this.dataItem.maxBytes >= 0) { - let [size, unit] = - DownloadUtils.convertByteUnits(this.dataItem.maxBytes); - stateLabel = s.sizeWithUnits(size, unit); - break; - } - // Fallback to default unknown state. - default: + + if (this.download.succeeded) { + // For completed downloads, show the file size (e.g. "1.5 MB") + let maxBytes = DownloadsCommon.maxBytesOfDownload(this.download); + if (maxBytes >= 0) { + let [size, unit] = DownloadUtils.convertByteUnits(maxBytes); + stateLabel = s.sizeWithUnits(size, unit); + } else { stateLabel = s.sizeUnknown; - break; + } + } 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 referrer = this.download.source.referrer || this.download.source.url; let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer); - let date = new Date(this.dataItem.endTime); + let date = new Date(this.download.endTime); let [displayDate, fullDate] = DownloadUtils.getReadableDates(date); let firstPart = s.statusSeparator(stateLabel, displayHost); |