Wednesday, 20 June 2012

Barebones Javascript Framework

Basic Philosophy :

Any full fledged web UI ends up becoming tightly coupled with its javascript framework -jQuery, dojo, mootools ,e.t.c. Hence any component developed for one project is hard to reuse for another project . Attempting to use multiple libraries on the same project will lead to performance issues and the usual namespacing problems. This leads us to keep on rewriting the same components.The main problem is that testing and bug fixing done in one place is not applicable for the other because many of the bugs are at times due to the javascript framework.
Eg : improper use of dojo dijits have led to numerous bugs and waste of a development time.

The Suggested Solution :
Instead of overrelying on the framework which have been made keeping in mind ancient browsers relying on many practices which can be considered bad in the long run , we can stick to native Javascript and CSS solutions as much as possible.
Problem :
Many of things achieved in frameworks cannot be achieved using native JS. While that might be the case with older javascript and CSS versions, but in reality the simple utility functions introduced in frameworks have now been adapted into native javascript.

So , the target is to provide the new magic native functions in older browsers and ensure cross browser compatibility. At the same time we start shifting our codebase to native javascript which will basically reduce our dependency on frameworks. And as more browsers support these functions , the size of the library would actually reduce , While frameworks tend to get bloated over time - just compare the core javascript library size of all major frameworks.

Eg: dojo.query ( most important function in dojo core lib of size > 27 kb uncompressed ) or its analogous function in jQuery or other library which take nearly the same size can be replaced with document.querySelectorAll in all modern browsers.

Target Gist :
Make older browsers compatible with latest standards for cross browser compatibility and shift our codebase to native javascript which have all the required powerful functions that we commonly use in frameworks.

Benefits:
- Reusability of testing and bug fixing experience across all UI frameworks
- Can create and maintain a library of useful UI components and be able to use them on any clients projects which already use a specific javascript library , say dojo or jquery .
- Developer learning time won't be wasted mastering multiple frameworks and multiple sets of documentation
- Since we will be not using a lot of hacks hence we have a greater probability that the code would work on mulitple platforms and have proper navigation.
Case in Point : dojo dijits or jquery UI hack the html up using templated markup . Hence they need to manually redefine basic usability stuff like remember password in their code. By using a proper tehnique while their is a chance we might get a less glossier or cooler UI but we would get a UI which would be less buggy across multiple platforms and also get the normal benefits and navigation that the browser provides.

Main Gameplan:
Categorize the required functions as per complexity and frequency of use, then provide guidelines and make them available across all browsers. We can do it step by step in the following manner :

1)Basic Operations
Aim : Make all basic ECMA 3 javascript functions available across all browsers in the same way
Motivation :
    - Make the code which uses basic language features independent of libraries or framework for basic operations
    - Any browser complying with ECMA 3 standards would not need the file
    - code written can easily be moved from a project using jquery to one using dojo or where there are no liraries at all
   
Basic Operations :
    - String operations : directly overloaded into the existing string where the string operations are not available
    - JSON Manipulations : overload methods where they don't exist like JSON.stringify , JSON.parse e.t.c
    - Array operation : slice,join, indexOf unavailable in many older browsers
    - OOP syntactic sugar available in newer versions of JS  ( not sure what all features)
        // TODO create proper best practices document and list cross browser support
       
GamePlan :
    - No library namespace should be used ,add the functions directly to existing class in javascript
    Eg :
        String trim is not available in IE<8
        So we add it as follows :
       
        //Check if function exists
        if (typeof String.prototype.trim !== 'function') {
            //Override so that browser has trim()
            String.prototype.trim = function(s) {
                return s.replace(/^\s+|\s+$/g, "");
            }
        }


2)DOM Operations :
Aim : Basic aim is to make the code as less library dependent as possible
Motivation:
    - Isolate library dependent code and make the code reusable
    - Depend on native selectors
        - One of the most frequently used DOM function is dojo.query or $ to get an array of all required DOM nodes
        An uncompressed version of the selector can be upto 27 kb (dojo.query and nodeList)
        Alternative Solution is to use document.querySelectorAll which is available in IE < 8 , FF <3.1 and Safari < 2.1,  then provide it wherever it is not available
       
Basic Operations :
- Query Selectors   - Use document.querySelector , document.querySelectorAll . Provide it where it is not available
    - Currently unavailable in IE < 8 , FF <3.1 and Safari < 2.1 ( No need of browser detection- directly property detection )
    - Will Reduce code dependency on dojo.query or $ , making the code more reusable .
    - Code Size will reduce when the property is available on all browsers
- Nodelist manipulations - Provide utility functions but of small size to make it similar to dojo.query  // NOTE : Open to debate
- Event Attaching and Registering - Special emphasis on ability to detach whenever required
    - Need to ensure standard event flow on all browsers
        - Event Bubbling
        - Event Order
        - Event Cancelling methods ( prevent Default )
        - Special emphasis on form element events    
    - Maintain global registry
        - Follow model similar to dojo.behavior but with additional capabilities of deleting behavior   
- Standardization of form elements like radio button,checkbox,comobox [ For querying and validation ] without modifying their DOM     structure. Only add extra attributes wherever required to store information.
- Simple animate function and ability to plugin to 3rd party animation code like dojo.fx and jquery.fx
- Simple Timer for time based operations

Friday, 3 February 2012

InnerHTML : The biggest source of Ugly & Unreadable JS

If tomorrow browsers stopped supporting the innerHTML property , most of the worlds Javascript code would stop working except possible the "hello world" programs :P, But this can't hide the fact the worst JS written is mostly because of the overuse of innerHTML .
Problems :
 -> HTML inside JS file , extremely bad for maintainability
 -> Can overwrite existing data by mistake
 -> Can introduce invalid html into the page which would break the DOM tree practically ensuring that most of the JS in the page has bugs or does not work
 Example
    Given we need to add a person to list from a combobox similar to how you add people on facebook message or in email sender in yahoomail


    It could be acheived in many ways :
    a) When an option is selected in the combobox , we could get the user details construct the div element inside the javascript and append it to the box
    Something similar to this :
        element.onselect=function(){
// getData() gets a JSON object containing data of selected user 

            var data =getData(element.selectedIndex);
            var innerHtml="<div class='containBox'><span class='user'>"+ data.Name+"</span></div>";
            this.innerHTML=this.innerHTML+innerHtml;
        }
    Disadvantages :
    -To change DOM structure we need to access the javascript function
    -String gets bigger and harder to maintain as the widget functionality increases    
    -Population of data is cumbersome with contant appending
    -Easy to introduce bugs since html cannot be validated inside JS strings
   
    Alternative Approach  1 :
    b) In this approach we first create a template HTML copy the DOM element and then append it to the node, then we populate the data as required .
    Example :
        Append the template container as such in an HTML file (include the HTML file wherever required using server side script or dojo xhrGet )
        <div id="containBoxTemplate" class="templateContainer" style="display:none;">
            <div class='containBox'>
                <span class='user'></span>
            </div>
        </div>
       
        The above code can be now rewritten as :
        element.onselect=function(){
// getData() gets a JSON object containing data of selected user 

            var data =getData(element.selectedIndex);
            var innerHtml=dojo.byId("containBoxTemplate").innerHTML;           
            this.innerHTML=this.innerHTML+innerHtml;
            this.lastChild.innerHTML=data.name;       
        }
    Advantages :    
    -HTML template is easier to maintain
    -Probability of bugs are significantly reduced
   
    Disadvantages :
    -Data population is still cumbersome
   
    Alternative Approach 2 :
    c) In this approach we will programattically create all the elements and then populate data as required then append it
        element.onselect=function(){
// getData() gets a JSON object containing data of selected user 

            var data =getData(element.selectedIndex);
            var div = document.createElement("div");
            var span= document.createElement("span");
            span.className="user";
            span.innerHTML=data.name;
            div.appendChild(span);
            this.appendChild(div);           
        }
    Advantages :
    -Chance of accidental deletion of previous content is removed since we are not playing around with innerHTML of parent element
    -No Strings used , clear programmatic structure
    -Efficient
   
    Disadvantages :
    -Complex code
    -Hard to change the HTML template (DOM structure)
   
    While approach c) seems programatically correct , it makes for some really complex and unmaintainable code. It is a pure JS solution where it is not required.
   
    Alternative Approach 3 :
    d) In this approach we will clone the template ,populate the data and then append it
    Now Given the same HTML template ,the code can be rewritten as follows  :
    element.onselect=function(){
// getData() gets a JSON object containing data of selected user 

            var data =getData(element.selectedIndex);
            var cloneNode=dojo.clone(dojo.byId("containBoxTemplate"));
           
            //Query the cloned node only and populate data
            dojo.query(cloneNode).query("span.user")[0].innerHTML=data.name;
           
            this.appendChild(cloneNode);
        }
    Advantages :
    -Code is safe since it does not append to the DOM tree until it is fully populated 
    -Cannot affect existing data since we do not use innerHTML
    -Depends on template and does not modify it ( otherwise that would introduce bugs :) )
   
    Disadvantages :
    Can't think of any - well that would be too patronizing, i think this should be it
    -Slightly complex code 

End of the day none of the techniques are defacto standards to create new DOM elements (or widgets as we like to call them),but a combination of any of the alternative 3 techniques should provide a good combination of advantages and simple code.I would personally use option d) ( no wonder i couldn't think of disadvantages) but any suggestions and better practice would be duly appreciated.Please do share what you practice and would prefer in the above mentioned scenario.
   

Thursday, 2 February 2012

dojo.query -The Magical DOM Selector and Best practices

One of the most powerful tool which is a quintessential part of any javascript library is the DOM selector function in the library .
Given an HTML snippet as

<div id="menuList">
    <span class="sub">sm Item</span>
    <span class="sub active">
        <span class="superSub">smthing more </span>       
    </span>
    <span class="sub">sm Item</span>
    <span class="sub">sm Item</span>
</div>

Normally in simple javascript the way to get the DOM element would be something like this :
var menu=document.getElementById("menuList");
//Get sub elements
var subItems=menu.childNodes;

Then you run a loop on the subItems to check if it is an Element or Text node and then apply the busines logic :
for( var i =0 ;i<subItems.length;i++){
    if(subItems[i].nodeType==document.ELEMENT_NODE){
        //Do something with the node
    }
}

Now the same thing using Dojo would be
    dojo.query("#menuList > span").forEach(function(x){
        //Do something with this
    });

Test 1:
        Usecase :     Modify sub menu items under id="menuList"
        Features Used : dojo.query with forEach on it
Well that drastically simplifies the code and makes it more readable , but that is just the tip of the  iceberg
Test 2 :
    Usecase : Create a function which takes the index of the sub menu item to make active ( i.e add the class active to it ) . There can be only one active item

Simple Javascript :
-First we need to get all the span elements under the menu in the same way
 -then check for the class name , remove the class active without affecting the class="sub" which is already there
 -add the class active for the required inde
Code :
        var subItems=menu.childNodes;
        for( var i =0 ;i<subItems.length;i++){
            if(subItems[i].nodeType==document.ELEMENT_NODE){
                subItems[i].className=subItems[i].className.split("active").join("");           
                if(i==INDEX)
                    subItems[i].className=subItems[i].className+" active";
            }
        }   

Result :
Achieved with relative ease but with extremely inefficient (who cares about efficiency in JS ! :) ) string functions .Biggest issue is the possibility of bugs in the logic if the string "active" instead of " active" , the code would have failed.More possibilities of bugs are there in a relatively very common activity .
   
Dojo :
Similar procedure :
Imagine doing the same thing with dojo.addClass and dojo.removeClass .It makes it much more easier .
2 Ways :
        Way 1 :
            var i=0;
            dojo.query("#menuList > span").forEach(function(x){
                if(i!=INDEX)
                    dojo.removeClass(x,"active");               
                else
                    dojo.addClass(x,"active");               
                i++;
            });

           
        Way 2 :
  But the magic of dojo.query is that most DOM utility functions can be applied on returned array directly.So , Best practice :
      dojo.query("#menuList > span").removeClass("active");
   dojo.addClass(dojo.query("#menuList > span")[INDEX],("active"));

    Result : 
Well,thats 2 lines of code with not a for loop in sight (ok ,its inside the function ) and which is more intutive,readable and easier to maintain.The possibility of bugs are also reduced to a great extent .   
Now in the same way we could do various things like :
    -> dojo.query(".....").style(PropertyName,NewValue)
    -> dojo.query(".....").attr(PropertyName,NewValue)  - Especially useful when we set properties in HTML as custom attributes
    -> ofcourse dojo.query(".....").addClass , dojo.query(".....").removeClass , dojo.query(".....").toggleClass
    -> Attach EventListeners - the most useful aspect

    Example Usecase : Onclick of any submenu item should make them active and rest inactive  :
    Code :
            dojo.query("#menuList > span").onclick(function(){
                    dojo.query("#menuList > span").removeClass("active");
                    dojo.addClass(this,"active");
            });

 This leads to much cleaner code than mixing the onclick with the html and calling a function .
   
The Problem of the unique ID :
Normally when we initially start writing JS we tend to assign ID's in too many places.Every DOM element that we need gets assigned an ID adn we directly get that element and work with it in our JS function -animation , validation e.t.c.
But We soon run up into the following issues :
 -> Run out of unique ID's - For someone like me used to variable names like "kk" , "i" and "asd" ("foo" for many others) , the ID's start getting longer and
 the chance of duplicity increases and with it unknown bugs
 -> May not have control of the JSP ( or anyother thing for that matter ) for which the JS is to be written which means that we need to contantly trouble the other guy to add Id's or do code merges ( god save your code when merging it )
 -> Duplicity of code , we might not see the generalization of business logic and end up writing duplicate code for what could be essentially the same thing

Well , the best practice would be to seperate discrete UI components like Top Menu , Body ,Status Bar e.t.c with discrete ID's and tag similar UI compontents with similar class name.
Then, the DOM element which needs to be selected should be queried according to the DOM structure .
Example :
Given the snippet
<body>
    <div id="menuList">
        <span class="sub">sm Item</span>
        <span class="sub active">
            <span class="superSub">smthing more </span>       
        </span>
        <span class="sub">sm Item</span>
        <span class="sub">sm Item</span>
    </div>
    <div id="contentbody">
        ...
    </div>
    <div id="commentContainer">
        <div class="comment">....</div>
        <div class="comment">....</div>
        <div class="comment">....</div>
    </div>
    <div id="footer">
    </div>
</body>

   
In this way the HTML should have as few Id's as possible so that CSS and JS are lot simpler and generalized to avoid duplicity of codes which directly reduces the number of bugs (lesser work for the M&E team - seems bad for me in the long run  :) ) . Especially now that we have dojo.query , it is much better to stop avoiding the usage of a thousand id's and rather an expression to get to the DOM element .
Something like :
dojo.query("#idName class1 tag1.className2 > span")
and then use it to implement JS logic .

Tuesday, 31 January 2012

AOP , Dojo and the Eventlistener

One of the most revoloutionary concepts to emerge after OOP ( ofcourse,the same OOP invented centuries back just after the invention of the fire and wheel ) is aspect oriented programming or AOP. While AOP has still not been widely adopted on a level that such a simple and amazing concept is expected to , nevertheless it has inspired enough people to spawn various language improvements, implementations and achitectures.
For those unfamiliar with AOP , a simple way to put it is -> injecting code at specific conditions called join points
Example of join points are :
-Function execution ( entry , exit and processing )
-Field change  -> i.e getters and setters
-Exception Conditions

The injection of code basically ensures that only business logic needs to be written in the function and other aspects such as :
-Logging -> the most irritating aspect of programming especially with property files
-Exception Handling
-Tracing

Ok , AOP is awesome - how do you use it ?
Well , while an enterprise implementation of AOP might need a new language ( think aspectj ), a framework (spring AOP ) or maybe an amazing architecture.It is actually quite simple to implement it to a limited level in javascript with dojo .

A simple AOP "hello world" would look like this (for those who understand java better than english)  :

Main.java  :
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World ");
    }
}


Aspect (pseudocode) : logging.aspect ( or logging.aj if you are using aspectj)

public aspect log {
    //The pointcut or jointpoint - this is the place to specific code conditions
    pointcut logEntry() : execution(* *.*(..));
  
    //The function to be executed before the condition occurs
    before() : logEntry() {      
        System.out.println("Entering :"+thisJoinPointStaticPart.getSignature().getName());  
    }
  
    //The function to be executed after the condition occurs
    after() : logEntry() {      
        System.out.println("Exiting :"+thisJoinPointStaticPart.getSignature().getName());  
    }
}


Output :

Entering main
Hello world

Explanation for dummies :
The pointcut in its weird syntax (yeah its aspectj, i accept it ok.. ) is the condition where the code should be injected.
The "thisJoinPointStaticPart" gives us information about the joint point so that we can use it in the function .
It is similar to regular expression to specify a condition (ok not very similar ,regexp fans) where the code can be injected.In this way we can seperate code to be
executed before and after the business logic though it is just "hello world" here.In this way logging is seperated from our business code. In the same way we can seperate exception handling , validation,resource allocation and deallocation e.t.c from our code leading to easy,maintanable and most importantly readable code (ok atleast in theory - we guys can create disorder even with a straight line ).

Now in the real world shifting to AOP would be a pain, the alternatives are
- learn a new language
- learn a new framework
- design an awesome architecture

But in the gravity defying world of javascript it can be quite easy - especially with dojo -that baby dinosaur of a JS library that IBM loves
Dojo has had a package for AOP  from version 1.1 ( wow , even though AOP is quite old) the "dojox.lang.aspect" package

Example code :

dojo.require("dojox.lang.aspect");
var aop = dojox.lang.aspect;


Now that we have the aop object , how do we use it ?
Given that we have a JS class (now don't ask me if JS has classes-they have something in their own gravity defying way  ):

myclass=function(n){
    this.name=n;  
    this.setName=function(n){
        this.name=n;
    }  
    this.talk=function(){      
        console.log(this.name);
    }
}

Now the aspect can be applied to in the following way :

kk=new myclass();
aop.advise(kk, [/.*/], {
    before: function(){
        var instance = aop.getContext().joinPoint;
        console.log("Entered "+instance.targetName);
    }
});

Yes , the same weird syntax that you can find no documentation about .Well but the code seems quite simple
"kk" is an object and a regular expression(the 2nd argument) is applied on it so whenever its functions are called the code is executed before it .

Now before you want a tutorial or actual documentation ,it'd be better to explain why you actually might use it - especially in javascript !
Javascript is possibly the worst language to write structured code - since it is gravity defying in every way (yes it seems to want to use every new language
concept that is being thought of ) and that is exactly the reason why it is even more harder to actually find the place where we might want to add some code. JS if well written ( i can't say that with a straight face ) can be extremely unreadable and AOP provides a good way to add code and seperate it from the original code without actually reading the code -just plain playing with it in the firebug console would do .
But the main reason are Eventlisteners :
- While JS took visual programming to a new,easier and standard level it created something called eventlisteners. Now while they are awesome but
the only issue with them is that the function could have been attached anywhere in millions of lines of obfuscated JS code or in the hundreds of JS
files included onto one JSP file ( think portal and the pagebuilder JS monster ["undocumented monster"] ) .
A simple example:
Given a element as :

<div id="cl" style="display: block;width: 100px;height: 100px;background: black;"></div>

<script>
dojo.addOnLoad(function(){  
    k=new myclass("Something");
    dojo.query("#cl").onclick(function(){
        k.talk();  
    });
});
</script>
<script>
//The same class we used earlier
myclass=function(n){
    this.name=n;  
    this.setName=function(n){
        this.name=n;
    }  
    this.talk=function(){      
        console.log(this.name);
    }
}
</script>



Now if we want to find out what function was called through the eventlistener , unless we get to the source there is no easy way to find out using firebug(yes the greatest JS dev. tool).A simple printing of the 'onclick' function would have sufficed in simpler times when there were no event listeners.But adding a simple aspect to all the classes in which your custom functions are encapsulated would make life so much more easier in tracing the function call.
Example :
//yeah the same example
aop.advise(k, [/.*/], {
    before: function(){
         var instance = aop.getContext().joinPoint;
        console.log("Entered "+instance.targetName);
    }
});


Now when we click the div area we get :

Entered talk
Something

That makes life so much more easier (especially if you are in a maintenance project like me :) )
-> Add a little more info to your aspect and it becomes the perfect logger without you writing a million lines of code in every JS function.
Now if i could just think of a better usecase - something that is not about logging ,just joking :
-> Animation Triggers - imagine just setting the value of a DOM element and it animates itself
-> Tracing timers , yes we do need to keep track of those functions which can kill your browser
e.t.c ,(yes , i just ran out of ideas)

A complete tutorial on the dojox.aspect can be found here :
http://lazutkin.com/blog/2008/may/18/aop-aspect-javascript-dojo/
    Author : Eugene - Thank you eugene , you are god !!

Please do check the wiki page on "Aspect oriented programming" and AspectJ language if you like the concept or have finally decided to give it a look