Created
February 12, 2013 07:48
-
-
Save liamzebedee/4760832 to your computer and use it in GitHub Desktop.
Before I restarted doing the Thunderbird Tabbed Composition support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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