Creating Your Own User Scripts
You've already learned most of what you need to know to create user scripts since they're written in JavaScript. In this section, you'll create and test a simple script, and look at some features you'll use when creating more advanced scripts.
Creating a Simple User Script
One of the best uses for Greasemonkey is to solve annoyances with sites you visit. For example, a site might use green text on an orange background. Although you could contact the webmaster and beg for a color change, user scripting lets you deal with the problem quickly yourself.
As a simple demonstration of user scripting, you can create a user script that changes the text and background colors of paragraphs in sites you visit. Listing 18.1 shows this user script.
Listing 18.1. A Simple User Script to Change Paragraph Colors
// Change the color of each paragraph
var zParagraphs = document.getElementsByTagName("p");
for (var i=0; i<zParagraphs.length; i++) {
zParagraphs[i].style.backgroundColor="#000000";
zParagraphs[i].style.color="#FFFFFF";
}
|
This script uses the getElementsByTagName() DOM method to find all of the paragraph tags in the current document and store their objects in the zParagraphs array. The for loop iterates through the array and changes the style.color and style.backgroundColor properties for each one.
Describing a User Script
Greasemonkey supports metadata at the beginning of your script. These are JavaScript comments that aren't executed by the script, but provide information to Greasemonkey. To use this feature, enclose your comments between // ==UserScript== and // ==/UserScript comments.
The metadata section can contain any of the following directives. All of these are optional, but using them will make your user script easier to install and use.
@name A short name for the script, displayed in Greasemonkey's list of scripts after installation. @namespace An optional URL for the script author's site. This is used as a namespace for the script: Two scripts can have the same name as long as the namespace is different. @description A one-line description of the script's purpose. @include The URL of a site on which the script should be used. You can specify any number of URLs, each in its own @include line. You can also use the wildcard * to run the script on all sites, or a partial URL with a wildcard to run it on a group of sites. @exclude The URL of a site on which the script should not be used. You can specify a wildcard for @include and then exclude one or more sites that the script is incompatible with. The @exclude directive can also use wildcards.
Listing 18.2 shows the color-changing example with a complete set of metadata comments added at the top.
Listing 18.2. The Color-Changing Script with Metadata Comments
// ==UserScript==
// @name WhiteOnBlack
// @namespace http://www.jsworkshop.com/
// @description Display paragraphs in white text on black
// @include *
// ==/UserScript==
//
// Change the color of each paragraph
var zParagraphs = document.getElementsByTagName("p");
for (var i=0; i<zParagraphs.length; i++) {
zParagraphs[i].style.backgroundColor="#000000";
zParagraphs[i].style.color="#FFFFFF";
}
|
Testing Your Script
Now that you've added the metadata, installing your script is simple. Follow these steps to install the script in Firefox:
1. | Save the script file as colors.user.js. The filename must end in .user.js to be recognized as a Greasemonkey script.
| 2. | In Firefox, choose File, Open from the menu.
| 3. | Select your script from the Open File dialog.
| | | 4. | After the script is displayed in the browser, select Tools, Install This User Script.
| 5. | An alert will display to inform you that the installation was successful. The new user script is now running on all sites.
|
If you're using Turnabout under Internet Explorer, click on the Turnabout toolbar and select Options, and then click the Install Feature button. Select the script and click Open to install it.
Both Greasemonkey and Turnabout for IE will use the metadata you specified to set the script's included pages, description, and other options when you install it.
After you've installed and enabled the script, any page you load will have its paragraphs displayed in white text on a black background. For example, Figure 18.4 shows the user script's effect on the Date and Time example from Hour 2, "Creating Simple Scripts." Because the date and time are within <p> tags, they are displayed in white on black.
By the Way
You probably don't want to make a change this drastic to all sites you visit. Instead, you can use @include to make this script affect only one or two sites whose colors you find hard to read. Don't forget that you can also change the colors in the script to your own preference.
Greasemonkey API Functions
You can use all of the DOM methods covered in this book to work with pages in user scripts, along with JavaScript's built-in functions. In addition to these, Greasemonkey defines an API (Application Programmer's Interface) with a few functions that can be used exclusively in user scripts:
GM_log(message, level) Inserts a message into the JavaScript console. The level parameter indicates the severity of the message: 0 for information, 1 for a warning, and 2 for an error. GM_setValue(variable, value) Sets a variable stored by Greasemonkey. These variables are stored on the local machine. They are specific to the script that set them, and can be used in the future by the same script. (These are similar to cookies, but are not sent to a server.) GM_getValue(variable) Retrieves a value previously set with GM_setValue. GM_registerMenuCommand(command, function) Adds a command to the browser menu. These commands appear under Tools, User Script Commands. The command parameter is the name listed in the menu, and function is a function in your script that the menu selection will activate. GM_xmlhttpRequest(details) Requests a file from a remote server, similar to the AJAX features described in Hour 17, "AJAX: Remote Scripting." The details parameter is an object that can contain a number of properties to control the request. See the Greasemonkey documentation for all of the properties you can specify.
Turnabout for Internet Explorer also supports all of these API functions, so aside from the usual browser differences, scripts that use these functions should work in both browsers. Because Internet Explorer does not have a JavaScript console, Turnabout includes its own console, available from the menu, where log messages are displayed.
Creating a Site-Specific Script
You might want to use a user script to fix a problem or add a feature to a specific site. In addition to using @include to specify the site's URL, you'll need to know something about the site's DOM.
You can use the DOM Inspector in Firefox (or the similar feature in Internet Explorer's developer toolbar) to browse the DOM for the site and find the objects you want to work with. Depending on how they are marked up, you can access them through the DOM:
If an element has an id attribute, you can simply use document.getElementById() in your script to find its object. If a nearby element has an id defined, you can use DOM methods to find itfor example, if the parent element has an id, you can use a method such as firstChild() to find the object you need. If all else fails, you can use document.getElementsByTagName() to find all objects of a certain typefor example, all paragraphs. If you need to refer to a specific one, you can use a loop and check each one for a certain attribute.
By the Way
See Hour 16, "Debugging JavaScript Applications," for information about Firefox's DOM Inspector and IE's developer toolbar. See Hours 13, "Using the W3C DOM" and 14, "Using Advanced DOM Features," for information about DOM methods.
As an example, Listing 18.3 shows a simple user script you could use as a site-specific script to automatically fill out certain fields in forms.
Listing 18.3. A User Script to Fill Out Form Fields Automatically
// ==UserScript==
// @name AutoForm
// @namespace http://www.jsworkshop.com/
// @description Fills in forms automatically
// @include *
// ==/UserScript==
// this function fills out form fields
//
var zTextFields = document.getElementsByTagName("input");
for (var i=0; i<zTextFields.length; i++) {
thefield=zTextFields[i].name;
if (!thefield) thefield=zTextFields[i].id;
// Set up your auto-fill values here
if (thefield == "yourname") zTextFields[i].value="Your Name Here";
if (thefield == "phone") zTextFields[i].value="(xxx) xxx-xxxx";
alert("field:" + thefield + " value: " + zTextFields[i].value);
}
|
This script uses getElementsByTagName() to find all of the <input> elements in a document, including text fields. It uses a for loop to examine each one. If it finds a field with the name or id value "yourname" or "phone", it inserts the appropriate value.
To test this script, save it as autoform.user.js and install the user script as described earlier in this hour. To test it, load Listing 11.1 from Hour 11, "Getting Data with Forms," into the browserit happens to have both of the field names the script looks for. The yourname and phone fields will be automatically filled out, as shown in Figure 18.5.
To make it easy to test, Listing 18.3 doesn't include specific sites in the @include line. To make a true site-specific script, you would need to find out the field names for a particular site, add if statements to the script to fill them out, and use @include to make sure the script only runs on the site.
Debugging User Scripts
Debugging a user script is much like debugging a regular JavaScript programerrors are displayed in the JavaScript Console in Firefox or in an error message in Internet Explorer. Here are a few debugging tips:
As with regular scripts, you can also use the alert() method to display information about what's going on in your script. The browser may display a line number with an error message, but when you're working with user scripts, these line numbers are meaninglessthey refer neither to lines in your user script nor to the page you're currently viewing. Use the GM_log() method described earlier in this hour to log information about your script, such as the contents of variables, to the JavaScript console. If you're trying to write a cross-browser user script, watch for methods that are browser specific. See Hour 15, "Unobtrusive Scripting," for information about cross-browser issues. Watch for conflicts with any existing scripts on the page. If you're using multiple user scripts, be sure they don't conflict. Use unique variable and function names in your scripts.
Most of the issues with user scripts are the same as for regular JavaScript. See Hour 16 for information on debugging tools, techniques, and common mistakes.
|
Now that you've learned the basics of Greasemonkey, you can try a more complexand more usefulexample of a user script.
If you spend much time on the Web, you'll find yourself needing to fill out web forms often, and you probably type certain thingssuch as your name or URLinto forms over and over. The user script you create here will let you define macros for use in any text area. When you type a macro keyword (a period followed by a code) and then type another character, the macro keyword will be instantly replaced by the text you've defined. For example, you can define a macro so that every time you type .cu, it will expand into the text "See you later.".
Watch Out!
This script has been tested on Greasemonkey 0.6.4 for Firefox and Turnabout Advanced 0.31 b3 for Internet Explorer. Because browsers and extensions are always changing, it might stop working at some pointsee this book's website for the latest updates.
Listing 18.4 shows the text area macro user script.
Listing 18.4. The Text Area Macro User Script
// ==UserScript==
// @name TextMacro
// @namespace http://www.jsworkshop.com/
// @description expands macros in text areas as you type
// @include *
// ==/UserScript==
// this function handles the macro replacements
function textmacro(e) {
// define your macros here
zmacros = [
[".mm", "Michael Moncur"],
[".js", "JavaScript"],
[".cu", "See you later."]
];
if (!e) var e = window.event;
// which textarea are we in?
thisarea= (e.target) ? e.target : e.srcElement;
// replace text
for (i=0; i<zmacros.length; i++) {
vv = thisarea.value;
vv = vv.replace(zmacros[i][0],zmacros[i][1]);
thisarea.value=vv;
}
}
// install the event handlers
var zTextAreas = document.getElementsByTagName("textarea");
for (var i=0; i<zTextAreas.length; i++) {
if (zTextAreas[i].addEventListener)
zTextAreas[i].addEventListener("keydown",textmacro,0);
else if (zTextAreas[i].attachEvent)
zTextAreas[i].attachEvent("onkeydown",textmacro);
}
|
This user script begins with the usual comment metadata. The @include command specifies a wildcard, *, so the script will work on all sites. The actual work is done in the textmacro() function. This function begins by defining the macros that will be available:
zmacros = [
[".mm", "Michael Moncur"],
[".js", "JavaScript"],
[".cu", "See you later."]
];
This example defines three macros using a two-dimensional array. To make the script useful to you, define your own. You can have any number of macrosjust add a comma after the last macro line and add your items before the closing bracket.
Next, the function uses the target property to find the text area in which you're currently typing. Next, it uses a for loop to do a search and replace within the text area's value property for each of your macros.
The section of code after the textmacro() function sets up an event handler for each text area. First, it uses getElementsByTagName() to find all of the text areas, and then it uses a for loop to add an onkeydown event handler to each one.
By the Way
To avoid conflicts with existing event handlers within web pages, this example uses the addEventListener() method to add the event handler. This method defines an event handler without overwriting existing events. In Internet Explorer, it uses the similar attachEvent() method. See Hour 15 for more information.
To use this script, first make sure you've installed and enabled Greasemonkey as described earlier this hour. Save the script as textmacro.user.js. You can then install the user script.
After the script is installed, try loading any page with a text area. You should be able to type a macro, such as .mm or .js, followed by another character such as a space, within the text area and see it instantly expand into the correct text.
Did you Know?
This script runs on all sites by default. If you only want the macros to work on certain sites, you can change the @include directive to specify them. If the script causes trouble on some sites, you can exclude them with @exclude.
|
|
Main Menu
|