UNPKG

selectize

Version:

Selectize is a jQuery-based custom <select> UI control. Useful for tagging, contact lists, country selectors, etc.

1,554 lines (1,550 loc) 84.4 kB
/** * Syn - 0.0.3 * * @copyright 2014 Bitovi * Wed, 10 Dec 2014 16:34:18 GMT * @license MIT */ /*[global-shim]*/ (function (exports, global){ var origDefine = global.define; var get = function(name){ var parts = name.split("."), cur = global, i; for(i = 0 ; i < parts.length; i++){ cur = cur[parts[i]]; } return cur; }; var modules = global.define && global.define.modules || {}; var ourDefine = global.define = function(moduleName, deps, callback){ var module; if(typeof deps === "function") { callback = deps; deps = []; } var args = [], i; for(i =0; i < deps.length; i++) { args.push( exports[deps[i]] ? get(exports[deps[i]]) : modules[deps[i]] ); } // CJS has no dependencies but 3 callback arguments if(!deps.length && callback.length) { module = { exports: {} }; var require = function(name) { return exports[name] ? get(exports[name]) : modules[name]; }; args.push(require, module.exports, module); } global.define = origDefine; var result = callback ? callback.apply(null, args) : undefined; global.define = ourDefine; // Favor CJS module.exports over the return value modules[moduleName] = module && module.exports ? module.exports : result; }; global.define.modules = modules; global.System = { define: function(__name, __code){ global.define = origDefine; eval("(function() { " + __code + " \n }).call(global);"); global.define = ourDefine; } }; })({},window) /*syn/synthetic*/ define('syn/synthetic', [], function () { var opts = window.syn ? window.syn : {}; var extend = function (d, s) { var p; for (p in s) { d[p] = s[p]; } return d; }, browser = { msie: !!(window.attachEvent && !window.opera), opera: !!window.opera, webkit: navigator.userAgent.indexOf('AppleWebKit/') > -1, safari: navigator.userAgent.indexOf('AppleWebKit/') > -1 && navigator.userAgent.indexOf('Chrome/') === -1, gecko: navigator.userAgent.indexOf('Gecko') > -1, mobilesafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/), rhino: navigator.userAgent.match(/Rhino/) && true }, createEventObject = function (type, options, element) { var event = element.ownerDocument.createEventObject(); return extend(event, options); }, data = {}, id = 1, expando = '_synthetic' + new Date().getTime(), bind, unbind, schedule, key = /keypress|keyup|keydown/, page = /load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll/, activeElement, syn = function (type, element, options, callback) { return new syn.init(type, element, options, callback); }; syn.config = opts; syn.__tryFocus = function tryFocus(element) { try { element.focus(); } catch (e) { } }; bind = function (el, ev, f) { return el.addEventListener ? el.addEventListener(ev, f, false) : el.attachEvent('on' + ev, f); }; unbind = function (el, ev, f) { return el.addEventListener ? el.removeEventListener(ev, f, false) : el.detachEvent('on' + ev, f); }; schedule = syn.config.schedule || function (fn, ms) { setTimeout(fn, ms); }; extend(syn, { init: function (type, element, options, callback) { var args = syn.args(options, element, callback), self = this; this.queue = []; this.element = args.element; if (typeof this[type] === 'function') { this[type](args.element, args.options, function (defaults, el) { if (args.callback) { args.callback.apply(self, arguments); } self.done.apply(self, arguments); }); } else { this.result = syn.trigger(args.element, type, args.options); if (args.callback) { args.callback.call(this, args.element, this.result); } } }, jquery: function (el, fast) { if (window.FuncUnit && window.FuncUnit.jQuery) { return window.FuncUnit.jQuery; } if (el) { return syn.helpers.getWindow(el).jQuery || window.jQuery; } else { return window.jQuery; } }, args: function () { var res = {}, i = 0; for (; i < arguments.length; i++) { if (typeof arguments[i] === 'function') { res.callback = arguments[i]; } else if (arguments[i] && arguments[i].jquery) { res.element = arguments[i][0]; } else if (arguments[i] && arguments[i].nodeName) { res.element = arguments[i]; } else if (res.options && typeof arguments[i] === 'string') { res.element = document.getElementById(arguments[i]); } else if (arguments[i]) { res.options = arguments[i]; } } return res; }, click: function (element, options, callback) { syn('click!', element, options, callback); }, defaults: { focus: function focus() { if (!syn.support.focusChanges) { var element = this, nodeName = element.nodeName.toLowerCase(); syn.data(element, 'syntheticvalue', element.value); if (nodeName === 'input' || nodeName === 'textarea') { bind(element, 'blur', function () { if (syn.data(element, 'syntheticvalue') !== element.value) { syn.trigger(element, 'change', {}); } unbind(element, 'blur', focus); }); } } }, submit: function () { syn.onParents(this, function (el) { if (el.nodeName.toLowerCase() === 'form') { el.submit(); return false; } }); } }, changeOnBlur: function (element, prop, value) { bind(element, 'blur', function onblur() { if (value !== element[prop]) { syn.trigger(element, 'change', {}); } unbind(element, 'blur', onblur); }); }, closest: function (el, type) { while (el && el.nodeName.toLowerCase() !== type.toLowerCase()) { el = el.parentNode; } return el; }, data: function (el, key, value) { var d; if (!el[expando]) { el[expando] = id++; } if (!data[el[expando]]) { data[el[expando]] = {}; } d = data[el[expando]]; if (value) { data[el[expando]][key] = value; } else { return data[el[expando]][key]; } }, onParents: function (el, func) { var res; while (el && res !== false) { res = func(el); el = el.parentNode; } return el; }, focusable: /^(a|area|frame|iframe|label|input|select|textarea|button|html|object)$/i, isFocusable: function (elem) { var attributeNode; if (elem.getAttributeNode) { attributeNode = elem.getAttributeNode('tabIndex'); } return this.focusable.test(elem.nodeName) || attributeNode && attributeNode.specified && syn.isVisible(elem); }, isVisible: function (elem) { return elem.offsetWidth && elem.offsetHeight || elem.clientWidth && elem.clientHeight; }, tabIndex: function (elem) { var attributeNode = elem.getAttributeNode('tabIndex'); return attributeNode && attributeNode.specified && (parseInt(elem.getAttribute('tabIndex')) || 0); }, bind: bind, unbind: unbind, schedule: schedule, browser: browser, helpers: { createEventObject: createEventObject, createBasicStandardEvent: function (type, defaults, doc) { var event; try { event = doc.createEvent('Events'); } catch (e2) { event = doc.createEvent('UIEvents'); } finally { event.initEvent(type, true, true); extend(event, defaults); } return event; }, inArray: function (item, array) { var i = 0; for (; i < array.length; i++) { if (array[i] === item) { return i; } } return -1; }, getWindow: function (element) { if (element.ownerDocument) { return element.ownerDocument.defaultView || element.ownerDocument.parentWindow; } }, extend: extend, scrollOffset: function (win, set) { var doc = win.document.documentElement, body = win.document.body; if (set) { window.scrollTo(set.left, set.top); } else { return { left: (doc && doc.scrollLeft || body && body.scrollLeft || 0) + (doc.clientLeft || 0), top: (doc && doc.scrollTop || body && body.scrollTop || 0) + (doc.clientTop || 0) }; } }, scrollDimensions: function (win) { var doc = win.document.documentElement, body = win.document.body, docWidth = doc.clientWidth, docHeight = doc.clientHeight, compat = win.document.compatMode === 'CSS1Compat'; return { height: compat && docHeight || body.clientHeight || docHeight, width: compat && docWidth || body.clientWidth || docWidth }; }, addOffset: function (options, el) { var jq = syn.jquery(el), off; if (typeof options === 'object' && options.clientX === undefined && options.clientY === undefined && options.pageX === undefined && options.pageY === undefined && jq) { el = jq(el); off = el.offset(); options.pageX = off.left + el.width() / 2; options.pageY = off.top + el.height() / 2; } } }, key: { ctrlKey: null, altKey: null, shiftKey: null, metaKey: null }, dispatch: function (event, element, type, autoPrevent) { if (element.dispatchEvent && event) { var preventDefault = event.preventDefault, prevents = autoPrevent ? -1 : 0; if (autoPrevent) { bind(element, type, function ontype(ev) { ev.preventDefault(); unbind(this, type, ontype); }); } event.preventDefault = function () { prevents++; if (++prevents > 0) { preventDefault.apply(this, []); } }; element.dispatchEvent(event); return prevents <= 0; } else { try { window.event = event; } catch (e) { } return element.sourceIndex <= 0 || element.fireEvent && element.fireEvent('on' + type, event); } }, create: { page: { event: function (type, options, element) { var doc = syn.helpers.getWindow(element).document || document, event; if (doc.createEvent) { event = doc.createEvent('Events'); event.initEvent(type, true, true); return event; } else { try { event = createEventObject(type, options, element); } catch (e) { } return event; } } }, focus: { event: function (type, options, element) { syn.onParents(element, function (el) { if (syn.isFocusable(el)) { if (el.nodeName.toLowerCase() !== 'html') { syn.__tryFocus(el); activeElement = el; } else if (activeElement) { var doc = syn.helpers.getWindow(element).document; if (doc !== window.document) { return false; } else if (doc.activeElement) { doc.activeElement.blur(); activeElement = null; } else { activeElement.blur(); activeElement = null; } } return false; } }); return true; } } }, support: { clickChanges: false, clickSubmits: false, keypressSubmits: false, mouseupSubmits: false, radioClickChanges: false, focusChanges: false, linkHrefJS: false, keyCharacters: false, backspaceWorks: false, mouseDownUpClicks: false, tabKeyTabs: false, keypressOnAnchorClicks: false, optionClickBubbles: false, ready: 0 }, trigger: function (element, type, options) { if (!options) { options = {}; } var create = syn.create, setup = create[type] && create[type].setup, kind = key.test(type) ? 'key' : page.test(type) ? 'page' : 'mouse', createType = create[type] || {}, createKind = create[kind], event, ret, autoPrevent, dispatchEl = element; if (syn.support.ready === 2 && setup) { setup(type, options, element); } autoPrevent = options._autoPrevent; delete options._autoPrevent; if (createType.event) { ret = createType.event(type, options, element); } else { options = createKind.options ? createKind.options(type, options, element) : options; if (!syn.support.changeBubbles && /option/i.test(element.nodeName)) { dispatchEl = element.parentNode; } event = createKind.event(type, options, dispatchEl); ret = syn.dispatch(event, dispatchEl, type, autoPrevent); } if (ret && syn.support.ready === 2 && syn.defaults[type]) { syn.defaults[type].call(element, options, autoPrevent); } return ret; }, eventSupported: function (eventName) { var el = document.createElement('div'); eventName = 'on' + eventName; var isSupported = eventName in el; if (!isSupported) { el.setAttribute(eventName, 'return;'); isSupported = typeof el[eventName] === 'function'; } el = null; return isSupported; } }); extend(syn.init.prototype, { then: function (type, element, options, callback) { if (syn.autoDelay) { this.delay(); } var args = syn.args(options, element, callback), self = this; this.queue.unshift(function (el, prevented) { if (typeof this[type] === 'function') { this.element = args.element || el; this[type](this.element, args.options, function (defaults, el) { if (args.callback) { args.callback.apply(self, arguments); } self.done.apply(self, arguments); }); } else { this.result = syn.trigger(args.element, type, args.options); if (args.callback) { args.callback.call(this, args.element, this.result); } return this; } }); return this; }, delay: function (timeout, callback) { if (typeof timeout === 'function') { callback = timeout; timeout = null; } timeout = timeout || 600; var self = this; this.queue.unshift(function () { schedule(function () { if (callback) { callback.apply(self, []); } self.done.apply(self, arguments); }, timeout); }); return this; }, done: function (defaults, el) { if (el) { this.element = el; } if (this.queue.length) { this.queue.pop().call(this, this.element, defaults); } }, '_click': function (element, options, callback, force) { syn.helpers.addOffset(options, element); syn.trigger(element, 'mousedown', options); schedule(function () { syn.trigger(element, 'mouseup', options); if (!syn.support.mouseDownUpClicks || force) { syn.trigger(element, 'click', options); callback(true); } else { syn.create.click.setup('click', options, element); syn.defaults.click.call(element); schedule(function () { callback(true); }, 1); } }, 1); }, '_rightClick': function (element, options, callback) { syn.helpers.addOffset(options, element); var mouseopts = extend(extend({}, syn.mouse.browser.right.mouseup), options); syn.trigger(element, 'mousedown', mouseopts); schedule(function () { syn.trigger(element, 'mouseup', mouseopts); if (syn.mouse.browser.right.contextmenu) { syn.trigger(element, 'contextmenu', extend(extend({}, syn.mouse.browser.right.contextmenu), options)); } callback(true); }, 1); }, '_dblclick': function (element, options, callback) { syn.helpers.addOffset(options, element); var self = this; this._click(element, options, function () { schedule(function () { self._click(element, options, function () { syn.trigger(element, 'dblclick', options); callback(true); }, true); }, 2); }); } }); var actions = [ 'click', 'dblclick', 'move', 'drag', 'key', 'type', 'rightClick' ], makeAction = function (name) { syn[name] = function (element, options, callback) { return syn('_' + name, element, options, callback); }; syn.init.prototype[name] = function (element, options, callback) { return this.then('_' + name, element, options, callback); }; }, i = 0; for (; i < actions.length; i++) { makeAction(actions[i]); } return syn; }); /*syn/mouse*/ define('syn/mouse', ['syn/synthetic'], function (syn) { var h = syn.helpers, getWin = h.getWindow; syn.mouse = {}; h.extend(syn.defaults, { mousedown: function (options) { syn.trigger(this, 'focus', {}); }, click: function () { var element = this, href, type, createChange, radioChanged, nodeName, scope; try { href = element.href; type = element.type; createChange = syn.data(element, 'createChange'); radioChanged = syn.data(element, 'radioChanged'); scope = getWin(element); nodeName = element.nodeName.toLowerCase(); } catch (e) { return; } if (!syn.support.linkHrefJS && /^\s*javascript:/.test(href)) { var code = href.replace(/^\s*javascript:/, ''); if (code !== '//' && code.indexOf('void(0)') === -1) { if (window.selenium) { eval('with(selenium.browserbot.getCurrentWindow()){' + code + '}'); } else { eval('with(scope){' + code + '}'); } } } if (!syn.support.clickSubmits && (nodeName === 'input' && type === 'submit') || nodeName === 'button') { var form = syn.closest(element, 'form'); if (form) { syn.trigger(form, 'submit', {}); } } if (nodeName === 'a' && element.href && !/^\s*javascript:/.test(href)) { scope.location.href = href; } if (nodeName === 'input' && type === 'checkbox') { if (!syn.support.clickChanges) { syn.trigger(element, 'change', {}); } } if (nodeName === 'input' && type === 'radio') { if (radioChanged && !syn.support.radioClickChanges) { syn.trigger(element, 'change', {}); } } if (nodeName === 'option' && createChange) { syn.trigger(element.parentNode, 'change', {}); syn.data(element, 'createChange', false); } } }); h.extend(syn.create, { mouse: { options: function (type, options, element) { var doc = document.documentElement, body = document.body, center = [ options.pageX || 0, options.pageY || 0 ], left = syn.mouse.browser && syn.mouse.browser.left[type], right = syn.mouse.browser && syn.mouse.browser.right[type]; return h.extend({ bubbles: true, cancelable: true, view: window, detail: 1, screenX: 1, screenY: 1, clientX: options.clientX || center[0] - (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0), clientY: options.clientY || center[1] - (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0), ctrlKey: !!syn.key.ctrlKey, altKey: !!syn.key.altKey, shiftKey: !!syn.key.shiftKey, metaKey: !!syn.key.metaKey, button: left && left.button !== null ? left.button : right && right.button || (type === 'contextmenu' ? 2 : 0), relatedTarget: document.documentElement }, options); }, event: function (type, defaults, element) { var doc = getWin(element).document || document, event; if (doc.createEvent) { try { event = doc.createEvent('MouseEvents'); event.initMouseEvent(type, defaults.bubbles, defaults.cancelable, defaults.view, defaults.detail, defaults.screenX, defaults.screenY, defaults.clientX, defaults.clientY, defaults.ctrlKey, defaults.altKey, defaults.shiftKey, defaults.metaKey, defaults.button, defaults.relatedTarget); } catch (e) { event = h.createBasicStandardEvent(type, defaults, doc); } event.synthetic = true; return event; } else { try { event = h.createEventObject(type, defaults, element); } catch (e) { } return event; } } }, click: { setup: function (type, options, element) { var nodeName = element.nodeName.toLowerCase(); if (!syn.support.clickChecks && !syn.support.changeChecks && nodeName === 'input') { type = element.type.toLowerCase(); if (type === 'checkbox') { element.checked = !element.checked; } if (type === 'radio') { if (!element.checked) { try { syn.data(element, 'radioChanged', true); } catch (e) { } element.checked = true; } } } if (nodeName === 'a' && element.href && !/^\s*javascript:/.test(element.href)) { syn.data(element, 'href', element.href); } if (/option/i.test(element.nodeName)) { var child = element.parentNode.firstChild, i = -1; while (child) { if (child.nodeType === 1) { i++; if (child === element) { break; } } child = child.nextSibling; } if (i !== element.parentNode.selectedIndex) { element.parentNode.selectedIndex = i; syn.data(element, 'createChange', true); } } } }, mousedown: { setup: function (type, options, element) { var nn = element.nodeName.toLowerCase(); if (syn.browser.safari && (nn === 'select' || nn === 'option')) { options._autoPrevent = true; } } } }); return syn; }); /*syn/mouse.support*/ define('syn/mouse.support', [ 'syn/synthetic', 'syn/mouse' ], function checkSupport(syn) { if (!document.body) { syn.schedule(function () { checkSupport(syn); }, 1); return; } window.__synthTest = function () { syn.support.linkHrefJS = true; }; var div = document.createElement('div'), checkbox, submit, form, select; div.innerHTML = '<form id=\'outer\'>' + '<input name=\'checkbox\' type=\'checkbox\'/>' + '<input name=\'radio\' type=\'radio\' />' + '<input type=\'submit\' name=\'submitter\'/>' + '<input type=\'input\' name=\'inputter\'/>' + '<input name=\'one\'>' + '<input name=\'two\'/>' + '<a href=\'javascript:__synthTest()\' id=\'synlink\'></a>' + '<select><option></option></select>' + '</form>'; document.documentElement.appendChild(div); form = div.firstChild; checkbox = form.childNodes[0]; submit = form.childNodes[2]; select = form.getElementsByTagName('select')[0]; syn.trigger(form.childNodes[6], 'click', {}); checkbox.checked = false; checkbox.onchange = function () { syn.support.clickChanges = true; }; syn.trigger(checkbox, 'click', {}); syn.support.clickChecks = checkbox.checked; checkbox.checked = false; syn.trigger(checkbox, 'change', {}); syn.support.changeChecks = checkbox.checked; form.onsubmit = function (ev) { if (ev.preventDefault) { ev.preventDefault(); } syn.support.clickSubmits = true; return false; }; syn.trigger(submit, 'click', {}); form.childNodes[1].onchange = function () { syn.support.radioClickChanges = true; }; syn.trigger(form.childNodes[1], 'click', {}); syn.bind(div, 'click', function onclick() { syn.support.optionClickBubbles = true; syn.unbind(div, 'click', onclick); }); syn.trigger(select.firstChild, 'click', {}); syn.support.changeBubbles = syn.eventSupported('change'); div.onclick = function () { syn.support.mouseDownUpClicks = true; }; syn.trigger(div, 'mousedown', {}); syn.trigger(div, 'mouseup', {}); document.documentElement.removeChild(div); syn.support.ready++; }); /*syn/browsers*/ define('syn/browsers', [ 'syn/synthetic', 'syn/mouse' ], function (syn) { syn.key.browsers = { webkit: { 'prevent': { 'keyup': [], 'keydown': [ 'char', 'keypress' ], 'keypress': ['char'] }, 'character': { 'keydown': [ 0, 'key' ], 'keypress': [ 'char', 'char' ], 'keyup': [ 0, 'key' ] }, 'specialChars': { 'keydown': [ 0, 'char' ], 'keyup': [ 0, 'char' ] }, 'navigation': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'special': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'tab': { 'keydown': [ 0, 'char' ], 'keyup': [ 0, 'char' ] }, 'pause-break': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'caps': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'escape': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'num-lock': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'scroll-lock': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'print': { 'keyup': [ 0, 'key' ] }, 'function': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, '\r': { 'keydown': [ 0, 'key' ], 'keypress': [ 'char', 'key' ], 'keyup': [ 0, 'key' ] } }, gecko: { 'prevent': { 'keyup': [], 'keydown': ['char'], 'keypress': ['char'] }, 'character': { 'keydown': [ 0, 'key' ], 'keypress': [ 'char', 0 ], 'keyup': [ 0, 'key' ] }, 'specialChars': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'navigation': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'special': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, '\t': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'pause-break': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'caps': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'escape': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'num-lock': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'scroll-lock': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, 'print': { 'keyup': [ 0, 'key' ] }, 'function': { 'keydown': [ 0, 'key' ], 'keyup': [ 0, 'key' ] }, '\r': { 'keydown': [ 0, 'key' ], 'keypress': [ 0, 'key' ], 'keyup': [ 0, 'key' ] } }, msie: { 'prevent': { 'keyup': [], 'keydown': [ 'char', 'keypress' ], 'keypress': ['char'] }, 'character': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'char' ], 'keyup': [ null, 'key' ] }, 'specialChars': { 'keydown': [ null, 'char' ], 'keyup': [ null, 'char' ] }, 'navigation': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'special': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'tab': { 'keydown': [ null, 'char' ], 'keyup': [ null, 'char' ] }, 'pause-break': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'caps': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'escape': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'num-lock': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'scroll-lock': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'print': { 'keyup': [ null, 'key' ] }, 'function': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, '\r': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] } }, opera: { 'prevent': { 'keyup': [], 'keydown': [], 'keypress': ['char'] }, 'character': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'char' ], 'keyup': [ null, 'key' ] }, 'specialChars': { 'keydown': [ null, 'char' ], 'keypress': [ null, 'char' ], 'keyup': [ null, 'char' ] }, 'navigation': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ] }, 'special': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'tab': { 'keydown': [ null, 'char' ], 'keypress': [ null, 'char' ], 'keyup': [ null, 'char' ] }, 'pause-break': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'caps': { 'keydown': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'escape': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ] }, 'num-lock': { 'keyup': [ null, 'key' ], 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ] }, 'scroll-lock': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] }, 'print': {}, 'function': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] }, '\r': { 'keydown': [ null, 'key' ], 'keypress': [ null, 'key' ], 'keyup': [ null, 'key' ] } } }; syn.mouse.browsers = { webkit: { 'right': { 'mousedown': { 'button': 2, 'which': 3 }, 'mouseup': { 'button': 2, 'which': 3 }, 'contextmenu': { 'button': 2, 'which': 3 } }, 'left': { 'mousedown': { 'button': 0, 'which': 1 }, 'mouseup': { 'button': 0, 'which': 1 }, 'click': { 'button': 0, 'which': 1 } } }, opera: { 'right': { 'mousedown': { 'button': 2, 'which': 3 }, 'mouseup': { 'button': 2, 'which': 3 } }, 'left': { 'mousedown': { 'button': 0, 'which': 1 }, 'mouseup': { 'button': 0, 'which': 1 }, 'click': { 'button': 0, 'which': 1 } } }, msie: { 'right': { 'mousedown': { 'button': 2 }, 'mouseup': { 'button': 2 }, 'contextmenu': { 'button': 0 } }, 'left': { 'mousedown': { 'button': 1 }, 'mouseup': { 'button': 1 }, 'click': { 'button': 0 } } }, chrome: { 'right': { 'mousedown': { 'button': 2, 'which': 3 }, 'mouseup': { 'button': 2, 'which': 3 }, 'contextmenu': { 'button': 2, 'which': 3 } }, 'left': { 'mousedown': { 'button': 0, 'which': 1 }, 'mouseup': { 'button': 0, 'which': 1 }, 'click': { 'button': 0, 'which': 1 } } }, gecko: { 'left': { 'mousedown': { 'button': 0, 'which': 1 }, 'mouseup': { 'button': 0, 'which': 1 }, 'click': { 'button': 0, 'which': 1 } }, 'right': { 'mousedown': { 'button': 2, 'which': 3 }, 'mouseup': { 'button': 2, 'which': 3 }, 'contextmenu': { 'button': 2, 'which': 3 } } } }; syn.key.browser = function () { if (syn.key.browsers[window.navigator.userAgent]) { return syn.key.browsers[window.navigator.userAgent]; } for (var browser in syn.browser) { if (syn.browser[browser] && syn.key.browsers[browser]) { return syn.key.browsers[browser]; } } return syn.key.browsers.gecko; }(); syn.mouse.browser = function () { if (syn.mouse.browsers[window.navigator.userAgent]) { return syn.mouse.browsers[window.navigator.userAgent]; } for (var browser in syn.browser) { if (syn.browser[browser] && syn.mouse.browsers[browser]) { return syn.mouse.browsers[browser]; } } return syn.mouse.browsers.gecko; }(); return syn; }); /*syn/typeable*/ define('syn/typeable', ['syn/synthetic'], function (syn) { var typeables = []; var __indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) { return i; } } return -1; }; syn.typeable = function (fn) { if (__indexOf.call(typeables, fn) === -1) { typeables.push(fn); } }; syn.typeable.test = function (el) { for (var i = 0, len = typeables.length; i < len; i++) { if (typeables[i](el)) { return true; } } return false; }; var type = syn.typeable; var typeableExp = /input|textarea/i; type(function (el) { return typeableExp.test(el.nodeName); }); type(function (el) { return __indexOf.call([ '', 'true' ], el.getAttribute('contenteditable')) !== -1; }); return syn; }); /*syn/key*/ define('syn/key', [ 'syn/synthetic', 'syn/typeable', 'syn/browsers' ], function (syn) { var h = syn.helpers, getSelection = function (el) { var real, r, start; if (el.selectionStart !== undefined) { if (document.activeElement && document.activeElement !== el && el