angular.js/src/jqLite.js
2010-04-22 17:11:56 -07:00

244 lines
6.1 KiB
JavaScript

//////////////////////////////////
//JQLite
//////////////////////////////////
var jqCache = {};
var jqName = 'ng-' + new Date().getTime();
var jqId = 1;
function jqNextId() { return (jqId++); }
var addEventListener = window.document.attachEvent ?
function(element, type, fn) {
element.attachEvent('on' + type, fn);
} : function(element, type, fn) {
element.addEventListener(type, fn, false);
};
var removeEventListener = window.document.detachEvent ?
function(element, type, fn) {
element.detachEvent('on' + type, fn);
} : function(element, type, fn) {
element.removeEventListener(type, fn, false);
};
function jqClearData(element) {
var cacheId = element[jqName],
cache = jqCache[cacheId];
if (cache) {
foreach(cache.bind || {}, function(fn, type){
removeEventListener(element, type, fn);
});
delete jqCache[cacheId];
if (msie)
element[jqName] = ''; // ie does not allow deletion of attributes on elements.
else
delete element[jqName];
}
}
function JQLite(element) {
if (isElement(element)) {
this[0] = element;
this.length = 1;
} else if (isDefined(element.length) && element.item) {
for(var i=0; i < element.length; i++) {
this[i] = element[i];
}
this.length = element.length;
}
}
JQLite.prototype = {
data: function(key, value) {
var element = this[0],
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;
}
},
removeData: function(){
jqClearData(this[0]);
},
dealoc: function(){
(function dealoc(element){
jqClearData(element);
for ( var i = 0, children = element.childNodes; i < children.length; i++) {
dealoc(children[i]);
}
})(this[0]);
},
bind: function(type, fn){
var self = this,
element = self[0],
bind = self.data('bind'),
eventHandler;
if (!bind) this.data('bind', bind = {});
foreach(type.split(' '), function(type){
eventHandler = bind[type];
if (!eventHandler) {
bind[type] = eventHandler = function(event) {
var bubbleEvent = false;
foreach(eventHandler.fns, function(fn){
bubbleEvent = bubbleEvent || fn.call(self, event);
});
if (!bubbleEvent) {
if (msie) {
event.returnValue = false;
event.cancelBubble = true;
} else {
event.preventDefault();
event.stopPropagation();
}
}
};
eventHandler.fns = [];
addEventListener(element, type, eventHandler);
}
eventHandler.fns.push(fn);
});
},
trigger: function(type) {
var evnt = document.createEvent('MouseEvent');
evnt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
this[0].dispatchEvent(evnt);
},
replaceWith: function(replaceNode) {
this[0].parentNode.replaceChild(jqLite(replaceNode)[0], this[0]);
},
children: function() {
return new JQLite(this[0].childNodes);
},
append: function(node) {
var self = this[0];
node = jqLite(node);
foreach(node, function(child){
self.appendChild(child);
});
},
remove: function() {
this.dealoc();
var parentNode = this[0].parentNode;
if (parentNode) parentNode.removeChild(this[0]);
},
removeAttr: function(name) {
this[0].removeAttribute(name);
},
after: function(element) {
this[0].parentNode.insertBefore(jqLite(element)[0], this[0].nextSibling);
},
hasClass: function(selector) {
var className = " " + selector + " ";
if ( (" " + this[0].className + " ").replace(/[\n\t]/g, " ").indexOf( className ) > -1 ) {
return true;
}
return false;
},
removeClass: function(selector) {
this[0].className = trim((" " + this[0].className + " ").replace(/[\n\t]/g, " ").replace(" " + selector + " ", ""));
},
toggleClass: function(selector, condition) {
var self = this;
(condition ? self.addClass : self.removeClass).call(self, selector);
},
addClass: function( selector ) {
if (!this.hasClass(selector)) {
this[0].className = trim(this[0].className + ' ' + selector);
}
},
css: function(name, value) {
var style = this[0].style;
if (isString(name)) {
if (isDefined(value)) {
style[name] = value;
} else {
return style[name];
}
} else {
extend(style, name);
}
},
attr: function(name, value){
var e = this[0];
if (isObject(name)) {
foreach(name, function(value, name){
e.setAttribute(name, value);
});
} else if (isDefined(value)) {
e.setAttribute(name, value);
} else {
var attributes = e.attributes,
item = attributes ? attributes.getNamedItem(name) : undefined;
return item && item.specified ? item.value : undefined;
}
},
text: function(value) {
if (isDefined(value)) {
this[0].textContent = value;
}
return this[0].textContent;
},
val: function(value) {
if (isDefined(value)) {
this[0].value = value;
}
return this[0].value;
},
html: function(value) {
if (isDefined(value)) {
var parent = this[0], child;
while(parent.childNodes.length) {
child = parent.childNodes[0];
jqLite(child).dealoc();
parent.removeChild(child);
}
this[0].innerHTML = value;
}
return this[0].innerHTML;
},
parent: function() { return jqLite(this[0].parentNode);},
clone: function() { return jqLite(this[0].cloneNode(true)); }
};
if (msie) {
extend(JQLite.prototype, {
text: function(value) {
var e = this[0];
if (isDefined(value)) {
e.innerText = value;
}
// NodeType == 3 is text node
return e.nodeType == 3 ? e.nodeValue : e.innerText;
},
trigger: function(type) {
this[0].fireEvent('on' + type);
}
});
}