Learn to Code By Cheating

My kids love Cookie Clicker. And, only because they can’t stop talking about it, I checked it out. My 14 year-old told me he’s figured out how to cheat at the game so bad that he basically ends up with “infinity cookies”.

Wait, let’s step back. The game is weird and silly and involves clicking a big cookie to get more cookies. You can buy upgrades like cursors that click cookies for you, grandmas who bake cookies for you, all the way up to time machines that go back in time and bring you cookies that before they’ve been eaten – and you purchase all of these with cookies that you, wait for it, click.

Back to the cheating. The game is all done in Javascript and all done in the browser, so it’s really fun to mess around with things and cheat – and learn some Javascript fundamentals while you’re at it (and even some jQuery). There’s even a page on the Cookie Clicker Wiki dedicated to cheating. You’ll notice that all of those cheats are Javascript functions. Here’s one I wrote that is a little longer than the one on the wiki, but makes me happy because it’s all object-notated and is called cookie_monster:

<code>var cookie_monster = {
  gimme:function() { 
    Game.ClickCookie(); 
    setTimeout("cookie_monster.gimme()", 1); 
  }
};
cookie_monster.gimme();</code>

That’s all broken out so you can see what it’s doing. Here it is if you want to just cut and paste it into the Javascript Console in Chrome (the browser made for cheating):

<code>var cookie_monster = {gimme:function() { Game.ClickCookie(); setTimeout("cookie_monster.gimme()", 1); }}; cookie_monster.gimme()</code>

Basically, the cookie\_monster.gimme() method clicks the cookie and then sets a timer to run itself again in 1 millisecond. That ends up being a lot of cookies per second. It also unlocks a bunch of achievements, which is cool (but still cheating).

And here it is as a bookmarklet: Cookie Monster. Just drag that to your bookmarks bar, and click on it while you’re in Cookie Clicker and the cheat will magically start running. I love Javascript.

I’ve been talking to both of my kids now about Javascript and how we can more efficiently cheat at the game, which I think is awesome. If I can get them to think of programming as a game, then I’ve already won.

Web AIM and the Amazing Mr. Chipman

The Amazing Mr. Chipman has been hard at work on this for the past couple months, and I’ve had a lot of fun walking past his desk and looking over his shoulder at the sheer awesomeness of it. What is it? It’s AIM on the Web! Web AIM allows you to drop visitors’ buddy lists in your site and use it and messaging in all sort of neat mashed up sort of ways. I’m sure we haven’t thought of all of them yet, but I foresee some very interesting applications in the next couple months. Once I get some sleep, look for some fun with it on this site as well.\
Check it out, let me know what you think, and bow down before the sheer awesomeness of Mr. Chipman!

The Evils of document.write

As a developer who works on a site where users can paste in all manner of crappy code from all corners of the web, I’m here to beg. Please, for the love of all that is holy, it’s time to stop using document.write. Yes, I know that it’s being used in the header and footer on AIM Pages, but we own that page (and we’re not going to be doing it for long). Your code has to live all over the web, if say, you’re the Flickr badge. There are so many other, better, ways to do the same thing, there’s no reason to use document.write.\
It’s old and evil, a lot like Dick Cheney. Yes, it will shoot your friend in the face and sneer all the time. You don’t want to code like Dick Cheney, do you?

PayPal Seeks DOM Nerd for Unobtrusive Servitude

I got an e-mail from Steve Ganz asking if anyone knew any javascript wizard who need a job. I met Steve at SXSW and he’s swell (he’s also on the microformats discussion list, which is also a +1 in my book). He’s looking for a javascript expert to help take PayPal out of the 90’s and into today (his words, not mine).\
If you’re interested, go bug him. And none of you guys who work with me better leave, or I’ll hunt you down.

Child Scripts Making Child Scripts!

I’ve been wrestling with a bug in one of my modules for AIM Pages for_ever_, and just found a fix today. I created this well-intentioned module called code snippet that allows you to paste in markup and it’ll get inserted into the DOM. This is really just a stopgap to allow people to add stuff that a module doesn’t exist for yet. I never should have written it. Do you know how bad DOM support is in IE? It’s awful!\
The big problem is that people wanted/needed to insert script elements with inline script using the code snippet module, and I couldn’t figure out a good way to do it (ok, any way, good or otherwise). Just adding them to the DOM using innerHTML doesn’t work. IE won’t allow you to create a new script element and set the text content to the code.\
Today, I stumbled on a message board post that hints at the answer. What’s the answer?\
Create a new script element, and set the text property to the script content and then append it to the body. Voila, actual evaluated javascript! Here’s an example:

<code>var b=document.getElementsByTagName("body")[0];
var txt="function doIt(msg) {alert(msg)}";
var scr=document.createElement("script");
scr.setAttribute("type","text/javascript");
scr.text=txt;
b.appendChild(scr);</code>

Enjoy! Oh, and the fixed version of the module isn’t live yet. I’m letting the QA guys look at it first before I unleash it on an unsuspecting world.

AIM Pages and Safari

I’ve seen this now a couple places, and figured I’d comment on it (not in an official way, but in a “I feel your pain” way). The current falderal is about AIM Pages and Safari and how it doesn’t work yet. We tried, honest we did. But, Safari has certain “issues” with its DOM support (it’s a standard, ya know) and other javascript features. We did our best to work around them and get things working, but when it came down to crunch time, we had to concentrate on the big two (Firefox and IE). We will support Safari. We’re actually very close, just have a few annoying things to work around and it’ll be done. We love Safari. All us Mac users on the team were really sad that we had to drop it for the first release. But, we had to.\
It actually has very little to do with standards compliance. No modern browser is fully DOM 2 compliant. No modern browser is fully CSS 2.1 compliant. They all have quirks. We’ve found more one-line crash-causing javascript commands working on this project than I can count. We’ve found things to hate in all the browsers.\
I used to think that browsers were in a pretty good place, especially Firefox and Safari. I was wrong. They’re all too slow, too quirky and aren’t reliable enough. They all crash too easily, take too much work to do things the “right” way, and in most cases, it’s actually better to do things the wrong way because that’s the way the browsers “like” it. For example, it’s way faster, takes less code and uses less CPU to use innerHTML than creating DOM nodes and appending them. If the right way’s not the right way, it’s the wrong way. Until the browsers actually reward using the standard, there isn’t much point. The rewards for using semantic and valid markup, and good CSS are well known. There aren’t a lot of rewards right now for using the DOM.\
But, where was I? Oh yeah, Safari… we’re working on it.

I Know Something!

Today is a banner day. No, it’s not because the cold I’ve had for four days has reached Biblical mucous proportions (if Pharoah hadn’t relented, it would have been the next plague: multi-colored, never-ending mucous). It’s not that I’ve had three days off in the last thirty. It’s not that I’ve interviewed two kids out of college in the last week who are actually curious and qualified. It’s not that I’ve forgotten how to sleep.\
What is it? It’s that today, April 13th 2006, I knew something about javascript and the DOM that Mr. Javascript didn’t know, and I got to tell him what it was. What was it? Well, it’s this horrible little Internet Explorer quirk where it won’t let you update the text of a style element with the normal ways (you know, appending a text node, or gasp using innerHTML). You have to use node.styleSheet.cssText to get or change the text. Isn’t that crazy?

Stenomonkey

I dread taking minutes at working group meetings because it usually means projecting a text editor which is hard to read for the other people in the meeting, and hard to edit for the minute taker. I’ve used IRC, but I hate that the minutes get polluted by the “back channel” discussion. On the flight over, I thought to myself, “Hey, I could easily make a little web app to do this.” Here it is. Everything is stored in the DOM, and there’s no save back to the server which is an issue. It would be nice to have a backend store for minutes to make sure there’s a backup in case of a browser crash, but I did this between the plane and jet lag. I also haven’t tested it in anything but Firefox and Safari. If it works for you, great. If not, sorry.

Changing Style Elements In IE

Everyone knows what I’m working on, right? Well, this is a little story I’m telling so I don’t have to remember it. I’m working on the generic style API so users can change stuff, and wow… I didn’t think it would be as painful as it was. What caused the pain? Oh, you should know by now that it was caused by Internet Explorer for Windows!! Hooray for the truly strange!\
The other browsers (Safari and Firefox, chiefly) did fine with removing the existing text node in the style element, and replacing it with the new one. I tried using the CSS DOM, but that was a lost cause, so I wrote a simple CSS parser in Javascript (only about 10 lines) to throw all the selectors and properties into objects and then more functions to change, update, delete, etc, properties and update the associated style elements.\
What happened in IE? It blew up as soon as I tried to remove the child text node of style, or even set innerHTML. What did I have to do? I had to crawl the properties of that element’s object and find the styleSheet property, which is an object and has a property of cssText, which I can set.\
So, now my code looks like this (\_style is the style element, output is the text I’m setting and yes, I’m using Dojo):

<code>if ( !isIE ) {
dojo.dom.textContent(_style,output);
} else {
_style.styleSheet.cssText=output;
}</code>

I hope you never have to do this, but if you do, that’s how.