mf Object Methods Part 1 {mf.object}

This is a series of posts that explains some of the fundamental rules for developing complex JavaScript applications and the mf framework.

It has been a few weeks since I wrote a post on mf but this has most been due to the time it took to complete all of the object methods available.  Object methods along with array methods are some of the most important methods that any framework can have and as such taking some extra time is required. At present there are 28 methods written and fully tested. Given this number it would obviously be far to much for one single blog post. As a result I will be writing several blog posts each covering several methods at a time. In this post I will discuss the following methods:

  • mf.object.each
  • mf.object.deepEach
  • mf.object.clense
  • mf.object.typeMap
  • mf.object.containsKeys
  • mf.object.containsVals

Continue reading

Making a Browser Sniffer for mf

This is a series of posts that explains some of the fundamental rules for developing complex JavaScript applications and the mf framework.

One of the first key things that is required in any JavaScript framework is a browser sniffer. Browser sniffers are easy to create and as with all of the modules that will be placed into mf it uses my standard design pattern. Here is the code:

var browser = Object.freeze((function(){
     var app = new String(navigator.userAgent),
     mode = document.documentMode,
     isIE = app.match('MSIE')!==null,
     isSafari = app.match('Safari')!==null && app.match('Chrome')===null,
     isChrome = app.match('Safari')!==null && app.match('Chrome')!==null,
     isFireFox = app.match('Firefox')!==null,
     tests = {
           isSafari : isSafari,
           isChrome : isChrome,
           isFireFox : isFireFox,
           isIE : isIE,
           isIE5 : isIE && mode===5,
           isIE6 : isIE && mode===6,
           isIE7 : isIE && mode===7,
           isIE8 : isIE && mode===8,
           isIE9 : isIE && mode===9,
           isIE10 : isIE && mode===10,
           version : 0,
           isWin : navigator.platform.toLowerCase()==='win32',
           isMac : navigator.platform.toLowerCase()!=='win32',
           isSecure : (window.location.protocol).toLowerCase().substr(0,5)==='https'
     },
     Public = {};
     // get browser version
     if(isFireFox){
           tests.version = parseInt(/Firefox\/(\d+\.)/.exec(app)[1],10)
     }else if(isChrome){
           tests.version = parseInt(/Chrome\/(\d+\.)/.exec(app)[1],10)
     }else if(isSafari){
           tests.version = parseInt(/Version\/(\d+\.)/.exec(app)[1],10)
     }else if(isIE) {
           tests.version = parseInt(/MSIE (\d+\.)/.exec(app)[1],10)
     };                             
     tests.mfCompliant = (isSafari && test.version>4) || (isIE && tests.version >8 && mode>8) || (isChrome && tests.version>20) || (isFireFox && tests.version>14);
     // convert results into anonymous function calls
     for(prop in tests){
           Public[prop]=new Function('return '+tests[prop]+';')
     };
     return Public;                                    
}()));

Note that I am adding the mfCompliant property onto the tests object and setting my browser minimum requirements.  I am also not testing for Opera although that certainly could be added in very easily at any point in the future.  Finally I enumerate through the tests object and create anonymous functions within the Public object that return the values of the subsequent property in the tests object.  Note also the the public returned by the outer anonymous function is passed to the Object.freeze method in order to freeze the resulting object. This will prevent users from overriding existing methods or removing them.

In the case of IE9 it does not support the Object.freeze method.  As a result I had to place the following code above this module.

// Ensure we have freeze method on Object for IE9
if((typeof Object.freeze).toLowerCase()!=='function'){
       Object.prototype.freeze = function(o){
              return o
       }
}

Sine the freeze method returns the object being frozen this little override does the same thing in order to ensure when running the framework in IE9 it does not blow up on you.  Freezing is certainly handy on objects but does not add any direct functionality to the framework.

The mf global variable browser is then returned as belonging as a child object to the framework.  This then allows external users to make calls such as mf.browser.isIE() or mf.browser.isSecure(). Certainly over time there may be other items to add under the browser module but these are the basics.

In my next post I will be fleshing out some other core methods for Objects, Arrays along with some base prototyping of core JavaScript objects such as String and Number.

Why am I writing the mf Framework

I suppose the question of why write yet another framework should be answered to some degree. Over the many years of working with JavaScript developers from junior to senior I have noted a common theme. In almost every case the developer indicates that they know this framework or another framework yet none of them seem to understand how it is written. It is akin to knowing how to drive a car yet not understanding how it works. I think that is a dangerous mindset for both driving and writing JavaScript.

All JavaScript frameworks have common methods each with its’ own unique slant on implementation. All frameworks consist of browser sniffers, DOM normalization plus Event and Component Management along with methods to make life a little easier for the programmer. Each of these concepts offer the same or similar implementation yet there seems to be a gross lack of understanding on how they work.

So the goal of creating the mf framework is to demonstrate to JavaScript developers the basic concepts of how frameworks are put together in order to further their understanding of other frameworks. So like driving a car you should have some idea of how the engine actually works!

So, in the next several months I will be building up the framework piece by piece with one or more blog posts on each of the components that will constitute the end product.  Once I have the framework developed to a certain point I will also be placing it up on Google code for people to play with, enhance or throw mean reviews back at me.

Cheers
Keith

Creating Object Properties {the dangling participle of JS Objects}

This is a series of posts that explains some of the fundamental rules for developing complex JavaScript applications.

As most of us know, well I would hope most of us that is, properties in objects have some fundamental flaws in them, that, like many situations in JavaScript our bits and bites are left hanging out!  Object properties that are exposed publicly, whether in a module pattern or an instance have absolutely zero control over them.

If one does some research however you will dig up the Object.defineProperty method and supporting methods that as of IE9 are now common across all modern browsers.  If you are interested in reading up on the defineProperty Object method I have found the best documentation to be over at Mozilla . While Object.defineProperty does provide us enhancements such as read only, freezing and preventing deletion is certainly does not, in my opinion, provide much power. A property should provide the following:

  • Verbose setters and getter methods,
  • Conditional checking on setters,
  • Chaining of base object setters,
  • Watches and events.

Continue reading

Dynamic Drag Alignment Rulers {elegance sometimes happens}

In most cases when you work on a product, requests from ‘those who shall be obeyed’ and I don’t mean your mother, are fairly simple.  You are given a functional idea or a behavior to be implemented within a product and you say to yourself ‘yep, no problem’. In other words, not often is there a challenge. Then there are those rare cases where you come across a task where you need to think outside of the box and we all crave those tasks. Such is a task that I recently faced on a product I work on.  In essence think of the product as an online version of Microsoft PowerPoint, it’s not, but it’s the closest I can think of in the context of the post. The request was to display rulers top, bottom, center, middle, left and right on the selected object. As the object was dragged around the screen when any of these rulers came into alignment on the X or Y of any other object they were to be displayed.  A very similar UI behavior that you would see in PhotoShop, for example.  To make it even more difficult the rulers had to gradually get stronger as it got close to any alignment on any other element on the page on its 3 horizontal or 3 vertical axis!

So imagine the below scenario:

So in the above image there are three shapes.  The blue square has been selected and when any of the 3 horizontal rulers comes into contact with the top, middle or bottom of the other shapes they would need to appear.  Same goes for the vertical if the user where to drag the blue square to the right. So this means that for each element/shape on the page there are 3 vertical and 3 horizontal points to compare to the current points on the actively dragged element, in this case the blue box. Now consider you could have any number of shapes you need to align to! This leads one to the conclusion that any sort of heavy on the fly calculation while dragging will simply destroy performance.  So the question then becomes how can we do this with ZERO calculations/conditions while the selected element is being dragged.  The answer is YES we can and here is how. Just a quick note regarding some of the code, in order to preserve the privacy of the application I am not using the general namespace we use for our toolkit that provides DOM manipulation. However you can easily see how to do this in jQuery, ExtJS etc.  The point is the solution not so much the implementation. Continue reading

Writing Flexible JavaScript Functions

This is a series of posts that explains some of the fundamental rules for developing complex JavaScript applications.

How often have we seen function grow over time with just one more parameter added for that supposed last little piece of functionality we have to add. Far too often I would imagine.  Then add in the new requirement that some of the parameters on the function need to be optional and the next thing you know you are in a world of hurt. There is a basic maxim in any software development, the only constant is change. As a result as a software writer I strive to ensure my code recognizes this maxim along with a couple of others.

Alas for JavaScript, the poor Yorick of languages we all know so well, it does not give us a lot of flexibility in the function object. Unlike other languages, even SQL, functions/methods provide much greater flexibility in there definition, including default values, optional parameters, name parameter calling, e.t.c. It would certainly be nice if we could provide a similar model to JS function calls and definitions. Many a moon a go I started developing in ExtJS and was introduced to a very simple method called Ext.apply and Ext.applyIf. In essence these methods take two objects as parameters and merge them into one. So if you call Ext.apply({a:1,b:2},{c:1}) you would get back {a:1,b:2,c:1}.  Sounds simple enough right? The applyIf works in the same fashion but makes a test in the receiving object to see if the property already exists and if so does not over write it. This is a very simple piece of code that we can look at below:

function applyIf(objectTo,objectFrom){
              if(objectTo){
                          for(var property in objectFrom){
                                      if(typeof objectTo[property] == 'undefined' ){
                                                  objectTo[propety] = objectFrom[property];
                                      }
                          }
              }
              return objecTo;
  }

So in essence, enumerate through the properties in objectFrom and if the property does not exist in the objectTo then add the property and its value from the objectFrom. So what does this have to do with functions you are probably asking? Let’s have a look at a mythical function as an example

function doSomethingCool(
              // width of element
              width,
              // height of element
              height,  
              // text of element
              text,
              // optional x and y, element type and style string
              ,x,y,elType,style){…do some stuff}

Looks simple enough but what’s with the four of optional parameters at the end of the function.  As you well know from in your function code you end up with a bunch of if statements along the lines of if(x===undefined){x=0}.  This of course gets to be a pain in the code rear. Now let’s change our function to accept to a single parameters as an object.

function doSomethingCool(config){
            config=applyIf(config,{
                          width : null,
                          height : null,
                          text : ’’,
                          x : 0,
                          y : 0,
                          elType : ‘div’,
                          style : ‘position:relative’
              })
… do some stuff
  }

So now in our doSomethingCool function we can easily default each parameter in our function and reduce the amount of if conditions to test for them.  By defaulting each of our values we also reduce the risk of errors being introduced by bad callers.

This may seem like a simple idea but it has a couple of extremely important advantages.  How many times have you had to go and look up a function you wish to call to check the order or the parameters? I would guess far too many times. Using a single parameters object order of the values in the object to not matter. But there is a far more important reason to use this method and that is in regards to the caller.  In the standard function design you would see some code calling the method like thus:

doSomethingCool(10,10,’my text to display’,undefined,undefined,’span’)

Really does not really tell you much when you look at it does it. When another developer has to go through your code the above line tells him/her absolutely nothing and forces them to go and look at the doSomethingCool function to determine what 10 and 10 is and why are there two undefined. Now lets make the same call to the function using the config object parameters:

doSomethingCool({
              width : 10,
              elType : ‘span’,
              height : 10,
              text : ‘my text to desolay’ 
  })

Looks a lot better doesn’t it! Not only is it very clear on what we are passing, we also did not need to add in a bunch of undefined definitions to get to the elType parameter. Notice also that in the above the order of object properties do not matter either.

A couple of noteworthy things about implementing your functions this way. If you need to add another parameter to your doSomethingCool function you can simply default it the default config object that is applied without any concern of impacting existing callers.  Another great benefit is code readability. How often have you had to take someone else’s code over? Now imagine reading through that code and seeing all these clearly understandable calls.  Not only does it benefit you when you need to revisit something but it will benefits the next developer who has to hit your code to make a modification.

In the next part of the series I will be exploring Crockford’s singleton pattern vs the prototypal pattern and how to merge, extend them and organize code.

Hide your JavaScript from Firebug and other Dev Tools

I write just about everything now a days in Module Pattern, ta Mr. Crockford.  However one of my biggest worries in developing web applications is other people like me.  You know, the geek that hits your web page and immediately hits F12 in Firefox to see what’s going on, what framework your using and inevitably starts doing console.log statements just for fun.  For the serious hacker, once they find those exposed AJAX methods and what to push, life can become a real nightmare for you server not to mention the developers as they feebly attempt to explain to management ‘that’s just the way it is’.

So after several days of adding to a JavaScript Coding Standards document explaining Design Patterns at my most recent job, it got me to thinking ‘how can I protect the code yet not loose any flexibility that the Module Pattern provides?‘ It’s one of those problems you think about when you go to sleep and are still going at it when you awake at sunrise and stubbornly refuse to get up despite your brain saying ‘get at it lad’ just to add to the encouragement from your bladder. Like many problems you fiddle about with code constantly hitting F5 in your browser as your brain goes into overdrive as it is fully convinced this has to be possible!  Then the solution hits you and you exclaim to yourself ‘man that’s so f’ing obvious and simple what was I thinking!!‘.  The solution is wrap your singleton in an anonymous function – duh! So here you go enjoy:

(function(){

	var myApp =function(){
		//add your application code here as you normally would
	}();

}());

Yes its that simple!  In essence wrap your application in an anonymous function.  So long as all of your child classes within myApp reference myApp.whatever then no problem.  Give it a try then hit your page with Firebug or any other dev tool and look in vain for myApp, you will not find it.

But this introduces a problem.  Your busy working on your highly complex web app and you need to be able to do console.log statements to my app. Well no problem:

(function(){

	var DEBUG = true,

	var myApp =function(){
		//add your application code here as you normally would
	}();

	if(DEBUG){
		window.MyApp=myApp
	}
}());

Now you can debug to your hearts content and when ready for the big release set your DEBUG switch to false.  So now the next issue, ‘ya that’s all very nice Keith but I NEED to expose some of my methods for consumption by 3rd parties‘.  Again very simple:

(function(){

	var DEBUG = true,
	EXPOSED_NS = 'ForTheCosumer';

	var myApp =function(){
		//add your application code here as you normally would
		return {
			DoSomething 	: function(){},
			DoSomethingElse : function(){}
		}
	}();

	// expose my public methods
	window[EXPOSED_NS]={
		doSomething 	: myApp.DoSomething,
		doSomethingElse	: myApp.DoSomethingElse
	};

	if(DEBUG){
		window.MyApp=myApp
	}
}());

So thats about all there is to it.  In my next post I will deal with another contentious issue with the Module Pattern. Code segmentation into separate files and how to get them into your now hidden application.

Cheers

Keith