Article
Rewrite the Web with Chickenfoot
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:
When it's run in the Chickenfoot environment, however, the same code produces the following dialog box:
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:
find("Chickenfoot");
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 thefileio.jslibrary.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 Data\Mozilla\Firefox\Profiles\{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.