////////////////////////////////// //JQLite ////////////////////////////////// var jqCache = {}, jqName = 'ng-' + new Date().getTime(), jqId = 1, addEventListenerFn = (window.document.addEventListener ? function(element, type, fn) {element.addEventListener(type, fn, false);} : function(element, type, fn) {element.attachEvent('on' + type, fn);}), removeEventListenerFn = (window.document.removeEventListener ? function(element, type, fn) {element.removeEventListener(type, fn, false); } : function(element, type, fn) {element.detachEvent('on' + type, fn); }); function jqNextId() { return (jqId++); } function getStyle(element) { var current = {}, style = element[0].style, value, name, i; if (typeof style.length == 'number') { for(i = 0; i < style.length; i++) { name = style[i]; current[name] = style[name]; } } else { for (name in style) { value = style[name]; if (1*name != name && name != 'cssText' && value && typeof value == 'string' && value !='false') current[name] = value; } } return current; } if (msie) { extend(JQLite.prototype, { text: function(value) { var e = this[0]; // NodeType == 3 is text node if (e.nodeType == 3) { if (isDefined(value)) e.nodeValue = value; return e.nodeValue; } else { if (isDefined(value)) e.innerText = value; return e.innerText; } } }); } ///////////////////////////////////////////// function jqLiteWrap(element) { if (isString(element) && element.charAt(0) != '<') { throw new Error('selectors not implemented'); } return new JQLite(element); } function JQLite(element) { if (element instanceof JQLite) { return element; } else if (isString(element)) { var div = document.createElement('div'); // Read about the NoScope elements here: // http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx div.innerHTML = '
 
' + element; // IE insanity to make NoScope elements work! div.removeChild(div.firstChild); // remove the superfluous div JQLiteAddNodes(this, div.childNodes); this.remove(); // detach the elements from the temporary DOM div. } else { JQLiteAddNodes(this, element); } } function JQLiteClone(element) { return element.cloneNode(true); } function JQLiteDealoc(element){ JQLiteRemoveData(element); for ( var i = 0, children = element.childNodes || []; i < children.length; i++) { JQLiteDealoc(children[i]); } } function JQLiteRemoveData(element) { var cacheId = element[jqName], cache = jqCache[cacheId]; if (cache) { forEach(cache.bind || {}, function(fn, type){ removeEventListenerFn(element, type, fn); }); delete jqCache[cacheId]; element[jqName] = undefined; // ie does not allow deletion of attributes on elements. } } function JQLiteData(element, key, value) { var cacheId = element[jqName], cache = jqCache[cacheId || -1]; if (isDefined(value)) { if (!cache) { element[jqName] = cacheId = jqNextId(); cache = jqCache[cacheId] = {}; } cache[key] = value; } else { return cache ? cache[key] : null; } } function JQLiteHasClass(element, selector, _) { // the argument '_' is important, since it makes the function have 3 arguments, which // is neede for delegate function to realize the this is a getter. var className = " " + selector + " "; return ((" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf( className ) > -1); } function JQLiteRemoveClass(element, selector) { element.className = trim( (" " + element.className + " ") .replace(/[\n\t]/g, " ") .replace(" " + selector + " ", "") ); } function JQLiteAddClass(element, selector ) { if (!JQLiteHasClass(element, selector)) { element.className = trim(element.className + ' ' + selector); } } function JQLiteAddNodes(root, elements) { if (elements) { elements = (!elements.nodeName && isDefined(elements.length) && !isWindow(elements)) ? elements : [ elements ]; for(var i=0; i < elements.length; i++) { root.push(elements[i]); } } } ////////////////////////////////////////// // Functions which are declared directly. ////////////////////////////////////////// var JQLitePrototype = JQLite.prototype = { ready: function(fn) { var fired = false; function trigger() { if (fired) return; fired = true; fn(); } this.bind('DOMContentLoaded', trigger); // works for modern browsers and IE9 // we can not use jqLite since we are not done loading and jQuery could be loaded later. jqLiteWrap(window).bind('load', trigger); // fallback to window.onload for others }, toString: function(){ var value = []; forEach(this, function(e){ value.push('' + e);}); return '[' + value.join(', ') + ']'; }, length: 0, push: push, sort: [].sort, splice: [].splice }; ////////////////////////////////////////// // Functions iterating getter/setters. // these functions return self on setter and // value on get. ////////////////////////////////////////// forEach({ data: JQLiteData, scope: function(element) { var scope; while (element && !(scope = jqLite(element).data($$scope))) { element = element.parentNode; } return scope; }, removeAttr: function(element,name) { element.removeAttribute(name); }, hasClass: JQLiteHasClass, css: function(element, name, value) { if (isDefined(value)) { element.style[name] = value; } else { return element.style[name]; } }, attr: function(element, name, value){ if (isDefined(value)) { element.setAttribute(name, value); } else if (element.getAttribute) { // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code // some elements (e.g. Document) don't have get attribute, so return undefined return element.getAttribute(name, 2); } }, text: extend((msie < 9) ? function(element, value) { // NodeType == 3 is text node if (element.nodeType == 3) { if (isUndefined(value)) return element.nodeValue; element.nodeValue = value; } else { if (isUndefined(value)) return element.innerText; element.innerText = value; } } : function(element, value) { if (isUndefined(value)) { return element.textContent; } element.textContent = value; }, {$dv:''}), val: function(element, value) { if (isUndefined(value)) { return element.value; } element.value = value; }, html: function(element, value) { if (isUndefined(value)) { return element.innerHTML; } for (var i = 0, childNodes = element.childNodes; i < childNodes.length; i++) { JQLiteDealoc(childNodes[i]); } element.innerHTML = value; } }, function(fn, name){ /** * Properties: writes return selection, reads return first value */ JQLite.prototype[name] = function(arg1, arg2) { var i, key; if ((fn.length == 2 ? arg1 : arg2) === undefined) { if (isObject(arg1)) { // we are a write, but the object properties are the key/values for(i=0; i < this.length; i++) { for (key in arg1) { fn(this[i], key, arg1[key]); } } // return self for chaining return this; } else { // we are a read, so read the first child. if (this.length) return fn(this[0], arg1, arg2); } } else { // we are a write, so apply to all children for(i=0; i < this.length; i++) { fn(this[i], arg1, arg2); } // return self for chaining return this; } return fn.$dv; }; }); ////////////////////////////////////////// // Functions iterating traversal. // These functions chain results into a single // selector. ////////////////////////////////////////// forEach({ removeData: JQLiteRemoveData, dealoc: JQLiteDealoc, bind: function(element, type, fn){ var bind = JQLiteData(element, 'bind'), eventHandler; if (!bind) JQLiteData(element, 'bind', bind = {}); forEach(type.split(' '), function(type){ eventHandler = bind[type]; if (!eventHandler) { bind[type] = eventHandler = function(event) { if (!event.preventDefault) { event.preventDefault = function(){ event.returnValue = false; //ie }; } if (!event.stopPropagation) { event.stopPropagation = function() { event.cancelBubble = true; //ie }; } forEach(eventHandler.fns, function(fn){ fn.call(element, event); }); }; eventHandler.fns = []; addEventListenerFn(element, type, eventHandler); } eventHandler.fns.push(fn); }); }, replaceWith: function(element, replaceNode) { var index, parent = element.parentNode; JQLiteDealoc(element); forEach(new JQLite(replaceNode), function(node){ if (index) { parent.insertBefore(node, index.nextSibling); } else { parent.replaceChild(node, element); } index = node; }); }, children: function(element) { var children = []; forEach(element.childNodes, function(element){ if (element.nodeName != '#text') children.push(element); }); return children; }, append: function(element, node) { forEach(new JQLite(node), function(child){ if (element.nodeType === 1) element.appendChild(child); }); }, remove: function(element) { JQLiteDealoc(element); var parent = element.parentNode; if (parent) parent.removeChild(element); }, after: function(element, newElement) { var index = element, parent = element.parentNode; forEach(new JQLite(newElement), function(node){ parent.insertBefore(node, index.nextSibling); index = node; }); }, addClass: JQLiteAddClass, removeClass: JQLiteRemoveClass, toggleClass: function(element, selector, condition) { if (isUndefined(condition)) { condition = !JQLiteHasClass(element, selector); } (condition ? JQLiteAddClass : JQLiteRemoveClass)(element, selector); }, parent: function(element) { var parent = element.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, next: function(element) { return element.nextSibling; }, find: function(element, selector) { return element.getElementsByTagName(selector); }, clone: JQLiteClone }, function(fn, name){ /** * chaining functions */ JQLite.prototype[name] = function(arg1, arg2) { var value; for(var i=0; i < this.length; i++) { if (value == undefined) { value = fn(this[i], arg1, arg2); if (value !== undefined) { // any function which returns a value needs to be wrapped value = jqLite(value); } } else { JQLiteAddNodes(value, fn(this[i], arg1, arg2)); } } return value == undefined ? this : value; }; });