From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../components/downloads/content/aboutDownloads.js | 414 +++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 comm/mail/components/downloads/content/aboutDownloads.js (limited to 'comm/mail/components/downloads/content/aboutDownloads.js') diff --git a/comm/mail/components/downloads/content/aboutDownloads.js b/comm/mail/components/downloads/content/aboutDownloads.js new file mode 100644 index 0000000000..6cd7e2973c --- /dev/null +++ b/comm/mail/components/downloads/content/aboutDownloads.js @@ -0,0 +1,414 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ +/* 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/. */ + +/* globals goUpdateCommand */ + +"use strict"; + +ChromeUtils.defineESModuleGetters(this, { + Downloads: "resource://gre/modules/Downloads.sys.mjs", + DownloadUtils: "resource://gre/modules/DownloadUtils.sys.mjs", +}); + +window.addEventListener("load", event => { + DownloadsView.init(); +}); + +var DownloadsView = { + init() { + window.controllers.insertControllerAt(0, this); + this.listElement = document.getElementById("msgDownloadsRichListBox"); + + this.items = new Map(); + + Downloads.getList(Downloads.ALL) + .then(list => list.addView(this)) + .catch(console.error); + + window.addEventListener("unload", aEvent => { + Downloads.getList(Downloads.ALL) + .then(list => list.removeView(this)) + .catch(console.error); + window.controllers.removeController(this); + }); + }, + + insertOrMoveItem(aItem) { + let compare = (a, b) => { + // active downloads always before stopped downloads + if (a.stopped != b.stopped) { + return b.stopped ? -1 : 1; + } + // most recent downloads first + return b.startTime - a.startTime; + }; + + let at = this.listElement.firstElementChild; + while (at && compare(aItem.download, at.download) > 0) { + at = at.nextElementSibling; + } + this.listElement.insertBefore(aItem.element, at); + }, + + onDownloadAdded(aDownload) { + let isPurgedFromDisk = download => { + if (!download.succeeded) { + return false; + } + let targetFile = Cc["@mozilla.org/file/local;1"].createInstance( + Ci.nsIFile + ); + targetFile.initWithPath(download.target.path); + return !targetFile.exists(); + }; + if (isPurgedFromDisk(aDownload)) { + Downloads.getList(Downloads.ALL).then(list => list.remove(aDownload)); + return; + } + + let item = new DownloadItem(aDownload); + this.items.set(aDownload, item); + this.insertOrMoveItem(item); + }, + + onDownloadChanged(aDownload) { + let item = this.items.get(aDownload); + if (!item) { + console.error("No DownloadItem found for download"); + return; + } + + if (item.stateChanged) { + this.insertOrMoveItem(item); + } + + item.onDownloadChanged(); + }, + + onDownloadRemoved(aDownload) { + let item = this.items.get(aDownload); + if (!item) { + console.error("No DownloadItem found for download"); + return; + } + + this.items.delete(aDownload); + this.listElement.removeChild(item.element); + }, + + onDownloadContextMenu() { + this.updateCommands(); + }, + + clearDownloads() { + Downloads.getList(Downloads.ALL) + .then(list => list.removeFinished()) + .catch(console.error); + }, + + searchDownloads() { + let searchString = document.getElementById("searchBox").value.toLowerCase(); + for (let i = 0; i < this.listElement.itemCount; i++) { + let downloadElem = this.listElement.getItemAtIndex(i); + downloadElem.collapsed = !downloadElem.downloadItem.fileName + .toLowerCase() + .includes(searchString); + } + this.listElement.clearSelection(); + }, + + supportsCommand(aCommand) { + return ( + this.commands.includes(aCommand) || + DownloadItem.prototype.supportsCommand(aCommand) + ); + }, + + isCommandEnabled(aCommand) { + switch (aCommand) { + case "msgDownloadsCmd_clearDownloads": + case "msgDownloadsCmd_searchDownloads": + // We could disable these if there are no downloads in the list, but + // updating the commands when new items become available is tricky. + return true; + } + + let element = this.listElement.selectedItem; + if (element) { + return element.downloadItem.isCommandEnabled(aCommand); + } + + return false; + }, + + doCommand(aCommand) { + switch (aCommand) { + case "msgDownloadsCmd_clearDownloads": + this.clearDownloads(); + return; + case "msgDownloadsCmd_searchDownloads": + this.searchDownloads(); + return; + } + + if (this.listElement.selectedCount == 0) { + return; + } + + for (let element of this.listElement.selectedItems) { + element.downloadItem.doCommand(aCommand); + } + }, + + onEvent() {}, + + updateCommands() { + this.commands.forEach(goUpdateCommand); + DownloadItem.prototype.commands.forEach(goUpdateCommand); + }, + + commands: [ + "msgDownloadsCmd_clearDownloads", + "msgDownloadsCmd_searchDownloads", + ], +}; + +function DownloadItem(aDownload) { + this._download = aDownload; + this._updateFromDownload(); + + if (aDownload._unknownProperties && aDownload._unknownProperties.sender) { + this._sender = aDownload._unknownProperties.sender; + } else { + this._sender = ""; + } + this._fileName = this._htmlEscape(PathUtils.filename(aDownload.target.path)); + this._iconUrl = "moz-icon://" + this._fileName + "?size=32"; + this._startDate = this._htmlEscape( + DownloadUtils.getReadableDates(aDownload.startTime)[0] + ); + this._filePath = aDownload.target.path; +} + +var kDownloadStatePropertyNames = [ + "stopped", + "succeeded", + "canceled", + "error", + "startTime", +]; + +DownloadItem.prototype = { + _htmlEscape(s) { + s = s.replace(/&/g, "&"); + s = s.replace(/>/g, ">"); + s = s.replace(/ this.launch()); + + // Show the downloaded file in folder if the folder icon is clicked. + downloadButton.addEventListener("click", aEvent => this.show()); + + // set download as an expando property for the context menu + element.download = this.download; + element.downloadItem = this; + + this.updateElement(element); + + return element; + }, + + updateElement(element) { + let fileTypeIcon = element.querySelector(".fileTypeIcon"); + fileTypeIcon.setAttribute("src", this.iconUrl); + + let size = element.querySelector(".size"); + size.setAttribute("value", this.size); + size.setAttribute("tooltiptext", this.size); + + let fileName = element.querySelector(".fileName"); + fileName.setAttribute("value", this.fileName); + fileName.setAttribute("tooltiptext", this.fileName); + + let sender = element.querySelector(".sender"); + sender.setAttribute("value", this.sender); + sender.setAttribute("tooltiptext", this.sender); + + let startDate = element.querySelector(".startDate"); + startDate.setAttribute("value", this.startDate); + startDate.setAttribute("tooltiptext", this.startDate); + }, + + launch() { + if (this.download.succeeded) { + this.download.launch().catch(console.error); + } + }, + + remove() { + Downloads.getList(Downloads.ALL) + .then(list => list.remove(this.download)) + .then(() => this.download.finalize(true)) + .catch(console.error); + }, + + show() { + if (this.download.succeeded) { + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + file.initWithPath(this._filePath); + file.reveal(); + } + }, + + onDownloadChanged() { + this._updateFromDownload(); + this.updateElement(this.element); + }, + + get fileName() { + return this._fileName; + }, + + get iconUrl() { + return this._iconUrl; + }, + + get sender() { + return this._sender; + }, + + get size() { + let bytes; + if (this.download.succeeded || this.download.hasProgress) { + bytes = this.download.target.size; + } else { + bytes = this.download.currentBytes; + } + return DownloadUtils.convertByteUnits(bytes).join(""); + }, + + get startDate() { + return this._startDate; + }, + + supportsCommand(aCommand) { + return this.commands.includes(aCommand); + }, + + isCommandEnabled(aCommand) { + switch (aCommand) { + case "msgDownloadsCmd_open": + case "msgDownloadsCmd_show": + return this.download.succeeded; + case "msgDownloadsCmd_remove": + return true; + } + return false; + }, + + doCommand(aCommand) { + switch (aCommand) { + case "msgDownloadsCmd_open": + this.launch(); + break; + case "msgDownloadsCmd_show": + this.show(); + break; + case "msgDownloadsCmd_remove": + this.remove(); + break; + } + }, + + commands: [ + "msgDownloadsCmd_remove", + "msgDownloadsCmd_open", + "msgDownloadsCmd_show", + ], +}; -- cgit v1.2.3