summaryrefslogtreecommitdiffstats
path: root/comm/mail/base/content/widgets/foldersummary.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/base/content/widgets/foldersummary.js')
-rw-r--r--comm/mail/base/content/widgets/foldersummary.js295
1 files changed, 295 insertions, 0 deletions
diff --git a/comm/mail/base/content/widgets/foldersummary.js b/comm/mail/base/content/widgets/foldersummary.js
new file mode 100644
index 0000000000..48bcb34d26
--- /dev/null
+++ b/comm/mail/base/content/widgets/foldersummary.js
@@ -0,0 +1,295 @@
+/**
+ * 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/. */
+
+/* global MozElements */
+/* global MozXULElement */
+/* import-globals-from ../../../../mailnews/base/content/newmailalert.js */
+
+// Wrap in a block to prevent leaking to window scope.
+{
+ const { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+ );
+
+ /**
+ * MozFolderSummary displays a listing of NEW mails for the folder in question.
+ * For each mail the subject, sender and a message preview can be included.
+ *
+ * @augments {MozXULElement}
+ */
+ class MozFolderSummary extends MozXULElement {
+ constructor() {
+ super();
+ this.maxMsgHdrsInPopup = 8;
+
+ this.showSubject = Services.prefs.getBoolPref(
+ "mail.biff.alert.show_subject"
+ );
+ this.showSender = Services.prefs.getBoolPref(
+ "mail.biff.alert.show_sender"
+ );
+ this.showPreview = Services.prefs.getBoolPref(
+ "mail.biff.alert.show_preview"
+ );
+ this.messengerBundle = Services.strings.createBundle(
+ "chrome://messenger/locale/messenger.properties"
+ );
+
+ ChromeUtils.defineModuleGetter(
+ this,
+ "MailUtils",
+ "resource:///modules/MailUtils.jsm"
+ );
+ }
+
+ hasMessages() {
+ return this.lastElementChild;
+ }
+
+ static createFolderSummaryMessage() {
+ let vbox = document.createXULElement("vbox");
+ vbox.setAttribute("class", "folderSummaryMessage");
+
+ let hbox = document.createXULElement("hbox");
+ hbox.setAttribute("class", "folderSummary-message-row");
+
+ let subject = document.createXULElement("label");
+ subject.setAttribute("class", "folderSummary-subject");
+
+ let sender = document.createXULElement("label");
+ sender.setAttribute("class", "folderSummary-sender");
+ sender.setAttribute("crop", "end");
+
+ hbox.appendChild(subject);
+ hbox.appendChild(sender);
+
+ let preview = document.createXULElement("description");
+ preview.setAttribute(
+ "class",
+ "folderSummary-message-row folderSummary-previewText"
+ );
+ preview.setAttribute("crop", "end");
+
+ vbox.appendChild(hbox);
+ vbox.appendChild(preview);
+ return vbox;
+ }
+
+ /**
+ * Check the given folder for NEW messages.
+ *
+ * @param {nsIMsgFolder} folder - The folder to examine.
+ * @param {nsIUrlListener} urlListener - Listener to notify if we run urls
+ * to fetch msgs.
+ * @param Object outAsync - Object with value property set to true if there
+ * are async fetches pending (a message preview will be available later).
+ * @returns true if the folder knows about messages that should be shown.
+ */
+ parseFolder(folder, urlListener, outAsync) {
+ // Skip servers, Trash, Junk folders and newsgroups.
+ if (
+ !folder ||
+ folder.isServer ||
+ !folder.hasNewMessages ||
+ folder.getFlag(Ci.nsMsgFolderFlags.Junk) ||
+ folder.getFlag(Ci.nsMsgFolderFlags.Trash) ||
+ folder.server instanceof Ci.nsINntpIncomingServer
+ ) {
+ return false;
+ }
+
+ let folderArray = [];
+ let msgDatabase;
+ try {
+ msgDatabase = folder.msgDatabase;
+ } catch (e) {
+ // The database for this folder may be missing (e.g. outdated/missing .msf),
+ // so just skip this folder.
+ return false;
+ }
+
+ if (folder.flags & Ci.nsMsgFolderFlags.Virtual) {
+ let srchFolderUri =
+ msgDatabase.dBFolderInfo.getCharProperty("searchFolderUri");
+ let folderUris = srchFolderUri.split("|");
+ for (let uri of folderUris) {
+ let realFolder = this.MailUtils.getOrCreateFolder(uri);
+ if (!realFolder.isServer) {
+ folderArray.push(realFolder);
+ }
+ }
+ } else {
+ folderArray.push(folder);
+ }
+
+ let haveMsgsToShow = false;
+ for (let folder of folderArray) {
+ // now get the database
+ try {
+ msgDatabase = folder.msgDatabase;
+ } catch (e) {
+ // The database for this folder may be missing (e.g. outdated/missing .msf),
+ // then just skip this folder.
+ continue;
+ }
+
+ folder.msgDatabase = null;
+ let msgKeys = msgDatabase.getNewList();
+
+ let numNewMessages = folder.getNumNewMessages(false);
+ if (!numNewMessages) {
+ continue;
+ }
+ // NOTE: getNewlist returns all nsMsgMessageFlagType::New messages,
+ // while getNumNewMessages returns count of new messages since the last
+ // biff. Only show newly received messages since last biff in
+ // notification.
+ msgKeys = msgKeys.slice(-numNewMessages);
+ if (!msgKeys.length) {
+ continue;
+ }
+
+ if (this.showPreview) {
+ // fetchMsgPreviewText forces the previewText property to get generated
+ // for each of the message keys.
+ try {
+ outAsync.value = folder.fetchMsgPreviewText(msgKeys, urlListener);
+ folder.msgDatabase = null;
+ } catch (ex) {
+ // fetchMsgPreviewText throws an error when we call it on a news
+ // folder
+ folder.msgDatabase = null;
+ continue;
+ }
+ }
+
+ // If fetching the preview text is going to be an asynch operation and the
+ // caller is set up to handle that fact, then don't bother filling in any
+ // of the fields since we'll have to do this all over again when the fetch
+ // for the preview text completes.
+ // We don't expect to get called with a urlListener if we're doing a
+ // virtual folder.
+ if (outAsync.value && urlListener) {
+ return false;
+ }
+
+ // In the case of async fetching for more than one folder, we may
+ // already have got enough to show (added by another urllistener).
+ let curHdrsInPopup = this.children.length;
+ if (curHdrsInPopup >= this.maxMsgHdrsInPopup) {
+ return false;
+ }
+
+ for (
+ let i = 0;
+ i + curHdrsInPopup < this.maxMsgHdrsInPopup && i < msgKeys.length;
+ i++
+ ) {
+ let msgBox = MozFolderSummary.createFolderSummaryMessage();
+ let msgHdr = msgDatabase.getMsgHdrForKey(msgKeys[i]);
+ msgBox.addEventListener("click", event => {
+ if (event.button !== 0) {
+ return;
+ }
+ this.MailUtils.displayMessageInFolderTab(msgHdr, true);
+ });
+
+ if (this.showSubject) {
+ let msgSubject = msgHdr.mime2DecodedSubject;
+ const kMsgFlagHasRe = 0x0010; // MSG_FLAG_HAS_RE
+ if (msgHdr.flags & kMsgFlagHasRe) {
+ msgSubject = msgSubject ? "Re: " + msgSubject : "Re: ";
+ }
+ msgBox.querySelector(".folderSummary-subject").textContent =
+ msgSubject;
+ }
+
+ if (this.showSender) {
+ let addrs = MailServices.headerParser.parseEncodedHeader(
+ msgHdr.author,
+ msgHdr.effectiveCharset,
+ false
+ );
+ let folderSummarySender = msgBox.querySelector(
+ ".folderSummary-sender"
+ );
+ // Set the label value instead of textContent to avoid wrapping.
+ folderSummarySender.value =
+ addrs.length > 0 ? addrs[0].name || addrs[0].email : "";
+ if (addrs.length > 1) {
+ let andOthersStr =
+ this.messengerBundle.GetStringFromName("andOthers");
+ folderSummarySender.value += " " + andOthersStr;
+ }
+ }
+
+ if (this.showPreview) {
+ msgBox.querySelector(".folderSummary-previewText").textContent =
+ msgHdr.getStringProperty("preview") || "";
+ }
+ this.appendChild(msgBox);
+ haveMsgsToShow = true;
+ }
+ }
+ return haveMsgsToShow;
+ }
+
+ /**
+ * Render NEW messages in a folder.
+ *
+ * @param {nsIMsgFolder} folder - A real folder containing new messages.
+ * @param {number[]} msgKeys - The keys of new messages.
+ */
+ render(folder, msgKeys) {
+ let msgDatabase = folder.msgDatabase;
+ for (let msgKey of msgKeys.slice(0, this.maxMsgHdrsInPopup)) {
+ let msgBox = MozFolderSummary.createFolderSummaryMessage();
+ let msgHdr = msgDatabase.getMsgHdrForKey(msgKey);
+ msgBox.addEventListener("click", event => {
+ if (event.button !== 0) {
+ return;
+ }
+ this.MailUtils.displayMessageInFolderTab(msgHdr, true);
+ });
+
+ if (this.showSubject) {
+ let msgSubject = msgHdr.mime2DecodedSubject;
+ const kMsgFlagHasRe = 0x0010; // MSG_FLAG_HAS_RE
+ if (msgHdr.flags & kMsgFlagHasRe) {
+ msgSubject = msgSubject ? "Re: " + msgSubject : "Re: ";
+ }
+ msgBox.querySelector(".folderSummary-subject").textContent =
+ msgSubject;
+ }
+
+ if (this.showSender) {
+ let addrs = MailServices.headerParser.parseEncodedHeader(
+ msgHdr.author,
+ msgHdr.effectiveCharset,
+ false
+ );
+ let folderSummarySender = msgBox.querySelector(
+ ".folderSummary-sender"
+ );
+ // Set the label value instead of textContent to avoid wrapping.
+ folderSummarySender.value =
+ addrs.length > 0 ? addrs[0].name || addrs[0].email : "";
+ if (addrs.length > 1) {
+ let andOthersStr =
+ this.messengerBundle.GetStringFromName("andOthers");
+ folderSummarySender.value += " " + andOthersStr;
+ }
+ }
+
+ if (this.showPreview) {
+ msgBox.querySelector(".folderSummary-previewText").textContent =
+ msgHdr.getStringProperty("preview") || "";
+ }
+ this.appendChild(msgBox);
+ }
+ }
+ }
+ customElements.define("folder-summary", MozFolderSummary);
+}