Follow me: @D_mitar

Most read posts recently



Feb 2nd 2012 × Using overloadSetter / overloadGetter to make flexible functions in mootools

This is a really helpful feature of MooTools that a few people know and use. Basically, there is a pair of 2 Function prototypes called ‘overloadGetter‘ and ‘overloadSetter‘. They are very simple in what they can provide. Say, you have a function that is a private property setter in a Class that takes 2 arguments: key & value. After a while, you may get bored having to call it all the time for every property you wish to add or having to write object loops for longer updates.

By defining using the Function decorator overloadSetter, you can – without any code adjustment – make your single key/value pair setter take an object and automatically iterate through the properties for you.

Similarly, by using the decorator overloadGetter, you can pass on multiple properties to retrieve that you are interested in – and it will return a single object with all your properties of interest as key.

Pretty cool?

Here’s a real world example. Let’s say, you are making a MVC Model Class that you’d like to use to deal with data objects and dispatch events.

(function() {

    // private real setter functions, not on prototype, see note on .set
    var _set = function(key, value) {
        // needs to be bound the the instance.
        if (!key || typeof value === undefined)
           return this;

        // no change? return. better rely on _.js _.eq but this is crude and works for primitives.
        if (this._attributes[key] && this._attributes[key] === value)
           return this;

        if (value === null) {
            this._attributes.delete(key); // delete = null.
        }
        else {
            this._attributes[key] = value;
        }
        // fire an event.
        return this.fireEvent("change:" + key, value);
    }.overloadSetter();   

    this.Model = new Class({

        _attributes: {}, // initial private object,

        Implements: [Options, Events],

        initialize: function(data, options) {
            data && typeOf(data) === 'object' && this.set(data);
            this.setOptions(options);
        },

        set: function() {
            // call the real getter. we proxy this because we want
            // a single event after all properties are updated
            _set.apply(this, arguments);
            this.fireEvent("change");
        },

        get: function(key) {
            // and the overload getter
            return (key && typeof this._attributes[key] !== undefined)
                ? this._attributes[key]
                : null;
        }.overloadGetter()

    });

})();

// now make an abstraction of your Model class for users
var User = new Class({

    Extends: Model,

    _attributes: {
        name: "Please enter your name",
        email: "Enter your email address"
    }

});

// initialise your User Model with default data and set some property change events
var user = new User(null, {
    "onChange:email": function(value) {
        // can dispatch to controller/view the change
        console.log("new email now is", value);
    },
    "onChange:name": function(value) {
        console.log("new name now is", value);
    },
    onChange: function() {
        console.log("data has changed!");
    }
});

// let's test this. initial set via single value set:
user.set("email", "dimitar@securemail.com");

// now let's try multiple properties at the same time:
user.set({
    "email": "dimitar@securemail.com",
    "name": "coda"
});

// get the name
console.log(user.get("name")); // coda;

// get multiple properties in a single object
console.log(user.get(["name","email"]));
// Object { name="coda",  email="dimitar@securemail.com"}

View and play with this on http://jsfiddle.net/dimitar/39x7T/

That’s about it. Please note that this Class was only created for the purposes of a demo and is not meant to be used in a real MVC pattern – look at Composer.js (for MooTools), Backbone.js or Ember.js – formerly Sprout Core – if you are interested in doing serious event-based application development.


Feb 2nd 2012 × MooTools in a distant future: how to write to better survive the changes

You may have already heard this, or maybe not. But this won’t change the fact that javascript is changing and the way people write it and specifically, how they write the libraries, modules and widgets we all share and use is slowly being edged towards an AMD pattern. This stands for Asynchronous Module Definition, pioneered by the DOJO framework with a one main goal in mind: being able to define and load any module and its dependencies asynchronously. Whereas it is not a standard yet, it is considered as a step towards the module system proposed in ES Harmony. I also won’t go into any possible shortcomings of this dependency system and the dangers of remote dependencies (bloat), that’s an entirely different topic.

Anyway, with that out of the way, what is the single most important thing to take away from the message that MooTools 2.0 (aka, Milk) will be AMD compliant? In order to become truly modular and compartmentalised into the small parts that have been the building blocks of the framework for years, MooTools is going to stop changing and extending the javascript natives Types’ prototypes. Only then does it guarantee that any of its modules can co-exist with any other AMD module without any conflicts.

When I say ‘stop changing’ natives, it does not mean it won’t ever modify an existing method (Function.bind comes to mind as an example) but in all likelihood, it won’t be doing much of that. You can start to treat bits of it like a microjs library. Even mix-n-match your favourite components from around the web, eg, take Class and use it on top of jQuery (if you really have to!), or bring Sizzle into MooTools instead of Slick with the utility functions of Underscore.js.

Sounds like a win. Now, the unpleasant part. Not being able to modify Element.prototype (for example) means a likely end to code like this:

document.id("someid").addEvent("click", function(e) {
    this.addClass("open");
    var divsWithImages = this.getElements("li").filter(function(el) {
        return !!el.getElement('img');
    });
    // I know you can use a reverse combinator selector for this. not the point.
});

Though the team will probably do a function wrapper like jquery that can allow the above in part, document.id() will stop returning the element itself but will return a function instead. The modified code may look the same but how it’s interpreted will be different. For instance, this.addClass(“open”); won’t work at all. Instead, it will probably need to go through either $(this) / document.id(this) or via the native Type or Slick.

Basically, all Array, Element, String etc methods (see the popular MooTools Types) are still available on the native object instead. You _could_ write the above like so:

Element.addClass($(this), 'open');

The Array / Elements.filter can be called like this:

var divsWithImages = Array.filter(document.id(this).getElements("li"), function(el) }
    return !!document.id(this).getElement("img");
});

Although I honestly have no idea what the new API will really look like, one thing is certain: even as of MooTools version 1.4.3 (time of writing), you can dual use most methods on the host object or through the prototype.

eg,

var strTest = "dimitar was here";
// old way via String.prototype
console.log(strTest.capitalize()); // Dimitar Was Here
// new way, same result.
console.log(String.capitalize(strTest));

It’s a small shift in the way we write code. Since both work already, I would advise you to use the latter one so you have less of a refactor to do if you ever hope to drive your existing code base with the future versions of mootools.

Now, how do you create a String method that will work with both the prototype and the host object? Seems simple. The scope is the host object so, here is a sample rot13 method that can work as both…

(function() {
    var n;
    String.implement({
        rot13: function() {
            return String(this).replace(/[a-z]/gi, function(match) {
                return String.fromCharCode((n = match.charCodeAt() + 13) > 122 || n < 104 && n > 90 ? n - 26 : n);
            });
        }
    });
})();

console.log(strTest.rot13());
console.log(String.rot13(strTest));

I suspect Type.prototype will become protected in the sense that implement will not affect them, making implement behave like Object.extend does at present. If you swapped .implement for .extend in the above code block and then String(this) to String(namedArg), you get a simple and safe-ish native type method.

This is all too similar to how you extend the Object Type (prototyping Object itself has always been a bad idea as everything in javascript inherits from Object):

// extend, not implement.
Object.extend({
    getPropertiesCount: function(object) {
        var props = [],
            hasOwnProperty = this.prototype.hasOwnProperty;
        for (var prop in object) {
            if (hasOwnProperty.call(object, prop))
                props.push(prop);
        }
        return props.length;
    }
});

console.log(Object.getPropertiesCount(this)); // return your global variables count!

I am certain these will not be the only changes but they will certainly be the most difficult to get used to. On the upside, there will be a compatibility layer as usual, including the ability to ‘install’ the prototype methods where possible. Even so, don’t be naive and write code that won’t outlive mootools 1.x without a lot of changes.

In conclusion, things are looking up for MooTools – it is headed in the right direction, even if slowly. My only gripe with this is that we need somebody from the core team to give news of how the release of Milk is coming along every so often. So we can get ready or even help…

*note: parts of this post are based on hearsay and sporadic data from various mootools members over IRC and Twitter. Don’t go writing any books on MooTools 2.0 just yet, you may even have to change the title (cough-Aaron-cough)*


Jan 12th 2012 × A larger MooTools logo

I had to look around and find an up-to date mootools logo of a decent size and I couldn’t find one. Hence, I took an old and small AI file and updated it to the current colours, ending up with the logo at 25cm and 300 DPI!

Whereas I won’t post this size here (see note below), I rendered a smaller version to an alpha PNG. Hope it helps someone to create great MooTools inspired fan art, wallpapers or whatever.

mootools logo - large

**note: apparently, use of the MooTools logo is under the strict control of Valerio Proietti, aka Kamicane. I am not going to post any high res logo and if you end up using this one, you really ought to ask for his permission.**


Dec 25th 2011 × substitutePath – a string method that recursively replaces values from an object

Originally, this was meant to be released as something for String.Extras in mootools-more as an idea by Oskar, coined by myself with input from csuwldcat – but it seems that the pull request is not going anywhere so I will release it here instead.

The idea is to extend the behaviour of String.substitute to be able to work with deep properties of the object that is being passed on, which means easier templating without having to flatten objects beforehand so the properties of interest are on the same level.

View on github as per pull request

String.implement({
    substitutePath: function(object, regexp) {
        return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name) {
            if (match.charAt(0) == '\\') return match.slice(1);
            if (object[name] != null) return object[name];

            var retStr = "",
                path = name.split('.'),
                length = path.length,
                sub = object;

            if (length <= 1)
                return retStr;

            for (var i = 0; i < length; i++) {
                if((sub = sub[path[i]]) == null) return retStr;
            }
            return sub;
        });
    }
});

The use goes like this:

var foo = "this is a bar called \"{lame.bar.name.here}\"";
var objOK = {
    lame: {
        bar: {
            name: {
                here: 0
            }
        }
    }
};

var objFail = {
    lame: {
        bar: {
            lame: {
                here: "hello"
            }
        }
    }
};

console.log(foo.substitutePath(objOK)); // works
console.log(foo.substitutePath(objFail)); // should fail
console.log(foo.substitutePath({foo:"bar"})); // should fail
console.log("this is a {bar}".substitutePath({bar:"success"})); // should work (legacy as .substitute);

Here's the jsfiddle you can play with: http://jsfiddle.net/dimitar/RtBMm/

Please note that the above will only deal with non-primitives (numbers, strings) and will fail if the key matches a function or an object. To address that, I have made a change in the jsfiddle (still being tested) that deals with it in a reasonable way here: http://jsfiddle.net/dimitar/RtBMm/6/ - though calling the function with the scope of the object and w/o parameters may not be ideal, it should cover a large percentage of cases. For any other types, I guess it will do a .toString() anyway.


Dec 24th 2011 × New mootools plugins released on github/forge

Time to wrap up the year, I think. I released 2 more small plugins of mine on github and the MooTools forge.

mooTagify
GitGub project page: https://github.com/DimitarChristoff/mooTagify
Forge link: http://mootools.net/forge/p/mootagify

A plugin for small tag lists input. Also, provides an ajax auto-completion sub-class that can be used as a standalone anyway.

Screenshot:

Example with ajax tag completion: http://fragged.org/mooTagify/Demo/
The plugin is quite easy to setup and you can style it via CSS only or via the many options available to the 2 classes that run it.

Modal.BootStrap
GitGub project page: https://github.com/DimitarChristoff/Modal
Forge link: hhttp://mootools.net/forge/p/modal_bootstrap

This is a combination of several things: the flexible modal markup experiment by @csuwldcat (Daniel Buchner from Mozila), implemented in the Modal.Base class and the Modal.BootStrap class.

The BootStrpa itself (not to be confused with Twitter’s BootStrap) provides a flexible implementation of content in the Modal window through HTML5 element mark-up only, including support for ajax links, grabbing content from elements on the page or setting pure text, even image support (pseudo-lightbox). It also works with location.hash so you can have page.html#terms_and_conditions as a link, if there’s a matching element managed by the BootStrap instance on the page.html, it will open it automatically for you. The modal will ALWAYS stay in the middle of the screen, it has support for responsive design with minimum width and max width as well as support for CSS3 transitions over js morphing of style properties (if available). Very useful for things like terms and conditions, privacy policies, quick contact forms, questionnaires and so forth. It also has support for buttons in the footer with custom events fired in the instance, so its flexible for scripting.

Screenshot:

Example with location.hash: http://www.fragged.org/dev/Modal/Demo/#interview2

Merry Christmas, everyone and a Happy New Year – unless I release anything in-between.


Nov 2nd 2011 × mooGrowl: a lightweight growl style class for mootools 1.4

There was notiMoo and I am sure there have been other javascript/mootools Growl notification solutions already. Yet, none of them were CSS3 and mootools 1.4 friendly, so I created a new Class instead.

Check out mooGrowl on GitHub
https://github.com/DimitarChristoff/mooGrowl

View the demo on jsfiddle:
Full screen or normal jsfiddle

Screenshot of some Growls:

no

Aug 24th 2011 × So long and thanks for all the fish

This is one of these posts that you write with your heart sunk and a feeling of regret… After 4+ fabulous years with WebTogs, I am moving on to pastures new.

It has been an absolute blast. I got the chance to start with a simple whiteboard idea and built a e-commerce start-up from the ground-up. A chance that I dare say took and did well out of, considering the lack of resources and other developers. Today, WebTogs is no longer a mere start-up site: it is a widely recognised and award-winning brand name, probably one of the biggest in the outdoors e-commerce industry. I cannot help but step back and marvel at our accomplishment with pride.

I got the chance to work with all aspects of the development process, from server administration, mysql structure and optimisation, PHP code, HTML 5, CSS3, javascript, SEO and SEM. I also got to discover the wonderful world of MooTools and have not looked back since.

But it is now time to pursue a career in what I have discovered that I enjoy doing the most: Front-End development with JavaScript and MooTools in particular. To that end, I am happy to say I have joined a new startup by QMetric and am looking forward to whatever new challenges that brings as well as whatever new skills and practices working there will allow me to develop.

I will continue helping out the guys at WebTogs as much as I can and hope we can continue our relationship together. Some of the people at Webtogs I have known and worked with for over 10 years and that’s a loooong time indeed. Thank you for all the great moments and the incredible mutual respect, flexibility and understanding that allowed us to create the site and build the business.

no

Jul 6th 2011 × MooTools pattern fun: Class Implements + Extends at the same time

Update: Thanks to @CarstenSchwede, who pointed out that the MooTools Class Constructor expects the Extends mutator __before__ the Implements one, meaning you don’t need to worry about any of the stuff I had to come up with (described in this post). Upon further investigation with Arian, it turns out that MooTools 2.0 will NOT be dependent on order of Extends and Implements declarations in classes, thanks to this change by Kamicane.

The neverending debacle of Extends vs Implements, which one to use and how to use them together – has been a source of discomfort for me in MooTools for a while so I thought I’d write up parts of my experiences with it in the hope it may help somebody else.

I came to have a need to write a class that serves as my new mixin and brings a new method ‘kill‘ – (say, Class ninja) to another class (Class badass) that extends Class human. Pretty crazy, right?

The problem is, the pattern of:

var ninja = new Class({
    kill: function() {
        alert("kill!");
    }
});

var human = new Class({
    initialize: function(){
        alert("i r human!");
    }
});

var badass = new Class({
    Implements: [ninja],
    Extends: human,
    initialize: function() {
        alert("i r badass and.. ");
        this.parent();
        this.kill();
    }
});

new badass(); // i r badass, i r human, this.kill is not a function exception.

… simply does not work. The Extend here means the human prototype is the base and it lacks the kill method. Wut?

The main practical difference in subclassing approaches is that the `Implements` (mixin) does not instantiate the subclass whereas `Extends` does, so there can be only one class that is extended whereas implemented ones just copy the methods from the prototypes. How to get around being able to extend a single class only? You need class human to implement ninja instead and class badass to simply extend human. Aside from the side-effect of humans getting a new kill method (which they may or may not know about), it will mean that badass will be able to use .kill as well as call upon his direct parent human.

The whole point is, you may not always be at liberty to rewrite / refactor classes the way you want them without creating complications with other parts of your web app. You could also be be extending a Mootools native class like Request.JSONP and then decide to mixin a new storage class into your extended one (true story!)…

An interesting pattern (or rather, the only pattern I have found to work… ) to overcome this goes something like this:

var ninja = new Class({
    kill: function() {
        alert("kill!");
    }
})

var human = new Class({
    initialize: function(){
        alert("i r human!");
    }
});

human.implement(new ninja);

var badass = new Class({
    Extends: human,
    initialize: function() {
        alert("i r badass and.. ");
        this.parent();
        this.kill();
    }
});

new badass(); // this.kill works.

You could even write this as:

Extends: human.implement(new ninja),

Obviously, you can simply modiy the prototype of the parent class and do:

human.implement({
    kill: function() {
        alert("kills!");
    }
});

But this means the code you already have in ninja needs to be duplicated and this will go for all methods or properties you want to gain access to.

A practical example with Request.JSONP and an example caching class, created to allow use of localStorage. Why would you want to do that? Well, having a class that can allow you to cache replies from Request or Request.JSONP or anything at all is handy. And doing things that fetch non-volatile data through a rate-limited API is expensive, you are encouraged to cache. In other words, if you read a particular user’s Twitter profile / timeline, you should not have to request it again on a reload within the session. Same applies if you are expanding tiny URLs like bit.ly – the URL won’t change for any given hash so there’s no point in continuously fetching it.

In the following example, we cache the response for a user profile JSONP request via the Twitter API:

View the full fiddle here: http://jsfiddle.net/dimitar/AjP5A/.

For a real detailed explanation of Extends vs Implements in MooTools, grab a copy of Pro Javascript with MooTools by keeto.


May 10th 2011 × Just a quick heads-up: updated site live header to new sprite animation

It’s been an year since I last touched on the live header malarkey and though the old one was OK, it was more to do with playing with the idea and developing a basic parallax effect in javascript. Oh, and learning more MooTools.

The new one is a complete (or near enough) rewrite of the lemming class. Each lemming is a simple referenced object by the instance, with its own properties and controllable by the instance. The array index of each lemming is the key to a number of pre-defined methods that can help do the storyboard example (along with events the instance or the lemmings fire).

You can view the source and play with them here on jsfiddle: http://jsfiddle.net/dimitar/bYtLz/. The storyboarding was a bit messy but the code is fairly simple. Change var letters = [] to spell something else. Have fun!


Apr 22nd 2011 × Tutorial: write a small content slider Class in MooTools and extend it

Difficulty: moderate
Framework: MooTools 1.3 (no previous ver compatibility)
Dependencies: MooTools-more 1.3.1 (no compat mode, just Element.Delegation required to build it)
DocType: HTML5 – optional

Before I begin, if you have not made a MooTools Class before, I suggest you first read this tutorial I made last month on creating a Sliding Tips plugin, which is a good entry level.

I imagine you’d want to see what the end result will will look like before you waste your time reading so:
http://jsfiddle.net/dimitar/Ea4Gp/show/ – the Base Class, cross-fading
http://jsfiddle.net/dimitar/Ea4Gp/5/show/ – the Extended Class with alternative transition effect
http://jsfiddle.net/dimitar/Ea4Gp/5/ – the editable fiddle to play with.
preview

Anyway. I just had cause to write a small class that allows me to swap between various content divs/panes that are part of the DOM and allow for any markup/child elements within. I thought I’d share the code as I could not readily find one that did things how I wanted them to be.

First, let us examine the requirements from a HTML point of view: a parent node (element) contains all the divs that will rotate. The Class needs to pick them up and enhance them. Should javascript be available, the user gets to see multiple content divs, otherwise–just the first one (progressive enhancement). Google has to be able to read text and follow any links within the content divs.

The resulting HTML markup looks like this:

<section class="rotator" id="rotator">
    <div class="pane" style="background-image:url(http://fragged.org/img/home/hunting-home.jpg)">
        <div class="info">
            <h2>Hunting CS style</h2>
            Built for your `camping` pleasure.
        </div>
    </div>
    <div class="pane hide" style="background-image:url(http://fragged.org/img/home/fishing-home.jpg)">
        <div class="info">
            <h2>Fishing? Really? </h2>
            Fishing is for mongs. <a href="#">Click here</a>
        </div>
    </div>
    <div class="pane hide" style="background-image:url(http://fragged.org/img/home/tourism-home.jpg)">
       <div class="info rambling">
           <h2>Rambling and walking</h2>
           Wish you were here? Can't blame you, it's lame.
        </div>
    </div>
</section>

The accompanying CSS that goes along with the markup above:

section.rotator {
    border-bottom: 4px solid #000;
    width: 700px !important;
    height: 280px !important;
    overflow: hidden;
    position: relative;
}

section.rotator div.pane {
    position: absolute;
    width: 700px;
    height: 280px;
    background-repeat: no-repeat;
    background-position: left top;
}

Come the MooTools magic. The Class is _very_ simple:

this.contentSwapper = new Class({

    // mootools options and events mixins as standard
    Implements: [Options, Events],

    // some defaults...
    options: {
        delay: 3000,
        selector: "div",
        controlLeft: "http://fragged.org/img/home/moveLeft.png",
        controlRight: "http://fragged.org/img/home/moveRight.png"
    },

    initialize: function(element, options) {
        // base constructor.

        // check to see if it's called with an element...
        this.element = document.id(element);
        if (!this.element)
            return;

        this.setOptions(options);

        // grab the child divs
        this.elements = this.element.getChildren(this.options.selector);
        this.index = 0;

        // call some methods we are about to define.
        this.attachControls();
        this.startRotation();
        this.attachEvents();
        this.fireEvent("ready");
    },

Once again, I like to break up all the things the Class does into small methods – ideally, as small as possible without getting into ridiculous territory where you write a method that returns a property you can access directly (eg, this.getSize = function() { return this.size; }).

attachControls is a cool method, as it makes use of some of MooTools 1.3′s new features: Slick and zen-like element construction.

attachControls: function() {
    this.controls = $$(
        new Element("img#moveLeft.contentControl[title=Previous][src={controlLeft}]".substitute(this.options)).inject(this.element, "top"),
        new Element("img#moveRight.contentControl[title=Next][src={controlRight}]".substitute(this.options)).inject(this.element, "top")
    );
},

Notice the $$() around the controls. This will create a MooTools HTML collection that is iteration-able (.each or any methods). The collection is basically like an array with added Element prototypes working. Other than that, nothing too complicated takes place – makes a new image with id #moveLeft, class .contentControl, sets the title and the src property.

To attach events: we want the rotation to stop when the user mouses over the main element (section.rotator) so they can read in peace and possibly click any call to action it may have.

attachEvents: function() {
    this.element.addEvents({
        mouseenter: this.stopRotation.bind(this),
        mouseleave: this.startRotation.bind(this),
        "click:relay(img.contentControl)": this.move.bind(this)
    });
},

Hence, mousenter calls our stop method and mouseleave starts again. The “click:relay(img.contentControl)” is MooTools’ way to doing Event Delegation. Saves us you having to bind 2 events and callbacks to both controls by just binding to the parent element.

The movement methods. Very minimal logic, they literally just set variables.

move: function(e, el) {
    // based upon image id, it will match a method name.
    this[el.get("id")](); // call it dynamically
},

moveLeft: function() {
    // set the next frame coming to previous one or last
    var next = (this.index == 0) ? this.elements.length-1 : this.index-1;
    this.swapFrames(next);
    this.fireEvent("left");
},

moveRight: function() {
    // set the next frame coming to next one or first
    var next = (this.index < this.elements.length-1) ? this.index+1 : 0;
    this.swapFrames(next);
    this.fireEvent("right");
},

Now we get to the more interesting parts. The actual swapping of the content is the core of the Class and is what we will modify later when we extend it to make it work differently.

The base class version does a VERY simple transition based around tweening the opacity of the 2 relevant content panes. One fades in while the other fades out.

swapFrames: function(next) {
    // element currently visible is in this.index (as key of this.elements array)
    var curEl = this.elements[this.index];

    // clean up from before, just in case
    curEl.get("tween").removeEvents();

    // reset element and set tween options.
    curEl.set({
        "tween": {
            link: "cancel",
            onComplete: function() {
                // add a css class that sets display to none, for example
                this.element.addClass("hide");
            }
        },
        styles: {
            opacity: 1 // initial opacity reset in case quick clicks
        }
    }).fade(0);

    // now set our new visible frame from this.moveLeft/Right argument
    this.index = next;

    var newEl = this.elements[this.index];
    //clean up, reset, show and fade in.
    newEl.get("tween").removeEvents();
    newEl.setStyle("opacity", 0).removeClass("hide").fade(1);
}

The end result: panes will cross-fade between each other, giving a morphing impression. Less is more, as they say.

Finally, we have 2 small methods that start and stop the automatic rotation. To keep the user interested in your site content, you really need to take no more than 2.5 second from their initial impression of the site or they may _subconciously_ lose interest and just bounce based upon the failure to connect with content shown from the start.

startRotation: function() {
    clearInterval(this.timer);
    this.controls.fade(.5);
    this.timer = this.moveRight.periodical(this.options.delay, this);
    this.fireEvent("start");
},
stopRotation: function() {
    clearInterval(this.timer);
    this.controls.fade(1);
    this.fireEvent("stop");
}

// and end class...
});

The controls collection we did earlier fades up and down based upon interaction: when it's stopped, the user is 'over' the element so we make the left and right more visible and we fade them out afterwards so they are less distracting.

This is it. To call the Class with your default options, all you need is:

new contentSwapper(document.id("rotator"));

You can, of course, attach event callbacks that respond to the ones the class has fired:

new contentSwapper.Fancy(document.id("rotator"), {
    onReady: function() {
        console.log("we are up!");
    },
    onStart: function() {
        console.log("and we are moving");
    },
    onStop: function() {
        console.log("Oh! they are reading with mouse on top!");
    }
});

... and so forth and so forth.

Simple. Now, imagine you are happy with your base Class but would like to extend it somewhat, by modifying it slightly to better suit your needs. In this case, we no longer desire to have a standard opacity cross-fade transition between panes so we will try to override that.

MooTools allows you to use the Extends: mutator(?) as part of your class declaration.

contentSwapper.Fancy = new Class({

    Extends: contentSwapper,

    initialize: function(element, options) {
        this.parent(element, options);
    },

We have now extended the base class and have everything it does inherited. But we want to actually override one of the methods to make things snazzy. We will try to make a vertical transition of the new pane over the old one as an experiment.

swapFrames: function(next) {
    var curEl = this.elements[this.index];
    // using morph for multiple CSS properties we will adjust
    // on the same timer, eg, opacity and margintop:
    curEl.get("morph").removeEvents();
    curEl.set({
        styles: {
            zIndex: 1000,
            opacity: 1
        },
        "morph": {
            link: "cancel",
            duration: 1000,
            onComplete: function() {
                this.element.addClass("hide");
            }
        }
    }).morph({
        // we really just want opacity as it looked better but experiment
        opacity: 0
    });

    this.index = next;

    // bring the new element in from the top, 280px.
    var newEl = this.elements[this.index];
    newEl.get("morph").removeEvents();
    newEl.removeClass("hide").setStyles({
        zIndex: 1001,
        marginTop: -280,
        opacity: 0
    }).morph({
        marginTop: 0,
        opacity: 1
    });
}

}); // end extended class

That's it. Now, you can improve that further by setting the marginTop offset into the Fancy options or read the height of this.element instead, your call.

To use the alternative and fancier way of transitioning, you do:

new contentSwapper.Fancy(document.id("rotator"));

Supplemental CSS required:

img.contentControl {
    position: absolute;
    margin-top: 90px;
    z-index: 10000;
    cursor: pointer;
    _cursor: hand;
}
#moveLeft {
    margin-left: 0;
}

#moveRight {
    margin-left: 662px;
}

Dead simple, isn't it? Have fun with MooTools. Any comments, questions or feedback, @D_mitar on Twitter or coda- on #mootools (irc.freenode.net).