Introduction




Greasemonkey is aimed at simple javascript. However, quite a few javascript libraries are now very complicated. If you need to use external functionality, it can be difficult. Follow these instructions.




Self Contained Scripts - Quick 'n' Dirty




Some libraries, like the excellent DOM manipulators jQuery and cssQuery are self contained. If you need to use just a simple script see the example contained in Rich Manalang's blog post. Richard's post mentions Prototype. To modify his example to fit your need, you should :





  • change the proto.src = 'http://prototype.conio.net/dist/prototype-1.3.1.js'; to wherever you're getting the source code from.

  • inspect the source code of the library you want to include

  • look for the root level javascript object

    • most packages have a root level object

    • check the usual suspects like **Application.js, **Main.js, or **Start.js

  • change Richard's waitForProto() function to wait for that root level object
    • in Richard's example he is waiting for the root level object Prototype (if (typeof p.Prototype=='undefined'))

Scripts With Many Files

If you would like to use scripts with many files, the self contained approach does not work. This is due to a few things

Problems:

  • Scripts think their location is that of the window.
    • If you are requesting a page to alter, say http://news.bbc.co.uk/
    • you are trying to load a script from Dojo, say http://dojotoolkit.org/dojo/dojo.js
    • if dojo.js tries to download further libraries say dojo.require("dojo.widget.LinkPane"); , then it will try to request them from http://news.bbc.co.uk/widget/LinkPane.js
  • Uncertainty of which libaries to load
  • Images and Other Binary Objects
    • To include an image on a page, you need to make a data: url
      • See gmail-saved-searches.user.js
      • e.g.
        const UP_TRIANGLE_IMAGE = "data:image/gif;base64,R0lGODlhCwALAKEAAP///wAAAA4" +
        "ODv///yH5BAEAAAMALAAAAAALAAsAAAITnI+pGmsBF5xp2mPzmCJHB4ZJAQA7";
    • Although there are conversion tools [example], this is a pain for a lot of files.
  • Speed
    • A lot more http requests
  • Security
    • You're trusting a lot more remote content :(
Solution
.
Summary:
  • Preparation
    • Hack Greasemonkey,
    • Place Libraries in Greasemonkey's Extension,
    • Change Libraries to use chrome:// Internally,
    • Allow a lot longer for the Hacked Greasemonkey extension to install
  • When In a User Script
    • Include Libraries and Resources from chrome://
    • Reference external libary entities using unsafeWindow .
    • Invoke any black magic initialization code that your handler has overriden
.
Hack Greasemonkey
.
See my previous post about how to download the source code for greasemonkey. It is not currently (2006-07-21) easy. The greasemonkey team may make the guest access a little less opaque at some stage. I have a sneaking suspicion that I could simply have downloaded the XPI to the desktop, expanded it and used that as the source reference... oh well, I'm used to the cvs method, and that is what it recommended on the greasemonkey page.
.
I have an enhanced build.sh that you can use in bash [avail on windows too]:
.
perl#!/bin/sh echo Starting `date` mv build build_ nice -n 19 rm -rf build_ & mv greasemonkey.xpi greasemonkey.xpi_old rm greasemonkey.xpi_old& mkdir build cp chrome.manifest build/ cp install.js build/ cp install.rdf build/ cp license.txt build/ cp -r components build/ cp -r chrome build/ cd build find * | grep -v '.svn' | grep -v 'CVS' | grep -v .DS_Store | zip -q greasemonkey.xpi -@ mv greasemonkey.xpi ../ cd .. echo Finishing `date`
  1. rm -rf build&
find build | grep '.svn$' | xargs rm -rf &/perl
.
Place Libraries in Greasemonkey's Extension — Download your library any expand it on disk
.
From here on in i'm going to concentrate on a concrete example I used to get all this working. I used the qooxdoo gui library. This turned out to be a very comprehensive library with a very flexible architecture. This was a good thing because the whole process was fucking difficult anyway and I would have given up if it had been even one tad more difficult.
.
I downloaded the source code and expanded it. This gives me a folder qooxdoo-0.5.3-unix. Copy this to your chrome/chromeFiles/content/ directory of the greasemonkey extension.
.
That' pretty much all there is too it for this step. This works because chrome/chromeFiles/content/ is already specified in the manifest file chrome.manifest
Change Libraries to use chrome:// Internally - This can be VERY difficult
Firefox has a method of referencing its internal elements called chrome. Using this chrome:// you can construct URLs for your javascripts so that they behave like they do normally.
As an example type this url into your Firefox: chrome://greasemonkey/content/status_off.gif . You should see this image if you have greasemonkey: Greasemonkey Chrome Status Image. [Maybe I should have made that a brighter example]. I took the time to check that you can receive a remote page which can include local chrome. Dunno if this is much of a potential security hole or not, but is is possible.
.
How easy it is to change a javascript library to use chrome:// varies from library to library.You will have to hunt down just how the library references unloaded objects.
.
Generally this is done by trying building a hacked Greasemonkey XPI with debugging in the external library to display progress alert("I got here! - 0038"); messages.
.
You'll need to sprinke these around.
.
Create a very simple greasemonkey user.js and run it on a simple web page which you have authored. This will invoke your hacked code, and you can change both.
.
An example of the user.js is provided below, as is a simple web page. I will detail my experience with qooxdoo.