extend: function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; if (length < 2) return target; // Handle a deep copy situation if (typeof target === 'boolean') { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if (typeof target !== 'object' && !typeCheck.isFunction(target)) { target = {}; } for (; i < length; i++) { // Only deal with non-null/undefined values if ((options = arguments[i]) != null) { // Extend the base object for (name in options) { src = target[name]; copy = options[name]; // Prevent never-ending loop if (target === copy) { continue; } // Recurse if we're merging plain objects or arrays if (deep && copy && (typeCheck.isObject(copy) || (copyIsArray = typeCheck.isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && typeCheck.isArray(src) ? src : []; } else { clone = src && typeCheck.isObject(src) ? src : {}; } // Never move original objects, clone them target[name] = this.extend(deep, clone, copy); // Don't bring in undefined values } else if (copy !== undefined) { target[name] = copy; } } } } // Return the modified object return target; },
set: function(element, property, value) { var setter = element.style.setProperty ? 'setProperty' : 'setAttribute'; if (typecheck.isObject(property)) { for (var prop in property) { // if there's a value, set it. if (typeof property[prop] != 'undefined') { element.style[setter](prop, property[prop].toString()); } // else, remove the property. else { this.remove(element, prop); } } } else if (typecheck.isString(property)) { if (value) { element.style[setter](property, value.toString()); } else { this.remove(element, property); } } },
fire: function(object, eventName, data, bubbles, cancelable) { if (!object) return; // if the object is a dom-node, // dispatch the dom-event on the element. if (_typecheck.isElement(object)) { // construct the event. var event, eventInitDict = { bubbles: bubbles || true, cancelable: cancelable, detail: data }; // Event constructor is supported. if (typeof CustomEvent == 'function') { event = new CustomEvent(eventName, eventInitDict); } else if (document.createEvent) { // the old-fashioned way. event = document.createEvent('Event'); event.initEvent(eventName, bubbles || true, cancelable); event.detail = data; } else if (document.createEventObject) { // the prehistoric way. event = document.createEventObject(); } if (document.createEvent) { object.dispatchEvent(event); } else if (document.createEventObject) { object.fireEvent('on' + eventName, event); } } else { // if the object is a some other object, // execute the eventhandler for this event-type. var events = _storage.get(object, this.storage_key); if (events && events[eventName]) { var handlers = events[eventName].handlers; _executeCallbacks(object, handlers, null, data); } } },
off: function(object, eventName, callback) { var handlers = _storage.get(object, this.storage_key); if (!handlers || !handlers[eventName]) return; // if no handler is specified, remove all handlers for the event. if (!callback) { // if the object is a dom-node, remove the actual eventlistener. if (_typecheck.isElement(object)) { object.removeEventListener(eventName, handlers[eventName].domEventHandler); } // remove all callbacks for this event-type from the storage. delete handlers[eventName]; } else { // remove the specific callback. var typeHandlers = handlers[eventName].handlers; for (var i = 0; i < typeHandlers.length; i++) { if (typeHandlers[i].callback === callback) { // remove the callback from the handlers. typeHandlers.splice(i, 1); break; } } } }
on: function(object, eventName, callback, selector) { if (!object || typeof callback !== 'function') return; var isDomObject = _typecheck.isElement(object) || object == document || object == window; if (isDomObject && !object.addEventListener) { eventName = 'on' + eventName; } var handlers = _storage.get(object, this.storage_key) || {}; if (!handlers[eventName]) { handlers[eventName] = {handlers: []}; } handlers[eventName].handlers.push({ callback: callback, selector: selector }); // store the handler on the object so it can be removed later. _storage.set(object, this.storage_key, handlers); // if the object is a dom-node and there's no eventlistener for this eventtype on the element, // add an actual eventlistener. if (isDomObject && !handlers[eventName].domEventHandler) { handlers[eventName].domEventHandler = function(event) { _executeCallbacks(object, handlers[eventName].handlers, event); }; if (object.addEventListener) { object.addEventListener(eventName, handlers[eventName].domEventHandler); } else if (object.attachEvent) { object.attachEvent(eventName, handlers[eventName].domEventHandler); } } },