Twitter Autocomplete (Tw-autocomplete Firefox Extension)

After lots of code, tests, and fun, I’ve produced a Firefox extension to add a useful, new feature to Twitter, as opposed to writing Twitter extensions as a joke 😀

Simply put, the extension provides autocomplete for Twitter usernames from your own list of friends while you’re using the web interface at twitter.com. It’s totally secure — no separate login required. Just install it, and use Twitter naturally.

When you start typing messages to people — using “@user” or “d user” — a list of matching contacts (along with icons) will drop in. You can click the person’s name to fill their username into the text box, or use the arrow keys along with tab/enter to select. As an added bonus, if you can’t remember their username at all, just type their first name, and the extension will figure it out.

There is another autocomplete script for Twitter, but it requires installing extra libraries, and I think this is simpler. Clearly it’s a feature in-demand.

The extension is hosted at addons.mozilla.org, a highly reputable site. They also provide lots of great management features that are handy to developers. I hope you enjoy using Tw-autocomplete.

Javascript Events, the DOM, and Firefox/Gecko

OK, here’s the deal, as quick as I can put it, but with enough words that Google will correctly index this post and make this information easier to find for the next person who needs it.

Let’s say you’re developing a Firefox extension, and you need to look at the HTML of the page. You know that Firefox is constantly throwing event notifications — there’s the MouseEvent “click” when something is clicked, the KeyboardEvent “keyup” when a key is release, and so on.

So, you figure “well, I need the HTML of the page, so I’ll wait until it loads, then grab the source/parse the DOM tree/unleash flying monkeys”. You know that the style of

window.onload = the_function_name;

is bad, because it only lets one function receive the load event. So, you write some code like

gBrowser.addEventListener(“load”, the_function_name, true);

because this is what you want. You wait for the “load” event to fire, and then run your function. Test this code out, and it will work well-enough, most of the time. Sometimes, it lags, sometimes it doesn’t even fire at all. WTF? Well, I’ve been there.

Here’s the thing: the “load” event fires when loading is done. If you’re looking at the whole window/document, it’s not done loading until the whole document is loaded, including bandwith-and-time-heavy images. And these things can be slow to load, or hang entirely. This can seriously mess with the concept of “loading”. You don’t care about any of these things, you just want the HTML.

Well, Firefox is a very deep project, and there’s a few secret events that aren’t widely used or documented. If you want to know when the HTML is loaded — or more accurately, when the DOM Tree’s content is loaded — there’s a special event you can monitor: “DOMContentLoaded”

gBrowser.addEventListener(“DOMContentLoaded”, the_function_name, true);

This is a very reliable way of knowing when the browser has loaded only the page. The catch is that it’s Firefox-internal only. Which means it only works from an extension — you can’t use this in a web page. There are techniques for duplicating this functionality in other browsers, but that’s getting beyond this post.

Javascript, Dates, Times, and One Man’s Dream

OK, so the title of this post might be a bit overstating.

But, if you work with Javascript and need to use dates/times, you should absolutely check out a JS library for formatted dates and times by Steven Levithan (who is obviously cool; his blog is titled “Flagrant Badassery”).

It’s a library that extends the stock Date object in Javascript to let you easily generate nicely formatted dates. Just put the code in a file and load it up. Then you can do neat things like this (adapted from his blog)

var now = new Date();

now.format(“m/dd/yy”);
// Returns, e.g., 6/09/07

// You can use one of several named masks
now.format(“isoDateTime”);
// 2007-06-09T17:46:21

// …Or add your own
dateFormat.masks.hammerTime = ‘HH:MM! “Can\’t touch this!”‘;
now.format(“hammerTime”);
// 17:46! Can’t touch this!

Detecting page loads in a Firefox Extension

Detecting page loads is a useful ability. It’s easy enough to throw in a

gBrowser.addEventListener(“load”, function_name, true);

But, it causes extra events to get generated. There’s load events occurring in the browser that aren’t page loads. The trick to detecting real page loads (but not Back/Forward navigation when the page is still in memory — only page loads that have a server hit) is to look at the event’s target. In this example, “event” has been passed into the function specified in the addEventListener call above.

if(event.originalTarget instanceof HTMLDocument) {

will make sure that the load event came from a web page being loaded. You can even go a step further and filter out different types of HTMLDocuments.

if(event.originalTarget.defaultView.frameElement) {

will catch events that were triggered as the result of a frame or iframe. It’s an important step, because lots of advertising networks embed their ads in iframes, and you probably are more interested in the actual web page than the ads on that page.

Trash aware rm for OSX — never lose a file again

OK, so let’s say you’re an OSX user, and you use the command line a lot. I bet you’ve accidentally deleted a file using rm, and wished that it had gone to the Trash.

We had this problem a few days ago, and fortunately the file was under version control. But we looked for a solution that would rm into the trash. There was only one solution and it didn’t work in Leopard (10.5)

I mentioned this on Twitter, and my buddy Jason threw a working version of trash-aware-rm for OSX together in no time flat. Check it out.

Listing Ruby Gems, or just viewing documentation

Here’s a neat trick, if you’re working with Ruby. Ever wondered how to get a list of all installed gems?

At the command prompt, type

sudo gem server

Once you’ve done this, go to http://localhost:8808, and you can see all the Ruby Gems installed, along with info and documentation about them. Awesome!

Hat tip to Matt

Firefox extension debugging

One hugely important thing in coding is debugging. Unfortunately, a lot of Javascript debugging gets done via alert() calls. This gets awkward quickly, with the alerts affecting timing, and just being annoying if you have to dump large amounts of data out.

Firebug is a great development tool, and has a really handy logging interface that you can dump debugging info to. Just calling console.log(whatever) will dump it to the main Firebug interface as text that you can copy/paste, scroll through, etc.

If you’re developing a Firefox extension, this debugging capability is really useful. Except, calling console.log() doesn’t work, console isn’t defined for the browser, only for each window.

The trick? Call it directly from the Firebug extension object.

Firebug.Console.log()

Be sure to capitalize both Firebug and Console, and you’ll be good to go. In addition to having great capabilities for logging, the console will prevent your debugging messages from popping up to your users, in case you leave some code where it shouldn’t be.

By the way — if you found this helpful, check back here in a few days. I’ve submitted a presentation proposal to SXSW for Firefox extension development, where I’ve got tons of info for creating extensions for web applications. They collect votes from the community, and I’d like your support. Plus, if the presentation goes through, I’ll be collecting lots of my best tips and putting them online as a resource for the attendees. That means you’ll get all of them too, and you don’t have to go anywhere! 😀

Edit (2008-08-21: Added link for SXSW voting panel)

Javascripting

I’ve been writing a lot of JS lately, and I wanted to take this opportunity to drop some knowledge right here.

Lots of languages have support for some type of for-each-looping. This is great for looping over associative arrays, and even regular arrays, since it’s a bit cleaner than the standard for-loop. Sadly, Javascript doesn’t totally support this. There is a for-each equivalent in JS, but it’s a bad choice to use, since in JS, everything is an object, and objects can be accessed with different notations — you can either do thing.property or thing[“property”]. This notation should throw a hint as to why looping for-each isn’t the same as other language — if you try and loop over everything in an Array, you’ll also get methods that have been assigned to the Array object. Fortunately, Javascript isn’t totally foolish, you won’t get every single method, but you can definitely get some noise. Here’s Mozilla’s explanation of Javascript for-each:

Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea. The for...in statement iterates over user-defined properties in addition to the array elements, so if you modify the array’s non-integer or non-positive properties (e.g. by adding a "foo" property to it or even by adding a method or property to Array.prototype), the for...in statement will return the name of your user-defined properties in addition to the numeric indexes. Also, because order of iteration is arbitrary, iterating over an array may not visit elements in numeric order. Thus it is better to use a traditional for loop with a numeric index when iterating over arrays.

It’s a shame, because a nice for-each is some of my favorite sugar in a programming language. But, I like Javascript enough that I will forgive it for this. I have a suspicion that with some type checking, a more traditional for-each might be possible, but that’s for another time.

I also found the site of a very cool dude, Kent Brewster. Just one example of his awesomeness is found in his article on hardened Javascript. I also really like that he makes notes and lists and saves information; it’s probably one key to his success.