Defaults – a convenience or a time bomb?

Time BombAll programmers at all languages are familiar with the concept of default values.
Many languages allow default parameter values when calling a functions, some provide a function overloading mechanism which is an expansion of this idea.

For example in python you can have named parameters with default values:

def multiply(v, mult=2.0)
  return v * mult
 
multiply(5) # returns 10.0
multiply(5, 3.0) # returns 15.0
multiply(5, mult=3.0) # returns 15.0; it's the same as before, only using a named parameter

The concept of default values is found not only in function but in many other places, such as Java Property files.
Java implements by default a nice properties mechanism which lets you quite easily separate between program logic and its data. Just create a my-properties.properties file, instantiate a Properties object and read properties from the file.

my-properties.properties

me.prettyprint.my_value=nice!

In Java:

Properties props = new Properties();
URL url = ClassLoader.getSystemResource("my-properties.properties");
props.load(url.openStream());
String myValue = props.getValue("me.prettyprint.my_value");

The properties mechanism is quite convenient and useful; However, in my opinion they went a bit too far with regards to convenience by adding yet another Properties.getValue(String key, String defaultValue) method.
Now you can do this:

// If me.prettyprint.my_value doesn't exist, assign "awful" to myValue
String myValue = props.getValue("me.prettyprint.my_value", "awful");

That’s an example of how default values are more of a time-bomb then they are a convenience. Imagine the following quite typical accidents that happen to programmers daily:

  • Accidentally mistype me.prettyprinl.ny_value in your Java code
  • Accidentally mistype ne.prettyprimt.my_value in the properties file
  • Accidentally mistype the file name ClassLoader.getSystemResource(“my-propetries.properties”)
  • Forget to package the properties file in your jar; or package it in the wrong way.
  • … you get it, right? It’s so easy to make these mistakes that eventually you will; or the next programmer to edit your files will…

The problem is that since there are default values, the defaults are loaded and you have absolutely no clue that something is going wrong here. The compiler won’t help you b/c you’re not making a syntax error. The program may continue to run fine or appear to run fine until…

To make this situation even worse, many programmers (including myself for a long time) set their defaults to the exact same value as the ones in the properties files.  So what happens is that even if you mistype something once, everything works well by loading the default value, but when you go to your production environment and want to change a property, nothing changes. The property is changed in the file, yet, but it’s not loaded to the program variable because of some silly typos. That is the time-bomb!

Defensive programming means – program as if everything could go wrong; Assumption is the mother of all fuck-ups; Assume nothing! While this is somewhat extreme, I tend to agree to that approach. What could go wrong here is programmers typos or similar small mistakes. Assume they will happen and protect your code against them. Don’t use Properties.getValue(value, devaultValue); Only use Properties.getValue(value).


Yet another visual diff for git

I’m relatively new to git and I’m already in love with it, but there was one thing that bugged me and I couldn’t get a good answer anywhere else, so I wrote my own thing, posting it so maybe you can find it helpful.

The problem: Use a visual diff tool for git; and view all diffs at once.

All other solutions show me how to use a visual diff tool for git but they all have a common weakness – they show only one file at a time, which is a bummer b/c many times what I’d like to do is look at all the changed files and switch between them going back and forth.

So, as mentioned there are already many posted solutions how to set up visual diff in git for various platforms including linux, windows, osx (just Google it), so all I had to do is implement a really small change to one of them.

Step 1: Create a wrapper script in /usr/bin/git-diffmerge-wrapper.sh

#!/bin/sh
# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode
 
cp $2 %2-keepme
diffmerge "$2-keepme" "$5" &
sleep 5 && rm $2-keepme &

Don’t forget to chmod +x /usr/bin/git-diffmerge-wrapper.sh

Step 2: Configure git to use your script

$ git config --global diff.external /usr/bin/git-diffmerge-wrapper.sh

That’s all!

I use os x so for linux systems it’s basically the same script. Windows might have to change a bit, but I’m not that good and win…

I assume you have diffmerge installed. If not, either use a different visual diff tool or download and install it (free).

Here’s the trick : when git runs a a diff it creates temporary files for each index file and deletes them right after the external diff program for that specific file exited. So what I did is simple copy the files to other files ($2-keepme), run the diff in the background, sleep for 5 seconds to make sure the diff program reads the files and then delete them for clean up.

cp $2 %2-keepme
diffmerge “$2-keepme” “$5″ &
sleep 5 && rm $2-keepme &


Flash and encryption? No way dude!

flash

I was asked by a fellow worker whether flash can be? Short answer: no. Long answer below.

But why would you even want to encrypt flash? I asked.

He told me about a product he’s working on, some kind of hook for online games which identifies cheaters and bots as they play in real-time  by collecting many signals looking at some smart patters etc. I realized, ok, this guy really needs to hide his top-secret code from hackers, he doesn’t want them to be able to read his code and break his top-secret sauce, plus his code needs to run on the client to be able to collect its signals => he’s in trouble. Flash code just can not be encrypted, tough luck.

But before getting to that conclusion I researched a bit and found out there are quite a few companies and products that have already thought about this problem and have come out with almost-good-enough products called code obfuscators. It appears that flash developers (me being one) are concerned about their work getting stolen. You work hard making an online game or a video player or mp3 player, put it on your site and baam, someone downloads your swf, runs it by a flash decompiler and has source code access to your hard work; now he can implement slight changes, brand it as his and get your fame.  Code obfuscators try to solve this problem by making it difficult for a hacker to reverse engineer, or decompile the code. Put another way, code obfuscators want to protect your work from being copied. Only that sadly they can’t :( . They may do a decent job at making it somewhat harder to reverse engineer the code but they cannot and will never be able to completely protect your code, not even theoretically and that is the key point.

It’s important to realize that code on the client cannot simply be encrypted. There are other solutions to the problem but let’s establish the theory first. When code runs on your computer, and it doesn’t matter weather it’s flash or anything else, the computer needs to understand the code in order to run it, it needs to be able to read it. Now, as long as you have physical access to your computer, and I assume you do, you can hack it no matter how hard it’s encrypted. Let us assume the code is indeed encrypted; at some stage the computer will have to run it, so it will have to decrypt it; In the flash case it’s the flash bytecode that needs to be run by the flash VM (like in Java VM flash has it’s own bytecode and VM), so in order to run the code the computer will have to decrypt the code first; To the best of my knowledge, no CPU can run encrypted code and no flash VM can run encrypted flash bytecode; if the computer is able the decrypt the code, so can a hacker decrypt it, simply by running the same lines as the computer does; if the computer cannot decrypt the code, if won’t run it, so in that sense your code is pretty safe, but at the same time not usable.

What flash obfuscators do is not encryption (although some of them brand themselves unrightfuly so), they simply apply various transformations on the code to make it harder to read. They rename variables to unreadable names, they run transformations on for and while loops etc, and it is indeed a bummer to try to read their output; if I were to copy source code from a game I’d go for the one that did not get obfuscated, so in that sense they do a reasonable job but they are not cryptographically secure; a hacker with enough time at his hand will be able to crack them.

What do you do, then? he asked me. I really need to protect my code but I also need to run it on the client, so what do I do?

There are several ways to go around this. One is: perform only the simple dumb signal collection on the client and send it to a server and let the secret code run on a server, not on the client. There is no general high level solution to the problem, it’s all very specific to the application, so in this case I suggested him to run the analysis on the server side, but in other cases the solution may be different, but the only thing that’s important to understand is that you can’t protect code on the client.

Keep safe ;)


Required: CSS islands

sheetsHey CSS guys, how about a CSS island tag?!

This is what I’m talking about:

<html>
<style>
h1 {
 font-size: bigger;
}
</style>
<body>
lots of html code....
<cssisland resets="h1;h2;div.img;#id">
<style>
h1 {
 font-size: smaller;
}
</style>
here all page css code is preserved except for h1, h2, div.img and #id
h1 has a smaller font-size only within the scope of this block.
</cssisland>
more html code... Here h1 has font-size bigger again.
</body>
</html>

Here’s the problem: It’s very common that web pages are constructed by many sources. For example in my about page I have a stack overflow badge. Most of the content of this page was constructed by me, but this badge is from stackoverflow.com. The badge widget uses some CSS styles that might conflict with my page styles. For example it may use h1 or default fonts etc. The widget author can’t possibly know who’s going to use her widget, in what pages or how those pages are constructed and so it’s very likely that there will be a CSS conflict. The browser will know what to do with the CSS conflict, after all that’s how CSS is designed, it’ll find what needs to cascade what, but the problem is that either the widget is going to look awful b/c it’s author didn’t think of setting some CSS properties that have odd values on my page or that the page suffers b/c the widget has changes some CSS attribute that messes up the page.

One possible solution to this problem of CSS conflict may be using an iFrame, but this is also a very limited solution b/c sometimes you don’t want to use an iframe and you do want to preserve most of the page styles. See my previous post on the subject.

The common practice today, which pretty much sucks (IMO…), is to set all style attributes inline, for example:

<html>
<style>
h1 {
 font-size: bigger;
}
</style>
<body>
lots of html code....
<h1 style="font-size: smaller">My great widget</h1>
more html code... Here h1 has font-size bigger again.
</body>
</html>

Here we set the h1 font-size as an inline style attribute but this sucks b/c the code is ugly and not very robust.

To do it nicely you’d want to add a <style> block but you can’t. If you do:

<html>
<style>
h1 {
 font-size: bigger;
}
</style>
<body>
lots of html code....
<style>
h1 {
 font-size: smaller;
}
</style>
<h1>My great widget</h1>

more html code... Here h1 has font-size bigger again.
</body>
</html>

… then you’re going to mess up the page display by changing all h1 on it.

So what I’m suggesting is a css-island block which isolates all CSS definitions declared inside it and as a convenience may also reset other CSS selectors defined on the page. This is a “scratch” idea, so optimizations are in place but as a general thought, how does it sound?

Does that sound like a good idea?


Widgets – iframe vs. inline

Inspector GadgetWhen writing a widget, should you use an iFrame or make the widget inline?

Widgets are small web applications that can easily be added to any web page. They are sometimes called Gadgets and are vastly used in growing number of web pages, blogs, social sites, personalized home pages such as iGoogle, my Yahoo, netvibes etc. In this blog I use several widgets, such as the RSS counter to the right which displays how many users are subscribed to this blog (don’t worry, it’ll grow, that’s a new blog ;-) ). Widgets are great in the sense that they are small reusable piece of functionality that even non-programmers can utilize to enrich their site.

I’ve written several such widgets over the time both “raw” widgets that can get embedded in any site as well as iGoogle gadgets which are more structured, worpress*, typepad and blogger widgets, so I’m happy to share my experience.

As a widget author, for widgets that run on the client side (simple embeddable HTML code) you have the choice of writing your widget inside an iframe or simply inline the page and make it part of the dom of the hosting page. The rest of the post discusses the pros and cons of both methods.

How is it technically done?

How to use an iframe or how to implement an inline widget?

Iframes are somewhat easier to implement. The following example renders a simple iframe widget:
<iframe src='http://my-great-widget.com/widgwt' width="100" height="100" frameborder='0'> </iframe>

frameborder=’0′ is used to make sure the ifrmae doesn’t have a border so it looks more natural on the page. The http://my-great-widget.com/widget is responsible of serving the widget content as a complete HTML page.

Inline gadgets might look like this:

function createMyWidgetHtml() {
 return "Hello world of widgets";
}
document.getElementById('myWidget').innerHTML = createMyWidgetHtml();

As you can see, the function createMyWidgetHtml() it responsible for creating the actual widget content and does not necessarily have to talk to a server to do that. In the iframe example there must be a server. In the inline example there does not need to be a server, although if needed, it’s possible to get data from the server, which actually is a very common case, widgets typically do call server side code. Using the inline method server side code is invoked by means of on-demmand javascript.

So, to summarize, in the iframe case we simply place an iframe HTML code and point the source of the iframe to a sever location which actually serves the content of the widget. In the inline case we create the content locally using javascript. You may of course combine usage of iframe with javascript as well as use of the inline method with server side calls, you’re not restricted by that, but the paths start differentially.

So what is the big deal? What’s the difference?

There are several important differences, so here starts the interesting part of the post.

Security.

iFrame widgets are more secure.

What risks do gadgets impose and who’s actually being put at risk? The user of the site and the site’s reputation are at risk.

With inline gadgets the browser thinks that the source of the gadget code code comes from the hosting site. Let’s assume you’re browsing your favorite mail application http://my-wonderful-email.com and this mail application has installed a widget that displays a clock from http://great-clock-widgets.com/. If that widgets is implemented as an inline widget the browser thinks that the widget’s code originated at my-wonderful-email.com and not at great-clock-widgets.com and so it’ll let the widget’s code ultimately get access to the cookies owned by my-wonderful-email.com and the widget’s evil author will steal your email. It’s important to realize that browsers don’t care about where the javascript file is hosted; as long as the code runs on the same frame, the browser regards all code as originationg at the frame’s domain. So, you as a user get hurt by losing control over your email account and my-wonderful-email gets hurt by losing its reputation.

If the same clock would have gotten implemented inside an iframe and the iframe source is different from the page source (which is the common case, e.g. the page source is my-wonderful-email.com and the gadget source is great-clock-widgets.com) then the browser would not allow the clock widgets access to the page cookies, nor will it allow access to any other part of the hosting document, including the host page dom. That’s way more secure. As a matter of fact, personal home pages such as iGoogle don’t even allow inline gadgets, only iframe gadgets are allowed. (inline gadgets are allowed only in rare cases, only after thorough inspection by the iGoogle team to make sure they’re not malicious)

To sum up, iframe widgets are way more secure. However, they are also way more limited in functionality. Next we’ll discuss what you lose in functionality.

Look and feel

In the look and feel battle inline gadgets (usually**) win. The nice thing about them is that they can be made to look as part of the page. They can inherit CSS styles from the page, including fonts, colors, text size etc. Iframes, OTHO must define their CSS from the grounds up so it’s pretty hard for them to blend nicely in the page.

But what’s even more important is that iframes must declare what their size is going to be. When adding an iframe to a page you must include a width and a height property and if you don’t, the browser will use some default settings. Now, if your widget is a clock widget that’s easy enough b/c you know exacly what size you want it to be, but in many cases you don’t know ahead of time how much space your widget is going to take. If, for example you’re authoring a widget that displays a list of some sort and you don’t know how long this list is going to be or how wide each item is going to be. Usually in HTML this is not a big deal because HTML is a declarative based language so all you need to do is tell the browser what you want to display and the browser will figure out a reasonable layout for it, however with iframe this is not the case; with ifrmaes browsers demand that you tell it exactly what the iframe size is and it will not figure it out by itself. This is a real problem for widget authors that want to use iframes – if you require too much space the page will have voids in it and if you specify too little the page will have scrollbars in it, god forbids.

Look and feel wise, inline wins. But note that this really depends on your widget application. If all you want to do is a clock, you may get along with an iframe just as well.

Server side vs. Client side

IFrmaes require you specify a src URL so when implementing a widget using an iframe you must have server side code. This could both be a limitation and a headache to some (owning a server, domain name etc, dealing with load, paying network bills etc) but to others this is actually a point in favor of iframes b/c it let’s you completely write your widgets in server side technologies, so you can write a lot of the code and actually almost all of it using your favorite server side technology whether it be asp.net, django, ror, jsp, struts , perl or other dinosaurs. When implementing an inline gadget you’ll find yourself more and more practicing your javascript Ninja.

What’s the decision algorithm then?

Widget authors: If the widget can be implemented as an iframe, prefer an Iframe simply for preserving users security and trust. If a widget requires inlining (and the medium allows that, e.g. not iGoogle and friends) use inline but dare not exploit users trust!

Widget installers: When installing a widget in your blog you don’t see a “safe for users” ribbon on the widgets. How can you tell if the widget is safe or not? There are two alternatives I can suggest: 1) trust the vendor 2) read the code. Either you trust the widget provider and install it anyway or you take the time to read its code and determine yourself whether it’s trustworthy or not. Reality is that most site owners don’t bother reading code or are not even aware of the risk they’re putting their users at, and so widget providers are blindly trusted. In many cases this is not an issue since blogs don’t usually hold personal information about their readers. I suspect things will start changing once there are few high profile exploits (and I hope it’ll never get to it).

Users: Usres are kept in the dark. Just as there are no “safe for users” ribbons on widgets site owners install, there are no “safe to use” sites and basically users are kept in the dark and have no idea, even if they have the technical skills, whether or not the site they are using contains widgets, whether the widgets are inline or not and whether they are malicious. Although in theory a trained developer can inspect the code up-front, before running it in her browser and losing her email account to a hacker, however this is not practical and there should be no expectation that users en mass will do that. IMO this is an unfortunate condition and I only hope attackers will not find a way of taking advantage of that and doom the wonderful open widget culture on the web.

Happy widgeting folks!


* Some blog platforms have a somewhat different structures for widgets and they may sometimes have both widgets and plugins that may correlate in their functionality, but for the matter of the discussion here I’ll lously use the term widget to discuss the “raw” type which consists of client side javascript code

** Although in most cases you’d want widgets to inherit styles from the hosting page to make them look consistent with it, sometimes you actually don’t want the widget to inherit styles from the page, so in this case iFrames let you start your CSS from scratch.


Sometimes look on the bright side of life

I’m a big fan of Jeff Atwood, author of coding-horror and, co-author of the stack-overflow podcast so when I started this new blog I thought wouldn’t it be cool if I found a cool domain name a-la coding-horror or stack-overflow or such? But then I realized that all those names have negative connotations: stack-overflow (see the immortal smashing the stack for fun and for profit), coding-horror, the new server-fault site and there’s another cool site, The Daily WTF

I’ve decided I’d like to, at least sometimes, if not always look on the bright side of life

So I chose PrettyPrint.me to stay on a positive note.


The hitchhikers guide to bookmarklet authoring

I’ve written several bookmarklets lately so I wanted to write a tutorial/Q&A to help newbees and share what I’ve learned. Please leave comments if you have questions or you think I got something wrong and good luck with your first bookmarklet.

Count Bookmarklet

What are bookmarklets?,

Bookmarklets are small plugins/extensions to your browser. They are called that way because they’re implemented using the browser’s built-in Bookmarks mechanism (although IE uses a different terminology, Favorites, they are still called bookmarklets even in IE jargon). Example bookmarklets are Count which I authored which counts characters of the text you select. There are plenty of other useful bookmarklet examples here as well.

How to install a bookmarklet?

Bookmarklet’s don’t really require installation. They are simply links you can add to your bookmarks toolbar. There are several ways to do that (depending on your OS and browser), so here’s a short explanation that tries to catch them all.

  • Right click the bookmarklet link
  • Select “Bookmark this link” (on FF) or similar wording in IE/other browsers
  • That’s all, really

Now that your bookmarklet is installed, simply click it to use it. For example if you’ve installed the Count bookmarklet, when you want to count characters simply click the bookmark. So, bookmarklets are best described as “additional browser buttons”.

One tweak is that some browsers tend to hide their bookmarks folder, so you have to configure your browser to show it so you have all buttons at hand and don’t have to click through the bookmarks toolbar in order to get to them. It’s usually done by either right clicking the navigation bar area or similar technique.

A lot of browsers simply let you drag and drop the bookmarklet to the bookmarks toolbar, so that’s much easier.

There’s also a video I found that explains how to install (a different) bookmarklet here.

How to write a bookmarklet?

Alright, let’s get down to business  and write some software!

This is your first bookmarklet: Say hello and here’s the code:

<a href="javascript:alert("Hello first bookmarklet world")">Say hello</a>

That’s easy, right? All you have to do is add a link at your web page and set the href of that link to javascript:… We’ll talk about this javascript: more later. Now all your users have to do is add this link to their bookmarks and that’s it.

What does javascript: stand for?

A URL is comprised of several sections. For example in http://www.google.com/ we have www.google.com as the host name and http as the protocol. Browsers know all sorts of protocols, to name a few http, https, ftp, irc and yes, javascript as well. Sometimes a browser relayes a protocol to the operating system, such as the case wtih irc or ed2k but at least for http, https and javascript the browser handles them by itself. So when you have an <a href=’javascript:…”> it actually tells the browser to run javascript when the user clicks on that link. A simple extension to this is what makes bookmarklet so powerful – if you have a bookmark wtih a link that starts with javascript: as its protocol, the browser will, instead of navigating to a different page, simply run that javascript in the context of the current page. This is great because now you’re able to add functionality to other pages. For example , you may count characters on any page you visit. Many bookmarklets operate on the current page, but they strictly don’t have to, they can be independent of the page such as the Say hello bookmarklet above, which simply doesn’t care about what page the user is currently browsing, but to me the real power of bookmarklets is to be able to interact with the page.

You may know about plugins/extensions/toolbars, which in many cases also operate on the “current page”, so if you’re wondering what’s the difference between an extension and a bookmarklet, that’s a good question, but we’ll get to that later.

Let’s write a non-trivial bookmarklet

In the previous example we had a simple bookmarklet that only says hello. That’s cute, but not that useful. Let’s do a real one then, one that counts the number of words on the current page.

First, let’s write just the javascript code, run it and only then turn it into a bookmarklet. I like to use firebug for writing short snippets of code and testing them, so just copy the code below, paste it into firebug console and run it.

var t = document.body.innerHTML; // Gets all body content
t = t.replace(/<(.|\n)*?>/g,''); // Removes all html tags
t = t.replace(/\s+/g,' '); // Crunch consecutive whitespaces
alert('Length: ' + t.split(' ').length); // split by spaces and count length

Now stay tuned because this is important. To turn this piece of javascript code to a bookmarklet we’ll need to apply several transformations, so let’s do them one step at a time.

1. First step is trivial, remove comments.

var t = document.body.innerHTML;
t = t.replace(/<(.|\n)*?>/g,'');
t = t.replace(/\s+/g,' ');
alert('Length: ' + t.split(' ').length);

2. Next we need to crunch it all to one line. Bookmarks should not have newlines in them (although some browsers are OK with that, let’s play it clean)

var t = document.body.innerHTML; t= t.replace(/&lt;(.|\n)*?&gt;/g,''); t = t.replace(/\s+/g,' '); alert('Length: ' + t.split(' ').length);

Later we’ll introduce an automated tool that does all that, but for now it’s instructive that you do it yourself.

3. Next, wrap it all in a function construct. This is the most importance point, so pay attension.

(function(){var t = document.body.innerHTML; t= t.replace(/&lt;(.|\n)*?&gt;/g,''); t = t.replace(/\s+/g,' '); alert('Length: ' + t.split(' ').length);})()

Let’s talk about what just happened here. We wrapped the code inside this weird construct (function(){…})(). What does it mean?

What you see here is an anonymous function definition followed immediately by the function execution. JavaScript is great in allowing anonymous functions and what we get from it is two important things. First we get namespace safety – if there was another variable on the page named t if will not get overrun. Bookmarklet need to be good citizens and if you run over the local page variable no one will want to use your bookmarklet so you have to be careful. Keep in mind that you have no control over what page your bookmarklet is run at, so you don’t know whether that page has already defined a variable named t or not. Now, you could have gotten away with using __my_ugly_bookmarklet_unique_variable_name as a somewhat unique var name on the page in hope no one gets as smart as you making up var names, but c’mon, this is way un-elegant. And there’s more.

The second thing you get from using the anonymous function construct is even more important – A single statement. Remember the talk about protocols before, the javascript: protocol? So, the thing is that javascript: protocol may only accept one statement. So if the statement is a simple alert() that’s fine but if your program has more than a single statement, (and that’s why we call them non-trivial) then you need to wrap all the statements in one big block. That block is this function construct.

So, let’s get back to the function construct and see what we have.

First, we have an anonymous function

function(){...code...}

Next, we wrap this function definition in braces to make sure associativity works for us:

(function(){...code...})

And next, we invoke this function

(function(){...code...})()

By invoking the function we effectively run the code inside the function, which is exactly what we need. OK, so that was the hard part, now the easy part.

4. Next, add an <a href=”javascript:” to it

<a href="javascript:(function(){var t = document.body.innerHTML; t= t.replace(/&lt;(.|\n)*?&gt;/g,''); t = t.replace(/\s+/g,' '); alert('Length: ' + t.split(' ').length);})()">Count words on page</a>

So, with step 4 you have your bookmarklet ready. Let’s summarize all steps so far

0. Write the javascript code for the bookmarklet. This is the heart of your application where all logic goes. All the rest are more or less trivial plumbing once you get the hang of it. I use Firebug for testing small snippets of code, and usually just save the javascript I develop in a local file.

1. remove comments

2. crunch into one line

3. wrap in (function(){…})()

4. Add the <a href=”javascript code on an HTML page (this is optional by the way, only if you want other ppl to see your bookmarklet)

About code crunching, otherwise known as javascript-minification or compression, there are automated tools to help you do that. They remove comments, remove newlines and extra whitespaces, so what I do is keep the js file well formatted and only when I want to deploy it, I run it through the minifier. An online minifier version is also available, which is quite handy here and a downloadable minifier from Yahoo here

Now you are ready to write your first bookmarklet. In the next sections we’ll dig into more advanced techniques and some meta discussions.

Bookmarklets vs. extensions

A short recap: Bookmarklets are small extensions to the browser’s functionality implemented as a simple bookmark. What are browser extensions then (also called add-ons, sometimes plugins, sometimes toolbars etc)? They are also extensions to the common browser functionality. There are dozens of examples extensions such as the Google Toolbar, Yahoo, MSN and so many more. So what is the difference b/w a bookmarklet and an extension?

Well, there are many differences but I’ll only talk about a few which I think matter the most and would hopefully help you determine whether you want to write a bookmarklet or an extension

Functionality. Functionality wise I think extensions win. Browser extensions can do so much more than bookmarklets. They can open a sidebar, they can have as many buttons as they like (instead of  just one), they can have more than just buttons, they can have text boxes, graphics, control the mouse cursor ans so much more. A user can play with the extension settings to personalize it etc. Bookmarklets are much simpler and don’t provide all that rich functionality. They are bookmarks, and they will always look like bookmarks, you can’t make them use a logo (except for your site’s favicon, but that’s lame and doesn’t work by default on all browsers). Functionality wise, extensions win. But wait, there’s more.

Ease of development. If you’ve read this tutorial you can write a bookmarklet. It’s that easy. To write a bookmarklet you need to know about the usual web stuff, javascript, css, html, but that’s all, no need to learn something specific except from what is in this blog. Extensions are a whole different story. Firefox extensions, which are relatively easy to make compared to IE toolbars make you learn about XUL and about the special firefox extensions registry, they make you create an xpi, an installable version etc. IE is much much worse in that sense. Now, all that is definitly possible of course, people have been doing it for a long time, but you have to admit this is order of magnitude more complex than the javascript, html and css you already know. In ease of development bookmarklets win.

Interoperability. When authoring a bookmarklet, just like authoring a web site, you write them for all browsers. All browsers have support for bookmarks, hence all browsers support bookmarklets. OTOH, not all browsers support extensions and those that do (IE, FF) have a whole different structure for doing that. If you choose the bookmarklet way, by definition you develop for all platforms. If you choose the extensions way you’d have to write one extension for IE (good luck with that), one for FF, you can’t write extensions for Safari, which happens to be my favorite browser, none for Opera and I rest my case. Interoperability wise, bookmarklets win.

User-friendliness. I don’t know. I think some users are more confirmable with extensions just because they are one-click to install (or several clicks) whereas bookmarklets require you to add a bookmark, which as silly as it may sound, some ppl are having real hard time with that. So I think the installation process of toolbars is better at least for some users. OTOH, I think advanced users much prefer bookmarklets b/c they feel more in control when installing them. When I install a browser extension I think very hard on whether this extension is going to slow my browser down, or wheather it’s going to change my layout, or whether it’s going to take some preceaus browser real-estate. As a minimalist I prefer bookmarkletrs as I’m in full control – they hardly take up space, they can’t operate and slow my browser down unless I click them, so I’m in control. But I see why some users prefer extensions. Let’s call it a tie then.

The bottom line is this: for your applicaton you should determine whether to use an extension or a bookmarklet according to the following criteria:

  • What functionality do you want to provide? Some things just can’t be done using a bookmarklet.
  • What browsers would you like to support? Not all browsers support extensions, and even those who do require you to rewrite your code for them
  • Do you have time to develop an extension? In most cases extensions are order of magnitude harder to implement.
  • What is your audience? It is going to be comfortable with a bookmarklet? Is it going to be comfortable with an extension? This is sometimes hard to figure out, BTW, but that’s how life is…
Advanced: Loading code from remote server

In the Count bookmarklet I authored I use jQuery to display a nice floating window and animations. I chose to use jQuery and animations make the whole thing look nicer. I could have gotten through with a simple alert() message but it just didn’t feel right.

Now, the challenge is twofold:

  • bookmarklets have limited space in them, which means you can’t crunch so much code into them, and definitly not the whole jQuery library. I don’t remember what the exact limitation is and I’d bet different browsers have different limitation, but it’s safe to assume that 1024 chars are about the max since this is a normal limitation HTTP imposes in URLs. Anyway, even if it was 2000, 4000 or more that wouldn’t have been enough.
  • Say you want  to upgrade your bookmarklet – fix a bug or add a feature. If all the code would have been implemented inside the bookmarklet itself, you’d have to ask all your users who already installed that to remove and reinstall, then you’re in big trouble.

So, what you want to do is have a bookmarklet that actually loads javascriopt to the page from a remote server. That way it’s simple to ugdate your bookmarklet.

To load javascript to a page that’s actually already fully loaded we use a technique called dynamic script injection, which is common to other applications such as jsonp and here’s how it works:

var s = document.createElement('script'); // Create a script dom element
s.setAttribute('src', 'http://charcount.appspot.com/s/jquery.js'); // Set the element source to the js file you want to load
s.setAttribute('type', 'text/javascript');
document.body.appendChild(s); // attaching the element to the body (or to head) results in the browser loading the script and executing it. That's just how browser magic works, which is cool... all browsers do that!

So the trick is to attach a <script> dom element to the head (or body) which results in browser execution. How cool is that? By the way, don’t try to use document.write(“<script..”), it will not work. Once a page is fully loaded calling document.write simply messes everything up and you’re likely to find your browser unstble if you choose to do that (beleive me, I tried ;) )

Loading a script from a remote server is very cool and it opens up interesting possibilities. You’re no longer bound to writing very very compact code and you can use 3rd party libraries, so that’s awesome. There are, however. a small tradeoff and a few gotchas:

  • The tradeoff is in performance. If all your code is local the browser runs it very fast whereas if you have to load remote resources depending on your server availability, this may be slower. It’s usually not a big deal, but I had to mention this.
  • You need to have a server. Or at least something static that can serve javascript.
  • Gotcha: be careful not to load your script more than once. If the user clicks on your bookmarklet again and again you don’t want to load your js files over and over again. There’s a simple way to guard agains this, look at the example below.

To prevent your scripts from being loaded more than once you make use a guard, a variable or a page element that gets initialized in the js file and the bookmarklet code checks for its existence. Here’s an example from the Count bookmarklet:

javascript:(function(){if(document.getElementById('__wc_display')){__wc_refresh();return} // That was the guard. The rest of the code will load the js files
 
window.__wc_base='http://charcount.appspot.com/';var%20d=document;var%20s=d.createElement('script');s.setAttribute('src',__wc_base+'s/jquery.js');s.setAttribute('type','text/javascript');d.body.appendChild(s);s=d.createElement('script');s.setAttribute('src',__wc_base+'s/wc.js');s.setAttribute('type','text/javascript');d.body.appendChild(s);})()
Bookmarklets Dos and Don’ts

DO: Be polite. Remember, you’re not running your own show here, you’re only a guest on some other page. Do what you need to do but don’t stand in the user’s way and make it use a bookmarklet-block (as if there’s something like that… I just made it up, but you get the point – be polite).

DON’T mess with user privacy. You’re a guest, don’t forget that. NEVER look at cookies. Users trust you when they install, don’t betray that trust. Both bookmarklets and browser extensions are able to compromise security.

DO: graceful degregate. In case your server is not up or something else is going wrong, make sure that your bookmarklet leaves the browser in good condition. No javascript errors, no broken page etc.

DO: Test multiple browsers. It’s unfortunate, but very common for code to work perfect on one browsr and be completely broken on another. You must test at least the commonly used browsers, it’s a pain, but it’s a must.

DONT burn CPU, don’t leak memory. That’s true not only for bookmarklets, but is especially true for them. Messing with your own site is one thing, but messing with another site is a whole different story. You’re a guest, behave!

I hope this tutorial was useful. Pleae feel free to leave cometns if you feel something is missing.


Hello Pretty World

As professional programmers you’re familiar with the term Pretty-print. Getting a cool domain name isn’t easy these days, so after weeks in search I was happy to finally get PrettyPrint.me how cool is that?
Code aesthetics and readability is just one of the things I care about the most when writing code.I’m a professional software developer with experience in software methodology and web frontends in particular. I hope to share my wisdom on this blog and learn as I go.

Print it then, and keep it pretty

function startBlog(pretty) {
 prettyPrint("Hello " + (pretty ? "Pretty " : "")+ "World!");
}
startBlog(true);

Hello World