A Thunderbird "stdlib"

413 views
Skip to first unread message

Jonathan Protzenko

unread,
Dec 16, 2010, 4:13:50 PM12/16/10
to tb-pl...@mozilla.org
Hi,

In the process of writing Thunderbird Conversations, I've been writing a
considerable amount of small utility functions. Such functions include
wrappers to easily get a given address book, a wrapper that deletes
messages, archives some, tells you whether a message is in a "Drafts"
folder, a function to get a given message's body... these wrappers have
been pretty stable for quite some time now.

I'll probably enrich the set with my JS message sending backend, which
should be shared by both Thunderbird Conversations (for quick reply) and
"Compose in a tab" [1].

I don't feel like this is worth integrating into the tree. However, what
if I spun off these "common parts" into a separate github repo and we
started advertising it as a "readymade" package that extension authors
can include in their own builds, to make their lives easier? I feel like
that's exactly the kind of stuff I missed when I was starting...

Here are some sample files:
https://github.com/protz/GMail-Conversation-View/blob/master/modules/AddressBookUtils.jsm
https://github.com/protz/GMail-Conversation-View/blob/master/modules/MsgHdrUtils.jsm
https://github.com/protz/GMail-Conversation-View/blob/master/modules/VariousUtils.jsm

(the last one is is kinda messy, as it includes specific quote detection
heuristics, but the first functions are very useful imho).

Thoughts?

jonathan

[1] The backend was initially developed inside Compose in a tab, it's
been improved in Thunderbird Conversations, and now I need to factor out
the common parts and make the two addons share as much code as possible.
_______________________________________________
tb-planning mailing list
tb-pl...@mozilla.org
https://mail.mozilla.org/listinfo/tb-planning

Patrick Cloke

unread,
Dec 16, 2010, 7:43:09 PM12/16/10
to tb-pl...@mozilla.org
From your description, it sounds to me like this is the idea that
STEEL/FUEL [1] was originally created for, I'm not sure how much work
was ever done on it, but at least the Application interface exists.
Maybe that would be a good approach to including these for other
extension developers? I think modules might be confusing enough for new
extension developers that it could be worth it to have them included by
default. FUEL contains some simple methods for adding/removing
bookmarks, accessing browser tabs, etc. but (as far as I know) the
Thunderbird version (STEEL) was never really developed as far.

Just an idea,

Patrick Cloke

[1] https://developer.mozilla.org/en/Toolkit_API/STEEL &
https://developer.mozilla.org/en/Toolkit_API/FUEL

Jonathan Protzenko

unread,
Dec 17, 2010, 3:24:55 AM12/17/10
to Patrick Cloke, tb-pl...@mozilla.org
Yes, I'm aware of STEEL but it never got really far. I don't know the
reasons for it (lack of resources?), so I thought that keeping some kind
of a standard library off the tree, in something more flexible than
Mozilla's own hg repo, would allow other people to contribute more easily.

There's also the infamous "MailUtils.jsm" that does include a couple
useful functions. I was thinking about something more in the spirit of
"MailUtils.jsm" rather than an XPCOM-like STEEL library with interfaces.

Ludovic Hirlimann

unread,
Dec 17, 2010, 3:52:52 AM12/17/10
to Jonathan Protzenko, tb-pl...@mozilla.org
On 17/12/10 09:24, Jonathan Protzenko wrote:
> Yes, I'm aware of STEEL but it never got really far. I don't know the
> reasons for it (lack of resources?), so I thought that keeping some
> kind of a standard library off the tree, in something more flexible
> than Mozilla's own hg repo, would allow other people to contribute
> more easily.
>

How about we try to mix both concepts method. Dev happens on github but
it ends up in product via a merge. This keeps the nice decentralized way
of developing on github, makes it possible to get the libs into the
product and usable by all, and would avoid bloating all extension
depending on the libs.

I'd think protz would make a nice STEEL module owner in that scenario.

Ludo

--
Ludovic Hirlimann MozillaMessaging QA lead
https://wiki.mozilla.org/Thunderbird:Testing
http://www.spreadthunderbird.com/aff/79/2


Andrew Sutherland

unread,
Dec 17, 2010, 4:13:23 AM12/17/10
to tb-pl...@mozilla.org
On 12/16/2010 01:13 PM, Jonathan Protzenko wrote:
> I don't feel like this is worth integrating into the tree. However,
> what if I spun off these "common parts" into a separate github repo
> and we started advertising it as a "readymade" package that extension
> authors can include in their own builds, to make their lives easier? I
> feel like that's exactly the kind of stuff I missed when I was
> starting...

This sounds like a good idea to me. This is roughly how the Add-on
SDK/Jetpack does things; every extension built with Jetpack includes its
own copy of Jetpack and any libraries.

As an elaboration of agreement, I think Python has a good model for
these kinds of things. Some things have to be in the core, but a lot of
things do not, especially libraries. It can be useful to move libraries
into the core, but they should have reached a stable API point because
evolving them once they've moved into the core can be problematic.

Continuing the Python example, the need for moving things into the core
library greatly decreases with a good package management system. I have
to concede that non-Jetpack extensions do not have this provided to them
on a platter, but as long as the github repo is structured so that you
can easily check it out into a subdir of an extension, that should not
actually pose a problem.

Specifically, I could structure my extension so that I check out
"tb-stdlib" into "content/modules" of my extension if tb-stdlib keeps
things in the root. (Or maybe the .gitmodules mechanism lets you check
out a subdir of a repo? I don't have enough experience with it yet.)

Once things are stabilized and if they have tons of unit tests, it could
make sense to move things into the core. In this specific case, since
the abstractions all operate at the nsIMsgDBHdr, I would suggest we
don't migrate the library into core just because I don't think we want
that to be part of our official/supported/friendly API substrate.

Andrew

Jonathan Protzenko

unread,
Jan 18, 2011, 9:08:26 AM1/18/11
to tb-pl...@mozilla.org
Dear Thunderbird fellows,

I've spent some time moving out useful functions out of Thunderbird
Conversations, into thunderbird-stdlib. The result is this wonderful
web page http://protz.github.com/thunderbird-stdlib/ (color theme
bikeshedding welcome). More seriously, I've put in there all the
functions I consider reusable enough. The documentation is here:
http://protz.github.com/thunderbird-stdlib/doc/symbols/_global_.html .
Unfortunately, jsdoc doesn't allow me to regroup functions according to
the file they belong to, so they're all messed up and in the wrong
order.

Anyway, there's different sections:
- msgHdrUtils.js contains a whole bunch of functions that allow you to
query nsIMsgDbHdrs. Although in the long run, we might want to move
away from that representation, and favor Gloda instead, right now
there's a whole range of things that this function abstracts away from
you: marking headers as read, archiving/deleting them, transforming
them back and forth into URIs, knowing whether they're junk, archived,
etc... Most of these are one-liners, but it takes some time to figure
them out (e.g. msgHdrIsJunk), so that might save other extension
authors some time. Some of the low-level functions expect
nsISupportsArrays, nsIArrays, which is a little bit penible to deal
with, so we're abstracting it for you.
- send.js contains the JS function that performs the message send
process. I think many people will want to use that one, and it will be
overhauled soon as I plug "compose in a tab" into that function as well.
- compose.js contains utilities related to composition: wrapping text,
converting back and forth between text and html, streaming a message
through libmime and getting it quoted, wrapping text...
- addressBookUtils.js is just a set of small wrappers to quickly add a
contact / get a given address book,
- misc.js contains various functions I found useful.

There's also a SimpleStorage wrapper which implements an asynchronous
get/set/has/remove API on top of mozStorage. It has a callback-style
API and an Iterator-yield-style API. The latter is used inside
Thunderbird Conversations. I plan to add a promises-style API soon,
because more extension authors will be familiar with it. Then, I'll
blog about it.

The API will probably be a little bit shaky in the upcoming weeks, but
any comments / feature requests / remarks are most welcome. It
certainly is very rough, but I hope this is a step in the right
direction. I'll probably advertise this bit when I do my presentation
at FOSDEM.

jonathan

Karsten Düsterloh

unread,
Jan 18, 2011, 3:08:48 PM1/18/11
to tb-pl...@mozilla.org
Jonathan Protzenko aber hob zu reden an und schrieb:

> I've spent some time moving out useful functions out of Thunderbird
> Conversations, into thunderbird-stdlib.

How does this lib relate to STEEL?
Will it be part of/extend it, will it replace it?
Or is it Yet Another Lib To Make Things Easier™?


Karsten

Andrew Sutherland

unread,
Jan 18, 2011, 4:40:37 PM1/18/11
to tb-pl...@mozilla.org
On 01/18/2011 12:08 PM, Karsten Düsterloh wrote:
> How does this lib relate to STEEL?
> Will it be part of/extend it, will it replace it?
> Or is it Yet Another Lib To Make Things Easier™?

From my impression, a good summary is that it shares similar goals to
the STEEL concept but is more in-line with our new style of
extension-driven development. Its APIs can be flexible and there are no
worries about breaking extensions using it with implementation changes
because every extension will just ship its own copy of the stdlib.

It is worth noting that this is also how the Add-On SDK (formerly known
as Jetpack) works.

Andrew

Karsten Düsterloh

unread,
Jan 18, 2011, 5:22:53 PM1/18/11
to tb-pl...@mozilla.org
Andrew Sutherland aber hob zu reden an und schrieb:

> Its APIs can be flexible and there are no worries about breaking
> extensions using it with implementation changes because every
> extension will just ship its own copy of the stdlib.

This sounds like looking for trouble, if various extension start trying
to include different versions of the lib into the global namespace -
unless you are very careful when changing its behaviour or its API...


Karsten

Andrew Sutherland

unread,
Jan 18, 2011, 5:31:36 PM1/18/11
to tb-pl...@mozilla.org
On 01/18/2011 02:22 PM, Karsten Düsterloh wrote:
> Andrew Sutherland aber hob zu reden an und schrieb:
>> Its APIs can be flexible and there are no worries about breaking
>> extensions using it with implementation changes because every
>> extension will just ship its own copy of the stdlib.
> This sounds like looking for trouble, if various extension start trying
> to include different versions of the lib into the global namespace -
> unless you are very careful when changing its behaviour or its API...

But no extension should be doing this and this is enforced by the
addons.mozilla.org review guidelines and reviewers. The good news is
that even if the review process does not catch it (the side-effecting
version of Cu.import is not obvious), only extensions doing the wrong
thing will get hurt by other extensions also doing the wrong thing.

Andrew

Karsten Düsterloh

unread,
Jan 18, 2011, 6:05:22 PM1/18/11
to tb-pl...@mozilla.org
Andrew Sutherland aber hob zu reden an und schrieb:
>> This sounds like looking for trouble, if various extension start trying
>> to include different versions of the lib into the global namespace -
>> unless you are very careful when changing its behaviour or its API...

"its" as in "the stdlib we're talking about here".

> But no extension should be doing this and this is enforced by the
> addons.mozilla.org review guidelines and reviewers. The good news is
> that even if the review process does not catch it (the side-effecting
> version of Cu.import is not obvious), only extensions doing the wrong
> thing will get hurt by other extensions also doing the wrong thing.

Huh?
I suspect a misunderstanding here.

Why would amo complain here:
- Addon A ships with v0 of stdlib and loads it in a script tag in a XUL
overlay to, say, messenger.xul.
- Addon B ships with v1 of stdlib and loads it in a script tag in a XUL
overlay to, say, messenger.xul - but v0 and v1 behave differently
although the API hasn't changed.


Karsten

Jonathan Protzenko

unread,
Jan 18, 2011, 6:44:56 PM1/18/11
to Karsten Düsterloh, tb-pl...@mozilla.org
Hi,

On Wed 19 Jan 2011 12:05:22 AM CET, Karsten Düsterloh wrote:
> Andrew Sutherland aber hob zu reden an und schrieb:
>>> This sounds like looking for trouble, if various extension start trying
>>> to include different versions of the lib into the global namespace -
>>> unless you are very careful when changing its behaviour or its API...
>
> "its" as in "the stdlib we're talking about here".
>
>> But no extension should be doing this and this is enforced by the
>> addons.mozilla.org review guidelines and reviewers. The good news is
>> that even if the review process does not catch it (the side-effecting
>> version of Cu.import is not obvious), only extensions doing the wrong
>> thing will get hurt by other extensions also doing the wrong thing.
>
> Huh?
> I suspect a misunderstanding here.
>
> Why would amo complain here:
> - Addon A ships with v0 of stdlib and loads it in a script tag in a XUL
> overlay to, say, messenger.xul.
> - Addon B ships with v1 of stdlib and loads it in a script tag in a XUL
> overlay to, say, messenger.xul - but v0 and v1 behave differently
> although the API hasn't changed.
>

AMO forbids any kind of import into the global scope. So if Addon A
loads thunderbird-stdlib in a script tag in a XUL overlay, this will
add bindings in the global scope and AMO should refuse this.

To take the example of Thunderbird Conversations, thunderbird-stdlib
lives in resource://conversations/stdlib/ and the stdlib imports are
all done in specific js modules, which have their own scope. If you
look at content/overlay.js
<https://github.com/protz/GMail-Conversation-View/blob/master/content/overlay.js>,
you'll see all imports are restricted to a temporary object not to
pollute the global namespace.

I hope this clears the matter! :-)

jonathan

Reply all
Reply to author
Forward
0 new messages