Right now, however, this proposal is based entirely on my own experiences
and very limited knowledge of the mail-news codebase from my previous work
on the Lightning project. Accordingly, I would love to collect other
thoughts on
- What are notoriously tricky areas for extension integration in
Thunderbird?
- What are valuable, but perhaps under-utilized, areas of extension
integration?
- What was your experience like building a Thunderbird extension?
Comments are welcome in these newsgroups, or on the wiki-page.
-Joey
I would recommend avoiding renaming the copied interfaces. It hurts
multi-application extensions.
Nickolay
I had a chat with mfinkle about this yesterday. In reality, it doesn't
matter. One of the advantages of FUEL is that you never actually need to QI
any of its objects. Nor will you ever call createInstance/getService to
obtain then. In short, regardless of the name, the exact same code will
work in both Firefox and Thunderbird for these applications. As a result,
the naming is only for documentation purposes, at which point I thought the
'F' in FUEL was more confusing than a renaming.
-Joey
Just glancing at the proposed interfaces, I didn't see an easy way to
get hold of the current displayed account/folder/message. Those things
should be children of Application I would think, and it should be easy
to listen for changes to them through an event listener on the
application. At least, there were times I wanted them. None of my
extension attempts ever came to real fruition though, so I can't
really speak as anyone who's had a whole lot of success.
> My experience building TB extensions is that its a whole lot harder
> than FF. That may be because FF is better documented, or because web
> programming experience translates better, or just because I'm stupid.
> I don't know. I found myself digging through XULPlanet's MailNews
> interface listing a lot though. Things seemed way too convoluted, and
> I really wished something like this was around. I don't have a real
> dev environment set up right now, but I'd be willing to help however
> was possible.
This is exactly the type of problem we're trying to solve by having some
simple, up-front interfaces for the basic extension functions.
>
> Just glancing at the proposed interfaces, I didn't see an easy way to
> get hold of the current displayed account/folder/message. Those things
> should be children of Application I would think, and it should be easy
> to listen for changes to them through an event listener on the
> application. At least, there were times I wanted them.
I intended to address this with the onMsgShow event, accessible via
steelIApplication's addListener function. Every time a new message was
shown in the message pane (or maybe via a new window) this event would fire
and include the steelIMessage object for the displayed message.
Perhaps, however, we should elevate this to a more top-level area, with a
steelIView object. A preliminary sketch would look something like:
[scriptable, uuid(xxx)]
interface steelIView : nsISupports {
attribute steelIMessage currentMessage;
attribute steelIFolder currenFolder;
attribute unsigned long viewType;
const unsigned long TYPE_CLASSIC = 1;
const unsigned long TYPE_WIDE = 2;
const unsigned long TYPE_VERTICAL = 3;
};
I'm not sure that we gain a lot from this, but I'm open to be persuaded
otherwise.
-Joey
- What are notoriously tricky areas for extension integration in
Thunderbird?
* Compose window stuff. For example changing the From-address on-the-
fly for a single mail.
* Getting the plain text body of an email.
* Open a compose window with stuff defined. Like an attachment or body
text.
- What was your experience like building a Thunderbird extension?
* Bad documentation. Mostly read source code because I couldn't find
other sources.
* Trial and error.
* Send an e-mail with given headers/body/attachments. Here's the more
direct way I've found:
var sAccountManager =
Components.classes["@mozilla.org/messenger/account-manager;1"].
getService(Components.interfaces.nsIMsgAccountManager);
var identity =
sAccountManager.allIdentities.GetElementAt(0).
QueryInterface(Components.interfaces.nsIMsgIdentity);
var gMsgCompose =
Components.classes["@mozilla.org/messengercompose/compose;1"].
createInstance(Components.interfaces.nsIMsgCompose);
var params =
Components.classes["@mozilla.org/messengercompose/composeparams;1"].
createInstance(Components.interfaces.nsIMsgComposeParams);
var compfields =
Components.classes["@mozilla.org/messengercompose/composefields;1"].
createInstance(Components.interfaces.nsIMsgCompFields);
var progress =
Components.classes["@mozilla.org/messenger/progress;1"].
createInstance(Components.interfaces.nsIMsgProgress);
var account = sAccountManager.defaultAccount;
compfields.to = ...;
compfields.subject = ...';
compfields.body = ...;
params.identity = identity;
params.composeFields = compfields;
params.format = 2; // PlainText
var tmp_win =
window.open("chrome://nostalgy/content/dummy_window.xul", "_blank",
"chrome,dialog='no',width=0,height=0,centerscreen,alwaysLowered
");
setTimeout(function(){ tmp_win.minimize(); },2000);
gMsgCompose.Initialize(tmp_win, params );
gMsgCompose.SendMsg(Components.interfaces.nsIMsgCompDeliverMode.Now,
identity, account.key, null, progress);
* Register callbacks to be applied once when some event occurs (e.g.
on a DeleteOrMoveMsgCompleted event, or when a message is completely
rendered in the preview pane).
> - What was your experience like building a Thunderbird extension?
> * Bad documentation. Mostly read source code because I couldn't find
> other sources.
> * Trial and error.
* Quite often, I've had to delay actions with setTimeout, otherwise some
GUI actions seem to be lost (e.g. give the focus to a widget immediatly
after un-hiding it does not seem to work; or the minimize in the code
above). This is probably related to the toolkit more than to TB, though
(and it is likely that I missed some important points about GUI
programming with the toolkit).
-- Alain
Hi Joey,
not sure if you can help on this:
I'm searching how to directly accessing a msg's 'Message-ID' after/with
sending a message out.
From my understanding there is no return value with eg.
GenericSendMessage(nsIMsgCompDeliverMode.Now);
But maybe you -- or someone else -- has a good reliable solution for this??
Günter
My main concern here is where such an API - which by nature is not
UI-dependent - will reside in the source. Especially Thunderbird and
SeaMonkey share many UI _tasks_, although not the UI or the actual code,
so such an API "negotiating" between frontend and backend code could
well serve both apps.
We really should think about a "shared js component directory" under
/mailnews.
Karsten
--
Feel free to correct my English. :)
Sounds sane to me. Almost wanting to be named mailnews/toolkit (or
mail/toolkit).
Dan
Since SM's distinct mailnews UI (except some larger shared parts) will
move out of /mailnews, /mailnews seems to be a better place for shared
stuff than /mail...
(See also bug 390262.)
Yeah, I wasn't aware of that move when I posted. Your suggestion makes
sense, I think.
Dan