Skip to content

Instantly share code, notes, and snippets.

@liamzebedee
Created February 12, 2013 07:48
Show Gist options
  • Save liamzebedee/4760832 to your computer and use it in GitHub Desktop.
Save liamzebedee/4760832 to your computer and use it in GitHub Desktop.
Before I restarted doing the Thunderbird Tabbed Composition support
# HG changeset patch
# User Liam Zebedee Edwards-Playne <liamzebedee@yahoo.com.au>
# Date 1360655048 -36000
# Branch tabbed_composition #449299
# Node ID 10362e9d3bd927bbe9e33c3d10452bba11d73f1e
# Parent 88ff0c65f2442bc49ce4b3f6cef1405d87f38a53
Current working dir before project restart
diff -r 88ff0c65f244 -r 10362e9d3bd9 mail/base/content/mailCommands.js
--- a/mail/base/content/mailCommands.js Tue Jan 29 14:05:42 2013 +1000
+++ b/mail/base/content/mailCommands.js Tue Feb 12 17:44:08 2013 +1000
@@ -139,39 +139,66 @@
return (match) ? match[1] : null;
}
-// type is a nsIMsgCompType and format is a nsIMsgCompFormat
+function DoComposeMessageInTab() {
+ // I think this func is supposed to be dictated in a British accent
+ //return getPref("mail.ComposeInTab");
+ return true;
+}
+
+function ComposeMessageInTabOrWindow(msgComposeParams)
+{
+ let mail3PaneWindow = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator)
+ .getMostRecentWindow("mail:3pane");
+ if (mail3PaneWindow && DoComposeMessageInTab()) {
+ tabmail = mail3PaneWindow.document.getElementById("tabmail");
+ mail3PaneWindow.focus();
+ tabmail.openTab("chromeTab", {
+ chromePage: "chrome://messenger/content/messengercompose/messengercompose.xul",
+ onload: function(event, domNode) {
+ domNode.contentWindow.arguments[0] = msgComposeParams;
+ }
+ });
+ window.arguments[0] = msgComposeParams; // XXX necessary ?
+ } else {
+ dump("Couldn't get tabmail - opening in new window instead", "\n");
+ MailServices.compose.OpenComposeWindowWithParams(msgUrl, params);
+ }
+}
+
function ComposeMessage(type, format, folder, messageArray)
{
- // Check if the draft is already open in another window. If it is, just focus the window.
+ var msgComposeType = Components.interfaces.nsIMsgCompType;
+
+ // Check if the draft is already open in another window. If it is, just focus the window.
if (type == Components.interfaces.nsIMsgCompType.Draft && messageArray.length == 1) {
- // We'll search this uri in the opened windows.
let messageKey = GetMsgKeyFromURI(messageArray[0]);
let wenum = Services.wm.getEnumerator("");
while (wenum.hasMoreElements()) {
let w = wenum.getNext();
- // Check if it is a compose window.
if (w.document.defaultView.gMsgCompose && w.document.defaultView.gMsgCompose.compFields.draftId) {
let wKey = GetMsgKeyFromURI(w.document.defaultView.gMsgCompose.compFields.draftId);
if (wKey == messageKey) {
- // Found ! just focus it...
+ // Found it.
w.focus();
- // ...and nothing to do anymore.
return;
}
}
}
}
- var msgComposeType = Components.interfaces.nsIMsgCompType;
+
+ // Declared for clarity, not necessarily changed
+ var msgComposeWindowURL = null
+ var msgHdr = null;
+ var msgURI = null;
+ var type = type;
+ var format = format;
var identity = null;
- var newsgroup = null;
- var hdr;
-
- // dump("ComposeMessage folder=" + folder + "\n");
+
try
{
if (folder)
{
- // Get the incoming server associated with this uri.
var server = folder.server;
// If they hit new or reply and they are reading a newsgroup,
@@ -179,77 +206,161 @@
if (!folder.isServer && server.type == "nntp" && type == msgComposeType.New)
{
type = msgComposeType.NewsPost;
- newsgroup = folder.folderURL;
+ msgURI = folder.folderURL;
}
identity = folder.customIdentity;
if (!identity)
identity = getIdentityForServer(server);
- // dump("identity = " + identity + "\n");
}
}
catch (ex)
{
dump("failed to get an identity to pre-select: " + ex + "\n");
}
-
- // dump("\nComposeMessage from XUL: " + identity + "\n");
-
- switch (type)
+
+ switch (type)
{
- case msgComposeType.New: //new message
- // dump("OpenComposeWindow with " + identity + "\n");
-
- // If the addressbook sidebar panel is open and has focus, get
- // the selected addresses from it.
+ case msgComposeType.New:
if (document.commandDispatcher.focusedWindow &&
document.commandDispatcher.focusedWindow
.document.documentElement.hasAttribute("selectedaddresses"))
NewMessageToSelectedAddresses(type, format, identity);
else
- MailServices.compose.OpenComposeWindow(null, null, null, type,
+ var params = ComposeMessageSetupParams(msgComposeWindowURL, msgHdr, msgURI, type,
format, identity, msgWindow);
+ ComposeMessageInTabOrWindow(params);
return;
+
case msgComposeType.NewsPost:
- // dump("OpenComposeWindow with " + identity + " and " + newsgroup + "\n");
- MailServices.compose.OpenComposeWindow(null, null, newsgroup, type,
- format, identity, msgWindow);
+ var params = ComposeMessageSetupParams(msgComposeWindowURL, msgHdr, msgURI, type,
+ format, identity, msgWindow);
+ ComposeMessageInTabOrWindow(params);
return;
+
case msgComposeType.ForwardAsAttachment:
if (messageArray && messageArray.length)
{
// If we have more than one ForwardAsAttachment then pass null instead
// of the header to tell the compose service to work out the attachment
// subjects from the URIs.
- hdr = messageArray.length > 1 ? null : messenger.msgHdrFromURI(messageArray[0]);
- MailServices.compose.OpenComposeWindow(null, hdr, messageArray.join(','),
- type, format, identity, msgWindow);
+ msgHdr = messageArray.length > 1 ? null : messenger.msgHdrFromURI(messageArray[0]);
+ msgURI = messageArray.join(',');
+
+ var params = ComposeMessageSetupParams(msgComposeWindowURL, msgHdr, msgURI, type,
+ format, identity, msgWindow);
+ ComposeMessageInTabOrWindow(params);
return;
}
+
default:
if (!messageArray)
return;
-
- // Limit the number of new compose windows to 8. Why 8 ?
- // I like that number :-)
- if (messageArray.length > 8)
- messageArray.length = 8;
-
+
for (var i = 0; i < messageArray.length; ++i)
{
- var messageUri = messageArray[i];
- hdr = messenger.msgHdrFromURI(messageUri);
- identity = getIdentityForHeader(hdr, type);
- if (FeedMessageHandler.isFeedMessage(hdr))
- openComposeWindowForRSSArticle(null, hdr, messageUri, type,
+ msgURI = messageArray[i];
+ msgHdr = messenger.msgHdrFromURI(msgURI);
+ identity = getIdentityForHeader(msgHdr, type);
+ if (FeedMessageHandler.isFeedMessage(msgHdr)) {
+ openComposeWindowForRSSArticle(msgComposeWindowURL, msgHdr, msgURI, type,
format, identity, msgWindow);
- else
- MailServices.compose.OpenComposeWindow(null, hdr, messageUri, type,
+ } else {
+ var params = ComposeMessageSetupParams(msgComposeWindowURL, msgHdr, msgURI, type,
format, identity, msgWindow);
+ ComposeMessageInTabOrWindow(params);
+ }
}
}
}
+function ComposeMessageSetupParams(msgComposeWindowURL, origMsgHdr, originalMsgURI, type, format, aIdentity, aMsgWindow) {
+ if (!aMsgWindow)
+ aMsgWindow = msgWindow
+ var msgComposeType = Components.interfaces.nsIMsgCompType;
+ var nsMimeOutput = Components.interfaces.nsMimeOutput;
+
+ /* Actually, the only way to implement forward inline is to simulate a template message.
+ Maybe one day when we will have more time we can change that
+ */
+ if (type == msgComposeType.ForwardInline || type == msgComposeType.Draft || type == msgComposeType.Template
+ || type == msgComposeType.ReplyWithTemplate || type == msgComposeType.Redirect)
+ {
+ var uriToOpen = originalMsgURI;
+ uriToOpen += (uriToOpen.indexOf('?') === -1) ? '?' : '&';
+ uriToOpen += "fetchCompleteMessage=true";
+ if (type == msgComposeType.Redirect)
+ uriToOpen += "&redirect=true";
+
+ // aMsgWindow.SetCharsetOverride(true); XXX make interface in nsIMsgCompose.idl
+ return MailServices.compose.LoadDraftOrTemplate(uriToOpen,
+ type == msgComposeType.ForwardInline || type == msgComposeType.Draft ?
+ nsMimeOutput.nsMimeMessageDraftOrTemplate : nsMimeOutput.nsMimeMessageEditorTemplate,
+ identity, originalMsgURI, origMsgHdr, type == msgComposeType.ForwardInline,
+ format == msgComposeType.OppositeOfDefault, aMsgWindow); // XXX TODO TABS
+ }
+
+ var msgComposeParams = Components.classes["@mozilla.org/messengercompose/composeparams;1"].createInstance(Components.interfaces.nsIMsgComposeParams);
+ var msgComposeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"].createInstance (Components.interfaces.nsIMsgCompFields);
+ if(!msgComposeParams || !msgComposeFields)
+ dump("Failed to create compose parameters");
+
+ msgComposeParams.type = type;
+ msgComposeParams.format = format;
+ msgComposeParams.identity = aIdentity;
+
+ // When doing a reply (except with a template) see if there's a selection that we should quote
+ if (type == msgComposeType.Reply ||
+ type == msgComposeType.ReplyAll ||
+ type == msgComposeType.ReplyToSender ||
+ type == msgComposeType.ReplyToGroup ||
+ type == msgComposeType.ReplyToSenderAndGroup ||
+ type == msgComposeType.ReplyToList)
+ {
+ var selHTML = "";
+ try {
+ MailServices.compose.GetOrigWindowSelection(type, aMsgWindow, selHTML);
+ msgComposeParams.htmlToQuote = selHTML;
+ }
+ catch (ex) {
+ dump("Failed GetOrigWindowSelection - ", ex, "\n");
+ }
+ }
+
+ if (originalMsgURI)
+ {
+ if (type == msgComposeType.NewsPost)
+ {
+ var newsURI = originalMsgURI;
+ var group = "";
+ var host = "";
+
+ var slashpos = newsURI.indexOf('/');
+ if (slashpos > 0)
+ {
+ // uri is "[s]news://host[:port]/group"
+ host = newsURI.substring(0, slashpos); // from first character to slashpos
+ group = newsURI.slice(slashpos + 1);
+ }
+ else
+ group = originalMsgURI;
+
+ var unescapedName = "";
+ /*MsgUnescapeString(group, nsINetUtil::ESCAPE_URL_FILE_BASENAME | nsINetUtil::ESCAPE_URL_FORCED, unescapedName);
+ msgComposeFields.SetNewsgroups(NS_ConvertUTF8toUTF16(unescapedName));
+ msgComposeFields.SetNewspostUrl(host.get()); XXX */
+ }
+ else
+ {
+ msgComposeParams.originalMsgURI = originalMsgURI;
+ msgComposeParams.origMsgHdr = origMsgHdr;
+ }
+ }
+
+ msgComposeParams.composeFields = msgComposeFields;
+ return msgComposeParams;
+}
+
function NewMessageToSelectedAddresses(type, format, identity) {
var abSidebarPanel = document.commandDispatcher.focusedWindow;
var abResultsTree = abSidebarPanel.document.getElementById("abResultsTree");
@@ -270,7 +381,8 @@
}
composeFields.to = addressList;
params.composeFields = composeFields;
- MailServices.compose.OpenComposeWindowWithParams(null, params);
+ // TODO port this into ComposeMessageSetupParams for brevity's sake
+ ComposeMessageInTabOrWindow(params);
}
}
}
diff -r 88ff0c65f244 -r 10362e9d3bd9 mailnews/compose/public/nsIMsgComposeService.idl
--- a/mailnews/compose/public/nsIMsgComposeService.idl Tue Jan 29 14:05:42 2013 +1000
+++ b/mailnews/compose/public/nsIMsgComposeService.idl Tue Feb 12 17:44:08 2013 +1000
@@ -7,6 +7,7 @@
#include "nsISupports.idl"
#include "nsIMsgCompose.idl"
#include "nsIMsgComposeParams.idl"
+#include "nsIMimeStreamConverter.idl"
interface nsIURI;
interface nsIDocShell;
@@ -15,7 +16,7 @@
interface nsIMsgIncomingServer;
interface nsIMsgDBHdr;
-[scriptable, uuid(8de65170-a452-11e0-8264-0800200c9a66)]
+[scriptable, uuid(5d480fd3-9a62-470b-9172-9ce85e25954c)]
interface nsIMsgComposeService : nsISupports {
/* we need a msg window because when we forward inline we may need progress */
@@ -147,4 +148,11 @@
* the passed in docShell.
*/
nsIMsgCompose getMsgComposeForDocShell(in nsIDocShell aDocShell);
+
+ void LoadDraftOrTemplate(in ACString aMsgURI, in nsMimeOutputType aOutType,
+ in nsIMsgIdentity aIdentity, in string aOriginalMsgURI,
+ in nsIMsgDBHdr aOrigMsgHdr, in boolean aForwardInline,
+ in boolean overrideComposeFormat, in nsIMsgWindow aMsgWindow);
+
+ void GetOrigWindowSelection(in MSG_ComposeType type, in nsIMsgWindow aMsgWindow, out ACString aSelHTML);
};
diff -r 88ff0c65f244 -r 10362e9d3bd9 mailnews/compose/src/nsMsgComposeService.cpp
--- a/mailnews/compose/src/nsMsgComposeService.cpp Tue Jan 29 14:05:42 2013 +1000
+++ b/mailnews/compose/src/nsMsgComposeService.cpp Tue Feb 12 17:44:08 2013 +1000
@@ -391,7 +391,7 @@
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
nsMsgComposeService::GetOrigWindowSelection(MSG_ComposeType type, nsIMsgWindow *aMsgWindow, nsACString& aSelHTML)
{
nsresult rv;
@@ -1483,7 +1483,7 @@
* Helper routine used to run msgURI through libmime in order to fetch the contents for a
* draft or template.
*/
-nsresult
+NS_IMETHODIMP
nsMsgComposeService::LoadDraftOrTemplate(const nsACString& aMsgURI, nsMimeOutputType aOutType,
nsIMsgIdentity * aIdentity, const char * aOriginalMsgURI,
nsIMsgDBHdr * aOrigMsgHdr,
diff -r 88ff0c65f244 -r 10362e9d3bd9 mailnews/compose/src/nsMsgComposeService.h
--- a/mailnews/compose/src/nsMsgComposeService.h Tue Jan 29 14:05:42 2013 +1000
+++ b/mailnews/compose/src/nsMsgComposeService.h Tue Feb 12 17:44:08 2013 +1000
@@ -59,7 +59,7 @@
void Reset();
void DeleteCachedWindows();
nsresult AddGlobalHtmlDomains();
-
+
private:
bool mLogComposePerformance;
@@ -68,12 +68,6 @@
void CloseHiddenCachedWindow(nsIDOMWindow *domWindow);
- nsresult LoadDraftOrTemplate(const nsACString& aMsgURI, nsMimeOutputType aOutType,
- nsIMsgIdentity * aIdentity, const char * aOriginalMsgURI,
- nsIMsgDBHdr * aOrigMsgHdr, bool aForwardInline,
- bool overrideComposeFormat,
- nsIMsgWindow *aMsgWindow);
-
nsresult RunMessageThroughMimeDraft(const nsACString& aMsgURI,
nsMimeOutputType aOutType,
nsIMsgIdentity * aIdentity,
@@ -89,10 +83,6 @@
// hash table mapping dom windows to nsIMsgCompose objects
nsInterfaceHashtable<nsISupportsHashKey, nsIWeakReference> mOpenComposeWindows;
- // When doing a reply and the settings are enabled, get the HTML of the selected text
- // in the original message window so that it can be quoted instead of the entire message.
- nsresult GetOrigWindowSelection(MSG_ComposeType type, nsIMsgWindow *aMsgWindow, nsACString& aSelHTML);
-
#ifdef MSGCOMP_TRACE_PERFORMANCE
PRIntervalTime mStartTime;
PRIntervalTime mPreviousTime;
diff -r 88ff0c65f244 -r 10362e9d3bd9 mailnews/extensions/newsblog/content/newsblogOverlay.js
--- a/mailnews/extensions/newsblog/content/newsblogOverlay.js Tue Jan 29 14:05:42 2013 +1000
+++ b/mailnews/extensions/newsblog/content/newsblogOverlay.js Tue Feb 12 17:44:08 2013 +1000
@@ -44,8 +44,9 @@
if (gShowFeedSummary)
{
// The user is viewing the summary.
- MailServices.compose.OpenComposeWindow(aMsgComposeWindow, aMsgHdr, aMessageUri,
+ let params = ComposeMessageSetupParams(aMsgComposeWindow, aMsgHdr, aMessageUri,
aType, aFormat, aIdentity, aMsgWindow);
+ ComposeMessageInTabOrWindow(params);
}
else
@@ -96,20 +97,23 @@
{
params.composeFields.body = aMimeMsg.headers["content-base"];
params.bodyIsLink = true;
- MailServices.compose.OpenComposeWindowWithParams(null, params);
+ ComposeMessageInTabOrWindow(params);
}
else
// No content-base url, use the summary.
- MailServices.compose.OpenComposeWindow(aMsgComposeWindow, aMsgHdr, aMessageUri,
- aType, aFormat, aIdentity, aMsgWindow);
+ // XXX need to do more parameter processing in ComposeMessageSetupParams
+ /*let params = ComposeMessageSetupParams(aMsgComposeWindow, aMsgHdr, aMessageUri,
+ aType, aFormat, aIdentity, aMsgWindow);*/
+ ComposeMessageInTabOrWindow(params);
}, false, {saneBodySize: true});
}
catch (ex)
{
// Error getting header, use the summary.
- MailServices.compose.OpenComposeWindow(aMsgComposeWindow, aMsgHdr, aMessageUri,
- aType, aFormat, aIdentity, aMsgWindow);
+ /*var params = ComposeMessageSetupParams(aMsgComposeWindow, aMsgHdr, aMessageUri,
+ aType, aFormat, aIdentity, aMsgWindow); XXX see above*/
+ ComposeMessageInTabOrWindow(params);
}
}
}
diff -r 88ff0c65f244 -r 10362e9d3bd9 temp2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/temp2 Tue Feb 12 17:44:08 2013 +1000
@@ -0,0 +1,72 @@
+/*
+- IMPLEMENT AND TEST
+*/
+function GetOrigWindowSelection(type, aMsgWindow, aSelHTML) {
+ // Good hygeine.
+ aSelHTML = "";
+
+ if (!getPref("mailnews.reply_quoting_selection"))
+ return Components.results.NS_ERROR_ABORT;
+
+ // Now delve down in to the message to get the HTML representation of the selection
+ .createInstance(Components.interfaces.nsIDocShell)
+ var rootDocShell;
+ aMsgWindow.GetRootDocShell(rootDocShell);
+
+ var rootDocShellAsNode = rootDocShell;
+ childAsItem = rootDocShellAsNode->FindChildWithName("messagepane", true, false, nullptr, nullptr, getter_AddRefs(childAsItem));
+
+ var docShell = childAsItem;
+ var domWindow = childAsItem;
+
+ var sel = domWindow.GetSelection(sel);
+
+ var requireMultipleWords = getPref("mailnews.reply_quoting_selection.multi_word", true);
+ var charsOnlyIf = getPref("mailnews.reply_quoting_selection.only_if_chars");
+
+ if (sel && (requireMultipleWords || !charsOnlyIf === ''))
+ {
+ var selPlain = sel.ToString();
+
+ // If "mailnews.reply_quoting_selection.multi_word" is on, then there must be at least
+ // two words selected in order to quote just the selected text
+ if (requireMultipleWords)
+ {
+ lineBreaker = Services.NS_LBRK_CONTRACTID;
+ if (lineBreaker)
+ {
+ length = selPlain.length;
+ endWordPos = lineBreaker.Next(selPlain, length, 0);
+
+ // If there's not even one word, then there's not multiple words
+ if (endWordPos == NS_LINEBREAKER_NEED_MORE_TEXT)
+ return Components.results.NS_ERROR_ABORT;
+
+ // If after the first word is only space, then there's not multiple words
+ /*var end;
+ for (end = selPlain + endWordPos; NS_IsSpace(end); end++)
+ ;
+ if (!end)
+ return Components.results.NS_ERROR_ABORT;*/
+ }
+
+ }
+
+ if (!charsOnlyIf === '')
+ {
+ if (MsgFindCharInSet(selPlain, charsOnlyIf.get()) < 0)
+ return Components.results.NS_ERROR_ABORT;
+ }
+ }
+
+ var contentViewer = docShell.GetContentViewer();
+ var domDocument = contentViewer.GetDOMDocument();
+ var docEncoder;
+ docEncoder.Init(domDocument, "text/html", 0);
+ docEncoder.SetSelection(sel);
+
+ var selHTML = "";
+ docEncoder.EncodeToString(selHTML);
+
+ aSelHTML = NS_ConvertUTF16toUTF8(selHTML);
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment