diff options
Diffstat (limited to 'comm/mailnews/extensions/newsblog/newsblogOverlay.js')
-rw-r--r-- | comm/mailnews/extensions/newsblog/newsblogOverlay.js | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/comm/mailnews/extensions/newsblog/newsblogOverlay.js b/comm/mailnews/extensions/newsblog/newsblogOverlay.js new file mode 100644 index 0000000000..9145ad0dab --- /dev/null +++ b/comm/mailnews/extensions/newsblog/newsblogOverlay.js @@ -0,0 +1,416 @@ +/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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 ReloadMessage, getMessagePaneBrowser, openContentTab, + GetNumSelectedMessages, gMessageNotificationBar */ + +var { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); +var { FeedUtils } = ChromeUtils.import("resource:///modules/FeedUtils.jsm"); +var { MailE10SUtils } = ChromeUtils.import( + "resource:///modules/MailE10SUtils.jsm" +); + +XPCOMUtils.defineLazyModuleGetters(this, { + MsgHdrToMimeMessage: "resource:///modules/gloda/MimeMessage.jsm", +}); + +// This global is for SeaMonkey compatibility. +var gShowFeedSummary; + +var FeedMessageHandler = { + gShowSummary: true, + gToggle: false, + kSelectOverrideWebPage: 0, + kSelectOverrideSummary: 1, + kSelectFeedDefault: 2, + kOpenWebPage: 0, + kOpenSummary: 1, + kOpenToggleInMessagePane: 2, + kOpenLoadInBrowser: 3, + + FeedAccountTypes: ["rss"], + + /** + * How to load message on threadpane select. + */ + get onSelectPref() { + return Services.prefs.getIntPref("rss.show.summary"); + }, + + set onSelectPref(val) { + Services.prefs.setIntPref("rss.show.summary", val); + ReloadMessage(); + }, + + /** + * Load web page on threadpane select. + */ + get loadWebPageOnSelectPref() { + return Services.prefs.getIntPref("rss.message.loadWebPageOnSelect"); + }, + + /** + * How to load message on open (enter/dbl click in threadpane, contextmenu). + */ + get onOpenPref() { + return Services.prefs.getIntPref("rss.show.content-base"); + }, + + set onOpenPref(val) { + Services.prefs.setIntPref("rss.show.content-base", val); + }, + + /** + * Determine whether to show a feed message summary or load a web page in the + * message pane. + * + * @param {nsIMsgDBHdr} aMsgHdr - The message. + * @param {boolean} aToggle - true if in toggle mode, false otherwise. + * + * @returns {Boolean} - true if summary is to be displayed, false if web page. + */ + shouldShowSummary(aMsgHdr, aToggle) { + // Not a feed message, always show summary (the message). + if (!FeedUtils.isFeedMessage(aMsgHdr)) { + return true; + } + + // Notified of a summary reload when toggling, reset toggle and return. + if (!aToggle && this.gToggle) { + return !(this.gToggle = false); + } + + let showSummary = true; + this.gToggle = aToggle; + + // Thunderbird 2 rss messages with 'Show article summary' not selected, + // ie message body constructed to show web page in an iframe, can't show + // a summary - notify user. + let browser = getMessagePaneBrowser(); + let contentDoc = browser ? browser.contentDocument : null; + let rssIframe = contentDoc + ? contentDoc.getElementById("_mailrssiframe") + : null; + if (rssIframe) { + if (this.gToggle || this.onSelectPref == this.kSelectOverrideSummary) { + this.gToggle = false; + } + + return false; + } + + if (aToggle) { + // Toggle mode, flip value. + return (gShowFeedSummary = this.gShowSummary = !this.gShowSummary); + } + + let wintype = document.documentElement.getAttribute("windowtype"); + let tabMail = document.getElementById("tabmail"); + let messageTab = tabMail && tabMail.currentTabInfo.mode.type == "message"; + let messageWindow = wintype == "mail:messageWindow"; + + switch (this.onSelectPref) { + case this.kSelectOverrideWebPage: + showSummary = false; + break; + case this.kSelectOverrideSummary: + showSummary = true; + break; + case this.kSelectFeedDefault: + // Get quickmode per feed folder pref from feed subscriptions. If the feed + // message is not in a feed account folder (hence the folder is not in + // the feeds database), err on the side of showing the summary. + // For the former, toggle or global override is necessary; for the + // latter, a show summary checkbox toggle in Subscribe dialog will set + // one on the path to bliss. + let folder = aMsgHdr.folder; + showSummary = true; + const ds = FeedUtils.getSubscriptionsDS(folder.server); + for (let sub of ds.data) { + if (sub.destFolder == folder.URI) { + showSummary = sub.quickMode; + break; + } + } + break; + } + + gShowFeedSummary = this.gShowSummary = showSummary; + + if (messageWindow || messageTab) { + // Message opened in either standalone window or tab, due to either + // message open pref (we are here only if the pref is 0 or 1) or + // contextmenu open. + switch (this.onOpenPref) { + case this.kOpenToggleInMessagePane: + // Opened by contextmenu, use the value derived above. + // XXX: allow a toggle via crtl? + break; + case this.kOpenWebPage: + showSummary = false; + break; + case this.kOpenSummary: + showSummary = true; + break; + } + } + + // Auto load web page in browser on select, per pref; shouldShowSummary() is + // always called first to 1)test if feed, 2)get summary pref, so do it here. + if (this.loadWebPageOnSelectPref) { + setTimeout(FeedMessageHandler.loadWebPage, 20, aMsgHdr, { + browser: true, + }); + } + + return showSummary; + }, + + /** + * Load a web page for feed messages. Use MsgHdrToMimeMessage() to get + * the content-base url from the message headers. We cannot rely on + * currentHeaderData; it has not yet been streamed at our entry point in + * displayMessageChanged(), and in the case of a collapsed message pane it + * is not streamed. + * + * @param {nsIMsgDBHdr} aMessageHdr - The message. + * @param {Object} aWhere - name value=true pair, where name is in: + * 'messagepane', 'browser', 'tab', 'window'. + * @returns {void} + */ + loadWebPage(aMessageHdr, aWhere) { + MsgHdrToMimeMessage(aMessageHdr, null, function (aMsgHdr, aMimeMsg) { + if ( + aMimeMsg && + aMimeMsg.headers["content-base"] && + aMimeMsg.headers["content-base"][0] + ) { + let url = aMimeMsg.headers["content-base"], + uri; + try { + // The message and headers are stored as a string of UTF-8 bytes + // and we need to convert that cpp |string| to js UTF-16 explicitly + // for idn and non-ascii urls with this api. + url = decodeURIComponent(escape(url)); + uri = Services.io.newURI(url); + } catch (ex) { + FeedUtils.log.info( + "FeedMessageHandler.loadWebPage: " + + "invalid Content-Base header url - " + + url + ); + return; + } + if (aWhere.browser) { + Cc["@mozilla.org/uriloader/external-protocol-service;1"] + .getService(Ci.nsIExternalProtocolService) + .loadURI(uri); + } else if (aWhere.messagepane) { + let browser = getMessagePaneBrowser(); + // Load about:blank in the browser before (potentially) switching + // to a remote process. This prevents sandbox flags being carried + // over to the web document. + MailE10SUtils.loadAboutBlank(browser); + MailE10SUtils.loadURI(browser, url); + } else if (aWhere.tab) { + openContentTab(url, "tab", null); + } else if (aWhere.window) { + openContentTab(url, "window", null); + } + } else { + FeedUtils.log.info( + "FeedMessageHandler.loadWebPage: could not get " + + "Content-Base header url for this message" + ); + } + }); + }, + + /** + * Display summary or load web page for feed messages. Caller should already + * know if the message is a feed message. + * + * @param {nsIMsgDBHdr} aMsgHdr - The message. + * @param {Boolean} aShowSummary - true if summary is to be displayed, + * false if web page. + * @returns {void} + */ + setContent(aMsgHdr, aShowSummary) { + if (aShowSummary) { + // Only here if toggling to summary in 3pane. + if (this.gToggle && window.gDBView && GetNumSelectedMessages() == 1) { + ReloadMessage(); + } + } else { + let browser = getMessagePaneBrowser(); + if (browser && browser.contentDocument && browser.contentDocument.body) { + browser.contentDocument.body.hidden = true; + } + // If in a non rss folder, hide possible remote content bar on a web + // page load, as it doesn't apply. + gMessageNotificationBar.clearMsgNotifications(); + + this.loadWebPage(aMsgHdr, { messagepane: true }); + this.gToggle = false; + } + }, +}; + +function openSubscriptionsDialog(aFolder) { + // Check for an existing feed subscriptions window and focus it. + let subscriptionsWindow = Services.wm.getMostRecentWindow( + "Mail:News-BlogSubscriptions" + ); + + if (subscriptionsWindow) { + if (aFolder) { + subscriptionsWindow.FeedSubscriptions.selectFolder(aFolder); + subscriptionsWindow.FeedSubscriptions.mView.tree.ensureRowIsVisible( + subscriptionsWindow.FeedSubscriptions.mView.selection.currentIndex + ); + } + + subscriptionsWindow.focus(); + } else { + window.browsingContext.topChromeWindow.openDialog( + "chrome://messenger-newsblog/content/feed-subscriptions.xhtml", + "", + "centerscreen,chrome,dialog=no,resizable", + { folder: aFolder } + ); + } +} + +// Special case attempts to reply/forward/edit as new RSS articles. For +// messages stored prior to Tb15, we are here only if the message's folder's +// account server is rss and feed messages moved to other types will have their +// summaries loaded, as viewing web pages only happened in an rss account. +// The user may choose whether to load a summary or web page link by ensuring +// the current feed message is being viewed as either a summary or web page. +function openComposeWindowForRSSArticle( + aMsgComposeWindow, + aMsgHdr, + aMessageUri, + aType, + aFormat, + aIdentity, + aMsgWindow +) { + // Ensure right content is handled for web pages in window/tab. + let tabmail = document.getElementById("tabmail"); + let is3pane = + tabmail && tabmail.selectedTab && tabmail.selectedTab.mode + ? tabmail.selectedTab.mode.type == "folder" + : false; + let showingwebpage = + "FeedMessageHandler" in window && + !is3pane && + FeedMessageHandler.onOpenPref == FeedMessageHandler.kOpenWebPage; + + if (gShowFeedSummary && !showingwebpage) { + // The user is viewing the summary. + MailServices.compose.OpenComposeWindow( + aMsgComposeWindow, + aMsgHdr, + aMessageUri, + aType, + aFormat, + aIdentity, + null, + aMsgWindow + ); + } else { + // Set up the compose message and get the feed message's web page link. + let msgHdr = aMsgHdr; + let type = aType; + let msgComposeType = Ci.nsIMsgCompType; + let subject = msgHdr.mime2DecodedSubject; + let fwdPrefix = Services.prefs.getCharPref("mail.forward_subject_prefix"); + fwdPrefix = fwdPrefix ? fwdPrefix + ": " : ""; + + let params = Cc[ + "@mozilla.org/messengercompose/composeparams;1" + ].createInstance(Ci.nsIMsgComposeParams); + + let composeFields = Cc[ + "@mozilla.org/messengercompose/composefields;1" + ].createInstance(Ci.nsIMsgCompFields); + + if ( + type == msgComposeType.Reply || + type == msgComposeType.ReplyAll || + type == msgComposeType.ReplyToSender || + type == msgComposeType.ReplyToGroup || + type == msgComposeType.ReplyToSenderAndGroup || + type == msgComposeType.ReplyToList + ) { + subject = "Re: " + subject; + } else if ( + type == msgComposeType.ForwardInline || + type == msgComposeType.ForwardAsAttachment + ) { + subject = fwdPrefix + subject; + } + + params.composeFields = composeFields; + params.composeFields.subject = subject; + params.composeFields.body = ""; + params.bodyIsLink = false; + params.identity = aIdentity; + + try { + // The feed's web page url is stored in the Content-Base header. + MsgHdrToMimeMessage( + msgHdr, + null, + function (aMsgHdr, aMimeMsg) { + if ( + aMimeMsg && + aMimeMsg.headers["content-base"] && + aMimeMsg.headers["content-base"][0] + ) { + let url = decodeURIComponent( + escape(aMimeMsg.headers["content-base"]) + ); + params.composeFields.body = url; + params.bodyIsLink = true; + MailServices.compose.OpenComposeWindowWithParams(null, params); + } else { + // No content-base url, use the summary. + MailServices.compose.OpenComposeWindow( + aMsgComposeWindow, + aMsgHdr, + aMessageUri, + aType, + aFormat, + aIdentity, + null, + aMsgWindow + ); + } + }, + false, + { saneBodySize: true } + ); + } catch (ex) { + // Error getting header, use the summary. + MailServices.compose.OpenComposeWindow( + aMsgComposeWindow, + aMsgHdr, + aMessageUri, + aType, + aFormat, + aIdentity, + null, + aMsgWindow + ); + } + } +} |