ProtoAspx
Integrating Prototype and ASP.Net to create the next generation of web applications

Google Chrome

September 3rd, 2008 . by Loris

google chrome logo

Taking the web by surprise (didn’t they have a partnership with Mozilla?), Google has made another step towards a better web (or towards world domination, some may argue :) ) by releasing its browser, Google Chrome, yesterday.

Based on the WebKit rendering engine (the one powering Konqueror and Safari), but otherwise designed from the ground-up, Chrome promises web developers something they have being begging for since the (re)discovery of AJAX: blazing fast javascript performance and a multi-threaded browsing experience.

The performance gains come from the V8 javascript engine, that compiles javascript code down to bytecode, instead of just interpreting it.

Also, in Chrome, every tab is hosted in a separate (and sandboxed) process, which means that the javascript execution in one tab won’t impact negatively on the execution of other tabs.

You can read more on the online cartoon/book:

js_perf

In the end, what does Chrome mean for us web developers?

In my opinion, it means that soon we will have better browsers.

The release of Chrome comes after two very important announcements: TraceMonkey, the new javascript engine that will power Firefox 3.1 and SquirrelFish, the new javascript engine that will power Safari 4.0, both of which promise tremendous peformance gains over SpiderMonkey (the engine powering Firefox 3.0, which should also be the fastest one at the moment).

The only browser left behind is, sadly, Internet Explorer, as shown by the benchmarks. Sure, IE8 is much faster than IE7, but it’s still way slower than any of its competitors.

The browser war has just got a bit more intense and Microsoft will have to do much better if they want to remain competitive.


Creating classes with Prototype

August 27th, 2008 . by Loris

If you use Script.aculo.us or some other library written on top of Prototype, you probably have already encountered the Class object. Every time you call a new Effect.Appear() or a new Draggable() you are, in fact, instantiating a Prototype class.

Just like software developers abandoned procedural languages like C or Pascal for object oriented ones like C++ all the way up to C# and Java, the same concept applies to the web: with (web)applications growing in complexity, it’s better to keep a modular approach and have a finite number of classes instead of a million of functions.

A *very* basic example

For this example, we are going to create a new class that observes an element and adds the ‘hover’ class name to it when the mouse is over it. If you are impatient, you can see the end result on this demo page.

Let’s start by declaring the new class. The class must be declared with the var keyword. The function Class.create takes a javascript object and transforms it into a Prototype class.

var HoverObserver = Class.create({
    initialize: function(element)
    {
    }
});

The initialize function is very important, as it will be the constructor for our class.

Let’s add some more code:

var HoverObserver = Class.create({
    initialize: function(element)
    {
        this.element = element;
        element.observe('mouseover', this.addClass.bindAsEventListener(this));
        element.observe('mouseout', this.removeClass.bindAsEventListener(this));
    },
    addClass : function(event)
    {
        this.element.addClassName('hover');
    },
    removeClass : function(event)
    {
        this.element.removeClassName('hover');
    }
});

Now that our class is actually doing something, we can start using it:

document.observe('dom:loaded', function(){
    new HoverObserver($('someDiv'));
});

You can see that the element we are passing to the constructor is actually passed by Prototype to the initialize function.

Adding options

Another nice thing we can do is to add an options parameter to the initialize function, so that we can pass one or more additional parameters to the constructor. For example, we can add an option to specify the class name to use instead of the default ‘hover’:

var HoverObserver = Class.create({
    initialize: function(element, options)
    {
        this.options = Object.extend({
            hoverClass : 'hover'
        }, options ||{});

        this.element = element;
        element.observe('mouseover', this.addClass.bindAsEventListener(this));
        element.observe('mouseout', this.removeClass.bindAsEventListener(this));
    },
    addClass : function(event)
    {
        this.element.addClassName(this.options.hoverClass);
    },
    removeClass : function(event)
    {
        this.element.removeClassName(this.options.hoverClass);
    }
});

This is how we can use the options parameter:

document.observe('dom:loaded', function(){
    new HoverObserver($('someDiv'), {hoverClass: 'highlighted'});
});

The nice thing about this approach is not that we can specify every single parameter in the options argument, but that we don’t have to, since every parameter we don’t specify will use its default value.

Common (and not-so-common) mistakes explained

Problem: I can’t use my object’s properties or methods, it says they are undefined!

Solution: You forget to add a .bind(this) or .bindAsEventListener(this) to a function called by an event handler or an iterator.

// wrong
element.observe('click', this.doClickAction);
elements.each(this.doSomething);
// right
element.observe('click', this.doClickAction.bindAsEventListener(this));
elements.each(this.doSomething.bind(this));

Problem: Everything works fine in Firefox, Opera and Safari, but IE refuses to run my script. It looks like IE doesn’t even recognize it as JS code!

Solution: You forgot a comma next to the last function declaration.

var MyClass = Class.create({
    initialize: function(){
    },
    method1: function(){
    },
    lastMethod: function(){
    },  // <-- this is the evil bastard
});

In this particular case none of the browsers I tested throws an error (they should!): IE simply refuses to parse the javascript file while the others ignore the syntactical error.