In designing the Firefox-facing APIs of Account Manager, thunder [sandmill.org] and I decided to make most of the interfaces take a callback/continuation. Two main reasons were 1) to allow add-ons to add extra account types like OpenID and 2) to find out if you’re logged-in to a site over multiple network requests.

For an add-on to provide a new account type, it needs to be able to tell Firefox what saved accounts are available and how to connect to them. These might need to read data from disk and/or network; or perhaps request more information from the user like a 1-time code sent over SMS. For Firefox to support these more-complex interactions, it can’t assume that a method implemented by the add-on can return a value immediately.

Asking for additional information to connect to a banking site

In this particular mockup, the site has told Firefox not to use the basic username-password account type but instead to use an account type that asks for more information. Here, an add-on has already saved the username/password and doesn’t to ask for them, but it can’t immediately connect without asking for more information, so it tells Firefox to show this popup. With the async. API, the add-on can later tell Firefox that it has finished the connect process.

The second reason for going async. overlaps with the first of supporting add-ons; Account Manager and account types need to talk over the network to other machines. These requests can take more than just a few milliseconds, so blocking the rest of Firefox when you click on the “Sign in” button using a synchronous request would be bad. In the case of finding the account status, Firefox might need to make requests for any or all of host-meta, AMCD and the session status.

The Password Manager API in Firefox happens to be synchronous—as are many other interfaces in Firefox. Converting it to be asynchronous for use in the username/password account type was fairly simple, but there’s a couple things to keep in mind: when the work is done and when the result is given.

Implementing the async. interface with the synchronous Password Manager

Here, we’ve made the call to savedAccounts immediately do the work of finding the logins, so this means the caller might have to wait before the asynchronous savedAccounts call returns. We could have just as easily delayed this work to run after the function returns by moving the logic into the async function call, but one needs to be aware that if the arguments are live objects, the contents might change by the time async triggers the callback.

The second point of “when the result is given” is less flexible. The function above could have been written to just call onComplete(accounts) immediately without the async wrapper, but that could break the caller as the implementation is no longer truly asynchronous. The caller would stop working if code is supposed to execute after the call to savedAccounts but before the call to continuation, onComplete.

Trivial example of how non-async. implementations could break

For web developers, implementing async is pretty simple as the global window object has setTimeout. So one implementation could look like function async(callback) setTimeout(callback, 0);

Making the choice of having the APIs be asynchronous does have some drawbacks in terms of code structure. Any function that eventually calls an async. function will be forced to take a callback as well, and if it needs to call multiple async. functions, the logic needs to be broken up into multiple callbacks. If you want to share variables across these callbacks, you’ll end up creating many nested anonymous functions (closures).

Additionally, some simple things like doing Array.reduce (fold), which visits each array item and applies a function to produce a single result, can get pretty complicated if you want to pass in an async. function. In a later post, I’ll describe a way to have asynchronous functions look like they’re synchronous so that you can avoid some of this callback craziness. 😉

Since helping get Firefox Sync and Firefox Panorama into Firefox 4, I’ve been hacking recently on a neat feature called Account Manager. For end users, it makes it easy to connect to sites, and for web developers, it makes it easy to add that functionality. In the process of testing the feature, I added some basic functionality to my website in less than 5 lines of PHP!

(If you already know the details and just want the download, here they are: Windows, OS X and Linux)

An icon shows up in the location bar

If you visit my site using Firefox with Account Manager, you should see something like the picture above. By default, you get a plain image indicating that the site allows you to personalize your experience. Clicking on the icon indicates to Firefox that you want to sign-in.

Firefox asking for information to Sign In (WIP graphics!)

After successfully signing in, Firefox will reload the page. Notice that in addition to the page showing I’m signed-in, Firefox also knows who I’m signed-in as and informs me from the location bar.

Firefox and the website showing my signed-in status

What’s happening is that my site tells Firefox how to sign-in, and Firefox POSTs a request to my connect page, which just does the following:

<?php // connect.php
$_SESSION["id"] = $_POST["id"];
?>

My site also tells Firefox how to figure out what account I’m signed in as, and my site responds as so:

As a web developer, I didn’t need to write any HTML forms with input boxes and make sure they’re styled nicely. Firefox handles all that and makes it available from any page on my site. This is useful to blend into the look-n-feel of the user’s platform whether it be Windows or OS X or other devices like phones or TVs.

As an end user, I didn’t need to search for the fields to enter my information or find a link on the page that leads to a sign-in box. I know that I can just click in the same spot that I would click to sign in for other sites to sign-in. Additionally, I know at a glance that I’m looking at a personalized site and if I’m connected to the wrong account.

Now, if I were to restart Firefox, it has already remembered that I’ve signed-in to my site before, so signing-in is even easier the second time!

Signing-in to sites you've been to

Instead of the plain image, Firefox shows “Sign in” because it can do that for me. In a single click, Firefox will talk to the site in the background and reload the page. It’s so easy! Just one click. 🙂

Additionally, if I have multiple accounts on the site, perhaps an admin account and a user account, or if multiple people use one Firefox to visit the same web site, clicking “Sign in” will provide a list of those accounts.

If you’d like to look into the details of how my site informs Firefox how to connect and get account status, you can take a peek at my Account Management Control Document which is linked from my host-meta. From there, you can start adding support for Account Manager to your own site!

We’ve been busy updating the New Tab add-on, About:Tab. We made it available a couple weeks back and plenty of new changes are based on the useful feedback in the comments section and elsewhere.

One big change is that we’ve switched to a more text-focused view. Instead of having gray thumbnails that aren’t too recognizable to you, we focus more on the site’s icon that you normally see in tabs. We can have a cleaner display for the site’s name yet still make it easy to click (basically anywhere) in that site’s box. Also, instead of being overloaded by too many feeds you don’t want, the default is now 3 and there’s more breathing room.

New text-based view for new tabs with customizations on the side

Another big change is customizability. A lot of people want to be able to reorder the list and get rid of things they don’t want. The initial release allowed you to drag things up and down, but it didn’t save that ordering, but now it does (for just the current browsing session, for now). You can now remove sites by clicking the edit text then de-selecting the checkbox (where the site’s icon would be) then confirming to remove the site.

Some people didn’t really want feeds for some sites, but for other sites, the feeds were very useful. You can now get rid of feeds by clicking edit and dropping the number of items shown to 0. (Just pretend the 2 radio buttons were actually buttons with “-” and “+”… 😛 ) After adjusting the length to what you want, you can click on save.

As a bonus for comparison, you can hit the asterisk (∗) at the bottom corner of the screen to switch to the old thumbnail view. It uses the same data as the text version, so customizations you do on the text view will show up on the thumbnail view. It’ll even remember which view you used last, so next time you open a tab, it’ll show the right one. But just to note, we’re focusing more on the text view right now, so there will be features missing from the thumbnail view.

But we’re still focusing on speed and streamlining the behavior so that you don’t need to do much customization after using it for a bit. We now prefetch sites and their feeds, so the new tab opens up much faster, and the feeds will automatically get the newest information from time to time. Also, some have asked to be able to customize which feeds are shown, but if we can pick the right feed all the time, that saves the extra step. 🙂

For my first week working remotely from Champaign, I focused mostly on the About:Tab sprint, but I got in some time for other Labs projects like Weave and the Design Challenge.

I’ve already written about the About:Tab initial prototype release that provides a streamlined new tab page that needs no configuration, so I’ll mention specifically what I worked on: frecency site listing, thumbnails, feeds, and predicting behavior.

About:Tab Sites

The site listing was the easiest part as I’ve already had plenty of experience with the Places database with the Location Bar for Firefox 3 and Auto Dial. The query I used is actually quite different from the existing queries as it focuses on finding top pages of sites instead of just any top-frecency pages. At one point I was tempted to also show related pages of that site similar to EdBrowser’s Site Launcher, but Beltzner set us back on track of quickly creating a prototype. 😉

For those using About:Tab, you might have noticed you can drag the sites around, but that doesn’t actually do anything. (Actually, it’s useful for preparing screenshots..) I used jQuery UI’s Sortable [jqueryui.com] to let things get dragged around. This was actually the first time I used a framework like jQuery, so I had to do a lot of digging around the API Documentation [docs.jquery.com]. So if you look through the mercurial code repository [hg.mozilla.org], you’ll see plenty of chained $()s.

About:Tab Thumbnails

I had some trouble coding up the thumbnails as I kept thinking about how to efficiently grab thumbs and save them, but then I realized it was just a prototype, so for now it just loads the thumbnails once and saves them in memory for the session. This turns out to work pretty well as the site listing doesn’t change much and the thumbnails are just there to help remind you “yes, this is the site I want” as after a while, it should be muscle memory for going to site you want.

Testing grayscale filters on cake!

I also got to play around with SVG to make the thumbnails gray until hovered. I found roc’s post on applying SVG effects to HTML [weblogs.mozillazine.org] and quickly put together my own example. I had some troubles getting it to work in about:tab because the about: protocol doesn’t support #fragments, but because we clear out the location bar anyway, I decided to switch the page to just use the chrome:// URI.

About:Tab Feeds

A lot of the heavy lifting of automatically finding and tracking feeds was straight from Atul’s Ambient News [toolness.com]. The main part I worked on was grabbing feeds for just the corresponding sites shown instead of showing any feed from top sites. Here I used an asynchronous SQLite query to get the feed data, so that’s part of the reason why feeds slowly fade in after opening a new tab.

About:Tab Predicting Behavior

There already is some behavior predicting in the prototype like suggesting undo closed tab and searching for addresses, but I’m actually working on something separate.. predicting where you would want to go next based on where you’ve already been. The Places backend already remembers your history to help decide which pages to show in the Location Bar, so mining useful data like starting pages is totally possible.

This functionality isn’t in the initial prototype, but I’ve got some results that seem promising.. at least for my own browsing history, so we’ll figure out a way to show this information to the user. The ability for Firefox to accurately provide useful pages is pretty neat but kinda creepy at the same time..

For example, after searching for “weather champaign,” it would suggest the GPS-tracking bus results. Or after going to Air Mozilla [air.mozilla.com], it knows that I open up the Weekly Status Updates [wiki.mozilla.com]. Or when I go to one news site, I frequently go to other news sites.

In terms of the Design Challenge [labs.mozilla.com], I figured that while I’m working remotely in Champaign, it would be good for me to reach out to the University of Illinois’ HCI group. So I’ll be talking with some of my former professors like Karrie Karahalios [social.cs.uiuc.edu] who focuses on social computing.