Mar 09

Heading towards Calendar 1.0 Beta 1

The original plan regarding Thunderbird 3 Beta 2 was to release a beta of Sunbird/Lightning that fits together well. Due to other obligations this goal has slipped quite a bit. We have tagged the list of blocking bugs by bugs needed for the beta and those we can move into the next beta.

Currently, there is only one bug left that we really need to solve for this beta. It has a preliminary patch and will require string changes. Unfortunately, the mentioned bug is not quite trivial, since a lot of UI changes need to be done and we haven’t quite agreed on some aspects.

This means we will announce a string freeze as soon as the bug has been fixed and release 2 weeks afterwards, or sooner if all strings have been translated earlier.

Nevertheless, we’d like to provide a beta as soon as possible. To help make this possible what we need most at the moment is testing! Please download Thunderbird 3 Beta 2 at:


And our latest nightly version of Lightning:


Be sure to back up your data before using this version, since it upgrades your local storage database. Downgrading is not easily possible afterwards without creating a new profile.

IMPORTANT:Note however as we’ve announced in an earlier blog post this will be the last release for the time being that includes Sunbird. This means that now more than ever, testing is needed to make sure that Sunbird doesn’t contain any critical bugs.

If you want future Sunbird releases to happen and either have experience with the Mozilla build architecture or are willing to learn, please do send me an Email and I’ll send you some information to get you started.

We will make an effort towards releasing more beta versions of Lightning on the road towards 1.0 to make sure the next release will be as bug-free as possible and still contain the nice new features we have been working on. Remember that we need you to fulfill this goal! Without your valuable testing, we will surely be up for a surprise in case a critical bug has made it into the final version without notice.

Mar 09

Scalable OpenGroupware.org 1.0 released

I just wanted to let you know that our friends over at Scalable OpenGroupware.org (SOGo) pushed out their 1.0 release yesterday.

Congratulations fellas!

SOGo is a free scalable groupware server. It offers shared calendars, address books and emails through your favorite Web browser or by using a native client such as our Mozilla Thunderbird with Lightning. SOGo is standard-compliant and supports CalDAV, CardDAV, GroupDAV and reuses existing IMAP, SMTP and database servers.

The SOGo developers are good friends of ours and have helped us with developing Lightning today and in the past. So give their software a try! I’m sure they will appreciate it.

You can download their server software here. The source code is also available.

Mar 09

Support the Calendar Project with a donation

One of the most often made statements within the last few years from our users and supporters was that people would really like to support us by donating a few bucks to the Calendar Project.

That wasn’t possible until now. But thanks to the Mozilla Foundation and the efforts of its employees, particularly David Boswell, it’s now finally possible to support the Calendar Project by donating to our cause.

All the necessary details are on our donation web page. You can support us via:

  • a one time donation online (using Paypal or a Credit Card)
  • a recurring donation each month (using Paypal or a Credit Card)
  • a personal check

If you are a regular user of our software, please consider donating to our cause.

Thanks in advance
The Calendar Project team

Mar 09

Philipp’s Developer Notes: Using JavaScript 1.7 Iterators to simplify code

The list of new features in JavaScript 1.7 have been out for a while but only since the move to Trunk (Gecko 1.9.1 codebase) have we taken a look into it.

The concept of iterators is nothing new, the way they are implemented in JavaScript initially confused me. Consider the following bits of code:

function range(begin, end) {
for (let i = begin; i++; i < end) {
yield i;
let it = range(10, 20);

What is this!? A function with a loop that doesn’t return anything and contains a strange statement called yield? Without much reading, my next though was: why does |it| contain anything? Shouldn’t |it| be undefined? The function doesn’t return anything, so why should yield make a difference?

I guess the return “issue” just takes a bit getting used to. Most iterator functions are very small, so |yield| should be easy to spot. Now I’d like you to see why this strange construct is indeed very useful. Consider this (old) bit of code. It was used when turning an ICS string into an item:

for (var attprop = icalcomp.getFirstProperty("ATTENDEE");
attprop = icalcomp.getNextProperty("ATTENDEE")) {
var att = new CalAttendee();
att.icalProperty = attprop;

A multi-line for() looks very cumbersome even aside from the fact that the different line lengths make it harder to read, don’t you think? Now lets see what magic we can do with iterators:

for (let attprop in cal.ical.propertyIterator(icalcomp, "ATTENDEE")) {
let att = cal.createAttendee();
att.icalProperty = attprop;

You’ll notice a few things changed. The loop now uses the newly introduced property iterator and only one line (even though its a bit longer). You’ll also see use of the new “cal” namespace, which probably deserves its own blog post. While this may look like a minimal change please consider a lot of such for loops are used when turning an ICS string into an item. Also I feel this makes the formerly quite native code pattern (getFirstXXX, getNextXXX) fit more naturaly into JavaScript.

We can go even further, using more language features of JavaScript 1.7. This bit of code used in the same context:

this.mCategories = [];
for (var catprop = icalcomp.getFirstProperty("CATEGORIES");
catprop = icalcomp.getNextProperty("CATEGORIES")) {

Can be compromised into a single line, using iterators as described above and array comprehensions:

this.mCategories = [ catprop.value for (catprop in cal.ical.propertyIterator(icalcomp, "CATEGORIES")) ];

I’ll admit this line is a bit long. I have found no sensible way to split it, comments welcome. You’re surely interested how to create something that can be used as an iterator so that you can use it in your own code. I’ll give you the source for the above cal.ical.propertyIterator:

function cal_ical_propertyIterator(aComponent, aProperty) {
return {
__iterator__: function icalPropertyIterator(aWantKeys) {
cal.ASSERT(aWantKeys, "Please use for() on the property iterator");
let propertyName = (aProperty || "ANY");
for (let prop = aComponent.getFirstProperty(propertyName);
prop = aComponent.getNextProperty(propertyName)) {
yield prop;

Looks quite similar to the old code, doesn’t it? The concept is quite simple. We return an object that implements the special __iterator__ method. This is where we put the old loop code. Then we “yield” the value that should be availibe in our new loop code. The argument aWantKeys differentiates if only the key is wanted or not. If the iterator is used in a for() loop, then aWantKeys is true. If it is used in a for each() loop, then the argument is false.

for (let key in myIterator()) {
// A for(...in..) loop goes through all keys in the array or iterator.
// The aWantKeys argument is true.
for each (let [key, value] in myIterator()) {
// Standard object iterators return an array with key and value
// when aWantKeys is false.
for each (let value in myOtherIterator()) {
// Some iterators prefer only returning the value in this case.

The above code is of course only an example. You are of course free to return anything you want in your iterator.

Note that you can use the __iterator__ on any object, it doesn’t have to be an object that has no other properties.

function calPropertyBag() {
this.mData = {};
calPropertyBag.prototype = {
mData: null,
__iterator__: function cpb_iterator(aWantKeys) {
for (let key in this.mData) {
yield (aWantKeys ? key : [key, this.mData[key]]);
/* In this case, instead of the above you can shorten this iterator to:
return Iterator(this.mData, aWantKeys);
/* Also implement other methods like setProperty,deleteProperty,... */

See how this basic property bag now has an iterator that can be used directly? Without the iterator, using this code:

var bag = new calPropertyBag();
for (let key in bag) {
dump("Key: " + key + "n");

Would give you all keys in the object: mData, setProperty, deleteProperty and so on. With the new iterator, the above code would rather give you the actual properties in the bag, since the __iterator__ yields all keys in this.mData.

I hope this inspires you, regardless of if you are working on a Sunbird/Lightning extension, or any other piece of Javascript code for that matter. Please do feel free to correct me, I’m quite new to these features so not everything might be 100% correct.

If I come across more new langauges features, I’ll keep you posted!

Mar 09

Lightning is an unusual Mozilla application

Since the start of February, the statistics capabilities of addons.mozilla.org have been upgraded. It is now possible to see the number of active users on a daily basis, where before it was only shown on a monthly basis. This shows some interesting facts about Lightning.

What is pretty apparent from the stats is that Lightning’s usage is much higher during the week than on the weekend. This is a stark contrast to Mozilla’s main application Firefox, which is usually used by more people on the weekend than during the week.
[UPDATE: As I was informed, Firefox’s usage numbers are also much higher during the week than on the weekend. It seems that I mixed up Firefox’s market share numbers (which are normally higher on the weekend than during the week) with its total usage numbers.]

On Windows the usage numbers during the week are about twice as high as on the weekends, while on the other operating systems (Linux, MacOS X, Solaris, *BSD, OS/2) the usage numbers are just about 30% – 40% lower on the weekends.

This seems to indicate that we have a lot of business users out there using Lightning and that most of these business users use Windows as their platform of choice.

What we also see is that roughly 87.5% – 89.1% of our users are on the Windows platform, 7.6% – 8.6% use Linux and 3.1% – 3.8% are MacOS X users. Users of other operating systems range between 0.13% and 0.16%.

Those of you, that want to play more with our download numbers, can do this on the Lightning Statistics Dashboard, where you can find much more data to play with.

PS: Don’t ask me about the low numbers on five days in early February. These are clearly incorrect and probably a result of an addons.mozilla.org bug, that was fixed later on.