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