summaryrefslogtreecommitdiffstats
path: root/comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js')
-rw-r--r--comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js282
1 files changed, 282 insertions, 0 deletions
diff --git a/comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js b/comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js
new file mode 100644
index 0000000000..4412be2ffe
--- /dev/null
+++ b/comm/mail/extensions/mailviews/content/msgViewPickerOverlay.js
@@ -0,0 +1,282 @@
+/* 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 OpenOrFocusWindow */ // From mailWindowOverlay.js
+/* globals GetSelectedMsgFolders */ // From messenger.js
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { MailViewConstants } = ChromeUtils.import(
+ "resource:///modules/MailViewManager.jsm"
+);
+
+// these constants are now authoritatively defined in MailViewManager.jsm (above)
+// tag views have kViewTagMarker + their key as value
+var kViewItemAll = MailViewConstants.kViewItemAll;
+var kViewItemUnread = MailViewConstants.kViewItemUnread;
+var kViewItemTags = MailViewConstants.kViewItemTags; // former labels used values 2-6
+var kViewItemNotDeleted = MailViewConstants.kViewItemNotDeleted;
+// not a real view! a sentinel value to pop up a dialog
+var kViewItemVirtual = MailViewConstants.kViewItemVirtual;
+// not a real view! a sentinel value to pop up a dialog
+var kViewItemCustomize = MailViewConstants.kViewItemCustomize;
+var kViewItemFirstCustom = MailViewConstants.kViewItemFirstCustom;
+
+var kViewCurrent = MailViewConstants.kViewCurrent;
+var kViewCurrentTag = MailViewConstants.kViewCurrentTag;
+var kViewTagMarker = MailViewConstants.kViewTagMarker;
+
+/**
+ * A reference to the nsIMsgMailViewList service that tracks custom mail views.
+ */
+var gMailViewList = null;
+
+// perform the view/action requested by the aValue string
+// and set the view picker label to the aLabel string
+function ViewChange(aValue) {
+ let about3Pane = document.getElementById("tabmail").currentAbout3Pane;
+ let viewWrapper = about3Pane.gViewWrapper;
+ if (!viewWrapper) {
+ return;
+ }
+
+ if (aValue == kViewItemCustomize || aValue == kViewItemVirtual) {
+ // restore to the previous view value, in case they cancel
+ if (aValue == kViewItemCustomize) {
+ LaunchCustomizeDialog();
+ } else {
+ about3Pane.folderPane.newVirtualFolder(
+ ViewPickerBinding.currentViewLabel,
+ viewWrapper.search.viewTerms,
+ about3Pane.gFolder
+ );
+ }
+ return;
+ }
+
+ // tag menuitem values are of the form :<keyword>
+ if (isNaN(aValue)) {
+ // split off the tag key
+ var tagkey = aValue.substr(kViewTagMarker.length);
+ viewWrapper.setMailView(kViewItemTags, tagkey);
+ } else {
+ var numval = Number(aValue);
+ viewWrapper.setMailView(numval, null);
+ }
+}
+
+function ViewChangeByMenuitem(aMenuitem) {
+ // Mac View menu menuitems don't have XBL bindings
+ ViewChange(aMenuitem.getAttribute("value"));
+}
+
+/**
+ * Mediates interaction with the #viewPickerPopup. In theory this should be
+ * an XBL binding, but for the insanity where the view picker may not be
+ * visible at all times (or ever). No view picker widget, no binding.
+ */
+var ViewPickerBinding = {
+ /**
+ * Return true if the view picker is visible. This is used by the
+ * FolderDisplayWidget to know whether or not to actually use mailviews. (The
+ * idea is that if we are not visible, then it would be confusing to the user
+ * if we filtered their mail since they would have no feedback about this and
+ * no way to change it.)
+ */
+ get isVisible() {
+ return !!document.querySelector("#unifiedToolbarContent .view-picker");
+ },
+
+ /**
+ * Return the string value representing the current mail view value as
+ * understood by the view picker widgets. The value is the index for
+ * everything but tags. for tags it's the ":"-prefixed tagname.
+ */
+ get currentViewValue() {
+ let about3Pane = document.getElementById("tabmail").currentAbout3Pane;
+ let viewWrapper = about3Pane.gViewWrapper;
+ if (!viewWrapper) {
+ return "";
+ }
+ if (viewWrapper.mailViewIndex == kViewItemTags) {
+ return kViewTagMarker + viewWrapper.mailViewData;
+ }
+ return viewWrapper.mailViewIndex + "";
+ },
+
+ /**
+ * @returns The label for the current mail view value.
+ */
+ get currentViewLabel() {
+ return document.querySelector(
+ `#toolbarViewPickerPopup [value="${this.currentViewValue}"]`
+ )?.label;
+ },
+};
+
+function LaunchCustomizeDialog() {
+ OpenOrFocusWindow(
+ {},
+ "mailnews:mailviewlist",
+ "chrome://messenger/content/mailViewList.xhtml"
+ );
+}
+
+/**
+ * All of these Refresh*ViewPopup* methods have to deal with several menu
+ * instances. For example, the "View... Messages" menu, the view picker menu
+ * list in the toolbar, in appmenu/View/Messages, etc.
+ *
+ * @param {Element} viewPopup - A menu popup element.
+ */
+function RefreshAllViewPopups(viewPopup) {
+ RefreshViewPopup(viewPopup);
+ let menupopups = viewPopup.getElementsByTagName("menupopup");
+ if (menupopups.length > 1) {
+ // When we have menupopups, we assume both tags and custom views are there.
+ RefreshTagsPopup(menupopups[0]);
+ RefreshCustomViewsPopup(menupopups[1]);
+ }
+}
+
+/**
+ * Refresh the view messages popup menu/panel. For example set checked and
+ * hidden state on menu items. Used for example for appmenu/View/Messages panel.
+ *
+ * @param {Element} viewPopup - A menu popup element.
+ */
+function RefreshViewPopup(viewPopup) {
+ // Mark default views if selected.
+ let currentViewValue = ViewPickerBinding.currentViewValue;
+
+ let viewAll = viewPopup.querySelector('[value="' + kViewItemAll + '"]');
+ viewAll.setAttribute("checked", currentViewValue == kViewItemAll);
+
+ let viewUnread = viewPopup.querySelector('[value="' + kViewItemUnread + '"]');
+ viewUnread.setAttribute("checked", currentViewValue == kViewItemUnread);
+
+ let viewNotDeleted = viewPopup.querySelector(
+ '[value="' + kViewItemNotDeleted + '"]'
+ );
+
+ let folderArray = GetSelectedMsgFolders();
+ if (folderArray.length == 0) {
+ return;
+ }
+
+ // Only show the "Not Deleted" item for IMAP servers that are using the IMAP
+ // delete model.
+ viewNotDeleted.setAttribute("hidden", true);
+ var msgFolder = folderArray[0];
+ var server = msgFolder.server;
+ if (server.type == "imap") {
+ let imapServer = server.QueryInterface(Ci.nsIImapIncomingServer);
+
+ if (imapServer.deleteModel == Ci.nsMsgImapDeleteModels.IMAPDelete) {
+ viewNotDeleted.setAttribute("hidden", false);
+ viewNotDeleted.setAttribute(
+ "checked",
+ currentViewValue == kViewItemNotDeleted
+ );
+ }
+ }
+}
+
+/**
+ * Refresh the contents of the custom views popup menu/panel.
+ * Used for example for appmenu/View/Messages/CustomViews panel.
+ *
+ * @param {Element} parent - Parent element that will receive the menu items.
+ * @param {string} [elementName] - Type of menu items to create (e.g. "menuitem", "toolbarbutton").
+ * @param {string} [classes] - Classes to set on the menu items.
+ */
+function RefreshCustomViewsPopup(parent, elementName = "menuitem", classes) {
+ if (!gMailViewList) {
+ gMailViewList = Cc["@mozilla.org/messenger/mailviewlist;1"].getService(
+ Ci.nsIMsgMailViewList
+ );
+ }
+
+ // Remove all menu items.
+ while (parent.hasChildNodes()) {
+ parent.lastChild.remove();
+ }
+
+ // Rebuild the list.
+ const currentView = ViewPickerBinding.currentViewValue;
+ const numItems = gMailViewList.mailViewCount;
+
+ for (let i = 0; i < numItems; ++i) {
+ const viewInfo = gMailViewList.getMailViewAt(i);
+ const item = document.createXULElement(elementName);
+
+ item.setAttribute("label", viewInfo.prettyName);
+ item.setAttribute("value", kViewItemFirstCustom + i);
+ item.setAttribute("type", "radio");
+
+ if (classes) {
+ item.setAttribute("class", classes);
+ }
+ if (kViewItemFirstCustom + i == currentView) {
+ item.setAttribute("checked", true);
+ }
+
+ item.addEventListener("command", () =>
+ ViewChange(kViewItemFirstCustom + i)
+ );
+
+ parent.appendChild(item);
+ }
+}
+
+/**
+ * Refresh the contents of the tags popup menu/panel. For example, used for
+ * appmenu/View/Messages/Tags.
+ *
+ * @param {Element} parent - Parent element that will receive the menu items.
+ * @param {string} [elementName] - Type of menu items to create (e.g. "menuitem", "toolbarbutton").
+ * @param {string} [classes] - Classes to set on the menu items.
+ */
+function RefreshTagsPopup(parent, elementName = "menuitem", classes) {
+ // Remove all pre-existing menu items.
+ while (parent.hasChildNodes()) {
+ parent.lastChild.remove();
+ }
+
+ // Create tag menu items.
+ let about3Pane = document.getElementById("tabmail").currentAbout3Pane;
+ let viewWrapper = about3Pane.gViewWrapper;
+ if (!viewWrapper) {
+ return;
+ }
+ const currentTagKey =
+ viewWrapper.mailViewIndex == kViewItemTags ? viewWrapper.mailViewData : "";
+
+ const tagArray = MailServices.tags.getAllTags();
+
+ tagArray.forEach(tagInfo => {
+ const item = document.createXULElement(elementName);
+
+ item.setAttribute("label", tagInfo.tag);
+ item.setAttribute("value", kViewTagMarker + tagInfo.key);
+ item.setAttribute("type", "radio");
+
+ if (tagInfo.key == currentTagKey) {
+ item.setAttribute("checked", true);
+ }
+ if (tagInfo.color) {
+ item.setAttribute("style", `color: ${tagInfo.color};`);
+ }
+ if (classes) {
+ item.setAttribute("class", classes);
+ }
+
+ item.addEventListener("command", () =>
+ ViewChange(kViewTagMarker + tagInfo.key)
+ );
+
+ parent.appendChild(item);
+ });
+}