1 /**
  2 	Kis JS		Keep It Simple JS Library
  3 	Copyright	Timothy J. Warren
  4 	License		Public Domain
  5 	Version		0.5.0-pre
  6  */
  7 (function (){
  8 
  9 	"use strict";
 10 
 11 	//Browser requirements check
 12 	if (!document.querySelectorAll)
 13 	{
 14 		return;
 15 	}
 16 
 17 	var $_, $, dcopy, sel, sel_string;
 18 	
 19 
 20 	/**
 21 	 * $_
 22 	 *
 23 	 * Constructor function
 24 	 *
 25 	 * @constuctor
 26 	 * @namespace
 27 	 * @param string selector
 28 	 * @return object
 29 	 */
 30 	$_ = function(s)
 31 	{
 32 		//Have documentElement be default selector, just in case
 33 		if(typeof s === "undefined")
 34 		{
 35 			//Defines a "global" selector for that instance
 36 			sel = (typeof $_.el !== "undefined") 
 37 				? $_.el
 38 				: document.documentElement;
 39 		}
 40 		else
 41 		{
 42 			sel = (typeof s !== "object") ? $(s) : s;
 43 		}
 44 		
 45 		// Add the selector to the prototype
 46 		$_.prototype.el = sel;
 47 
 48 		// Make a copy before adding properties
 49 		var self = dcopy($_);
 50 
 51 		// Give sel to each extension.
 52 		for(var i in self) 
 53 		{
 54 			if(typeof self[i] === "object")
 55 			{
 56 				self[i].el = sel;
 57 			}	
 58 		}
 59 
 60 		self.el = sel;
 61 	
 62 		return self;
 63 	};
 64 	
 65 	/**
 66 	 * $
 67 	 *
 68 	 * Simple DOM selector function
 69 	 *
 70 	 * @memberOf $_
 71 	 * @param string selector
 72 	 * @param string context
 73 	 * @return object
 74 	 * @type object
 75 	 */
 76 	$ = function (a, context)
 77 	{
 78 		var x, c;
 79 		
 80 		if (typeof a != "string" || typeof a === "undefined"){ return a;}
 81 		
 82 		//Check for a context of a specific element, otherwise, just run on the document
 83 		c  = (context != null && context.nodeType === 1) 
 84 			? context 
 85 			: document;
 86 		
 87 		//Pick the quickest method for each kind of selector
 88 		if (a.match(/^#([\w\-]+$)/))
 89 		{
 90 			return document.getElementById(a.split('#')[1]);
 91 		}
 92 		else
 93 		{
 94 			x = c.querySelectorAll(a);
 95 		}
 96 		
 97 		//Return the single object if applicable
 98 		return (x.length === 1) ? x[0] : x;
 99 	};
100 	
101 	/**
102 	 * Deep copy/prototypical constructor function
103 	 *
104 	 * @param object obj
105 	 * @private
106 	 * @return object
107 	 * @type object
108 	 */
109 	dcopy = function(obj)
110 	{
111 		var type, F;
112 		
113 		if(typeof obj === "undefined")
114 		{
115 			return;
116 		}
117 		
118 		if(typeof Object.create !== "undefined")
119 		{
120 			return Object.create(obj);
121 		}
122 		
123 		type = typeof obj;
124 		
125 		if(type !== "object" && type !== "function")
126 		{
127 			return;
128 		}
129 		
130 		/**
131 		 * @private
132 		 */
133 		F = function(){};
134 		
135 		F.prototype = obj;
136 		
137 		return new F();
138 		
139 	};
140 	
141 	/**
142 	 * Adds the property `obj` to the $_ object, calling it `name`
143 	 * 
144 	 * @param string name
145 	 * @param object obj
146 	 * @return void
147 	 */
148 	$_.ext = function(name, obj)
149 	{
150 		obj.el = sel;
151 		$_[name] = obj;
152 	};
153 	
154 	/**
155 	 * Iterates over a $_ object, applying a callback to each item
156 	 *
157 	 * @name $_.each
158 	 * @function
159 	 * @param function callback
160 	 * @return void
161 	 */
162 	$_.ext('each', function (callback)
163 	{
164 		if(typeof sel.length !== "undefined" && sel !== window)
165 		{
166 			var len = sel.length;
167 
168 			if (len === 0)
169 			{
170 				return;
171 			}
172 
173 			var selx;
174 			for (var x = 0; x < len; x++)
175 			{
176 				selx = (sel.item(x)) ? sel.item(x) : sel[x];
177 				callback(selx);
178 			}
179 		}
180 		else
181 		{
182 			callback(sel);
183 		}
184 	});
185 	
186 	/**
187 	 * Retrieves the type of the passed variable
188 	 *
189 	 * @param mixed obj
190 	 * @return string
191 	 * @type string
192 	 */
193 	$_.type = function(obj) 
194 	{
195 		if((function() {return obj && (obj !== this)}).call(obj))
196 		{
197 			//fallback on 'typeof' for truthy primitive values
198 			return (typeof obj).toLowerCase();
199 		}
200 		
201 		return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
202 	};
203 
204 	//Set global variables
205 	$_ = window.$_ = window.$_ || $_;
206 	$_.$ = $;
207 	
208 	//console.log polyfill
209 	if(typeof window.console === "undefined")
210 	{
211 		window.console = {
212 			log:function(){}
213 		};
214 	}
215 	
216 	/**
217 	 * String trim function polyfill
218 	 */
219 	if(typeof String.prototype.trim === "undefined")
220 	{
221 		/**
222 		 * @private
223 		 */
224 		String.prototype.trim = function(){
225 			return this.replace(/^\s+|\s+$/g, "");
226 		};
227 	}
228 	
229 }());