1 /**
  2 	Kis JS		Keep It Simple JS Library
  3 	Copyright	Timothy J. Warren
  4 	License		Public Domain
  5 	Version		0.8.0
  6  */
  7 (function (undefined){
  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 (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 (s === undefined)
 39 		{
 40 			// Defines a "global" selector for that instance
 41 			sel = ($_.el !== undefined)
 42 				? $_.el
 43 				: document.documentElement;
 44 		}
 45 		else
 46 		{
 47 			sel = $(s);
 48 		}
 49 
 50 		// Add the selector to the prototype
 51 		$_.prototype.el = sel;
 52 
 53 		// Use the $_ object as it's own prototype
 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" || 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(obj === undefined)
117 		{
118 			return;
119 		}
120 
121 		if(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(sel.length !== undefined && sel !== window)
166 		{
167 			// Use the native method, if it exists
168 			if(Array.prototype.forEach !== undefined)
169 			{
170 				[].forEach.call(sel, callback);
171 				return;
172 			}
173 
174 			// Otherwise, fall back to a for loop
175 			var len = sel.length;
176 
177 			if (len === 0)
178 			{
179 				return;
180 			}
181 
182 			var selx;
183 			for (var x = 0; x < len; x++)
184 			{
185 				selx = (sel.item(x)) ? sel.item(x) : sel[x];
186 				callback.call(selx, selx);
187 			}
188 		}
189 		else
190 		{
191 			callback.call(sel, sel);
192 		}
193 	});
194 
195 	/**
196 	 * Retrieves the type of the passed variable
197 	 *
198 	 * @param mixed obj
199 	 * @return string
200 	 * @type string
201 	 */
202 	$_.type = function(obj)
203 	{
204 		if((function() {return obj && (obj !== this)}).call(obj))
205 		{
206 			//fallback on 'typeof' for truthy primitive values
207 			return (typeof obj).toLowerCase();
208 		}
209 
210 		//Strip x from [object x] and return
211 		return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
212 	};
213 
214 	//Set global variables
215 	$_ = window.$_ = window.$_ || $_;
216 	$_.$ = $;
217 
218 }());