1 /**
  2  * DOM
  3  * 
  4  * Dom manipulation module
  5  */
  6 (function (){
  7 
  8 	"use strict";
  9 
 10 	var d, tag_reg, class_reg;
 11 	
 12 	tag_reg = /^([\w\-]+)$/;
 13 	class_reg = /\.([\w\-]+)$/;
 14 	
 15 	
 16 	//Private function for getting/setting attributes
 17 	function _attr(sel, name, value)
 18 	{
 19 		var oldVal, doAttr;
 20 
 21 		//Get the value of the attribute, if it exists
 22 		if (typeof sel.hasAttribute !== "undefined")
 23 		{
 24 			if (sel.hasAttribute(name))
 25 			{
 26 				oldVal = sel.getAttribute(name);
 27 			}
 28 
 29 			doAttr = true;
 30 		}
 31 		else if (typeof sel[name] !== "undefined")
 32 		{
 33 			oldVal = sel[name];
 34 			doAttr = false;
 35 		}
 36 		else if (name === "class" && typeof 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 (typeof oldVal === "undefined" && (typeof value === "undefined" || value === null))
 45 		{
 46 			console.log(value);
 47 			console.log(sel);
 48 			console.log("Element does not have the selected attribute");
 49 			return;
 50 		}
 51 
 52 		//No value to set? Return the current value
 53 		if (typeof value === "undefined")
 54 		{
 55 			return oldVal;
 56 		}
 57 
 58 		//Determine what to do with the attribute
 59 		if (typeof value !== "undefined" && value !== null)
 60 		{
 61 			if(doAttr === true)
 62 			{
 63 				sel.setAttribute(name, value);
 64 			}
 65 			else
 66 			{
 67 				sel[name] = value;
 68 			} 
 69 		}
 70 		else if (value === null)
 71 		{
 72 			if(doAttr === true)
 73 			{
 74 				sel.removeAttribute(name);
 75 			}
 76 			else
 77 			{
 78 				delete sel[name];
 79 			} 
 80 		}
 81 
 82 		return (typeof value !== "undefined") ? value : oldVal;
 83 	}
 84 	
 85 	function _toCamel(s)
 86 	{
 87 		return s.replace(/(\-[a-z])/g, function($1){
 88 			return $1.toUpperCase().replace('-','');
 89 		});
 90 	}
 91 
 92 	function _css(sel, prop, val)
 93 	{
 94 		var equi;
 95 		
 96 		//Camel-case
 97 		prop = _toCamel(prop);
 98 
 99 		//Equivalent properties for 'special' browsers
100 		equi = {
101 			outerHeight: "offsetHeight",
102 			outerWidth: "offsetWidth",
103 			top: "posTop"
104 		};
105 		
106 		
107 		//If you don't define a value, try returning the existing value
108 		if(typeof val === "undefined" && sel.style[prop] !== "undefined")
109 		{
110 			return sel.style[prop];
111 		}
112 		else if(typeof val === "undefined" && sel.style[equi[prop]] !== "undefined")
113 		{
114 			return sel.style[equi[prop]];
115 		}
116 
117 		//Let's try the easy way first
118 		if(typeof sel.style[prop] !== "undefined")
119 		{
120 			sel.style[prop] = val;
121 
122 			//Short circuit
123 			return;
124 		}
125 		else if(sel.style[equi[prop]])
126 		{
127 			sel.style[equi[prop]] = val;
128 			return;
129 		}
130 		
131 		//No matches? Well, lets log it for now
132 		console.log("Property " + prop + " nor an equivalent seems to exist");
133 	}
134 	
135 	// --------------------------------------------------------------------------
136 
137 	/**
138 	 * DOM
139 	 * 
140 	 * Dom manipulation module
141 	 * @namespace
142 	 * @memberOf $_
143 	 * @name dom
144 	 */
145 	d = {
146 		/**
147 		 * Adds a class to the element(s) specified by the current
148 		 * selector
149 		 * 
150 		 * @name addClass
151 		 * @memberOf $_.dom
152 		 * @function
153 		 * @param string class
154 		 * @return void
155 		 */
156 		addClass: function (c)
157 		{
158 			$_.each(function (e){
159 				e.classList.add(c);
160 			});
161 		},
162 		/**
163 		 * Removes a class from the element(s) specified by the current
164 		 * selector
165 		 * 
166 		 * @name removeClass
167 		 * @memberOf $_.dom
168 		 * @function
169 		 * @param string class
170 		 * @return void
171 		 */
172 		removeClass: function (c)
173 		{
174 			$_.each(function (e){
175 				e.classList.remove(c);
176 			});
177 		},
178 		/**
179 		 * Hides the element(s) specified by the current selector
180 		 * 
181 		 * @name hide
182 		 * @memberOf $_.dom
183 		 * @function
184 		 * @return void
185 		 */
186 		hide: function ()
187 		{
188 			this.css('display', 'none');
189 		},
190 		/**
191 		 * Shows the element(s) specified by the current selector. 
192 		 * if type is specified, the element will have it's style
193 		 * property set to "display:[your type]". If type is not
194 		 * specified, the element is set to "display:block".
195 		 * 
196 		 * @name  show
197 		 * @memberOf $_.dom
198 		 * @function
199 		 * @param [string] type
200 		 * @return void
201 		 */
202 		show: function (type)
203 		{
204 			if (typeof type === "undefined")
205 			{
206 				type = "block";
207 			}
208 
209 			this.css("display", type);
210 		},
211 		/**
212 		 * Sets attributes on element(s) specified by the current 
213 		 * selector, or, if name is not specified, returns the 
214 		 * value of the attribute of the element specified by the
215 		 * current selector.
216 		 *
217 		 * @name attr
218 		 * @memberOf $_.dom
219 		 * @function
220 		 * @param string name
221 		 * @param string value
222 		 * @return string
223 		 * @type string
224 		 */
225 		attr: function (name, value)
226 		{
227 			var sel = this.el;
228 
229 			//Make sure you don't try to get a bunch of elements
230 			if (sel.length > 1 && typeof value === "undefined")
231 			{
232 				console.log(sel);
233 				console.log("Must be a singular element");
234 				return;
235 			}
236 			else if (sel.length > 1 && typeof value !== "undefined") //You can set a bunch, though
237 			{
238 				$_.each(function (e){
239 					return _attr(e, name, value);
240 				});
241 			}
242 			else //Normal behavior
243 			{
244 				return _attr(sel, name, value);
245 			}
246 		},
247 		/**
248 		 * Sets or retrieves the text content of the element
249 		 * specified by the current selector. If a value is 
250 		 * passed, it will set that value on the current element,
251 		 * otherwise it will return the value of the current element
252 		 *
253 		 * @name text
254 		 * @memberOf $_.util
255 		 * @function
256 		 * @param [string] value
257 		 * @returns string
258 		 * @type string
259 		 */
260 		text: function (value)
261 		{
262 			var oldValue, set, type, sel;
263 		
264 			sel = this.el;
265 			
266 			set = (typeof value !== "undefined") ? true : false;
267 			
268 			type = (typeof sel.innerText !== "undefined")
269 				? "innerText"
270 				: (typeof sel.textContent !== "undefined")
271 					? "textContent"
272 					: "innerHTML";
273 
274 			oldValue = sel[type];
275 			
276 			if(set)
277 			{
278 				sel[type] = value;
279 				return value;
280 			}
281 			else
282 			{
283 				return oldValue;
284 			}
285 		},
286 		/**
287 		 * Sets or retrieves a css property of the element
288 		 * specified by the current selector. If a value is 
289 		 * passed, it will set that value on the current element,
290 		 * otherwise it will return the value of the css property
291 		 * on the current element
292 		 *
293 		 * @name css
294 		 * @memberOf $_.util
295 		 * @function
296 		 * @param string property
297 		 * @param [string] value
298 		 * @returns string
299 		 * @type string
300 		 */
301 		css: function (prop, val)
302 		{
303 			//Return the current value if a value is not set
304 			if(typeof val === "undefined")
305 			{
306 				return _css(this.el, prop);
307 			}
308 		
309 			$_.each(function (e){
310 				_css(e, prop, val);
311 			});
312 		}
313 	};
314 
315 	$_.ext('dom', d);
316 	
317 }());
318