UNPKG

chicago

Version:

A front-end JavaScript library for user-interface developers.

1,700 lines (1,692 loc) 49.3 kB
/*! * Chicago - A front-end JavaScript library for user-interface developers. * * Copyright (c) 2015 Erik Nielsen * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * https://nielse63.github.io/Chicago/ * * Version: 1.1.0 * */ Array.prototype.diff = function(a) { return this.filter(function(i) { return a.indexOf(i) < 0; }); }; /*! * Chicago - Core * Base core of the Chicago library * * Copyright (c) 2015 Erik Nielsen * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * https://nielse63.github.io/Chicago/ * * Version: 1.1.0 * */ (function(global, factory) { if(typeof window === "undefined" && global.window) { global = global.window; } if(typeof define === "function" && define.amd) { define("chicago", function() { var chicago = global.Chicago || factory(global.jQuery, global, global.document); chicago.load = function(res, req, onload, config) { var resources = res.split(','), load = [], i, base = (config.config && config.config.chicago && config.config.chicago.base ? config.config.chicago.base : "").replace(/\/+$/g, ""); if(!base) { throw new Error("Please define base path to Chicago in the requirejs config."); } for(i = 0; i < resources.length; i += 1) { var resource = resources[i].replace(/\./g, '/'); load.push(base + '/modules/' + resource); } req(load, function() { onload(chicago); }); }; return chicago; }); } if(!global.jQuery) { throw new Error('Chicago requires jQuery'); } global.Chicago = factory(global.jQuery, global, global.document); return global.Chicago; })(typeof window !== "undefined" ? window : this, function($, win, doc) { var _cTemp = win.Chicago; var eventnames = { beforeready : 'beforeready.chicago.dom', ready : 'ready.chicago.dom', load : 'reloaded.chicago.dom', init : 'init.chicago.module' }; var _c = { version : '1.1.0', doc : doc, win : win, $ : $, $doc : $(doc), $win : $(win), $html : $('html'), $head : $('html head'), $body : $('body'), utils : {}, support : {}, modules : {}, create : {}, css : {}, elements : {}, deprecated : {}, domReady : false, langdirection : $('html').attr('dir') ? $('html').attr('dir') : 'ltr', extend : function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; if(_c.utils.is.boolean(target)) { deep = target; target = arguments[i] || {}; i++; } if(typeof target !== "object" && !_c.utils.is.function(target)) { target = {}; } for(; i < length; i++) { if((options = arguments[i]) !== null) { for(name in options) { src = target[name]; copy = options[name]; if(target === copy) { continue; } if(deep && copy && (_c.utils.is.object(copy) || (copyIsArray = _c.utils.is.array(copy)))) { if(copyIsArray) { copyIsArray = false; clone = src && _c.utils.is.array(src) ? src : []; } else { clone = src && _c.utils.is.object(src) ? src : {}; } target[name] = _c.extend(deep, clone, copy); } else if(copy !== undefined) { target[name] = copy; } } } } return target; }, noConflict : function() { if(_cTemp) { win.Chicago = _cTemp; $.Chicago = _cTemp; $.fn.chicago = _cTemp.fn; return _cTemp; } return this; }, fn : function(command, options) { var args = arguments, cmd = command.match(/^([a-z\-]+)(?:\.([a-z]+))?/i), module = cmd[1], method = cmd[2]; if(!method && typeof options === 'string') { method = options; } if(!_c[module]) { $.error('Chicago module [' + module + '] does not exist.'); return this; } return this.each(function() { var $this = _c.$(this); var data = $this.data(module); if(!data) { $this.data(module, data = _c[module](this, (method ? void 0 : options))); } if(method) { data[method].apply(data, Array.prototype.slice.call(args, 1)); } }); }, on : function(evt, handler, data) { if(evt && evt.indexOf(eventnames.ready) > -1 && _c.domReady) { return handler.apply(_c.$doc); } return _c.$doc.on(evt, handler, data); }, trigger : function(evt, params) { return _c.$doc.trigger(evt, params); }, }; _c.ready = function(fn) { if(_c.domReady) { return fn(doc); } return _c.on(eventnames.ready); }; _c.module = function(name, methods) { if(!this.create[name]) { this.create[name] = function(_this) { return function(options) { return _this.factory.make(name, options); }; }(this); } var dataKey = 'chicago.data.' + name, fn = function(element, options) { this.element = element ? _c.$(element) : null; this.options = _c.extend(true, {}, this.defaults, options); if(this.element) { this.element.data(dataKey, this); if(!_c.elements[name]) { _c.elements[name] = null; } } this.init(); this.trigger(eventnames.init, [name, this]); return this; }; this.extend(true, fn.prototype, { defaults : {}, boot : function() {}, init : function() {}, destroy : function() {}, on : function(evt, data, handler) { return _c.$(this.element || this).on(evt, data, handler); }, one : function(evt, data, handler) { return _c.$(this.element || this).one(evt, data, handler); }, off : function(evt) { return _c.$(this.element || this).off(evt); }, trigger : function(evt, params) { return _c.$(this.element || this).trigger(evt, params); }, proxy : function(obj, methods) { return methods.split(' ').forEach(function(_this) { return function(method) { if(!_this[method]) { _this[method] = function() { return obj[method].apply(obj, arguments); }; } }; }(this)); }, }, methods); this.modules[name] = fn; this[name] = function() { var args = arguments, ele, options; if(args.length) { switch(args.length) { case 1: if(_c.utils.is.string(args[0]) || args[0].nodeType || _c.utils.is.jQueryObject(args[0])) { ele = $(args[0]); } else { options = args[0]; } break; case 2: ele = _c.$(args[0]); options = args[1]; break; } } if(ele && ele.data(dataKey)) { return ele.data(dataKey); } return new _c.modules[name](ele, options); }; if(!this[name].template) { this[name].template = {}; } this[name].template = _c.extend(this[name].template, methods.template); if(_c.domReady) { _c.module.boot(name); } return fn; }; _c.module.boot = function(name) { if(_c.modules[name] && _c.modules[name].prototype && _c.modules[name].prototype.boot && !_c.modules[name].booted) { _c.modules[name].booted = true; _c.modules[name].prototype.boot.apply(_c, []); } }; _c.bootComponents = function() { for(var module in _c.modules) { _c.module.boot(module); } }; _c.on(eventnames.ready, function() { if(_c.domReady) { return; } _c.domReady = true; }); _c.support = _c.$.extend(_c.support, { requestAnimationFrame : win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.msRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) { win.setTimeout(callback, 1e3 / 60); }, touch : 'ontouchstart' in win || win.DocumentTouch && win.document instanceof win.DocumentTouch || win.navigator.msPointerEnabled && win.navigator.msMaxTouchPoints > 0 || win.navigator.pointerEnabled && win.navigator.maxTouchPoints > 0 || false, mutationobserver : win.MutationObserver || win.WebKitMutationObserver || null, transition : { end : (function() { var ele = doc.body || doc.documentElement, eventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd otransitionend', transition : 'transitionend', }; for(var name in eventNames) { if(ele.style[name] !== undefined) { return eventNames[name]; } } })() }, animation : { start : (function() { var ele = doc.body || doc.documentElement, eventNames = { WebkitAnimation : 'webkitAnimationStart', MozAnimation : 'animationstart', OAnimation : 'oAnimationStart oanimationstart', MSAnimation : 'MSAnimationStart', animation : 'animationstart', }; for(var name in eventNames) { if(ele.style[name] !== undefined) { return eventNames[name]; } } })(), iteration : (function() { var ele = doc.body || doc.documentElement, eventNames = { WebkitAnimation : 'webkitAnimationIteration', MozTransition : 'animationiteration', OTransition : 'oAnimationIteration oanimationiteration', MSAnimation : 'MSAnimationIteration', transition : 'animationiteration', }; for(var name in eventNames) { if(ele.style[name] !== undefined) { return eventNames[name]; } } })(), end : (function() { var ele = doc.body || doc.documentElement, eventNames = { WebkitAnimation : 'webkitAnimationEnd', MozAnimation : 'animationend', OAnimation : 'oAnimationEnd oanimationend', MSAnimation : 'MSAnimationEnd', transition : 'animationend', }; for(var name in eventNames) { if(ele.style[name] !== undefined) { return eventNames[name]; } } })() } }); _c.utils = _c.$.extend(_c.utils, { is : { undefined : function(obj) { return obj === undefined || typeof obj === 'undefined'; }, null : function(obj) { return Object.prototype.toString.call(obj) === '[object Null]'; }, boolean : function(obj) { return typeof obj === 'boolean'; }, string : function(obj) { return typeof obj === 'string' || Object.prototype.toString.call(obj) === '[object String]'; }, numeric : function(obj) { return !isNaN(parseFloat(obj)) && isFinite(obj); }, integer : function(obj) { return obj && Number(obj) === obj && obj % 1 === 0; }, float : function(obj) { return obj && Number(obj) === obj && obj % 1 !== 0; }, date : function(obj) { var d = new Date(obj); return d !== 'Invalid Date' && d.toString() !== 'Invalid Date' && !isNaN(d); }, jQueryObject : function(obj) { return obj instanceof win.jQuery; }, element : function(obj) { var ele = this.jQueryObject(obj) ? obj[0] : obj; return(typeof HTMLElement === 'object' ? ele instanceof HTMLElement : (ele && typeof ele === 'object' && ele.nodeType === 1 && typeof ele.nodeName === 'string')); }, function : function(obj) { return typeof obj === 'function'; }, array : function(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; }, object : function(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; }, }, now : Date.now || function() { return new Date().getTime(); }, inArray : function(array, item) { return array.indexOf(item) > -1; }, debounce : function(fn, wait, immediate) { var timeout; return function() { var context = this, args = arguments, later = function() { timeout = null; if(!immediate) { fn.apply(context, args); } }, callNow = immediate && !timeout; win.clearTimeout(timeout); timeout = win.setTimeout(later, wait); if(callNow) { fn.apply(context, args); } }; }, toCamelCase : function(string) { if(string === null || string === undefined) { return ''; } string = String(string).trim(); return string.replace(/(\-[a-z])/g, function(letter) { return letter.toUpperCase().replace('-', ''); }); }, uid : function(prefix) { var d = _c.utils.now(); prefix = prefix || ''; return prefix + 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return(c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); }, watch : function(object, property, callback) { var watch = Object.prototype.watch || Object.defineProperty(Object.prototype, "watch", { enumerable : false, configurable : true, writable : false, value : function(prop, handler) { var oldval = this[prop], newval = oldval, getter = function() { return this.__clones[prop]; }, setter = function(val) { if(newval !== val) { oldval = newval; newval = this.__clones[prop] = val; return handler.call(this, prop, oldval, val); } }; if(delete this[prop]) { Object.defineProperty(this, prop, { get : getter, set : setter, enumerable : true, configurable : true }); } } }); if(!object.hasOwnProperty('__clones')) { object.__clones = {}; } object.__clones[property] = object[property]; object.watch(property, callback); }, unwatch : function(object, property) { var unwatch = Object.prototype.unwatch || Object.defineProperty(Object.prototype, "unwatch", { enumerable : false, configurable : true, writable : false, value : function(prop) { var val = this[prop]; delete this[prop]; this[prop] = val; } }); function applyUnwatch(prop) { object.unwatch(prop); if(object.__clones && object.__clones[prop]) { delete object.__clones[prop]; } if(!Object.keys(object.__clones).length) { delete object.__clones; } } if(property === undefined) { for(var key in object) { applyUnwatch(key); } } else { applyUnwatch(property); } }, getCSSValue : function(ele, property) { var value = ele.css(property).replace(/px/gi, ''); if(_c.utils.is.numeric(value)) { value = parseFloat(value); if(_c.utils.is.float(value)) { value = parseFloat(value.toFixed(2)); } } return value; }, stringToMilliseconds : function(string) { if(!_c.utils.is.string(string)) { string = String(string); } return parseInt(parseFloat(string.replace('s', '')) * 1000, 10); }, stringToSlug : function(string) { string = String(string) || ''; return string .replace(/[^a-zA-Z0-9]/g, ' ') .replace(/\s+/g, '-') .toLowerCase(); }, str2json : function(str, notevil) { try { if(notevil) { return JSON.parse(str.replace(/([\$\w]+)\s* :/g, function(_, $1) { return '"' + $1 + '" :'; }).replace(/'([^']+)'/g, function(_, $1) { return '"' + $1 + '"'; })); } else { var newFN = Function; return new newFN('', 'var json = ' + str + '; return JSON.parse(JSON.stringify(json));')(); } } catch(e) { return false; } }, options : function(string) { if(_c.utils.is.object(string)) { return string; } var start = string ? string.indexOf('{') : -1; var options = {}; if(start !== -1) { try { options = _c.utils.str2json(string.substr(start)); } catch(_error) {} } return options; }, }); var shouldVendorize = [ 'box-sizing', 'transition', 'transform', 'perspective', 'calc', 'border-radius', 'background-clip', ]; _c.factory = { template : function(str, data) { var tokens = str.replace(/\n/g, '\\n').replace(/\{\{\{\s*(.+?)\s*\}\}\}/g, "{{!$1}}").split(/(\{\{\s*(.+?)\s*\}\})/g), i = 0, toc, cmd, prop, val, fn, output = [], openblocks = 0; while(i < tokens.length) { toc = tokens[i]; if(toc.match(/\{\{\s*(.+?)\s*\}\}/)) { i = i + 1; toc = tokens[i]; cmd = toc[0]; prop = toc.substring(toc.match(/^(\^|\#|\!|\~|\:)/) ? 1 : 0); switch(cmd) { case '#': output.push("if(" + prop + ") {"); openblocks++; break; case '/': output.push("}"); openblocks--; break; case '!': output.push("__ret.push(" + prop + ");"); break; default: output.push("__ret.push(" + prop + ");"); break; } } else { output.push("__ret.push('" + toc.replace(/\'/g, "\\'") + "');"); } i = i + 1; } fn = new Function('$data', [ 'var __ret = [];', 'try {', 'with($data){', (!openblocks ? output.join('') : '__ret = ["Not all blocks are closed correctly."]'), '};', '}catch(e){__ret = [e.message];}', 'return __ret.join("").replace(/\\n\\n/g, "\\n");', 'function escape(html) { return String(html).replace(/&/g, \'&amp;\').replace(/\"/g, \'&quot;\').replace(/</g, \'&lt;\').replace(/>/g, \'&gt;\');}' ].join("\n")); return data ? fn(data) : fn; }, make : function(name, options) { if(!_c[name] || !_c[name].template) { return; } options = options || {}; var templateOptions = {}, ele; if(_c[name].template.options) { for(var prop in options) { if(!_c.utils.is.undefined(_c[name].template.options[prop])) { if(prop === 'id') { options[prop] = _c.utils.stringToSlug(options[prop]); } templateOptions[prop] = options[prop]; } } templateOptions = _c.extend(true, {}, _c[name].template.options, templateOptions); } if(_c[name].template.css && !_c.css[name]) { _c.css[name] = true; var css = _c.factory.css(_c[name].template.css, name); _c.$head.prepend(css); } if(_c[name].template.html) { var html = _c.factory.template(_c[name].template.html, templateOptions); ele = _c.$(html); _c.$body.append(ele); } else { ele = _c.$doc; } return _c[name](ele, options); }, vendorize : function(property, value) { if(_c.utils.is.numeric(value)) { return property + ':' + value + ';'; } property = String(property); value = String(value); var prefixes = [ '-webkit-', '-moz-', ], output = property + ':' + value + ';\n'; for(var i = 0; i < shouldVendorize.length; i++) { var prop = shouldVendorize[i]; if(output.indexOf(prop) > -1) { var prefix = _c.browser.getPrefix(prop); output = output.replace(new RegExp(prop, 'g'), prefix + prop); } } return output; }, needsUnit : function(property) { var needsUnit = [ 'width', 'height', 'top', 'left', 'bottom', 'right', 'margin', 'padding', 'font-size', ]; return _c.utils.inArray(needsUnit, property) }, css : function(object, name) { name = name || 'module'; if(!_c.utils.is.object(object)) { throw new Error('_c.factory.css requires an object'); } var output = ['<style data-css="' + name + '-css">', '</style>']; for(var selector in object) { var len = output.length, index = len - 1, set = object[selector]; if(!_c.utils.is.object(set)) { continue; } output.splice(index, 0, selector); var setString = '{'; for(var prop in set) { var value = set[prop]; if(value && _c.utils.is.numeric(value)) { value = _c.factory.needsUnit(prop) ? value += 'px' : value; } setString += _c.factory.vendorize(prop, value); } len = output.length; index = len - 1; output.splice(index, 0, setString + '}'); } return output.join(''); }, }; _c.factory.make.css = function(name) { if(_c[name] && _c[name].template.css && !_c.css[name]) { _c.css[name] = true; var css = _c.factory.css(_c[name].template.css, name); _c.$head.prepend(css); } }; (function() { _c.$doc.on('ready', function() { _c.$body = _c.$('body'); _c.trigger(eventnames.beforeready); _c.bootComponents(); _c.$win.on('load resizeend orientationchange', _c.utils.debounce(function() { _c.$doc.trigger(eventnames.load); }, 100)); _c.trigger(eventnames.ready); }); })(); return _c; }); /*! * Chicago - Browser * A collection of browser capability methods * * Copyright (c) 2015 Erik Nielsen * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * https://nielse63.github.io/Chicago/ * * Version: 1.1.0 * */ (function(global, factory) { var module; var Chicago = global.Chicago || null; if(Chicago) { module = factory(Chicago, global, global.document); } if(typeof define === 'function' && define.amd) { define('chicago-browser', ['chicago'], function() { return module || factory(Chicago, global, global.document); }); } })(typeof window !== "undefined" ? window : (typeof this.window !== "undefined" ? this.window : this), function(_c, win, doc) { var test = function(rgx) { var ua = win.navigator.userAgent; return rgx.test(ua) || rgx.test(ua.toLowerCase()); }; var exec = function(rgx) { var ua = win.navigator.userAgent; return rgx.exec(ua) || rgx.exec(ua.toLowerCase()); }; var uamatches = function(key) { var ua = win.navigator.userAgent; return ua.indexOf(key) > -1 || ua.toLowerCase().indexOf(key) > -1; }; var match = function(key) { var matches = win.navigator.userAgent.match(key); return !!matches ? matches[0] : null; }; var version = function(obj, string) { var returnObj = { version : { full : string } }; var versionArray = string.split('.'); if(versionArray.length > 0) { versionArray = versionArray.reverse(); returnObj.version.major = parseFloat(versionArray.pop()); if(versionArray.length > 0) { returnObj.version.minor = parseFloat(versionArray.pop()); if(versionArray.length > 0) { versionArray = versionArray.reverse(); returnObj.version.patch = parseFloat(versionArray.join('.')); } else { returnObj.version.patch = 0; } } else { returnObj.version.minor = 0; } } else { returnObj.version.major = 0; } return _c.$.extend(obj, returnObj); }; var objectHasKey = function(search, obj) { if(!_c.utils.is.object(obj)) { return false; } if(_c.utils.is.string(search)) { search = search.toLowerCase(); } for(var k in obj) { var val = obj[k]; if(_c.utils.is.string(val)) { val = val.toLowerCase(); } if(_c.utils.is.object(val)) { var contains = objectHasKey(search, val); if(contains) { return true; } } if(val === search) { return true; } } return false; }; var defs = { device : { types : ['TV', 'Tablet', 'Mobile', 'Desktop'], }, screens : { mini : 0, small : 480, medium : 768, large : 960, xlarge : 1220 }, }; _c.browser = { is : function(string) { return objectHasKey(string, this); }, can : function(style) { var supports = (function() { var div = doc.createElement('div'); var vendors = 'Khtml Ms ms O Moz Webkit'.split(' '); return function(prop) { if(!_c.utils.is.undefined(div.style[prop])) { return true; } prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); }); for(var i = 0; i < vendors.length; i++) { var vendor = vendors[i]; if(!_c.utils.is.undefined(div.style[vendor + prop])) { return true; } } return false; }; })(); return supports(style); }, getPrefix : function(prop) { var div = doc.createElement('div'), vendors = 'Khtml Ms ms O Moz Webkit'.split(' '); prop = _c.utils.toCamelCase(prop); if(!_c.utils.is.undefined(div.style[prop])) { return ''; } for(var i = 0; i < vendors.length; i++) { var vendor = vendors[i]; if(!_c.utils.is.undefined(div.style[vendor + prop])) { return '-' + vendor.toLowerCase() + '-'; } } return ''; }, }; return _c.module('browserProxy', { defaults : { check : { borwser : true, device : true, language : true, os : true, plugins : true, screen : true, touch : true, }, addHTMLClasses : true, }, classes : [], boot : function() { return _c.ready(function() { var ele = _c.$doc; if(!ele.data('chicago.data.browserProxy')) { _c.browserProxy(ele); } }); }, init : function() { _c.$doc.on('ready.chicago.dom reloaded.chicago.dom', function(_this) { return function(e) { _this.setBrowserData(); }; }(this)); }, setBrowserData : function() { if(this.options.check.touch) { _c.browser.touch = this.getTouch(); } if(this.options.check.device) { _c.browser.device = this.getDevice(); } if(this.options.check.screen) { _c.browser.screen = this.getScreen(); } if(this.options.check.os) { _c.browser.os = this.getOS(); } if(this.options.check.borwser) { _c.browser.browser = this.getBrowser(); } if(this.options.check.language) { _c.browser.language = this.getLanguage(); } if(this.options.check.plugins) { _c.browser.plugins = this.getPlugins(); } if(this.options.addHTMLClasses) { this.addHTMLClasses(); } win.setTimeout(function() { _c.$doc.trigger('updated.chicago.browser'); }); }, getTouch : function() { var touch = 'ontouchstart' in win && win.navigator.userAgent.toLowerCase().match(/mobile|tablet/) || win.DocumentTouch && doc instanceof win.DocumentTouch || win.navigator.msPointerEnabled && win.navigator.msMaxTouchPoints > 0 || win.navigator.pointerEnabled && win.navigator.maxTouchPoints > 0 || false; return !!touch; }, getDevice : function() { var device = { type : null, model : null }; if(test(/GoogleTV|SmartTV|SMART-TV|Internet.TV|NetCast|NetTV|AppleTV|Boxee|Kylo|Roku|dlnadoc|Roku|POV_TV|HbbTV|ce\-html/)) { device.type = defs.device.types[0]; device.model = 'SmartTV'; } else if(test(/Xbox|PLAYSTATION 3|Wii/)) { device.type = defs.device.types[0]; device.model = 'Game Console'; } else if(test(/ip(a|ro)d/)) { device.type = defs.device.types[1]; device.model = 'iPad'; } else if((test(/tablet/) && !test(/rx-34/)) || test(/folio/)) { device.type = defs.device.types[1]; device.model = String(exec(/PlayBook/) || ''); } else if(test(/linux/) && test(/Android/) && !test(/Fennec|mobi|htc.magic|htcX06ht|nexus.one|sc-02b|fone.945/)) { device.type = defs.device.types[1]; device.model = 'Android'; } else if(test(/Kindle/) || (test(/mac.os/) && test(/silk/))) { device.type = defs.device.types[1]; device.model = 'Kindle'; } else if(test(/gt-p10|sc-01c|shw-m180s|sgh-t849|sch-i800|shw-m180l|sph-p100|sgh-i987|zt180|htc(.flyer|\_flyer)|sprint.atp51|viewpad7|pandigital(sprnova|nova)|ideos.s7|dell.streak.7|advent.vega|a101it|a70bht|mid7015|next2|nook/) || (test(/mb511/) && test(/rutem/))) { device.type = defs.device.types[1]; device.model = 'Android'; } else if(test(/bb10/)) { device.type = defs.device.types[1]; device.model = 'BlackBerry'; } else { device.model = exec(/iPhone|iPod|Android|BlackBerry|Opera Mini|Opera Mobi|Skyfire|Maemo|Windows Phone|Palm|IEMobile|Symbian|SymbianOS|Fennec|J2ME/); if(device.model !== null) { device.type = defs.device.types[2]; device.model = match(String(device.model)); } else { device.model = ''; if(test(/Bolt|Fennec|Iris|Maemo|minimo|mobi|mowser|netfront|novarra|prism|rx-34|Skyfire|tear|xv6875|xv6975|google.wireless.transcoder/)) { device.type = defs.device.types[2]; } else if(test(/opera/) && test(/windows.nt.5/) && test(/htc|xda|mini|vario|samsung\-gt\-i8000|samsung\-sgh\-i9/)) { device.type = defs.device.types[2]; } else if((test(/windows.(nt|xp|me|9)/) && !test(/phone/)) || test(/win(9|.9|nt)/) || test(/\(windows 8\)/)) { device.type = defs.device.types[3]; } else if(test(/macintosh|powerpc/) && !test(/silk/)) { device.type = defs.device.types[3]; device.model = 'Mac'; } else if(test(/linux/) && test(/x11/)) { device.type = defs.device.types[3]; } else if(test(/solaris|sunos|bsd/)) { device.type = defs.device.types[3]; } else if(test(/cros/)) { device.type = defs.device.types[3]; } else if(test(/bot|crawler|spider|yahoo|ia_archiver|covario-ids|findlinks|dataparksearch|larbin|mediapartners-google|ng-search|snappy|teoma|jeeves|tineye/) && !test(/mobile/)) { device.type = defs.device.types[3]; device.model = 'Crawler'; } else { device.type = defs.device.types[3]; } } } if(device.type !== 'Desktop' && device.type !== 'TV') { device.orientation = 'landscape'; if(win.innerHeight > win.innerWidth) { device.orientation = 'portrait'; } } return device; }, getScreen : function() { var keys = Object.keys(defs.screens).reverse(); for(var i = 0; i < keys.length; i++) { var size = keys[i]; var width = defs.screens[size]; if(win.innerWidth > (width - 1)) { return size; } } }, getOS : function() { var os = { name : null, addressRegisterSize : null, }; if(_c.browser.device.model !== '') { if(_c.browser.device.model === 'iPad' || _c.browser.device.model === 'iPhone' || _c.browser.device.model === 'iPod') { os.name = 'iOS'; os = version(os, (test(/os\s([\d_]+)/) ? RegExp.$1 : '').replace(/_/g, '.')); } else if(_c.browser.device.model === 'Android') { os.name = 'Android'; os = version(os, (test(/Android\s([\d\.]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'BlackBerry') { os.name = 'BlackBerry'; os = version(os, (test(/version\/([^\s]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'PlayBook') { os.name = 'BlackBerry'; os = version(os, (test(/os ([^\s]+)/) ? RegExp.$1.replace(';', '') : '')); } } if(!os.name) { var options = [ 'iOS', 'Android', 'BlackBerry', 'Opera Mini', 'Windows', 'Mac OS', 'OS X', 'AIX', 'Amiga', 'AROS', 'Bada', 'BeOS', 'Brew', 'Chrome OS', 'COS', 'Danger Hiptop', 'DragonFly BSD', 'Fire OS', 'Firefox OS', 'FreeBSD', 'GNU OS', 'Haiku OS', 'HP-UX', 'Inferno OS', 'IRIX', 'Joli OS', 'JVM (Java)', 'JVM', 'KIN OS', 'Linux', 'LiveArea', 'Maemo', 'MeeGo', 'MINIX 3', 'MorphOS', 'MSN TV (WebTV)', 'NetBSD', 'Nintendo 3DS', 'Nintendo DS', 'OpenBSD', 'OpenVM', 'Orbis OS', 'OS/2', 'OS/2 Warp', 'Palm OS', 'PClinuxOS', 'Plan 9', 'QNX x86pc', 'RISK OS', 'Sailfish', 'SCO OpenServer', 'SkyOS', 'Solaris', 'Syllable', 'Symbian OS', 'Tizen', 'Ubuntu Touch', 'webOS', 'Wii OS', 'Wii U OS', 'Xbox', 'XrossMediaBar (XMB)', 'Yun OS', 'unknown', ]; for(var i = 0; i < options.length; i++) { var option = options[i]; if(uamatches(option)) { os.name = option; break; } } } if(!os.name) { if(_c.browser.device.model !== '') { if(_c.browser.device.model === 'ipad' || _c.browser.device.model === 'iphone' || _c.browser.device.model === 'ipod') { os.name = 'ios'; version(os, (test(/os\s([\d_]+)/) ? RegExp.$1 : '').replace(/_/g, '.')); } else if(_c.browser.device.model === 'Android') { os.name = 'Android'; version(os, (test(/Android\s([\d\.]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'BlackBerry') { os.name = 'BlackBerry'; version(os, (test(/version\/([^\s]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'PlayBook') { os.name = 'BlackBerry'; version(os, (test(/os ([^\s]+)/) ? RegExp.$1.replace(';', '') : '')); } } } if(!os.name) { if(uamatches('win') || uamatches('16bit')) { os.name = 'windows'; if(uamatches('windows nt 6.3')) { os = version(os, '8.1'); } else if(uamatches('windows nt 6.2') || test(/\(windows 8\)/)) { os = version(os, '8'); } else if(uamatches('windows nt 6.1')) { os = version(os, '7'); } else if(uamatches('windows nt 6.0')) { os = version(os, 'vista'); } else if(uamatches('windows nt 5.2') || uamatches('windows nt 5.1') || uamatches('windows xp')) { os = version(os, 'xp'); } else if(uamatches('windows nt 5.0') || uamatches('windows 2000')) { os = version(os, '2k'); } else if(uamatches('winnt') || uamatches('windows nt')) { os = version(os, 'nt'); } else if(uamatches('win98') || uamatches('windows 98')) { os = version(os, '98'); } else { if(uamatches('win95') || uamatches('windows 95')) { os = version(os, '95'); } } } else if(uamatches('mac') || uamatches('darwin')) { os.name = 'mac'; if(uamatches('68k') || uamatches('68000')) { os = version(os, '68k'); } else if(uamatches('ppc') || uamatches('powerpc')) { os = version(os, 'ppc'); } else { if(uamatches('os x')) { os = version(os, (test(/os\sx\s([\d_]+)/) ? RegExp.$1 : 'os x').replace(/_/g, '.')); } } } else if(uamatches('webtv')) { os.name = 'webtv'; } else if(uamatches('x11') || uamatches('inux')) { os.name = 'linux'; } else if(uamatches('sunos')) { os.name = 'sun'; } else if(uamatches('irix')) { os.name = 'irix'; } else if(uamatches('freebsd')) { os.name = 'freebsd'; } else { if(uamatches('bsd')) { os.name = 'bsd'; } } } if(test(/\sx64|\sx86|\swin64|\swow64|\samd64/)) { os.addressRegisterSize = '64bit'; } else { os.addressRegisterSize = '32bit'; } return os; }, getBrowser : function() { var browser = { name : null, engine : null, }; if(!test(/opera|webtv/) && (test(/msie\s([\d\w\.]+)/) || uamatches('trident'))) { browser.engine = 'trident'; browser.name = 'ie'; if(!win.addEventListener && doc.documentMode && doc.documentMode === 7) { browser = version(browser, '8.compat'); } else if(test(/trident.*rv[ :](\d+)\./)) { browser = version(browser, RegExp.$1); } else { browser = version(browser, (test(/trident\/4\.0/) ? '8' : RegExp.$1)); } } else if(uamatches('firefox')) { browser.engine = 'gecko'; browser.name = 'firefox'; browser = version(browser, (test(/firefox\/([\d\w\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('gecko/')) { browser.engine = 'gecko'; } else if(uamatches('opera') || uamatches('opr')) { browser.name = 'opera'; browser.engine = 'presto'; browser = version(browser, (test(/version\/([\d\.]+)/) ? RegExp.$1 : (test(/opera(\s|\/)([\d\.]+)/) ? RegExp.$2 : ''))); } else if(uamatches('konqueror')) { browser.name = 'konqueror'; } else if(uamatches('chrome')) { browser.engine = 'webkit'; browser.name = 'chrome'; browser = version(browser, (test(/chrome\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('iron')) { browser.engine = 'webkit'; browser.name = 'iron'; } else if(uamatches('crios')) { browser.name = 'chrome'; browser.engine = 'webkit'; browser = version(browser, (test(/crios\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('applewebkit/')) { browser.name = 'safari'; browser.engine = 'webkit'; browser = version(browser, (test(/version\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('mozilla/')) { browser.engine = 'gecko'; } return browser; }, getLanguage : function() { return { direction : _c.$html.attr('dir') || win.getComputedStyle(doc.body || doc.documentElement).direction || 'ltr', code : win.navigator.userLanguage || win.navigator.language, }; }, getPlugins : function() { var output = []; if(!_c.utils.is.undefined(win.navigator.plugins)) { for(var i = 0; i < win.navigator.plugins.length; i++) { output.push(win.navigator.plugins[i]); } } return output; }, addHTMLClasses : function() { var classes = []; if(_c.browser.screen) { classes.push('screen-' + _c.browser.screen); } if(!_c.utils.is.undefined(_c.browser.touch)) { classes.push(_c.browser.touch ? 'touch' : 'notouch'); } if(classes.diff(this.classes).length) { _c.$html.removeClass(this.classes.join(' ')); _c.$html.addClass(classes.join(' ')); this.classes = classes; } } }); }); /*! * Chicago - Events * Creates custom event bindings * * Copyright (c) 2015 Erik Nielsen * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * https://nielse63.github.io/Chicago/ * * Version: 1.1.0 * */ (function(global, factory) { if(typeof window === "undefined" && global.window) { global = global.window; } var component; if(global.Chicago) { component = factory(global.Chicago, global, global.document); } if(typeof define === 'function' && define.amd) { define('chicago-events', ['chicago'], function() { return component || factory(global.Chicago, global, global.document); }); } })(typeof window !== "undefined" ? window : this, function(_c, win, doc) { _c.events = { scrollend : { latency : 150, setup : function(data) { data = _c.$.extend({ latency : _c.$.event.special.scrollend.latency }, data); var uid = _c.utils.uid('scrollend'), timer = null, handler = function(e) { if(timer) { win.clearTimeout(timer); } timer = win.setTimeout(function() { timer = null; var target = _c.$(e.target); return target.trigger('scrollend', [{ top : target.scrollTop(), left : target.scrollLeft(), }]); }, data.latency); }; _c.$(this).data('chicago.event.scrolltop.uid', uid); return _c.$(this).on('scroll', _c.utils.debounce(handler, 100)).data(uid, handler); }, teardown : function() { var uid = _c.$(this).data('chicago.event.scrolltop.uid'); _c.$(this).off('scroll', _c.$(this).data(uid)); _c.$(this).removeData(uid); return _c.$(this).removeData('chicago.event.scrolltop.uid'); } }, scrollstart : { setup : function(data) { var uid = _c.utils.uid('scrollstart'), handler = function(e) { e.type = 'scrollstart.chicago.dom'; _c.$(e.target).trigger('scrollstart', [{ top : _c.$(e.target).scrollTop(), left : _c.$(e.target).scrollLeft(), }]); }; _c.$(this).on('scrollstart', function() { return _c.$(this).off('scroll', handler); }); _c.$(this).on('scrollend', function() { return _c.$(this).on('scroll', handler).data(uid, handler); }); _c.$(this).data('chicago.event.scrollstart.uid', uid); return _c.$(this).on('scroll', handler).data(uid, handler); }, teardown : function() { var uid = _c.$(this).data('chicago.event.scrollstart.uid'); _c.$(this).off('scroll', _c.$(this).data(uid)); _c.$(this).removeData(uid); return _c.$(this).removeData('chicago.event.scrollstart.uid'); } }, resizeend : { latency : 250, setup : function(data) { var uid = _c.utils.uid('resizeend'), _data = _c.$.extend({ latency : _c.$.event.special.resizeend.latency }, data), timer, handler = function(e) { if(timer) { win.clearTimeout(timer); } timer = win.setTimeout(function() { timer = null; var target = _c.$(e.target); return target.trigger('resizeend', [{ width : target.width(), height : target.height(), }]); }, _data.latency); }; _c.$(this).data('chicago.event.resizeend.uid', uid); _c.$(this).on('resizeend', function() { return _c.$(this).off('resize', _c.utils.debounce(handler, 100)); }); return _c.$(this).on('resizestart', function() { return _c.$(this).on('resize', _c.utils.debounce(handler, 100)).data(uid, handler); }); }, teardown : function() { var uid = _c.$(this).data('chicago.event.resizeend.uid'); _c.$(this).off('resize', _c.$(this).data(uid)); _c.$(this).removeData(uid); return _c.$(this).removeData('chicago.event.resizeend.uid'); } }, resizestart : { setup : function() { var ele = _c.$(this), uid = _c.utils.uid('resizestart'), handler = function(e) { var target = _c.$(e.target); return target.trigger('resizestart', [{ width : target.width(), height : target.height(), }]); }; ele.data('chicago.event.resizestart.uid', uid); ele.on('resizestart', function(e) { return _c.$(this).off('resize', handler); }); ele.on('resizeend', function(e) { return _c.$(this).on('resize', handler).data(uid, handler); }); return ele.on('resize', handler).data(uid, handler); }, teardown : function() { var uid = _c.$(this).data('chicago.event.resizestart.uid'); _c.$(this).off('resize', _c.$(this).data(uid)); _c.$(this).removeData(uid); return _c.$(this).removeData('chicago.event.resizestart.uid'); } }, transition : { defaults : { start : function(property) {}, progress : function(property, duration, value) {}, complete : function(property) {}, }, setup : function(data, namespaces, eventHandle) { var uid = _c.utils.uid('transition'), ele = _c.$(this), keys = { uid : 'chicago.event.transition.uid', base : 'chicago.event.' + uid, event : 'chicago.event.' + uid + '.event', info : 'chicago.event.' + uid + '.info', }, intervalCount = 15, _event = { initalValues : {} }, tracker = _c.win.performace ? _c.win.performace.now : _c.utils.now; data = _c.extend({}, _c.$.event.special.transition.defaults, data); function getTransitionData() { var info = ele.data(keys.info); if(info) { return info; } info = {}; var transition = ele.css('transition').split(','); for(var i = 0; i < transition.length; i++) { var values = transition[i].trim().split(' '), property = values[0]; if(!info.hasOwnProperty(property)) { info[property] = { duration : _c.utils.stringToMilliseconds(values[1]), function : values[2], delay : _c.utils.stringToMilliseconds(values[3]), value : _c.utils.getCSSValue(ele, property) }; } } ele.data(keys.info, info); return info; } function removeDataForProperty(property) { var keyBase = keys.base + '.' + property, _keys = { bindStart : keyBase + '.did.bind.start', didStart : keyBase + '.did.start', didStartAt : keyBase + '.did.start.at', progressValue : keyBase + '.progress.value' }; for(var key in _keys) { var string = _keys[key]; ele.removeData(string); } } function setInitialValues(property) { if(!property) { for(var prop in getTransitionData()) { _event.initalValues[prop] = _c.utils.getCSSValue(ele, prop); } } else { _event.initalValues[property] = _c.utils.getCSSValue(ele, property); } } ele.data(keys.uid, uid); if(!ele.data(keys.event)) { var did = { begin : {}, end : {} }, diff = 0; function completeCallback(property, cssValue, elapsedTime) { diff = 0; did.end[property] = { time : tracker() }; setInitialValues(property); delete did.begin[property]; data.complete.call(ele[0], property, cssValue, elapsedTime); ele.trigger('transition'); } setInitialValues(); ele.on(_c.support.transition.end, function(e) { var property = e.originalEvent.propertyName, cssValue = _c.utils.getCSSValue(ele, property), info = getTransitionData(), elapsedTime = info[property].duration; completeCallback(property, cssValue, elapsedTime); }); _event.interval = win.setInterval(function() { info = getTransitionData(); for(var property in info) { var initialValue = _event.initalValues[property], currentValue = _c.utils.getCSSValue(ele, property), obj = info[property]; if(diff && did.begin[property]) { diff = tracker() - did.begin[property].time; } if(!did.begin[property] && currentValue !== initialValue) { did.begin[property] = { time : tracker() }; if(did.end[property]) { delete did.end[property]; } data.start.call(ele[0], property, initialValue); } else if(did.begin[property] && !did.end[property] && diff < (obj.duration + 1)) { data.progress.call(ele[0], property, currentValue, diff); } } }, intervalCount); ele.data(keys.event, _event); } return true; }, teardown : function() { var uid = _c.$(this).data('chicago.event.transition.uid'), keys = { uid : 'chicago.event.transition.uid', base : 'chicago.event.' + uid, event : 'chicago.event.' + uid + '.event', info : 'chicago.event.' + uid + '.info', }; for(var k in keys) { var key = keys[k], value = _c.$(this).data(key); if(k === 'event' && value && value.interval) { win.clearInterval(value.interval); } if(value) { _c.$(this).removeData(key); } } } }, animation : { defaults : { start : function(name) {}, iteration : function(name, iterationCount) {}, complete : function(name, elapsedTime) {}, }, setup : function(data, namespaces, eventHandle) { var uid = _c.utils.uid('animation'), ele = _c.$(this), keys = { uid : 'chicago.event.animation.uid', base : 'chicago.event.' + uid, iterations : 'chicago.event.' + uid + '.iterations', event : 'chicago.event.' + uid + '.event', }, intervalCount = 15; data = _c.$.extend({}, _c.$.event.special.animation.defaults, data); ele.data(keys.uid, uid); if(!ele.data(keys.event)) { function iterationHandler(e) { var name = e.originalEvent.animationName, count = ele.data(keys.iterations); count++; ele.data(keys.iterations, count); data.iteration.call(ele, name, count); } ele.data(keys.event, { start : ele.on(_c.support.animation.start, function(e) { data.start.call(ele, e.originalEvent.animationName); ele.data(keys.iterations, 0); }), iteration : ele.on(_c.support.animation.iteration, iterationHandler), end : ele.on(_c.support.animation.end, function(e) { iterationHandler(e); var name = e.originalEvent.animationName; var time = _c.utils.stringToMilliseconds(e.originalEvent.elapsedTime); data.complete.call(ele, name, time); ele.trigger('animation'); }) }); } return true; }, teardown : function() { var uid = _c.$(this).data('chicago.event.animation.uid'), keys = { uid : 'chicago.event.animation.uid', base : 'chicago.event.' + uid, iterations : 'chicago.event.' + uid + '.iterations', event : 'chicago.event.' + uid + '.event', }; for(var k in keys) { var key = keys[k], value = _c.$(this).data(key); if(value) { _c.$(this).removeData(key); } } } }, swipe : { setup : function(data) { var uid = _c.utils.uid('scrollstart'), target = _c.$(this), events = { down : 'touchstart MSPointerDown pointerdown mousedown', move : 'touchmove MSPointerMove pointermove mousemove', up : 'touchend MSPointerUp pointerup mouseup mouseleave' }, memory = { down : { x : 0, y : 0, }, up : { x : 0, y : 0, }, }; function swipeDirection(x1, x2, y1, y2) { return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'left' : 'right') : (y1 - y2 > 0 ? 'up' : 'down'); } function unbind(string, handler) { string.split(' ').forEach(function(evt) { target.off(evt, handler); }); } function downHandler(e) { memory.down = { x : e.screenX, y : e.screenY, }; target.on(events.move, moveHanlder); } function moveHanlder(e) { unbind(events.up, upHandler); target.one(events.up, upHandler); } function upHandler(e) { unbind(events.move, moveHanlder); unbind(events.up, upHandler); memory.up = { x : e.screenX, y : e.screenY, }; var dir = swipeDirection(memory.down.x, memory.up.x, memory.down.y, memory.up.y); target.trigger('swipe', [dir]); target.trigger('swipe' + dir); } target.on(events.down, downHandler); _c.$(this).data('chicago.event.swipe.uid', uid).data(uid, downHandler); }, teardown : function() { var uid = _c.$(this).data('chicago.event.scrollstart.uid'); return _c.$(this).removeData(uid).removeData('chicago.event.scrollstart.uid'); } }, }; (function() { for(var k in _c.events) { var v = _c.events[k]; if(_c.utils.is.object(v)) { _c.$.event.special[k] = v; var fn = function(options, callback) { return this.each(function() { return _c.$(this).on(k, options, callback); }); }; _c.$.fn[k] = fn; } } })(); });