1 //This is used so IE can use the classList api
  2 /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
  3 if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){if(!("HTMLElement" in j)&&!("Element" in j)){return}var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(){var s=arguments,r=0,p=s.length,q,o=false;do{q=s[r]+"";if(g(this,q)===-1){this.push(q);o=true}}while(++r<p);if(o){this._updateClassName()}};e.remove=function(){var t=arguments,s=0,p=t.length,r,o=false;do{r=t[s]+"";var q=g(this,r);if(q!==-1){this.splice(q,1);o=true}}while(++s<p);if(o){this._updateClassName()}};e.toggle=function(p,q){p+="";var o=this.contains(p),r=o?q!==true&&"remove":q!==false&&"add";if(r){this[r](p)}return !o};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
  4 
  5 /**
  6  * DOM
  7  *
  8  * Dom manipulation module
  9  */
 10 (function (undefined){
 11 
 12 	"use strict";
 13 
 14 	var d;
 15 
 16 	//Private function for getting/setting attributes/properties
 17 	function _attr(sel, name, value)
 18 	{
 19 		var oldVal, doAttr;
 20 
 21 		//Get the value of the attribute, if it exists
 22 		if (sel.hasAttribute !== undefined)
 23 		{
 24 			if (sel.hasAttribute(name))
 25 			{
 26 				oldVal = sel.getAttribute(name);
 27 			}
 28 
 29 			doAttr = true;
 30 		}
 31 		else if (sel[name] !== undefined)
 32 		{
 33 			oldVal = sel[name];
 34 			doAttr = false;
 35 		}
 36 		else if (name === "class" && sel.className !== undefined) //className attribute
 37 		{
 38 			name = "className";
 39 			oldVal = sel.className;
 40 			doAttr = false;
 41 		}
 42 
 43 		//Well, I guess that attribute doesn't exist
 44 		if (oldVal === undefined && (value === undefined || value === null))
 45 		{
 46 			return null;
 47 		}
 48 
 49 		//No value to set? Return the current value
 50 		if (value === undefined)
 51 		{
 52 			return oldVal;
 53 		}
 54 
 55 		//Determine what to do with the attribute
 56 		if (value !== undefined && value !== null)
 57 		{
 58 			if(doAttr === true)
 59 			{
 60 				sel.setAttribute(name, value);
 61 			}
 62 			else
 63 			{
 64 				sel[name] = value;
 65 			}
 66 		}
 67 		else if (value === null)
 68 		{
 69 			if(doAttr === true)
 70 			{
 71 				sel.removeAttribute(name);
 72 			}
 73 			else
 74 			{
 75 				delete sel[name];
 76 			}
 77 		}
 78 
 79 		return (value !== undefined) ? value : oldVal;
 80 	}
 81 
 82 	/**
 83 	 * Change css property name to it's
 84 	 * javascript camel case equivalent
 85 	 */
 86 	function _toCamel(s)
 87 	{
 88 		return s.replace(/(\-[a-z])/g, function($1){
 89 			return $1.toUpperCase().replace('-','');
 90 		});
 91 	}
 92 
 93 	function _css(sel, prop, val)
 94 	{
 95 		var equi;
 96 
 97 		//Camel-case
 98 		prop = _toCamel(prop);
 99 
100 		//Equivalent properties for 'special' browsers
101 		equi = {
102 			outerHeight: "offsetHeight",
103 			outerWidth: "offsetWidth",
104 			top: "posTop"
105 		};
106 
107 
108 		//If you don't define a value, try returning the existing value
109 		if(val === undefined && sel.style[prop] !== undefined)
110 		{
111 			return sel.style[prop];
112 		}
113 		else if(val === undefined && sel.style[equi[prop]] !== undefined)
114 		{
115 			return sel.style[equi[prop]];
116 		}
117 
118 		//Let's try the easy way first
119 		if(sel.style[prop] !== undefined)
120 		{
121 			sel.style[prop] = val;
122 
123 			//Short circuit
124 			return null;
125 		}
126 		else if(sel.style[equi[prop]])
127 		{
128 			sel.style[equi[prop]] = val;
129 			return null;
130 		}
131 	}
132 
133 	// --------------------------------------------------------------------------
134 
135 	/**
136 	 * DOM
137 	 *
138 	 * Dom manipulation module
139 	 * @namespace
140 	 * @memberOf $_
141 	 * @name dom
142 	 */
143 	d = {
144 		/**
145 		 * Adds a class to the element(s) specified by the current
146 		 * selector
147 		 *
148 		 * @name addClass
149 		 * @memberOf $_.dom
150 		 * @function
151 		 * @param string class
152 		 */
153 		addClass: function (c)
154 		{
155 			$_.each(function (e){
156 				e.classList.add(c);
157 			});
158 		},
159 		/**
160 		 * Removes a class from the element(s) specified by the current
161 		 * selector
162 		 *
163 		 * @name removeClass
164 		 * @memberOf $_.dom
165 		 * @function
166 		 * @param string class
167 		 */
168 		removeClass: function (c)
169 		{
170 			$_.each(function (e){
171 				e.classList.remove(c);
172 			});
173 		},
174 		/**
175 		 * Hides the element(s) specified by the current selector
176 		 *
177 		 * @name hide
178 		 * @memberOf $_.dom
179 		 * @function
180 		 */
181 		hide: function ()
182 		{
183 			this.css('display', 'none');
184 		},
185 		/**
186 		 * Shows the element(s) specified by the current selector.
187 		 * if type is specified, the element will have it's style
188 		 * property set to "display:[your type]". If type is not
189 		 * specified, the element is set to "display:block".
190 		 *
191 		 * @name  show
192 		 * @memberOf $_.dom
193 		 * @function
194 		 * @param [string] type
195 		 */
196 		show: function (type)
197 		{
198 			if (type === undefined)
199 			{
200 				type = "block";
201 			}
202 
203 			this.css("display", type);
204 		},
205 		/**
206 		 * Sets attributes on element(s) specified by the current
207 		 * selector, or, if name is not specified, returns the
208 		 * value of the attribute of the element specified by the
209 		 * current selector.
210 		 *
211 		 * @name attr
212 		 * @memberOf $_.dom
213 		 * @function
214 		 * @param string name
215 		 * @param [string] value
216 		 * @return string
217 		 * @type string
218 		 */
219 		attr: function (name, value)
220 		{
221 			var sel = this.el;
222 
223 			//Make sure you don't try to get a bunch of elements
224 			if (sel.length > 1 && value === undefined)
225 			{
226 				return null;
227 			}
228 			else if (sel.length > 1 && value !== undefined) //You can set a bunch, though
229 			{
230 				$_.each(function (e){
231 					return _attr(e, name, value);
232 				});
233 			}
234 			else //Normal behavior
235 			{
236 				return _attr(sel, name, value);
237 			}
238 		},
239 		/**
240 		 * Sets or retrieves the text content of the element
241 		 * specified by the current selector. If a value is
242 		 * passed, it will set that value on the current element,
243 		 * otherwise it will return the value of the current element
244 		 *
245 		 * @name text
246 		 * @memberOf $_.dom
247 		 * @function
248 		 * @param [string] value
249 		 * @return string
250 		 * @type string
251 		 */
252 		text: function (value)
253 		{
254 			var oldValue, set, sel;
255 
256 			sel = this.el;
257 
258 			set = (value !== undefined) ? true : false;
259 
260 			oldValue = sel.textContent;
261 
262 			if(set)
263 			{
264 				sel.textContent = value;
265 				return value;
266 			}
267 			else
268 			{
269 				return oldValue;
270 			}
271 		},
272 		/**
273 		 * Sets or retrieves a css property of the element
274 		 * specified by the current selector. If a value is
275 		 * passed, it will set that value on the current element,
276 		 * otherwise it will return the value of the css property
277 		 * on the current element
278 		 *
279 		 * @name css
280 		 * @memberOf $_.dom
281 		 * @function
282 		 * @param string property
283 		 * @param [string] value
284 		 * @return string
285 		 * @type string
286 		 */
287 		css: function (prop, val)
288 		{
289 			//Return the current value if a value is not set
290 			if(val === undefined)
291 			{
292 				return _css(this.el, prop);
293 			}
294 
295 			$_.each(function (e){
296 				_css(e, prop, val);
297 			});
298 		},
299 		/**
300 		 * Adds to the innerHTML of the current element, after the last child.
301 		 *
302 		 * @example $_("ul").dom.append("<li></li>") adds an li element to the end of the selected ul element
303 		 * @name append
304 		 * @memberOf $_.dom
305 		 * @function
306 		 * @param string htm
307 		 */
308 		append: function(htm)
309 		{
310 			this.el.insertAdjacentHTML('beforeend', htm);
311 		},
312 		/**
313 		 * Adds to the innerHTML of the selected element, before the current children
314 		 *
315 		 * @name prepend
316 		 * @memberOf $_.dom
317 		 * @function
318 		 * @param string htm
319 		 */
320 		 prepend: function(htm)
321 		 {
322 		 	this.el.insertAdjacentHTML('afterbegin', htm);
323 		 },
324 		/**
325 		 * Sets or gets the innerHTML propery of the element(s) passed
326 		 *
327 		 * @name html
328 		 * @memberOf $_.dom
329 		 * @function
330 		 * @param [string] htm
331 		 * @return string
332 		 * @type string
333 		 */
334 		html: function(htm)
335 		{
336 
337 			if(htm !== undefined)
338 			{
339 				this.el.innerHTML = htm;
340 			}
341 
342 			//If the parameter is undefined, just return the current value
343 			return this.el.innerHTML;
344 		}
345 	};
346 
347 	$_.ext('dom', d);
348 
349 }());