Browser Add-ons, Extend Firefox, FireFound, Mozilla, Mozilla Firefox

FireFound Shutting Down

FireFound is a Firefox add-on and companion Web service that I wrote for the Extend Firefox 3.5 competition in 2009. It allows users to track their device’s location via Firefox’s then-new geolocation API; additional features include the ability to view a device’s location history on the website and the ability to turn on a “killswitch” that would clear your browsing data (history, saved passwords, etc.) if someone opened your browser and could not provide your chosen password. It was the first add-on of its kind, and it has been well-received.

That being said, FireFound will be shutting down on April 1, 2012. I don’t have the time to keep it compatible with the newest Firefox and Firefox Mobile releases, nor can I keep up with the feature requests and bug reports.

FireFound users who would like to save a copy of their location data can, as always, export their data by logging in and clicking the “Download” button on the “My Data” page. Any users who have pre-paid for a Premium account past April 1 will be given a prorated refund.

For those looking for a suitable replacement, I recommend Prey. It’s an open-source implementation of a similar idea, but it runs at the operating system level rather than inside the browser, so it’s always on.

(If you’re interested in taking over FireFound, e-mail me at If you’d just like to run your own instance of FireFound, all of the code is open-source.)

FireFound was shut down on April 1, 2012.

Mozilla, Mozilla Firefox, Mozilla Firefox for Mobile, Programming, Technology, URL Fixer

What do people type in the address bar?

Update: URL Fixer was acquired and is now hosted at

Earlier this year, I added a feature to URL Fixer (a browser add-on that fixes errors in URLs that you type in the address bar) that collects anonymous usage stats from users who opt in in order to help improve the ways that URL Fixer corrects typos; the collected data includes domains that are typed in the URL bar as well as the locale (language/country) of the user who typed them.

I now have six months of data, and I’ve run some statistical analysis on it in order to share some interesting stats with you. (If I were more creative, I would make an infographic out of this information.) Note that this data does not include bookmarked links or links that users click on in websites. It is strictly domains that have been typed directly into the address bar.

Care to guess the most commonly typed domain? That’s right: It was typed almost three times as often as the second most popular domain,

The top 10 domains account for 20% of all typed domains. 9% 1.1% 0.5% 3.3% 0.6% 0.5% 3.3% 0.6% 1.1% 0.6%

The most popular TLD for typed domains is .com, followed by .org, .net, and .de.

.com 63%
.org 4%
.net 4%
.de 4%
.ru 2%
.hu 1%
.fr 1% 1%
.br 1%


The top 17 TLD typos are all variations of .com. In order of frequency, they are .com\, .ocm, .con, .cmo, .copm, .xom, “.com,”, .vom, .comn, .com’, “.co,”, .comj, .coim, .cpm, .colm, .conm, and .coom.

The website that appears to benefit the most from users mistyping a legitimate URL is (count the o’s). It’s a scammy website set up to make you think that you have been chosen as a “Facebook Winner.” However, it is only typed once for every 7,930 times that someone correctly types ( and are runners-up in this category, albeit with much less scammy sites in place than

49.5% of domains are typed with a leading “www.”.

The most popular domains:, (a Russian social network), and

The only locales where neither Google nor Facebook control the most popular domain are ru-RU (Russia –, fi-FI (Finland –, a gaming website), ko-KR (Korea –, an e-sports website), and zh-CN (China –

How does domain length correlate with typing frequency?

Domain Length vs Frequency Graph

(Facebook is to thank for the spike at 12 characters.)

How about alphabetical order? Has the old trick of choosing a site name early in the alphabet in order to show up above the fold on DMOZ had any lasting effect?

Facebook and Google certainly make their letters stand out, but there doesn’t appear to be a correlation between the first letter of the domain and its popularity.

None of the domains with more than a 0.0005% share are unregistered, indicating that this kind of usage data would not be very useful to a scammer or phisher looking for new domain names.

Browser Add-ons, Google Chrome, Mozilla, Mozilla Firefox, Programming

Using Google Chrome locale files in Firefox extensions, updated

After I posted my latest revision to some code for using Google Chrome locale files in Firefox extensions, Wladimir Palant pointed out some shortcomings with the code; I’ve made some changes to address these issues, and the new code is shown below.

View the code at GitHub.


The new usage rules are as follows:

  • Replace MY_EXTENSION_NAMESPACE with the namespace of your extension’s files. e.g., if your files are at chrome://abcdefg/content/, then replace MY_EXTENSION_NAMESPACE with abcdefg.
  • Rename MY_EXTENSION_STRINGS to something that won’t interfere with another extension.
  • The _locales directory from your Chrome extension should be in the chrome/content/ directory of your Firefox extension (or update my code to point to wherever you put it).


This code has four advantages over the previous versions:

  1. It’s a single code block that works with all recent versions of Firefox.
  2. You don’t need to include an additional library for file I/O.
  3. It fixes a bug in retrieving the proper locale code in Firefox on Linux.
  4. You don’t have to specify <em:unpack>true</em:unpack> in your install.rdf in Firefox 4.

Thanks Wladimir for your input; this version is undoubtedly better than both previous versions. I can’t ensure that it’s the best possible solution, but it’s the best one that I’ve found so far.

Browser Add-ons, Google Chrome, Mozilla, Mozilla Firefox, Programming

How to use Google Chrome extension locales in Firefox 4 extensions

Update: Don’t use this code. Use this new version.

A few months ago, I posted a snippet of code that provides an API for using locale files from Google Chrome extensions in extensions for Firefox 3.6 and older. I’ve now added support for Firefox 4, and the updated code is shown below:

View the code at GitHub.

The same usage rules still apply:

  • Replace “MY_EXTENSION_ID” with the ID of your extension.
  • Rename “MY_EXTENSION_STRINGS” to something that won’t interfere with another extension.
  • The _locales directory from your Chrome extension should be in the chrome/content/ directory of your Firefox extension (or update my code to point to wherever you put it).
  • Include the excellent io.js library in your extension.
  • NEW: For Firefox 4, you’ll need to specify <em:unpack>true</em:unpack> in your install.rdf.

I’ve been using this solution in ScribeFire in Firefox 3.5, 3.6, and 4.0 (and 5 and 6) for a while now with no complaints. Let me know if you implement this in your extension, and I’d love any feedback you have on the code or its performance.

Browser Add-ons, Mozilla, Mozilla Add-ons, Mozilla Firefox, Slashdot, Slashdotter

Discontinuing Slashdotter

Slashdotter is an extension I wrote in 2006 in order to customize the Slashdot experience. It was covered on Slashdot and was received favorably by the Slashdot audience, but I don’t have the time anymore to update it every time Slashdot changes their UI or HTML.

If you’d like to take over development, let me know, and I’ll transfer the Slashdotter add-on to you on AMO; if nobody volunteers, I’ll be removing the add-on from AMO in a couple of weeks. (Like all of my browser extensions, Slashdotter’s source code is open source, so you could still develop your own version if you want.)

Browser Add-ons, HootBar, HootSuite, Mozilla, Mozilla Firefox, Twitter, TwitterBar

TwitterBar is now HootBar

Update: TwitterBar for Firefox was sold to HootSuite and renamed HootBar in March of 2011. TwitterBar for Chrome was discontinued in October of 2012.

My Firefox add-on TwitterBar, the world’s most popular Twitter client for Firefox’s URL bar, has been acquired by HootSuite and has been renamed “HootBar.”

HootBar users now have access to great HootSuite features like the Hootlet: instead of typing “–post” at the end of your tweet, if you type “–hoot”, you can schedule your tweet for later, send your message to networks besides Twitter (like Facebook or LinkedIn), and track stats for link clicks.

The rebranded version of TwitterBar is still awaiting approval by Mozilla, but you can install it manually here. More information on the TwitterBar-to-HootBar change is available at HootSuite’s “TwitterBar to HootBar” transition page.

Browser Add-ons, Comment Snob, Google Chrome, JavaScript, Mozilla, Mozilla Firefox, Programming, Software, Technology, YouTube Comment Snob

Announcing Typo.js: Client-side JavaScript Spellchecking

When I first ported YouTube Comment Snob to Chrome, Chrome’s lack of a spellchecking API for extensions meant that I would be unable to implement Comment Snob’s most popular and distinguishing feature: the ability to filter out comments based on spelling mistakes. That, my friend, is about to change.

I’ve finished work on the first version of a client-side spellchecker written entirely in JavaScript, and I’m calling it Typo.js. Its express purpose is to allow Chrome extensions to perform spellchecking, although there’s no reason it wouldn’t work in other JavaScript environments. (Don’t use it for Firefox extensions though; use Firefox’s native spellchecking API.)

How does it work?

Typo.js uses Hunspell-style dictionaries – the same ones used in the spellcheckers of and Firefox. (Typo.js ships with the latest American English dictionary, but you could add any number of other dictionary files to it yourself.) You initialize a Typo.js instance in one of two ways:

Method #1

var dictionary = new Typo("en_US");

This tells Typo.js to load the dictionary represented by two files in the dictionaries/en_US/ directory: en_US.aff and en_US.dic. The .aff file is an affix file: a list of rules for creating multiple forms of a word by adding prefixes and suffixes. The .dic file is the dictionary file: a list of root words and the affix rules that apply to them. Typo parses these files and generates a complete dictionary by applying the applicable affix rules to the list of root words.

Method #2

var dictionary = new Typo("en_US", affData, dicData);

With this initialization method, you supply the data from the affix and dictionary files. This method is preferable if you wish to change the location of the affix and dictionary files or if you are using Typo.js in an environment other than a Chrome extension, such as in a webpage or in a server-side JavaScript environment.

Once you’ve initialized a Typo instance, you can use it to check whether a word is misspelled:

var is_correct_spelling = dictionary.check("mispelled");


Depending on your needs, you can configure Typo.js to perform word lookups in one of two ways:

  1. hash: Stores the dictionary words as the keys of a hash and does a key existence check to determine whether a word is spelled correctly. Lookups are very fast, but this method uses more memory.
  2. binary search: Concatenates dictionary words of identical length into sets of long strings and uses binary search in these strings to check whether a word exists in the dictionary. It uses less memory than the hash implementation, but lookups are slower. This method was abandoned as it became impractical to implement for some features.

See this blog post by John Resig for a more detailed exploration of possible dictionary representations in JavaScript.

Practice vs. Theory

Typo.js is already in use in my Comment Snob extension. You can install it today to experience Typo.js in action, filtering comments on YouTube based on the number of spelling mistakes in each one.

What’s next for Typo.js?

The next step is adding support for returning spelling suggestions; right now, all Typo.js can do is tell you whether a word is spelled correctly or not. It also needs to support Hunspell’s compound word rules. These are the rules that a spellchecker uses to determine whether words like “100th”, “101st”, “102th” are correct spellings (yes, yes, and no, for those of you keeping track) since it would be impossible to precompute a list of all possible words of these forms.

The Typo.js code is available on GitHub. I welcome any and all suggestions or code contributions.

Browser Add-ons, Google Chrome,, Launch Announcement, Mozilla, Mozilla Firefox, Programming

Improving the browser extension localization process

Executive summary: I’ve developed a new site to help extension authors and translators collaborate; it’s called

My least favorite aspect of developing browser extensions is localization. Writing the actual code to internationalize an extension isn’t so bad, but keeping the translation files up to date has always been a chore. (Localization is the process of translating software into different languages; internationalization is writing software that can be easily localized.)

The preeminent site in the extension localization space is Babelzilla. Babelzilla has been around since 2006, and it is the only site that I know of for pairing extension developers with translators. It works, but I’ve never felt that it works especially well, and when you can’t release an update to your extension because Babelzilla is down or buggy (preventing you from retrieving the latest locale files), it’s very frustrating.

Localizing Google Chrome Extensions

When I started developing browser extensions for Google Chrome, I was surprised to find that no Babelzilla equivalent exists, even though Chrome has very full-featured internationalization support for extensions – apparently, extension developers in this ecosystem are expected to come up with their own ad hoc solutions for managing their extension translations. “Ad hoc” is not a term I enjoy applying to solutions, so I decided to see what I could do to improve upon the Babelzilla experience for Chrome extension developers.

Centralizing Extension Internationalization

In developing a translation site for Chrome extensions, I had two goals:

  1. A full-featured API that allows developers to interact with the site without visiting it.
  2. A clean and simple interface for translators that reduces the barrier to entry as close to zero as possible.

With these two goals in mind, I developed On, developers upload their extensions, translators localize them into their native language, and then developers can download the new locale files to use in their next extension update. for Developers

Developer interaction is limited to the upload and download of locale files. In fact, developers can interact with completely from the command line via the /api/upload and /api/download API methods. (There are also API methods for translating messages and retrieving the translation history of a message.) for Translators

Once an extension has been uploaded to, a status page is generated that shows the progress made on all of the locales supported by Chrome for extensions. Here’s an example screenshot of that page:

Each locale code links to a translation page, which is a listing of all of the messages (or “phrases” or “strings”) used in the extension. Here’s what one of those messages looks like:

There are 4 aspects to the UI for translating a single message:

  1. The original un-translated message.
  2. A description of the message from the developer, which adds context to the message.
  3. The placeholders in the message, used to insert information which can’t or shouldn’t be translated.
  4. The history of the message’s translation, which shows previous revisions and allows a developer or translator to revert changes.

(Not every message will have a description, placeholders, and a translation history.) The translator types the translated phrase in the box, and as soon as they hit the tab key (or click outside of the box), the message is automatically saved without a page reload.

Additional Features

Sign in/out is tied to your Google account, so you don’t have to create another username and password; it seemed like a natural fit for a site focused on Google Chrome extensions.

The site itself is localized using itself. ( obviously isn’t a browser extension, but it does use Google Chrome-style JSON locale files, so it’s compatible with’s translation system.) To access a localized version of, select a locale code from the menu in top-right corner of the website, or manually type a URL like will also automatically fill in any translations that have been previously completed for other extensions. For example, if a translator has already translated ‘Thank you’ into French for another extension, and a different developer’s extension uses the phrase ‘Thank you,’ will automatically transfer that translation. (There’s been some discussion as to whether this will backfire, but I have been unable to come up with identical English phrases that would result in different translated phrases. If you can come up with some, I’d love to hear them.)

Open for Business

If you’re a Chrome extension developer, you can upload your extension to right now. I’m already using it to manage localization for the website and two of my Chrome extensions, and so far, thirteen different translators have translated a total of 1087 messages.

After I have some more time to collect feedback from developers and translators, I plan on either adding support for Mozilla browser extensions or possibly donating code to the Babelzilla project to improve their experience for developers (if they’re interested).


If you’ve read this far, I want your feedback. Even if you’re not involved in the development or translation of browser extensions, I want to know what you think – were you not aware of the process at all? Does it sound like a problem worth solving? If you are familiar with the problems faced by developers and translators, do you think that is an improvement upon the Babelzilla experience? Or am I wasting my time reimplementing something that already (kind of) exists? What features would you like to see? What localization/internationalization issues do you find irritating? Leave your thoughts in the comments.