1 /**
  2 * @namespace Holds core static functions
  3 * @class Crayon class
  4 * @description
  5 * This class is originated from jQuery.core functions and provides basic functions for Crayon libraries.
  6 * @see <a href="http://jqueryjs.googlecode.com/svn/tags/1.3.2/src/core.js">jQuery 1.3.2</a>
  7 */
  8 var Crayon = {};
  9 
 10 /**
 11 * @function
 12 * @return true when object is Function, otherwise false.
 13 */
 14 Crayon.isFunction = function( obj ) {
 15   return toString.call(obj) === "[object Function]";
 16 };
 17 
 18 /**
 19 * @function
 20 * @return true when object is Array, otherwise false.
 21 */
 22 Crayon.isArray = function( obj ) {
 23   return toString.call(obj) === "[object Array]";
 24 };
 25 
 26 /**
 27 * @function
 28 * @return true when object is Object, otherwise false.
 29 */
 30 Crayon.isObject = function(obj){
 31   return toString.call(obj) === "[object Object]";
 32 };
 33 
 34 /**
 35 * @function
 36 * @return true when object is Date, otherwise false.
 37 */
 38 Crayon.isDate = function(obj){
 39    return toString.call(obj) === "[object Date]";
 40 };
 41 
 42 Crayon.extractOptions = function(){
 43   if( arguments.length.length == 0 ){
 44     return {
 45       args    : [],
 46       options : null
 47     };
 48   }else{
 49     var args = new Array(arguments.length);
 50     for(var i=0; i<args.length; i++){
 51       args[i] = arguments[i];
 52     }
 53     if( Crayon.isObject(args[args.length - 1]) ){
 54       var options = args.pop();
 55       return {
 56         args: args,
 57         options: options
 58       };
 59     }else{
 60       return {
 61         args: args,
 62         options: null
 63       };
 64     }
 65   }
 66 }
 67 /**
 68 * Extends a objecct or Crayon itself.
 69 * @param [Object] object
 70 */
 71 Crayon.extend = function(){
 72   // copy reference to target object
 73   var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
 74 
 75   // Handle a deep copy situation
 76   if ( typeof target === "boolean" ) {
 77     deep = target;
 78     target = arguments[1] || {};
 79     // skip the boolean and the target
 80     i = 2;
 81   }
 82 
 83   // Handle case when target is a string or something (possible in deep copy)
 84   if ( typeof target !== "object" && !Crayon.isFunction(target) ) {
 85     target = {};
 86   }
 87 
 88   // extend Crayon itself if only one argument is passed
 89   if ( length === i ) {
 90     target = this;
 91     --i;
 92   }
 93 
 94   for ( ; i < length; i++ ) {
 95     // Only deal with non-null/undefined values
 96     if ( (options = arguments[ i ]) != null ) {
 97       // Extend the base object
 98       for ( name in options ) {
 99         src = target[ name ];
100         copy = options[ name ];
101 
102         // Prevent never-ending loop
103         if ( target === copy ) {
104           continue;
105         }
106 
107         // Recurse if we're merging object values
108         if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
109           var clone;
110 
111           if ( src ) {
112             clone = src;
113           } else if ( Crayon.isArray(copy) ) {
114             clone = [];
115           } else if ( Crayon.isObject(copy) ) {
116             clone = {};
117           } else {
118             clone = copy;
119           }
120 
121           // Never move original objects, clone them
122           target[ name ] = Crayon.extend( deep, clone, copy );
123 
124           // Don't bring in undefined values
125         } else if ( copy !== undefined ) {
126           target[ name ] = copy;
127         }
128       }
129     }
130   }
131 
132   // Return the modified object
133   return target;
134 };
135