How to load jQuery UI CSS In Greasemonkey

// ==UserScript==
// @name           Test
// @namespace
// @description    jquery-ui-1.6rc6 Resource Include Test
// @include        *
// @resource       jQuery     
// @resource       jQueryUI   
// @resource       jQueryUICSS
// @resource    ui-bg_diagonals-thick_18_b81900_40x40.png
// @resource    ui-bg_glass_100_f6f6f6_1x400.png      
// @resource    ui-bg_diagonals-thick_20_666666_40x40.png
// @resource    ui-bg_glass_65_ffffff_1x400.png       
// @resource    ui-bg_gloss-wave_35_f6a828_500x100.png
// @resource    ui-icons_222222_256x240.png           
// @resource    ui-bg_flat_10_000000_40x100.png       
// @resource    ui-icons_ef8c08_256x240.png           
// @resource    ui-icons_ffd27a_256x240.png           
// @resource    ui-bg_glass_100_fdf5ce_1x400.png      
// @resource    ui-icons_228ef1_256x240.png           
// @resource    ui-icons_ffffff_256x240.png           
// @resource    ui-bg_highlight-soft_75_ffe45c_1x100.png
// @resource    ui-bg_highlight-soft_100_eeeeee_1x100.png
// ==/UserScript==

// Inject jQuery into page... gross hack... for now...
(function() {
  var head = document.getElementsByTagName('head')[0];

  var script = document.createElement('script');
  script.type = 'text/javascript';

  var jQuery = GM_getResourceText('jQuery');
  var jQueryUI = GM_getResourceText('jQueryUI');

  script.innerHTML = jQuery + jQueryUI;

  $ = unsafeWindow.$;

// Load UI Styles
(function() {
    var resources = {
      'ui-bg_diagonals-thick_18_b81900_40x40.png': GM_getResourceURL('ui-bg_diagonals-thick_18_b81900_40x40.png'),
      'ui-bg_glass_100_f6f6f6_1x400.png': GM_getResourceURL('ui-bg_glass_100_f6f6f6_1x400.png'),
      'ui-bg_diagonals-thick_20_666666_40x40.png': GM_getResourceURL('ui-bg_diagonals-thick_20_666666_40x40.png'),
      'ui-bg_glass_65_ffffff_1x400.png': GM_getResourceURL('ui-bg_glass_65_ffffff_1x400.png'),
      'ui-bg_gloss-wave_35_f6a828_500x100.png': GM_getResourceURL('ui-bg_gloss-wave_35_f6a828_500x100.png'),
      'ui-icons_222222_256x240.png': GM_getResourceURL('ui-icons_222222_256x240.png'),
      'ui-bg_flat_10_000000_40x100.png': GM_getResourceURL('ui-bg_flat_10_000000_40x100.png'),
      'ui-icons_ef8c08_256x240.png': GM_getResourceURL('ui-icons_ef8c08_256x240.png'),
      'ui-icons_ffd27a_256x240.png': GM_getResourceURL('ui-icons_ffd27a_256x240.png'),
      'ui-bg_glass_100_fdf5ce_1x400.png': GM_getResourceURL('ui-bg_glass_100_fdf5ce_1x400.png'),
      'ui-icons_228ef1_256x240.png': GM_getResourceURL('ui-icons_228ef1_256x240.png'),
      'ui-icons_ffffff_256x240.png': GM_getResourceURL('ui-icons_ffffff_256x240.png'),
      'ui-bg_highlight-soft_75_ffe45c_1x100.png': GM_getResourceURL('ui-bg_highlight-soft_75_ffe45c_1x100.png'),
      'ui-bg_highlight-soft_100_eeeeee_1x100.png': GM_getResourceURL('ui-bg_highlight-soft_100_eeeeee_1x100.png')

    var head = document.getElementsByTagName('head')[0];

    var style = document.createElement('style');
    style.type = 'text/css';

    var css = GM_getResourceText ('jQueryUICSS');
    $.each(resources, function(resourceName, resourceUrl) {
      console.log(resourceName + ': ' + resourceUrl);
      css = css.replace( 'images/' + resourceName, resourceUrl);

    style.innerHTML = css;

This technique works whether or not you inject or @require the jQuery js libraries.

The drawback to injecting jQuery is that it is forced to run in the unsafe window context which doesn’t allow you to use GM_* methods in callbacks (this make $.each pretty weak). Also, it breaks pages that define the $ function, but I believe this can be avoided by telling jQuery not to interfere and you can set $ as the local alias within your GM script zone (if that makes any sense).

The drawback of using require is that the UI classes throw exceptions (at least on version 1.6rc6). The dialogs display ok, but you need to catch the exceptions they throw. Also, they throw an exception when you try and drag. I’m pretty sure that it has to do with XPCNativeWrapper. One day UI will be easy in Greasemonkey… one day… Until then this should get you part way there.

The @resource technique works for more than just jQueryUI, use it for your own css and images, at least until jQuery UI gets fixed.

I can't stop thinking about these little yellow boxes…

I just created an Annotations spin-off of GreasyThug. This doesn’t have an interactive console, or use Gears. It does let you add comments to any web page in any location, for all the world (who have installed the script) to see.

Take a look at this page after installing it, and leave some annotations of your own.

GreasyThug – Greasemonkey, Gears and jQuery

I’ve been called a greasy thug, too. It never stops hurting. So here’s what we’re gonna do: We’re gonna grease ourselves up real good and trash that place with a baseball bat. – Homer

Presenting: GreasyThug

Here’s my problem, I want to develop Greasemonkey scripts. This doesn’t sound like a problem, but JavaScript has a certain terribleness to it, at least in its current browser implementations, and I can never go back to raw JS, NEVER. I’ve also grown accustom to having an interactive console for development and debugging, but Firebug doesn’t have access to Greasemonkey code. And another thing, shouldn’t I be able to make changes to a page, on the fly, and have them persist, without having to dig out my scripts and modify them? Shouldn’t every website be using Gears by now? Wouldn’t it be great to be able to use jQuery in your browser console on every website you go to?

Fact: GreasyThug will make all of your wildest dreams come true.

GreasyThug – Interactive JavaScript Console Features

  • Built in jQuery functionality.
  • Google Gears included.
  • A persistent command history across page reloads and browser restarts.
  • Drag and drop – remembers where you put it for each site.
  • Ability to persist micro-scripts and apply them automatically everytime you visit the page.

Warning! GreasyThug is slick (it’s the grease) and dangerous (it’s a thug). An interactive console is essentially a pipe straight into eval(). So… BE CAREFUL! If your thug becomes compromised it will be your house that gets trashed with a baseball bat. Remember, this is eval in the elevated Greasemonkey privilages context, its strength for development is also its weakness for security.



Let’s spruce up the google search page. Maybe we should make a whole Greasemonkey user script? Nah, that’s a huge hassle now that we already have GreasyThug.

  1. Go to
  2. A “The website below wants to store information on your computer using Gears” security warning will pop up, as it will do for everydomain that you have GreasyThug enabled for. It’s not really the website using Gears, though some might eventually. Click “Allow”. (This is how the command history and micro-scripts are saved).
  3. Now let’s get cracking! Drag the interactive console to a comfortable location. (It will begin in the top left by default)greasy_thug-1
  4. Execute some JavaScript statements to get a feel for it. No need for semicolons, we’re not chumps.
  5. Now on to the cool stuff: that white background is a little bland for Valentine’s Day, let’s spice it up. Pop this into your console:
    $('body').css('background-color', '#F8A')

    greasy_thug-03 It’s beautiful! See how I can use jQuery? Neat! Also, the up arrow populates the input with my previous command.

  6. Maybe it’s not quite as good looking as I thought, probably best to stick with white… let’s just refresh and forget about this debacle. greasy_thug-04 Back to normal… but the history remembered my command in case I want to try it again.
  7. It is my strong belief that there should be a link to STRd6 right next to everyone’s email address on the Google search page. Obviously this should only be for logged in users… I can only change it for myself though…
    $('#gb nobr').prepend($('STRd6'))
  8. But what about when I refresh… it’ll disappear and all that hard work will be gone?!? Not so good friend:

    This will store whatever command you last executed to be executed again when you return. You can save many commands. These are those micro-scripts that you’ve been hearing so much about and they are the future.greasy_thug-06

So is this the end? It is for today. Now imagine sharing micro-scripts with your friends. It’s our internet now. It just takes some elbow grease and a little thuggery.

Feature requests go in the comments.

Microsoft Loves Firefox

Today at work Sharepoint was blocking access to Internet Explorer. Something like about:protectedmodeoff. I could look into it, do some searches and figure it out. But it was just quicker to tell anyone affected to download Firefox Portable, which worked.

Another interesting feature: when connecting to the Exchange server in IE it automatically logs in to your email. Which is great until you want to log in to access a different in-box, because you can never log out… EVER! Oops, Firefox time again.

Mathematical Image Example for Ruby Quiz #191

This image was generated as an example for Ruby Quiz
This image was generated as an example for Ruby Quiz

This weeks quiz is about generating images from mathematical functions. Here is an example to see what I’m talking about.

depth: 3
red: Math.sin(Math::PI * Math.cos(Math::PI * y * x))
green: Math.sin(Math::PI * (Math.sin(Math::PI * y)) ** 3)
blue: (Math.cos(Math::PI * Math.cos(Math::PI * y))) ** 3

See the full quiz here:

Looking Towards Performance With YSlow

Recently during one of my trips down the internet rabbit hole I came across YSlow. This sweet little extension to Firebug blew me away. Firebug is already extremely excellent, I would say that it makes web development possible, but YSlow brings it all the way to your server and makes server optimization possible.

We all know that we should be worried about performance. That’s what everyone keeps telling us (but… will it scale?!?). And we’ve heard of all kinds of techniques that sound pretty cool which we should probably look into one day. And we always keep putting off performance optimization, after all it would be premature. Would my user even notice? But, thanks to YSlow I was able to easily identify at least a half a dozen things that I could do within minutes to improve my performance. All in all it took a couple of hours, mostly spent searching for how to enable the features in Rails an nginx that improve performance.

I won’t keep you waiting any longer, here’s how I turned my performance grade from a 48 to an 80:

1. Enable gzip compression

I’m using nginx, I know almost nothing about it (it’s Russian!), but because it is a well designed piece of software it was incredibly simple to accomplish a simple task. First: search google for nginx + gzip. Second: crack open your trusty ol’ nginx.conf. Third:

    gzip            on;
    gzip_comp_level 3;
    gzip_proxied    any;
    gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

Restart nginx and witness the savings.

2. Make Fewer HTTP Requests

I was serving something like 6 js files and 7 CSS files. Keeping them seperate sure makes it easy to navigate during development, but can really multiply your HTTP request count. Thanks to Rails this one is an easy fix too:


    = javascript_include_tag 'prototype', 'effects', 'dragdrop', 'application', :juggernaut
    = stylesheet_link_tag :all

    = stylesheet_link_tag :all, :cache => true
    = javascript_include_tag 'prototype', 'effects', 'dragdrop', :juggernaut, :cache => 'base'
    = javascript_include_tag 'application'

Rails has caching enabled by default when running in production mode, but in order to take advantage of it you either need to read the docs or google that shit need to tell it what to cache. This gathers your multitude of files into one or two little happy files. They get even little-er when gzipped, though I am unsure what that does to their happiness. I also took this time to put my CSS above my JS. If possible the JS should be loaded nearer the bottom of the page (tell me more…). I’ll count that as a third and fourth thing I did to improve performance.

5. Add an Expires Header

If you’re like me you’re probably thinking: “What would Stevey do? Should I really become a wino? … and btw wtf is an expires header?” Step one. Step two:

        if ($request_uri ~* ".(ico|css|js|gif|jpe?g|png)?[0-9]+$") {
            expires max;

Blast that into your nginx.conf. I’m not going to explain it. If you are still confused see step 1.

Well as you can see it was not quite half a dozen things, even with my creative counting. I hope this will help you get started on your road to glorious optimization using YSlow to tweak your Rails and nginx configurations. It’s tired in here… *honk-shu*

UK Lottery Victory!! … IP Defeat :*(

Account Account,
  You have been confirm a lucky winner of the Uk Lottery, Do
contact our fuduciary agent with your personal details for
further proceeding

Smith Stanford


Dear Fuduciary Agent,
  This friscal windfall will be a joyous bounty for my
proud nation. I am a quiet and frugal people. I will
invest half of the money in gold and the other half in
gold-insurance. I pray you can refer me to an aurum
insurance specialist.

Following are my personal details:
    Dr. Krumpenstein's Monster M.D.
    1048576 Manufacturing Way
    City of Industry, CA 90502

Giuseppe Mississippi
250 W Houston St,
San Antonio, TX

Date: 2008-09-29
Sir or Madam
1048576 Manufacturing Way
City of Industry, CA 90502
Re: File #032154709 - Infringement Case #10024652519701 -
Dear Discreditor:
  Our Client, Dr. Krumpenstein's Monster, heretofore referred to as
Client, or DK'sM; DEMANDS that you immediately CEASE the use and
distribution of all infringing works derived from DK'sM, and all
copies of him, and that you deliver to me all unused, undistributed
copies of him, or DESTROY such copies IMMEDIATELY, and that you
desist from him or any other infringement of DK'sM (CLIENT's)
personage in the future.
 This will serve as your legal notice under provisions of
federal law, the Fair Practices Act (FPA), to CEASE
all communication. If you fail to heed this notice, I will file
a formal COMPLAINT against you with the Federal Krumping
Commission who is RESPONSIBLE for enforcement, the States
Attorney General office and/or the American Krumpists Association
or local State BAR Association.
 You are also notified that should any ADVERSE information be
placed against ME/(CLIENT/DK'sM) as a result of this notice that
appropriate actions will be taken. Give this very important
matter the ATTENTION it deserves.
Giuseppe Mississippi

Google Notebook has been rocking my world

As I’ve been scouring the internet for data I often find that I’m searching for the same things over and over. Google Notebook let’s me keep track of anything that I think is useful. Just install the browser plug-in and information storage is just a select and right click away.

I started using Google Notebook a couple years ago,  but then gave it up. Now that I spend more time seeking information throughout the web-o-sphere it is just about a must have. I might even start coordinating my shopping list on it again!

Here’s my published programming notebook, if your interests are in Ruby or Rails then there is probably something of use to you in there.