Makefile for building/distributing extensions

I’ve written a Makefile to help build and distribute Personas and Snowl. It automates the process of generating manifests; packaging the extension into a JAR and a XPI; and, for a “development” distribution channel, autogenerating successive version numbers and rsyncing the builds and update.rdf file to a distribution server.

The file makes it easy for me to update the latest development build of Personas after checking in a fix via:

make build channel=dev make package channel=dev make publish

For release builds, it’s:

make build channel=rel make package channel=rel [manually upload to AMO]

And when I just want to test locally, I can build and install to a local profile:

make build make install profile=~/dev-profile firefox -profile ~/dev-profile

Or I can package the build and install via Firefox’s Add-ons Manager:

make build make package [manually install via Firefox's Add-ons Manager]

Because I reuse it for multiple projects, project-specific variables are defined in a separate client.mk file. If you have similar needs and would find it useful, you are welcome to it!

Just grab the Makefile, see client.mk for the variables you should define, and check out the Personas source directory for the general layout that the Makefile handles as well as the install.rdf.in, chrome.manifest.in, and update.rdf.in templates from which their respective files are built.

Notes:

  1. It’s originally based on Weave’s top-level Makefile, although it doesn’t currently support the binary components that Weave’s Makefile builds.
  2. It assumes a directory structure in which content/, locale/, and skin/ directories are at the top level of the source directory (not within a chrome/ subdirectory).
  3. It currently builds in the source directory rather than in an object directory, which means it can leave old install.rdf, chrome.manifest, and chrome.jar files around, so sometimes I need to make clean && make build to get rid of the ones I previously built (f.e. for a release build whose chrome files are archived) and generate new ones for continued development.
  4. For Personas, I use a defaults/preferences/prefs.js.in template to generate prefs that contain the Mercurial revision ID (so I can identify the version of code in a development build with which someone is reporting problems) and the distribution channel (which the extension uses to suppress the “You’ve been updated!” page for the “dev” channel, since that would get annoying fast).

 

Personas for Email Messages

Here’s a thought (I had in the middle of a dream about brightly garbed superheroes): use Personas to style email messages in Thunderbird! It’d be a simple way to easily add some style to your messages to friends and family, highlighting your current mood, your perennial interests, or the subject of the message.

A dramatization mockup:

There are some tricky issues, like how to select a background color for the message that blends in attractively with the bottom of the header image. And it’s not clear if the footer image is useful in this case.

But overall the idea seems quite promising. What do you think? And, if you’re a Mozilla extension hacker (or would like to become one), would you be interested in prototyping it?

 

The Problems With Pagination

Many web sites and applications paginate their content. Often this makes them harder to use.

Partly it’s because site-provided pagination interacts poorly with the browser’s built-in scrolling, because the content on any given web page usually takes up more than one vertical screen of space, and you have to jump back and forth between site pagination and browser scrolling, hunting down their controls each time you do so.

Sites compound this problem by moving their pagination controls around, so you can’t leave your mouse over the Next Page button and assume you can simply click the mouse button repeatedly to jump to subsequent pages.

And pagination control click targets are small, which makes them hard to hit. Page-specific targets are often a single number (1, 2, 3), while the Next Page target is sometimes a single character (>).

Finally, pagination confounds searching through content using a browser’s Find in Page feature, since it requires you to switch back and forth between searching for the content on the current page and navigating to the next one until you find the text you’re looking for (and beyond, if you’re looking for multiple occurrences of it).

And it similarly confounds any other activity in which you want to engage with all the content in an application, like when I wanted to turn off tracebacks/pingbacks for all 56 posts in a WordPress blog, which is a six step process, and I had to repeat those six steps four times each because WordPress’s list of posts only lets me see 15 at a time.

Nevertheless, there are legitimate uses for pagination:

  • sites whose content is computationally intensive to generate (like search engines) use it to reduce load and cost;
  • those with large quantities of content that strains server, client, and network resources to display all at once (search engines again, the Personas gallery) use it to improve responsiveness;
  • those whose content cannot usefully be browsed in its entirety much of the time (search engines a third time, messaging applications) use it to reduce the cognitive overload of providing all their content at once;
  • and those with an ad-based revenue model (you guessed it, search engines, but also online news and many other sites) use it to show more ads.

For those kinds of sites, pagination makes sense, although doing it right still matters, like giving its controls large click targets and putting them in the same place on every page.

And, for content that spills across multiple screens, including the pagination controls at both the top and bottom of the content, the two scroll positions at which users often find themselves when they want to change pages; or positioning them absolutely, so they’re always visible; or only loading a screenful of content at a time, so users never have to both page and scroll; or using endless/infinite scrolling.

Are there even better approaches, and are there ways for the web platform to support them so that web sites don’t have to roll their own? Perhaps browsers and servers could collaborate to provide content in screenfuls with integrated scrolling and paging controls that play well together and don’t change from site to site.

What do you think?

 

syntaxes for iterating arrays in JavaScript

JavaScript lets you iterate arrays using the for each…in statement:

for each (var item in [1, 2, 3]) alert(item);

JavaScript 1.6 added the Array.forEach method:

[1, 2, 3].forEach(function(item) { alert(item) });

I’ve always preferred Perl’s statement modifiers, though, for the popular English-like order of their clauses (“do this for each of those”):

print $_ foreach (1, 2, 3);

JavaScript 1.7 added array comprehensions for array initialization:

var squares = [item * item for each (item in [1, 2, 3])];

I just realized I can (ab)use comprehensions to iterate arrays with Perl-like syntax by throwing away the result:

[alert(item) for each (item in [1, 2, 3])];

I can iterate object properties the same way:

var obj = { foo: 1, bar: 2, baz: 3 };
[alert(name + "=" + obj[name]) for (name in obj)];

Sweet!

 

Snowl Integration with Places

alta88 has recently done a bunch of work to integrate Snowl with Places. His initial efforts have focused on getting sources and people into Places, as he describes in this post to the discussion forum.

This will make the list of collections in the next version of Snowl work like Firefox’s list of bookmarks in the Bookmarks Sidebar, and sources/people will also show up in the AwesomeBar:

Snowl doesn’t yet register the snowl: protocol, however, so selecting those items doesn’t do anything (yet). What do you think it should do?

And what additional Places-backed features would be useful?

(Picking up on something dietrich said on Twitter last week, I’d love to see Places get populated with tweets that reference a URL, setting the title of the Places entry to the content of the tweet, so you can use the AwesomeBar to find that site you saw last week in a tweet, as other folks have done with Delicious.)

 

Snowl development builds

I’ve created a distribution channel to get Snowl changes out to its testing community faster. I’ll push development snapshots to the channel on a regular basis as significant fixes are committed (or perhaps nightly, if I can automate the process).

Once you install a development build, Firefox will automatically check for newer ones and prompt you to update when it finds one, just as it does for the release builds on AMO.

This is truly the slicing edge. If you use these builds, be prepared for the possibility of regressions and bustage. On the other hand, you’ll also get to test new features earlier, like alta88’s Places integration work.

Install the latest development build, then discuss it and report bugs you find. (If you don’t want to be on the slicing edge, try the latest stabler release instead.)

 

ISO simple open web image editor

Is there a simple open web image editor? I know about Pixlr, Picnik, and Aviary, but those all use Flash. It seems like it should be possible to make one using Canvas and other modern open web technologies.

In addition to using it for simple photo manipulations, I’d like one that can be embedded into other applications, like Personas (to make it easy for users to make and refine their own personas) and image hosting sites (so users don’t have to go to a separate website and import their images to edit them).

In other words, I want the web-based image editing equivalent of Gecko+Firefox: a great open-source image rendering and editing engine with a flagship product that demonstrates its capabilities and an API for embedding it into other applications.

Is there such a thing? Does anyone want to create one?

 

The Extension Bootcamp Tutorial

A few weeks ago, as part of Mozilla LabsDesign Challenge, I taught a tutorial on extension development. My goal was to impart the minimum necessary information to build a simple extension using modern best practices. I called it Extension Bootcamp: Zero to “Hello world!” in 45 Minutes.

The tutorial, which borrowed from other ones (including my ancient Tinderstatus tutorial, the venerable Building an Extension, and the new Firefox addons developer guide), covered:

  • what extensions are, what they can do, and what they’re made of;
  • how to configure your development environment on Windows, Mac OS X, or Linux;
  • how to construct an extension, including required files and directory structure;
  • how to package and test your extension;
  • a simple extension that inserts XUL into the main browser window via an overlay, styles it with CSS, listens for and responds to a DOM event on it using JavaScript, and localizes its strings with both a DTD and a properties file.

It explicitly excluded:

  • archiving chrome files into a JAR archive (valuable for large, popular, and stable extensions, but not worth the added complexity for the rest);
  • developing XPCOM components (most extensions should use JavaScript modules instead);
  • putting CSS/image files into a separate skin package (Firefox doesn’t ship with two themes, which was the original impetus for segregating these files thusly, and most extensions don’t support third-party themes, so this is unnecessary).

To conserve time, I didn’t cover:

  • developing JavaScript modules;
  • accessing XPCOM components;
  • using tools and documentation to introspect and learn Mozilla code and APIs.

Developing a Firefox extension is pretty complicated, since there are so many different pieces to it, and the tutorial ended up taking two hours, including time for the students to practice each lesson on their own computers (for which my colleague Jono‘s assistance in fielding questions was invaluable).

The video of the tutorial, edited down to 1.5 hours, as well as the slides and accompanying files are available. If I had time to work more on this, I’d expand it to include the essential topics I didn’t cover. I’d also update the Building an Extension tutorial to adopt the pedagogy of this one. If you’d like to do either of those things, please do!

 

Personas in Thunderbird

Huang Yaoquan recently contributed a patch to make Personas work in Thunderbird! Here’s Thunderbird with the Groovy Blue persona selected:

The patch requires a Thunderbird 3 beta, and it landed after the cutoff for the Personas 1.0 release, so it’s not in the version on AMO, but it is in the latest development build, so give that one a spin if you’re developmentally inclined, and provide feedback in the discussion forums or by filing bugs.