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 	 * Simple DOM selector function
 72 	 *
 73 	 * @memberOf $_
 74 	 * @param string selector
 75 	 * @param object context
 76 	 * @return object
 77 	 * @type object
 78 	 */
 79 	$ = function (a, context)
 80 	{
 81 		var x, c;
 82 		
 83 		if (typeof a != "string" || typeof a === "undefined"){ return a;}
 84 		
 85 		//Check for a context of a specific element, otherwise, just run on the document
 86 		c  = (context != null && context.nodeType === 1) 
 87 			? context 
 88 			: document;
 89 		
 90 		//Pick the quickest method for each kind of selector
 91 		if (a.match(/^#([\w\-]+$)/))
 92 		{
 93 			return document.getElementById(a.split('#')[1]);
 94 		}
 95 		else
 96 		{
 97 			x = c.querySelectorAll(a);
 98 		}
 99 		
100 		//Return the single object if applicable
101 		return (x.length === 1) ? x[0] : x;
102 	};
103 	
104 	/**
105 	 * Deep copy/prototypical constructor function
106 	 *
107 	 * @param object obj
108 	 * @private
109 	 * @return object
110 	 * @type object
111 	 */
112 	dcopy = function(obj)
113 	{
114 		var type, F;
115 		
116 		if(typeof obj === "undefined")
117 		{
118 			return;
119 		}
120 		
121 		if(typeof Object.create !== "undefined")
122 		{
123 			return Object.create(obj);
124 		}
125 		
126 		type = typeof obj;
127 		
128 		if(type !== "object" && type !== "function")
129 		{
130 			return;
131 		}
132 		
133 		/**
134 		 * @private
135 		 */
136 		F = function(){};
137 		
138 		F.prototype = obj;
139 		
140 		return new F();
141 		
142 	};
143 	
144 	/**
145 	 * Adds the property `obj` to the $_ object, calling it `name`
146 	 * 
147 	 * @param string name
148 	 * @param object obj
149 	 */
150 	$_.ext = function(name, obj)
151 	{
152 		obj.el = sel;
153 		$_[name] = obj;
154 	};
155 	
156 	/**
157 	 * Iterates over a $_ object, applying a callback to each item
158 	 *
159 	 * @name $_.each
160 	 * @function
161 	 * @param function callback
162 	 */
163 	$_.ext('each', function (callback)
164 	{
165 		if(typeof sel.length !== "undefined" && sel !== window)
166 		{
167 			var len = sel.length;
168 
169 			if (len === 0)
170 			{
171 				return;
172 			}
173 
174 			var selx;
175 			for (var x = 0; x < len; x++)
176 			{
177 				selx = (sel.item(x)) ? sel.item(x) : sel[x];
178 				callback.call(selx, selx);
179 			}
180 		}
181 		else
182 		{
183 			callback.call(sel, sel);
184 		}
185 	});
186 	
187 	/**
188 	 * Retrieves the type of the passed variable
189 	 *
190 	 * @param mixed obj
191 	 * @return string
192 	 * @type string
193 	 */
194 	$_.type = function(obj) 
195 	{	
196 		if((function() {return obj && (obj !== this)}).call(obj))
197 		{
198 			//fallback on 'typeof' for truthy primitive values
199 			return (typeof obj).toLowerCase();
200 		}
201 		
202 		//Strip x from [object x] and return 
203 		return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
204 	};
205 
206 	//Set global variables
207 	$_ = window.$_ = window.$_ || $_;
208 	$_.$ = $;
209 	
210 }());