/* eslint-env browser */ (function() { var cache = [0], expando = 'data' + Date.now(); function data(elem) { var cacheIndex = elem[expando], nextCacheIndex = cache.length; if (!cacheIndex) { cacheIndex = elem[expando] = nextCacheIndex; cache[cacheIndex] = {}; } return cache[cacheIndex]; }; /** * Add/Read private data to a DOM element. * @global * @method * @param {object} elem - DOM element to bind data to. * @return {void} * @example * var elem = document.getElementById('foo'); * // Attach private data to element: * dataBind(elem).someName = { value: 42 }; * dataBind(elem)['other-name'] = { value: 43 }; * // Read private data from element: * var some = dataBind(elem).someName; * var other = dataBind(elem)['other-name']; */ window.dataBind = data; })(); /** * Event manager. * @global * @module Event */ window.Event = { /** * Add event to DOM element. * @memberof module:Event * @param {object|string} elem - DOM element or selector. * @param {string} type - Event type. * @param {function} fn - Callback. * @return {void} * @example * Event.add(document.getElementById('foo'), 'click', function fooClick(evt) { * // Element was clicked. * }); * Event.add('#foo', 'click', function fooClick(evt) { * // Element was clicked. * }); */ add: function(elem, type, fn) { if (!elem) return false; if (typeof elem === 'string') elem = document.querySelector(elem); if (elem.addEventListener) { // W3C standard elem.addEventListener(type, fn, false); } else if (elem.attachEvent) { // Old IE versions elem.attachEvent('on'+type, fn); } else { // Really old browser elem[type+fn] = function() { fn(window.event); }; } }, /** * Remove event from DOM element. * @memberof module:Event * @param {object|string} elem - DOM element or selector. * @param {string} type - Event type. * @param {function} fn - Callback. * @return {void} * @example * // Assuming elemen had the `fooClick` function (see previous example): * Event.remove(document.getElementById('foo'), 'click', fooClick); * Event.remove('#foo'), 'click', fooClick); */ remove: function(elem, type, fn) { if (!elem) return false; if (typeof elem === 'string') elem = document.querySelector(elem); if (elem.removeEventListener) { // W3C standard elem.removeEventListener(type, fn, false); } else if (elem.detachEvent) { // Old IE versions elem.detachEvent('on'+type, fn); } else { // Really old browser elem[type+fn] = null; } }, /** * Determine if an event is a "right click" event. * @memberof module:Event * @param {object} ev - DOM event. * @return {boolean} * @example * // Assume this function is a click event listener. * function clickHandler(evt) { * alert(Event.isRightClick(evt)); * }); */ isRightClick: function(ev) { if (!ev) ev = window.event; if (ev.which) return ev.which === 3; else if (ev.button) return e.button === 2; return false; }, }; /** * A handy method to (deep) extend an object. * The input object is modified. * @global * @param {object} myObj - Input object. * @return {object} * @example * var one = { foo:1, bar: { a:true, b:false } }; * var two = { bar: { a:false } }; * // In this case both `ext` and `one` will be the same object. * var ext = deepExtend(one, two); * // To create a fresh copy, pass in an empty object as first arg. * var ext = deepExtend({}, one, two); * // Now `ext` is `{ foo:1, bar: { a:false, b:false } }` * // and `one` is left intact. */ window.deepExtend = function(myObj) { myObj = myObj || {}; for (var i = 1; i < arguments.length; i++) { var obj = arguments[i]; for (var key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'object') { myObj[key] = deepExtend(myObj[key], obj[key]); } else { myObj[key] = obj[key]; } } } } return myObj; };