Rewrite the Web with Chickenfoot

A number of plugins and extensions are available for the Firefox browser to allow developers to interact with the DOM and with other exposed parts of a web page. Tools such as the JavaScript Shell Bookmarklet, Firebug, Greasemonkey, and Platypus have proven useful for allowing developers to add custom interactivity to a page, debug DOM and CSS problems, and test ideas.

However, if a user wants to dynamically interact with multiple pages, to automate different parts of the Firefox interface, to script activities across a number of pages, or to work with both the web page and the local file system concurrently, the options have historically been limited. But this has begun to change recently with extensions such as CoScripter, and the extension that forms the subject of this article: Chickenfoot.

What is Chickenfoot?

Chickenfoot is a Firefox extension from the MIT User Interface Group. It offers the ability to:

  • interact with the chrome of the browser
  • use an interactive shell for manipulating the page and to monitor page interactions in various ways
  • write scripts that run over multiple sites, so that one can write a script that visits one web page, copies some text from a part of the page, goes to Google, searches for that text, and then appends the first link to a page on the local filesystem

Chickenfoot is an extremely powerful tool for any developer wishing to automate actions or extend the functionality of the web pages he or she utilizes regularly.

Installing Chickenfoot

Chickenfoot is installed in the same way as other Firefox extensions: simply download and accept the XPI file that’s available from the Chickenfoot install page.

Despite the fact that Firefox is a cross-platform browser, the extension works best on Windows. If you’re on a Mac, you can still install Chickenfoot and play along with the code in this article, but you may see inconsistent behaviour. Unfortunately, until the kinks are ironed out, the warning this.docShell has no properties will appear frequently, and your output may not match that described here.

Once you’ve installed the extension and restarted your browser, you can access the Chickenfoot interactive shell by either pressing F8 or selecting the View > Sidebar > Chickenfoot menu option. The shell will open in a sidebar, and will look something like the image below.

Rewrite the Web with Chickenfoot

When the Chickenfoot sidebar is first launched, it shows a split view — the top panel contains a text field labeled Untitled; this is the input area where we’ll write our Chickenfoot code.

The bottom panel contains four tabs. The tab that’s selected by default is labelled Output, and displays a history of all your actions, and all of Chickenfoot’s actions, that were applied to the browser. First, we have to tell Chickenfoot to record our actions, though — click on the Actions tab, and make sure that the Record actions option is checked.

Let’s test that our output is being captured. To do so, open a new Firefox tab and load the Google homepage. Once the page has loaded, click on the Images link in the top left of the page, which will take you to Google’s Image Search. If you select the Chickenfoot Output tab once again, you should see the following text:


This is more than just a description of what has occurred — it is in fact a snippet of Chickenfoot code! To test this code, click the Back arrow to return to the Google homepage, then copy and paste the snippet we created into the top Chickenfoot panel. Click the green arrow at the top of the panel, and your code snippet will be executed. The page will once again navigate to the Google Image Search page.

Ideas Behind Chickenfoot

Chickenfoot shares certain ideas with other tools that enable a scriptable web.

The main idea behind Chickenfoot is to provide users with a tool for creating macros that anyone can use or write, without needing a programmer’s assistance. I should note here that it’s my opinion that this aim will not be achieved, because there will always be demand for scripts with complex functionality that can only be implemented by a programmer. However, the fact that this idealistic goal is the driving force behind Chickenfoot has resulted in a very useful tool.

These aims are similar to those of CoScripter — indeed, CoScripter uses part of the Chickenfoot version 0.9 code. I won’t go into any details about CoScripter in this article, but if you’re interested in reading more, see Alex Faaborg’s writeup.

Finding Our Feet

Let’s look at how Chickenfoot scripts can be recorded, much like a macro in MS Word or Adobe Photoshop. For this example, we’ll create a script that’s only slightly more involved than the single command we saw in the previous section. For this demo, I’ve taken inspiration from a Getting Started with CoScripter tutorial.

When we’ve finished, our script will cause our browser to:

  1. Load the page
  2. Click the Images link.
  3. Place the text "koalas" into the Search Images textbox.
  4. Click the Search Images button.

Let’s get scripting! Open your Chickenfoot sidebar if you haven’t already, and type the following command in the top panel:


Then click the green arrow. As you might expect, your browser will load the Google homepage.

To record the rest of our script, we’ll basically just perform the steps I’ve described above. Click on the Images link, then type the text "koalas" in the search box, and hit Tab to exit the field. Finally, click the Search Images button.

Your Output tab should now display something similar to the following:

go("")  click("Images")  go("")  enter("Sign in", "koalas")  click("Search Images button")  go("  &gbv=2")

If you performed these steps while you were logged into your Google account, some of the text values listed may be different, but the actions should still be identical.

Now that we’ve recorded our actions, we can pick and choose from this code output, and copy the desired lines to the top panel of our Chickenfoot sidebar. Voila! We have a working script!

Apart from the initial go action, the commands we’re after are the click and enter commands. We can also simplify the values passed in, so that our script looks something like this:

go("")  click("Images")  enter("koalas")  click("Search Images button")

One thing you may notice from the above example is that Chickenfoot syntax has much in common with many C-based languages, like JavaScript. Chickenfoot commands are, in fact, JavaScript.

Scratching the Surface

One concept that is important to grasp is that Chickenfoot doesn’t run in the normal (X)HTML environment with which most JavaScript users are familiar, but in FireFox’s XUL environment. This environment has been extended for Chickenfoot to allow it to more easily interact with the context of a web page.

If you reference or modify an object to which JavaScript has access in the context of a normal page, it’s likely to behave as you would expect. However, because the Chickenfoot JavaScript engine has a deeper level of access, you can take more liberties than usual, such as accessing objects outside of their default context.

As you explore Chickenfoot further, you may encounter differences between the two environments and how objects behave in them. Most often, the reason for these differences will be down to native functions from the browser environment that have been reimplemented in the XUL Chickenfoot environment for the sake of familiarity.

One such example is the alert function; consider the following snippet of JavaScript code:

Object.prototype.describe=function(){alert("Description: " + this);return this;}   alert("Describe:" + alert);

When this code is run in the HTML environment in Firefox, it displays the following dialog box:

Rewrite the Web with Chickenfoot

When it’s run in the Chickenfoot environment, however, the same code produces the following dialog box:

Rewrite the Web with Chickenfoot

In addition to the many shared functions, there are some additional functions that are not available in the regular browser-based JavaScript implementation, but are available within the Chickenfoot environment. A list of these functions can be found in the Chickenfoot API documentation.

Pecking at the Chickenfoot API

As with technology, there are certain parts of Chickenfoot that are more useful than others, and parts that you will absolutely need to understand in order to make the most of Chickenfoot.

The following are the parts that I find the most useful.

The Pattern Datatype

Most Chickenfoot functions accept Patterns for parameters. A Pattern is described in the API documentation as "a union of a number of other datatypes."

It’s easiest to think of a Pattern as a shorthand phrase for accessing objects on an HTML page. For example, the pattern "second Chickenfoot" refers to the second occurrence of the word "Chickenfoot" on a page. If you were to visit the Chickenfoot API page and execute the following code, the second occurrence of the word "Chickenfoot" on the page would be selected:

click("second Chickenfoot");

There are a few variations on this approach, and Chickenfoot uses some logic to try to intelligently figure out which pattern your phrase is using. Because of this, certain functions (such as click) don’t work well with Patterns, as they’ll generate errors if they’re given a Pattern that could return more than one possible result.

For example, suppose we were to change the above code to the following:

click("2 Chickenfoot");

It’s likely that this will produce an error message in the Output panel similar to the following:

Error: More than one best match for click(2 Chickenfoot)

To use Patterns effectively, you therefore need either to make your patterns especially precise (for example, by using XPath syntax or LAPIS query syntax if you have the LAPIS extension installed) or else use the find function, and iterate through the array of objects that this function returns. We’ll look at this approach next.

A Pattern is a union of the following datatypes:

  • string
  • TC
  • Match
  • Node
  • Range
  • Xpath

The find function

The find function takes a Pattern and returns the objects that match that Pattern. Place the following code in your top panel and execute it on this very page:


You’ll notice an object appear in your Output panel. Clicking on this object will cause all instances of the word "Chickenfoot" to be highlighted.

The object that this function returns is, unfortunately, not a JavaScript array. As a rule of thumb, you’ll need to pipe the results of Chickenfoot’s find function into an array, then loop through the array to pick out the individual object that you’re after.

The include function

The include function allows you to include other JavaScript files in your Chickenfoot script. Chickenfoot comes with some built-in libraries (most of the names are self-explanatory):

  • prototype.js, a modified version the 1.5.0_rc0 release of Prototype. Unfortunately, at the time of writing, Chickenfoot’s XUL environment raises errors with the Prototype library, rendering newer versions of the Prototype library incompatible.
  • facebook.js, for querying the Facebook API.
  • fileio.js, which provides functions for interacting with the local file system.
  • google-ajax-search.js, for performing AJAX-based Google search queries from any web page.
  • google-maps.js, for querying the Google Maps API.
  • google-search.js, a wrapper for the Google web search API. (Unless you happen to have a Google API key — they’re no longer being issued — this particular library is of little interest.)
  • greasemonkey.js, which implements most of the Greasemonkey API, allowing you to reuse existing Greasemonkey scripts.
  • json.js, for performing JSON serialization and deserialization of data.
  • screenshot.js, which allows you to take screenshots and save them to the local file system via the fileio.js library.
  • scriptaculous.js, version 1.6.1 of the popular Prototype-based effects library.
  • strings.js, which contains functions for removing trailing and leading whitespace from strings.
  • us-geocoder.js, the non-commercially licensed library for geocoding U.S addresses.
  • wz_jsgraphics.js, A version of Walter Zorn’s JavaScript Graphics library.

When you factor in the functionality that each of these libraries brings to the table, you should start to appreciate the potential that Chickenfoot brings to the Web.

You can include a library in your Chickenfoot script in one of four different ways:

  • via a chrome URI
  • via a file path
  • via the name of a file stored in your Chickenfoot profile directory (under Application DataMozillaFirefoxProfiles{profile id}chickenfoot)
  • by explicitly referencing the library by name

A note concerning using new libraries: I’ve found that often the kinds of libraries that work best are those that provide specific functionality, like CssQuery or similar libraries, rather than libraries that attempt to be all-encompassing.

The include function also takes an optional object parameter that can be very useful for inspecting what’s available inside a particular library or set of libraries, although this functionality isn’t covered in this article.

Chickenfoot also has several other language constructs, such as after, before, and insert, that allow you to retrieve an element on the page using find, and then to navigate from that element to the element you’re really after. These functions also make it possible to dynamically insert content into that element or into a surrounding HTML element.

Useful Tasks Turned into Chickenfeed

Any technology that purports to automate tasks should make it easy to do useful things quickly. In this section, I’ll describe some tasks for which Chickenfoot is really useful. I’ve included fragments of code, and although they may not illustrate JavaScript best practices, they do a good job of illustrating various uses of Chickenfoot.

Let’s get started! Here are a few handy Chickenfoot scripts.

First, let’s find out what variables are bound at the top level of your FireFox chrome:


This single line should provide you with quite a bit of information. You can also view a heap of information about the current document using this command:


Next, let’s output the current web page as an XHTML string to the Output pane:

var xhtmldom = Chickenfoot.domToString(document);    output(xhtmldom);

Now, let’s write the XHTML string above to your desktop. It’s possible to write the XHTML output from the example above to a file on your desktop. Replace the escaped file separator "\" in the last line with "//" if you’re on a Mac or Linux machine:

include("fileio.js");     //use    Defs.html      // Firefox directory service to use various built in Windows directories    var xhtmldom = Chickenfoot.domToString(document);    var desktop =       Components.classes[";1"].      getService(Components.interfaces.nsIProperties).get("Desk",      Components.interfaces.nsILocalFile);   

var fname= "xhtmldom.xml";    write(desktop.path + "\" + fname,xhtmldom);

The above task can actually be performed using even simpler code in the soon-to-be-released version of Chickenfoot, because it uses the default Firefox download directory (usually the Desktop).

Now, let’s interact with the browser chrome that you’ve inspected.

In Firefox, parts of your browser’s window chrome can be accessed if you have the ID of the object in question. This can be retrieved using the function chromeWindow.document.getElementByID. For example, the ID of the Context Menu that’s displayed when you right-click on a page is contentAreaContextMenu. If we were to take the script from example 3 above, which saves the DOM to the desktop, and wrap it in a function, we could then call this function from the Context Menu, like so:


function saveDom() {      var xhtmldom = Chickenfoot.domToString(document);      var desktop =         Components.classes[";1"].        getService(Components.interfaces.nsIProperties).        get("Desk", Components.interfaces.nsILocalFile);   

var fname= prompt("What filename would you like to save as?");      write(desktop.path + "\" + fname,xhtmldom);    }    var chromeDoc = chromeWindow.document;    var contextMenu = chromeDoc.getElementById("contentAreaContextMenu");    var menuItem = chromeDoc.createElement("menuitem");    menuItem.setAttribute("label","Save Dom");   

menuItem.addEventListener("command", saveDom, false);    contextMenu.appendChild(menuItem);

Note that the Chickenfoot function append function allows you to append data to a document. You use it like this:

append(desktop.path + "\" + fname, "text to append");

Hopefully, these examples give you a feel for some of the simple but powerful tasks that can be automated by Chickenfoot script.

A More Advanced Chickenfoot Script

Enough with the simple tasks — let’s do something a bit more advanced with Chickenfoot!

I use the following script to add functionality to Gmail — specifically, to search for and select from a page the conversations that contain text that matches a particular Chickenfoot Pattern. It’s a useful and powerful enhancement to everybody’s favourite web-based email client.

Here’s the script:

var i = 0;    var wasextracted = "";    var  searchstring ="";    var selection = prompt("Select messages with the following text:");    var found = find(selection);    var results = new Array();    for (found;found.hasMatch;found = {      results[i]=found.text      i = i + 1;    }   

var searchnumber;    for (var x = 0; x <= results.length; x++) {      searchnumber = x + 1;      try {        extracted=results[x];        if (wasextracted==extracted) {          searchstring = searchnumber + " " + extracted;          check (searchstring);        } else {          searchstring = extracted;          check(searchstring);          wasextracted=extracted;        }      }      catch(e) {}    }

This script prompts the user for some input, then passes that input as a parameter to a Chickenfoot find function. Remember that find accepts a Chickenfoot Pattern, so the possible uses for this kind of search are almost limitless given that you can ask it to match more than just strings.

You may recall from when we first encountered the find method that it doesn’t return an array. We therefore need to read the results into an array. You’ll probably find the fragment of code that performs this task to be useful in other Chickenfoot scripts that you write:

for (found;found.hasMatch;found = {      results[i]=found.text      i = i + 1;    }

After this, the script loops through the array returned by the find function, and tries to construct a Chickenfoot Pattern that will match the text that contained our search string exactly. We then use the Chickenfoot check function to toggle the checkbox nearest to that section of text, thus selecting that message.

Remember that check needs to be able to make sure it has the exact piece of text, or it will throw an error, which is why we can’t just do a check on found.text.

One notable aspect of the script above is its small size relative to the functionality it achieves. Chickenfoot’s functions provide easier ways of dynamically interacting with a document than such standard APIs as the DOM.


In this article, we looked at a number of ways in which you can easily use Chickenfoot to interact with the browser. We’ve only scratched the surface in terms of what can be done with Chickenfoot in this article — the potential is huge, and it’s limited only by your imagination!

If you’re interested in learning more, check out the following resources:

If you create a killer script, I encourage you to submit it to the Chickenfoot wiki. Happy scripting!


Category: javascript Time: 2008-02-01 Views: 0

Related post

  • Optimizing Images For The Web With Photoshop 2009-07-07

    The Save For Web command in Photoshop allows you to optimize your images for use on the web. Broadband may be allowing us to use larger images online, but it's still important to remember the visitors who aren't on broadband and optimize all images o

  • SitePoint Podcast #64: Learning the Web with Russ Weakley 2010-06-04

    Episode 64 of The SitePoint Podcast is now available! This week, Kevin Yank (@sentience) chats with Russ Weakley (@russmaxdesign) about SitePoint's new courses, CSS Live and PHP Live, as well as the Web Standards Group and Full Code Press. Listen in

  • how do I share photos on the web with iPhoto / iCloud? 2012-11-08

    I have a new Mac (Mountain Lion) with iPhoto '11. I want to share photos on the web. In the past, I would launch iWeb and build a little photo album web page. My understanding was that if I subscribed to .Mac/MobileMe I could share my iWeb page that

  • Can I run a minimalist web-server on my router without rewriting the firmware with DD-WRT? 2012-08-20

    I read this article on that says that you can make a web-server on your router providing that you rewrite its firmware with a free DD-WRT, Tomato, or equivalent. Leaving apart the fact there is no DD-WRT available for my router, I don't kn

  • What are the statistics on users posting photos to the web with a color profile embedded? 2011-04-25

    I am coming from StackOverflow, from this question specifically: How to stop GD2 from washing away the colors upon resizing images? Summary: I have a photo gallery website on which the image resizing feature throws away a lot of the saturation of a p

  • What is ethical/unethical while seeking help on the web with programming assignments? 2011-12-11

    I have used the web and Stack Overflow extensively during the past month or so in creating my final project for my C# class. I have used so much code that I didn't write myself that I feel I am being unethical by not giving proper credit to the peopl

  • Quick-Search the web with query string 2013-08-31

    The Mac app has some pretty neat features. One of them called "Quick-Search the web" (see more here) allows to search the web by typing a keyword (i.e twitter) and getting a web page directly (i.e But even better

  • Powering the Web with Python Web Frameworks 2013-11-19

    Introduction Web frameworks are primarily server-side technologies that are designed to accomplish a series of specialized tasks. As it relates, Python Web frameworks are module and package collections that enable developers to build Web applications

  • Navigate the web with the terminal 2015-03-30

    I'm trying to learn how to use the terminal, and I want to try sending and receiving data from a common website like Amazon or Google. I want the terminal to enter a string into a website's search bar and "click" search. I don't need it to open

  • Bringing VR to the Web with Google Cardboard and Three.js 2015-05-18

    Virtual reality is coming. You know that as a developer – you want in. The Oculus Rift, Gear VR, HTC Vive and more are making waves, yet many developers don't realise just how much potential there is in the simplest of them all – Google Cardboard. I'

  • Decorating the Web with CSS Border Images 2015-12-09

    Not too long ago, adding decorative elements like fancy borders to a web page involved slicing images and patiently tweaking away at the CSS until it looked just right. CSS has changed all this. A few lines of code are all you need to decorate your w

  • De-clutter the Web With the Readability Bookmarklet 2009-10-30

    Sometimes it's nice to read an article without distractions. SitePoint's design features links, forms and adverts but I personally think its layout offers good readability. Unfortunately, there are many sites that give the impression their advertisin

  • How can I get html code from the web with vala(gtk)? 2011-01-07

    How can I get a html code from some site(e.g. using vala(gtk)? --------------Solutions------------- Use the Vala GIO File open shown here var web_page = File.new_for_uri ("

  • Is it safe to browse the web with Firefox during Ubuntu install? 2012-11-25

    As asked in the title. I clicked on one of the links in the Quantal installer (set up via UNetbootin) and it launched Firefox. Will using it for a longer time during install cause conflict with language packs that I'm installing (example: Polish)? --

  • How can I save images on the web with drag and drop? 2014-05-01

    In firefox on Mac OSX I usually save images by dragging them from the browser to the folder I want to save them to. I prefer this method compared to navigating through the file browser as it is much faster. When I do the same in Ubuntu Trusty 14.04 i

  • Is it possible for a reverse proxy to make its request to another proxy and rewrite the urls in the response content? 2013-07-19

    I'm currently looking into reverse proxies and don't have a specific one in mind yet. I am trying to forward my requests from a reverse proxy through another proxy on the web with authentication. The main reason for a reverse proxy is to have the url

  • Do all WiFi printers allow for a method of printing from the web? 2009-11-24

    Wifi printers - good job if you don't like kicking against your printer under your desk. Can you also print from a remote location on the web with them generally? --------------Solutions------------- If I understand what you are asking, the answer is

  • Is Facebook a Threat to the Web? 2010-11-27

    Sir Tim Berners-Lee has been in the news this week following his article "Long Live the Web: A Call for Continued Open Standards and Neutrality" which appeared in Scientific American. The web's inventor criticized Apple and it's proprietary 'iTu

  • Why is that when I download a binary from the web it doesn't have executable permissions set, but when I use gcc to build a binary it does? 2013-07-11

    For example, if I have the file hello.c which just contains: int main() { printf("Hello world"); return 0; } and I built it in gcc with gcc hello.c -o hello I can then run ./hello and it runs. However, if I try to download a binary from the web

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development


Front-end development


development tools

Open Platform

Javascript development

.NET development

cloud computing


Copyright (C), All Rights Reserved.

processed in 2.488 (s). 13 q(s)