diff options
Diffstat (limited to 'browser/components/downloads/DownloadsViewUI.jsm')
-rw-r--r-- | browser/components/downloads/DownloadsViewUI.jsm | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/browser/components/downloads/DownloadsViewUI.jsm b/browser/components/downloads/DownloadsViewUI.jsm deleted file mode 100644 index 3b0e4c1b7..000000000 --- a/browser/components/downloads/DownloadsViewUI.jsm +++ /dev/null @@ -1,395 +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 module is imported by code that uses the "download.xml" binding, and - * provides prototypes for objects that handle input and display information. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "DownloadsViewUI", -]; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", - "resource://gre/modules/Downloads.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils", - "resource://gre/modules/DownloadUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon", - "resource:///modules/DownloadsCommon.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); - -this.DownloadsViewUI = { - /** - * Returns true if the given string is the name of a command that can be - * handled by the Downloads user interface, including standard commands. - */ - isCommandName(name) { - return name.startsWith("cmd_") || name.startsWith("downloadsCmd_"); - }, -}; - -/** - * 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. - */ -this.DownloadsViewUI.DownloadElementShell = function () {} - -this.DownloadsViewUI.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); - }, - - /** - * 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 = - this.element.ownerDocument.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("image", this.image); - this.element.setAttribute("state", - DownloadsCommon.stateOfDownload(this.download)); - - if (!this.download.succeeded && this.download.error && - this.download.error.becauseBlockedByReputationCheck) { - this.element.setAttribute("verdict", - this.download.error.reputationCheckVerdict); - } else { - this.element.removeAttribute("verdict"); - } - - // 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"); - } - } - - // When a block is confirmed, the removal of blocked data will not trigger a - // state change for the download, so this class must be updated here. - this.element.classList.toggle("temporary-block", - !!this.download.hasBlockedData); - - // 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"); - } - - if (this.download.stopped && this.download.canceled && - this.download.hasPartialData) { - this.element.setAttribute("progresspaused", "true"); - } else { - this.element.removeAttribute("progresspaused"); - } - - // Dispatch the ValueChange event for accessibility, if possible. - if (this._progressElement) { - let event = this.element.ownerDocument.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() { - return this.rawStatusTextAndTip; - }, - - /** - * Derived objects may call this to get the status text. - */ - get rawStatusTextAndTip() { - let s = DownloadsCommon.strings; - - let text = ""; - let tip = ""; - - if (!this.download.stopped) { - let totalBytes = 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 datails in the main area instead. - [text] = DownloadUtils.getDownloadStatusNoRate( - this.download.currentBytes, - totalBytes, - this.download.speed, - this.lastEstimatedSecondsLeft); - let newEstimatedSecondsLeft; - [tip, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus( - this.download.currentBytes, - totalBytes, - this.download.speed, - this.lastEstimatedSecondsLeft); - this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft; - } else if (this.download.canceled && this.download.hasPartialData) { - let totalBytes = this.download.hasProgress ? this.download.totalBytes - : -1; - let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes, - totalBytes); - - // 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 = this.rawBlockedTitleAndDetails[0]; - } 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 }; - }, - - /** - * Returns [title, [details1, details2]] for blocked downloads. - */ - get rawBlockedTitleAndDetails() { - let s = DownloadsCommon.strings; - if (!this.download.error || - !this.download.error.becauseBlockedByReputationCheck) { - return [null, null]; - } - switch (this.download.error.reputationCheckVerdict) { - case Downloads.Error.BLOCK_VERDICT_UNCOMMON: - return [s.blockedUncommon2, [s.unblockTypeUncommon2, s.unblockTip2]]; - case Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED: - return [s.blockedPotentiallyUnwanted, - [s.unblockTypePotentiallyUnwanted2, s.unblockTip2]]; - case Downloads.Error.BLOCK_VERDICT_MALWARE: - return [s.blockedMalware, [s.unblockTypeMalware, s.unblockTip2]]; - } - throw new Error("Unexpected reputationCheckVerdict: " + - this.download.error.reputationCheckVerdict); - // return anyway to avoid a JS strict warning. - return [null, null]; - }, - - /** - * Shows the appropriate unblock dialog based on the verdict, and executes the - * action selected by the user in the dialog, which may involve unblocking, - * opening or removing the file. - * - * @param window - * The window to which the dialog should be anchored. - * @param dialogType - * Can be "unblock", "chooseUnblock", or "chooseOpen". - */ - confirmUnblock(window, dialogType) { - DownloadsCommon.confirmUnblockDownload({ - verdict: this.download.error.reputationCheckVerdict, - window, - dialogType, - }).then(action => { - if (action == "open") { - return this.unblockAndOpenDownload(); - } else if (action == "unblock") { - return this.download.unblock(); - } else if (action == "confirmBlock") { - return this.download.confirmBlock(); - } - }).catch(Cu.reportError); - }, - - /** - * Unblocks the downloaded file and opens it. - * - * @return A promise that's resolved after the file has been opened. - */ - unblockAndOpenDownload() { - return this.download.unblock().then(() => this.downloadsCmd_open()); - }, - - /** - * Returns the name of the default command to use for the current state of the - * download, when there is a double click or another default interaction. If - * there is no default command for the current state, returns an empty string. - * The commands are implemented as functions on this object or derived ones. - */ - get currentDefaultCommandName() { - switch (DownloadsCommon.stateOfDownload(this.download)) { - case Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED: - return "downloadsCmd_cancel"; - case Ci.nsIDownloadManager.DOWNLOAD_FAILED: - case Ci.nsIDownloadManager.DOWNLOAD_CANCELED: - return "downloadsCmd_retry"; - case Ci.nsIDownloadManager.DOWNLOAD_PAUSED: - return "downloadsCmd_pauseResume"; - case Ci.nsIDownloadManager.DOWNLOAD_FINISHED: - return "downloadsCmd_open"; - case Ci.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL: - return "downloadsCmd_openReferrer"; - case Ci.nsIDownloadManager.DOWNLOAD_DIRTY: - return "downloadsCmd_showBlockedInfo"; - } - return ""; - }, - - /** - * Returns true if the specified command can be invoked on the current item. - * The commands are implemented as functions on this object or derived ones. - * - * @param aCommand - * Name of the command to check, for example "downloadsCmd_retry". - */ - isCommandEnabled(aCommand) { - switch (aCommand) { - case "downloadsCmd_retry": - return this.download.canceled || this.download.error; - case "downloadsCmd_pauseResume": - return this.download.hasPartialData && !this.download.error; - case "downloadsCmd_openReferrer": - return !!this.download.source.referrer; - case "downloadsCmd_confirmBlock": - case "downloadsCmd_chooseUnblock": - case "downloadsCmd_chooseOpen": - case "downloadsCmd_unblock": - case "downloadsCmd_unblockAndOpen": - return this.download.hasBlockedData; - } - return false; - }, - - downloadsCmd_cancel() { - // This is the correct way to avoid race conditions when cancelling. - this.download.cancel().catch(() => {}); - this.download.removePartialData().catch(Cu.reportError); - }, - - downloadsCmd_retry() { - // Errors when retrying are already reported as download failures. - this.download.start().catch(() => {}); - }, - - downloadsCmd_pauseResume() { - if (this.download.stopped) { - this.download.start(); - } else { - this.download.cancel(); - } - }, - - downloadsCmd_confirmBlock() { - this.download.confirmBlock().catch(Cu.reportError); - }, -}; |