<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff">
Hi,<br>
<br>
As proposed by asuth in the latest comments on bug 241197, I'd like to
offer some feedback from my experience developing an extension for
Thunderbird 3. I've had to deal with ugly parts of the code, and I
think I might have some (constructive, I hope) remarks to offer. As
this newly-created list seems to be the right place to do so, I'm
offering my thoughts. Maybe we will be able to set some specific goals
that will provide better APIs for extension developers, and foster the
development of more cool extensions :).<br>
<br>
To sum things up, I'm developing an extension called GMail Conversation
View [1] that, as the name indicates, changes the regular thread
summary code into a "Gmail-like" conversation view, including your own
messages and stuff (see [2]). I decided to tackle this issue because
I've been wanting such a thing for years, and I'm convinced Thunderbird
3 has some innovating features that make it worth spending some time on
it. I'm really hoping for more innovations in future versions of
Thunderbird and I like to think that having nice extensions such as
mine prevents people from switching to Postbox (as some people said in
the comments an AMO) or GMail or whatever.<br>
<br>
First of all, it was a real relief dealing with the revamped codebase
from Thunderbird 3. Many parts of the code have been ported to JS (I'm
thinking about things like folderPane.js and messageDisplay.js here,
among others). These are much cleaner and much easier to work with than
previous code, that's really great. Moreover, without the Gloda API, I
would not be able to design such an extension, so congratulations for
all the hard work.<br>
<br>
I would also like to thank all the people in #maildev who've always
been patient at answering my dumb questions and who have always been
incredibly helpful. Thanks guys :).<br>
<br>
However, there are still some key points that make it excruciatingly
painful to design extensions. I will start with some general thoughts,
then move on to more specific points (such as: "Gloda doesn't provide
feature X or Y").<br>
<br>
<b>I. General remarks</b><br>
<br>
One of the most useful things I discovered was
<a class="moz-txt-link-freetext" href="https://developer.mozilla.org/@api/deki/files/3579/=MessageRepresentations.png">https://developer.mozilla.org/@api/deki/files/3579/=MessageRepresentations.png</a>
-- however, it's only after struggling for a few months that I
discovered it thanks to standard8 who incidentally mentioned it on IRC.
How I wish I knew that sooner! :). What's missing is the same kind of
diagram but in a more general way. How the folderPane, the
messageDisplay, the messageHeaders, the DB view, the folder view...
relate to each other. I know there's already interface diagrams on MXR,
but I think a hand-made diagram would be much more useful.<br>
<br>
One big disappointment to me was the fact that STEEL (and, by the way,
FUEL) seems to be completely abandoned. I was hoping for a real
"standard library" for Thunderbird extensions, providing wrappers for
extremely common actions such as getting the contents of a mail,
marking a message as read... However, no such thing exists. The only
useful resource is MDC [3] which is extremely sparse.<br>
<br>
<!-- //rant<br>
To go on with the "mark message as read" example, nowhere is it
specified that nsIMsgDbHdr :: markRead() is useless for IMAP accounts
and that the right way to do that is to create a nsIArray, to populate
it with the nsIMsgDbHdr and then to call
msgHdr.folder.markMessagesRead. But, wait, how do I create a nsIArray
myself ? Well... You see my point :): we could use some wrappers here.<br>
<br>
There also seems to be some overlap between what is being rewritten and
what is legacy code. That's normal but it can get confusing sometimes.
For instance, there exist both GetMsgFolderFromUri and
MailUtils.getFolderForURI. But, look, there's this wonderful
nsIFolderLookupService :: getFolderById ! [4] Wait, there's an
interface but no implementation ? Oh sure, that's bug 441437... the
implementation was there before but was backed out. An "official
reference" would be helpful there.<br>
--><br>
<br>
The ideal solution would be to have some .jsm that offers helpers for
the most common actions. I've been doing this more or less for my
extensions, but I think there should be some "official" way of doing
this. If this is too hard to maintain, I think updating the Thunderbird
how-to list on MDC would be a nice alternative. I plan to do some of it
myself, but I'm no Thunderbird developer and I might not always write
the best solution.<br>
<br>
Some other functions I've been dreaming of:
messageIsDraft(nsIMsgDbHdr), messageIsArchive, messageIsSent (instead
of re-writing const nsMsgFolderFlag_... again and again),
getMessageBody(bool wantHTML), msgHdrToNeckoURL, replyTo(msgHdr),
replyToAll, replyToList, senderNameToNameAndEmailAddress (separates the
name from the email address in "John Doe <a class="moz-txt-link-rfc2396E" href="mailto:john@blah.com"><john@blah.com></a>")... Of
course I've found how to do that and many of these functions are
two-liners, but I'd rather have at least code samples or pre-built
wrappers that don't require me to jump from file to file on MXR to get
to the right code.<br>
<br>
<b>II. Some more specific remarks about Gloda</b><br>
<br>

I needed to display messages using the regular display code. That is,
using the HTML if the message has HTML, but stripped of all JS, with
images blocked according to the global security policy. I first thought
that Gloda would offer a wrapper for that. But all I could find was
GlodaMessage::coerceBodyToPlaintext. That was pretty useful, but I
found it odd that, given that all the MIME structure was built, no such
equivalent was available for the HTML contents. I wrote a custom
function that recursively walks down the
GlodaMessage's .parts and returns whatever has contentType "text/html"
and
looks like a "message body". However, JS is not stripped, images are
not blocked... I finally resorted to copying nsMessenger.cpp's behavior
using loadURI, nsIMarkupDocumentViewer and nice gory details such as
hintCharacterSetSource on the contentViewer.<br>
<br>
It's working fine but I still haven't found the "right way" to get rid
of the header block "From: / Date: / etc." that is automatically
prepended when the message is streamed to the <iframe> (yes, I'm
using an <iframe>, I wish I weren't but that's all I found). I'm
currently appending "?header=quotebody" to the URL but it's not meant
for that purpose. That's the kind of situation where I wish there was
some pre-built wrapper around this, because I'm a bit reluctant to
spend even more evenings digging through MXR just to get this done.<br>
<br>
② Concerning my specific needs, I need to quickly get the
MessagesCollection from a nsIMsgDbHdr. That's currently a two-part
process, where I first use getMessageCollectionForHeaders to get the
GlodaMessage corresponding to my nsIMsgDbHdr. I then query that
GlodaMessage using GlodaMessage.conversation.getMessagesCollection.
That's completely sub-optimal, and I could really use a
"getConversationsForHeaders". I'm comfortable with nesting function ()
{}s but I wish this were a more direct process.<br>
<br>
To be even more specific, Gloda conversations respect "strict
threading". This means that when my extension is used in conjunction
with mail.strict_threading set to false, I need to repeat the two-part
process for each message in the "false thread" because Gloda won't
relate these messages together in a GlodaConversation. The Gloda logic
is perfectly fine, it's nice to have strong semantics, but once again
I'd need a getConversation*s*ForHeader*s*.<br>
<br>
③ I also have some bugs I'd like to see fixed (more specifically bug
534449 and bug 538750, the latter being partly fixed by my extension),
but I'm pretty confident these will get resolved in time. I'd also like
to see bug 478167 fixed, but this probably isn't going to happen
because of limited resources.<br>
<br>
④ Some other things I'd like to see in Gloda:<br>
<span id="summary_alias_container"><span id="short_desc_nonedit_display"></span></span>-
mimeMsgToContentSnippetAndMeta's meta part never seems to return the
author properly. Ideally, that would be a GlodaIdentity that
corresponds to the name stored in the Address Book.<br>
- the ability to preformat a plain/text message (recognize *bold*,
_underscore_, email addresses, links, and others, plus blockquotes but
we've already been discussing this on bug 241197).
CC["@mozilla.org/txttohtmlconv;1"]::scanTXT already does that, but once
again, it took me ages to discover that component.<br>
- the ability to make a difference between a forwarded message and a
"real" attachment (currently, both have .isRealAttachment set to true).<br>
<br>
<b>III. Other remarks</b><br>
<br>
There are definitely more and more parts of the UI that use HTML
(search results, thread summaries). What a shame that functions such as
_mm_addClass, _mm_removeClass are defined locally and not made
available in a .jsm somewhere for extension developers! I partly used
jQuery at the beginning, but as I really was not satisfied (slows
things down, does not always play nice with XUL, spits tons of errors),
I resorted to more old-style DOM code. I'm unsure as to what is the
best solution here.<br>
<br>
<b>IV. Conclusion</b><br>
<br>
This was quite a long email (congrats if you read all the way down) but
I felt the need to discuss those many points with the team, as I think
it's important for extension developers to give feedback. I still
believe in Thunderbird which is why I'm trying to fill the gaps I
consider the more important (but that's subjective). However, although
a lot of progress has been made, the internals are not yet as good as
they could be. I really think some clear foundations need to be built
to leverage the potential for addons. There are a lot of things to
explore (I already have at least three other extensions in mind), but
if properly getting a message's body takes you three days when you're
not familiar with the code, that's going to discourage a lot of people.<br>
<br>
Finally, if I sounded a bit harsh, I apologize in advance. Please take
this as a starting point for further discussion, not an angry rant. I
understand you're a bit short on resources and you don't always have
the time for building stable APIs, but I'm convinced that attracting
extension developers will bring the project more momentum and, in the
end, more contributors.<br>
<br>
jonathan (:protz)<br>
<br>
[1] <a class="moz-txt-link-freetext" href="https://addons.mozilla.org/en-US/thunderbird/addon/54035">https://addons.mozilla.org/en-US/thunderbird/addon/54035</a><br>
[2] <a class="moz-txt-link-freetext" href="http://wiki.github.com/protz/GMail-Conversation-View/tour">http://wiki.github.com/protz/GMail-Conversation-View/tour</a><br>
[3]
<a class="moz-txt-link-freetext" href="https://developer.mozilla.org/en/Extensions/Thunderbird/HowTos#Thread_Pane">https://developer.mozilla.org/en/Extensions/Thunderbird/HowTos#Thread_Pane</a><br>
[4]
<a class="moz-txt-link-freetext" href="http://mxr.mozilla.org/comm-central/source/mailnews/base/public/nsIFolderLookupService.idl#42">http://mxr.mozilla.org/comm-central/source/mailnews/base/public/nsIFolderLookupService.idl#42</a><br>
</body>
</html>