Friday, 25 July 2008

Facebook JavaScript is annoying but cool.

I consider myself a competent programmer; I'm a bit of a 'jack of all trades' and as the adage goes, possibly a master of none. The advantage, I feel, of my approach, is that I can dip in and out of stuff really easily most of the time. So I'm not usually afraid to try new technologies, languages etc. My current fetish in this respect is the Facebook platform.

I recently started development of a Facebook application which is basically a reimplementation of the classic MUDs (Multi User Dungeons). These were text-only adventure games based, I suppose, on the classic Dungeons and Dragons books, with computer-simulated rolling die to generate the characteristics of the players and their antagonists, and to affect their effectiveness in conflicts. These simple games, which by their nature were laden with a great deal of descriptive prose, eventually developed into what was clumsily acronymed (sic) MMORPG - or Massively Multiplayer Online Role Playing Games, and became 3D wonders like Acheron's Call, (the first MMORPG I played), and the now ubiquitous World of Warcraft. My game is a very poor cousin to those, but should turn out to be a multiplayer online roleplaying game, although I suspect not 'massively multiplayer', which I guess must mean 1000s or tens of 1000s of players online concurrently.

I very briefly blogged my frustration with my excursion into the Facebook platform a week or so ago. However, I'm over the hump now and I'm starting to see, if not the advantages, then at least the cleverness of what Facebook have done with their code.

Any web app you use which is highly interactive has to run a lot of code on your machine, rather than on the server, in order to respond quickly to user input. Unless you're using a plugin like Flash or Java, this is very likely to be executed in Javascript. Javascript is a great language in my opinion, and while I struggled with the different implementations in IE 3 and Mozilla all those years ago, I also came to love the language for the ways I could work round those differences.

I came to Facebook development, then, with an idea that my previous Javascript skills would be fundamental to my discovery of the FB development platform. Fundamentally, that assumption was true, but as usual the Devil is in the Details, and in this case, the detail was that Facebook were fucking with my code.

It's understandable; Javascript code can be dangerous; you can redirect users to pages that look like, say, their bank, or some other valuable site like PayPal, or you can show them important-looking popup boxes telling them to perform some action or other on their computer which might render them vulnerable. Facebook are proud that they have made a platform where you can run code as a first-class citizen, and thereby have access to their own code libraries, (or of them to yours, I'm not quite sure yet) and not, as other sites might apparently have you do, run your code in a "sandbox" environment, where it cannot interact with the code in the main body of the web page, and therefore not trick users.

Now to come to the clever bit. Let's assume that the alert() function is dangerous. All it does is display a message to the user, but let's assume that a gullible user will act as a result of this dialog box, perhaps telephoning a criminal masquerading as their bank, or something similar. It appears that facebook consider alert() dangerous, as they don't let you use it. The way they do this is the interesting bit.

Consider a bit of code:

var i = "1234";
alert(i);
setTimeout("doSomething(i)", 1000);

With facebook you get an application key, which is a string of letters and numbers. Let's say for now that key is "a007". The code above will be translated, before interpretation, into the following:

var a007_i = "1234";
a007_alert(a007_i);
a007_setTimeout("doSomething(a007_i)", 1000);

If you read that closely, you'll see that if Facebook, who modify this code before it hits their Javascript engine, decide to implement a007_setTimeout() as an alias to the setTimeout() function you'll be able to use the setTimeout() function, but if they don't implement a007_alert(), you, as a user submitting Javascript to Facebook for execution, will not be able to use thealert() function.

And that, from my analysis, appears to be exactly what Facebook do. For functions that they want to allow you to run, they implement aliases from, say, aFunction() to a007_aFunction(). For functions they don't want you to run, they don't implement those aliases. Of course, they first translate your code so that all variables and function calls are prefixed by "a007_"

Damned clever.

No comments: