Planet Thunderbird

January 27, 2012

James Burke

RequireJS 1.0.5 released

RequireJS 1.0.5 is available.
 
The notable changes:
Complete set of changes:

January 27, 2012 09:04 PM

SeaMonkey Trunk Tracker

Add-ons Sync Prefs: A Restartless Add-on for SeaMonkey 2.8

Ever since I ported Sync to SeaMonkey (2.1), the list of supported engines had been fixed: Bookmarks, History, Passwords, Preferences, and Tabs. With Firefox 11, the Sync developers added a new engine capable of syncing add-ons (or more precisely, which add-ons are installed). Since the Sync back-end is shared code, SeaMonkey 2.8 will include it, too. But while Firefox 11 will include UI for activating the new Add-ons engine, SeaMonkey 2.8 will lack it. This is because the Firefox changes landed pretty close to the l10n freeze so we were not able to port them in time. SeaMonkey 2.9 will include the UI changes, but why wait so long?

On January 31st, SeaMonkey 2.7 will be released (well, that's the plan). A few days later, the first beta of SeaMonkey 2.8 will follow. People like me who are on the beta channel will upgrade directly from 2.7b5 (ETA today) to 2.8b1. This is when my main working environment will be ready for Add-ons Sync.

Now I was wondering what the SeaMonkey developers could do to allow users of SeaMonkey 2.8 (on aurora, beta or release) to enable/disable the Add-ons Sync engine through preferences UI. Well, the answer is simple: Provide an add-on that adds the corresponding option!

I decided early on to give it a try myself and create that add-on. I also felt that users were probably more likely to install such an add-on if it didn't interrupt their work flow (i.e. not require a restart of the application, which in the case of SeaMonkey is often used for both browsing and mail) and took care to not break anything if it was installed on an incompatible version of SeaMonkey (say, 2.7 or 2.9). The first requirement could be solved through writing a restartless add-on, the latter by adding explicit checks to the code.

I quickly found some documentation for restartless add-ons on MDN (though they are called "bootstrapped" there). Unlike classic add-ons (which rely on XUL overlays and usually consist of many files and levels), a restartless add-on can be as simple as two files: The install manifest (install.rdf) and the code, written in JavaScript (bootstrap.js).

I guess for someone new to Mozilla-specific code, starting from scratch like this could be hard. During the development I faced several issues that you would probably not have seen with a classic XUL overlay approach. The Add-ons SDK might have been a better alternative if I had intended to write an add-on for Firefox, but since this one is SeaMonkey-only and given the requirements, there was not much of a choice.

The main issue I faced was actually in shared XBL code (preferences.xml): The constructor and destructor of preference elements throw if the element in question is not inside a preferences element. What is probably always the case with XUL (including overlays) is not true for elements dynamically added or removed through JavaScript (cloneNode/removeChild). In the end I had to replace cloneNode by createElement and stop using removeChild (i.e. the preference element is left in the preferences window until it is closed; if the add-on is disabled while the window is still open, the preference element just gets disabled).

Another surprise was that JavaScript errors inside bootstrap.js are reported as warnings in the Error Console. So if you enable the Errors filter, you won't see these warnings and assume everything is alright, while in fact the add-on does not work at all! Brilliant. :-(

Anyway, I was finally able to finish the add-on (with friendly help from Neil Rashbrook), upload it to AMO, and get it fully reviewed. :-) Here it is.

Now of course none of this would have been possible without…

Note: If you look at the source code you might see that the prefs handling (user vs. default prefs) is not perfect yet. This is something that both Neil and Kris Maglione (AMO reviewer) pointed out, but which I deliberately disregarded for the first version of the add-on.

January 27, 2012 12:21 AM

January 26, 2012

Siddharth Agarwal

Important upcoming change: starting Gecko 12, pre-Windows 7 SDKs will no longer be supported

tl;dr: if you're on an outdated Windows build configuration, upgrade.

I just checked in a patch to mozilla-inbound to drop support for SDKs prior to the Windows 7 SDK. Depending on when you last updated your build configuration, your Mozilla build might break.

Everything's documented on the Windows SDK versions page on MDN; here's a quick summary of what you need to do:

January 26, 2012 05:59 PM

January 25, 2012

Siddharth Agarwal

MSVC9+ opt builds currently broken due to a compiler bug

Optimized builds with Microsoft Visual Studio 2008 (VC9) and above are currently broken because of what we believe is a compiler bug. More information and workaround in bug 718541.

January 25, 2012 11:37 AM

More experiences with an Apple notebook

It's now been eight months since I got my first Apple notebook. A few months ago I wrote about my initial opinion, where I was pretty sure it would be my last Apple notebook too.

Since then I've had the chance to use it in a variety of situations. Spoiler: none of what I've seen has improved my opinion of it one bit.
  1. The decision to make the outer body out of aluminium is literally shocking. If the notebook isn't plugged in to a grounded socket (for instance, if I'm using the plug that comes with the power brick BY DEFAULT), I'm liable to get electric shocks if I touch the casing. I received a couple of shocks, a mild one and a jolting one, before I realized what was happening. Electrical common sense is that if the outer surface is electrically conducting, it MUST be grounded properly. Having an ungrounded plug by default, or even having one in the first place, is inexcusable. (Update: I've had several people complain to me about this, and one person also complain about his plastic macbook's screws shocking him several times. I'm clearly not the only one with this issue.)
  2. The Wi-Fi reception is the worst I've ever seen in a laptop, and only slightly better than the reception my Nexus S with its puny little antenna gets. Friends tell me it's because the aluminium casing acts as a Faraday cage and attenuates the signal. The "unibody" marketing's clearly far more important to Apple than shipping a working product. (Update: guess who says metal has a "very high" potential to interfere with wireless connections?)
  3. The original power adapters were T-shaped. However, presumably because Apple didn't like the look of and subsequently didn't include the strain-relieving flexes found on all other cables, they were easily frayed. To "fix" this, they started using L-shaped adapters. Of course, what it now means is that depending on the way I insert it, either the power cord blocks the Ethernet port or it gets subjected to strain if I tilt the notebook back.
  4. There's no VGA, DVI or HDMI port, so I need to carry around a set of three dongles everywhere I go. There's plenty of space on the left side, too, so that's not an excuse.
  5. The lack of working sleep is more annoying than I thought it would be. Amazingly, the EFI equivalent to the POST takes almost as long as Windows resuming from hibernation. A few people seem to be working on getting Windows to boot via EFI, and my hopes are mostly pinned on that.
My iPod nano media player, the only other Apple product I own, is actually well-designed (save for the fact that I need to keep the piece of crap called iTunes around on my computer, even though I don't need to use it.) This is not. This stinks of form-over-function failure.

Edit (25/1): Two inline updates.

January 25, 2012 08:32 AM

January 24, 2012

Robert Kaiser

Weekly Status Report, W03/2012

Here's a short summary of Mozilla-related work I've done in week 03/2012 (January 16 - 22, 2012):

One thing I noticed this week again wasn't just that I was able to quite productive in the end, but also that people from the community hired by Mozilla (as employees or contractors) often don't work in the same roles as they did before and therefore may end up having less time to still have that community stuff working as well as it should. Also, there's some question on how much you can engage with the community or try out other stuff in Mozilla when you work full-time on one part - and are passionate enough to also get some stuff done in what should be your free time, at times. Some localizations, add-ons, and similar projects have been feeling this in recent years and have a hard(er) time surviving due to it. After all, some people claim that "real life" isn't a myth but does exist somewhere out there and it might be an interesting quest to find out about that as well.
I think, with the kind of organization Mozilla is, we might want to think about maybe giving our staff some possibility even in their paid time to engage in the community in roles that are not strictly their work area. Of course, this can be a hairy topic, so all I'm saying is that we might want to think about that - it's far from sure that there is a good solution to be had there, but maybe there is. In the end, the community with its many aspects is what makes Mozilla great and enables us to create products like Firefox that make the life of millions of people better (yes, Firefox started as a fun side project as well, IIRC).

January 24, 2012 06:41 PM

January 23, 2012

James Burke

AMD support for Underscore and Backbone

As mentioned previously, at the moment there is no support for AMD in Underscore, a decision that also affects Backbone.

However, there have been enough developers interested in using Underscore and Backbone with AMD that forks were set up under the amdjs organization that have optional define() calls in them:

https://github.com/amdjs/underscore

https://github.com/amdjs/backbone

Ryan Florence suggested the AMD community maintain these forks, and if you would like to see AMD support as part of the main repos, click on the links above and click the Watch button. But only do it if you actually use the libraries above in an AMD context.

Hopefully this will give the DocumentCloud folks some indication of how many people might benefit from having support directly in the main repos, and maybe over time AMD support can be added to the main repos.

Both forks optionally register as AMD modules but also export global objects. This is to address the difficulty Underscore saw when only doing the AMD call, which led to the AMD removal from Underscore.

If you want an easy way to fetch these AMD versions from the command line, or to have a tool to make it easy to AMD-wrap older releases of those libraries, use volo. The README's Usage section has specific instructions on how to fetch these libraries.

If you would like to try an AMD+Backbone option that does to not modify the source files, check out Tim Branyen's explorations.


January 23, 2012 07:14 AM

January 20, 2012

James Burke

AMD, the question, and a JavaScript sugar analogy

I want to expand more on the feedback from Tom Dale and Patrick Mueller (see part 2 too), who do not think AMD is the answer, and Dave Geddes asking at the end of his post what was the question?

More on the question, and an analogy:

How can we get to a future where we can easily share JS code, one that works on the server and in the browser? 

I have been talking about the advantages of AMD because it answers that question very well, and I have been reading people's responses to suggest CommonJS (CJS) modules as the format as impractical because it cannot work everywhere. Maybe what we can do is agree on some basics that still allow for sugar.

In other words, consider AMD the "base format" for distributing JS code, because it can work anywhere. That was its design goal. However, it is fine to use sugar on top of that, and even distribute source in that sugared form. But it would be great if the runtimes/tools you use have the capability to ingest AMD (if you take in outside code) and the tools that output your code should be be able to register as AMD modules.

An analogy:

JavaScript is winning because it is widely deployed. However, not everyone wants to program in plain JS. Some folks like to use sugar, like CoffeeScript and Stratified JS. In the end though, those sugared forms reduce to JS so that it can run in the most widely deployed environment.

AMD is to JavaScript as CJS modules/browser globals are to CoffeeScript/Stratified JS

It is fine to use sugar, it just helps if that sugar can take input/generate output that works everywhere. A bit more on why AMD can work everywhere:

Wrap It Up

Any complete JS module solution needs to have a wrapped format to allow:

1) serving optimized code, where multiple modules are combined into one file.
2) dynamically loading code from CDNs.

AMD solves this need, by allowing string IDs and a function wrapper, the shortest form is here:

define('module/id/here', function (require) {
    //Module code in here.
});

The current ES harmony module proposal may be able to get around a wrapped format for case #2 (cross domain script fetching), but they need a "wrapped" format to allow #1, and it looks like:

module moduleIdHere {
    //Module code in here.
}

I think it is better to use string IDs for the harmony case, and harmony is by no means done, but still, the need is the same: when combining multiple modules together. they need to be demarcated and named.

Given old browsers and old code that cannot participate in harmony, I believe any harmony module format should be designed to be translatable to AMD since AMD works everywhere. At the same time, we should make converters from AMD to harmony. I can appreciate these conversions may not allow 100% conversion, but it should be a very large percentage. I see any harmony proposal as sugar given it will not be ubiquitous. Maybe in 2-5 years after ES.next comes out the story will be different.

Give Me Some Sugar

Tom and Patrick object to having to write too much boilerplate, or ceremony, to code a module, and that is great goal. It is the same reason why some people like CoffeeScript or Stratified JS. But, we need to have a common wrapped format if we want to share code in one file bundles and from CDNs.

The Middle Way

Viewed in this light, I'm hoping we can all code in our preferred sugar, but still be able to share modular code at the base level. Here are some suggestions for us to get to that goal, some for browser library authors, node library authors, JS environment authors, and AMD Toolmakers:

Browser Library Authors

Not all of these may work for you. If you cannot do the first or second one, at least consider the third option.

Consider writing your modules using AMD. The define(function(require){}) wrapper is really light on boilerplate/ceremony, particularly if you are already using a CJS-style of code. There are AMD tools you can use to help with the building of your library, and it allows others with AMD tools to easily use your code in source form.

You get a free "custom builder" capability with this approach. Consumers of your source, particularly if it consists of multiple modules, can just drop your library code in their project, and when they do a build with AMD tools, it will only pull out the modular pieces of your library that they actually use. That is awesome.

You will be using a common idiom that people understand. It will be easier to translate skills.

CJS modules have this quality too, so feel free to use them if you prefer that style. In that case, I hope you will still consider the rest of these suggestions.

Consider using AMD if you need to bundle more than one module together. Almond can be used to provide the AMD API shim. Ace's mini-require might be another option.

If you limit yourself to just define() declarations, no loader plugins or callback-style require, then you can easily make your own wrapper. If you just need a way to concatenate the modules together, but do not need the require calls after a build because you are using globals (I think Tom fits in this group) then you might be able to get by with plain anonymous function wrappings, so this item may not apply to you.

For the top-level, public API for your module, feature detect for define.amd, and register your code as an AMD module. This is particularly helpful when you have dependencies. You can also get away from using globals and allowing better named dependencies.

You can still export a global for now, even in the AMD case, because AMD is still new to some people, and as underscore discovered, it can lead to problems. I expect this type of problem will go away after AMD support has been around a while and the global export can be removed. Since modules are still a new thing to many JS programmers, there will be a transition period while developers get used to not relying completely on globals. This will be true even if/when harmony modules ship.

By calling define() an AMD consumer now has the option now to get direct references for your code under a name of their choosing, and properly state and wait for its dependencies before running with them. The umdjs/umd project has some boilerplate examples to help you get started with this item.

Node Library Authors

If you author user-land node modules for others to use, in other words, do not develop Node core, and you think your library may be usable in the browser, then:

Stick with declarative dependencies. Avoid using calculated values for dependency names:

var a = require(someCondition ? 'a' : 'a1');

Ideally node would support a callback-style require(), as AMD does, to help when you do have a calculated dependency (see JS environment authors section below), but in the meantime, the module will translate very easily to AMD with just declarative dependencies:

var a = require('a'),
    b = require('b');

These type of calculated dependencies will not work in harmony modules either, so it is good to get used to this now.

Avoid __dirname and __filename. Or at least, be aware that in AMD loaders, you have access to module.uri which is like __filename, and a __dirname can be calculated from that value. So this type of detection is a good way to go: var uri = module.uri || __filename.

Use amdefine to create a define() method in your module, and call define() to define your module. This will make it easier for browser authors to directly consume your code, and the RequireJS optimizer removes the if(){} block that uses amdefine, so browser developers will not take the hit of that code or that module.

Consider using AMD as the bundling format, if you make a bundling tool, like browserify. If you need help with this or have questions on how best to do it, feel free to contact me.

The wrapper can be as simple as define('id', function(require, exports, module){});. You may need to provide an option to wrap your output in a function and use an internal define inside that function, but call the global define to expose the public API for the bundled set of modules.

By using the amdefine module as a dependency in your package.json, this will help test a real implementation of define(), and help core Node contributors get a feel for how many modules would like to have define() as an API option directly in Node.

JS Environment Authors

Do you make an environment that can run JavaScript? Like Node, Rhino, Mozilla's Jetpack?

Support AMD APIs for easily ingesting code. You can support the sugared CJS modules as a default, but allow JS library authors to reduce their feature detection boilerplate and allow easier code transfer by allowing define()'d modules.

This does not mean that you must load modules asynchronously. The nice thing about the basic define() API is that it works well in synchronous environments too, particularly with the declarative dependencies.

For Node in particular, I know this has been a contentious thing to consider, and it can be done in phases. Not all the phases need to be done, particularly loader plugins, but each one allows easier code sharing:
The previously mentioned amdefine package for Node, which consists of one file, does all of the above, and I am happy to continue work on it, build up unit tests for it, do whatever code changes you think are needed that would allow something like its define() implementation to land in core.

I think Node's synchronous module behavior can be maintained, but still open up easier code sharing pathways with code written by browser-based developers.

I hope my previous posts show why Node's module system as-is is not the right general solution for module-based development in the browser. The ES Harmony module proposal set has similar high level features as AMD, like a module in a block, the equivalent of a callback-style require. The need for those things are not going away.

Plus, the more browser developers (the biggest JS audience there is) can easily transfer their knowledge/idioms/code to run under Node, the more it helps ensure Node's longevity.

Support in other JS environments is also encouraged. It can take a similar path to the one outlined for Node. Mozilla's Jetpack right now only supports a simple define() call, and that is great. It still allows for some basic code sharing. Even getting a little bit of support, doing small steps is fine.

AMD Toolmakers

For those of us that make AMD tools, there are some things we can do that can help people share their code easier. Here is what I am doing:

Create translation tools. I'm working on volo, which can do this, among other things. With volo, you can download your favorite libraries from GitHub and optionally specify AMD wrapping for the library. Right now it is set up to wrap a library that uses globals. I want to add support for converting CJS/Node modules to AMD. CJS conversion is cleaner than the globals wrapping -- the globals wrapping needs more information from the developer to work.

Consider configuration of global import and export of module values. In a runtime loader, allow the developer to configure something like "when underscore loads, grab the global _ and use it as the value for the module". And conversely, "when this AMD module loads, also assign the module export value to a global named 'foo'". This may be better served by the translation tool -- it can be more direct, precise -- but this might help for cases in which the developer does not want a tool to modify the library source. It would only help with libraries that have no dependencies though, so it may not be useful enough on its own.

It is still best for library authors to call define() themselves since they can be more precise on the dependencies and allow getting direct references instead of using globals. However, the AMD toolmakers can help bridge the gap.

Globalize All The Things

All of the above assumes you think getting local handles on other modules/scripts is better than using globals. Not all JS developers hold that position though. In particular, I think Thomas Fuchs, Jeremy Ashkenas and to some extent Scott Gonzalez have all expressed a desire for a system that does not require changing the source files from using globals.

I'm open to hearing how that might work, but I think it is unrealistic as a general approach because:

We already have a problem with globals today, where multiple third party libraries want to use the same global but at different versions. For anything larger than a simple app, it is not scalable to try to do a "noConflict()" approach on nested dependencies.

You could try to get around that by executing module sets in a "sandbox", but the tech to do that with today's browsers, iframes, is riddled with land mines and it has trouble sharing things across frames.

It is bad practice for modules to name themselves. Case in point: Zepto. Zepto is targeted as a jQuery replacement. However, to use it as-is, it means libraries like Backbone have to do manual detection for it: var $ = root.jQuery || root.Zepto. This is not scalable, and it would be to Zepto's advantage to register as an anonymous module, and then allow the end developer, not every library author, to map require('jquery') to a path that resolves to Zepto instead.

It does not map well to other environments like Node and Jetpack, which have gone away from globals.

To be clear here though -- I want a module format that allows for the use of globals, and AMD does allow that. It is just not good to enforce use of globals as the path to code sharing/use. There needs to be a way to get local references via string names that can be mapped to other providers of that functionality.

In the end, I see globals as another kind of sugar. The tricky part is that it is hard to auto-convert given the variability between what a file is called, what global(s) it can export and what dependencies it uses, and mapping those dependencies effectively to files. Systems like AMD/CJS have a much more consistent approach to this, which leads to cleaner code and more effective sharing and tooling.

Summary

Hopefully this gives some concrete ways we can work together even if you prefer some sort of sugar over plain AMD.

Supporting AMD, even just on the output/input edges, is not because you think dynamic loading of scripts is the way to go, or that you have to throw away your favorite sugar. It is about getting a base level of code understanding that allows effective sharing, tooling and reuse across all JS environments.

January 20, 2012 07:44 PM

Ludovic Hirlimann

Major Update testday this coming Thursday , January 26th 2012

On January 26th 2012 , the Thunderbird team is organizing a Testday. Our objective is to make sure that we aren't breaking anything for people that will update from 3.1.x to 10.

Instructions on how to participate and how to join are available here : https://wiki.mozilla.org/Thunderbird:QA_TestDay:2012-01-26

January 20, 2012 10:39 AM

January 18, 2012

Siddharth Agarwal

C# 5.0 to have fresh bindings per iteration

Straight from Eric Lippert. Great news. Now if only ECMAScript Harmony included a fix for this bug...

January 18, 2012 10:08 AM

January 17, 2012

Robert Kaiser

Weekly Status Report, W02/2012

Here's a short summary of Mozilla-related work I've done in week 02/2012 (January 9 - 15, 2012):

I've seen that my previous work style created a lot of personal stress so I'm now trying a variation to try and deal with it somewhat (fitting with my post on change) and try to do fixed work times every day to see if that reduces the stress potential. For now, I'll try to work from noon to 9pm every work day (with an hour in between for a meal and grocery shopping), though I'll probably be somewhat flexible about that, so I can make some evening appointments at some days or be able to have some late meetings sometimes. Still, it centers around fixed times and I'm setting an alarm to get up everyday. I hope this more regular schedule helps me somewhat. We'll see. :)

January 17, 2012 07:27 PM

James Burke

Reply to Tom on AMD

Tom Dale had a good post about why he dislikes AMD. Please go check it out. We talked about it a bit while he was writing it. It is great he took the time to write it out. We need more of that. We are all trying to find the best path, and it is great we are talking this out.

While I appreciate the critique, what is missing is a solid alternative to AMD. In particular, "use build tools to wrap up CommonJS modules" is not a generic solution. It does not allow for generic dynamic loading of resources, particularly from CDNs. Dynamic loading is needed for big sites that still do builds but want to stage loading of the site as the user uses it.

On his concern about too much ceremony -- this is the minimum amount of ceremony:

define(function(require) {
    //Module code in here
});

By doing that, it is easier for other people to consume your module since module authors do not have to provide "built" versions of their module to use on CDNs. And if they did have to do builds, what format would they publish it in? It would need a function wrapper. Hey, AMD has that!

That simple function wrapper allows moving away from globals, although you still can use globals if you want. It allows for dynamic loading. Recall I'm talking about built layers for staged loading/performance, not "load each module with a separate HTTP request". It allows very simple module sharing now. It allows easier sharing of built files too, since AMD specifies the built file format.

With AMD, you can still use build tools if that is how you like to roll in dev. Go for it. Almond is a great AMD one for that purpose. Here is an example of using the RequireJS optimizer for runtime HTTP-served builds. And since there are multiple AMD implementations, you can choose how big of an AMD lib you want.

I'm sure Tom could adjust his 50 line loader to process the define calls, since his built code probably has function wrappers. He could even adapt his "hydrate from strings" loader to use the AMD syntax.

By using that function wrapper, others could consume his individual modules and use their own choice of AMD loader to deal with their particular loading needs.

On the "hydrate from strings" build approach: I would prefer using appcache and using built layers of AMD code instead. This gives much better overall mobile app performance since more than just JS can be cached. But that is more of a side point. Feel free to use the "hydrate from strings" approach, AMD could be used in that fashion too.


My summary: it sounds like he just wants to avoid a small function wrapping and a level of indent. And to be fair, many simple AMD introductions use the array of dependencies syntax, not the sugared form above, so I can appreciate the confusion.

But trying to avoid that function wrap+indent comes with some code sharing costs, and the alternative he mentions does not handle the breadth of JS module consumption.

January 17, 2012 07:02 AM

January 12, 2012

Robert Kaiser

Weekly Status Report, W51/2011-W01/2012

Here's a short summary of Mozilla-related work I've done in weeks 51/2011-01/2012 (December 19, 2011 - January 8, 2012):

This report is both covering 3 weeks and running late despite that, but it's not due to laziness on my side, it's most due to the holidays, as I took two weeks mostly off and then had a number of backlog stuff to work on this week. I followed bugmail and most planet and newsgroup traffic I'm interesting in even while I was at home with my parents, but I didn't go too deep into anything during that time, and it was good to not strain myself too much for some time. Also, I'm happy I found the time to write about all the change going on in my life but also all around here at Mozilla. This week I'm back to work with full power, and a lot of stuff is happening as a lot of exciting goals have been set at various levels in multiple Mozilla project for this first quarter of 2012. And I have a couple of interesting milestones and events to look forward to myself in this new year! ;-)

January 12, 2012 10:32 PM

Calendar

Lightning 1.2b2 is now available

Just a short note, the second beta of Lightning 1.2 is now available on the developer channel of addons.mozilla.org. It fixes a regression that keeps the user from saving events with attendees. If you were having trouble in the past, please do update!

Also, if you are a localizer, please note that we are nearing the final beta of Lightning 1.2. A total of 9 locales are green but have not signed off yet and 5 other locales are just missing one string for translation. I'd love to get some more locales in the Lightning 1.2 release, as right now its only 26 locales.

January 12, 2012 03:00 PM

James Burke

Simplicity and JavaScript modules

All of us are looking for simplicity, but there are different levels to simplification. This is a story of what could be considered simple for modules in JavaScript. This post was prompted by the removal the optional AMD define() call in underscore.

For a post on simplicity, it is a bit long, but I'm not a great writer, and I find I normally edit myself so much as to lose interest in posting, so then I end up not communicating. Better to start communicating even if imperfect.

I want to lay out why AMD modules are the simplest overall module solution for JavaScript at the moment, and where other approaches are not as simple as they may appear.

Script Tags

JavaScript does not have syntax for modules, but most programming languages do. "import", "require", "include" seem like popular choices.

JavaScript on the web has meant using script tags and manually ordering those script tags so that dependencies on global objects are worked out correctly. It is also important that those dependencies execute in order.

That sucks for the following reasons:
So what happens?
Option 1 is clearly not appropriate for the full spectrum of web development. There are HTML game engines, webmail/office suites, and then browser-based "no server" development like Phonegap-backed mobile apps.

So it is best to have some API or syntax in JavaScript to get units of code. For it to work well, we should all be using the same API. Otherwise things get messy real fast.

CommonJS

The CommonJS group tried to work out a system for doing this. It is pretty simple too:
There were some wrinkles though:
AMD

The original participants on the CommonJS list thought it was better to blue-sky the development of a module syntax, not be held back by what might work in the browser, just what might work with existing JS syntax. The group also started off as ServerJS, so they were also in the mindset of what would work best on the server, where file I/O is cheaper/easier.

The hope was that if they worked out a module system that worked well with the existing JS syntax but had problems in the browser, hopefully they could convince browser makers to plug the holes to make it possible. In the meantime, since they were developing servers that could run JS -- they could just bundle up/transform the JS using server tools, or offer a compile step, while browsers caught up.

However, for those of us who came from Dojo, requiring a server tool or compile step to just develop in JS was a complication. I'm going to mangle Alex Russell's quote on this, but "the web already has a compile step. It's called Reload".

Why force the use of a tool to just start developing? It should be simple: just a browser and a text editor.

This was accomplished by taking the CommonJS format and allowing a function wrapper around the code:

define(function (require){
    var dep = require('dep');
    return value;
});

Or, the shorter form::

define(['dep'], function (dep) {
    return value;
});

Since a function wrapper was used, it meant:
So the story around modules gets very simple, no special tooling to start, no worrying about "I need to run a converter to share this module", no special sets of instructions for your server of choice to do conversions.

Yes, a loader library is needed, but one is needed in any case, there is no native JS syntax. That is the basic ante for any module system that scales up beyond a simple JS concatenation for a Rails application.

For some people, a function wrapper with a level of indent was not seen as simple enough. However, designing a system without it meant a bunch of complexity once you stopped looking at an individual file. A miscalculation of the overall complexity cost.

Loader Plugins

Another simplicity in AMD systems: loader plugins. Loader plugins would not be considered if you had copious, synchronous IO capabilities. However, by fully embracing the network/async loading on the web, you start to see how creating a loader plugin that treats a dependency as a simple string as useful.

Some dependencies are not static scripts, but could have more complex loading (Google Maps code) or simple HTML templates that need to be loaded for the module to be useful.

In AMD, this can look like so:

define(function (require) {
    var maps = require('googleapi!maps?sensor=false'),
        template = require('text!form.html');

    return function (data) {
        //You can  synchronously return a value
        //based on the template.
        return template.replace(...);
    });
});

Compare that with a non-plugin approach. Do you want to load those two resources in parallel? That would be ideal, but then to do that, you probably need something like a promise library to help out. And now you have two problems. I mean that partly in jest -- I use a promise library for some types of code -- but it is definitely a complexity hurdle to jump.

The async networking also means your module is not completely ready until those resources are available, so your public module API now must be a callback API. For "simplicity" assume you just load the dependencies serially, to avoid some of the promise-isms.


define(function (require) {
    var googleapi = require('googleapi'),
        text = require('text');
        googleapi.fetch('maps?sensor=false', function (map) {
            text.fetch('form.html'), function (text) {
                //dependencies are now loaded.
            });
        });

    return function (data, callback) {
        waitForDependenciesToLoad(function (data, callback) {
            callback(template.replace(...));
        });
    }
});

Loader plugins simplify async development, and some of their resources, like the text templates, can be inlined in a build file with other JS modules. Loader plugins give you simplicity and speed.

If you like transpiling other languages into JS, they are great for that purpose too.

ECMAScript

The ECMAScript group wants to get modules in for the harmony effort, the next ECMAScript release. They chose to not go with the CommonJS syntax, but what did they did choose looks fairly similar on the surface. It favors the introduction of new syntax to get some advantages with compile time checks. You can check out the following for more information:

Those links have changed over time, so the rest of this feedback may not be valid in the future. As I read it today, I do not believe harmony modules give much benefit over what AMD can do now, but harmony modules do introduce more complexity, and has some unanswered questions:
The new syntax in harmony modules is used to enable some compile time checking of export names and if they are referenced correctly.

However, compile time checking to see if an export name is use correctly is a very small benefit for the end developer given the other costs above. Furthermore, I want more than just an export name/type check. I want intellisense on the arguments that can be passed to functions, general data type information and comments on usage.

Working out a comment-based system that can reflect this info into text editors will provide much more value. Since it is comment based it fits in with old browsers. I know it is harder to agree on that comment syntax (mostly because it is easy to bikeshed), but it will simplify developers' lives more, and lead to faster turn-around time on development.

If something like loader plugins are not natively supported, and the optimization story is not sorted out, it does not have an advantage for AMD today, and AMD is simpler.

However, the harmony module_loaders API is really useful. I'm not sure it needs to be as big as it currently is. I would be fine with something like Node's vm module API as a start. Basically, some container or vat I can load scripts into without interfering with other scripts. This is one area that is very hard to do on the web today.

So for me, the "simple" solution for any ES6 module-related work:
I will post this feedback to the es-discuss group. I wanted to hone my feedback before giving it to the es-discuss group, but this will have to do, otherwise I may never give it.

Underscore and AMD

This brings us to the recent code change to remove the AMD block from underscore. The arguments for removing it are listed here, but I think the main argument is really about what is simple for Jeremy: He does not need it for the kinds of sites he builds, and by adding it, he has gotten reports of problems.

Those problem reports go away if he also exports underscore as a global, but he does not think he should have to do that if AMD is available. I do not think that is a fair bar to hold for AMD, since he would have to do the same for a harmony syntax, so his lib could be used in cases where ES loading and old style global loading is still in play.

Some feedback on his specific reasons:

Folks requesting other module formats for other loaders.

No other module format comes close to the level of support AMD has: AMD has multiple implementations, better support in other libraries (Dojo, jQuery, libraries friendly to Ender-bundling, MooTools), it is used in real sites, and has a thriving amd-implement list and thriving implementations. What else can claim all of those things? What else is being asked for inclusion?

I can appreciate it is easy for someone to come up with a loader syntax and want people to use it. I think AMD has gone the extra steps though to be considered more of a standard. But it depends on what you want to use as for standards of legitimacy.

If any library that depends on Underscore (and there are many of them: http://search.npmjs.org/) does not yet 'support' AMD, but Underscore does, things get royally screwed up.

npm is for node modules, not browser modules, so they would not have the error that was being reported for Underscore.

That said, I do believe Underscore is a common dependency for browser-based code. But for the browser, as mentioned, registering a global is perfectly acceptable for this transition period, something I believe will need to happen anyway no matter what modular format is chosen. There will always be a transition period.

In an ideal situation, libraries do not have to be modified to support a particular script loader (or group of loaders).

The point is to make developer's lives simpler. A script loader like that does nothing to help order the dependency tree correctly, or use a naming convention that can be parsed easily by tools like optimizers.

The browser globals with implicit dependencies just do not scale well past maybe 15 dependencies? Not everything fits as "lets concat all the scripts" Rails app. But I'm open to seeing a design that might scale up.

JavaScript's upcoming native module support is entirely incompatible with AMD.

They are very compatible as far as base semantics. As mentioned above, ES harmony modules are still baking, not ready for prime time. But even with that, it would be very easy to convert AMD code to harmony module code -- since the dependencies are all string names it fits in. Loader plugins would be a problem for sure, but basic modules are easy.

It is much more compatible than the current "browser globals and implicit dependencies" approach.

Loading individual modules piecemeal is a terrifically inefficient way to built a website. Because of this, there's the great RequireJS optimizer, which will turn your modules into ordinary packages.

The browser globals approach already depends on build tools, so I'm not sure why this is a knock against using AMD. A bunch of manually typed HTML script tags perform just as poorly.

Fortunately, since dependencies can be easily statically determined with AMD calls, the developer no longer has to worry about manually figuring out the load order, and there can be (and are!) many different build tools built on top of the standardized AMD API.

Summary

In the end, though I just think it boils down to Jeremy not needing this personally based on the scope of his work, and he has other things he would rather work on. It is hard to get a standard of legitimacy in this area, so it is easier to just wait it out. For the particular issue in Underscore, the simple export of a global even in the AMD case would have solved the issue, but such is life.

I'm a bit sad because Backbone and RequireJS have been a very popular combination. They fit very well together. The thought of maintaining a fork/branch is distasteful, particularly since the AMD patch for Backbone was smaller than the code it replaced.

Auto-wrapping tools are difficult to do generically given how scripts want to grab globals. The dependency name can have weirder names that do not match the file name, so it loses the nice, simple dependency parsing of AMD module IDs. It means creating a centralized list of global names that map to IDs/paths. Not very webby/distributed. Not very simple.

Oh well. It probably means AMD just needs a bit more time out in the wild, even more adoption, and we'll see how people feel in 6 months.

Another Approach?

I have heard complaints from folks on the internet about AMD from time to time, but they have not offered anything better, particularly given the simplicity tradeoffs mentioned above. I think it is just an NIH thing most of the time, or getting it mixed up with generic browser script loader.

Here is a survey of things I know about:

Ender is fine if you want to just build a file that you will not change often and use it in place of jQuery, but it really does not help with the larger site structure and loading issues, being able to dynamically load. It is not a general module system for the web. It basically is just like the CommonJS "do a build before starting development" approach. Same as SproutCore/Ember. Same complexity problems as mentioned above, and complicates individual module debugging.

Dan Webb started something with loadrunner. It supports part of AMD, and the "native format" it supported do not seem better than AMD, maybe just another function nesting and different API names.

Ext has something similar to AMD, but mixes in a particular class declaration syntax into the format, so that will not fly as a general solution.

YUI is close, but obscuring what a dependency name loads on a Y instance makes it hard to associate what came from what module, and the API to add a module relies on naming the module and putting named fields on the Y instance. This will lead to name collisions.

What else am I missing?

One thing these approaches all have in common: they get away from the browser globals and implicit dependency approach used by traditional browser scripts. If you think something using that traditional pattern is the future, please describe how it might work. Remember, requiring build step to just start developing is a complication. That does not scale well across all the types of JS development mentioned above.

While Jeremy and I were talking in the documentcloud room, he mentioned that Ryan Dahl, if he could do it over again, would prefer not to use CommonJS modules system for Node, but do something closer to how browsers load scripts in script tags.

I think I have heard that comment too, but in the context I heard it, it seemed like an off-hand comment. I'm not sure how much that was just about having to wade through CommonJS discussions or actual problems with the module API. I would love to hear more about it though. Ryan or someone how has more info on this, if you happen to see this post, please clue me in. I'm on github, the amd-implement list, or on gmail as jrburke.

I want to get to a workable, simple solution that works well in web browser too. I only do AMD because I need it and I think it is the simplest overall path for end developers. But I want to solve other higher level problems. I want something to good to win. It does not have to be AMD, but I do think it hits the right simplicity goals particularly given browser use. It will not be brain-dead simple because upgrading the web is not simple. But it does a pretty good job considering.

I feel like the folks doing AMD have done their due diligence on the matter. ES harmony may be able to do something a bit different, but the basic mechanisms will be the same: get a handle on a piece of code via a string ID and export a value. The rest starts to look like arguing paint colors.

Anyway, enough of that. Back to making things to make things better.

January 12, 2012 06:38 AM

Thunderbird Blog

The Plan for the Mozilla Thunderbird Extended Support Release

We are pleased to announce that Thunderbird is following the Firefox Extended Support Release plan as documented in proposal for an Extended Support Release (ESR) of Firefox. As mentioned a few months ago in Thunderbird Enterprise specific wiki pages, the ESR version of Thunderbird is for use by enterprises, public institutions, Universities and other organizations… Read more

January 12, 2012 05:01 AM

January 11, 2012

Joshua Cranmer

How bugs get fixed

Recently, I have had the misfortuneopportunity to fix bug 695309. This bug is perhaps a good exemplar of why "obvious" bugs take weeks or months to fix; it is also a good example of why just reporting that a bug occurs for the filer is insufficient to fix. In the hope that others might find this useful, I will explain in a fake liveblogging format how I fixed the bug (fake because I'm writing most of these entries well after they happened).

October 20

There's a bug that "Thunderbird sometimes marks entire newsgroups as unread" in my email. Time to open up the bug report… reported in version 8… I'm pretty sure I've seen this once or twice before, so I don't think it's just a "the news server borked itself" issue. Time to file it away until when I have more time.

November 12

Another comment reminded me that I have this tab open. I've definitely seen it a few times, but I need to remember to keep Thunderbird open with logging enabled to figure out what's going on. It's reported as being a regression from version 8, when I checked in a slew of the NNTP URI parsing patches, so that seems like a probable target to look at. The question is why URI parsing would be causing an intermittent problem instead of a constant issue?

December 3

Some NNTP logs. Nothing is obviously amiss (not terribly unexpected, since logging either tends to drown you in useless information or omit the things you really want to know). Note after the fact: the NNTP logs in fact contain the smoking gun; it's just that the poster trimmed it out.

December 6

Bienvenu comments that no developer has seen the problem; this isn't true, as I have seen it (but just taken to avoiding it as much as possible). At some point in time, I figured out that the issue could be avoided by shutting down Thunderbird before putting my laptop to sleep. After being prodded over IRC, I finally sat down and attempted to debug it. The working thesis is that the problem is that newsrc files are getting corrupted, so I faithfully save several copies of the newsrc for confirmation. The msf files are also generally good candidates, but since other flags are untouched, it's highly unlikely in this bug.

I successfully trigger the bug once. The reports are mixed: the newsrc didn't get trashed as expected at first, but later it did. However, there is a brief window of time after the bug happens which allows you to fix it, if you shut down Thunderbird. Knowing what I now know, this is because the newsrc file is written out on a timer, so the newly-all-unread messages wouldn't have been saved to disk to show the bug. Since I always think of what to log after the fact, I try to trigger it a few more times.

None of the later tests are quite so successful as the first one. It does start to dawn on me that the bug probably has two parts. There is a first step that puts the group into a pre-bug situation; a second step actually produces the symptoms of the bug. Omniscient addendum: the first step is where the bug happens; the second step is just the delay in getting the bug to occur. I report my findings, and subsequent comments all but confirm my hypothesis for a necessary component.

December 12

This bug seems to be happening for me only when I don't want it to happen. I thought of more things to test earlier, and had them ready to copy-paste into my error console to try to find a smoking gun. This test confirms that the fault originates with the newsrcLine (so something reset that); more investigation leads to only one truly likely scenario to cause this to happen. At this point, I am all but convinced that the bug happens in two parts. All of the debugging needs to focus on when the first part happens; the symptoms (everything being marked read) are a result of Thunderbird attempting to repair the damage that had already been done. Since most people are going to try to report based on when they see the problems, I'm probably not going to get anything useful.

December 13

Hey, I found it again. Tests confirm that the high water number was first set to 0. This means either we have memory corruption or we are setting the value incorrectly initially. Looking at the code, this is set from a call to sscanf. A simple test indicates that I can set the input value to 0 if I don't have it scan a number. Now all I need to do is figure out network traffic that can cause this. Time to try to trigger it with xpcshell tests. And then get frustrated because I still can't do it reliably.

December 18

With Wireshark (logging on Windows is rather annoying), I finally can track down the network traffic of interest. It turns out that we are off-by-one in terms of responses. This really should be enough to get xpcshell to report the error. However, it also means I probably should finally give up and go for the NNTP logs again to catch the error: it is painfully obvious that the problem is that the internal state is futzed up. This also means that other various newly-reported issues (more frequent auth failures, various alerts like "Not in a newsgroup", etc.) are pretty much confirmed to be the same bug.

January 9

I finally buckled down and turned my very old hackish code for NSPR log management into an extension. This means that I don't have to futz with environment variables on Windows, and it also gives me an easy way to trim down my log size (since unlike environment variables, I can stop logging). I test and finally get the NNTP log of interest.

Now that I have a log, I can try to work backwards and figure out how this bug happens. The failure is easily ascribable to somehow thinking we've already opened the socket when we open a socket; this much I have known for almost a month (the Wireshark told me). What the NNTP log gives me is a more fine-grained ability to try to trace the code after-the-fact to figure out where the bug is.

Working backwards from the log

NNTP logs helpfully record the address of the the NNTP protocol object when emitting output, so the best place to start is from the first line of that object. Since the numbers are hard to read, so I replace the addresses with a more obvious string like "evil." The next state was set to SEND_FIRST_NNTP_COMMAND—that clearly should be NNTP_LOGIN_RESPONSE, so let's see why it might be skipped. The latter is set if m_socketIsOpen is false, so perhaps someone could open a socket if it isn't set.

This variable is set only by nsMsgProtocol, specifically the LoadUrl method. So who might call that? Still nothing out of the ordinary is popping out at me, so it's time to return to the logs (A particularly astute developer might be able to find out the bug without returning to the log here, but I doubt most people would come up with the final flash of insight yet).

To figure out the problem, it's important (to me, at least) to set out the time frames. The natural sequence of events for a connection is to be created, connected to the server, and then go through several iterations of running URLs. Is this bad connection a new connection or an old one (since I started the log after TB started up, I can't guarantee that this is truly a new connection)? Thunderbird stupidly (but helpfully, in this case) tells me when the connection is created, since we get a log message of "creating" in the constructor. Since this message doesn't appear, it's being reused.

Wait—that message is there, tucked just underneath the lines that tell me LoadUrl is run. As I am often wont to do, I announce my revelation to IRC: "< jcranmer> bienvenu: please slap me". The code for the constructor is pretty simple, but there is one little function call that ends up causing the problem. If I tell you the exact revision that caused the regression (specifically, the first hunk of that the patch), can you find the regression? Click me if you can't

Reproducing the bug

Now that I know the exact sequence of events to cause the bug, I can write a test to reliably reproduce the bug. I can also explain why the symptoms occur. First, a connection's socket dies, but it doesn't fail the timeout check in mailnews code, so it remains in the cache. Next, the server schedules a URL on the connection, which promptly dies. If there are many more URLs to be run (when we're doing, say, a timed update), then we have several elements in the queue waiting to be processed. Now, we attempt to run a new URL; with no connections available in the cache, we now create a new connection and run the new URL on that. Since the queue is not empty, the SetIsBusy(false) call ends up pulling a queued URL and setting up the state (including opening up the connection) and running that. Then the constructor finishes, and the new URL for which the connection was constructed is used to initialize it. Since the connection is by now open, the code moves straight to the run-my-URL part of the state machine, which misinterprets the login response as the answer to the command it just sent. This ends up leading to all of the various badness subsequently observed.

The description of these events is pretty complicated. A condensed version is added to the test I constructed to get this to happen, which is called, fittingly enough, test_bug695309.js. I am not going to try to come up with a better name, as I think most people might agree that this is where naming tests after bug numbers is most desirable. Naturally, the code to actually trigger this is complicated: I started with code to trigger just the unread effect, and then switched to monitoring the highwater mark instead (one less download of messages). I need to fill up the connection cache and then figure out how to kill the connections (restarting the server seems to do an adequate job). After that, I need to run enough URLs to cause the connections to queue, and then trigger a load of the folder in question at precisely the right moment. All of these requires paying careful attention to what happens synchronously and what does not, and it all relies on knowing the precise steps of what will happen as a result of each action. Any of a small number of changes I could make in the future is probably going to "break" the test, in that it will cease to test anything meaningful.

Postmortem on fixing it

I'm sure some people might look at this bug and ask several questions. Let me try to anticipate some of them and answer them.

Why did the reviewers fail to notice this change?
This bug is a result of the confluence of several changes. In the beginning, SetIsBusy was mostly a no-op, so calling it from the constructor was safe. Then the URL queue was added, and SetIsBusy was used to indicate that the connection was ready to receive a new URL from the queue. This turned it into a time bomb, since the code was correct only because the server was null in the constructor and the queue should have been empty during connection construction anyways. The final change was moving initialization of the server, which triggered the time bomb. But even then, it triggered the bomb only in a rather abnormal circumstance. At no time would the code have failed any automated tests or any of the "does your patch work" tests that a reviewer normally goes through: robustness during connection interruption is both sufficiently difficult to test and rare enough that it generally doesn't get tested.
Why did this bug take so long to track down?
The time since December 1 is truly a result of lack of time: I have had maybe 1 good week to work on anything due to outside factors. There are two, maybe three, people in active participation with Mozilla who know this code well, and out of those, only one was able to somewhat reliably reproduce it (specifically, the one with the least amount of time on his hands). I could have relied on others to gather the information I needed, but my previous efforts in QA have taught me that getting people to give you necessary information is often very difficult, especially when the information collectable at the obvious point in time is completely useless. I realize in retrospect that there were some more technically inclined people in the bug (at which point in time I was already devoting as much attention as I felt I could spare on the bug anyways). The bug is also particularly pernicious in that the most valuable information is that which is gathered before any visible symptoms occur; it was after I figured out how to discover that the bug was going to occur that I could track it down further.
Will the fix be backported to more stable branches?
At this stage, I am looking at two fixes: the small one-liner that fixes the specific bug, and the larger patch which fixes the larger issue of "the NNTP URL connection queue is a ticking time bomb". The former I would definitely like to see backported to aurora and beta (and possibly release if there are plans for another one before the next uplift), and I can't see any reason a small patch on the most-highly-voted TB bug filed since 01-01-2011 would get rejected (it is the newest bug to have more than 5 votes, and the next largest has 1/3 less and is almost twice as old).
Why is this bug so hard to reproduce?
If you think to the cause of the bug, it is that it is passing a check in a function that is always called. It therefore seems like this bug should be triggered a majority of the time, and not an undependable minority. As I alluded to earlier, the problem is that this also has to interact with a buggy pending URL queue management system. In short, most of the time, this queue will be empty during the initial, buggy call; with a poor timing of events (less likely to happen on most developers' computers, in short), the queue will cease to be empty and cause the problem. Indeed, when crafting my test for reproduction, I discovered that letting the event loop spin in one particular location (after killing connections) would fail to trigger the bug. In the real world, that is one of the places where the event loop is most liable to spinning for the longest.

January 11, 2012 02:59 AM

January 10, 2012

Mike Conley

Cut the Rope in HTML5 and Javascript

The developers of the puzzle game Cut The Rope have ported their code from Objective-C to Javascript and HTML5.

And, despite the IE slant, the game works really well in Firefox!  Check it out:

Visit http://www.cuttherope.ie to try it out!

January 10, 2012 01:58 PM

January 09, 2012

Rumbling Edge - Thunderbird

2012-01-08 Calendar builds

Calendar release history

Common (excluding Website bugs): (12)

One can get the latest Lightning .xpis here.

Sunbird will no longer be actively developed by the Calendar team.

January 09, 2012 08:04 AM

2012-01-08 Thunderbird comm-central builds

Thunderbird release history

Thunderbird-specific: (21)

MailNews Core: (16)

Windows builds Official Windows, Official Windows installer (discussion)

Linux builds Official Linux (i686), Official Linux (x86_64)

Mac builds Official Mac

January 09, 2012 08:01 AM

January 08, 2012

Mike Conley

Monkey Island 1: The Secret of Monkey Island running via Javascript

Some fine fellow has written some Javascript that runs one of my favourite games in the browser.  I just watched the opening cutscene of Monkey Island in Firefox!

It’s still a bit buggy, but it’s a start!

Here’s the source code.

 

January 08, 2012 09:28 PM

January 06, 2012

Calendar

Lightning 1.2b1 is ready

In case you are using Thunderbird 10 or Seamonkey 2.7 betas, you will be happy to hear that after some Christmas delay we have released Lightning 1.2b1 to the addons.mozilla.org beta channel.

To get it, please visit Lightning on addons.mozilla.org and click on the Development Channel.

If you have previously installed Lightning 1.1 betas, you should automatically get updates by tomorrow.

January 06, 2012 04:29 PM

Lightning 1.1.1 fixes a critical error on Windows XP

Due to a critical issue that some Windows XP users are experiencing, we have decided to release Lightning 1.1.1, an intermediate release compatible with Thunderbird 9/Seamonkey 2.6. We recommend all users to upgrade, especially those who cannot see their calendar data and are getting an error console message "Failed to load native module at path ...\calbasecomps.dll".

You can get the builds on addons.mozilla.org, as always.

January 06, 2012 11:07 AM

Thunderbird Blog

Improving Performance and Feedback in Thunderbird

In the newest version of Thunderbird, we’ve added Test Pilot, Mozilla’s platform for collecting structured user feedback, and Telemetry a platform for collecting performance data. Over the past few years, Test Pilot has provided valuable information to the Firefox developers with over a dozen Test Pilot studies launched covering tabbed browsing behavior, search interfaces, and… Read more

January 06, 2012 05:01 AM

Mike Conley

Sync Thunderbird with your Google Contacts

There are a bunch of add-ons out there to help you sync Thunderbird with your Google Contacts.

I want to share my favourite one with you.

Simply named, “Google Contacts”, this add-on automatically detects if you have a GMail account in your profile, and does the rest of the heavy lifting for you.

Honestly, it’s as easy as falling off a bike.

Get it here.

So a big thank you to the add-on developer, H. Ogi!

January 06, 2012 04:21 AM

January 04, 2012

Robert Kaiser

The Winds Of Change

Quote:
The winds of change continue blowing
And they just carry me away. -- Albert Hammond

Like many others, I've been thinking quite a bit these days about what went on last year and what will or might come up in 2012. (And I figure I should bring in a bit more from my overall personality into my future blog posts and mention or quote songs I have in my mind on a particular topic, so I'll start with that here).

One topic that has been with me throughout the year and will probably also continue to be with me is change. A lot of it started with my visit to Mozilla headquarters in Mountain View, CA, in October 2010, actually - I posted about my changing personal priorities back then. And I still remember driving my rental car up to Lake Tahoe, thinking about all those things and listening to the then-just-released Zac Brown Band album "You Get What You Give" and in particular the song "Let It Go", whose lyrics gave me the right mindset for what was I was going through and what 2011 would bring: "Save your strength for things that you can change, forget the ones you can't, you gotta let it go."

Following that, I started 2011 by transferring the vast majority of my responsibilities in SeaMonkey over to other people (we have built up a great team there over the last years, including awesome people like Callek, InvisibleSmiley, etc. - kudos to them to be able to take all that over in their free time) and get the ball rolling on making the project even more sustainable in the future (I hope we'll have news for you on that soon).

Instead, I followed another piece of advice from this song - "When the pony he comes ridin' by, you better sit your sweet ass on it" - and started contracting for Mozilla on the CrashKill team in February, first half-time, finally full-time. With that, my focus changed from SeaMonkey to Firefox and from project management to crash analysis.

For one thing, I ended up growing into that role better than I imagined at first, finding crash analysis more interesting than expected, for the other, this change ended up having more influence on my life than I had imagined. With the need to communicate a lot with different people in this job, from the CrashKill team via the Socorro team that works on the crash-stats server and which I'm coordinating with to various devs, engineering managers or release managers as the need arises in crash analysis.
Unfortunately with me being a "remotie" all communication needs to be online (or via phone) and is stripped down to the essentials needed for the job. Being a very social person, I'm missing the additional nuances that face-to-face communication would bring to the table, and more need for communication as part of the job makes that more obvious to me.
Then, the whole CrashKill team is based in Mountain View, the vast majority of the Socorro team spread across the US, and most engineering or release managers also based in Northern America, so most of that communication as well as all my meetings is happening during US working hours, which from my point of view in Europe is in the evening to night hours, which requires my work time to be mostly at the end of the day. I have been doing work at late hours in the years before, but there was not as much requirement of that before, while now I have to make at least the meetings, and should be available for more conversation on IRC at those times. Making evening appointments becomes quite difficult in that light.
And speaking of requirements, while I could basically completely make my own schedule before, I now should bring in 8 hours of work per day, and with doing that at the end of every day, I need to make all shopping and other private stuff in the afternoon, leaving me all day with "I still have a full work day to deliver today" in mind - until I achieve that and fall into bed. This causes its own share of subconscious stress.
And I'm doing all the work from my own private apartment, not getting out unless I go shopping or take my usual Monday and Tuesday evening off for some Karaoke.
So, I learned that working from home and remotely has its downsides, esp. for the kind of job I'm in there. This is one area I need to work on a lot in 2012 and find solutions that will be connected with another share of change I'm sure.

But not only my role and work life have changed - Mozilla went in a direction I had often spoken for and has changed to a rapid release cycle and started planning for that shortly after I started contracting. I commented in the planning phase and tried to help shape this process and always was convinced it was a good idea, even though we hit more road bumps than expected. I was heavily involved in coordinating to get crash-stats support rapid releases usefully and also laid out publicly how the new process can improve stability.
Mozilla also has revamped its mobile efforts completely - both with a completely new "native UI" version of Firefox for Android, which is in Aurora testing now and with a completely open mobile stack in the form of Boot To Gecko (B2G), a complete "operating system" based on the browser and open web standards (requiring new WebAPIs), which is also coming together piece by piece now.
And next to those changes, we're also working on changing how identity and logins work on the web and changing the current "silo"ed app store model by bringing open concepts for web apps and markets into the fold that easily allow decentralization and users really "owning" their apps.
In the middle of all that, Mozilla has restructured a bit, brought some previously split-off groups back into the common Mozilla fold, hired a lot of new people, lost (as employees but not as community members) a few high-profile ones who were looking for new challenges, worked on the MPL 2.0, founded exciting new initiatives like WebFWD and went stronger on marketing that we are a non-profit - clearly a lot of change happening everywhere, with the mission and the Manifesto standing unchanged and as clear as ever over all of it, though.

All this makes it clear that a lot of change has come in 2011, both to me and Mozilla, and that it's still only the seed for what's to come in the year(s) ahead. The winds of change are still blowing, and I'm excited for what they propel and which interesting experiences they drag in for all of us.

Quote:
The future's in the air
I can feel it everywhere
Blowing with the wind
Of change. -- Klaus Meine / The Scorpions

January 04, 2012 08:26 PM

December 29, 2011

Siddharth Agarwal

So, what *is* recursion?

Recursion's one of the cornerstones of computer science. The fundamental thesis of computer science says that recursion and iteration (and the untyped λ-calculus) have the same power. People introduced to programming through imperative languages often find the idea of recursion hard, though there are good arguments that that's really a deficiency in our teaching.

So, what exactly is recursion then? And what, for that matter, is iteration?

Wikipedia defines recursion as "a method where the solution to a problem depends on solutions to smaller instances of the same problem". I haven't had major problems with this definition until recently, when I was reading the wonderful Concepts, Techniques and Models of Computer Programming (CTM), which unsurprisingly defines an iterative computation as "a loop whose stack size is bounded by a constant". The examples that it gives are far more surprising, though. Here's an iterative computation to find the length of a list in Oz, the language CTM uses:

fun {IterLength I Ys}
  case Ys
    of nil then I
    [] _|Yr then {IterLength I+1 Yr}
  end
end

Programs like this wouldn't be called iterative in a language like C at all! They'd instead all be called tail recursive. Oz optimizes tail calls so that they don't cause the stack to blow up.1

Even more surprisingly, and perhaps a bit confusingly, it then goes ahead and calls iterative computations a special case of recursive computations, rather than something distinct. It then talks about converting recursive computations to iterative ones (using accumulators and the like), which I take to mean converting non-iterative computations to iterative ones.

Granted that these definitions are from a declarative point of view, where all state is immutable and thus for or while loops don't make sense, but does that then mean that recursion and iteration can only be defined with respect to the language you're writing in? I've never been fully convinced by Guido van Rossum's arguments against tall call optimization in Python, but considering that the feature can determine whether a given program is iterative or not, the arguments start making a lot more sense.

And what about tail recursion modulo cons then, as found in languages like Haskell and Oz? Optimizing tail recursion modulo cons allows functions that aren't tail-recursive, but where the only thing left to execute after the call is a data constructor like cons, to avoid blowing up the stack2. Consider this definition of the map function:

fun {Map F Xs}
  if Xs==nil then nil
    else {F Xs.1}|{Map F Xs.2}
  end
end

This function is clearly not tail recursive, and if translated directly to a language like Scheme which optimizes tail calls but not tail recursion modulo cons, this function would cause a stack overflow with a large enough list. However, since the only thing left after the recursive call is the cons operation (denoted by |), in Oz this function is iterative by the CTM definition3.

So, then, does it make sense to define iteration as any computation in a given language which only takes O(1) implicit (stack) space when executed, and recursion as any computation in a given language which references itself? This would mean that the two aren't quite the opposites they're often portrayed to be, and that depending on the language, recursion and iteration could either overlap or be distinct.

And does it make sense to make this explicit while teaching kids how to program?


1 Interestingly, Oz doesn't have a separate optimization for tail calls. That tail calls don't cause the stack to blow up follows naturally from the way Oz executes programs, as became clear to me when I wrote a self-interpreter for Oz for a school assignment.

2 Again, neither Haskell or Oz have a separate optimization for this. It's a natural, straightforward result of Haskell's laziness and Oz's data-flow variables (everything's a promise in Oz!).

3 Peter Van Roy, one of the authors of CTM and an Oz developer, explains how this happens in Oz.

December 29, 2011 08:04 PM

December 27, 2011

Rumbling Edge - Thunderbird

2011-12-26 Calendar builds

Calendar release history

Common (excluding Website bugs): (15)

One can get the latest Lightning .xpis here.

Sunbird will no longer be actively developed by the Calendar team.

December 27, 2011 12:35 AM

2011-12-26 Thunderbird comm-central builds

Thunderbird release history

Thunderbird-specific: (55)

MailNews Core: (32)

Windows builds Official Windows, Official Windows installer (discussion)

Linux builds Official Linux (i686), Official Linux (x86_64)

Mac builds Official Mac

December 27, 2011 12:28 AM

December 24, 2011

SeaMonkey Trunk Tracker

SeaMonkey 2.7 Beta 1 is Compatible by Default

Today, on Christmas Eve (local time), SeaMonkey 2.7 Beta 1 will be released. This version features something that will probably make a huge difference to ordinary users: Compatible-by-default add-ons (called CBD in the following). This is basically a change of opinion regarding add-on compatibility: Instead of assuming that an add-on is not compatible with a new application version, we will henceforth assume that it is, which should better reflect reality. Switching to a faster release cycle (with less ground-breaking, incompatible changes per release) certainly helped this come true.

So far, support channels have seen many complaints from users who didn't want to upgrade to a new version of SeaMonkey because their favorite add-ons didn't work with it (yet). Sometimes people only upgraded later, or only when they were told how to override compatibility checks (e.g. using the ACR).

Unlike Firefox add-ons, SeaMonkey add-ons did never benefit from automatic compatibility bumps on AMO. Thus as far as SeaMonkey was concerned, if the add-on developers didn't do the bump themselves, it was up to each individual user to take measures if they wanted to keep their add-ons active. And of course they did. Finding no UI option for that, they asked on the support channels, delayed the update, or gave up.

Now if you take a look at the SeaMonkey Add-on Compatibility Tracking page, you'll easily see that about half the add-ons listed under the AMO category are not marked compatible with the current stable version of SeaMonkey (or better). Add-on authors generally got better at bumping compatibility, but it's still a manual task as far as SeaMonkey is concerned.

So what's different with the new CBD feature? Simply put, almost all of that other half from above will be compatible with SeaMonkey 2.7 Beta 1. Automatically. Without any end-user having to change or install anything in addition. That's what I call a UX win! :-) [1]

So, why not all add-ons from the above list? Because some restrictions apply. For CBD to take effect for a SeaMonkey add-on, the following requirements need to be met:
  1. The add-on is compatible with at least SeaMonkey 2.1 or Toolkit 2.0 (the matching Firefox version is 4.0, which is also their lower bound for CBD). This makes sense since that was when fully SeaMonkey adopted the Places back-end (formerly use for history only, then for bookmarks, too) and added Sync support. [2]
  2.  
  3. The add-on does not contain binary components (this rules out popular add-ons like Lightning and Enigmail).
  4.  
  5. The add-on does not claim to only support a later version of SeaMonkey than the one that is currently running the check (in other words: the add-on minVersion must not be larger than the app version).
  6.  
  7. The add-on did not opt out of CBD (by setting the strictCompatibility flag in install.rdf or on AMO).


From my experience, the majority of frequently used SeaMonkey add-ons pass all of these checks. So instead of instructing all users with add-on compatibility issues to install the ACR, we can now limit that advice to those who want to test and give feedback for Beta, Aurora and trunk builds. With CBD, the ACR cannot be used to enable old (pre-2.1) add-ons anymore anyway.

That's it for our next beta, but there's more! In early 2012, when SeaMonkey 2.9 hits Beta, users on that channel will be able to have Sync distribute their installed add-ons across multiple instances of SeaMonkey (provided the add-ons are available from AMO). Note that Firefox will ship the new feature one release earlier (it landed very close to the Aurora uplift, which is the cut-off for changes that affect localization), but that's not too bad since this feature doesn't work across applications anyway.


Now what's left to say? Merry Christmas everyone! Let there be peace on earth.


[1]: Thanks to everyone who worked on this feature! I know you primarily have Firefox on multiple platforms in mind when you develop things in Toolkit, but still.


[2]: Toolkit/AOM Bug 680845 still applies, i.e. if an add-on is marked as compatible with SeaMonkey on AMO, installation will fail if the add-on's install.rdf doesn't list SeaMonkey.


Note to self: Contact the developers of the add-ons listed under 2.0x since these will not benefit from CBD as-is, though at least some of them still work with current SeaMonkey version for sure, e.g. Nostalgy. If anyone reads this and shares my concerns, feel free to help (e.g. using the ACR to give feedback), it is surely appreciated!

December 24, 2011 04:22 PM

Thunderbird Blog

Latest Thunderbird Beta and Earlybird are Live

As part of Mozilla’s new rapid release development process, the Beta development channel and the Earlybird channel have been updated with the latest versions. For information about Thunderbird Beta and Earlybird please visit: Download Thunderbird Beta or Earlybird: http://www.mozilla.org/thunderbird/channel/ Release Notes: http://www.mozilla.org/thunderbird/10.0beta/releasenotes/ For desktop users, if you previously installed a beta or Earlybird version of… Read more

December 24, 2011 07:00 AM

December 23, 2011

Calendar

Lightning 1.1. released

I'm happy to announce that Lightning 1.1 has been released. If you were having trouble with alarms then you will want to upgrade to Thunderbird 9 (or Seamonkey 2.6) and Lightning 1.1.

If you are experiencing issues (Lightning not installing or the calendar not working at all), I'd suggest uninstalling Lightning and then doing a fresh install. Your calendar data will be kept intact, as it is contained in your profile.

You can get the builds on addons.mozilla.org, as always.

December 23, 2011 09:41 AM

December 21, 2011

Thunderbird Blog

New Thunderbird updates now available for download

Mozilla, a global, nonprofit organization dedicated to making the Web better, today released new versions of Mozilla Thunderbird, its free and open source email application, available for Windows, Mac, and Linux. The new Thunderbird, available in 51 different languages, is based on the Mozilla Gecko 9 engine and includes improvements to Personas, better keyboard support… Read more

December 21, 2011 05:30 PM

December 20, 2011

Robert Kaiser

Weekly Status Report, W50/2011

Here's a short summary of Mozilla-related work I've done in weeks 50/2011 (December 12 - 18, 2011):

A dozen years of my contributing to Mozilla just became full this Saturday, and that looked like a good point in time to try another new avenue of contribution.
I have been thinking about a web-based OpenStreetMap-using mapping and tracking application for some time, and even created a concept page on my wiki some time ago when a volunteer came up who wanted to contribute something to B2G - and a maps app is still missing there. This weekend, with the web app developer preview being announced, I finally took the chance to dig into it myself. That said, Lantea Maps had its first field test yesterday and I recorded GPX tracks successfully on my N9 and they look reasonable in an application that can show them against a map. I'm looking forward to improving it - and hopefully even someone making it into an app to run and looks really fitting on B2G/Gaia at some point. :)

December 20, 2011 06:06 PM

David Ascher

You knew the old Mozilla, meet the new Mozilla

One of the notable things about working at Mozilla over the last few years right now is that our aims have gotten much more ambitious, but perception moves slower than reality, even among people who spend every working hour working on the project. I’ve been privileged enough to have a lot of conversations with a lot of people, and to see an evolution in the thinking that motivates our priorities. I’ve also been unfortunate enough to see and participate in high-emotion conflicts, which emerge from the disconnect between various individuals’ perceived priorities. I’m hoping that this post can explain the high level reasons for our current initiatives & why they matter, and maybe help get people past short-term conflicts.

History

For many years, the area that Mozilla needed to focus on was clear: to save the promise of the web, we needed to make a fast and useful browser that didn’t get in the users’ way, and get lots and lots of people to adopt it. This was (and is) a product play, which implies is that success would be determined by what real people would choose to use based on the real choices in front of them. And the people demanded high quality code, zarro boogs, security, etc., but they mostly demanded compelling experiences that solved their problems. In the case of the browser wars, the outcome has been pretty good for society, if slower than we’d have liked: standards have evolved, browsers got better and faster, and websites got more interesting (I’ll note in passing that cross-browser dev work is still way too painful).

Rethink

While that fight is far from over, we’re now at a distinct point in the evolution of the web, and Mozilla has appropriately looked around, and broadened its reach. In particular, the browser isn’t the only strategic front in the struggle to promote and maintain people’s sovereignty over their online lives. There are now at least three other fronts where Mozilla is making significant investments of time, energy, passion, sweat & tears. They’re still in their infancy, but they’re important to understand if you want to understand Mozilla:

The first such effort is, in some ways, “lower in the stack” than the browser. We started an ambitious exploration called Boot to Gecko (B2G), which I don’t yet understand well enough in detail, but which is clearly trying to ensure that there are realistic options for mobile devices which bake in the right values as low as possible in the stack. As I discussed in my last post, the verticalization of the internet means that we’re heading towards a world where who you get your phone from will determine way too much about how you can experience the internet. B2G is a bold exploration tackling the operating system layer of that world.

The two other such efforts are higher-level in the stack, specifically in areas which I’ve been following closely: user identity, and apps. Both of these are spaces where the shape of the real world ergonomics & economics of the internet have managed to completely sneak around the “traditional” world view of browsers & websites.

User-centric Identity on the web

For identity in particular, it’s now possible to create highly engaging experiences thanks to personalization, but that personalization is by far easiest to achieve by adopting technologies like Facebook Connect, which, while appropriate in some contexts, is inappropriate in many, and highlights how much “we in the internet” have failed to address the very real needs of website developers and their users. It’s taken Mozilla a fair bit of time & experimentation to get to something that feels truly great, but I’m very bullish on our first big push in this space, which we’re calling BrowserID for now. The goals of BrowserID are simple:

With BrowserID Mozilla took a bold step, which is still poorly understood even within Mozilla:

For Mozilla devs, this is a bit shocking, as we’re not starting by putting a feature in Firefox first (although we sure hope that Firefox will implement BrowserID before the others!). While I love Firefox, this makes me happy, because in my mind, Mozilla is about making the internet work better for everyone, not just Firefox users, and in this case being browser-neutral is the right strategic play.

Note that Mozilla has always been about making the internet better for everyone, and that’s what’s driving e.g. our policy work. Pragmatically, Mozilla is now big enough that I believe we’ll be more effective if we fight on several fronts at once — coordination costs are very real, and progress on BrowserID in no way diminishes Firefox’s value proposition, although they can (and will!) be better together.

Apps that are of the web

The other critical challenge to the web is the rise of Apps, as a mechanism that developers are turning to because it’s easier to get your apps found & bought, and that users love because it’s an easier way to experience functionality on mobile devices in particular. And here too, Mozilla has a strong play, which is just starting, but which I believe has legs. We launched a developer preview of our Apps initiative, which has the following bold (but doable!) aims:

There are many more things to say about our Apps effort, but I like to summarize it as teaching the web about the good bits of apps, and teaching apps about the good bits of the web. Right now we’re watching the sausage being made (something you don’t see in the Apple and Google kitchens), and it’s a bit chaotic.  But over time, and by the time it gets into consumer hands, it’s going to be splendid.

Here too, the goal is complementary to the success of the Firefox browser. And here too, we need so much help, from app developers to help us prioritize features, from web runtime developers to negotiate and implement the APIs that app developers need, and from early adopters to help us iron out the experience (and be forgiving especially in these early days).

“Finally!”

I’ve been speaking to app & website developers about BrowserID and Apps for a few weeks, and the feedback has been great — webdevs & entrepreneurs are very aware of the dangers of relying on Facebook, Google, or Apple as the bridges to distribution or users. They desperately want an upgrade to the internet that solves these issues in an infrastructural way, and they are quite aware that Mozilla has a unique position beyond being the makers of Firefox.  Webdevs understand the public benefit charter of Mozilla, and many are keen for us to take on more responsibilities there, and happy to help.

Culture shock

I expect it’s not obvious from a distance, but this kind of strategic broadening is hard on a culture. It means that we don’t have a single way of going after things. It means that others in the project seem to work in directions which don’t appear to line up with your own. It means that now engineers don’t just argue with product folks (a tradition in every software organization), but with other engineers with different priorities. It means that it’s impossible (and frustrating!) to keep track of what everyone is doing. All that is painful, especially as the odds are long in each of these battles, so it’s natural to want everyone else to drop what they’re doing and come help you out.

The best advice I have if you find yourself in this kind of culture shock is to first recognize it for what it is: you’re looking up from something you’ve been heads-down in, and your world (and your Mozilla!) looks like it’s changed in surprising ways — that’s scary, for limbic-brain kinds of reasons. We all tend to feel this way when we learn about new developments around us that we weren’t deeply involved with, from SOPA to “what the kids are up to these days”. We have to moderate that gut reaction with a bit of brainpower, and realize that just because it makes us uncomfortable, it’s not necessarily bad. That’s when the work begins: finding out who is working on whatever it is that’s making you uncomfortable, and reaching out to them to get looped in. In particular, doing so tends to work better face-to-face, or at least one-on-one. Finding the right people to talk to will take effort and time. It’s on you to do that work, though, and get informed.  Take the time to understand the history of the change before expressing your unhappiness — the people involved are likely just as smart as you, and if they’re Mozillians, they’re motivated by the same mission.

Looking forward

So while there’s tension aplenty, when I think about this new Mozilla, which not only is committed to producing the best possible browser on desktops and phones, but is willing to invest in shaping what mobile devices should and could be like in 5 years, and reaching out of its comfort zone by standing up to internet bullies in critical areas like identity and apps, I’m pretty proud to be involved.  I’m confident that 2012 is going to see the emergence of new facets of Mozilla, just as the net needs its particular blend of values, ambition, and pragmatism more than ever.

December 20, 2011 04:05 AM

December 17, 2011

Joshua Cranmer

2011 LLVM Developers' Meeting

This feels a bit late to be talking about the 2011 LLVM Developers' Meeting (seeing as how it happened almost exactly a month ago), but since the slides have been put up over the past week and the talks were only put up on Youtube this week, I suppose I can finally back notes up with links and not talk so abstractly.

Of the talks I went to, I think by far the most interesting one was Doug Gregor's talk on Extending Clang. It covered various extension points in Clang and some of their capabilities with simple examples. It also ended in what might be impolitely titled "Where Extending Clang Sucks" and what was politely titled "Help Wanted." This boils down to "plugins are hard to use" and "one-off rewriters are hard to write". Indeed, I think the refrain of problematic architecture for further tools was repeated in more than a few presentations: Clang has the information you want and need, but squeezing the information out is inordinately difficult.

What was probably the most popular talk was Chandler Carruth's talk on Clang MapReduce—Automatic C++ Refactoring at Google Scale (his slides appear to not yet be posted). From what I recall, the more interesting parts of the talk are closer to the end. He had a discussion on developing a language for semantic queries to identify code that needs to be replaced (the example query was essentially "find all calls to Foo::get()"); the previous things people have tried are regexes (C++ is not syntactically regular, it's recursively enumerable), XPath (unfortunately, ASTs, despite their name, aren't exactly tree structures), and pattern matching ASTs (not always sufficient textual clues). The team's idea was to use a matcher library on "AST" values as predicates. He also spoke a bit about some of the efforts they did on using Clang with Chromium.

There is a point brought up in Chandler's talk that I want to reiterate. One of the problems with writing refactoring tools (or static analysis tools in general) is in getting people to trust that they work. For any sufficiently large codebase—millions of lines of code or more—it is fairly certain that the project will run up against the nasty edge cases in parsing tools. If a tool is intended to run mostly automated analysis on such code, it is impossible for anyone to be able to look at the output and ensure complete correctness. However, most sufficiently large codebases come with massive testsuites to help people believe their code is correct; if the same parser is capable of producing code that passes the entire testsuite, then one only needs to trust that the analysis is done correctly, a much smaller task. Without such a capability, no one would be willing to trust the analysis; in other words, any parser which is not capable of then generating code is never going to be trusted as a basis for further work, at least, not if you are looking at million-line projects.

Speaking of Chromium and Clang, there was talk on this too. As I am sure most of my audience is well aware, Chromium uses Clang for several of its buildbots (and all of its recent Mac development); I wish Mozilla could get Clang to be a tier 2 or tier 1 platform for Mac and Linux. As for why they prefer it, the brief rundown is this: better diagnostics, faster, smaller object sizes, they can write a style checker, and they can build better tools off of it (like AddressSanitizer, which, unsurprisingly, itself had a talk). Again, there were the complaints: building the rewriter proved to be difficult a task (notice a trend here?). Incidentally, I also attended the AddressSanitizer talk, but I'm getting tired of copying down notes of talks, so I'll let those slides and the video speak for themselves.

Finally, I did give a talk on DXR. It seemed to be well-received; I had a few people coming up to me later in the day thanking me for the talk and asking more questions about DXR. Something I did discover when giving it, though, is just how difficult giving a talk really is. I had specific notes on the slides written in my notebook, only to discover that I wasn't able to gracefully retreat to the podium and read the notes long enough to figure out what to say next. If you're wondering what I forgot to mention in the talk, it's mostly a more coherent explanation during the undead demo.

December 17, 2011 02:30 AM

December 12, 2011

SeaMonkey Trunk Tracker

11-12-13

[Note: This post is quite different from those I made in the past. Long story short: Due to time constraints I will hardly ever be able to revive the old SeaMonkey Trunk Tracker style of release updates or even complete the missing ones. That's not too bad, though, since I'm now responsible for the SeaMonkey website, which includes the list of changes per release (of which we have more now, as you know). This allows me to re-focus this blog on what it is actually about: tracking trunk development. The below is probably a good example of what is still to come.]

Welcome back! It's 11-12-13 now (at least in my timezone) and I feel this is the perfect time to share something with you that just landed on trunk.

If you are building SeaMonkey or Thunderbird on Windows, you can now finally replace this:

make -f client.mk

or this:

autoconf-2.13
cd mozilla
autoconf-2.13
cd js/src
autoconf-2.13
mkdir -p $MOZ_OBJDIR
cd $MOZ_OBJDIR
../comm-central/configure
time python -O ../comm-central/mozilla/build/pymake/make.py

by this:

time python -OO mozilla/build/pymake/make.py -f client.mk

and replace this:

mk_add_options MOZ_OBJDIR=/e/mozilla-src/comm-central-build

by this:

mk_add_options MOZ_OBJDIR=e:/mozilla-src/comm-central-build

and add back this:

mk_add_options MOZ_MAKE_FLAGS=-j8

in your .mozconfig and there you'll have it: Parallelized building on Windows, using pymake! On a fast PC like mine (i7) you can get a full debug build done from scratch in only about 25 minutes now, without the fear of experiencing intermittent hangs. :-)

Thanks go to all the people who worked on pymake and especially the ones who fixed the last issue on comm-central (Bug 706905).

BTW: AFAICS the comm-central client.mk is still missing some pymake-related fixes that were recently made to the mozilla-central equivalent, especially Bug 707512 and Bug 643167. Please correct me if I'm wrong.

In the next issue I'm going to talk about compatible-by-default extensions (a.k.a. add-ons) and the implications for SeaMonkey. Stay tuned!

December 12, 2011 11:36 PM

December 11, 2011

Mike Conley

My Thunderbird / Firefox wallet – one of a kind

My friend Joel Beck is kind of a badass.

When he’s not designing / building reactors for Atlantic Hydrogen in New Brunswick, he’s learning all sorts of cool skills.

Skills like leather-working.

Look what he gave me as an early Xmas gift:

A hand-made leather wallet by my friend Joel Beck
A hand-made leather wallet by my friend Joel Beck10-Dec-2011 22:44, google Nexus S, 2.6, 3.43mm, 0.017 sec, ISO 50
Thunderbird!
Thunderbird!10-Dec-2011 22:44, google Nexus S, 2.6, 3.43mm, 0.008 sec, ISO 50
Firefox!
Firefox!10-Dec-2011 22:44, google Nexus S, 2.6, 3.43mm, 0.008 sec, ISO 100
10-Dec-2011 22:45, google Nexus S, 2.6, 3.43mm, 0.008 sec, ISO 100
10-Dec-2011 22:45, google Nexus S, 2.6, 3.43mm, 0.008 sec, ISO 50
Just look at that detail.
Just look at that detail.10-Dec-2011 22:45, google Nexus S, 2.6, 3.43mm, 0.003 sec, ISO 50
Mind = blown.
Mind = blown.10-Dec-2011 22:45, google Nexus S, 2.6, 3.43mm, 0.004 sec, ISO 50

This is a one-of-a-kind, hand-made leather wallet, made by my good friend Joel Beck.

Thanks Joel.

December 11, 2011 06:45 PM

December 08, 2011

Blake Winton

What the heck am I pushing, anyways?

Much of the new work I’m doing these days is being stored in git repositories. Now, I’m not the biggest fan of git, particularly its UI, but the advantages of GitHub and GitX are hard to ignore. Despite that, I still really missed being able to type hg out to see which patches I would be pushing, so, after a short chat with (and demo from) Ben, I came up with the following:

Somewhere in your path, add a file named git-outgoing which contains the following contents:

# !/bin/sh
# Uh, there shouldn’t be a space between the # and ! in the previous
# line, but the highlighter I’m using seems to require it…
git push --dry-run $1 2>&1 | awk '/^ / {print $1}' | xargs git log

(Make sure it’s executable by whomever needs to use it!)

Then, in your git config, add the following section:

[alias]
    out = outgoing

And finally, you should be able to type git out, and see something like:

commit 7d4c9b89a4663a07bed030669bae2d3c73ec78dc
Author: Blake Winton <bwinton@latte.ca>
Date:   Thu Dec 8 12:22:41 2011 -0500

    Blear 2

commit a4e8c6627bc26d7371fb2614a1c47aaf694957bd
Author: Blake Winton <bwinton@latte.ca>
Date:   Thu Dec 8 12:18:04 2011 -0500

    Bleah.

So, hopefully some of the rest of you will find this helpful, too, and if you know of a better way to do this, please let me know in the comments!

December 08, 2011 06:04 PM

Thunderbird Design

A thought about integrating chat into Thunderbird from Florian.



A thought about integrating chat into Thunderbird from Florian.

December 08, 2011 03:11 PM

December 03, 2011

Jonathan Protzenko

Leveraging pdf.js in Thunderbird

Thunderbird Conversations 2.2.1 has been released.

Open this PDF in a new tab

You can now view PDF attachments inside Thunderbird using pdf.js! You don't need an external viewer anymore. That's the pdf.js magic.

PDF Viewer

Clicking the icon opens a new tab with a mini-viewer (very basic functionality). It works pretty well, and the plan is to add a viewer inside the conversation, so that you can get some sort of inline pdf viewer, just below the email. That's a reasonably sized chunk of work, but I'm really busy right now, so it's not going to happen anytime soon; therefore, anyone coming with a patch would be extremely well-received :).

December 03, 2011 10:54 PM

November 30, 2011

Thunderbird Blog

Thunderbird survey results

We want to thank you for having taken the time to answer the survey we conducted this last November amongst Thunderbird users. We wanted to better understand who you are, what you like, and what features you expect from Thunderbird. We have collected and scrutinized more than 2300 questionnaires in English, German, French and Japanese… Read more

November 30, 2011 09:30 PM

Rumbling Edge - Thunderbird

2011-11-29 Calendar builds

Calendar release history

Common (excluding Website bugs): (20)

Lightning 1.0 has been released, and is likely to follow Thunderbird in a time-based release schedule.

Whatever bug misses the release train can catch the next one (YouTube video), so outstanding bug lists are no longer relevant.

One can get the latest Lightning .xpis here.

Sunbird will no longer be actively developed by the Calendar team.

November 30, 2011 06:40 PM

Mike Conley

Build Thunderbird Faster on Windows

There’s no denying it: the vast majority of Thunderbird users are using some flavour of Windows.

So it’s a bit strange that I do most of my development on Linux, and use Thunderbird most regularly on Mac OSX.

Therefore, I’ve recently gotten a hold of a new, super-powerful Windows 7 box.  Furthermore, in an effort to better understand what my users go through and experience, I’ll also be using Thunderbird on Windows as my primary mechanism for reading my mail.

So that’s all good, but there’s one problem:  building Thunderbird on Windows takes forever.

But it doesn’t have to.

So the Simple Build Instructions for Thunderbird instructs developers to get the MozillaBuild package, which includes a bunch of the tools you need to get Mozilla stuff up and building on Windows.  One of those tools is “make“, which is a tool that originates from the world of UNIX and Linux.

The problem with the make included with MozillaBuild is that it doesn’t take advantage of multiple processor cores on Windows.  So even if you have a crazy-powerful 8-core machine, when you just use the vanilla “make -f client.mk” command, you’re only going to be using one of your cores.

Enter pymake.  Pymake is a Mozilla-maintained mostly-compatible implementation of make in Python.  The advantage?  On Windows, we can finally use all of our cores.

So here’s how to set that up.

  1. I assume you’ve followed the instructions for setting up your Windows build environment, laid out here.
  2. I also assume you’ve checked out a copy of comm-central, have set up your .mozconfig, and have run “python client.py checkout” to grab Gecko, etc.
  3. If your Windows username has a space in it, like “Mike Conley”, you might want to create a new Windows account for the stuff we’re about to do.  I use “mconley”.
  4. You’re going to want to alias pymake – open up an editor, and create a file called .profile under C:/Users/[username]/  (I assume you’re on the C drive anyhow, and are using Windows 7)
  5. In that .profile file, put in the following line:   alias pymake=/c/Users/[username]/[path to comm-central]/mozilla/build/pymake/make.py
  6. Restart your shell, and ensure there are no errors in the first couple of lines that spring up at the top.  If you type pymake, it should say towards the bottom “No makefile found”.
  7. Go to the parent of your comm-central directory, and create a new directory for your obj-dir (where your binaries and executable will eventually end up).\
  8. In that directory, run the command:  “../comm-central/configure” – so we’re invoking the configure within the comm-central directory, but within the obj-dir folder we created
  9. The configure might fail while looking for the compiler.  Just try it again until it works.  *sigh*.
  10. Once the configure command is done, within your obj-dir folder, type:   pymake -sj4 (or 8, if you have 8 cores)

And blam, now you’re cookin’!

I can get a debug build done, from scratch, in about 22 minutes.  Woo!

November 30, 2011 03:27 PM

Ludovic Hirlimann

Jeudis du Libre de Bruxelles - 01/12/2011 : Thunderbird, ce qui arrive et pourquoi ça arrive

Ce premier décembre 2011, les Jeudis du Libre de Bruxelles sont
accueillis pour la première fois par le Betagroup Coworking et l'ICAB
et reçoivent Ludovic Hirlimann pour la seconde fois de la saison.

Au mois de septembre, Ludovic avait présenté le fontionnement général
de la messagerie électronique et les moyens de la sécuriser. Ce
mois-ci, il revient pour une présentation plus pratique de la mise en
oeuvre des moyens présentés lors de la première séance: Thunderbird, ce
qui arrive et pourquoi ça arrive, la mise en oeuvre de certificats SSL
avec CAcert, et de clés numériques avec GnuPG.

http://jeudisdulibre.be/


*Le thème de cette séance :*

Conférence:

Thunderbird, ce qui arrive et pourquoi ça arrive.

Atelier pratiques:

Devenir assureur CAcert.
Échanger des signatures de clés GnuPG.

L'animateur conférencier :

Ludovic Hirlimann (Mozilla).


*** Attention nouveau lieu! ***

Betagroup Coworking,

4 rue des pères blancs,
1040 Bruxelles.

Arrêt Arsenal. Tram 7, 25; Bus 34.

Merci au Betagroup Coworking et à l'ICAB.

Horaires

Date : 01/12/2011

Accueil : 18:30

Début de la présentation: 19:00

Fin de la présentation et des ateliers : 21:00

Après 21:00: diner dans le quartier.

Pour participer à la session

Merci de vous inscrire:

http://jdl-bruxelles-2011-decembre.eventbrite.com

Pour participer à la session CAcert:

  1. Avoir un compte sur http://CAcert.org et en lire la documentation.
  2. Imprimer des Cap forms (sous cap forms) et venir avec ces Capforms et des papiers d'identités.
  3. Ensuite on crée une queue en face des assureurs.
  4. Chaque assureur regarde remplie une Cap form (cf cap-5.pdf) et la garde.
  5. En rentrant les assureurs donnes des points.
  6. Plus on a de point plus les certificats que l'on peut obtenir sont forts et valides.

Pour participer à la session GnuPG :

  1. Installer GnuPG .
  2. Créer une paire de clefs.
  3. Uploader sa clef sur un serveur de clefs.
  4. Envoyer le fingerprint de sa clé à Ludovic avant 12:00 le 1er décembre: .

November 30, 2011 09:52 AM

November 24, 2011

Calendar

Localization Schedule for Lightning 1.1 and beyond

Now that Lightning 1.0 has been released, we can move forward and adapt to the rapid release schedule that Thunderbird and Firefox are using. In terms of development we will do this gradually but for localization we will do so right away. From now on, if you are already used to the Firefox/Thunderbird localizations you can think the same for Calendar.

Here is an overview of where to get the sources and see the translation progress

en-US source locale source dashboard current version until merge
comm-beta l10n/mozilla-beta cal_beta Lighting 1.1 / Thunderbird 9
comm-aurora l10n/mozilla-aurora cal_aurora Lighting 1.2 / Thunderbird 10
comm-central l10n-central cal_central Lighting 1.3 / Thunderbird 11

Specifically for Lightning 1.1, we have managed to open a milestone for Lightning 1.1. I'd like to encourage you to sign off on this milestone until December 5th so we can be ready in time for the release on December 20th.

November 24, 2011 08:10 PM

November 23, 2011

Instantbird

Weekly Meetings: November 7, 14 and 21, 2011

We’ve been a bit bad about posting summaries of our weekly meetings the past few weeks, but that doesn’t mean nothings been going on! In fact, we’ve had a lot of major changes coming down the pipeline: here’s a summary of what’s new with Instantbird.

Weekly meetings are held every Monday at 4pm UTC (that’s 6pm for people in France, and 9am for people in San Francisco) in #instantbird on irc.mozilla.org.

What’s Been Done?

What’s Been Happening?

There’s been lots of big changes landing, and more to come! Although many of them are back end changes, they’ll pave the way for more visible features in the future.  We’ll try to do a better job of keeping our blog up to date with what’s going on.

As always, full chat logs and the EtherPad is available for each meeting; November 7 (chat logs, etherpad), November 14 (etherpad), and November 21 (chat logs, etherpad).  Note that no real discussion occurred on November 14th, just a summary of the week’s progress.

November 23, 2011 04:57 AM

November 22, 2011

Ludovic Hirlimann

Lightning and Thunderbird testing week, a post mortem.

Last week we had our last (to date) community testing effort and the focus was Thunderbird 10 and Lightning 1.0. This was a first for me, dealing with two products during the same week and dealing with a product I don't use too much. I was not too confident that the test cases available for Lightning were up to date - but I thought that some testing was better than none. So I did My usual call to testers using the too many ways we have to do that :


And I didn't do that on the same day but on the course of two weeks. And I got a bit stressed and worried because the numbers of answers I got was very low. And then Philipp posted on the Calendar blog and my mailbox got filled with people willing to spend some time testing.
The plan was to send instructions when I would get back from mozcamp in Berlin and start the testing effort. Unfortunately I came back sick and was in bed for most of the testing week. I did send instructions and then left my computer unattended for the week as I was sleeping and fighting fever. The instructions I sent did the job for most of the volunteers that had signed up for Thunderbird testing but were confusing to say the least for the many new comers who had signed up for Lightning.

I would like to apologize to the people who wanted to help but got confusing instructions f from me.
I would like to thanks standard8 for getting into #tb-qa and answering people.

And I would like to point out our results :

And I've learned a lot on something I thought I mastered so next time it won't happen the same way for sure.

November 22, 2011 10:35 AM

November 21, 2011

Ludovic Hirlimann

Mozilla Camp Eu 2011

Last week-end I had the pleasure to attend MozCamp Europe 2011 in Berlin, Germany. As always those events are for me the occasion to meet the people involved in the product I work on.
Mobile We are !
It was interesting to listen to old face that were ranting. It was nice to see and meet new people or people I wouldn't expect to see in Berlin (nice idea to mix an AMO editors meeting with the event). I arrived a bit late on the first evening, but not as late a some, so I had the pleasure to enjoy a german-like diner and the time to meet most of the french crowd that was around. Giving us a taste of history as our first social act was nice - even If i had seen the video before. Ended up having drinks with a few old timers and that did wrap up the evening.
Like in whistler I shared my room with Tonnes - a contributor from the Netherlands. Tonnes mind you translate most of the knowledge base article from both sumo and sumomo. While we chatted he told me that was roughly around 20 hours of his time devoted to the task on a weekly basis (a good part of it being sucked into following what Mozilla does and where it goes).
The next day started with a bunch of updates on where Mozilla was going and that was quite interesting - even if I skipped the end to go sign up some pgp keys with two Berliners.
The afternoon was pretty packed - with JB presenting's his vision of where Thunderbird will go. Then Protz giving a 101 demo on how to build and make interesting extensions for Thunderbird - Both presentation had full rooms (room name was mosaic) - which was better than what we had achieved at the last mozcamp. I then followed Florian's presentation of Instantbird - and I still owe him a why I prefer Adium email.
We ended the day having diner in a cave - diner was nice but the place was a bit crowded and very noisy for some. I did meet a new mozillian over diner - but I believe that it was more due to luck than anything else (big hello to mcsmurf).
The next day was more based around private conversation and introducing people to each other. Overall a very long week-end but very productive too. Of course I ended up taking pictures and they are available on flickr.

November 21, 2011 04:31 PM

Mozilla Camp Eu 2011

Last week-end I had the pleasure to attend MozCamp Europe 2011 in Berlin, Germany. As always those events are for me the occasion to meet the people involved in the product I work on.
Mobile We are !
It was interesting to listen to old face that were ranting. It was nice to see and meet new people or people I wouldn't expect to see in Berlin (nice idea to mix an AMO editors meeting with the event). I arrived a bit late on the first evening, but not as late a some, so I had the pleasure to enjoy a german-like diner and the time to meet most of the french crowd that was around. Giving us a taste of history as our first social act was nice - even If i had seen the video before. Ended up having drinks with a few old timers and that did wrap up the evening.
Like in whistler I shared my room with Tonnes - a contributor from the Netherlands. Tonnes mind you translate most of the knowledge base article from both sumo and sumomo. While we chatted he told me that was roughly around 20 hours of his time devoted to the task on a weekly basis (a good part of it being sucked into following what Mozilla does and where it goes).
The next day started with a bunch of updates on where Mozilla was going and that was quite interesting - even if I skipped the end to go sign up some pgp keys with two Berliners.
The afternoon was pretty packed - with JB presenting's his vision of where Thunderbird will go. Then Protz giving a 101 demo on how to build and make interesting extensions for Thunderbird - Both presentation had full rooms (room name was mosaic) - which was better than what we had achieved at the last mozcamp. I then followed Florian's presentation of Instantbird - and I still owe him a why I prefer Adium email.
We ended the day having diner in a cave - diner was nice but the place was a bit crowded and very noisy for some. I did meet a new mozillian over diner - but I believe that it was more due to luck than anything else (big hello to mcsmurf).
The next day was more based around private conversation and introducing people to each other. Overall a very long week-end but very productive too. Of course I ended up taking pictures and they are available on flickr.

November 21, 2011 04:25 PM

November 12, 2011

Jonathan Protzenko

MozCamp 2011 demo addons

EDIT: the slides are available at http://www.xulforum.org/mozcamp2011/presentation/

I'm just writing it down so that it's easy for other people to find it. Here are the demo addons for my MozCamp talk this afternoon.

http://www.xulforum.org/mozcamp2011/

Both add a new button to the main toolbar so you need to right-click the main toolbar and hit customize.

November 12, 2011 03:16 PM

November 04, 2011

Instantbird

Weekly Meeting: October 31, 2011

At the weekly meeting held on October 31, 2011 plans for Instantbird 1.2 were discussed as well as a summary of what’s happened since the 1.1 release. (Full chat logs are also available, as well as the Etherpad timelime.)

Weekly meetings are held every Monday at 4pm UTC (that’s 6pm for people in France, and 9am for people in San Francisco) in #instantbird on irc.mozilla.org.

What’s Happened Since the 1.1 Release:

What’s Being Worked On:

Active participants are highlighted in color.

 

Ways You Help Out:

There’s a few tasks that we could use help with, if you’re interested in any of these, please contact us.  (And if there’s something else you’re interested, let us know about that too!)

Stop by at our next meeting on November 7, 2011 at 6:00 PM France time in #instantbird on irc.mozilla.org!  And as always, please file any bugs you see in our bug tracker.

November 04, 2011 03:52 PM

October 27, 2011

Thunderbird Design

No idea why I can't see existing comments.<br /> <br /> Things to ask:<br /> - how many email accounts (average, median)<br /> - number of message in Inbox (average, median)<br /> - how many people are using archiving at all? Should Thunderbird auto-archive? - size (on-disk) of messages / indexing; should we optimise for disk space, or index lookup?<br /> <br /> <br /> -

(More TestPilot ideas…)

Ooh, archiving is a good area to investigate.  Thanks!

October 27, 2011 02:33 PM

October 25, 2011

Thunderbird Design

Proposed New AddressBook UI: Part 2.













Proposed New AddressBook UI: Part 2.

October 25, 2011 02:46 PM

October 24, 2011

Thunderbird Design

Proposed New AddressBook UI: Part 1.











Proposed New AddressBook UI: Part 1.

October 24, 2011 09:07 PM

October 21, 2011

Instantbird

Weekly Meeting: October 17, 2011

Weekly meetings are held every Monday at 4pm UTC (that’s 6pm for people in France, and 9am for people in San Francisco) in #instantbird on irc.mozilla.org.

The second weekly meeting discussed some final details for the 1.1 release, which happened on October 18, 2011!  Read the blog post about the release. In addition, some plans for Instantbird 1.2 were discussed.

Development Issues Discussed:

Non-Development Issues Discussed:

Ways to Help Out:

Stop by at our next meeting on October 24, 2011 at 6:00 PM France time.  Oh, and try out Instantbird 1.1 if you haven’t (and tell your friends)!

(Full chat logs are available, as well as the Etherpad timelime.)

October 21, 2011 09:36 PM

Thunderbird Design

A followup on the previous image.

A followup on the previous image.:

Any help implementing these things would be more than welcome!

October 21, 2011 07:27 PM

October 19, 2011

Jennifer Zickerman

Mozilla Contributor Survey

If you are current or past volunteer with the Mozilla Project, please take the Mozilla Contributor Survey. David Eaves, coordinator of the survey, is helping Mozilla “design an engagement audit, something to enable them [to] assess how effective they are at engaging and empowering the community.”

Your feedback is much appreciated!

October 19, 2011 05:28 PM

October 18, 2011

Instantbird

Instantbird 1.1 released!

Exactly 4 years after the very early 0.1 preview, Instantbird 1.1 has just been released today in 13 locales (Swedish and Estonian are new)!

In addition to several stability fixes and a dramatic reduction of resource consumption in some cases, this new release will make Twitter and IRC much more usable in Instantbird:

All these changes have been commonly requested, so no surprise here. But there’s one last feature I would like to talk about before offering you a download link: Instantbird 1.1 brings support for putting conversation on hold. This means you can now close conversation tabs without leaving the conversation, the conversation will sit at the top of the Contacts window until you reopen it or someone talks to you. While this may seem like a small change, it’s exceptionally useful for IRC users who tend to idle in lots of channels because they want to “be there just in case” but don’t interact much with the conversation.

Enough talk! Time to go download Instantbird 1.1 (or read the more detailed release notes).

As always, your feedback is welcome! And if you like Instantbird, maybe you will want to share the good news with your friends on Facebook or twitter?

October 18, 2011 03:17 PM

October 15, 2011

Joshua Cranmer

How I got involved with Mozilla

My journey to become a contributor to Mozilla started during the summer of 2007, which was when I started very heavily using Thunderbird. The initial impetus is probably best traced to this thread in a newsgroup: a long, semi-flame war. I wanted to excise the flame war portions from the rest of the thread, so I filed bug 392404 (the first bug I ever filed!). That bug was marked as a duplicate of bug 11054.

At that time, I had a fair amount of free time (this was around the time my summer internship ended but before school started). I downloaded the source code to Thunderbird and then built it, only to discover that every time I built it, it crashed in a linker. After bugging people about it on IRC, I learned that I needed a swap file, and I finally managed to get a successful build. Then, having had programming experience, I decided just to fix the bug myself. I honestly can't remember for certain, but I believe I built the original patch without much aide from people on IRC--it was only the inability to build that I had needed to ask for help.

I do remember that I needed guidance on how to get a patch committed. This being mailnews code around the time that Mozilla Messaging was being set up, the pool of potential reviewers and superreviewers was rather slim. I had been advised that David Bienvenu and Scott McGregor were my best candidates for review. Unfortunately, around this time, Scott had cut off all work with Mozilla; after two months of not getting any response from him whatsoever, I switched to another reviewer.

While I was waiting for the patch to be reviewed, I recall Dan Mosedale talking about bug 132340 indirectly; later, when I asked if there was a fix that people would be interested in, that bug was what I was pointed towards. This patch took about two months and four review cycles to be accepted, but it eventually satisfied my reviewer and superreviewer and became my first contribution to Mozilla. That first patch I worked on? It turned out to be significantly more complicated than I first appreciated and finally was closed 9 months after I started work on it. After bug 132340, I started getting more and more involved with Mozilla development and have been a contributor since then.

October 15, 2011 07:28 PM

Instantbird

The Interruptions Manager

For Instantbird 1.1, which will be released soon, we realized a weak spot in our API was the ability to control whether events should be shown to a user or cancelled under certain conditions.  This fits in as part of our mission about giving control of instant messaging to the user: the user should only be interrupted by events that deserve their attention.  If you’re wondering how this is useful; extensions now have great control over how Instantbird is allowed to interact with the user.  For example, extensions could: keep conversations from opening (i.e. spam guards), quiet sounds during a full screen video, or even stop new conversations from opening if the user has set their status as Unavailable.

Extensions are able to simply register themselves with the interruptions manager and they will automatically be notified if certain events happen, including when Instantbird wants to: get your attention (e.g. flash the task bar), open a new conversation, play a sound or show a message notification.

The API is really easy to use and we’ve created some example add-ons that use it!  We have created an an add-on to not allow the NickServ from IRC accounts to open (source), an update of NickServKiller.  Additionally there is an add-on to force auto-joined chats to be held on the buddy list (source), allowing you to give them your attention when you want to.  Another example of a great add-on is the Do Not Disturb add-on, which does not allow Instantbird to disturb the user while their status is set to Unavailable, really allowing you to concentrate on something more important (source).

There’s also a skeleton for an anti-spam add-on (an often requested feature!) that is just waiting to be finished!  Contact us on #instantbird on irc.mozilla.org if you’re interested in helping out.  And don’t worry, these extensions will be available on addons.instantbird.org soon!

We think this is a great addition for add-on developers working on Instantbird and can’t wait to see what exciting ideas people come up with!

October 15, 2011 12:24 AM

October 08, 2011

SeaMonkey

SeaMonkey 2.5 Beta 2 -- Introduces new features

SeaMonkey 2.5 Beta 2 is available for free download now in 24 languages and makes a list of new functionality available to a wider testing audience for the first time. Please note that this pre-release version is still intended for testers only and might still show some problems in everyday use. As always, we appreciate any feedback you may have and encourage users to help us by filing bugs.

This version is built on top of Gecko 8 and features the following new improvements:

The changes page lists a more detailed overview of new features and fixes relative to our last stable release, SeaMonkey 2.4.1.

We welcome any and all discussions on this beta on our newsgroups, or you can even file a bug if you find one. Be sure to check our Known Issues prior to filing bugs.

SeaMonkey 2.5 Beta 2 is available for free download on the SeaMonkey website. Once you have downloaded and installed this release, we'd like to encourage you to get involved in discussing and reporting problems as well as further improving the product.

Thanks for testing and helping us to make SeaMonkey even better!

Thank You,
~Justin Wood (Callek), SeaMonkey Release Engineer

October 08, 2011 05:28 AM

October 05, 2011

SeaMonkey

Attention: Users on older SeaMonkey Versions may be unable to update.

For those of you who are reading this and on a SeaMonkey version 2.1 through 2.3.0 you will be unable to currently update your version of SeaMonkey through automated means. (SeaMonkey 2.0.x did not have this update security measure, so is unaffected)

WHY:
Our secure certificate for updates, used to protect you, our users, from fraud and issues with the update had to be changed. The one we had expired and we were unable to renew it with the same information we baked into SeaMonkey by default.

WHAT:
We fixed this issue in our version 2.3.1, so if you have that version or newer you will not be affected. And no need to worry.

WORKAROUND:
You can manually install a new version from our website at www.seamonkey-project.org. Or apply our hotfix

HOTFIX AVAILABLE:
I have created a hotfix addon you can install into your SeaMonkey to once again update to a newer version of SeaMonkey via our internal update mechanics. This hotfix currently requires a restart of SeaMonkey, though I do plan to update it in the future to be a "restartless" addon for the versions I am able to.

NOTES:
This is different than a confusing error that gets reported in versions from 2.3.1 and newer that indicates the update server is a wrong certificate. This error is reported whenever we check against our builtin list, and of course it finds the first one we have listed as incorrect and reports it. The next cert in line is found to be ok. So this error ends up being a false positive.

October 05, 2011 11:54 PM

October 01, 2011

Dan Mosedale

what I’ve been up to lately: 3D web gaming

I haven’t blogged much lately, because I’ve been busy working with a fantastic group of folks from all parts of Mozilla and the surrounding community. Over on the Labs blog, I’ve just posted more details…

October 01, 2011 05:52 PM

SeaMonkey

SeaMonkey 2.4.1 Release -- Corrects Important Stability Flaw

The SeaMonkey project is proud to present SeaMonkey 2.4.1: The new major release of the all-in-one Internet suite is available for download now! Building on the same Mozilla platform as Firefox 7.0.1, it delivers the latest developments in web technologies such as HTML5, hardware acceleration and improved JavaScript speed.

SeaMonkey 2.4.1 is available in 24 languages, for Windows, Mac OS X and Linux.

SeaMonkey 2.4.1:

Also fixed in SeaMonkey 2.4 this release features:

For a more complete list of major changes in SeaMonkey 2.4.1, see the What's New in SeaMonkey 2.4.1 section of the Release Notes, which also contain a list of known issues and answers to frequently asked questions. For a more general overview of the SeaMonkey project (and screen shots!), visit www.seamonkey-project.org.

October 01, 2011 12:55 AM

SeaMonkey 2.5 Beta 1 -- Introduces new features

SeaMonkey 2.5 Beta 1 is available for free download now in 24 languages and makes a list of new functionality available to a wider testing audience for the first time. Please note that this pre-release version is still intended for testers only and might still show some problems in everyday use. As always, we appreciate any feedback you may have and encourage users to help us by filing bugs.

This version is built on top of Gecko 8 and features the following new improvements:

The changes page lists a more detailed overview of new features and fixes relative to our last stable release, SeaMonkey 2.4.1.

We welcome any and all discussions on this beta on our newsgroups, or you can even file a bug if you find one. Be sure to check our Known Issues prior to filing bugs.

SeaMonkey 2.5 Beta 1 is available for free download on the SeaMonkey website. Once you have downloaded and installed this release, we'd like to encourage you to get involved in discussing and reporting problems as well as further improving the product.

Thanks for testing and helping us to make SeaMonkey even better!

Thank You,
~Justin Wood (Callek), SeaMonkey Release Engineer

October 01, 2011 12:46 AM

September 29, 2011

Andrew Sutherland

The joy of integrated logging and log viewing with fancy logs

The deuxdrop messaging experiment‘s current incarnation exists as an (under development) Jetpack that runs in Firefox.  I am still trying to shake out functionality to be driven by the UI rather than headless unit tests.  While firebug has been a great help, another boon has been the logging framework and log viewing framework developed for the unit tests.  (Previous posts here and here).  Since the log is made up of structured JSON data, all the log processing logic is written in JS, and the log viewing UI is HTML/CSS/JS, it is trivial to embed the log viewer into the Jetpack itself.

If you type about:loggest in the URL bar (or better yet, create a bookmark on the bookmark bar and click that), the log viewer is displayed.  Deuxdrop’s client daemon logic (which runs in a hidden frame), uses a log reaper that runs at 1-second intervals.  If anything happens log-wise during that second, it is packaged and added to a circular-buffer style list of the last 60 seconds where anything happened.  When the log viewer starts up, it asks for and receives the data.  The result looks like the above small screenshot.  If no errors were logged during the time interval, it is automatically collapsed.

Let us experience the joy of integrated logging by looking at a real problem I recently encountered.  In the development UI (accessible via about:dddev), I brought up a list of my contacts after starting a conversation.  It looks like this right now:

The problem is that I, the user, am “Andrew Sutherland” and should not be in my own contact list.  Also, the display should not be claiming there are an undefined number of unread messages from me, but that is likely fallout from the system intentionally not maintaining such information about me, the user.

I want to quickly figure out why this is happening, so I bring up about:loggest and open the most recent time entry to see what happened when this query was issued and filled:

I can see that the query ended up issuing database requests for both Walternate (purple) and myself (green), strongly suggesting that the database index being queried on names me.

I wonder if the conversation processing logic was the code that did this… let’s check by going to the time slice where the conversation was processed, expanding it, and only screenshotting some of it:

Yes, the conversation logic did this.  It’s generating index values in the peepData table for the idxPeepAny and idxPeepRecip indices.  But I thought my unit tests covered this?  Nope.  It turns that although we test that a peep query returns the right thing both cold from the database and inductively via notifications as contact relationships are established, we don’t issue a new query after creating a conversation.  Furthermore, we only issued queries against the alphabetical index, not against idxPeepAny.  So we rectify that by augmenting the unit test:

  // - make sure that the conversation addition did not screw up our peeps list
  T.group('check peeps list after conversation join');
  lqFinalAllPeeps = moda_a.do_queryPeeps("allPeepsFinal:any", {by: 'any'});

And the test indeed now fails:

The relevant bit is in the lower right, which I blow up here with the “unexpected event” obj popup displayed above it, and the “failed expectation” obj popup below it.  The postAnno stuff is to indicate what is new in the query result.  Because it’s a freshly issued query and this is the first set of results, everything is new.  It’s probably worth noting that these errors would usually show up as a single “mismatched” error instead of an unexpected/failed pair in our tests, but the specific logger was operating in unordered set mode because we don’t care about the exact order that different query notifications occur in, we just care that they do occur.

(The structure is intended to later be enhanced to provide a nicer visualization where we only show the contents of the “state” attribute and use preAnno to indicate annotations on a representation of the most recent state for the object (from a previous log entry) and postAnno to indicate annotations on the now-current representation “state”.  For postAnno, values of 1 represent an addition, and values of 0 represent a change or event firing on the object.)

A potentially even more exciting bit of integrated logging is that about:loggest-server opens a tab that retrieves its contents from the server.  When run with the –loggest-web-debug flag, the server loads a module that cranks up the logging and does the same 1-second interval log reaping magic and exposes it for HTTP retrieval.  While this specific configuration with the high level of detailed logging is only appropriate for a developer-machine test server, it is incredibly valuable to be able to just pop open another tab and see what the server just got up to.

In any event, I leave it as an exercise to the reader to assume that I will take care of the bug now that it’s extremely clear what the problem is.  Well, extremely clear if I had taken a bigger screenshot of the conversation creation log.  Above the region captured is a header that indicates the actions are being triggered by the ‘convJoin’ task and the entry (which is visible) indicates the update_conv_data function likely kicked off the database activity.

PS: All the gibberish looking characters in the screenshots are crypto keys or other binary data that lack aliases mapping them to known objects.  Examples of successfully mapped aliases are the colored blocks.  In the case of the conversation creation gibberish, we are seeing the conversation id.  Those aliases are generated as a separate pass by the log reaper by walking the set of existing queries and using helper functions to map the items currently exposed by the queries to human names because it’s quick and easy and is O(what’s being looked at) not O(size of the database).  In the case of the conversation, there was no query against the conversation and I also have not written the helper function yet, which is why it did not get aliased.  Unit tests don’t have the problem because we create aliases for everything.

September 29, 2011 02:16 AM

September 28, 2011

David Ascher

Am I reading these trends right?

Let’s see… in the last few weeks, we have seen:

Facebook shifting the definition of the Open Graph and moving the locus of control about sharing from an actual user-initiated action (“share!”) to the terms of service that users agree to at “app installation time”. This will likely lead users to overshare, and many more websites to require facebook accounts.

Amazon building a new way of using the web which many fear will be a data mining engine that “acts on your behalf” as you do anything on the web, not just with Amazon sites. Until now, only regulated ISPs or government agencies had that level of access to our online activities.

Microsoft preparing a version of Windows which will demote third-party browsers and bake in support for a single-vendor appstore.

Google aggressively promoting their mostly closed social network on all of its properties.

(All of whom are basically following Apple’s lead on how to verticalize the world).

The threat models are fascinating too. According to the blogosphere, Facebook is feeling threatened by users shifting to mobile (read: iPhone); Google’s threatened by Facebook; Apple needs to figure out social; Everyone’s going to get bit by patents, but they all have huge cash reserves to apply to that problem.

This industry is heading in a direction that is sure to be full of fireworks, but I’m having a hard time seeing how normal people end up winning at the end.

If these trends continue, in a few years at most we’ll basically choose one of 3 or 4 vertical stacks to work in. Rich people will be able to afford to play in all of them (an iOS macphone, an android tablet, a kindle Plasma, a facebook TV, etc.).

Consumption will go up, free access will be contingent on actual consumption. Kindle people will have a heck of a time communicating with Apple people. Facebookers will make fun of Googlers. App developers will slowly realize that they’re the outsourced R&D department for the big 5, and success will be defined as being acquired for a few bucks rather than creating jobs or making the world a better place.

Consumers are part of the problem too, of course — we like simple, shiny, integrated solutions. We want freedom from choice more than we actually value choice.

The next generation will likely think of our notions of privacy, autonomy, and various freedoms as quaint or foolish, much like we look on our parents’ notions of decorum and modesty. Either that, or they’ll unplug and start to riot, because of the co-occuring global economic climate which, to put it bluntly, will suck for people who don’t have stock in said 5 companies.

So, that’s a pretty bleak assessment, and it tends to depress me. What’s the silver lining? I don’t have a very rosy picture yet, although I’m trying! I have a few proto-thoughts:

First, those five companies, while very impressive and influential, represent a tiny fraction of the creative, intellectual and even financial resources of the world. Furthermore, those companies are all US-based, which simply isn’t a stable configuration. So while those companies are defining extremely aggressive winner-take-all strategies, and executing for the most part exceedingly well, we should realize that there are way more of “us” than “them”.

Second, these companies all have competitors, and I expect always will. Even if there were no other market forces at play, these five will keep beating each other up forever. Mergers of giants might even be a good thing, given that those tend to destroy focus and operational excellence.

Third, I think that there is a growing shared understanding of what’s wrong with these trends from a public policy point of view. The internet, the web, were not intended to facilitate these empires, and I expect that over time, as John Gilmore said, “The Net interprets censorship as damage and routes around it.” So somehow, we’ll figure out a way to take the bits of net life that truly matter, and extract those from the silos being built.

There are many projects in this general vein already under way, some with significant involvement from Mozilla. For example, we’re pushing hard on federating identity on the web, and teaching the web about apps and vice versa. I’m hopeful that we’ll also find ways to recognize friends and partners along the way. I’ve got a list in my head, but it’s probably worth building it out. If you have pointers to projects that touch on these issues, let me know in comments.

September 28, 2011 09:14 PM

September 27, 2011

SeaMonkey

SeaMonkey 2.4 -- Introduces new features

The SeaMonkey project is proud to present SeaMonkey 2.4: The new major release of the all-in-one Internet suite is available for download now! Building on the same Mozilla platform as Firefox 7, it delivers the latest developments in web technologies such as HTML5, hardware acceleration and improved JavaScript speed.

SeaMonkey 2.4 is available in 24 languages, for Windows, Mac OS X and Linux.

Most notably, this release features for the first time:

For a more complete list of major changes in SeaMonkey 2.4, see the What's New in SeaMonkey 2.4 section of the Release Notes, which also contain a list of known issues and answers to frequently asked questions. For a more general overview of the SeaMonkey project (and screen shots!), visit www.seamonkey-project.org.

September 27, 2011 09:11 PM

Blake Winton

Thunderbird’s UI Directions.

On a previous post in a different blog, some commenters were asking us if we were considering doing things that we have planned to do for a while now, and that led me to realize that I haven’t been communicating the future of Thunderbird’s UI nearly well enough. I mainly blame it on my trying to do too many other things, and thus failing to cover all the bases. So, having said all that, here is the list of things, in no particular order, that I would like to see worked on in the next few versions of Thunderbird. But first, I’ld like to say a little bit about why I want them.

I recently heard about someone who said “Thunderbird looks like iTunes”, and while that’s rather complimentary given the amount of time Apple puts into making things look good, it doesn’t really lead me to believe that people can pick our product out of a screenshot. And so one of the overall goals is to make Thunderbird iconic. You can always tell when a screenshot is of Apple mail, based on the layout and the lack of colour, and Firefox is similarly immediately recognizable because of the big circular back button and smaller rectangular forward button. Similarly, I’m hoping to have Thunderbird look different to other apps, while still fitting in on the platform, and maintaining a little consistency with Firefox. Of course, that’s not the only goal, nor even the main goal. My main idea for Thunderbird is to let you focus on the content that’s important to you, and not be distracted by things you don’t care about. Hopefully most of the changes I talk about here will help that, and as a side benefit also help to give us a more unique style.

See all the bugs in one big list.

Many thank-yous to Alex Faaborg, and areweprettyyet for the code to link the bugs, and the basis of the styling to make them stand out.

September 27, 2011 03:02 PM

September 20, 2011

Joshua Cranmer

Public Service Announcement #2

A brief note to all application and operating system developers:

Failure to respond to a prompt does not indicate accession to perform the actions that would otherwise occur. Especially if those actions have a high risk of losing my data. So I would like to thank you (whichever product is responsible for my most recent undesired restart) for completely obliterating my class notes. At the very least, you did not destroy all of my research too, just a day's worth.

September 20, 2011 02:41 AM

September 19, 2011

Jonathan Protzenko

Git mirror of comm-central

Mozilla is the only project where I use hg, and because I'm more comfortable with git, I decided to follow Chris Double's instructions and create a git mirror of comm-central. It now lives at https://github.com/protz/comm-central. It will be updated regularly.

September 19, 2011 07:34 AM

September 11, 2011

Jonathan Protzenko

Restartless addons for Thunderbird Conversations

OEmbed addon

Thunderbird Conversations can now have its own addons! I just created a sample plugin for Conversations that uses oembed to analyze links to Flickr in emails. Once it's found a link, it displays a small version of the image below the email, with the title of the picture and its author. You can click the picture to open the original link to Flickr in a new tab. I packaged this plugin as a Thunderbird addon.

The good thing is this addon is restartless! As always, it's been a little bit of a fight to get it to work (I ♥ you restartless), but I managed to get it right. Enough talk, download it now.

Some remarks:

Comments are welcome!

September 11, 2011 02:34 PM

September 08, 2011

Blake Winton

A Proposal for Updates with Add-ons.

Add-ons are an important part of many Mozilla products, and many people have noticed that they’ve taken a hit as we’ve switched to the Rapid Release process. To help users have a little more control over how well their Firefox works, I would like to propose the following slight modification to the automatic Update process:

It all starts when Firefox (and Thunderbird) notice an update is available.

We immediately check the user’s add-ons to see if they are compatible, or if there are compatible versions we haven’t downloaded yet.

If all the add-ons are compatible (or will be made so at the next download), we show the NoAddons dialog:

NoAddons dialog

It‘s the same as the current Firefox or Thunderbird update dialog, and as you would expect, the “Ask Later” and “Update Firefox” buttons do the same things that they do now.

On the other hand, if there are in-compatible add-ons, we show the Addons dialog:

Addons dialog

As you can see, we let the user know which add-ons are incompatible, and give the user an extra button at the bottom to do something different.

The new “Update when my add-ons work” button (wording to be clarified later) will check the add-ons periodically, and automatically update Firefox when all the add-ons are compatible. If the add-ons aren’t compatible after a week (period of time to be configurable), the user will be shown this dialog again, with the (hopefully smaller) list of incompatible add-ons.

Showing the user which add-ons are incompatible will let them decide whether the add-ons are important enough to not upgrade, or whether they can live with the (hopefully short) period of reduced functionality.

As always, comments welcome, but keep them polite or they’ll be deleted.

September 08, 2011 06:49 PM

Kent James

Avoiding namespace leaks in event handlers

A common pattern that we see in review of Mozilla addons is code that looks like the following:

var myExtension = {
  saveMe: null,
  onLoad: function () {
    this.saveMe = "I am saved";
  }
}
window.addEventListener("load", myExtension.onLoad);

Unfortunately the value of “this.saveMe” that is used in onLoad is the value from the global window, not the value from the myExtension object. Really the event listener is looking for an object of type nsIDOMEventListener, with a method handleEvent. When it does not find that, it applies some magic and just uses the entered function. Unfortunately, in the process the “this” does not get defined from the parent object, and you are stuck with “this” being the global object.

Here are three alternatives that don’t leak:

1) give it what it wants, namely a handleEvent method:

var myExtension = {
  saveMe: null,
  handleEvent: function (evt) {
    if (evt.type == "load")
      this.saveMe = "I am saved";
  }
}
window.addEventListener("load", myExtension);

2) wrap the function call with a function:

var myExtension = {
  saveMe: null,
  onLoad: function () {
    this.saveMe = "I am saved";
  }
}
window.addEventListener("load", function() { myExtension.onLoad(); });

3) use the bind function to manually specify what “this” will be used:

var myExtension = {
  saveMe: null,
  onLoad: function () {
    this.saveMe = "I am saved";
  }
}
window.addEventListener("load", myExtension.onLoad.bind(myExtension));

These kinds of issue can be difficult to spot just by looking at code. Addon authors are strongly encouraged to use the “Extension Test” addon to catch leaks of names to global namespaces.

 

Share

September 08, 2011 04:58 PM