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
Just an idea,
Patrick Cloke
[1] https://developer.mozilla.org/en/Toolkit_API/STEEL &
https://developer.mozilla.org/en/Toolkit_API/FUEL
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.
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
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
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
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
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
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
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
"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
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