At the moment If you want to run a bleeding edge version of Thunderbird, you need to choose between running 3.2x and 3.1x builds. In fact, it appears that most people willing to run bleeding edge are now running 3.2x builds.
Whilst our most dedicated testers are running 3.2x builds, the engineering team is working on bringing features and bug fixes to the 3.1x branch. There's a discrepancy here. This means that the issues that might exist in 3.1x have a greater chance to be discovered after releases rather than before. It's easy to fix that, instead of running 3.2x builds, we would like our bleeding edge user to use the 3.1x builds (you can find them at http://ftp.mozilla.org/pub/mozilla.org/thunderbird/nightly/latest-comm-1.9.2/). By doing this simple switch you'll help to make the 3.1 series a great series.
Here's a summary of SeaMonkey/Mozilla-related work I've done in week 05/2010 (February 1 - 7, 2010):
Releases:
I prepared SeaMonkey 2.0.3 builds, which are now available on FTP as well as the beta update channel for testing by our community, offering well over 100 bug fixes. If things go well, we should be able to release this update in sync with Firefox 3.5.8 on February 16th.
The 2.0.x nightlies now carry a 2.0.4pre version number, but we have no firm schedule for the following updates yet (will coordinate with Firefox, possibly also Thunderbird drivers on that).
Work on 2.0.3 also included putting up a first version of the release notes.
I also tried to let the release process generate 64bit builds for Linux this time, those are fully experimental and will only appear as "contributed" builds though, they have no official status at all.
Build Infrastructure:
The move of our core buildbot master code to a shared location could be completed, Thunderbird will look into using the same code in the future and we closely mirror the Firefox setup now, making it easier for people patching their side to fix ours as well (and the other way round). Revision reporting on packaged tests is now both generic and respecting applications that are built from different repositories as the platform (like SeaMonkey or Thunderbird).
Additionally, I continued working with Mozilla teams to get SeaMonkey data up on the graph server, which needed a firewall rule and a correction on the staging server's database, but testing looks good now and we should be able to go live on the real server soon.
Download Progress Windows:
I created screen shots of some additional proposals for improving the progress windows, requested ui-review on them to see which one wins out with our "UI tsar", and finally implemented the winning proposal in a patch, which should be very close to positive review by now.
Build System, Packaging:
After a few runs on the Mozilla Messaging try server, I could finalize the patch for merging our package manifests and also make Mac use a manifest, get reviews and check it in.
Another patch I worked on is about making branding usage fit Mozilla standards more closely, which should also ease the life of people wanting to ship suite versions with a different branding than the official "SeaMonkey" trademark designs.
Some discussions about build system variables reminded me that I should re-test and attach the papering-over patch for mailnews Qt port bustage which I've had locally for quite some time now.
SeaMonkey L10n:
Starting with SeaMonkey 2.0.3, the language packs are marked compatible with all 2.0.* versions.
Also with this release, Japanese is joining the collection of officially available localizations.
This was also the first time I played with and used the new L10n sign-off dashboard for a release - further opt-ins / sign-offs for SeaMonkey 2.0.x will all run through this tool now. See the m.d.l10n thread for more details on using this tool.
Various Discussions:
2.1 planning discussions, Alpha 1 and further steps for 1.9.3, Gecko 1.8.1.24 and SeaMonkey 1.x EOL, KompoZer integration work, new machines, FOSDEM, places history changes, module ownership, mozilla.org planning and "Mozilla" vs. "Firefox" websites, EOL for Mac OS X 10.4 "Tiger" on 1.9.3, langpacks and switching, etc.
I may not have posted a lot of Mozilla-related blog posts this week, but I got around to do quite some actual work. I wondered for a bit if I should post separately about the progress window work, but the ignorance of hard work I have been and am putting into those tiny windows as well as the vitriol from people who can't stand designs being modernized made me decide not to mention this work much. I know that it needed my work to even have progress windows at all in SeaMonkey 2.0 and I'm convinced that my current proposals and work can fix some of the shortcomings I had already know when doing the initial work and that were criticized by users, but a number of those users seem convinced that our team (especially myself) is not caring about what they say at all, so I don't feel like taking their dreams away. And the attempt of humor in the title of my post about the initial work was not well-received as well. In any case, I feel an obligation to improve work I started, but discussions with those users have taken any fun out of working on this part of the code. Maybe my rare tries of actually doing some coding should stay that rare or even stop completely. It's not like I wouldnj't have enough other work on my TODO list.
Good news, for localizers. With the new release of the l10n dashboard, co-developed by Pike (Axel Hecht) and Gandalf (Zbigniew Braniecki) we're killing off the opt-in threads for localizers.
Every localizer should take a close look at all the functionality that the new dashboard exposes. There is also a 5-minute screencast, that hopefully guides you through some of the new features.
We'll start to use this new functionality once Thunderbird 3.0.2 is out of the door. So Thunderbird 3.0.3 and onwards as well as Thunderbird 3.1 beta1 will be our starting points.
Now that we're moving full-steam towards the Lightning 1.0 beta2 release, it's also time to make clean slate and show you in terms of fixed bugs, what has happened since the last status update back in late November 2009.
Overall we have fixed an impressive 55 bugs since then, keeping in mind the whole release process hassle, the holidays and Philipp's exam schedule. Here's the complete list of fixed bugs:
I almost can't believe it - even though I really do believe in the New Orleans Saints.
When they Saints go marching in.... Too bad I can' beam over and be on Bourbon Street this night. It surely is being flooded - by cheers this time, by partying, by celebration. The "fleur de lis" made it to Football heaven!
This is a victory not only for an astonishing team, it is a victory for the whole city and people people who cherish it, restore it and rebuild it by investing their hearts in it. I've been there, and I felt what a great city it is. And I'll come back, that's a promise.
In the end, Peyton - that son of New Orleans area who has grown to be one of the greatest quarterbacks up there in Indy - could not outcoach and outcall Mr. Payton. The coach on the field needed to give in to the team he usually cheers for, a team with many great people - Payton, Bush, Porter, Vilma, and of course their own quarterback - they call him the Brees...
I'm not sure I really have fully realized that "my" Saints have actually done it and WON the Super Bowl in their first attempt ever to do so.
Some people have already noticed that we no longer release nightly builds that support Thunderbird 3.0 and SeaMonkey 2.0. As of January 31st, our nightly builds will no longer live in the latest-comm-1.9.1 folder, but in the latest-comm-1.9.2 directory.
The main difference between the 1.9.1 builds and the 1.9.2 builds is, that the latter will only support nightly builds of the Thunderbird 3.1 and the SeaMonkey 2.1 development branch. This also means that our next Lightning release (1.0 beta2) will not support Thunderbird 3.0.x and SeaMonkey 2.0.x and users of those releases will have to update to be able to get the latest Lightning release then. For now, users that want to test the latest Lightning fixes should either download Lanikai 3.1 alpha1 or a recent nightly build of Thunderbird (also called Shredder) or SeaMonkey.
The reason for this decision is (again) one of (developer) resources. Currently the following development areas/branches are available to us:
The comm-1.9.1 branch, where development for Thunderbird 3.0 and SeaMonkey 2.0 took place.
The Gecko 1.9.2 branch (home of Firefox 3.6) that in combination with the (soon to be created comm-1.9.2 branch) will be the basis for Thunderbird 3.1, which is currently scheduled for a release in April 2010.
The so called trunk, on which the release after Thunderbird 3.1 will be developed. The SeaMonkey folks are targeting the trunk for their 2.1 release.
With our current resource situation we are not able to fully support all three areas/branches. We have therefore decided to only fully support the Gecko 1.9.2 branch and give a somewhat limited support to the trunk. Those of you who want to follow our work are encouraged to download the Lightning Nightly Updater add-on, which should make updating Lightning much easier for you.
Four weeks ago we released Lightning 1.0 beta1. At the time we also said, that we would make a 1.0 beta1 release available for Sunbird as well, the last Sunbird release from us as previously announced.
Now what's holding it up? The answers are: technical stuff and real life. To elaborate more, we're still having problems to produce the Sunbird 1.0 beta1 release builds in all our supported locales. The only two people who could fix that (Philipp and Gozer) are either too busy because they have to learn for their university exams (Philipp) or too busy, because they have to work on getting other (higher priority) releases out of the door (Lanika 3.1 alpha1 and Thunderbird 3.0.2).
The good news is that Philipp's exams will be done in the coming week and Gozer's main time consumer is either already done (Lanikai 3.1 alpha1) or will be done from his side in the coming week (Thunderbird 3.0.2). So expect a Sunbird release shortly thereafter.
This series of blog posts discusses the creation of a new account type implemented in JavaScript. Over the course of these blogs, I use the development of my Web Forums extension to explain the necessary actions in creating new account types. I hope to add a new post once every two weeks (I cannot guarantee it, though).
In the previous blog post, I gave a broad overview on the overall structure of the backend interfaces and the components of account implementation. Now, we will prepare the necessary components of getting your extension's folder displayed in the folder pane.
Account implementation decisions
Before you start implementing, you have to decide how to structure the account. The first decision is what the internal account type will be. This
will be the value of nsIMsgAccount::type and will dictate the contract IDs for several interfaces. The next decision is what the account URI scheme is. This will be the scheme for the URI and dictates the contract IDs for a few more interfaces; for mailbox accounts, this scheme will be mailbox. For my extension, I have decided to choose webforum for both of these.
Another important decision to make will be the server for which you will be doing most of your initial tests. It should be something that is manageable for debugging purposes. In my case, I've decided to bestow this honor on the
Kompozer web forum, because it seems lower traffic than any other forum I'm reasonably interested in. As you may notice, I am starting my extension with the intention of focusing on phpBB access—it's sufficiently widely used that I expect that only supporting phpBB at first would still make a worthwhile extension.
Once you have decided that, you should take the time to study how things will be structured: what determines a folder? What determines a message? A thread? Replies? How are you going to be carrying out new actions, such as checking for new messages? What internal information are you going to need to save for accessing? Heck, what determines the "server" to begin with? In my case, the DOM inspector is an invaluable tool for answering this questions. Don't worry about how to figure out the list of possible subscribable folders yet. Subscription will come into play much later; we are going to start by just hardcoding this list somewhere.
In my case, I am choosing to structure the folders as a Category → Forum hierarchy. I'll pick a few of the smaller forums to use so I don't overwhelm debug logs.
Implementing protocol information
Since nsIMsgProtocolInfo is the shortest and simplest of the interfaces, let me start by implementing this one. There are a total of 12 attributes and 1 function on this interface, so the code will not be hard to write. Following is an implementation of the code [1]:
wfService.prototype ={
contractID:["@mozilla.org/messenger/protocol/info;1?type=webforum"],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMsgProtocolInfo]), // Used by the account wizard and account managerget defaultLocalPath(){let dirSvc =Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);let file = dirSvc.get("ProfD",Ci.nsIFile);
file.append("WebForums");if(!file.exists())
file.create(Ci.nsIFile.DIRECTORY_TYPE,0775);return file;},get serverIID(){returnCi.nsIMsgIncomingServer;},get defaultDoBiff(){returntrue;},get requiresUsername(){returnfalse;},
getDefaultServerPort:function(secure){return-1;},get canDelete(){returntrue;}, // Used by UI codeget canLoginAtStartup(){returntrue;},get canGetMessages(){returntrue;},get canGetIncomingMessages(){returnfalse;},get showComposeMsgLink(){returnfalse;},get specialFoldersDeletionAllowed(){returnfalse;}};
The meaning of each of the attributes can be found in more detail on the MDC page. The properties used by the account wizard mostly control initial preference values; those used by the UI code mostly control which UI elements are enabled. I have excluded from the implementation also those attributes which are unused.
Perhaps the most leeway you have is in implementing defaultLocalPath. In this case, I have adapted the RSS implementation, which does not allow users to change this location. The other implementation (used by IMAP, POP, NNTP, Movemail, and Local Folders) uses a preference to return the default path. An example implementation of this method
is like thus:
get defaultLocalPath(){ // This will probably be found in the constructorthis._prefs =Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch("extensions.webfora."); // Preference looks like [ProfD]WebForumslet pref =this._prefs.getComplexValue("rootDir",Ci.nsIRelativeFilePref);return pref.file;},
Once you have completed that, you should test that the service implementations work as expected via test snippets in the Error Console. The account manager can be mean when it comes to unusable
account types [2], so this will help fix the most obvious bugs before the account manager attempts to do it for you.
Server and root folder discovery
Before I start going any further with code, let me take a minute to explain how servers and folders interact. The server objects themselves do surprisingly little in the UI; the most common property calls are probably rootFolder and type. This even includes
what you might think of as server attributes: the bold display name, has new messages treeview properties, etc. Instead, those features can be found on the root folder, which is a "fake" folder object. Most of what we care about in this part happens on the root folder instead of the server; however, if you browse the implementation in nsMsgDBFolder, you can see that some of the property calls get forwarded back to the server for root folders.
The backend code will create server objects early on and hold onto them for the duration of the program (or until they are deleted). The server objects then create the root folders which then create subfolders as necessary. Links that go backwards (parent links and server links) are weak references to avoid refcount cycles. Most of this work is hidden in nsMsgDBFolder for you. After creation, various properties are accessed at will; some properties will be loaded in from the database info (a topic for later).
In more concrete code terms, the following is the steps in loading the
folder pane:
The account manager loads the mail.accountmanager.accounts preference; the values here are a comma-separated list of account keys.
For each account key, an account is instantiated. Per-account data is read off of the mail.account.<key> preference branch; in specific, the server preference contains the server key to load and the identities preference is a comma-separated list of identity keys.
The identities and servers are then bootstrapped. In the case of servers, the server is created as an object with the @mozilla.org/messenger/server;1?type=<type>
contract ID. The server pref branch is mail.server.<key>; key preferences here are type, the type for the contract ID; userName, the (optional) username of the server; and hostname, the (required) host of the server.
The account manager sets the key, type, username, and hostName properties, in that order on the server object instance and then retrieves the port property. The (type, username, hostName, port) tuple is the unique identifier for a server: no two servers can have the same
combination of these values. Now your server is constructed and returned to the folder pane.
The folder pane retrieves the rootFolder of your server. If you happened to be saved in the expanded state, subFolders is recursively retrieved from folders as corresponding to the saved open state. The folder pane also calls performExpand() on the
server if the root folder is expanded.
So that explains how your server gets created; how do your folders get created? nsMsgIncomingServer::GetRootFolder[3] calls nsMsgIncomingServer::CreateRootFolder, which calls serverURI and uses it to construct an RDF resource. serverURI creates a URI of the form localstoretype://[<username>@]<hostname> by default. This URI is actually the URI of your root folder; other code will assume that this invariant holds true (especially subscribe!). Other folders are created when you get the subFolders property. When the
folder URI is parsed (which is pretty much the first time a useful property is called), getIncomingServerType is called to get the type of the server.
In summary, you may need to implement localStoreType and possible serverURI on your server, and subFolders, and getIncomingServerType, and CreateBaseMessageURI on your folder [4]. First we'll start by getting the root folder display working:
At this point, I recommend you again check to make sure resources are properly registering via the Error Console. With that in hand, it's time to modify your preferences manually. I personally recommend changing settings via editing prefs.js while Thunderbird is off so you
don't accidentally confuse the account manager. I'm using the keys account99 and server99 to make it plain which account is being edited. First, I copy the mail.identity.id3 pref branch (any identity would do) and change the id3 to id99. Then I copy the mail.account.account3 pref branch and change the 3's to 99's.
The next changes are the server preferences, which are going to be the most unique. directorydirectory-rel are set to a folder where I want to store stuff ([ProfD]WebForums/kompozer, in my case). download_on_biff and login_at_startup are set to false (to avoid
dealing with biff for a bit longer). name is set to be the display name of the server. hostname and userName were set to the appropriate values for this account [5]. To the preference mail.accountmanager.accounts, I appended account99. With those changes done, I then start up Thunderbird to see the outcome:
Perhaps I should have chosen a shorter name for display.
Folder discovery
Now that the root folder is displayed, we need to get the folders added to the display pane.
Somehow, we need to figure out what the folder hierarchy looks like—it has to be stored in some file, in other words. The NNTP code uses the newsrc file to store its folder tree, and local folders looks at the directory hierarchy for its map, to name two examples.
In my code, I'm going to choose the use of a JSON file to store this data. I've considered SQLite, but I don't really need synchronization (per-server files work nicely here), and I'm mostly doing simple lookups. Plus, I can probably handle automatic schema migration more easily in SQLite.
For this next part, we concentrate on a single property: subFolders. This function typically has two parts: it first checks for initialization (if so, it returns the enumerator to the stored values); if it's not initialized, the rest of the function, or perhaps a second function altogether, is used to create the subfolders.
Some code to initialize these subfolders is as follows (the logic to retrieve the database is not included and can instead be found in the source code for my extension):
get subFolders(){if(this._folders)return array2enum(this._folders);// If we're here, we need to initialize.this._inner.QueryInterface(Ci.nsIMsgFolder);let serverDB =this._inner.server.wrappedJSObject._db;// Uninitialized -> no subfoldersif(!serverDB.categories)return array2enum(this._folders =[]);// First find our levellet level =/* some logic */;let URI =this._inner.URI +'/';let folders =[];// Yes, we still use RDFlet RDF =Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);let netUtils =Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsINetUtil);for each (let sub in level){// Some URIs may contain spaces, etc. -> escapelet folder = RDF.GetResource(URI + netUtils.escapeString(sub.name,Ci.nsINetUtil.ESCAPE_URL_PATH));
folder.QueryInterface(Ci.nsIMsgFolder);.parent =this;
folders.push(folder);}this._folders = folders;return array2enum(this._folders);}
There are a few major things to note. First, the new folders are created via the RDF resource. Both Thunderbird and SeaMonkey use RDF for folder access, so it is still a good idea to create via the RDF service so you don't confuse the caller code. Also, with that in mind, the subfolder name still needs to be escaped as well in the URI, hence the calls to nsINetUtil. The auxiliary function array2enum takes in a JS array and returns a proper nsISimpleEnumerator for the array. I've excluded it's definition here do to its simplicity and the length of this document; if you want to see it, you can view it from the extension source code. The last thing to note is that this code is using this._inner: this variable is a link to the nsMsgDBFolder implementation which was created for us by the JSExtendedUtils inheritance call. I will defer a more thorough treatment of this C++-JS glue until later.
Folder pane extras
At this point, you should have a simple, plain folder hierarchy, which is navigable if not fully usable. In terms of UI, though, it's not quite fully perfect: if you have an inbox, it will be rather indistinguishable from other folders; similarly, "fake" folders (think the [Gmail] folder if you have Gmail IMAP) show up as regular folders. These things are handled to a large degree by CSS.
I would provide some example styling code here, but when I was doing testing, I discovered some related assertion failures that I have not yet had time to grok. In the interest of keeping to a posting every two weeks, I am going to defer this until either a mini "part 1.5" or the beginning of part 2, depending on how much time I will have available next week.
Notes
I will not, in general, post the full code for any of the classes, only enough to demonstrate what needs to be done. For example, the classID property is omitted in this example. Something to note is that I have a modification to XPCOMUtils locally that will accept arrays of contract IDs as opposed to a single one (wfService will be implementing more than one contract ID).
What it specifically does is attempt to get the server; if it fails, then it removes the account from the accounts pref. If you are compiling your own builds for your extension development profile, I recommend you remove the lines in nsMsgAccountManager::LoadAccount that remove the account on failure.
In general, I will mix the IDL and C++ names for methods and properties in the course of the guide. As a basic rule of thumb, if you see a :: in the name, it's a C++ name; otherwise, it's the IDL name.
getBaseMessageURI is a local function called by nsMsgDBFolder during initialization that is used to set up the URIs for getting individual messages. This function will be covered in more depth as we get messages working, but it is technically necessary for startup (a stub that does nothing is provided).
A strong temptation for accounts whose sources are some web address (for example, RSS or my web forums account) is to put the base address as the hostname property. However, as you would quickly realize, that plays havoc on URI parsing, and nsMsgDBFolder::parseURI is not virtual. A better option would probably be to leave the hostname as some identifier that you use only for guaranteeing uniqueness and to store the base URI somewhere else. Since all of my folders have independent URIs associated with them, I can safely ignore the issue until account creation and subscription are covered.
Thanks to hard work by a whole bunch of folks, we shipped Lanikai Alpha 1 (the first development release of Thunderbird after 3.0) yesterday. More details about Lanikai can be found on the project page.
This release is a first in several notable ways:
* we're now requiring automated tests to land with most code changes
* the release cycle was much shorter than any development release in recent memory
* we're now having to do development and releases across both a development and a stability branch.
We've already learned a bunch of stuff from all the changes, and I expect that learning to continue for a little while before we're fully in a groove.
Thanks to everyone who has been part of making the release happen!
Recently I’ve been talking to Bryan about how we can differentiate between Unread and Read messages. Before we were simply using background colors to indicate old vs new. We felt this created too much of a responsibility to mark everything as read, and wanted something more subtle. We decided to leave the background color white no matter what, and simply change the way information is presented in older messages. We also make a subtle but obvious change in the opacity of the message title in older messages.
A message appearing as unread. We display full information, preview the message body, and thumbnail attachments.
The same message appearing as read. We display less information, cut out the message body preview, and summarize attachments.
An even more compressed version of a read message.
Six years ago, the lowly Bush administration announced a short-sighted, uninspiring view for human space "exploration" that got titled "to the moon, mars and beyond" in NASA marketing speak later on.
But the tables have turned - the US has an inspired, bold visionary as their new president, who already earned a Nobel Prize for his great achievements in bringing around world peace once and for all. While he backed the old, short-sighted plan for some time last year, he and his administration now goes for the next step and did set up a new, bold vision that will surely inspire thousands of people and give new hope: Humanity will go nowhere!
I think that's finally a clear word and a good way, we all know that we have no business in exploring new worlds or achieve extreme things, we should stick to ourselves and boldly envision to change nothing. Even if some yesterday-minded people like Astronaut Ron Garan still believe the moon is valuable, or that the only chance for long-time survival of the human race is to make sure we can live outside of Earth, as Stephen Hawkinglikes toput it, those doubters will soon be gone and everyone will cheer for the strong and life-worthy future our all-beloved world leader has dared to set our directions to.
The task set up for public administration is not to boldly go where no private enterprise would, or to lead the world in science and exploration, but to trash already-started promising programs like Constellation and let others do the jobs Kennedy and Bush have wrongly envisioned for NASA. China and India surely agree as well, as they finally have a chance to overtake the US in space exploration and rip away the dreams of those lowly capitalists that still see a Captain Kirk in the future of this world - well, the interplanetary ships might come, but under a strong communist Chinese leadership, possibly backed by Russia.
Obama did come into office with a strong promise of "Change", and we surely are seeing what he was meaning all along. We don't need to go to just "to the moon, mars and beyond" - now we finally have a bold new vision to go... nowhere!
And we, as space enthusiasts and future-orientated humans, fully support NASA in fulfilling this mission.
I’ve embarked on an effort to investigate adding support for Exchange server to the mailnews code. Although Exchange in Windows has traditionally used port 135-based protocols, my understanding is that the future for them is SOAP-based Exchange Web Services (EWS). As a first step, I wanted to get a basic SOAP library working in current mailnews code.
I considered a variety of approaches to this. One extension “Asertiva Thunderbird Extension for Sugar” uses the IBM/Prototype js library for SOAP access. Others recommended that I consider one of the open source SOAP libraries, such as a python-based library, or Apache’s AXIS2 library. Or that I cooperate with the existing project to provide an open-source method of accessing Exchange server.
But I’m not sure of how “open source” I want all of this to be. From my perspective, “open source” as a charitable activity is not successful. We all need to eat, and so the revenue model needs to be clear if a project is going to be more than a phase of life I am going through at the moment. So I would rather keep my options open until I understand that better. Anyway, that’s a long discussion which is beyond the scope of the current posting, which is supposed to be a status update.
I am still in an education phase, trying to understand SOAP and the related protocols, and to figure out what exactly I gain from using any existing library versus doing things more directly from the raw XML. So as both a trial and education step (and against the recommendation of others I might add) I’ve tried to update the old Gecko webservices extension to work in current Gecko 1.9.2, and to work with some current Microsoft SOAP protocols.
Rather than start with EWS, I started with the simpler BING search calls. I used existing Microsoft demos in C#, and could capture the communications using Wireshark to see what I was supposed to be sending and receiving.
Updating the abandoned webservices extension to Gecko 1.9.2
After testing webservices some under an old Firefox 2 build, I upgraded portions of the code to work under a current comm-central trunk build, using Gecko 1.9.2. My requirements are somewhat simpler than the original extension:
Most importantly, my target is chrome-based extensions rather than browser code, so a lot of the security issues that FF folks worried about were not important to me.
I had no interest also in allowing native JS creation of components, as I could rely on using .createInstance calls instead.
At least initially, I am not supporting the reading of wsdl files, nor the associated automatic creation of proxy calls and interfaces. Instead, I read in a schema file, and generate my own code for each method. My understanding is that Microsoft, in their EWS libraries, also does not actually automatically generate method calls from a WSDL-based proxy, but follows this same approach of starting with the schema files.
That allowed me to avoid about half of the existing code, and focus on the /schema and /soap directories of the webservices extension.
Looking at my hg logs, it took one week of development time, and 17 patches to get to the point where I could write a unit test under Gecko 1.9.2, and confirm that I could create webservices components using a unit test. (I’m doing things in a test-driven development fashion, writing XPCSHELL unit tests to try out different features of webservices.)
Learning and testing Gecko webservices
Although there was a little old documentation around on Gecko webservices, ultimately I just needed to learn things the old fashioned way, reading the code and its interfaces and experimenting to see what worked. I took little baby steps, starting first with an XML schema primer and eventually working my way toward duplicating the functionality in some Microsoft Bing search demo C# code. This phase, starting from the first demonstration of loading of SOAP components under Gecko 1.9.2 through testing of encoding and decoding of a Bing search message, took about 2 weeks of coding and 23 patches, with the creation of 22 unit tests in the process.
The main issue that I had to deal with in the existing SOAP code is that it did not support maxOccurs>1 schema types, such as this one from the Bing schema:
I solved this by using an nsIArray to hold multiple values of the same element.
Sample Code
So now I can do a Bing search in an XPCSHELL test, and decode and test the results. I want to show some of the js that I use, to give some idea of the complexity (or lack thereof) of using this.
I create a class BingSearch, then encode some values to setup the search. A basic call for a search looks like this:
The “BingSearch” object is presumably what a sophisticated library would create automatically from the WSDL file. Instead, I create it by hand. Here’s my partial implementation, that does not support all of the allowed inputs to a Bing search, but works for my tests:
function BingSearch()
{
// defaults
this.Version = "2.0";
this.AppId = "<you get this from Microsoft for your application>";
this.Market = "en-us";
}
BingSearch.prototype = new BingBase();
BingSearch.prototype.invoke = function BingSearch_invoke(aSOAPResponseListener)
{
let parametersBag = objectPropertyBag({
Version: this.Version,
Market: this.Market,
Query: this.Query,
AppId: this.AppId,
Options: arrayPropertyBag("SearchOption", this.Options),
Sources: arrayPropertyBag("SourceType", this.Sources),
News: objectPropertyBag(this.News)
});
// soap message component
let soapCall = Cc["@mozilla.org/xmlextras/soap/call;1"]
.createInstance(Ci.nsISOAPCall);
let parameters = [];
parameters.push(new soapParameter("parameters",
parametersBag,
this._schema.getTypeByName('SearchRequest')));
soapCall.encode(Ci.nsISOAPMessage.VERSION_1_2,
'SearchRequest',
this._schema.targetNamespace,
0, null, // header blocks
parameters.length, parameters);
soapCall.transportURI = "http://api.bing.net:80/soap.asmx";
soapCall.encoding = this._encoding;
soapCall.asyncInvoke(aSOAPResponseListener);
}
const kSchema = {
file: 'data/bing20.xsd',
schemaNamespace: 'http://www.w3.org/2001/XMLSchema',
targetNamespace: 'http://schemas.microsoft.com/LiveSearch/2008/03/Search'
}
function BingBase()
{
if (typeof this._schema == "undefined")
{
this._schema = getSchema(kSchema);
// use the 2001 SOAP encoder
this._encoding = Cc["@mozilla.org/xmlextras/soap/encoding;1"]
.createInstance(Ci.nsISOAPEncoding);
this._encoding.getAssociatedEncoding("http://www.w3.org/2001/09/soap-encoding", true);
this._encoding.schemaCollection = this._schema.collection;
}
}
So far, the complexity of this does not seem unmanageable to me. I’ve only shown the endoding step. Decoding the response consists of a creating a call-specific translator similar to the “BingSearch.prototype.invoke” function above, which relies on the webservices soap library decode method. All of the other functions I’ve created (such as arrayPropertyBag) are not at all specific to the nature of the SOAP interface being used. I am not seeing the need to process the WSDL file automatically and generate proxy functions.
I’m not yet convinced that this resurrection of the old webservices library is the right approach, but I am not seeing any obstacles to using it either. I can generate and decode soap calls fairly efficiently, debug issues that arise, plus I have code that will integrate fairly easily with either javascript or C++ code in a Gecko chrome environment.
Next steps
I’m trying to decide on the next step toward moving this forward. I’m leaning toward attempting a specific EWS application, such as read-only access to an Exchange calendar as a Lightning extension. Another option might be to add some core mailnews hooks to allow me to create either message accounts or addressbooks using an extension – though I’m hoping jcranmer will beat me to it.
Here's a summary of SeaMonkey/Mozilla-related work I've done in week 04/2010 (January 25 - 31, 2010):
Build Infrastructure:
I installed a newer gcc on the Linux machines and started using it for trunk builds. Additionally, I synched our mozconfig files for trunk much more to what Firefox is running on trunk as well.
Because I might be a bit crazy and like to put our machines under more pressure than they should be under, I even tried to turn on one additional test suite on trunk to try and find bugs to fix.
I also helped Armen from Mozilla release engineering to get his current L10n build work into a shape so that it works fine with SeaMonkey/Thunderbird builds as well.
Last not least, I filed a bug on disappearing Windows slaves - seems like we've overused the space available on our Parallels server.
Packaging:
As we want to run packaged tests on Mac some time, we will need to turn on tests on normal builds there, but need to care that the test files don't end up in file we deliver to users. That and us probably being the only ones who haven't done it yet was enough motivation for me to finally look into merging our package manifests and use one preprocessed file for all (three!) main platforms. I got all the way to having the "browser" section complete, based on the Firefox manifest and our current Linux/Windows ones, now I just need to do the sections for mail and all the other stuff we don't nearly have in common with Firefox - and then get this sucker tested and reviewed!
Support Emails:
Even if I tell people that I'm not the person to contact for support, a number of emails about that topic end up in my mailbox nevertheless, some directly, some via seamonkey-council. I tend to move them into a folder and batch-handle all of them every few weeks - or rather months. This week, it was time to do such a pass again, and I sent about 70-80 replies to them (I try to leave nobody without an answer), even though most of those are just one sentence and a templated section to look at our community page to find better and more responsive soruce for support.
Various Discussions:
2.1 planning discussions, Alpha 1 and further steps for 1.9.3, Gecko 1.8.1.24 and SeaMonkey 1.x EOL, YouTube and "HTML5 video" vs. Ogg, geolocation service options, new machines, getting codesighs and leak test data on graphs server, KompoZer integration work, L10n dashboard and sign-off, future add-ons UI, etc.
A good part of this week did run into various discussions and more buildbot tweaks, things are moving forward positively from all I'm seeing - we just need to get some more real development done on trunk, even though that slowly starts to pick up now. Any help to make SeaMonkey 2.1 an even better suite than 2.0 is appreciated, of course!
There was a thread that started on the CommonJS list about a transport format, something that works well in the browser via script injection. I sketched out a proposal, Transport/C, that builds on the Transport/B and Transport/A specs.
Transport/C is very similar to some basic mechanics of RunJS but uses require() as the top level function, and supports the special "module" and "exports" free variables used in the normal CommonJS module spec.
In order to prove the concept for Transport/C, I made a branch of the RunJS code, calling it RequireJS, that implements Transport/C.
It seems like it fits with the existing CommonJS module spec, but is something that works well in the browser. I also made a simple conversion script that converts traditional CommonJS modules to this format.
I am tempted to convert from RunJS to this RequireJS branch, and to start evangelizing that approach for browser toolkits. It would be great if Transport/C would also be approved as the transport format for CommonJS too.
Kris Kowal has some concerns about the *very* long-term effects of the approach. I read his comments as possibly pointing out some things that would be done differently if the primordials and e-maker type of modules were ever accepted as part of an ECMAScript standard.
As I read the primordials and e-maker strawman proposals, I think the only difference is Transport/C functions are only expected to be called once, but e-maker style would favor calling the function on every require() call. As I say in my response, I believe e-maker support, would affect regular CommonJS modules in the same way as the transport format, and it is assuming the strawmans make it in to the spec at some point, as they are specified now.
I also believe how it works in how I coded Transport/C as part of the RequireJS branch is what a normal developer would expect, and I think fits better with existing browser/script behavior, and the assumptions that go along with coding CommonJS modules today.
So I am tempted to rename the RunJS project to RequireJS and proceed with that. If you have any feedback to the contrary, please let me know. Otherwise, I will likely do the change early this week.
About a year ago, in my FOSDEM 2009 talk, I presented our future vision for SeaMonkey, containing the "Everything Is A Tab" plan that should bring browser, mail, web editing, and probably even preferences into tabs that can live in the same window.
Now I read in jboriss' blog post on add-on manager that the Firefox team is thinking about putting the add-on manager in atab, and possibly also - who would have thought that - preferences!
Sounds like different people come to the same ideas, and I really hope we can move that way - esp. as this, when it is done correctly, should still allow anyone to open those things as "the only tab in a window" which should make it act and feel just like a normal standalone window and so still gets the same user experience to those people who don't want to have all those things in tabs.
(That said, I still think tabs are mostly an excuse for having a bad window manager and bad window managment widgets in the desktop environment, but having gone through some strange bugs in my on-the-edge development desktop versions, I needed to resort to tabs as well and found the grouping of related tabs in windows an actually quite interesting and seductive feature myself...)
I just wonder who will manage to get the "Everything Is A Tab" story actually implemented first - Firefox may have the advantage of a larger development team and fewer different things to host in tabs...
The Thunderbird 3.0 release is just around the proverbial corner. And we’d like to release the SUMO knowledge base for Mozilla Messaging, support.mozillamessaging.com, code-named “SuMoMo” (initially only Thunderbird of course since Raindrop is still in its early days) at about the same time as Thunderbird 3.0.
SuMoMo is currently in beta preview mode on our staging server and currently has the Firefox look and feel but we are in the process of theming it to look like the rest of the Mozilla Messaging web presence. Theming should complete in a few days.
The last thing to do before release is to add knowledge aka “content”, in English (of course you can contribute English plus other languages but for the first release we’d like to do English as the first priority). This is one of the easiest ways to contribute for people who are not software developers (other than helping out Ludo and the QA team).
No software development experience required! We just need people who are using Thunderbird and can write regardless of whether they are developers or not. SuMoMo is for users not developers. Developers have lots of other places for their documentation e.g. Mozilla Development Center, etc
Download Thunderbird 3 (SuMoMo will only document Thunderbird 3 and higher) Release Candidate 1 or newer official pre-release build. As Thunderbird 3 is still in release candidate status at the moment, please do a backup and then try it out on a test email account.
One week ago, I told you that we won't be able to release Thunderbird 3.1 alpha1 as a localized release and that the release will be en-US-only. We've reversed course on that issue, since we now have a working l10n dashboard now for TB 3.1 and because the TB 3.1 alpha1 release will be postponed by one week.
Therefore everyone interested in being part of the TB 3.1 alpha1 release should hop over to the mozilla.dev.l10n newsgroup and opt in for this release.
L10n-wise we will be doing this release from the l10n-mozilla-1.9.2 repository. Please do not opt-in to this release, unless
the comm-1.9.2 trees on your l10n tinderbox page (http://tinderbox.mozilla.org/showbuilds.cgi?tree=Mozilla-l10n-locale) is green for Linux, Windows and Mac OS X
A few weeks ago on IRC dmose and I discussed the general issue of how QA communicates priorities to developers. I’d like to hear some comments on that from others, and possibly participate in some sort of trial of improvements.
The issue here is that I see lots of good work going on by people who are mostly involved in QA, such as wsmwk, WADA, and Ludo, but I as a developer don’t really know how to make the best use of that work.
I assume there is supposed to be a waterfall here, from (bug reporter)->(QA)->(developer)->(code reviewer)->(bug landing). I understand all of the steps of the process except this (QA)->(developer) handoff. I would be curious to hear from people involved in QA about what they view the main outcome of their work is supposed to be, as viewed by a developer.
Here’s what my understanding is of the current process. After bugs are submitted, QA has three main responsibilities: 1) get the bug in the correct component, 2) move the status to NEW or one of the inactive states (DUPE, INVALID, etc.) 3) clarify the bug information to get clear steps to reproduce.
Is this accurate?
Let’s look to see how that is working by looking at my recent work. In the last three months, I fixed eight bugs (that’s a little off my desired pace, but we were frozen a lot of that time). What brought those bugs to my attention?
(3) bugs I reported myself, either due to issues I observed or as a result of following support forums.
(3) bugs are fixes of crashes that wsmwk reported from crash stats
(2) bugs were filed earlier by others. If I recall correctly, both of those bugs were items that I noticed first in support forums, then located the bug in Bugzilla and fixed it.
In no cases did the standard QA waterfall process play a significant role in bringing a bug to my attention. And that concerns me, because I see some very competent and dedicated people working hard on QA, but I don’t seem to be making effective use of that work.
Am I somehow not following the process that I am supposed to be following, or is that process flawed? In theory I am probably in a better position than most people here, because I primarily track items that appear in the mailnews core/filters component.
I wish there was a clear way for the QA people to bring a limited number of bugs to my attention that are 1) important, 2) clearly defined and reproducible, and 3) likely to be fairly easy to fix.
The mailnews core/filters category currently has 326 NEW/ASSIGNED/REOPENED bugs in it. I could probably fix a few per month that were brought to my attention. A reasonable expectation might be that 10% of those are addressed in the next year. How are the QA folks supposed to influence the selection of which 32 bugs actually get my attention?
(posted to http://mesquilla.com and m.d.a.thunderbird, followup to m.d.a.thunderbird please.)
This series of blog posts discusses the creation of a new account type implemented in JavaScript. Over the course of these blogs, I use the development of my Web Forums extension to
explain the necessary actions in creating new account types. I hope to add a new post once every two weeks (I cannot guarantee it, though).
Before I begin the actual discussion, let me give some background. The ability to develop new account types has been my biggest extension goal for about two years now. Probably because of its difficulty, I know of only two extensions that have tried to do it: what is now the RSS code, and Webmail. In the first case, the implementer resorted to creating a binary component for the incoming server; in the latter, the implementer wrote a fake IMAP (and POP, SMTP) server to proxy the information to the web interface.
Some preliminary points: making a new account type is not a Good First Extension. You will need a fair amount of XPCOM experience, and probably decent experience at delving into implementations of undocumented interfaces. How much XUL and DOM (for stuff like webscraping) you use is up to you. MDC has a guide on building a Thunderbird extension from scratch. It is also probably not a bad idea to get comfortable with manual preference editing.
I am also trying a different form of development in this guide. This is not being done via my more common method of manually editing HTML by hand, but by writing in Kompozer. I'm also attempting to get more code included in my posts, and hopefully some images as well (the last part will be hardest). Like my first guide, I do expect that this will be adapted into a series of documents on MDC at some point. Some more
reference-oriented documentation will be posted on MDC as I write this.
I
personally use a debug version of Thunderbird, on Linux, very near the tip as the source code as the basis for my extension development (my regular profile is some 370 MB of stuff I don't dare threaten with developmental work). This is the same build I do patch development on, so I will rely on patches in said tree from time to time. One patch in particular is required [1], but otherwise, it should work on 1.9.2 and probably 1.9.1 as well.
This guide is structured to first demonstrate the actual activity components (e.g., displaying messages) and only cover configuration (e.g., the wizard to create a new account) when the more basic stuff has been completed. Therefore, you will need to get comfortable with editing configuration files by hand if you follow these steps exactly.
Backend introduction
So, let's start with an overview of the backend interfaces in mailnews. A list of the interfaces a front-end widget might use to talk to an account is: nsIMsgAccount, nsIMsgDatabase, nsIMsgDBView[2], nsIMsgFolder, nsIMsgDBHdr, nsIMsgIdentity, nsIMsgIncomingServer, nsIMsgMailNewsUrl, nsIMsgMessageService, nsIMsgProtocolInfo,
nsIChannel, nsIProtocolHandler, and nsIRDFResource. Many of these would need to be implemented, and a few of them are not in any way small; to implement nsIMsgFolder would require a total of 186 methods, setters, and getters (as of this writing), many of which are not well-documented.
In reality, implementations are not from scratch. Everything tends to boil down into two or five different implementing classes: the server, the service, the folder, the url, and the database (there is also typically a protocol implementation as well). Of these, only the service is implemented from scratch, and it gets the simplest interfaces to implement. When I said "two or five," I am referring to the fact that there are actually two types of accounts. The first type,
which only has to implement a server and service, can be called mailbox accounts: all of the messages are downloaded into local folders [3]. The second type implements all of the above, as the messages are
generally stored on the server and downloaded on demand (or cached).
Of these two types, the less interesting is the first one. I will therefore generally ignore this account type. If you want to make such an account type, look at the RSS implementation for guidelines. The primary distinction is that mailbox accounts lack their own folder types, and therefore databases and URLs. In such a case, all you need to worry about is delivering the messages.
Following is a description of the major implemented components:
Server
The server represents the source of messages for an account. It also serves as the per-account configuration information for implementers. For example, NNTP stores the maximum connection limit to a server off of this implementation.
Folder
The folder represents a container of messages. Ultimately, the UI interacts more with folders than with servers, at least on a regular basis. This is the most complex interface to deal with, primarily because it can be hard to tell precisely what you need to implement
versus what (eventually) calls back on some other message.
Database
The database represents a store of a subset of message information. It generally stores by default what NNTP would call overview information (enough to create a threaded message list), plus some flags like read status, as well as some information that extensions which to preserve.
Service
The service is more of a "how-to" guide for accounts. This is the external endpoint for ultimately copying messages, viewing messages, etc. Note that this is the only service implementation, so the actual server communication code typically happens in a different
implementation.
URL
URLs are what the name implies. It's how one refers to messages, folders, and servers, although only messages are typically instantiated with the object in question. They also tend to be used as the primary internal communication system.
Protocol
The protocol instance represents a connection to a server. Unlike the other implementations, this one is not mandatory and is typically not visible via the "main" interfaces (nsIChannel is perhaps the most useful one they export). I suspect this is primarily useful for binary protocols, but I have not yet delved far enough into creating a new account to say for certain.
nsIMsgAccount represents an account. The interface itself is not terribly useful—it's mostly just a step on the way to get to a server or an identity.
nsIMsgIdentity represents an identity. Identities are essentially a way of persisting compose settings; since their use is wholly related to compose code, I will not discuss them in detail until later parts of the guide.
nsIMsgIncomingServer, as mentioned earlier, represents a message source. This is one of the interfaces you will have to implement, although much of it is already done for you. Everything that is specific to a server hangs off of this interface; everything that is specific to a folder hangs off of nsIMsgFolder; folders are accessible via the root folder of a server.
nsIMsgFolder, as mentioned earlier, represents a container of messages. This is one of the interfaces that has to be implemented, unless you are using a mailbox account. All folders have a database.
nsIMsgDatabase represents the message store overview. This has to be implemented if you are implementing nsIMsgFolder (unless you want to be sneaky). Databases are used to get at thread and header information, via nsIMsgThread and nsIMsgDBHdr, respectively. Messages themselves have numerous representations: URIs, header objects, message keys, and (sometimes) message IDs. Conversion between these forms is common.
nsIDBFolderInfo represents folder properties normally stored in the database. All of these properties are also stored in the folder cache (nsIMsgFolderCache) to avoid opening up all of the databases just to figure out how many unread messages are in each folder.
nsIMsgAccountManager and nsIMsgBiffManager are two managers that handle account creation and the periodic mail download (generally called biff), respectively. Expect to see these calling your code a lot.
nsIMsgDBView represents the thread pane view. This is going to be the primary consumer of nsIMsgDatabase, and this is where you should go to look to find out what happens if, e.g., you select a new message.
nsIMsgFilterList, nsIMsgFilterPlugin, nsIMsgFilterService, and nsIMsgFilter are the interfaces that deal with filtering. None of these will have to be implemented to support filtering [4].
The nsIMsgSearch* interfaces are those that deal with search (there are around 9 of them). Most of these will not have to be implemented to support searching. More on this when searching is discussed.
nsIMsgWindow represents the bridge to the front-end. It is passed into many functions, although it may be null, typically when being invoked from
the backend.
nsIMsgMailNewsUrl represents the URL object that loads a message. This will generally have to be implemented if nsIMsgFolder is.
nsIMsgProtocolInfo represents the basic information about an account type's capabilities. This interface is one that is required to be implemented. As the name implies, it is generally geared towards the capabilities of the connection to the server.
nsIMsgMessageService and nsIMsgMessageFetchPartService represent the ability to retrieve the message (and message parts, more often known as attachments [5]). This is another interface that one must implement if folders are being implemented.
The MIME, compose, and import interfaces are omitted from this list of backend interfaces, as these are topics that will not be discussed for a while, and I am not certain they are useful to know about making new account types at present.
Notes
The purpose behind this patch is to enable extensions to reuse files from base/utils like C++ components can. If you were to adapt this to use C++ instead of JS, this patch would not be necessary. As the comments in the linked bug indicate, there is no guarantee that this will be implemented for Thunderbird 3.1; however, in such a scenario, the specifically required binary components would be available for reuse on some webpage. More on this when a decision is made.
Strictly speaking, this interface uses other interfaces in the list to talk to you. That said, a lot of interaction with folders and databases happens through this interface.
I say local folders—not Local Folders—here because Global Inbox settings actually rely on POP-specific attributes. It is still possible, via a reimplementation, to change the delivery settings. Such a mechanism is outside the scope of this guide.
It's not strictly necessary to implement these, but if you want to add custom filter terms or actions or custom search terms, some interfaces will need to be implemented. Such actions are beyond the scope of this guide.
Classifying all message parts as attachments is a pretty big oversimplification. In general, the only time specific parts are requested in Thunderbird and SeaMonkey are when attachments are involved. For more information on message parts, please see RFC 2045, RFC 2046 (two of the five MIME specifications), as well as the IMAP FETCH subsection (for numbering).
Why is async neat? It does not block the rest of the page, and will just evaluate the script once it is retrieved. More information is in the HTML5 spec. Note that the script you add async to should NOT use document.write(), as doc.write will likely destroy your page.
Also, be aware that async is a boolean attribute, but that does not mean you should use async="true" to turn it on. The HTML5 spec on boolean attributes says that a value of empty string or a string that matches the attribute name should only be used. To avoid async, just do not include the attribute. For Raindrop, I used async="async" since that looks better to me than an empty string.
Raindrop uses RunJS for the module loader, and RunJS uses dynamically added script tags via head.appendChild(), so the modules loaded by RunJS already behave in an async manner.
However apps that want to use the raindrop front end libraries normally include a script called rdconfig.js as their own script file, and that config file does a document.write to write out the Dojo+RunJS and jQuery tags. Those Dojo+RunJS and jQuery tags now use the async attribute.
as most of you know, after the successful release of Thunderbird 3, we are now moving towards our next major release Thunderbird 3.1 (codename Lanikai). Lanikai is scheduled to be released in early April 2010 and will be a considerably smaller release compared with the move from TB2 to TB3. This should result in a lot less string changes.
A draft release schedule of Thunderbird 3.1 is available on the mozilla.org wiki. Please note, that this is a preliminary schedule and still subject to change. In case of significant changes, I will of course notify the l10n community as soon as I become aware of those changes.
As a consequence that, l10n work on the respective TB3.1 localizations should happen on the respective l10n-mozilla-1.9.2 repositories. The same repositories that you use for the Firefox 3.6 localization.
For this we have updated the l10n dashboard. The tb31x tree there should now correctly report each localization's l10n-status. Looking at the dashboard now, it looks like many localizations will need to sync their 1.9.2 l10n repository with the work that they performed on their 1.9.1 l10n repository already. Some locales will have to move all their Thunderbird-related work (mail/, editor/ directories plus from other-licenses/branding/thunderbird/) over to their 1.9.2 repository. If you need any help with this, feel free to contact me and I'll help you with the move.
Yesterday we released Thunderbird 3.0.1 into the wild, our first security and stability release.
What makes this release so special is that we released TB 3.0.1 in 50 languages, thanks to the huge efforts of the Danish l10n community.
In this release, the Danish builds are released as "beta", but this is really just a precaution on our side and not necessarily an indicator of the localization quality of the Danish builds. It is our policy to let localizations go through a beta cycle, in most cases along the beta cycle of the product itself. If a localization is late-in-coming, we'll be releasing it for at least one release in "beta" state and move it to the final state, if we do not hear any major complaints from the local community.
Yesterday, Mozilla Messaging released Thunderbird 3.0.1, its first security, stability and maintenance release after the initial Thunderbird 3 release.
While it's always a good idea to quickly update to such a maintenance release for security reasons, this release also contains one important fix for Lightning users, who like to use Lightning in combination with other popular Thunderbird extensions (Enigmail, Quick Folders, Buttons!, etc.). Without this fix, some of our users were affected by bug 398702, which caused the File, Edit and View menus to disappear.
This bug has now been fixed in Thunderbird 3.0.1, which is why we recommend this update to all our users of Lightning 1.0 beta1.
The people in charge of the quality of Thunderbird , are organizing on a weekly basis a quality team event. These event cover most of the area where quality is involved. This means testing new feature, testing pre-release version of the software, and maintaining the known bug database. If you come to think about it, none of these activities require to be done on a given date, so why bother with an "event" ?
First of All the event is virtual, it happens online - this is for practical reasons, it would be very difficult to have people living in Singapore, the US east coast or The Netherlands to meet and work in the same physical place. We do bother to have an event because sometimes when looking at a problem or at something new being able to ask other if they see the same thing is valuable, because they might know something you don't or might have encountered the same issue earlier etc ... The value of the event is communicating with other people doing the same thing as you do, but with a different perspective. This is specially true for people who want to join. Asking the people that have been doing quality for quite some time will be available to help new comers.
We are using a distributed chat system called IRC, which is available with dedicated clients or through a web interface. As all the people available for a chat are not always in front of the chat window, you might not get an immediate answer. Typing a name a person being in the chat room will help you get noticed and get a faster answer. And don't be afraid to ask or participate , it's not that difficult.
Now that you know how those events take place, you might be interested in figuring out the subject that is going to be going on during the event. We publish a wiki page for each event that take place, and we have an other page referencing all past and future events (well most of the future events are being announced on a weekly basis). This week for example will be focused on duplicate events. I'm also announcing the events on Thunderbird dev mailing list.
Hey everyone - Sorry for the major delay since the last update. In this blog post I’m going to try and summarize what’s been happening here at Raindrop for the past month, and consolidate all of its Flickr activity into one post. I’ll be talking about what’s currently live, what we’re still iterating on, and what we still need to think about. I’ll also talk about our near future plans for a hosted version (so you can easily get your hands on it), and included at the end is a short screencast of our current interactions. Ok go!
So starting from the beginning of the user experience - the user is first brought to this prompt which informs you of your participation in gathering metrics data. The metrics data is a way for raindrop users to share anonymous information about their email and twitter habits with the raindrop designers who study the information to improve future versions. Once the user closes this prompt they are brought to their inflow of messages which will look something like this.
The inflow displays a combination of direct and group emails sent to you, as well as twitter @mentions from people you follow. As seen in the above screenshot we are now able to pull out youtube links and thumbnail them for you. Thanks to Bryan Clark this also applies so far for vimeo and flickr links, as well as expanding bit.ly links. We have plans for link expansion and thumbnailing for many more services to come. Below the first twitter message you can see a message with several email attachments. We now also provide thumbnailing for image attachments, and allow the user to scroll through them all within the preview box. Eventually we would like to be able to open several image attachments into a lightbox style gallery.
The above screenshot shows an example of a youtube video being expanded inline.
Message in personal inflow about to be moved to bulk
Message now moved to bulk
Another feature we had previously blogged about was the ability to move messages from your inflow to your bulk section. Ideally Raindrop would automatically know how to deal with every one of your messages, but this feature was definitely necessary at this stage. This feature has since been implemented, and as you can see from the above two screenshots the message is moved from personal to bulk.
Adding a contact
Something we started iterating upon was the steps one would take to add a new contact. Gmail currently has a contact manager which is, in our opinion, under utilized and not very well advertised. We would like Raindrop to allow you to have a very well sorted contact list, and encourage the user to assist in the process of organization without being overly intrusive. One iteration of this (shown above), would be to pull out a Raindrop Notification which alerts you when you have a pending contact when you receive a personal email from a new sender, and encourages the user to act upon this. The user would then be able to add the contact, or act on a suggestion such as merging the new contact with an existing contact (such as an email from someone who you already have on twitter). This way the user acts on the organization of contacts right away, much like one would accept a facebook friend request. This is likely to generate better organization than gmails system which hides the merge contact panel.
This series of events is still in the process stages. There is a discussion on the flickr group as to whether or not this is the right solution, and if it offers the user enough incentive for it to not simply be an annoyance. Another suggestion was to have the pending contact prompt within the message itself.
Clearing bulk
One idea I had and never really discussed much was a method for handling your bulk messages. Here I’ve mocked up a system which would allow you to mark bulk items as read without having to navigate to it’s full view which might be useful for messages that are short or that you get the gist of right away. There is then a method of clearing read bulk messages. The current iteration of Raindrop simply clears out your bulk messages when you navigate to their full view. Some thoughts on how people would like to handle their bulk mail would be interesting.
A stacked conversation
The last thing we started mocking up was conversation stacking similar to that of Gmail, except with the use of avatars for instant recognition. As of right now we don’t provide avatars for email messages, however with the use combining email and twitter contacts, gravatars, and facebook we feel we will slowly be able to almost guarantee an avatar image for all users.
The Next Steps
Inspired by the work of the Mozilla Labs Ubqiuity team search interface. We have been iterating on a similar system for searching and browsing your conversations inside Raindrop. A simple, single point where you can search with auto-complete helpers and browse for conversations and people within your Raindrop. Right now we’re working collecting the data and getting it to fit into our own Raindrop style.
And then finally around spring time we’ll be looking into a hosted alpha version of Raindrop. Just like all our other designs we’ll start small and invite as many people as we can into the process. As we iterate and expand the invite system we hope more people can join us so we can integrate the feedback and work towards a better system together. If you’d like to keep tabs on this you’ll want to check in with the Raindrop Milestone Planning wiki page
Lastly here’s a screencast demonstrating the currently live features of Raindrop.
As mentioned during the release announcement of Thunderbird 3, we missed the 50 locales mark by just one locale. The main reason for that was, that three of the locales that had supported us for the Thunderbird 2 release 2.5 years ago (Danish, Macedonian and Slovenian) didn't have the resources to localize Thunderbird in time for the final release.
Fortunately I can now report, that two of those three locales (Danish and Slovenian) have recruited new talent for their localization teams:
The Danish team has been able to recruit about half a dozen volunteers, who have been really hard at work during the weeks after the Thunderbird 3 release, tackling over 2000 unlocalized strings, removing hundreds of obsolete strings and doing lots of QA work after the initial localization work was finished. They will already be part of our upcoming Thunderbird 3.0.1 maintenance release, which will be out on Wednesday.
The Slovenian team has recruited one new team member, who is also working through over 2000 unlocalized strings, though at a smaller pace for obvious reasons. I currently hope to add Slovenian as a supported locale for the second maintenance release, Thunderbird 3.0.2.
Each of these locales (as well as the 48 others, that already were part of the Thunderbird 3 release) would certainly welcome each interested person, who is willing to help. If you want to help, hop over to the list of l10n teams and contact the team leader.
There are various ways where help is needed and you can also help if your English isn't good enough to do the actual translation work by proofreading the translations or doing QA work (e.g. checking keyboard shortcuts). Each effort is very much appreciated and you could make a difference for thousands of people in your country and around the world.
I just pushed some changes into the front-end code for Raindrop. Besides using JSLint as the code style, and JSDoc for the format of the files, it now uses a modified version of Dojo 1.4 that uses the RunJS code loader.
I am fortunate enough to work with people that will tolerate this sort of brief experimentation to help improve the state of browser code loading. Do you know Mozilla Messaging is hiring? Great people, great technology, and a great mission. OK, end of the sales speech.
The code conversion to JSLint, JSDoc and a new loader all at one time took longer than I would have liked, but I am glad I did it.
For one thing, the code looks a lot more uniform thanks to using JSLint. While I do not care for all of the rules mandated by JSLint, no one ever likes a coding standard 100%, and JSLint is widely known and a programmatic code checker.
Converting Raindrop to RunJS was really beneficial for RunJS. While RunJS has unit tests, nothing helps shake out the kinks like a large project. RunJS is now more robust because of it.
If you want to peruse the Raindrop code, you can hop to the Raindrop Mercurial source web view. That link will take you to Raindrop's client/lib/rdw directory, where we keep the UI widgets. You can click on some files to see how they look with the RunJS loader and the new formatting.
One thing that became apparent, particularly when talking to David Ascher about the code: the way the dependencies in RunJS are specified as an array, and having a separate list of function arguments that must match that array might be prone to errors.
I condensed the run boilerplate to the top to three lines, otherwise, it would have been quite long vertically to express it all. But you can see the problem. Looks scary.
David and I talked about it. I talked about how YUI uses just a Y object as the only argument to the function, but I did not like how they use odd module names like "yui-anim", and then you have to know that creates a Y.anim property that you can use in your function.
So David suggested the following:
run("rdw/Message", { rd: "rd", dojo: "dojo", Base: "rdw/_Base", friendly: "rd/friendly", hyperlink: "rd/hyperlink", api: "rd/api", template: "text!rdw/templates/Message!html" }, function(R) { //Use things like R.api and R.Base in here that map to the modules up above. ... });
I like this better. It is much clearer what module gets assigned to what variable, no "off by one" errors.
The downside: it does not minify as nicely as the existing run format. However, in this case, avoiding developer errors probably trumps the minification cost, and the extra cost to type R. in front of the dependent module references. You can call it r. if you want. Hmm, I might prefer the lower-case version. Easier to type. Although the capital stands out better.
So I am very tempted to convert RunJS to use this format for listing dependencies and passing them to the function callback. I will likely do the work this weekend.
Another thing we talked about was the multiple invocations of run(): run() can be called with a starting string argument to define a module, but then can also be called without that starting string argument if you just want to run some code that has some dependencies.
David felt it would be clearer if those two actions were two different function names. I can see that being clearer. So what about the following for the API:
run(), for just running code that does not define a module.
run.def() for defining a module.
run.mod() for a module modifier (the existing run.modify() API call)
run.get() for getting a defined module after initial module evaluation (needed for some some dynamic cases where you do not know the module name before-hand and in circular dependency cases). This is an existing API.
So the changes are renaming run.modify() to run.mod() and moving the run() call style that defined a module to run.def().
Thanks to David for the feedback, and for the rest of the Raindrop team for being patient with me as I did some experimentation in browser module loading.
Speaking of feedback on RunJS, Rawld Gill (one of the authors of Mastering Dojo) was already working on a loader, and he did some work to convert it to use the same API as RunJS. I am still processing the results, but it is great to see alternate implementations. I am hoping we can take the best of both and make a great loader. I already changed the module evaluation algorithm to use the recursive style he suggested.
RunJS takes its roots from the cross-domain Dojo loader, and that loader was constructed when Dojo had to support Safari 2. Safari 2 has a ridiculously small call stack, so a recursive module evaluator blew up very easily. I switched to a model that traced the dependencies to work out an array of sequenced modules, then a separate loop to then call them into being. That allowed the loader to work in Safari 2, but now that we do not need to support that browser, the more natural, straight-forward recursive model can be used.
Really neat stuff! Feels like we are getting close to a robust but compact loader.
Just a quick note to get back into the blogging groove (been somewhat preoccupied microblogging on Facebook and to an extent Twitter).
The next version of Thunderbird has the project name Lanikai which made me super happy because it’s one of my favorite beaches of all time. Some photos.
Lanikai beach is on the East side of Oahu, in Lanikai and near Kailua (which is where the Obamas like to stay when they visit Hawaii). You can walk up to Kailua beach for more action where there’s windsurfing, kite surfing, and kayak rentals. What’s interesting is that they’re not crowded at all, probably because the towns of Kailua and Lanikai are a bit far from Honolulu and they’re small sleepy towns, more local than tourist area.
The water is very clear, warm, and it’s a very swimmable beach. The sand is white to light tan and soft. The beaches are easy to access, and stores are near enough for some coffee, snow cones, or sun block.
I like to think that part of the reason we’re going with Lanikai and beach themes is that it’s aligned to how we’re thinking about the Thunderbird email client. We want to make Thunderbird run so efficiently that people spend more time on the beach than in their email. Sounds good to me.
There seems to be some doubt in our community regarding the status of the recent Lightning 1.0 beta1 release in our release hierarchy.
So let me unequivocally state for the entire Calendar developers team:
We (the Calendar developers) consider Lightning 1.0 beta to be the best Lightning release, that has been released to the public so far.
We consider Lightning 1.0 beta1 to be the stable release built for users of Thunderbird 3 and SeaMonkey 2.
It contains numerous bugfixes and improvements (nearly 500) over the 16-month-old 0.9 release, that improve the add-on's stability, performance and memory consumption.
We encourage everyone to update to this release from Lightning 0.9 or earlier Lightning releases.
We are not planning to release any updates to Lightning 0.9 users, that want to remain on Thunderbird 2. Thunderbird 3 is the future as far as we are concerned.
As part of Mozilla's ongoing stability and security update process, SeaMonkey 2.0.2 is now available for Windows, Mac, and Linux as a free download from www.seamonkey-project.org.
We strongly recommend that all SeaMonkey and old suite users upgrade to this latest release. If you already have SeaMonkey 2.0, you will receive an automated update notification within 24 to 48 hours. This update can also be applied manually by selecting "Check for Updates..." from the Help menu.
Note: All SeaMonkey 1.x and old Mozilla or Netscape suite users are encouraged to upgrade to SeaMonkey 2.0.x by downloading it from www.seamonkey-project.org.
In my last post, I talked about a suggestion from David Ascher to try to improve the syntax of specifying dependencies when declaring a module. Here is an example of that suggestion, using run.def(), a possibly new API dedicated to just defining a module called "rdw/Message":
run.def("rdw/Message", { rd: "rd", dojo: "dojo", Base: "rdw/_Base", friendly: "rd/friendly", hyperlink: "rd/hyperlink", api: "rd/api", template: "text!rdw/templates/Message!html" }, function(R) { //Module definition function. //Use things like R.api and R.Base in here that map to the modules up above. ... });
While that does make it clear what each module name's variable will be inside the function that defines the module, it has the following drawbacks:
1) It hurts minification -- having properties off the R object passed to the module function means that minification tools will not be able to minify those references as easy.
2) All the modules dependencies must be referenced via a prefix "R.". For example R.api. It is a small bit of typing and an extra property lookup. That might be seen as an advantage too -- it is clear that a symbol is a dependency because it is off the R. function.
3) Makes it hard to find typos for properties on the R. function. With the current runjs format, JSLint can actually find typos for a dependency's variable name.
4) This syntax is more verbose for JS files that do not care about scope encapsulation. For JavaScript libraries like jQuery, MooTools and Prototype, they pretty much operate in the same global scope. jQuery does have a noConflict(), but that just helps if there is only one other thing called $ in the page. MooTools and Prototype add things to global prototypes.
So for these libraries, specifying dependencies is more like just specifying script tags, and they do not need a local-scoped variable in the function module to get things defined. They would just need to do the following:
run.def("rdw/Message", ["some/module", "something/else", ...] function() { //This function does not need some locally scoped variables, and most //likely, the script dependencies above may not call run.def() and define //an object, just add things to the global space });
So for these libraries, it would be onerous to be forced to create variable names for each of those dependencies.
This last point seems to be enough to tip the scales back to using the current model used by run. However I am aware that it is possible for the developer to not get the order or number correct, matching the dependency string with the correct variable for the function.
I am hoping using a coding standard like the following will help:
run.def("rdw/Message", ["rd", "dojo", "rdw/Base"], function( rd, dojo, Base) { //Define the module for rdw/Message and return it. });
Basically, make sure all dependencies are on one line, along with the function keyword, then put the variable that matches each dependency aligned directly under the depdendency name (the example above may not be correctly aligned depending on the font or format you are viewing this message).
I purposely trimmed the list of dependencies, so I can get this example to show up in this blog. That is the down-side with this sort of code style: it can have a very long line for the dependency names.
For Raindrop, I want to try to keep local scope encapsulation, particularly since I expect some slicker extensions to it that may introduce other code into the page that may conflict. However, if I did not care to do that, I could shorten up the above example quite a bit.
So at this point, I am favoring making it easy to use RunJS for other toolkits that do not care about local scope encapsulation and detecting bad references to variables inside the module definition over avoiding errors with a mismatched function variable name to a dependency name.
It is a hard choice to make. Neither path is perfect. If you have an opinion, feel free to share it.
For a course I'm TAing, we (the other TAs and I) decided to revamp the tools so that students could more easily install them on their own computers. This was really my first look into actually producing packages for other people. Here is the long tale:
Step 1: Build simpl
Okay, the basic, core tools here compile and work easily. The more complicated tale is the GUI, built on qt. qt 3, to be precise. Except the autodiscovery thinks we want to try building qt 4. A single post-configure change gets this working. Only took a few hours here (trying to go the qt4 route didn't work so well, and we had interesting endeavors trying to figure out how to get KDE headers to work).
Step 2: Build binutils
This wasn't all that hard at first. Configure ran nicely and without problems, and building... oops, there's a warning and someone turned on -Werror. Another reconfigure gets this building quickly.
Step 3: Build (cross-compiling) gcc
Configure... build... fail... reconfigure... rebuild... fail... Repeat for several hours. Make that days. Do I want these options? Or those options? Still failing. Try editing files mid-build, so if that gets it to work. And, no. Okay, let's try binutils again. Solution: make install binutils first, then build gcc. That works without problems.
Step 3.5: Test the build
I have a Makefile that just requires me to change a few lines to swap gcc versions and directories of everything. Do that, try it, and... it doesn't work. Something about libc not working correctly.
Step 4: Build newlib
By this point, I know the drill: copy the configure from elsewhere, configure, and build. Apparently there's a typo in one of the ARM assembly files. I teach myself a tiny bit more of ARM (this is turning out to be very educational!) and fix the file. Reconfigure, rebuild, install, and test again. This time, it's complaining about missing a few functions. I found some more documentation online, and wrote my own sbrk function (where "wrote" means copied from some file online and tweaked to make it build). Testing fails again, so I make myself a few more functions and everybody's happy.
Step 5: Build vba
As you might imagine, this one didn't work either. So many build errors. I look at what Debian did, so I ponder some more, talk it over with the other TAs, and give up. Skritch, skritch.
Step 5: Build vbam
This fork builds... oh, wait, I need cmake. Okay, this fork builds without problem. They don't have version package downloads for my build script to pull, so I just have it yank a specific svn revision. Nice, simple package to work with after the mess that is cross-compiling.
Step 6: Build gdb
No problems here. Worked fine the first time, no patching, no need to rebuild. Even the testing had no problems. Stunned me.
Step 7: Package and test on school computer
Problems:
Can't find libmpfr.so
cc1: /lib/libc.so.6: version `GLIBC_2.7' not found
as: /lib/libc.so.6: version `GLIBC_2.7' not found
(vbam) Segmentation fault
Solutions:
Statically compile libmpfr.so. Not too hard...
Statically link gcc. Not very trivial. Eventually, LDFLAGS=-static in the configure arguments works.
Statically link as (and other binutils). This requires manually copying the final line and adding in the -static argument. Every time I rebuild binutils.
Debug, find backtrace. It's in pthreads, called from SDL. Try statically linking SDL (no luck). Try using different SDL versions. Rebuild vbam with debug. Notice that the primary reason for fault is... no sound device. Patch vbam. Test again, it works!
For the sake of clarity, every time I had to test in the final step, I had to reupload the tarball, which started out at 49 MB and grew to 55 MB (thanks to static compilation). Sometimes I had to reupload it again, if the connection died in the middle (my internet connection started getting flaky... possibly related to the 100s of MB I was uploading a day. Or maybe the 100s of MB I was downloading (every time I restarted the script, it downloaded 100 MB of source archives....).
So, in short, I had to override build scripts for 2 different packages, patch another 2, and build 3 out of 5 packages statically. One package doesn't have a point release; the other three are spread out among three separate servers to download. Running the build script from scratch requires nearly 2GB of disk space and takes several hours. At least now I repackaged it in Makefile form so you don't have to restart all over from square one if you forgot to install cmake first. Building the final tarball requires a good minute on my system.
But, I've finally finished the experience. Plus, I won't have to do it again... after I build the 64-bit version.
As mentioned in David’s blog post, we’re using Lanikai as the code name for the Thunderbird 3.1 branch.
Last week we transitioned our Thunderbird 3.1 nightly builds to be building with Gecko 1.9.2 and to have the Lanikai code name. We’re still missing some new images for the branding, but hopefully they will come soon.
In tandem with the setting up of Lanikai builds, we’ve also set up new trunk builds with Gecko 1.9.3. These builds currently have the version number “3.2a1pre” - this does not mean that the release after Thunderbird 3.1 will be called Thunderbird 3.2, it is just the lowest increase that we need to implement at this stage to be something different from 3.1.
Trunk builds are retaining the Shredder branding but will hopefully get new images at some stage.
At the moment, these builds are pretty much the same as the Lanikai builds from the Thunderbird perspective. It is only the core files that are different.
There’s no changes on the stable builds for Thunderbird 3.0.x - just mentioning for completeness. The nightly builds are still in the latest-comm-1.9.1 (or latest-comm-1.9.1-l10n) directory on ftp.
For Developers / Other interested parties
The Lanikai and Thunderbird 3.2 builds are both generated using the comm-central repository (this has not been branched yet).
Thunderbird 3.2 builds are using the core mozilla-central repository.
Lanikai builds are using the mozilla-1.9.2 repository (specify --mozilla-repo=http://hg.mozilla.org/releases/mozilla-1.9.2/ to client.py to pull that repository).
The branch date for comm-central into comm-1.9.2 has not yet been agreed, iirc it is likely to happen around about the first Lanikai preview build, more on that later.
It's a new year, so it's time for me to predict (and probably overestimate, who knows) what I would like to do and see in the realm of Thunderbird (and SeaMonkey) and other tidbits in the Mozilla realm.
News submodule
Thunderbird 3 improved the filter story dramatically here; the next two biggest itches are the complete inanity that is news URIs (too many bugs to count), and the venerable old crossposts bug. I still contend that the latter would best be served by per-account database functionality; in any case, it does require some database changes to work properly. I doubt I'll find time to look at that bug in particular this year.
The URI issues are more tractable, but I don't think I'll find time to hit them for 3.1; in any case, I now consider them to be the highest priority news bugs. So, to anyone with time on their hands: feel free to take one or two of these and start fixing. You'll get much kudos from Thunderbird Usenet users.
Other various "nice-to-haves" on my list: fixing subscribe, cleaning up some of the gunk in the code, adding support for RFC 3977 CAPABILITIES, possibly changing how news:a.group URIs work (open the folder view, not necessarily subscribing to them), among others. Combine-and-decode also falls under this list, but it's a lot less tractable than some of the other stuff.
Analysis tools
jshydra could use some more love: I hope to be able to be able to get a converter to a more natural AST working by the end of the year, as well as an automated test suite to verify correctness whenever I change m-c versions. I've also been working on-and-off on getting symbols for DXR via MSVC, which should hopefully also be finished this year.
Other Mozilla/Mailnews work
As I've mentioned before, my biggest goal for 3.1 is to be able to specify new account types in Javascript. I basically have the necessary framework completed locally, I just need to finish writing the tests and fix some bugs before getting it reviewed and committed; after that, I'll be writing a series of blog entries on developing an account type in JS, similar to (and hopefully better than) my pork guides. Speaking of which, I hope to finish that sometime this year as well. Possibly during summer again.
I've yet to see a roadmap for the address book in 3.1 and later, so I don't know what I'll be doing for the address book in this upcoming year. I expect, though, that I won't do anything near the scale of what I did for bug 413260. De-RDF and de-morkification are another two things I'd like to see worked on that I don't expect to get to this next year as well.
Time to see how much I'll actually get done this year!
Plugins for RunJS are supported. i18n bundles have been pulled out as a plugin, and a new text plugin allows you to set text files (think HTML/XML/SVG files) as dependencies for a module. The plugin will use async XMLHttpRequest (XHR) to fetch those files and will pass the text of those files as an argument to a module's module definition function. The RunJS build system will then *inline* those text files with the module, so that the XHR calls be removed in deployed code, and allow cross-domain use of those text files.
Any function return type is allowed from the module definition function. Before only objects and functions were allowed and functions had to be called out in a special way. Now, that special call out is removed and any return type is allowed. The cost was an extra call, run.get() that needs to be used in circular dependency cases. See the Circular Dependencies section in the README.
The build system that comes with RunJS now supports build pragmas.
The build pragma support was used to build RunJS in a couple of different configurations. I am trying to get a handle on where the bulk of implementation lies, and what features add to its file size. Here is the breakdown (warning, Google Doc iframe inclusion, but interesting numbers inlined in this post after the iframe):
Let's look at the non-license sizes, since they give a better indication of code density. Google's Closure Compiler did the minification for this evaluation.
The normal config, with no plugins included (but with plugin support) is 7,970 bytes minified, 3,167 gzipped. Including both the i18n and text plugins with run.js bumps it up to 11,759 minified, 4,655 gzipped.
The interesting number for me is the version of run.js without plugin support, no run.modify, no multiversion support and no page load (run.ready/DOMContentLoaded callbacks). This version of run has just the following features:
support for the run() module format
nested dependency resolution
configure paths to modules
load just plain .js files that do not define run.js modules (scripts that do not call run(), for example jQuery, or plugins for jQuery).
That bare bones loader comes in at 5,086 minified and 2,204 gzipped. The one you should use, the one with the license, is 5,245 minified and 2,317 bytes gzipped. I need to work on the size of that license block!
That size could probably be brought down a tiny bit (probably reaching the 2,000 gzip size) if I were to really be aggressive and remove all context references, but that would be a mess to maintain and there would be no easy upgrade path to multiversion support.
I believe that is the lower limit a functional loader that does nested dependencies via run() module calls. I view run.ready/DOMContentLoaded support more of a necessity for a loader, so unless you already had an implementation for that, I suggest the version that has run.ready() support, which comes in (with license) at 5,867 minifed, 2,522 gzipped.
The nice thing about the build pragma setup for RunJS, you can upgrade run without having to change your code if you find you want more features, like plugin support, or i18n/text dependency support via plugins.
I am interested in trying to sell more front-end JavaScript toolkits on this loader. For some, I can see the bare-bones 2.3K gzipped loader a nice way to step into it, and then their users have the option to swap out a more powerful version via a different RunJS build output.
Right now I believe around 2KB gzipped is close to the lower bound for a stand-alone code loader in the browser. At least for a loader I would consider using: anything that uses XHR and eval are dead to me. Using plain script src="" tags helps the xdomain case, and just fits better with debugging. While Dojo has used an XHR-based loader for quite a while (and it will continue to be supported), it just does not work as well with the browser as a script-tag based loader. Any loader should also do nested dependency loading too -- if a module in a script has dependencies in other modules, be sure to evaluate the dependencies in the right order.
As a point of comparison, consider LABjs. I feel a kinship with the author of LABjs, Kyle Simpson, even though we have never talked. We are both focusing on efficient code loading in the browser. I recommend LABjs if it fits your style.
While LABjs does not quite do nested dependency resolution, it does something related where you can tell it to wait to load a script before continuing to load other scripts. LABjs is not trying to push a module format like run is, but targeted more at existing code that does not have the concept of a module format.
By the way, RunJS can also handle loading these types of files. Where LABjs has a wait() call for holding off loading scripts that depend on another script being loaded (like a framework), RunJS uses nested run calls.
Taking the 1.0.2rc1 version of LABjs and using Closure Compiler on it (without the license) gives LABjs a size of 4,360 bytes minified and 2,170 gzipped. As a reminder, the equivalent RunJS file is 5,086 minified and 2,204 gzipped. I may be able to do better with making the structure of the RunJS code more amenable to minification, but the gzip sizes come up fairly close. I do not believe the code tricks I would do to help minification will help the gzip size any.
Both LABjs and RunJS end up around 2KB gzipped. So, about 2KB gzipped seems close to the lower limit on a standalone loader, one that uses script tags/plays nice with the browser and can do nested dependencies. I would like to be proven wrong though, and ideally by modifying RunJS to fit that lower limit. :) I am sure the code can be improved.
But remember the guidelines, no goofy XHR stuff/something that works well with the browser and can handle nested dependencies. No script tags with inlined source/eval tricks. Even though Firefox and WebKit make eval debugging easier, it is still not as nice as regular script src tags.
Irakli Gozalishvili believes web workers might help, but I do not see it. The workers are restricted to message passing, and anything interesting in a web browser will likely need to touch the DOM, so a web worker solution will just be another async-XHR-like approach, where you will need to eval the scripts or inline-script inject to get all the scripts for them to see each other and the DOM.
Irakli does have an async-XHR based loader for CommonJS modules. As of today, it comes in at 1,527 minified, 838 gzipped (license not included). But it uses XHR, so limited to the same domain as the page, and debugging support is just not as nice across browsers. It also uses CommonJS module syntax, but I have decided CommonJS modules do not play well out of the box in the browser, and I believe the format's "module", "exports", and "require.main" parts are unnecessary.
I don’t yet have a full job description handy, but figured I could start with a draft:
Mozilla Messaging is looking someone who can help us drive forward Thunderbird’s test automation framework, tooling, coverage, and community. We’re looking for someone who combines the usual skills we need:
Strong domain expertise: in this case test automation of a multi-platform desktop application
Big-picture thinking: you’d be the first paid test engineer working on a huge codebase with lots of developers and millions of users, so the hard thing won’t be to find things to do, rather figuring out what’s the right thing to work on
Ability to lead and build a community of peers and contributors
Ability to prioritize and drive your own work, and happy to collaborate with a wide variety of contributors
Our current test infrastructure relies primarily on MozMill, and most tests are written in Python or JavaScript, so solid understanding of those technologies is obviously useful.
This is a unique opportunity for someone who takes testing, engineering, and community seriously, and who wants to have a huge impact on software that is used daily by millions of people.
Relocation not necessary.
Pass the word!
(resume submissions to jobs at mozillamessaging.com)
I’ve just uploaded a new version of TaQuilla to Mozilla’s add-on site. You can download it here. It is still listed as experimental status, so updates are not automatic. Details of the changes in this revision are available here, but briefly it mostly adds some user interface consolidations for consistency, plus support for Thunderbird 3.0 and SeaMonkey 2.0.
Frankly, I’ve struggled to find a good personal use of TaQuilla for use in my dogfooding. I’ve tried using it to categorize “interesting” posts, but I can’t even agree myself from day-to-day what is “interesting”, and the soft tagging is even more indecisive. But I’ve finally hit on a good use for it in my workflow – rejecting of sports articles in newsfeeds!
I have an RSS feed that subscribes to local news for the “Seattle Times” newspaper, but I find a lot of the articles are sports related. Now I am a certified geek, and not really interested in those types of articles. So what I did is to create a tag “Sports”, then I setup TaQuilla soft tags for “Sports” on the RSS feed, create a virtual folder that filters out articles tagged with “Sports”, and voila I can read the newspaper feed without all of those annoying sports articles. It’s particularly useful since many of the same articles get updated multiple times, and the updates are very efficiently rejected with the bayes filter if I tag the original.
Since Thunderbird 3.0 shipped last week, our community support traffic has increased dramatically. We have roughly three times the number of support topics as well as 15 times the amount of traffic. Needless to say we need help!
Do you use Thunderbird? Always wanted to contribute to a open source project but don’t know how? But you love explaining things and helping others? Then helping our community support Thunderbird is a great way to start.
You don’t have to be a coder or be “technical”. Just somebody uses Thunderbird and wants to help other Thunderbird users.
Here’s how to start:
Join Get Satisfaction (you can use your Facebook, Google, Twitter or Open ID login if you don’t want to create another login)
Download and start using Thunderbird 3.0 if you aren’t already a Thunderbird 3.0 user (NB: if you are a Thunderbird 2.0 user and depend on add-ons like Lightning, we recommend holding off on upgrading to 3.0 until those add-ons are available for 3.0. And of course it’s always worthwhile doing a backup)
Get in where you fit in i.e. help where you can by replying to support topics, and by tagging,
Questions? Need help on using Get Satisfaction and providing Thunderbird community support? Email me: roland AT mozillamessaging.com or ask myself (I am generally on there M-F 10am.-5p.m Pacific) and the other folks on the IRC chat channel #gsfn on irc.mozilla.org
As part of Mozilla's ongoing stability and security update process, SeaMonkey 2.0.1 is now available for Windows, Mac, and Linux as a free download from www.seamonkey-project.org.
We strongly recommend that all SeaMonkey and old suite users upgrade to this latest release. If you already have SeaMonkey 2.0, you will receive an automated update notification within 24 to 48 hours. This update can also be applied manually by selecting "Check for Updates..." from the Help menu.
Note: All SeaMonkey 1.x and old Mozilla or Netscape suite users are encouraged to upgrade to SeaMonkey 2.0.x by downloading it from www.seamonkey-project.org.
Now that we are living in a Thunderbird 3.0 world, there will be times when we will want to indicate that content on the Mozilla Developer Center applies to a specific Thunderbird release version. (We’ve already been doing this to some degree with Thunderbird 3, but over the next year we will have many more release versions to manage.)
There are two mechanisms for labeling content on the Mozilla Developer Center: tags and templates.
Tags
At the bottom of each MDC page there is a section called “Tags”. These are folksonomy tags that apply to an entire page (for example, “Thunderbird” or “Thunderbird 3″). These are not pre-defined, so you can add a new tag (such as “Thunderbird 3.2″) as needed. However, please check the list of tags that is displayed as you enter letters in the “Tags” field, and try to avoid duplicating existing tags.
The main benefit of tags is that you can list all the pages that have a particular tag by clicking the hyperlinked tag word. Therefore, don’t be afraid of adding lots of tags, and don’t be afraid of making tags too specific.
Templates
There are four MDC templates that are used to indicate that page (or a section on a page) applies to a specific version:
{{template.Tb_minversion_header(N)}}: This template should be used when the content of the whole page or section applies to Thunderbird version N or higher.
{{template.tb_minversion_inline(N)}}: This template should be used when an individual item in a list or a table appeared in Thunderbird version N.
{{template.Tb_minversion_note(N, “The <code>foobar()</code> method works differently in Thunderbird N.”)}}: This template should be used when you need to insert a Thunderbird version-specific note into an article.
{{template.Tb_minversion_section(N)}}: This template should be used when the content of a section applies to Thunderbird version N or higher.
So, for example, if you were to paste (as text ) the following into the MDC editor:
{{template.Tb_minversion_header(3.2)}}
{{template.Tb_minversion_section(3.2)}}
{{template.tb_minversion_inline(3.2)}}
{{template.Tb_minversion_note(3.2, "The <code>foobar()</code> method works differently in Thunderbird 3.2.")}}
…you would see this after saving the page:
Another useful template is {{template.draft(”")}}. This generates:
See the Template page on MDC for a complete list of MDC templates.
Firefox releases have cool codenames while in gestation. As Chelsea explains, Firefox picks national parks as codenames, as metaphors for the values that go into making a Firefox release.
The idea made a lot of sense to us, so we decided to follow suit for Thunderbird. Rather than parks, we picked beaches. A good beach is a clear and compelling example of a public good. We can all go to the beach, share in the beauty and poetry of the place, swim, maybe surf. All that’s required of us in exchange is to treat it well — don’t fence it in, don’t litter, don’t crash your oil tankers into it. Yet beaches as a public commons are under threat. If Thunderbird can help beaches and beaches can help make it clear why Thunderbird matters, we all win.
Given the weather outside, it’s not too surprising that the codename for the next version of Thunderbird is Lanakai, in sunny Hawaii. “Warm turquoise green waters brush up against a fine sand beach while gentle trade winds offer a cool relief from the hot Hawaiian days. This beach is great for relaxing on the sand or taking a swim in it’s clear waters”. That pretty much sold us. Also, we can dream about having a Thunderbird summit there someday.
So it has been a little while since the last update but we have been busy putting together some plans for the very near future. Hit the jump to check out some new mockups as well as an update on the current status of Raindrop.
Since the last iteration we’ve thought up a way in which users will navigate through Raindrop. The primary means of navigation will be through a search bar, coupled with a drop down menu. When the user clicks within the search field a drop down menu will appear giving the users the ability to navigate to where they want to go through quick links (such as to quickly navigate to the inflow, mailing lists, tweets, etc). These quick links also act as filters, as when the user types in a search query the quick links will filter down to only those which are relevant. For example if you were to search for Raindrop, the quick links might only show RSS feeds and Mailing lists, and within those links display your results - for example a Raindrop Get Satisfaction RSS feed, and a Raindrop development mailing list. This search system is highly inspired by the Mozilla Labs product, Ubiquity.
The next thing we started thinking about was a system in which we could move messages from your personal inflow to your bulk mail. In this mockup the user has clicked “not personal” and is creating a filter. The user has a choice to filter all future messages from that sender, or to simply put that specific conversation and it’s subsequent replies in the bulk.
We’ve also started mocking up different uses for the summary area (the gray area in the right hand column). We think this is a very useful space for showing the user content relevant to what they are looking at. For example we can now search for a contact, in this case Harrison Boyce, and it will display all their activity on the left hand side, and contact information on the right hand side. This is an example of what a twitter contact page could be like. Ideally when we merge contacts, the contact info would show more than just twitter info, and we would show email activity as well as twitter activity. Also note in this screen shot that we show conversation threading when viewing tweets. This is currently a live feature in Raindrop.
Another necessary feature for the twitter view is the quick compose. This screenshot is pretty self explanatory.
Finally we have this screenshot which is a live representation of where Raindrop is currently. Most of what was shown in this blog post is currently in place, however we are still working on getting the interactions to all work properly.
Please help out with our first Doc Day, this Thursday December 17. By expanding the developer documentation available to the community, you help people become involved with Thunderbird.
Feel free to write in whatever environment works best for you. If you want to write directly on MDC - great, go for it. If you prefer to brain-dump to a text file - that’s fine too. Just email it to me (jen at mozillamessaging.com) and I’ll edit and publish it.
Don’t have the time or inclination to write a full piece? No problem - send me an outline or a partial draft. These are helpful too - other people can come along and continue your work later.
Thanks in advance to everyone who helps out! If you need help or have questions, contact me at jen at mozillamessaging.com or “jenzed” on the Mozilla maildev IRC channel.
We have been contacted by lots of individuals who volunteered to translate Instantbird into their native language and were eager to start working on it. As we were not ready to host the translations, we asked people to wait before starting their work on localized versions of Instantbird.
As we plan to release the next beta of Instantbird 0.2 in several languages, we feel that now is a good time to start translating the UI of Instantbird. Please note that the development work is not finished yet, and that there will still be string changes before we are ready to release this next milestone.
You will find information on the translation process on our wiki at http://wiki.instantbird.org/Instantbird:Translation. As usual, if you have any question, feel free to ask them in #instantbird on irc.mozilla.org or to contact us at contact AT instantbird DOT org.
The MozQA community is holding a Testday tomorrow, Friday, December 11th, for users interested in the use, development and/or testing of Seamonkey 2.0! We're going to have Robert Kaiser, the lead for SeaMonkey available to help users test the new project, learn how to report out the results of the tests and just generally chat about the project with the community via IRC Chat (channel #testday on irc://irc.mozilla.org). So, if you're interested, come on by anytime between 7AM to 5PM PDT tomorrow!
While it's not in the format I would ideally want, I recently got Google Wave inside Thunderbird 3. How, you might ask. Simple: the new content tabs feature.
So, to do it, go into the Error Console, and type this line in: Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("mail:3pane").document.getElementById("tabmail").openTab("contentTab", {contentPage: "https://wave.google.com/wave/?nouacheck"});. Note that Google Wave for some idiotic reason decides that Thunderbird isn't a valid UA to be using, so you have to convince it to disable the UA with the ?nouacheck. I thought browser sniffing died out years ago...
For bonus points, if you restart Thunderbird, the tab will stay open, so all you need to do is login again!
We are happy to announce the release of Instantbird 0.2 beta 1.
The two most significant improvements in this release are new tabs in conversation windows and the preferences window. There's a lot more new stuff, read the release notes for a more detailed list.
You can download the beta and read the release notes from here.
The MozQA community is holding a Testday on Friday, December 11th, for users interested in the use, development and/or testing of Seamonkey 2.0! We're going to have Robert Kaiser, the lead for SeaMonkey available to help users test the new project, learn how to report out the results of the tests and just generally chat about the project with the community via IRC Chat (channel #testday on irc://irc.mozilla.org). So, if you're interested, come on by anytime between 7AM to 5PM PDT that Friday!
Note from the SeaMonkey team: We probably will actually focus testing on the candidate builds for SeaMonkey 2.0.1, which are available now and are planned to go public next Tuesday, December 15.
This is a quick demo of the way in which we would preview a new message that has arrived in the inflow. This is showing an example which has a lot of information - several replies in a group message with many links and attachments. This demo shows the way in which we will allow you to preview and navigate through links and attachments (try the prev/next links), as well as how we could expand content (click the read more link) within the inflow itself (ideally this would transition or animate from a preview to full message, not just an open/close state).
Also, please excuse my poorly pieced together html for this demo, it’s just hacked together and is no indication of the actual code! Check out the DEMO HERE.
This post goes into detail about the subtle differences within message types, and how they are displayed.
Email: Direct Message This is the most simple form of a direct message. Someone has sent you an email which involves no one else. The message is displayed followed by a quick compose field and the rest of your actions. The quick compose field is shown as this message only involves you, and as such you are likely on the hook to reply.
Email: Direct Message > Direct reply A direct reply is type of direct message. It is when you have initiated a conversation with a single person and they have replied to you. The message you wrote is highlighted in yellow, indicating an e-mail you sent. As with all direct message types the quick compose field is still present.
Email: Direct Message > Direct reply with preview This is the same scenario as a direct reply, only this example shows a preview of a link attached to the email. If links or attachments are present the message field will split into two columns to display the preview and the messages.
Email: Direct Message > Direct conversation A direct conversation is a string of messages sent between you and one other person. Again, your messages are highlighted in yellow.
Twitter: Direct Message A Twitter direct message is displayed slightly differently than an Email direct message. For one the width of the message is half of the space of an e-mail message. This is because we can predict the length of each message (140 characters), and can show the entire body of the message. As such all links will be viewable in the message and, as is the nature of twitter, the message body will most likely describe the link. The background of the conversation is also blue.
Twitter: Direct Message > Direct reply A Twitter direct reply is when someone replies to a message you sent to them. As with E-mail messages, the messages you write are highlighted in yellow.
Email: Group Message A basic E-mail group message is a message that is sent between you and several other people. There is no quick compose field as it is possible that the email is only sent to you as information, and a reply from you is not necessary. The reply button however is still present for quick and easy access.
Twitter: Group Message A twitter group message is one in which there several @replies in response to something you tweeted. These are put in the inflow only if the people who are @replying to you are people you follow. If someone @replies or mentions you and you do not follow them it will still be possible to view these tweets in the full twitter view.
Released on 01 Dec 09, and this
changelog was last updated on 04 Dec 09.
Thunderbird
3 RC 2 has been released. Release notes are
available. This post lists the improvements in Thunderbird 3 RC 2
over Thunderbird 3 RC 1. This list encompasses almost every single
known fix that went into this release, but excludes platform-wide
fixes. Do check out the known
issues as well.
Now based on Gecko 1.9.1.5 platform version.
Changes in Thunderbird 3 RC 2:
(4)
Thunderbird-specific: (3)
Fixed: 516950
- [autoconfiguration] “Download new messages automatically” should be
checked/activated/enabled by default (at least for POP3 accounts!)
Well I finally decided to quit adding new stuff, and just get a compatible FiltaQuilla out the door that works with Thunderbird 3.0 and SeaMonkey 2.0. You can get the new version from Mozilla’s download site here.
In addition to some new filter actions (print, add sender to address list, and save attachments to a folder) this release introduces “custom search terms” for the first time. This is a new feature that has been added recently to the mailnews core code, and is part of the TB 3.0 and SM 2.0 releases.
The search I am talking about is the old-style Thunderbird search, not the newer global database (gloda) search that was added to Thunderbird. Gloda gets all of the press, but we’ve also taught the old style search a few tricks as well! These are particularly useful in saved searchs (also called virtual folders).
I think that the most interesting new capability is that you can define a search (and therefore a virtual folder) by adding a few lines of javascript code that does precisely what you want. Let me give a very simple example.
Let’s assume that you want a virtual folder to contain all of the active items that you currently need to process involving projects. Incoming emails are marked with tags, either manually or by some sort of filter. You define new tags for each project, and each tag begins with “pro” and ends with some sort of project marker, say a number or word. You want to have your active folder contain messages that have a tag containing “pro”, but NOT include messages that are tagged “done”.
The standard mailnews tag search forces you to enter the tag name for each tag that you want. There is no way to search for tags by the characters in the tags. Plus, searching for several tags is an OR function, and saying to not include DONE messages is an AND function. But the standard mailnews search does not handle complex boolean searches.
The javascript custom search comes to the rescue! Go to the folder that contains the messages that you want, and select the Javascript search term:
Click on the script icon and you will get a small editor window, where you can enter a few lines of javascript. All that we need to do is grab the string that has the tags in it, and make sure it includes “pro” but does not include “done”. Our javacript is given a variable “message” which is the database header object that can be used to get message properties. We need to execute an expression as the last statement, whose value is either true if we want the message, or false if we do not. That’s just the following two lines of javascript:
let tags = message.getStringProperty('keywords');
(/pro/.test(tags) && !(/done/.test(tags));
So here’s what our javascript window and code looks like:
Now save this as a virtual folder, and you have the exact virtual folder that you want!
OK, this is just for geeks, but it is really powerful in letting you define folders that can precisely define the workflow that you want. There’s also a few other geek-friendly search terms, including the much-requested regular expression search by subject or other header. For details, see the updated FiltaQuilla page on this site.
FiltaQuilla is still in experimental status, though I have now nominated it to be public. Still it may be a few weeks before it gets there. If you are an existing FiltaQuilla user, you will need to go to the download page directly and download and install the new version.
I’ve been tracking some difficulties in my junk analysis recently, which was caused when I enabled some experimental changes to tokenization. (I added full tokenization of the Received: and x-spam-status: headers). At the same time, I started some experiments where I am automatically training certain incoming emails as good.
What I am seeing is that the common, unchanging words in the Received: header, like “received:from” and “received:(exim”, are persistently occurring with a moderate “good” score, such as 36, even after training junk messages with those headers. There are a lot of these little meaningless tokens per message though, and they are dragging down the junk score of junk messages into the Uncertain category.
I think what is happening is this, and it could be caused by any change in your common environment. I started adding new tokens such as “received:from”, without restarting training. Because I also started training temporarily many more good messages than junk, these new tokens are showing up disproportionately as good.
Suppose, for example, I start with 1000 good messages and 1000 junk messages in my corpus, then suddenly add a new token to all incoming emails. Then I train 100 good messages with that new token, and 10 junk messages. The spam corpus will claim that the new token appears in 10% of good emails, but only 1% of junk emails, so the presence of that token is a marker that the message is more likely to be good. Which is not true, since now ALL emails have that new token!
I suppose that one defense against this would be to make sure that the proportion of good and junk emails trained always stays about the same. That is not easy to do, however.
Whilst tracking the Thunderbird 3 release and looking through the bugs, every now and again we get a bug where something isn’t working and it turns out that it is due to one of the add-ons the bug reporter is using (unfortunately, in the cases I’ve seen recently I suspect it is because we’ve been forcing the extension author to decide on a single compatibility range for their add-on which means supporting the current branch and trunk, or just the current branch).
When we’ve been getting these reports, rather asking the bug reporter to report back to the add-on author, I’ve been spending an extra 5 minutes using the add-on compatibility reporter to pass a report back to addons.mozilla.org that will then make it back to the extension author. Although this takes me a bit longer, it isn’t as long as going to amo and looking for a web site or email address. It also means the add-on author will get back a good report (with versions and other information) and hopefully will subsequently fix the extension.
I like this way of reporting issues, the only thing I would like is a preference in the add-on compatibility reporter to allow me to decide if I want compatibility checking enabled or not - but that is more because I’m using it in a slightly different way (more towards bug reporting) than it was originally intended.
Even so, the original intention is good, and I like the way the reporter works and the ideas behind it.
Ashlee Vance wrote a story in today’s nytimes.com (I presume it’s in the print edition too about the business world’s supposed disappointment in the shareholder value of open source based businesses.
I suppose if you ignore all of the companies listed in the article who were sold for hundreds of millions of dollars, and you squint really hard, you can see their point: investors in open source companies in aggregate haven’t made as much money as investors in proprietary software companies. Given how short the age of open source has been, that’s hardly surprising. (Given how open source is missing the boat on services-based businesses, that’s also likely to continue, but that’s another story).
Others will I’m sure criticize the article based on proposing some better metrics for success for investors in open source companies. I don’t really care — what did strike me was this sentence:
The fight illuminates a larger truth about open-source companies: their societal and strategic importance far exceeds their financial value as operating businesses.
Exactly! It’s critical to me as CEO of Mozilla Messaging that it be a healthy business. But my requirements for “health” aren’t those of wall street. They include reaching a state of making more money than we need to operate, but they also include some variation on the triple bottom line, with some additional twists related to making sure that we operate in ways that are consistent with our values.
I was recently at a business meeting where a bunch of CEOs were “networking”. It was fascinating how quickly the conversation shifted when I answered the usual question about “exit” (the polite term for: “get rich by selling the company) with “well, no, I can’t, as we’re owned by a non-profit”. After a period of shock, it turns out that even CEOs (!) are interested in a business that isn’t all about financial rewards for shareholders. It can be about much more interesting pursuits, such as building a team of people who respect each other and work together for a common goal; it can be about providing awesome customer experiences; it can be about making the world better. There are lots of companies like that. It’d be nice if the “business” section of the newspaper spent more time thinking about that and less about how people who are merely shareholders can make money through speculation.
It’s probably healthy for Wall Street to realize that what’s interesting about open source isn’t some magically cheaper way to produce goods and services. To me, what’s much more important are the complex implications like transparency, a permeable barrier between your consumers and your staff, a built-in safeguard against complacency, and ideally a much more human relationship between your organization and everyone else. I look forward to seeing what the Economist’s new Schumpeter column on business says about it, whenever they get around to it.
In the meantime, I’m looking forward to exploring how to work with business-savvy types who are interested in how to make a deeply healthy business. Based on talking to other CEOs of open source companies, I’m pretty sure that just like we can find talented programmers, quality nuts and localizers to contribute to the products, I’ll find some smart business types who will find it rewarding to contribute to the business challenges.
Now that RC1 is out the door - congratulations! - I’m hoping that Thunderbird developers can spend some time on documentation. Here are the tasks (in order of importance):
Please review, add new stuff, expand existing stuff. Please use lots of links (to pages on MDC, if available, otherwise to MXR pages and relevant bugs).
New Modules
Protovis, jQuery: what they are, how they’re available to add-on authors, and ideally a sample extension
Shout if you need help - jen at mozillamessaging.com. Feel free to brain-dump into a text file and I’ll take care of the rest. (I know MDC is somewhat painful these days - don’t let that be an impediment.)
Released on 24 Nov 09, and this
changelog was last updated on 27 Nov 09.
Thunderbird
3 RC 1 has been released. Release notes are
available. This post lists the improvements in Thunderbird 3 RC 1
over Thunderbird 3 Beta 4. This list encompasses almost every single
known fix that went into this release, but excludes platform-wide
fixes. Do check out the known
issues as well.
Now based on Gecko 1.9.1.5 platform version.
Changes in Thunderbird 3 RC 1:
(310)
Thunderbird-specific: (224)
Fixed: 227305
- Support drag-drop single message to desktop / file-system window
(e.g. Explorer)
Fixed: 248681
- Add backend support for ability to toggle “Reply”/”Reply to All” in
Composer
Fixed: 281877
- Thunderbird doesn’t have “Copy Image” on context menu
Fixed: 296781
- “delete” attachment should be “remove attachment”
Fixed: 337964
- changing account during message composing doesn’t apply signing prefs
from new account.
Fixed: 353347
- Wrong Quick Search label “Entire Message” must be renamed to “Body”
as it does NOT search the entire message! Gross inconsistency with
“Search messages” UI where the same search is labeled “Body”.
Fixed: 397838
- Tag button shrinks in its disabled state
Fixed: 408480
- data loss using extensions (notably lightning): Ctrl+C (and other
keys) in standalone message window deletes mail, missing or empty menus
Fixed: 420744
- Shutdown fails with 100% cpu load when auto-complete over LDAP is used
Fixed: 438927
- ###!!! ASSERTION: XPConnect is being called on a scope without a
‘Components’ property! (Thunderbird mail windows)
Fixed: 442222
- Update About > Credits for Thunderbird3
Fixed: 442730
- composition security options for encrypt should only be one menu item
(with checkbox) like signing
Fixed: 450710
- Mail account auto-configuration via a database of ISP configs fetched
via HTTP
Fixed: 455038
- The spinner should disappear when not spinning
Fixed: 456840
- messagereader: allow easy removing of contact from address book
Fixed: 457304
- Edit contact overlay doesn’t display the address the message was sent
to
Fixed: 457882
- News (nntp) option “ask me before downloading …” is ignored
Fixed: 462578
- Implement Quick Search option “Subject, Sender or Recipient”
(Subject, From, To, CC or BCC) to allow filtering for full
conversations with a contact easily
Fixed: 465138
- New message-reader UI elements in header pane need to be customizable
Fixed: 471312
- Cosmetic and font issues with the Shredder message header block
Fixed: 472076
- Changing the layout view when seeing a single message on a tab cause
weird behaviors
Fixed: 507508
- Modify Tango icon for Sent folder to match new Send button in
composition toolbar
Fixed: 507593
- Windows/Linux new mail alert onclick broken when a message tab is
displayed
Fixed: 507595
- More vista styled appearance for the address book
Fixed: 508548
- Crumbled paper as a metaphor for junk is hard to recognize
Fixed: 509044
- text beside icons in default mail toolbar
Fixed: 509258
- Update theme icon.png and preview.pngs for 3.0
Fixed: 509268
- Attachment icon is big compared to the other elements
Fixed: 509748
- Message list for Inbox blanks until manually selecting another folder
to view (IMAP folder, after “Compact”)
Fixed: 510643
- Thread pane is cleared after rebuild-index of local mail folder
Fixed: 511417
- Attachment reminder should not search signatures
Fixed: 511780
- Archiving does not always place the messages in the correct account’s
Archive folder (Archive shouldn’t use X-Account-Key: header, at least
when account is not Global Inbox owner)
Fixed: 511924
- Need option/preference/some way to avoid changing default values for
combined “reply” dropdown button in new header (to make “reply (to
sender)” the default instead of “reply all” for many recipients)
Fixed: 516170
- [faceted search] need better understandability of the faceting
controls
Fixed: 516261
- [faceted search] further improvements to search results look&feel
Fixed: 516277
- [faceted search]: header area can suffer from overlap
Fixed: 516322
- Often, the first compose window breaks on initialization
Fixed: 516327
- Closing compose window with customize panel open should clean it up
for recycling
Fixed: 516353
- “Get New Messages for > All accounts” is missing
Fixed: 516384
- [Vista] New toolbar button icon improvements
Fixed: 516652
- uninitialized vars in destructor for searchbar widget
Fixed: 516676
- “require all/any” button looks different from the other buttons
Fixed: 516680
- [faceted search] Add keyboard navigation capabilities to new search
Fixed: 516776
- Make it possible for browser elements to navigate through links/pages
Fixed: 516860
- Using stars for NEW messages and starred messages is confusing.
Fixed: 516863
- Need to package nssdbm3.chk on 1.9.1 too, now
Fixed: 516884
- High-level UI to control major feature changes between TB2 and TB3
Fixed: 516923
- Some folders do not appear in Smart folder view
Fixed: 517036
- Disable autocomplete in search field if one of the quick-search modes
is selected.
Fixed: 517081
- [faceted search] message result display should coalesce messages with
the same message-id header
Fixed: 517087
- Message tabs/windows without a backing view shouldn’t depend on the
message’s folder to provide the view
Fixed: 517134
- Per-server newsgroup filters do not work
Fixed: 517171
- need to clean up inactive controls in autoconfig window
Fixed: 517198
- Compact doesn’t expunge messages with IMAP deleted flag (CONDSTORE
supported IMAP with “mark as deleted” model)
Fixed: 517200
- [faceted search] Can’t remove quick filter after switching from an
active traditional Quicksearch filter to “Search all messages” (can
cause blank message list although no filter set)
Fixed: 222388
- Set initial SMTP server choice to “Always Use Default SMTP Server”
instead of specific SMTP server which is set as “Default” when account
definition
Fixed: 368415
- if you only download message headers, mails which are recognised as
junk (spam) lose their “junk” status if you download their content
Fixed: 373573
- SMTP server dropdown doesn’t play nicely with Use Default Server
Fixed: 440236
- crash after connection lost [@
nsMsgDatabase::GetTableCreateIfMissing(char const*, char const*,
nsIMdbTable**, unsigned int&, unsigned int&)]
Fixed: 447927
- Additional Email field of address book entries not included in
address autocompletion
Fixed: 455714
- nsIAbCollection::getCardFromProperty and
nsIAbCollection::cardForEmailAddress should be able to return multiple
cards
Fixed: 461117
- Implement new keyboard shortcut for Paste as Quotation (Now that
CTRL+SHIFT+V is for Paste Without Formatting)
Fixed: 463116
- Re-implement runtest.pl for leak and bloat tests in python.
Fixed: 465618
- gloda deleted message processing logic is not purging messages
Fixed: 472764
- gloda full-text search always uses SQLite’s porter stemmer without
regard to effective locale, etc.
Fixed: 474790
- mails with References: to itself break threading in thunderbird
mailnews DB view backend
Fixed: 480090
- Crash when sending email after being in offline mode [@
morkRowObject::CloseRowObject(morkEnv*)] – [@
nsMsgOfflineImapOperation::SetCopiesToDB -
nsMsgOfflineImapOperation::Release]
Fixed: 480942
- Cannot Set Unix Mailspool Account As Default
Fixed: 483329
- gloda indexer onAnnouncerGoingAway handler does not cleanup
sufficiently
Fixed: 484639
- gloda should not index junk messages
Fixed: 487992
- File size of offline store of IMAP folder increases upon each
“Rebuild Index”
Fixed: 494014
- shutdown hang, high cpu, no open imap connections
Fixed: 494764
- Conditional jump or move depends on uninitialised value at
nsNNTPProtocol::ParseURL()
Fixed: 495572
- gloda should explicitly handle compaction
Fixed: 497598
- hang on shutdown appending msg to imap folder via a filter
Fixed: 498493
- gloda error (labeled as warning): Got impossible folder ID
Fixed: 505949
- Junk folder on Local Folders not created and possible data loss
Fixed: 506726
- “No Feed Summary” warning is obnoxious for rss entries with no
summaries
Fixed: 508001
- Mac Trace-malloc leak regression of approx 30k after landing of dock
icon changes/Investigate replacing RestoreApplicationDockTileImage
Fixed: 508978
- VirtualFolderChangeListener should defer notifications, only
periodically commit
Fixed: 509163
- SeaMonkey 2 beta dock icon (showing new emails) does not reset
Fixed: 510703
- NEW Message filters are created with garbage names
Fixed: 512917
- gloda needs to mark some messages as damaged and never try and index
them
Fixed: 514504
- Gloda: messages for which the clean bit hasn’t been committed yet can
be indexed in both event and sweep modes
Fixed: 515316
- Retention policy settings of folders are altered to an other folder’s
setting when “Use my account settings” of a different folder is changed
Fixed: 519797
- [Gmail] Thunderbird creates spurious Trash folder (autoconfig doesn’t
generate mail.server.serverN.trash_folder_name, then root-level Trash
is created by existence check of trash folder even though [Gmail]/Trash
is already used as trash folder)
Fixed: 519801
- compacting imap offline stores can cause message fetches
Fixed: 519979
- move/deletes of large number of imap messages slow
Fixed: 520172
- gloda indexer stringifies MessagesByMessageIdCallback results for
debug even when not in debug mode
Fixed: 520432
- Personal vcard editing shouldn’t have a “photo” tab.
Fixed: 520459
- MsgHdrToMimeMessage: headers for MIME subparts not populated
And are a Enigmail user - please update to the latest enigmail nightly. As previous versions or some previous nightlies (from a few weeks to a few month) , might crash Thunderbird. Actually we believe that our top crashers is due to incompatible versions of enigmail being installed.
If you’re interested in trying what a web application would look like running inside a Thunderbird tab without modifying an extension use the following code snippet.
Open the Error Console from the Tools Menu
Copy & Paste this code into the input entry at the top:
You can continue to iterate the tab application by creating a new click handler, however at that point it might be worthwhile to start with the extension code instead of working in the error console.
Jetpack for Thunderbird
In the hopefully not too distant future Thunderbird will gain Jetpack as it’s new extension model and it will be no longer necessary for add-ons like this these be created but instead a simple Jetpack which can do the same things without restarts or complicated installs.
If you’re interested in this take a look at Andrew’s recent Jetpack in Thunderbird post.
If you’re a Google Calendar user like myself you might want to check out this really simple add-on for Thunderbird, which should be available as an official add-on for the coming Thunderbird 3 release.
The Google Calendar Tab
As simple as it sounds, this adds the Google Calendar web interface as a new tab directly into Thunderbird. Creating and viewing events works just as it would in a browser like Firefox.
If your calendar is setup to show popup alerts you’ll continue to see them from the calendar tab while in other, mail, tabs.
Here’s my family Pinochle game reminder alert showing.
There is no official release of this extension yet, however you could grab the latest XPI, download and install it into the latest (at least rc1) Shredder release.
More Extensions
It’s easy to get started integrating a web application like Twitter, Remember the Milk, and other sites into Thunderbird. Once you get the initial pieces you can start working on better integration into your email conversations.
If you’re interested in creating an extension similar to this one, here are a couple links you probably want to check out:
This calendar extension only handles a single url for Google Calendar. If you’re looking for actual calendar integration with different calendars, including google calendar, you’ll want to check out the Lightning Calendar extension which also runs inside Thunderbird tabs.
jetpack.future.import("thunderbird.compose");
jetpack.thunderbird.compose.appendComposePanel({
onReady:function(panel, composeContext){
let doc = panel.contentDocument;
let msgNode = $("<span />", doc.body).appendTo(doc.body);
let started = Date.now();
setInterval(function(){
let words = composeContext.getPlaintextContents().split(/\s+/);
let secs = Math.ceil((Date.now()- started)/1000);
let wordsPerMinute = Math.floor((words.length*60)/ secs);
msgNode.text(wordsPerMinute +" words per minute.");},1000);
panel.show();},
html:<><body style="overflow: hidden"></body></>});
The other day I did a quick hack using Raindrop & Jetpack to get new mail notifications from Raindrop. In total it took me less than an hour. It’s no Joe Shaw hack, so I don’t expect to get in the paper for this but I figured I’d share anyway.
This Jetpack checks Raindrop to see if there are new messages and bubbles them up as notifications if there are. Here’s the source code:
var messages = {};
function checkMail() {
var api="http://localhost:5984/raindrop/_api/inflow/conversations/home?limit=10";
jQuery.getJSON(api,
function(data, textStatus){
jQuery.each(data, function(i,item){
if (item.unread) {
if (!messages[item.id] || messages[item.id] != item.messages.length) {
var n={title: item.subject,
body : item.messages[0].schemas["rd.msg.body"]["body_preview"],
icon : 'http://localhost:5984/raindrop/inflow/i/logo.png'};
jetpack.notifications.show(n);
}
messages[item.id] = item.messages.length;
}
});
});
}
setInterval(checkMail, 10000);
To try this out you’ll need Raindrop installed and running and Jetpack installed in Firefox.
Go to about:jetpack and copy the above code into the Develop tab, then click the try out this code link just below the Bespin editor.
If you don’t want to do all that you can just watch the video below (no sound, so you might want to play some music)
By far the largest set of support requests that we end up seeing for Thunderbird have to do with being unable to receive or send mail. By far the largest single cause of these failures is some unilateral change by the ISP which cause previously working configurations to stop working. In other words, people come to us for help solving problems we can’t solve. It makes us feel bad, it makes you look uncaring, and it certainly doesn’t help your customers (except for those cases when we go beyond the call of duty and help them as neighbors would, guiding them through the diagnostic & fix).
In our next revisions of Thunderbird, we’ll probably work on making our error dialogs better, so that we transmit whatever wisdom we can to your users to give them a fighting chance. But we can do better for your customers, if you get involved.
Let’s figure out how to work together to provide better experiences for your customers and our users. I’m quite sure that we can come up with solutions which would save you costs compared to having your customers tie up your tech support lines only to be rebuffed by your staff who often don’t understand how email systems work. It might also help you avoid commoditization…
Here are some ideas to start the conversation going:
Let’s make sure that our configuration of ISP databases works for as many users as possible. We’ll likely need to evolve the format and protocol over time, but we can only do that with input (some ESPs have already joined the effort, which is great!).
Consider making a useful add-on that would let you inform your customers of planned service downtime, configuration changes, etc. (no marketing messages, please, or your customers will not use it).
If there are changes we could make in Thunderbird that would help you help your customers, let’s talk!.
Together, we can figure out how to get your customers setup with a Thunderbird that works for them, for us, and for you.
We’ve recently promoted the Activity Manager docs from the planning area (that is, the Mozilla Wiki) to the Mozilla Developer Center. The Activity Manager is a new Thunderbird component that displays a combination of user activity and history.
I’ve tended to limit my link referrals to my Twitter feed over the last year, but I wanted to advertise Tim O’Reilly’s latest post on this channel as well (it also feels great to have more than 100 characters to express myself!). Tim explains well what the new battlegrounds for the future of the web are. It’s a war that’s currently being fought with shiny discounted hardware, free access to proprietary data, and competing “privileged” interfaces to the web. The stakes are huge, but oh-so-hard for people to grasp, as much of the mechanics of who wins what depend on economics which are far removed from the battleground:
People don’t pay transparently for mobile services or devices
People don’t pay for online news (although some surveys indicate many would)
People often end up “subscribing” to brands (Apple, Google, Facebook) and becoming brand consumers rather than active participants in their own digital life. That delegation of trust is often pragmatic, but it’s worrisome if unchecked by alternatives.
The heterogeneity of the original internet can lead to an appearance of chaos, and many people prefer simpler, more uniform experiences. Both technical and psychological factors encourage centralization of services with single providers. Financially as well, “small, independent startups” have huge incentives to become part of one of the big centers of mass.
Finally, the huge psychological distance between the value of free services and the costs that funds them is one of the big topics that puzzle. It applies to “how come I can get free map directions from Google but I have to pay to get them from TomTom?” as well as “how can I convince my neighbors that electing so-and-so to office will mean more tax revenue overall, which in turn will mean better schools?”. In both cases, the number of steps between cost and service is huge, and coupling them tighter would destroy the huge advantages that centralization and scale offer. (If I knew more about the derivatives crash I could make some pithy reference here).
I agree with Tim that “If you don’t want a repeat of the PC era, place your bets now on open systems. Don’t wait till it’s too late.” I think he’d also agree that we need to think beyond code and copyright. That’s like going to war with trucks but no tanks. For the open, distributed, heterogeneous web to thrive, we need to incorporate thinking from a host of other fields, such as contract law, design, psychology, consumer behavior, brand marketing, and more. Figuring out how to engage thinkers and leaders in those fields is likely one of the critical, still missing steps.
From an email to the enigmail mailing list : I am starting to prepare a new version of Enigmail for Thunderbird 3.0.
I think that after more than 8 years of development, it's about time to
finally call it "1.0"!
For this, of course I'd like to have as many translations as possible
:-) Please send your translations directly to me. In case you don't know
how to translate Enigmail, instructions can be found here: http://enigmail.mozdev.org/download/langpack.php#instruct
Attached is the diff file between v0.96.0 and the next version -- as you
can see it's really not much. In case your language wasn't updated from
v0.95.7 to v0.97.0, I have also added the previous versions' diff.
Please het in touch with patrick if you want to give a hand.
If you are crashing or having error messages while trying to send email, and that you are using a shredder nightly, and using enigmail to sign/encrypt your emails, consider updating to the latest enigmail nightlies which fixes those issues.
In this picture cbeard and I are still editing the press release and getting ready to make the announcement. dbaron I believe is checking on the bits with Ben. Blake is wondering why the Rock is still here. We had some celebratory drinks and eventually headed home.
It's Wednesday, and with that, time for another post in the ongoing series of SeaMonkey 2 contributor intereviews! This time, we'll continue with a guy who's known on IRC as InvisibleSmiley:
Who are you?
I'm Jens Hatlak, German/Austrian, single, located in Frankfurt, Germany, and still on the better side of 30. :-) I've been working as a PHP web developer for a large logistics company since I left university (computer science, TU Darmstadt) in 2007.
I chose my nickname, InvisibleSmiley, because I think it's funny to tell people that's what they missed when someone made a statement with hidden irony. ;-)
I like to play the piano, although I'm not especially good at it. I'm a good swimmer, though, a science fiction fan, and a grammar guru (avoiding the more popular alternative term here for hopefully obvious reasons).
How did you become a SeaMonkey contributor?
I started using Mozilla when it was still in the Milestone phase (around 2000), so I was a beta tester almost from the beginning, but only watching the game back then.
In 2001 I made my first Bugzilla comment and filed an enhancement bug (still open!). I also started university that year where I joined a group of system administrators responsible for the computers of the computer science department (some thousand students). After some time I took over the responsibility of not only the web server but also parts of the software installation, including Mozilla (later also Firefox, Thunderbird, and SeaMonkey), all on Sparc/Solaris. During that time I learned how to compile software from source under difficult conditions and how to write patches. However I was still not actively contributing code. Even when I worked on MozPETs I sticked to what I knew (compiling ) instead of diving into extension development and trying to understand the basic principles like XUL.
I kept using SeaMonkey when Mozilla decided to drop the suite, staying on the bleeding edge (nightly builds). When MozillaNews went on hiatus (and with it its Bonsai Watch bug tracker) I started to track SeaMonkey-affecting bugs myself, just out of interest. At some point in time I decided to push the results to a place where I (and others) could find and search them: The SeaMonkey Trunk Tracker was born. I learned how to build SeaMonkey on Windows and updated my public build instructions, but other than that I just watched development progress.
My active participation in SeaMonkey development started only last year, in October 2008 (funnily by posting a patch one minute after another developer submitted almost exactly the same), when the code had already moved to Mercurial. I was surprised by the fact that simple changes and corrections were much easier to accomplish than I had thought, so I continued to contribute small patches. The rest is history . :-)
What notable contribution did you make to SeaMonkey 2.0?
I must have touched almost all parts of the UI by now... Let's see.
fixing Get All Messages (my only trip to C++ land)
improving the Cookie Manager (making it searchable, among other things)
adding the ability to delete bookmarks from search results (and working with Neil to make sure deleted bookmarks do not show up there anymore)
writing several new or updated Help articles
adding support for more Firefox-compatible command-line options
adding UI for the MailNews Archive functionality
supporting standard key and double click events in the new Download Manager
adding support for multimedia keyboards to MailNews
porting the Master Password workaround in time for SeaMonkey 2.0
This may look like much (and it's certainly not few) but it's nothing compared to what people like Neil contributed in the same period of time: just think of all the reviews he made! Respect.
Beyond that I looked into making some popular extensions compatible with SeaMonkey 2, i.e. ones that need more than just a version bump. So far I have been successful with Nostalgy, Flat Bookmark Editing, Download Statusbar, and Firebug (yes, that's right!). I hope the latter can be fixed at the source, the others should appear at the xSidebar site sooner or later.
How can users give something back to you?
I don't know, maybe a bar of good chocolate? :-)
Seriously, my personal needs aside I'd like to see more people getting involved in the project. If you are maintaining an add-on (extension or theme), now would be a fine time to make it SeaMonkey 2.0 compatible. But coding is only part of it, so if you feel like you should give something back, you could help with marketing, quality assurance (e.g. organizing bug days), design (especially icons!), featured articles (e.g. blog posts with screen shots or videos) or even usability considerations. Helping other people in fora and newsgroups is also appreciated, of course. :-)
Oh, and if people would stop mistaking "it's" for "its" that would be nice, it hurts my eyes. :-P
Why, in your eyes, should people use SeaMonkey 2.0?
Because it has everything you need in one place. I think it's the combination of browser and MailNews that I like best but I've learned that people have different reasons for using SeaMonkey, and all of them are valid. I'm not saying that everyone should use SeaMonkey, though; in fact I tell people who really want to use just a browser to use Firefox instead if they feel comfortable with it. In the end it's just a matter of personal preference.
What next step do you see for SeaMonkey, and what would you like to happen in the Mozilla and SeaMonkey projects?
In the imminent future I think we need to concentrate on getting it right, i.e. fixing the most evident problems people have with SeaMonkey 2.0 (like the recurring high CPU load issue). The next step is to make use of more Toolkit features like the Places back-end for bookmarks which will enable syncing bookmarks with Weave, and to foster integration (Lightning, KompoZer; maybe instant messaging?). In the more distant future we'll have to keep an eye on what people expect from a modern Internet application and cautiously make the necessary adjustments.
What I would like to see is an evolution of usability (supporting the user's work flow), and an improved collaboration of Mozilla projects. The comm projects (Thunderbird, SeaMonkey and Calendar) are already cooperating quite nicely but I think there's room for improvement elsewhere.