diff options
Diffstat (limited to 'comm/mail/components/preferences/messagestyle.js')
-rw-r--r-- | comm/mail/components/preferences/messagestyle.js | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/comm/mail/components/preferences/messagestyle.js b/comm/mail/components/preferences/messagestyle.js new file mode 100644 index 0000000000..7d10553296 --- /dev/null +++ b/comm/mail/components/preferences/messagestyle.js @@ -0,0 +1,259 @@ +/* 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/. */ + +/* import-globals-from preferences.js */ + +var { GenericConvIMPrototype, GenericMessagePrototype } = + ChromeUtils.importESModule("resource:///modules/jsProtoHelper.sys.mjs"); +var { getThemeByName, getThemeVariants } = ChromeUtils.importESModule( + "resource:///modules/imThemes.sys.mjs" +); + +var { IMServices } = ChromeUtils.importESModule( + "resource:///modules/IMServices.sys.mjs" +); + +function Conversation(aName) { + this._name = aName; + this._observers = []; + let now = new Date(); + this._date = + new Date(now.getFullYear(), now.getMonth(), now.getDate(), 10, 42, 22) * + 1000; +} +Conversation.prototype = { + __proto__: GenericConvIMPrototype, + account: { + protocol: { name: "Fake Protocol" }, + alias: "", + name: "Fake Account", + get statusInfo() { + return IMServices.core.globalUserStatus; + }, + }, +}; + +function Message(aWho, aMessage, aObject, aConversation) { + this._init(aWho, aMessage, aObject, aConversation); +} +Message.prototype = { + __proto__: GenericMessagePrototype, + get displayMessage() { + return this.originalMessage; + }, +}; + +// Message style tooltips use this. +function getBrowser() { + return document.getElementById("previewbrowser"); +} + +var previewObserver = { + _loaded: false, + load() { + let makeDate = function (aDateString) { + let array = aDateString.split(":"); + let now = new Date(); + return ( + new Date( + now.getFullYear(), + now.getMonth(), + now.getDate(), + array[0], + array[1], + array[2] + ) / 1000 + ); + }; + let bundle = document.getElementById("themesBundle"); + let msg = {}; + [ + "nick1", + "buddy1", + "nick2", + "buddy2", + "message1", + "message2", + "message3", + ].forEach(function (aText) { + msg[aText] = bundle.getString(aText); + }); + let conv = new Conversation(msg.nick2); + conv.messages = [ + new Message( + msg.buddy1, + msg.message1, + { + outgoing: true, + _alias: msg.nick1, + time: makeDate("10:42:22"), + }, + conv + ), + new Message( + msg.buddy1, + msg.message2, + { + outgoing: true, + _alias: msg.nick1, + time: makeDate("10:42:25"), + }, + conv + ), + new Message( + msg.buddy2, + msg.message3, + { + incoming: true, + _alias: msg.nick2, + time: makeDate("10:43:01"), + }, + conv + ), + ]; + previewObserver.conv = conv; + + let themeName = document.getElementById("messagestyle-themename"); + previewObserver.browser = document.getElementById("previewbrowser"); + + // If the preferences tab is opened straight to the message styles, + // loading the preview fails. Pushing this to back of the event queue + // prevents that failure. + setTimeout(() => { + previewObserver.displayTheme(themeName.value); + this._loaded = true; + }); + }, + + currentThemeChanged() { + if (!this._loaded) { + return; + } + + let currentTheme = document.getElementById("messagestyle-themename").value; + if (!currentTheme) { + return; + } + + this.displayTheme(currentTheme); + }, + + _ignoreVariantChange: false, + currentVariantChanged() { + if (!this._loaded || this._ignoreVariantChange) { + return; + } + + let variant = document.getElementById("themevariant").value; + if (!variant) { + return; + } + + this.theme.variant = variant; + this.reloadPreview(); + }, + + displayTheme(aTheme) { + try { + this.theme = getThemeByName(aTheme); + } catch (e) { + let previewBoxBrowser = document + .getElementById("previewBox") + .querySelector("browser"); + if (previewBoxBrowser) { + previewBoxBrowser.hidden = true; + } + document.getElementById("noPreviewScreen").hidden = false; + return; + } + + let menulist = document.getElementById("themevariant"); + if (menulist.menupopup) { + menulist.menupopup.remove(); + } + let popup = menulist.appendChild(document.createXULElement("menupopup")); + let variants = getThemeVariants(this.theme); + + let defaultVariant = ""; + if ( + "DefaultVariant" in this.theme.metadata && + variants.includes(this.theme.metadata.DefaultVariant) + ) { + defaultVariant = this.theme.metadata.DefaultVariant.replace(/_/g, " "); + } + + let defaultText = defaultVariant; + if (!defaultText && "DisplayNameForNoVariant" in this.theme.metadata) { + defaultText = this.theme.metadata.DisplayNameForNoVariant; + } + // if the name in the metadata is 'Default', use the localized version + if (!defaultText || defaultText.toLowerCase() == "default") { + defaultText = document + .getElementById("themesBundle") + .getString("default"); + } + + let menuitem = document.createXULElement("menuitem"); + menuitem.setAttribute("label", defaultText); + menuitem.setAttribute("value", "default"); + popup.appendChild(menuitem); + popup.appendChild(document.createXULElement("menuseparator")); + + variants.sort().forEach(function (aVariantName) { + let displayName = aVariantName.replace(/_/g, " "); + if (displayName != defaultVariant) { + let menuitem = document.createXULElement("menuitem"); + menuitem.setAttribute("label", displayName); + menuitem.setAttribute("value", aVariantName); + popup.appendChild(menuitem); + } + }); + this._ignoreVariantChange = true; + if (!this._loaded) { + menulist.value = this.theme.variant = menulist.value; + } else { + menulist.value = this.theme.variant; // (reset to "default") + Preferences.userChangedValue(menulist); + } + this._ignoreVariantChange = false; + + // disable the variant menulist if there's no variant, or only one + // which is the default + menulist.disabled = + variants.length == 0 || (variants.length == 1 && defaultVariant); + + this.reloadPreview(); + document.getElementById("noPreviewScreen").hidden = true; + }, + + reloadPreview() { + this.browser.init(this.conv); + this.browser._theme = this.theme; + Services.obs.addObserver(this, "conversation-loaded"); + }, + + observe(aSubject, aTopic, aData) { + if (aTopic != "conversation-loaded" || aSubject != this.browser) { + return; + } + + // We want to avoid the convbrowser trying to scroll to the last + // added message, as that causes the entire pref pane to jump up + // (bug 1179943). Therefore, we override the method convbrowser + // uses to determine if it should scroll, as well as its + // mirror in the contentWindow (that messagestyle JS can call). + this.browser.convScrollEnabled = () => false; + this.browser.contentWindow.convScrollEnabled = () => false; + + // Display all queued messages. Use a timeout so that message text + // modifiers can be added with observers for this notification. + setTimeout(function () { + for (let message of previewObserver.conv.messages) { + aSubject.appendMessage(message, false); + } + }, 0); + + Services.obs.removeObserver(this, "conversation-loaded"); + }, +}; |