Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Saturday, April 20, 2013

Jasmine Tips: Spies!

We Started using Jasmine for JavaScript testing about 4 months ago. It was chosen because it resembles rspec, and lately minimizing context shift has been a goal for our team. So far I really like Jasmine. There are however, some cases that can be frustrating for someone new to unit tests with JavaScript or Jasmine.

Undersanding spyOn

One of the most important parts of Jasmine tests is understanding spies. I use spyOn because jasmine.spy is a long string to type. Spies can be confusing initially, but they are very useful. Their primary function is to check that a specific method is called, but they can also be used for stubbing.
What spy does is replace the argument with a function that tracks function calls. This means that the replaced function will not be called, the spy has taken its place.

This can be useful when testing objects that involve form submissions, it prevents a situation where your test browser keeps submitting and never finishes the suite.

andCallThrough()

You might want the method being spied on to be called as well. Sometimes not doing so will cause an exception. This is easy to do.

andReturn()

It is also possible to force the spy to return a specific value. This can be useful for stubbing external methods and testing how your code responds based on external conditions, withought going through the trouble of causing those changes. It also helps keep the unit tests isolated, which is very good.

andCallFake()

For testing callbacks it is possible to mock a response, and make sure the correct responses are triggered for different cases. The below example is a little long. But what is happen is that andCallFake is used to make sure that the correct callbacks are used to respond to save success and failure.

Checking Events

A common test I will write is to make sure that an event is getting fire when a method is called. For this you want to use a spy. I usually use spyOn for this. The important pattern to remember is.
  1. spy
  2. bind
  3. trigger event
  4. expect
The first step is to spy on the event you expect to be trigger. Next, if necessary, bind your spy to the event. Trigger that event. And then expect the spy to have been called.

Another option for the case above would be to spy on the model's trigger method. This has the benefit of terseness. It also requires testing the arguments. This can be done simply

Nick hates the word "Gotchas!", I agree

The spy, bind, trigger, expect pattern is simple enough. But when the object being spec'd is doing the binding the patter can be more difficult to grasp. Look at the below example.

This will fail, because spyOn replaces the reference to the function with a spy, but the original method has already been bound to the event. The pattern above is: bind, spy, trigger, expect. It will not work. I like to fix this by splitting event binding out of the initiaize method.

The above code will pass because the spy has been bound to the event. And you can see that it has taken on the form of spy, bind, trigger, expect.
In general it is a good do as little as possible directly in the constructor (initialize for backbone classes). This makes the code more testable. And writing testable code is good.

Conclusion

Spies are awesome. They are kinda a Swiss Army knife of Jasmine testing. Its a straightforward way of solving a lot problems associated with unit testing (stubbing, mocking, testing events). They can be tricky, but with a little experience they can be very useful.

Sunday, April 14, 2013

Why I'm using Coffeescript... For Now

To put it mildly, JavaScript has some idiosyncrasies. I've enjoyed manipulating, and exploiting some of JavaScript's more interesting aspects. However, it's uniqueness can cause confusion. It is perfectly fine to those with experience with JavaScript, but they often trip up even experience programmers that aren't well versed in the language.

Concerns about debugging

One major advantage of JavaScript development is how well debugging is integrated. Chrome and now Firefox debugging is pretty awesome. The only comparable interfaces I've used are Eclipse and XCode, and Chrome preforms better than either of these.
Initially I was concerned that the change in syntax and line numbers would make debugging difficult. Put simply, this turns out to this is much less of an issue than I anticipated. It is trivial to identify corresponding CoffeeScript code working backward from compiled JavaScript.

Class creation

It starts with simple class creation. In JavaScript there isn't anything to distinguish a Class from any other named function.
var MyClass = function(){};
That is, until you add methods to it.
MyClass.prototype.foo = function(){};
This is just weird.
CoffeeScript makes it a little more clear what is a class.
class MyClass   
    foo: ->

Which this is this

Here's a common scenario. I want to bind an instance method of an object to listen to an event (Mouse Click, AJAX response whatever). In java script I have to store this in a local variable so that I can use it later. Looks something like this.
var MyClass = function(){
    var t = this;
    $("a.bindo").click(function(){
        t.onClick();
    })
}

MyClass.prototype.onClick = function(){
    console.log("This is me", this);
}
I've used that pattern hundreds of time. It is useful, but again confusing to someone new to the language. The CoffeeScript version, by contrast, is succinct.
class MyClass   
    constructor: ->
        $("a.bindo").click @onClick

    onClick: => 
        console.log("This is me", @)
It is true that the developer has to understand on a conceptual level what is happening with the bind event, but I find that a simple character difference is more readily accessible and apparent than the JavaScript pattern.

Inheritance

CoffeeScript inheritance murders JavaScript inheritance. I have an older post on JavaScript prototype inheritance. It works (kinda), but again is unfamiliar to people coming from other languages.
CoffeeScript inheritance is easy, and offers something I've not seen cleanly executed in raw JavaScript. The super keyword in CoffeeScript called the super
in JavaScript to call the parent method it looks something like this.
var MyClass = function(){
    ParentClassName.call(this, arguments)
}
Now I think call and apply are super dope, but most of the time I would prefer to never touch them. Now the CoffeeScript equivalent
class MyClass extends ParentClassName
    constructor: ->
        super
That's is way easier, and way less likely to cause hard to track down bugs.

Integration with Ruby stack

In the 12 months we moved over to a Ruby stack after spending a long neolithic era using PHP. It is very easy to integrate CoffeeScript into an application using several Ruby frameworks including: Rails, Sinatra, and Serve. Not having to do any extra work to integrate CoffeeScript was a huge plus!

Dart

Dart looks awesome and I'll be following its progress, once it is supported by a couple major browsers (not just compiled to JavaScript), I'll be more than happy to give it a serious look. Strong typing and isolates are enough reason for serious consideration.

Conclusion

CoffeeScript isn't perfect. And I'm looking forward to new languages to come out for the browser platform. But the bottom line is productivity. And right now, for me and our team, CoffeeScript has a few key features that make web client dev less of a grind, while allowing us to leverage our JavaScript knowledge.

Wednesday, June 6, 2012

Dissapointed Dad


Another pass at the paralax plugin I developed a few months ago. This time messing around with inserting negative rel values for different layers. I think the effect is a lot more compelling.

The collage named "Dissapointed Dad" was create by my friend Tim Scahill.

Saturday, May 5, 2012

Javascript OOP - Multiple Inheritance

Multiple inheritance is a behavior when a single class extends the functionality of multiple parent classes. For example, an alarm-clock has the properties of both a clock and an alarm. The desired situation is that the parent classes handle the distinct behaviors without needing to know about each other. For an alarm-clock, this means that the clock class will track time, the alarm class would make an alarm action, and the alarm-clock class would allow different events to be set at specific times of the clock.

Many OOP languages support multiple inheritance either directly (C++) or through some other mechanism (Java Interfaces, Objective-C Protocols). How can this be implement in JavaScript. Enter jQuery.

jQuery has this baller function, $.extend. It receives n arguments ( $.extend(arg0, arg1, …., argN); ) and all the members of argN are copied to arg(N-1), then from arg(N-1) to arg(N-2), and so on down the line. This is perfect for creating options for jQuery parameters. However, it can also be used to implement Multiple Inheritance for javascript objects.

Lets check out a very simple, snarky alarm clock.

//create parent Alarm
Alarm = function(){};
//with one instance method
Alarm.prototype.ring = function(){
     console.log("AAAAAHHHHHHHH");
}

//create parent Clock
Clock = function(){};
//with one instance method
Clock.prototype.time = function(){
     console.log("is an illusion");
}

//create child
AlarmClock = function(){};
//inherit from A and B
AlarmClock.prototype = $.extend(new Clock(), new Alarm()); // BOOM!

c = new AlarmClock();
c.ring();//AAAAAHHHHHHHH
c.time();//is an illusion

Pretty cool. However, multiple inheritance presents situations that single inheritance doesn't. What happens if parent classes contain identically named methods? In $.extend the right hand parameter overrides the one to its left. So, if ClassA and ClassB have identically named methods, then ClassB's will override ClassA's.

Lets see this in action.

//create parent with cry
Human = function(){};
Human.prototype.cry = function(){
     console.log("OUCH!!!");
}

//create another parent, also with cry
SpaceMarine = function(){};
SpaceMarine.prototype.cry = function(){
     console.log("FOR THE EMPEROR!");
};

//inherit from both parents
Character = function(){};
Character.prototype = $.extend(new Human(), new SpaceMarine()); // BOOM!
c = new Character();
c. cry(); //FOR THE EMPEROR!
//cry is inherited from SpaceMarine

Multiple inheritance also evokes an interesting question for object type. What is the object type of ClassC? In this case only the leftmost parent class passes on its type.

ClassC = function(){};
ClassC.prototype = $.extend(new ClassA(), new ClassB()); // BOOM!
var c = new ClassC();
console.log(c instanceof ClassA); //true
console.log(c instanceof ClassB); //false

This technique requires some function to duplicate properties and methods from object to object. I use jQuery.extend, because I use jQuery it on most projects, but there could be alternatives out there, and it would be simple to create a  rudimentary replacement.

Multiple inheritance is especially useful with protocols. For example, a single class to provide data for and respond to interaction with a datalist, ala UIKit's UITableViewDataSource and UITableViewDelegate. To allow a single object to perform two distinct tasks, some form of multiple inheritance must be used.

Thursday, March 29, 2012

What I learned from THREE.js: calling parent methods

Three.js is awesome, it simplifies working with WebGL, and is a great source for JavaScript ideas. This article presents another idea I came across while working THREE.js source; applying a parent class' constructor to an inheriting class. To do this the parent constructor is invoked using apply or call.

var ClassA = function(){};

//ClassB inherits ClassA
var ClassB = function(){
    ClassA.call(this); //run parent constructor on this object
};
ClassB.prototype = new ClassA(); //inherit parent methods

The example above does call the parent constructor, but doesn't accomplish anything. Instance methods and properties are added to the prototype on the last line of the block. Calling the parent constructor is only useful when there are parameters. A simple example is extending DataModel object that manipulate and hold information pulled from a database.

//assume data has been converted to a javascript object
var DataModel = function(data){
    data = data || {}; //make sure data is a valid object
    this.id = data.id || ""; //stores id on the instance
};

//person inherits from data model
var Person = function(data){
    DataModel.call(this, data); //get a valid id

    data = data || {}; //make sure data is a valid object
    this.firstName = data.firstName || ""; //stores id on the instance
    this.lastName = data.lastName || ""; //stores id on the instance
}
Person.prototype = new DataModel();

Now any class that extends DataModel will have some defined value for id. Similarly an extension of Person would have a defined value for firstName and lastName.

You can take this concept even further. It can be used when overriding inherited methods as well. Note: this will not work as expected if using THREE.js' technique of defining instance methods as explained in the preceding THREE.js article.

In this next block, the DataModel and Person classes implement a toObject function, that returns the instance property values. The DataModel handles the the id property, while the Person handles the first and lastName properties.

//returns the 
DataModel.prototype.toObj = function(){
    var obj;
    obj.id = this.id;
    return obj;
}

//overrides DataModel toObj.
Person.prototype.toObj = function(){
    var obj = DataModel.prototype.call(this); //get object with id
    obj.firstName = this.firstName;
    obj.lastName = this.lastName;
    return obj;
}

In retrospect, this idea seems obvious. After all, this article demonstrates how to use call or apply to implement private methods, and the idea presented in this post simply uses the same concept on parent methods.

Sunday, March 25, 2012

What I learned from THREE.js: new way to encapsulate

Recently I've had the oportunity to work extensively with THREE.js, a WebGL framework primarily authored by Mr. Doob. This library simplifies the use of the powerful WebGL graphics engine. Not only is this library an excellent resource for WebGL, it also introduced me to some new techniques for JavaScript encapsulation and inheritance. This article presents a technique for simplifying method definition syntax.

Restructuring Class Implementation

The common method for adding methods to an object is to add the method names directly to the prototype.

var ClassName = function(){};
ClassName.prototype.methodName = function(){};

This works, but is a little verbose, and requires a lot of find/replace when overriding inherited methods. The clases in THREE.js avoid this repetition by defining instance methods during object construction. It looks like this.

var ClassName = function(){
        this.methodName = function(){};
};

The benefits are twofold. The syntax for method definition and overriding has been simplified. Also, Using the constructor for encapsulation obviates the use of closures to obfuscate private methods (as demonstrated in this previous post), further simplifying syntax.

Consider the following two classes.

/*
Class: ClassA
*/
var ClassA = function () {
        //add functions to object inside of constructor, simpler syntax
        this.foo = function () {
            console.log("parent foo");
            privateFoo.call(this);
        };
        //private methods also defined inside constructor
        function privateFoo() {
            console.log("parent private foo");
        }
    };

/*
Class: classB
inherits from classA.
*/
var ClassB = function () {
        this.foo = function () {
            console.log("child foo");
            ClassB.prototype.foo.call(this); //calling parent method
        };

        this.bar = function () {
            console.log("child bar");
        };
    };
ClassB.prototype = new ClassA();

var b = new ClassB();
b.bar(); //child bar
b.foo(); //child foo, parent foo, parent private foo

This is significantly more concise, and worth investigating further.

Issues

An obvious fault is that to call the parent method you have to access the child's prototype. This is conceptually confusing and a regression from the previously outlined method, where the parent prototype would be accessed (ie. ClassA.foo.call(this) ).

There is also a potential performance issue. It is possible that creating a new definition of instance methods at runtime will have an adverse affect on either memory footprint or speed. This will have to be tested.

Conclusion

It is to early to tell if I will start using this particular encapsulation scheme. The parent method mapping is a little strange, and the performance issue is something I'll have to investigate further. I will post any findings.

Saturday, March 10, 2012

JavaScript OOP - Extending Objects

An interesting concept in Objective-C is the Category. Categories allow developers to add methods to existing Classes, even if the source code is unavailable. This can be done in JavaScript by adding functions to an existing class' prototype. This article demonstrates how to add methods to Array.

/*
  * Function: removeItem
  *  This function removes all occurrences of this item
  *  
  * Parameter:
  *  item - The item being removed. Can be primitive or object. If object must be same instance.
  */
 Array.prototype.removeItem = function(item){
  var length = this.length, i;
  
  for(i=0; i < length; i++){
   var member = this.pop();
   
   if(member !== item){
    this.unshift(member);
   }
  }
 };
Now items can be removed from any array just by calling that method.
//Remove Numbers
var numberArr = [1,2,3,2];
console.log(numberArr); // 1 2 3 2
numberArr.removeItem(2);
console.log(numberArr); // 1 3

//Remove string
var numberArr = ["1","2","3","2"];
console.log(numberArr); // "1" "2" "3" "2"
numberArr.removeItem("2");
console.log(numberArr); // "1" "3"

How cool is that? Even objects defined with native code can be extended to increase their utility and ease of use.

Thursday, February 23, 2012

JavaScript OOP - type checking and inheritance

When working on large project, likely requiring a large OOP structure for coherence, it is important to have consistent types. If you're expecting an object to have this property or that method, it should be there. In fact a major benefit of working with a statically typed language such as Java or Objective-C, is that variable type is determined at compile time, is that variable type is strictly enforced. For example, when a function receives a parameter that is of incorrect type, a compile time warning or error can be generated. By contrast, JavaScript is dynamically typed (determined at runtime). This can lead to type runtime errors that can be difficult to track down.

To combat this, the instanceof operator can be used to enforce type. instanceof B evaluates to true when a is an instance of B, simple enough. What is really interesting is that when using the inheritance method outlined previously instanceof can also be used to determine if an object inherits from a prototype as well as implementing one.

//Create prototypes
var classA = function(){};
var classB = function(){};
classB.prototype = new classA(); //classB inherits from classA

var a = new classA();
var b = new classB();

//a is not identified as an instance of classB,   
console.log(a instanceof classA); //true
console.log(a instanceof classB); //false

//b is identified as an instance of classA. 
console.log(b instanceof classB); //true
console.log(b instanceof classA); //true


Here is a quick example of how to use this in a function to enforce type safety.

//function that requires classB
function needsClassB(b){
  if(!(b instanceof classB)){
    throw("needsClassB passed invalid argument: "+b);
  }

  console.log("we can do super awesome classB only stuff!");
}

//objects
var a = new classA();
var b = new classB();

needsClassB(b); //we can do super awesome classB only stuff!
needsClassB(a); //throws error

This lacks the elegance of defining types in the method definition, as you would in Java or Objective-C, but JavaScript often requires compromise. And this technique provides as least a measure of certainty that the arguments are going to be what is expected.

Thursday, February 9, 2012

Javascript OOP - NameSpaces

A fundamental issue with any large code project is maintaining unique identifiers, that is making sure that classes or global functions and variables have unique names. This problem can be mitigated with the use of namespaces. Grouping classes into sets is an explicit feature in many languages that support OOP: Java (packages), Python (modules), and C++(namespaces). JavaScript namespaces are not built in, but are possible with the requisite initiative.

This post demonstrates a simple namespace implementation. Two object prototypes named Person are created in two separate namespaces and thereby avoid convolution.

//if namespace exist use it, otherwise use a new object
var ENG = ENG || {};
//add person to the namespace
ENG.Person = function(){};
ENG.Person.prototype.sayHi = function(){
    console.log("Good Day, My name is John");
}

//if namespace exists use it, otherwise use a new object
var GRM = GRM || {};
//add person to the namespace
GRM.Person = function(){};
GRM.Person.prototype.sayHi = function(){
    console.log("Guten Tag, Ich Heiße Johan");
}

//create two people from two different namespaces.
var englishman = new ENG.Person();
var german = new GRM.Person();

englishman.sayHi(); // Good Day, My name is John
german.sayHi();     // Guten Tag, Ich Heiße Johan

Namespace switching isn't built into JavaScript, so it would be advisable to keep the namespace identifiers short, because they will have to be repeated.

Prominent libraries that encapsulate using namespace like structures:
$ - jQuery, Prototype
THREE - Three.js

For a library that offers a rich set of namespace functionality, investigate Namespace.js.

Saturday, January 28, 2012

JavaScript OOP - Protocols


Protocol are essential in life as well as programming. They define expected and required behaviors for different situations, allowing meaningful interaction to take place between unfamiliar entities. This allows common tasks to be completed in the face of new circumstances with minimal improvisation.

This post expands upon prototype inheritance, as outlined here, and demonstrates an implementation of protocols using Javascript objects. The common task in this case if the creation of a Mathematical series, and the protocol defines the series content

Protocol Base Class

This protocol (SeriesDataProvider) will have one required and one optional method. The required method (valueForIndex) generates the value of the member of a series for an index. it is require because an error will be thrown if it is not overridden in the inheriting class. The optional method (initFinished) is a callback that is called after the Series has been created.

/*/*
 * Protocol constructor
 */
var SeriesDataProvider = function(){};

//required method
SeriesDataProvider.prototype.valueForIndex = function(index){
     throw("this should be overridden by the inheriting class");
};

//optional method
//the passed series has finished initialization
SeriesDataProvider.prototype.initFinished = function(series){
     console.log("Series initialized", series);
};

*Series*

This next class uses a series data provider to generate its values. Looping from start to end indices asking the provider what the values are.

/*
/*
 * series implementation
 */
var Series = function(startIndex, endIndex, dataProvider){
     dataProvider.series = this;     

     //get servies values for indices in range
     for(var i=startIndex; i <= endIndex; i++){
          this.push(dataProvider.valueForIndex(i));
     }
     
     dataProvider.initFinished(this);
};
Series.prototype = new Array();

This first implementation overrides both inherited methods, and generates an arithmetic series.

var arith = new SeriesDataProvider();
arith.valueForIndex = function(i){
      return 1+i*3;
};
var arithSeries = new Series(0, 4, arith); //1, 4, 7, 10, 13

The next implementation overrides both inherited methods, creating a geometric series.

var geo = new SeriesDataProvider();
geo.valueForIndex = function(i){
      return 5+Math.pow(3,i);
};
var geoSeries = new Series(0, 4, geo); //6, 8, 14, 32, 86

This demonstrates how two similar, yet distinct, entities can be created with a minimal amount of new code. And while the example above illustrates a trivial case, the concept can be applied to more practical uses. One such case would be a protocol that works with a list of elements, providing elements for the list and determining behavior for different UI events.

EDIT:
Originally this post said that it was about delegates. That was not correct.

See Also:
Protocol in action.
Javascript Prototype inheritance

Friday, December 23, 2011

Straight Forward (sorta) custom Android Views

Pre-ramble

I started mobile development on the iOS platform, so, naturally I'm completely spoiled. So, just as naturally, I've found a number of aspects of Android development to be very frustrating. One major frustration was creating custom views. I say was, because like just about everything in programming once a method is discovered things suddenly become less opaque than previously perceived.

The difficultly I had with creating custom views stems from the same source as majority of my android problems: terrible documentation. As a spoiled iOS developer I'm use to a thoroughly documented library complete with working examples. Android is a completely different story, but I digress. After about a week of banging my head against my keyboard, I was able to come up with an apparently novel method from creating and manipulating custom views in a simple way. I'm sure this has been done before, but I haven't seen it.

Actually Doing the Thing

The first thing to do is create an xml file for the view definition. The root element probably needs to be some kind of layout, so that children can be added. Any child elements added need to have an id unique within the file.


    
   
   
   



Next a Java Class needs to be created inheriting from the class used as the root element in the XML definition.

The Class needs to contains two constructors one that only passes the context as a parameter and another that also passes an Attribute Set. This second constructor allows xml attributes to be added to the element.

To manipulate child views, they need to be grabbed after to the xml file is loaded and ready for action. This is done by overriding the onFinishInflate method, and then finding them by id and assigning them instance variables.

package com.packagename.CustomView

public class CustomView extends LinearLayout{

   public TextView text1, text2;
   public ImageView icon;

   public BelligerentDetailView(Context context){  
      super(context);
   }
 
   public BelligerentDetailView(Context context, AttributeSet attrs){  
      super(context, attrs);
   }
 
   @Override
   protected void onFinishInflate (){
      text1  = (TextView)findViewById(R.id.text1);
      text2  = (TextView)findViewById(R.id.text2);
      icon  = (ImageView)findViewById(R.id.icon);
   }
   
}

Return to XML definition and replace the root element with the full package name (ex. com.packagename.CustomView)





Now the custom view can be included in another XML layout file as a subview.


  

Sunday, December 11, 2011

Chamber of the Painted Table


Click Here to interact (Works in Chrome, works better in Safari).

This is the second of my "A Song of Ice and Fire" webkit experiments. The first was a simple animation built using a pretty sweet WYSIWYG. This one is a little more complex. I wanted to experiment with manipulating 3d objects, but didn't want to get bogged down with complicated framework. Webkit-3d transforms seemed like the ticket.

I've create a scene inspired by Aegon the Conqueror's Painted Table. There is a map of westeros on a large table with a spinning dice. Each face has the sigil of a major house on it (all of them involved in Aegon's War of Conquest). I attempted to add floors and walls, but the browser just couldn't handle it. It could be possible to reduce the size of the objects and simply create a smaller scene.

Transforms

To create the objects in the scene square divs are rotated and translated into position, adjusting transform origin where necessary. When transforming shapes within other transformed shapes the -webkit-transform-style attribute must be set to 'preserve-3d', otherwise the transforms will be projected onto the 'surface' of the container as 2d objects. Three containers serve as examples for the different attributes used to position the shapes.

#dice{
 -webkit-transform-style: preserve-3d;
 -webkit-transform-origin: 200px 200px;
 -webkit-transform: rotateX(45deg) rotateY(45deg);
}
#dice_tilt{
 -webkit-transform-style: preserve-3d;
 -webkit-transform-origin: 200px 200px;
 -webkit-transform: rotateY(15deg);
}
#dice_wrapper{
-webkit-transform-origin: 200px 200px;
 -webkit-transform: scaleX(0.3) scaleY(0.3) scaleZ(0.3) translateZ(335px);
}

The dice is rotated on is X and Y axis to make it stand on it point. The dice tilt rotates the dice to one side slightly to allow for a wobbly look, and the dice wrapper is moved above the table and is scaled down to 1/3 normal size.

The animation is based on a ~30 hz timer that updates the rotation of the Dice, and the dice tilt, to create the  the wobbling dice look. The dice_tilt has the inner rotation and the dice wrapper has the wobble (half speed rotation speed) applied to it.

Sprite3d and Matrix Transforms

The Sprite3d class allows the rotation, scale and translation of a div to be set; adjust the transform center, and the transform matrix to be recalculated on request. The class uses the sylvester.js http://sylvester.jcoglan.com/ library to combine the transforms before applying them to the -webkit-transform atribute.

View Change

The rest is simply capturing keyboard input and updating the transform values of the objects. I split rotation x, rotation z, and translation divs, the rotation axis are a little strange if all the transformations are applied to the same function.

Thursday, November 24, 2011

JavaScript OOP - Prototyping Encapsulation and Inheritance

JavaScript is a really cool language. Its flexibility allows a clever developer to achieve some incredible things. However, this unbridled freedom comes at a price. It is the responsibility of the programmer to impose order to this chaotic environment. A good first step in this daunting challenge is to implement some useful object oriented concepts. This post demonstrates how to implement encapsulation and inheritance for javascript prototype classes.

Encapsulation

The fundamental goal for encapsulation is to control what variables/functions are available for external access. The mechanism for doing this in JavaScript is a closure. By wrapping the class definition in a closure it is possible to have private functions accesible only this class, since objects outside of the closure won't be in the same scope.

(function(){
 
 //constructor
 window.JSObject = function(){
  this.publicInstanceVar1 = 1
 }; 

 // public function
 JSObject.prototype.foo = function(){
  privateFunction.apply(this); //call private function
 }; 

 //private function
 function bar(){} 

 var privateClassVar1 = "1"

}());

The constructor must be attached to the window, or declared outside of the closure, otherwise it will not be accessible externally. The public method is added to the object prototype. The private method is a function declared inside of the closure and must be called using apply or call to maintain the consistency the this variable.

Inheritance

Inheritance for a prototype object is very simple. Assigning a new parent object to the prototype of the inheriting object will do the trick.

(function(){
 window.Child = function(){};
 Child.prototype = new Parent();
}());

The instance variables and public functions are now available in the child class. The private methods and private class variables will not be inherited.

Click Here to see a demo.

Tuesday, May 10, 2011

jQuery OOP - Inheritance

In my last post I outlined how to achieve some encapsulation behaviors within a jQuery plugin framework. This time I'll be taking a look at inheritance. Specifically I want to able to inherit or override members of one class for use in an inheriting class.

The full objects and examples can be found here.

Super Class

To facilitate inheritance one change had to be made to the super class. The plugin needs a a function (hasFunction) that determines if the plugin responds to a given function.

(function($) {
        //public functions
        var methods = {
                init : function(options) {
                        var defaults = {};
                        $.extend(this, defaults, options);
                        ...
                        return this
                },
                //function to check if plugin responds to function
                hasFunction : function(functionName){
                        return (methods[functionName] !== undefined);
                }
        };                
        $.fn.objectA = function(method) {
                if (methods[method]) {
                        return methods[method].apply(this, 
                               Array.prototype.slice.call(arguments, 1));
                } else if (typeof method === 'object' || !method) {
                        return methods.init.apply(this, arguments);
                } else {
                        $.error('Method ' + method + ' does not exist on jQuery.');
                }
        };
})(jQuery);

Sub Class

Some more work has to be done on the sub class. There is the hasFunction method again, but now that function has to check its parent as well.

Also, In the initialization block two extra changes have to be made. After checking if this plugin responds to a method name, the plugin must check to see if the parent responds, and if so, call the method on the parent plugin. If the plugin is initializing, the parent must be initialized with the same parameters,

(function($) {
        //public functions
        var methods = {
                init : function(options) {
                        var defaults = {};
                        $.extend(this, defaults, options);
                        this.objectBInstance = "Intance B";
                        
                        return this;
                },
                //function to check if plugin responds to function
                hasFunction : function(functionName){
                    //does this or the super class respond to this?
                    return (methods[functionName] !== undefined || this.$super(functionName));
                }
        };        
        /*
                Initialization
        */        
        $.fn.objectB = function(method) {
                if (methods[method]) { //check this class for the method
                        return methods[method].apply(this, 
                                Array.prototype.slice.call(arguments, 1));
                } else if(this.objectA("hasFunction", method)){ //next check the parent
                        //use apply without changing to maintain args
                        return this.objectA.apply(this, arguments);
                }else if (typeof method === 'object' || !method) {//try to init
                        //inherit first inheritance method
                        this.objectA.apply(this, arguments); //inherit from objectA
                        this.$super = this.objectA; //objectA is $super                        
                        return methods.init.apply(this, arguments); //initialize this 
                } else {//if missing from parent/self and not init err out
                        $.error('Method ' + method + ' does not exist on jQuery.');
                }
        };
})(jQuery);

Summary
The inheritance method I outlined above enables public methods and instance variables can be inherited from the super class. In the future I would like to extend this to facilitate multiple inheritance.

Monday, April 4, 2011

jQuery OOP - Encapsulation

Since I already include jQuery in every project I work on. I figured why not try to implement some features of OOP within the framework of a jQuery plugin. In this post I'll be outlining how to implement some useful features of encapsulation.

The full object and examples can be found here.

Frame and Public/Private Functions

I would like to thank my friend Zach for the plugin method utilized in this code. The plugin reads in the method name and calls it from an object's methods. These methods can then be indirectly called outside of the plugin (ie. $(obj).plugin("function") ):
(function($) {
     var methods = {
          init : function(options) {              
               var settings = {
                    ...
               };
               $.extend(this, settings, options);
               
               $t = $(this);
               $t.each(function(){
                    ...
               });
               return this;
          },
          func1 : function(){}
     },

     $.fn.object = function(method) {
          if (methods[method]) {
               return methods[method].apply(this,
                             Array.prototype.slice.call(arguments, 1));
          } else if (typeof method === 'object' || !method) {
               return methods.init.apply(this, arguments);
          } else {
               $.error('Method ' + method + ' does not exist on jQuery.');
          }
     };
})(jQuery);     
The functions contained in the methods object also return values as expected. Since these functions are accessible outside of the plugin, and other functions defined inside the plugin are not; it is then possible to create public and private functions.
(function($) {
     //public functions
     var methods = {
          ....
          foo : function(){
               ...
          },
          bar : function (){
               //call private function
               privy.apply(this);
          }
     },
  //private functions
     function privy(){
          ...
     }
    ...
})(jQuery);     
The apply function is used to maintain consistent scoping for the this pointer. apply() should be used whenever the called function needs to reference the this object. To call the public version of a method inside of the plugin you have to call it from the methods object, (ie. methods.bar.apply(this)). Once instance variables are implemented, private methods can be used as getters and setters.

Class and Instance Variable
To attatch instance variables to individual objects, I used the $.extend function to attach the passed options object to this:
(function($){
     //public functions
     var methods = {
          init : function(options) {              
               $.extend(this, settings, options);
               //apply functionality to every member of the set sent in    
               $(this).each(function(){});
               return this;
          }
     ...
})(jQuery);     
Now these instance variables are accessible throughout the plugin.

The apply method should be used to call methods from inside the plugin. Otherwise this will be defined as the methods object (public methods) or the wrapping function itself (private methods).
(function($){
     //public functions
     var methods = {
          init : function(options) {              
               //default instance vars
               var settings = {
                    name : ""
               };
               $.extend(this, settings, options);
               //apply functionality to every member of the set sent    
               $(this).each(function(){});
               return this;
          },
          foo : function(){
               console.log(this.name);
          },
          bar : function (){
               bar.apply(this);
          }
     },
     ...
     function bar(){
          console.log(this.name);
     }
     ...
})(jQuery);     
Class variables are even simpler to implement, for example the methods object is a class variable. Any variable instantiated in the same scope will be a class variable.
(function($){
     var methods = {
     ...
     },
     //class variables
     class1 = 0;
     //private functions
     function bar(){
          class1++;
          console.log(class1);
     }
     ....
})(jQuery);     
Summary
In this post I've show how to implement parts of encapsulation within a jQuery plugin. Instance and class variables, as well as public and private methods were implemented. I figure thats a pretty good start.

Sunday, March 20, 2011

Richard III

When I was first learning jQuery, what immediately excited me was the ease of creating cool animations. Anyone who has tried to animate in JavaScript using setInterval can appreciate the elegance of $.animate(). One plugin that really caught my eye was a paralax plugin. It handled image layers: stacking them on top of each other and shifted them horizontally and vertically to simulate depth in a scene. With the right scene the effect is pretty cool.

Art
I'd like to thank my friend  Nolan Tredway for letting me use some of his work for this demo. The graphics in this scene come from a piece that depicts the nursery rhyme 'Humpty Dumpty' and its roots in the story of King Richard III of England and the Battle of Bosworth Field.


HTML/CSS
The html and css is pretty simple. Each layer of the scene is a png image with transparency. A relatively positioned div wraps the list of layer images from back to front in the scene. Each <img />  tag has a rel value corresponding to the z value read in by the plugin.

JavaScript
Once the images a lined up on top of each other, a JavaScript plugin tracks the mouse cursor and adjusts the position of the layers accordingly.
To do the plugin must:
  • keep track of mouse position
  • keep track of window size
  • update layer position on interval

Keep track of mouse position and window size
With jQuery tracking the mouse position is trivial.
var methods = {
     init : function(options){
          ...
          //listen for mouse move
          $(document).mousemove(methods.onMouseMove);
          ...
     },
     onMouseMove : function(event){
               mouseX = event.clientX;
               mouseY = event.clientY;
     }
}
...
var mouseX, mouseY;
As is tracking the mouse position.
var methods = {
     init : function(options){
          ...
          //get and keep window size
          $window.resize(methods.onWindowResize).resize();
          ...
     },
     onWindowResize : function(event){onWindowResize : function(event){
               wHeight = $window.height();
               wWidth = $window.width();
      }
}
...
var wHeight, wWidth;

}

Updating layer position
The meat of the plugin is responsible for shifting each layer based on its z index and mouse position.
var methods = {

var settings = {
        magnitudeX: 100, //control baseline of x movement
        magnitudeY: 50,  //control baseline of y movement
        paralaxFactor : 10 //sets baseline zindex for paralax movement
    }, $frames, originalPosition; //list of frames and original position

var methods = {
      init : function(options) {          
         if(options){
              $.extend(settings, options);
         }
            
         settings = $.extend(settings, options);
          ...
          $t = $(this);
          $frames = $t.children(".frame");
          $frames.each(function(){
               //store paralax index as float
               $.data(this, "paralaxLayer", parseFloat($(this).attr('rel')));
          });
          originalPosition = $frames.position();
          ...
          //reposition on interval rather than mouse move
          setInterval(methods.calculatePosition, 100);
          ...
     },
     calculatePosition : function(){
          //calculate baseline offset for this mouse position
          var offsetX = (settings.magnitudeX)*(mouseX/wWidth);
                      - (settings.magnitudeX/2),
          offsetY = (settings.magnitudeY)*(mouseY/wHeight);
                      - (settings.magnitudeY/2),
          frame, paralaxLayer, paralaxFactorX, paralaxFactorY;
          
          //go through and reposition each frame
          for(i=0; i<$frames.length; i++){
              $frame = $($frames[i]);
              paralaxLayer = $.data($frames[i], "paralaxLayer")/
              settings.paralaxFactor;
              paralaxFactorX = -paralaxLayer*offsetX,
              paralaxFactorY = -paralaxLayer*offsetY;
                   
              //use animate for smooth transition
              $frame.clearQueue().animate({
                  top: originalPosition.top+paralaxFactorY,
                  left: originalPosition.left+paralaxFactorX,
              }, 300);
          }
     }
}

There were a couple of steps I took to increase the performance of the position calculation. In the init function the $.each() function is used to loop through frames for ease of implementation, but the calculatePosition function needs to run a bit faster so I used a for loop. Secondly, I decided to calculate the new position of the frames on an interval, rather than on mouse move. Mouse move occurs too often to perform any significant calculation and translation, so a interval and the jQuery animate plugin was utilized.


Possible Improvements
  • load layer data into object or array instead of using $.data plugin
  • integrate text shadow into plugin

Thursday, March 10, 2011

Applescript Adventures: How to visit 3,000 webpages in 10 minutes

My first experience with AppleScript has left me with some mixed feelings about the language. I was able to complete a menial task that I would not have wanted to do manually. However, I found the natural language structure to be an obstacle to performing progressively more advanced tasks. That said, would recommend learning AppleScript, it's pretty awesome.

Task
The impetus for learning ApplesSript was a simple but mind numbing assignment. I had pull down around images and data for almost 1000 items from a system while maintaining a relationship between the data and the image files. The system was behind password protection so wget alone wouldn't suffice. Also, to download the images the click event had to be triggered on the page (thank you ASP.NET). And the company who built and maintains the system was not being helpful.

Hello AppleScript!
I was left with no alternative but to visit every page and click all the links, LAME! Thankfully AppleScript is pretty powerful. Every Apple user has to try this out at least once. AppleScript can open applications and perform different operations, then pass the results to another application. Why do something when I can tell my computer to do it for me?

The script itself ended up being pretty simple:
  • grab jQuery
  • Open browser
  • grab list of links
  • visit each link
    • inject jQuery
    • get data from this link
    • download image
  • go to next link

Opening up applications is trivial with AppleScript. The tricky parts are pulling down the list of links and then visiting them in order.

Gimme jQuery
Both Chrome and Safari allow JavaScript to be executed through AppleScript. To make everything easier jQuery was injected on page load. First jQuery has to be loaded by the AppleScript.

set jqueryFile to ("/Path/to/jQuery/file/jquery.js")
open for access jqueryFile
set jqueryContents to (read jqueryFile)
close access jqueryFile

Grabbing links
The next step is to open up Safari, tell it to open into a new window, go to an address and inject jquery. Unfortunately, Safari doesn't provide an easy way to determine a page is loading. Setting a delay is a pretty quick if unreliable solution.
tell application "Safari"
 activate
 --make new document and wait for new page to load
 delay 1 
 tell front document to set URL to "http://sickawesome.com"
 delay 15
 
 set doc to front document
 tell doc  
  do JavaScript jqueryContents
  -- the do JavaScript command returns javascript arrays as a list
  set image_hrefs to (do JavaScript "var hrefs = []; $('#list of links').each(function(){hrefs.push($(this).attr('href'))}); hrefs;")
 end tell
end tell

The downside of scripting Safari is already apparent. The loading status of a current document isn't directly available to AppleScript. Some other method has to be found to delay until the document is ready to run JavaScript. However, Safari was used for this step, because of how well it handles JavaScript. Safari, unlike Chrome, returns the value of a JavaScript statement, so that AppleScript can use it later. When Safari returns a JavaScript array AppleScript handles it as a list, no conversion to do. Awesome.

Quick Visits Only
The next step is the longest of the whole process. Visiting each page in succession, pulling down info and then going to the next. Chrome was chosen for two reasons: Chome is fastest browser out there, and Chrome tabs provide access to the loading status of the page. This is important, because after a couple dozen pages the connection speed fell dramatically, rendering delays ineffective.

However, as I mentioned before, Chrome does not return values from executed JavaScript. So a little more creativity is required. Fortunately both JavaScript and AppleScript have access to the title of a tab. So as long as the value can be cast as a string (unsure about arrays), Chrome can still pull out the data.

tell application "Google Chrome"
 activate
 tell (make new window) to tell tab 1  
  -- repeat loop essentially like python for in loop
  repeat with href in image_hrefs
   execute JavaScript "window.location ='https://baseURL" & href & "'"
 
   my waitForReady()
   execute JavaScript jqueryContents   
   --get something
   execute JavaScript "document.title = $('#block').html()"
   delay 0.2
   set value to get title
               end repeat
      end tell

A delay was stuck in just to make sure the JavaScript has time to execute before the AppleScript assumes it is done. The wait for ready subroutine is the key to Chromes suitability for this task.

on waitForReady()
 delay 1
 tell application "Google Chrome"
  tell window 1 to tell tab 1
   repeat
    execute JavaScript "document.title = document.readyState"
    set status to get title
    if status is "complete" and loading is not true then
     return true
    else
     delay 0.1
    end if
    
   end repeat
  end tell
 end tell
end waitForReady

The above function executes ten times a second until the the browser and document are ready loaded. JavaScript can be run when the document.readyState is "interactive", but sometimes the content of the page isn't ready to pull.

Conclusion
Writing this script was fun. Once I discovered the dictionaries, it was much easier to start experimenting. The uses for this language are innumerable. However, it has to be used in the right situation, writing and debugging these scripts can be a little frustrating. It could easily take more time to write than the script ends up saving.

As a programmer, I didn't appreciate the natural language syntax for AppleScript. I found it a little verbose and somewhat confusing. That is, I found it difficult to look at AppleScript samples and figure out how I could manipulate the code for another situation.

Google Book Stuffs
Go here for free info:
AppleScript: Definitive Guide
AppleScript: The Comprehensive Guide to Scripting and Automation on Mac OS X

Sunday, February 13, 2011

What 9000!

If this isn't the wackiest piece of code I've ever written, then it is pretty close. There are three components to the page: a randomly generated grid, the changing letter sizes, and the "awesome song" in the background.

Random Grid

The toughest part was generating the random grid. The grid is made up of two types of components. The grid itself, and the blocks. Each the grids and blocks are have a visual and a data component. The visual components is handled by css,

Grid size

The first step is to determine the number of rows and columns that the grid will have. This is done by taking the ceiling of the quotient of the width or height of the container divided by the height or width of the cell. In this case the cells are 50x50 (40px with 10px of padding). I used the ceiling function rather than the floor because I wanted to fill the screen. Also the number of cells is recalculated on window resize.
$(window).resize(function(){
     hcells = Math.ceil($grid.width()/50); //collumns
     vcells = Math.ceil($grid.height()/50); //rows
}).resize();

Representing grid and shapes

Both the grid and the shapes are represented by 2-dimensional boolean matrices. The grid is initialized so that every cell contains a false value (meaning that grid position is not occupied).
for(i = 0; i < hcells; i++){
     grid.push([]);
     for(j = 0; j < vcells; j++){
          grid[i].push(false);                    
     }
}
Likewise, each of the block shapes has a shape array where the positions occupied by the shape are represented by a true value.
//default shape, single square block 
     oneSquare = {
        shape: [ [true] ],
        className: "oneSquare"
    };
    //three wide by one tall 
    threeXOne = {
        className: "threeXone",            
        shape: [ [true], [true], [true] ]
    };

Placing Blocks

After the grid is initialized, each position is looped through and a block shape is chosen at random. Then the shape array of the block is compared the the grid starting at the current position. The block is placed into the grid if all the positions that will be take up by this shape are unoccupied.
function placeBlock(i, j, shape){              
        //loop over space checking for occupation
        for(x = 0; x < shape.length; x++){
            for(y = 0; y < shape[x].length; y++){
                 if (grid[x + i][y + j] || x+i >= grid.length || y+j >= grid[x+i].length) {                             
                      return false;                              
                  }                                          
            }                                      
        }
        //go back and mark spots as taken up
        for (x = 0; x < shape.length; x++) {
            for (y = 0; y < shape[x].length; y++) {
                grid[x + i][y + j] = true;
            }
        }              
        return true;       
    }
If the function returns true then the block is placed absolutely in the grid using the cell size and i,j coordinates. The process of emptying the grid and filling it with random block is set to repeat 10 times a second. This makes the grid a pretty interesting browser benchmark.

Title

To spice up the title a little bit. I use the lettering.js a jQuery plugin to wrap each of the letters in there own div. Then on an interval the letters are looped through and a random size (within bounds) is chosen for each letter, and it is assigned one of 4 colors;
var colors = ["#0099FF", "#800080", "#0FF000", "#FF0000"];
     function logoDance(){
        $logo.children("span").each(function(){
            randy = Math.random();                 
            $(this).css({
                fontSize: Math.round(randy*150)+75,
                color: colors[Math.floor(4 * randy)]
            });
        });
    }

Audio

The music is played through an HTML audio tag.To get the OGG version of the file I used Firefogg.

Summary

That pretty much covers it. Some arrays operations to create and fill the grid, lettering.js to jazz up the title page, and some quick html audio for the background music.