var EventManager = function(debug){ var bindings = getEmptyObj(), referenceTable = getEmptyObj(); this.add = add; this.remove = removeRequest; this.removeAll = removeAll; this.removeByTag = removeByTag; this.reset = reset; function Binding(t, type, fn, tag, keyID, id){ this.t = t; this.type = type; this.fn = fn; this.tag = tag; this.keyID = keyID; this.is = id; } function add(t, type, fn, tag){ if(isValidTag(tag)){ t.addEventListener(type, fn); return insertReference(t, type, fn, tag); } else addError(); return null; } function addError(){ console.error('Well, we\'ve encountered an issue. It appears that a protected prefix was used in the tag for this add request. Please refer to the API documentation'); } function removeRequest(t, id){ if(isDefined(t) && isDefined(id)) remove(bindings[t][id]); else removeRequestError(); } function removeRequestError(){ console.error("Well shucks, it looks like I'm missing some information. Please include both target and id attributes to remove a single event."); } function remove(b){ if(b){ b.t.removeEventListener(b.type, b.fn); removeReference(b); } } function removeReference(b){ var kID = b.keyID; delete bindings[kID][b.id]; if(bindings[kID].length == 0) delete referenceTable[kID]; } function removeAll(id){ var o = bindings[id]; for(var k in o){ if(k != 'length') remove(o[k]); } } function removeByTag(tag){ var o = bindings; for(var k in o){ if(k !== 'length') processKey(o[k], tag); } function processKey(o, tag){ for(var k in o){ if(isValidRemoval(o[k], tag) && (k != 'length')) remove(o[k]); } } } function reset(){ for(var k in bindings){ removeAll(k); } } function insertReference(t, type, fn, tag){ var keyID = setKey(t), o = bindings[keyID], l = o.length; o[l] = new Binding(t, type, fn, tag, keyID, l); return o.length++; } function setTagKey(tag){ if(bindings[tag] === undefined) bindings[tag] = { 'length' : 0 }; } function setKey(t){ var k = getKey(t); if(k === null) k = addKey(t, referenceTable, bindings); return k; } function addKey(t, r, b){ if(b[r.length] === undefined) b[r.length] = getEmptyObj(); r[r.length] = t; return r.length++; } function getKey(t){ var o = referenceTable; for(var k in o){ if(k !== 'length' && o[k] == t) return k; } return null; } function getEmptyObj(){ return { 'length' : 0 }; } function isValidRemoval(t, tag){ return tag === undefined || tag == t.tag; } function isValidTag(tag){ return tag === undefined || tag.indexOf('__') !== 0; } function invalidTagError(){ console.error('Sorry, a restricted prefix was used as a tag. Please refer to the documentation for acceptable tag names.'); } };