Paul Irish

Making the www great

How to: Speed Up the MacRumorsLive Ajax Refresh

title_macrumors.gifBy default, MacRumorsLive polls the server for updates only every 60 seconds. I know, I know.. <enter sad puppy face here> If you’re like me, you probably want that action with a touch more zip to it! And thus…

To poke the server every 10 seconds for a new update, drop this badboy into the location bar on your MacRumorsLive tab and hit enter:

1
javascript:(function(){var booyah=10,str='ro[0].firstChild.nodeValue',countdown='document.getElementById("ti").innerHTML  = (rr-x) + " seconds till next update..."; setTimeout';rr=booyah;eval('d = '+d.toString().replace(str,booyah));eval('ppd = '+ppd.toString().replace(str,booyah));eval("l = "+l.toString().replace('setTimeout',countdown));x=5;})();

btw- this doesn’t work in IE. Deal with it.

Update (11:41am): It now has a countdown till next update. countdown.PNG

Bookmarklet: Inject New Css Rules

I love doing as much CSS debugging as I can without hitting reload. (see also: my ‘refresh css’ bookmarklet)

newcssrule.PNGFirebug can get you a far way in playing with styles. You can edit current css rules and add new styles to a given element, but there is no way to add a brand new rule to the page. UNTIL NOW!!!

Drag this bad boy to your bookmark bar:

Update (2009.02.06):

This will work in all browsers (ie6+,ff,saf,chrome). [Source here]

>>> newcssrule <<<

The code is obviously trivial, but it’s a helpful button to have around sometimes. Plus you can then edit those rules in firebug immediately.

For full compatibility, understand the landscape at InstallStyles on Google Doctype.

Best Practice: Poll Instead of a setTimeout Hack

Very often you’ll have events happening asynchronously, but you need to wait until one has completed before you fire the second. And you may not have the ability of attaching a callback function to the first.

In my less wise days I’d say “Lets just setTimeout it for a couple seconds…” but always felt really dirty about it.

A classier approach I’ve used lately is to poll for a change. Here I’m using the gmail greasemonkey API and waiting for it to load in before I start using it:

1
2
3
4
5
6
7
8
9
10
11
12
13
gmonkey.load("1.0");

// this is a self-executing anonymous function that uses setTimeout to call itself 
// at 50ms intervals until the isLoaded variable resolves as true.

(function(){
  if (gmonkey.isLoaded){
    // do stuff i want to do with the API
    gmonkey.get('1.0').addNavModule('notepad', '<iframe src="http://aaronboodman.com/halfnote/"></iframe>');
  } else {
    setTimeout(arguments.callee,50);
  }
})();

I found myself doing this a lot when loading in multiple external resources and playing with them.. So to generalize the code I wrote executeWhenLoaded():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// executeWhenLoaded() will be overloaded with as many arguments as i want to check for presence.
function executeWhenLoaded(func){

  for (var i = 1; i<arguments.length; i++){ // for loop starts at 1 to skip the function argument.
    if (! window[ arguments[i] ]) {
      setTimeout(arguments.callee,50);
      return;
    }
  }

  func(); // only reaches here when for loop is satisfied.
}

// and in use:

executeWhenLoaded(function(){
    console.log(session.data);
},'session');   // session will return a value when the whatever preceding functionality is done. 

executeWhenLoaded’s first argument is the function to call, it can an unlimited number of arguments, which are all strings that reflect objects in the global namespace that have to be present in order to execute that function.

Update: In the comments, ProggerPete notes that this is not cross-browser compatible.. yet! In IE6, at least, the browser loses the original reference to the arguments object when it cycles through on the arguments.callee call. He offers a fix below.