From ecde0ea7a28fa3d16362373907bc8816bf5c9f0d Mon Sep 17 00:00:00 2001 From: Jacob Hash Date: Wed, 21 May 2014 15:11:52 -0400 Subject: [PATCH 1/9] Selectize Modifications For Pasting Delimited Values --- dist/css/selectize.bootstrap2.css | 95 --------- dist/css/selectize.bootstrap3.css | 95 --------- dist/css/selectize.css | 95 --------- dist/css/selectize.default.css | 95 --------- dist/css/selectize.legacy.css | 95 --------- dist/js/selectize.js | 265 ++---------------------- dist/js/selectize.min.js | 3 +- dist/js/standalone/selectize.js | 265 ++---------------------- dist/js/standalone/selectize.min.js | 4 +- dist/less/plugins/drag_drop.less | 16 -- dist/less/plugins/dropdown_header.less | 20 -- dist/less/plugins/optgroup_columns.less | 17 -- dist/less/plugins/remove_button.less | 37 ---- dist/less/selectize.less | 5 +- src/defaults.js | 1 + src/selectize.js | 19 +- 16 files changed, 58 insertions(+), 1069 deletions(-) delete mode 100644 dist/less/plugins/drag_drop.less delete mode 100644 dist/less/plugins/dropdown_header.less delete mode 100644 dist/less/plugins/optgroup_columns.less delete mode 100644 dist/less/plugins/remove_button.less diff --git a/dist/css/selectize.bootstrap2.css b/dist/css/selectize.bootstrap2.css index 5dca1f770..f2d45646a 100644 --- a/dist/css/selectize.bootstrap2.css +++ b/dist/css/selectize.bootstrap2.css @@ -13,101 +13,6 @@ * * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 3px 10px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 10px; - top: 50%; - color: #333333; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 1px 0 0 0; - border-left: 1px solid #cccccc; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: #0077b3; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: #e0e0e0; -} .selectize-control { position: relative; } diff --git a/dist/css/selectize.bootstrap3.css b/dist/css/selectize.bootstrap3.css index 9807775df..fa62586f1 100644 --- a/dist/css/selectize.bootstrap3.css +++ b/dist/css/selectize.bootstrap3.css @@ -13,101 +13,6 @@ * * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 3px 12px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 12px; - top: 50%; - color: #333333; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 1px 0 0 0; - border-left: 1px solid rgba(0, 0, 0, 0); - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: rgba(0, 0, 0, 0); -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: rgba(77, 77, 77, 0); -} .selectize-control { position: relative; } diff --git a/dist/css/selectize.css b/dist/css/selectize.css index b3002c139..72bbfa696 100644 --- a/dist/css/selectize.css +++ b/dist/css/selectize.css @@ -14,101 +14,6 @@ * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 5px 8px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 8px; - top: 50%; - color: #303030; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 2px 0 0 0; - border-left: 1px solid #d0d0d0; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: #cacaca; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: #ffffff; -} .selectize-control { position: relative; } diff --git a/dist/css/selectize.default.css b/dist/css/selectize.default.css index 0d8947e90..fb111bef6 100644 --- a/dist/css/selectize.default.css +++ b/dist/css/selectize.default.css @@ -13,101 +13,6 @@ * * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 5px 8px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 8px; - top: 50%; - color: #303030; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 2px 0 0 0; - border-left: 1px solid #0073bb; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: #00578d; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: #aaaaaa; -} .selectize-control { position: relative; } diff --git a/dist/css/selectize.legacy.css b/dist/css/selectize.legacy.css index b5d5d03e8..721b7bb0a 100644 --- a/dist/css/selectize.legacy.css +++ b/dist/css/selectize.legacy.css @@ -13,101 +13,6 @@ * * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0, 0, 0, 0.06) !important; - border: 0 none !important; - -webkit-box-shadow: inset 0 0 12px 4px #ffffff; - box-shadow: inset 0 0 12px 4px #ffffff; -} -.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; -} -.selectize-control.plugin-drag_drop .ui-sortable-helper { - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); -} -.selectize-dropdown-header { - position: relative; - padding: 7px 10px; - border-bottom: 1px solid #d0d0d0; - background: #f8f8f8; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.selectize-dropdown-header-close { - position: absolute; - right: 10px; - top: 50%; - color: #303030; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: #000000; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { - border-right: 0 none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup:before { - display: none; -} -.selectize-dropdown.plugin-optgroup_columns .optgroup-header { - border-top: 0 none; -} -.selectize-control.plugin-remove_button [data-value] { - position: relative; - padding-right: 24px !important; -} -.selectize-control.plugin-remove_button [data-value] .remove { - z-index: 1; - /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: 1px 0 0 0; - border-left: 1px solid #74b21e; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.selectize-control.plugin-remove_button [data-value] .remove:hover { - background: rgba(0, 0, 0, 0.05); -} -.selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: #6f9839; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { - background: none; -} -.selectize-control.plugin-remove_button .disabled [data-value] .remove { - border-left-color: #b4b4b4; -} .selectize-control { position: relative; } diff --git a/dist/js/selectize.js b/dist/js/selectize.js index 2b44c6430..770e9c643 100644 --- a/dist/js/selectize.js +++ b/dist/js/selectize.js @@ -836,6 +836,16 @@ var self = this; if (self.isFull() || self.isInputHidden || self.isLocked) { e.preventDefault(); + } else { + // If a regex or string is included, this will split the pasted input and create Items for each separate value + if (self.settings.splitOn) { + setTimeout($.proxy(function() { + var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); + splitInput.forEach($.proxy(function(input) { + self.createItem(input); + }, self)); + }, self), 0); + } } }, @@ -1842,13 +1852,18 @@ var self = this; var input = $.trim(self.$control_input.val() || ''); var caret = self.caretPos; - if (!input.length) return false; - self.lock(); if (typeof triggerDropdown === 'undefined') { triggerDropdown = true; + + // allow a string to be passed in, like the API docs say + } else if (typeof triggerDropdown === 'string') { + input = triggerDropdown; } + if (!input.length) return false; + self.lock(); + var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) { var data = {}; data[self.settings.labelField] = input; @@ -2360,6 +2375,7 @@ Selectize.defaults = { plugins: [], delimiter: ',', + splitOn: /[,]+/, // Regex or string for splitting up values from a paste command persist: true, diacritics: true, create: false, @@ -2570,251 +2586,6 @@ }; $.fn.selectize.defaults = Selectize.defaults; - - Selectize.define('drag_drop', function(options) { - if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); - if (this.settings.mode !== 'multi') return; - var self = this; - - self.lock = (function() { - var original = self.lock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.disable(); - return original.apply(self, arguments); - }; - })(); - - self.unlock = (function() { - var original = self.unlock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.enable(); - return original.apply(self, arguments); - }; - })(); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(this, arguments); - - var $control = self.$control.sortable({ - items: '[data-value]', - forcePlaceholderSize: true, - disabled: self.isLocked, - start: function(e, ui) { - ui.placeholder.css('width', ui.helper.css('width')); - $control.css({overflow: 'visible'}); - }, - stop: function() { - $control.css({overflow: 'hidden'}); - var active = self.$activeItems ? self.$activeItems.slice() : null; - var values = []; - $control.children('[data-value]').each(function() { - values.push($(this).attr('data-value')); - }); - self.setValue(values); - self.setActiveItem(active); - } - }); - }; - })(); - - }); - - Selectize.define('dropdown_header', function(options) { - var self = this; - - options = $.extend({ - title : 'Untitled', - headerClass : 'selectize-dropdown-header', - titleRowClass : 'selectize-dropdown-header-title', - labelClass : 'selectize-dropdown-header-label', - closeClass : 'selectize-dropdown-header-close', - - html: function(data) { - return ( - '
' + - '
' + - '' + data.title + '' + - '×' + - '
' + - '
' - ); - } - }, options); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(self, arguments); - self.$dropdown_header = $(options.html(options)); - self.$dropdown.prepend(self.$dropdown_header); - }; - })(); - - }); - - Selectize.define('optgroup_columns', function(options) { - var self = this; - - options = $.extend({ - equalizeWidth : true, - equalizeHeight : true - }, options); - - this.getAdjacentOption = function($option, direction) { - var $options = $option.closest('[data-group]').find('[data-selectable]'); - var index = $options.index($option) + direction; - - return index >= 0 && index < $options.length ? $options.eq(index) : $(); - }; - - this.onKeyDown = (function() { - var original = self.onKeyDown; - return function(e) { - var index, $option, $options, $optgroup; - - if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { - self.ignoreHover = true; - $optgroup = this.$activeOption.closest('[data-group]'); - index = $optgroup.find('[data-selectable]').index(this.$activeOption); - - if(e.keyCode === KEY_LEFT) { - $optgroup = $optgroup.prev('[data-group]'); - } else { - $optgroup = $optgroup.next('[data-group]'); - } - - $options = $optgroup.find('[data-selectable]'); - $option = $options.eq(Math.min($options.length - 1, index)); - if ($option.length) { - this.setActiveOption($option); - } - return; - } - - return original.apply(this, arguments); - }; - })(); - - var equalizeSizes = function() { - var i, n, height_max, width, width_last, width_parent, $optgroups; - - $optgroups = $('[data-group]', self.$dropdown_content); - n = $optgroups.length; - if (!n || !self.$dropdown_content.width()) return; - - if (options.equalizeHeight) { - height_max = 0; - for (i = 0; i < n; i++) { - height_max = Math.max(height_max, $optgroups.eq(i).height()); - } - $optgroups.css({height: height_max}); - } - - if (options.equalizeWidth) { - width_parent = self.$dropdown_content.innerWidth(); - width = Math.round(width_parent / n); - $optgroups.css({width: width}); - if (n > 1) { - width_last = width_parent - width * (n - 1); - $optgroups.eq(n - 1).css({width: width_last}); - } - } - }; - - if (options.equalizeHeight || options.equalizeWidth) { - hook.after(this, 'positionDropdown', equalizeSizes); - hook.after(this, 'refreshOptions', equalizeSizes); - } - - - }); - - Selectize.define('remove_button', function(options) { - if (this.settings.mode === 'single') return; - - options = $.extend({ - label : '×', - title : 'Remove', - className : 'remove', - append : true - }, options); - - var self = this; - var html = '' + options.label + ''; - - /** - * Appends an element as a child (with raw HTML). - * - * @param {string} html_container - * @param {string} html_element - * @return {string} - */ - var append = function(html_container, html_element) { - var pos = html_container.search(/(<\/[^>]+>\s*)$/); - return html_container.substring(0, pos) + html_element + html_container.substring(pos); - }; - - this.setup = (function() { - var original = self.setup; - return function() { - // override the item rendering method to add the button to each - if (options.append) { - var render_item = self.settings.render.item; - self.settings.render.item = function(data) { - return append(render_item.apply(this, arguments), html); - }; - } - - original.apply(this, arguments); - - // add event listener - this.$control.on('click', '.' + options.className, function(e) { - e.preventDefault(); - if (self.isLocked) return; - - var $item = $(e.currentTarget).parent(); - self.setActiveItem($item); - if (self.deleteSelection()) { - self.setCaret(self.items.length); - } - }); - - }; - })(); - - }); - - Selectize.define('restore_on_backspace', function(options) { - var self = this; - - options.text = options.text || function(option) { - return option[this.settings.labelField]; - }; - - this.onKeyDown = (function(e) { - var original = self.onKeyDown; - return function(e) { - var index, option; - if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { - index = this.caretPos - 1; - if (index >= 0 && index < this.items.length) { - option = this.options[this.items[index]]; - if (this.deleteSelection(e)) { - this.setTextboxValue(options.text.apply(this, [option])); - this.refreshOptions(true); - } - e.preventDefault(); - return; - } - } - return original.apply(this, arguments); - }; - })(); - }); return Selectize; })); \ No newline at end of file diff --git a/dist/js/selectize.min.js b/dist/js/selectize.min.js index 3aaaf2382..a2cf8448e 100644 --- a/dist/js/selectize.min.js +++ b/dist/js/selectize.min.js @@ -1,3 +1,2 @@ /*! selectize.js - v0.9.1 | https://github.com/brianreavis/selectize.js | Apache License (v2) */ -!function(a,b){"function"==typeof define&&define.amd?define(["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(a){var b=this;(b.isFull()||b.isInputHidden||b.isLocked)&&a.preventDefault()},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height()); -j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L}); \ No newline at end of file diff --git a/dist/js/standalone/selectize.js b/dist/js/standalone/selectize.js index ffa81b6ee..d5e8f6b85 100644 --- a/dist/js/standalone/selectize.js +++ b/dist/js/standalone/selectize.js @@ -1422,6 +1422,16 @@ var self = this; if (self.isFull() || self.isInputHidden || self.isLocked) { e.preventDefault(); + } else { + // If a regex or string is included, this will split the pasted input and create Items for each separate value + if (self.settings.splitOn) { + setTimeout($.proxy(function() { + var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); + splitInput.forEach($.proxy(function(input) { + self.createItem(input); + }, self)); + }, self), 0); + } } }, @@ -2428,13 +2438,18 @@ var self = this; var input = $.trim(self.$control_input.val() || ''); var caret = self.caretPos; - if (!input.length) return false; - self.lock(); if (typeof triggerDropdown === 'undefined') { triggerDropdown = true; + + // allow a string to be passed in, like the API docs say + } else if (typeof triggerDropdown === 'string') { + input = triggerDropdown; } + if (!input.length) return false; + self.lock(); + var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) { var data = {}; data[self.settings.labelField] = input; @@ -2946,6 +2961,7 @@ Selectize.defaults = { plugins: [], delimiter: ',', + splitOn: /[,]+/, // Regex or string for splitting up values from a paste command persist: true, diacritics: true, create: false, @@ -3156,251 +3172,6 @@ }; $.fn.selectize.defaults = Selectize.defaults; - - Selectize.define('drag_drop', function(options) { - if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); - if (this.settings.mode !== 'multi') return; - var self = this; - - self.lock = (function() { - var original = self.lock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.disable(); - return original.apply(self, arguments); - }; - })(); - - self.unlock = (function() { - var original = self.unlock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.enable(); - return original.apply(self, arguments); - }; - })(); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(this, arguments); - - var $control = self.$control.sortable({ - items: '[data-value]', - forcePlaceholderSize: true, - disabled: self.isLocked, - start: function(e, ui) { - ui.placeholder.css('width', ui.helper.css('width')); - $control.css({overflow: 'visible'}); - }, - stop: function() { - $control.css({overflow: 'hidden'}); - var active = self.$activeItems ? self.$activeItems.slice() : null; - var values = []; - $control.children('[data-value]').each(function() { - values.push($(this).attr('data-value')); - }); - self.setValue(values); - self.setActiveItem(active); - } - }); - }; - })(); - - }); - - Selectize.define('dropdown_header', function(options) { - var self = this; - - options = $.extend({ - title : 'Untitled', - headerClass : 'selectize-dropdown-header', - titleRowClass : 'selectize-dropdown-header-title', - labelClass : 'selectize-dropdown-header-label', - closeClass : 'selectize-dropdown-header-close', - - html: function(data) { - return ( - '
' + - '
' + - '' + data.title + '' + - '×' + - '
' + - '
' - ); - } - }, options); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(self, arguments); - self.$dropdown_header = $(options.html(options)); - self.$dropdown.prepend(self.$dropdown_header); - }; - })(); - - }); - - Selectize.define('optgroup_columns', function(options) { - var self = this; - - options = $.extend({ - equalizeWidth : true, - equalizeHeight : true - }, options); - - this.getAdjacentOption = function($option, direction) { - var $options = $option.closest('[data-group]').find('[data-selectable]'); - var index = $options.index($option) + direction; - - return index >= 0 && index < $options.length ? $options.eq(index) : $(); - }; - - this.onKeyDown = (function() { - var original = self.onKeyDown; - return function(e) { - var index, $option, $options, $optgroup; - - if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { - self.ignoreHover = true; - $optgroup = this.$activeOption.closest('[data-group]'); - index = $optgroup.find('[data-selectable]').index(this.$activeOption); - - if(e.keyCode === KEY_LEFT) { - $optgroup = $optgroup.prev('[data-group]'); - } else { - $optgroup = $optgroup.next('[data-group]'); - } - - $options = $optgroup.find('[data-selectable]'); - $option = $options.eq(Math.min($options.length - 1, index)); - if ($option.length) { - this.setActiveOption($option); - } - return; - } - - return original.apply(this, arguments); - }; - })(); - - var equalizeSizes = function() { - var i, n, height_max, width, width_last, width_parent, $optgroups; - - $optgroups = $('[data-group]', self.$dropdown_content); - n = $optgroups.length; - if (!n || !self.$dropdown_content.width()) return; - - if (options.equalizeHeight) { - height_max = 0; - for (i = 0; i < n; i++) { - height_max = Math.max(height_max, $optgroups.eq(i).height()); - } - $optgroups.css({height: height_max}); - } - - if (options.equalizeWidth) { - width_parent = self.$dropdown_content.innerWidth(); - width = Math.round(width_parent / n); - $optgroups.css({width: width}); - if (n > 1) { - width_last = width_parent - width * (n - 1); - $optgroups.eq(n - 1).css({width: width_last}); - } - } - }; - - if (options.equalizeHeight || options.equalizeWidth) { - hook.after(this, 'positionDropdown', equalizeSizes); - hook.after(this, 'refreshOptions', equalizeSizes); - } - - - }); - - Selectize.define('remove_button', function(options) { - if (this.settings.mode === 'single') return; - - options = $.extend({ - label : '×', - title : 'Remove', - className : 'remove', - append : true - }, options); - - var self = this; - var html = '' + options.label + ''; - - /** - * Appends an element as a child (with raw HTML). - * - * @param {string} html_container - * @param {string} html_element - * @return {string} - */ - var append = function(html_container, html_element) { - var pos = html_container.search(/(<\/[^>]+>\s*)$/); - return html_container.substring(0, pos) + html_element + html_container.substring(pos); - }; - - this.setup = (function() { - var original = self.setup; - return function() { - // override the item rendering method to add the button to each - if (options.append) { - var render_item = self.settings.render.item; - self.settings.render.item = function(data) { - return append(render_item.apply(this, arguments), html); - }; - } - - original.apply(this, arguments); - - // add event listener - this.$control.on('click', '.' + options.className, function(e) { - e.preventDefault(); - if (self.isLocked) return; - - var $item = $(e.currentTarget).parent(); - self.setActiveItem($item); - if (self.deleteSelection()) { - self.setCaret(self.items.length); - } - }); - - }; - })(); - - }); - - Selectize.define('restore_on_backspace', function(options) { - var self = this; - - options.text = options.text || function(option) { - return option[this.settings.labelField]; - }; - - this.onKeyDown = (function(e) { - var original = self.onKeyDown; - return function(e) { - var index, option; - if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { - index = this.caretPos - 1; - if (index >= 0 && index < this.items.length) { - option = this.options[this.items[index]]; - if (this.deleteSelection(e)) { - this.setTextboxValue(options.text.apply(this, [option])); - this.refreshOptions(true); - } - e.preventDefault(); - return; - } - } - return original.apply(this, arguments); - }; - })(); - }); return Selectize; })); \ No newline at end of file diff --git a/dist/js/standalone/selectize.min.js b/dist/js/standalone/selectize.min.js index ae868386e..799551208 100644 --- a/dist/js/standalone/selectize.min.js +++ b/dist/js/standalone/selectize.min.js @@ -1,3 +1,3 @@ /*! selectize.js - v0.9.1 | https://github.com/brianreavis/selectize.js | Apache License (v2) */ -!function(a,b){"function"==typeof define&&define.amd?define("sifter",b):"object"==typeof exports?module.exports=b():a.Sifter=b()}(this,function(){var a=function(a,b){this.items=a,this.settings=b||{diacritics:!0}};a.prototype.tokenize=function(a){if(a=d(String(a||"").toLowerCase()),!a||!a.length)return[];var b,c,f,h,i=[],j=a.split(/ +/);for(b=0,c=j.length;c>b;b++){if(f=e(j[b]),this.settings.diacritics)for(h in g)g.hasOwnProperty(h)&&(f=f.replace(new RegExp(h,"g"),g[h]));i.push({string:j[b],regex:new RegExp(f,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=f(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;c>b;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,d,e,f;c=this,a=c.prepareSearch(a,b),e=a.tokens,d=a.options.fields,f=e.length;var g=function(a,b){var c,d;return a?(a=String(a||""),d=a.search(b.regex),-1===d?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},h=function(){var a=d.length;return a?1===a?function(a,b){return g(b[d[0]],a)}:function(b,c){for(var e=0,f=0;a>e;e++)f+=g(c[d[e]],b);return f/a}:function(){return 0}}();return f?1===f?function(a){return h(e[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;f>c;c++){if(b=h(e[c],a),0>=b)return 0;d+=b}return d/f}:function(a){for(var b=0,c=0;f>b;b++)c+=h(e[b],a);return c/f}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var d,e,f,g,h,i,j,k,l,m,n;if(f=this,a=f.prepareSearch(a,c),n=!a.query&&c.sort_empty||c.sort,l=function(a,b){return"$score"===a?b.score:f.items[b.id][a]},h=[],n)for(d=0,e=n.length;e>d;d++)(a.query||"$score"!==n[d].field)&&h.push(n[d]);if(a.query){for(m=!0,d=0,e=h.length;e>d;d++)if("$score"===h[d].field){m=!1;break}m&&h.unshift({field:"$score",direction:"desc"})}else for(d=0,e=h.length;e>d;d++)if("$score"===h[d].field){h.splice(d,1);break}for(k=[],d=0,e=h.length;e>d;d++)k.push("desc"===h[d].direction?-1:1);return i=h.length,i?1===i?(g=h[0].field,j=k[0],function(a,c){return j*b(l(g,a),l(g,c))}):function(a,c){var d,e,f;for(d=0;i>d;d++)if(f=h[d].field,e=k[d]*b(l(f,a),l(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,g=b.sort_empty;return d&&!f(d)&&(b.fields=[d]),e&&!f(e)&&(b.sort=[e]),g&&!f(g)&&(b.sort_empty=[g]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(b.filter===!1||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:b>a?-1:0:(a=String(a||"").toLowerCase(),b=String(b||"").toLowerCase(),a>b?1:b>a?-1:0)},c=function(a){var b,c,d,e;for(b=1,c=arguments.length;c>b;b++)if(e=arguments[b])for(d in e)e.hasOwnProperty(d)&&(a[d]=e[d]);return a},d=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},e=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},f=Array.isArray||$&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},g={a:"[aÀÁÂÃÄÅàáâãäå]",c:"[cÇçćĆčČ]",d:"[dđĐďĎ]",e:"[eÈÉÊËèéêëěĚ]",i:"[iÌÍÎÏìíîï]",n:"[nÑñňŇ]",o:"[oÒÓÔÕÕÖØòóôõöø]",r:"[rřŘ]",s:"[sŠš]",t:"[tťŤ]",u:"[uÙÚÛÜùúûüůŮ]",y:"[yŸÿýÝ]",z:"[zŽž]"};return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;d>c;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(a){var b=this;(b.isFull()||b.isInputHidden||b.isLocked)&&a.preventDefault()},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e) -}}),L.count=0,L.defaults={plugins:[],delimiter:",",persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height());j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&db;b++){if(f=e(j[b]),this.settings.diacritics)for(h in g)g.hasOwnProperty(h)&&(f=f.replace(new RegExp(h,"g"),g[h]));i.push({string:j[b],regex:new RegExp(f,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=f(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;c>b;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,d,e,f;c=this,a=c.prepareSearch(a,b),e=a.tokens,d=a.options.fields,f=e.length;var g=function(a,b){var c,d;return a?(a=String(a||""),d=a.search(b.regex),-1===d?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},h=function(){var a=d.length;return a?1===a?function(a,b){return g(b[d[0]],a)}:function(b,c){for(var e=0,f=0;a>e;e++)f+=g(c[d[e]],b);return f/a}:function(){return 0}}();return f?1===f?function(a){return h(e[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;f>c;c++){if(b=h(e[c],a),0>=b)return 0;d+=b}return d/f}:function(a){for(var b=0,c=0;f>b;b++)c+=h(e[b],a);return c/f}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var d,e,f,g,h,i,j,k,l,m,n;if(f=this,a=f.prepareSearch(a,c),n=!a.query&&c.sort_empty||c.sort,l=function(a,b){return"$score"===a?b.score:f.items[b.id][a]},h=[],n)for(d=0,e=n.length;e>d;d++)(a.query||"$score"!==n[d].field)&&h.push(n[d]);if(a.query){for(m=!0,d=0,e=h.length;e>d;d++)if("$score"===h[d].field){m=!1;break}m&&h.unshift({field:"$score",direction:"desc"})}else for(d=0,e=h.length;e>d;d++)if("$score"===h[d].field){h.splice(d,1);break}for(k=[],d=0,e=h.length;e>d;d++)k.push("desc"===h[d].direction?-1:1);return i=h.length,i?1===i?(g=h[0].field,j=k[0],function(a,c){return j*b(l(g,a),l(g,c))}):function(a,c){var d,e,f;for(d=0;i>d;d++)if(f=h[d].field,e=k[d]*b(l(f,a),l(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,g=b.sort_empty;return d&&!f(d)&&(b.fields=[d]),e&&!f(e)&&(b.sort=[e]),g&&!f(g)&&(b.sort_empty=[g]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(b.filter===!1||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:b>a?-1:0:(a=String(a||"").toLowerCase(),b=String(b||"").toLowerCase(),a>b?1:b>a?-1:0)},c=function(a){var b,c,d,e;for(b=1,c=arguments.length;c>b;b++)if(e=arguments[b])for(d in e)e.hasOwnProperty(d)&&(a[d]=e[d]);return a},d=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},e=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},f=Array.isArray||$&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},g={a:"[aÀÁÂÃÄÅàáâãäå]",c:"[cÇçćĆčČ]",d:"[dđĐďĎ]",e:"[eÈÉÊËèéêëěĚ]",i:"[iÌÍÎÏìíîï]",n:"[nÑñňŇ]",o:"[oÒÓÔÕÕÖØòóôõöø]",r:"[rřŘ]",s:"[sŠš]",t:"[tťŤ]",u:"[uÙÚÛÜùúûüůŮ]",y:"[yŸÿýÝ]",z:"[zŽž]"};return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;d>c;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; +return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L}); \ No newline at end of file diff --git a/dist/less/plugins/drag_drop.less b/dist/less/plugins/drag_drop.less deleted file mode 100644 index 9d42e4ac2..000000000 --- a/dist/less/plugins/drag_drop.less +++ /dev/null @@ -1,16 +0,0 @@ -.selectize-control.plugin-drag_drop { - &.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0,0,0,0.06) !important; - border: 0 none !important; - .selectize-box-shadow(inset 0 0 12px 4px #fff); - } - .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; - } - .ui-sortable-helper { - .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); - } -} \ No newline at end of file diff --git a/dist/less/plugins/dropdown_header.less b/dist/less/plugins/dropdown_header.less deleted file mode 100644 index c3e777e16..000000000 --- a/dist/less/plugins/dropdown_header.less +++ /dev/null @@ -1,20 +0,0 @@ -.selectize-dropdown-header { - position: relative; - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - border-bottom: 1px solid @selectize-color-border; - background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); -} -.selectize-dropdown-header-close { - position: absolute; - right: @selectize-padding-dropdown-item-x; - top: 50%; - color: @selectize-color-text; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: darken(@selectize-color-text, 25%); -} \ No newline at end of file diff --git a/dist/less/plugins/optgroup_columns.less b/dist/less/plugins/optgroup_columns.less deleted file mode 100644 index 5c72d7a0a..000000000 --- a/dist/less/plugins/optgroup_columns.less +++ /dev/null @@ -1,17 +0,0 @@ -.selectize-dropdown.plugin-optgroup_columns { - .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - .selectize-box-sizing(border-box); - } - .optgroup:last-child { - border-right: 0 none; - } - .optgroup:before { - display: none; - } - .optgroup-header { - border-top: 0 none; - } -} \ No newline at end of file diff --git a/dist/less/plugins/remove_button.less b/dist/less/plugins/remove_button.less deleted file mode 100644 index c478cd49c..000000000 --- a/dist/less/plugins/remove_button.less +++ /dev/null @@ -1,37 +0,0 @@ -.selectize-control.plugin-remove_button { - [data-value] { - position: relative; - padding-right: 24px !important; - } - [data-value] .remove { - z-index: 1; /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: @selectize-padding-item-y 0 0 0; - border-left: 1px solid @selectize-color-item-border; - .selectize-border-radius(0 2px 2px 0); - .selectize-box-sizing(border-box); - } - [data-value] .remove:hover { - background: rgba(0,0,0,0.05); - } - [data-value].active .remove { - border-left-color: @selectize-color-item-active-border; - } - .disabled [data-value] .remove:hover { - background: none; - } - .disabled [data-value] .remove { - border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } -} \ No newline at end of file diff --git a/dist/less/selectize.less b/dist/less/selectize.less index a06d20568..866d82d50 100644 --- a/dist/less/selectize.less +++ b/dist/less/selectize.less @@ -1,7 +1,4 @@ -@import "plugins/drag_drop"; -@import "plugins/dropdown_header"; -@import "plugins/optgroup_columns"; -@import "plugins/remove_button"; + // base styles diff --git a/src/defaults.js b/src/defaults.js index b05491429..1c69bee6b 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -2,6 +2,7 @@ Selectize.count = 0; Selectize.defaults = { plugins: [], delimiter: ',', + splitOn: /[,]+/, // Regex or string for splitting up values from a paste command persist: true, diacritics: true, create: false, diff --git a/src/selectize.js b/src/selectize.js index 8ea0b6de8..9230f62ea 100644 --- a/src/selectize.js +++ b/src/selectize.js @@ -373,6 +373,16 @@ $.extend(Selectize.prototype, { var self = this; if (self.isFull() || self.isInputHidden || self.isLocked) { e.preventDefault(); + } else { + // If a regex or string is included, this will split the pasted input and create Items for each separate value + if (self.settings.splitOn) { + setTimeout($.proxy(function() { + var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); + splitInput.forEach($.proxy(function(input) { + self.createItem(input); + }, self)); + }, self), 0); + } } }, @@ -1379,13 +1389,18 @@ $.extend(Selectize.prototype, { var self = this; var input = $.trim(self.$control_input.val() || ''); var caret = self.caretPos; - if (!input.length) return false; - self.lock(); if (typeof triggerDropdown === 'undefined') { triggerDropdown = true; + + // allow a string to be passed in, like the API docs say + } else if (typeof triggerDropdown === 'string') { + input = triggerDropdown; } + if (!input.length) return false; + self.lock(); + var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) { var data = {}; data[self.settings.labelField] = input; From ef8c568975ac7a8fc4916b667ebaba214a913d55 Mon Sep 17 00:00:00 2001 From: Jacob Hash Date: Wed, 21 May 2014 16:27:03 -0400 Subject: [PATCH 2/9] Including All Plugins --- dist/css/selectize.bootstrap2.css | 95 +++++++++++ dist/css/selectize.bootstrap3.css | 95 +++++++++++ dist/css/selectize.css | 95 +++++++++++ dist/css/selectize.default.css | 95 +++++++++++ dist/css/selectize.legacy.css | 95 +++++++++++ dist/js/selectize.js | 245 ++++++++++++++++++++++++++++ dist/js/selectize.min.js | 3 +- dist/js/standalone/selectize.js | 245 ++++++++++++++++++++++++++++ dist/js/standalone/selectize.min.js | 2 +- dist/less/selectize.less | 5 +- 10 files changed, 972 insertions(+), 3 deletions(-) diff --git a/dist/css/selectize.bootstrap2.css b/dist/css/selectize.bootstrap2.css index f2d45646a..5dca1f770 100644 --- a/dist/css/selectize.bootstrap2.css +++ b/dist/css/selectize.bootstrap2.css @@ -13,6 +13,101 @@ * * @author Brian Reavis */ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 3px 10px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 10px; + top: 50%; + color: #333333; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 1px 0 0 0; + border-left: 1px solid #cccccc; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #0077b3; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #e0e0e0; +} .selectize-control { position: relative; } diff --git a/dist/css/selectize.bootstrap3.css b/dist/css/selectize.bootstrap3.css index fa62586f1..9807775df 100644 --- a/dist/css/selectize.bootstrap3.css +++ b/dist/css/selectize.bootstrap3.css @@ -13,6 +13,101 @@ * * @author Brian Reavis */ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 3px 12px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 12px; + top: 50%; + color: #333333; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 1px 0 0 0; + border-left: 1px solid rgba(0, 0, 0, 0); + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: rgba(0, 0, 0, 0); +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: rgba(77, 77, 77, 0); +} .selectize-control { position: relative; } diff --git a/dist/css/selectize.css b/dist/css/selectize.css index 72bbfa696..b3002c139 100644 --- a/dist/css/selectize.css +++ b/dist/css/selectize.css @@ -14,6 +14,101 @@ * @author Brian Reavis */ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 5px 8px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 8px; + top: 50%; + color: #303030; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 2px 0 0 0; + border-left: 1px solid #d0d0d0; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #cacaca; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #ffffff; +} .selectize-control { position: relative; } diff --git a/dist/css/selectize.default.css b/dist/css/selectize.default.css index fb111bef6..0d8947e90 100644 --- a/dist/css/selectize.default.css +++ b/dist/css/selectize.default.css @@ -13,6 +13,101 @@ * * @author Brian Reavis */ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 5px 8px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 8px; + top: 50%; + color: #303030; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 2px 0 0 0; + border-left: 1px solid #0073bb; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #00578d; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #aaaaaa; +} .selectize-control { position: relative; } diff --git a/dist/css/selectize.legacy.css b/dist/css/selectize.legacy.css index 721b7bb0a..b5d5d03e8 100644 --- a/dist/css/selectize.legacy.css +++ b/dist/css/selectize.legacy.css @@ -13,6 +13,101 @@ * * @author Brian Reavis */ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 7px 10px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 10px; + top: 50%; + color: #303030; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 1px 0 0 0; + border-left: 1px solid #74b21e; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #6f9839; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #b4b4b4; +} .selectize-control { position: relative; } diff --git a/dist/js/selectize.js b/dist/js/selectize.js index 770e9c643..04e541c42 100644 --- a/dist/js/selectize.js +++ b/dist/js/selectize.js @@ -2586,6 +2586,251 @@ }; $.fn.selectize.defaults = Selectize.defaults; + + Selectize.define('drag_drop', function(options) { + if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); + if (this.settings.mode !== 'multi') return; + var self = this; + + self.lock = (function() { + var original = self.lock; + return function() { + var sortable = self.$control.data('sortable'); + if (sortable) sortable.disable(); + return original.apply(self, arguments); + }; + })(); + + self.unlock = (function() { + var original = self.unlock; + return function() { + var sortable = self.$control.data('sortable'); + if (sortable) sortable.enable(); + return original.apply(self, arguments); + }; + })(); + + self.setup = (function() { + var original = self.setup; + return function() { + original.apply(this, arguments); + + var $control = self.$control.sortable({ + items: '[data-value]', + forcePlaceholderSize: true, + disabled: self.isLocked, + start: function(e, ui) { + ui.placeholder.css('width', ui.helper.css('width')); + $control.css({overflow: 'visible'}); + }, + stop: function() { + $control.css({overflow: 'hidden'}); + var active = self.$activeItems ? self.$activeItems.slice() : null; + var values = []; + $control.children('[data-value]').each(function() { + values.push($(this).attr('data-value')); + }); + self.setValue(values); + self.setActiveItem(active); + } + }); + }; + })(); + + }); + + Selectize.define('dropdown_header', function(options) { + var self = this; + + options = $.extend({ + title : 'Untitled', + headerClass : 'selectize-dropdown-header', + titleRowClass : 'selectize-dropdown-header-title', + labelClass : 'selectize-dropdown-header-label', + closeClass : 'selectize-dropdown-header-close', + + html: function(data) { + return ( + '
' + + '
' + + '' + data.title + '' + + '×' + + '
' + + '
' + ); + } + }, options); + + self.setup = (function() { + var original = self.setup; + return function() { + original.apply(self, arguments); + self.$dropdown_header = $(options.html(options)); + self.$dropdown.prepend(self.$dropdown_header); + }; + })(); + + }); + + Selectize.define('optgroup_columns', function(options) { + var self = this; + + options = $.extend({ + equalizeWidth : true, + equalizeHeight : true + }, options); + + this.getAdjacentOption = function($option, direction) { + var $options = $option.closest('[data-group]').find('[data-selectable]'); + var index = $options.index($option) + direction; + + return index >= 0 && index < $options.length ? $options.eq(index) : $(); + }; + + this.onKeyDown = (function() { + var original = self.onKeyDown; + return function(e) { + var index, $option, $options, $optgroup; + + if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { + self.ignoreHover = true; + $optgroup = this.$activeOption.closest('[data-group]'); + index = $optgroup.find('[data-selectable]').index(this.$activeOption); + + if(e.keyCode === KEY_LEFT) { + $optgroup = $optgroup.prev('[data-group]'); + } else { + $optgroup = $optgroup.next('[data-group]'); + } + + $options = $optgroup.find('[data-selectable]'); + $option = $options.eq(Math.min($options.length - 1, index)); + if ($option.length) { + this.setActiveOption($option); + } + return; + } + + return original.apply(this, arguments); + }; + })(); + + var equalizeSizes = function() { + var i, n, height_max, width, width_last, width_parent, $optgroups; + + $optgroups = $('[data-group]', self.$dropdown_content); + n = $optgroups.length; + if (!n || !self.$dropdown_content.width()) return; + + if (options.equalizeHeight) { + height_max = 0; + for (i = 0; i < n; i++) { + height_max = Math.max(height_max, $optgroups.eq(i).height()); + } + $optgroups.css({height: height_max}); + } + + if (options.equalizeWidth) { + width_parent = self.$dropdown_content.innerWidth(); + width = Math.round(width_parent / n); + $optgroups.css({width: width}); + if (n > 1) { + width_last = width_parent - width * (n - 1); + $optgroups.eq(n - 1).css({width: width_last}); + } + } + }; + + if (options.equalizeHeight || options.equalizeWidth) { + hook.after(this, 'positionDropdown', equalizeSizes); + hook.after(this, 'refreshOptions', equalizeSizes); + } + + + }); + + Selectize.define('remove_button', function(options) { + if (this.settings.mode === 'single') return; + + options = $.extend({ + label : '×', + title : 'Remove', + className : 'remove', + append : true + }, options); + + var self = this; + var html = '' + options.label + ''; + + /** + * Appends an element as a child (with raw HTML). + * + * @param {string} html_container + * @param {string} html_element + * @return {string} + */ + var append = function(html_container, html_element) { + var pos = html_container.search(/(<\/[^>]+>\s*)$/); + return html_container.substring(0, pos) + html_element + html_container.substring(pos); + }; + + this.setup = (function() { + var original = self.setup; + return function() { + // override the item rendering method to add the button to each + if (options.append) { + var render_item = self.settings.render.item; + self.settings.render.item = function(data) { + return append(render_item.apply(this, arguments), html); + }; + } + + original.apply(this, arguments); + + // add event listener + this.$control.on('click', '.' + options.className, function(e) { + e.preventDefault(); + if (self.isLocked) return; + + var $item = $(e.currentTarget).parent(); + self.setActiveItem($item); + if (self.deleteSelection()) { + self.setCaret(self.items.length); + } + }); + + }; + })(); + + }); + + Selectize.define('restore_on_backspace', function(options) { + var self = this; + + options.text = options.text || function(option) { + return option[this.settings.labelField]; + }; + + this.onKeyDown = (function(e) { + var original = self.onKeyDown; + return function(e) { + var index, option; + if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { + index = this.caretPos - 1; + if (index >= 0 && index < this.items.length) { + option = this.options[this.items[index]]; + if (this.deleteSelection(e)) { + this.setTextboxValue(options.text.apply(this, [option])); + this.refreshOptions(true); + } + e.preventDefault(); + return; + } + } + return original.apply(this, arguments); + }; + })(); + }); return Selectize; })); \ No newline at end of file diff --git a/dist/js/selectize.min.js b/dist/js/selectize.min.js index a2cf8448e..1969cdc15 100644 --- a/dist/js/selectize.min.js +++ b/dist/js/selectize.min.js @@ -1,2 +1,3 @@ /*! selectize.js - v0.9.1 | https://github.com/brianreavis/selectize.js | Apache License (v2) */ -!function(a,b){"function"==typeof define&&define.amd?define(["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L}); \ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define(["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height());j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d' + + '
' + + '' + data.title + '' + + '×' + + '
' + + '
' + ); + } + }, options); + + self.setup = (function() { + var original = self.setup; + return function() { + original.apply(self, arguments); + self.$dropdown_header = $(options.html(options)); + self.$dropdown.prepend(self.$dropdown_header); + }; + })(); + + }); + + Selectize.define('optgroup_columns', function(options) { + var self = this; + + options = $.extend({ + equalizeWidth : true, + equalizeHeight : true + }, options); + + this.getAdjacentOption = function($option, direction) { + var $options = $option.closest('[data-group]').find('[data-selectable]'); + var index = $options.index($option) + direction; + + return index >= 0 && index < $options.length ? $options.eq(index) : $(); + }; + + this.onKeyDown = (function() { + var original = self.onKeyDown; + return function(e) { + var index, $option, $options, $optgroup; + + if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { + self.ignoreHover = true; + $optgroup = this.$activeOption.closest('[data-group]'); + index = $optgroup.find('[data-selectable]').index(this.$activeOption); + + if(e.keyCode === KEY_LEFT) { + $optgroup = $optgroup.prev('[data-group]'); + } else { + $optgroup = $optgroup.next('[data-group]'); + } + + $options = $optgroup.find('[data-selectable]'); + $option = $options.eq(Math.min($options.length - 1, index)); + if ($option.length) { + this.setActiveOption($option); + } + return; + } + + return original.apply(this, arguments); + }; + })(); + + var equalizeSizes = function() { + var i, n, height_max, width, width_last, width_parent, $optgroups; + + $optgroups = $('[data-group]', self.$dropdown_content); + n = $optgroups.length; + if (!n || !self.$dropdown_content.width()) return; + + if (options.equalizeHeight) { + height_max = 0; + for (i = 0; i < n; i++) { + height_max = Math.max(height_max, $optgroups.eq(i).height()); + } + $optgroups.css({height: height_max}); + } + + if (options.equalizeWidth) { + width_parent = self.$dropdown_content.innerWidth(); + width = Math.round(width_parent / n); + $optgroups.css({width: width}); + if (n > 1) { + width_last = width_parent - width * (n - 1); + $optgroups.eq(n - 1).css({width: width_last}); + } + } + }; + + if (options.equalizeHeight || options.equalizeWidth) { + hook.after(this, 'positionDropdown', equalizeSizes); + hook.after(this, 'refreshOptions', equalizeSizes); + } + + + }); + + Selectize.define('remove_button', function(options) { + if (this.settings.mode === 'single') return; + + options = $.extend({ + label : '×', + title : 'Remove', + className : 'remove', + append : true + }, options); + + var self = this; + var html = '' + options.label + ''; + + /** + * Appends an element as a child (with raw HTML). + * + * @param {string} html_container + * @param {string} html_element + * @return {string} + */ + var append = function(html_container, html_element) { + var pos = html_container.search(/(<\/[^>]+>\s*)$/); + return html_container.substring(0, pos) + html_element + html_container.substring(pos); + }; + + this.setup = (function() { + var original = self.setup; + return function() { + // override the item rendering method to add the button to each + if (options.append) { + var render_item = self.settings.render.item; + self.settings.render.item = function(data) { + return append(render_item.apply(this, arguments), html); + }; + } + + original.apply(this, arguments); + + // add event listener + this.$control.on('click', '.' + options.className, function(e) { + e.preventDefault(); + if (self.isLocked) return; + + var $item = $(e.currentTarget).parent(); + self.setActiveItem($item); + if (self.deleteSelection()) { + self.setCaret(self.items.length); + } + }); + + }; + })(); + + }); + + Selectize.define('restore_on_backspace', function(options) { + var self = this; + + options.text = options.text || function(option) { + return option[this.settings.labelField]; + }; + + this.onKeyDown = (function(e) { + var original = self.onKeyDown; + return function(e) { + var index, option; + if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { + index = this.caretPos - 1; + if (index >= 0 && index < this.items.length) { + option = this.options[this.items[index]]; + if (this.deleteSelection(e)) { + this.setTextboxValue(options.text.apply(this, [option])); + this.refreshOptions(true); + } + e.preventDefault(); + return; + } + } + return original.apply(this, arguments); + }; + })(); + }); return Selectize; })); \ No newline at end of file diff --git a/dist/js/standalone/selectize.min.js b/dist/js/standalone/selectize.min.js index 799551208..4db49933c 100644 --- a/dist/js/standalone/selectize.min.js +++ b/dist/js/standalone/selectize.min.js @@ -1,3 +1,3 @@ /*! selectize.js - v0.9.1 | https://github.com/brianreavis/selectize.js | Apache License (v2) */ !function(a,b){"function"==typeof define&&define.amd?define("sifter",b):"object"==typeof exports?module.exports=b():a.Sifter=b()}(this,function(){var a=function(a,b){this.items=a,this.settings=b||{diacritics:!0}};a.prototype.tokenize=function(a){if(a=d(String(a||"").toLowerCase()),!a||!a.length)return[];var b,c,f,h,i=[],j=a.split(/ +/);for(b=0,c=j.length;c>b;b++){if(f=e(j[b]),this.settings.diacritics)for(h in g)g.hasOwnProperty(h)&&(f=f.replace(new RegExp(h,"g"),g[h]));i.push({string:j[b],regex:new RegExp(f,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=f(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;c>b;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,d,e,f;c=this,a=c.prepareSearch(a,b),e=a.tokens,d=a.options.fields,f=e.length;var g=function(a,b){var c,d;return a?(a=String(a||""),d=a.search(b.regex),-1===d?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},h=function(){var a=d.length;return a?1===a?function(a,b){return g(b[d[0]],a)}:function(b,c){for(var e=0,f=0;a>e;e++)f+=g(c[d[e]],b);return f/a}:function(){return 0}}();return f?1===f?function(a){return h(e[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;f>c;c++){if(b=h(e[c],a),0>=b)return 0;d+=b}return d/f}:function(a){for(var b=0,c=0;f>b;b++)c+=h(e[b],a);return c/f}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var d,e,f,g,h,i,j,k,l,m,n;if(f=this,a=f.prepareSearch(a,c),n=!a.query&&c.sort_empty||c.sort,l=function(a,b){return"$score"===a?b.score:f.items[b.id][a]},h=[],n)for(d=0,e=n.length;e>d;d++)(a.query||"$score"!==n[d].field)&&h.push(n[d]);if(a.query){for(m=!0,d=0,e=h.length;e>d;d++)if("$score"===h[d].field){m=!1;break}m&&h.unshift({field:"$score",direction:"desc"})}else for(d=0,e=h.length;e>d;d++)if("$score"===h[d].field){h.splice(d,1);break}for(k=[],d=0,e=h.length;e>d;d++)k.push("desc"===h[d].direction?-1:1);return i=h.length,i?1===i?(g=h[0].field,j=k[0],function(a,c){return j*b(l(g,a),l(g,c))}):function(a,c){var d,e,f;for(d=0;i>d;d++)if(f=h[d].field,e=k[d]*b(l(f,a),l(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,g=b.sort_empty;return d&&!f(d)&&(b.fields=[d]),e&&!f(e)&&(b.sort=[e]),g&&!f(g)&&(b.sort_empty=[g]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(b.filter===!1||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:b>a?-1:0:(a=String(a||"").toLowerCase(),b=String(b||"").toLowerCase(),a>b?1:b>a?-1:0)},c=function(a){var b,c,d,e;for(b=1,c=arguments.length;c>b;b++)if(e=arguments[b])for(d in e)e.hasOwnProperty(d)&&(a[d]=e[d]);return a},d=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},e=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},f=Array.isArray||$&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},g={a:"[aÀÁÂÃÄÅàáâãäå]",c:"[cÇçćĆčČ]",d:"[dđĐďĎ]",e:"[eÈÉÊËèéêëěĚ]",i:"[iÌÍÎÏìíîï]",n:"[nÑñňŇ]",o:"[oÒÓÔÕÕÖØòóôõöø]",r:"[rřŘ]",s:"[sŠš]",t:"[tťŤ]",u:"[uÙÚÛÜùúûüůŮ]",y:"[yŸÿýÝ]",z:"[zŽž]"};return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;d>c;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j/g,">").replace(/"/g,""")},A=function(a){return(a+"").replace(/\$/g,"$$$$")},B={};B.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},B.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var C=function(b,c){if(!a.isArray(c))return c;var d,e,f={};for(d=0,e=c.length;e>d;d++)c[d].hasOwnProperty(b)&&(f[c[d][b]]=c[d]);return f},D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g=this;f=c[0],f.selectize=g,e=window.getComputedStyle?window.getComputedStyle(f,null).getPropertyValue("direction"):f.currentStyle&&f.currentStyle.direction,e=e||c.parents("[dir]:first").attr("dir")||"",a.extend(g,{settings:d,$input:c,tagType:"select"===f.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(e),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?g.onSearchChange:E(g.onSearchChange,d.loadThrottle)}),g.sifter=new b(this.options,{diacritics:d.diacritics}),a.extend(g.options,C(d.valueField,d.options)),delete g.settings.options,a.extend(g.optgroups,C(d.optgroupValueField,d.optgroups)),delete g.settings.optgroups,g.settings.mode=g.settings.mode||(1===g.settings.maxItems?"single":"multi"),"boolean"!=typeof g.settings.hideSelected&&(g.settings.hideSelected="multi"===g.settings.mode),g.initializePlugins(g.settings.plugins),g.setupCallbacks(),g.setupTemplates(),g.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l,m=this,n=m.settings,o=m.eventNS,p=a(window),q=a(document);i=m.settings.mode,j=m.$input.attr("tabindex")||"",k=m.$input.attr("class")||"",b=a("
").addClass(n.wrapperClass).addClass(k).addClass(i),c=a("
").addClass(n.inputClass).addClass("items").appendTo(b),d=a('').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; -return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L}); \ No newline at end of file +return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height());j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d Date: Wed, 21 May 2014 16:27:13 -0400 Subject: [PATCH 3/9] Including All Plugins --- dist/less/plugins/drag_drop.less | 16 +++++++++++ dist/less/plugins/dropdown_header.less | 20 +++++++++++++ dist/less/plugins/optgroup_columns.less | 17 ++++++++++++ dist/less/plugins/remove_button.less | 37 +++++++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 dist/less/plugins/drag_drop.less create mode 100644 dist/less/plugins/dropdown_header.less create mode 100644 dist/less/plugins/optgroup_columns.less create mode 100644 dist/less/plugins/remove_button.less diff --git a/dist/less/plugins/drag_drop.less b/dist/less/plugins/drag_drop.less new file mode 100644 index 000000000..9d42e4ac2 --- /dev/null +++ b/dist/less/plugins/drag_drop.less @@ -0,0 +1,16 @@ +.selectize-control.plugin-drag_drop { + &.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0,0,0,0.06) !important; + border: 0 none !important; + .selectize-box-shadow(inset 0 0 12px 4px #fff); + } + .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; + } + .ui-sortable-helper { + .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); + } +} \ No newline at end of file diff --git a/dist/less/plugins/dropdown_header.less b/dist/less/plugins/dropdown_header.less new file mode 100644 index 000000000..c3e777e16 --- /dev/null +++ b/dist/less/plugins/dropdown_header.less @@ -0,0 +1,20 @@ +.selectize-dropdown-header { + position: relative; + padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; + border-bottom: 1px solid @selectize-color-border; + background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); + .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); +} +.selectize-dropdown-header-close { + position: absolute; + right: @selectize-padding-dropdown-item-x; + top: 50%; + color: @selectize-color-text; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: darken(@selectize-color-text, 25%); +} \ No newline at end of file diff --git a/dist/less/plugins/optgroup_columns.less b/dist/less/plugins/optgroup_columns.less new file mode 100644 index 000000000..5c72d7a0a --- /dev/null +++ b/dist/less/plugins/optgroup_columns.less @@ -0,0 +1,17 @@ +.selectize-dropdown.plugin-optgroup_columns { + .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + .selectize-box-sizing(border-box); + } + .optgroup:last-child { + border-right: 0 none; + } + .optgroup:before { + display: none; + } + .optgroup-header { + border-top: 0 none; + } +} \ No newline at end of file diff --git a/dist/less/plugins/remove_button.less b/dist/less/plugins/remove_button.less new file mode 100644 index 000000000..c478cd49c --- /dev/null +++ b/dist/less/plugins/remove_button.less @@ -0,0 +1,37 @@ +.selectize-control.plugin-remove_button { + [data-value] { + position: relative; + padding-right: 24px !important; + } + [data-value] .remove { + z-index: 1; /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: @selectize-padding-item-y 0 0 0; + border-left: 1px solid @selectize-color-item-border; + .selectize-border-radius(0 2px 2px 0); + .selectize-box-sizing(border-box); + } + [data-value] .remove:hover { + background: rgba(0,0,0,0.05); + } + [data-value].active .remove { + border-left-color: @selectize-color-item-active-border; + } + .disabled [data-value] .remove:hover { + background: none; + } + .disabled [data-value] .remove { + border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); + } +} \ No newline at end of file From cb6d0882622b63464aaff9651fd3f8978abe16a3 Mon Sep 17 00:00:00 2001 From: Jacob Hash Date: Thu, 5 Jun 2014 12:17:43 -0400 Subject: [PATCH 4/9] Selectize Pulled Into Mediaviewers --- .gitignore | 5 - .travis.yml | 11 - Gruntfile.js | 217 - LICENSE | 202 - Makefile | 33 - README.md | 96 - bower.json | 39 - dist/css/selectize.bootstrap2.css | 486 - dist/css/selectize.bootstrap3.css | 390 - dist/css/selectize.css | 316 - dist/css/selectize.default.css | 386 - dist/css/selectize.legacy.css | 363 - dist/js/selectize.js | 2836 ---- dist/js/selectize.min.js | 3 - dist/js/standalone/selectize.js | 3422 ----- dist/js/standalone/selectize.min.js | 3 - dist/less/plugins/drag_drop.less | 16 - dist/less/plugins/dropdown_header.less | 20 - dist/less/plugins/optgroup_columns.less | 17 - dist/less/plugins/remove_button.less | 37 - dist/less/selectize.bootstrap2.less | 161 - dist/less/selectize.bootstrap3.less | 136 - dist/less/selectize.default.less | 84 - dist/less/selectize.legacy.less | 75 - dist/less/selectize.less | 293 - docs/api.md | 235 - docs/events.md | 85 - docs/plugins.md | 101 - docs/usage.md | 335 - examples/api.html | 81 - examples/basic.html | 472 - examples/cities.html | 145 - examples/confirm.html | 41 - examples/contacts.html | 150 - examples/css/normalize.css | 375 - examples/css/stylesheet.css | 132 - examples/customization.html | 82 - examples/dynamic.html | 48 - examples/events.html | 107 - examples/github.html | 154 - examples/images/bg.png | Bin 7475 -> 0 bytes examples/images/check@2x.png | Bin 6177 -> 0 bytes examples/images/repo-forked.png | Bin 3427 -> 0 bytes examples/images/repo-source.png | Bin 3410 -> 0 bytes examples/images/spinner.gif | Bin 3208 -> 0 bytes examples/js/es5.js | 17 - examples/js/index.js | 50 - examples/js/jquery.js | 2 - examples/js/jqueryui.js | 15003 ------------------- examples/lock.html | 66 - examples/movies.html | 165 - examples/optgroups.html | 174 - examples/performance.html | 59 - examples/plugins.html | 118 - examples/required.html | 53 - examples/rtl.html | 56 - package.json | 37 - selectize.jquery.json | 32 - src/.wrapper.js | 34 - src/constants.js | 21 - src/contrib/highlight.js | 39 - src/contrib/microevent.js | 48 - src/defaults.js | 68 - src/less/.wrapper.css | 17 - src/less/selectize.bootstrap2.less | 161 - src/less/selectize.bootstrap3.less | 136 - src/less/selectize.default.less | 84 - src/less/selectize.legacy.less | 75 - src/less/selectize.less | 288 - src/plugins/drag_drop/plugin.js | 67 - src/plugins/drag_drop/plugin.less | 16 - src/plugins/dropdown_header/plugin.js | 48 - src/plugins/dropdown_header/plugin.less | 20 - src/plugins/optgroup_columns/plugin.js | 92 - src/plugins/optgroup_columns/plugin.less | 17 - src/plugins/remove_button/plugin.js | 70 - src/plugins/remove_button/plugin.less | 37 - src/plugins/restore_on_backspace/plugin.js | 43 - src/selectize.jquery.js | 146 - src/selectize.js | 1908 --- src/utils.js | 344 - test/api.js | 572 - test/events.js | 215 - test/events_dom.js | 64 - test/interaction.js | 205 - test/setup.js | 223 - test/vendor/chai.js | 4254 ------ test/vendor/mocha.css | 251 - test/vendor/mocha.js | 5373 ------- test/vendor/syn.js | 2490 --- test/xss.js | 61 - testem.json | 6 - 92 files changed, 45515 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 Gruntfile.js delete mode 100644 LICENSE delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 bower.json delete mode 100644 dist/css/selectize.bootstrap2.css delete mode 100644 dist/css/selectize.bootstrap3.css delete mode 100644 dist/css/selectize.css delete mode 100644 dist/css/selectize.default.css delete mode 100644 dist/css/selectize.legacy.css delete mode 100644 dist/js/selectize.js delete mode 100644 dist/js/selectize.min.js delete mode 100644 dist/js/standalone/selectize.js delete mode 100644 dist/js/standalone/selectize.min.js delete mode 100644 dist/less/plugins/drag_drop.less delete mode 100644 dist/less/plugins/dropdown_header.less delete mode 100644 dist/less/plugins/optgroup_columns.less delete mode 100644 dist/less/plugins/remove_button.less delete mode 100644 dist/less/selectize.bootstrap2.less delete mode 100644 dist/less/selectize.bootstrap3.less delete mode 100644 dist/less/selectize.default.less delete mode 100644 dist/less/selectize.legacy.less delete mode 100644 dist/less/selectize.less delete mode 100644 docs/api.md delete mode 100644 docs/events.md delete mode 100644 docs/plugins.md delete mode 100644 docs/usage.md delete mode 100644 examples/api.html delete mode 100644 examples/basic.html delete mode 100644 examples/cities.html delete mode 100644 examples/confirm.html delete mode 100644 examples/contacts.html delete mode 100644 examples/css/normalize.css delete mode 100644 examples/css/stylesheet.css delete mode 100644 examples/customization.html delete mode 100644 examples/dynamic.html delete mode 100644 examples/events.html delete mode 100644 examples/github.html delete mode 100644 examples/images/bg.png delete mode 100644 examples/images/check@2x.png delete mode 100644 examples/images/repo-forked.png delete mode 100644 examples/images/repo-source.png delete mode 100644 examples/images/spinner.gif delete mode 100644 examples/js/es5.js delete mode 100644 examples/js/index.js delete mode 100644 examples/js/jquery.js delete mode 100644 examples/js/jqueryui.js delete mode 100644 examples/lock.html delete mode 100644 examples/movies.html delete mode 100644 examples/optgroups.html delete mode 100644 examples/performance.html delete mode 100644 examples/plugins.html delete mode 100644 examples/required.html delete mode 100644 examples/rtl.html delete mode 100644 package.json delete mode 100644 selectize.jquery.json delete mode 100644 src/.wrapper.js delete mode 100644 src/constants.js delete mode 100644 src/contrib/highlight.js delete mode 100644 src/contrib/microevent.js delete mode 100644 src/defaults.js delete mode 100644 src/less/.wrapper.css delete mode 100644 src/less/selectize.bootstrap2.less delete mode 100644 src/less/selectize.bootstrap3.less delete mode 100644 src/less/selectize.default.less delete mode 100644 src/less/selectize.legacy.less delete mode 100644 src/less/selectize.less delete mode 100644 src/plugins/drag_drop/plugin.js delete mode 100644 src/plugins/drag_drop/plugin.less delete mode 100644 src/plugins/dropdown_header/plugin.js delete mode 100644 src/plugins/dropdown_header/plugin.less delete mode 100644 src/plugins/optgroup_columns/plugin.js delete mode 100644 src/plugins/optgroup_columns/plugin.less delete mode 100644 src/plugins/remove_button/plugin.js delete mode 100644 src/plugins/remove_button/plugin.less delete mode 100644 src/plugins/restore_on_backspace/plugin.js delete mode 100644 src/selectize.jquery.js delete mode 100644 src/selectize.js delete mode 100644 src/utils.js delete mode 100644 test/api.js delete mode 100644 test/events.js delete mode 100644 test/events_dom.js delete mode 100644 test/interaction.js delete mode 100644 test/setup.js delete mode 100644 test/vendor/chai.js delete mode 100644 test/vendor/mocha.css delete mode 100644 test/vendor/mocha.js delete mode 100644 test/vendor/syn.js delete mode 100644 test/xss.js delete mode 100644 testem.json diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 005a40e07..000000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -.DAV -node_modules -bower_components -*.log \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7c0c61f92..000000000 --- a/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js -node_js: - - "0.10" -before_script: - - npm install -g bower - - npm install -g testem - - npm install -g grunt-cli - - npm install - - make -script: - - testem ci \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 8f68bd55f..000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,217 +0,0 @@ -var fs = require('fs'); - -module.exports = function(grunt) { - grunt.loadNpmTasks('grunt-bower-cli'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-less'); - grunt.loadNpmTasks('grunt-replace'); - - grunt.registerTask('configure', [ - 'clean:pre', - 'bower:install', - ]); - - grunt.registerTask('compile', [ - 'copy:less', - 'copy:less_plugins', - 'concat:less_theme_dependencies', - 'concat:less_plugins', - 'concat:js', - 'less:uncompressed', - 'clean_bootstrap2_css', - 'replace', - 'build_standalone', - 'uglify', - 'clean:post', - ]); - - grunt.registerTask('default', [ - 'configure', - 'compile' - ]); - - grunt.registerTask('clean_bootstrap2_css', 'Cleans CSS rules ocurring before the header comment.', function() { - var file = 'dist/css/selectize.bootstrap2.css'; - var source = fs.readFileSync(file, 'utf8'); - grunt.file.write(file, source.replace(/^(.|\s)+?\/\*/m, '/*')); - grunt.log.writeln('Cleaned "' + file + '".'); - }); - - grunt.registerTask('build_standalone', '', function() { - var files, i, n, source, name, path, modules = []; - - // amd definitions must be changed to be not anonymous - // @see https://github.com/brianreavis/selectize.js/issues/89 - files = []; - for (i = 0, n = files_js_dependencies.length; i < n; i++) { - path = files_js_dependencies[i]; - name = path.match(/([^\/]+?).js$/)[1]; - source = grunt.file.read(path).replace('define(factory);', 'define(\'' + name + '\', factory);'); - modules.push(source); - } - - path = 'dist/js/selectize.js'; - source = grunt.file.read(path).replace(/define\((.*?)factory\);/, 'define(\'selectize\', $1factory);'); - modules.push(source); - - // write output - path = 'dist/js/standalone/selectize.js'; - grunt.file.write(path, modules.join('\n\n')); - grunt.log.writeln('Built "' + path + '".'); - }); - - var files_js = [ - 'src/contrib/*.js', - 'src/*.js', - '!src/.wrapper.js', - '!src/defaults.js', - '!src/selectize.js', - '!src/selectize.jquery.js', - 'src/selectize.js', - 'src/defaults.js', - 'src/selectize.jquery.js', - ]; - - var files_js_dependencies = [ - 'bower_components/sifter/sifter.js', - 'bower_components/microplugin/src/microplugin.js', - ]; - - var less_imports = []; - var less_plugin_files = []; - - // enumerate plugins - (function() { - var selector_plugins = grunt.option('plugins'); - if (!selector_plugins) return; - - if (selector_plugins.indexOf(',') !== -1) { - selector_plugins = '{' + plugins.split(/\s*,\s*/).join(',') + '}'; - } - - // javascript - files_js.push('src/plugins/' + selector_plugins + '/*.js'); - - // less (css) - var matched_files = grunt.file.expand(['src/plugins/' + selector_plugins + '/plugin.less']); - for (var i = 0, n = matched_files.length; i < n; i++) { - var plugin_name = matched_files[i].match(/src\/plugins\/(.+?)\//)[1]; - less_imports.push('@import "plugins/' + plugin_name + '";'); - less_plugin_files.push({src: matched_files[i], dest: 'dist/less/plugins/' + plugin_name + '.less'}); - } - })(); - - grunt.initConfig({ - pkg: grunt.file.readJSON('bower.json'), - bower: { - install: { - options: { - directory: 'bower_components', - action: 'install' - } - } - }, - clean: { - pre: ['dist'], - post: ['**/*.tmp*'] - }, - copy: { - less: { - files: [{expand: true, flatten: true, src: ['src/less/*.less'], dest: 'dist/less'}] - }, - less_plugins: { - files: less_plugin_files - } - }, - replace: { - options: {prefix: '@@'}, - main: { - options: { - variables: { - 'version': '<%= pkg.version %>', - 'js': '<%= grunt.file.read("dist/js/selectize.js").replace(/\\n/g, "\\n\\t") %>', - 'css': '<%= grunt.file.read("dist/css/selectize.css") %>', - }, - }, - files: [ - {src: ['src/.wrapper.js'], dest: 'dist/js/selectize.js'}, - {src: ['src/less/.wrapper.css'], dest: 'dist/css/selectize.css'} - ] - }, - css_post: { - options: { - variables: { - 'version': '<%= pkg.version %>' - }, - }, - files: [ - {expand: true, flatten: false, src: ['dist/css/*.css'], dest: ''}, - {expand: true, flatten: false, src: ['dist/less/*.less'], dest: ''}, - {expand: true, flatten: false, src: ['dist/less/plugins/*.less'], dest: ''}, - ] - } - }, - less: { - options: {}, - uncompressed: { - files: { - 'dist/css/selectize.css': ['dist/less/selectize.less'], - 'dist/css/selectize.default.css': ['dist/less/selectize.default.less'], - 'dist/css/selectize.legacy.css': ['dist/less/selectize.legacy.less'], - 'dist/css/selectize.bootstrap2.css': ['dist/less/selectize.bootstrap2.tmp.less'], - 'dist/css/selectize.bootstrap3.css': ['dist/less/selectize.bootstrap3.tmp.less'] - } - } - }, - concat: { - options: { - stripBanners: true, - separator: grunt.util.linefeed + grunt.util.linefeed - }, - js: { - files: { - 'dist/js/selectize.js': files_js, - } - }, - less_plugins: { - options: { - banner: less_imports.join('\n') + grunt.util.linefeed + grunt.util.linefeed - }, - files: { - 'dist/less/selectize.less': ['dist/less/selectize.less'] - } - }, - less_theme_dependencies: { - options: {stripBanners: false}, - files: { - 'dist/less/selectize.bootstrap2.tmp.less': [ - 'bower_components/bootstrap2/less/variables.less', - 'bower_components/bootstrap2/less/mixins.less', - 'dist/less/selectize.bootstrap2.less' - ], - 'dist/less/selectize.bootstrap3.tmp.less': [ - 'bower_components/bootstrap3/less/variables.less', - 'bower_components/bootstrap3/less/mixins.less', - 'dist/less/selectize.bootstrap3.less' - ] - } - } - }, - uglify: { - main: { - options: { - 'banner': '/*! selectize.js - v<%= pkg.version %> | https://github.com/brianreavis/selectize.js | Apache License (v2) */\n', - 'report': 'gzip', - 'ascii-only': true - }, - files: { - 'dist/js/selectize.min.js': ['dist/js/selectize.js'], - 'dist/js/standalone/selectize.min.js': ['dist/js/standalone/selectize.js'] - } - } - } - }); -}; \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8e9684407..000000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2013 Brian Reavis - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile deleted file mode 100644 index 719a7901e..000000000 --- a/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -.PHONY: compile release test -plugins=* -GRUNT=node_modules/.bin/grunt -TESTEM=node_modules/.bin/testem - -all: compile -test: - $(TESTEM) -compile: - $(GRUNT) --plugins=$(plugins) -release: -ifeq ($(strip $(version)),) - @echo "\033[31mERROR:\033[0;39m No version provided." - @echo "\033[1;30mmake release version=1.0.0\033[0;39m" -else - sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' selectize.jquery.json - sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' bower.json - sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' package.json - rm *.bak - make compile - cp dist/js/standalone/selectize.js ../.selectize.js - git add . - git commit -a -m "Released $(version)." - git tag v$(version) - git push origin master - git push origin --tags - git checkout gh-pages - mv -f ../.selectize.js js/selectize.js - git commit -a -m "Updated selectize.js to latest version." - git push origin gh-pages - git checkout master - @echo "\033[32mv${version} released\033[0;39m" -endif \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index dda8b4975..000000000 --- a/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# selectize.js -[![Build Status](https://travis-ci.org/brianreavis/selectize.js.png?branch=master)](https://travis-ci.org/brianreavis/selectize.js) - -Selectize is an extensible jQuery-based custom <select> UI control. It's useful for tagging, contact lists, country selectors, and so on. It clocks in at around ~7kb (gzipped). The goal is to provide a solid & usable experience with a clean and powerful API. - -- [Demos](http://brianreavis.github.io/selectize.js/) -- [Changelog](https://github.com/brianreavis/selectize.js/releases) -- [Examples](examples/) -- [Usage Documentation](docs/usage.md) -- [API Documentation](docs/api.md) -- [Plugin Documentation](docs/plugins.md) - -### Features - -- **Smart Option Searching / Ranking**
Options are efficiently scored and sorted on-the-fly (using [sifter](https://github.com/brianreavis/sifter.js)). Want to search an item's title *and* description? No problem. -- **Caret between items**
Order matters sometimes. Use the and arrow keys to move between selected items. -- **Select & delete multiple items at once**
Hold down option on Mac or ctrl on Windows to select more than one item to delete. -- **Díåcritîçs supported**
Great for international environments. -- **Item creation**
Allow users to create items on the fly (async saving is supported; the control locks until the callback is fired). -- **Remote data loading**
For when you have thousands of options and want them provided by the server as the user types. -- **Clean API & code**
Interface with it and make modifications easily. Pull requests welcome! -- **Extensible**
[Plugin API](docs/plugins.md) for developing custom features (uses [microplugin](https://github.com/brianreavis/microplugin.js)). -- **Touch Support**
Plays nice with iOS 5+ devices. - -### Dependencies - -- [jquery](https://github.com/jquery/jquery) (1.7 and greater) -- [sifter](https://github.com/brianreavis/sifter.js) (bundled in ["standalone" build](dist/js/standalone)) -- [microplugin](https://github.com/brianreavis/microplugin.js) (bundled in ["standalone" build](dist/js/standalone)) - -### Files - -All pre-built files needed to use Selectize can be found in the ["dist"](dist/) folder. - -- [**js/**](dist/js) - - [**standalone/**](dist/js/standalone) - - [selectize.js](dist/js/standalone/selectize.js) — With dependencies, minus jquery - - [selectize.js](dist/js/selectize.js) — Without dependencies -- [**less/**](dist/less) - - [selectize.less](dist/less/selectize.less) — Core styles - - [selectize.default.less](dist/less/selectize.default.less) — Default theme - - [selectize.bootstrap2.less](dist/less/selectize.bootstrap2.less) — Bootstrap 2 theme - - [selectize.bootstrap3.less](dist/less/selectize.bootstrap3.less) — Bootstrap 3 theme - - [**plugins/**](dist/less/plugins) — Individual plugin styles -- [**css/**](dist/css) - - [selectize.css](dist/css/selectize.css) — Core styles - - [selectize.default.css](dist/css/selectize.default.css) — Default theme (with core styles) - - [selectize.bootstrap2.css](dist/css/selectize.bootstrap2.css) - Bootstrap 2 theme - - [selectize.bootstrap3.css](dist/css/selectize.bootstrap3.css) - Bootstrap 3 theme - -### Usage - -```js -$('select').selectize(options); -``` - -The available options are [documented here](docs/usage.md). - -#### IE8 Support - -To support Internet Explorer 8, [es5-shim](https://github.com/kriskowal/es5-shim/) must be added your page. - -```html - -``` - -### Custom Builds - -By default, all [plugins](src/plugins) are included. To hand-pick what plugins (if any) to include, run [`grunt`](http://gruntjs.com/) with the "--plugins" flag. After this completes, grab the files you need from the ["dist"](dist) folder. - -```sh -# dependencies -npm install -g bower -npm install - -# build selectize -grunt --plugins= -grunt --plugins=* -grunt --plugins=remove_button,restore_on_backspace -``` - -### Contributing - -First build your copy then try out the [bundled examples](examples/). - -To use the automated test runner, either open ["tests/index.html"](tests/index.html) in a browser, or run `make test`. The latter requires [node.js](http://nodejs.org/) and [testem](https://github.com/airportyh/testem) to be installed (`npm install -g testem`). - -When issuing a pull request, please exclude changes in the "dist" folder to avoid merge conflicts. - -## License - -Copyright © 2013 [Brian Reavis](http://twitter.com/brianreavis) & [Contributors](https://github.com/brianreavis/selectize.js/graphs/contributors) - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/bower.json b/bower.json deleted file mode 100644 index 18c7d8103..000000000 --- a/bower.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "selectize", - "keywords": ["select", "ui", "form", "input", "control", "autocomplete", "tagging", "tag"], - "description": "Selectize is a jQuery-based custom ').appendTo($control).attr('tabindex', tab_index); - $dropdown_parent = $(settings.dropdownParent || $wrapper); - $dropdown = $('
').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent); - $dropdown_content = $('
').addClass(settings.dropdownContentClass).appendTo($dropdown); - - $wrapper.css({ - width: self.$input[0].style.width - }); - - if (self.plugins.names.length) { - classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-'); - $wrapper.addClass(classes_plugins); - $dropdown.addClass(classes_plugins); - } - - if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) { - self.$input.attr('multiple', 'multiple'); - } - - if (self.settings.placeholder) { - $control_input.attr('placeholder', settings.placeholder); - } - - if (self.$input.attr('autocorrect')) { - $control_input.attr('autocorrect', self.$input.attr('autocorrect')); - } - - if (self.$input.attr('autocapitalize')) { - $control_input.attr('autocapitalize', self.$input.attr('autocapitalize')); - } - - self.$wrapper = $wrapper; - self.$control = $control; - self.$control_input = $control_input; - self.$dropdown = $dropdown; - self.$dropdown_content = $dropdown_content; - - $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); }); - $dropdown.on('mousedown', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); }); - watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); }); - autoGrow($control_input); - - $control.on({ - mousedown : function() { return self.onMouseDown.apply(self, arguments); }, - click : function() { return self.onClick.apply(self, arguments); } - }); - - $control_input.on({ - mousedown : function(e) { e.stopPropagation(); }, - keydown : function() { return self.onKeyDown.apply(self, arguments); }, - keyup : function() { return self.onKeyUp.apply(self, arguments); }, - keypress : function() { return self.onKeyPress.apply(self, arguments); }, - resize : function() { self.positionDropdown.apply(self, []); }, - blur : function() { return self.onBlur.apply(self, arguments); }, - focus : function() { return self.onFocus.apply(self, arguments); }, - paste : function() { return self.onPaste.apply(self, arguments); } - }); - - $document.on('keydown' + eventNS, function(e) { - self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey']; - self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey']; - self.isShiftDown = e.shiftKey; - }); - - $document.on('keyup' + eventNS, function(e) { - if (e.keyCode === KEY_CTRL) self.isCtrlDown = false; - if (e.keyCode === KEY_SHIFT) self.isShiftDown = false; - if (e.keyCode === KEY_CMD) self.isCmdDown = false; - }); - - $document.on('mousedown' + eventNS, function(e) { - if (self.isFocused) { - // prevent events on the dropdown scrollbar from causing the control to blur - if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) { - return false; - } - // blur on click outside - if (!self.$control.has(e.target).length && e.target !== self.$control[0]) { - self.blur(); - } - } - }); - - $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() { - if (self.isOpen) { - self.positionDropdown.apply(self, arguments); - } - }); - $window.on('mousemove' + eventNS, function() { - self.ignoreHover = false; - }); - - // store original children and tab index so that they can be - // restored when the destroy() method is called. - this.revertSettings = { - $children : self.$input.children().detach(), - tabindex : self.$input.attr('tabindex') - }; - - self.$input.attr('tabindex', -1).hide().after(self.$wrapper); - - if ($.isArray(settings.items)) { - self.setValue(settings.items); - delete settings.items; - } - - // feature detect for the validation API - if (self.$input[0].validity) { - self.$input.on('invalid' + eventNS, function(e) { - e.preventDefault(); - self.isInvalid = true; - self.refreshState(); - }); - } - - self.updateOriginalInput(); - self.refreshItems(); - self.refreshState(); - self.updatePlaceholder(); - self.isSetup = true; - - if (self.$input.is(':disabled')) { - self.disable(); - } - - self.on('change', this.onChange); - self.trigger('initialize'); - - // preload options - if (settings.preload === true) { - self.onSearchChange(''); - } - }, - - /** - * Sets up default rendering functions. - */ - setupTemplates: function() { - var self = this; - var field_label = self.settings.labelField; - var field_optgroup = self.settings.optgroupLabelField; - - var templates = { - 'optgroup': function(data) { - return '
' + data.html + '
'; - }, - 'optgroup_header': function(data, escape) { - return '
' + escape(data[field_optgroup]) + '
'; - }, - 'option': function(data, escape) { - return '
' + escape(data[field_label]) + '
'; - }, - 'item': function(data, escape) { - return '
' + escape(data[field_label]) + '
'; - }, - 'option_create': function(data, escape) { - return '
Add ' + escape(data.input) + '
'; - } - }; - - self.settings.render = $.extend({}, templates, self.settings.render); - }, - - /** - * Maps fired events to callbacks provided - * in the settings used when creating the control. - */ - setupCallbacks: function() { - var key, fn, callbacks = { - 'initialize' : 'onInitialize', - 'change' : 'onChange', - 'item_add' : 'onItemAdd', - 'item_remove' : 'onItemRemove', - 'clear' : 'onClear', - 'option_add' : 'onOptionAdd', - 'option_remove' : 'onOptionRemove', - 'option_clear' : 'onOptionClear', - 'dropdown_open' : 'onDropdownOpen', - 'dropdown_close' : 'onDropdownClose', - 'type' : 'onType' - }; - - for (key in callbacks) { - if (callbacks.hasOwnProperty(key)) { - fn = this.settings[callbacks[key]]; - if (fn) this.on(key, fn); - } - } - }, - - /** - * Triggered when the main control element - * has a click event. - * - * @param {object} e - * @return {boolean} - */ - onClick: function(e) { - var self = this; - - // necessary for mobile webkit devices (manual focus triggering - // is ignored unless invoked within a click event) - if (!self.isFocused) { - self.focus(); - e.preventDefault(); - } - }, - - /** - * Triggered when the main control element - * has a mouse down event. - * - * @param {object} e - * @return {boolean} - */ - onMouseDown: function(e) { - var self = this; - var defaultPrevented = e.isDefaultPrevented(); - var $target = $(e.target); - - if (self.isFocused) { - // retain focus by preventing native handling. if the - // event target is the input it should not be modified. - // otherwise, text selection within the input won't work. - if (e.target !== self.$control_input[0]) { - if (self.settings.mode === 'single') { - // toggle dropdown - self.isOpen ? self.close() : self.open(); - } else if (!defaultPrevented) { - self.setActiveItem(null); - } - return false; - } - } else { - // give control focus - if (!defaultPrevented) { - window.setTimeout(function() { - self.focus(); - }, 0); - } - } - }, - - /** - * Triggered when the value of the control has been changed. - * This should propagate the event to the original DOM - * input / select element. - */ - onChange: function() { - this.$input.trigger('change'); - }, - - - /** - * Triggered on paste. - * - * @param {object} e - * @returns {boolean} - */ - onPaste: function(e) { - var self = this; - if (self.isFull() || self.isInputHidden || self.isLocked) { - e.preventDefault(); - } else { - // If a regex or string is included, this will split the pasted input and create Items for each separate value - if (self.settings.splitOn) { - setTimeout($.proxy(function() { - var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); - splitInput.forEach($.proxy(function(input) { - self.createItem(input); - }, self)); - }, self), 0); - } - } - }, - - /** - * Triggered on keypress. - * - * @param {object} e - * @returns {boolean} - */ - onKeyPress: function(e) { - if (this.isLocked) return e && e.preventDefault(); - var character = String.fromCharCode(e.keyCode || e.which); - if (this.settings.create && character === this.settings.delimiter) { - this.createItem(); - e.preventDefault(); - return false; - } - }, - - /** - * Triggered on keydown. - * - * @param {object} e - * @returns {boolean} - */ - onKeyDown: function(e) { - var isInput = e.target === this.$control_input[0]; - var self = this; - - if (self.isLocked) { - if (e.keyCode !== KEY_TAB) { - e.preventDefault(); - } - return; - } - - switch (e.keyCode) { - case KEY_A: - if (self.isCmdDown) { - self.selectAll(); - return; - } - break; - case KEY_ESC: - self.close(); - return; - case KEY_N: - if (!e.ctrlKey || e.altKey) break; - case KEY_DOWN: - if (!self.isOpen && self.hasOptions) { - self.open(); - } else if (self.$activeOption) { - self.ignoreHover = true; - var $next = self.getAdjacentOption(self.$activeOption, 1); - if ($next.length) self.setActiveOption($next, true, true); - } - e.preventDefault(); - return; - case KEY_P: - if (!e.ctrlKey || e.altKey) break; - case KEY_UP: - if (self.$activeOption) { - self.ignoreHover = true; - var $prev = self.getAdjacentOption(self.$activeOption, -1); - if ($prev.length) self.setActiveOption($prev, true, true); - } - e.preventDefault(); - return; - case KEY_RETURN: - if (self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - e.preventDefault(); - return; - case KEY_LEFT: - self.advanceSelection(-1, e); - return; - case KEY_RIGHT: - self.advanceSelection(1, e); - return; - case KEY_TAB: - if (self.settings.selectOnTab && self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - if (self.settings.create && self.createItem()) { - e.preventDefault(); - } - return; - case KEY_BACKSPACE: - case KEY_DELETE: - self.deleteSelection(e); - return; - } - - if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) { - e.preventDefault(); - return; - } - }, - - /** - * Triggered on keyup. - * - * @param {object} e - * @returns {boolean} - */ - onKeyUp: function(e) { - var self = this; - - if (self.isLocked) return e && e.preventDefault(); - var value = self.$control_input.val() || ''; - if (self.lastValue !== value) { - self.lastValue = value; - self.onSearchChange(value); - self.refreshOptions(); - self.trigger('type', value); - } - }, - - /** - * Invokes the user-provide option provider / loader. - * - * Note: this function is debounced in the Selectize - * constructor (by `settings.loadDelay` milliseconds) - * - * @param {string} value - */ - onSearchChange: function(value) { - var self = this; - var fn = self.settings.load; - if (!fn) return; - if (self.loadedSearches.hasOwnProperty(value)) return; - self.loadedSearches[value] = true; - self.load(function(callback) { - fn.apply(self, [value, callback]); - }); - }, - - /** - * Triggered on focus. - * - * @param {object} e (optional) - * @returns {boolean} - */ - onFocus: function(e) { - var self = this; - - self.isFocused = true; - if (self.isDisabled) { - self.blur(); - e && e.preventDefault(); - return false; - } - - if (self.ignoreFocus) return; - if (self.settings.preload === 'focus') self.onSearchChange(''); - - if (!self.$activeItems.length) { - self.showInput(); - self.setActiveItem(null); - self.refreshOptions(!!self.settings.openOnFocus); - } - - self.refreshState(); - }, - - /** - * Triggered on blur. - * - * @param {object} e - * @returns {boolean} - */ - onBlur: function(e) { - var self = this; - self.isFocused = false; - if (self.ignoreFocus) return; - - if (self.settings.create && self.settings.createOnBlur) { - self.createItem(false); - } - - self.close(); - self.setTextboxValue(''); - self.setActiveItem(null); - self.setActiveOption(null); - self.setCaret(self.items.length); - self.refreshState(); - }, - - /** - * Triggered when the user rolls over - * an option in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionHover: function(e) { - if (this.ignoreHover) return; - this.setActiveOption(e.currentTarget, false); - }, - - /** - * Triggered when the user clicks on an option - * in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionSelect: function(e) { - var value, $target, $option, self = this; - - if (e.preventDefault) { - e.preventDefault(); - e.stopPropagation(); - } - - $target = $(e.currentTarget); - if ($target.hasClass('create')) { - self.createItem(); - } else { - value = $target.attr('data-value'); - if (value) { - self.lastQuery = null; - self.setTextboxValue(''); - self.addItem(value); - if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) { - self.setActiveOption(self.getOption(value)); - } - } - } - }, - - /** - * Triggered when the user clicks on an item - * that has been selected. - * - * @param {object} e - * @returns {boolean} - */ - onItemSelect: function(e) { - var self = this; - - if (self.isLocked) return; - if (self.settings.mode === 'multi') { - e.preventDefault(); - self.setActiveItem(e.currentTarget, e); - } - }, - - /** - * Invokes the provided method that provides - * results to a callback---which are then added - * as options to the control. - * - * @param {function} fn - */ - load: function(fn) { - var self = this; - var $wrapper = self.$wrapper.addClass('loading'); - - self.loading++; - fn.apply(self, [function(results) { - self.loading = Math.max(self.loading - 1, 0); - if (results && results.length) { - self.addOption(results); - self.refreshOptions(self.isFocused && !self.isInputHidden); - } - if (!self.loading) { - $wrapper.removeClass('loading'); - } - self.trigger('load', results); - }]); - }, - - /** - * Sets the input field of the control to the specified value. - * - * @param {string} value - */ - setTextboxValue: function(value) { - var $input = this.$control_input; - var changed = $input.val() !== value; - if (changed) { - $input.val(value).triggerHandler('update'); - this.lastValue = value; - } - }, - - /** - * Returns the value of the control. If multiple items - * can be selected (e.g. or - * element to reflect the current state. - */ - updateOriginalInput: function() { - var i, n, options, self = this; - - if (self.$input[0].tagName.toLowerCase() === 'select') { - options = []; - for (i = 0, n = self.items.length; i < n; i++) { - options.push(''); - } - if (!options.length && !this.$input.attr('multiple')) { - options.push(''); - } - self.$input.html(options.join('')); - } else { - self.$input.val(self.getValue()); - } - - if (self.isSetup) { - self.trigger('change', self.$input.val()); - } - }, - - /** - * Shows/hide the input placeholder depending - * on if there items in the list already. - */ - updatePlaceholder: function() { - if (!this.settings.placeholder) return; - var $input = this.$control_input; - - if (this.items.length) { - $input.removeAttr('placeholder'); - } else { - $input.attr('placeholder', this.settings.placeholder); - } - $input.triggerHandler('update', {force: true}); - }, - - /** - * Shows the autocomplete dropdown containing - * the available options. - */ - open: function() { - var self = this; - - if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return; - self.focus(); - self.isOpen = true; - self.refreshState(); - self.$dropdown.css({visibility: 'hidden', display: 'block'}); - self.positionDropdown(); - self.$dropdown.css({visibility: 'visible'}); - self.trigger('dropdown_open', self.$dropdown); - }, - - /** - * Closes the autocomplete dropdown menu. - */ - close: function() { - var self = this; - var trigger = self.isOpen; - - if (self.settings.mode === 'single' && self.items.length) { - self.hideInput(); - } - - self.isOpen = false; - self.$dropdown.hide(); - self.setActiveOption(null); - self.refreshState(); - - if (trigger) self.trigger('dropdown_close', self.$dropdown); - }, - - /** - * Calculates and applies the appropriate - * position of the dropdown. - */ - positionDropdown: function() { - var $control = this.$control; - var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); - offset.top += $control.outerHeight(true); - - this.$dropdown.css({ - width : $control.outerWidth(), - top : offset.top, - left : offset.left - }); - }, - - /** - * Resets / clears all selected items - * from the control. - */ - clear: function() { - var self = this; - - if (!self.items.length) return; - self.$control.children(':not(input)').remove(); - self.items = []; - self.setCaret(0); - self.updatePlaceholder(); - self.updateOriginalInput(); - self.refreshState(); - self.showInput(); - self.trigger('clear'); - }, - - /** - * A helper method for inserting an element - * at the current caret position. - * - * @param {object} $el - */ - insertAtCaret: function($el) { - var caret = Math.min(this.caretPos, this.items.length); - if (caret === 0) { - this.$control.prepend($el); - } else { - $(this.$control[0].childNodes[caret]).before($el); - } - this.setCaret(caret + 1); - }, - - /** - * Removes the current selected item(s). - * - * @param {object} e (optional) - * @returns {boolean} - */ - deleteSelection: function(e) { - var i, n, direction, selection, values, caret, option_select, $option_select, $tail; - var self = this; - - direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1; - selection = getSelection(self.$control_input[0]); - - if (self.$activeOption && !self.settings.hideSelected) { - option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value'); - } - - // determine items that will be removed - values = []; - - if (self.$activeItems.length) { - $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first')); - caret = self.$control.children(':not(input)').index($tail); - if (direction > 0) { caret++; } - - for (i = 0, n = self.$activeItems.length; i < n; i++) { - values.push($(self.$activeItems[i]).attr('data-value')); - } - if (e) { - e.preventDefault(); - e.stopPropagation(); - } - } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) { - if (direction < 0 && selection.start === 0 && selection.length === 0) { - values.push(self.items[self.caretPos - 1]); - } else if (direction > 0 && selection.start === self.$control_input.val().length) { - values.push(self.items[self.caretPos]); - } - } - - // allow the callback to abort - if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) { - return false; - } - - // perform removal - if (typeof caret !== 'undefined') { - self.setCaret(caret); - } - while (values.length) { - self.removeItem(values.pop()); - } - - self.showInput(); - self.positionDropdown(); - self.refreshOptions(true); - - // select previous option - if (option_select) { - $option_select = self.getOption(option_select); - if ($option_select.length) { - self.setActiveOption($option_select); - } - } - - return true; - }, - - /** - * Selects the previous / next item (depending - * on the `direction` argument). - * - * > 0 - right - * < 0 - left - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceSelection: function(direction, e) { - var tail, selection, idx, valueLength, cursorAtEdge, $tail; - var self = this; - - if (direction === 0) return; - if (self.rtl) direction *= -1; - - tail = direction > 0 ? 'last' : 'first'; - selection = getSelection(self.$control_input[0]); - - if (self.isFocused && !self.isInputHidden) { - valueLength = self.$control_input.val().length; - cursorAtEdge = direction < 0 - ? selection.start === 0 && selection.length === 0 - : selection.start === valueLength; - - if (cursorAtEdge && !valueLength) { - self.advanceCaret(direction, e); - } - } else { - $tail = self.$control.children('.active:' + tail); - if ($tail.length) { - idx = self.$control.children(':not(input)').index($tail); - self.setActiveItem(null); - self.setCaret(direction > 0 ? idx + 1 : idx); - } - } - }, - - /** - * Moves the caret left / right. - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceCaret: function(direction, e) { - var self = this, fn, $adj; - - if (direction === 0) return; - - fn = direction > 0 ? 'next' : 'prev'; - if (self.isShiftDown) { - $adj = self.$control_input[fn](); - if ($adj.length) { - self.hideInput(); - self.setActiveItem($adj); - e && e.preventDefault(); - } - } else { - self.setCaret(self.caretPos + direction); - } - }, - - /** - * Moves the caret to the specified index. - * - * @param {int} i - */ - setCaret: function(i) { - var self = this; - - if (self.settings.mode === 'single') { - i = self.items.length; - } else { - i = Math.max(0, Math.min(self.items.length, i)); - } - - // the input must be moved by leaving it in place and moving the - // siblings, due to the fact that focus cannot be restored once lost - // on mobile webkit devices - var j, n, fn, $children, $child; - $children = self.$control.children(':not(input)'); - for (j = 0, n = $children.length; j < n; j++) { - $child = $($children[j]).detach(); - if (j < i) { - self.$control_input.before($child); - } else { - self.$control.append($child); - } - } - - self.caretPos = i; - }, - - /** - * Disables user input on the control. Used while - * items are being asynchronously created. - */ - lock: function() { - this.close(); - this.isLocked = true; - this.refreshState(); - }, - - /** - * Re-enables user input on the control. - */ - unlock: function() { - this.isLocked = false; - this.refreshState(); - }, - - /** - * Disables user input on the control completely. - * While disabled, it cannot receive focus. - */ - disable: function() { - var self = this; - self.$input.prop('disabled', true); - self.isDisabled = true; - self.lock(); - }, - - /** - * Enables the control so that it can respond - * to focus and user input. - */ - enable: function() { - var self = this; - self.$input.prop('disabled', false); - self.isDisabled = false; - self.unlock(); - }, - - /** - * Completely destroys the control and - * unbinds all event listeners so that it can - * be garbage collected. - */ - destroy: function() { - var self = this; - var eventNS = self.eventNS; - var revertSettings = self.revertSettings; - - self.trigger('destroy'); - self.off(); - self.$wrapper.remove(); - self.$dropdown.remove(); - - self.$input - .html('') - .append(revertSettings.$children) - .removeAttr('tabindex') - .attr({tabindex: revertSettings.tabindex}) - .show(); - - $(window).off(eventNS); - $(document).off(eventNS); - $(document.body).off(eventNS); - - delete self.$input[0].selectize; - }, - - /** - * A helper method for rendering "item" and - * "option" templates, given the data. - * - * @param {string} templateName - * @param {object} data - * @returns {string} - */ - render: function(templateName, data) { - var value, id, label; - var html = ''; - var cache = false; - var self = this; - var regex_tag = /^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; - - if (templateName === 'option' || templateName === 'item') { - value = hash_key(data[self.settings.valueField]); - cache = !!value; - } - - // pull markup from cache if it exists - if (cache) { - if (!isset(self.renderCache[templateName])) { - self.renderCache[templateName] = {}; - } - if (self.renderCache[templateName].hasOwnProperty(value)) { - return self.renderCache[templateName][value]; - } - } - - // render markup - html = self.settings.render[templateName].apply(this, [data, escape_html]); - - // add mandatory attributes - if (templateName === 'option' || templateName === 'option_create') { - html = html.replace(regex_tag, '<$1 data-selectable'); - } - if (templateName === 'optgroup') { - id = data[self.settings.optgroupValueField] || ''; - html = html.replace(regex_tag, '<$1 data-group="' + escape_replace(escape_html(id)) + '"'); - } - if (templateName === 'option' || templateName === 'item') { - html = html.replace(regex_tag, '<$1 data-value="' + escape_replace(escape_html(value || '')) + '"'); - } - - // update cache - if (cache) { - self.renderCache[templateName][value] = html; - } - - return html; - } - - }); - - - Selectize.count = 0; - Selectize.defaults = { - plugins: [], - delimiter: ',', - splitOn: /[,]+/, // Regex or string for splitting up values from a paste command - persist: true, - diacritics: true, - create: false, - createOnBlur: false, - highlight: true, - openOnFocus: true, - maxOptions: 1000, - maxItems: null, - hideSelected: null, - addPrecedence: false, - selectOnTab: false, - preload: false, - - scrollDuration: 60, - loadThrottle: 300, - - dataAttr: 'data-data', - optgroupField: 'optgroup', - valueField: 'value', - labelField: 'text', - optgroupLabelField: 'label', - optgroupValueField: 'value', - optgroupOrder: null, - - sortField: '$order', - searchField: ['text'], - searchConjunction: 'and', - - mode: null, - wrapperClass: 'selectize-control', - inputClass: 'selectize-input', - dropdownClass: 'selectize-dropdown', - dropdownContentClass: 'selectize-dropdown-content', - - dropdownParent: null, - - /* - load : null, // function(query, callback) { ... } - score : null, // function(search) { ... } - onInitialize : null, // function() { ... } - onChange : null, // function(value) { ... } - onItemAdd : null, // function(value, $item) { ... } - onItemRemove : null, // function(value) { ... } - onClear : null, // function() { ... } - onOptionAdd : null, // function(value, data) { ... } - onOptionRemove : null, // function(value) { ... } - onOptionClear : null, // function() { ... } - onDropdownOpen : null, // function($dropdown) { ... } - onDropdownClose : null, // function($dropdown) { ... } - onType : null, // function(str) { ... } - onDelete : null, // function(values) { ... } - */ - - render: { - /* - item: null, - optgroup: null, - optgroup_header: null, - option: null, - option_create: null - */ - } - }; - - $.fn.selectize = function(settings_user) { - var defaults = $.fn.selectize.defaults; - var settings = $.extend({}, defaults, settings_user); - var attr_data = settings.dataAttr; - var field_label = settings.labelField; - var field_value = settings.valueField; - var field_optgroup = settings.optgroupField; - var field_optgroup_label = settings.optgroupLabelField; - var field_optgroup_value = settings.optgroupValueField; - - /** - * Initializes selectize from a element. - * - * @param {object} $input - * @param {object} settings_element - */ - var init_textbox = function($input, settings_element) { - var i, n, values, option, value = $.trim($input.val() || ''); - if (!value.length) return; - - values = value.split(settings.delimiter); - for (i = 0, n = values.length; i < n; i++) { - option = {}; - option[field_label] = values[i]; - option[field_value] = values[i]; - - settings_element.options[values[i]] = option; - } - - settings_element.items = values; - }; - - /** - * Initializes selectize from a ').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height());j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d - */ - -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define('sifter', factory); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.Sifter = factory(); - } -}(this, function() { - - /** - * Textually searches arrays and hashes of objects - * by property (or multiple properties). Designed - * specifically for autocomplete. - * - * @constructor - * @param {array|object} items - * @param {object} items - */ - var Sifter = function(items, settings) { - this.items = items; - this.settings = settings || {diacritics: true}; - }; - - /** - * Splits a search string into an array of individual - * regexps to be used to match results. - * - * @param {string} query - * @returns {array} - */ - Sifter.prototype.tokenize = function(query) { - query = trim(String(query || '').toLowerCase()); - if (!query || !query.length) return []; - - var i, n, regex, letter; - var tokens = []; - var words = query.split(/ +/); - - for (i = 0, n = words.length; i < n; i++) { - regex = escape_regex(words[i]); - if (this.settings.diacritics) { - for (letter in DIACRITICS) { - if (DIACRITICS.hasOwnProperty(letter)) { - regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]); - } - } - } - tokens.push({ - string : words[i], - regex : new RegExp(regex, 'i') - }); - } - - return tokens; - }; - - /** - * Iterates over arrays and hashes. - * - * ``` - * this.iterator(this.items, function(item, id) { - * // invoked for each item - * }); - * ``` - * - * @param {array|object} object - */ - Sifter.prototype.iterator = function(object, callback) { - var iterator; - if (is_array(object)) { - iterator = Array.prototype.forEach || function(callback) { - for (var i = 0, n = this.length; i < n; i++) { - callback(this[i], i, this); - } - }; - } else { - iterator = function(callback) { - for (var key in this) { - if (this.hasOwnProperty(key)) { - callback(this[key], key, this); - } - } - }; - } - - iterator.apply(object, [callback]); - }; - - /** - * Returns a function to be used to score individual results. - * - * Good matches will have a higher score than poor matches. - * If an item is not a match, 0 will be returned by the function. - * - * @param {object|string} search - * @param {object} options (optional) - * @returns {function} - */ - Sifter.prototype.getScoreFunction = function(search, options) { - var self, fields, tokens, token_count; - - self = this; - search = self.prepareSearch(search, options); - tokens = search.tokens; - fields = search.options.fields; - token_count = tokens.length; - - /** - * Calculates how close of a match the - * given value is against a search token. - * - * @param {mixed} value - * @param {object} token - * @return {number} - */ - var scoreValue = function(value, token) { - var score, pos; - - if (!value) return 0; - value = String(value || ''); - pos = value.search(token.regex); - if (pos === -1) return 0; - score = token.string.length / value.length; - if (pos === 0) score += 0.5; - return score; - }; - - /** - * Calculates the score of an object - * against the search query. - * - * @param {object} token - * @param {object} data - * @return {number} - */ - var scoreObject = (function() { - var field_count = fields.length; - if (!field_count) { - return function() { return 0; }; - } - if (field_count === 1) { - return function(token, data) { - return scoreValue(data[fields[0]], token); - }; - } - return function(token, data) { - for (var i = 0, sum = 0; i < field_count; i++) { - sum += scoreValue(data[fields[i]], token); - } - return sum / field_count; - }; - })(); - - if (!token_count) { - return function() { return 0; }; - } - if (token_count === 1) { - return function(data) { - return scoreObject(tokens[0], data); - }; - } - - if (search.options.conjunction === 'and') { - return function(data) { - var score; - for (var i = 0, sum = 0; i < token_count; i++) { - score = scoreObject(tokens[i], data); - if (score <= 0) return 0; - sum += score; - } - return sum / token_count; - }; - } else { - return function(data) { - for (var i = 0, sum = 0; i < token_count; i++) { - sum += scoreObject(tokens[i], data); - } - return sum / token_count; - }; - } - }; - - /** - * Returns a function that can be used to compare two - * results, for sorting purposes. If no sorting should - * be performed, `null` will be returned. - * - * @param {string|object} search - * @param {object} options - * @return function(a,b) - */ - Sifter.prototype.getSortFunction = function(search, options) { - var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort; - - self = this; - search = self.prepareSearch(search, options); - sort = (!search.query && options.sort_empty) || options.sort; - - /** - * Fetches the specified sort field value - * from a search result item. - * - * @param {string} name - * @param {object} result - * @return {mixed} - */ - get_field = function(name, result) { - if (name === '$score') return result.score; - return self.items[result.id][name]; - }; - - // parse options - fields = []; - if (sort) { - for (i = 0, n = sort.length; i < n; i++) { - if (search.query || sort[i].field !== '$score') { - fields.push(sort[i]); - } - } - } - - // the "$score" field is implied to be the primary - // sort field, unless it's manually specified - if (search.query) { - implicit_score = true; - for (i = 0, n = fields.length; i < n; i++) { - if (fields[i].field === '$score') { - implicit_score = false; - break; - } - } - if (implicit_score) { - fields.unshift({field: '$score', direction: 'desc'}); - } - } else { - for (i = 0, n = fields.length; i < n; i++) { - if (fields[i].field === '$score') { - fields.splice(i, 1); - break; - } - } - } - - multipliers = []; - for (i = 0, n = fields.length; i < n; i++) { - multipliers.push(fields[i].direction === 'desc' ? -1 : 1); - } - - // build function - fields_count = fields.length; - if (!fields_count) { - return null; - } else if (fields_count === 1) { - field = fields[0].field; - multiplier = multipliers[0]; - return function(a, b) { - return multiplier * cmp( - get_field(field, a), - get_field(field, b) - ); - }; - } else { - return function(a, b) { - var i, result, a_value, b_value, field; - for (i = 0; i < fields_count; i++) { - field = fields[i].field; - result = multipliers[i] * cmp( - get_field(field, a), - get_field(field, b) - ); - if (result) return result; - } - return 0; - }; - } - }; - - /** - * Parses a search query and returns an object - * with tokens and fields ready to be populated - * with results. - * - * @param {string} query - * @param {object} options - * @returns {object} - */ - Sifter.prototype.prepareSearch = function(query, options) { - if (typeof query === 'object') return query; - - options = extend({}, options); - - var option_fields = options.fields; - var option_sort = options.sort; - var option_sort_empty = options.sort_empty; - - if (option_fields && !is_array(option_fields)) options.fields = [option_fields]; - if (option_sort && !is_array(option_sort)) options.sort = [option_sort]; - if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty]; - - return { - options : options, - query : String(query || '').toLowerCase(), - tokens : this.tokenize(query), - total : 0, - items : [] - }; - }; - - /** - * Searches through all items and returns a sorted array of matches. - * - * The `options` parameter can contain: - * - * - fields {string|array} - * - sort {array} - * - score {function} - * - filter {bool} - * - limit {integer} - * - * Returns an object containing: - * - * - options {object} - * - query {string} - * - tokens {array} - * - total {int} - * - items {array} - * - * @param {string} query - * @param {object} options - * @returns {object} - */ - Sifter.prototype.search = function(query, options) { - var self = this, value, score, search, calculateScore; - var fn_sort; - var fn_score; - - search = this.prepareSearch(query, options); - options = search.options; - query = search.query; - - // generate result scoring function - fn_score = options.score || self.getScoreFunction(search); - - // perform search and sort - if (query.length) { - self.iterator(self.items, function(item, id) { - score = fn_score(item); - if (options.filter === false || score > 0) { - search.items.push({'score': score, 'id': id}); - } - }); - } else { - self.iterator(self.items, function(item, id) { - search.items.push({'score': 1, 'id': id}); - }); - } - - fn_sort = self.getSortFunction(search, options); - if (fn_sort) search.items.sort(fn_sort); - - // apply limits - search.total = search.items.length; - if (typeof options.limit === 'number') { - search.items = search.items.slice(0, options.limit); - } - - return search; - }; - - // utilities - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var cmp = function(a, b) { - if (typeof a === 'number' && typeof b === 'number') { - return a > b ? 1 : (a < b ? -1 : 0); - } - a = String(a || '').toLowerCase(); - b = String(b || '').toLowerCase(); - if (a > b) return 1; - if (b > a) return -1; - return 0; - }; - - var extend = function(a, b) { - var i, n, k, object; - for (i = 1, n = arguments.length; i < n; i++) { - object = arguments[i]; - if (!object) continue; - for (k in object) { - if (object.hasOwnProperty(k)) { - a[k] = object[k]; - } - } - } - return a; - }; - - var trim = function(str) { - return (str + '').replace(/^\s+|\s+$|/g, ''); - }; - - var escape_regex = function(str) { - return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); - }; - - var is_array = Array.isArray || ($ && $.isArray) || function(object) { - return Object.prototype.toString.call(object) === '[object Array]'; - }; - - var DIACRITICS = { - 'a': '[aÀÁÂÃÄÅàáâãäå]', - 'c': '[cÇçćĆčČ]', - 'd': '[dđĐďĎ]', - 'e': '[eÈÉÊËèéêëěĚ]', - 'i': '[iÌÍÎÏìíîï]', - 'n': '[nÑñňŇ]', - 'o': '[oÒÓÔÕÕÖØòóôõöø]', - 'r': '[rřŘ]', - 's': '[sŠš]', - 't': '[tťŤ]', - 'u': '[uÙÚÛÜùúûüůŮ]', - 'y': '[yŸÿýÝ]', - 'z': '[zŽž]' - }; - - // export - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return Sifter; -})); - - - -/** - * microplugin.js - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define('microplugin', factory); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.MicroPlugin = factory(); - } -}(this, function() { - var MicroPlugin = {}; - - MicroPlugin.mixin = function(Interface) { - Interface.plugins = {}; - - /** - * Initializes the listed plugins (with options). - * Acceptable formats: - * - * List (without options): - * ['a', 'b', 'c'] - * - * List (with options): - * [{'name': 'a', options: {}}, {'name': 'b', options: {}}] - * - * Hash (with options): - * {'a': { ... }, 'b': { ... }, 'c': { ... }} - * - * @param {mixed} plugins - */ - Interface.prototype.initializePlugins = function(plugins) { - var i, n, key; - var self = this; - var queue = []; - - self.plugins = { - names : [], - settings : {}, - requested : {}, - loaded : {} - }; - - if (utils.isArray(plugins)) { - for (i = 0, n = plugins.length; i < n; i++) { - if (typeof plugins[i] === 'string') { - queue.push(plugins[i]); - } else { - self.plugins.settings[plugins[i].name] = plugins[i].options; - queue.push(plugins[i].name); - } - } - } else if (plugins) { - for (key in plugins) { - if (plugins.hasOwnProperty(key)) { - self.plugins.settings[key] = plugins[key]; - queue.push(key); - } - } - } - - while (queue.length) { - self.require(queue.shift()); - } - }; - - Interface.prototype.loadPlugin = function(name) { - var self = this; - var plugins = self.plugins; - var plugin = Interface.plugins[name]; - - if (!Interface.plugins.hasOwnProperty(name)) { - throw new Error('Unable to find "' + name + '" plugin'); - } - - plugins.requested[name] = true; - plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]); - plugins.names.push(name); - }; - - /** - * Initializes a plugin. - * - * @param {string} name - */ - Interface.prototype.require = function(name) { - var self = this; - var plugins = self.plugins; - - if (!self.plugins.loaded.hasOwnProperty(name)) { - if (plugins.requested[name]) { - throw new Error('Plugin has circular dependency ("' + name + '")'); - } - self.loadPlugin(name); - } - - return plugins.loaded[name]; - }; - - /** - * Registers a plugin. - * - * @param {string} name - * @param {function} fn - */ - Interface.define = function(name, fn) { - Interface.plugins[name] = { - 'name' : name, - 'fn' : fn - }; - }; - }; - - var utils = { - isArray: Array.isArray || function(vArg) { - return Object.prototype.toString.call(vArg) === '[object Array]'; - } - }; - - return MicroPlugin; -})); - -/** - * selectize.js (v0.9.1) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -/*jshint curly:false */ -/*jshint browser:true */ - -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define('selectize', ['jquery','sifter','microplugin'], factory); - } else if (typeof exports === 'object') { - module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); - } else { - root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); - } -}(this, function($, Sifter, MicroPlugin) { - 'use strict'; - - var highlight = function($element, pattern) { - if (typeof pattern === 'string' && !pattern.length) return; - var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern; - - var highlight = function(node) { - var skip = 0; - if (node.nodeType === 3) { - var pos = node.data.search(regex); - if (pos >= 0 && node.data.length > 0) { - var match = node.data.match(regex); - var spannode = document.createElement('span'); - spannode.className = 'highlight'; - var middlebit = node.splitText(pos); - var endbit = middlebit.splitText(match[0].length); - var middleclone = middlebit.cloneNode(true); - spannode.appendChild(middleclone); - middlebit.parentNode.replaceChild(spannode, middlebit); - skip = 1; - } - } else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { - for (var i = 0; i < node.childNodes.length; ++i) { - i += highlight(node.childNodes[i]); - } - } - return skip; - }; - - return $element.each(function() { - highlight(this); - }); - }; - - var MicroEvent = function() {}; - MicroEvent.prototype = { - on: function(event, fct){ - this._events = this._events || {}; - this._events[event] = this._events[event] || []; - this._events[event].push(fct); - }, - off: function(event, fct){ - var n = arguments.length; - if (n === 0) return delete this._events; - if (n === 1) return delete this._events[event]; - - this._events = this._events || {}; - if (event in this._events === false) return; - this._events[event].splice(this._events[event].indexOf(fct), 1); - }, - trigger: function(event /* , args... */){ - this._events = this._events || {}; - if (event in this._events === false) return; - for (var i = 0; i < this._events[event].length; i++){ - this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); - } - } - }; - - /** - * Mixin will delegate all MicroEvent.js function in the destination object. - * - * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent - * - * @param {object} the object which will support MicroEvent - */ - MicroEvent.mixin = function(destObject){ - var props = ['on', 'off', 'trigger']; - for (var i = 0; i < props.length; i++){ - destObject.prototype[props[i]] = MicroEvent.prototype[props[i]]; - } - }; - - var IS_MAC = /Mac/.test(navigator.userAgent); - - var KEY_A = 65; - var KEY_COMMA = 188; - var KEY_RETURN = 13; - var KEY_ESC = 27; - var KEY_LEFT = 37; - var KEY_UP = 38; - var KEY_P = 80; - var KEY_RIGHT = 39; - var KEY_DOWN = 40; - var KEY_N = 78; - var KEY_BACKSPACE = 8; - var KEY_DELETE = 46; - var KEY_SHIFT = 16; - var KEY_CMD = IS_MAC ? 91 : 17; - var KEY_CTRL = IS_MAC ? 18 : 17; - var KEY_TAB = 9; - - var TAG_SELECT = 1; - var TAG_INPUT = 2; - - - var isset = function(object) { - return typeof object !== 'undefined'; - }; - - /** - * Converts a scalar to its best string representation - * for hash keys and HTML attribute values. - * - * Transformations: - * 'str' -> 'str' - * null -> '' - * undefined -> '' - * true -> '1' - * false -> '0' - * 0 -> '0' - * 1 -> '1' - * - * @param {string} value - * @returns {string} - */ - var hash_key = function(value) { - if (typeof value === 'undefined' || value === null) return ''; - if (typeof value === 'boolean') return value ? '1' : '0'; - return value + ''; - }; - - /** - * Escapes a string for use within HTML. - * - * @param {string} str - * @returns {string} - */ - var escape_html = function(str) { - return (str + '') - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - - /** - * Escapes "$" characters in replacement strings. - * - * @param {string} str - * @returns {string} - */ - var escape_replace = function(str) { - return (str + '').replace(/\$/g, '$$$$'); - }; - - var hook = {}; - - /** - * Wraps `method` on `self` so that `fn` - * is invoked before the original method. - * - * @param {object} self - * @param {string} method - * @param {function} fn - */ - hook.before = function(self, method, fn) { - var original = self[method]; - self[method] = function() { - fn.apply(self, arguments); - return original.apply(self, arguments); - }; - }; - - /** - * Wraps `method` on `self` so that `fn` - * is invoked after the original method. - * - * @param {object} self - * @param {string} method - * @param {function} fn - */ - hook.after = function(self, method, fn) { - var original = self[method]; - self[method] = function() { - var result = original.apply(self, arguments); - fn.apply(self, arguments); - return result; - }; - }; - - /** - * Builds a hash table out of an array of - * objects, using the specified `key` within - * each object. - * - * @param {string} key - * @param {mixed} objects - */ - var build_hash_table = function(key, objects) { - if (!$.isArray(objects)) return objects; - var i, n, table = {}; - for (i = 0, n = objects.length; i < n; i++) { - if (objects[i].hasOwnProperty(key)) { - table[objects[i][key]] = objects[i]; - } - } - return table; - }; - - /** - * Wraps `fn` so that it can only be invoked once. - * - * @param {function} fn - * @returns {function} - */ - var once = function(fn) { - var called = false; - return function() { - if (called) return; - called = true; - fn.apply(this, arguments); - }; - }; - - /** - * Wraps `fn` so that it can only be called once - * every `delay` milliseconds (invoked on the falling edge). - * - * @param {function} fn - * @param {int} delay - * @returns {function} - */ - var debounce = function(fn, delay) { - var timeout; - return function() { - var self = this; - var args = arguments; - window.clearTimeout(timeout); - timeout = window.setTimeout(function() { - fn.apply(self, args); - }, delay); - }; - }; - - /** - * Debounce all fired events types listed in `types` - * while executing the provided `fn`. - * - * @param {object} self - * @param {array} types - * @param {function} fn - */ - var debounce_events = function(self, types, fn) { - var type; - var trigger = self.trigger; - var event_args = {}; - - // override trigger method - self.trigger = function() { - var type = arguments[0]; - if (types.indexOf(type) !== -1) { - event_args[type] = arguments; - } else { - return trigger.apply(self, arguments); - } - }; - - // invoke provided function - fn.apply(self, []); - self.trigger = trigger; - - // trigger queued events - for (type in event_args) { - if (event_args.hasOwnProperty(type)) { - trigger.apply(self, event_args[type]); - } - } - }; - - /** - * A workaround for http://bugs.jquery.com/ticket/6696 - * - * @param {object} $parent - Parent element to listen on. - * @param {string} event - Event name. - * @param {string} selector - Descendant selector to filter by. - * @param {function} fn - Event handler. - */ - var watchChildEvent = function($parent, event, selector, fn) { - $parent.on(event, selector, function(e) { - var child = e.target; - while (child && child.parentNode !== $parent[0]) { - child = child.parentNode; - } - e.currentTarget = child; - return fn.apply(this, [e]); - }); - }; - - /** - * Determines the current selection within a text input control. - * Returns an object containing: - * - start - * - length - * - * @param {object} input - * @returns {object} - */ - var getSelection = function(input) { - var result = {}; - if ('selectionStart' in input) { - result.start = input.selectionStart; - result.length = input.selectionEnd - result.start; - } else if (document.selection) { - input.focus(); - var sel = document.selection.createRange(); - var selLen = document.selection.createRange().text.length; - sel.moveStart('character', -input.value.length); - result.start = sel.text.length - selLen; - result.length = selLen; - } - return result; - }; - - /** - * Copies CSS properties from one element to another. - * - * @param {object} $from - * @param {object} $to - * @param {array} properties - */ - var transferStyles = function($from, $to, properties) { - var i, n, styles = {}; - if (properties) { - for (i = 0, n = properties.length; i < n; i++) { - styles[properties[i]] = $from.css(properties[i]); - } - } else { - styles = $from.css(); - } - $to.css(styles); - }; - - /** - * Measures the width of a string within a - * parent element (in pixels). - * - * @param {string} str - * @param {object} $parent - * @returns {int} - */ - var measureString = function(str, $parent) { - if (!str) { - return 0; - } - - var $test = $('').css({ - position: 'absolute', - top: -99999, - left: -99999, - width: 'auto', - padding: 0, - whiteSpace: 'pre' - }).text(str).appendTo('body'); - - transferStyles($parent, $test, [ - 'letterSpacing', - 'fontSize', - 'fontFamily', - 'fontWeight', - 'textTransform' - ]); - - var width = $test.width(); - $test.remove(); - - return width; - }; - - /** - * Sets up an input to grow horizontally as the user - * types. If the value is changed manually, you can - * trigger the "update" handler to resize: - * - * $input.trigger('update'); - * - * @param {object} $input - */ - var autoGrow = function($input) { - var currentWidth = null; - - var update = function(e, options) { - var value, keyCode, printable, placeholder, width; - var shift, character, selection; - e = e || window.event || {}; - options = options || {}; - - if (e.metaKey || e.altKey) return; - if (!options.force && $input.data('grow') === false) return; - - value = $input.val(); - if (e.type && e.type.toLowerCase() === 'keydown') { - keyCode = e.keyCode; - printable = ( - (keyCode >= 97 && keyCode <= 122) || // a-z - (keyCode >= 65 && keyCode <= 90) || // A-Z - (keyCode >= 48 && keyCode <= 57) || // 0-9 - keyCode === 32 // space - ); - - if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) { - selection = getSelection($input[0]); - if (selection.length) { - value = value.substring(0, selection.start) + value.substring(selection.start + selection.length); - } else if (keyCode === KEY_BACKSPACE && selection.start) { - value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1); - } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') { - value = value.substring(0, selection.start) + value.substring(selection.start + 1); - } - } else if (printable) { - shift = e.shiftKey; - character = String.fromCharCode(e.keyCode); - if (shift) character = character.toUpperCase(); - else character = character.toLowerCase(); - value += character; - } - } - - placeholder = $input.attr('placeholder'); - if (!value && placeholder) { - value = placeholder; - } - - width = measureString(value, $input) + 4; - if (width !== currentWidth) { - currentWidth = width; - $input.width(width); - $input.triggerHandler('resize'); - } - }; - - $input.on('keydown keyup update blur', update); - update(); - }; - - var Selectize = function($input, settings) { - var key, i, n, dir, input, self = this; - input = $input[0]; - input.selectize = self; - - // detect rtl environment - dir = window.getComputedStyle ? window.getComputedStyle(input, null).getPropertyValue('direction') : input.currentStyle && input.currentStyle.direction; - dir = dir || $input.parents('[dir]:first').attr('dir') || ''; - - // setup default state - $.extend(self, { - settings : settings, - $input : $input, - tagType : input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT, - rtl : /rtl/i.test(dir), - - eventNS : '.selectize' + (++Selectize.count), - highlightedValue : null, - isOpen : false, - isDisabled : false, - isRequired : $input.is('[required]'), - isInvalid : false, - isLocked : false, - isFocused : false, - isInputHidden : false, - isSetup : false, - isShiftDown : false, - isCmdDown : false, - isCtrlDown : false, - ignoreFocus : false, - ignoreHover : false, - hasOptions : false, - currentResults : null, - lastValue : '', - caretPos : 0, - loading : 0, - loadedSearches : {}, - - $activeOption : null, - $activeItems : [], - - optgroups : {}, - options : {}, - userOptions : {}, - items : [], - renderCache : {}, - onSearchChange : settings.loadThrottle === null ? self.onSearchChange : debounce(self.onSearchChange, settings.loadThrottle) - }); - - // search system - self.sifter = new Sifter(this.options, {diacritics: settings.diacritics}); - - // build options table - $.extend(self.options, build_hash_table(settings.valueField, settings.options)); - delete self.settings.options; - - // build optgroup table - $.extend(self.optgroups, build_hash_table(settings.optgroupValueField, settings.optgroups)); - delete self.settings.optgroups; - - // option-dependent defaults - self.settings.mode = self.settings.mode || (self.settings.maxItems === 1 ? 'single' : 'multi'); - if (typeof self.settings.hideSelected !== 'boolean') { - self.settings.hideSelected = self.settings.mode === 'multi'; - } - - self.initializePlugins(self.settings.plugins); - self.setupCallbacks(); - self.setupTemplates(); - self.setup(); - }; - - // mixins - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MicroEvent.mixin(Selectize); - MicroPlugin.mixin(Selectize); - - // methods - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $.extend(Selectize.prototype, { - - /** - * Creates all elements and sets up event bindings. - */ - setup: function() { - var self = this; - var settings = self.settings; - var eventNS = self.eventNS; - var $window = $(window); - var $document = $(document); - - var $wrapper; - var $control; - var $control_input; - var $dropdown; - var $dropdown_content; - var $dropdown_parent; - var inputMode; - var timeout_blur; - var timeout_focus; - var tab_index; - var classes; - var classes_plugins; - - inputMode = self.settings.mode; - tab_index = self.$input.attr('tabindex') || ''; - classes = self.$input.attr('class') || ''; - - $wrapper = $('
').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode); - $control = $('
').addClass(settings.inputClass).addClass('items').appendTo($wrapper); - $control_input = $('').appendTo($control).attr('tabindex', tab_index); - $dropdown_parent = $(settings.dropdownParent || $wrapper); - $dropdown = $('
').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent); - $dropdown_content = $('
').addClass(settings.dropdownContentClass).appendTo($dropdown); - - $wrapper.css({ - width: self.$input[0].style.width - }); - - if (self.plugins.names.length) { - classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-'); - $wrapper.addClass(classes_plugins); - $dropdown.addClass(classes_plugins); - } - - if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) { - self.$input.attr('multiple', 'multiple'); - } - - if (self.settings.placeholder) { - $control_input.attr('placeholder', settings.placeholder); - } - - if (self.$input.attr('autocorrect')) { - $control_input.attr('autocorrect', self.$input.attr('autocorrect')); - } - - if (self.$input.attr('autocapitalize')) { - $control_input.attr('autocapitalize', self.$input.attr('autocapitalize')); - } - - self.$wrapper = $wrapper; - self.$control = $control; - self.$control_input = $control_input; - self.$dropdown = $dropdown; - self.$dropdown_content = $dropdown_content; - - $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); }); - $dropdown.on('mousedown', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); }); - watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); }); - autoGrow($control_input); - - $control.on({ - mousedown : function() { return self.onMouseDown.apply(self, arguments); }, - click : function() { return self.onClick.apply(self, arguments); } - }); - - $control_input.on({ - mousedown : function(e) { e.stopPropagation(); }, - keydown : function() { return self.onKeyDown.apply(self, arguments); }, - keyup : function() { return self.onKeyUp.apply(self, arguments); }, - keypress : function() { return self.onKeyPress.apply(self, arguments); }, - resize : function() { self.positionDropdown.apply(self, []); }, - blur : function() { return self.onBlur.apply(self, arguments); }, - focus : function() { return self.onFocus.apply(self, arguments); }, - paste : function() { return self.onPaste.apply(self, arguments); } - }); - - $document.on('keydown' + eventNS, function(e) { - self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey']; - self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey']; - self.isShiftDown = e.shiftKey; - }); - - $document.on('keyup' + eventNS, function(e) { - if (e.keyCode === KEY_CTRL) self.isCtrlDown = false; - if (e.keyCode === KEY_SHIFT) self.isShiftDown = false; - if (e.keyCode === KEY_CMD) self.isCmdDown = false; - }); - - $document.on('mousedown' + eventNS, function(e) { - if (self.isFocused) { - // prevent events on the dropdown scrollbar from causing the control to blur - if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) { - return false; - } - // blur on click outside - if (!self.$control.has(e.target).length && e.target !== self.$control[0]) { - self.blur(); - } - } - }); - - $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() { - if (self.isOpen) { - self.positionDropdown.apply(self, arguments); - } - }); - $window.on('mousemove' + eventNS, function() { - self.ignoreHover = false; - }); - - // store original children and tab index so that they can be - // restored when the destroy() method is called. - this.revertSettings = { - $children : self.$input.children().detach(), - tabindex : self.$input.attr('tabindex') - }; - - self.$input.attr('tabindex', -1).hide().after(self.$wrapper); - - if ($.isArray(settings.items)) { - self.setValue(settings.items); - delete settings.items; - } - - // feature detect for the validation API - if (self.$input[0].validity) { - self.$input.on('invalid' + eventNS, function(e) { - e.preventDefault(); - self.isInvalid = true; - self.refreshState(); - }); - } - - self.updateOriginalInput(); - self.refreshItems(); - self.refreshState(); - self.updatePlaceholder(); - self.isSetup = true; - - if (self.$input.is(':disabled')) { - self.disable(); - } - - self.on('change', this.onChange); - self.trigger('initialize'); - - // preload options - if (settings.preload === true) { - self.onSearchChange(''); - } - }, - - /** - * Sets up default rendering functions. - */ - setupTemplates: function() { - var self = this; - var field_label = self.settings.labelField; - var field_optgroup = self.settings.optgroupLabelField; - - var templates = { - 'optgroup': function(data) { - return '
' + data.html + '
'; - }, - 'optgroup_header': function(data, escape) { - return '
' + escape(data[field_optgroup]) + '
'; - }, - 'option': function(data, escape) { - return '
' + escape(data[field_label]) + '
'; - }, - 'item': function(data, escape) { - return '
' + escape(data[field_label]) + '
'; - }, - 'option_create': function(data, escape) { - return '
Add ' + escape(data.input) + '
'; - } - }; - - self.settings.render = $.extend({}, templates, self.settings.render); - }, - - /** - * Maps fired events to callbacks provided - * in the settings used when creating the control. - */ - setupCallbacks: function() { - var key, fn, callbacks = { - 'initialize' : 'onInitialize', - 'change' : 'onChange', - 'item_add' : 'onItemAdd', - 'item_remove' : 'onItemRemove', - 'clear' : 'onClear', - 'option_add' : 'onOptionAdd', - 'option_remove' : 'onOptionRemove', - 'option_clear' : 'onOptionClear', - 'dropdown_open' : 'onDropdownOpen', - 'dropdown_close' : 'onDropdownClose', - 'type' : 'onType' - }; - - for (key in callbacks) { - if (callbacks.hasOwnProperty(key)) { - fn = this.settings[callbacks[key]]; - if (fn) this.on(key, fn); - } - } - }, - - /** - * Triggered when the main control element - * has a click event. - * - * @param {object} e - * @return {boolean} - */ - onClick: function(e) { - var self = this; - - // necessary for mobile webkit devices (manual focus triggering - // is ignored unless invoked within a click event) - if (!self.isFocused) { - self.focus(); - e.preventDefault(); - } - }, - - /** - * Triggered when the main control element - * has a mouse down event. - * - * @param {object} e - * @return {boolean} - */ - onMouseDown: function(e) { - var self = this; - var defaultPrevented = e.isDefaultPrevented(); - var $target = $(e.target); - - if (self.isFocused) { - // retain focus by preventing native handling. if the - // event target is the input it should not be modified. - // otherwise, text selection within the input won't work. - if (e.target !== self.$control_input[0]) { - if (self.settings.mode === 'single') { - // toggle dropdown - self.isOpen ? self.close() : self.open(); - } else if (!defaultPrevented) { - self.setActiveItem(null); - } - return false; - } - } else { - // give control focus - if (!defaultPrevented) { - window.setTimeout(function() { - self.focus(); - }, 0); - } - } - }, - - /** - * Triggered when the value of the control has been changed. - * This should propagate the event to the original DOM - * input / select element. - */ - onChange: function() { - this.$input.trigger('change'); - }, - - - /** - * Triggered on paste. - * - * @param {object} e - * @returns {boolean} - */ - onPaste: function(e) { - var self = this; - if (self.isFull() || self.isInputHidden || self.isLocked) { - e.preventDefault(); - } else { - // If a regex or string is included, this will split the pasted input and create Items for each separate value - if (self.settings.splitOn) { - setTimeout($.proxy(function() { - var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); - splitInput.forEach($.proxy(function(input) { - self.createItem(input); - }, self)); - }, self), 0); - } - } - }, - - /** - * Triggered on keypress. - * - * @param {object} e - * @returns {boolean} - */ - onKeyPress: function(e) { - if (this.isLocked) return e && e.preventDefault(); - var character = String.fromCharCode(e.keyCode || e.which); - if (this.settings.create && character === this.settings.delimiter) { - this.createItem(); - e.preventDefault(); - return false; - } - }, - - /** - * Triggered on keydown. - * - * @param {object} e - * @returns {boolean} - */ - onKeyDown: function(e) { - var isInput = e.target === this.$control_input[0]; - var self = this; - - if (self.isLocked) { - if (e.keyCode !== KEY_TAB) { - e.preventDefault(); - } - return; - } - - switch (e.keyCode) { - case KEY_A: - if (self.isCmdDown) { - self.selectAll(); - return; - } - break; - case KEY_ESC: - self.close(); - return; - case KEY_N: - if (!e.ctrlKey || e.altKey) break; - case KEY_DOWN: - if (!self.isOpen && self.hasOptions) { - self.open(); - } else if (self.$activeOption) { - self.ignoreHover = true; - var $next = self.getAdjacentOption(self.$activeOption, 1); - if ($next.length) self.setActiveOption($next, true, true); - } - e.preventDefault(); - return; - case KEY_P: - if (!e.ctrlKey || e.altKey) break; - case KEY_UP: - if (self.$activeOption) { - self.ignoreHover = true; - var $prev = self.getAdjacentOption(self.$activeOption, -1); - if ($prev.length) self.setActiveOption($prev, true, true); - } - e.preventDefault(); - return; - case KEY_RETURN: - if (self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - e.preventDefault(); - return; - case KEY_LEFT: - self.advanceSelection(-1, e); - return; - case KEY_RIGHT: - self.advanceSelection(1, e); - return; - case KEY_TAB: - if (self.settings.selectOnTab && self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - if (self.settings.create && self.createItem()) { - e.preventDefault(); - } - return; - case KEY_BACKSPACE: - case KEY_DELETE: - self.deleteSelection(e); - return; - } - - if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) { - e.preventDefault(); - return; - } - }, - - /** - * Triggered on keyup. - * - * @param {object} e - * @returns {boolean} - */ - onKeyUp: function(e) { - var self = this; - - if (self.isLocked) return e && e.preventDefault(); - var value = self.$control_input.val() || ''; - if (self.lastValue !== value) { - self.lastValue = value; - self.onSearchChange(value); - self.refreshOptions(); - self.trigger('type', value); - } - }, - - /** - * Invokes the user-provide option provider / loader. - * - * Note: this function is debounced in the Selectize - * constructor (by `settings.loadDelay` milliseconds) - * - * @param {string} value - */ - onSearchChange: function(value) { - var self = this; - var fn = self.settings.load; - if (!fn) return; - if (self.loadedSearches.hasOwnProperty(value)) return; - self.loadedSearches[value] = true; - self.load(function(callback) { - fn.apply(self, [value, callback]); - }); - }, - - /** - * Triggered on focus. - * - * @param {object} e (optional) - * @returns {boolean} - */ - onFocus: function(e) { - var self = this; - - self.isFocused = true; - if (self.isDisabled) { - self.blur(); - e && e.preventDefault(); - return false; - } - - if (self.ignoreFocus) return; - if (self.settings.preload === 'focus') self.onSearchChange(''); - - if (!self.$activeItems.length) { - self.showInput(); - self.setActiveItem(null); - self.refreshOptions(!!self.settings.openOnFocus); - } - - self.refreshState(); - }, - - /** - * Triggered on blur. - * - * @param {object} e - * @returns {boolean} - */ - onBlur: function(e) { - var self = this; - self.isFocused = false; - if (self.ignoreFocus) return; - - if (self.settings.create && self.settings.createOnBlur) { - self.createItem(false); - } - - self.close(); - self.setTextboxValue(''); - self.setActiveItem(null); - self.setActiveOption(null); - self.setCaret(self.items.length); - self.refreshState(); - }, - - /** - * Triggered when the user rolls over - * an option in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionHover: function(e) { - if (this.ignoreHover) return; - this.setActiveOption(e.currentTarget, false); - }, - - /** - * Triggered when the user clicks on an option - * in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionSelect: function(e) { - var value, $target, $option, self = this; - - if (e.preventDefault) { - e.preventDefault(); - e.stopPropagation(); - } - - $target = $(e.currentTarget); - if ($target.hasClass('create')) { - self.createItem(); - } else { - value = $target.attr('data-value'); - if (value) { - self.lastQuery = null; - self.setTextboxValue(''); - self.addItem(value); - if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) { - self.setActiveOption(self.getOption(value)); - } - } - } - }, - - /** - * Triggered when the user clicks on an item - * that has been selected. - * - * @param {object} e - * @returns {boolean} - */ - onItemSelect: function(e) { - var self = this; - - if (self.isLocked) return; - if (self.settings.mode === 'multi') { - e.preventDefault(); - self.setActiveItem(e.currentTarget, e); - } - }, - - /** - * Invokes the provided method that provides - * results to a callback---which are then added - * as options to the control. - * - * @param {function} fn - */ - load: function(fn) { - var self = this; - var $wrapper = self.$wrapper.addClass('loading'); - - self.loading++; - fn.apply(self, [function(results) { - self.loading = Math.max(self.loading - 1, 0); - if (results && results.length) { - self.addOption(results); - self.refreshOptions(self.isFocused && !self.isInputHidden); - } - if (!self.loading) { - $wrapper.removeClass('loading'); - } - self.trigger('load', results); - }]); - }, - - /** - * Sets the input field of the control to the specified value. - * - * @param {string} value - */ - setTextboxValue: function(value) { - var $input = this.$control_input; - var changed = $input.val() !== value; - if (changed) { - $input.val(value).triggerHandler('update'); - this.lastValue = value; - } - }, - - /** - * Returns the value of the control. If multiple items - * can be selected (e.g. or - * element to reflect the current state. - */ - updateOriginalInput: function() { - var i, n, options, self = this; - - if (self.$input[0].tagName.toLowerCase() === 'select') { - options = []; - for (i = 0, n = self.items.length; i < n; i++) { - options.push(''); - } - if (!options.length && !this.$input.attr('multiple')) { - options.push(''); - } - self.$input.html(options.join('')); - } else { - self.$input.val(self.getValue()); - } - - if (self.isSetup) { - self.trigger('change', self.$input.val()); - } - }, - - /** - * Shows/hide the input placeholder depending - * on if there items in the list already. - */ - updatePlaceholder: function() { - if (!this.settings.placeholder) return; - var $input = this.$control_input; - - if (this.items.length) { - $input.removeAttr('placeholder'); - } else { - $input.attr('placeholder', this.settings.placeholder); - } - $input.triggerHandler('update', {force: true}); - }, - - /** - * Shows the autocomplete dropdown containing - * the available options. - */ - open: function() { - var self = this; - - if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return; - self.focus(); - self.isOpen = true; - self.refreshState(); - self.$dropdown.css({visibility: 'hidden', display: 'block'}); - self.positionDropdown(); - self.$dropdown.css({visibility: 'visible'}); - self.trigger('dropdown_open', self.$dropdown); - }, - - /** - * Closes the autocomplete dropdown menu. - */ - close: function() { - var self = this; - var trigger = self.isOpen; - - if (self.settings.mode === 'single' && self.items.length) { - self.hideInput(); - } - - self.isOpen = false; - self.$dropdown.hide(); - self.setActiveOption(null); - self.refreshState(); - - if (trigger) self.trigger('dropdown_close', self.$dropdown); - }, - - /** - * Calculates and applies the appropriate - * position of the dropdown. - */ - positionDropdown: function() { - var $control = this.$control; - var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); - offset.top += $control.outerHeight(true); - - this.$dropdown.css({ - width : $control.outerWidth(), - top : offset.top, - left : offset.left - }); - }, - - /** - * Resets / clears all selected items - * from the control. - */ - clear: function() { - var self = this; - - if (!self.items.length) return; - self.$control.children(':not(input)').remove(); - self.items = []; - self.setCaret(0); - self.updatePlaceholder(); - self.updateOriginalInput(); - self.refreshState(); - self.showInput(); - self.trigger('clear'); - }, - - /** - * A helper method for inserting an element - * at the current caret position. - * - * @param {object} $el - */ - insertAtCaret: function($el) { - var caret = Math.min(this.caretPos, this.items.length); - if (caret === 0) { - this.$control.prepend($el); - } else { - $(this.$control[0].childNodes[caret]).before($el); - } - this.setCaret(caret + 1); - }, - - /** - * Removes the current selected item(s). - * - * @param {object} e (optional) - * @returns {boolean} - */ - deleteSelection: function(e) { - var i, n, direction, selection, values, caret, option_select, $option_select, $tail; - var self = this; - - direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1; - selection = getSelection(self.$control_input[0]); - - if (self.$activeOption && !self.settings.hideSelected) { - option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value'); - } - - // determine items that will be removed - values = []; - - if (self.$activeItems.length) { - $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first')); - caret = self.$control.children(':not(input)').index($tail); - if (direction > 0) { caret++; } - - for (i = 0, n = self.$activeItems.length; i < n; i++) { - values.push($(self.$activeItems[i]).attr('data-value')); - } - if (e) { - e.preventDefault(); - e.stopPropagation(); - } - } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) { - if (direction < 0 && selection.start === 0 && selection.length === 0) { - values.push(self.items[self.caretPos - 1]); - } else if (direction > 0 && selection.start === self.$control_input.val().length) { - values.push(self.items[self.caretPos]); - } - } - - // allow the callback to abort - if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) { - return false; - } - - // perform removal - if (typeof caret !== 'undefined') { - self.setCaret(caret); - } - while (values.length) { - self.removeItem(values.pop()); - } - - self.showInput(); - self.positionDropdown(); - self.refreshOptions(true); - - // select previous option - if (option_select) { - $option_select = self.getOption(option_select); - if ($option_select.length) { - self.setActiveOption($option_select); - } - } - - return true; - }, - - /** - * Selects the previous / next item (depending - * on the `direction` argument). - * - * > 0 - right - * < 0 - left - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceSelection: function(direction, e) { - var tail, selection, idx, valueLength, cursorAtEdge, $tail; - var self = this; - - if (direction === 0) return; - if (self.rtl) direction *= -1; - - tail = direction > 0 ? 'last' : 'first'; - selection = getSelection(self.$control_input[0]); - - if (self.isFocused && !self.isInputHidden) { - valueLength = self.$control_input.val().length; - cursorAtEdge = direction < 0 - ? selection.start === 0 && selection.length === 0 - : selection.start === valueLength; - - if (cursorAtEdge && !valueLength) { - self.advanceCaret(direction, e); - } - } else { - $tail = self.$control.children('.active:' + tail); - if ($tail.length) { - idx = self.$control.children(':not(input)').index($tail); - self.setActiveItem(null); - self.setCaret(direction > 0 ? idx + 1 : idx); - } - } - }, - - /** - * Moves the caret left / right. - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceCaret: function(direction, e) { - var self = this, fn, $adj; - - if (direction === 0) return; - - fn = direction > 0 ? 'next' : 'prev'; - if (self.isShiftDown) { - $adj = self.$control_input[fn](); - if ($adj.length) { - self.hideInput(); - self.setActiveItem($adj); - e && e.preventDefault(); - } - } else { - self.setCaret(self.caretPos + direction); - } - }, - - /** - * Moves the caret to the specified index. - * - * @param {int} i - */ - setCaret: function(i) { - var self = this; - - if (self.settings.mode === 'single') { - i = self.items.length; - } else { - i = Math.max(0, Math.min(self.items.length, i)); - } - - // the input must be moved by leaving it in place and moving the - // siblings, due to the fact that focus cannot be restored once lost - // on mobile webkit devices - var j, n, fn, $children, $child; - $children = self.$control.children(':not(input)'); - for (j = 0, n = $children.length; j < n; j++) { - $child = $($children[j]).detach(); - if (j < i) { - self.$control_input.before($child); - } else { - self.$control.append($child); - } - } - - self.caretPos = i; - }, - - /** - * Disables user input on the control. Used while - * items are being asynchronously created. - */ - lock: function() { - this.close(); - this.isLocked = true; - this.refreshState(); - }, - - /** - * Re-enables user input on the control. - */ - unlock: function() { - this.isLocked = false; - this.refreshState(); - }, - - /** - * Disables user input on the control completely. - * While disabled, it cannot receive focus. - */ - disable: function() { - var self = this; - self.$input.prop('disabled', true); - self.isDisabled = true; - self.lock(); - }, - - /** - * Enables the control so that it can respond - * to focus and user input. - */ - enable: function() { - var self = this; - self.$input.prop('disabled', false); - self.isDisabled = false; - self.unlock(); - }, - - /** - * Completely destroys the control and - * unbinds all event listeners so that it can - * be garbage collected. - */ - destroy: function() { - var self = this; - var eventNS = self.eventNS; - var revertSettings = self.revertSettings; - - self.trigger('destroy'); - self.off(); - self.$wrapper.remove(); - self.$dropdown.remove(); - - self.$input - .html('') - .append(revertSettings.$children) - .removeAttr('tabindex') - .attr({tabindex: revertSettings.tabindex}) - .show(); - - $(window).off(eventNS); - $(document).off(eventNS); - $(document.body).off(eventNS); - - delete self.$input[0].selectize; - }, - - /** - * A helper method for rendering "item" and - * "option" templates, given the data. - * - * @param {string} templateName - * @param {object} data - * @returns {string} - */ - render: function(templateName, data) { - var value, id, label; - var html = ''; - var cache = false; - var self = this; - var regex_tag = /^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; - - if (templateName === 'option' || templateName === 'item') { - value = hash_key(data[self.settings.valueField]); - cache = !!value; - } - - // pull markup from cache if it exists - if (cache) { - if (!isset(self.renderCache[templateName])) { - self.renderCache[templateName] = {}; - } - if (self.renderCache[templateName].hasOwnProperty(value)) { - return self.renderCache[templateName][value]; - } - } - - // render markup - html = self.settings.render[templateName].apply(this, [data, escape_html]); - - // add mandatory attributes - if (templateName === 'option' || templateName === 'option_create') { - html = html.replace(regex_tag, '<$1 data-selectable'); - } - if (templateName === 'optgroup') { - id = data[self.settings.optgroupValueField] || ''; - html = html.replace(regex_tag, '<$1 data-group="' + escape_replace(escape_html(id)) + '"'); - } - if (templateName === 'option' || templateName === 'item') { - html = html.replace(regex_tag, '<$1 data-value="' + escape_replace(escape_html(value || '')) + '"'); - } - - // update cache - if (cache) { - self.renderCache[templateName][value] = html; - } - - return html; - } - - }); - - - Selectize.count = 0; - Selectize.defaults = { - plugins: [], - delimiter: ',', - splitOn: /[,]+/, // Regex or string for splitting up values from a paste command - persist: true, - diacritics: true, - create: false, - createOnBlur: false, - highlight: true, - openOnFocus: true, - maxOptions: 1000, - maxItems: null, - hideSelected: null, - addPrecedence: false, - selectOnTab: false, - preload: false, - - scrollDuration: 60, - loadThrottle: 300, - - dataAttr: 'data-data', - optgroupField: 'optgroup', - valueField: 'value', - labelField: 'text', - optgroupLabelField: 'label', - optgroupValueField: 'value', - optgroupOrder: null, - - sortField: '$order', - searchField: ['text'], - searchConjunction: 'and', - - mode: null, - wrapperClass: 'selectize-control', - inputClass: 'selectize-input', - dropdownClass: 'selectize-dropdown', - dropdownContentClass: 'selectize-dropdown-content', - - dropdownParent: null, - - /* - load : null, // function(query, callback) { ... } - score : null, // function(search) { ... } - onInitialize : null, // function() { ... } - onChange : null, // function(value) { ... } - onItemAdd : null, // function(value, $item) { ... } - onItemRemove : null, // function(value) { ... } - onClear : null, // function() { ... } - onOptionAdd : null, // function(value, data) { ... } - onOptionRemove : null, // function(value) { ... } - onOptionClear : null, // function() { ... } - onDropdownOpen : null, // function($dropdown) { ... } - onDropdownClose : null, // function($dropdown) { ... } - onType : null, // function(str) { ... } - onDelete : null, // function(values) { ... } - */ - - render: { - /* - item: null, - optgroup: null, - optgroup_header: null, - option: null, - option_create: null - */ - } - }; - - $.fn.selectize = function(settings_user) { - var defaults = $.fn.selectize.defaults; - var settings = $.extend({}, defaults, settings_user); - var attr_data = settings.dataAttr; - var field_label = settings.labelField; - var field_value = settings.valueField; - var field_optgroup = settings.optgroupField; - var field_optgroup_label = settings.optgroupLabelField; - var field_optgroup_value = settings.optgroupValueField; - - /** - * Initializes selectize from a element. - * - * @param {object} $input - * @param {object} settings_element - */ - var init_textbox = function($input, settings_element) { - var i, n, values, option, value = $.trim($input.val() || ''); - if (!value.length) return; - - values = value.split(settings.delimiter); - for (i = 0, n = values.length; i < n; i++) { - option = {}; - option[field_label] = values[i]; - option[field_value] = values[i]; - - settings_element.options[values[i]] = option; - } - - settings_element.items = values; - }; - - /** - * Initializes selectize from a ').appendTo(c).attr("tabindex",j),h=a(n.dropdownParent||b),e=a("
").addClass(n.dropdownClass).addClass(k).addClass(i).hide().appendTo(h),g=a("
").addClass(n.dropdownContentClass).appendTo(e),b.css({width:m.$input[0].style.width}),m.plugins.names.length&&(l="plugin-"+m.plugins.names.join(" plugin-"),b.addClass(l),e.addClass(l)),(null===n.maxItems||n.maxItems>1)&&m.tagType===v&&m.$input.attr("multiple","multiple"),m.settings.placeholder&&d.attr("placeholder",n.placeholder),m.$input.attr("autocorrect")&&d.attr("autocorrect",m.$input.attr("autocorrect")),m.$input.attr("autocapitalize")&&d.attr("autocapitalize",m.$input.attr("autocapitalize")),m.$wrapper=b,m.$control=c,m.$control_input=d,m.$dropdown=e,m.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return m.onOptionHover.apply(m,arguments)}),e.on("mousedown","[data-selectable]",function(){return m.onOptionSelect.apply(m,arguments)}),G(c,"mousedown","*:not(input)",function(){return m.onItemSelect.apply(m,arguments)}),K(d),c.on({mousedown:function(){return m.onMouseDown.apply(m,arguments)},click:function(){return m.onClick.apply(m,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return m.onKeyDown.apply(m,arguments)},keyup:function(){return m.onKeyUp.apply(m,arguments)},keypress:function(){return m.onKeyPress.apply(m,arguments)},resize:function(){m.positionDropdown.apply(m,[])},blur:function(){return m.onBlur.apply(m,arguments)},focus:function(){return m.onFocus.apply(m,arguments)},paste:function(){return m.onPaste.apply(m,arguments)}}),q.on("keydown"+o,function(a){m.isCmdDown=a[f?"metaKey":"ctrlKey"],m.isCtrlDown=a[f?"altKey":"ctrlKey"],m.isShiftDown=a.shiftKey}),q.on("keyup"+o,function(a){a.keyCode===t&&(m.isCtrlDown=!1),a.keyCode===r&&(m.isShiftDown=!1),a.keyCode===s&&(m.isCmdDown=!1)}),q.on("mousedown"+o,function(a){if(m.isFocused){if(a.target===m.$dropdown[0]||a.target.parentNode===m.$dropdown[0])return!1;m.$control.has(a.target).length||a.target===m.$control[0]||m.blur()}}),p.on(["scroll"+o,"resize"+o].join(" "),function(){m.isOpen&&m.positionDropdown.apply(m,arguments)}),p.on("mousemove"+o,function(){m.ignoreHover=!1}),this.revertSettings={$children:m.$input.children().detach(),tabindex:m.$input.attr("tabindex")},m.$input.attr("tabindex",-1).hide().after(m.$wrapper),a.isArray(n.items)&&(m.setValue(n.items),delete n.items),m.$input[0].validity&&m.$input.on("invalid"+o,function(a){a.preventDefault(),m.isInvalid=!0,m.refreshState()}),m.updateOriginalInput(),m.refreshItems(),m.refreshState(),m.updatePlaceholder(),m.isSetup=!0,m.$input.is(":disabled")&&m.disable(),m.on("change",this.onChange),m.trigger("initialize"),n.preload===!0&&m.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'
'+a.html+"
"},optgroup_header:function(a,b){return'
'+b(a[d])+"
"},option:function(a,b){return'
'+b(a[c])+"
"},item:function(a,b){return'
'+b(a[c])+"
"},option_create:function(a,b){return'
Add '+b(a.input)+"
"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(a.proxy(function(){var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn);b.forEach(a.proxy(function(a){c.createItem(a)},c))},c),0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void b.close();case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void a.preventDefault();case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&b.onOptionSelect({currentTarget:b.$activeOption}),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this;return b.isFocused=!0,b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||("focus"===b.settings.preload&&b.onSearchChange(""),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(){var a=this;a.isFocused=!1,a.ignoreFocus||(a.settings.create&&a.settings.createOnBlur&&a.createItem(!1),a.close(),a.setTextboxValue(""),a.setActiveItem(null),a.setActiveOption(null),a.setCaret(a.items.length),a.refreshState())},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem():(c=d.attr("data-value"),c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass("loading");b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass("loading"),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a){F(this,["change"],function(){this.clear(),this.addItems(a)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!x(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(){this.$control_input.trigger("blur")},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b={field:b}),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(y(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=t.$control_input.val(),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&y(t.$activeOption.attr("data-value"));if(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},t.settings.optgroupOrder)for(i=t.settings.optgroupOrder,c=0;cc;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.settings.create&&v.query.length,p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else e=y(b[f.settings.valueField]),e&&!f.options.hasOwnProperty(e)&&(f.userOptions[e]=!0,f.options[e]=b,f.lastQuery=null,f.trigger("option_add",e,b))},addOptionGroup:function(a,b){this.optgroups[a]=b,this.trigger("optgroup_add",a,b)},updateOption:function(b,c){var d,e,f,g,h,i,j=this;if(b=y(b),f=y(c[j.settings.valueField]),j.options.hasOwnProperty(b)){if(!f)throw new Error("Value must be set in option data");f!==b&&(delete j.options[b],g=j.items.indexOf(b),-1!==g&&j.items.splice(g,1,f)),j.options[f]=c,h=j.renderCache.item,i=j.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==j.items.indexOf(f)&&(d=j.getItem(b),e=a(j.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),j.isOpen&&j.refreshOptions(!1)}},removeOption:function(a){var b=this;a=y(a);var c=b.renderCache.item,d=b.renderCache.option;c&&delete c[a],d&&delete d[a],delete b.userOptions[a],delete b.options[a],b.lastQuery=null,b.trigger("option_remove",a),b.removeItem(a)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b){for(var c=a.isArray(b)?b:[b],d=0,e=c.length;e>d;d++)this.isPending=e-1>d,this.addItem(c[d])},addItem:function(b){F(this,["change"],function(){var c,d,e,f,g=this,h=g.settings.mode;return b=y(b),-1!==g.items.indexOf(b)?void("single"===h&&g.close()):void(g.options.hasOwnProperty(b)&&("single"===h&&g.clear(),"multi"===h&&g.isFull()||(c=a(g.render("item",g.options[b])),g.items.splice(g.caretPos,0,b),g.insertAtCaret(c),g.refreshState(),g.isSetup&&(e=g.$dropdown_content.find("[data-selectable]"),this.isPending||(d=g.getOption(b),f=g.getAdjacentOption(d,1).attr("data-value"),g.refreshOptions(g.isFocused&&"single"!==h),f&&g.setActiveOption(g.getOption(f))),!e.length||null!==g.settings.maxItems&&g.items.length>=g.settings.maxItems?g.close():g.positionDropdown(),g.updatePlaceholder(),g.trigger("item_add",b,c),g.updateOriginalInput()))))})},removeItem:function(a){var b,c,d,e=this;b="object"==typeof a?a:e.getItem(a),a=y(b.attr("data-value")),c=e.items.indexOf(a),-1!==c&&(b.remove(),b.hasClass("active")&&(d=e.$activeItems.indexOf(b[0]),e.$activeItems.splice(d,1)),e.items.splice(c,1),e.lastQuery=null,!e.settings.persist&&e.userOptions.hasOwnProperty(a)&&e.removeOption(a),c0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(){var a,b,c,d=this;if("select"===d.$input[0].tagName.toLowerCase()){for(c=[],a=0,b=d.items.length;b>a;a++)c.push('');c.length||this.$input.attr("multiple")||c.push(''),d.$input.html(c.join(""))}else d.$input.val(d.getValue());d.isSetup&&d.trigger("change",d.$input.val())},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(){var a=this;a.items.length&&(a.$control.children(":not(input)").remove(),a.items=[],a.setCaret(0),a.updatePlaceholder(),a.updateOriginalInput(),a.refreshState(),a.showInput(),a.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b));var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g);c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").attr({tabindex:d.tabindex}).show(),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; -return("option"===a||"item"===a)&&(c=y(b[g.settings.valueField]),f=!!c),f&&(x(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,z]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+A(z(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+A(z(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)}}),L.count=0,L.defaults={plugins:[],delimiter:",",splitOn:/[,]+/,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,scrollDuration:60,loadThrottle:300,dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",optgroupOrder:null,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var e,h,i,j,k=a.trim(b.val()||"");if(k.length){for(i=k.split(d.delimiter),e=0,h=i.length;h>e;e++)j={},j[f]=i[e],j[g]=i[e],c.options[i[e]]=j;c.items=i}},l=function(b,c){var d,k,l,m,n=0,o=c.options,p=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},q=function(b,d){var e,i;if(b=a(b),e=b.attr("value")||"",e.length){if(o.hasOwnProperty(e))return void(d&&(o[e].optgroup?a.isArray(o[e].optgroup)?o[e].optgroup.push(d):o[e].optgroup=[o[e].optgroup,d]:o[e].optgroup=d));i=p(b)||{},i[f]=i[f]||b.text(),i[g]=i[g]||e,i[h]=i[h]||d,i.$order=++n,o[e]=i,b.is(":selected")&&c.items.push(e)}},r=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=p(b)||{},g[i]=f,g[j]=f,c.optgroups[f]=g),h=a("option",b),d=0,e=h.length;e>d;d++)q(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,m=b.children(),d=0,k=m.length;k>d;d++)l=m[d].tagName.toLowerCase(),"optgroup"===l?r(m[d]):"option"===l&&q(m[d])};return this.each(function(){if(!this.selectize){var d,e=a(this),f=this.tagName.toLowerCase(),g={placeholder:e.children('option[value=""]').text()||e.attr("placeholder"),options:{},optgroups:{},items:[]};"select"===f?l(e,g):k(e,g),d=new L(e,a.extend(!0,{},c,g,b)),e.data("selectize",d),e.addClass("selectized")}})},a.fn.selectize.defaults=L.defaults,L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'
'+a.title+'×
'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&ed;d++)f=Math.max(f,j.eq(d).height());j.css({height:f})}b.equalizeWidth&&(i=c.$dropdown_content.innerWidth(),g=Math.round(i/e),j.css({width:g}),e>1&&(h=i-g*(e-1),j.eq(e-1).css({width:h})))}};(b.equalizeHeight||b.equalizeWidth)&&(B.after(this,"positionDropdown",d),B.after(this,"refreshOptions",d))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"×",title:"Remove",className:"remove",append:!0},b);var c=this,d=''+b.label+"",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0,0,0,0.06) !important; - border: 0 none !important; - .selectize-box-shadow(inset 0 0 12px 4px #fff); - } - .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; - } - .ui-sortable-helper { - .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); - } -} \ No newline at end of file diff --git a/dist/less/plugins/dropdown_header.less b/dist/less/plugins/dropdown_header.less deleted file mode 100644 index c3e777e16..000000000 --- a/dist/less/plugins/dropdown_header.less +++ /dev/null @@ -1,20 +0,0 @@ -.selectize-dropdown-header { - position: relative; - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - border-bottom: 1px solid @selectize-color-border; - background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); -} -.selectize-dropdown-header-close { - position: absolute; - right: @selectize-padding-dropdown-item-x; - top: 50%; - color: @selectize-color-text; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: darken(@selectize-color-text, 25%); -} \ No newline at end of file diff --git a/dist/less/plugins/optgroup_columns.less b/dist/less/plugins/optgroup_columns.less deleted file mode 100644 index 5c72d7a0a..000000000 --- a/dist/less/plugins/optgroup_columns.less +++ /dev/null @@ -1,17 +0,0 @@ -.selectize-dropdown.plugin-optgroup_columns { - .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - .selectize-box-sizing(border-box); - } - .optgroup:last-child { - border-right: 0 none; - } - .optgroup:before { - display: none; - } - .optgroup-header { - border-top: 0 none; - } -} \ No newline at end of file diff --git a/dist/less/plugins/remove_button.less b/dist/less/plugins/remove_button.less deleted file mode 100644 index c478cd49c..000000000 --- a/dist/less/plugins/remove_button.less +++ /dev/null @@ -1,37 +0,0 @@ -.selectize-control.plugin-remove_button { - [data-value] { - position: relative; - padding-right: 24px !important; - } - [data-value] .remove { - z-index: 1; /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: @selectize-padding-item-y 0 0 0; - border-left: 1px solid @selectize-color-item-border; - .selectize-border-radius(0 2px 2px 0); - .selectize-box-sizing(border-box); - } - [data-value] .remove:hover { - background: rgba(0,0,0,0.05); - } - [data-value].active .remove { - border-left-color: @selectize-color-item-active-border; - } - .disabled [data-value] .remove:hover { - background: none; - } - .disabled [data-value] .remove { - border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } -} \ No newline at end of file diff --git a/dist/less/selectize.bootstrap2.less b/dist/less/selectize.bootstrap2.less deleted file mode 100644 index 2817bbdf6..000000000 --- a/dist/less/selectize.bootstrap2.less +++ /dev/null @@ -1,161 +0,0 @@ -/** - * selectize.bootstrap2.css (v0.9.1) - Bootstrap 2 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @baseFontFamily; -@selectize-font-size: @baseFontSize; -@selectize-line-height: @baseLineHeight; - -@selectize-color-text: @textColor; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @inputBackground; -@selectize-color-input-full: @inputBackground; -@selectize-color-disabled: @inputBackground; -@selectize-color-item: @btnBackgroundHighlight; -@selectize-color-item-border: @btnBorder; -@selectize-color-item-active: @dropdownLinkBackgroundHover; -@selectize-color-item-active-text: @dropdownLinkColorHover; -@selectize-color-item-active-border: darken(@selectize-color-item-active, 5%); -@selectize-color-optgroup: @dropdownBackground; -@selectize-color-optgroup-text: @grayLight; -@selectize-color-optgroup-border: @dropdownDividerTop; -@selectize-color-dropdown: @dropdownBackground; -@selectize-color-dropdown-border: @inputBorder; -@selectize-color-dropdown-border-top: @dropdownDividerTop; -@selectize-color-dropdown-item-active: @dropdownLinkBackgroundHover; -@selectize-color-dropdown-item-active-text: @dropdownLinkColorHover; -@selectize-color-dropdown-item-create-active-text: @dropdownLinkColorHover; -@selectize-lighten-disabled-item: 8%; -@selectize-lighten-disabled-item-text: 8%; -@selectize-lighten-disabled-item-border: 8%; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border-radius: @inputBorderRadius; - -@selectize-padding-x: 10px; -@selectize-padding-y: 7px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @black; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -@selectize-width-item-border: 1px; - -.selectize-dropdown { - margin: 2px 0 0 0; - z-index: @zindexDropdown; - border: 1px solid @dropdownBorder; - border-radius: @baseBorderRadius; - .box-shadow(0 5px 10px rgba(0,0,0,.2)); - - .optgroup-header { - font-size: 11px; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255,255,255,.5); - text-transform: uppercase; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } - - [data-selectable].active { - #gradient > .vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%)); - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - .transition(~"border linear .2s, box-shadow linear .2s"); - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.input-active, &.input-active:hover, .selectize-control.multi &.focus { - background: @selectize-color-input !important; - border-color: rgba(82,168,236,.8) !important; - outline: 0 !important; - outline: thin dotted \9 !important; - .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)") !important; - } -} - -.selectize-control { - &.single { - .selectize-input { - .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &:hover { - color: @grayDark; - text-decoration: none; - background-position: 0 -15px; - .transition(background-position .1s linear); - } - &.disabled { - background: @btnBackgroundHighlight !important; - .box-shadow(none); - } - } - } - &.multi { - .selectize-input { - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - &.has-items { - @padding-x: @selectize-padding-x - @selectize-padding-item-x; - padding-left: @padding-x; - padding-right: @padding-x; - } - } - .selectize-input > div { - .gradientBar(@btnBackground, @btnBackgroundHighlight, @selectize-color-item-text, none); - *background-color: @selectize-color-item; - border: @selectize-width-item-border solid @selectize-color-item-border; - .border-radius(@baseBorderRadius); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &.active { - .box-shadow(~"0 1px 2px rgba(0,0,0,.05)"); - .gradientBar(@selectize-color-item-active, @selectize-color-item-active-border, @selectize-color-item-active-text, none); - *background-color: @selectize-color-item-active; - border: @selectize-width-item-border solid @dropdownLinkBackgroundHover; - } - } - } -} \ No newline at end of file diff --git a/dist/less/selectize.bootstrap3.less b/dist/less/selectize.bootstrap3.less deleted file mode 100644 index 4834da2b8..000000000 --- a/dist/less/selectize.bootstrap3.less +++ /dev/null @@ -1,136 +0,0 @@ -/** - * selectize.bootstrap3.css (v0.9.1) - Bootstrap 3 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @font-family-base; -@selectize-font-size: @font-size-base; -@selectize-line-height: @line-height-computed; - -@selectize-color-text: @text-color; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @input-bg; -@selectize-color-input-full: @input-bg; -@selectize-color-disabled: @input-bg; -@selectize-color-item: #efefef; -@selectize-color-item-border: rgba(0,0,0,0); -@selectize-color-item-active: @component-active-bg; -@selectize-color-item-active-text: #fff; -@selectize-color-item-active-border: rgba(0,0,0,0); -@selectize-color-optgroup: @dropdown-bg; -@selectize-color-optgroup-text: @dropdown-header-color; -@selectize-color-optgroup-border: @dropdown-divider-bg; -@selectize-color-dropdown: @dropdown-bg; -@selectize-color-dropdown-border-top: mix(@input-border, @input-bg, 0.8); -@selectize-color-dropdown-item-active: @dropdown-link-hover-bg; -@selectize-color-dropdown-item-active-text: @dropdown-link-hover-color; -@selectize-color-dropdown-item-create-active-text: @dropdown-link-hover-color; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border: 1px solid @input-border; -@selectize-border-radius: @input-border-radius; - -@selectize-width-item-border: 0; -@selectize-padding-x: @padding-base-horizontal; -@selectize-padding-y: @padding-base-vertical; -@selectize-padding-dropdown-item-x: @padding-base-horizontal; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @selectize-color-text; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -.selectize-dropdown, .selectize-dropdown.form-control { - height: auto; - padding: 0; - margin: 2px 0 0 0; - z-index: @zindex-dropdown; - background: @selectize-color-dropdown; - border: 1px solid @dropdown-fallback-border; - border: 1px solid @dropdown-border; - .selectize-border-radius(@border-radius-base); - .selectize-box-shadow(0 6px 12px rgba(0,0,0,.175)); -} - -.selectize-dropdown { - .optgroup-header { - font-size: @font-size-small; - line-height: @line-height-base; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - min-height: @input-height-base; - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.focus { - @color: @input-border-focus; - @color-rgba: rgba(red(@color), green(@color), blue(@color), .6); - border-color: @color; - outline: 0; - .selectize-box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); - } -} - -.selectize-control { - &.multi { - .selectize-input.has-items { - padding-left: @selectize-padding-x - @selectize-padding-item-x; - padding-right: @selectize-padding-x - @selectize-padding-item-x; - } - .selectize-input > div { - .selectize-border-radius(@selectize-border-radius - 1px); - } - } -} - -.form-control.selectize-control { - padding: 0; - height: auto; - border: none; - background: none; - .selectize-box-shadow(none); - .selectize-border-radius(0); -} \ No newline at end of file diff --git a/dist/less/selectize.default.less b/dist/less/selectize.default.less deleted file mode 100644 index 888d69daa..000000000 --- a/dist/less/selectize.default.less +++ /dev/null @@ -1,84 +0,0 @@ -/** - * selectize.default.css (v0.9.1) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-color-item: #1da7ee; -@selectize-color-item-text: #fff; -@selectize-color-item-active-text: #fff; -@selectize-color-item-border: #0073bb; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #00578d; -@selectize-width-item-border: 1px; -@selectize-caret-margin: 0 1px; - -.selectize-control { - &.multi { - .selectize-input { - &.has-items { - @padding-x: @selectize-padding-x - 3px; - padding-left: @padding-x; - padding-right: @padding-x; - } - &.disabled [data-value] { - color: #999; - text-shadow: none; - background: none; - .selectize-box-shadow(none); - - &, .remove { - border-color: #e6e6e6; - } - .remove { - background: none; - } - } - [data-value] { - text-shadow: 0 1px 0 rgba(0,51,83,0.3); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#1da7ee, #178ee9); - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)"); - &.active { - .selectize-vertical-gradient(#008fd8, #0075cf); - } - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8)"); - .selectize-vertical-gradient(#fefefe, #f2f2f2); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - padding-top: @selectize-padding-dropdown-item-y + 2px; - font-weight: bold; - font-size: 0.85em; - } - .optgroup { - border-top: 1px solid @selectize-color-dropdown-border-top; - &:first-child { - border-top: 0 none; - } - } -} \ No newline at end of file diff --git a/dist/less/selectize.legacy.less b/dist/less/selectize.legacy.less deleted file mode 100644 index da50d8ae6..000000000 --- a/dist/less/selectize.legacy.less +++ /dev/null @@ -1,75 +0,0 @@ -/** - * selectize.legacy.css (v0.9.1) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-size: 13px; -@selectize-line-height: 20px; - -@selectize-color-input-full: #f2f2f2; -@selectize-color-item: #b8e76f; -@selectize-color-item-text: #3d5d18; -@selectize-color-item-border: #74b21e; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #6f9839; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-dropdown-item-active: #fffceb; -@selectize-color-dropdown-item-active-text: @selectize-color-text; -@selectize-color-optgroup: #f8f8f8; -@selectize-color-optgroup-text: @selectize-color-text; -@selectize-width-item-border: 1px; - -@selectize-padding-x: 10px; -@selectize-padding-y: 10px; -@selectize-padding-item-x: 5px; -@selectize-padding-item-y: 1px; -@selectize-padding-dropdown-item-x: 10px; -@selectize-padding-dropdown-item-y: 7px; -@selectize-margin-item-x: 4px; -@selectize-margin-item-y: 4px; - -.selectize-control { - &.multi { - .selectize-input [data-value] { - text-shadow: 0 1px 0 rgba(255,255,255,0.1); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#b8e76f, #a9e25c); - .selectize-box-shadow(0 1px 1px rgba(0,0,0,0.1)); - &.active { - .selectize-vertical-gradient(#92c836, #7abc2c); - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1)"); - .selectize-vertical-gradient(#f5f5f5, #efefef); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - font-weight: bold; - font-size: 0.8em; - border-bottom: 1px solid @selectize-color-dropdown-border-top; - border-top: 1px solid @selectize-color-dropdown-border-top; - } -} \ No newline at end of file diff --git a/dist/less/selectize.less b/dist/less/selectize.less deleted file mode 100644 index a06d20568..000000000 --- a/dist/less/selectize.less +++ /dev/null @@ -1,293 +0,0 @@ -@import "plugins/drag_drop"; -@import "plugins/dropdown_header"; -@import "plugins/optgroup_columns"; -@import "plugins/remove_button"; - -// base styles - -@selectize-font-family: inherit; -@selectize-font-smoothing: inherit; -@selectize-font-size: 13px; -@selectize-line-height: 18px; - -@selectize-color-text: #303030; -@selectize-color-border: #d0d0d0; -@selectize-color-highlight: rgba(125,168,208,0.2); -@selectize-color-input: #fff; -@selectize-color-input-full: @selectize-color-input; -@selectize-color-disabled: #fafafa; -@selectize-color-item: #f2f2f2; -@selectize-color-item-text: @selectize-color-text; -@selectize-color-item-border: #d0d0d0; -@selectize-color-item-active: #e8e8e8; -@selectize-color-item-active-text: @selectize-color-text; -@selectize-color-item-active-border: #cacaca; -@selectize-color-dropdown: #fff; -@selectize-color-dropdown-border: @selectize-color-border; -@selectize-color-dropdown-border-top: #f0f0f0; -@selectize-color-dropdown-item-active: #f5fafd; -@selectize-color-dropdown-item-active-text: #495c68; -@selectize-color-dropdown-item-create-text: rgba(red(@selectize-color-text), green(@selectize-color-text), blue(@selectize-color-text), 0.5); -@selectize-color-dropdown-item-create-active-text: @selectize-color-dropdown-item-active-text; -@selectize-color-optgroup: @selectize-color-dropdown; -@selectize-color-optgroup-text: @selectize-color-text; -@selectize-lighten-disabled-item: 30%; -@selectize-lighten-disabled-item-text: 30%; -@selectize-lighten-disabled-item-border: 30%; -@selectize-opacity-disabled: 0.5; - -@selectize-shadow-input: inset 0 1px 1px rgba(0,0,0,0.1); -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border: 1px solid @selectize-color-border; -@selectize-border-radius: 3px; - -@selectize-width-item-border: 0; -@selectize-max-height-dropdown: 200px; - -@selectize-padding-x: 8px; -@selectize-padding-y: 8px; -@selectize-padding-item-x: 6px; -@selectize-padding-item-y: 2px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: 5px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: #808080; -@selectize-arrow-offset: 15px; - -@selectize-caret-margin: 0 2px 0 0; -@selectize-caret-margin-rtl: 0 4px 0 -2px; - -.selectize-border-radius (@radii) { - -webkit-border-radius: @radii; - -moz-border-radius: @radii; - border-radius: @radii; -} -.selectize-unselectable () { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.selectize-box-shadow (@shadow) { - -webkit-box-shadow: @shadow; - box-shadow: @shadow; -} -.selectize-box-sizing (@type: border-box) { - -webkit-box-sizing: @type; - -moz-box-sizing: @type; - box-sizing: @type; -} -.selectize-vertical-gradient (@color-top, @color-bottom) { - background-color: mix(@color-top, @color-bottom, 60%); - background-image: -moz-linear-gradient(top, @color-top, @color-bottom); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@color-top), to(@color-bottom)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @color-top, @color-bottom); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, @color-top, @color-bottom); // Opera 11.10 - background-image: linear-gradient(to bottom, @color-top, @color-bottom); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@color-top),argb(@color-bottom))); // IE9 and down -} - -.selectize-control { - position: relative; -} - -.selectize-dropdown, .selectize-input, .selectize-input input { - color: @selectize-color-text; - font-family: @selectize-font-family; - font-size: @selectize-font-size; - line-height: @selectize-line-height; - -webkit-font-smoothing: @selectize-font-smoothing; -} - -.selectize-input, .selectize-control.single .selectize-input.input-active { - background: @selectize-color-input; - cursor: text; - display: inline-block; -} - -.selectize-input { - border: @selectize-border; - padding: @selectize-padding-y @selectize-padding-x; - display: inline-block; - width: 100%; - overflow: hidden; - position: relative; - z-index: 1; - .selectize-box-sizing(border-box); - .selectize-box-shadow(@selectize-shadow-input); - .selectize-border-radius(@selectize-border-radius); - - .selectize-control.multi &.has-items { - @padding-x: @selectize-padding-x; - @padding-top: @selectize-padding-y - @selectize-padding-item-y - @selectize-width-item-border; - @padding-bottom: @selectize-padding-y - @selectize-padding-item-y - @selectize-margin-item-y - @selectize-width-item-border; - padding: @padding-top @padding-x @padding-bottom; - } - - &.full { - background-color: @selectize-color-input-full; - } - &.disabled, &.disabled * { - cursor: default !important; - } - &.focus { - .selectize-box-shadow(@selectize-shadow-input-focus); - } - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); - } - - > * { - vertical-align: baseline; - display: -moz-inline-stack; - display: inline-block; - zoom: 1; - *display: inline; - } - .selectize-control.multi & > div { - cursor: pointer; - margin: 0 @selectize-margin-item-x @selectize-margin-item-y 0; - padding: @selectize-padding-item-y @selectize-padding-item-x; - background: @selectize-color-item; - color: @selectize-color-item-text; - border: @selectize-width-item-border solid @selectize-color-item-border; - - &.active { - background: @selectize-color-item-active; - color: @selectize-color-item-active-text; - border: @selectize-width-item-border solid @selectize-color-item-active-border; - } - } - .selectize-control.multi &.disabled > div { - &, &.active { - color: lighten(desaturate(@selectize-color-item-text, 100%), @selectize-lighten-disabled-item-text); - background: lighten(desaturate(@selectize-color-item, 100%), @selectize-lighten-disabled-item); - border: @selectize-width-item-border solid lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } - } - > input { - &::-ms-clear { - display: none; - } - padding: 0 !important; - min-height: 0 !important; - max-height: none !important; - max-width: 100% !important; - margin: @selectize-caret-margin !important; - text-indent: 0 !important; - border: 0 none !important; - background: none !important; - line-height: inherit !important; - -webkit-user-select: auto !important; - .selectize-box-shadow(none) !important; - &:focus { outline: none !important; } - } -} - -.selectize-input::after { - content: ' '; - display: block; - clear: left; -} - -.selectize-input.dropdown-active::before { - content: ' '; - display: block; - position: absolute; - background: @selectize-color-dropdown-border-top; - height: 1px; - bottom: 0; - left: 0; - right: 0; -} - -.selectize-dropdown { - position: absolute; - z-index: 10; - border: @selectize-border; - background: @selectize-color-dropdown; - margin: -1px 0 0 0; - border-top: 0 none; - .selectize-box-sizing(border-box); - .selectize-box-shadow(0 1px 3px rgba(0,0,0,0.1)); - .selectize-border-radius(0 0 @selectize-border-radius @selectize-border-radius); - - [data-selectable] { - cursor: pointer; - overflow: hidden; - .highlight { - background: @selectize-color-highlight; - .selectize-border-radius(1px); - } - } - [data-selectable], .optgroup-header { - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - } - .optgroup:first-child .optgroup-header { - border-top: 0 none; - } - .optgroup-header { - color: @selectize-color-optgroup-text; - background: @selectize-color-optgroup; - cursor: default; - } - .active { - background-color: @selectize-color-dropdown-item-active; - color: @selectize-color-dropdown-item-active-text; - &.create { - color: @selectize-color-dropdown-item-create-active-text; - } - } - .create { - color: @selectize-color-dropdown-item-create-text; - } -} - -.selectize-dropdown-content { - overflow-y: auto; - overflow-x: hidden; - max-height: @selectize-max-height-dropdown; -} - -.selectize-control.single .selectize-input { - &, input { cursor: pointer; } - &.input-active, &.input-active input { cursor: text; } - - &:after { - content: ' '; - display: block; - position: absolute; - top: 50%; - right: @selectize-arrow-offset; - margin-top: round(-@selectize-arrow-size / 2); - width: 0; - height: 0; - border-style: solid; - border-width: @selectize-arrow-size @selectize-arrow-size 0 @selectize-arrow-size; - border-color: @selectize-arrow-color transparent transparent transparent; - } - &.dropdown-active:after { - margin-top: @selectize-arrow-size * -0.8; - border-width: 0 @selectize-arrow-size @selectize-arrow-size @selectize-arrow-size; - border-color: transparent transparent @selectize-arrow-color transparent; - } -} - -.selectize-control.rtl { - &.single .selectize-input:after { - left: @selectize-arrow-offset; - right: auto; - } - .selectize-input > input { - margin: @selectize-caret-margin-rtl !important; - } -} - -.selectize-control .selectize-input.disabled { - opacity: @selectize-opacity-disabled; - background-color: @selectize-color-disabled; -} diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index 2fd42f802..000000000 --- a/docs/api.md +++ /dev/null @@ -1,235 +0,0 @@ -## Selectize API - -Selectize controls can be controlled programmatically via the methods described in this section. -When initializing the control, the "selectize" property is -added on the original <select> / <input> element—this -property points to the underlying Selectize instance. - -```js -// initialize the selectize control -var $select = $('select').selectize(options); - -// fetch the instance -var selectize = $select[0].selectize; -``` - -#### Related Topics - -- [Event Documentation](events.md) -- [Developing Plugins](plugins.md) - -### Methods - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Options
MethodDescription
addOption(data)Adds an available option. If it already exists, nothing will happen. Note: this does not refresh the options list dropdown (use refreshOptions() for that).
updateOption(value, data)Updates an option available for selection. If it is visible in the selected items or options dropdown, it will be re-rendered automatically.
removeOption(value)Removes the option identified by the given value.
clearOptions()Removes all options from the control.
getOption(value)Retrieves the jQuery element for the option identified by the given value.
getAdjacentOption(value, direction)Retrieves the jQuery element for the previous or next option, relative to the currently highlighted option. The "direction" argument should be 1 for "next" or -1 for "previous".
refreshOptions(triggerDropdown)Refreshes the list of available options shown in the autocomplete dropdown menu.
Items
MethodDescription
clear()Resets / clears all selected items from the control.
getItem(value)Returns the jQuery element of the item matching the given value.
addItem(value)"Selects" an item. Adds it to the list at the current caret position.
removeItem(value)Removes the selected item matching the provided value.
createItem(value)Invokes the "create" method provided in the selectize options that should provide the data for the new item, given the user input. Once this completes, it will be added to the item list.
refreshItems()Re-renders the selected item lists.
Optgroups
MethodDescription
addOptionGroup(id, data)Registers a new optgroup for options to be bucketed into. The "id" argument refers to a value of the property in option identified by the "optgroupField" setting.
Events
MethodDescription
on(event, handler)Adds an event listener.
off(event, handler)Removes an event listener.
off(event)Removes all event listeners.
trigger(event, ...)Triggers event listeners.
Dropdown
MethodDescription
open()Shows the autocomplete dropdown containing the available options.
close()Closes the autocomplete dropdown menu.
positionDropdown()Calculates and applies the appropriate position of the dropdown.
Other
MethodDescription
destroy()Destroys the control and unbinds event listeners so that it can be garbage collected.
load(fn)Loads options by invoking the the provided function. The function should accept one argument (callback) and invoke the callback with the results once they are available.
focus()Brings the control into focus.
blur()Forces the control out of focus.
lock()Disables user input on the control (note: the control can still receive focus).
unlock()Re-enables user input on the control.
disable()Disables user input on the control completely. While disabled, it cannot receive focus.
enable()Enables the control so that it can respond to focus and user input.
getValue()Returns the value of the control. If multiple items can be selected (e.g. <select multiple>), this returns an array. If only one item can be selected, this returns a string.
setValue(value)Resets the selected items to the given value.
setCaret(index)Moves the caret to the specified position ("index" being the index in the list of selected items).
isFull()Returns whether or not the user can select more items.
- -### Related Objects - -#### Search - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescriptionType
optionsOriginal search options.object
queryThe raw user input.string
tokensAn array containing parsed search tokens. A token is an object containing two properties: "string" and "regex".array
totalThe total number of results.int
itemsA list of matched results. Each result is an object containing two properties: "score" and "id".array
diff --git a/docs/events.md b/docs/events.md deleted file mode 100644 index 2eca2c9fa..000000000 --- a/docs/events.md +++ /dev/null @@ -1,85 +0,0 @@ -## Selectize API – Events - -In the [usage documentation](usage.md), a few callbacks are listed that -allow you to listen for certain events. Callbacks aren't always ideal though; -specifically when you wish to have multiple handlers. - -Selectize instances have a basic event emitter interface that mimics jQuery, Backbone.js, et al: - -```js -var handler = function() { /* ... */ }; -selectize.on('event_name', handler); -selectize.off('event_name'); -selectize.off('event_name', handler); -``` - -### List of Events - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventParamsDescription
"initialize"Invoked once the control is completely initialized.
"change"valueInvoked when the value of the control changes.
"item_add"value, $itemInvoked when an item is selected.
"item_remove"valueInvoked when an item is deselected.
"clear"Invoked when the control is manually cleared via the clear() method.
"option_add"value, dataInvoked when a new option is added to the available options list.
"option_remove"valueInvoked when an option is removed from the available options.
"dropdown_open"$dropdownInvoked when the dropdown opens.
"dropdown_close"$dropdownInvoked when the dropdown closes.
"type"strInvoked when the user types while filtering options.
"load"dataInvoked when new options have been loaded and added to the control (via the "load" option or "load" API method).
"destroy"Invoked right before the control is destroyed.
\ No newline at end of file diff --git a/docs/plugins.md b/docs/plugins.md deleted file mode 100644 index d829cd18e..000000000 --- a/docs/plugins.md +++ /dev/null @@ -1,101 +0,0 @@ -## Selectize API – Plugins - -Via the [microplugin](https://github.com/brianreavis/microplugin.js) interface, -features can be added to Selectize without modifying the main library. -This is great because it protects against code bloat, allows for lean builds, -and allows for addons to be sanely isolated. The plugin system isn't meant -to be sexy; it's lean, makes very few assumptions, and gives the developer -complete control. - -[**Example Plugins**](../src/plugins) - -**A few notes:** -- All plugins live in their own folders in ["src/plugins"](../src/plugins). -- Plugin names should be in follow the format: `/[a-z_]+$` -- JS source should live in a "plugin.js" file (required). -- CSS should live in a "plugin.less" file (optional). It will be bundled at build time. -- Plugins are initialized right before the control is setup. - This means that if you want to listen for events on any of the control's - elements, you should override the `setup()` method (see ["DOM Events"](#dom-events)). - -### Boilerplate - -```js -Selectize.define('plugin_name', function(options) { - // options: plugin-specific options - // this: selectize instance -}); -``` - -#### Adding Dependencies - -```js -Selectize.define('plugin_name', function(options) { - this.require('another_plugin'); -}); -``` - -## Overriding Methods - -Methods should be extended by [wrapping them](http://coreymaynard.com/blog/extending-a-javascript-function/): - -```js -var self = this; -this.someMethod = function() { - var original = self.someMethod; - return function() { - // do your logic - return original.apply(this, arguments); - }; -}); -``` - -**Important:** If the method you're overriding returns a value, make sure the -overridden function returns a value as well. - -## DOM Events - -Because all elements for the control are created within the `setup()` method (which is -invoked after the plugin initialized) events should be added by overriding the setup method, -like so: - -```js -Selectize.define('plugin_name', function(options) { - var self = this; - - // override the setup method to add an extra "click" handler - this.setup = (function() { - var original = self.setup; - return function() { - original.apply(this, arguments); - this.$control.on('click', 'div', function(e) { - alert('A div was clicked!'); - }); - }; - })(); - -}); -``` - -## Plugin Usage - -#### List (without options) - -```js -$('select').selectize({ - plugins: ['plugin_a', 'plugin_b'] -}); -``` - -#### List (with options) - -```js -$('select').selectize({ - plugins: { - 'plugin_a': { /* ... */ }, - 'plugin_b': { /* ... */ } - } -}); -``` - -For a more detailed description of plugin option formats and how the plugin system works, check out the [microplugin](https://github.com/brianreavis/microplugin.js) documentation. \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md deleted file mode 100644 index 6b5739b21..000000000 --- a/docs/usage.md +++ /dev/null @@ -1,335 +0,0 @@ -## Selectize – Usage - -```html - - - -``` - -### Options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
General
OptionDescriptionTypeDefault
delimiterThe string to separate items by. This option is only used when Selectize is instantiated from a <input type="text"> element.string','
diacriticsEnable or disable international character support.booleantrue
create - Allows the user to create a new items that aren't in the list of options. This option can be any of the following: "true" (default behavior), "false" (disabled), or a function that accepts two arguments: "input" and "callback". The callback should be invoked with the final data for the option.mixedfalse
createOnBlur - If true, when user exits the field (clicks outside of input or presses ESC) new option is created and selected (if `create`-option is enabled). - booleanfalse
highlightToggles match highlighting within the dropdown menu.booleantrue
persistIf false, items created by the user will not show up as available options once they are unselected.booleantrue
openOnFocusShow the dropdown immediately when the control receives focus.booleantrue
maxOptionsThe max number of items to render at once in the dropdown list of options.int1000
maxItemsThe max number of items the user can select.int
hideSelectedIf true, the items that are currently selected will not be shown in the dropdown list of available options.booleanfalse
scrollDurationThe animation duration (in milliseconds) of the scroll animation triggered when going [up] and [down] in the options dropdown.int60
loadThrottleThe number of milliseconds to wait before requesting options from the server or null. If null, throttling is disabled.int300
preloadIf true, the "load" function will be called upon control initialization (with an empty search). Alternatively it can be set to "focus" to call the "load" function when control receives focus.boolean/stringfalse
dropdownParentThe element the dropdown menu is appended to. This should be "body" or null. If null, the dropdown will be appended as a child of the selectize control.stringnull
addPrecedenceSets if the "Add..." option should be the default selection in the dropdown.booleanfalse
selectOnTabIf true, the tab key will choose the currently selected item.booleanfalse
Data / Searching
OptionDescriptionTypeDefault
optionsOptions available to select; array of objects. If your element is <select> with <option>s specified this property gets populated accordingly. Setting this property is convenient if you have your data as an array and want to automatically generate the <option>s.array[]
dataAttrThe <option> attribute from which to read JSON data about the option.string'data-data'
valueFieldThe name of the property to use as the "value" when an item is selected.string'value'
optgroupValueFieldThe name of the option group property that serves as its unique identifier.string'value'
labelFieldThe name of the property to render as an option / item label (not needed when custom rendering functions are defined).string'text'
optgroupLabelFieldThe name of the property to render as an option group label (not needed when custom rendering functions are defined).string'label'
optgroupFieldThe name of the property to group items by.string'optgroup'
sortField - A single field or an array of fields to sort by. Each item in the array should be an object containing at - least a "field" property. Optionally, "direction" can be set to "asc" or "desc". The - order of the array defines the sort precedence.

- - Unless present, a special "$score" field will be automatically added to the beginning - of the sort list. This will make results sorted primarily by match quality (descending).

- - For more information, see the sifter documentation. -
string|array'$order'
searchFieldAn array of property names to analyze when filtering options.array['text']
searchConjunctionWhen searching for multiple terms (separated by a space), this is the operator used. Can be "and" or "or".string'and'
optgroupOrderAn array of optgroup values that indicates the order they should be listed in in the dropdown. If not provided, groups will be ordered by the ranking of the options within them.arraynull
Callbacks
OptionDescriptionTypeDefault
load(query, callback)Invoked when new options should be loaded from the server.functionnull
score(search)Overrides the scoring function used to sort available options. The provided function should return a function that returns a number greater than or equal to zero to represent the "score" of an item (the function's first argument). If 0, the option is declared not a match. The "search" argument is a Search object. For an example, see the "GitHub" example.functionnull
onInitialize()Invoked once the control is completely initialized.functionnull
onChange(value)Invoked when the value of the control changes.functionnull
onItemAdd(value, $item)Invoked when an item is selected.functionnull
onItemRemove(value)Invoked when an item is deselected.functionnull
onClear()Invoked when the control is manually cleared via the clear() method.functionnull
onDelete(values)Invoked when the user attempts to delete the current selection.functionnull
onOptionAdd(value, data)Invoked when a new option is added to the available options list.functionnull
onOptionRemove(value)Invoked when an option is removed from the available options.functionnull
onDropdownOpen($dropdown)Invoked when the dropdown opens.functionnull
onDropdownClose($dropdown)Invoked when the dropdown closes.functionnull
onType(str)Invoked when the user types while filtering options.functionnull
onLoad(data)Invoked when new options have been loaded and added to the control (via the "load" option or "load" API method).functionnull
Rendering
render - Custom rendering functions. Each function should accept two arguments: "data" and "escape". - The "escape" argument is a function that takes a string and escapes all special HTML characters. - This is very important to use to prevent XSS vulnerabilities. - - - - - - - - - - - - - - - - - - - - - -
optionAn option in the dropdown list of available options.
itemAn item the user has selected.
option_createThe "create new" option at the bottom of the dropdown. The data contains one property: "input" (which is what the user has typed).
optgroup_headerThe header of an option group.
optgroupThe wrapper for an optgroup. The "html" property in the data will be the raw html of the optgroup's header and options.
-
object
diff --git a/examples/api.html b/examples/api.html deleted file mode 100644 index 21310c6ee..000000000 --- a/examples/api.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js

-
-

API

-

Examples of how to interact with the control programmatically.

-
- - -
-
- - - - - -
- -
-
- - diff --git a/examples/basic.html b/examples/basic.html deleted file mode 100644 index 7a57b11c1..000000000 --- a/examples/basic.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js

- -
-

<input type="text">

-
- - -
- -
- -
-

<select>

-
- - -
- -
- -
-

<select> (disabled)

-
- - -
- -
- -
-

<select multiple>

-
- - -
- -
-
-
- - -
- -
- - -
-

<select multiple> (disabled)

-
- - -
- -
-
- - \ No newline at end of file diff --git a/examples/cities.html b/examples/cities.html deleted file mode 100644 index e8612c78c..000000000 --- a/examples/cities.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js

-
-

State / City Selection

-

A demonstration showing how to use the API to cascade controls for a classic state / city selector.

-

Note: The API for fetching cities is a little spotty, so if it fails to list cities, that's the problem.

-
- - - - -
- -
-
- - \ No newline at end of file diff --git a/examples/confirm.html b/examples/confirm.html deleted file mode 100644 index a7327fa88..000000000 --- a/examples/confirm.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js

- -
-

Confirm Delete

-
- - -
- -
-
- - \ No newline at end of file diff --git a/examples/contacts.html b/examples/contacts.html deleted file mode 100644 index b3cb20241..000000000 --- a/examples/contacts.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
-

Selectize.js

-
-

Email Contacts

-

An example showing how you might go about creating contact selector like those used in Email apps.

-
- - -
- -
-
- - \ No newline at end of file diff --git a/examples/css/normalize.css b/examples/css/normalize.css deleted file mode 100644 index 57b5d2679..000000000 --- a/examples/css/normalize.css +++ /dev/null @@ -1,375 +0,0 @@ -/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ - -/* ========================================================================== - HTML5 display definitions - ========================================================================== */ - -/* - * Corrects `block` display not defined in IE 8/9. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section, -summary { - display: block; -} - -/* - * Corrects `inline-block` display not defined in IE 8/9. - */ - -audio, -canvas, -video { - display: inline-block; -} - -/* - * Prevents modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/* - * Addresses styling for `hidden` attribute not present in IE 8/9. - */ - -[hidden] { - display: none; -} - -/* ========================================================================== - Base - ========================================================================== */ - -/* - * 1. Sets default font family to sans-serif. - * 2. Prevents iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ - -ms-text-size-adjust: 100%; /* 2 */ -} - -/* - * Removes default margin. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/* - * Addresses `outline` inconsistency between Chrome and other browsers. - */ - -a:focus { - outline: thin dotted; -} - -/* - * Improves readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* ========================================================================== - Typography - ========================================================================== */ - -/* - * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, - * Safari 5, and Chrome. - */ - -h1 { - font-size: 2em; -} - -/* - * Addresses styling not present in IE 8/9, Safari 5, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/* - * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/* - * Addresses styling not present in Safari 5 and Chrome. - */ - -dfn { - font-style: italic; -} - -/* - * Addresses styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - - -/* - * Corrects font family set oddly in Safari 5 and Chrome. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -/* - * Improves readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/* - * Sets consistent quote types. - */ - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -/* - * Addresses inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/* - * Prevents `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* ========================================================================== - Embedded content - ========================================================================== */ - -/* - * Removes border when inside `a` element in IE 8/9. - */ - -img { - border: 0; -} - -/* - * Corrects overflow displayed oddly in IE 9. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* ========================================================================== - Figures - ========================================================================== */ - -/* - * Addresses margin not present in IE 8/9 and Safari 5. - */ - -figure { - margin: 0; -} - -/* ========================================================================== - Forms - ========================================================================== */ - -/* - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/* - * 1. Corrects color not being inherited in IE 8/9. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/* - * 1. Corrects font family not being inherited in all browsers. - * 2. Corrects font size not being inherited in all browsers. - * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome - */ - -button, -input, -select, -textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 2 */ - margin: 0; /* 3 */ -} - -/* - * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -button, -input { - line-height: normal; -} - -/* - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Corrects inability to style clickable `input` types in iOS. - * 3. Improves usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/* - * Re-set default cursor for disabled elements. - */ - -button[disabled], -input[disabled] { - cursor: default; -} - -/* - * 1. Addresses box sizing set to `content-box` in IE 8/9. - * 2. Removes excess padding in IE 8/9. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/* - * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/* - * Removes inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* - * Removes inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/* - * 1. Removes default vertical scrollbar in IE 8/9. - * 2. Improves readability and alignment in all browsers. - */ - -textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ -} - -/* ========================================================================== - Tables - ========================================================================== */ - -/* - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/examples/css/stylesheet.css b/examples/css/stylesheet.css deleted file mode 100644 index ab6cff1fd..000000000 --- a/examples/css/stylesheet.css +++ /dev/null @@ -1,132 +0,0 @@ -body { - margin: 70px 0; - padding: 0; - font-family: Helvetica, arial, sans-serif; - font-size: 15px; - color: #454545; - background: #fff url(../images/bg.png); - text-shadow: 0 1px 0 rgba(0,0,0,0.02); - -webkit-font-smoothing: antialiased; -} -a, a:visited { - color: #3fabff; - text-decoration: none; -} -a:hover { - color: #008af5; -} -h1 { - margin: 0; - font-weight: 300; - font-size: 35px; - letter-spacing: -1px; -} -h2 { - font-size: 15px; - color: #a0a0a0; - margin: 30px 0; -} -label { - display: block; - font-weight: bold; - margin-bottom: 10px; -} -p, .control-group { - margin: 0 0 20px 0; -} -.demo { - border-bottom: 1px solid #e8e8e8; - padding-top: 50px; - padding-bottom: 50px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.demo:last-child { - border-bottom: 0 none; -} -.demo select, .demo input, .demo .selectize-control { - width: 100%; -} -.demo > *:first-child { - margin-top: 0; -} -.demo > *:last-child { - margin-bottom: 0; -} -.demo .value { - margin: 0 0 10px 0; - font-size: 12px; -} -.demo .value span { - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; -} -.theme-selector { - margin-top: 10px; - font-size: 13px; -} -.theme-selector:before { - content: 'Themes: '; -} -.theme-selector a { - margin: 0 5px; -} -.theme-selector a.active { - color: #202020; - font-weight: bold; -} -#wrapper { - margin: 0; -} -#wrapper > * { - padding-left: 100px; - padding-right: 100px; -} -pre { - background: #f8f8f8; - border: 1px solid #f2f2f2; - padding: 10px; - font-size: 12px; - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -input[type=button] { - margin: 0 10px 0 0; - padding: 6px 10px; - color: #606060; - background: #e0e0e0; - border: 0 none; - width: auto; - display: inline-block; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-font-smoothing: antialiased; -} -.buttons { - margin: 0 0 25px 0; -} -input[type=button]:hover { - background: #dadada; -} - -@media only screen and (max-width : 320px) { - body { - margin: 20px 0; - } - #wrapper { - margin: 0; - } - #wrapper > * { - padding-left: 10px; - padding-right: 10px; - } - .demo { - padding: 20px; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - } -} \ No newline at end of file diff --git a/examples/customization.html b/examples/customization.html deleted file mode 100644 index ac080e71a..000000000 --- a/examples/customization.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
-

Selectize.js

-
-

Customizing Appearance

-

Render items on your own & apply unique CSS styles.

-
- - -
- -

TODO: explain how to bind events.

-
-
- - \ No newline at end of file diff --git a/examples/dynamic.html b/examples/dynamic.html deleted file mode 100644 index 31b7be994..000000000 --- a/examples/dynamic.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js

-
-

Dynamic Options

-

The options are created straight from an array.

-
- - -
- -
-
- - \ No newline at end of file diff --git a/examples/events.html b/examples/events.html deleted file mode 100644 index cfff347dc..000000000 --- a/examples/events.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
-

Selectize.js Demos

-
-

Events

-

Check out the console for more details about each event.

-
- - -
-

Event Log

-

-				

Source

- -
-
- - diff --git a/examples/github.html b/examples/github.html deleted file mode 100644 index e76b7fe18..000000000 --- a/examples/github.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
-

Selectize.js

-
-

Loading + Custom Scoring

-

This demo shows how to integrate third-party data and override the scoring method.

-
- - -
- -
-
- - \ No newline at end of file diff --git a/examples/images/bg.png b/examples/images/bg.png deleted file mode 100644 index 4da56314492e59d8f5242b4c69cc6f497b2bbf6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7475 zcmV-39n9j1P)F1pwZnN$-W=|{`>ErZ|^_fzkmPs@$vEP zb?n>UfB*gM&!0c%zd82%_wP^d=h$C={dKOLKl9l!*Uosqe*L=l&zN&=uA6b^{y9Id z{>XN^zT*ijB^UIxwPE4JEPix`-(CN5p=0R+qz!zEk;7nr$V3`=b=sVP|b`33_4?u zZAwBZXmG9tsumJz6~cV973BeNHMDCi^R%01yyoP@{Nu-uKQqt-jRVn4x!eL3OEDlA zwLojN16P)p%jp){F}GPjA!7QU7`}}M5p}(;RD^ajKp3kgMy%G|?pBCWlnw_jKzO1) z^jOedsvJ>QH3@+d9Iovo-{K%s@*zRTp^;gPv7wFjl->j?F_KqWtD|up;RGZcUm&!b zYBE~*Z5-MWMKXQG9_^%AJ64!iITR~x6`Mlef{*R3Zdg=By8Ng(+r=oBiHaVR5%B7h zqFQ8mzV|g*Pu5ZKAyNXji$iNoW+}ySAf+GO29zZ>z0-!qTiTZ&Y=nkyx4bHPL|sC( zBOx@Q&yrMku+K?qk%SVf6Xx9kLpX#AUO_Ed2X#I`aBUOc>#G$7MfV$$)Hro9P!vGG zybX%@XZ-ntx{6eZQsh$OjD_;Fy<}JG>RyUM z*XjaslnLA`aV=0C9G=G#5?rmV1G67$4$342h!Px zuFi+Uknnax(WlEKw2MczHlSjt!zndzLpzaJ0o~PVqdt__rCQyZHvK80@E#?W?3cM39X#(8>s#|I`iFFGCd1Bi1Xy*lBjJ0N{7xVrebeO*~S5~h%+!juf()y&Q9gi+*VanNa zo=!=eq;+?0VOz)0Zh;`Vod?x22)b^&v#zhj*G0??0Bvo;26J3DADSME#SIj#Gq6O@ zh4iIPVuF;6Iu#48$d;?o7W=pnMUzksJ;CRt9R;6r3RLQw^JM@VHalqR1TwlN_EJ$@ zXE&`Vy`V158yld^VLgg|j`vxXs&*5%5pLnz$<&V40rfi9be~ZzQ2^I*E$yh90%#Va zxGk`oP-8&jEFO0^E`_=j@_t4JM031aRT^|}K_Xv3-v^P^z}rDI#s&cAC7Q<2+;->8uiJG63hyR#*7PyYvIMd#43&ydZ7?BzFXx&Rz3jvg z?mD=NU*Fet5q?SkD*2Aj^-mp354#^}qBiGm4H929!(OiEYp zTCN%c8-4QYbs6mx2&+XV#C28Mg`vbZ<;ghiK_8vSQqgV*}BqJq8VPKP1|xbaKHrNjj#TV-b+&9GdKY ziGz~FE%t<5L5lqHee;1bbr7&vADS1}7WA5fZD7pbG0w)Y6rqg;C5g3^l8Ndz-3UU# zEJinUOwObUf!K2P9Fy>Q&nTdZj#CQgTu&geUa@gOO{{Y*u+GqZGj=zL#w~sCqR~tF zI^8#XrG1)c-C|+|+WgPQH(8}Rfob`+wf72#CKRMpQ)5u$pdh8r?f3CDx~Y&F3$5r_ zu8|NyAP>@s(@Q(b)nr};onci`?YuHLaCdstyTA3zzt<-am6SF z)e3g-QUsnQX1b`fQs)Cr64R#u4OFnD1qn2lIJAF7R~#s=pQ~NfJ!^NZEkPNh0P21O zfOL~_yH$9~aRGE)mIZ00xoC>vsbrnjOxztOT5|m)tBY4~owTV@kfjfc(n+6$FF$Rq z_J|SJLmmAqiY2~Gz-2KKioY#>%@1Ip$#!jb=Nwmc1~qrxS3~e$+tR{n(G;wkw`x#D ztdvusCeS*-XGm)B5~r)SVW{o^0s1m7z|@Y4(|EeP;A%YEvMPXebq(GFi-PVhb}tP* z8^aOxww=Y4^CY8>3HoIZB%%SRu8`Mh;plGK_MSsWpo~o=7F&^gdK|)Z&@Wol`=Ppg zj{3GW?M_{6b6?$A!Ht%6y!&est5VG)hA~l+IBooDjl1^%x)ua*>d2~v=(g^t8ZhrA9a#3RyoIk;oj7$!ce!(e|L`as zFbSH1Y_<&rbW+LO)Ha{%o}k78J63^FffW}zn0q(p*F+R3JN5!fK`P*74|6C?I}WJI zG74RalcR$BenF+R=Z2!tf}u@C1&^)-hJ!aX^tqNI3l7!QF&R%Rn?l7^N>Q|l6~LMR z2}L6)r~3v^6}rw106FUSMa`4qls$9~dINaf1f2J0Kzk>y6T0u1W4ICxL0K*Dwz2$u zJA`2n5ERpjZa7P6#_&4H?MAO|tX;lAP`yFfH6hm1qE*kf>jTj0C$a9Dti`cy)9*Ki zMR@HV#Hg_9w*@7)-Bo8(>L~>jHLf=X>M2D^yfKO{_s^@YK?$^FKW;%SEpDmT+S_s7 zcPwC16rBi&r7(I&w-nG^w;=5hd|dRaHj1)I)cy^y$k;Zr6e1Dz^7b%&QtKXbl_nvr z9SdB5;C_^7t!ScMP{#>$;zX^$B8dtQn8sHi$>&U)GvL2_Cy!2`j-YPJXh&4Q>XypI zJGgzFMB-;w@oA$bku3zy-l8kc-HDT&K3$+muA>M0k;ry)P~R?S!OYL{&u6q$-7DY} z_T*w*mS7&y87d zwWsvvag78?es!ottM*k?H@}zauz~`$GfR8@eu(BkKUx9?^tDY8P;zrOKd%7qUyG(4 zZCk@ZL91vNE!B_x97uPxgV=8xCa!ivJGk@fP3+?LIsQh%G0J@ zK#`x5iz!GQj|H2oNYP^54@kh=XLnpAG?~U?1}uK>CoEc^<#r-kDnSEVbIQ+8`v)Ma zIcT@*XeL2C3ZUCskV!h~+itYubVE!BPp)1!-+ws30y-fc-@K^}n>_D(u8UHfihXUb zj_6b1+R?UtyRBU#_F73)i+Z7*76PBH-L!KzZSQ}P0-(&*?y(+}yEmm`QLO#o@&1$) zGAiN|C`8sRRKT_67E&~5vE_AwTm+Y^J;G?BHZV#t3bnhslu?^nrzQEWb=@{8z=S2x zbh|*l8k=sh)_#j9-aZL9wzmRl0tpmYcjgs9Z4cE3C+yvTZEdI!w`(TQ?pg41DNi@n zNYDt~Q`=hP&iT5gSu=h|-`3@GH+quV{Yr)1ctF_=v-ew*=h{~?r*ZHqZ-mQ1F@daZ%o-tJ7!T<>!WKKIfP zv?+(DAZ}9SIu+=o1rlAGLdISGK?cUUh2CiM`b+{)jr1YPJ11fEXII-BD_RJe|}e_EAdF zQDKzG@-w8?l~kYlXc&$OFT}t(r zKDPxVURug|;;)F^TshW+38dGve~MXJ(1~?*?W%UHF-vcfsq0#B^AXw_k-DA&Zc_?v z6jNzjJngUo*8WF++Sylk_Fs$cV*}OgexPDlL~L8!_OA{rS~X+u}kY{57qWs)IP_2@poO8#ceb;u@y_mC@)txdR`H` z4{0|+;T&_kozNI8x~^&K8E43KDSneejB7_*^nN`Hc;?0)l8c@sR-yq}eAQ^3tk^U5 z*$2H2oQP%~qWlU>MW6`7EIpC_zPfMHUsJnVyp@ z2v)p)ji6}s0^jdKv`}&Ygr&tY!3N$1sJ~;_>h3|x_1(-#47AP|O;*Q|6ovgtqbi~m zUy0L^JI2mkgmO~dY@$O6X9DPzUz7HV&y{_&F09ZZ+GVk74>H@)cf%HP6UE7UkU6J#R2gObtK-az0rIhyuuGhC4 z%+n_yr7G)WUNC@I@4va&?=}Qg?%W80Le_E;Y(Jy51uePUMU!vCq>y_LG@tEd*vq0% zfl58PLQIgp=@9iaiH_BgS%;2#+DjO_rpJA9rTYs6#j_3WfUEfV`ohe{ARzQ~K8egBW)ncE& z^ro$u1K95ptakRbhy@k>t zTGjI#JQ7yg5o@*0dKGM5OP`W$Jh`axxO$MExmx=MTV3M;+K76Et?dU1&@EXg3aUy& zeM0MaEv$QJT7 zvjOwQJR8G`SoOprpj1GfaY;ZQ7G80B|8SzMDkwZX*Gk5`XHP505;{qMyjggQU0OtE zMSo3!4k_4Ld|g*Mk^DJUcei)`@>9ywIUU0~9v|zoy`8MiVYj$*TDv^iW2Gu$){d%u z?t8(u8;fKVQUprAc_g*TgGvBtGHP+r(_BYv6?DI%x*CC+A>g2^j8Eg$02j#PvbHm- zqausW}ss&fi;U=Y(*CXND7*a>p~Y^XGXqTJWyIrqfz<#vf+ z8gx*pMJIOSRs#b7=v$#MgHCmw{4`H;rLaEJsZWI)%BsK;DV2n{esA82*KrZM{+tHN zs}5Cq5J<(@ z65(e(7F<4Va*OB4%VwKfg--&8_yPm)aT|HtJrk&hY*nLx`)xz?&_GuBe+3 zu;guC^;w~-HKiO#+|J74Bn!1@^DUr_M=^9_UEhqiEv?VB&AQ(F(2j06wK}lUT^}AQ z8V2bXdWX_xr{1I(bUP-CuHenJ7VLdnv$VC{MD3omu{gU_Biv3gNf>ljidLtwVW+n+kXG1xM+2MO-Ri_0a$cPV!=oQj3qx3 zKcA~z&5f~v9QYhR2H~}+`}ad20E+Hr<&By--XE)}Y$qsXDekt3iXd=Kh1)?<5<%CT z?;_EhL@7**=p2o+&USXYOo6O_J58Y5uB&zy?N*Bz4uw_-407Uo9h^V+DW;QJ(T1tT z(J8pKNOFCP)x_$A1|z``uKsL#1x_Ey6y@DO(!q&!uGiJ=@?HFPN5L+hlkd@x zR?x9C7$=m^@{l{FbfHd;~u1^Q~wFxQt(@OqyJ(6j!c5Cg%Nx0uA91;?mZNwi+SqK(pmQ@ z=oLWfdKA5yfX3RXkX?4@b-F;u%(=-&*CxS^%b~)EnZpED8l_nD_|yM6anZO7A<-6r z&bs)1bJk6m1=Sk1fM}&!CE%iQVt{f5QAGMe#~LrB_bCMW;jWBRbKpJtD>c?Qh)K+f zq!@LfbM5_=;`;}EpK|J71Crn-+N2O6pa!UocYE&65Nw0lN$F-%p-X=jC=RG}E&Wj7 zx7Kp${QW((TAMO_cjh|jubtt~k7p#aq%$?oobi@LSl zr@eJa2F0QDA^E9lyB#nTU-uZZT2}N|lQ4pL znU`v46HKU$%_PW+aU2KGV{FD^^|?xUye`SYnhYXW-ra$9ms|U+11gdhVxdiT=dv(` zlt>!2>A*O~Ma32H0!z^darLz9(KzG>T^Vn#>84PTs)5zZ`?OaObuD!@ZOL-AfuXX_ zq!zjy{KT=6B}p43j^lc+(4MD`N+*_XS_}zp!D*m8bZ>x~x~FPBym#JSq}ztltwNit zd!hUPj<6SuIvUviEz=Zl@4DMz-s9g2p#pBo)5gZFiz_d;fQpU#+m-I=xfZ+H)*oM# z3B<6Aq(j@8rR!2`&5~=Ht81-a6W{ODp-yEB`%uyDB0!lW&NcP^Eyx@~x_JHEgXhIl3r?NGQKuahIf-vx}<0S~xl^|I(s%A7FR|9G$VdzmHqQ!N{PM z7FI&5T{T5$w0f}xz5q1Nc^y$VnO%5k0#YQdEpAYg3BIBVk>+S%+Ia6L6iggYr(i|w zlZf`1PN;ip@%Gp?7VW5~O|7^Uya3SU#J>Qg`XFkO+r?Dqi zR9%`s`SP85MHZ?!kBvx)GZ^&MyF=HEE5Qw@&II}@h>%*UEI2B_uuZ12`T z^S8t2o(&}9RBOuwH3wotmve8wLG3!v7(-c}v~m$zN+C9P_mKxAY%XWzn)p6%0s!|B zJ)LJE#wnc^vDK4Za1>fftrbR%U0>(70j%+;l^2svHg@S580cqXmjgvPa^UZW;IVcG z@xMri8S1T&f+n|)P3#dL` zm!qaASSCb}d>Iqg=Sr*6xyI2}BtRjn+`%jB5@Fw2*E} zYdDMvSQg)+*3q?VYNL(6zb$ke<)C5gQoRIfbXP{{SK_t3x4T~l&yO5TD6x_~pJyT6 z5ok|`F2*Ku3#bicR& zVB20@VctDXfy*9074mf5e5YQ`FzLJ&*_}iopjKi^K{}+O?7bxK1*02tNmw^k;@dP< z9_|krXxvUJZDT~{I_uTBb#>JVbXBS{XB}sO>YlwNaQxEY*xm|Hk)`r|jJ|aRm06%< zLm@Fk5ej7<_iJ;VWr5vf2_Aqds?fhRN|6=6&zroLY}b@-tBG{MTm_W%C}Pb>fmQ|q zDl~i6=N~ZR3~E6I)@L;mThTHJf$EPOByZc$I+3puQ3{eYMJR|+9F(;ab#Ljh0uC@m x`^3}k7ssZ!xu%=CCfoYZSWONFsO{D{{{heMl^rIKLZ*U+nvc`Mw zNifWia~^WeIp>@+h`^9@&IS+_6_g}NKm`nlC?E(T7ytu`fFL3$q6869R1^^emHXh8 z|2e1beYjP(pMKT#)wfo!u2p+iF96PRYHVyI$_Nk@ofz+AZY1d8=_N>*0z6=W2t2?~ z4M>PJba1eN|2YtV@6P}M02q~}#>Pg%|1FpTgAxJ&5C;J84@?M%0zj?;AXNde@reK! z2LKRBNsLVdz$5|yYrKc27Xaok0I-Jq;VJ-N_5Z`o0KgjW;$#efxeGu;qEh2S0O*DR zKrlHVBoTma834~59T*l3z>EdJ>ji{T0|7Wq06-=xDkczsGZp|O{Qt!#_!U zkZt}`3jhGnn1m(7MpDz@|2v{0lm4#34*;Zu2xn^m5CK3^1E{9Xe>pVB(&jJ6CK@^Y z<*-Ccmu*dwh3j8Vif}dj%Mmfw+xlpKJNs?_1Y@tioF3}p{+9!TOicfBe2mk!J|WrJ z^dG&k-Cqu;S~>h>YCOPS4vI8)`e)A$+xv`;wA-#FINoeq6O`~zy@{bN7TX-}vaJaY zGqc>TH{RkO|44^z&-f&#?Q;lE!co5n1CP{Ll{Iu5JUkL1i=KtAOT__ z5~z@t7?hd_0AL&wn-(7y5}GJz7#kZIBqL}U9UvzosHC8%3?80df`8h#;sgi)AncF- z$;BlCXlVkVC;!P&r2#r+09Y^mlM_(`psNJvnhQvZPyUm`0s!EE2n@gqT)+>)AOW(V z1ZtoS24D(SU=J?f2|f@2p%4Y}kOI45A7n!=6hH}7z-c%G7vM6qz%{r5J#Zf$!7z-$ zBuv9Re1K*64x0#q5D+rLf^Z=Mh$teBC?Oh%9%72vAWn!U;)jGF(MS@q8`+QKB1K3A zQiIeZSCH#S5AqNhL7pQs$RhF;*+4NU31vn3P%%^<)j$nVYt#kZiH4wYXgYcT%|px4 zTJ#dyj`pCB&@prx{eZ4w07Hji$51e`7!8au#vbE^3C6@@_F{4{rI=bwBc>D6hZ)68 zW0o*Kuy`yBRuC(T)y7(2U9kb!IP6~RQEUbF0=6A{7dwib!7gKe9E2~vCPEhDWc ztro34Z6IwLZ9eT;+D_WXwDYu^L?)s*QJ3gK3@7d*mJ=I^_lPfvD|B>pLUfvRj&xyk znRMlJ&2$gwX6Sy9m`PG3W0E&1iIhjGBXyIWlUB%NvKZNb>_tu_=aK8lcgU~E>+~%2 za`cw;f%F;lmGtfOPv}1}&@zZJ7&7=Uq%)K2L(?h0r%mijJW>e-s<^#-UnC~#pv0zw)S&Uf%SoX7=Wx2;P&x&Ui zXSHMvXU%23%sRxn%*M>7!sf=7%2vsClWm$E!!E{d$sWm`&)&lRjD3THkHe57h~o%H zBgYetHBKH*1I{4M9L^@rG0qJxK`v9S2(Ch|Yg|*@SZ*n9NA48vQ{4Bsmv~rtw0Qz} za(G&JUhty4QoK&QyLiv=4)Ct>@$;GU#qyotyTiA{&(3eaAI@LQe~W)nfJH!0AWWcG z;I_bfK{i1{!AQY!!MlRX6kdu2C5ci)8KP_oi3_<3WeGJ2O$if)HH3qOi-miImqi3b zY(;j9G>E(qr4`i>4HYdD?Gs%S6BlzAJ0x~Z?43BLxTScyc!T&$39^K~M4Uve#8XMU zq=saKajE`ttK5NeNuWv1}CE_6D?CKGcHS#HIz-3ZIGRjW0$j$ z%aXe$_eowv-b=nvzEA$Qf~rEK!dZn$MP@}S#Vo~6#ji?IN&!lhN>7!^%4W(L${osI zRHRjcR8FZ(sIsWqsvc79RsE%=t`@J>sJ5ssqVA_&r9Q5~s^Oqc9c8DLp&xoo9wwa4nNHObo9y25(aM#?7MrqdR+wX!{K`_fL- zF52#zJ=j~?AGe=!5O;`k=yJq6IyhE3zI9S`+U?Zm%;N0pe9`&4i;+vd%cQG>Ym#fP z8-ts-TfN(wyNP>|`?QC=#~zPIp4^^co*iBUFE_9AUaLDyca-dy_g3}J_I|cgd}r#; zhd$gskv=zl8GNa}t$sK^cfX5%KdJWATI#C5rGJ(Ga)5C_S-^)tgTUgz#US0FqM(If z-Qc3&cOkkV$3qrF^+QWTm%@z0D#E^mTZEquUyHDhsEgQ&bdPL`qKWd0x*p9O9T9yu zhCe1XW+YZRHam7YPAje?ZaLmM{(J(Gurr|}ku@0r`KvR-m!@_LF}N^2@p zYIN#AnpE16w1srD^mDtgy8?Fg?xyVCw|i!f;hvhk$X@@wy&1w82Qua}%`-3TBkqgX zH<+c6Rh0E@zx)2q1AGTE56m4jKiH5>pBBHE=VTXr~C?7d-TlYu9noH97oc$)8Y?&*!{ zuW|O^SS4L)kW7$UvRo`w_d%z{vz+i{06ik zsbTSw_od;>CYL)JWgBan*qd^jp*gAf{T06}&swZodRsMG8?TC9t!iUw%V|g2)7qD> zgzS;ddeTIFvALu@~@lfmG^?r^1Ymd|(wGXHcv<<2bwhgHbwLeyW z+%c><+&Q8%a_foylb%tN(fdy=pFSG18yk7%`fOs{dwhB#aN^zb$md^PB){04%zTM^ znKQ*WRr-qeRqboZ*GG^KW(H=RXD8ahCid(`*M zwVZXX^$R~Ve)Mg)Z!B!4{3QG=|0VgW^SAZyms?R=Td~x5DgXdr000dR2KZVBK=uS+ z83rKI|M~y@@4z4cC;+%2a>xhtB*q6Ti6h{?;1>zwG_PrAh-)MqS&ZJAA(63~X`F?Q zRgW#5y@_LiONyJyQ^xz4A19zH7(~evY7u@S@<|L8rk{e+EqIHb;I?X^z{s63SKM0NTRpCNUiE6-(c*n&XOmBpZ;M|C zwa0%T;CbNNpl`ujp>$#F;X)D8k*ZPp(Uvi;u|aVu@y8O*C*Dq)NdA&anY{)%$9)PVX;2kbf{cd)J}3!@)O#x$n>y@F3-3 zPJh*-rh%Tpk)i3wABR^*HlF+(-F&(}w)*VL_{WKN&*xsenw)s~WNPr$gV*<_@6Ytl zKAD?(vpB!HfV?9ua=sV-Ah)FX(fE_)XX|B?FG^oIzJ6Wl`*vbA;=9fo{o3pGrXQIb zj+>OtFF$*J75?_yQrO!1xBkoF1aT|)MZ$ZUS=ujjM3N}kls=RppRt!|g+-Rtm+b`m zQ%*9ME%!m5Zr<wWf0>P7n7h!a!S!jtxM0!49RxNosmDPkgVvZ zWT~v6!lCj@^^ID;dXq-6X1bP-wvmpQE{*O7y%GHmgENMOMp?!wCXuH8W^U%z7J8P7 zR>Ib7HUyh>+xK=a?MECQIQBZ-a_(~JaBXvIc5m=F?^)wjv7^}g*v>;fS-u&58PqKQ zoPgtjRY7&Z%^@A3-C+;HA4iNuzKnVky%e(^hmYq-kV!O3@<@(O*`HdLb}9Y#t|z{-n~Gl~1?vq<~#`+pz!c5pF!>d?sHdq+BQ8gfq^EjX5ymy#b<5KQr^^2!sn74?R| zl9E#5(i9nPSw=Zpd5~XGSWui$dZ65{a$dDWZNGY)#!gLZEp=^S9eSO0-8sEs{ceL+ z!wW{$#+4=|rg>(E%rh-gEn}@htbJ@;Y%T5d?A09P9VMN_oJCxOTq$k>?z|pcp6p)C zJ4oJyoyg8#K0kcd{MM&l(-UD7wiZVKJvzs=Ll z)5G5@a!2;A`aPrjwtemo{2xa4CqK#&vM5POze4{ z@*-w3^rhdF=PT#e4%3b^?z8@Lac{EbOWs~s=z2G}IQ{@a}qApn~~fK%E4VnhHE zJ%9rlz(o^KqkKS>l>t>av;F-*01LFh2%JCxX;24aa0Fk7fea{sT4;lZFa;|J5uqSj zhzk;f=1+5t0e%8d-{bik^-B7y}K%K}H8*1GgRbH=Zh9bKVucYJOY(4S_mAR|<~OE)*_I z5q=?3BI+c@A~q&oA>k(}F8NWaRXR;ZUluR>Sguk&R6#?LPVu!;yK;d_q^gaYk~+Tz zizdAmqc(>QMOR)=U*Fjv-0*-=jd733oEgDf%EH<*%<7k`RH zDamhAUDEn?>F#ddtCZ2aPcf_IfbzjBhhz_*&*9H4KgN<*Sin?Re4M+uwp6yP>x6B^ zTvf&?;nTx42hSLu!<>J3q3ELTC51*z(~B!tTMOIbt~p*;=%TwZd#kNGyVv8c%zd

$b7f?;{`+oCIoXRx|FX%7lf%Id?J&gm0~{PBH|w;+9WfjY@|7)=VTgX z)8x$LS>@*yIu!Gif|LzZcvUu4r_}DKH)+&pR%lgf*XlIt-qah`e`~O1#AB>w;%&Om ztloUY;)fN#wZ4t7?H;?6_O~2nooJnvTzp)Qx!rPK@s#xP-%;s3>O=H3^h>2)@&6Dg z5fln%A~ecDwz$k!LTZr?1v9n_<82ks8uuX+&GZ!o|yxcqovq+v8~EO|WSdB|k?RNdfieRzu*5?u!0Z~Aw&ytL86fyqz<`<%%eC| z9JNMc(K7Tl`X0lMF~y`{8Zfh1KCBnE0{aq2!G++OaX;}^_)7d|f+^u7VV%a6rj3?^ zb~o)D(U#arCqY+Eq9LV|mdL*3r}Q@T_Zf^BdKiru?=#sjjWJW1KeOy*rDv^XQ)0W% z?#=#b+xQaGs*>60>Hvg&dKx##kY3I`Q^l(dw&ls8mfsrIS0sW)g`&}`J|(jL&6(cREz zH&8Y7FxqQeXEJJrF;}(-uq?3Zw4Sx4wNteBayaC8&1unv-__l%$bHz8(aU*9srQ5r zx9<+WD(b5M;lS{qt073JLs)J2TBLncLkuxCDsC*nD6u73Jf%8~H@$K<@1EKWsm!)4 zn~ea=jCimAg*zpSoKeQ!8-h*}0NBuX@po ztCt=$o^DQSalfkG&eMTjU+Nma*>k(DC;N`?J;grc!Ek@|K>U#Tu)xTV(Pv}r;}y^M zO-4`ozxJI8nM<2LzR_x_m%Y9o{nq<^^N0Fo@~`V#TL1~c%1VD;0!T&xxK~?S zD`EhIB7k3oTU(p8TU)=*0AOAMbVvS~tpfny83BsKP!TPKeqF1~|D19E7i|krVac5T zf&c&jAY({UO#lFGm;eBCjsO7oe*gf2>Hq+6q5uHvS^xkrRYNkj=3M9`}P{ zjx}((gKCa5+ud*xY?VJ#qrpS#HxK9B-z|9!rYUq>z^4sHC0+1zu?E(0Bp=$Jb9ic0l;-#Q}Cu>#heUgUbT4smY3re@E?g4{39`+ldZ0t znVB??s0%(T=!WM6K8~0co(i%#*1%&yF~=IX2&y^Oz(qhjU(^bPY>)*!ZDd*v&&8Bh z!b=^ER>5mMnO4ACLj`H!%v}A-q=8q+V!a0dVsw!^vU9E&00000NkvXXu0mjf4qous diff --git a/examples/images/repo-forked.png b/examples/images/repo-forked.png deleted file mode 100644 index e2a4ab90524b84a36f9f83cf89bfb6435940d8e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3427 zcmV-p4V?0cP)KLZ*U+P!Yk3u7D`G7C_d5Sg^1N_P!vC zin=ZqY^dBnSi-$`?)~G=+;`^8{N|l!o^#%F&L0l|t&J;{icvLyEQwqe9pcYUOiE@G z9{~=CpaNQe=kju;eo;{o@Sh6-_;4E#0Dv2|T&YwH|68f^1-U!`Bnkjh`MJC-0OS|| zvXdv3$pNrf05DlBm&yUKd;nm|5|fevuyO!k3MY6s05DT0_!s~%WwFr#0N5n}5{=81 z2?3}#0f3#y6UqUo?*YJG!WT&ZXeI#Q%}eL<0cd;xu*u5G<^#|+0Dwj6Klup%#WPju z$>j=_JTVIZ0FVMjxl%E=0RG>VC00!Cp$`DG+{~D805AhU@_F2#m`P3-a3UsID)*0` zWRaW`tJEk$<0e^=8Rs|2nc3k=y(D!`q|!e(AbFAt(_<4RnJ)+onq*mav{Ij&7ZWt4 z512E_8Qid_N#@D`CRrd3iJm%hl=7Ss@f_tWX|iCYMvyx-uRJ|ARLQbfr6x@j%u&uO z3!U;8M=3pJifH9M2qbYzPd+zLdAAS?>7W1!@Ie4FNQG<=gB;ip2qMS@DTsj!1psnE zz8nA`AX{1>6A9DhY(J?~EU;m7Bs@DCwxhj+6C@@jvnQVL9SaZuKv-9%dN~~c?xg^T zaH_{O1~~B)fbn6fXZ&{JpPuUFDP(yQJsbc49w?v+Owa~>Fa`^-1xIiJPw<5x2!lw7 zg(O%AJV=KukilYD3M-)m%3uR*foj+Vd!Zf;~44y}~}@2sj3gjkCph z;zDt8I36wsw;WfFtH#yiT5#uaH*f>E5!`n?9j}YG#(Us7_(Z%AzZhSFuf*@iAID$7 z-@*^!KM)867Qvk0N(dz+5i$r%2<3zwgl0kqp^q>~7$p*k+C*!j7cr8^CCZ5<#BIcb z#52U}#3AA*5|v~?awG+ll1UQMDpDos0O>U8I_Vi{jI2gBC3}z~$$WAFc|Ca_xt)BC zJVYL&s8h@-UX)l$24y9siqb^6KzT@cN2OAYsP5FcR1vj^T17ofy+j?Lex_;AtY`tW z`7{M>9j%VmLAytLN2k-x=)Ux1x}3g_-atP`e@y?R!cehO;i&LcR;bjdw5VKHd96xT zHC6RfU8q{9TB&+e^_uD{HL{wST7Vi?ZMj;F+6lEgYNP55bqDoG^(^&r^#kgc)t_q+ zHOw@EH250D8hbU)X$&$jhA|_6!DFmu>|9bw&OeVL{=&2O4u+S+MN)2>hZs5M>7S4*H(s@1G@OY4g^ zTRTWQQ+uO!tM(%uoQ{>wT%E-_J9RGTyqeCO?m3+|y>$AK>GyR}T`S#a-6gtvb-Q&( z_4M^Z^rU**^v>zM(r4-W>SyS0)<3O3Y``$^HV_$XHaKJOg00E+V~g2U?DOmqLtVpA zLxtfU!ydyiBXgrTqg6)DMvsgs#%{)G#+!{hjYmujOlF%bHEA@tZ%Q_GGfg+$YT9M` z(ahW|!EB9LtJ!mNEpv`}p?RbELkqfvk426}t;J1Cf~A{frsWRHUMtkf*(%+t#_F0i zYVBezvfg3cXM?wKw~^S?+T5|F+4|Y$**4k^*s<&)>{i*e+P$7(G9!7$#u;5RzS}$7 zi|zN>KXA}+2yCH^*nSz-+XWn&YIL~%o}ukg;=0}SjvLc0%B|e(k~`kr-+hJqN%zklE*^4^BOZTw+InVs9`JlV z%Y2q#*1lPTUPfMAuRUJ<-fZs_@7>=0K88MApIVs-RzsJS(BpGG@GFOBYsVZ3Cy&kxnzv=%(0u3lCG&4DFkg_r;POJ9h2n*$7O5`cE;^cm zPf18Qkn)uq$*tv%rgBoZr;hLfcw2cd`M&(k{9%EYphEC0%`2@U?YYoPxJfvi?vq}b z{z?=esusP;2+i1)@i8+pvo3R7oFHz_B4wpyoseiqG9~A;^|SM{`=r*=5@~;qN6wa< z5m~rwe=d@{Ah%7T;%*tI`DO(j=`>P_V z+P0Z&+pz6xb$a!!8vmN+?Yi67ZvVK0zvKE&-u0y08}{q$FWdjEPEyxjA6&qmekgFBJ4zG zyJ!3HU+sRaJ85{b=9K2C^`|MPi%*ZADLgaUA?b5ZAmbBX6}o}YWZ=R){} zOBaJLp6l}KI&;bE(#gvnmrq=AyV82qY|&GlMauX}HM->kmV z*L|*^y%Bih;!V!YtGDLd>bo6x`|h3jclz)0?>@gLzW3&S-udGcV8H~8|8+&{h!6+fjvt$b$itl_!i^OM8D!@V!&y%>5a zeL423f z`0wnFOr`k$#uGUi003M7>U;s>iU1-y0Csi&m=*!hIsl>oAl4U9Cnx3lyK>W<94EYJ zG64Li@$q+h0K|5HZ?f_6u^r>%-}V7u_W(L_CbBmG06`6)!klGoxT3rMWzoN9;C}#; zwf@{UZ(%wB001CkNK#Dz0Bv;u0CS)K0Q}tm0E1)z0C4C40PJW005CoP01%Mm?3wBS z00JjTL_t(|+MJg$a@9Z#hCewwLlMc!4QO8U$=^t6x@ zh{n$-8cDm(R#k?A?~0K7ADVMT8h`lX3dbut_Xg8fLRwvIuML{}ts&F<_H z>_<^kKqmW=pc$=&kyLp7IynUzD3cw9SlzS8w{z1#F13@>=$?;YTCCHKkV~TIlaYT8 zqFJV~bX#pzfHJ(-hH)00+oxzWz(xjtjkkVo2%;X(p*vgTY9HqD&b0Joi! zjTFW-X*^|`T0%ULBg;-Fhd$?4RA{drWN?bAfJrOzH5VwfQzucXmZ(0a9esaf_|SrW zC908D7<>i%Hu8)i=Ol{O!8ci5Oa-bdb8&PkilXuw_>!e5B91%rS2V&0BR?g_{lCDO zm7fG-*(2~Cc=60GnaTeE-+_DUl<$TVjJ727J11$7qEI(IZJ>(1{3e} z-mU}i&Foz~;}d=Iev;%Y>f@(o%mVna%6=BJK(|=`4FD?F)}eb7$`Akm002ovPDHLk FV1gV+cc}mX diff --git a/examples/images/repo-source.png b/examples/images/repo-source.png deleted file mode 100644 index c402ac47910f2b8f43682015f28270cb23763100..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3410 zcmV-Y4XyHtP)KLZ*U+P!Yk3u7D`G7C_d5Sg^1N_P!vC zin=ZqY^dBnSi-$`?)~G=+;`^8{N|l!o^#%F&L0l|t&J;{icvLyEQwqe9pcYUOiE@G z9{~=CpaNQe=kju;eo;{o@Sh6-_;4E#0Dv2|T&YwH|68f^1-U!`Bnkjh`MJC-0OS|| zvXdv3$pNrf05DlBm&yUKd;nm|5|fevuyO!k3MY6s05DT0_!s~%WwFr#0N5n}5{=81 z2?3}#0f3#y6UqUo?*YJG!WT&ZXeI#Q%}eL<0cd;xu*u5G<^#|+0Dwj6Klup%#WPju z$>j=_JTVIZ0FVMjxl%E=0RG>VC00!Cp$`DG+{~D805AhU@_F2#m`P3-a3UsID)*0` zWRaW`tJEk$<0e^=8Rs|2nc3k=y(D!`q|!e(AbFAt(_<4RnJ)+onq*mav{Ij&7ZWt4 z512E_8Qid_N#@D`CRrd3iJm%hl=7Ss@f_tWX|iCYMvyx-uRJ|ARLQbfr6x@j%u&uO z3!U;8M=3pJifH9M2qbYzPd+zLdAAS?>7W1!@Ie4FNQG<=gB;ip2qMS@DTsj!1psnE zz8nA`AX{1>6A9DhY(J?~EU;m7Bs@DCwxhj+6C@@jvnQVL9SaZuKv-9%dN~~c?xg^T zaH_{O1~~B)fbn6fXZ&{JpPuUFDP(yQJsbc49w?v+Owa~>Fa`^-1xIiJPw<5x2!lw7 zg(O%AJV=KukilYD3M-)m%3uR*foj+Vd!Zf;~44y}~}@2sj3gjkCph z;zDt8I36wsw;WfFtH#yiT5#uaH*f>E5!`n?9j}YG#(Us7_(Z%AzZhSFuf*@iAID$7 z-@*^!KM)867Qvk0N(dz+5i$r%2<3zwgl0kqp^q>~7$p*k+C*!j7cr8^CCZ5<#BIcb z#52U}#3AA*5|v~?awG+ll1UQMDpDos0O>U8I_Vi{jI2gBC3}z~$$WAFc|Ca_xt)BC zJVYL&s8h@-UX)l$24y9siqb^6KzT@cN2OAYsP5FcR1vj^T17ofy+j?Lex_;AtY`tW z`7{M>9j%VmLAytLN2k-x=)Ux1x}3g_-atP`e@y?R!cehO;i&LcR;bjdw5VKHd96xT zHC6RfU8q{9TB&+e^_uD{HL{wST7Vi?ZMj;F+6lEgYNP55bqDoG^(^&r^#kgc)t_q+ zHOw@EH250D8hbU)X$&$jhA|_6!DFmu>|9bw&OeVL{=&2O4u+S+MN)2>hZs5M>7S4*H(s@1G@OY4g^ zTRTWQQ+uO!tM(%uoQ{>wT%E-_J9RGTyqeCO?m3+|y>$AK>GyR}T`S#a-6gtvb-Q&( z_4M^Z^rU**^v>zM(r4-W>SyS0)<3O3Y``$^HV_$XHaKJOg00E+V~g2U?DOmqLtVpA zLxtfU!ydyiBXgrTqg6)DMvsgs#%{)G#+!{hjYmujOlF%bHEA@tZ%Q_GGfg+$YT9M` z(ahW|!EB9LtJ!mNEpv`}p?RbELkqfvk426}t;J1Cf~A{frsWRHUMtkf*(%+t#_F0i zYVBezvfg3cXM?wKw~^S?+T5|F+4|Y$**4k^*s<&)>{i*e+P$7(G9!7$#u;5RzS}$7 zi|zN>KXA}+2yCH^*nSz-+XWn&YIL~%o}ukg;=0}SjvLc0%B|e(k~`kr-+hJqN%zklE*^4^BOZTw+InVs9`JlV z%Y2q#*1lPTUPfMAuRUJ<-fZs_@7>=0K88MApIVs-RzsJS(BpGG@GFOBYsVZ3Cy&kxnzv=%(0u3lCG&4DFkg_r;POJ9h2n*$7O5`cE;^cm zPf18Qkn)uq$*tv%rgBoZr;hLfcw2cd`M&(k{9%EYphEC0%`2@U?YYoPxJfvi?vq}b z{z?=esusP;2+i1)@i8+pvo3R7oFHz_B4wpyoseiqG9~A;^|SM{`=r*=5@~;qN6wa< z5m~rwe=d@{Ah%7T;%*tI`DO(j=`>P_V z+P0Z&+pz6xb$a!!8vmN+?Yi67ZvVK0zvKE&-u0y08}{q$FWdjEPEyxjA6&qmekgFBJ4zG zyJ!3HU+sRaJ85{b=9K2C^`|MPi%*ZADLgaUA?b5ZAmbBX6}o}YWZ=R){} zOBaJLp6l}KI&;bE(#gvnmrq=AyV82qY|&GlMauX}HM->kmV z*L|*^y%Bih;!V!YtGDLd>bo6x`|h3jclz)0?>@gLzW3&S-udGcV8H~8|8+&{h!6+fjvt$b$itl_!i^OM8D!@V!&y%>5a zeL423f z`0wnFOr`k$#uGUi003M7>U;s>iU1-y0Csi&m=*!hIsl>oAl4U9Cnx3lyK>W<94EYJ zG64Li@$q+h0K|5HZ?f_6u^r>%-}V7u_W(L_CbBmG06`6)!klGoxT3rMWzoN9;C}#; zwf@{UZ(%wB001CkNK#Dz0Bv;u0CS)K0Q}tm0E1)z0C4C40PJW005CoP01%Mm?3wBS z00I_CL_t(|+N_s9ZWTcc#(&Nd93vk{iI(5e4IF07)J6l0@f_n){tAKPBAV|XQ z1Yo}jcM7xs#E3ita1KP--$yC4_R%T8nqk#K@7^y>L_kMEDMFu>NI3LMx z)LUp6=m8d$uGu^}81U3olS-=Bj<-9@PkcRY~i{Ah?_;=&*s;Gn-d~b5%{2N5$ o?Has|yY<~&qIeQKAL6_W02hMJ)NpJdFE7h`I{IF)0|5<6L}(j=N}5%L009EB2nYfyF)E0PvIqo$u!IC; z4PgyY5|S9AEh38G)(9eq4TbH7_UHg@yWrlIJ$6smIADL7s^P;_O;ykRc9soXl`UC*LwQJXkii*0rx|*7rI2=x7WaRkx_~XZqFJ8R3c=2Kg zf@aSAv8+BJ8+^hyay>(QR@t*blbKzsf0}bscEqRc5Hd3o(-N5RyW=zWB*zQw6Zh>* z2CROCDAbu#D`)S|J_o(lL9Yn3l*+8RdiRD_>iNz$#_IAzCna&Wl5 zSF_(rRCDD!wi#i8oAm&jYtn2_@VB%2-H*G%bN#|(6R6N?wM)3u`PiGzwuX7qmTgyF zpE)h0kuoxQ9?=kW7Y!=R@DmhU9)vwT*EZWzJ zrt+=2tqFts72yIp?|gvdLhs8Hfku^Z(){gmN%Y=K#P|%fkvgUj~HfIp3CuXqCtYGtJ#me+n+-LmP( z*XNuk%!aH8bIE@_Bj46>M*dSro|7<6vZ7WUHh5YQzN$>IJFqCb|CT!wj~R2C2%=q{ zpt8rzY$aw?W?=Ustv{jo?Ow@ZRkLe<)NItY>Cyhle*wR59dTdF6(@{5^ zAQBOB*hNtc3bkY-8{Cm$nFS@elbTtSqrt7MB{h_4y+~`!mVa}?c&N>&?P}GqdMuhQ z&@TD5Czd((DcG_Su~dKKV)Pj$-qi1WHM8_vc^O4?^!oY|tmK~i!{fjd&@_1E(T~r7 z_REZy&hMT^ySJB3W7l$4YhR`M(J7S5S~+4Q&3HPa)z%zPpisOp$^ zTEe99ig2$5_qFr!$;7A6CJ}PJmRhli>w?LC}Y`#HLGy6 zMU4EhL~dKCN5Ut;U2jd*83ShBNiu zcJB0l9>1Modc?-oM<R4?}3g}UJ%@K);kriq>)e*rh%hdqM)5Q)*+O8 zXm;SEbs@koiYS!9YXIclSg+5m_s~yrW#kKMdiRszg(gCP5HPmP7L)vCf8@fxUh6qY z@Z#TmkjzAZX{rwE+q|K~F2v5{_@vt%>yT_a#fF03SFt{0RXvDAiaY~K9CgS1O>frXgAjBCS}mEd4mIWZ$=ovd5| zR?GRdU}d6+Q`+JRW)|=v7$)XNkn3yE`!nAiSCvOB1jKT zG<1aK3s<0b0m==egTD#8i(Of=1pGDTOCho0XpIOMQ&P87cVKY1W=C6kIg z9cH=@a&zbm2+`|{(_?YC9fdm?1TY~-pwlBn?>=(~1pDKbco6jloP;0-cqRiwV1A_S zEyV0Dj8Pwy!nekzaN>{)7rgZ&_QLxK{~1yRe865^yx>}+a!ECd>#MMwddow z@CU{l+Rt$xuXuf}?ga{3IAr?Raql^c@a%sI0U5m}HvJ5O1#I%_MMPt#BH>OqUZ{-k zt>4Xzz=%jT*FVW(uYkWyx}9Gw$HdN*qU?Bit#ji(Wi7p-u|_8?h^%szIS^s^fNM}b zgGy>|=cbEufpguY5_6w~&ZLv=Bo06UF9EYIY;Er-1VK)SyF&!|J{axiE1z^(hXwVq zsFS=K-#zC}CcOs^8W{KAt+kK)jYDgDYbCXv{{rwsgqtIU3<910$CJi)s?? z_t8k{>7*0~4l~LLF7$WXT5OSq5QCTbP_l!SN|{R}3D&eWA8~0ltWh1IL+ZBX4rRSt zWF6Om3WDMu4xK^1(BF`2cL}rUCzhHAB`@j5&R-yk_l*t;mPGY|u2^o|myvcOdrg0W z%=lX;f^Vkqfp?u7*4qQq%A3Mpf!xspWBSKS@O%r*TSM}?dl(@*%{0Jm_8;(h{R__M Bt>>0;if(h(a)!="[object Function]")throw new TypeError;for(;++e>>0,f=Array(e);if(h(a)!="[object Function]")throw new TypeError(a+" is not a function");for(var g=0;g>>0,f=[],g;if(h(a)!="[object Function]")throw new TypeError(a+" is not a function");for(var i=0;i>>0;if(h(a)!="[object Function]")throw new TypeError(a+" is not a function");for(var f=0;f>>0;if(h(a)!="[object Function]")throw new TypeError(a+" is not a function");for(var f=0;f>>0;if(h(a)!="[object Function]")throw new TypeError(a+ -" is not a function");if(!c&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var e=0,f;if(arguments.length>=2)f=arguments[1];else{do{if(e in d){f=d[e++];break}if(++e>=c)throw new TypeError("reduce of empty array with no initial value");}while(1)}for(;e>>0;if(h(a)!= -"[object Function]")throw new TypeError(a+" is not a function");if(!c&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var e,c=c-1;if(arguments.length>=2)e=arguments[1];else{do{if(c in d){e=d[c--];break}if(--c<0)throw new TypeError("reduceRight of empty array with no initial value");}while(1)}do c in this&&(e=a.call(void 0,e,d[c],c,b));while(c--);return e});if(!Array.prototype.indexOf||-1!=[0,1].indexOf(1,2))Array.prototype.indexOf=function(a){var b=l&& -h(this)=="[object String]"?this.split(""):n(this),d=b.length>>>0;if(!d)return-1;var c=0;arguments.length>1&&(c=v(arguments[1]));for(c=c>=0?c:Math.max(0,d+c);c>>0;if(!d)return-1;var c=d-1;arguments.length>1&&(c=Math.min(c,v(arguments[1])));for(c=c>=0?c:d-Math.abs(c);c>=0;c--)if(c in b&& -a===b[c])return c;return-1};if(!Object.keys){var w=!0,x="toString toLocaleString valueOf hasOwnProperty isPrototypeOf propertyIsEnumerable constructor".split(" "),A=x.length,r;for(r in{toString:null})w=!1;Object.keys=function(a){if(typeof a!="object"&&typeof a!="function"||a===null)throw new TypeError("Object.keys called on a non-object");var b=[],d;for(d in a)t(a,d)&&b.push(d);if(w)for(d=0;d9999?"+":"")+("00000"+Math.abs(c)).slice(0<=c&&c<=9999?-4:-6);for(b=a.length;b--;){d=a[b];d<10&&(a[b]="0"+d)}return c+"-"+a.slice(0,2).join("-")+"T"+a.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+ -"Z"};r=!1;try{r=Date.prototype.toJSON&&null===(new Date(NaN)).toJSON()&&-1!==(new Date(-621987552E5)).toJSON().indexOf("-000001")&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(H){}r||(Date.prototype.toJSON=function(){var a=Object(this),b;a:if(s(a))b=a;else{b=a.valueOf;if(typeof b==="function"){b=b.call(a);if(s(b))break a}b=a.toString;if(typeof b==="function"){b=b.call(a);if(s(b))break a}throw new TypeError;}if(typeof b==="number"&&!isFinite(b))return null;b=a.toISOString; -if(typeof b!="function")throw new TypeError("toISOString property is not callable");return b.call(a)});var g=Date,m=function(a,b,d,c,e,f,h){var i=arguments.length;if(this instanceof g){i=i==1&&String(a)===a?new g(m.parse(a)):i>=7?new g(a,b,d,c,e,f,h):i>=6?new g(a,b,d,c,e,f):i>=5?new g(a,b,d,c,e):i>=4?new g(a,b,d,c):i>=3?new g(a,b,d):i>=2?new g(a,b):i>=1?new g(a):new g;i.constructor=m;return i}return g.apply(this,arguments)},u=function(a,b){var d=b>1?1:0;return B[b]+Math.floor((a-1969+d)/4)-Math.floor((a- -1901+d)/100)+Math.floor((a-1601+d)/400)+365*(a-1970)},C=RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),B=[0,31,59,90,120,151,181,212,243,273,304,334,365],j;for(j in g)m[j]=g[j];m.now=g.now;m.UTC=g.UTC;m.prototype=g.prototype;m.prototype.constructor=m;m.parse=function(a){var b=C.exec(a);if(b){var d=Number(b[1]),c=Number(b[2]||1)-1,e=Number(b[3]||1)-1,f=Number(b[4]||0),h=Number(b[5]||0),i=Number(b[6]|| -0),j=Number(b[7]||0),m=!b[4]||b[8]?0:Number(new g(1970,0)),k=b[9]==="-"?1:-1,l=Number(b[10]||0),b=Number(b[11]||0);if(f<(h>0||i>0||j>0?24:25)&&h<60&&i<60&&j<1E3&&c>-1&&c<12&&l<24&&b<60&&e>-1&&e'); - - var $themes = $('

').addClass('theme-selector').insertAfter('h1'); - for (var i = 0; i < themes.length; i++) { - $themes.append('' + themes[i] + ''); - } - - // display scripts on the page - $('script', $wrapper).each(function() { - var code = this.text; - if (code && code.length) { - var lines = code.split('\n'); - var indent = null; - - for (var i = 0; i < lines.length; i++) { - if (/^[ ]*$/.test(lines[i])) continue; - if (!indent) { - var lineindent = lines[i].match(/^([ ]+)/); - if (!lineindent) break; - indent = lineindent[1]; - } - lines[i] = lines[i].replace(new RegExp('^' + indent), ''); - } - - var code = $.trim(lines.join('\n')).replace(/ /g, ' '); - var $pre = $('
').addClass('js').text(code);
-			$pre.insertAfter(this);
-		}
-	});
-
-	// show current input values
-	$('select.selectized,input.selectized', $wrapper).each(function() {
-		var $container = $('
').addClass('value').html('Current Value: '); - var $value = $('').appendTo($container); - var $input = $(this); - var update = function(e) { $value.text(JSON.stringify($input.val())); } - - $(this).on('change', update); - update(); - - $container.insertAfter($input); - }); -}); \ No newline at end of file diff --git a/examples/js/jquery.js b/examples/js/jquery.js deleted file mode 100644 index f121291c4..000000000 --- a/examples/js/jquery.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v@1.8.0 jquery.com | jquery.org/license */ -(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write(""),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b
a",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="
t
",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="
",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;jq&&u.push({elem:this,matches:o.slice(q)});for(d=0;d0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;ai){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}function bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+|((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="
",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for(h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){var d=[],e=c?1:0,f=a.length;for(;e$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSelector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="

",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b0)for(e=d;e=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*\s*$/g,bz={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X
","
"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1>");try{for(;d1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]===""&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$/,co=/^\/\//,cp=/\?/,cq=/)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("
").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A===l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c$.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c$.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=c_(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file diff --git a/examples/js/jqueryui.js b/examples/js/jqueryui.js deleted file mode 100644 index 5700b3a87..000000000 --- a/examples/js/jqueryui.js +++ /dev/null @@ -1,15003 +0,0 @@ -/*! jQuery UI - v1.10.3 - 2013-05-03 -* http://jqueryui.com -* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js -* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ -(function( $, undefined ) { - -var uuid = 0, - runiqueId = /^ui-id-\d+$/; - -// $.ui might exist from components with no dependencies, e.g., $.ui.position -$.ui = $.ui || {}; - -$.extend( $.ui, { - version: "1.10.3", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - scrollParent: function() { - var scrollParent; - if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { - scrollParent = this.parents().filter(function() { - return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } else { - scrollParent = this.parents().filter(function() { - return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } - - return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - //
- value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - }, - - uniqueId: function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + (++uuid); - } - }); - }, - - removeUniqueId: function() { - return this.each(function() { - if ( runiqueId.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap=#" + mapName + "]" )[0]; - return !!img && visible( img ); - } - return ( /input|select|textarea|button|object/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support: jQuery <1.8 -if ( !$( "" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - - - - - -// deprecated -$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -$.support.selectstart = "onselectstart" in document.createElement( "div" ); -$.fn.extend({ - disableSelection: function() { - return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + - ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }, - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - } -}); - -$.extend( $.ui, { - // $.ui.plugin is deprecated. Use $.widget() extensions instead. - plugin: { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args ) { - var i, - set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } - }, - - // only used by resizable - hasScroll: function( el, a ) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; - } -}); - -})( jQuery ); - -(function( $, undefined ) { - -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); -}; - -$.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( value === undefined ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( value === undefined ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^(\w+)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -})( jQuery ); - -(function( $, undefined ) { - -var mouseHandled = false; -$( document ).mouseup( function() { - mouseHandled = false; -}); - -$.widget("ui.mouse", { - version: "1.10.3", - options: { - cancel: "input,textarea,button,select,option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind("mousedown."+this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind("click."+this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { - $.removeData(event.target, that.widgetName + ".preventClickEvent"); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("."+this.widgetName); - if ( this._mouseMoveDelegate ) { - $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if( mouseHandled ) { return; } - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { - $.removeData(event.target, this.widgetName + ".preventClickEvent"); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - $(document) - .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .bind("mouseup."+this.widgetName, this._mouseUpDelegate); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + ".preventClickEvent", true); - } - - this._mouseStop(event); - } - - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(/* event */) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } -}); - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.draggable", $.ui.mouse, { - version: "1.10.3", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false, - - // callbacks - drag: null, - start: null, - stop: null - }, - _create: function() { - - if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { - this.element[0].style.position = "relative"; - } - if (this.options.addClasses){ - this.element.addClass("ui-draggable"); - } - if (this.options.disabled){ - this.element.addClass("ui-draggable-disabled"); - } - - this._mouseInit(); - - }, - - _destroy: function() { - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); - this._mouseDestroy(); - }, - - _mouseCapture: function(event) { - - var o = this.options; - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { - return false; - } - - //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) { - return false; - } - - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { - $("
") - .css({ - width: this.offsetWidth+"px", height: this.offsetHeight+"px", - position: "absolute", opacity: "0.001", zIndex: 1000 - }) - .css($(this).offset()) - .appendTo("body"); - }); - - return true; - - }, - - _mouseStart: function(event) { - - var o = this.options; - - //Create and append the visible helper - this.helper = this._createHelper(event); - - this.helper.addClass("ui-draggable-dragging"); - - //Cache the helper size - this._cacheHelperProportions(); - - //If ddmanager is used for droppables, set the global draggable - if($.ui.ddmanager) { - $.ui.ddmanager.current = this; - } - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Store the helper's css position - this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent(); - this.offsetParent = this.helper.offsetParent(); - this.offsetParentCssPosition = this.offsetParent.css( "position" ); - - //The element's absolute position on the page minus margins - this.offset = this.positionAbs = this.element.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - //Reset scroll cache - this.offset.scroll = false; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - //Generate the original position - this.originalPosition = this.position = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Set a containment if given in the options - this._setContainment(); - - //Trigger event + callbacks - if(this._trigger("start", event) === false) { - this._clear(); - return false; - } - - //Recache the helper size - this._cacheHelperProportions(); - - //Prepare the droppable offsets - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - - - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position - - //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStart(this, event); - } - - return true; - }, - - _mouseDrag: function(event, noPropagation) { - // reset any necessary cached properties (see #5009) - if ( this.offsetParentCssPosition === "fixed" ) { - this.offset.parent = this._getParentOffset(); - } - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - //Call plugins and callbacks and use the resulting position if something is returned - if (!noPropagation) { - var ui = this._uiHash(); - if(this._trigger("drag", event, ui) === false) { - this._mouseUp({}); - return false; - } - this.position = ui.position; - } - - if(!this.options.axis || this.options.axis !== "y") { - this.helper[0].style.left = this.position.left+"px"; - } - if(!this.options.axis || this.options.axis !== "x") { - this.helper[0].style.top = this.position.top+"px"; - } - if($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); - } - - return false; - }, - - _mouseStop: function(event) { - - //If we are using droppables, inform the manager about the drop - var that = this, - dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) { - dropped = $.ui.ddmanager.drop(this, event); - } - - //if a drop comes from outside (a sortable) - if(this.dropped) { - dropped = this.dropped; - this.dropped = false; - } - - //if the original element is no longer in the DOM don't bother to continue (see #8269) - if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { - return false; - } - - if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if(that._trigger("stop", event) !== false) { - that._clear(); - } - }); - } else { - if(this._trigger("stop", event) !== false) { - this._clear(); - } - } - - return false; - }, - - _mouseUp: function(event) { - //Remove frame helpers - $("div.ui-draggable-iframeFix").each(function() { - this.parentNode.removeChild(this); - }); - - //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) - if( $.ui.ddmanager ) { - $.ui.ddmanager.dragStop(this, event); - } - - return $.ui.mouse.prototype._mouseUp.call(this, event); - }, - - cancel: function() { - - if(this.helper.is(".ui-draggable-dragging")) { - this._mouseUp({}); - } else { - this._clear(); - } - - return this; - - }, - - _getHandle: function(event) { - return this.options.handle ? - !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : - true; - }, - - _createHelper: function(event) { - - var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); - - if(!helper.parents("body").length) { - helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); - } - - if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { - helper.css("position", "absolute"); - } - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ("left" in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ("right" in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ("top" in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ("bottom" in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - //This needs to be actually done for all browsers, since pageX/pageY includes this information - //Ugly IE fix - if((this.offsetParent[0] === document.body) || - (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition === "relative") { - var p = this.element.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.element.css("marginLeft"),10) || 0), - top: (parseInt(this.element.css("marginTop"),10) || 0), - right: (parseInt(this.element.css("marginRight"),10) || 0), - bottom: (parseInt(this.element.css("marginBottom"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var over, c, ce, - o = this.options; - - if ( !o.containment ) { - this.containment = null; - return; - } - - if ( o.containment === "window" ) { - this.containment = [ - $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, - $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, - $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment === "document") { - this.containment = [ - 0, - 0, - $( document ).width() - this.helperProportions.width - this.margins.left, - ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment.constructor === Array ) { - this.containment = o.containment; - return; - } - - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; - } - - c = $( o.containment ); - ce = c[ 0 ]; - - if( !ce ) { - return; - } - - over = c.css( "overflow" ) !== "hidden"; - - this.containment = [ - ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), - ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , - ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, - ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom - ]; - this.relative_container = c; - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) { - pos = this.position; - } - - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; - - //Cache the scroll - if (!this.offset.scroll) { - this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; - } - - return { - top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) - ), - left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) - ) - }; - - }, - - _generatePosition: function(event) { - - var containment, co, top, left, - o = this.options, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, - pageX = event.pageX, - pageY = event.pageY; - - //Cache the scroll - if (!this.offset.scroll) { - this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - // If we are not dragging yet, we won't check for options - if ( this.originalPosition ) { - if ( this.containment ) { - if ( this.relative_container ){ - co = this.relative_container.offset(); - containment = [ - this.containment[ 0 ] + co.left, - this.containment[ 1 ] + co.top, - this.containment[ 2 ] + co.left, - this.containment[ 3 ] + co.top - ]; - } - else { - containment = this.containment; - } - - if(event.pageX - this.offset.click.left < containment[0]) { - pageX = containment[0] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top < containment[1]) { - pageY = containment[1] + this.offset.click.top; - } - if(event.pageX - this.offset.click.left > containment[2]) { - pageX = containment[2] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top > containment[3]) { - pageY = containment[3] + this.offset.click.top; - } - } - - if(o.grid) { - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) - top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; - pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; - pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) - ), - left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) - ) - }; - - }, - - _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); - if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { - this.helper.remove(); - } - this.helper = null; - this.cancelHelperRemoval = false; - }, - - // From now on bulk stuff - mainly helpers - - _trigger: function(type, event, ui) { - ui = ui || this._uiHash(); - $.ui.plugin.call(this, type, [event, ui]); - //The absolute position has to be recalculated after plugins - if(type === "drag") { - this.positionAbs = this._convertPositionTo("absolute"); - } - return $.Widget.prototype._trigger.call(this, type, event, ui); - }, - - plugins: {}, - - _uiHash: function() { - return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs - }; - } - -}); - -$.ui.plugin.add("draggable", "connectToSortable", { - start: function(event, ui) { - - var inst = $(this).data("ui-draggable"), o = inst.options, - uiSortable = $.extend({}, ui, { item: inst.element }); - inst.sortables = []; - $(o.connectToSortable).each(function() { - var sortable = $.data(this, "ui-sortable"); - if (sortable && !sortable.options.disabled) { - inst.sortables.push({ - instance: sortable, - shouldRevert: sortable.options.revert - }); - sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). - sortable._trigger("activate", event, uiSortable); - } - }); - - }, - stop: function(event, ui) { - - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper - var inst = $(this).data("ui-draggable"), - uiSortable = $.extend({}, ui, { item: inst.element }); - - $.each(inst.sortables, function() { - if(this.instance.isOver) { - - this.instance.isOver = 0; - - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) - - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" - if(this.shouldRevert) { - this.instance.options.revert = this.shouldRevert; - } - - //Trigger the stop of the sortable - this.instance._mouseStop(event); - - this.instance.options.helper = this.instance.options._helper; - - //If the helper has been the original item, restore properties in the sortable - if(inst.options.helper === "original") { - this.instance.currentItem.css({ top: "auto", left: "auto" }); - } - - } else { - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance - this.instance._trigger("deactivate", event, uiSortable); - } - - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("ui-draggable"), that = this; - - $.each(inst.sortables, function() { - - var innermostIntersecting = false, - thisSortable = this; - - //Copy over some variables to allow calling the sortable's native _intersectsWith - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - - if(this.instance._intersectsWith(this.instance.containerCache)) { - innermostIntersecting = true; - $.each(inst.sortables, function () { - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - if (this !== thisSortable && - this.instance._intersectsWith(this.instance.containerCache) && - $.contains(thisSortable.instance.element[0], this.instance.element[0]) - ) { - innermostIntersecting = false; - } - return innermostIntersecting; - }); - } - - - if(innermostIntersecting) { - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if(!this.instance.isOver) { - - this.instance.isOver = 1; - //Now we fake the start of dragging for the sortable instance, - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; - - event.target = this.instance.currentItem[0]; - this.instance._mouseCapture(event, true); - this.instance._mouseStart(event, true, true); - - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes - this.instance.offset.click.top = inst.offset.click.top; - this.instance.offset.click.left = inst.offset.click.left; - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; - - inst._trigger("toSortable", event); - inst.dropped = this.instance.element; //draggable revert needs that - //hack so receive/update callbacks work (mostly) - inst.currentItem = inst.element; - this.instance.fromOutside = inst; - - } - - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if(this.instance.currentItem) { - this.instance._mouseDrag(event); - } - - } else { - - //If it doesn't intersect with the sortable, and it intersected before, - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval - if(this.instance.isOver) { - - this.instance.isOver = 0; - this.instance.cancelHelperRemoval = true; - - //Prevent reverting on this forced stop - this.instance.options.revert = false; - - // The out event needs to be triggered independently - this.instance._trigger("out", event, this.instance._uiHash(this.instance)); - - this.instance._mouseStop(event, true); - this.instance.options.helper = this.instance.options._helper; - - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size - this.instance.currentItem.remove(); - if(this.instance.placeholder) { - this.instance.placeholder.remove(); - } - - inst._trigger("fromSortable", event); - inst.dropped = false; //draggable revert needs that - } - - } - - }); - - } -}); - -$.ui.plugin.add("draggable", "cursor", { - start: function() { - var t = $("body"), o = $(this).data("ui-draggable").options; - if (t.css("cursor")) { - o._cursor = t.css("cursor"); - } - t.css("cursor", o.cursor); - }, - stop: function() { - var o = $(this).data("ui-draggable").options; - if (o._cursor) { - $("body").css("cursor", o._cursor); - } - } -}); - -$.ui.plugin.add("draggable", "opacity", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data("ui-draggable").options; - if(t.css("opacity")) { - o._opacity = t.css("opacity"); - } - t.css("opacity", o.opacity); - }, - stop: function(event, ui) { - var o = $(this).data("ui-draggable").options; - if(o._opacity) { - $(ui.helper).css("opacity", o._opacity); - } - } -}); - -$.ui.plugin.add("draggable", "scroll", { - start: function() { - var i = $(this).data("ui-draggable"); - if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { - i.overflowOffset = i.scrollParent.offset(); - } - }, - drag: function( event ) { - - var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; - - if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { - - if(!o.axis || o.axis !== "x") { - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; - } - } - - if(!o.axis || o.axis !== "y") { - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; - } - } - - } else { - - if(!o.axis || o.axis !== "x") { - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - } - - if(!o.axis || o.axis !== "y") { - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(i, event); - } - - } -}); - -$.ui.plugin.add("draggable", "snap", { - start: function() { - - var i = $(this).data("ui-draggable"), - o = i.options; - - i.snapElements = []; - - $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { - var $t = $(this), - $o = $t.offset(); - if(this !== i.element[0]) { - i.snapElements.push({ - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - }); - } - }); - - }, - drag: function(event, ui) { - - var ts, bs, ls, rs, l, r, t, b, i, first, - inst = $(this).data("ui-draggable"), - o = inst.options, - d = o.snapTolerance, - x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - - for (i = inst.snapElements.length - 1; i >= 0; i--){ - - l = inst.snapElements[i].left; - r = l + inst.snapElements[i].width; - t = inst.snapElements[i].top; - b = t + inst.snapElements[i].height; - - if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { - if(inst.snapElements[i].snapping) { - (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - } - inst.snapElements[i].snapping = false; - continue; - } - - if(o.snapMode !== "inner") { - ts = Math.abs(t - y2) <= d; - bs = Math.abs(b - y1) <= d; - ls = Math.abs(l - x2) <= d; - rs = Math.abs(r - x1) <= d; - if(ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - } - if(bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; - } - if(ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; - } - if(rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; - } - } - - first = (ts || bs || ls || rs); - - if(o.snapMode !== "outer") { - ts = Math.abs(t - y1) <= d; - bs = Math.abs(b - y2) <= d; - ls = Math.abs(l - x1) <= d; - rs = Math.abs(r - x2) <= d; - if(ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; - } - if(bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - } - if(ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; - } - if(rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; - } - } - - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - } - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); - - } - - } -}); - -$.ui.plugin.add("draggable", "stack", { - start: function() { - var min, - o = this.data("ui-draggable").options, - group = $.makeArray($(o.stack)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); - }); - - if (!group.length) { return; } - - min = parseInt($(group[0]).css("zIndex"), 10) || 0; - $(group).each(function(i) { - $(this).css("zIndex", min + i); - }); - this.css("zIndex", (min + group.length)); - } -}); - -$.ui.plugin.add("draggable", "zIndex", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data("ui-draggable").options; - if(t.css("zIndex")) { - o._zIndex = t.css("zIndex"); - } - t.css("zIndex", o.zIndex); - }, - stop: function(event, ui) { - var o = $(this).data("ui-draggable").options; - if(o._zIndex) { - $(ui.helper).css("zIndex", o._zIndex); - } - } -}); - -})(jQuery); - -(function( $, undefined ) { - -function isOverAxis( x, reference, size ) { - return ( x > reference ) && ( x < ( reference + size ) ); -} - -$.widget("ui.droppable", { - version: "1.10.3", - widgetEventPrefix: "drop", - options: { - accept: "*", - activeClass: false, - addClasses: true, - greedy: false, - hoverClass: false, - scope: "default", - tolerance: "intersect", - - // callbacks - activate: null, - deactivate: null, - drop: null, - out: null, - over: null - }, - _create: function() { - - var o = this.options, - accept = o.accept; - - this.isover = false; - this.isout = true; - - this.accept = $.isFunction(accept) ? accept : function(d) { - return d.is(accept); - }; - - //Store the droppable's proportions - this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; - - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; - $.ui.ddmanager.droppables[o.scope].push(this); - - (o.addClasses && this.element.addClass("ui-droppable")); - - }, - - _destroy: function() { - var i = 0, - drop = $.ui.ddmanager.droppables[this.options.scope]; - - for ( ; i < drop.length; i++ ) { - if ( drop[i] === this ) { - drop.splice(i, 1); - } - } - - this.element.removeClass("ui-droppable ui-droppable-disabled"); - }, - - _setOption: function(key, value) { - - if(key === "accept") { - this.accept = $.isFunction(value) ? value : function(d) { - return d.is(value); - }; - } - $.Widget.prototype._setOption.apply(this, arguments); - }, - - _activate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) { - this.element.addClass(this.options.activeClass); - } - if(draggable){ - this._trigger("activate", event, this.ui(draggable)); - } - }, - - _deactivate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) { - this.element.removeClass(this.options.activeClass); - } - if(draggable){ - this._trigger("deactivate", event, this.ui(draggable)); - } - }, - - _over: function(event) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { - return; - } - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) { - this.element.addClass(this.options.hoverClass); - } - this._trigger("over", event, this.ui(draggable)); - } - - }, - - _out: function(event) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { - return; - } - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) { - this.element.removeClass(this.options.hoverClass); - } - this._trigger("out", event, this.ui(draggable)); - } - - }, - - _drop: function(event,custom) { - - var draggable = custom || $.ui.ddmanager.current, - childrenIntersection = false; - - // Bail if draggable and droppable are same element - if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { - return false; - } - - this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { - var inst = $.data(this, "ui-droppable"); - if( - inst.options.greedy && - !inst.options.disabled && - inst.options.scope === draggable.options.scope && - inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && - $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) - ) { childrenIntersection = true; return false; } - }); - if(childrenIntersection) { - return false; - } - - if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.activeClass) { - this.element.removeClass(this.options.activeClass); - } - if(this.options.hoverClass) { - this.element.removeClass(this.options.hoverClass); - } - this._trigger("drop", event, this.ui(draggable)); - return this.element; - } - - return false; - - }, - - ui: function(c) { - return { - draggable: (c.currentItem || c.element), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - } - -}); - -$.ui.intersect = function(draggable, droppable, toleranceMode) { - - if (!droppable.offset) { - return false; - } - - var draggableLeft, draggableTop, - x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, - y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, r = l + droppable.proportions.width, - t = droppable.offset.top, b = t + droppable.proportions.height; - - switch (toleranceMode) { - case "fit": - return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); - case "intersect": - return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half - x2 - (draggable.helperProportions.width / 2) < r && // Left Half - t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half - y2 - (draggable.helperProportions.height / 2) < b ); // Top Half - case "pointer": - draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); - draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); - return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); - case "touch": - return ( - (y1 >= t && y1 <= b) || // Top edge touching - (y2 >= t && y2 <= b) || // Bottom edge touching - (y1 < t && y2 > b) // Surrounded vertically - ) && ( - (x1 >= l && x1 <= r) || // Left edge touching - (x2 >= l && x2 <= r) || // Right edge touching - (x1 < l && x2 > r) // Surrounded horizontally - ); - default: - return false; - } - -}; - -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { "default": [] }, - prepareOffsets: function(t, event) { - - var i, j, - m = $.ui.ddmanager.droppables[t.options.scope] || [], - type = event ? event.type : null, // workaround for #2317 - list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); - - droppablesLoop: for (i = 0; i < m.length; i++) { - - //No disabled and non-accepted - if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { - continue; - } - - // Filter out elements in the current dragged item - for (j=0; j < list.length; j++) { - if(list[j] === m[i].element[0]) { - m[i].proportions.height = 0; - continue droppablesLoop; - } - } - - m[i].visible = m[i].element.css("display") !== "none"; - if(!m[i].visible) { - continue; - } - - //Activate the droppable if used directly from draggables - if(type === "mousedown") { - m[i]._activate.call(m[i], event); - } - - m[i].offset = m[i].element.offset(); - m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; - - } - - }, - drop: function(draggable, event) { - - var dropped = false; - // Create a copy of the droppables in case the list changes during the drop (#9116) - $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { - - if(!this.options) { - return; - } - if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { - dropped = this._drop.call(this, event) || dropped; - } - - if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - this.isout = true; - this.isover = false; - this._deactivate.call(this, event); - } - - }); - return dropped; - - }, - dragStart: function( draggable, event ) { - //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { - if( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - }); - }, - drag: function(draggable, event) { - - //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. - if(draggable.options.refreshPositions) { - $.ui.ddmanager.prepareOffsets(draggable, event); - } - - //Run through all droppables and check their positions based on specific tolerance options - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { - - if(this.options.disabled || this.greedyChild || !this.visible) { - return; - } - - var parentInstance, scope, parent, - intersects = $.ui.intersect(draggable, this, this.options.tolerance), - c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); - if(!c) { - return; - } - - if (this.options.greedy) { - // find droppable parents with same scope - scope = this.options.scope; - parent = this.element.parents(":data(ui-droppable)").filter(function () { - return $.data(this, "ui-droppable").options.scope === scope; - }); - - if (parent.length) { - parentInstance = $.data(parent[0], "ui-droppable"); - parentInstance.greedyChild = (c === "isover"); - } - } - - // we just moved into a greedy child - if (parentInstance && c === "isover") { - parentInstance.isover = false; - parentInstance.isout = true; - parentInstance._out.call(parentInstance, event); - } - - this[c] = true; - this[c === "isout" ? "isover" : "isout"] = false; - this[c === "isover" ? "_over" : "_out"].call(this, event); - - // we just moved out of a greedy child - if (parentInstance && c === "isout") { - parentInstance.isout = false; - parentInstance.isover = true; - parentInstance._over.call(parentInstance, event); - } - }); - - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); - //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) - if( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - } -}; - -})(jQuery); - -(function( $, undefined ) { - -function num(v) { - return parseInt(v, 10) || 0; -} - -function isNumber(value) { - return !isNaN(parseInt(value, 10)); -} - -$.widget("ui.resizable", $.ui.mouse, { - version: "1.10.3", - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - // See #7960 - zIndex: 90, - - // callbacks - resize: null, - start: null, - stop: null - }, - _create: function() { - - var n, i, handle, axis, hname, - that = this, - o = this.options; - this.element.addClass("ui-resizable"); - - $.extend(this, { - _aspectRatio: !!(o.aspectRatio), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null - }); - - //Wrap the element if it cannot hold child nodes - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { - - //Create a wrapper element and set the wrapper to the new current internal element - this.element.wrap( - $("
").css({ - position: this.element.css("position"), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css("top"), - left: this.element.css("left") - }) - ); - - //Overwrite the original this.element - this.element = this.element.parent().data( - "ui-resizable", this.element.data("ui-resizable") - ); - - this.elementIsWrapper = true; - - //Move margins to the wrapper - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); - - //Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css("resize"); - this.originalElement.css("resize", "none"); - - //Push the actual element to our proportionallyResize internal array - this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); - - // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css("margin") }); - - // fix handlers offset - this._proportionallyResize(); - - } - - this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); - if(this.handles.constructor === String) { - - if ( this.handles === "all") { - this.handles = "n,e,s,w,se,sw,ne,nw"; - } - - n = this.handles.split(","); - this.handles = {}; - - for(i = 0; i < n.length; i++) { - - handle = $.trim(n[i]); - hname = "ui-resizable-"+handle; - axis = $("
"); - - // Apply zIndex to all handles - see #7960 - axis.css({ zIndex: o.zIndex }); - - //TODO : What's going on here? - if ("se" === handle) { - axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); - } - - //Insert into internal handles object and append to element - this.handles[handle] = ".ui-resizable-"+handle; - this.element.append(axis); - } - - } - - this._renderAxis = function(target) { - - var i, axis, padPos, padWrapper; - - target = target || this.element; - - for(i in this.handles) { - - if(this.handles[i].constructor === String) { - this.handles[i] = $(this.handles[i], this.element).show(); - } - - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { - - axis = $(this.handles[i], this.element); - - //Checking the correct pad and border - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); - - //The padding type i have to apply... - padPos = [ "padding", - /ne|nw|n/.test(i) ? "Top" : - /se|sw|s/.test(i) ? "Bottom" : - /^e$/.test(i) ? "Right" : "Left" ].join(""); - - target.css(padPos, padWrapper); - - this._proportionallyResize(); - - } - - //TODO: What's that good for? There's not anything to be executed left - if(!$(this.handles[i]).length) { - continue; - } - } - }; - - //TODO: make renderAxis a prototype function - this._renderAxis(this.element); - - this._handles = $(".ui-resizable-handle", this.element) - .disableSelection(); - - //Matching axis name - this._handles.mouseover(function() { - if (!that.resizing) { - if (this.className) { - axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); - } - //Axis, default = se - that.axis = axis && axis[1] ? axis[1] : "se"; - } - }); - - //If we want to auto hide the elements - if (o.autoHide) { - this._handles.hide(); - $(this.element) - .addClass("ui-resizable-autohide") - .mouseenter(function() { - if (o.disabled) { - return; - } - $(this).removeClass("ui-resizable-autohide"); - that._handles.show(); - }) - .mouseleave(function(){ - if (o.disabled) { - return; - } - if (!that.resizing) { - $(this).addClass("ui-resizable-autohide"); - that._handles.hide(); - } - }); - } - - //Initialize the mouse interaction - this._mouseInit(); - - }, - - _destroy: function() { - - this._mouseDestroy(); - - var wrapper, - _destroy = function(exp) { - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); - }; - - //TODO: Unwrap at same DOM position - if (this.elementIsWrapper) { - _destroy(this.element); - wrapper = this.element; - this.originalElement.css({ - position: wrapper.css("position"), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css("top"), - left: wrapper.css("left") - }).insertAfter( wrapper ); - wrapper.remove(); - } - - this.originalElement.css("resize", this.originalResizeStyle); - _destroy(this.originalElement); - - return this; - }, - - _mouseCapture: function(event) { - var i, handle, - capture = false; - - for (i in this.handles) { - handle = $(this.handles[i])[0]; - if (handle === event.target || $.contains(handle, event.target)) { - capture = true; - } - } - - return !this.options.disabled && capture; - }, - - _mouseStart: function(event) { - - var curleft, curtop, cursor, - o = this.options, - iniPos = this.element.position(), - el = this.element; - - this.resizing = true; - - // bugfix for http://dev.jquery.com/ticket/1749 - if ( (/absolute/).test( el.css("position") ) ) { - el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); - } else if (el.is(".ui-draggable")) { - el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); - } - - this._renderProxy(); - - curleft = num(this.helper.css("left")); - curtop = num(this.helper.css("top")); - - if (o.containment) { - curleft += $(o.containment).scrollLeft() || 0; - curtop += $(o.containment).scrollTop() || 0; - } - - //Store needed variables - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalPosition = { left: curleft, top: curtop }; - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; - - //Aspect Ratio - this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); - - cursor = $(".ui-resizable-" + this.axis).css("cursor"); - $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); - - el.addClass("ui-resizable-resizing"); - this._propagate("start", event); - return true; - }, - - _mouseDrag: function(event) { - - //Increase performance, avoid regex - var data, - el = this.helper, props = {}, - smp = this.originalMousePosition, - a = this.axis, - prevTop = this.position.top, - prevLeft = this.position.left, - prevWidth = this.size.width, - prevHeight = this.size.height, - dx = (event.pageX-smp.left)||0, - dy = (event.pageY-smp.top)||0, - trigger = this._change[a]; - - if (!trigger) { - return false; - } - - // Calculate the attrs that will be change - data = trigger.apply(this, [event, dx, dy]); - - // Put this in the mouseDrag handler since the user can start pressing shift while resizing - this._updateVirtualBoundaries(event.shiftKey); - if (this._aspectRatio || event.shiftKey) { - data = this._updateRatio(data, event); - } - - data = this._respectSize(data, event); - - this._updateCache(data); - - // plugins callbacks need to be called first - this._propagate("resize", event); - - if (this.position.top !== prevTop) { - props.top = this.position.top + "px"; - } - if (this.position.left !== prevLeft) { - props.left = this.position.left + "px"; - } - if (this.size.width !== prevWidth) { - props.width = this.size.width + "px"; - } - if (this.size.height !== prevHeight) { - props.height = this.size.height + "px"; - } - el.css(props); - - if (!this._helper && this._proportionallyResizeElements.length) { - this._proportionallyResize(); - } - - // Call the user callback if the element was resized - if ( ! $.isEmptyObject(props) ) { - this._trigger("resize", event, this.ui()); - } - - return false; - }, - - _mouseStop: function(event) { - - this.resizing = false; - var pr, ista, soffseth, soffsetw, s, left, top, - o = this.options, that = this; - - if(this._helper) { - - pr = this._proportionallyResizeElements; - ista = pr.length && (/textarea/i).test(pr[0].nodeName); - soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; - soffsetw = ista ? 0 : that.sizeDiff.width; - - s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; - left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; - top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; - - if (!o.animate) { - this.element.css($.extend(s, { top: top, left: left })); - } - - that.helper.height(that.size.height); - that.helper.width(that.size.width); - - if (this._helper && !o.animate) { - this._proportionallyResize(); - } - } - - $("body").css("cursor", "auto"); - - this.element.removeClass("ui-resizable-resizing"); - - this._propagate("stop", event); - - if (this._helper) { - this.helper.remove(); - } - - return false; - - }, - - _updateVirtualBoundaries: function(forceAspectRatio) { - var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, - o = this.options; - - b = { - minWidth: isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity - }; - - if(this._aspectRatio || forceAspectRatio) { - // We want to create an enclosing box whose aspect ration is the requested one - // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; - - if(pMinWidth > b.minWidth) { - b.minWidth = pMinWidth; - } - if(pMinHeight > b.minHeight) { - b.minHeight = pMinHeight; - } - if(pMaxWidth < b.maxWidth) { - b.maxWidth = pMaxWidth; - } - if(pMaxHeight < b.maxHeight) { - b.maxHeight = pMaxHeight; - } - } - this._vBoundaries = b; - }, - - _updateCache: function(data) { - this.offset = this.helper.offset(); - if (isNumber(data.left)) { - this.position.left = data.left; - } - if (isNumber(data.top)) { - this.position.top = data.top; - } - if (isNumber(data.height)) { - this.size.height = data.height; - } - if (isNumber(data.width)) { - this.size.width = data.width; - } - }, - - _updateRatio: function( data ) { - - var cpos = this.position, - csize = this.size, - a = this.axis; - - if (isNumber(data.height)) { - data.width = (data.height * this.aspectRatio); - } else if (isNumber(data.width)) { - data.height = (data.width / this.aspectRatio); - } - - if (a === "sw") { - data.left = cpos.left + (csize.width - data.width); - data.top = null; - } - if (a === "nw") { - data.top = cpos.top + (csize.height - data.height); - data.left = cpos.left + (csize.width - data.width); - } - - return data; - }, - - _respectSize: function( data ) { - - var o = this._vBoundaries, - a = this.axis, - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), - dw = this.originalPosition.left + this.originalSize.width, - dh = this.position.top + this.size.height, - cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); - if (isminw) { - data.width = o.minWidth; - } - if (isminh) { - data.height = o.minHeight; - } - if (ismaxw) { - data.width = o.maxWidth; - } - if (ismaxh) { - data.height = o.maxHeight; - } - - if (isminw && cw) { - data.left = dw - o.minWidth; - } - if (ismaxw && cw) { - data.left = dw - o.maxWidth; - } - if (isminh && ch) { - data.top = dh - o.minHeight; - } - if (ismaxh && ch) { - data.top = dh - o.maxHeight; - } - - // fixing jump error on top/left - bug #2330 - if (!data.width && !data.height && !data.left && data.top) { - data.top = null; - } else if (!data.width && !data.height && !data.top && data.left) { - data.left = null; - } - - return data; - }, - - _proportionallyResize: function() { - - if (!this._proportionallyResizeElements.length) { - return; - } - - var i, j, borders, paddings, prel, - element = this.helper || this.element; - - for ( i=0; i < this._proportionallyResizeElements.length; i++) { - - prel = this._proportionallyResizeElements[i]; - - if (!this.borderDif) { - this.borderDif = []; - borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; - paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; - - for ( j = 0; j < borders.length; j++ ) { - this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); - } - } - - prel.css({ - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 - }); - - } - - }, - - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); - - if(this._helper) { - - this.helper = this.helper || $("
"); - - this.helper.addClass(this._helper).css({ - width: this.element.outerWidth() - 1, - height: this.element.outerHeight() - 1, - position: "absolute", - left: this.elementOffset.left +"px", - top: this.elementOffset.top +"px", - zIndex: ++o.zIndex //TODO: Don't modify option - }); - - this.helper - .appendTo("body") - .disableSelection(); - - } else { - this.helper = this.element; - } - - }, - - _change: { - e: function(event, dx) { - return { width: this.originalSize.width + dx }; - }, - w: function(event, dx) { - var cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function(event, dx, dy) { - var cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function(event, dx, dy) { - return { height: this.originalSize.height + dy }; - }, - se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - }, - ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - } - }, - - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.ui()]); - (n !== "resize" && this._trigger(n, event, this.ui())); - }, - - plugins: {}, - - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -}); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add("resizable", "animate", { - - stop: function( event ) { - var that = $(this).data("ui-resizable"), - o = that.options, - pr = that._proportionallyResizeElements, - ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width, - style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, - left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; - - that.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseInt(that.element.css("width"), 10), - height: parseInt(that.element.css("height"), 10), - top: parseInt(that.element.css("top"), 10), - left: parseInt(that.element.css("left"), 10) - }; - - if (pr && pr.length) { - $(pr[0]).css({ width: data.width, height: data.height }); - } - - // propagating resize, and updating values for each animation step - that._updateCache(data); - that._propagate("resize", event); - - } - } - ); - } - -}); - -$.ui.plugin.add("resizable", "containment", { - - start: function() { - var element, p, co, ch, cw, width, height, - that = $(this).data("ui-resizable"), - o = that.options, - el = that.element, - oc = o.containment, - ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; - - if (!ce) { - return; - } - - that.containerElement = $(ce); - - if (/document/.test(oc) || oc === document) { - that.containerOffset = { left: 0, top: 0 }; - that.containerPosition = { left: 0, top: 0 }; - - that.parentData = { - element: $(document), left: 0, top: 0, - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight - }; - } - - // i'm a node, so compute top, left, right, bottom - else { - element = $(ce); - p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); - - that.containerOffset = element.offset(); - that.containerPosition = element.position(); - that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; - - co = that.containerOffset; - ch = that.containerSize.height; - cw = that.containerSize.width; - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); - height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); - - that.parentData = { - element: ce, left: co.left, top: co.top, width: width, height: height - }; - } - }, - - resize: function( event ) { - var woset, hoset, isParent, isOffsetRelative, - that = $(this).data("ui-resizable"), - o = that.options, - co = that.containerOffset, cp = that.position, - pRatio = that._aspectRatio || event.shiftKey, - cop = { top:0, left:0 }, ce = that.containerElement; - - if (ce[0] !== document && (/static/).test(ce.css("position"))) { - cop = co; - } - - if (cp.left < (that._helper ? co.left : 0)) { - that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); - if (pRatio) { - that.size.height = that.size.width / that.aspectRatio; - } - that.position.left = o.helper ? co.left : 0; - } - - if (cp.top < (that._helper ? co.top : 0)) { - that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); - if (pRatio) { - that.size.width = that.size.height * that.aspectRatio; - } - that.position.top = that._helper ? co.top : 0; - } - - that.offset.left = that.parentData.left+that.position.left; - that.offset.top = that.parentData.top+that.position.top; - - woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); - hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); - - isParent = that.containerElement.get(0) === that.element.parent().get(0); - isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); - - if(isParent && isOffsetRelative) { - woset -= that.parentData.left; - } - - if (woset + that.size.width >= that.parentData.width) { - that.size.width = that.parentData.width - woset; - if (pRatio) { - that.size.height = that.size.width / that.aspectRatio; - } - } - - if (hoset + that.size.height >= that.parentData.height) { - that.size.height = that.parentData.height - hoset; - if (pRatio) { - that.size.width = that.size.height * that.aspectRatio; - } - } - }, - - stop: function(){ - var that = $(this).data("ui-resizable"), - o = that.options, - co = that.containerOffset, - cop = that.containerPosition, - ce = that.containerElement, - helper = $(that.helper), - ho = helper.offset(), - w = helper.outerWidth() - that.sizeDiff.width, - h = helper.outerHeight() - that.sizeDiff.height; - - if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - } - - if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - } - - } -}); - -$.ui.plugin.add("resizable", "alsoResize", { - - start: function () { - var that = $(this).data("ui-resizable"), - o = that.options, - _store = function (exp) { - $(exp).each(function() { - var el = $(this); - el.data("ui-resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) - }); - }); - }; - - if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function (exp) { _store(exp); }); } - }else{ - _store(o.alsoResize); - } - }, - - resize: function (event, ui) { - var that = $(this).data("ui-resizable"), - o = that.options, - os = that.originalSize, - op = that.originalPosition, - delta = { - height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, - top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 - }, - - _alsoResize = function (exp, c) { - $(exp).each(function() { - var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, - css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; - - $.each(css, function (i, prop) { - var sum = (start[prop]||0) + (delta[prop]||0); - if (sum && sum >= 0) { - style[prop] = sum || null; - } - }); - - el.css(style); - }); - }; - - if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ - _alsoResize(o.alsoResize); - } - }, - - stop: function () { - $(this).removeData("resizable-alsoresize"); - } -}); - -$.ui.plugin.add("resizable", "ghost", { - - start: function() { - - var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; - - that.ghost = that.originalElement.clone(); - that.ghost - .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) - .addClass("ui-resizable-ghost") - .addClass(typeof o.ghost === "string" ? o.ghost : ""); - - that.ghost.appendTo(that.helper); - - }, - - resize: function(){ - var that = $(this).data("ui-resizable"); - if (that.ghost) { - that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); - } - }, - - stop: function() { - var that = $(this).data("ui-resizable"); - if (that.ghost && that.helper) { - that.helper.get(0).removeChild(that.ghost.get(0)); - } - } - -}); - -$.ui.plugin.add("resizable", "grid", { - - resize: function() { - var that = $(this).data("ui-resizable"), - o = that.options, - cs = that.size, - os = that.originalSize, - op = that.originalPosition, - a = that.axis, - grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, - gridX = (grid[0]||1), - gridY = (grid[1]||1), - ox = Math.round((cs.width - os.width) / gridX) * gridX, - oy = Math.round((cs.height - os.height) / gridY) * gridY, - newWidth = os.width + ox, - newHeight = os.height + oy, - isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), - isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), - isMinWidth = o.minWidth && (o.minWidth > newWidth), - isMinHeight = o.minHeight && (o.minHeight > newHeight); - - o.grid = grid; - - if (isMinWidth) { - newWidth = newWidth + gridX; - } - if (isMinHeight) { - newHeight = newHeight + gridY; - } - if (isMaxWidth) { - newWidth = newWidth - gridX; - } - if (isMaxHeight) { - newHeight = newHeight - gridY; - } - - if (/^(se|s|e)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - } else if (/^(ne)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.top = op.top - oy; - } else if (/^(sw)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.left = op.left - ox; - } else { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.top = op.top - oy; - that.position.left = op.left - ox; - } - } - -}); - -})(jQuery); - -(function( $, undefined ) { - -$.widget("ui.selectable", $.ui.mouse, { - version: "1.10.3", - options: { - appendTo: "body", - autoRefresh: true, - distance: 0, - filter: "*", - tolerance: "touch", - - // callbacks - selected: null, - selecting: null, - start: null, - stop: null, - unselected: null, - unselecting: null - }, - _create: function() { - var selectees, - that = this; - - this.element.addClass("ui-selectable"); - - this.dragged = false; - - // cache selectee children based on filter - this.refresh = function() { - selectees = $(that.options.filter, that.element[0]); - selectees.addClass("ui-selectee"); - selectees.each(function() { - var $this = $(this), - pos = $this.offset(); - $.data(this, "selectable-item", { - element: this, - $element: $this, - left: pos.left, - top: pos.top, - right: pos.left + $this.outerWidth(), - bottom: pos.top + $this.outerHeight(), - startselected: false, - selected: $this.hasClass("ui-selected"), - selecting: $this.hasClass("ui-selecting"), - unselecting: $this.hasClass("ui-unselecting") - }); - }); - }; - this.refresh(); - - this.selectees = selectees.addClass("ui-selectee"); - - this._mouseInit(); - - this.helper = $("
"); - }, - - _destroy: function() { - this.selectees - .removeClass("ui-selectee") - .removeData("selectable-item"); - this.element - .removeClass("ui-selectable ui-selectable-disabled"); - this._mouseDestroy(); - }, - - _mouseStart: function(event) { - var that = this, - options = this.options; - - this.opos = [event.pageX, event.pageY]; - - if (this.options.disabled) { - return; - } - - this.selectees = $(options.filter, this.element[0]); - - this._trigger("start", event); - - $(options.appendTo).append(this.helper); - // position helper (lasso) - this.helper.css({ - "left": event.pageX, - "top": event.pageY, - "width": 0, - "height": 0 - }); - - if (options.autoRefresh) { - this.refresh(); - } - - this.selectees.filter(".ui-selected").each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.startselected = true; - if (!event.metaKey && !event.ctrlKey) { - selectee.$element.removeClass("ui-selected"); - selectee.selected = false; - selectee.$element.addClass("ui-unselecting"); - selectee.unselecting = true; - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - }); - - $(event.target).parents().addBack().each(function() { - var doSelect, - selectee = $.data(this, "selectable-item"); - if (selectee) { - doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); - selectee.$element - .removeClass(doSelect ? "ui-unselecting" : "ui-selected") - .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); - selectee.unselecting = !doSelect; - selectee.selecting = doSelect; - selectee.selected = doSelect; - // selectable (UN)SELECTING callback - if (doSelect) { - that._trigger("selecting", event, { - selecting: selectee.element - }); - } else { - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - return false; - } - }); - - }, - - _mouseDrag: function(event) { - - this.dragged = true; - - if (this.options.disabled) { - return; - } - - var tmp, - that = this, - options = this.options, - x1 = this.opos[0], - y1 = this.opos[1], - x2 = event.pageX, - y2 = event.pageY; - - if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } - if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } - this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); - - this.selectees.each(function() { - var selectee = $.data(this, "selectable-item"), - hit = false; - - //prevent helper from being selected if appendTo: selectable - if (!selectee || selectee.element === that.element[0]) { - return; - } - - if (options.tolerance === "touch") { - hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); - } else if (options.tolerance === "fit") { - hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); - } - - if (hit) { - // SELECT - if (selectee.selected) { - selectee.$element.removeClass("ui-selected"); - selectee.selected = false; - } - if (selectee.unselecting) { - selectee.$element.removeClass("ui-unselecting"); - selectee.unselecting = false; - } - if (!selectee.selecting) { - selectee.$element.addClass("ui-selecting"); - selectee.selecting = true; - // selectable SELECTING callback - that._trigger("selecting", event, { - selecting: selectee.element - }); - } - } else { - // UNSELECT - if (selectee.selecting) { - if ((event.metaKey || event.ctrlKey) && selectee.startselected) { - selectee.$element.removeClass("ui-selecting"); - selectee.selecting = false; - selectee.$element.addClass("ui-selected"); - selectee.selected = true; - } else { - selectee.$element.removeClass("ui-selecting"); - selectee.selecting = false; - if (selectee.startselected) { - selectee.$element.addClass("ui-unselecting"); - selectee.unselecting = true; - } - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - if (selectee.selected) { - if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { - selectee.$element.removeClass("ui-selected"); - selectee.selected = false; - - selectee.$element.addClass("ui-unselecting"); - selectee.unselecting = true; - // selectable UNSELECTING callback - that._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - } - }); - - return false; - }, - - _mouseStop: function(event) { - var that = this; - - this.dragged = false; - - $(".ui-unselecting", this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass("ui-unselecting"); - selectee.unselecting = false; - selectee.startselected = false; - that._trigger("unselected", event, { - unselected: selectee.element - }); - }); - $(".ui-selecting", this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); - selectee.selecting = false; - selectee.selected = true; - selectee.startselected = true; - that._trigger("selected", event, { - selected: selectee.element - }); - }); - this._trigger("stop", event); - - this.helper.remove(); - - return false; - } - -}); - -})(jQuery); - -(function( $, undefined ) { - -/*jshint loopfunc: true */ - -function isOverAxis( x, reference, size ) { - return ( x > reference ) && ( x < ( reference + size ) ); -} - -function isFloating(item) { - return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); -} - -$.widget("ui.sortable", $.ui.mouse, { - version: "1.10.3", - widgetEventPrefix: "sort", - ready: false, - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: "auto", - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: "> *", - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000, - - // callbacks - activate: null, - beforeStop: null, - change: null, - deactivate: null, - out: null, - over: null, - receive: null, - remove: null, - sort: null, - start: null, - stop: null, - update: null - }, - _create: function() { - - var o = this.options; - this.containerCache = {}; - this.element.addClass("ui-sortable"); - - //Get the items - this.refresh(); - - //Let's determine if the items are being displayed horizontally - this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; - - //Let's determine the parent's offset - this.offset = this.element.offset(); - - //Initialize mouse events for interaction - this._mouseInit(); - - //We're ready to go - this.ready = true; - - }, - - _destroy: function() { - this.element - .removeClass("ui-sortable ui-sortable-disabled"); - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) { - this.items[i].item.removeData(this.widgetName + "-item"); - } - - return this; - }, - - _setOption: function(key, value){ - if ( key === "disabled" ) { - this.options[ key ] = value; - - this.widget().toggleClass( "ui-sortable-disabled", !!value ); - } else { - // Don't call widget base _setOption for disable as it adds ui-state-disabled class - $.Widget.prototype._setOption.apply(this, arguments); - } - }, - - _mouseCapture: function(event, overrideHandle) { - var currentItem = null, - validHandle = false, - that = this; - - if (this.reverting) { - return false; - } - - if(this.options.disabled || this.options.type === "static") { - return false; - } - - //We have to refresh the items data once first - this._refreshItems(event); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - $(event.target).parents().each(function() { - if($.data(this, that.widgetName + "-item") === that) { - currentItem = $(this); - return false; - } - }); - if($.data(event.target, that.widgetName + "-item") === that) { - currentItem = $(event.target); - } - - if(!currentItem) { - return false; - } - if(this.options.handle && !overrideHandle) { - $(this.options.handle, currentItem).find("*").addBack().each(function() { - if(this === event.target) { - validHandle = true; - } - }); - if(!validHandle) { - return false; - } - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - - _mouseStart: function(event, overrideHandle, noActivation) { - - var i, body, - o = this.options; - - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture - this.refreshPositions(); - - //Create and append the visible helper - this.helper = this._createHelper(event); - - //Cache the helper size - this._cacheHelperProportions(); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Get the next scrolling parent - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - // Only after we got the offset, we can change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); - - //Generate the original position - this.originalPosition = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; - - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way - if(this.helper[0] !== this.currentItem[0]) { - this.currentItem.hide(); - } - - //Create the placeholder - this._createPlaceholder(); - - //Set a containment if given in the options - if(o.containment) { - this._setContainment(); - } - - if( o.cursor && o.cursor !== "auto" ) { // cursor option - body = this.document.find( "body" ); - - // support: IE - this.storedCursor = body.css( "cursor" ); - body.css( "cursor", o.cursor ); - - this.storedStylesheet = $( "" ).appendTo( body ); - } - - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) { - this._storedOpacity = this.helper.css("opacity"); - } - this.helper.css("opacity", o.opacity); - } - - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) { - this._storedZIndex = this.helper.css("zIndex"); - } - this.helper.css("zIndex", o.zIndex); - } - - //Prepare scrolling - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { - this.overflowOffset = this.scrollParent.offset(); - } - - //Call callbacks - this._trigger("start", event, this._uiHash()); - - //Recache the helper size - if(!this._preserveHelperProportions) { - this._cacheHelperProportions(); - } - - - //Post "activate" events to possible containers - if( !noActivation ) { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); - } - } - - //Prepare possible droppables - if($.ui.ddmanager) { - $.ui.ddmanager.current = this; - } - - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - - this.dragging = true; - - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, - - _mouseDrag: function(event) { - var i, item, itemElement, intersection, - o = this.options, - scrolled = false; - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Do scrolling - if(this.options.scroll) { - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; - } - - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; - } - - } else { - - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - } - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper position - if(!this.options.axis || this.options.axis !== "y") { - this.helper[0].style.left = this.position.left+"px"; - } - if(!this.options.axis || this.options.axis !== "x") { - this.helper[0].style.top = this.position.top+"px"; - } - - //Rearrange - for (i = this.items.length - 1; i >= 0; i--) { - - //Cache variables and intersection, continue if no intersection - item = this.items[i]; - itemElement = item.item[0]; - intersection = this._intersectsWithPointer(item); - if (!intersection) { - continue; - } - - // Only put the placeholder inside the current Container, skip all - // items form other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this moving items in "sub-sortables" can cause the placeholder to jitter - // beetween the outer and inner container. - if (item.instance !== this.currentContainer) { - continue; - } - - // cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if (itemElement !== this.currentItem[0] && - this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && - !$.contains(this.placeholder[0], itemElement) && - (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) - ) { - - this.direction = intersection === 1 ? "down" : "up"; - - if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); - } else { - break; - } - - this._trigger("change", event, this._uiHash()); - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); - } - - //Call callbacks - this._trigger("sort", event, this._uiHash()); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function(event, noPropagation) { - - if(!event) { - return; - } - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) { - $.ui.ddmanager.drop(this, event); - } - - if(this.options.revert) { - var that = this, - cur = this.placeholder.offset(), - axis = this.options.axis, - animation = {}; - - if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); - } - if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); - } - this.reverting = true; - $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { - that._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - - cancel: function() { - - if(this.dragging) { - - this._mouseUp({ target: null }); - - if(this.options.helper === "original") { - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, this._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) { - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - } - if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { - this.helper.remove(); - } - - $.extend(this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - }); - - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); - } else { - $(this.domPosition.parent).prepend(this.currentItem); - } - } - - return this; - - }, - - serialize: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - str = []; - o = o || {}; - - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); - if (res) { - str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); - } - }); - - if(!str.length && o.key) { - str.push(o.key + "="); - } - - return str.join("&"); - - }, - - toArray: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - ret = []; - - o = o || {}; - - items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function(item) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height, - l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height, - dyClick = this.offset.click.top, - dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( this.options.tolerance === "pointer" || - this.options.forcePointerForContainers || - (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) - ) { - return isOverElement; - } else { - - return (l < x1 + (this.helperProportions.width / 2) && // Right Half - x2 - (this.helperProportions.width / 2) < r && // Left Half - t < y1 + (this.helperProportions.height / 2) && // Bottom Half - y2 - (this.helperProportions.height / 2) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function(item) { - - var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (!isOverElement) { - return false; - } - - return this.floating ? - ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); - - }, - - _intersectsWithSides: function(item) { - - var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (this.floating && horizontalDirection) { - return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); - } else { - return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && (delta > 0 ? "down" : "up"); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && (delta > 0 ? "right" : "left"); - }, - - refresh: function(event) { - this._refreshItems(event); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; - }, - - _getItemsAsjQuery: function(connected) { - - var i, j, cur, inst, - items = [], - queries = [], - connectWith = this._connectWith(); - - if(connectWith && connected) { - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i]); - for ( j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); - } - } - } - } - - queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); - - for (i = queries.length - 1; i >= 0; i--){ - queries[i][0].each(function() { - items.push(this); - }); - } - - return $(items); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); - - this.items = $.grep(this.items, function (item) { - for (var j=0; j < list.length; j++) { - if(list[j] === item.item[0]) { - return false; - } - } - return true; - }); - - }, - - _refreshItems: function(event) { - - this.items = []; - this.containers = [this]; - - var i, j, cur, inst, targetData, _queries, item, queriesLength, - items = this.items, - queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], - connectWith = this._connectWith(); - - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i]); - for (j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); - } - } - } - } - - for (i = queries.length - 1; i >= 0; i--) { - targetData = queries[i][1]; - _queries = queries[i][0]; - - for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { - item = $(_queries[j]); - - item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) - - items.push({ - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - }); - } - } - - }, - - refreshPositions: function(fast) { - - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { - this.offset.parent = this._getParentOffset(); - } - - var i, item, t, p; - - for (i = this.items.length - 1; i >= 0; i--){ - item = this.items[i]; - - //We ignore calculating positions of all connected containers when we're not over them - if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { - continue; - } - - t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; - - if (!fast) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - p = t.offset(); - item.left = p.left; - item.top = p.top; - } - - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); - } else { - for (i = this.containers.length - 1; i >= 0; i--){ - p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); - } - } - - return this; - }, - - _createPlaceholder: function(that) { - that = that || this; - var className, - o = that.options; - - if(!o.placeholder || o.placeholder.constructor === String) { - className = o.placeholder; - o.placeholder = { - element: function() { - - var nodeName = that.currentItem[0].nodeName.toLowerCase(), - element = $( "<" + nodeName + ">", that.document[0] ) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper"); - - if ( nodeName === "tr" ) { - that.currentItem.children().each(function() { - $( "
", that.document[0] ) - .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) - .appendTo( element ); - }); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); - } - - if ( !className ) { - element.css( "visibility", "hidden" ); - } - - return element; - }, - update: function(container, p) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) { - return; - } - - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } - if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } - } - }; - } - - //Create the placeholder - that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); - - //Append it after the actual current item - that.currentItem.after(that.placeholder); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(that, that.placeholder); - - }, - - _contactContainers: function(event) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, - innermostContainer = null, - innermostIndex = null; - - // get innermost container that intersects with item - for (i = this.containers.length - 1; i >= 0; i--) { - - // never consider a container that's located within the item itself - if($.contains(this.currentItem[0], this.containers[i].element[0])) { - continue; - } - - if(this._intersectsWith(this.containers[i].containerCache)) { - - // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { - continue; - } - - innermostContainer = this.containers[i]; - innermostIndex = i; - - } else { - // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", event, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - // if no intersecting containers found, return - if(!innermostContainer) { - return; - } - - // move the item into the container if it's not there already - if(this.containers.length === 1) { - if (!this.containers[innermostIndex].containerCache.over) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - } else { - - //When entering a new container, we will find the item with the least distance and append our item near it - dist = 10000; - itemWithLeastDistance = null; - floating = innermostContainer.floating || isFloating(this.currentItem); - posProperty = floating ? "left" : "top"; - sizeProperty = floating ? "width" : "height"; - base = this.positionAbs[posProperty] + this.offset.click[posProperty]; - for (j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { - continue; - } - if(this.items[j].item[0] === this.currentItem[0]) { - continue; - } - if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { - continue; - } - cur = this.items[j].item.offset()[posProperty]; - nearBottom = false; - if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ - nearBottom = true; - cur += this.items[j][sizeProperty]; - } - - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - this.direction = nearBottom ? "up": "down"; - } - } - - //Check if dropOnEmpty is enabled - if(!itemWithLeastDistance && !this.options.dropOnEmpty) { - return; - } - - if(this.currentContainer === this.containers[innermostIndex]) { - return; - } - - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - this.currentContainer = this.containers[innermostIndex]; - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - - - }, - - _createHelper: function(event) { - - var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); - - //Add the helper to the DOM if that didn't happen already - if(!helper.parents("body").length) { - $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - } - - if(helper[0] === this.currentItem[0]) { - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; - } - - if(!helper[0].style.width || o.forceHelperSize) { - helper.width(this.currentItem.width()); - } - if(!helper[0].style.height || o.forceHelperSize) { - helper.height(this.currentItem.height()); - } - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ("left" in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ("right" in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ("top" in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ("bottom" in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - // This needs to be actually done for all browsers, since pageX/pageY includes this information - // with an ugly IE fix - if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition === "relative") { - var p = this.currentItem.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var ce, co, over, - o = this.options; - if(o.containment === "parent") { - o.containment = this.helper[0].parentNode; - } - if(o.containment === "document" || o.containment === "window") { - this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, - ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - } - - if(!(/^(document|window|parent)$/).test(o.containment)) { - ce = $(o.containment)[0]; - co = $(o.containment).offset(); - over = ($(ce).css("overflow") !== "hidden"); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) { - pos = this.position; - } - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, - scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var top, left, - o = this.options, - pageX = event.pageX, - pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { - this.offset.relative = this._getRelativeOffset(); - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) { - pageX = this.containment[0] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top < this.containment[1]) { - pageY = this.containment[1] + this.offset.click.top; - } - if(event.pageX - this.offset.click.left > this.containment[2]) { - pageX = this.containment[2] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top > this.containment[3]) { - pageY = this.containment[3] + this.offset.click.top; - } - } - - if(o.grid) { - top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _rearrange: function(event, i, a, hardRefresh) { - - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay(function() { - if(counter === this.counter) { - this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove - } - }); - - }, - - _clear: function(event, noPropagation) { - - this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again - var i, - delayedTriggers = []; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) { - this.placeholder.before(this.currentItem); - } - this._noFinalSort = null; - - if(this.helper[0] === this.currentItem[0]) { - for(i in this._storedCSS) { - if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { - this._storedCSS[i] = ""; - } - } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - if(this.fromOutside && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); - } - if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - } - - // Check if the items Container has Changed and trigger appropriate - // events. - if (this !== this.currentContainer) { - if(!noPropagation) { - delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - } - } - - - //Post events to containers - for (i = this.containers.length - 1; i >= 0; i--){ - if(!noPropagation) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - } - if(this.containers[i].containerCache.over) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - this.containers[i].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if ( this.storedCursor ) { - this.document.find( "body" ).css( "cursor", this.storedCursor ); - this.storedStylesheet.remove(); - } - if(this._storedOpacity) { - this.helper.css("opacity", this._storedOpacity); - } - if(this._storedZIndex) { - this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); - } - - this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return false; - } - - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - } - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - - if(this.helper[0] !== this.currentItem[0]) { - this.helper.remove(); - } - this.helper = null; - - if(!noPropagation) { - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return true; - - }, - - _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { - this.cancel(); - } - }, - - _uiHash: function(_inst) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $([]), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; - } - -}); - -})(jQuery); - -(function($, undefined) { - -var dataSpace = "ui-effects-"; - -$.effects = { - effect: {} -}; - -/*! - * jQuery Color Animations v2.1.2 - * https://github.com/jquery/jquery-color - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * Date: Wed Jan 16 08:47:09 2013 -0600 - */ -(function( jQuery, undefined ) { - - var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", - - // plusequals test for += 100 -= 100 - rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, - // a set of RE's that can match strings and generate color tuples. - stringParsers = [{ - re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] - ]; - } - }, { - re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ] * 2.55, - execResult[ 2 ] * 2.55, - execResult[ 3 ] * 2.55, - execResult[ 4 ] - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ) - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) - ]; - } - }, { - re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - space: "hsla", - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ] / 100, - execResult[ 3 ] / 100, - execResult[ 4 ] - ]; - } - }], - - // jQuery.Color( ) - color = jQuery.Color = function( color, green, blue, alpha ) { - return new jQuery.Color.fn.parse( color, green, blue, alpha ); - }, - spaces = { - rgba: { - props: { - red: { - idx: 0, - type: "byte" - }, - green: { - idx: 1, - type: "byte" - }, - blue: { - idx: 2, - type: "byte" - } - } - }, - - hsla: { - props: { - hue: { - idx: 0, - type: "degrees" - }, - saturation: { - idx: 1, - type: "percent" - }, - lightness: { - idx: 2, - type: "percent" - } - } - } - }, - propTypes = { - "byte": { - floor: true, - max: 255 - }, - "percent": { - max: 1 - }, - "degrees": { - mod: 360, - floor: true - } - }, - support = color.support = {}, - - // element for support tests - supportElem = jQuery( "

" )[ 0 ], - - // colors = jQuery.Color.names - colors, - - // local aliases of functions called often - each = jQuery.each; - -// determine rgba support immediately -supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; -support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; - -// define cache name and alpha properties -// for rgba and hsla spaces -each( spaces, function( spaceName, space ) { - space.cache = "_" + spaceName; - space.props.alpha = { - idx: 3, - type: "percent", - def: 1 - }; -}); - -function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; - - if ( value == null ) { - return (allowEmpty || !prop.def) ? null : prop.def; - } - - // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); - - // IE will pass in empty strings as value for alpha, - // which will hit this case - if ( isNaN( value ) ) { - return prop.def; - } - - if ( type.mod ) { - // we add mod before modding to make sure that negatives values - // get converted properly: -10 -> 350 - return (value + type.mod) % type.mod; - } - - // for now all property types without mod have min and max - return 0 > value ? 0 : type.max < value ? type.max : value; -} - -function stringParse( string ) { - var inst = color(), - rgba = inst._rgba = []; - - string = string.toLowerCase(); - - each( stringParsers, function( i, parser ) { - var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), - spaceName = parser.space || "rgba"; - - if ( values ) { - parsed = inst[ spaceName ]( values ); - - // if this was an rgba parse the assignment might happen twice - // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; - rgba = inst._rgba = parsed._rgba; - - // exit each( stringParsers ) here because we matched - return false; - } - }); - - // Found a stringParser that handled it - if ( rgba.length ) { - - // if this came from a parsed string, force "transparent" when alpha is 0 - // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( rgba.join() === "0,0,0,0" ) { - jQuery.extend( rgba, colors.transparent ); - } - return inst; - } - - // named colors - return colors[ string ]; -} - -color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; - return this; - } - if ( red.jquery || red.nodeType ) { - red = jQuery( red ).css( green ); - green = undefined; - } - - var inst = this, - type = jQuery.type( red ), - rgba = this._rgba = []; - - // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; - type = "array"; - } - - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); - } - - if ( type === "array" ) { - each( spaces.rgba.props, function( key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); - }); - return this; - } - - if ( type === "object" ) { - if ( red instanceof color ) { - each( spaces, function( spaceName, space ) { - if ( red[ space.cache ] ) { - inst[ space.cache ] = red[ space.cache ].slice(); - } - }); - } else { - each( spaces, function( spaceName, space ) { - var cache = space.cache; - each( space.props, function( key, prop ) { - - // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { - - // if the value was null, we don't need to copy it - // if the key was alpha, we don't need to copy it either - if ( key === "alpha" || red[ key ] == null ) { - return; - } - inst[ cache ] = space.to( inst._rgba ); - } - - // this is the only case where we allow nulls for ALL properties. - // call clamp with alwaysAllowEmpty - inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); - }); - - // everything defined but alpha? - if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { - // use the default of 1 - inst[ cache ][ 3 ] = 1; - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); - } - } - }); - } - return this; - } - }, - is: function( compare ) { - var is = color( compare ), - same = true, - inst = this; - - each( spaces, function( _, space ) { - var localCache, - isCache = is[ space.cache ]; - if (isCache) { - localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; - each( space.props, function( _, prop ) { - if ( isCache[ prop.idx ] != null ) { - same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); - return same; - } - }); - } - return same; - }); - return same; - }, - _space: function() { - var used = [], - inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); - } - }); - return used.pop(); - }, - transition: function( other, distance ) { - var end = color( other ), - spaceName = end._space(), - space = spaces[ spaceName ], - startColor = this.alpha() === 0 ? color( "transparent" ) : this, - start = startColor[ space.cache ] || space.to( startColor._rgba ), - result = start.slice(); - - end = end[ space.cache ]; - each( space.props, function( key, prop ) { - var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; - - // if null, don't override start value - if ( endValue === null ) { - return; - } - // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; - } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { - startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { - startValue -= type.mod; - } - } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); - } - }); - return this[ spaceName ]( result ); - }, - blend: function( opaque ) { - // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { - return this; - } - - var rgb = this._rgba.slice(), - a = rgb.pop(), - blend = color( opaque )._rgba; - - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; - })); - }, - toRgbaString: function() { - var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - return v == null ? ( i > 2 ? 1 : 0 ) : v; - }); - - if ( rgba[ 3 ] === 1 ) { - rgba.pop(); - prefix = "rgb("; - } - - return prefix + rgba.join() + ")"; - }, - toHslaString: function() { - var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { - v = i > 2 ? 1 : 0; - } - - // catch 1 and 2 - if ( i && i < 3 ) { - v = Math.round( v * 100 ) + "%"; - } - return v; - }); - - if ( hsla[ 3 ] === 1 ) { - hsla.pop(); - prefix = "hsl("; - } - return prefix + hsla.join() + ")"; - }, - toHexString: function( includeAlpha ) { - var rgba = this._rgba.slice(), - alpha = rgba.pop(); - - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); - } - - return "#" + jQuery.map( rgba, function( v ) { - - // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); - return v.length === 1 ? "0" + v : v; - }).join(""); - }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); - } -}); -color.fn.parse.prototype = color.fn; - -// hsla conversions adapted from: -// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - -function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { - return p + (q - p) * h * 6; - } - if ( h * 2 < 1) { - return q; - } - if ( h * 3 < 2 ) { - return p + (q - p) * ((2/3) - h) * 6; - } - return p; -} - -spaces.hsla.to = function ( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; - } - var r = rgba[ 0 ] / 255, - g = rgba[ 1 ] / 255, - b = rgba[ 2 ] / 255, - a = rgba[ 3 ], - max = Math.max( r, g, b ), - min = Math.min( r, g, b ), - diff = max - min, - add = max + min, - l = add * 0.5, - h, s; - - if ( min === max ) { - h = 0; - } else if ( r === max ) { - h = ( 60 * ( g - b ) / diff ) + 360; - } else if ( g === max ) { - h = ( 60 * ( b - r ) / diff ) + 120; - } else { - h = ( 60 * ( r - g ) / diff ) + 240; - } - - // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% - // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) - if ( diff === 0 ) { - s = 0; - } else if ( l <= 0.5 ) { - s = diff / add; - } else { - s = diff / ( 2 - add ); - } - return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; -}; - -spaces.hsla.from = function ( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; - } - var h = hsla[ 0 ] / 360, - s = hsla[ 1 ], - l = hsla[ 2 ], - a = hsla[ 3 ], - q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, - p = 2 * l - q; - - return [ - Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), - Math.round( hue2rgb( p, q, h ) * 255 ), - Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), - a - ]; -}; - - -each( spaces, function( spaceName, space ) { - var props = space.props, - cache = space.cache, - to = space.to, - from = space.from; - - // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { - - // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); - } - if ( value === undefined ) { - return this[ cache ].slice(); - } - - var ret, - type = jQuery.type( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); - - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; - } - local[ prop.idx ] = clamp( val, prop ); - }); - - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; - return ret; - } else { - return color( local ); - } - }; - - // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { - // alpha is included in more than one space - if ( color.fn[ key ] ) { - return; - } - color.fn[ key ] = function( value ) { - var vtype = jQuery.type( value ), - fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), - local = this[ fn ](), - cur = local[ prop.idx ], - match; - - if ( vtype === "undefined" ) { - return cur; - } - - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = jQuery.type( value ); - } - if ( value == null && prop.empty ) { - return this; - } - if ( vtype === "string" ) { - match = rplusequals.exec( value ); - if ( match ) { - value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); - } - } - local[ prop.idx ] = value; - return this[ fn ]( local ); - }; - }); -}); - -// add cssHook and .fx.step function for each named hook. -// accept a space separated string of properties -color.hook = function( hook ) { - var hooks = hook.split( " " ); - each( hooks, function( i, hook ) { - jQuery.cssHooks[ hook ] = { - set: function( elem, value ) { - var parsed, curElem, - backgroundColor = ""; - - if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { - curElem = hook === "backgroundColor" ? elem.parentNode : elem; - while ( - (backgroundColor === "" || backgroundColor === "transparent") && - curElem && curElem.style - ) { - try { - backgroundColor = jQuery.css( curElem, "backgroundColor" ); - curElem = curElem.parentNode; - } catch ( e ) { - } - } - - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? - backgroundColor : - "_default" ); - } - - value = value.toRgbaString(); - } - try { - elem.style[ hook ] = value; - } catch( e ) { - // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' - } - } - }; - jQuery.fx.step[ hook ] = function( fx ) { - if ( !fx.colorInit ) { - fx.start = color( fx.elem, hook ); - fx.end = color( fx.end ); - fx.colorInit = true; - } - jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); - }; - }); - -}; - -color.hook( stepHooks ); - -jQuery.cssHooks.borderColor = { - expand: function( value ) { - var expanded = {}; - - each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { - expanded[ "border" + part + "Color" ] = value; - }); - return expanded; - } -}; - -// Basic color names only. -// Usage of any of the other color names requires adding yourself or including -// jquery.color.svg-names.js. -colors = jQuery.Color.names = { - // 4.1. Basic color keywords - aqua: "#00ffff", - black: "#000000", - blue: "#0000ff", - fuchsia: "#ff00ff", - gray: "#808080", - green: "#008000", - lime: "#00ff00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - purple: "#800080", - red: "#ff0000", - silver: "#c0c0c0", - teal: "#008080", - white: "#ffffff", - yellow: "#ffff00", - - // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], - - _default: "#ffffff" -}; - -})( jQuery ); - - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -(function() { - -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; - } - }; -}); - -function getElementStyles( elem ) { - var key, len, - style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : - elem.currentStyle, - styles = {}; - - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - styles[ $.camelCase( key ) ] = style[ key ]; - } - } - // support: Opera, IE <9 - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - styles[ key ] = style[ key ]; - } - } - } - - return styles; -} - - -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; - - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } - } - } - } - - return diff; -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); - - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; - - // map the animated objects to store the original styles. - allAnimations = allAnimations.map(function() { - var el = $( this ); - return { - el: el, - start: getElementStyles( this ) - }; - }); - - // apply class change - applyClassChange = function() { - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - }); - }; - applyClassChange(); - - // map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map(function() { - this.end = getElementStyles( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - }); - - // apply original class - animated.attr( "class", baseClass ); - - // map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map(function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = $.extend({}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - }); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - }); - - // once all animations have completed: - $.when.apply( $, allAnimations.get() ).done(function() { - - // set the final class - applyClassChange(); - - // for each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function(key) { - el.css( key, "" ); - }); - }); - - // this is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - }); - }); -}; - -$.fn.extend({ - addClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.addClass ), - - removeClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return arguments.length > 1 ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.removeClass ), - - toggleClass: (function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { - // without speed parameter - return orig.apply( this, arguments ); - } else { - return $.effects.animateClass.call( this, - (force ? { add: classNames } : { remove: classNames }), - speed, easing, callback ); - } - } else { - // without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }; - })( $.fn.toggleClass ), - - switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -(function() { - -$.extend( $.effects, { - version: "1.10.3", - - // Saves a set of properties in a data storage - save: function( element, set ) { - for( var i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i; - for( i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - // support: jQuery 1.6.2 - // http://bugs.jquery.com/ticket/9917 - // jQuery 1.6.2 incorrectly returns undefined for any falsy value. - // We can't differentiate between "" and 0 here, so we just assume - // empty string since it's likely to be a more common value... - if ( val === undefined ) { - val = ""; - } - element.css( set[ i ], val ); - } - } - }, - - setMode: function( el, mode ) { - if (mode === "toggle") { - mode = el.is( ":hidden" ) ? "show" : "hide"; - } - return mode; - }, - - // Translates a [top,left] array into a baseline value - // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { - var y, x; - switch ( origin[ 0 ] ) { - case "top": y = 0; break; - case "middle": y = 0.5; break; - case "bottom": y = 1; break; - default: y = origin[ 0 ] / original.height; - } - switch ( origin[ 1 ] ) { - case "left": x = 0; break; - case "center": x = 0.5; break; - case "right": x = 1; break; - default: x = origin[ 1 ] / original.width; - } - return { - x: x, - y: y - }; - }, - - // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { - - // if the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" )) { - return element.parent(); - } - - // wrap the element - var props = { - width: element.outerWidth(true), - height: element.outerHeight(true), - "float": element.css( "float" ) - }, - wrapper = $( "

" ) - .addClass( "ui-effects-wrapper" ) - .css({ - fontSize: "100%", - background: "transparent", - border: "none", - margin: 0, - padding: 0 - }), - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; - - // support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - active.id; - } catch( e ) { - active = document.body; - } - - element.wrap( wrapper ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element - - // transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css({ position: "relative" }); - element.css({ position: "relative" }); - } else { - $.extend( props, { - position: element.css( "position" ), - zIndex: element.css( "z-index" ) - }); - $.each([ "top", "left", "bottom", "right" ], function(i, pos) { - props[ pos ] = element.css( pos ); - if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = "auto"; - } - }); - element.css({ - position: "relative", - top: 0, - left: 0, - right: "auto", - bottom: "auto" - }); - } - element.css(size); - - return wrapper.css( props ).show(); - }, - - removeWrapper: function( element ) { - var active = document.activeElement; - - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - } - - - return element; - }, - - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - }); - return value; - } -}); - -// return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { - - // allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } - - // convert to an object - effect = { effect: effect }; - - // catch (effect, null, ...) - if ( options == null ) { - options = {}; - } - - // catch (effect, callback) - if ( $.isFunction( options ) ) { - callback = options; - speed = null; - options = {}; - } - - // catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } - - // catch (effect, options, callback) - if ( $.isFunction( speed ) ) { - callback = speed; - speed = null; - } - - // add options to effect - if ( options ) { - $.extend( effect, options ); - } - - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; - - effect.complete = callback || options.complete; - - return effect; -} - -function standardAnimationOption( option ) { - // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { - return true; - } - - // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { - return true; - } - - // Complete callback - if ( $.isFunction( option ) ) { - return true; - } - - // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { - return true; - } - - // Didn't match any standard API - return false; -} - -$.fn.extend({ - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - mode = args.mode, - queue = args.queue, - effectMethod = $.effects.effect[ args.effect ]; - - if ( $.fx.off || !effectMethod ) { - // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, args.complete ); - } else { - return this.each( function() { - if ( args.complete ) { - args.complete.call( this ); - } - }); - } - } - - function run( next ) { - var elem = $( this ), - complete = args.complete, - mode = args.mode; - - function done() { - if ( $.isFunction( complete ) ) { - complete.call( elem[0] ); - } - if ( $.isFunction( next ) ) { - next(); - } - } - - // If the element already has the correct final state, delegate to - // the core methods so the internal tracking of "olddisplay" works. - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[0], args, done ); - } - } - - return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); - }, - - show: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }; - })( $.fn.show ), - - hide: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }; - })( $.fn.hide ), - - toggle: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }; - })( $.fn.toggle ), - - // helper functions - cssUnit: function(key) { - var style = this.css( key ), - val = []; - - $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { - if ( style.indexOf( unit ) > 0 ) { - val = [ parseFloat( style ), unit ]; - } - }); - return val; - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ - -(function() { - -// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) - -var baseEasings = {}; - -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -}); - -$.extend( baseEasings, { - Sine: function ( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); - }, - Circ: function ( p ) { - return 1 - Math.sqrt( 1 - p * p ); - }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); - }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); - }, - Bounce: function ( p ) { - var pow2, - bounce = 4; - - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -}); - -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -}); - -})(); - -})(jQuery); - -(function( $, undefined ) { - -var uid = 0, - hideProps = {}, - showProps = {}; - -hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = - hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; -showProps.height = showProps.paddingTop = showProps.paddingBottom = - showProps.borderTopWidth = showProps.borderBottomWidth = "show"; - -$.widget( "ui.accordion", { - version: "1.10.3", - options: { - active: 0, - animate: {}, - collapsible: false, - event: "click", - header: "> li > :first-child,> :not(li):even", - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" - }, - - // callbacks - activate: null, - beforeActivate: null - }, - - _create: function() { - var options = this.options; - this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) - // ARIA - .attr( "role", "tablist" ); - - // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { - options.active = 0; - } - - this._processPanels(); - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; - } - this._refresh(); - }, - - _getCreateEventData: function() { - return { - header: this.active, - panel: !this.active.length ? $() : this.active.next(), - content: !this.active.length ? $() : this.active.next() - }; - }, - - _createIcons: function() { - var icons = this.options.icons; - if ( icons ) { - $( "" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) - .remove(); - }, - - _destroy: function() { - var contents; - - // clean up main element - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); - - // clean up headers - this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - this._destroyIcons(); - - // clean up content panels - contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); - } - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } - - this._super( key, value ); - - // setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } - - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - - // #5332 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); - } - }, - - _keydown: function( event ) { - /*jshint maxcomplexity:15*/ - if ( event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); - event.preventDefault(); - } - }, - - _panelKeyDown : function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); - } - }, - - refresh: function() { - var options = this.options; - this._processPanels(); - - // was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { - options.active = false; - this.active = $(); - // active false only when collapsible is true - } else if ( options.active === false ) { - this._activate( 0 ); - // was active, but active panel is gone - } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - // all remaining panel are disabled - if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { - options.active = false; - this.active = $(); - // activate previous panel - } else { - this._activate( Math.max( 0, options.active - 1 ) ); - } - // was active, active panel still exists - } else { - // make sure active index is correct - options.active = this.headers.index( this.active ); - } - - this._destroyIcons(); - - this._refresh(); - }, - - _processPanels: function() { - this.headers = this.element.find( this.options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); - - this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) - .filter(":not(.ui-accordion-content-active)") - .hide(); - }, - - _refresh: function() { - var maxHeight, - options = this.options, - heightStyle = options.heightStyle, - parent = this.element.parent(), - accordionId = this.accordionId = "ui-accordion-" + - (this.element.attr( "id" ) || ++uid); - - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) - .removeClass( "ui-corner-all" ); - this.active.next() - .addClass( "ui-accordion-content-active" ) - .show(); - - this.headers - .attr( "role", "tab" ) - .each(function( i ) { - var header = $( this ), - headerId = header.attr( "id" ), - panel = header.next(), - panelId = panel.attr( "id" ); - if ( !headerId ) { - headerId = accordionId + "-header-" + i; - header.attr( "id", headerId ); - } - if ( !panelId ) { - panelId = accordionId + "-panel-" + i; - panel.attr( "id", panelId ); - } - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - }) - .next() - .attr( "role", "tabpanel" ); - - this.headers - .not( this.active ) - .attr({ - "aria-selected": "false", - tabIndex: -1 - }) - .next() - .attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }) - .hide(); - - // make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr({ - "aria-selected": "true", - tabIndex: 0 - }) - .next() - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - } - - this._createIcons(); - - this._setupEvents( options.event ); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - - this.headers.each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.headers.next() - .each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - }) - .height( maxHeight ); - } - }, - - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; - - // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; - - this._eventHandler({ - target: active, - currentTarget: active, - preventDefault: $.noop - }); - }, - - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, - - _setupEvents: function( event ) { - var events = { - keydown: "_keydown" - }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.headers.add( this.headers.next() ) ); - this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" }); - this._hoverable( this.headers ); - this._focusable( this.headers ); - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; - - event.preventDefault(); - - if ( - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.headers.index( clicked ); - - // when the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - - // switch classes - // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); - if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); - } - - if ( !clickedIsActive ) { - clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); - if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); - } - - clicked - .next() - .addClass( "ui-accordion-content-active" ); - } - }, - - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - - // handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; - - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } - - toHide.attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - toHide.prev().attr( "aria-selected", "false" ); - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.headers.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }) - .prev() - .attr({ - "aria-selected": "true", - tabIndex: 0 - }); - }, - - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; - - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; - - if ( !toHide.length ) { - return toShow.animate( showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( hideProps, duration, easing, complete ); - } - - total = toShow.show().outerHeight(); - toHide.animate( hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - }); - toShow - .hide() - .animate( showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - adjust += fx.now; - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - }); - }, - - _toggleComplete: function( data ) { - var toHide = data.oldPanel; - - toHide - .removeClass( "ui-accordion-content-active" ) - .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); - - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[0].className = toHide.parent()[0].className; - } - - this._trigger( "activate", null, data ); - } -}); - -})( jQuery ); - -(function( $, undefined ) { - -// used to prevent race conditions with remote data sources -var requestIndex = 0; - -$.widget( "ui.autocomplete", { - version: "1.10.3", - defaultElement: "", - options: { - appendTo: null, - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, - - pending: 0, - - _create: function() { - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput, - nodeName = this.element[0].nodeName.toLowerCase(), - isTextarea = nodeName === "textarea", - isInput = nodeName === "input"; - - this.isMultiLine = - // Textareas are always multi-line - isTextarea ? true : - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - isInput ? false : - // All other element types are determined by whether or not they're contentEditable - this.element.prop( "isContentEditable" ); - - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; - this.isNewMenu = true; - - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); - - this._on( this.element, { - keydown: function( event ) { - /*jshint maxcomplexity:15*/ - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - case keyCode.NUMPAD_ENTER: - // when menu is open and has focus - if ( this.menu.active ) { - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - this._value( this.term ); - this.close( event ); - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - event.preventDefault(); - } - return; - } - if ( suppressKeyPressRepeat ) { - return; - } - - // replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; - } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); - } - }); - - this._initSource(); - this.menu = $( "
 
" + - ""; - thead = (showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "" + dayNamesMin[day] + ""; - } - calender += thead + ""; - daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - } - leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += ""; - tbody = (!showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += ""; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + ""; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += "
" + this._get(inst, "weekHeader") + "
" + - this._get(inst, "calculateWeek")(printDate) + "" + // actions - (otherMonth && !showOtherMonths ? " " : // display for other months - (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + "
" + (isMultiMonth ? "
" + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "
" : "") : ""); - group += calender; - } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get(inst, "changeMonth"), - changeYear = this._get(inst, "changeYear"), - showMonthAfterYear = this._get(inst, "showMonthAfterYear"), - html = "
", - monthHtml = ""; - - // month selection - if (secondary || !changeMonth) { - monthHtml += "" + monthNames[drawMonth] + ""; - } else { - inMinYear = (minDate && minDate.getFullYear() === drawYear); - inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); - monthHtml += ""; - } - - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); - } - - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if (secondary || !changeYear) { - html += "" + drawYear + ""; - } else { - // determine range of years to display - years = this._get(inst, "yearRange").split(":"); - thisYear = new Date().getFullYear(); - determineYear = function(value) { - var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - year = determineYear(years[0]); - endYear = Math.max(year, determineYear(years[1] || "")); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += ""; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; - } - html += "
"; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period === "Y" ? offset : 0), - month = inst.drawMonth + (period === "M" ? offset : 0), - day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), - date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); - - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); - } - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - newDate = (minDate && date < minDate ? minDate : date); - return (maxDate && newDate > maxDate ? maxDate : newDate); - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, "onChangeMonthYear"); - if (onChange) { - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); - } - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, "numberOfMonths"); - return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + "Date"), null); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst), - date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - - if (offset < 0) { - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); - } - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - minYear = null, - maxYear = null, - years = this._get(inst, "yearRange"); - if (years){ - yearSplit = years.split(":"); - currentYear = new Date().getFullYear(); - minYear = parseInt(yearSplit[0], 10); - maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { - minYear += currentYear; - } - if ( yearSplit[1].match(/[+\-].*/) ) { - maxYear += currentYear; - } - } - - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime()) && - (!minYear || date.getFullYear() >= minYear) && - (!maxYear || date.getFullYear() <= maxYear)); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, "shortYearCutoff"); - shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; - }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = (day ? (typeof day === "object" ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); - } -}); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function bindHover(dpDiv) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { - $(this).removeClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).removeClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).removeClass("ui-datepicker-next-hover"); - } - }) - .delegate(selector, "mouseover", function(){ - if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); - } - } - }); -} - -/* jQuery extend now ignores nulls! */ -function extendRemove(target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] == null) { - target[name] = props[name]; - } - } - return target; -} - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick); - $.datepicker.initialized = true; - } - - /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { - $("body").append($.datepicker.dpDiv); - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - return this.each(function() { - typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.10.3"; - -})(jQuery); - -(function( $, undefined ) { - -var sizeRelatedOptions = { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - resizableRelatedOptions = { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }; - -$.widget( "ui.dialog", { - version: "1.10.3", - options: { - appendTo: "body", - autoOpen: true, - buttons: [], - closeOnEscape: true, - closeText: "close", - dialogClass: "", - draggable: true, - hide: null, - height: "auto", - maxHeight: null, - maxWidth: null, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", - // Ensure the titlebar is always visible - using: function( pos ) { - var topOffset = $( this ).css( pos ).offset().top; - if ( topOffset < 0 ) { - $( this ).css( "top", pos.top - topOffset ); - } - } - }, - resizable: true, - show: null, - title: null, - width: 300, - - // callbacks - beforeClose: null, - close: null, - drag: null, - dragStart: null, - dragStop: null, - focus: null, - open: null, - resize: null, - resizeStart: null, - resizeStop: null - }, - - _create: function() { - this.originalCss = { - display: this.element[0].style.display, - width: this.element[0].style.width, - minHeight: this.element[0].style.minHeight, - maxHeight: this.element[0].style.maxHeight, - height: this.element[0].style.height - }; - this.originalPosition = { - parent: this.element.parent(), - index: this.element.parent().children().index( this.element ) - }; - this.originalTitle = this.element.attr("title"); - this.options.title = this.options.title || this.originalTitle; - - this._createWrapper(); - - this.element - .show() - .removeAttr("title") - .addClass("ui-dialog-content ui-widget-content") - .appendTo( this.uiDialog ); - - this._createTitlebar(); - this._createButtonPane(); - - if ( this.options.draggable && $.fn.draggable ) { - this._makeDraggable(); - } - if ( this.options.resizable && $.fn.resizable ) { - this._makeResizable(); - } - - this._isOpen = false; - }, - - _init: function() { - if ( this.options.autoOpen ) { - this.open(); - } - }, - - _appendTo: function() { - var element = this.options.appendTo; - if ( element && (element.jquery || element.nodeType) ) { - return $( element ); - } - return this.document.find( element || "body" ).eq( 0 ); - }, - - _destroy: function() { - var next, - originalPosition = this.originalPosition; - - this._destroyOverlay(); - - this.element - .removeUniqueId() - .removeClass("ui-dialog-content ui-widget-content") - .css( this.originalCss ) - // Without detaching first, the following becomes really slow - .detach(); - - this.uiDialog.stop( true, true ).remove(); - - if ( this.originalTitle ) { - this.element.attr( "title", this.originalTitle ); - } - - next = originalPosition.parent.children().eq( originalPosition.index ); - // Don't try to place the dialog next to itself (#8613) - if ( next.length && next[0] !== this.element[0] ) { - next.before( this.element ); - } else { - originalPosition.parent.append( this.element ); - } - }, - - widget: function() { - return this.uiDialog; - }, - - disable: $.noop, - enable: $.noop, - - close: function( event ) { - var that = this; - - if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { - return; - } - - this._isOpen = false; - this._destroyOverlay(); - - if ( !this.opener.filter(":focusable").focus().length ) { - // Hiding a focused element doesn't trigger blur in WebKit - // so in case we have nothing to focus on, explicitly blur the active element - // https://bugs.webkit.org/show_bug.cgi?id=47182 - $( this.document[0].activeElement ).blur(); - } - - this._hide( this.uiDialog, this.options.hide, function() { - that._trigger( "close", event ); - }); - }, - - isOpen: function() { - return this._isOpen; - }, - - moveToTop: function() { - this._moveToTop(); - }, - - _moveToTop: function( event, silent ) { - var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; - if ( moved && !silent ) { - this._trigger( "focus", event ); - } - return moved; - }, - - open: function() { - var that = this; - if ( this._isOpen ) { - if ( this._moveToTop() ) { - this._focusTabbable(); - } - return; - } - - this._isOpen = true; - this.opener = $( this.document[0].activeElement ); - - this._size(); - this._position(); - this._createOverlay(); - this._moveToTop( null, true ); - this._show( this.uiDialog, this.options.show, function() { - that._focusTabbable(); - that._trigger("focus"); - }); - - this._trigger("open"); - }, - - _focusTabbable: function() { - // Set focus to the first match: - // 1. First element inside the dialog matching [autofocus] - // 2. Tabbable element inside the content element - // 3. Tabbable element inside the buttonpane - // 4. The close button - // 5. The dialog itself - var hasFocus = this.element.find("[autofocus]"); - if ( !hasFocus.length ) { - hasFocus = this.element.find(":tabbable"); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogButtonPane.find(":tabbable"); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialog; - } - hasFocus.eq( 0 ).focus(); - }, - - _keepFocus: function( event ) { - function checkFocus() { - var activeElement = this.document[0].activeElement, - isActive = this.uiDialog[0] === activeElement || - $.contains( this.uiDialog[0], activeElement ); - if ( !isActive ) { - this._focusTabbable(); - } - } - event.preventDefault(); - checkFocus.call( this ); - // support: IE - // IE <= 8 doesn't prevent moving focus even with event.preventDefault() - // so we check again later - this._delay( checkFocus ); - }, - - _createWrapper: function() { - this.uiDialog = $("
") - .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + - this.options.dialogClass ) - .hide() - .attr({ - // Setting tabIndex makes the div focusable - tabIndex: -1, - role: "dialog" - }) - .appendTo( this._appendTo() ); - - this._on( this.uiDialog, { - keydown: function( event ) { - if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { - event.preventDefault(); - this.close( event ); - return; - } - - // prevent tabbing out of dialogs - if ( event.keyCode !== $.ui.keyCode.TAB ) { - return; - } - var tabbables = this.uiDialog.find(":tabbable"), - first = tabbables.filter(":first"), - last = tabbables.filter(":last"); - - if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { - first.focus( 1 ); - event.preventDefault(); - } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { - last.focus( 1 ); - event.preventDefault(); - } - }, - mousedown: function( event ) { - if ( this._moveToTop( event ) ) { - this._focusTabbable(); - } - } - }); - - // We assume that any existing aria-describedby attribute means - // that the dialog content is marked up properly - // otherwise we brute force the content as the description - if ( !this.element.find("[aria-describedby]").length ) { - this.uiDialog.attr({ - "aria-describedby": this.element.uniqueId().attr("id") - }); - } - }, - - _createTitlebar: function() { - var uiDialogTitle; - - this.uiDialogTitlebar = $("
") - .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") - .prependTo( this.uiDialog ); - this._on( this.uiDialogTitlebar, { - mousedown: function( event ) { - // Don't prevent click on close button (#8838) - // Focusing a dialog that is partially scrolled out of view - // causes the browser to scroll it into view, preventing the click event - if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { - // Dialog isn't getting focus when dragging (#8063) - this.uiDialog.focus(); - } - } - }); - - this.uiDialogTitlebarClose = $("") - .button({ - label: this.options.closeText, - icons: { - primary: "ui-icon-closethick" - }, - text: false - }) - .addClass("ui-dialog-titlebar-close") - .appendTo( this.uiDialogTitlebar ); - this._on( this.uiDialogTitlebarClose, { - click: function( event ) { - event.preventDefault(); - this.close( event ); - } - }); - - uiDialogTitle = $("") - .uniqueId() - .addClass("ui-dialog-title") - .prependTo( this.uiDialogTitlebar ); - this._title( uiDialogTitle ); - - this.uiDialog.attr({ - "aria-labelledby": uiDialogTitle.attr("id") - }); - }, - - _title: function( title ) { - if ( !this.options.title ) { - title.html(" "); - } - title.text( this.options.title ); - }, - - _createButtonPane: function() { - this.uiDialogButtonPane = $("
") - .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); - - this.uiButtonSet = $("
") - .addClass("ui-dialog-buttonset") - .appendTo( this.uiDialogButtonPane ); - - this._createButtons(); - }, - - _createButtons: function() { - var that = this, - buttons = this.options.buttons; - - // if we already have a button pane, remove it - this.uiDialogButtonPane.remove(); - this.uiButtonSet.empty(); - - if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { - this.uiDialog.removeClass("ui-dialog-buttons"); - return; - } - - $.each( buttons, function( name, props ) { - var click, buttonOptions; - props = $.isFunction( props ) ? - { click: props, text: name } : - props; - // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); - // Change the context for the click callback to be the main element - click = props.click; - props.click = function() { - click.apply( that.element[0], arguments ); - }; - buttonOptions = { - icons: props.icons, - text: props.showText - }; - delete props.icons; - delete props.showText; - $( "", props ) - .button( buttonOptions ) - .appendTo( that.uiButtonSet ); - }); - this.uiDialog.addClass("ui-dialog-buttons"); - this.uiDialogButtonPane.appendTo( this.uiDialog ); - }, - - _makeDraggable: function() { - var that = this, - options = this.options; - - function filteredUi( ui ) { - return { - position: ui.position, - offset: ui.offset - }; - } - - this.uiDialog.draggable({ - cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", - handle: ".ui-dialog-titlebar", - containment: "document", - start: function( event, ui ) { - $( this ).addClass("ui-dialog-dragging"); - that._blockFrames(); - that._trigger( "dragStart", event, filteredUi( ui ) ); - }, - drag: function( event, ui ) { - that._trigger( "drag", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - options.position = [ - ui.position.left - that.document.scrollLeft(), - ui.position.top - that.document.scrollTop() - ]; - $( this ).removeClass("ui-dialog-dragging"); - that._unblockFrames(); - that._trigger( "dragStop", event, filteredUi( ui ) ); - } - }); - }, - - _makeResizable: function() { - var that = this, - options = this.options, - handles = options.resizable, - // .ui-resizable has position: relative defined in the stylesheet - // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css("position"), - resizeHandles = typeof handles === "string" ? - handles : - "n,e,s,w,se,sw,ne,nw"; - - function filteredUi( ui ) { - return { - originalPosition: ui.originalPosition, - originalSize: ui.originalSize, - position: ui.position, - size: ui.size - }; - } - - this.uiDialog.resizable({ - cancel: ".ui-dialog-content", - containment: "document", - alsoResize: this.element, - maxWidth: options.maxWidth, - maxHeight: options.maxHeight, - minWidth: options.minWidth, - minHeight: this._minHeight(), - handles: resizeHandles, - start: function( event, ui ) { - $( this ).addClass("ui-dialog-resizing"); - that._blockFrames(); - that._trigger( "resizeStart", event, filteredUi( ui ) ); - }, - resize: function( event, ui ) { - that._trigger( "resize", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - options.height = $( this ).height(); - options.width = $( this ).width(); - $( this ).removeClass("ui-dialog-resizing"); - that._unblockFrames(); - that._trigger( "resizeStop", event, filteredUi( ui ) ); - } - }) - .css( "position", position ); - }, - - _minHeight: function() { - var options = this.options; - - return options.height === "auto" ? - options.minHeight : - Math.min( options.minHeight, options.height ); - }, - - _position: function() { - // Need to show the dialog to get the actual offset in the position plugin - var isVisible = this.uiDialog.is(":visible"); - if ( !isVisible ) { - this.uiDialog.show(); - } - this.uiDialog.position( this.options.position ); - if ( !isVisible ) { - this.uiDialog.hide(); - } - }, - - _setOptions: function( options ) { - var that = this, - resize = false, - resizableOptions = {}; - - $.each( options, function( key, value ) { - that._setOption( key, value ); - - if ( key in sizeRelatedOptions ) { - resize = true; - } - if ( key in resizableRelatedOptions ) { - resizableOptions[ key ] = value; - } - }); - - if ( resize ) { - this._size(); - this._position(); - } - if ( this.uiDialog.is(":data(ui-resizable)") ) { - this.uiDialog.resizable( "option", resizableOptions ); - } - }, - - _setOption: function( key, value ) { - /*jshint maxcomplexity:15*/ - var isDraggable, isResizable, - uiDialog = this.uiDialog; - - if ( key === "dialogClass" ) { - uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); - } - - if ( key === "disabled" ) { - return; - } - - this._super( key, value ); - - if ( key === "appendTo" ) { - this.uiDialog.appendTo( this._appendTo() ); - } - - if ( key === "buttons" ) { - this._createButtons(); - } - - if ( key === "closeText" ) { - this.uiDialogTitlebarClose.button({ - // Ensure that we always pass a string - label: "" + value - }); - } - - if ( key === "draggable" ) { - isDraggable = uiDialog.is(":data(ui-draggable)"); - if ( isDraggable && !value ) { - uiDialog.draggable("destroy"); - } - - if ( !isDraggable && value ) { - this._makeDraggable(); - } - } - - if ( key === "position" ) { - this._position(); - } - - if ( key === "resizable" ) { - // currently resizable, becoming non-resizable - isResizable = uiDialog.is(":data(ui-resizable)"); - if ( isResizable && !value ) { - uiDialog.resizable("destroy"); - } - - // currently resizable, changing handles - if ( isResizable && typeof value === "string" ) { - uiDialog.resizable( "option", "handles", value ); - } - - // currently non-resizable, becoming resizable - if ( !isResizable && value !== false ) { - this._makeResizable(); - } - } - - if ( key === "title" ) { - this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); - } - }, - - _size: function() { - // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content - // divs will both have width and height set, so we need to reset them - var nonContentHeight, minContentHeight, maxContentHeight, - options = this.options; - - // Reset content sizing - this.element.show().css({ - width: "auto", - minHeight: 0, - maxHeight: "none", - height: 0 - }); - - if ( options.minWidth > options.width ) { - options.width = options.minWidth; - } - - // reset wrapper sizing - // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css({ - height: "auto", - width: options.width - }) - .outerHeight(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); - maxContentHeight = typeof options.maxHeight === "number" ? - Math.max( 0, options.maxHeight - nonContentHeight ) : - "none"; - - if ( options.height === "auto" ) { - this.element.css({ - minHeight: minContentHeight, - maxHeight: maxContentHeight, - height: "auto" - }); - } else { - this.element.height( Math.max( 0, options.height - nonContentHeight ) ); - } - - if (this.uiDialog.is(":data(ui-resizable)") ) { - this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); - } - }, - - _blockFrames: function() { - this.iframeBlocks = this.document.find( "iframe" ).map(function() { - var iframe = $( this ); - - return $( "
" ) - .css({ - position: "absolute", - width: iframe.outerWidth(), - height: iframe.outerHeight() - }) - .appendTo( iframe.parent() ) - .offset( iframe.offset() )[0]; - }); - }, - - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, - - _allowInteraction: function( event ) { - if ( $( event.target ).closest(".ui-dialog").length ) { - return true; - } - - // TODO: Remove hack when datepicker implements - // the .ui-front logic (#8989) - return !!$( event.target ).closest(".ui-datepicker").length; - }, - - _createOverlay: function() { - if ( !this.options.modal ) { - return; - } - - var that = this, - widgetFullName = this.widgetFullName; - if ( !$.ui.dialog.overlayInstances ) { - // Prevent use of anchors and inputs. - // We use a delay in case the overlay is created from an - // event that we're going to be cancelling. (#2804) - this._delay(function() { - // Handle .dialog().dialog("close") (#4065) - if ( $.ui.dialog.overlayInstances ) { - this.document.bind( "focusin.dialog", function( event ) { - if ( !that._allowInteraction( event ) ) { - event.preventDefault(); - $(".ui-dialog:visible:last .ui-dialog-content") - .data( widgetFullName )._focusTabbable(); - } - }); - } - }); - } - - this.overlay = $("
") - .addClass("ui-widget-overlay ui-front") - .appendTo( this._appendTo() ); - this._on( this.overlay, { - mousedown: "_keepFocus" - }); - $.ui.dialog.overlayInstances++; - }, - - _destroyOverlay: function() { - if ( !this.options.modal ) { - return; - } - - if ( this.overlay ) { - $.ui.dialog.overlayInstances--; - - if ( !$.ui.dialog.overlayInstances ) { - this.document.unbind( "focusin.dialog" ); - } - this.overlay.remove(); - this.overlay = null; - } - } -}); - -$.ui.dialog.overlayInstances = 0; - -// DEPRECATED -if ( $.uiBackCompat !== false ) { - // position option with array notation - // just override with old implementation - $.widget( "ui.dialog", $.ui.dialog, { - _position: function() { - var position = this.options.position, - myAt = [], - offset = [ 0, 0 ], - isVisible; - - if ( position ) { - if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { - myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; - if ( myAt.length === 1 ) { - myAt[1] = myAt[0]; - } - - $.each( [ "left", "top" ], function( i, offsetPosition ) { - if ( +myAt[ i ] === myAt[ i ] ) { - offset[ i ] = myAt[ i ]; - myAt[ i ] = offsetPosition; - } - }); - - position = { - my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + - myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), - at: myAt.join(" ") - }; - } - - position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); - } else { - position = $.ui.dialog.prototype.options.position; - } - - // need to show the dialog to get the actual offset in the position plugin - isVisible = this.uiDialog.is(":visible"); - if ( !isVisible ) { - this.uiDialog.show(); - } - this.uiDialog.position( position ); - if ( !isVisible ) { - this.uiDialog.hide(); - } - } - }); -} - -}( jQuery ) ); - -(function( $, undefined ) { - -var rvertical = /up|down|vertical/, - rpositivemotion = /up|left|vertical|horizontal/; - -$.effects.effect.blind = function( o, done ) { - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - direction = o.direction || "up", - vertical = rvertical.test( direction ), - ref = vertical ? "height" : "width", - ref2 = vertical ? "top" : "left", - motion = rpositivemotion.test( direction ), - animation = {}, - show = mode === "show", - wrapper, distance, margin; - - // if already wrapped, the wrapper's properties are my property. #6245 - if ( el.parent().is( ".ui-effects-wrapper" ) ) { - $.effects.save( el.parent(), props ); - } else { - $.effects.save( el, props ); - } - el.show(); - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - distance = wrapper[ ref ](); - margin = parseFloat( wrapper.css( ref2 ) ) || 0; - - animation[ ref ] = show ? distance : 0; - if ( !motion ) { - el - .css( vertical ? "bottom" : "right", 0 ) - .css( vertical ? "top" : "left", "auto" ) - .css({ position: "absolute" }); - - animation[ ref2 ] = show ? margin : distance + margin; - } - - // start at 0 if we are showing - if ( show ) { - wrapper.css( ref, 0 ); - if ( ! motion ) { - wrapper.css( ref2, margin + distance ); - } - } - - // Animate - wrapper.animate( animation, { - duration: o.duration, - easing: o.easing, - queue: false, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.bounce = function( o, done ) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - - // defaults: - mode = $.effects.setMode( el, o.mode || "effect" ), - hide = mode === "hide", - show = mode === "show", - direction = o.direction || "up", - distance = o.distance, - times = o.times || 5, - - // number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), - speed = o.duration / anims, - easing = o.easing, - - // utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), - i, - upAnim, - downAnim, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - // Avoid touching opacity to prevent clearType and PNG issues in IE - if ( show || hide ) { - props.push( "opacity" ); - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); // Create Wrapper - - // default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; - } - - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = 0; - - // if we are showing, force opacity 0 and set the initial position - // then do the "first" animation - el.css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); - } - - // start at the smallest distance if we are hiding - if ( hide ) { - distance = distance / Math.pow( 2, times - 1 ); - } - - downAnim = {}; - downAnim[ ref ] = 0; - // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( i = 0; i < times; i++ ) { - upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); - - distance = hide ? distance * 2 : distance / 2; - } - - // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ); - } - - el.queue(function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.clip = function( o, done ) { - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "vertical", - vert = direction === "vertical", - size = vert ? "height" : "width", - position = vert ? "top" : "left", - animation = {}, - wrapper, animate, distance; - - // Save & Show - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - animate = ( el[0].tagName === "IMG" ) ? wrapper : el; - distance = animate[ size ](); - - // Shift - if ( show ) { - animate.css( size, 0 ); - animate.css( position, distance / 2 ); - } - - // Create Animation Object: - animation[ size ] = show ? distance : 0; - animation[ position ] = show ? 0 : distance / 2; - - // Animate - animate.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( !show ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.drop = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", - animation = { - opacity: show ? 1 : 0 - }, - distance; - - // Adjust - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; - - if ( show ) { - el - .css( "opacity", 0 ) - .css( ref, motion === "pos" ? -distance : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( motion === "pos" ? "+=" : "-=" ) : - ( motion === "pos" ? "-=" : "+=" ) ) + - distance; - - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.explode = function( o, done ) { - - var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, - cells = rows, - el = $( this ), - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - - // show and then visibility:hidden the element before calculating offset - offset = el.show().css( "visibility", "hidden" ).offset(), - - // width and height of a piece - width = Math.ceil( el.outerWidth() / cells ), - height = Math.ceil( el.outerHeight() / rows ), - pieces = [], - - // loop - i, j, left, top, mx, my; - - // children animate complete: - function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { - animComplete(); - } - } - - // clone the element for each row and cell. - for( i = 0; i < rows ; i++ ) { // ===> - top = offset.top + i * height; - my = i - ( rows - 1 ) / 2 ; - - for( j = 0; j < cells ; j++ ) { // ||| - left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2 ; - - // Create a clone of the now hidden main element that will be absolute positioned - // within a wrapper div off the -left and -top equal to size of our pieces - el - .clone() - .appendTo( "body" ) - .wrap( "
" ) - .css({ - position: "absolute", - visibility: "visible", - left: -j * width, - top: -i * height - }) - - // select the wrapper - make it overflow: hidden and absolute positioned based on - // where the original was located +left and +top equal to the size of pieces - .parent() - .addClass( "ui-effects-explode" ) - .css({ - position: "absolute", - overflow: "hidden", - width: width, - height: height, - left: left + ( show ? mx * width : 0 ), - top: top + ( show ? my * height : 0 ), - opacity: show ? 0 : 1 - }).animate({ - left: left + ( show ? 0 : mx * width ), - top: top + ( show ? 0 : my * height ), - opacity: show ? 1 : 0 - }, o.duration || 500, o.easing, childComplete ); - } - } - - function animComplete() { - el.css({ - visibility: "visible" - }); - $( pieces ).remove(); - if ( !show ) { - el.hide(); - } - done(); - } -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.fade = function( o, done ) { - var el = $( this ), - mode = $.effects.setMode( el, o.mode || "toggle" ); - - el.animate({ - opacity: mode - }, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: done - }); -}; - -})( jQuery ); - -(function( $, undefined ) { - -$.effects.effect.fold = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - hide = mode === "hide", - size = o.size || 15, - percent = /([0-9]+)%/.exec( size ), - horizFirst = !!o.horizFirst, - widthFirst = show !== horizFirst, - ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], - duration = o.duration / 2, - wrapper, distance, - animation1 = {}, - animation2 = {}; - - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - distance = widthFirst ? - [ wrapper.width(), wrapper.height() ] : - [ wrapper.height(), wrapper.width() ]; - - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; - } - if ( show ) { - wrapper.css( horizFirst ? { - height: 0, - width: size - } : { - height: size, - width: 0 - }); - } - - // Animation - animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; - animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; - - // Animate - wrapper - .animate( animation1, duration, o.easing ) - .animate( animation2, duration, o.easing, function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.highlight = function( o, done ) { - var elem = $( this ), - props = [ "backgroundImage", "backgroundColor", "opacity" ], - mode = $.effects.setMode( elem, o.mode || "show" ), - animation = { - backgroundColor: elem.css( "backgroundColor" ) - }; - - if (mode === "hide") { - animation.opacity = 0; - } - - $.effects.save( elem, props ); - - elem - .show() - .css({ - backgroundImage: "none", - backgroundColor: o.color || "#ffff99" - }) - .animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - elem.hide(); - } - $.effects.restore( elem, props ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.pulsate = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "show" ), - show = mode === "show", - hide = mode === "hide", - showhide = ( show || mode === "hide" ), - - // showing or hiding leaves of the "last" animation - anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), - duration = o.duration / anims, - animateTo = 0, - queue = elem.queue(), - queuelen = queue.length, - i; - - if ( show || !elem.is(":visible")) { - elem.css( "opacity", 0 ).show(); - animateTo = 1; - } - - // anims - 1 opacity "toggles" - for ( i = 1; i < anims; i++ ) { - elem.animate({ - opacity: animateTo - }, duration, o.easing ); - animateTo = 1 - animateTo; - } - - elem.animate({ - opacity: animateTo - }, duration, o.easing); - - elem.queue(function() { - if ( hide ) { - elem.hide(); - } - done(); - }); - - // We just queued up "anims" animations, we need to put them next in the queue - if ( queuelen > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - elem.dequeue(); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.puff = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "hide" ), - hide = mode === "hide", - percent = parseInt( o.percent, 10 ) || 150, - factor = percent / 100, - original = { - height: elem.height(), - width: elem.width(), - outerHeight: elem.outerHeight(), - outerWidth: elem.outerWidth() - }; - - $.extend( o, { - effect: "scale", - queue: false, - fade: true, - mode: mode, - complete: done, - percent: hide ? percent : 100, - from: hide ? - original : - { - height: original.height * factor, - width: original.width * factor, - outerHeight: original.outerHeight * factor, - outerWidth: original.outerWidth * factor - } - }); - - elem.effect( o ); -}; - -$.effects.effect.scale = function( o, done ) { - - // Create element - var el = $( this ), - options = $.extend( true, {}, o ), - mode = $.effects.setMode( el, o.mode || "effect" ), - percent = parseInt( o.percent, 10 ) || - ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), - direction = o.direction || "both", - origin = o.origin, - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }, - factor = { - y: direction !== "horizontal" ? (percent / 100) : 1, - x: direction !== "vertical" ? (percent / 100) : 1 - }; - - // We are going to pass this effect to the size effect: - options.effect = "size"; - options.queue = false; - options.complete = done; - - // Set default origin and restore for show/hide - if ( mode !== "effect" ) { - options.origin = origin || ["middle","center"]; - options.restore = true; - } - - options.from = o.from || ( mode === "show" ? { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - } : original ); - options.to = { - height: original.height * factor.y, - width: original.width * factor.x, - outerHeight: original.outerHeight * factor.y, - outerWidth: original.outerWidth * factor.x - }; - - // Fade option to support puff - if ( options.fade ) { - if ( mode === "show" ) { - options.from.opacity = 0; - options.to.opacity = 1; - } - if ( mode === "hide" ) { - options.from.opacity = 1; - options.to.opacity = 0; - } - } - - // Animate - el.effect( options ); - -}; - -$.effects.effect.size = function( o, done ) { - - // Create element - var original, baseline, factor, - el = $( this ), - props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], - - // Always restore - props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], - - // Copy for children - props2 = [ "width", "height", "overflow" ], - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], - - // Set options - mode = $.effects.setMode( el, o.mode || "effect" ), - restore = o.restore || mode !== "effect", - scale = o.scale || "both", - origin = o.origin || [ "middle", "center" ], - position = el.css( "position" ), - props = restore ? props0 : props1, - zero = { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - }; - - if ( mode === "show" ) { - el.show(); - } - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }; - - if ( o.mode === "toggle" && mode === "show" ) { - el.from = o.to || zero; - el.to = o.from || original; - } else { - el.from = o.from || ( mode === "show" ? zero : original ); - el.to = o.to || ( mode === "hide" ? zero : original ); - } - - // Set scaling factor - factor = { - from: { - y: el.from.height / original.height, - x: el.from.width / original.width - }, - to: { - y: el.to.height / original.height, - x: el.to.width / original.width - } - }; - - // Scale the css box - if ( scale === "box" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( vProps ); - el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - props = props.concat( hProps ); - el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); - el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); - } - } - - // Scale the content - if ( scale === "content" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( cProps ).concat( props2 ); - el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); - } - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - el.css( "overflow", "hidden" ).css( el.from ); - - // Adjust - if (origin) { // Calculate baseline shifts - baseline = $.effects.getBaseline( origin, original ); - el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; - el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; - el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; - el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; - } - el.css( el.from ); // set top & left - - // Animate - if ( scale === "content" || scale === "both" ) { // Scale the children - - // Add margins/font-size - vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); - hProps = hProps.concat([ "marginLeft", "marginRight" ]); - props2 = props0.concat(vProps).concat(hProps); - - el.find( "*[width]" ).each( function(){ - var child = $( this ), - c_original = { - height: child.height(), - width: child.width(), - outerHeight: child.outerHeight(), - outerWidth: child.outerWidth() - }; - if (restore) { - $.effects.save(child, props2); - } - - child.from = { - height: c_original.height * factor.from.y, - width: c_original.width * factor.from.x, - outerHeight: c_original.outerHeight * factor.from.y, - outerWidth: c_original.outerWidth * factor.from.x - }; - child.to = { - height: c_original.height * factor.to.y, - width: c_original.width * factor.to.x, - outerHeight: c_original.height * factor.to.y, - outerWidth: c_original.width * factor.to.x - }; - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); - child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); - child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); - } - - // Animate children - child.css( child.from ); - child.animate( child.to, o.duration, o.easing, function() { - - // Restore children - if ( restore ) { - $.effects.restore( child, props2 ); - } - }); - }); - } - - // Animate - el.animate( el.to, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( el.to.opacity === 0 ) { - el.css( "opacity", el.from.opacity ); - } - if( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - if ( !restore ) { - - // we need to calculate our new positioning based on the scaling - if ( position === "static" ) { - el.css({ - position: "relative", - top: el.to.top, - left: el.to.left - }); - } else { - $.each([ "top", "left" ], function( idx, pos ) { - el.css( pos, function( _, str ) { - var val = parseInt( str, 10 ), - toRef = idx ? el.to.left : el.to.top; - - // if original was "auto", recalculate the new value from wrapper - if ( str === "auto" ) { - return toRef + "px"; - } - - return val + toRef + "px"; - }); - }); - } - } - - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.shake = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "effect" ), - direction = o.direction || "left", - distance = o.distance || 20, - times = o.times || 3, - anims = times * 2 + 1, - speed = Math.round(o.duration/anims), - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - animation = {}, - animation1 = {}, - animation2 = {}, - i, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; - - // Animate - el.animate( animation, speed, o.easing ); - - // Shakes - for ( i = 1; i < times; i++ ) { - el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); - } - el - .animate( animation1, speed, o.easing ) - .animate( animation, speed / 2, o.easing ) - .queue(function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.slide = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "width", "height" ], - mode = $.effects.setMode( el, o.mode || "show" ), - show = mode === "show", - direction = o.direction || "left", - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - distance, - animation = {}; - - // Adjust - $.effects.save( el, props ); - el.show(); - distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); - - $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - if ( show ) { - el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( positiveMotion ? "+=" : "-=") : - ( positiveMotion ? "-=" : "+=")) + - distance; - - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.effects.effect.transfer = function( o, done ) { - var elem = $( this ), - target = $( o.to ), - targetFixed = target.css( "position" ) === "fixed", - body = $("body"), - fixTop = targetFixed ? body.scrollTop() : 0, - fixLeft = targetFixed ? body.scrollLeft() : 0, - endPosition = target.offset(), - animation = { - top: endPosition.top - fixTop , - left: endPosition.left - fixLeft , - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = elem.offset(), - transfer = $( "
" ) - .appendTo( document.body ) - .addClass( o.className ) - .css({ - top: startPosition.top - fixTop , - left: startPosition.left - fixLeft , - height: elem.innerHeight(), - width: elem.innerWidth(), - position: targetFixed ? "fixed" : "absolute" - }) - .animate( animation, o.duration, o.easing, function() { - transfer.remove(); - done(); - }); -}; - -})(jQuery); - -(function( $, undefined ) { - -$.widget( "ui.menu", { - version: "1.10.3", - defaultElement: "
    ", - delay: 300, - options: { - icons: { - submenu: "ui-icon-carat-1-e" - }, - menus: "ul", - position: { - my: "left top", - at: "right top" - }, - role: "menu", - - // callbacks - blur: null, - focus: null, - select: null - }, - - _create: function() { - this.activeMenu = this.element; - // flag used to prevent firing of the click handler - // as the event bubbles up through nested menus - this.mouseHandled = false; - this.element - .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) - .attr({ - role: this.options.role, - tabIndex: 0 - }) - // need to catch all clicks on disabled menu - // not possible through _on - .bind( "click" + this.eventNamespace, $.proxy(function( event ) { - if ( this.options.disabled ) { - event.preventDefault(); - } - }, this )); - - if ( this.options.disabled ) { - this.element - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } - - this._on({ - // Prevent focus from sticking to links inside menu after clicking - // them (focus should always stay on UL during navigation). - "mousedown .ui-menu-item > a": function( event ) { - event.preventDefault(); - }, - "click .ui-state-disabled > a": function( event ) { - event.preventDefault(); - }, - "click .ui-menu-item:has(a)": function( event ) { - var target = $( event.target ).closest( ".ui-menu-item" ); - if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { - this.mouseHandled = true; - - this.select( event ); - // Open submenu on click - if ( target.has( ".ui-menu" ).length ) { - this.expand( event ); - } else if ( !this.element.is( ":focus" ) ) { - // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); - - // If the active item is on the top level, let it stay active. - // Otherwise, blur the active item since it is no longer visible. - if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { - clearTimeout( this.timer ); - } - } - } - }, - "mouseenter .ui-menu-item": function( event ) { - var target = $( event.currentTarget ); - // Remove ui-state-active class from siblings of the newly focused menu item - // to avoid a jump caused by adjacent elements both having a class with a border - target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); - this.focus( event, target ); - }, - mouseleave: "collapseAll", - "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { - // If there's already an active item, keep it active - // If not, activate the first item - var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); - - if ( !keepActiveItem ) { - this.focus( event, item ); - } - }, - blur: function( event ) { - this._delay(function() { - if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { - this.collapseAll( event ); - } - }); - }, - keydown: "_keydown" - }); - - this.refresh(); - - // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( !$( event.target ).closest( ".ui-menu" ).length ) { - this.collapseAll( event ); - } - - // Reset the mouseHandled flag - this.mouseHandled = false; - } - }); - }, - - _destroy: function() { - // Destroy (sub)menus - this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).addBack() - .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-disabled" ) - .removeUniqueId() - .show(); - - // Destroy menu items - this.element.find( ".ui-menu-item" ) - .removeClass( "ui-menu-item" ) - .removeAttr( "role" ) - .removeAttr( "aria-disabled" ) - .children( "a" ) - .removeUniqueId() - .removeClass( "ui-corner-all ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-carat" ) ) { - elem.remove(); - } - }); - - // Destroy menu dividers - this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); - }, - - _keydown: function( event ) { - /*jshint maxcomplexity:20*/ - var match, prev, character, skip, regex, - preventDefault = true; - - function escape( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - break; - case $.ui.keyCode.UP: - this.previous( event ); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - break; - case $.ui.keyCode.LEFT: - this.collapse( event ); - break; - case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); - } - break; - case $.ui.keyCode.ENTER: - case $.ui.keyCode.SPACE: - this._activate( event ); - break; - case $.ui.keyCode.ESCAPE: - this.collapse( event ); - break; - default: - preventDefault = false; - prev = this.previousFilter || ""; - character = String.fromCharCode( event.keyCode ); - skip = false; - - clearTimeout( this.filterTimer ); - - if ( character === prev ) { - skip = true; - } else { - character = prev + character; - } - - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); - }); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : - match; - - // If no matches on the current filter, reset to the last character pressed - // to move down the menu to the first item that starts with that character - if ( !match.length ) { - character = String.fromCharCode( event.keyCode ); - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); - }); - } - - if ( match.length ) { - this.focus( event, match ); - if ( match.length > 1 ) { - this.previousFilter = character; - this.filterTimer = this._delay(function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } - } else { - delete this.previousFilter; - } - } - - if ( preventDefault ) { - event.preventDefault(); - } - }, - - _activate: function( event ) { - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - this.expand( event ); - } else { - this.select( event ); - } - } - }, - - refresh: function() { - var menus, - icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); - - // Initialize nested menus - submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .hide() - .attr({ - role: this.options.role, - "aria-hidden": "true", - "aria-expanded": "false" - }) - .each(function() { - var menu = $( this ), - item = menu.prev( "a" ), - submenuCarat = $( "" ) - .addClass( "ui-menu-icon ui-icon " + icon ) - .data( "ui-menu-submenu-carat", true ); - - item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCarat ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); - }); - - menus = submenus.add( this.element ); - - // Don't refresh list items that are already adapted - menus.children( ":not(.ui-menu-item):has(a)" ) - .addClass( "ui-menu-item" ) - .attr( "role", "presentation" ) - .children( "a" ) - .uniqueId() - .addClass( "ui-corner-all" ) - .attr({ - tabIndex: -1, - role: this._itemRole() - }); - - // Initialize unlinked menu-items containing spaces and/or dashes only as dividers - menus.children( ":not(.ui-menu-item)" ).each(function() { - var item = $( this ); - // hyphen, em dash, en dash - if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { - item.addClass( "ui-widget-content ui-menu-divider" ); - } - }); - - // Add aria-disabled attribute to any disabled menu item - menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); - - // If the active item has been removed, blur the menu - if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - this.blur(); - } - }, - - _itemRole: function() { - return { - menu: "menuitem", - listbox: "option" - }[ this.options.role ]; - }, - - _setOption: function( key, value ) { - if ( key === "icons" ) { - this.element.find( ".ui-menu-icon" ) - .removeClass( this.options.icons.submenu ) - .addClass( value.submenu ); - } - this._super( key, value ); - }, - - focus: function( event, item ) { - var nested, focused; - this.blur( event, event && event.type === "focus" ); - - this._scrollIntoView( item ); - - this.active = item.first(); - focused = this.active.children( "a" ).addClass( "ui-state-focus" ); - // Only update aria-activedescendant if there's a role - // otherwise we assume focus is managed elsewhere - if ( this.options.role ) { - this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); - } - - // Highlight active parent menu item, if any - this.active - .parent() - .closest( ".ui-menu-item" ) - .children( "a:first" ) - .addClass( "ui-state-active" ); - - if ( event && event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay(function() { - this._close(); - }, this.delay ); - } - - nested = item.children( ".ui-menu" ); - if ( nested.length && ( /^mouse/.test( event.type ) ) ) { - this._startOpening(nested); - } - this.activeMenu = item.parent(); - - this._trigger( "focus", event, { item: item } ); - }, - - _scrollIntoView: function( item ) { - var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; - scroll = this.activeMenu.scrollTop(); - elementHeight = this.activeMenu.height(); - itemHeight = item.height(); - - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } - } - }, - - blur: function( event, fromFocus ) { - if ( !fromFocus ) { - clearTimeout( this.timer ); - } - - if ( !this.active ) { - return; - } - - this.active.children( "a" ).removeClass( "ui-state-focus" ); - this.active = null; - - this._trigger( "blur", event, { item: this.active } ); - }, - - _startOpening: function( submenu ) { - clearTimeout( this.timer ); - - // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the carat icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { - return; - } - - this.timer = this._delay(function() { - this._close(); - this._open( submenu ); - }, this.delay ); - }, - - _open: function( submenu ) { - var position = $.extend({ - of: this.active - }, this.options.position ); - - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) - .hide() - .attr( "aria-hidden", "true" ); - - submenu - .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); - }, - - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay(function() { - // If we were passed an event, look for the submenu that contains the event - var currentMenu = all ? this.element : - $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - - // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; - } - - this._close( currentMenu ); - - this.blur( event ); - this.activeMenu = currentMenu; - }, this.delay ); - }, - - // With no arguments, closes the currently active menu - if nothing is active - // it closes all menus. If passed an argument, it will search for menus BELOW - _close: function( startMenu ) { - if ( !startMenu ) { - startMenu = this.active ? this.active.parent() : this.element; - } - - startMenu - .find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); - }, - - collapse: function( event ) { - var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { - this._close(); - this.focus( event, newItem ); - } - }, - - expand: function( event ) { - var newItem = this.active && - this.active - .children( ".ui-menu " ) - .children( ".ui-menu-item" ) - .first(); - - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); - - // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay(function() { - this.focus( event, newItem ); - }); - } - }, - - next: function( event ) { - this._move( "next", "first", event ); - }, - - previous: function( event ) { - this._move( "prev", "last", event ); - }, - - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; - }, - - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; - }, - - _move: function( direction, filter, event ) { - var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { - next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .eq( -1 ); - } else { - next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .eq( 0 ); - } - } - if ( !next || !next.length || !this.active ) { - next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); - } - - this.focus( event, next ); - }, - - nextPage: function( event ) { - var item, base, height; - - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isLastItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.nextAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base - height < 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ) - [ !this.active ? "first" : "last" ]() ); - } - }, - - previousPage: function( event ) { - var item, base, height; - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isFirstItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.prevAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base + height > 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - } - }, - - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); - }, - - select: function( event ) { - // TODO: It should never be possible to not have an active item at this - // point, but the tests don't trigger mouseenter before click. - this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); - var ui = { item: this.active }; - if ( !this.active.has( ".ui-menu" ).length ) { - this.collapseAll( event, true ); - } - this._trigger( "select", event, ui ); - } -}); - -}( jQuery )); - -(function( $, undefined ) { - -$.ui = $.ui || {}; - -var cachedScrollbarWidth, - max = Math.max, - abs = Math.abs, - round = Math.round, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+(\.[\d]+)?%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} - -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -function getDimensions( elem ) { - var raw = elem[0]; - if ( raw.nodeType === 9 ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: 0, left: 0 } - }; - } - if ( $.isWindow( raw ) ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } - }; - } - if ( raw.preventDefault ) { - return { - width: 0, - height: 0, - offset: { top: raw.pageY, left: raw.pageX } - }; - } - return { - width: elem.outerWidth(), - height: elem.outerHeight(), - offset: elem.offset() - }; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "
    " ), - innerDiv = div.children()[0]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[0].clientWidth; - } - - div.remove(); - - return (cachedScrollbarWidth = w1 - w2); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), - overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); - return { - width: hasOverflowY ? $.position.scrollbarWidth() : 0, - height: hasOverflowX ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isWindow = $.isWindow( withinElement[0] ); - return { - element: withinElement, - isWindow: isWindow, - offset: withinElement.offset() || { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - width: isWindow ? withinElement.width() : withinElement.outerWidth(), - height: isWindow ? withinElement.height() : withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - target = $( options.of ), - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - dimensions = getDimensions( target ); - if ( target[0].preventDefault ) { - // force left top to allow flipping - options.at = "left top"; - } - targetWidth = dimensions.width; - targetHeight = dimensions.height; - targetOffset = dimensions.offset; - // clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - }); - - // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each(function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - // if the browser doesn't support fractions, then round for consistent results - if ( !$.support.offsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); - } - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem : elem - }); - } - }); - - if ( options.using ) { - // adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - }); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // element is wider than within - if ( data.collisionWidth > outerWidth ) { - // element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; - position.left += overLeft - newOverRight; - // element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - // element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - // too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - // too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - // adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // element is taller than within - if ( data.collisionHeight > outerHeight ) { - // element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; - position.top += overTop - newOverBottom; - // element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - // element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - // too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - // too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - // adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } - else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { - position.top += myOffset + atOffset + offset; - } - } - else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; - if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -// fraction support test -(function () { - var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); - - //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" - }; - if ( body ) { - $.extend( testElementStyle, { - position: "absolute", - left: "-1000px", - top: "-1000px" - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - div.style.cssText = "position: absolute; left: 10.7432222px;"; - - offsetLeft = $( div ).offset().left; - $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; - - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); -})(); - -}( jQuery ) ); - -(function( $, undefined ) { - -$.widget( "ui.progressbar", { - version: "1.10.3", - options: { - max: 100, - value: 0, - - change: null, - complete: null - }, - - min: 0, - - _create: function() { - // Constrain initial value - this.oldValue = this.options.value = this._constrainedValue(); - - this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .attr({ - // Only set static values, aria-valuenow and aria-valuemax are - // set inside _refreshValue() - role: "progressbar", - "aria-valuemin": this.min - }); - - this.valueDiv = $( "
    " ) - .appendTo( this.element ); - - this._refreshValue(); - }, - - _destroy: function() { - this.element - .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - - this.valueDiv.remove(); - }, - - value: function( newValue ) { - if ( newValue === undefined ) { - return this.options.value; - } - - this.options.value = this._constrainedValue( newValue ); - this._refreshValue(); - }, - - _constrainedValue: function( newValue ) { - if ( newValue === undefined ) { - newValue = this.options.value; - } - - this.indeterminate = newValue === false; - - // sanitize value - if ( typeof newValue !== "number" ) { - newValue = 0; - } - - return this.indeterminate ? false : - Math.min( this.options.max, Math.max( this.min, newValue ) ); - }, - - _setOptions: function( options ) { - // Ensure "value" option is set after other values (like max) - var value = options.value; - delete options.value; - - this._super( options ); - - this.options.value = this._constrainedValue( value ); - this._refreshValue(); - }, - - _setOption: function( key, value ) { - if ( key === "max" ) { - // Don't allow a max less than min - value = Math.max( this.min, value ); - } - - this._super( key, value ); - }, - - _percentage: function() { - return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); - }, - - _refreshValue: function() { - var value = this.options.value, - percentage = this._percentage(); - - this.valueDiv - .toggle( this.indeterminate || value > this.min ) - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); - - this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); - - if ( this.indeterminate ) { - this.element.removeAttr( "aria-valuenow" ); - if ( !this.overlayDiv ) { - this.overlayDiv = $( "
    " ).appendTo( this.valueDiv ); - } - } else { - this.element.attr({ - "aria-valuemax": this.options.max, - "aria-valuenow": value - }); - if ( this.overlayDiv ) { - this.overlayDiv.remove(); - this.overlayDiv = null; - } - } - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - if ( value === this.options.max ) { - this._trigger( "complete" ); - } - } -}); - -})( jQuery ); - -(function( $, undefined ) { - -// number of pages in a slider -// (how many times can you page up/down to go through the whole range) -var numPages = 5; - -$.widget( "ui.slider", $.ui.mouse, { - version: "1.10.3", - widgetEventPrefix: "slide", - - options: { - animate: false, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null, - - // callbacks - change: null, - slide: null, - start: null, - stop: null - }, - - _create: function() { - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - - this.element - .addClass( "ui-slider" + - " ui-slider-" + this.orientation + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all"); - - this._refresh(); - this._setOption( "disabled", this.options.disabled ); - - this._animateOff = false; - }, - - _refresh: function() { - this._createRange(); - this._createHandles(); - this._setupEvents(); - this._refreshValue(); - }, - - _createHandles: function() { - var i, handleCount, - options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), - handle = "", - handles = []; - - handleCount = ( options.values && options.values.length ) || 1; - - if ( existingHandles.length > handleCount ) { - existingHandles.slice( handleCount ).remove(); - existingHandles = existingHandles.slice( 0, handleCount ); - } - - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); - } - - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); - - this.handle = this.handles.eq( 0 ); - - this.handles.each(function( i ) { - $( this ).data( "ui-slider-handle-index", i ); - }); - }, - - _createRange: function() { - var options = this.options, - classes = ""; - - if ( options.range ) { - if ( options.range === true ) { - if ( !options.values ) { - options.values = [ this._valueMin(), this._valueMin() ]; - } else if ( options.values.length && options.values.length !== 2 ) { - options.values = [ options.values[0], options.values[0] ]; - } else if ( $.isArray( options.values ) ) { - options.values = options.values.slice(0); - } - } - - if ( !this.range || !this.range.length ) { - this.range = $( "
    " ) - .appendTo( this.element ); - - classes = "ui-slider-range" + - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - " ui-widget-header ui-corner-all"; - } else { - this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) - // Handle range switching from true to min/max - .css({ - "left": "", - "bottom": "" - }); - } - - this.range.addClass( classes + - ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); - } else { - this.range = $([]); - } - }, - - _setupEvents: function() { - var elements = this.handles.add( this.range ).filter( "a" ); - this._off( elements ); - this._on( elements, this._handleEvents ); - this._hoverable( elements ); - this._focusable( elements ); - }, - - _destroy: function() { - this.handles.remove(); - this.range.remove(); - - this.element - .removeClass( "ui-slider" + - " ui-slider-horizontal" + - " ui-slider-vertical" + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" ); - - this._mouseDestroy(); - }, - - _mouseCapture: function( event ) { - var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, - that = this, - o = this.options; - - if ( o.disabled ) { - return false; - } - - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); - - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - this.handles.each(function( i ) { - var thisDistance = Math.abs( normValue - that.values(i) ); - if (( distance > thisDistance ) || - ( distance === thisDistance && - (i === that._lastChangedValue || that.values(i) === o.min ))) { - distance = thisDistance; - closestHandle = $( this ); - index = i; - } - }); - - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; - - this._handleIndex = index; - - closestHandle - .addClass( "ui-state-active" ) - .focus(); - - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - - ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + - ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) - }; - - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); - } - this._animateOff = true; - return true; - }, - - _mouseStart: function() { - return true; - }, - - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); - - this._slide( event, this._handleIndex, normValue ); - - return false; - }, - - _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); - this._mouseSliding = false; - - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); - - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; - - return false; - }, - - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; - }, - - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); - } - - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; - } - - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; - - return this._trimAlignValue( valueMouse ); - }, - - _start: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - return this._trigger( "start", event, uiHash ); - }, - - _slide: function( event, index, newVal ) { - var otherVal, - newValues, - allowed; - - if ( this.options.values && this.options.values.length ) { - otherVal = this.values( index ? 0 : 1 ); - - if ( ( this.options.values.length === 2 && this.options.range === true ) && - ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) - ) { - newVal = otherVal; - } - - if ( newVal !== this.values( index ) ) { - newValues = this.values(); - newValues[ index ] = newVal; - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal, - values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal, true ); - } - } - } else { - if ( newVal !== this.value() ) { - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); - } - } - } - }, - - _stop: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "stop", event, uiHash ); - }, - - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - //store the last changed value index for reference when handles overlap - this._lastChangedValue = index; - - this._trigger( "change", event, uiHash ); - } - }, - - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; - } - - if ( arguments.length ) { - if ( $.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this.options.values && this.options.values.length ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } - }, - - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( key === "range" && this.options.range === true ) { - if ( value === "min" ) { - this.options.value = this._values( 0 ); - this.options.values = null; - } else if ( value === "max" ) { - this.options.value = this._values( this.options.values.length-1 ); - this.options.values = null; - } - } - - if ( $.isArray( this.options.values ) ) { - valsLength = this.options.values.length; - } - - $.Widget.prototype._setOption.apply( this, arguments ); - - switch ( key ) { - case "orientation": - this._detectOrientation(); - this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { - this._change( null, i ); - } - this._animateOff = false; - break; - case "min": - case "max": - this._animateOff = true; - this._refreshValue(); - this._animateOff = false; - break; - case "range": - this._animateOff = true; - this._refresh(); - this._animateOff = false; - break; - } - }, - - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; - }, - - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; - - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); - - return val; - } else if ( this.options.values && this.options.values.length ) { - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i+= 1) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); - } - - return vals; - } else { - return []; - } - }, - - // returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); - } - if ( val >= this._valueMax() ) { - return this._valueMax(); - } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = (val - this._valueMin()) % step, - alignValue = val - valModStep; - - if ( Math.abs(valModStep) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); - } - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed(5) ); - }, - - _valueMin: function() { - return this.options.min; - }, - - _valueMax: function() { - return this.options.max; - }, - - _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, - oRange = this.options.range, - o = this.options, - that = this, - animate = ( !this._animateOff ) ? o.animate : false, - _set = {}; - - if ( this.options.values && this.options.values.length ) { - this.handles.each(function( i ) { - valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; - _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( that.options.range === true ) { - if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } else { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - lastValPercent = valPercent; - }); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - }, - - _handleEvents: { - keydown: function( event ) { - /*jshint maxcomplexity:25*/ - var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - event.preventDefault(); - if ( !this._keySliding ) { - this._keySliding = true; - $( event.target ).addClass( "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; - } - - step = this.options.step; - if ( this.options.values && this.options.values.length ) { - curVal = newVal = this.values( index ); - } else { - curVal = newVal = this.value(); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = this._valueMin(); - break; - case $.ui.keyCode.END: - newVal = this._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { - return; - } - newVal = this._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { - return; - } - newVal = this._trimAlignValue( curVal - step ); - break; - } - - this._slide( event, index, newVal ); - }, - click: function( event ) { - event.preventDefault(); - }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); - - if ( this._keySliding ) { - this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - $( event.target ).removeClass( "ui-state-active" ); - } - } - } - -}); - -}(jQuery)); - -(function( $ ) { - -function modifier( fn ) { - return function() { - var previous = this.element.val(); - fn.apply( this, arguments ); - this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); - } - }; -} - -$.widget( "ui.spinner", { - version: "1.10.3", - defaultElement: "", - widgetEventPrefix: "spin", - options: { - culture: null, - icons: { - down: "ui-icon-triangle-1-s", - up: "ui-icon-triangle-1-n" - }, - incremental: true, - max: null, - min: null, - numberFormat: null, - page: 10, - step: 1, - - change: null, - spin: null, - start: null, - stop: null - }, - - _create: function() { - // handle string values that need to be parsed - this._setOption( "max", this.options.max ); - this._setOption( "min", this.options.min ); - this._setOption( "step", this.options.step ); - - // format the value, but don't constrain - this._value( this.element.val(), true ); - - this._draw(); - this._on( this._events ); - this._refresh(); - - // turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - }); - }, - - _getCreateOptions: function() { - var options = {}, - element = this.element; - - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value !== undefined && value.length ) { - options[ option ] = value; - } - }); - - return options; - }, - - _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { - event.preventDefault(); - } - }, - keyup: "_stop", - focus: function() { - this.previous = this.element.val(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - this._stop(); - this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); - } - }, - mousewheel: function( event, delta ) { - if ( !delta ) { - return; - } - if ( !this.spinning && !this._start( event ) ) { - return false; - } - - this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); - clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay(function() { - if ( this.spinning ) { - this._stop( event ); - } - }, 100 ); - event.preventDefault(); - }, - "mousedown .ui-spinner-button": function( event ) { - var previous; - - // We never want the buttons to have focus; whenever the user is - // interacting with the spinner, the focus should be on the input. - // If the input is focused then this.previous is properly set from - // when the input first received focus. If the input is not focused - // then we need to set this.previous based on the value before spinning. - previous = this.element[0] === this.document[0].activeElement ? - this.previous : this.element.val(); - function checkFocus() { - var isActive = this.element[0] === this.document[0].activeElement; - if ( !isActive ) { - this.element.focus(); - this.previous = previous; - // support: IE - // IE sets focus asynchronously, so we need to check if focus - // moved off of the input because the user clicked on the button. - this._delay(function() { - this.previous = previous; - }); - } - } - - // ensure focus is on (or stays on) the text field - event.preventDefault(); - checkFocus.call( this ); - - // support: IE - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - // and check (again) if focus moved off of the input. - this.cancelBlur = true; - this._delay(function() { - delete this.cancelBlur; - checkFocus.call( this ); - }); - - if ( this._start( event ) === false ) { - return; - } - - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { - // button will add ui-state-active if mouse was down while mouseleave and kept down - if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { - return; - } - - if ( this._start( event ) === false ) { - return false; - } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - // TODO: do we really want to consider this a stop? - // shouldn't we just stop the repeater and wait until mouseup before - // we trigger the stop event? - "mouseleave .ui-spinner-button": "_stop" - }, - - _draw: function() { - var uiSpinner = this.uiSpinner = this.element - .addClass( "ui-spinner-input" ) - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) - .parent() - // add buttons - .append( this._buttonHtml() ); - - this.element.attr( "role", "spinbutton" ); - - // button bindings - this.buttons = uiSpinner.find( ".ui-spinner-button" ) - .attr( "tabIndex", -1 ) - .button() - .removeClass( "ui-corner-all" ); - - // IE 6 doesn't understand height: 50% for the buttons - // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && - uiSpinner.height() > 0 ) { - uiSpinner.height( uiSpinner.height() ); - } - - // disable spinner if element was already disabled - if ( this.options.disabled ) { - this.disable(); - } - }, - - _keydown: function( event ) { - var options = this.options, - keyCode = $.ui.keyCode; - - switch ( event.keyCode ) { - case keyCode.UP: - this._repeat( null, 1, event ); - return true; - case keyCode.DOWN: - this._repeat( null, -1, event ); - return true; - case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); - return true; - case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); - return true; - } - - return false; - }, - - _uiSpinnerHtml: function() { - return ""; - }, - - _buttonHtml: function() { - return "" + - "" + - "" + - "" + - "" + - "" + - ""; - }, - - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { - return false; - } - - if ( !this.counter ) { - this.counter = 1; - } - this.spinning = true; - return true; - }, - - _repeat: function( i, steps, event ) { - i = i || 500; - - clearTimeout( this.timer ); - this.timer = this._delay(function() { - this._repeat( 40, steps, event ); - }, i ); - - this._spin( steps * this.options.step, event ); - }, - - _spin: function( step, event ) { - var value = this.value() || 0; - - if ( !this.counter ) { - this.counter = 1; - } - - value = this._adjustValue( value + step * this._increment( this.counter ) ); - - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { - this._value( value ); - this.counter++; - } - }, - - _increment: function( i ) { - var incremental = this.options.incremental; - - if ( incremental ) { - return $.isFunction( incremental ) ? - incremental( i ) : - Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); - } - - return 1; - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _adjustValue: function( value ) { - var base, aboveMin, - options = this.options; - - // make sure we're at a valid step - // - find out where we are relative to the base (min or 0) - base = options.min !== null ? options.min : 0; - aboveMin = value - base; - // - round to the nearest step - aboveMin = Math.round(aboveMin / options.step) * options.step; - // - rounding is based on 0, so adjust back to our base - value = base + aboveMin; - - // fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); - - // clamp the value - if ( options.max !== null && value > options.max) { - return options.max; - } - if ( options.min !== null && value < options.min ) { - return options.min; - } - - return value; - }, - - _stop: function( event ) { - if ( !this.spinning ) { - return; - } - - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); - this.counter = 0; - this.spinning = false; - this._trigger( "stop", event ); - }, - - _setOption: function( key, value ) { - if ( key === "culture" || key === "numberFormat" ) { - var prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); - return; - } - - if ( key === "max" || key === "min" || key === "step" ) { - if ( typeof value === "string" ) { - value = this._parse( value ); - } - } - if ( key === "icons" ) { - this.buttons.first().find( ".ui-icon" ) - .removeClass( this.options.icons.up ) - .addClass( value.up ); - this.buttons.last().find( ".ui-icon" ) - .removeClass( this.options.icons.down ) - .addClass( value.down ); - } - - this._super( key, value ); - - if ( key === "disabled" ) { - if ( value ) { - this.element.prop( "disabled", true ); - this.buttons.button( "disable" ); - } else { - this.element.prop( "disabled", false ); - this.buttons.button( "enable" ); - } - } - }, - - _setOptions: modifier(function( options ) { - this._super( options ); - this._value( this.element.val() ); - }), - - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { - val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; - } - return val === "" || isNaN( val ) ? null : val; - }, - - _format: function( value ) { - if ( value === "" ) { - return ""; - } - return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : - value; - }, - - _refresh: function() { - this.element.attr({ - "aria-valuemin": this.options.min, - "aria-valuemax": this.options.max, - // TODO: what should we do with values that can't be parsed? - "aria-valuenow": this._parse( this.element.val() ) - }); - }, - - // update the value without triggering change - _value: function( value, allowAny ) { - var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); - } - value = this._format( parsed ); - } - } - this.element.val( value ); - this._refresh(); - }, - - _destroy: function() { - this.element - .removeClass( "ui-spinner-input" ) - .prop( "disabled", false ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - this.uiSpinner.replaceWith( this.element ); - }, - - stepUp: modifier(function( steps ) { - this._stepUp( steps ); - }), - _stepUp: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * this.options.step ); - this._stop(); - } - }, - - stepDown: modifier(function( steps ) { - this._stepDown( steps ); - }), - _stepDown: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * -this.options.step ); - this._stop(); - } - }, - - pageUp: modifier(function( pages ) { - this._stepUp( (pages || 1) * this.options.page ); - }), - - pageDown: modifier(function( pages ) { - this._stepDown( (pages || 1) * this.options.page ); - }), - - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); - } - modifier( this._value ).call( this, newVal ); - }, - - widget: function() { - return this.uiSpinner; - } -}); - -}( jQuery ) ); - -(function( $, undefined ) { - -var tabId = 0, - rhash = /#.*$/; - -function getNextTabId() { - return ++tabId; -} - -function isLocal( anchor ) { - return anchor.hash.length > 1 && - decodeURIComponent( anchor.href.replace( rhash, "" ) ) === - decodeURIComponent( location.href.replace( rhash, "" ) ); -} - -$.widget( "ui.tabs", { - version: "1.10.3", - delay: 300, - options: { - active: null, - collapsible: false, - event: "click", - heightStyle: "content", - hide: null, - show: null, - - // callbacks - activate: null, - beforeActivate: null, - beforeLoad: null, - load: null - }, - - _create: function() { - var that = this, - options = this.options; - - this.running = false; - - this.element - .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ) - // Prevent users from focusing disabled tabs via click - .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); - } - }) - // support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); - } - }); - - this._processTabs(); - options.active = this._initialActive(); - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( $.isArray( options.disabled ) ) { - options.disabled = $.unique( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - }) - ) ).sort(); - } - - // check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( options.active ); - } else { - this.active = $(); - } - - this._refresh(); - - if ( this.active.length ) { - this.load( options.active ); - } - }, - - _initialActive: function() { - var active = this.options.active, - collapsible = this.options.collapsible, - locationHash = location.hash.substring( 1 ); - - if ( active === null ) { - // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each(function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { - active = i; - return false; - } - }); - } - - // check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); - } - - // no active tab, set to false - if ( active === null || active === -1 ) { - active = this.tabs.length ? 0 : false; - } - } - - // handle numbers: negative, out of range - if ( active !== false ) { - active = this.tabs.index( this.tabs.eq( active ) ); - if ( active === -1 ) { - active = collapsible ? false : 0; - } - } - - // don't allow collapsible: false and active: false - if ( !collapsible && active === false && this.anchors.length ) { - active = 0; - } - - return active; - }, - - _getCreateEventData: function() { - return { - tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) - }; - }, - - _tabKeydown: function( event ) { - /*jshint maxcomplexity:15*/ - var focusedTab = $( this.document[0].activeElement ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), - goingForward = true; - - if ( this._handlePageNav( event ) ) { - return; - } - - switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; - } - - // Focus the appropriate tab, based on which key was pressed - event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); - - // Navigating with control key will prevent automatic activation - if ( !event.ctrlKey ) { - // Update aria-selected immediately so that AT think the tab is already selected. - // Otherwise AT may confuse the user by stating that they need to activate the tab, - // but the tab will already be activated by the time the announcement finishes. - focusedTab.attr( "aria-selected", "false" ); - this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); - - this.activating = this._delay(function() { - this.option( "active", selectedIndex ); - }, this.delay ); - } - }, - - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { - return; - } - - // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { - event.preventDefault(); - this.active.focus(); - } - }, - - // Alt+page up/down moves focus to the previous/next tab (and activates) - _handlePageNav: function( event ) { - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { - this._activate( this._focusNextTab( this.options.active - 1, false ) ); - return true; - } - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { - this._activate( this._focusNextTab( this.options.active + 1, true ) ); - return true; - } - }, - - _findNextTab: function( index, goingForward ) { - var lastTabIndex = this.tabs.length - 1; - - function constrain() { - if ( index > lastTabIndex ) { - index = 0; - } - if ( index < 0 ) { - index = lastTabIndex; - } - return index; - } - - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { - index = goingForward ? index + 1 : index - 1; - } - - return index; - }, - - _focusNextTab: function( index, goingForward ) { - index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).focus(); - return index; - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "disabled" ) { - // don't use the widget factory's disabled handling - this._setupDisabled( value ); - return; - } - - this._super( key, value); - - if ( key === "collapsible" ) { - this.element.toggleClass( "ui-tabs-collapsible", value ); - // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); - } - } - - if ( key === "event" ) { - this._setupEvents( value ); - } - - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); - } - }, - - _tabId: function( tab ) { - return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); - }, - - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - - refresh: function() { - var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); - - // get disabled tabs from class attribute from HTML - // this will get converted to a boolean if needed in _refresh() - options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { - return lis.index( tab ); - }); - - this._processTabs(); - - // was collapsed or no tabs - if ( options.active === false || !this.anchors.length ) { - options.active = false; - this.active = $(); - // was active, but active tab is gone - } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { - // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { - options.active = false; - this.active = $(); - // activate previous tab - } else { - this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); - } - // was active, active tab still exists - } else { - // make sure active index is correct - options.active = this.tabs.index( this.active ); - } - - this._refresh(); - }, - - _refresh: function() { - this._setupDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); - - this.tabs.not( this.active ).attr({ - "aria-selected": "false", - tabIndex: -1 - }); - this.panels.not( this._getPanelForTab( this.active ) ) - .hide() - .attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - - // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active - .addClass( "ui-tabs-active ui-state-active" ) - .attr({ - "aria-selected": "true", - tabIndex: 0 - }); - this._getPanelForTab( this.active ) - .show() - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - } - }, - - _processTabs: function() { - var that = this; - - this.tablist = this._getList() - .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ); - - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .addClass( "ui-state-default ui-corner-top" ) - .attr({ - role: "tab", - tabIndex: -1 - }); - - this.anchors = this.tabs.map(function() { - return $( "a", this )[ 0 ]; - }) - .addClass( "ui-tabs-anchor" ) - .attr({ - role: "presentation", - tabIndex: -1 - }); - - this.panels = $(); - - this.anchors.each(function( i, anchor ) { - var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); - - // inline tab - if ( isLocal( anchor ) ) { - selector = anchor.hash; - panel = that.element.find( that._sanitizeSelector( selector ) ); - // remote tab - } else { - panelId = that._tabId( tab ); - selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); - } - panel.attr( "aria-live", "polite" ); - } - - if ( panel.length) { - that.panels = that.panels.add( panel ); - } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); - } - tab.attr({ - "aria-controls": selector.substring( 1 ), - "aria-labelledby": anchorId - }); - panel.attr( "aria-labelledby", anchorId ); - }); - - this.panels - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .attr( "role", "tabpanel" ); - }, - - // allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.element.find( "ol,ul" ).eq( 0 ); - }, - - _createPanel: function( id ) { - return $( "
    " ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .data( "ui-tabs-destroy", true ); - }, - - _setupDisabled: function( disabled ) { - if ( $.isArray( disabled ) ) { - if ( !disabled.length ) { - disabled = false; - } else if ( disabled.length === this.anchors.length ) { - disabled = true; - } - } - - // disable tabs - for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - $( li ) - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } else { - $( li ) - .removeClass( "ui-state-disabled" ) - .removeAttr( "aria-disabled" ); - } - } - - this.options.disabled = disabled; - }, - - _setupEvents: function( event ) { - var events = { - click: function( event ) { - event.preventDefault(); - } - }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); - - this._focusable( this.tabs ); - this._hoverable( this.tabs ); - }, - - _setupHeightStyle: function( heightStyle ) { - var maxHeight, - parent = this.element.parent(); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - maxHeight -= this.element.outerHeight() - this.element.height(); - - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - - this.element.children().not( this.panels ).each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.panels.each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.panels.each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }).height( maxHeight ); - } - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : this._getPanelForTab( tab ), - toHide = !active.length ? $() : this._getPanelForTab( active ), - eventData = { - oldTab: active, - oldPanel: toHide, - newTab: collapsing ? $() : tab, - newPanel: toShow - }; - - event.preventDefault(); - - if ( tab.hasClass( "ui-state-disabled" ) || - // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || - // can't switch durning an animation - this.running || - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.tabs.index( tab ); - - this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { - this.xhr.abort(); - } - - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); - } - - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); - } - this._toggle( event, eventData ); - }, - - // handles show/hide for selecting tabs - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel; - - this.running = true; - - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } - - function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); - } else { - toShow.show(); - complete(); - } - } - - // start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - show(); - }); - } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - toHide.hide(); - show(); - } - - toHide.attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - eventData.oldTab.attr( "aria-selected", "false" ); - // If we're switching tabs, remove the old tab from the tab order. - // If we're opening from collapsed state, remove the previous tab from the tab order. - // If we're collapsing, then keep the collapsing tab in the tab order. - if ( toShow.length && toHide.length ) { - eventData.oldTab.attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.tabs.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow.attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - eventData.newTab.attr({ - "aria-selected": "true", - tabIndex: 0 - }); - }, - - _activate: function( index ) { - var anchor, - active = this._findActive( index ); - - // trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the current active header - if ( !active.length ) { - active = this.active; - } - - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler({ - target: anchor, - currentTarget: anchor, - preventDefault: $.noop - }); - }, - - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); - }, - - _getIndex: function( index ) { - // meta-function to give users option to provide a href string instead of a numerical index. - if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); - } - - return index; - }, - - _destroy: function() { - if ( this.xhr ) { - this.xhr.abort(); - } - - this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); - - this.tablist - .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .removeAttr( "role" ); - - this.anchors - .removeClass( "ui-tabs-anchor" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeUniqueId(); - - this.tabs.add( this.panels ).each(function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); - } else { - $( this ) - .removeClass( "ui-state-default ui-state-active ui-state-disabled " + - "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-live" ) - .removeAttr( "aria-busy" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "role" ); - } - }); - - this.tabs.each(function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { - li - .attr( "aria-controls", prev ) - .removeData( "ui-tabs-aria-controls" ); - } else { - li.removeAttr( "aria-controls" ); - } - }); - - this.panels.show(); - - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); - } - }, - - enable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === false ) { - return; - } - - if ( index === undefined ) { - disabled = false; - } else { - index = this._getIndex( index ); - if ( $.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { - return num !== index ? num : null; - }); - } else { - disabled = $.map( this.tabs, function( li, num ) { - return num !== index ? num : null; - }); - } - } - this._setupDisabled( disabled ); - }, - - disable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === true ) { - return; - } - - if ( index === undefined ) { - disabled = true; - } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { - return; - } - if ( $.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); - } else { - disabled = [ index ]; - } - } - this._setupDisabled( disabled ); - }, - - load: function( index, event ) { - index = this._getIndex( index ); - var that = this, - tab = this.tabs.eq( index ), - anchor = tab.find( ".ui-tabs-anchor" ), - panel = this._getPanelForTab( tab ), - eventData = { - tab: tab, - panel: panel - }; - - // not remote - if ( isLocal( anchor[ 0 ] ) ) { - return; - } - - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - - // support: jQuery <1.8 - // jQuery <1.8 returns false if the request is canceled in beforeSend, - // but as of 1.8, $.ajax() always returns a jqXHR object. - if ( this.xhr && this.xhr.statusText !== "canceled" ) { - tab.addClass( "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); - - this.xhr - .success(function( response ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - panel.html( response ); - that._trigger( "load", event, eventData ); - }, 1 ); - }) - .complete(function( jqXHR, status ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - if ( status === "abort" ) { - that.panels.stop( false, true ); - } - - tab.removeClass( "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); - - if ( jqXHR === that.xhr ) { - delete that.xhr; - } - }, 1 ); - }); - } - }, - - _ajaxSettings: function( anchor, event, eventData ) { - var that = this; - return { - url: anchor.attr( "href" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); - } - }; - }, - - _getPanelForTab: function( tab ) { - var id = $( tab ).attr( "aria-controls" ); - return this.element.find( this._sanitizeSelector( "#" + id ) ); - } -}); - -})( jQuery ); - -(function( $ ) { - -var increments = 0; - -function addDescribedBy( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); -} - -function removeDescribedBy( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), - index = $.inArray( id, describedby ); - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } - - elem.removeData( "ui-tooltip-id" ); - describedby = $.trim( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } -} - -$.widget( "ui.tooltip", { - version: "1.10.3", - options: { - content: function() { - // support: IE<9, Opera in jQuery <1.7 - // .text() can't accept undefined, so coerce to a string - var title = $( this ).attr( "title" ) || ""; - // Escape title, since we're going from an attribute to raw HTML - return $( "" ).text( title ).html(); - }, - hide: true, - // Disabled elements have inconsistent behavior across browsers (#8661) - items: "[title]:not([disabled])", - position: { - my: "left top+15", - at: "left bottom", - collision: "flipfit flip" - }, - show: true, - tooltipClass: null, - track: false, - - // callbacks - close: null, - open: null - }, - - _create: function() { - this._on({ - mouseover: "open", - focusin: "open" - }); - - // IDs of generated tooltips, needed for destroy - this.tooltips = {}; - // IDs of parent tooltips where we removed the title attribute - this.parents = {}; - - if ( this.options.disabled ) { - this._disable(); - } - }, - - _setOption: function( key, value ) { - var that = this; - - if ( key === "disabled" ) { - this[ value ? "_disable" : "_enable" ](); - this.options[ key ] = value; - // disable element style changes - return; - } - - this._super( key, value ); - - if ( key === "content" ) { - $.each( this.tooltips, function( id, element ) { - that._updateContent( element ); - }); - } - }, - - _disable: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, element ) { - var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; - that.close( event, true ); - }); - - // remove title attributes to prevent native tooltips - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .attr( "title", "" ); - } - }); - }, - - _enable: function() { - // restore title attributes - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - }); - }, - - open: function( event ) { - var that = this, - target = $( event ? event.target : this.element ) - // we need closest here due to mouseover bubbling, - // but always pointing at the same event target - .closest( this.options.items ); - - // No element to show a tooltip for or the tooltip is already open - if ( !target.length || target.data( "ui-tooltip-id" ) ) { - return; - } - - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); - } - - target.data( "ui-tooltip-open", true ); - - // kill parent tooltips, custom or native, for hover - if ( event && event.type === "mouseover" ) { - target.parents().each(function() { - var parent = $( this ), - blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); - blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); - } - if ( parent.attr( "title" ) ) { - parent.uniqueId(); - that.parents[ this.id ] = { - element: this, - title: parent.attr( "title" ) - }; - parent.attr( "title", "" ); - } - }); - } - - this._updateContent( target, event ); - }, - - _updateContent: function( target, event ) { - var content, - contentOption = this.options.content, - that = this, - eventType = event ? event.type : null; - - if ( typeof contentOption === "string" ) { - return this._open( event, target, contentOption ); - } - - content = contentOption.call( target[0], function( response ) { - // ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { - return; - } - // IE may instantly serve a cached response for ajax requests - // delay this call to _open so the other call to _open runs first - that._delay(function() { - // jQuery creates a special event for focusin when it doesn't - // exist natively. To improve performance, the native event - // object is reused and the type is changed. Therefore, we can't - // rely on the type being correct after the event finished - // bubbling, so we set it back to the previous value. (#8740) - if ( event ) { - event.type = eventType; - } - this._open( event, target, response ); - }); - }); - if ( content ) { - this._open( event, target, content ); - } - }, - - _open: function( event, target, content ) { - var tooltip, events, delayedShow, - positionOption = $.extend( {}, this.options.position ); - - if ( !content ) { - return; - } - - // Content can be updated multiple times. If the tooltip already - // exists, then just update the content and bail. - tooltip = this._find( target ); - if ( tooltip.length ) { - tooltip.find( ".ui-tooltip-content" ).html( content ); - return; - } - - // if we have a title, clear it to prevent the native tooltip - // we have to check first to avoid defining a title if none exists - // (we don't want to cause an element to start matching [title]) - // - // We use removeAttr only for key events, to allow IE to export the correct - // accessible attributes. For mouse events, set to empty string to avoid - // native tooltip showing up (happens only when removing inside mouseover). - if ( target.is( "[title]" ) ) { - if ( event && event.type === "mouseover" ) { - target.attr( "title", "" ); - } else { - target.removeAttr( "title" ); - } - } - - tooltip = this._tooltip( target ); - addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); - - function position( event ) { - positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { - return; - } - tooltip.position( positionOption ); - } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { - mousemove: position - }); - // trigger once to override element-relative positioning - position( event ); - } else { - tooltip.position( $.extend({ - of: target - }, this.options.position ) ); - } - - tooltip.hide(); - - this._show( tooltip, this.options.show ); - // Handle tracking tooltips that are shown with a delay (#8644). As soon - // as the tooltip is visible, position the tooltip using the most recent - // event. - if ( this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval(function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); - } - }, $.fx.interval ); - } - - this._trigger( "open", event, { tooltip: tooltip } ); - - events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event(event); - fakeEvent.currentTarget = target[0]; - this.close( fakeEvent, true ); - } - }, - remove: function() { - this._removeTooltip( tooltip ); - } - }; - if ( !event || event.type === "mouseover" ) { - events.mouseleave = "close"; - } - if ( !event || event.type === "focusin" ) { - events.focusout = "close"; - } - this._on( true, target, events ); - }, - - close: function( event ) { - var that = this, - target = $( event ? event.currentTarget : this.element ), - tooltip = this._find( target ); - - // disabling closes the tooltip, so we need to track when we're closing - // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( this.closing ) { - return; - } - - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); - - // only set title if we had one before (see comment in _open()) - if ( target.data( "ui-tooltip-title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); - } - - removeDescribedBy( target ); - - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); - }); - - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); - // Remove 'remove' binding only on delegated targets - if ( target[0] !== this.element[0] ) { - this._off( target, "remove" ); - } - this._off( this.document, "mousemove" ); - - if ( event && event.type === "mouseleave" ) { - $.each( this.parents, function( id, parent ) { - $( parent.element ).attr( "title", parent.title ); - delete that.parents[ id ]; - }); - } - - this.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); - this.closing = false; - }, - - _tooltip: function( element ) { - var id = "ui-tooltip-" + increments++, - tooltip = $( "
    " ) - .attr({ - id: id, - role: "tooltip" - }) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ); - $( "
    " ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); - tooltip.appendTo( this.document[0].body ); - this.tooltips[ id ] = element; - return tooltip; - }, - - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? $( "#" + id ) : $(); - }, - - _removeTooltip: function( tooltip ) { - tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; - }, - - _destroy: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, element ) { - // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; - that.close( event, true ); - - // Remove immediately; destroying an open tooltip doesn't use the - // hide animation - $( "#" + id ).remove(); - - // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - element.removeData( "ui-tooltip-title" ); - } - }); - } -}); - -}( jQuery ) ); \ No newline at end of file diff --git a/examples/lock.html b/examples/lock.html deleted file mode 100644 index dfa24d491..000000000 --- a/examples/lock.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
    -

    Selectize.js

    -
    -

    Locking

    -

    Selectize controls can be locked to prevent user interaction.

    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    - -
    -
    - - diff --git a/examples/movies.html b/examples/movies.html deleted file mode 100644 index 76d7e8a8c..000000000 --- a/examples/movies.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
    -

    Selectize.js

    -
    -

    Loading from API

    -

    This demo shows how to integrate third-party data, loaded asynchronously.

    -
    - - -
    - -
    -
    - - \ No newline at end of file diff --git a/examples/optgroups.html b/examples/optgroups.html deleted file mode 100644 index 463c86333..000000000 --- a/examples/optgroups.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
    -

    Selectize.js

    - -
    -

    Optgroups (basic)

    -
    - - -
    - -
    - -
    -

    Optgroups (repeated options)

    -
    - - -
    - -
    - -
    -

    Optgroups (programmatic)

    -
    - - -
    - -
    - -
    -

    Plugin: "optgroup_columns"

    -
    - -
    - -
    -
    - - \ No newline at end of file diff --git a/examples/performance.html b/examples/performance.html deleted file mode 100644 index d53c5fd50..000000000 --- a/examples/performance.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
    -

    Selectize.js

    -
    -

    Performance

    -

    This shows how it performs with 25,000 items.

    -
    - - -
    - -
    -
    - - \ No newline at end of file diff --git a/examples/plugins.html b/examples/plugins.html deleted file mode 100644 index 8bd8447a2..000000000 --- a/examples/plugins.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - - -
    -

    Selectize.js

    - -
    -

    Plugin: "remove_button"

    -
    - - -
    -
    - - -
    - -
    - -
    -

    Plugin: "restore_on_backspace"

    -
    - - -
    - -
    - -
    -

    Plugin: "drag_drop"

    -
    - - -
    -
    - - -
    - -
    - -
    -

    Plugin: "dropdown_header"

    -
    - - -
    - -
    -
    - - \ No newline at end of file diff --git a/examples/required.html b/examples/required.html deleted file mode 100644 index 87b7c72db..000000000 --- a/examples/required.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
    -

    Selectize.js

    - -
    -

    Required Element

    -
    -
    - - -
    - -
    -
    -
    - -
    - -
    - - \ No newline at end of file diff --git a/examples/rtl.html b/examples/rtl.html deleted file mode 100644 index ce5a152be..000000000 --- a/examples/rtl.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - Selectize.js Demo - - - - - - - - - - -
    -

    Selectize.js

    - -
    -

    Right-to-left Support (RTL)

    -
    - - -
    - -
    - -
    -

    Right-to-left Support (RTL) – Single

    -
    - - -
    - -
    - -
    - - \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index 72aebb5b3..000000000 --- a/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "selectize", - "keywords": [ - "select", - "ui", - "form", - "input", - "control", - "autocomplete", - "tagging", - "tag" - ], - "description": "Selectize is a jQuery-based custom UI control. Useful for tagging, contact lists, country selectors, etc.", - "homepage": "http://brianreavis.github.io/selectize.js/", - "demo": "http://brianreavis.github.io/selectize.js/", - "docs": "https://github.com/brianreavis/selectize.js", - "bugs": "https://github.com/brianreavis/selectize.js/issues", - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - } - ], - "maintainers": [ - { - "name": "Brian Reavis", - "email": "brian@thirdroute.com", - "url": "http://thirdroute.com" - } - ], - "dependencies": { - "jquery": ">=1.6" - } -} diff --git a/src/.wrapper.js b/src/.wrapper.js deleted file mode 100644 index 8aed36cbe..000000000 --- a/src/.wrapper.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * selectize.js (v@@version) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -/*jshint curly:false */ -/*jshint browser:true */ - -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery','sifter','microplugin'], factory); - } else if (typeof exports === 'object') { - module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); - } else { - root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); - } -}(this, function($, Sifter, MicroPlugin) { - 'use strict'; - - @@js - - return Selectize; -})); \ No newline at end of file diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index 06390e6e8..000000000 --- a/src/constants.js +++ /dev/null @@ -1,21 +0,0 @@ -var IS_MAC = /Mac/.test(navigator.userAgent); - -var KEY_A = 65; -var KEY_COMMA = 188; -var KEY_RETURN = 13; -var KEY_ESC = 27; -var KEY_LEFT = 37; -var KEY_UP = 38; -var KEY_P = 80; -var KEY_RIGHT = 39; -var KEY_DOWN = 40; -var KEY_N = 78; -var KEY_BACKSPACE = 8; -var KEY_DELETE = 46; -var KEY_SHIFT = 16; -var KEY_CMD = IS_MAC ? 91 : 17; -var KEY_CTRL = IS_MAC ? 18 : 17; -var KEY_TAB = 9; - -var TAG_SELECT = 1; -var TAG_INPUT = 2; diff --git a/src/contrib/highlight.js b/src/contrib/highlight.js deleted file mode 100644 index 888bc9072..000000000 --- a/src/contrib/highlight.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * highlight v3 | MIT license | Johann Burkard - * Highlights arbitrary terms in a node. - * - * - Modified by Marshal 2011-6-24 (added regex) - * - Modified by Brian Reavis 2012-8-27 (cleanup) - */ - -var highlight = function($element, pattern) { - if (typeof pattern === 'string' && !pattern.length) return; - var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern; - - var highlight = function(node) { - var skip = 0; - if (node.nodeType === 3) { - var pos = node.data.search(regex); - if (pos >= 0 && node.data.length > 0) { - var match = node.data.match(regex); - var spannode = document.createElement('span'); - spannode.className = 'highlight'; - var middlebit = node.splitText(pos); - var endbit = middlebit.splitText(match[0].length); - var middleclone = middlebit.cloneNode(true); - spannode.appendChild(middleclone); - middlebit.parentNode.replaceChild(spannode, middlebit); - skip = 1; - } - } else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { - for (var i = 0; i < node.childNodes.length; ++i) { - i += highlight(node.childNodes[i]); - } - } - return skip; - }; - - return $element.each(function() { - highlight(this); - }); -}; \ No newline at end of file diff --git a/src/contrib/microevent.js b/src/contrib/microevent.js deleted file mode 100644 index 49c75260c..000000000 --- a/src/contrib/microevent.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * MicroEvent - to make any js object an event emitter - * - * - pure javascript - server compatible, browser compatible - * - dont rely on the browser doms - * - super simple - you get it immediatly, no mistery, no magic involved - * - * @author Jerome Etienne (https://github.com/jeromeetienne) - */ - -var MicroEvent = function() {}; -MicroEvent.prototype = { - on: function(event, fct){ - this._events = this._events || {}; - this._events[event] = this._events[event] || []; - this._events[event].push(fct); - }, - off: function(event, fct){ - var n = arguments.length; - if (n === 0) return delete this._events; - if (n === 1) return delete this._events[event]; - - this._events = this._events || {}; - if (event in this._events === false) return; - this._events[event].splice(this._events[event].indexOf(fct), 1); - }, - trigger: function(event /* , args... */){ - this._events = this._events || {}; - if (event in this._events === false) return; - for (var i = 0; i < this._events[event].length; i++){ - this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); - } - } -}; - -/** - * Mixin will delegate all MicroEvent.js function in the destination object. - * - * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent - * - * @param {object} the object which will support MicroEvent - */ -MicroEvent.mixin = function(destObject){ - var props = ['on', 'off', 'trigger']; - for (var i = 0; i < props.length; i++){ - destObject.prototype[props[i]] = MicroEvent.prototype[props[i]]; - } -}; \ No newline at end of file diff --git a/src/defaults.js b/src/defaults.js deleted file mode 100644 index 1c69bee6b..000000000 --- a/src/defaults.js +++ /dev/null @@ -1,68 +0,0 @@ -Selectize.count = 0; -Selectize.defaults = { - plugins: [], - delimiter: ',', - splitOn: /[,]+/, // Regex or string for splitting up values from a paste command - persist: true, - diacritics: true, - create: false, - createOnBlur: false, - highlight: true, - openOnFocus: true, - maxOptions: 1000, - maxItems: null, - hideSelected: null, - addPrecedence: false, - selectOnTab: false, - preload: false, - - scrollDuration: 60, - loadThrottle: 300, - - dataAttr: 'data-data', - optgroupField: 'optgroup', - valueField: 'value', - labelField: 'text', - optgroupLabelField: 'label', - optgroupValueField: 'value', - optgroupOrder: null, - - sortField: '$order', - searchField: ['text'], - searchConjunction: 'and', - - mode: null, - wrapperClass: 'selectize-control', - inputClass: 'selectize-input', - dropdownClass: 'selectize-dropdown', - dropdownContentClass: 'selectize-dropdown-content', - - dropdownParent: null, - - /* - load : null, // function(query, callback) { ... } - score : null, // function(search) { ... } - onInitialize : null, // function() { ... } - onChange : null, // function(value) { ... } - onItemAdd : null, // function(value, $item) { ... } - onItemRemove : null, // function(value) { ... } - onClear : null, // function() { ... } - onOptionAdd : null, // function(value, data) { ... } - onOptionRemove : null, // function(value) { ... } - onOptionClear : null, // function() { ... } - onDropdownOpen : null, // function($dropdown) { ... } - onDropdownClose : null, // function($dropdown) { ... } - onType : null, // function(str) { ... } - onDelete : null, // function(values) { ... } - */ - - render: { - /* - item: null, - optgroup: null, - optgroup_header: null, - option: null, - option_create: null - */ - } -}; \ No newline at end of file diff --git a/src/less/.wrapper.css b/src/less/.wrapper.css deleted file mode 100644 index 1cf4adb28..000000000 --- a/src/less/.wrapper.css +++ /dev/null @@ -1,17 +0,0 @@ -/** - * selectize.css (v@@version) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@@css \ No newline at end of file diff --git a/src/less/selectize.bootstrap2.less b/src/less/selectize.bootstrap2.less deleted file mode 100644 index df7594c09..000000000 --- a/src/less/selectize.bootstrap2.less +++ /dev/null @@ -1,161 +0,0 @@ -/** - * selectize.bootstrap2.css (v@@version) - Bootstrap 2 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @baseFontFamily; -@selectize-font-size: @baseFontSize; -@selectize-line-height: @baseLineHeight; - -@selectize-color-text: @textColor; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @inputBackground; -@selectize-color-input-full: @inputBackground; -@selectize-color-disabled: @inputBackground; -@selectize-color-item: @btnBackgroundHighlight; -@selectize-color-item-border: @btnBorder; -@selectize-color-item-active: @dropdownLinkBackgroundHover; -@selectize-color-item-active-text: @dropdownLinkColorHover; -@selectize-color-item-active-border: darken(@selectize-color-item-active, 5%); -@selectize-color-optgroup: @dropdownBackground; -@selectize-color-optgroup-text: @grayLight; -@selectize-color-optgroup-border: @dropdownDividerTop; -@selectize-color-dropdown: @dropdownBackground; -@selectize-color-dropdown-border: @inputBorder; -@selectize-color-dropdown-border-top: @dropdownDividerTop; -@selectize-color-dropdown-item-active: @dropdownLinkBackgroundHover; -@selectize-color-dropdown-item-active-text: @dropdownLinkColorHover; -@selectize-color-dropdown-item-create-active-text: @dropdownLinkColorHover; -@selectize-lighten-disabled-item: 8%; -@selectize-lighten-disabled-item-text: 8%; -@selectize-lighten-disabled-item-border: 8%; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border-radius: @inputBorderRadius; - -@selectize-padding-x: 10px; -@selectize-padding-y: 7px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @black; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -@selectize-width-item-border: 1px; - -.selectize-dropdown { - margin: 2px 0 0 0; - z-index: @zindexDropdown; - border: 1px solid @dropdownBorder; - border-radius: @baseBorderRadius; - .box-shadow(0 5px 10px rgba(0,0,0,.2)); - - .optgroup-header { - font-size: 11px; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255,255,255,.5); - text-transform: uppercase; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } - - [data-selectable].active { - #gradient > .vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%)); - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - .transition(~"border linear .2s, box-shadow linear .2s"); - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.input-active, &.input-active:hover, .selectize-control.multi &.focus { - background: @selectize-color-input !important; - border-color: rgba(82,168,236,.8) !important; - outline: 0 !important; - outline: thin dotted \9 !important; - .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)") !important; - } -} - -.selectize-control { - &.single { - .selectize-input { - .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &:hover { - color: @grayDark; - text-decoration: none; - background-position: 0 -15px; - .transition(background-position .1s linear); - } - &.disabled { - background: @btnBackgroundHighlight !important; - .box-shadow(none); - } - } - } - &.multi { - .selectize-input { - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - &.has-items { - @padding-x: @selectize-padding-x - @selectize-padding-item-x; - padding-left: @padding-x; - padding-right: @padding-x; - } - } - .selectize-input > div { - .gradientBar(@btnBackground, @btnBackgroundHighlight, @selectize-color-item-text, none); - *background-color: @selectize-color-item; - border: @selectize-width-item-border solid @selectize-color-item-border; - .border-radius(@baseBorderRadius); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &.active { - .box-shadow(~"0 1px 2px rgba(0,0,0,.05)"); - .gradientBar(@selectize-color-item-active, @selectize-color-item-active-border, @selectize-color-item-active-text, none); - *background-color: @selectize-color-item-active; - border: @selectize-width-item-border solid @dropdownLinkBackgroundHover; - } - } - } -} \ No newline at end of file diff --git a/src/less/selectize.bootstrap3.less b/src/less/selectize.bootstrap3.less deleted file mode 100644 index 64ac8c9fd..000000000 --- a/src/less/selectize.bootstrap3.less +++ /dev/null @@ -1,136 +0,0 @@ -/** - * selectize.bootstrap3.css (v@@version) - Bootstrap 3 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @font-family-base; -@selectize-font-size: @font-size-base; -@selectize-line-height: @line-height-computed; - -@selectize-color-text: @text-color; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @input-bg; -@selectize-color-input-full: @input-bg; -@selectize-color-disabled: @input-bg; -@selectize-color-item: #efefef; -@selectize-color-item-border: rgba(0,0,0,0); -@selectize-color-item-active: @component-active-bg; -@selectize-color-item-active-text: #fff; -@selectize-color-item-active-border: rgba(0,0,0,0); -@selectize-color-optgroup: @dropdown-bg; -@selectize-color-optgroup-text: @dropdown-header-color; -@selectize-color-optgroup-border: @dropdown-divider-bg; -@selectize-color-dropdown: @dropdown-bg; -@selectize-color-dropdown-border-top: mix(@input-border, @input-bg, 0.8); -@selectize-color-dropdown-item-active: @dropdown-link-hover-bg; -@selectize-color-dropdown-item-active-text: @dropdown-link-hover-color; -@selectize-color-dropdown-item-create-active-text: @dropdown-link-hover-color; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border: 1px solid @input-border; -@selectize-border-radius: @input-border-radius; - -@selectize-width-item-border: 0; -@selectize-padding-x: @padding-base-horizontal; -@selectize-padding-y: @padding-base-vertical; -@selectize-padding-dropdown-item-x: @padding-base-horizontal; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @selectize-color-text; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -.selectize-dropdown, .selectize-dropdown.form-control { - height: auto; - padding: 0; - margin: 2px 0 0 0; - z-index: @zindex-dropdown; - background: @selectize-color-dropdown; - border: 1px solid @dropdown-fallback-border; - border: 1px solid @dropdown-border; - .selectize-border-radius(@border-radius-base); - .selectize-box-shadow(0 6px 12px rgba(0,0,0,.175)); -} - -.selectize-dropdown { - .optgroup-header { - font-size: @font-size-small; - line-height: @line-height-base; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - min-height: @input-height-base; - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.focus { - @color: @input-border-focus; - @color-rgba: rgba(red(@color), green(@color), blue(@color), .6); - border-color: @color; - outline: 0; - .selectize-box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); - } -} - -.selectize-control { - &.multi { - .selectize-input.has-items { - padding-left: @selectize-padding-x - @selectize-padding-item-x; - padding-right: @selectize-padding-x - @selectize-padding-item-x; - } - .selectize-input > div { - .selectize-border-radius(@selectize-border-radius - 1px); - } - } -} - -.form-control.selectize-control { - padding: 0; - height: auto; - border: none; - background: none; - .selectize-box-shadow(none); - .selectize-border-radius(0); -} \ No newline at end of file diff --git a/src/less/selectize.default.less b/src/less/selectize.default.less deleted file mode 100644 index 18bc00dca..000000000 --- a/src/less/selectize.default.less +++ /dev/null @@ -1,84 +0,0 @@ -/** - * selectize.default.css (v@@version) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-color-item: #1da7ee; -@selectize-color-item-text: #fff; -@selectize-color-item-active-text: #fff; -@selectize-color-item-border: #0073bb; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #00578d; -@selectize-width-item-border: 1px; -@selectize-caret-margin: 0 1px; - -.selectize-control { - &.multi { - .selectize-input { - &.has-items { - @padding-x: @selectize-padding-x - 3px; - padding-left: @padding-x; - padding-right: @padding-x; - } - &.disabled [data-value] { - color: #999; - text-shadow: none; - background: none; - .selectize-box-shadow(none); - - &, .remove { - border-color: #e6e6e6; - } - .remove { - background: none; - } - } - [data-value] { - text-shadow: 0 1px 0 rgba(0,51,83,0.3); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#1da7ee, #178ee9); - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)"); - &.active { - .selectize-vertical-gradient(#008fd8, #0075cf); - } - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8)"); - .selectize-vertical-gradient(#fefefe, #f2f2f2); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - padding-top: @selectize-padding-dropdown-item-y + 2px; - font-weight: bold; - font-size: 0.85em; - } - .optgroup { - border-top: 1px solid @selectize-color-dropdown-border-top; - &:first-child { - border-top: 0 none; - } - } -} \ No newline at end of file diff --git a/src/less/selectize.legacy.less b/src/less/selectize.legacy.less deleted file mode 100644 index c6cfa6e74..000000000 --- a/src/less/selectize.legacy.less +++ /dev/null @@ -1,75 +0,0 @@ -/** - * selectize.legacy.css (v@@version) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-size: 13px; -@selectize-line-height: 20px; - -@selectize-color-input-full: #f2f2f2; -@selectize-color-item: #b8e76f; -@selectize-color-item-text: #3d5d18; -@selectize-color-item-border: #74b21e; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #6f9839; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-dropdown-item-active: #fffceb; -@selectize-color-dropdown-item-active-text: @selectize-color-text; -@selectize-color-optgroup: #f8f8f8; -@selectize-color-optgroup-text: @selectize-color-text; -@selectize-width-item-border: 1px; - -@selectize-padding-x: 10px; -@selectize-padding-y: 10px; -@selectize-padding-item-x: 5px; -@selectize-padding-item-y: 1px; -@selectize-padding-dropdown-item-x: 10px; -@selectize-padding-dropdown-item-y: 7px; -@selectize-margin-item-x: 4px; -@selectize-margin-item-y: 4px; - -.selectize-control { - &.multi { - .selectize-input [data-value] { - text-shadow: 0 1px 0 rgba(255,255,255,0.1); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#b8e76f, #a9e25c); - .selectize-box-shadow(0 1px 1px rgba(0,0,0,0.1)); - &.active { - .selectize-vertical-gradient(#92c836, #7abc2c); - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1)"); - .selectize-vertical-gradient(#f5f5f5, #efefef); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - font-weight: bold; - font-size: 0.8em; - border-bottom: 1px solid @selectize-color-dropdown-border-top; - border-top: 1px solid @selectize-color-dropdown-border-top; - } -} \ No newline at end of file diff --git a/src/less/selectize.less b/src/less/selectize.less deleted file mode 100644 index fe70f9663..000000000 --- a/src/less/selectize.less +++ /dev/null @@ -1,288 +0,0 @@ -// base styles - -@selectize-font-family: inherit; -@selectize-font-smoothing: inherit; -@selectize-font-size: 13px; -@selectize-line-height: 18px; - -@selectize-color-text: #303030; -@selectize-color-border: #d0d0d0; -@selectize-color-highlight: rgba(125,168,208,0.2); -@selectize-color-input: #fff; -@selectize-color-input-full: @selectize-color-input; -@selectize-color-disabled: #fafafa; -@selectize-color-item: #f2f2f2; -@selectize-color-item-text: @selectize-color-text; -@selectize-color-item-border: #d0d0d0; -@selectize-color-item-active: #e8e8e8; -@selectize-color-item-active-text: @selectize-color-text; -@selectize-color-item-active-border: #cacaca; -@selectize-color-dropdown: #fff; -@selectize-color-dropdown-border: @selectize-color-border; -@selectize-color-dropdown-border-top: #f0f0f0; -@selectize-color-dropdown-item-active: #f5fafd; -@selectize-color-dropdown-item-active-text: #495c68; -@selectize-color-dropdown-item-create-text: rgba(red(@selectize-color-text), green(@selectize-color-text), blue(@selectize-color-text), 0.5); -@selectize-color-dropdown-item-create-active-text: @selectize-color-dropdown-item-active-text; -@selectize-color-optgroup: @selectize-color-dropdown; -@selectize-color-optgroup-text: @selectize-color-text; -@selectize-lighten-disabled-item: 30%; -@selectize-lighten-disabled-item-text: 30%; -@selectize-lighten-disabled-item-border: 30%; -@selectize-opacity-disabled: 0.5; - -@selectize-shadow-input: inset 0 1px 1px rgba(0,0,0,0.1); -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border: 1px solid @selectize-color-border; -@selectize-border-radius: 3px; - -@selectize-width-item-border: 0; -@selectize-max-height-dropdown: 200px; - -@selectize-padding-x: 8px; -@selectize-padding-y: 8px; -@selectize-padding-item-x: 6px; -@selectize-padding-item-y: 2px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: 5px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: #808080; -@selectize-arrow-offset: 15px; - -@selectize-caret-margin: 0 2px 0 0; -@selectize-caret-margin-rtl: 0 4px 0 -2px; - -.selectize-border-radius (@radii) { - -webkit-border-radius: @radii; - -moz-border-radius: @radii; - border-radius: @radii; -} -.selectize-unselectable () { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.selectize-box-shadow (@shadow) { - -webkit-box-shadow: @shadow; - box-shadow: @shadow; -} -.selectize-box-sizing (@type: border-box) { - -webkit-box-sizing: @type; - -moz-box-sizing: @type; - box-sizing: @type; -} -.selectize-vertical-gradient (@color-top, @color-bottom) { - background-color: mix(@color-top, @color-bottom, 60%); - background-image: -moz-linear-gradient(top, @color-top, @color-bottom); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@color-top), to(@color-bottom)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @color-top, @color-bottom); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, @color-top, @color-bottom); // Opera 11.10 - background-image: linear-gradient(to bottom, @color-top, @color-bottom); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@color-top),argb(@color-bottom))); // IE9 and down -} - -.selectize-control { - position: relative; -} - -.selectize-dropdown, .selectize-input, .selectize-input input { - color: @selectize-color-text; - font-family: @selectize-font-family; - font-size: @selectize-font-size; - line-height: @selectize-line-height; - -webkit-font-smoothing: @selectize-font-smoothing; -} - -.selectize-input, .selectize-control.single .selectize-input.input-active { - background: @selectize-color-input; - cursor: text; - display: inline-block; -} - -.selectize-input { - border: @selectize-border; - padding: @selectize-padding-y @selectize-padding-x; - display: inline-block; - width: 100%; - overflow: hidden; - position: relative; - z-index: 1; - .selectize-box-sizing(border-box); - .selectize-box-shadow(@selectize-shadow-input); - .selectize-border-radius(@selectize-border-radius); - - .selectize-control.multi &.has-items { - @padding-x: @selectize-padding-x; - @padding-top: @selectize-padding-y - @selectize-padding-item-y - @selectize-width-item-border; - @padding-bottom: @selectize-padding-y - @selectize-padding-item-y - @selectize-margin-item-y - @selectize-width-item-border; - padding: @padding-top @padding-x @padding-bottom; - } - - &.full { - background-color: @selectize-color-input-full; - } - &.disabled, &.disabled * { - cursor: default !important; - } - &.focus { - .selectize-box-shadow(@selectize-shadow-input-focus); - } - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); - } - - > * { - vertical-align: baseline; - display: -moz-inline-stack; - display: inline-block; - zoom: 1; - *display: inline; - } - .selectize-control.multi & > div { - cursor: pointer; - margin: 0 @selectize-margin-item-x @selectize-margin-item-y 0; - padding: @selectize-padding-item-y @selectize-padding-item-x; - background: @selectize-color-item; - color: @selectize-color-item-text; - border: @selectize-width-item-border solid @selectize-color-item-border; - - &.active { - background: @selectize-color-item-active; - color: @selectize-color-item-active-text; - border: @selectize-width-item-border solid @selectize-color-item-active-border; - } - } - .selectize-control.multi &.disabled > div { - &, &.active { - color: lighten(desaturate(@selectize-color-item-text, 100%), @selectize-lighten-disabled-item-text); - background: lighten(desaturate(@selectize-color-item, 100%), @selectize-lighten-disabled-item); - border: @selectize-width-item-border solid lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } - } - > input { - &::-ms-clear { - display: none; - } - padding: 0 !important; - min-height: 0 !important; - max-height: none !important; - max-width: 100% !important; - margin: @selectize-caret-margin !important; - text-indent: 0 !important; - border: 0 none !important; - background: none !important; - line-height: inherit !important; - -webkit-user-select: auto !important; - .selectize-box-shadow(none) !important; - &:focus { outline: none !important; } - } -} - -.selectize-input::after { - content: ' '; - display: block; - clear: left; -} - -.selectize-input.dropdown-active::before { - content: ' '; - display: block; - position: absolute; - background: @selectize-color-dropdown-border-top; - height: 1px; - bottom: 0; - left: 0; - right: 0; -} - -.selectize-dropdown { - position: absolute; - z-index: 10; - border: @selectize-border; - background: @selectize-color-dropdown; - margin: -1px 0 0 0; - border-top: 0 none; - .selectize-box-sizing(border-box); - .selectize-box-shadow(0 1px 3px rgba(0,0,0,0.1)); - .selectize-border-radius(0 0 @selectize-border-radius @selectize-border-radius); - - [data-selectable] { - cursor: pointer; - overflow: hidden; - .highlight { - background: @selectize-color-highlight; - .selectize-border-radius(1px); - } - } - [data-selectable], .optgroup-header { - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - } - .optgroup:first-child .optgroup-header { - border-top: 0 none; - } - .optgroup-header { - color: @selectize-color-optgroup-text; - background: @selectize-color-optgroup; - cursor: default; - } - .active { - background-color: @selectize-color-dropdown-item-active; - color: @selectize-color-dropdown-item-active-text; - &.create { - color: @selectize-color-dropdown-item-create-active-text; - } - } - .create { - color: @selectize-color-dropdown-item-create-text; - } -} - -.selectize-dropdown-content { - overflow-y: auto; - overflow-x: hidden; - max-height: @selectize-max-height-dropdown; -} - -.selectize-control.single .selectize-input { - &, input { cursor: pointer; } - &.input-active, &.input-active input { cursor: text; } - - &:after { - content: ' '; - display: block; - position: absolute; - top: 50%; - right: @selectize-arrow-offset; - margin-top: round(-@selectize-arrow-size / 2); - width: 0; - height: 0; - border-style: solid; - border-width: @selectize-arrow-size @selectize-arrow-size 0 @selectize-arrow-size; - border-color: @selectize-arrow-color transparent transparent transparent; - } - &.dropdown-active:after { - margin-top: @selectize-arrow-size * -0.8; - border-width: 0 @selectize-arrow-size @selectize-arrow-size @selectize-arrow-size; - border-color: transparent transparent @selectize-arrow-color transparent; - } -} - -.selectize-control.rtl { - &.single .selectize-input:after { - left: @selectize-arrow-offset; - right: auto; - } - .selectize-input > input { - margin: @selectize-caret-margin-rtl !important; - } -} - -.selectize-control .selectize-input.disabled { - opacity: @selectize-opacity-disabled; - background-color: @selectize-color-disabled; -} diff --git a/src/plugins/drag_drop/plugin.js b/src/plugins/drag_drop/plugin.js deleted file mode 100644 index 2a1395cf7..000000000 --- a/src/plugins/drag_drop/plugin.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Plugin: "drag_drop" (selectize.js) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -Selectize.define('drag_drop', function(options) { - if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); - if (this.settings.mode !== 'multi') return; - var self = this; - - self.lock = (function() { - var original = self.lock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.disable(); - return original.apply(self, arguments); - }; - })(); - - self.unlock = (function() { - var original = self.unlock; - return function() { - var sortable = self.$control.data('sortable'); - if (sortable) sortable.enable(); - return original.apply(self, arguments); - }; - })(); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(this, arguments); - - var $control = self.$control.sortable({ - items: '[data-value]', - forcePlaceholderSize: true, - disabled: self.isLocked, - start: function(e, ui) { - ui.placeholder.css('width', ui.helper.css('width')); - $control.css({overflow: 'visible'}); - }, - stop: function() { - $control.css({overflow: 'hidden'}); - var active = self.$activeItems ? self.$activeItems.slice() : null; - var values = []; - $control.children('[data-value]').each(function() { - values.push($(this).attr('data-value')); - }); - self.setValue(values); - self.setActiveItem(active); - } - }); - }; - })(); - -}); \ No newline at end of file diff --git a/src/plugins/drag_drop/plugin.less b/src/plugins/drag_drop/plugin.less deleted file mode 100644 index 9d42e4ac2..000000000 --- a/src/plugins/drag_drop/plugin.less +++ /dev/null @@ -1,16 +0,0 @@ -.selectize-control.plugin-drag_drop { - &.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0,0,0,0.06) !important; - border: 0 none !important; - .selectize-box-shadow(inset 0 0 12px 4px #fff); - } - .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; - } - .ui-sortable-helper { - .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); - } -} \ No newline at end of file diff --git a/src/plugins/dropdown_header/plugin.js b/src/plugins/dropdown_header/plugin.js deleted file mode 100644 index 728914b06..000000000 --- a/src/plugins/dropdown_header/plugin.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Plugin: "dropdown_header" (selectize.js) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -Selectize.define('dropdown_header', function(options) { - var self = this; - - options = $.extend({ - title : 'Untitled', - headerClass : 'selectize-dropdown-header', - titleRowClass : 'selectize-dropdown-header-title', - labelClass : 'selectize-dropdown-header-label', - closeClass : 'selectize-dropdown-header-close', - - html: function(data) { - return ( - '
    ' - ); - } - }, options); - - self.setup = (function() { - var original = self.setup; - return function() { - original.apply(self, arguments); - self.$dropdown_header = $(options.html(options)); - self.$dropdown.prepend(self.$dropdown_header); - }; - })(); - -}); \ No newline at end of file diff --git a/src/plugins/dropdown_header/plugin.less b/src/plugins/dropdown_header/plugin.less deleted file mode 100644 index c3e777e16..000000000 --- a/src/plugins/dropdown_header/plugin.less +++ /dev/null @@ -1,20 +0,0 @@ -.selectize-dropdown-header { - position: relative; - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - border-bottom: 1px solid @selectize-color-border; - background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); -} -.selectize-dropdown-header-close { - position: absolute; - right: @selectize-padding-dropdown-item-x; - top: 50%; - color: @selectize-color-text; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: darken(@selectize-color-text, 25%); -} \ No newline at end of file diff --git a/src/plugins/optgroup_columns/plugin.js b/src/plugins/optgroup_columns/plugin.js deleted file mode 100644 index 354d0572f..000000000 --- a/src/plugins/optgroup_columns/plugin.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Plugin: "optgroup_columns" (selectize.js) - * Copyright (c) 2013 Simon Hewitt & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Simon Hewitt - */ - -Selectize.define('optgroup_columns', function(options) { - var self = this; - - options = $.extend({ - equalizeWidth : true, - equalizeHeight : true - }, options); - - this.getAdjacentOption = function($option, direction) { - var $options = $option.closest('[data-group]').find('[data-selectable]'); - var index = $options.index($option) + direction; - - return index >= 0 && index < $options.length ? $options.eq(index) : $(); - }; - - this.onKeyDown = (function() { - var original = self.onKeyDown; - return function(e) { - var index, $option, $options, $optgroup; - - if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { - self.ignoreHover = true; - $optgroup = this.$activeOption.closest('[data-group]'); - index = $optgroup.find('[data-selectable]').index(this.$activeOption); - - if(e.keyCode === KEY_LEFT) { - $optgroup = $optgroup.prev('[data-group]'); - } else { - $optgroup = $optgroup.next('[data-group]'); - } - - $options = $optgroup.find('[data-selectable]'); - $option = $options.eq(Math.min($options.length - 1, index)); - if ($option.length) { - this.setActiveOption($option); - } - return; - } - - return original.apply(this, arguments); - }; - })(); - - var equalizeSizes = function() { - var i, n, height_max, width, width_last, width_parent, $optgroups; - - $optgroups = $('[data-group]', self.$dropdown_content); - n = $optgroups.length; - if (!n || !self.$dropdown_content.width()) return; - - if (options.equalizeHeight) { - height_max = 0; - for (i = 0; i < n; i++) { - height_max = Math.max(height_max, $optgroups.eq(i).height()); - } - $optgroups.css({height: height_max}); - } - - if (options.equalizeWidth) { - width_parent = self.$dropdown_content.innerWidth(); - width = Math.round(width_parent / n); - $optgroups.css({width: width}); - if (n > 1) { - width_last = width_parent - width * (n - 1); - $optgroups.eq(n - 1).css({width: width_last}); - } - } - }; - - if (options.equalizeHeight || options.equalizeWidth) { - hook.after(this, 'positionDropdown', equalizeSizes); - hook.after(this, 'refreshOptions', equalizeSizes); - } - - -}); \ No newline at end of file diff --git a/src/plugins/optgroup_columns/plugin.less b/src/plugins/optgroup_columns/plugin.less deleted file mode 100644 index 5c72d7a0a..000000000 --- a/src/plugins/optgroup_columns/plugin.less +++ /dev/null @@ -1,17 +0,0 @@ -.selectize-dropdown.plugin-optgroup_columns { - .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - .selectize-box-sizing(border-box); - } - .optgroup:last-child { - border-right: 0 none; - } - .optgroup:before { - display: none; - } - .optgroup-header { - border-top: 0 none; - } -} \ No newline at end of file diff --git a/src/plugins/remove_button/plugin.js b/src/plugins/remove_button/plugin.js deleted file mode 100644 index 513298e80..000000000 --- a/src/plugins/remove_button/plugin.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Plugin: "remove_button" (selectize.js) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -Selectize.define('remove_button', function(options) { - if (this.settings.mode === 'single') return; - - options = $.extend({ - label : '×', - title : 'Remove', - className : 'remove', - append : true - }, options); - - var self = this; - var html = '' + options.label + ''; - - /** - * Appends an element as a child (with raw HTML). - * - * @param {string} html_container - * @param {string} html_element - * @return {string} - */ - var append = function(html_container, html_element) { - var pos = html_container.search(/(<\/[^>]+>\s*)$/); - return html_container.substring(0, pos) + html_element + html_container.substring(pos); - }; - - this.setup = (function() { - var original = self.setup; - return function() { - // override the item rendering method to add the button to each - if (options.append) { - var render_item = self.settings.render.item; - self.settings.render.item = function(data) { - return append(render_item.apply(this, arguments), html); - }; - } - - original.apply(this, arguments); - - // add event listener - this.$control.on('click', '.' + options.className, function(e) { - e.preventDefault(); - if (self.isLocked) return; - - var $item = $(e.currentTarget).parent(); - self.setActiveItem($item); - if (self.deleteSelection()) { - self.setCaret(self.items.length); - } - }); - - }; - })(); - -}); \ No newline at end of file diff --git a/src/plugins/remove_button/plugin.less b/src/plugins/remove_button/plugin.less deleted file mode 100644 index c478cd49c..000000000 --- a/src/plugins/remove_button/plugin.less +++ /dev/null @@ -1,37 +0,0 @@ -.selectize-control.plugin-remove_button { - [data-value] { - position: relative; - padding-right: 24px !important; - } - [data-value] .remove { - z-index: 1; /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: @selectize-padding-item-y 0 0 0; - border-left: 1px solid @selectize-color-item-border; - .selectize-border-radius(0 2px 2px 0); - .selectize-box-sizing(border-box); - } - [data-value] .remove:hover { - background: rgba(0,0,0,0.05); - } - [data-value].active .remove { - border-left-color: @selectize-color-item-active-border; - } - .disabled [data-value] .remove:hover { - background: none; - } - .disabled [data-value] .remove { - border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } -} \ No newline at end of file diff --git a/src/plugins/restore_on_backspace/plugin.js b/src/plugins/restore_on_backspace/plugin.js deleted file mode 100644 index 75aeae5db..000000000 --- a/src/plugins/restore_on_backspace/plugin.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Plugin: "restore_on_backspace" (selectize.js) - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -Selectize.define('restore_on_backspace', function(options) { - var self = this; - - options.text = options.text || function(option) { - return option[this.settings.labelField]; - }; - - this.onKeyDown = (function(e) { - var original = self.onKeyDown; - return function(e) { - var index, option; - if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { - index = this.caretPos - 1; - if (index >= 0 && index < this.items.length) { - option = this.options[this.items[index]]; - if (this.deleteSelection(e)) { - this.setTextboxValue(options.text.apply(this, [option])); - this.refreshOptions(true); - } - e.preventDefault(); - return; - } - } - return original.apply(this, arguments); - }; - })(); -}); \ No newline at end of file diff --git a/src/selectize.jquery.js b/src/selectize.jquery.js deleted file mode 100644 index b04a80dfe..000000000 --- a/src/selectize.jquery.js +++ /dev/null @@ -1,146 +0,0 @@ -$.fn.selectize = function(settings_user) { - var defaults = $.fn.selectize.defaults; - var settings = $.extend({}, defaults, settings_user); - var attr_data = settings.dataAttr; - var field_label = settings.labelField; - var field_value = settings.valueField; - var field_optgroup = settings.optgroupField; - var field_optgroup_label = settings.optgroupLabelField; - var field_optgroup_value = settings.optgroupValueField; - - /** - * Initializes selectize from a element. - * - * @param {object} $input - * @param {object} settings_element - */ - var init_textbox = function($input, settings_element) { - var i, n, values, option, value = $.trim($input.val() || ''); - if (!value.length) return; - - values = value.split(settings.delimiter); - for (i = 0, n = values.length; i < n; i++) { - option = {}; - option[field_label] = values[i]; - option[field_value] = values[i]; - - settings_element.options[values[i]] = option; - } - - settings_element.items = values; - }; - - /** - * Initializes selectize from a ').appendTo($control).attr('tabindex', tab_index); - $dropdown_parent = $(settings.dropdownParent || $wrapper); - $dropdown = $('
    ').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent); - $dropdown_content = $('
    ').addClass(settings.dropdownContentClass).appendTo($dropdown); - - $wrapper.css({ - width: self.$input[0].style.width - }); - - if (self.plugins.names.length) { - classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-'); - $wrapper.addClass(classes_plugins); - $dropdown.addClass(classes_plugins); - } - - if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) { - self.$input.attr('multiple', 'multiple'); - } - - if (self.settings.placeholder) { - $control_input.attr('placeholder', settings.placeholder); - } - - if (self.$input.attr('autocorrect')) { - $control_input.attr('autocorrect', self.$input.attr('autocorrect')); - } - - if (self.$input.attr('autocapitalize')) { - $control_input.attr('autocapitalize', self.$input.attr('autocapitalize')); - } - - self.$wrapper = $wrapper; - self.$control = $control; - self.$control_input = $control_input; - self.$dropdown = $dropdown; - self.$dropdown_content = $dropdown_content; - - $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); }); - $dropdown.on('mousedown', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); }); - watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); }); - autoGrow($control_input); - - $control.on({ - mousedown : function() { return self.onMouseDown.apply(self, arguments); }, - click : function() { return self.onClick.apply(self, arguments); } - }); - - $control_input.on({ - mousedown : function(e) { e.stopPropagation(); }, - keydown : function() { return self.onKeyDown.apply(self, arguments); }, - keyup : function() { return self.onKeyUp.apply(self, arguments); }, - keypress : function() { return self.onKeyPress.apply(self, arguments); }, - resize : function() { self.positionDropdown.apply(self, []); }, - blur : function() { return self.onBlur.apply(self, arguments); }, - focus : function() { return self.onFocus.apply(self, arguments); }, - paste : function() { return self.onPaste.apply(self, arguments); } - }); - - $document.on('keydown' + eventNS, function(e) { - self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey']; - self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey']; - self.isShiftDown = e.shiftKey; - }); - - $document.on('keyup' + eventNS, function(e) { - if (e.keyCode === KEY_CTRL) self.isCtrlDown = false; - if (e.keyCode === KEY_SHIFT) self.isShiftDown = false; - if (e.keyCode === KEY_CMD) self.isCmdDown = false; - }); - - $document.on('mousedown' + eventNS, function(e) { - if (self.isFocused) { - // prevent events on the dropdown scrollbar from causing the control to blur - if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) { - return false; - } - // blur on click outside - if (!self.$control.has(e.target).length && e.target !== self.$control[0]) { - self.blur(); - } - } - }); - - $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() { - if (self.isOpen) { - self.positionDropdown.apply(self, arguments); - } - }); - $window.on('mousemove' + eventNS, function() { - self.ignoreHover = false; - }); - - // store original children and tab index so that they can be - // restored when the destroy() method is called. - this.revertSettings = { - $children : self.$input.children().detach(), - tabindex : self.$input.attr('tabindex') - }; - - self.$input.attr('tabindex', -1).hide().after(self.$wrapper); - - if ($.isArray(settings.items)) { - self.setValue(settings.items); - delete settings.items; - } - - // feature detect for the validation API - if (self.$input[0].validity) { - self.$input.on('invalid' + eventNS, function(e) { - e.preventDefault(); - self.isInvalid = true; - self.refreshState(); - }); - } - - self.updateOriginalInput(); - self.refreshItems(); - self.refreshState(); - self.updatePlaceholder(); - self.isSetup = true; - - if (self.$input.is(':disabled')) { - self.disable(); - } - - self.on('change', this.onChange); - self.trigger('initialize'); - - // preload options - if (settings.preload === true) { - self.onSearchChange(''); - } - }, - - /** - * Sets up default rendering functions. - */ - setupTemplates: function() { - var self = this; - var field_label = self.settings.labelField; - var field_optgroup = self.settings.optgroupLabelField; - - var templates = { - 'optgroup': function(data) { - return '
    ' + data.html + '
    '; - }, - 'optgroup_header': function(data, escape) { - return '
    ' + escape(data[field_optgroup]) + '
    '; - }, - 'option': function(data, escape) { - return '
    ' + escape(data[field_label]) + '
    '; - }, - 'item': function(data, escape) { - return '
    ' + escape(data[field_label]) + '
    '; - }, - 'option_create': function(data, escape) { - return '
    Add ' + escape(data.input) + '
    '; - } - }; - - self.settings.render = $.extend({}, templates, self.settings.render); - }, - - /** - * Maps fired events to callbacks provided - * in the settings used when creating the control. - */ - setupCallbacks: function() { - var key, fn, callbacks = { - 'initialize' : 'onInitialize', - 'change' : 'onChange', - 'item_add' : 'onItemAdd', - 'item_remove' : 'onItemRemove', - 'clear' : 'onClear', - 'option_add' : 'onOptionAdd', - 'option_remove' : 'onOptionRemove', - 'option_clear' : 'onOptionClear', - 'dropdown_open' : 'onDropdownOpen', - 'dropdown_close' : 'onDropdownClose', - 'type' : 'onType' - }; - - for (key in callbacks) { - if (callbacks.hasOwnProperty(key)) { - fn = this.settings[callbacks[key]]; - if (fn) this.on(key, fn); - } - } - }, - - /** - * Triggered when the main control element - * has a click event. - * - * @param {object} e - * @return {boolean} - */ - onClick: function(e) { - var self = this; - - // necessary for mobile webkit devices (manual focus triggering - // is ignored unless invoked within a click event) - if (!self.isFocused) { - self.focus(); - e.preventDefault(); - } - }, - - /** - * Triggered when the main control element - * has a mouse down event. - * - * @param {object} e - * @return {boolean} - */ - onMouseDown: function(e) { - var self = this; - var defaultPrevented = e.isDefaultPrevented(); - var $target = $(e.target); - - if (self.isFocused) { - // retain focus by preventing native handling. if the - // event target is the input it should not be modified. - // otherwise, text selection within the input won't work. - if (e.target !== self.$control_input[0]) { - if (self.settings.mode === 'single') { - // toggle dropdown - self.isOpen ? self.close() : self.open(); - } else if (!defaultPrevented) { - self.setActiveItem(null); - } - return false; - } - } else { - // give control focus - if (!defaultPrevented) { - window.setTimeout(function() { - self.focus(); - }, 0); - } - } - }, - - /** - * Triggered when the value of the control has been changed. - * This should propagate the event to the original DOM - * input / select element. - */ - onChange: function() { - this.$input.trigger('change'); - }, - - - /** - * Triggered on paste. - * - * @param {object} e - * @returns {boolean} - */ - onPaste: function(e) { - var self = this; - if (self.isFull() || self.isInputHidden || self.isLocked) { - e.preventDefault(); - } else { - // If a regex or string is included, this will split the pasted input and create Items for each separate value - if (self.settings.splitOn) { - setTimeout($.proxy(function() { - var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); - splitInput.forEach($.proxy(function(input) { - self.createItem(input); - }, self)); - }, self), 0); - } - } - }, - - /** - * Triggered on keypress. - * - * @param {object} e - * @returns {boolean} - */ - onKeyPress: function(e) { - if (this.isLocked) return e && e.preventDefault(); - var character = String.fromCharCode(e.keyCode || e.which); - if (this.settings.create && character === this.settings.delimiter) { - this.createItem(); - e.preventDefault(); - return false; - } - }, - - /** - * Triggered on keydown. - * - * @param {object} e - * @returns {boolean} - */ - onKeyDown: function(e) { - var isInput = e.target === this.$control_input[0]; - var self = this; - - if (self.isLocked) { - if (e.keyCode !== KEY_TAB) { - e.preventDefault(); - } - return; - } - - switch (e.keyCode) { - case KEY_A: - if (self.isCmdDown) { - self.selectAll(); - return; - } - break; - case KEY_ESC: - self.close(); - return; - case KEY_N: - if (!e.ctrlKey || e.altKey) break; - case KEY_DOWN: - if (!self.isOpen && self.hasOptions) { - self.open(); - } else if (self.$activeOption) { - self.ignoreHover = true; - var $next = self.getAdjacentOption(self.$activeOption, 1); - if ($next.length) self.setActiveOption($next, true, true); - } - e.preventDefault(); - return; - case KEY_P: - if (!e.ctrlKey || e.altKey) break; - case KEY_UP: - if (self.$activeOption) { - self.ignoreHover = true; - var $prev = self.getAdjacentOption(self.$activeOption, -1); - if ($prev.length) self.setActiveOption($prev, true, true); - } - e.preventDefault(); - return; - case KEY_RETURN: - if (self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - e.preventDefault(); - return; - case KEY_LEFT: - self.advanceSelection(-1, e); - return; - case KEY_RIGHT: - self.advanceSelection(1, e); - return; - case KEY_TAB: - if (self.settings.selectOnTab && self.isOpen && self.$activeOption) { - self.onOptionSelect({currentTarget: self.$activeOption}); - } - if (self.settings.create && self.createItem()) { - e.preventDefault(); - } - return; - case KEY_BACKSPACE: - case KEY_DELETE: - self.deleteSelection(e); - return; - } - - if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) { - e.preventDefault(); - return; - } - }, - - /** - * Triggered on keyup. - * - * @param {object} e - * @returns {boolean} - */ - onKeyUp: function(e) { - var self = this; - - if (self.isLocked) return e && e.preventDefault(); - var value = self.$control_input.val() || ''; - if (self.lastValue !== value) { - self.lastValue = value; - self.onSearchChange(value); - self.refreshOptions(); - self.trigger('type', value); - } - }, - - /** - * Invokes the user-provide option provider / loader. - * - * Note: this function is debounced in the Selectize - * constructor (by `settings.loadDelay` milliseconds) - * - * @param {string} value - */ - onSearchChange: function(value) { - var self = this; - var fn = self.settings.load; - if (!fn) return; - if (self.loadedSearches.hasOwnProperty(value)) return; - self.loadedSearches[value] = true; - self.load(function(callback) { - fn.apply(self, [value, callback]); - }); - }, - - /** - * Triggered on focus. - * - * @param {object} e (optional) - * @returns {boolean} - */ - onFocus: function(e) { - var self = this; - - self.isFocused = true; - if (self.isDisabled) { - self.blur(); - e && e.preventDefault(); - return false; - } - - if (self.ignoreFocus) return; - if (self.settings.preload === 'focus') self.onSearchChange(''); - - if (!self.$activeItems.length) { - self.showInput(); - self.setActiveItem(null); - self.refreshOptions(!!self.settings.openOnFocus); - } - - self.refreshState(); - }, - - /** - * Triggered on blur. - * - * @param {object} e - * @returns {boolean} - */ - onBlur: function(e) { - var self = this; - self.isFocused = false; - if (self.ignoreFocus) return; - - if (self.settings.create && self.settings.createOnBlur) { - self.createItem(false); - } - - self.close(); - self.setTextboxValue(''); - self.setActiveItem(null); - self.setActiveOption(null); - self.setCaret(self.items.length); - self.refreshState(); - }, - - /** - * Triggered when the user rolls over - * an option in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionHover: function(e) { - if (this.ignoreHover) return; - this.setActiveOption(e.currentTarget, false); - }, - - /** - * Triggered when the user clicks on an option - * in the autocomplete dropdown menu. - * - * @param {object} e - * @returns {boolean} - */ - onOptionSelect: function(e) { - var value, $target, $option, self = this; - - if (e.preventDefault) { - e.preventDefault(); - e.stopPropagation(); - } - - $target = $(e.currentTarget); - if ($target.hasClass('create')) { - self.createItem(); - } else { - value = $target.attr('data-value'); - if (value) { - self.lastQuery = null; - self.setTextboxValue(''); - self.addItem(value); - if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) { - self.setActiveOption(self.getOption(value)); - } - } - } - }, - - /** - * Triggered when the user clicks on an item - * that has been selected. - * - * @param {object} e - * @returns {boolean} - */ - onItemSelect: function(e) { - var self = this; - - if (self.isLocked) return; - if (self.settings.mode === 'multi') { - e.preventDefault(); - self.setActiveItem(e.currentTarget, e); - } - }, - - /** - * Invokes the provided method that provides - * results to a callback---which are then added - * as options to the control. - * - * @param {function} fn - */ - load: function(fn) { - var self = this; - var $wrapper = self.$wrapper.addClass('loading'); - - self.loading++; - fn.apply(self, [function(results) { - self.loading = Math.max(self.loading - 1, 0); - if (results && results.length) { - self.addOption(results); - self.refreshOptions(self.isFocused && !self.isInputHidden); - } - if (!self.loading) { - $wrapper.removeClass('loading'); - } - self.trigger('load', results); - }]); - }, - - /** - * Sets the input field of the control to the specified value. - * - * @param {string} value - */ - setTextboxValue: function(value) { - var $input = this.$control_input; - var changed = $input.val() !== value; - if (changed) { - $input.val(value).triggerHandler('update'); - this.lastValue = value; - } - }, - - /** - * Returns the value of the control. If multiple items - * can be selected (e.g. or - * element to reflect the current state. - */ - updateOriginalInput: function() { - var i, n, options, self = this; - - if (self.$input[0].tagName.toLowerCase() === 'select') { - options = []; - for (i = 0, n = self.items.length; i < n; i++) { - options.push(''); - } - if (!options.length && !this.$input.attr('multiple')) { - options.push(''); - } - self.$input.html(options.join('')); - } else { - self.$input.val(self.getValue()); - } - - if (self.isSetup) { - self.trigger('change', self.$input.val()); - } - }, - - /** - * Shows/hide the input placeholder depending - * on if there items in the list already. - */ - updatePlaceholder: function() { - if (!this.settings.placeholder) return; - var $input = this.$control_input; - - if (this.items.length) { - $input.removeAttr('placeholder'); - } else { - $input.attr('placeholder', this.settings.placeholder); - } - $input.triggerHandler('update', {force: true}); - }, - - /** - * Shows the autocomplete dropdown containing - * the available options. - */ - open: function() { - var self = this; - - if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return; - self.focus(); - self.isOpen = true; - self.refreshState(); - self.$dropdown.css({visibility: 'hidden', display: 'block'}); - self.positionDropdown(); - self.$dropdown.css({visibility: 'visible'}); - self.trigger('dropdown_open', self.$dropdown); - }, - - /** - * Closes the autocomplete dropdown menu. - */ - close: function() { - var self = this; - var trigger = self.isOpen; - - if (self.settings.mode === 'single' && self.items.length) { - self.hideInput(); - } - - self.isOpen = false; - self.$dropdown.hide(); - self.setActiveOption(null); - self.refreshState(); - - if (trigger) self.trigger('dropdown_close', self.$dropdown); - }, - - /** - * Calculates and applies the appropriate - * position of the dropdown. - */ - positionDropdown: function() { - var $control = this.$control; - var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); - offset.top += $control.outerHeight(true); - - this.$dropdown.css({ - width : $control.outerWidth(), - top : offset.top, - left : offset.left - }); - }, - - /** - * Resets / clears all selected items - * from the control. - */ - clear: function() { - var self = this; - - if (!self.items.length) return; - self.$control.children(':not(input)').remove(); - self.items = []; - self.setCaret(0); - self.updatePlaceholder(); - self.updateOriginalInput(); - self.refreshState(); - self.showInput(); - self.trigger('clear'); - }, - - /** - * A helper method for inserting an element - * at the current caret position. - * - * @param {object} $el - */ - insertAtCaret: function($el) { - var caret = Math.min(this.caretPos, this.items.length); - if (caret === 0) { - this.$control.prepend($el); - } else { - $(this.$control[0].childNodes[caret]).before($el); - } - this.setCaret(caret + 1); - }, - - /** - * Removes the current selected item(s). - * - * @param {object} e (optional) - * @returns {boolean} - */ - deleteSelection: function(e) { - var i, n, direction, selection, values, caret, option_select, $option_select, $tail; - var self = this; - - direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1; - selection = getSelection(self.$control_input[0]); - - if (self.$activeOption && !self.settings.hideSelected) { - option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value'); - } - - // determine items that will be removed - values = []; - - if (self.$activeItems.length) { - $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first')); - caret = self.$control.children(':not(input)').index($tail); - if (direction > 0) { caret++; } - - for (i = 0, n = self.$activeItems.length; i < n; i++) { - values.push($(self.$activeItems[i]).attr('data-value')); - } - if (e) { - e.preventDefault(); - e.stopPropagation(); - } - } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) { - if (direction < 0 && selection.start === 0 && selection.length === 0) { - values.push(self.items[self.caretPos - 1]); - } else if (direction > 0 && selection.start === self.$control_input.val().length) { - values.push(self.items[self.caretPos]); - } - } - - // allow the callback to abort - if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) { - return false; - } - - // perform removal - if (typeof caret !== 'undefined') { - self.setCaret(caret); - } - while (values.length) { - self.removeItem(values.pop()); - } - - self.showInput(); - self.positionDropdown(); - self.refreshOptions(true); - - // select previous option - if (option_select) { - $option_select = self.getOption(option_select); - if ($option_select.length) { - self.setActiveOption($option_select); - } - } - - return true; - }, - - /** - * Selects the previous / next item (depending - * on the `direction` argument). - * - * > 0 - right - * < 0 - left - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceSelection: function(direction, e) { - var tail, selection, idx, valueLength, cursorAtEdge, $tail; - var self = this; - - if (direction === 0) return; - if (self.rtl) direction *= -1; - - tail = direction > 0 ? 'last' : 'first'; - selection = getSelection(self.$control_input[0]); - - if (self.isFocused && !self.isInputHidden) { - valueLength = self.$control_input.val().length; - cursorAtEdge = direction < 0 - ? selection.start === 0 && selection.length === 0 - : selection.start === valueLength; - - if (cursorAtEdge && !valueLength) { - self.advanceCaret(direction, e); - } - } else { - $tail = self.$control.children('.active:' + tail); - if ($tail.length) { - idx = self.$control.children(':not(input)').index($tail); - self.setActiveItem(null); - self.setCaret(direction > 0 ? idx + 1 : idx); - } - } - }, - - /** - * Moves the caret left / right. - * - * @param {int} direction - * @param {object} e (optional) - */ - advanceCaret: function(direction, e) { - var self = this, fn, $adj; - - if (direction === 0) return; - - fn = direction > 0 ? 'next' : 'prev'; - if (self.isShiftDown) { - $adj = self.$control_input[fn](); - if ($adj.length) { - self.hideInput(); - self.setActiveItem($adj); - e && e.preventDefault(); - } - } else { - self.setCaret(self.caretPos + direction); - } - }, - - /** - * Moves the caret to the specified index. - * - * @param {int} i - */ - setCaret: function(i) { - var self = this; - - if (self.settings.mode === 'single') { - i = self.items.length; - } else { - i = Math.max(0, Math.min(self.items.length, i)); - } - - // the input must be moved by leaving it in place and moving the - // siblings, due to the fact that focus cannot be restored once lost - // on mobile webkit devices - var j, n, fn, $children, $child; - $children = self.$control.children(':not(input)'); - for (j = 0, n = $children.length; j < n; j++) { - $child = $($children[j]).detach(); - if (j < i) { - self.$control_input.before($child); - } else { - self.$control.append($child); - } - } - - self.caretPos = i; - }, - - /** - * Disables user input on the control. Used while - * items are being asynchronously created. - */ - lock: function() { - this.close(); - this.isLocked = true; - this.refreshState(); - }, - - /** - * Re-enables user input on the control. - */ - unlock: function() { - this.isLocked = false; - this.refreshState(); - }, - - /** - * Disables user input on the control completely. - * While disabled, it cannot receive focus. - */ - disable: function() { - var self = this; - self.$input.prop('disabled', true); - self.isDisabled = true; - self.lock(); - }, - - /** - * Enables the control so that it can respond - * to focus and user input. - */ - enable: function() { - var self = this; - self.$input.prop('disabled', false); - self.isDisabled = false; - self.unlock(); - }, - - /** - * Completely destroys the control and - * unbinds all event listeners so that it can - * be garbage collected. - */ - destroy: function() { - var self = this; - var eventNS = self.eventNS; - var revertSettings = self.revertSettings; - - self.trigger('destroy'); - self.off(); - self.$wrapper.remove(); - self.$dropdown.remove(); - - self.$input - .html('') - .append(revertSettings.$children) - .removeAttr('tabindex') - .attr({tabindex: revertSettings.tabindex}) - .show(); - - $(window).off(eventNS); - $(document).off(eventNS); - $(document.body).off(eventNS); - - delete self.$input[0].selectize; - }, - - /** - * A helper method for rendering "item" and - * "option" templates, given the data. - * - * @param {string} templateName - * @param {object} data - * @returns {string} - */ - render: function(templateName, data) { - var value, id, label; - var html = ''; - var cache = false; - var self = this; - var regex_tag = /^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; - - if (templateName === 'option' || templateName === 'item') { - value = hash_key(data[self.settings.valueField]); - cache = !!value; - } - - // pull markup from cache if it exists - if (cache) { - if (!isset(self.renderCache[templateName])) { - self.renderCache[templateName] = {}; - } - if (self.renderCache[templateName].hasOwnProperty(value)) { - return self.renderCache[templateName][value]; - } - } - - // render markup - html = self.settings.render[templateName].apply(this, [data, escape_html]); - - // add mandatory attributes - if (templateName === 'option' || templateName === 'option_create') { - html = html.replace(regex_tag, '<$1 data-selectable'); - } - if (templateName === 'optgroup') { - id = data[self.settings.optgroupValueField] || ''; - html = html.replace(regex_tag, '<$1 data-group="' + escape_replace(escape_html(id)) + '"'); - } - if (templateName === 'option' || templateName === 'item') { - html = html.replace(regex_tag, '<$1 data-value="' + escape_replace(escape_html(value || '')) + '"'); - } - - // update cache - if (cache) { - self.renderCache[templateName][value] = html; - } - - return html; - } - -}); diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index 53a1192b5..000000000 --- a/src/utils.js +++ /dev/null @@ -1,344 +0,0 @@ -/** - * Determines if the provided value has been defined. - * - * @param {mixed} object - * @returns {boolean} - */ -var isset = function(object) { - return typeof object !== 'undefined'; -}; - -/** - * Converts a scalar to its best string representation - * for hash keys and HTML attribute values. - * - * Transformations: - * 'str' -> 'str' - * null -> '' - * undefined -> '' - * true -> '1' - * false -> '0' - * 0 -> '0' - * 1 -> '1' - * - * @param {string} value - * @returns {string} - */ -var hash_key = function(value) { - if (typeof value === 'undefined' || value === null) return ''; - if (typeof value === 'boolean') return value ? '1' : '0'; - return value + ''; -}; - -/** - * Escapes a string for use within HTML. - * - * @param {string} str - * @returns {string} - */ -var escape_html = function(str) { - return (str + '') - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; - -/** - * Escapes "$" characters in replacement strings. - * - * @param {string} str - * @returns {string} - */ -var escape_replace = function(str) { - return (str + '').replace(/\$/g, '$$$$'); -}; - -var hook = {}; - -/** - * Wraps `method` on `self` so that `fn` - * is invoked before the original method. - * - * @param {object} self - * @param {string} method - * @param {function} fn - */ -hook.before = function(self, method, fn) { - var original = self[method]; - self[method] = function() { - fn.apply(self, arguments); - return original.apply(self, arguments); - }; -}; - -/** - * Wraps `method` on `self` so that `fn` - * is invoked after the original method. - * - * @param {object} self - * @param {string} method - * @param {function} fn - */ -hook.after = function(self, method, fn) { - var original = self[method]; - self[method] = function() { - var result = original.apply(self, arguments); - fn.apply(self, arguments); - return result; - }; -}; - -/** - * Builds a hash table out of an array of - * objects, using the specified `key` within - * each object. - * - * @param {string} key - * @param {mixed} objects - */ -var build_hash_table = function(key, objects) { - if (!$.isArray(objects)) return objects; - var i, n, table = {}; - for (i = 0, n = objects.length; i < n; i++) { - if (objects[i].hasOwnProperty(key)) { - table[objects[i][key]] = objects[i]; - } - } - return table; -}; - -/** - * Wraps `fn` so that it can only be invoked once. - * - * @param {function} fn - * @returns {function} - */ -var once = function(fn) { - var called = false; - return function() { - if (called) return; - called = true; - fn.apply(this, arguments); - }; -}; - -/** - * Wraps `fn` so that it can only be called once - * every `delay` milliseconds (invoked on the falling edge). - * - * @param {function} fn - * @param {int} delay - * @returns {function} - */ -var debounce = function(fn, delay) { - var timeout; - return function() { - var self = this; - var args = arguments; - window.clearTimeout(timeout); - timeout = window.setTimeout(function() { - fn.apply(self, args); - }, delay); - }; -}; - -/** - * Debounce all fired events types listed in `types` - * while executing the provided `fn`. - * - * @param {object} self - * @param {array} types - * @param {function} fn - */ -var debounce_events = function(self, types, fn) { - var type; - var trigger = self.trigger; - var event_args = {}; - - // override trigger method - self.trigger = function() { - var type = arguments[0]; - if (types.indexOf(type) !== -1) { - event_args[type] = arguments; - } else { - return trigger.apply(self, arguments); - } - }; - - // invoke provided function - fn.apply(self, []); - self.trigger = trigger; - - // trigger queued events - for (type in event_args) { - if (event_args.hasOwnProperty(type)) { - trigger.apply(self, event_args[type]); - } - } -}; - -/** - * A workaround for http://bugs.jquery.com/ticket/6696 - * - * @param {object} $parent - Parent element to listen on. - * @param {string} event - Event name. - * @param {string} selector - Descendant selector to filter by. - * @param {function} fn - Event handler. - */ -var watchChildEvent = function($parent, event, selector, fn) { - $parent.on(event, selector, function(e) { - var child = e.target; - while (child && child.parentNode !== $parent[0]) { - child = child.parentNode; - } - e.currentTarget = child; - return fn.apply(this, [e]); - }); -}; - -/** - * Determines the current selection within a text input control. - * Returns an object containing: - * - start - * - length - * - * @param {object} input - * @returns {object} - */ -var getSelection = function(input) { - var result = {}; - if ('selectionStart' in input) { - result.start = input.selectionStart; - result.length = input.selectionEnd - result.start; - } else if (document.selection) { - input.focus(); - var sel = document.selection.createRange(); - var selLen = document.selection.createRange().text.length; - sel.moveStart('character', -input.value.length); - result.start = sel.text.length - selLen; - result.length = selLen; - } - return result; -}; - -/** - * Copies CSS properties from one element to another. - * - * @param {object} $from - * @param {object} $to - * @param {array} properties - */ -var transferStyles = function($from, $to, properties) { - var i, n, styles = {}; - if (properties) { - for (i = 0, n = properties.length; i < n; i++) { - styles[properties[i]] = $from.css(properties[i]); - } - } else { - styles = $from.css(); - } - $to.css(styles); -}; - -/** - * Measures the width of a string within a - * parent element (in pixels). - * - * @param {string} str - * @param {object} $parent - * @returns {int} - */ -var measureString = function(str, $parent) { - if (!str) { - return 0; - } - - var $test = $('').css({ - position: 'absolute', - top: -99999, - left: -99999, - width: 'auto', - padding: 0, - whiteSpace: 'pre' - }).text(str).appendTo('body'); - - transferStyles($parent, $test, [ - 'letterSpacing', - 'fontSize', - 'fontFamily', - 'fontWeight', - 'textTransform' - ]); - - var width = $test.width(); - $test.remove(); - - return width; -}; - -/** - * Sets up an input to grow horizontally as the user - * types. If the value is changed manually, you can - * trigger the "update" handler to resize: - * - * $input.trigger('update'); - * - * @param {object} $input - */ -var autoGrow = function($input) { - var currentWidth = null; - - var update = function(e, options) { - var value, keyCode, printable, placeholder, width; - var shift, character, selection; - e = e || window.event || {}; - options = options || {}; - - if (e.metaKey || e.altKey) return; - if (!options.force && $input.data('grow') === false) return; - - value = $input.val(); - if (e.type && e.type.toLowerCase() === 'keydown') { - keyCode = e.keyCode; - printable = ( - (keyCode >= 97 && keyCode <= 122) || // a-z - (keyCode >= 65 && keyCode <= 90) || // A-Z - (keyCode >= 48 && keyCode <= 57) || // 0-9 - keyCode === 32 // space - ); - - if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) { - selection = getSelection($input[0]); - if (selection.length) { - value = value.substring(0, selection.start) + value.substring(selection.start + selection.length); - } else if (keyCode === KEY_BACKSPACE && selection.start) { - value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1); - } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') { - value = value.substring(0, selection.start) + value.substring(selection.start + 1); - } - } else if (printable) { - shift = e.shiftKey; - character = String.fromCharCode(e.keyCode); - if (shift) character = character.toUpperCase(); - else character = character.toLowerCase(); - value += character; - } - } - - placeholder = $input.attr('placeholder'); - if (!value && placeholder) { - value = placeholder; - } - - width = measureString(value, $input) + 4; - if (width !== currentWidth) { - currentWidth = width; - $input.width(width); - $input.triggerHandler('resize'); - } - }; - - $input.on('keydown keyup update blur', update); - update(); -}; \ No newline at end of file diff --git a/test/api.js b/test/api.js deleted file mode 100644 index 53abb27ba..000000000 --- a/test/api.js +++ /dev/null @@ -1,572 +0,0 @@ -(function() { - - describe('API', function() { - - describe('disable()', function() { - var test; - - before(function() { - test = setup_test('', {}); - test.selectize.enable(); - }); - it('should remove "disabled" class', function() { - expect(test.selectize.$control.hasClass('disabled')).to.be.equal(false); - }); - it('should set isDisabled property to false', function() { - expect(test.selectize.isDisabled).to.be.equal(false); - }); - it('should remove "disabled" attribute on original input', function() { - expect(test.selectize.$input.is(':disabled')).to.be.equal(false); - }); - }); - - describe('focus()', function() { - var test; - - before(function(done) { - test = setup_test('', {}); - test.selectize.focus(); - window.setTimeout(function() { - test.selectize.blur(); - window.setTimeout(done, 5); - }, 5); - }); - it('should set isFocused property to false', function() { - expect(test.selectize.isFocused).to.be.equal(false); - }); - it('should remove focus from the control', function() { - expect(has_focus(test.selectize.$control_input[0])).to.be.equal(false); - }); - }); - - describe('createItem()', function() { - it('should fail if non-object returned by "create" callback', function() { - var test = setup_test('', { - valueField: 'value', - labelField: 'value', - create: function(input) { - return 'hello'; - } - }); - - test.selectize.$control_input.val('test'); - test.selectize.createItem(); - expect(test.selectize.items.length).to.be.equal(0); - }); - it('should add option upon completion (synchronous)', function() { - var test = setup_test('', { - valueField: 'value', - labelField: 'value', - create: function(input, callback) { - window.setTimeout(function() { - callback({value: input}); - expect(test.selectize.options).to.have.property('test'); - done(); - }, 0); - } - }); - - test.selectize.$control_input.val('test'); - test.selectize.createItem(); - }); - }); - - describe('addOptionGroup()', function() { - var test; - - before(function() { - test = setup_test('', {valueField: 'value', labelField: 'value'}); - }); - it('should allow string values', function() { - test.selectize.addOption({value: 'stringtest'}); - expect(test.selectize.options).to.have.property('stringtest'); - }); - it('should not allow null / undefined values', function() { - test.selectize.addOption({value: undefined}); - test.selectize.addOption({value: null}); - expect(test.selectize.options).to.not.have.property('undefined'); - expect(test.selectize.options).to.not.have.property('null'); - expect(test.selectize.options).to.not.have.property(''); - }); - it('should allow integer values', function() { - test.selectize.addOption({value: 0}); - test.selectize.addOption({value: 1}); - expect(test.selectize.options).to.have.property('0'); - expect(test.selectize.options).to.have.property('1'); - }); - it('should allow arrays of options', function() { - test.selectize.addOption([{value: 'a'}, {value: 'b'}]); - expect(test.selectize.options).to.have.property('a'); - expect(test.selectize.options).to.have.property('b'); - }); - it('should not override existing options', function() { - test.selectize.addOption([{value: 'a'}, {value: 'b'}]); - test.selectize.addOption({value: 'a', test: 'hello'}); - expect(test.selectize.options.a).to.not.have.property('test'); - }); - }); - - describe('addItem()', function() { - var test; - - before(function() { - test = setup_test('', { - valueField: 'value', - labelField: 'value', - options: [ - {value: 0}, - {value: 1}, - {value: 'a'}, - {value: 'b'}, - {value: 'c'}, - {value: 'd'}, - {value: 'e'}, - {value: 'f'}, - {value: 'null'}, - {value: 'undefined'}, - {value: '\''}, - {value: '"'}, - {value: '\\\''}, - {value: '\\"'}, - ], - items: ['e','f'] - }); - }); - it('should update option data', function() { - test.selectize.updateOption('a', {value: 'a', test: 'test'}); - expect(test.selectize.options).to.have.property('a'); - expect(test.selectize.options['a'].test).to.equal('test'); - }); - it('should update indexes', function() { - test.selectize.updateOption('e', {value: 'e_updated'}); - expect(test.selectize.options).to.not.have.property('e'); - expect(test.selectize.options).to.have.property('e_updated'); - expect(test.selectize.items.indexOf('e')).to.be.equal(-1); - expect(test.selectize.items.indexOf('e_updated')).to.be.equal(0); - }); - it('should allow integer values', function() { - test.selectize.updateOption(0, {value: '0_updated'}); - test.selectize.updateOption(1, {value: '1_updated'}); - expect(test.selectize.options).to.not.have.property('0'); - expect(test.selectize.options).to.not.have.property('1'); - expect(test.selectize.options).to.have.property('0_updated'); - expect(test.selectize.options).to.have.property('1_updated'); - }); - it('should throw error if value not set in data', function() { - expect(function() { - test.selectize.updateOption('c', {value: undefined, test: 'test'}); - test.selectize.updateOption('d', {value: null, test: 'test'}); - }).to.throw(Error); - }); - it('should ignore undefined / null value references', function() { - test.selectize.updateOption(undefined, {value: 'undefined', test: 'test'}); - test.selectize.updateOption(null, {value: 'null', test: 'test'}); - expect(test.selectize.options['undefined']).to.not.have.property('test'); - expect(test.selectize.options['null']).to.not.have.property('test'); - }); - it('should update DOM', function() { - test.selectize.updateOption('f', {value: 'f_updated'}); - expect(test.selectize.$control.find('[data-value=f]').length).to.be.equal(0); - expect(test.selectize.$control.find('[data-value=f_updated]').length).to.be.equal(1); - }); - }); - - describe('getOption()', function() { - var test; - - before(function() { - test = setup_test('', { - valueField: 'value', - labelField: 'value', - options: [ - {value: 0}, - {value: 1}, - {value: 'a'}, - {value: 'b'}, - {value: '\''}, - {value: '"'}, - {value: '\\\''}, - {value: '\\"'} - ], - items: ['0','1','a','b','\'','"','\\\'','\\"'] - }); - }); - it('should allow string values', function() { - expect(test.selectize.getItem('a')).to.be.ok; - expect(test.selectize.getItem('a').length).to.be.equal(1); - expect(test.selectize.getItem('b')).to.be.ok; - expect(test.selectize.getItem('b').length).to.be.equal(1); - }); - it('should allow integer values', function() { - expect(test.selectize.getItem(0)).to.be.ok; - expect(test.selectize.getItem(0).length).to.be.equal(1); - expect(test.selectize.getItem(1)).to.be.ok; - expect(test.selectize.getItem(1).length).to.be.equal(1); - }); - it('should allow values with quotation marks', function() { - expect(test.selectize.getItem('\'')).to.be.ok; - expect(test.selectize.getItem('\'').length).to.be.equal(1); - expect(test.selectize.getItem('"')).to.be.ok; - expect(test.selectize.getItem('"').length).to.be.equal(1); - }); - it('should allow values with backslashes', function() { - expect(test.selectize.getItem('\\\'')).to.be.ok; - expect(test.selectize.getItem('\\\'').length).to.be.equal(1); - expect(test.selectize.getItem('\\"')).to.be.ok; - expect(test.selectize.getItem('\\"').length).to.be.equal(1); - }); - it('should not allow undefined / null values', function() { - expect(test.selectize.getItem(null)).to.be.ok; - expect(test.selectize.getItem(null).length).to.be.equal(0); - expect(test.selectize.getItem(undefined)).to.be.ok; - expect(test.selectize.getItem(undefined).length).to.be.equal(0); - }); - }); - - describe('clear()', function() { - var test; - - before(function() { - test = setup_test('', { - valueField: 'value', - labelField: 'value', - options: [ - {value: 0}, - {value: 1} - ], - score: function() { } - }); - test.selectize.search('hello'); - }).to.throw(Error); - }); - it('should not throw error if "score" setting does return a function', function() { - var test; - - expect(function() { - test = setup_test('', { - valueField: 'value', - labelField: 'value', - searchField: 'value', - options: [] - }); - var fn = test.selectize.getScoreFunction('test'); - expect(typeof fn).to.be.equal('function'); - expect(typeof fn({value: 'test'})).to.be.equal('number'); - expect(fn({value: 'test'})).to.be.above(0); - }); - }); - - describe('destroy()', function() { - var has_namespaced_event = function($el, ns) { - var i, n, key; - var data = ($._data || $.data).apply($, [$(window)[0], 'events']); - ns = ns.replace(/^./, ''); - for (key in data) { - if (data.hasOwnProperty(key)) { - for (i = 0, n = data[key].length; i < n; i++) { - if (data[key][i].namespace.indexOf(ns) !== -1) { - return true; - } - } - } - } - - return false; - }; - it('should remove control from DOM', function() { - var test = setup_test('', {}); - test.selectize.destroy(); - expect(test.selectize.$input[0].selectize).to.be.equal(undefined); - }); - it('should unbind events on window', function() { - var test = setup_test('', {}); - test.selectize.destroy(); - expect(has_namespaced_event($(document), test.selectize.eventNS)).to.be.equal(false); - }); - it('should unbind events on ', function() { - var test = setup_test('' + children + '', {}); - test.selectize.destroy(); - expect(test.$select.html()).to.be.equal(children); - expect(test.$select.attr('tabindex')).to.be.equal('9999'); - }); - it('should remove tabindex if it was originally undefined', function() { - var test = setup_test('', {}); - var counter = 0; - test.selectize.on('change', function() { counter++; }); - test.selectize.setValue('b'); - - window.setTimeout(function() { - expect(counter).to.be.equal(1); - done(); - }, 0); - }); - it('should contain current value', function(done) { - var test = setup_test('', {}); - test.selectize.on('change', function(value) { - expect(value).to.be.equal('c'); - done(); - }); - test.selectize.setValue('c'); - }); - it('should not be triggered when the selected item has not changed', function(done) { - var test = setup_test(''); - - var counter = 0; - test.$select.on('change', function() { counter++; }); - - Syn.click(test.selectize.$control).delay(0, function() { - Syn - .click($('[data-value="a"]', test.selectize.$dropdown)) - .delay(0, function() { - expect(counter).to.be.equal(0); - done(); - }); - }); - }); - }); - - describe('item_add', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('item_add', function() { - done(); - }); - test.selectize.addItem('b'); - }); - it('should contain item\'s value', function(done) { - var test = setup_test('', {}); - test.selectize.on('item_add', function(value, $item) { - expect(value).to.be.equal('b'); - done(); - }); - test.selectize.addItem('b'); - }); - }); - - describe('item_remove', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('item_remove', function() { - done(); - }); - test.selectize.removeItem('a'); - }); - it('should contain item\'s value', function(done) { - var test = setup_test('', {}); - test.selectize.on('item_remove', function(value) { - expect(value).to.be.equal('b'); - done(); - }); - test.selectize.removeItem('b'); - }); - }); - - describe('clear', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('clear', function() { - done(); - }); - test.selectize.clear(); - }); - }); - - describe('optgroup_add', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('optgroup_add', function() { done(); }); - test.selectize.addOptionGroup('id', {label: 'Group'}); - }); - it('should contain optgroup id', function(done) { - var test = setup_test('', {}); - test.selectize.on('optgroup_add', function(id, data) { - expect(id).to.be.equal('id'); - done(); - }); - test.selectize.addOptionGroup('id', {label: 'Group'}); - }); - it('should contain outgroup data', function(done) { - var test = setup_test('', {}); - var optgroup = {label: 'Group'}; - test.selectize.on('optgroup_add', function(id, data) { - expect(data).to.eql(optgroup); - done(); - }); - test.selectize.addOptionGroup('id', optgroup); - }); - }); - - describe('option_add', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('option_add', function() { - done(); - }); - test.selectize.addOption({value: 'e'}); - }); - it('should contain option value', function(done) { - var test = setup_test('', {}); - test.selectize.on('option_add', function(value, data) { - expect(value).to.be.equal('e'); - done(); - }); - test.selectize.addOption({value: 'e'}); - }); - it('should contain option data', function(done) { - var test = setup_test('', {}); - var option = {value: 'e'}; - test.selectize.on('option_add', function(value, data) { - expect(option).to.eql(data); - done(); - }); - test.selectize.addOption(option); - }); - }); - - describe('option_remove', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('option_remove', function() { - done(); - }); - test.selectize.removeOption('a'); - }); - it('should contain option value', function(done) { - var test = setup_test('', {}); - test.selectize.on('option_remove', function(value) { - expect(value).to.be.equal('a'); - done(); - }); - test.selectize.removeOption('a'); - }); - }); - - describe('option_clear', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('option_clear', function() { - done(); - }); - test.selectize.clearOptions(); - }); - }); - - describe('dropdown_open', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('dropdown_open', function() { - done(); - }); - test.selectize.open(); - }); - }); - - describe('dropdown_close', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('dropdown_close', function() { - done(); - }); - test.selectize.open(); - test.selectize.close(); - }); - }); - - describe('destroy', function() { - it('should be triggered', function(done) { - var test = setup_test('', {}); - test.selectize.on('destroy', function() { - done(); - }); - test.selectize.destroy(); - }); - }); - - describe('type', function() { - it('should be triggered', function(done) { - var test = setup_test('', {create: true}); - test.selectize.on('type', function() { - done(); - }); - Syn.click(test.selectize.$control).type('a', test.selectize.$control_input); - }); - it('should contain current value', function(done) { - var test = setup_test('', {create: true}); - test.selectize.on('type', function(value) { - expect(value).to.be.equal('a'); - done(); - }); - Syn.click(test.selectize.$control).type('a', test.selectize.$control_input); - }); - }); - -}); \ No newline at end of file diff --git a/test/events_dom.js b/test/events_dom.js deleted file mode 100644 index 845d07575..000000000 --- a/test/events_dom.js +++ /dev/null @@ -1,64 +0,0 @@ -describe('DOM Events', function() { - describe('"change"', function() { - it('should be triggered once by addItem()', function(done) { - var test = setup_test('', { - valueField: 'value', - labelField: 'value', - options: [ - {value: 'a'}, - {value: 'b'}, - ], - items: ['a','b'] - }); - - var counter = 0; - test.$select.on('change', function() { counter++; }); - test.selectize.removeItem('b'); - - window.setTimeout(function() { - expect(counter).to.be.equal(1); - done(); - }, 0); - }); - it('should be triggered once by clear()', function(done) { - var test = setup_test('' + - '' + - '' + - '', {}); - - Syn - .click(test.selectize.$control) - .delay(0, function() { - expect(test.selectize.isFocused).to.be.equal(true); - done(); - }); - }); - - it('should open dropdown menu', function(done) { - var test = setup_test('', {}); - - Syn - .click(test.selectize.$control) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(true); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); - done(); - }); - }); - - }); - - describe('clicking option', function() { - - it('should select it', function(done) { - var test = setup_test('', {}); - - Syn.click(test.selectize.$control).delay(0, function() { - Syn - .click($('[data-value="b"]', test.selectize.$dropdown)) - .delay(0, function() { - expect(test.selectize.$input.val()).to.be.equal('b'); - done(); - }); - }); - }); - - it('should close dropdown', function(done) { - var test = setup_test('', {}); - - Syn.click(test.selectize.$control).delay(0, function() { - Syn - .click($('[data-value="b"]', test.selectize.$dropdown)) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(false); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); - done(); - }); - }); - }); - - }); - - describe('typing in input', function() { - - it('should filter results', function(done) { - var test = setup_test('', {}); - - Syn - .click(test.selectize.$control) - .type('a', test.selectize.$control_input) - .delay(0, function() { - expect($('[data-value="a"]', test.selectize.$dropdown).length).to.be.equal(1); - expect($('[data-value="b"]', test.selectize.$dropdown).length).to.be.equal(0); - done(); - }); - }); - - it('should hide dropdown if no results present', function(done) { - var test = setup_test('', {}); - - Syn - .click(test.selectize.$control) - .type('awaw', test.selectize.$control_input) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(false); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); - done(); - }); - }); - - it('should not hide dropdown if "create" option enabled and no results present', function(done) { - var test = setup_test('', {create: true}); - - Syn - .click(test.selectize.$control) - .type('awaw', test.selectize.$control_input) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(true); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); - done(); - }); - }); - - it('should restore dropdown visibility when backing out of a query without results (backspace)', function(done) { - var test = setup_test('', {}); - - Syn - .click(test.selectize.$control) - .type('awf', test.selectize.$control_input) - .type('\b\b\b', test.selectize.$control_input) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(true); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); - done(); - }); - }); - - it('should move caret when [left] or [right] pressed', function(done) { - var test = setup_test('', {create: true}); - - Syn - .click(test.selectize.$control) - .type('[left][left]whatt', test.selectize.$control_input) - .delay(0, function() { - expect(test.selectize.caretPos).to.be.equal(2); - done(); - }); - }); - - }); - - describe('blurring the input', function() { - it('should close dropdown when createOnBlur is true', function(done) { - var test = setup_test('', { - createOnBlur: true, - create: function(value){ - return { - value: value, - text: value - }; - } - }); - - Syn - .click(test.selectize.$control) - .type('fooo', test.selectize.$control_input) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(true); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); - - Syn - .click($("#mocha")[0]) - .delay(0, function() { - expect(test.selectize.isOpen).to.be.equal(false); - expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); - done(); - }); - }); - - }); - }); - - }); - -})(); \ No newline at end of file diff --git a/test/setup.js b/test/setup.js deleted file mode 100644 index 1754ee855..000000000 --- a/test/setup.js +++ /dev/null @@ -1,223 +0,0 @@ -(function() { - - describe('Setup', function() { - - it('should not allow duplicate initialization', function() { - var instance_before, instance_after, test; - - test = setup_test('', {}); - instance_before = test.$select[0].selectize; - test.$select.selectize(); - instance_after = test.$select[0].selectize; - - expect(instance_before).to.be.equal(instance_after); - }); - - describe('', function() { - it('should complete without exceptions', function() { - var test = setup_test('', {}); - }); - describe('getValue()', function() { - it('should return value as a string', function() { - var test = setup_test('', {delimiter: ','}); - expect(test.selectize.getValue()).to.be.a('string'); - }); - it('should return "" when empty', function() { - var test = setup_test('', {delimiter: ','}); - expect(test.selectize.getValue()).to.be.equal(''); - }); - it('should return proper value when not empty', function() { - var test = setup_test('', {delimiter: ','}); - expect(test.selectize.getValue()).to.be.equal('a,b'); - }); - }); - describe('', function() { - it('should propagate original input attributes to the generated input', function() { - var test = setup_test('', {}); - expect(test.selectize.$control_input.attr('autocorrect')).to.be.equal('off'); - expect(test.selectize.$control_input.attr('autocapitalize')).to.be.equal('none'); - }); - it('should not add attributes if not present in the original', function() { - var test = setup_test('', {}); - expect(test.selectize.$control_input.attr('autocorrect')).to.be.equal(undefined); - expect(test.selectize.$control_input.attr('autocapitalize')).to.be.equal(undefined); - }); - }); - }); - - describe('', {}); - }); - it('should add options in text form (no html entities)', function() { - var test = setup_test('', {}); - expect(test.selectize.options['a'].text).to.be.equal(''); - }); - it('should keep options in original order if no sort given', function(done) { - var test = setup_test([ - '' - ].join(), {}); - - var order_expected = ['AL','AK','AZ','AR','CO','CT','DE','DC','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','01','10']; - var order_actual = []; - - test.selectize.refreshOptions(true); - window.setTimeout(function() { - test.selectize.$dropdown.find('[data-value]').each(function(i, el) { - order_actual.push($(el).attr('data-value')); - }); - - expect(order_actual).to.eql(order_expected); - done(); - }, 0); - }); - describe('getValue()', function() { - it('should return "" when empty', function() { - var test = setup_test('', {}); - expect(test.selectize.getValue()).to.be.equal('a'); - }); - }); - }); - - describe('', {}); - }); - describe('getValue()', function() { - it('should return [] when empty', function() { - var test = setup_test('', {}); - expect(test.selectize.getValue()).to.deep.equal(['a']); - }); - }); - }); - - describe('', {}); - }); - it('should have "disabled" class', function() { - expect(test.selectize.$control.hasClass('disabled')).to.be.equal(true); - }); - it('should have isDisabled property set to true', function() { - expect(test.selectize.isDisabled).to.be.equal(true); - }); - }); - - describe('' + - '' + - '' + - '', {}); - $form = test.$select.parents('form'); - $button = $('") + .button({ + label: this.options.closeText, + icons: { + primary: "ui-icon-closethick" + }, + text: false + }) + .addClass("ui-dialog-titlebar-close") + .appendTo( this.uiDialogTitlebar ); + this._on( this.uiDialogTitlebarClose, { + click: function( event ) { + event.preventDefault(); + this.close( event ); + } + }); + + uiDialogTitle = $("") + .uniqueId() + .addClass("ui-dialog-title") + .prependTo( this.uiDialogTitlebar ); + this._title( uiDialogTitle ); + + this.uiDialog.attr({ + "aria-labelledby": uiDialogTitle.attr("id") + }); + }, + + _title: function( title ) { + if ( !this.options.title ) { + title.html(" "); + } + title.text( this.options.title ); + }, + + _createButtonPane: function() { + this.uiDialogButtonPane = $("
    ") + .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); + + this.uiButtonSet = $("
    ") + .addClass("ui-dialog-buttonset") + .appendTo( this.uiDialogButtonPane ); + + this._createButtons(); + }, + + _createButtons: function() { + var that = this, + buttons = this.options.buttons; + + // if we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { + this.uiDialog.removeClass("ui-dialog-buttons"); + return; + } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + // Change the context for the click callback to be the main element + click = props.click; + props.click = function() { + click.apply( that.element[0], arguments ); + }; + buttonOptions = { + icons: props.icons, + text: props.showText + }; + delete props.icons; + delete props.showText; + $( "", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ); + }); + this.uiDialog.addClass("ui-dialog-buttons"); + this.uiDialogButtonPane.appendTo( this.uiDialog ); + }, + + _makeDraggable: function() { + var that = this, + options = this.options; + + function filteredUi( ui ) { + return { + position: ui.position, + offset: ui.offset + }; + } + + this.uiDialog.draggable({ + cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", + handle: ".ui-dialog-titlebar", + containment: "document", + start: function( event, ui ) { + $( this ).addClass("ui-dialog-dragging"); + that._blockFrames(); + that._trigger( "dragStart", event, filteredUi( ui ) ); + }, + drag: function( event, ui ) { + that._trigger( "drag", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + options.position = [ + ui.position.left - that.document.scrollLeft(), + ui.position.top - that.document.scrollTop() + ]; + $( this ).removeClass("ui-dialog-dragging"); + that._unblockFrames(); + that._trigger( "dragStop", event, filteredUi( ui ) ); + } + }); + }, + + _makeResizable: function() { + var that = this, + options = this.options, + handles = options.resizable, + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = this.uiDialog.css("position"), + resizeHandles = typeof handles === "string" ? + handles : + "n,e,s,w,se,sw,ne,nw"; + + function filteredUi( ui ) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } + + this.uiDialog.resizable({ + cancel: ".ui-dialog-content", + containment: "document", + alsoResize: this.element, + maxWidth: options.maxWidth, + maxHeight: options.maxHeight, + minWidth: options.minWidth, + minHeight: this._minHeight(), + handles: resizeHandles, + start: function( event, ui ) { + $( this ).addClass("ui-dialog-resizing"); + that._blockFrames(); + that._trigger( "resizeStart", event, filteredUi( ui ) ); + }, + resize: function( event, ui ) { + that._trigger( "resize", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + options.height = $( this ).height(); + options.width = $( this ).width(); + $( this ).removeClass("ui-dialog-resizing"); + that._unblockFrames(); + that._trigger( "resizeStop", event, filteredUi( ui ) ); + } + }) + .css( "position", position ); + }, + + _minHeight: function() { + var options = this.options; + + return options.height === "auto" ? + options.minHeight : + Math.min( options.minHeight, options.height ); + }, + + _position: function() { + // Need to show the dialog to get the actual offset in the position plugin + var isVisible = this.uiDialog.is(":visible"); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( this.options.position ); + if ( !isVisible ) { + this.uiDialog.hide(); + } + }, + + _setOptions: function( options ) { + var that = this, + resize = false, + resizableOptions = {}; + + $.each( options, function( key, value ) { + that._setOption( key, value ); + + if ( key in sizeRelatedOptions ) { + resize = true; + } + if ( key in resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + }); + + if ( resize ) { + this._size(); + this._position(); + } + if ( this.uiDialog.is(":data(ui-resizable)") ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, + + _setOption: function( key, value ) { + /*jshint maxcomplexity:15*/ + var isDraggable, isResizable, + uiDialog = this.uiDialog; + + if ( key === "dialogClass" ) { + uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + + if ( key === "disabled" ) { + return; + } + + this._super( key, value ); + + if ( key === "appendTo" ) { + this.uiDialog.appendTo( this._appendTo() ); + } + + if ( key === "buttons" ) { + this._createButtons(); + } + + if ( key === "closeText" ) { + this.uiDialogTitlebarClose.button({ + // Ensure that we always pass a string + label: "" + value + }); + } + + if ( key === "draggable" ) { + isDraggable = uiDialog.is(":data(ui-draggable)"); + if ( isDraggable && !value ) { + uiDialog.draggable("destroy"); + } + + if ( !isDraggable && value ) { + this._makeDraggable(); + } + } + + if ( key === "position" ) { + this._position(); + } + + if ( key === "resizable" ) { + // currently resizable, becoming non-resizable + isResizable = uiDialog.is(":data(ui-resizable)"); + if ( isResizable && !value ) { + uiDialog.resizable("destroy"); + } + + // currently resizable, changing handles + if ( isResizable && typeof value === "string" ) { + uiDialog.resizable( "option", "handles", value ); + } + + // currently non-resizable, becoming resizable + if ( !isResizable && value !== false ) { + this._makeResizable(); + } + } + + if ( key === "title" ) { + this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); + } + }, + + _size: function() { + // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content + // divs will both have width and height set, so we need to reset them + var nonContentHeight, minContentHeight, maxContentHeight, + options = this.options; + + // Reset content sizing + this.element.show().css({ + width: "auto", + minHeight: 0, + maxHeight: "none", + height: 0 + }); + + if ( options.minWidth > options.width ) { + options.width = options.minWidth; + } + + // reset wrapper sizing + // determine the height of all the non-content elements + nonContentHeight = this.uiDialog.css({ + height: "auto", + width: options.width + }) + .outerHeight(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + maxContentHeight = typeof options.maxHeight === "number" ? + Math.max( 0, options.maxHeight - nonContentHeight ) : + "none"; + + if ( options.height === "auto" ) { + this.element.css({ + minHeight: minContentHeight, + maxHeight: maxContentHeight, + height: "auto" + }); + } else { + this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + } + + if (this.uiDialog.is(":data(ui-resizable)") ) { + this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + } + }, + + _blockFrames: function() { + this.iframeBlocks = this.document.find( "iframe" ).map(function() { + var iframe = $( this ); + + return $( "
    " ) + .css({ + position: "absolute", + width: iframe.outerWidth(), + height: iframe.outerHeight() + }) + .appendTo( iframe.parent() ) + .offset( iframe.offset() )[0]; + }); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _allowInteraction: function( event ) { + if ( $( event.target ).closest(".ui-dialog").length ) { + return true; + } + + // TODO: Remove hack when datepicker implements + // the .ui-front logic (#8989) + return !!$( event.target ).closest(".ui-datepicker").length; + }, + + _createOverlay: function() { + if ( !this.options.modal ) { + return; + } + + var that = this, + widgetFullName = this.widgetFullName; + if ( !$.ui.dialog.overlayInstances ) { + // Prevent use of anchors and inputs. + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling. (#2804) + this._delay(function() { + // Handle .dialog().dialog("close") (#4065) + if ( $.ui.dialog.overlayInstances ) { + this.document.bind( "focusin.dialog", function( event ) { + if ( !that._allowInteraction( event ) ) { + event.preventDefault(); + $(".ui-dialog:visible:last .ui-dialog-content") + .data( widgetFullName )._focusTabbable(); + } + }); + } + }); + } + + this.overlay = $("
    ") + .addClass("ui-widget-overlay ui-front") + .appendTo( this._appendTo() ); + this._on( this.overlay, { + mousedown: "_keepFocus" + }); + $.ui.dialog.overlayInstances++; + }, + + _destroyOverlay: function() { + if ( !this.options.modal ) { + return; + } + + if ( this.overlay ) { + $.ui.dialog.overlayInstances--; + + if ( !$.ui.dialog.overlayInstances ) { + this.document.unbind( "focusin.dialog" ); + } + this.overlay.remove(); + this.overlay = null; + } + } +}); + +$.ui.dialog.overlayInstances = 0; + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // position option with array notation + // just override with old implementation + $.widget( "ui.dialog", $.ui.dialog, { + _position: function() { + var position = this.options.position, + myAt = [], + offset = [ 0, 0 ], + isVisible; + + if ( position ) { + if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { + myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; + if ( myAt.length === 1 ) { + myAt[1] = myAt[0]; + } + + $.each( [ "left", "top" ], function( i, offsetPosition ) { + if ( +myAt[ i ] === myAt[ i ] ) { + offset[ i ] = myAt[ i ]; + myAt[ i ] = offsetPosition; + } + }); + + position = { + my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + + myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), + at: myAt.join(" ") + }; + } + + position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); + } else { + position = $.ui.dialog.prototype.options.position; + } + + // need to show the dialog to get the actual offset in the position plugin + isVisible = this.uiDialog.is(":visible"); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( position ); + if ( !isVisible ) { + this.uiDialog.hide(); + } + } + }); +} + +}( jQuery ) ); + +(function( $, undefined ) { + +var rvertical = /up|down|vertical/, + rpositivemotion = /up|left|vertical|horizontal/; + +$.effects.effect.blind = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + direction = o.direction || "up", + vertical = rvertical.test( direction ), + ref = vertical ? "height" : "width", + ref2 = vertical ? "top" : "left", + motion = rpositivemotion.test( direction ), + animation = {}, + show = mode === "show", + wrapper, distance, margin; + + // if already wrapped, the wrapper's properties are my property. #6245 + if ( el.parent().is( ".ui-effects-wrapper" ) ) { + $.effects.save( el.parent(), props ); + } else { + $.effects.save( el, props ); + } + el.show(); + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + distance = wrapper[ ref ](); + margin = parseFloat( wrapper.css( ref2 ) ) || 0; + + animation[ ref ] = show ? distance : 0; + if ( !motion ) { + el + .css( vertical ? "bottom" : "right", 0 ) + .css( vertical ? "top" : "left", "auto" ) + .css({ position: "absolute" }); + + animation[ ref2 ] = show ? margin : distance + margin; + } + + // start at 0 if we are showing + if ( show ) { + wrapper.css( ref, 0 ); + if ( ! motion ) { + wrapper.css( ref2, margin + distance ); + } + } + + // Animate + wrapper.animate( animation, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.bounce = function( o, done ) { + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + + // defaults: + mode = $.effects.setMode( el, o.mode || "effect" ), + hide = mode === "hide", + show = mode === "show", + direction = o.direction || "up", + distance = o.distance, + times = o.times || 5, + + // number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = o.duration / anims, + easing = o.easing, + + // utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i, + upAnim, + downAnim, + + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + + // Avoid touching opacity to prevent clearType and PNG issues in IE + if ( show || hide ) { + props.push( "opacity" ); + } + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); // Create Wrapper + + // default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } + + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = 0; + + // if we are showing, force opacity 0 and set the initial position + // then do the "first" animation + el.css( "opacity", 0 ) + .css( ref, motion ? -distance * 2 : distance * 2 ) + .animate( downAnim, speed, easing ); + } + + // start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); + } + + downAnim = {}; + downAnim[ ref ] = 0; + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( i = 0; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + el.animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); + + distance = hide ? distance * 2 : distance / 2; + } + + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + el.animate( upAnim, speed, easing ); + } + + el.queue(function() { + if ( hide ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + + // inject all the animations we just queued to be first in line (after "inprogress") + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + el.dequeue(); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.clip = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + direction = o.direction || "vertical", + vert = direction === "vertical", + size = vert ? "height" : "width", + position = vert ? "top" : "left", + animation = {}, + wrapper, animate, distance; + + // Save & Show + $.effects.save( el, props ); + el.show(); + + // Create Wrapper + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + animate = ( el[0].tagName === "IMG" ) ? wrapper : el; + distance = animate[ size ](); + + // Shift + if ( show ) { + animate.css( size, 0 ); + animate.css( position, distance / 2 ); + } + + // Create Animation Object: + animation[ size ] = show ? distance : 0; + animation[ position ] = show ? 0 : distance / 2; + + // Animate + animate.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( !show ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.drop = function( o, done ) { + + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + direction = o.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", + animation = { + opacity: show ? 1 : 0 + }, + distance; + + // Adjust + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + + distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; + + if ( show ) { + el + .css( "opacity", 0 ) + .css( ref, motion === "pos" ? -distance : distance ); + } + + // Animation + animation[ ref ] = ( show ? + ( motion === "pos" ? "+=" : "-=" ) : + ( motion === "pos" ? "-=" : "+=" ) ) + + distance; + + // Animate + el.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.explode = function( o, done ) { + + var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, + cells = rows, + el = $( this ), + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + + // show and then visibility:hidden the element before calculating offset + offset = el.show().css( "visibility", "hidden" ).offset(), + + // width and height of a piece + width = Math.ceil( el.outerWidth() / cells ), + height = Math.ceil( el.outerHeight() / rows ), + pieces = [], + + // loop + i, j, left, top, mx, my; + + // children animate complete: + function childComplete() { + pieces.push( this ); + if ( pieces.length === rows * cells ) { + animComplete(); + } + } + + // clone the element for each row and cell. + for( i = 0; i < rows ; i++ ) { // ===> + top = offset.top + i * height; + my = i - ( rows - 1 ) / 2 ; + + for( j = 0; j < cells ; j++ ) { // ||| + left = offset.left + j * width; + mx = j - ( cells - 1 ) / 2 ; + + // Create a clone of the now hidden main element that will be absolute positioned + // within a wrapper div off the -left and -top equal to size of our pieces + el + .clone() + .appendTo( "body" ) + .wrap( "
    " ) + .css({ + position: "absolute", + visibility: "visible", + left: -j * width, + top: -i * height + }) + + // select the wrapper - make it overflow: hidden and absolute positioned based on + // where the original was located +left and +top equal to the size of pieces + .parent() + .addClass( "ui-effects-explode" ) + .css({ + position: "absolute", + overflow: "hidden", + width: width, + height: height, + left: left + ( show ? mx * width : 0 ), + top: top + ( show ? my * height : 0 ), + opacity: show ? 0 : 1 + }).animate({ + left: left + ( show ? 0 : mx * width ), + top: top + ( show ? 0 : my * height ), + opacity: show ? 1 : 0 + }, o.duration || 500, o.easing, childComplete ); + } + } + + function animComplete() { + el.css({ + visibility: "visible" + }); + $( pieces ).remove(); + if ( !show ) { + el.hide(); + } + done(); + } +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.fade = function( o, done ) { + var el = $( this ), + mode = $.effects.setMode( el, o.mode || "toggle" ); + + el.animate({ + opacity: mode + }, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: done + }); +}; + +})( jQuery ); + +(function( $, undefined ) { + +$.effects.effect.fold = function( o, done ) { + + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + hide = mode === "hide", + size = o.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!o.horizFirst, + widthFirst = show !== horizFirst, + ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], + duration = o.duration / 2, + wrapper, distance, + animation1 = {}, + animation2 = {}; + + $.effects.save( el, props ); + el.show(); + + // Create Wrapper + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + distance = widthFirst ? + [ wrapper.width(), wrapper.height() ] : + [ wrapper.height(), wrapper.width() ]; + + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + if ( show ) { + wrapper.css( horizFirst ? { + height: 0, + width: size + } : { + height: size, + width: 0 + }); + } + + // Animation + animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; + animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; + + // Animate + wrapper + .animate( animation1, duration, o.easing ) + .animate( animation2, duration, o.easing, function() { + if ( hide ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.highlight = function( o, done ) { + var elem = $( this ), + props = [ "backgroundImage", "backgroundColor", "opacity" ], + mode = $.effects.setMode( elem, o.mode || "show" ), + animation = { + backgroundColor: elem.css( "backgroundColor" ) + }; + + if (mode === "hide") { + animation.opacity = 0; + } + + $.effects.save( elem, props ); + + elem + .show() + .css({ + backgroundImage: "none", + backgroundColor: o.color || "#ffff99" + }) + .animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + elem.hide(); + } + $.effects.restore( elem, props ); + done(); + } + }); +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.pulsate = function( o, done ) { + var elem = $( this ), + mode = $.effects.setMode( elem, o.mode || "show" ), + show = mode === "show", + hide = mode === "hide", + showhide = ( show || mode === "hide" ), + + // showing or hiding leaves of the "last" animation + anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = o.duration / anims, + animateTo = 0, + queue = elem.queue(), + queuelen = queue.length, + i; + + if ( show || !elem.is(":visible")) { + elem.css( "opacity", 0 ).show(); + animateTo = 1; + } + + // anims - 1 opacity "toggles" + for ( i = 1; i < anims; i++ ) { + elem.animate({ + opacity: animateTo + }, duration, o.easing ); + animateTo = 1 - animateTo; + } + + elem.animate({ + opacity: animateTo + }, duration, o.easing); + + elem.queue(function() { + if ( hide ) { + elem.hide(); + } + done(); + }); + + // We just queued up "anims" animations, we need to put them next in the queue + if ( queuelen > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + elem.dequeue(); +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.puff = function( o, done ) { + var elem = $( this ), + mode = $.effects.setMode( elem, o.mode || "hide" ), + hide = mode === "hide", + percent = parseInt( o.percent, 10 ) || 150, + factor = percent / 100, + original = { + height: elem.height(), + width: elem.width(), + outerHeight: elem.outerHeight(), + outerWidth: elem.outerWidth() + }; + + $.extend( o, { + effect: "scale", + queue: false, + fade: true, + mode: mode, + complete: done, + percent: hide ? percent : 100, + from: hide ? + original : + { + height: original.height * factor, + width: original.width * factor, + outerHeight: original.outerHeight * factor, + outerWidth: original.outerWidth * factor + } + }); + + elem.effect( o ); +}; + +$.effects.effect.scale = function( o, done ) { + + // Create element + var el = $( this ), + options = $.extend( true, {}, o ), + mode = $.effects.setMode( el, o.mode || "effect" ), + percent = parseInt( o.percent, 10 ) || + ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), + direction = o.direction || "both", + origin = o.origin, + original = { + height: el.height(), + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() + }, + factor = { + y: direction !== "horizontal" ? (percent / 100) : 1, + x: direction !== "vertical" ? (percent / 100) : 1 + }; + + // We are going to pass this effect to the size effect: + options.effect = "size"; + options.queue = false; + options.complete = done; + + // Set default origin and restore for show/hide + if ( mode !== "effect" ) { + options.origin = origin || ["middle","center"]; + options.restore = true; + } + + options.from = o.from || ( mode === "show" ? { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + } : original ); + options.to = { + height: original.height * factor.y, + width: original.width * factor.x, + outerHeight: original.outerHeight * factor.y, + outerWidth: original.outerWidth * factor.x + }; + + // Fade option to support puff + if ( options.fade ) { + if ( mode === "show" ) { + options.from.opacity = 0; + options.to.opacity = 1; + } + if ( mode === "hide" ) { + options.from.opacity = 1; + options.to.opacity = 0; + } + } + + // Animate + el.effect( options ); + +}; + +$.effects.effect.size = function( o, done ) { + + // Create element + var original, baseline, factor, + el = $( this ), + props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], + + // Always restore + props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], + + // Copy for children + props2 = [ "width", "height", "overflow" ], + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + + // Set options + mode = $.effects.setMode( el, o.mode || "effect" ), + restore = o.restore || mode !== "effect", + scale = o.scale || "both", + origin = o.origin || [ "middle", "center" ], + position = el.css( "position" ), + props = restore ? props0 : props1, + zero = { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; + + if ( mode === "show" ) { + el.show(); + } + original = { + height: el.height(), + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() + }; + + if ( o.mode === "toggle" && mode === "show" ) { + el.from = o.to || zero; + el.to = o.from || original; + } else { + el.from = o.from || ( mode === "show" ? zero : original ); + el.to = o.to || ( mode === "hide" ? zero : original ); + } + + // Set scaling factor + factor = { + from: { + y: el.from.height / original.height, + x: el.from.width / original.width + }, + to: { + y: el.to.height / original.height, + x: el.to.width / original.width + } + }; + + // Scale the css box + if ( scale === "box" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + props = props.concat( vProps ); + el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); + el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + props = props.concat( hProps ); + el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); + el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); + } + } + + // Scale the content + if ( scale === "content" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + props = props.concat( cProps ).concat( props2 ); + el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); + el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); + } + } + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + el.css( "overflow", "hidden" ).css( el.from ); + + // Adjust + if (origin) { // Calculate baseline shifts + baseline = $.effects.getBaseline( origin, original ); + el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; + el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; + el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; + el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; + } + el.css( el.from ); // set top & left + + // Animate + if ( scale === "content" || scale === "both" ) { // Scale the children + + // Add margins/font-size + vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); + hProps = hProps.concat([ "marginLeft", "marginRight" ]); + props2 = props0.concat(vProps).concat(hProps); + + el.find( "*[width]" ).each( function(){ + var child = $( this ), + c_original = { + height: child.height(), + width: child.width(), + outerHeight: child.outerHeight(), + outerWidth: child.outerWidth() + }; + if (restore) { + $.effects.save(child, props2); + } + + child.from = { + height: c_original.height * factor.from.y, + width: c_original.width * factor.from.x, + outerHeight: c_original.outerHeight * factor.from.y, + outerWidth: c_original.outerWidth * factor.from.x + }; + child.to = { + height: c_original.height * factor.to.y, + width: c_original.width * factor.to.x, + outerHeight: c_original.height * factor.to.y, + outerWidth: c_original.width * factor.to.x + }; + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); + child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); + child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); + } + + // Animate children + child.css( child.from ); + child.animate( child.to, o.duration, o.easing, function() { + + // Restore children + if ( restore ) { + $.effects.restore( child, props2 ); + } + }); + }); + } + + // Animate + el.animate( el.to, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( el.to.opacity === 0 ) { + el.css( "opacity", el.from.opacity ); + } + if( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + if ( !restore ) { + + // we need to calculate our new positioning based on the scaling + if ( position === "static" ) { + el.css({ + position: "relative", + top: el.to.top, + left: el.to.left + }); + } else { + $.each([ "top", "left" ], function( idx, pos ) { + el.css( pos, function( _, str ) { + var val = parseInt( str, 10 ), + toRef = idx ? el.to.left : el.to.top; + + // if original was "auto", recalculate the new value from wrapper + if ( str === "auto" ) { + return toRef + "px"; + } + + return val + toRef + "px"; + }); + }); + } + } + + $.effects.removeWrapper( el ); + done(); + } + }); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.shake = function( o, done ) { + + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "effect" ), + direction = o.direction || "left", + distance = o.distance || 20, + times = o.times || 3, + anims = times * 2 + 1, + speed = Math.round(o.duration/anims), + ref = (direction === "up" || direction === "down") ? "top" : "left", + positiveMotion = (direction === "up" || direction === "left"), + animation = {}, + animation1 = {}, + animation2 = {}, + i, + + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + + // Animate + el.animate( animation, speed, o.easing ); + + // Shakes + for ( i = 1; i < times; i++ ) { + el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); + } + el + .animate( animation1, speed, o.easing ) + .animate( animation, speed / 2, o.easing ) + .queue(function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + + // inject all the animations we just queued to be first in line (after "inprogress") + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + el.dequeue(); + +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.slide = function( o, done ) { + + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "width", "height" ], + mode = $.effects.setMode( el, o.mode || "show" ), + show = mode === "show", + direction = o.direction || "left", + ref = (direction === "up" || direction === "down") ? "top" : "left", + positiveMotion = (direction === "up" || direction === "left"), + distance, + animation = {}; + + // Adjust + $.effects.save( el, props ); + el.show(); + distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); + + $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + if ( show ) { + el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); + } + + // Animation + animation[ ref ] = ( show ? + ( positiveMotion ? "+=" : "-=") : + ( positiveMotion ? "-=" : "+=")) + + distance; + + // Animate + el.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); +}; + +})(jQuery); + +(function( $, undefined ) { + +$.effects.effect.transfer = function( o, done ) { + var elem = $( this ), + target = $( o.to ), + targetFixed = target.css( "position" ) === "fixed", + body = $("body"), + fixTop = targetFixed ? body.scrollTop() : 0, + fixLeft = targetFixed ? body.scrollLeft() : 0, + endPosition = target.offset(), + animation = { + top: endPosition.top - fixTop , + left: endPosition.left - fixLeft , + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = elem.offset(), + transfer = $( "
    " ) + .appendTo( document.body ) + .addClass( o.className ) + .css({ + top: startPosition.top - fixTop , + left: startPosition.left - fixLeft , + height: elem.innerHeight(), + width: elem.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + }) + .animate( animation, o.duration, o.easing, function() { + transfer.remove(); + done(); + }); +}; + +})(jQuery); + +(function( $, undefined ) { + +$.widget( "ui.menu", { + version: "1.10.3", + defaultElement: "
      ", + delay: 300, + options: { + icons: { + submenu: "ui-icon-carat-1-e" + }, + menus: "ul", + position: { + my: "left top", + at: "right top" + }, + role: "menu", + + // callbacks + blur: null, + focus: null, + select: null + }, + + _create: function() { + this.activeMenu = this.element; + // flag used to prevent firing of the click handler + // as the event bubbles up through nested menus + this.mouseHandled = false; + this.element + .uniqueId() + .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) + .attr({ + role: this.options.role, + tabIndex: 0 + }) + // need to catch all clicks on disabled menu + // not possible through _on + .bind( "click" + this.eventNamespace, $.proxy(function( event ) { + if ( this.options.disabled ) { + event.preventDefault(); + } + }, this )); + + if ( this.options.disabled ) { + this.element + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } + + this._on({ + // Prevent focus from sticking to links inside menu after clicking + // them (focus should always stay on UL during navigation). + "mousedown .ui-menu-item > a": function( event ) { + event.preventDefault(); + }, + "click .ui-state-disabled > a": function( event ) { + event.preventDefault(); + }, + "click .ui-menu-item:has(a)": function( event ) { + var target = $( event.target ).closest( ".ui-menu-item" ); + if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { + this.mouseHandled = true; + + this.select( event ); + // Open submenu on click + if ( target.has( ".ui-menu" ).length ) { + this.expand( event ); + } else if ( !this.element.is( ":focus" ) ) { + // Redirect focus to the menu + this.element.trigger( "focus", [ true ] ); + + // If the active item is on the top level, let it stay active. + // Otherwise, blur the active item since it is no longer visible. + if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { + clearTimeout( this.timer ); + } + } + } + }, + "mouseenter .ui-menu-item": function( event ) { + var target = $( event.currentTarget ); + // Remove ui-state-active class from siblings of the newly focused menu item + // to avoid a jump caused by adjacent elements both having a class with a border + target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); + this.focus( event, target ); + }, + mouseleave: "collapseAll", + "mouseleave .ui-menu": "collapseAll", + focus: function( event, keepActiveItem ) { + // If there's already an active item, keep it active + // If not, activate the first item + var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); + + if ( !keepActiveItem ) { + this.focus( event, item ); + } + }, + blur: function( event ) { + this._delay(function() { + if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { + this.collapseAll( event ); + } + }); + }, + keydown: "_keydown" + }); + + this.refresh(); + + // Clicks outside of a menu collapse any open menus + this._on( this.document, { + click: function( event ) { + if ( !$( event.target ).closest( ".ui-menu" ).length ) { + this.collapseAll( event ); + } + + // Reset the mouseHandled flag + this.mouseHandled = false; + } + }); + }, + + _destroy: function() { + // Destroy (sub)menus + this.element + .removeAttr( "aria-activedescendant" ) + .find( ".ui-menu" ).addBack() + .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-disabled" ) + .removeUniqueId() + .show(); + + // Destroy menu items + this.element.find( ".ui-menu-item" ) + .removeClass( "ui-menu-item" ) + .removeAttr( "role" ) + .removeAttr( "aria-disabled" ) + .children( "a" ) + .removeUniqueId() + .removeClass( "ui-corner-all ui-state-hover" ) + .removeAttr( "tabIndex" ) + .removeAttr( "role" ) + .removeAttr( "aria-haspopup" ) + .children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-carat" ) ) { + elem.remove(); + } + }); + + // Destroy menu dividers + this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); + }, + + _keydown: function( event ) { + /*jshint maxcomplexity:20*/ + var match, prev, character, skip, regex, + preventDefault = true; + + function escape( value ) { + return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + this.previousPage( event ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.nextPage( event ); + break; + case $.ui.keyCode.HOME: + this._move( "first", "first", event ); + break; + case $.ui.keyCode.END: + this._move( "last", "last", event ); + break; + case $.ui.keyCode.UP: + this.previous( event ); + break; + case $.ui.keyCode.DOWN: + this.next( event ); + break; + case $.ui.keyCode.LEFT: + this.collapse( event ); + break; + case $.ui.keyCode.RIGHT: + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + this.expand( event ); + } + break; + case $.ui.keyCode.ENTER: + case $.ui.keyCode.SPACE: + this._activate( event ); + break; + case $.ui.keyCode.ESCAPE: + this.collapse( event ); + break; + default: + preventDefault = false; + prev = this.previousFilter || ""; + character = String.fromCharCode( event.keyCode ); + skip = false; + + clearTimeout( this.filterTimer ); + + if ( character === prev ) { + skip = true; + } else { + character = prev + character; + } + + regex = new RegExp( "^" + escape( character ), "i" ); + match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { + return regex.test( $( this ).children( "a" ).text() ); + }); + match = skip && match.index( this.active.next() ) !== -1 ? + this.active.nextAll( ".ui-menu-item" ) : + match; + + // If no matches on the current filter, reset to the last character pressed + // to move down the menu to the first item that starts with that character + if ( !match.length ) { + character = String.fromCharCode( event.keyCode ); + regex = new RegExp( "^" + escape( character ), "i" ); + match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { + return regex.test( $( this ).children( "a" ).text() ); + }); + } + + if ( match.length ) { + this.focus( event, match ); + if ( match.length > 1 ) { + this.previousFilter = character; + this.filterTimer = this._delay(function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; + } + } else { + delete this.previousFilter; + } + } + + if ( preventDefault ) { + event.preventDefault(); + } + }, + + _activate: function( event ) { + if ( !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, + + refresh: function() { + var menus, + icon = this.options.icons.submenu, + submenus = this.element.find( this.options.menus ); + + // Initialize nested menus + submenus.filter( ":not(.ui-menu)" ) + .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .hide() + .attr({ + role: this.options.role, + "aria-hidden": "true", + "aria-expanded": "false" + }) + .each(function() { + var menu = $( this ), + item = menu.prev( "a" ), + submenuCarat = $( "" ) + .addClass( "ui-menu-icon ui-icon " + icon ) + .data( "ui-menu-submenu-carat", true ); + + item + .attr( "aria-haspopup", "true" ) + .prepend( submenuCarat ); + menu.attr( "aria-labelledby", item.attr( "id" ) ); + }); + + menus = submenus.add( this.element ); + + // Don't refresh list items that are already adapted + menus.children( ":not(.ui-menu-item):has(a)" ) + .addClass( "ui-menu-item" ) + .attr( "role", "presentation" ) + .children( "a" ) + .uniqueId() + .addClass( "ui-corner-all" ) + .attr({ + tabIndex: -1, + role: this._itemRole() + }); + + // Initialize unlinked menu-items containing spaces and/or dashes only as dividers + menus.children( ":not(.ui-menu-item)" ).each(function() { + var item = $( this ); + // hyphen, em dash, en dash + if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { + item.addClass( "ui-widget-content ui-menu-divider" ); + } + }); + + // Add aria-disabled attribute to any disabled menu item + menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + + // If the active item has been removed, blur the menu + if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + this.blur(); + } + }, + + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; + }, + + _setOption: function( key, value ) { + if ( key === "icons" ) { + this.element.find( ".ui-menu-icon" ) + .removeClass( this.options.icons.submenu ) + .addClass( value.submenu ); + } + this._super( key, value ); + }, + + focus: function( event, item ) { + var nested, focused; + this.blur( event, event && event.type === "focus" ); + + this._scrollIntoView( item ); + + this.active = item.first(); + focused = this.active.children( "a" ).addClass( "ui-state-focus" ); + // Only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + } + + // Highlight active parent menu item, if any + this.active + .parent() + .closest( ".ui-menu-item" ) + .children( "a:first" ) + .addClass( "ui-state-active" ); + + if ( event && event.type === "keydown" ) { + this._close(); + } else { + this.timer = this._delay(function() { + this._close(); + }, this.delay ); + } + + nested = item.children( ".ui-menu" ); + if ( nested.length && ( /^mouse/.test( event.type ) ) ) { + this._startOpening(nested); + } + this.activeMenu = item.parent(); + + this._trigger( "focus", event, { item: item } ); + }, + + _scrollIntoView: function( item ) { + var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + if ( this._hasScroll() ) { + borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; + paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; + offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; + scroll = this.activeMenu.scrollTop(); + elementHeight = this.activeMenu.height(); + itemHeight = item.height(); + + if ( offset < 0 ) { + this.activeMenu.scrollTop( scroll + offset ); + } else if ( offset + itemHeight > elementHeight ) { + this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); + } + } + }, + + blur: function( event, fromFocus ) { + if ( !fromFocus ) { + clearTimeout( this.timer ); + } + + if ( !this.active ) { + return; + } + + this.active.children( "a" ).removeClass( "ui-state-focus" ); + this.active = null; + + this._trigger( "blur", event, { item: this.active } ); + }, + + _startOpening: function( submenu ) { + clearTimeout( this.timer ); + + // Don't open if already open fixes a Firefox bug that caused a .5 pixel + // shift in the submenu position when mousing over the carat icon + if ( submenu.attr( "aria-hidden" ) !== "true" ) { + return; + } + + this.timer = this._delay(function() { + this._close(); + this._open( submenu ); + }, this.delay ); + }, + + _open: function( submenu ) { + var position = $.extend({ + of: this.active + }, this.options.position ); + + clearTimeout( this.timer ); + this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) + .hide() + .attr( "aria-hidden", "true" ); + + submenu + .show() + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .position( position ); + }, + + collapseAll: function( event, all ) { + clearTimeout( this.timer ); + this.timer = this._delay(function() { + // If we were passed an event, look for the submenu that contains the event + var currentMenu = all ? this.element : + $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); + + // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway + if ( !currentMenu.length ) { + currentMenu = this.element; + } + + this._close( currentMenu ); + + this.blur( event ); + this.activeMenu = currentMenu; + }, this.delay ); + }, + + // With no arguments, closes the currently active menu - if nothing is active + // it closes all menus. If passed an argument, it will search for menus BELOW + _close: function( startMenu ) { + if ( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; + } + + startMenu + .find( ".ui-menu" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ) + .end() + .find( "a.ui-state-active" ) + .removeClass( "ui-state-active" ); + }, + + collapse: function( event ) { + var newItem = this.active && + this.active.parent().closest( ".ui-menu-item", this.element ); + if ( newItem && newItem.length ) { + this._close(); + this.focus( event, newItem ); + } + }, + + expand: function( event ) { + var newItem = this.active && + this.active + .children( ".ui-menu " ) + .children( ".ui-menu-item" ) + .first(); + + if ( newItem && newItem.length ) { + this._open( newItem.parent() ); + + // Delay so Firefox will not hide activedescendant change in expanding submenu from AT + this._delay(function() { + this.focus( event, newItem ); + }); + } + }, + + next: function( event ) { + this._move( "next", "first", event ); + }, + + previous: function( event ) { + this._move( "prev", "last", event ); + }, + + isFirstItem: function() { + return this.active && !this.active.prevAll( ".ui-menu-item" ).length; + }, + + isLastItem: function() { + return this.active && !this.active.nextAll( ".ui-menu-item" ).length; + }, + + _move: function( direction, filter, event ) { + var next; + if ( this.active ) { + if ( direction === "first" || direction === "last" ) { + next = this.active + [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) + .eq( -1 ); + } else { + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .eq( 0 ); + } + } + if ( !next || !next.length || !this.active ) { + next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); + } + + this.focus( event, next ); + }, + + nextPage: function( event ) { + var item, base, height; + + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isLastItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.height(); + this.active.nextAll( ".ui-menu-item" ).each(function() { + item = $( this ); + return item.offset().top - base - height < 0; + }); + + this.focus( event, item ); + } else { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) + [ !this.active ? "first" : "last" ]() ); + } + }, + + previousPage: function( event ) { + var item, base, height; + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isFirstItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.height(); + this.active.prevAll( ".ui-menu-item" ).each(function() { + item = $( this ); + return item.offset().top - base + height > 0; + }); + + this.focus( event, item ); + } else { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + } + }, + + _hasScroll: function() { + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); + }, + + select: function( event ) { + // TODO: It should never be possible to not have an active item at this + // point, but the tests don't trigger mouseenter before click. + this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); + var ui = { item: this.active }; + if ( !this.active.has( ".ui-menu" ).length ) { + this.collapseAll( event, true ); + } + this._trigger( "select", event, ui ); + } +}); + +}( jQuery )); + +(function( $, undefined ) { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function getDimensions( elem ) { + var raw = elem[0]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
      " ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), + overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ); + return { + element: withinElement, + isWindow: isWindow, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[0].preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem : elem + }); + } + }); + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } + else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { + position.top += myOffset + atOffset + offset; + } + } + else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +}( jQuery ) ); + +(function( $, undefined ) { + +$.widget( "ui.progressbar", { + version: "1.10.3", + options: { + max: 100, + value: 0, + + change: null, + complete: null + }, + + min: 0, + + _create: function() { + // Constrain initial value + this.oldValue = this.options.value = this._constrainedValue(); + + this.element + .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .attr({ + // Only set static values, aria-valuenow and aria-valuemax are + // set inside _refreshValue() + role: "progressbar", + "aria-valuemin": this.min + }); + + this.valueDiv = $( "
      " ) + .appendTo( this.element ); + + this._refreshValue(); + }, + + _destroy: function() { + this.element + .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); + + this.valueDiv.remove(); + }, + + value: function( newValue ) { + if ( newValue === undefined ) { + return this.options.value; + } + + this.options.value = this._constrainedValue( newValue ); + this._refreshValue(); + }, + + _constrainedValue: function( newValue ) { + if ( newValue === undefined ) { + newValue = this.options.value; + } + + this.indeterminate = newValue === false; + + // sanitize value + if ( typeof newValue !== "number" ) { + newValue = 0; + } + + return this.indeterminate ? false : + Math.min( this.options.max, Math.max( this.min, newValue ) ); + }, + + _setOptions: function( options ) { + // Ensure "value" option is set after other values (like max) + var value = options.value; + delete options.value; + + this._super( options ); + + this.options.value = this._constrainedValue( value ); + this._refreshValue(); + }, + + _setOption: function( key, value ) { + if ( key === "max" ) { + // Don't allow a max less than min + value = Math.max( this.min, value ); + } + + this._super( key, value ); + }, + + _percentage: function() { + return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); + }, + + _refreshValue: function() { + var value = this.options.value, + percentage = this._percentage(); + + this.valueDiv + .toggle( this.indeterminate || value > this.min ) + .toggleClass( "ui-corner-right", value === this.options.max ) + .width( percentage.toFixed(0) + "%" ); + + this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); + + if ( this.indeterminate ) { + this.element.removeAttr( "aria-valuenow" ); + if ( !this.overlayDiv ) { + this.overlayDiv = $( "
      " ).appendTo( this.valueDiv ); + } + } else { + this.element.attr({ + "aria-valuemax": this.options.max, + "aria-valuenow": value + }); + if ( this.overlayDiv ) { + this.overlayDiv.remove(); + this.overlayDiv = null; + } + } + + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); + } + if ( value === this.options.max ) { + this._trigger( "complete" ); + } + } +}); + +})( jQuery ); + +(function( $, undefined ) { + +// number of pages in a slider +// (how many times can you page up/down to go through the whole range) +var numPages = 5; + +$.widget( "ui.slider", $.ui.mouse, { + version: "1.10.3", + widgetEventPrefix: "slide", + + options: { + animate: false, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null, + + // callbacks + change: null, + slide: null, + start: null, + stop: null + }, + + _create: function() { + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + + this.element + .addClass( "ui-slider" + + " ui-slider-" + this.orientation + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all"); + + this._refresh(); + this._setOption( "disabled", this.options.disabled ); + + this._animateOff = false; + }, + + _refresh: function() { + this._createRange(); + this._createHandles(); + this._setupEvents(); + this._refreshValue(); + }, + + _createHandles: function() { + var i, handleCount, + options = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), + handle = "", + handles = []; + + handleCount = ( options.values && options.values.length ) || 1; + + if ( existingHandles.length > handleCount ) { + existingHandles.slice( handleCount ).remove(); + existingHandles = existingHandles.slice( 0, handleCount ); + } + + for ( i = existingHandles.length; i < handleCount; i++ ) { + handles.push( handle ); + } + + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + + this.handle = this.handles.eq( 0 ); + + this.handles.each(function( i ) { + $( this ).data( "ui-slider-handle-index", i ); + }); + }, + + _createRange: function() { + var options = this.options, + classes = ""; + + if ( options.range ) { + if ( options.range === true ) { + if ( !options.values ) { + options.values = [ this._valueMin(), this._valueMin() ]; + } else if ( options.values.length && options.values.length !== 2 ) { + options.values = [ options.values[0], options.values[0] ]; + } else if ( $.isArray( options.values ) ) { + options.values = options.values.slice(0); + } + } + + if ( !this.range || !this.range.length ) { + this.range = $( "
      " ) + .appendTo( this.element ); + + classes = "ui-slider-range" + + // note: this isn't the most fittingly semantic framework class for this element, + // but worked best visually with a variety of themes + " ui-widget-header ui-corner-all"; + } else { + this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) + // Handle range switching from true to min/max + .css({ + "left": "", + "bottom": "" + }); + } + + this.range.addClass( classes + + ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); + } else { + this.range = $([]); + } + }, + + _setupEvents: function() { + var elements = this.handles.add( this.range ).filter( "a" ); + this._off( elements ); + this._on( elements, this._handleEvents ); + this._hoverable( elements ); + this._focusable( elements ); + }, + + _destroy: function() { + this.handles.remove(); + this.range.remove(); + + this.element + .removeClass( "ui-slider" + + " ui-slider-horizontal" + + " ui-slider-vertical" + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ); + + this._mouseDestroy(); + }, + + _mouseCapture: function( event ) { + var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, + that = this, + o = this.options; + + if ( o.disabled ) { + return false; + } + + this.elementSize = { + width: this.element.outerWidth(), + height: this.element.outerHeight() + }; + this.elementOffset = this.element.offset(); + + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + this.handles.each(function( i ) { + var thisDistance = Math.abs( normValue - that.values(i) ); + if (( distance > thisDistance ) || + ( distance === thisDistance && + (i === that._lastChangedValue || that.values(i) === o.min ))) { + distance = thisDistance; + closestHandle = $( this ); + index = i; + } + }); + + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; + } + this._mouseSliding = true; + + this._handleIndex = index; + + closestHandle + .addClass( "ui-state-active" ) + .focus(); + + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); + this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - + ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + + ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) + }; + + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); + } + this._animateOff = true; + return true; + }, + + _mouseStart: function() { + return true; + }, + + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); + + this._slide( event, this._handleIndex, normValue ); + + return false; + }, + + _mouseStop: function( event ) { + this.handles.removeClass( "ui-state-active" ); + this._mouseSliding = false; + + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); + + this._handleIndex = null; + this._clickOffset = null; + this._animateOff = false; + + return false; + }, + + _detectOrientation: function() { + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + }, + + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; + + if ( this.orientation === "horizontal" ) { + pixelTotal = this.elementSize.width; + pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); + } else { + pixelTotal = this.elementSize.height; + pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); + } + + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; + } + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { + percentMouse = 1 - percentMouse; + } + + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; + + return this._trimAlignValue( valueMouse ); + }, + + _start: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + return this._trigger( "start", event, uiHash ); + }, + + _slide: function( event, index, newVal ) { + var otherVal, + newValues, + allowed; + + if ( this.options.values && this.options.values.length ) { + otherVal = this.values( index ? 0 : 1 ); + + if ( ( this.options.values.length === 2 && this.options.range === true ) && + ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + ) { + newVal = otherVal; + } + + if ( newVal !== this.values( index ) ) { + newValues = this.values(); + newValues[ index ] = newVal; + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal, + values: newValues + } ); + otherVal = this.values( index ? 0 : 1 ); + if ( allowed !== false ) { + this.values( index, newVal, true ); + } + } + } else { + if ( newVal !== this.value() ) { + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal + } ); + if ( allowed !== false ) { + this.value( newVal ); + } + } + } + }, + + _stop: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "stop", event, uiHash ); + }, + + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + //store the last changed value index for reference when handles overlap + this._lastChangedValue = index; + + this._trigger( "change", event, uiHash ); + } + }, + + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); + return; + } + + return this._value(); + }, + + values: function( index, newValue ) { + var vals, + newValues, + i; + + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); + return; + } + + if ( arguments.length ) { + if ( $.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); + } else { + if ( this.options.values && this.options.values.length ) { + return this._values( index ); + } else { + return this.value(); + } + } + } else { + return this._values(); + } + }, + + _setOption: function( key, value ) { + var i, + valsLength = 0; + + if ( key === "range" && this.options.range === true ) { + if ( value === "min" ) { + this.options.value = this._values( 0 ); + this.options.values = null; + } else if ( value === "max" ) { + this.options.value = this._values( this.options.values.length-1 ); + this.options.values = null; + } + } + + if ( $.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "orientation": + this._detectOrientation(); + this.element + .removeClass( "ui-slider-horizontal ui-slider-vertical" ) + .addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + for ( i = 0; i < valsLength; i += 1 ) { + this._change( null, i ); + } + this._animateOff = false; + break; + case "min": + case "max": + this._animateOff = true; + this._refreshValue(); + this._animateOff = false; + break; + case "range": + this._animateOff = true; + this._refresh(); + this._animateOff = false; + break; + } + }, + + //internal value getter + // _value() returns value trimmed by min and max, aligned by step + _value: function() { + var val = this.options.value; + val = this._trimAlignValue( val ); + + return val; + }, + + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; + + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); + + return val; + } else if ( this.options.values && this.options.values.length ) { + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i+= 1) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); + } + + return vals; + } else { + return []; + } + }, + + // returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val <= this._valueMin() ) { + return this._valueMin(); + } + if ( val >= this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = (val - this._valueMin()) % step, + alignValue = val - valModStep; + + if ( Math.abs(valModStep) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); + } + + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed(5) ); + }, + + _valueMin: function() { + return this.options.min; + }, + + _valueMax: function() { + return this.options.max; + }, + + _refreshValue: function() { + var lastValPercent, valPercent, value, valueMin, valueMax, + oRange = this.options.range, + o = this.options, + that = this, + animate = ( !this._animateOff ) ? o.animate : false, + _set = {}; + + if ( this.options.values && this.options.values.length ) { + this.handles.each(function( i ) { + valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; + _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( that.options.range === true ) { + if ( that.orientation === "horizontal" ) { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } else { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + } + lastValPercent = valPercent; + }); + } else { + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + }, + + _handleEvents: { + keydown: function( event ) { + /*jshint maxcomplexity:25*/ + var allowed, curVal, newVal, step, + index = $( event.target ).data( "ui-slider-handle-index" ); + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + event.preventDefault(); + if ( !this._keySliding ) { + this._keySliding = true; + $( event.target ).addClass( "ui-state-active" ); + allowed = this._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = this.options.step; + if ( this.options.values && this.options.values.length ) { + curVal = newVal = this.values( index ); + } else { + curVal = newVal = this.value(); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = this._valueMin(); + break; + case $.ui.keyCode.END: + newVal = this._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === this._valueMax() ) { + return; + } + newVal = this._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === this._valueMin() ) { + return; + } + newVal = this._trimAlignValue( curVal - step ); + break; + } + + this._slide( event, index, newVal ); + }, + click: function( event ) { + event.preventDefault(); + }, + keyup: function( event ) { + var index = $( event.target ).data( "ui-slider-handle-index" ); + + if ( this._keySliding ) { + this._keySliding = false; + this._stop( event, index ); + this._change( event, index ); + $( event.target ).removeClass( "ui-state-active" ); + } + } + } + +}); + +}(jQuery)); + +(function( $ ) { + +function modifier( fn ) { + return function() { + var previous = this.element.val(); + fn.apply( this, arguments ); + this._refresh(); + if ( previous !== this.element.val() ) { + this._trigger( "change" ); + } + }; +} + +$.widget( "ui.spinner", { + version: "1.10.3", + defaultElement: "", + widgetEventPrefix: "spin", + options: { + culture: null, + icons: { + down: "ui-icon-triangle-1-s", + up: "ui-icon-triangle-1-n" + }, + incremental: true, + max: null, + min: null, + numberFormat: null, + page: 10, + step: 1, + + change: null, + spin: null, + start: null, + stop: null + }, + + _create: function() { + // handle string values that need to be parsed + this._setOption( "max", this.options.max ); + this._setOption( "min", this.options.min ); + this._setOption( "step", this.options.step ); + + // format the value, but don't constrain + this._value( this.element.val(), true ); + + this._draw(); + this._on( this._events ); + this._refresh(); + + // turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + }); + }, + + _getCreateOptions: function() { + var options = {}, + element = this.element; + + $.each( [ "min", "max", "step" ], function( i, option ) { + var value = element.attr( option ); + if ( value !== undefined && value.length ) { + options[ option ] = value; + } + }); + + return options; + }, + + _events: { + keydown: function( event ) { + if ( this._start( event ) && this._keydown( event ) ) { + event.preventDefault(); + } + }, + keyup: "_stop", + focus: function() { + this.previous = this.element.val(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + this._stop(); + this._refresh(); + if ( this.previous !== this.element.val() ) { + this._trigger( "change", event ); + } + }, + mousewheel: function( event, delta ) { + if ( !delta ) { + return; + } + if ( !this.spinning && !this._start( event ) ) { + return false; + } + + this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); + clearTimeout( this.mousewheelTimer ); + this.mousewheelTimer = this._delay(function() { + if ( this.spinning ) { + this._stop( event ); + } + }, 100 ); + event.preventDefault(); + }, + "mousedown .ui-spinner-button": function( event ) { + var previous; + + // We never want the buttons to have focus; whenever the user is + // interacting with the spinner, the focus should be on the input. + // If the input is focused then this.previous is properly set from + // when the input first received focus. If the input is not focused + // then we need to set this.previous based on the value before spinning. + previous = this.element[0] === this.document[0].activeElement ? + this.previous : this.element.val(); + function checkFocus() { + var isActive = this.element[0] === this.document[0].activeElement; + if ( !isActive ) { + this.element.focus(); + this.previous = previous; + // support: IE + // IE sets focus asynchronously, so we need to check if focus + // moved off of the input because the user clicked on the button. + this._delay(function() { + this.previous = previous; + }); + } + } + + // ensure focus is on (or stays on) the text field + event.preventDefault(); + checkFocus.call( this ); + + // support: IE + // IE doesn't prevent moving focus even with event.preventDefault() + // so we set a flag to know when we should ignore the blur event + // and check (again) if focus moved off of the input. + this.cancelBlur = true; + this._delay(function() { + delete this.cancelBlur; + checkFocus.call( this ); + }); + + if ( this._start( event ) === false ) { + return; + } + + this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + }, + "mouseup .ui-spinner-button": "_stop", + "mouseenter .ui-spinner-button": function( event ) { + // button will add ui-state-active if mouse was down while mouseleave and kept down + if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { + return; + } + + if ( this._start( event ) === false ) { + return false; + } + this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + }, + // TODO: do we really want to consider this a stop? + // shouldn't we just stop the repeater and wait until mouseup before + // we trigger the stop event? + "mouseleave .ui-spinner-button": "_stop" + }, + + _draw: function() { + var uiSpinner = this.uiSpinner = this.element + .addClass( "ui-spinner-input" ) + .attr( "autocomplete", "off" ) + .wrap( this._uiSpinnerHtml() ) + .parent() + // add buttons + .append( this._buttonHtml() ); + + this.element.attr( "role", "spinbutton" ); + + // button bindings + this.buttons = uiSpinner.find( ".ui-spinner-button" ) + .attr( "tabIndex", -1 ) + .button() + .removeClass( "ui-corner-all" ); + + // IE 6 doesn't understand height: 50% for the buttons + // unless the wrapper has an explicit height + if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && + uiSpinner.height() > 0 ) { + uiSpinner.height( uiSpinner.height() ); + } + + // disable spinner if element was already disabled + if ( this.options.disabled ) { + this.disable(); + } + }, + + _keydown: function( event ) { + var options = this.options, + keyCode = $.ui.keyCode; + + switch ( event.keyCode ) { + case keyCode.UP: + this._repeat( null, 1, event ); + return true; + case keyCode.DOWN: + this._repeat( null, -1, event ); + return true; + case keyCode.PAGE_UP: + this._repeat( null, options.page, event ); + return true; + case keyCode.PAGE_DOWN: + this._repeat( null, -options.page, event ); + return true; + } + + return false; + }, + + _uiSpinnerHtml: function() { + return ""; + }, + + _buttonHtml: function() { + return "" + + "" + + "" + + "" + + "" + + "" + + ""; + }, + + _start: function( event ) { + if ( !this.spinning && this._trigger( "start", event ) === false ) { + return false; + } + + if ( !this.counter ) { + this.counter = 1; + } + this.spinning = true; + return true; + }, + + _repeat: function( i, steps, event ) { + i = i || 500; + + clearTimeout( this.timer ); + this.timer = this._delay(function() { + this._repeat( 40, steps, event ); + }, i ); + + this._spin( steps * this.options.step, event ); + }, + + _spin: function( step, event ) { + var value = this.value() || 0; + + if ( !this.counter ) { + this.counter = 1; + } + + value = this._adjustValue( value + step * this._increment( this.counter ) ); + + if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { + this._value( value ); + this.counter++; + } + }, + + _increment: function( i ) { + var incremental = this.options.incremental; + + if ( incremental ) { + return $.isFunction( incremental ) ? + incremental( i ) : + Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); + } + + return 1; + }, + + _precision: function() { + var precision = this._precisionOf( this.options.step ); + if ( this.options.min !== null ) { + precision = Math.max( precision, this._precisionOf( this.options.min ) ); + } + return precision; + }, + + _precisionOf: function( num ) { + var str = num.toString(), + decimal = str.indexOf( "." ); + return decimal === -1 ? 0 : str.length - decimal - 1; + }, + + _adjustValue: function( value ) { + var base, aboveMin, + options = this.options; + + // make sure we're at a valid step + // - find out where we are relative to the base (min or 0) + base = options.min !== null ? options.min : 0; + aboveMin = value - base; + // - round to the nearest step + aboveMin = Math.round(aboveMin / options.step) * options.step; + // - rounding is based on 0, so adjust back to our base + value = base + aboveMin; + + // fix precision from bad JS floating point math + value = parseFloat( value.toFixed( this._precision() ) ); + + // clamp the value + if ( options.max !== null && value > options.max) { + return options.max; + } + if ( options.min !== null && value < options.min ) { + return options.min; + } + + return value; + }, + + _stop: function( event ) { + if ( !this.spinning ) { + return; + } + + clearTimeout( this.timer ); + clearTimeout( this.mousewheelTimer ); + this.counter = 0; + this.spinning = false; + this._trigger( "stop", event ); + }, + + _setOption: function( key, value ) { + if ( key === "culture" || key === "numberFormat" ) { + var prevValue = this._parse( this.element.val() ); + this.options[ key ] = value; + this.element.val( this._format( prevValue ) ); + return; + } + + if ( key === "max" || key === "min" || key === "step" ) { + if ( typeof value === "string" ) { + value = this._parse( value ); + } + } + if ( key === "icons" ) { + this.buttons.first().find( ".ui-icon" ) + .removeClass( this.options.icons.up ) + .addClass( value.up ); + this.buttons.last().find( ".ui-icon" ) + .removeClass( this.options.icons.down ) + .addClass( value.down ); + } + + this._super( key, value ); + + if ( key === "disabled" ) { + if ( value ) { + this.element.prop( "disabled", true ); + this.buttons.button( "disable" ); + } else { + this.element.prop( "disabled", false ); + this.buttons.button( "enable" ); + } + } + }, + + _setOptions: modifier(function( options ) { + this._super( options ); + this._value( this.element.val() ); + }), + + _parse: function( val ) { + if ( typeof val === "string" && val !== "" ) { + val = window.Globalize && this.options.numberFormat ? + Globalize.parseFloat( val, 10, this.options.culture ) : +val; + } + return val === "" || isNaN( val ) ? null : val; + }, + + _format: function( value ) { + if ( value === "" ) { + return ""; + } + return window.Globalize && this.options.numberFormat ? + Globalize.format( value, this.options.numberFormat, this.options.culture ) : + value; + }, + + _refresh: function() { + this.element.attr({ + "aria-valuemin": this.options.min, + "aria-valuemax": this.options.max, + // TODO: what should we do with values that can't be parsed? + "aria-valuenow": this._parse( this.element.val() ) + }); + }, + + // update the value without triggering change + _value: function( value, allowAny ) { + var parsed; + if ( value !== "" ) { + parsed = this._parse( value ); + if ( parsed !== null ) { + if ( !allowAny ) { + parsed = this._adjustValue( parsed ); + } + value = this._format( parsed ); + } + } + this.element.val( value ); + this._refresh(); + }, + + _destroy: function() { + this.element + .removeClass( "ui-spinner-input" ) + .prop( "disabled", false ) + .removeAttr( "autocomplete" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); + this.uiSpinner.replaceWith( this.element ); + }, + + stepUp: modifier(function( steps ) { + this._stepUp( steps ); + }), + _stepUp: function( steps ) { + if ( this._start() ) { + this._spin( (steps || 1) * this.options.step ); + this._stop(); + } + }, + + stepDown: modifier(function( steps ) { + this._stepDown( steps ); + }), + _stepDown: function( steps ) { + if ( this._start() ) { + this._spin( (steps || 1) * -this.options.step ); + this._stop(); + } + }, + + pageUp: modifier(function( pages ) { + this._stepUp( (pages || 1) * this.options.page ); + }), + + pageDown: modifier(function( pages ) { + this._stepDown( (pages || 1) * this.options.page ); + }), + + value: function( newVal ) { + if ( !arguments.length ) { + return this._parse( this.element.val() ); + } + modifier( this._value ).call( this, newVal ); + }, + + widget: function() { + return this.uiSpinner; + } +}); + +}( jQuery ) ); + +(function( $, undefined ) { + +var tabId = 0, + rhash = /#.*$/; + +function getNextTabId() { + return ++tabId; +} + +function isLocal( anchor ) { + return anchor.hash.length > 1 && + decodeURIComponent( anchor.href.replace( rhash, "" ) ) === + decodeURIComponent( location.href.replace( rhash, "" ) ); +} + +$.widget( "ui.tabs", { + version: "1.10.3", + delay: 300, + options: { + active: null, + collapsible: false, + event: "click", + heightStyle: "content", + hide: null, + show: null, + + // callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, + load: null + }, + + _create: function() { + var that = this, + options = this.options; + + this.running = false; + + this.element + .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) + .toggleClass( "ui-tabs-collapsible", options.collapsible ) + // Prevent users from focusing disabled tabs via click + .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { + if ( $( this ).is( ".ui-state-disabled" ) ) { + event.preventDefault(); + } + }) + // support: IE <9 + // Preventing the default action in mousedown doesn't prevent IE + // from focusing the element, so if the anchor gets focused, blur. + // We don't have to worry about focusing the previously focused + // element since clicking on a non-focusable element should focus + // the body anyway. + .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + }); + + this._processTabs(); + options.active = this._initialActive(); + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( $.isArray( options.disabled ) ) { + options.disabled = $.unique( options.disabled.concat( + $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { + return that.tabs.index( li ); + }) + ) ).sort(); + } + + // check for length avoids error when initializing empty list + if ( this.options.active !== false && this.anchors.length ) { + this.active = this._findActive( options.active ); + } else { + this.active = $(); + } + + this._refresh(); + + if ( this.active.length ) { + this.load( options.active ); + } + }, + + _initialActive: function() { + var active = this.options.active, + collapsible = this.options.collapsible, + locationHash = location.hash.substring( 1 ); + + if ( active === null ) { + // check the fragment identifier in the URL + if ( locationHash ) { + this.tabs.each(function( i, tab ) { + if ( $( tab ).attr( "aria-controls" ) === locationHash ) { + active = i; + return false; + } + }); + } + + // check for a tab marked active via a class + if ( active === null ) { + active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); + } + + // no active tab, set to false + if ( active === null || active === -1 ) { + active = this.tabs.length ? 0 : false; + } + } + + // handle numbers: negative, out of range + if ( active !== false ) { + active = this.tabs.index( this.tabs.eq( active ) ); + if ( active === -1 ) { + active = collapsible ? false : 0; + } + } + + // don't allow collapsible: false and active: false + if ( !collapsible && active === false && this.anchors.length ) { + active = 0; + } + + return active; + }, + + _getCreateEventData: function() { + return { + tab: this.active, + panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + }; + }, + + _tabKeydown: function( event ) { + /*jshint maxcomplexity:15*/ + var focusedTab = $( this.document[0].activeElement ).closest( "li" ), + selectedIndex = this.tabs.index( focusedTab ), + goingForward = true; + + if ( this._handlePageNav( event ) ) { + return; + } + + switch ( event.keyCode ) { + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + selectedIndex++; + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.LEFT: + goingForward = false; + selectedIndex--; + break; + case $.ui.keyCode.END: + selectedIndex = this.anchors.length - 1; + break; + case $.ui.keyCode.HOME: + selectedIndex = 0; + break; + case $.ui.keyCode.SPACE: + // Activate only, no collapsing + event.preventDefault(); + clearTimeout( this.activating ); + this._activate( selectedIndex ); + return; + case $.ui.keyCode.ENTER: + // Toggle (cancel delayed activation, allow collapsing) + event.preventDefault(); + clearTimeout( this.activating ); + // Determine if we should collapse or activate + this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + return; + default: + return; + } + + // Focus the appropriate tab, based on which key was pressed + event.preventDefault(); + clearTimeout( this.activating ); + selectedIndex = this._focusNextTab( selectedIndex, goingForward ); + + // Navigating with control key will prevent automatic activation + if ( !event.ctrlKey ) { + // Update aria-selected immediately so that AT think the tab is already selected. + // Otherwise AT may confuse the user by stating that they need to activate the tab, + // but the tab will already be activated by the time the announcement finishes. + focusedTab.attr( "aria-selected", "false" ); + this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); + + this.activating = this._delay(function() { + this.option( "active", selectedIndex ); + }, this.delay ); + } + }, + + _panelKeydown: function( event ) { + if ( this._handlePageNav( event ) ) { + return; + } + + // Ctrl+up moves focus to the current tab + if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { + event.preventDefault(); + this.active.focus(); + } + }, + + // Alt+page up/down moves focus to the previous/next tab (and activates) + _handlePageNav: function( event ) { + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { + this._activate( this._focusNextTab( this.options.active - 1, false ) ); + return true; + } + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { + this._activate( this._focusNextTab( this.options.active + 1, true ) ); + return true; + } + }, + + _findNextTab: function( index, goingForward ) { + var lastTabIndex = this.tabs.length - 1; + + function constrain() { + if ( index > lastTabIndex ) { + index = 0; + } + if ( index < 0 ) { + index = lastTabIndex; + } + return index; + } + + while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { + index = goingForward ? index + 1 : index - 1; + } + + return index; + }, + + _focusNextTab: function( index, goingForward ) { + index = this._findNextTab( index, goingForward ); + this.tabs.eq( index ).focus(); + return index; + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "disabled" ) { + // don't use the widget factory's disabled handling + this._setupDisabled( value ); + return; + } + + this._super( key, value); + + if ( key === "collapsible" ) { + this.element.toggleClass( "ui-tabs-collapsible", value ); + // Setting collapsible: false while collapsed; open first panel + if ( !value && this.options.active === false ) { + this._activate( 0 ); + } + } + + if ( key === "event" ) { + this._setupEvents( value ); + } + + if ( key === "heightStyle" ) { + this._setupHeightStyle( value ); + } + }, + + _tabId: function( tab ) { + return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); + }, + + _sanitizeSelector: function( hash ) { + return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; + }, + + refresh: function() { + var options = this.options, + lis = this.tablist.children( ":has(a[href])" ); + + // get disabled tabs from class attribute from HTML + // this will get converted to a boolean if needed in _refresh() + options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { + return lis.index( tab ); + }); + + this._processTabs(); + + // was collapsed or no tabs + if ( options.active === false || !this.anchors.length ) { + options.active = false; + this.active = $(); + // was active, but active tab is gone + } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { + // all remaining tabs are disabled + if ( this.tabs.length === options.disabled.length ) { + options.active = false; + this.active = $(); + // activate previous tab + } else { + this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); + } + // was active, active tab still exists + } else { + // make sure active index is correct + options.active = this.tabs.index( this.active ); + } + + this._refresh(); + }, + + _refresh: function() { + this._setupDisabled( this.options.disabled ); + this._setupEvents( this.options.event ); + this._setupHeightStyle( this.options.heightStyle ); + + this.tabs.not( this.active ).attr({ + "aria-selected": "false", + tabIndex: -1 + }); + this.panels.not( this._getPanelForTab( this.active ) ) + .hide() + .attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + + // Make sure one tab is in the tab order + if ( !this.active.length ) { + this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active + .addClass( "ui-tabs-active ui-state-active" ) + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); + this._getPanelForTab( this.active ) + .show() + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + } + }, + + _processTabs: function() { + var that = this; + + this.tablist = this._getList() + .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .attr( "role", "tablist" ); + + this.tabs = this.tablist.find( "> li:has(a[href])" ) + .addClass( "ui-state-default ui-corner-top" ) + .attr({ + role: "tab", + tabIndex: -1 + }); + + this.anchors = this.tabs.map(function() { + return $( "a", this )[ 0 ]; + }) + .addClass( "ui-tabs-anchor" ) + .attr({ + role: "presentation", + tabIndex: -1 + }); + + this.panels = $(); + + this.anchors.each(function( i, anchor ) { + var selector, panel, panelId, + anchorId = $( anchor ).uniqueId().attr( "id" ), + tab = $( anchor ).closest( "li" ), + originalAriaControls = tab.attr( "aria-controls" ); + + // inline tab + if ( isLocal( anchor ) ) { + selector = anchor.hash; + panel = that.element.find( that._sanitizeSelector( selector ) ); + // remote tab + } else { + panelId = that._tabId( tab ); + selector = "#" + panelId; + panel = that.element.find( selector ); + if ( !panel.length ) { + panel = that._createPanel( panelId ); + panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); + } + panel.attr( "aria-live", "polite" ); + } + + if ( panel.length) { + that.panels = that.panels.add( panel ); + } + if ( originalAriaControls ) { + tab.data( "ui-tabs-aria-controls", originalAriaControls ); + } + tab.attr({ + "aria-controls": selector.substring( 1 ), + "aria-labelledby": anchorId + }); + panel.attr( "aria-labelledby", anchorId ); + }); + + this.panels + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .attr( "role", "tabpanel" ); + }, + + // allow overriding how to find the list for rare usage scenarios (#7715) + _getList: function() { + return this.element.find( "ol,ul" ).eq( 0 ); + }, + + _createPanel: function( id ) { + return $( "
      " ) + .attr( "id", id ) + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .data( "ui-tabs-destroy", true ); + }, + + _setupDisabled: function( disabled ) { + if ( $.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + + // disable tabs + for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { + if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { + $( li ) + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } else { + $( li ) + .removeClass( "ui-state-disabled" ) + .removeAttr( "aria-disabled" ); + } + } + + this.options.disabled = disabled; + }, + + _setupEvents: function( event ) { + var events = { + click: function( event ) { + event.preventDefault(); + } + }; + if ( event ) { + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + } + + this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + this._on( this.anchors, events ); + this._on( this.tabs, { keydown: "_tabKeydown" } ); + this._on( this.panels, { keydown: "_panelKeydown" } ); + + this._focusable( this.tabs ); + this._hoverable( this.tabs ); + }, + + _setupHeightStyle: function( heightStyle ) { + var maxHeight, + parent = this.element.parent(); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + maxHeight -= this.element.outerHeight() - this.element.height(); + + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + + this.element.children().not( this.panels ).each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); + + this.panels.each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.panels.each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }).height( maxHeight ); + } + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + anchor = $( event.currentTarget ), + tab = anchor.closest( "li" ), + clickedIsActive = tab[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : this._getPanelForTab( tab ), + toHide = !active.length ? $() : this._getPanelForTab( active ), + eventData = { + oldTab: active, + oldPanel: toHide, + newTab: collapsing ? $() : tab, + newPanel: toShow + }; + + event.preventDefault(); + + if ( tab.hasClass( "ui-state-disabled" ) || + // tab is already loading + tab.hasClass( "ui-tabs-loading" ) || + // can't switch durning an animation + this.running || + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.tabs.index( tab ); + + this.active = clickedIsActive ? $() : tab; + if ( this.xhr ) { + this.xhr.abort(); + } + + if ( !toHide.length && !toShow.length ) { + $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); + } + + if ( toShow.length ) { + this.load( this.tabs.index( tab ), event ); + } + this._toggle( event, eventData ); + }, + + // handles show/hide for selecting tabs + _toggle: function( event, eventData ) { + var that = this, + toShow = eventData.newPanel, + toHide = eventData.oldPanel; + + this.running = true; + + function complete() { + that.running = false; + that._trigger( "activate", event, eventData ); + } + + function show() { + eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); + + if ( toShow.length && that.options.show ) { + that._show( toShow, that.options.show, complete ); + } else { + toShow.show(); + complete(); + } + } + + // start out by hiding, then showing, then completing + if ( toHide.length && this.options.hide ) { + this._hide( toHide, this.options.hide, function() { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + show(); + }); + } else { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + toHide.hide(); + show(); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + eventData.oldTab.attr( "aria-selected", "false" ); + // If we're switching tabs, remove the old tab from the tab order. + // If we're opening from collapsed state, remove the previous tab from the tab order. + // If we're collapsing, then keep the collapsing tab in the tab order. + if ( toShow.length && toHide.length ) { + eventData.oldTab.attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.tabs.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow.attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + eventData.newTab.attr({ + "aria-selected": "true", + tabIndex: 0 + }); + }, + + _activate: function( index ) { + var anchor, + active = this._findActive( index ); + + // trying to activate the already active panel + if ( active[ 0 ] === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the current active header + if ( !active.length ) { + active = this.active; + } + + anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; + this._eventHandler({ + target: anchor, + currentTarget: anchor, + preventDefault: $.noop + }); + }, + + _findActive: function( index ) { + return index === false ? $() : this.tabs.eq( index ); + }, + + _getIndex: function( index ) { + // meta-function to give users option to provide a href string instead of a numerical index. + if ( typeof index === "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); + } + + return index; + }, + + _destroy: function() { + if ( this.xhr ) { + this.xhr.abort(); + } + + this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); + + this.tablist + .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .removeAttr( "role" ); + + this.anchors + .removeClass( "ui-tabs-anchor" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeUniqueId(); + + this.tabs.add( this.panels ).each(function() { + if ( $.data( this, "ui-tabs-destroy" ) ) { + $( this ).remove(); + } else { + $( this ) + .removeClass( "ui-state-default ui-state-active ui-state-disabled " + + "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-live" ) + .removeAttr( "aria-busy" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "role" ); + } + }); + + this.tabs.each(function() { + var li = $( this ), + prev = li.data( "ui-tabs-aria-controls" ); + if ( prev ) { + li + .attr( "aria-controls", prev ) + .removeData( "ui-tabs-aria-controls" ); + } else { + li.removeAttr( "aria-controls" ); + } + }); + + this.panels.show(); + + if ( this.options.heightStyle !== "content" ) { + this.panels.css( "height", "" ); + } + }, + + enable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === false ) { + return; + } + + if ( index === undefined ) { + disabled = false; + } else { + index = this._getIndex( index ); + if ( $.isArray( disabled ) ) { + disabled = $.map( disabled, function( num ) { + return num !== index ? num : null; + }); + } else { + disabled = $.map( this.tabs, function( li, num ) { + return num !== index ? num : null; + }); + } + } + this._setupDisabled( disabled ); + }, + + disable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === true ) { + return; + } + + if ( index === undefined ) { + disabled = true; + } else { + index = this._getIndex( index ); + if ( $.inArray( index, disabled ) !== -1 ) { + return; + } + if ( $.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; + } + } + this._setupDisabled( disabled ); + }, + + load: function( index, event ) { + index = this._getIndex( index ); + var that = this, + tab = this.tabs.eq( index ), + anchor = tab.find( ".ui-tabs-anchor" ), + panel = this._getPanelForTab( tab ), + eventData = { + tab: tab, + panel: panel + }; + + // not remote + if ( isLocal( anchor[ 0 ] ) ) { + return; + } + + this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); + + // support: jQuery <1.8 + // jQuery <1.8 returns false if the request is canceled in beforeSend, + // but as of 1.8, $.ajax() always returns a jqXHR object. + if ( this.xhr && this.xhr.statusText !== "canceled" ) { + tab.addClass( "ui-tabs-loading" ); + panel.attr( "aria-busy", "true" ); + + this.xhr + .success(function( response ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + panel.html( response ); + that._trigger( "load", event, eventData ); + }, 1 ); + }) + .complete(function( jqXHR, status ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + if ( status === "abort" ) { + that.panels.stop( false, true ); + } + + tab.removeClass( "ui-tabs-loading" ); + panel.removeAttr( "aria-busy" ); + + if ( jqXHR === that.xhr ) { + delete that.xhr; + } + }, 1 ); + }); + } + }, + + _ajaxSettings: function( anchor, event, eventData ) { + var that = this; + return { + url: anchor.attr( "href" ), + beforeSend: function( jqXHR, settings ) { + return that._trigger( "beforeLoad", event, + $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); + } + }; + }, + + _getPanelForTab: function( tab ) { + var id = $( tab ).attr( "aria-controls" ); + return this.element.find( this._sanitizeSelector( "#" + id ) ); + } +}); + +})( jQuery ); + +(function( $ ) { + +var increments = 0; + +function addDescribedBy( elem, id ) { + var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); +} + +function removeDescribedBy( elem ) { + var id = elem.data( "ui-tooltip-id" ), + describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), + index = $.inArray( id, describedby ); + if ( index !== -1 ) { + describedby.splice( index, 1 ); + } + + elem.removeData( "ui-tooltip-id" ); + describedby = $.trim( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); + } +} + +$.widget( "ui.tooltip", { + version: "1.10.3", + options: { + content: function() { + // support: IE<9, Opera in jQuery <1.7 + // .text() can't accept undefined, so coerce to a string + var title = $( this ).attr( "title" ) || ""; + // Escape title, since we're going from an attribute to raw HTML + return $( "" ).text( title ).html(); + }, + hide: true, + // Disabled elements have inconsistent behavior across browsers (#8661) + items: "[title]:not([disabled])", + position: { + my: "left top+15", + at: "left bottom", + collision: "flipfit flip" + }, + show: true, + tooltipClass: null, + track: false, + + // callbacks + close: null, + open: null + }, + + _create: function() { + this._on({ + mouseover: "open", + focusin: "open" + }); + + // IDs of generated tooltips, needed for destroy + this.tooltips = {}; + // IDs of parent tooltips where we removed the title attribute + this.parents = {}; + + if ( this.options.disabled ) { + this._disable(); + } + }, + + _setOption: function( key, value ) { + var that = this; + + if ( key === "disabled" ) { + this[ value ? "_disable" : "_enable" ](); + this.options[ key ] = value; + // disable element style changes + return; + } + + this._super( key, value ); + + if ( key === "content" ) { + $.each( this.tooltips, function( id, element ) { + that._updateContent( element ); + }); + } + }, + + _disable: function() { + var that = this; + + // close open tooltips + $.each( this.tooltips, function( id, element ) { + var event = $.Event( "blur" ); + event.target = event.currentTarget = element[0]; + that.close( event, true ); + }); + + // remove title attributes to prevent native tooltips + this.element.find( this.options.items ).addBack().each(function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + element + .data( "ui-tooltip-title", element.attr( "title" ) ) + .attr( "title", "" ); + } + }); + }, + + _enable: function() { + // restore title attributes + this.element.find( this.options.items ).addBack().each(function() { + var element = $( this ); + if ( element.data( "ui-tooltip-title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + } + }); + }, + + open: function( event ) { + var that = this, + target = $( event ? event.target : this.element ) + // we need closest here due to mouseover bubbling, + // but always pointing at the same event target + .closest( this.options.items ); + + // No element to show a tooltip for or the tooltip is already open + if ( !target.length || target.data( "ui-tooltip-id" ) ) { + return; + } + + if ( target.attr( "title" ) ) { + target.data( "ui-tooltip-title", target.attr( "title" ) ); + } + + target.data( "ui-tooltip-open", true ); + + // kill parent tooltips, custom or native, for hover + if ( event && event.type === "mouseover" ) { + target.parents().each(function() { + var parent = $( this ), + blurEvent; + if ( parent.data( "ui-tooltip-open" ) ) { + blurEvent = $.Event( "blur" ); + blurEvent.target = blurEvent.currentTarget = this; + that.close( blurEvent, true ); + } + if ( parent.attr( "title" ) ) { + parent.uniqueId(); + that.parents[ this.id ] = { + element: this, + title: parent.attr( "title" ) + }; + parent.attr( "title", "" ); + } + }); + } + + this._updateContent( target, event ); + }, + + _updateContent: function( target, event ) { + var content, + contentOption = this.options.content, + that = this, + eventType = event ? event.type : null; + + if ( typeof contentOption === "string" ) { + return this._open( event, target, contentOption ); + } + + content = contentOption.call( target[0], function( response ) { + // ignore async response if tooltip was closed already + if ( !target.data( "ui-tooltip-open" ) ) { + return; + } + // IE may instantly serve a cached response for ajax requests + // delay this call to _open so the other call to _open runs first + that._delay(function() { + // jQuery creates a special event for focusin when it doesn't + // exist natively. To improve performance, the native event + // object is reused and the type is changed. Therefore, we can't + // rely on the type being correct after the event finished + // bubbling, so we set it back to the previous value. (#8740) + if ( event ) { + event.type = eventType; + } + this._open( event, target, response ); + }); + }); + if ( content ) { + this._open( event, target, content ); + } + }, + + _open: function( event, target, content ) { + var tooltip, events, delayedShow, + positionOption = $.extend( {}, this.options.position ); + + if ( !content ) { + return; + } + + // Content can be updated multiple times. If the tooltip already + // exists, then just update the content and bail. + tooltip = this._find( target ); + if ( tooltip.length ) { + tooltip.find( ".ui-tooltip-content" ).html( content ); + return; + } + + // if we have a title, clear it to prevent the native tooltip + // we have to check first to avoid defining a title if none exists + // (we don't want to cause an element to start matching [title]) + // + // We use removeAttr only for key events, to allow IE to export the correct + // accessible attributes. For mouse events, set to empty string to avoid + // native tooltip showing up (happens only when removing inside mouseover). + if ( target.is( "[title]" ) ) { + if ( event && event.type === "mouseover" ) { + target.attr( "title", "" ); + } else { + target.removeAttr( "title" ); + } + } + + tooltip = this._tooltip( target ); + addDescribedBy( target, tooltip.attr( "id" ) ); + tooltip.find( ".ui-tooltip-content" ).html( content ); + + function position( event ) { + positionOption.of = event; + if ( tooltip.is( ":hidden" ) ) { + return; + } + tooltip.position( positionOption ); + } + if ( this.options.track && event && /^mouse/.test( event.type ) ) { + this._on( this.document, { + mousemove: position + }); + // trigger once to override element-relative positioning + position( event ); + } else { + tooltip.position( $.extend({ + of: target + }, this.options.position ) ); + } + + tooltip.hide(); + + this._show( tooltip, this.options.show ); + // Handle tracking tooltips that are shown with a delay (#8644). As soon + // as the tooltip is visible, position the tooltip using the most recent + // event. + if ( this.options.show && this.options.show.delay ) { + delayedShow = this.delayedShow = setInterval(function() { + if ( tooltip.is( ":visible" ) ) { + position( positionOption.of ); + clearInterval( delayedShow ); + } + }, $.fx.interval ); + } + + this._trigger( "open", event, { tooltip: tooltip } ); + + events = { + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE ) { + var fakeEvent = $.Event(event); + fakeEvent.currentTarget = target[0]; + this.close( fakeEvent, true ); + } + }, + remove: function() { + this._removeTooltip( tooltip ); + } + }; + if ( !event || event.type === "mouseover" ) { + events.mouseleave = "close"; + } + if ( !event || event.type === "focusin" ) { + events.focusout = "close"; + } + this._on( true, target, events ); + }, + + close: function( event ) { + var that = this, + target = $( event ? event.currentTarget : this.element ), + tooltip = this._find( target ); + + // disabling closes the tooltip, so we need to track when we're closing + // to avoid an infinite loop in case the tooltip becomes disabled on close + if ( this.closing ) { + return; + } + + // Clear the interval for delayed tracking tooltips + clearInterval( this.delayedShow ); + + // only set title if we had one before (see comment in _open()) + if ( target.data( "ui-tooltip-title" ) ) { + target.attr( "title", target.data( "ui-tooltip-title" ) ); + } + + removeDescribedBy( target ); + + tooltip.stop( true ); + this._hide( tooltip, this.options.hide, function() { + that._removeTooltip( $( this ) ); + }); + + target.removeData( "ui-tooltip-open" ); + this._off( target, "mouseleave focusout keyup" ); + // Remove 'remove' binding only on delegated targets + if ( target[0] !== this.element[0] ) { + this._off( target, "remove" ); + } + this._off( this.document, "mousemove" ); + + if ( event && event.type === "mouseleave" ) { + $.each( this.parents, function( id, parent ) { + $( parent.element ).attr( "title", parent.title ); + delete that.parents[ id ]; + }); + } + + this.closing = true; + this._trigger( "close", event, { tooltip: tooltip } ); + this.closing = false; + }, + + _tooltip: function( element ) { + var id = "ui-tooltip-" + increments++, + tooltip = $( "
      " ) + .attr({ + id: id, + role: "tooltip" + }) + .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + + ( this.options.tooltipClass || "" ) ); + $( "
      " ) + .addClass( "ui-tooltip-content" ) + .appendTo( tooltip ); + tooltip.appendTo( this.document[0].body ); + this.tooltips[ id ] = element; + return tooltip; + }, + + _find: function( target ) { + var id = target.data( "ui-tooltip-id" ); + return id ? $( "#" + id ) : $(); + }, + + _removeTooltip: function( tooltip ) { + tooltip.remove(); + delete this.tooltips[ tooltip.attr( "id" ) ]; + }, + + _destroy: function() { + var that = this; + + // close open tooltips + $.each( this.tooltips, function( id, element ) { + // Delegate to close method to handle common cleanup + var event = $.Event( "blur" ); + event.target = event.currentTarget = element[0]; + that.close( event, true ); + + // Remove immediately; destroying an open tooltip doesn't use the + // hide animation + $( "#" + id ).remove(); + + // Restore the title + if ( element.data( "ui-tooltip-title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + element.removeData( "ui-tooltip-title" ); + } + }); + } +}); + +}( jQuery ) ); \ No newline at end of file diff --git a/examples/lock.html b/examples/lock.html new file mode 100644 index 000000000..dfa24d491 --- /dev/null +++ b/examples/lock.html @@ -0,0 +1,66 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + +
      +

      Selectize.js

      +
      +

      Locking

      +

      Selectize controls can be locked to prevent user interaction.

      +
      + + +
      +
      + + +
      +
      + + +
      +
      + + +
      + +
      +
      + + diff --git a/examples/movies.html b/examples/movies.html new file mode 100644 index 000000000..76d7e8a8c --- /dev/null +++ b/examples/movies.html @@ -0,0 +1,165 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + + +
      +

      Selectize.js

      +
      +

      Loading from API

      +

      This demo shows how to integrate third-party data, loaded asynchronously.

      +
      + + +
      + +
      +
      + + \ No newline at end of file diff --git a/examples/optgroups.html b/examples/optgroups.html new file mode 100644 index 000000000..463c86333 --- /dev/null +++ b/examples/optgroups.html @@ -0,0 +1,174 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + + +
      +

      Selectize.js

      + +
      +

      Optgroups (basic)

      +
      + + +
      + +
      + +
      +

      Optgroups (repeated options)

      +
      + + +
      + +
      + +
      +

      Optgroups (programmatic)

      +
      + + +
      + +
      + +
      +

      Plugin: "optgroup_columns"

      +
      + +
      + +
      +
      + + \ No newline at end of file diff --git a/examples/performance.html b/examples/performance.html new file mode 100644 index 000000000..d53c5fd50 --- /dev/null +++ b/examples/performance.html @@ -0,0 +1,59 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + +
      +

      Selectize.js

      +
      +

      Performance

      +

      This shows how it performs with 25,000 items.

      +
      + + +
      + +
      +
      + + \ No newline at end of file diff --git a/examples/plugins.html b/examples/plugins.html new file mode 100644 index 000000000..8bd8447a2 --- /dev/null +++ b/examples/plugins.html @@ -0,0 +1,118 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + + +
      +

      Selectize.js

      + +
      +

      Plugin: "remove_button"

      +
      + + +
      +
      + + +
      + +
      + +
      +

      Plugin: "restore_on_backspace"

      +
      + + +
      + +
      + +
      +

      Plugin: "drag_drop"

      +
      + + +
      +
      + + +
      + +
      + +
      +

      Plugin: "dropdown_header"

      +
      + + +
      + +
      +
      + + \ No newline at end of file diff --git a/examples/required.html b/examples/required.html new file mode 100644 index 000000000..87b7c72db --- /dev/null +++ b/examples/required.html @@ -0,0 +1,53 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + +
      +

      Selectize.js

      + +
      +

      Required Element

      +
      +
      + + +
      + +
      +
      +
      + +
      + +
      + + \ No newline at end of file diff --git a/examples/rtl.html b/examples/rtl.html new file mode 100644 index 000000000..ce5a152be --- /dev/null +++ b/examples/rtl.html @@ -0,0 +1,56 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + +
      +

      Selectize.js

      + +
      +

      Right-to-left Support (RTL)

      +
      + + +
      + +
      + +
      +

      Right-to-left Support (RTL) – Single

      +
      + + +
      + +
      + +
      + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..72aebb5b3 --- /dev/null +++ b/package.json @@ -0,0 +1,37 @@ +{ + "name": "selectize", + "keywords": [ + "select", + "ui", + "form", + "input", + "control", + "autocomplete", + "tagging", + "tag" + ], + "description": "Selectize is a jQuery-based custom UI control. Useful for tagging, contact lists, country selectors, etc.", + "homepage": "http://brianreavis.github.io/selectize.js/", + "demo": "http://brianreavis.github.io/selectize.js/", + "docs": "https://github.com/brianreavis/selectize.js", + "bugs": "https://github.com/brianreavis/selectize.js/issues", + "licenses": [ + { + "type": "Apache License, Version 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + ], + "maintainers": [ + { + "name": "Brian Reavis", + "email": "brian@thirdroute.com", + "url": "http://thirdroute.com" + } + ], + "dependencies": { + "jquery": ">=1.6" + } +} diff --git a/src/.wrapper.js b/src/.wrapper.js new file mode 100644 index 000000000..8aed36cbe --- /dev/null +++ b/src/.wrapper.js @@ -0,0 +1,34 @@ +/** + * selectize.js (v@@version) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +/*jshint curly:false */ +/*jshint browser:true */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery','sifter','microplugin'], factory); + } else if (typeof exports === 'object') { + module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); + } else { + root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); + } +}(this, function($, Sifter, MicroPlugin) { + 'use strict'; + + @@js + + return Selectize; +})); \ No newline at end of file diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 000000000..06390e6e8 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,21 @@ +var IS_MAC = /Mac/.test(navigator.userAgent); + +var KEY_A = 65; +var KEY_COMMA = 188; +var KEY_RETURN = 13; +var KEY_ESC = 27; +var KEY_LEFT = 37; +var KEY_UP = 38; +var KEY_P = 80; +var KEY_RIGHT = 39; +var KEY_DOWN = 40; +var KEY_N = 78; +var KEY_BACKSPACE = 8; +var KEY_DELETE = 46; +var KEY_SHIFT = 16; +var KEY_CMD = IS_MAC ? 91 : 17; +var KEY_CTRL = IS_MAC ? 18 : 17; +var KEY_TAB = 9; + +var TAG_SELECT = 1; +var TAG_INPUT = 2; diff --git a/src/contrib/highlight.js b/src/contrib/highlight.js new file mode 100644 index 000000000..888bc9072 --- /dev/null +++ b/src/contrib/highlight.js @@ -0,0 +1,39 @@ +/** + * highlight v3 | MIT license | Johann Burkard + * Highlights arbitrary terms in a node. + * + * - Modified by Marshal 2011-6-24 (added regex) + * - Modified by Brian Reavis 2012-8-27 (cleanup) + */ + +var highlight = function($element, pattern) { + if (typeof pattern === 'string' && !pattern.length) return; + var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern; + + var highlight = function(node) { + var skip = 0; + if (node.nodeType === 3) { + var pos = node.data.search(regex); + if (pos >= 0 && node.data.length > 0) { + var match = node.data.match(regex); + var spannode = document.createElement('span'); + spannode.className = 'highlight'; + var middlebit = node.splitText(pos); + var endbit = middlebit.splitText(match[0].length); + var middleclone = middlebit.cloneNode(true); + spannode.appendChild(middleclone); + middlebit.parentNode.replaceChild(spannode, middlebit); + skip = 1; + } + } else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { + for (var i = 0; i < node.childNodes.length; ++i) { + i += highlight(node.childNodes[i]); + } + } + return skip; + }; + + return $element.each(function() { + highlight(this); + }); +}; \ No newline at end of file diff --git a/src/contrib/microevent.js b/src/contrib/microevent.js new file mode 100644 index 000000000..49c75260c --- /dev/null +++ b/src/contrib/microevent.js @@ -0,0 +1,48 @@ +/** + * MicroEvent - to make any js object an event emitter + * + * - pure javascript - server compatible, browser compatible + * - dont rely on the browser doms + * - super simple - you get it immediatly, no mistery, no magic involved + * + * @author Jerome Etienne (https://github.com/jeromeetienne) + */ + +var MicroEvent = function() {}; +MicroEvent.prototype = { + on: function(event, fct){ + this._events = this._events || {}; + this._events[event] = this._events[event] || []; + this._events[event].push(fct); + }, + off: function(event, fct){ + var n = arguments.length; + if (n === 0) return delete this._events; + if (n === 1) return delete this._events[event]; + + this._events = this._events || {}; + if (event in this._events === false) return; + this._events[event].splice(this._events[event].indexOf(fct), 1); + }, + trigger: function(event /* , args... */){ + this._events = this._events || {}; + if (event in this._events === false) return; + for (var i = 0; i < this._events[event].length; i++){ + this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); + } + } +}; + +/** + * Mixin will delegate all MicroEvent.js function in the destination object. + * + * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent + * + * @param {object} the object which will support MicroEvent + */ +MicroEvent.mixin = function(destObject){ + var props = ['on', 'off', 'trigger']; + for (var i = 0; i < props.length; i++){ + destObject.prototype[props[i]] = MicroEvent.prototype[props[i]]; + } +}; \ No newline at end of file diff --git a/src/defaults.js b/src/defaults.js new file mode 100644 index 000000000..1c69bee6b --- /dev/null +++ b/src/defaults.js @@ -0,0 +1,68 @@ +Selectize.count = 0; +Selectize.defaults = { + plugins: [], + delimiter: ',', + splitOn: /[,]+/, // Regex or string for splitting up values from a paste command + persist: true, + diacritics: true, + create: false, + createOnBlur: false, + highlight: true, + openOnFocus: true, + maxOptions: 1000, + maxItems: null, + hideSelected: null, + addPrecedence: false, + selectOnTab: false, + preload: false, + + scrollDuration: 60, + loadThrottle: 300, + + dataAttr: 'data-data', + optgroupField: 'optgroup', + valueField: 'value', + labelField: 'text', + optgroupLabelField: 'label', + optgroupValueField: 'value', + optgroupOrder: null, + + sortField: '$order', + searchField: ['text'], + searchConjunction: 'and', + + mode: null, + wrapperClass: 'selectize-control', + inputClass: 'selectize-input', + dropdownClass: 'selectize-dropdown', + dropdownContentClass: 'selectize-dropdown-content', + + dropdownParent: null, + + /* + load : null, // function(query, callback) { ... } + score : null, // function(search) { ... } + onInitialize : null, // function() { ... } + onChange : null, // function(value) { ... } + onItemAdd : null, // function(value, $item) { ... } + onItemRemove : null, // function(value) { ... } + onClear : null, // function() { ... } + onOptionAdd : null, // function(value, data) { ... } + onOptionRemove : null, // function(value) { ... } + onOptionClear : null, // function() { ... } + onDropdownOpen : null, // function($dropdown) { ... } + onDropdownClose : null, // function($dropdown) { ... } + onType : null, // function(str) { ... } + onDelete : null, // function(values) { ... } + */ + + render: { + /* + item: null, + optgroup: null, + optgroup_header: null, + option: null, + option_create: null + */ + } +}; \ No newline at end of file diff --git a/src/less/.wrapper.css b/src/less/.wrapper.css new file mode 100644 index 000000000..1cf4adb28 --- /dev/null +++ b/src/less/.wrapper.css @@ -0,0 +1,17 @@ +/** + * selectize.css (v@@version) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +@@css \ No newline at end of file diff --git a/src/less/selectize.bootstrap2.less b/src/less/selectize.bootstrap2.less new file mode 100644 index 000000000..df7594c09 --- /dev/null +++ b/src/less/selectize.bootstrap2.less @@ -0,0 +1,161 @@ +/** + * selectize.bootstrap2.css (v@@version) - Bootstrap 2 Theme + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +@import "selectize"; + +@selectize-font-family: @baseFontFamily; +@selectize-font-size: @baseFontSize; +@selectize-line-height: @baseLineHeight; + +@selectize-color-text: @textColor; +@selectize-color-highlight: rgba(255,237,40,0.4); +@selectize-color-input: @inputBackground; +@selectize-color-input-full: @inputBackground; +@selectize-color-disabled: @inputBackground; +@selectize-color-item: @btnBackgroundHighlight; +@selectize-color-item-border: @btnBorder; +@selectize-color-item-active: @dropdownLinkBackgroundHover; +@selectize-color-item-active-text: @dropdownLinkColorHover; +@selectize-color-item-active-border: darken(@selectize-color-item-active, 5%); +@selectize-color-optgroup: @dropdownBackground; +@selectize-color-optgroup-text: @grayLight; +@selectize-color-optgroup-border: @dropdownDividerTop; +@selectize-color-dropdown: @dropdownBackground; +@selectize-color-dropdown-border: @inputBorder; +@selectize-color-dropdown-border-top: @dropdownDividerTop; +@selectize-color-dropdown-item-active: @dropdownLinkBackgroundHover; +@selectize-color-dropdown-item-active-text: @dropdownLinkColorHover; +@selectize-color-dropdown-item-create-active-text: @dropdownLinkColorHover; +@selectize-lighten-disabled-item: 8%; +@selectize-lighten-disabled-item-text: 8%; +@selectize-lighten-disabled-item-border: 8%; +@selectize-opacity-disabled: 0.5; +@selectize-shadow-input: none; +@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); +@selectize-border-radius: @inputBorderRadius; + +@selectize-padding-x: 10px; +@selectize-padding-y: 7px; +@selectize-padding-dropdown-item-x: @selectize-padding-x; +@selectize-padding-dropdown-item-y: 3px; +@selectize-padding-item-x: 3px; +@selectize-padding-item-y: 1px; +@selectize-margin-item-x: 3px; +@selectize-margin-item-y: 3px; +@selectize-caret-margin: 0; + +@selectize-arrow-size: 5px; +@selectize-arrow-color: @black; +@selectize-arrow-offset: @selectize-padding-x + 5px; + +@selectize-width-item-border: 1px; + +.selectize-dropdown { + margin: 2px 0 0 0; + z-index: @zindexDropdown; + border: 1px solid @dropdownBorder; + border-radius: @baseBorderRadius; + .box-shadow(0 5px 10px rgba(0,0,0,.2)); + + .optgroup-header { + font-size: 11px; + font-weight: bold; + text-shadow: 0 1px 0 rgba(255,255,255,.5); + text-transform: uppercase; + } + .optgroup:first-child:before { + display: none; + } + .optgroup:before { + content: ' '; + display: block; + .nav-divider(); + margin-left: @selectize-padding-dropdown-item-x * -1; + margin-right: @selectize-padding-dropdown-item-x * -1; + } + + [data-selectable].active { + #gradient > .vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%)); + } +} + +.selectize-dropdown-content { + padding: 5px 0; +} + +.selectize-dropdown-header { + padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; +} + +.selectize-input { + .transition(~"border linear .2s, box-shadow linear .2s"); + + &.dropdown-active { + .selectize-border-radius(@selectize-border-radius); + } + &.dropdown-active::before { + display: none; + } + &.input-active, &.input-active:hover, .selectize-control.multi &.focus { + background: @selectize-color-input !important; + border-color: rgba(82,168,236,.8) !important; + outline: 0 !important; + outline: thin dotted \9 !important; + .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)") !important; + } +} + +.selectize-control { + &.single { + .selectize-input { + .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); + .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); + &:hover { + color: @grayDark; + text-decoration: none; + background-position: 0 -15px; + .transition(background-position .1s linear); + } + &.disabled { + background: @btnBackgroundHighlight !important; + .box-shadow(none); + } + } + } + &.multi { + .selectize-input { + .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + &.has-items { + @padding-x: @selectize-padding-x - @selectize-padding-item-x; + padding-left: @padding-x; + padding-right: @padding-x; + } + } + .selectize-input > div { + .gradientBar(@btnBackground, @btnBackgroundHighlight, @selectize-color-item-text, none); + *background-color: @selectize-color-item; + border: @selectize-width-item-border solid @selectize-color-item-border; + .border-radius(@baseBorderRadius); + .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); + &.active { + .box-shadow(~"0 1px 2px rgba(0,0,0,.05)"); + .gradientBar(@selectize-color-item-active, @selectize-color-item-active-border, @selectize-color-item-active-text, none); + *background-color: @selectize-color-item-active; + border: @selectize-width-item-border solid @dropdownLinkBackgroundHover; + } + } + } +} \ No newline at end of file diff --git a/src/less/selectize.bootstrap3.less b/src/less/selectize.bootstrap3.less new file mode 100644 index 000000000..64ac8c9fd --- /dev/null +++ b/src/less/selectize.bootstrap3.less @@ -0,0 +1,136 @@ +/** + * selectize.bootstrap3.css (v@@version) - Bootstrap 3 Theme + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +@import "selectize"; + +@selectize-font-family: @font-family-base; +@selectize-font-size: @font-size-base; +@selectize-line-height: @line-height-computed; + +@selectize-color-text: @text-color; +@selectize-color-highlight: rgba(255,237,40,0.4); +@selectize-color-input: @input-bg; +@selectize-color-input-full: @input-bg; +@selectize-color-disabled: @input-bg; +@selectize-color-item: #efefef; +@selectize-color-item-border: rgba(0,0,0,0); +@selectize-color-item-active: @component-active-bg; +@selectize-color-item-active-text: #fff; +@selectize-color-item-active-border: rgba(0,0,0,0); +@selectize-color-optgroup: @dropdown-bg; +@selectize-color-optgroup-text: @dropdown-header-color; +@selectize-color-optgroup-border: @dropdown-divider-bg; +@selectize-color-dropdown: @dropdown-bg; +@selectize-color-dropdown-border-top: mix(@input-border, @input-bg, 0.8); +@selectize-color-dropdown-item-active: @dropdown-link-hover-bg; +@selectize-color-dropdown-item-active-text: @dropdown-link-hover-color; +@selectize-color-dropdown-item-create-active-text: @dropdown-link-hover-color; +@selectize-opacity-disabled: 0.5; +@selectize-shadow-input: none; +@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); +@selectize-border: 1px solid @input-border; +@selectize-border-radius: @input-border-radius; + +@selectize-width-item-border: 0; +@selectize-padding-x: @padding-base-horizontal; +@selectize-padding-y: @padding-base-vertical; +@selectize-padding-dropdown-item-x: @padding-base-horizontal; +@selectize-padding-dropdown-item-y: 3px; +@selectize-padding-item-x: 3px; +@selectize-padding-item-y: 1px; +@selectize-margin-item-x: 3px; +@selectize-margin-item-y: 3px; +@selectize-caret-margin: 0; + +@selectize-arrow-size: 5px; +@selectize-arrow-color: @selectize-color-text; +@selectize-arrow-offset: @selectize-padding-x + 5px; + +.selectize-dropdown, .selectize-dropdown.form-control { + height: auto; + padding: 0; + margin: 2px 0 0 0; + z-index: @zindex-dropdown; + background: @selectize-color-dropdown; + border: 1px solid @dropdown-fallback-border; + border: 1px solid @dropdown-border; + .selectize-border-radius(@border-radius-base); + .selectize-box-shadow(0 6px 12px rgba(0,0,0,.175)); +} + +.selectize-dropdown { + .optgroup-header { + font-size: @font-size-small; + line-height: @line-height-base; + } + .optgroup:first-child:before { + display: none; + } + .optgroup:before { + content: ' '; + display: block; + .nav-divider(); + margin-left: @selectize-padding-dropdown-item-x * -1; + margin-right: @selectize-padding-dropdown-item-x * -1; + } +} + +.selectize-dropdown-content { + padding: 5px 0; +} + +.selectize-dropdown-header { + padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; +} + +.selectize-input { + min-height: @input-height-base; + + &.dropdown-active { + .selectize-border-radius(@selectize-border-radius); + } + &.dropdown-active::before { + display: none; + } + &.focus { + @color: @input-border-focus; + @color-rgba: rgba(red(@color), green(@color), blue(@color), .6); + border-color: @color; + outline: 0; + .selectize-box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); + } +} + +.selectize-control { + &.multi { + .selectize-input.has-items { + padding-left: @selectize-padding-x - @selectize-padding-item-x; + padding-right: @selectize-padding-x - @selectize-padding-item-x; + } + .selectize-input > div { + .selectize-border-radius(@selectize-border-radius - 1px); + } + } +} + +.form-control.selectize-control { + padding: 0; + height: auto; + border: none; + background: none; + .selectize-box-shadow(none); + .selectize-border-radius(0); +} \ No newline at end of file diff --git a/src/less/selectize.default.less b/src/less/selectize.default.less new file mode 100644 index 000000000..18bc00dca --- /dev/null +++ b/src/less/selectize.default.less @@ -0,0 +1,84 @@ +/** + * selectize.default.css (v@@version) - Default Theme + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +@import "selectize"; + +@selectize-color-item: #1da7ee; +@selectize-color-item-text: #fff; +@selectize-color-item-active-text: #fff; +@selectize-color-item-border: #0073bb; +@selectize-color-item-active: #92c836; +@selectize-color-item-active-border: #00578d; +@selectize-width-item-border: 1px; +@selectize-caret-margin: 0 1px; + +.selectize-control { + &.multi { + .selectize-input { + &.has-items { + @padding-x: @selectize-padding-x - 3px; + padding-left: @padding-x; + padding-right: @padding-x; + } + &.disabled [data-value] { + color: #999; + text-shadow: none; + background: none; + .selectize-box-shadow(none); + + &, .remove { + border-color: #e6e6e6; + } + .remove { + background: none; + } + } + [data-value] { + text-shadow: 0 1px 0 rgba(0,51,83,0.3); + .selectize-border-radius(3px); + .selectize-vertical-gradient(#1da7ee, #178ee9); + .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)"); + &.active { + .selectize-vertical-gradient(#008fd8, #0075cf); + } + } + } + } + &.single { + .selectize-input { + .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8)"); + .selectize-vertical-gradient(#fefefe, #f2f2f2); + } + } +} + +.selectize-control.single .selectize-input, .selectize-dropdown.single { + border-color: #b8b8b8; +} + +.selectize-dropdown { + .optgroup-header { + padding-top: @selectize-padding-dropdown-item-y + 2px; + font-weight: bold; + font-size: 0.85em; + } + .optgroup { + border-top: 1px solid @selectize-color-dropdown-border-top; + &:first-child { + border-top: 0 none; + } + } +} \ No newline at end of file diff --git a/src/less/selectize.legacy.less b/src/less/selectize.legacy.less new file mode 100644 index 000000000..c6cfa6e74 --- /dev/null +++ b/src/less/selectize.legacy.less @@ -0,0 +1,75 @@ +/** + * selectize.legacy.css (v@@version) - Default Theme + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +@import "selectize"; + +@selectize-font-size: 13px; +@selectize-line-height: 20px; + +@selectize-color-input-full: #f2f2f2; +@selectize-color-item: #b8e76f; +@selectize-color-item-text: #3d5d18; +@selectize-color-item-border: #74b21e; +@selectize-color-item-active: #92c836; +@selectize-color-item-active-border: #6f9839; +@selectize-color-highlight: rgba(255,237,40,0.4); +@selectize-color-dropdown-item-active: #fffceb; +@selectize-color-dropdown-item-active-text: @selectize-color-text; +@selectize-color-optgroup: #f8f8f8; +@selectize-color-optgroup-text: @selectize-color-text; +@selectize-width-item-border: 1px; + +@selectize-padding-x: 10px; +@selectize-padding-y: 10px; +@selectize-padding-item-x: 5px; +@selectize-padding-item-y: 1px; +@selectize-padding-dropdown-item-x: 10px; +@selectize-padding-dropdown-item-y: 7px; +@selectize-margin-item-x: 4px; +@selectize-margin-item-y: 4px; + +.selectize-control { + &.multi { + .selectize-input [data-value] { + text-shadow: 0 1px 0 rgba(255,255,255,0.1); + .selectize-border-radius(3px); + .selectize-vertical-gradient(#b8e76f, #a9e25c); + .selectize-box-shadow(0 1px 1px rgba(0,0,0,0.1)); + &.active { + .selectize-vertical-gradient(#92c836, #7abc2c); + } + } + } + &.single { + .selectize-input { + .selectize-box-shadow(~"inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1)"); + .selectize-vertical-gradient(#f5f5f5, #efefef); + } + } +} + +.selectize-control.single .selectize-input, .selectize-dropdown.single { + border-color: #b8b8b8; +} + +.selectize-dropdown { + .optgroup-header { + font-weight: bold; + font-size: 0.8em; + border-bottom: 1px solid @selectize-color-dropdown-border-top; + border-top: 1px solid @selectize-color-dropdown-border-top; + } +} \ No newline at end of file diff --git a/src/less/selectize.less b/src/less/selectize.less new file mode 100644 index 000000000..fe70f9663 --- /dev/null +++ b/src/less/selectize.less @@ -0,0 +1,288 @@ +// base styles + +@selectize-font-family: inherit; +@selectize-font-smoothing: inherit; +@selectize-font-size: 13px; +@selectize-line-height: 18px; + +@selectize-color-text: #303030; +@selectize-color-border: #d0d0d0; +@selectize-color-highlight: rgba(125,168,208,0.2); +@selectize-color-input: #fff; +@selectize-color-input-full: @selectize-color-input; +@selectize-color-disabled: #fafafa; +@selectize-color-item: #f2f2f2; +@selectize-color-item-text: @selectize-color-text; +@selectize-color-item-border: #d0d0d0; +@selectize-color-item-active: #e8e8e8; +@selectize-color-item-active-text: @selectize-color-text; +@selectize-color-item-active-border: #cacaca; +@selectize-color-dropdown: #fff; +@selectize-color-dropdown-border: @selectize-color-border; +@selectize-color-dropdown-border-top: #f0f0f0; +@selectize-color-dropdown-item-active: #f5fafd; +@selectize-color-dropdown-item-active-text: #495c68; +@selectize-color-dropdown-item-create-text: rgba(red(@selectize-color-text), green(@selectize-color-text), blue(@selectize-color-text), 0.5); +@selectize-color-dropdown-item-create-active-text: @selectize-color-dropdown-item-active-text; +@selectize-color-optgroup: @selectize-color-dropdown; +@selectize-color-optgroup-text: @selectize-color-text; +@selectize-lighten-disabled-item: 30%; +@selectize-lighten-disabled-item-text: 30%; +@selectize-lighten-disabled-item-border: 30%; +@selectize-opacity-disabled: 0.5; + +@selectize-shadow-input: inset 0 1px 1px rgba(0,0,0,0.1); +@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); +@selectize-border: 1px solid @selectize-color-border; +@selectize-border-radius: 3px; + +@selectize-width-item-border: 0; +@selectize-max-height-dropdown: 200px; + +@selectize-padding-x: 8px; +@selectize-padding-y: 8px; +@selectize-padding-item-x: 6px; +@selectize-padding-item-y: 2px; +@selectize-padding-dropdown-item-x: @selectize-padding-x; +@selectize-padding-dropdown-item-y: 5px; +@selectize-margin-item-x: 3px; +@selectize-margin-item-y: 3px; + +@selectize-arrow-size: 5px; +@selectize-arrow-color: #808080; +@selectize-arrow-offset: 15px; + +@selectize-caret-margin: 0 2px 0 0; +@selectize-caret-margin-rtl: 0 4px 0 -2px; + +.selectize-border-radius (@radii) { + -webkit-border-radius: @radii; + -moz-border-radius: @radii; + border-radius: @radii; +} +.selectize-unselectable () { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.selectize-box-shadow (@shadow) { + -webkit-box-shadow: @shadow; + box-shadow: @shadow; +} +.selectize-box-sizing (@type: border-box) { + -webkit-box-sizing: @type; + -moz-box-sizing: @type; + box-sizing: @type; +} +.selectize-vertical-gradient (@color-top, @color-bottom) { + background-color: mix(@color-top, @color-bottom, 60%); + background-image: -moz-linear-gradient(top, @color-top, @color-bottom); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@color-top), to(@color-bottom)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @color-top, @color-bottom); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @color-top, @color-bottom); // Opera 11.10 + background-image: linear-gradient(to bottom, @color-top, @color-bottom); // Standard, IE10 + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@color-top),argb(@color-bottom))); // IE9 and down +} + +.selectize-control { + position: relative; +} + +.selectize-dropdown, .selectize-input, .selectize-input input { + color: @selectize-color-text; + font-family: @selectize-font-family; + font-size: @selectize-font-size; + line-height: @selectize-line-height; + -webkit-font-smoothing: @selectize-font-smoothing; +} + +.selectize-input, .selectize-control.single .selectize-input.input-active { + background: @selectize-color-input; + cursor: text; + display: inline-block; +} + +.selectize-input { + border: @selectize-border; + padding: @selectize-padding-y @selectize-padding-x; + display: inline-block; + width: 100%; + overflow: hidden; + position: relative; + z-index: 1; + .selectize-box-sizing(border-box); + .selectize-box-shadow(@selectize-shadow-input); + .selectize-border-radius(@selectize-border-radius); + + .selectize-control.multi &.has-items { + @padding-x: @selectize-padding-x; + @padding-top: @selectize-padding-y - @selectize-padding-item-y - @selectize-width-item-border; + @padding-bottom: @selectize-padding-y - @selectize-padding-item-y - @selectize-margin-item-y - @selectize-width-item-border; + padding: @padding-top @padding-x @padding-bottom; + } + + &.full { + background-color: @selectize-color-input-full; + } + &.disabled, &.disabled * { + cursor: default !important; + } + &.focus { + .selectize-box-shadow(@selectize-shadow-input-focus); + } + &.dropdown-active { + .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); + } + + > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; + } + .selectize-control.multi & > div { + cursor: pointer; + margin: 0 @selectize-margin-item-x @selectize-margin-item-y 0; + padding: @selectize-padding-item-y @selectize-padding-item-x; + background: @selectize-color-item; + color: @selectize-color-item-text; + border: @selectize-width-item-border solid @selectize-color-item-border; + + &.active { + background: @selectize-color-item-active; + color: @selectize-color-item-active-text; + border: @selectize-width-item-border solid @selectize-color-item-active-border; + } + } + .selectize-control.multi &.disabled > div { + &, &.active { + color: lighten(desaturate(@selectize-color-item-text, 100%), @selectize-lighten-disabled-item-text); + background: lighten(desaturate(@selectize-color-item, 100%), @selectize-lighten-disabled-item); + border: @selectize-width-item-border solid lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); + } + } + > input { + &::-ms-clear { + display: none; + } + padding: 0 !important; + min-height: 0 !important; + max-height: none !important; + max-width: 100% !important; + margin: @selectize-caret-margin !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + line-height: inherit !important; + -webkit-user-select: auto !important; + .selectize-box-shadow(none) !important; + &:focus { outline: none !important; } + } +} + +.selectize-input::after { + content: ' '; + display: block; + clear: left; +} + +.selectize-input.dropdown-active::before { + content: ' '; + display: block; + position: absolute; + background: @selectize-color-dropdown-border-top; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} + +.selectize-dropdown { + position: absolute; + z-index: 10; + border: @selectize-border; + background: @selectize-color-dropdown; + margin: -1px 0 0 0; + border-top: 0 none; + .selectize-box-sizing(border-box); + .selectize-box-shadow(0 1px 3px rgba(0,0,0,0.1)); + .selectize-border-radius(0 0 @selectize-border-radius @selectize-border-radius); + + [data-selectable] { + cursor: pointer; + overflow: hidden; + .highlight { + background: @selectize-color-highlight; + .selectize-border-radius(1px); + } + } + [data-selectable], .optgroup-header { + padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; + } + .optgroup:first-child .optgroup-header { + border-top: 0 none; + } + .optgroup-header { + color: @selectize-color-optgroup-text; + background: @selectize-color-optgroup; + cursor: default; + } + .active { + background-color: @selectize-color-dropdown-item-active; + color: @selectize-color-dropdown-item-active-text; + &.create { + color: @selectize-color-dropdown-item-create-active-text; + } + } + .create { + color: @selectize-color-dropdown-item-create-text; + } +} + +.selectize-dropdown-content { + overflow-y: auto; + overflow-x: hidden; + max-height: @selectize-max-height-dropdown; +} + +.selectize-control.single .selectize-input { + &, input { cursor: pointer; } + &.input-active, &.input-active input { cursor: text; } + + &:after { + content: ' '; + display: block; + position: absolute; + top: 50%; + right: @selectize-arrow-offset; + margin-top: round(-@selectize-arrow-size / 2); + width: 0; + height: 0; + border-style: solid; + border-width: @selectize-arrow-size @selectize-arrow-size 0 @selectize-arrow-size; + border-color: @selectize-arrow-color transparent transparent transparent; + } + &.dropdown-active:after { + margin-top: @selectize-arrow-size * -0.8; + border-width: 0 @selectize-arrow-size @selectize-arrow-size @selectize-arrow-size; + border-color: transparent transparent @selectize-arrow-color transparent; + } +} + +.selectize-control.rtl { + &.single .selectize-input:after { + left: @selectize-arrow-offset; + right: auto; + } + .selectize-input > input { + margin: @selectize-caret-margin-rtl !important; + } +} + +.selectize-control .selectize-input.disabled { + opacity: @selectize-opacity-disabled; + background-color: @selectize-color-disabled; +} diff --git a/src/plugins/drag_drop/plugin.js b/src/plugins/drag_drop/plugin.js new file mode 100644 index 000000000..2a1395cf7 --- /dev/null +++ b/src/plugins/drag_drop/plugin.js @@ -0,0 +1,67 @@ +/** + * Plugin: "drag_drop" (selectize.js) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +Selectize.define('drag_drop', function(options) { + if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); + if (this.settings.mode !== 'multi') return; + var self = this; + + self.lock = (function() { + var original = self.lock; + return function() { + var sortable = self.$control.data('sortable'); + if (sortable) sortable.disable(); + return original.apply(self, arguments); + }; + })(); + + self.unlock = (function() { + var original = self.unlock; + return function() { + var sortable = self.$control.data('sortable'); + if (sortable) sortable.enable(); + return original.apply(self, arguments); + }; + })(); + + self.setup = (function() { + var original = self.setup; + return function() { + original.apply(this, arguments); + + var $control = self.$control.sortable({ + items: '[data-value]', + forcePlaceholderSize: true, + disabled: self.isLocked, + start: function(e, ui) { + ui.placeholder.css('width', ui.helper.css('width')); + $control.css({overflow: 'visible'}); + }, + stop: function() { + $control.css({overflow: 'hidden'}); + var active = self.$activeItems ? self.$activeItems.slice() : null; + var values = []; + $control.children('[data-value]').each(function() { + values.push($(this).attr('data-value')); + }); + self.setValue(values); + self.setActiveItem(active); + } + }); + }; + })(); + +}); \ No newline at end of file diff --git a/src/plugins/drag_drop/plugin.less b/src/plugins/drag_drop/plugin.less new file mode 100644 index 000000000..9d42e4ac2 --- /dev/null +++ b/src/plugins/drag_drop/plugin.less @@ -0,0 +1,16 @@ +.selectize-control.plugin-drag_drop { + &.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0,0,0,0.06) !important; + border: 0 none !important; + .selectize-box-shadow(inset 0 0 12px 4px #fff); + } + .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; + } + .ui-sortable-helper { + .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); + } +} \ No newline at end of file diff --git a/src/plugins/dropdown_header/plugin.js b/src/plugins/dropdown_header/plugin.js new file mode 100644 index 000000000..728914b06 --- /dev/null +++ b/src/plugins/dropdown_header/plugin.js @@ -0,0 +1,48 @@ +/** + * Plugin: "dropdown_header" (selectize.js) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +Selectize.define('dropdown_header', function(options) { + var self = this; + + options = $.extend({ + title : 'Untitled', + headerClass : 'selectize-dropdown-header', + titleRowClass : 'selectize-dropdown-header-title', + labelClass : 'selectize-dropdown-header-label', + closeClass : 'selectize-dropdown-header-close', + + html: function(data) { + return ( + '
      ' + ); + } + }, options); + + self.setup = (function() { + var original = self.setup; + return function() { + original.apply(self, arguments); + self.$dropdown_header = $(options.html(options)); + self.$dropdown.prepend(self.$dropdown_header); + }; + })(); + +}); \ No newline at end of file diff --git a/src/plugins/dropdown_header/plugin.less b/src/plugins/dropdown_header/plugin.less new file mode 100644 index 000000000..c3e777e16 --- /dev/null +++ b/src/plugins/dropdown_header/plugin.less @@ -0,0 +1,20 @@ +.selectize-dropdown-header { + position: relative; + padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; + border-bottom: 1px solid @selectize-color-border; + background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); + .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); +} +.selectize-dropdown-header-close { + position: absolute; + right: @selectize-padding-dropdown-item-x; + top: 50%; + color: @selectize-color-text; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: darken(@selectize-color-text, 25%); +} \ No newline at end of file diff --git a/src/plugins/optgroup_columns/plugin.js b/src/plugins/optgroup_columns/plugin.js new file mode 100644 index 000000000..354d0572f --- /dev/null +++ b/src/plugins/optgroup_columns/plugin.js @@ -0,0 +1,92 @@ +/** + * Plugin: "optgroup_columns" (selectize.js) + * Copyright (c) 2013 Simon Hewitt & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Simon Hewitt + */ + +Selectize.define('optgroup_columns', function(options) { + var self = this; + + options = $.extend({ + equalizeWidth : true, + equalizeHeight : true + }, options); + + this.getAdjacentOption = function($option, direction) { + var $options = $option.closest('[data-group]').find('[data-selectable]'); + var index = $options.index($option) + direction; + + return index >= 0 && index < $options.length ? $options.eq(index) : $(); + }; + + this.onKeyDown = (function() { + var original = self.onKeyDown; + return function(e) { + var index, $option, $options, $optgroup; + + if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { + self.ignoreHover = true; + $optgroup = this.$activeOption.closest('[data-group]'); + index = $optgroup.find('[data-selectable]').index(this.$activeOption); + + if(e.keyCode === KEY_LEFT) { + $optgroup = $optgroup.prev('[data-group]'); + } else { + $optgroup = $optgroup.next('[data-group]'); + } + + $options = $optgroup.find('[data-selectable]'); + $option = $options.eq(Math.min($options.length - 1, index)); + if ($option.length) { + this.setActiveOption($option); + } + return; + } + + return original.apply(this, arguments); + }; + })(); + + var equalizeSizes = function() { + var i, n, height_max, width, width_last, width_parent, $optgroups; + + $optgroups = $('[data-group]', self.$dropdown_content); + n = $optgroups.length; + if (!n || !self.$dropdown_content.width()) return; + + if (options.equalizeHeight) { + height_max = 0; + for (i = 0; i < n; i++) { + height_max = Math.max(height_max, $optgroups.eq(i).height()); + } + $optgroups.css({height: height_max}); + } + + if (options.equalizeWidth) { + width_parent = self.$dropdown_content.innerWidth(); + width = Math.round(width_parent / n); + $optgroups.css({width: width}); + if (n > 1) { + width_last = width_parent - width * (n - 1); + $optgroups.eq(n - 1).css({width: width_last}); + } + } + }; + + if (options.equalizeHeight || options.equalizeWidth) { + hook.after(this, 'positionDropdown', equalizeSizes); + hook.after(this, 'refreshOptions', equalizeSizes); + } + + +}); \ No newline at end of file diff --git a/src/plugins/optgroup_columns/plugin.less b/src/plugins/optgroup_columns/plugin.less new file mode 100644 index 000000000..5c72d7a0a --- /dev/null +++ b/src/plugins/optgroup_columns/plugin.less @@ -0,0 +1,17 @@ +.selectize-dropdown.plugin-optgroup_columns { + .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + .selectize-box-sizing(border-box); + } + .optgroup:last-child { + border-right: 0 none; + } + .optgroup:before { + display: none; + } + .optgroup-header { + border-top: 0 none; + } +} \ No newline at end of file diff --git a/src/plugins/remove_button/plugin.js b/src/plugins/remove_button/plugin.js new file mode 100644 index 000000000..513298e80 --- /dev/null +++ b/src/plugins/remove_button/plugin.js @@ -0,0 +1,70 @@ +/** + * Plugin: "remove_button" (selectize.js) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +Selectize.define('remove_button', function(options) { + if (this.settings.mode === 'single') return; + + options = $.extend({ + label : '×', + title : 'Remove', + className : 'remove', + append : true + }, options); + + var self = this; + var html = '' + options.label + ''; + + /** + * Appends an element as a child (with raw HTML). + * + * @param {string} html_container + * @param {string} html_element + * @return {string} + */ + var append = function(html_container, html_element) { + var pos = html_container.search(/(<\/[^>]+>\s*)$/); + return html_container.substring(0, pos) + html_element + html_container.substring(pos); + }; + + this.setup = (function() { + var original = self.setup; + return function() { + // override the item rendering method to add the button to each + if (options.append) { + var render_item = self.settings.render.item; + self.settings.render.item = function(data) { + return append(render_item.apply(this, arguments), html); + }; + } + + original.apply(this, arguments); + + // add event listener + this.$control.on('click', '.' + options.className, function(e) { + e.preventDefault(); + if (self.isLocked) return; + + var $item = $(e.currentTarget).parent(); + self.setActiveItem($item); + if (self.deleteSelection()) { + self.setCaret(self.items.length); + } + }); + + }; + })(); + +}); \ No newline at end of file diff --git a/src/plugins/remove_button/plugin.less b/src/plugins/remove_button/plugin.less new file mode 100644 index 000000000..c478cd49c --- /dev/null +++ b/src/plugins/remove_button/plugin.less @@ -0,0 +1,37 @@ +.selectize-control.plugin-remove_button { + [data-value] { + position: relative; + padding-right: 24px !important; + } + [data-value] .remove { + z-index: 1; /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: @selectize-padding-item-y 0 0 0; + border-left: 1px solid @selectize-color-item-border; + .selectize-border-radius(0 2px 2px 0); + .selectize-box-sizing(border-box); + } + [data-value] .remove:hover { + background: rgba(0,0,0,0.05); + } + [data-value].active .remove { + border-left-color: @selectize-color-item-active-border; + } + .disabled [data-value] .remove:hover { + background: none; + } + .disabled [data-value] .remove { + border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); + } +} \ No newline at end of file diff --git a/src/plugins/restore_on_backspace/plugin.js b/src/plugins/restore_on_backspace/plugin.js new file mode 100644 index 000000000..75aeae5db --- /dev/null +++ b/src/plugins/restore_on_backspace/plugin.js @@ -0,0 +1,43 @@ +/** + * Plugin: "restore_on_backspace" (selectize.js) + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +Selectize.define('restore_on_backspace', function(options) { + var self = this; + + options.text = options.text || function(option) { + return option[this.settings.labelField]; + }; + + this.onKeyDown = (function(e) { + var original = self.onKeyDown; + return function(e) { + var index, option; + if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { + index = this.caretPos - 1; + if (index >= 0 && index < this.items.length) { + option = this.options[this.items[index]]; + if (this.deleteSelection(e)) { + this.setTextboxValue(options.text.apply(this, [option])); + this.refreshOptions(true); + } + e.preventDefault(); + return; + } + } + return original.apply(this, arguments); + }; + })(); +}); \ No newline at end of file diff --git a/src/selectize.jquery.js b/src/selectize.jquery.js new file mode 100644 index 000000000..b04a80dfe --- /dev/null +++ b/src/selectize.jquery.js @@ -0,0 +1,146 @@ +$.fn.selectize = function(settings_user) { + var defaults = $.fn.selectize.defaults; + var settings = $.extend({}, defaults, settings_user); + var attr_data = settings.dataAttr; + var field_label = settings.labelField; + var field_value = settings.valueField; + var field_optgroup = settings.optgroupField; + var field_optgroup_label = settings.optgroupLabelField; + var field_optgroup_value = settings.optgroupValueField; + + /** + * Initializes selectize from a element. + * + * @param {object} $input + * @param {object} settings_element + */ + var init_textbox = function($input, settings_element) { + var i, n, values, option, value = $.trim($input.val() || ''); + if (!value.length) return; + + values = value.split(settings.delimiter); + for (i = 0, n = values.length; i < n; i++) { + option = {}; + option[field_label] = values[i]; + option[field_value] = values[i]; + + settings_element.options[values[i]] = option; + } + + settings_element.items = values; + }; + + /** + * Initializes selectize from a ').appendTo($control).attr('tabindex', tab_index); + $dropdown_parent = $(settings.dropdownParent || $wrapper); + $dropdown = $('
      ').addClass(settings.dropdownClass).addClass(classes).addClass(inputMode).hide().appendTo($dropdown_parent); + $dropdown_content = $('
      ').addClass(settings.dropdownContentClass).appendTo($dropdown); + + $wrapper.css({ + width: self.$input[0].style.width + }); + + if (self.plugins.names.length) { + classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-'); + $wrapper.addClass(classes_plugins); + $dropdown.addClass(classes_plugins); + } + + if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) { + self.$input.attr('multiple', 'multiple'); + } + + if (self.settings.placeholder) { + $control_input.attr('placeholder', settings.placeholder); + } + + if (self.$input.attr('autocorrect')) { + $control_input.attr('autocorrect', self.$input.attr('autocorrect')); + } + + if (self.$input.attr('autocapitalize')) { + $control_input.attr('autocapitalize', self.$input.attr('autocapitalize')); + } + + self.$wrapper = $wrapper; + self.$control = $control; + self.$control_input = $control_input; + self.$dropdown = $dropdown; + self.$dropdown_content = $dropdown_content; + + $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); }); + $dropdown.on('mousedown', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); }); + watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); }); + autoGrow($control_input); + + $control.on({ + mousedown : function() { return self.onMouseDown.apply(self, arguments); }, + click : function() { return self.onClick.apply(self, arguments); } + }); + + $control_input.on({ + mousedown : function(e) { e.stopPropagation(); }, + keydown : function() { return self.onKeyDown.apply(self, arguments); }, + keyup : function() { return self.onKeyUp.apply(self, arguments); }, + keypress : function() { return self.onKeyPress.apply(self, arguments); }, + resize : function() { self.positionDropdown.apply(self, []); }, + blur : function() { return self.onBlur.apply(self, arguments); }, + focus : function() { return self.onFocus.apply(self, arguments); }, + paste : function() { return self.onPaste.apply(self, arguments); } + }); + + $document.on('keydown' + eventNS, function(e) { + self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey']; + self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey']; + self.isShiftDown = e.shiftKey; + }); + + $document.on('keyup' + eventNS, function(e) { + if (e.keyCode === KEY_CTRL) self.isCtrlDown = false; + if (e.keyCode === KEY_SHIFT) self.isShiftDown = false; + if (e.keyCode === KEY_CMD) self.isCmdDown = false; + }); + + $document.on('mousedown' + eventNS, function(e) { + if (self.isFocused) { + // prevent events on the dropdown scrollbar from causing the control to blur + if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) { + return false; + } + // blur on click outside + if (!self.$control.has(e.target).length && e.target !== self.$control[0]) { + self.blur(); + } + } + }); + + $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() { + if (self.isOpen) { + self.positionDropdown.apply(self, arguments); + } + }); + $window.on('mousemove' + eventNS, function() { + self.ignoreHover = false; + }); + + // store original children and tab index so that they can be + // restored when the destroy() method is called. + this.revertSettings = { + $children : self.$input.children().detach(), + tabindex : self.$input.attr('tabindex') + }; + + self.$input.attr('tabindex', -1).hide().after(self.$wrapper); + + if ($.isArray(settings.items)) { + self.setValue(settings.items); + delete settings.items; + } + + // feature detect for the validation API + if (self.$input[0].validity) { + self.$input.on('invalid' + eventNS, function(e) { + e.preventDefault(); + self.isInvalid = true; + self.refreshState(); + }); + } + + self.updateOriginalInput(); + self.refreshItems(); + self.refreshState(); + self.updatePlaceholder(); + self.isSetup = true; + + if (self.$input.is(':disabled')) { + self.disable(); + } + + self.on('change', this.onChange); + self.trigger('initialize'); + + // preload options + if (settings.preload === true) { + self.onSearchChange(''); + } + }, + + /** + * Sets up default rendering functions. + */ + setupTemplates: function() { + var self = this; + var field_label = self.settings.labelField; + var field_optgroup = self.settings.optgroupLabelField; + + var templates = { + 'optgroup': function(data) { + return '
      ' + data.html + '
      '; + }, + 'optgroup_header': function(data, escape) { + return '
      ' + escape(data[field_optgroup]) + '
      '; + }, + 'option': function(data, escape) { + return '
      ' + escape(data[field_label]) + '
      '; + }, + 'item': function(data, escape) { + return '
      ' + escape(data[field_label]) + '
      '; + }, + 'option_create': function(data, escape) { + return '
      Add ' + escape(data.input) + '
      '; + } + }; + + self.settings.render = $.extend({}, templates, self.settings.render); + }, + + /** + * Maps fired events to callbacks provided + * in the settings used when creating the control. + */ + setupCallbacks: function() { + var key, fn, callbacks = { + 'initialize' : 'onInitialize', + 'change' : 'onChange', + 'item_add' : 'onItemAdd', + 'item_remove' : 'onItemRemove', + 'clear' : 'onClear', + 'option_add' : 'onOptionAdd', + 'option_remove' : 'onOptionRemove', + 'option_clear' : 'onOptionClear', + 'dropdown_open' : 'onDropdownOpen', + 'dropdown_close' : 'onDropdownClose', + 'type' : 'onType' + }; + + for (key in callbacks) { + if (callbacks.hasOwnProperty(key)) { + fn = this.settings[callbacks[key]]; + if (fn) this.on(key, fn); + } + } + }, + + /** + * Triggered when the main control element + * has a click event. + * + * @param {object} e + * @return {boolean} + */ + onClick: function(e) { + var self = this; + + // necessary for mobile webkit devices (manual focus triggering + // is ignored unless invoked within a click event) + if (!self.isFocused) { + self.focus(); + e.preventDefault(); + } + }, + + /** + * Triggered when the main control element + * has a mouse down event. + * + * @param {object} e + * @return {boolean} + */ + onMouseDown: function(e) { + var self = this; + var defaultPrevented = e.isDefaultPrevented(); + var $target = $(e.target); + + if (self.isFocused) { + // retain focus by preventing native handling. if the + // event target is the input it should not be modified. + // otherwise, text selection within the input won't work. + if (e.target !== self.$control_input[0]) { + if (self.settings.mode === 'single') { + // toggle dropdown + self.isOpen ? self.close() : self.open(); + } else if (!defaultPrevented) { + self.setActiveItem(null); + } + return false; + } + } else { + // give control focus + if (!defaultPrevented) { + window.setTimeout(function() { + self.focus(); + }, 0); + } + } + }, + + /** + * Triggered when the value of the control has been changed. + * This should propagate the event to the original DOM + * input / select element. + */ + onChange: function() { + this.$input.trigger('change'); + }, + + + /** + * Triggered on paste. + * + * @param {object} e + * @returns {boolean} + */ + onPaste: function(e) { + var self = this; + if (self.isFull() || self.isInputHidden || self.isLocked) { + e.preventDefault(); + } else { + // If a regex or string is included, this will split the pasted input and create Items for each separate value + if (self.settings.splitOn) { + setTimeout($.proxy(function() { + var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn); + splitInput.forEach($.proxy(function(input) { + self.createItem(input); + }, self)); + }, self), 0); + } + } + }, + + /** + * Triggered on keypress. + * + * @param {object} e + * @returns {boolean} + */ + onKeyPress: function(e) { + if (this.isLocked) return e && e.preventDefault(); + var character = String.fromCharCode(e.keyCode || e.which); + if (this.settings.create && character === this.settings.delimiter) { + this.createItem(); + e.preventDefault(); + return false; + } + }, + + /** + * Triggered on keydown. + * + * @param {object} e + * @returns {boolean} + */ + onKeyDown: function(e) { + var isInput = e.target === this.$control_input[0]; + var self = this; + + if (self.isLocked) { + if (e.keyCode !== KEY_TAB) { + e.preventDefault(); + } + return; + } + + switch (e.keyCode) { + case KEY_A: + if (self.isCmdDown) { + self.selectAll(); + return; + } + break; + case KEY_ESC: + self.close(); + return; + case KEY_N: + if (!e.ctrlKey || e.altKey) break; + case KEY_DOWN: + if (!self.isOpen && self.hasOptions) { + self.open(); + } else if (self.$activeOption) { + self.ignoreHover = true; + var $next = self.getAdjacentOption(self.$activeOption, 1); + if ($next.length) self.setActiveOption($next, true, true); + } + e.preventDefault(); + return; + case KEY_P: + if (!e.ctrlKey || e.altKey) break; + case KEY_UP: + if (self.$activeOption) { + self.ignoreHover = true; + var $prev = self.getAdjacentOption(self.$activeOption, -1); + if ($prev.length) self.setActiveOption($prev, true, true); + } + e.preventDefault(); + return; + case KEY_RETURN: + if (self.isOpen && self.$activeOption) { + self.onOptionSelect({currentTarget: self.$activeOption}); + } + e.preventDefault(); + return; + case KEY_LEFT: + self.advanceSelection(-1, e); + return; + case KEY_RIGHT: + self.advanceSelection(1, e); + return; + case KEY_TAB: + if (self.settings.selectOnTab && self.isOpen && self.$activeOption) { + self.onOptionSelect({currentTarget: self.$activeOption}); + } + if (self.settings.create && self.createItem()) { + e.preventDefault(); + } + return; + case KEY_BACKSPACE: + case KEY_DELETE: + self.deleteSelection(e); + return; + } + + if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) { + e.preventDefault(); + return; + } + }, + + /** + * Triggered on keyup. + * + * @param {object} e + * @returns {boolean} + */ + onKeyUp: function(e) { + var self = this; + + if (self.isLocked) return e && e.preventDefault(); + var value = self.$control_input.val() || ''; + if (self.lastValue !== value) { + self.lastValue = value; + self.onSearchChange(value); + self.refreshOptions(); + self.trigger('type', value); + } + }, + + /** + * Invokes the user-provide option provider / loader. + * + * Note: this function is debounced in the Selectize + * constructor (by `settings.loadDelay` milliseconds) + * + * @param {string} value + */ + onSearchChange: function(value) { + var self = this; + var fn = self.settings.load; + if (!fn) return; + if (self.loadedSearches.hasOwnProperty(value)) return; + self.loadedSearches[value] = true; + self.load(function(callback) { + fn.apply(self, [value, callback]); + }); + }, + + /** + * Triggered on focus. + * + * @param {object} e (optional) + * @returns {boolean} + */ + onFocus: function(e) { + var self = this; + + self.isFocused = true; + if (self.isDisabled) { + self.blur(); + e && e.preventDefault(); + return false; + } + + if (self.ignoreFocus) return; + if (self.settings.preload === 'focus') self.onSearchChange(''); + + if (!self.$activeItems.length) { + self.showInput(); + self.setActiveItem(null); + self.refreshOptions(!!self.settings.openOnFocus); + } + + self.refreshState(); + }, + + /** + * Triggered on blur. + * + * @param {object} e + * @returns {boolean} + */ + onBlur: function(e) { + var self = this; + self.isFocused = false; + if (self.ignoreFocus) return; + + if (self.settings.create && self.settings.createOnBlur) { + self.createItem(false); + } + + self.close(); + self.setTextboxValue(''); + self.setActiveItem(null); + self.setActiveOption(null); + self.setCaret(self.items.length); + self.refreshState(); + }, + + /** + * Triggered when the user rolls over + * an option in the autocomplete dropdown menu. + * + * @param {object} e + * @returns {boolean} + */ + onOptionHover: function(e) { + if (this.ignoreHover) return; + this.setActiveOption(e.currentTarget, false); + }, + + /** + * Triggered when the user clicks on an option + * in the autocomplete dropdown menu. + * + * @param {object} e + * @returns {boolean} + */ + onOptionSelect: function(e) { + var value, $target, $option, self = this; + + if (e.preventDefault) { + e.preventDefault(); + e.stopPropagation(); + } + + $target = $(e.currentTarget); + if ($target.hasClass('create')) { + self.createItem(); + } else { + value = $target.attr('data-value'); + if (value) { + self.lastQuery = null; + self.setTextboxValue(''); + self.addItem(value); + if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) { + self.setActiveOption(self.getOption(value)); + } + } + } + }, + + /** + * Triggered when the user clicks on an item + * that has been selected. + * + * @param {object} e + * @returns {boolean} + */ + onItemSelect: function(e) { + var self = this; + + if (self.isLocked) return; + if (self.settings.mode === 'multi') { + e.preventDefault(); + self.setActiveItem(e.currentTarget, e); + } + }, + + /** + * Invokes the provided method that provides + * results to a callback---which are then added + * as options to the control. + * + * @param {function} fn + */ + load: function(fn) { + var self = this; + var $wrapper = self.$wrapper.addClass('loading'); + + self.loading++; + fn.apply(self, [function(results) { + self.loading = Math.max(self.loading - 1, 0); + if (results && results.length) { + self.addOption(results); + self.refreshOptions(self.isFocused && !self.isInputHidden); + } + if (!self.loading) { + $wrapper.removeClass('loading'); + } + self.trigger('load', results); + }]); + }, + + /** + * Sets the input field of the control to the specified value. + * + * @param {string} value + */ + setTextboxValue: function(value) { + var $input = this.$control_input; + var changed = $input.val() !== value; + if (changed) { + $input.val(value).triggerHandler('update'); + this.lastValue = value; + } + }, + + /** + * Returns the value of the control. If multiple items + * can be selected (e.g. or + * element to reflect the current state. + */ + updateOriginalInput: function() { + var i, n, options, self = this; + + if (self.$input[0].tagName.toLowerCase() === 'select') { + options = []; + for (i = 0, n = self.items.length; i < n; i++) { + options.push(''); + } + if (!options.length && !this.$input.attr('multiple')) { + options.push(''); + } + self.$input.html(options.join('')); + } else { + self.$input.val(self.getValue()); + } + + if (self.isSetup) { + self.trigger('change', self.$input.val()); + } + }, + + /** + * Shows/hide the input placeholder depending + * on if there items in the list already. + */ + updatePlaceholder: function() { + if (!this.settings.placeholder) return; + var $input = this.$control_input; + + if (this.items.length) { + $input.removeAttr('placeholder'); + } else { + $input.attr('placeholder', this.settings.placeholder); + } + $input.triggerHandler('update', {force: true}); + }, + + /** + * Shows the autocomplete dropdown containing + * the available options. + */ + open: function() { + var self = this; + + if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return; + self.focus(); + self.isOpen = true; + self.refreshState(); + self.$dropdown.css({visibility: 'hidden', display: 'block'}); + self.positionDropdown(); + self.$dropdown.css({visibility: 'visible'}); + self.trigger('dropdown_open', self.$dropdown); + }, + + /** + * Closes the autocomplete dropdown menu. + */ + close: function() { + var self = this; + var trigger = self.isOpen; + + if (self.settings.mode === 'single' && self.items.length) { + self.hideInput(); + } + + self.isOpen = false; + self.$dropdown.hide(); + self.setActiveOption(null); + self.refreshState(); + + if (trigger) self.trigger('dropdown_close', self.$dropdown); + }, + + /** + * Calculates and applies the appropriate + * position of the dropdown. + */ + positionDropdown: function() { + var $control = this.$control; + var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); + offset.top += $control.outerHeight(true); + + this.$dropdown.css({ + width : $control.outerWidth(), + top : offset.top, + left : offset.left + }); + }, + + /** + * Resets / clears all selected items + * from the control. + */ + clear: function() { + var self = this; + + if (!self.items.length) return; + self.$control.children(':not(input)').remove(); + self.items = []; + self.setCaret(0); + self.updatePlaceholder(); + self.updateOriginalInput(); + self.refreshState(); + self.showInput(); + self.trigger('clear'); + }, + + /** + * A helper method for inserting an element + * at the current caret position. + * + * @param {object} $el + */ + insertAtCaret: function($el) { + var caret = Math.min(this.caretPos, this.items.length); + if (caret === 0) { + this.$control.prepend($el); + } else { + $(this.$control[0].childNodes[caret]).before($el); + } + this.setCaret(caret + 1); + }, + + /** + * Removes the current selected item(s). + * + * @param {object} e (optional) + * @returns {boolean} + */ + deleteSelection: function(e) { + var i, n, direction, selection, values, caret, option_select, $option_select, $tail; + var self = this; + + direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1; + selection = getSelection(self.$control_input[0]); + + if (self.$activeOption && !self.settings.hideSelected) { + option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value'); + } + + // determine items that will be removed + values = []; + + if (self.$activeItems.length) { + $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first')); + caret = self.$control.children(':not(input)').index($tail); + if (direction > 0) { caret++; } + + for (i = 0, n = self.$activeItems.length; i < n; i++) { + values.push($(self.$activeItems[i]).attr('data-value')); + } + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) { + if (direction < 0 && selection.start === 0 && selection.length === 0) { + values.push(self.items[self.caretPos - 1]); + } else if (direction > 0 && selection.start === self.$control_input.val().length) { + values.push(self.items[self.caretPos]); + } + } + + // allow the callback to abort + if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) { + return false; + } + + // perform removal + if (typeof caret !== 'undefined') { + self.setCaret(caret); + } + while (values.length) { + self.removeItem(values.pop()); + } + + self.showInput(); + self.positionDropdown(); + self.refreshOptions(true); + + // select previous option + if (option_select) { + $option_select = self.getOption(option_select); + if ($option_select.length) { + self.setActiveOption($option_select); + } + } + + return true; + }, + + /** + * Selects the previous / next item (depending + * on the `direction` argument). + * + * > 0 - right + * < 0 - left + * + * @param {int} direction + * @param {object} e (optional) + */ + advanceSelection: function(direction, e) { + var tail, selection, idx, valueLength, cursorAtEdge, $tail; + var self = this; + + if (direction === 0) return; + if (self.rtl) direction *= -1; + + tail = direction > 0 ? 'last' : 'first'; + selection = getSelection(self.$control_input[0]); + + if (self.isFocused && !self.isInputHidden) { + valueLength = self.$control_input.val().length; + cursorAtEdge = direction < 0 + ? selection.start === 0 && selection.length === 0 + : selection.start === valueLength; + + if (cursorAtEdge && !valueLength) { + self.advanceCaret(direction, e); + } + } else { + $tail = self.$control.children('.active:' + tail); + if ($tail.length) { + idx = self.$control.children(':not(input)').index($tail); + self.setActiveItem(null); + self.setCaret(direction > 0 ? idx + 1 : idx); + } + } + }, + + /** + * Moves the caret left / right. + * + * @param {int} direction + * @param {object} e (optional) + */ + advanceCaret: function(direction, e) { + var self = this, fn, $adj; + + if (direction === 0) return; + + fn = direction > 0 ? 'next' : 'prev'; + if (self.isShiftDown) { + $adj = self.$control_input[fn](); + if ($adj.length) { + self.hideInput(); + self.setActiveItem($adj); + e && e.preventDefault(); + } + } else { + self.setCaret(self.caretPos + direction); + } + }, + + /** + * Moves the caret to the specified index. + * + * @param {int} i + */ + setCaret: function(i) { + var self = this; + + if (self.settings.mode === 'single') { + i = self.items.length; + } else { + i = Math.max(0, Math.min(self.items.length, i)); + } + + // the input must be moved by leaving it in place and moving the + // siblings, due to the fact that focus cannot be restored once lost + // on mobile webkit devices + var j, n, fn, $children, $child; + $children = self.$control.children(':not(input)'); + for (j = 0, n = $children.length; j < n; j++) { + $child = $($children[j]).detach(); + if (j < i) { + self.$control_input.before($child); + } else { + self.$control.append($child); + } + } + + self.caretPos = i; + }, + + /** + * Disables user input on the control. Used while + * items are being asynchronously created. + */ + lock: function() { + this.close(); + this.isLocked = true; + this.refreshState(); + }, + + /** + * Re-enables user input on the control. + */ + unlock: function() { + this.isLocked = false; + this.refreshState(); + }, + + /** + * Disables user input on the control completely. + * While disabled, it cannot receive focus. + */ + disable: function() { + var self = this; + self.$input.prop('disabled', true); + self.isDisabled = true; + self.lock(); + }, + + /** + * Enables the control so that it can respond + * to focus and user input. + */ + enable: function() { + var self = this; + self.$input.prop('disabled', false); + self.isDisabled = false; + self.unlock(); + }, + + /** + * Completely destroys the control and + * unbinds all event listeners so that it can + * be garbage collected. + */ + destroy: function() { + var self = this; + var eventNS = self.eventNS; + var revertSettings = self.revertSettings; + + self.trigger('destroy'); + self.off(); + self.$wrapper.remove(); + self.$dropdown.remove(); + + self.$input + .html('') + .append(revertSettings.$children) + .removeAttr('tabindex') + .attr({tabindex: revertSettings.tabindex}) + .show(); + + $(window).off(eventNS); + $(document).off(eventNS); + $(document.body).off(eventNS); + + delete self.$input[0].selectize; + }, + + /** + * A helper method for rendering "item" and + * "option" templates, given the data. + * + * @param {string} templateName + * @param {object} data + * @returns {string} + */ + render: function(templateName, data) { + var value, id, label; + var html = ''; + var cache = false; + var self = this; + var regex_tag = /^[\t ]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; + + if (templateName === 'option' || templateName === 'item') { + value = hash_key(data[self.settings.valueField]); + cache = !!value; + } + + // pull markup from cache if it exists + if (cache) { + if (!isset(self.renderCache[templateName])) { + self.renderCache[templateName] = {}; + } + if (self.renderCache[templateName].hasOwnProperty(value)) { + return self.renderCache[templateName][value]; + } + } + + // render markup + html = self.settings.render[templateName].apply(this, [data, escape_html]); + + // add mandatory attributes + if (templateName === 'option' || templateName === 'option_create') { + html = html.replace(regex_tag, '<$1 data-selectable'); + } + if (templateName === 'optgroup') { + id = data[self.settings.optgroupValueField] || ''; + html = html.replace(regex_tag, '<$1 data-group="' + escape_replace(escape_html(id)) + '"'); + } + if (templateName === 'option' || templateName === 'item') { + html = html.replace(regex_tag, '<$1 data-value="' + escape_replace(escape_html(value || '')) + '"'); + } + + // update cache + if (cache) { + self.renderCache[templateName][value] = html; + } + + return html; + } + +}); diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 000000000..53a1192b5 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,344 @@ +/** + * Determines if the provided value has been defined. + * + * @param {mixed} object + * @returns {boolean} + */ +var isset = function(object) { + return typeof object !== 'undefined'; +}; + +/** + * Converts a scalar to its best string representation + * for hash keys and HTML attribute values. + * + * Transformations: + * 'str' -> 'str' + * null -> '' + * undefined -> '' + * true -> '1' + * false -> '0' + * 0 -> '0' + * 1 -> '1' + * + * @param {string} value + * @returns {string} + */ +var hash_key = function(value) { + if (typeof value === 'undefined' || value === null) return ''; + if (typeof value === 'boolean') return value ? '1' : '0'; + return value + ''; +}; + +/** + * Escapes a string for use within HTML. + * + * @param {string} str + * @returns {string} + */ +var escape_html = function(str) { + return (str + '') + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Escapes "$" characters in replacement strings. + * + * @param {string} str + * @returns {string} + */ +var escape_replace = function(str) { + return (str + '').replace(/\$/g, '$$$$'); +}; + +var hook = {}; + +/** + * Wraps `method` on `self` so that `fn` + * is invoked before the original method. + * + * @param {object} self + * @param {string} method + * @param {function} fn + */ +hook.before = function(self, method, fn) { + var original = self[method]; + self[method] = function() { + fn.apply(self, arguments); + return original.apply(self, arguments); + }; +}; + +/** + * Wraps `method` on `self` so that `fn` + * is invoked after the original method. + * + * @param {object} self + * @param {string} method + * @param {function} fn + */ +hook.after = function(self, method, fn) { + var original = self[method]; + self[method] = function() { + var result = original.apply(self, arguments); + fn.apply(self, arguments); + return result; + }; +}; + +/** + * Builds a hash table out of an array of + * objects, using the specified `key` within + * each object. + * + * @param {string} key + * @param {mixed} objects + */ +var build_hash_table = function(key, objects) { + if (!$.isArray(objects)) return objects; + var i, n, table = {}; + for (i = 0, n = objects.length; i < n; i++) { + if (objects[i].hasOwnProperty(key)) { + table[objects[i][key]] = objects[i]; + } + } + return table; +}; + +/** + * Wraps `fn` so that it can only be invoked once. + * + * @param {function} fn + * @returns {function} + */ +var once = function(fn) { + var called = false; + return function() { + if (called) return; + called = true; + fn.apply(this, arguments); + }; +}; + +/** + * Wraps `fn` so that it can only be called once + * every `delay` milliseconds (invoked on the falling edge). + * + * @param {function} fn + * @param {int} delay + * @returns {function} + */ +var debounce = function(fn, delay) { + var timeout; + return function() { + var self = this; + var args = arguments; + window.clearTimeout(timeout); + timeout = window.setTimeout(function() { + fn.apply(self, args); + }, delay); + }; +}; + +/** + * Debounce all fired events types listed in `types` + * while executing the provided `fn`. + * + * @param {object} self + * @param {array} types + * @param {function} fn + */ +var debounce_events = function(self, types, fn) { + var type; + var trigger = self.trigger; + var event_args = {}; + + // override trigger method + self.trigger = function() { + var type = arguments[0]; + if (types.indexOf(type) !== -1) { + event_args[type] = arguments; + } else { + return trigger.apply(self, arguments); + } + }; + + // invoke provided function + fn.apply(self, []); + self.trigger = trigger; + + // trigger queued events + for (type in event_args) { + if (event_args.hasOwnProperty(type)) { + trigger.apply(self, event_args[type]); + } + } +}; + +/** + * A workaround for http://bugs.jquery.com/ticket/6696 + * + * @param {object} $parent - Parent element to listen on. + * @param {string} event - Event name. + * @param {string} selector - Descendant selector to filter by. + * @param {function} fn - Event handler. + */ +var watchChildEvent = function($parent, event, selector, fn) { + $parent.on(event, selector, function(e) { + var child = e.target; + while (child && child.parentNode !== $parent[0]) { + child = child.parentNode; + } + e.currentTarget = child; + return fn.apply(this, [e]); + }); +}; + +/** + * Determines the current selection within a text input control. + * Returns an object containing: + * - start + * - length + * + * @param {object} input + * @returns {object} + */ +var getSelection = function(input) { + var result = {}; + if ('selectionStart' in input) { + result.start = input.selectionStart; + result.length = input.selectionEnd - result.start; + } else if (document.selection) { + input.focus(); + var sel = document.selection.createRange(); + var selLen = document.selection.createRange().text.length; + sel.moveStart('character', -input.value.length); + result.start = sel.text.length - selLen; + result.length = selLen; + } + return result; +}; + +/** + * Copies CSS properties from one element to another. + * + * @param {object} $from + * @param {object} $to + * @param {array} properties + */ +var transferStyles = function($from, $to, properties) { + var i, n, styles = {}; + if (properties) { + for (i = 0, n = properties.length; i < n; i++) { + styles[properties[i]] = $from.css(properties[i]); + } + } else { + styles = $from.css(); + } + $to.css(styles); +}; + +/** + * Measures the width of a string within a + * parent element (in pixels). + * + * @param {string} str + * @param {object} $parent + * @returns {int} + */ +var measureString = function(str, $parent) { + if (!str) { + return 0; + } + + var $test = $('').css({ + position: 'absolute', + top: -99999, + left: -99999, + width: 'auto', + padding: 0, + whiteSpace: 'pre' + }).text(str).appendTo('body'); + + transferStyles($parent, $test, [ + 'letterSpacing', + 'fontSize', + 'fontFamily', + 'fontWeight', + 'textTransform' + ]); + + var width = $test.width(); + $test.remove(); + + return width; +}; + +/** + * Sets up an input to grow horizontally as the user + * types. If the value is changed manually, you can + * trigger the "update" handler to resize: + * + * $input.trigger('update'); + * + * @param {object} $input + */ +var autoGrow = function($input) { + var currentWidth = null; + + var update = function(e, options) { + var value, keyCode, printable, placeholder, width; + var shift, character, selection; + e = e || window.event || {}; + options = options || {}; + + if (e.metaKey || e.altKey) return; + if (!options.force && $input.data('grow') === false) return; + + value = $input.val(); + if (e.type && e.type.toLowerCase() === 'keydown') { + keyCode = e.keyCode; + printable = ( + (keyCode >= 97 && keyCode <= 122) || // a-z + (keyCode >= 65 && keyCode <= 90) || // A-Z + (keyCode >= 48 && keyCode <= 57) || // 0-9 + keyCode === 32 // space + ); + + if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) { + selection = getSelection($input[0]); + if (selection.length) { + value = value.substring(0, selection.start) + value.substring(selection.start + selection.length); + } else if (keyCode === KEY_BACKSPACE && selection.start) { + value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1); + } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') { + value = value.substring(0, selection.start) + value.substring(selection.start + 1); + } + } else if (printable) { + shift = e.shiftKey; + character = String.fromCharCode(e.keyCode); + if (shift) character = character.toUpperCase(); + else character = character.toLowerCase(); + value += character; + } + } + + placeholder = $input.attr('placeholder'); + if (!value && placeholder) { + value = placeholder; + } + + width = measureString(value, $input) + 4; + if (width !== currentWidth) { + currentWidth = width; + $input.width(width); + $input.triggerHandler('resize'); + } + }; + + $input.on('keydown keyup update blur', update); + update(); +}; \ No newline at end of file diff --git a/test/api.js b/test/api.js new file mode 100644 index 000000000..53abb27ba --- /dev/null +++ b/test/api.js @@ -0,0 +1,572 @@ +(function() { + + describe('API', function() { + + describe('disable()', function() { + var test; + + before(function() { + test = setup_test('', {}); + test.selectize.enable(); + }); + it('should remove "disabled" class', function() { + expect(test.selectize.$control.hasClass('disabled')).to.be.equal(false); + }); + it('should set isDisabled property to false', function() { + expect(test.selectize.isDisabled).to.be.equal(false); + }); + it('should remove "disabled" attribute on original input', function() { + expect(test.selectize.$input.is(':disabled')).to.be.equal(false); + }); + }); + + describe('focus()', function() { + var test; + + before(function(done) { + test = setup_test('', {}); + test.selectize.focus(); + window.setTimeout(function() { + test.selectize.blur(); + window.setTimeout(done, 5); + }, 5); + }); + it('should set isFocused property to false', function() { + expect(test.selectize.isFocused).to.be.equal(false); + }); + it('should remove focus from the control', function() { + expect(has_focus(test.selectize.$control_input[0])).to.be.equal(false); + }); + }); + + describe('createItem()', function() { + it('should fail if non-object returned by "create" callback', function() { + var test = setup_test('', { + valueField: 'value', + labelField: 'value', + create: function(input) { + return 'hello'; + } + }); + + test.selectize.$control_input.val('test'); + test.selectize.createItem(); + expect(test.selectize.items.length).to.be.equal(0); + }); + it('should add option upon completion (synchronous)', function() { + var test = setup_test('', { + valueField: 'value', + labelField: 'value', + create: function(input, callback) { + window.setTimeout(function() { + callback({value: input}); + expect(test.selectize.options).to.have.property('test'); + done(); + }, 0); + } + }); + + test.selectize.$control_input.val('test'); + test.selectize.createItem(); + }); + }); + + describe('addOptionGroup()', function() { + var test; + + before(function() { + test = setup_test('', {valueField: 'value', labelField: 'value'}); + }); + it('should allow string values', function() { + test.selectize.addOption({value: 'stringtest'}); + expect(test.selectize.options).to.have.property('stringtest'); + }); + it('should not allow null / undefined values', function() { + test.selectize.addOption({value: undefined}); + test.selectize.addOption({value: null}); + expect(test.selectize.options).to.not.have.property('undefined'); + expect(test.selectize.options).to.not.have.property('null'); + expect(test.selectize.options).to.not.have.property(''); + }); + it('should allow integer values', function() { + test.selectize.addOption({value: 0}); + test.selectize.addOption({value: 1}); + expect(test.selectize.options).to.have.property('0'); + expect(test.selectize.options).to.have.property('1'); + }); + it('should allow arrays of options', function() { + test.selectize.addOption([{value: 'a'}, {value: 'b'}]); + expect(test.selectize.options).to.have.property('a'); + expect(test.selectize.options).to.have.property('b'); + }); + it('should not override existing options', function() { + test.selectize.addOption([{value: 'a'}, {value: 'b'}]); + test.selectize.addOption({value: 'a', test: 'hello'}); + expect(test.selectize.options.a).to.not.have.property('test'); + }); + }); + + describe('addItem()', function() { + var test; + + before(function() { + test = setup_test('', { + valueField: 'value', + labelField: 'value', + options: [ + {value: 0}, + {value: 1}, + {value: 'a'}, + {value: 'b'}, + {value: 'c'}, + {value: 'd'}, + {value: 'e'}, + {value: 'f'}, + {value: 'null'}, + {value: 'undefined'}, + {value: '\''}, + {value: '"'}, + {value: '\\\''}, + {value: '\\"'}, + ], + items: ['e','f'] + }); + }); + it('should update option data', function() { + test.selectize.updateOption('a', {value: 'a', test: 'test'}); + expect(test.selectize.options).to.have.property('a'); + expect(test.selectize.options['a'].test).to.equal('test'); + }); + it('should update indexes', function() { + test.selectize.updateOption('e', {value: 'e_updated'}); + expect(test.selectize.options).to.not.have.property('e'); + expect(test.selectize.options).to.have.property('e_updated'); + expect(test.selectize.items.indexOf('e')).to.be.equal(-1); + expect(test.selectize.items.indexOf('e_updated')).to.be.equal(0); + }); + it('should allow integer values', function() { + test.selectize.updateOption(0, {value: '0_updated'}); + test.selectize.updateOption(1, {value: '1_updated'}); + expect(test.selectize.options).to.not.have.property('0'); + expect(test.selectize.options).to.not.have.property('1'); + expect(test.selectize.options).to.have.property('0_updated'); + expect(test.selectize.options).to.have.property('1_updated'); + }); + it('should throw error if value not set in data', function() { + expect(function() { + test.selectize.updateOption('c', {value: undefined, test: 'test'}); + test.selectize.updateOption('d', {value: null, test: 'test'}); + }).to.throw(Error); + }); + it('should ignore undefined / null value references', function() { + test.selectize.updateOption(undefined, {value: 'undefined', test: 'test'}); + test.selectize.updateOption(null, {value: 'null', test: 'test'}); + expect(test.selectize.options['undefined']).to.not.have.property('test'); + expect(test.selectize.options['null']).to.not.have.property('test'); + }); + it('should update DOM', function() { + test.selectize.updateOption('f', {value: 'f_updated'}); + expect(test.selectize.$control.find('[data-value=f]').length).to.be.equal(0); + expect(test.selectize.$control.find('[data-value=f_updated]').length).to.be.equal(1); + }); + }); + + describe('getOption()', function() { + var test; + + before(function() { + test = setup_test('', { + valueField: 'value', + labelField: 'value', + options: [ + {value: 0}, + {value: 1}, + {value: 'a'}, + {value: 'b'}, + {value: '\''}, + {value: '"'}, + {value: '\\\''}, + {value: '\\"'} + ], + items: ['0','1','a','b','\'','"','\\\'','\\"'] + }); + }); + it('should allow string values', function() { + expect(test.selectize.getItem('a')).to.be.ok; + expect(test.selectize.getItem('a').length).to.be.equal(1); + expect(test.selectize.getItem('b')).to.be.ok; + expect(test.selectize.getItem('b').length).to.be.equal(1); + }); + it('should allow integer values', function() { + expect(test.selectize.getItem(0)).to.be.ok; + expect(test.selectize.getItem(0).length).to.be.equal(1); + expect(test.selectize.getItem(1)).to.be.ok; + expect(test.selectize.getItem(1).length).to.be.equal(1); + }); + it('should allow values with quotation marks', function() { + expect(test.selectize.getItem('\'')).to.be.ok; + expect(test.selectize.getItem('\'').length).to.be.equal(1); + expect(test.selectize.getItem('"')).to.be.ok; + expect(test.selectize.getItem('"').length).to.be.equal(1); + }); + it('should allow values with backslashes', function() { + expect(test.selectize.getItem('\\\'')).to.be.ok; + expect(test.selectize.getItem('\\\'').length).to.be.equal(1); + expect(test.selectize.getItem('\\"')).to.be.ok; + expect(test.selectize.getItem('\\"').length).to.be.equal(1); + }); + it('should not allow undefined / null values', function() { + expect(test.selectize.getItem(null)).to.be.ok; + expect(test.selectize.getItem(null).length).to.be.equal(0); + expect(test.selectize.getItem(undefined)).to.be.ok; + expect(test.selectize.getItem(undefined).length).to.be.equal(0); + }); + }); + + describe('clear()', function() { + var test; + + before(function() { + test = setup_test('', { + valueField: 'value', + labelField: 'value', + options: [ + {value: 0}, + {value: 1} + ], + score: function() { } + }); + test.selectize.search('hello'); + }).to.throw(Error); + }); + it('should not throw error if "score" setting does return a function', function() { + var test; + + expect(function() { + test = setup_test('', { + valueField: 'value', + labelField: 'value', + searchField: 'value', + options: [] + }); + var fn = test.selectize.getScoreFunction('test'); + expect(typeof fn).to.be.equal('function'); + expect(typeof fn({value: 'test'})).to.be.equal('number'); + expect(fn({value: 'test'})).to.be.above(0); + }); + }); + + describe('destroy()', function() { + var has_namespaced_event = function($el, ns) { + var i, n, key; + var data = ($._data || $.data).apply($, [$(window)[0], 'events']); + ns = ns.replace(/^./, ''); + for (key in data) { + if (data.hasOwnProperty(key)) { + for (i = 0, n = data[key].length; i < n; i++) { + if (data[key][i].namespace.indexOf(ns) !== -1) { + return true; + } + } + } + } + + return false; + }; + it('should remove control from DOM', function() { + var test = setup_test('', {}); + test.selectize.destroy(); + expect(test.selectize.$input[0].selectize).to.be.equal(undefined); + }); + it('should unbind events on window', function() { + var test = setup_test('', {}); + test.selectize.destroy(); + expect(has_namespaced_event($(document), test.selectize.eventNS)).to.be.equal(false); + }); + it('should unbind events on ', function() { + var test = setup_test('' + children + '', {}); + test.selectize.destroy(); + expect(test.$select.html()).to.be.equal(children); + expect(test.$select.attr('tabindex')).to.be.equal('9999'); + }); + it('should remove tabindex if it was originally undefined', function() { + var test = setup_test('', {}); + var counter = 0; + test.selectize.on('change', function() { counter++; }); + test.selectize.setValue('b'); + + window.setTimeout(function() { + expect(counter).to.be.equal(1); + done(); + }, 0); + }); + it('should contain current value', function(done) { + var test = setup_test('', {}); + test.selectize.on('change', function(value) { + expect(value).to.be.equal('c'); + done(); + }); + test.selectize.setValue('c'); + }); + it('should not be triggered when the selected item has not changed', function(done) { + var test = setup_test(''); + + var counter = 0; + test.$select.on('change', function() { counter++; }); + + Syn.click(test.selectize.$control).delay(0, function() { + Syn + .click($('[data-value="a"]', test.selectize.$dropdown)) + .delay(0, function() { + expect(counter).to.be.equal(0); + done(); + }); + }); + }); + }); + + describe('item_add', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('item_add', function() { + done(); + }); + test.selectize.addItem('b'); + }); + it('should contain item\'s value', function(done) { + var test = setup_test('', {}); + test.selectize.on('item_add', function(value, $item) { + expect(value).to.be.equal('b'); + done(); + }); + test.selectize.addItem('b'); + }); + }); + + describe('item_remove', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('item_remove', function() { + done(); + }); + test.selectize.removeItem('a'); + }); + it('should contain item\'s value', function(done) { + var test = setup_test('', {}); + test.selectize.on('item_remove', function(value) { + expect(value).to.be.equal('b'); + done(); + }); + test.selectize.removeItem('b'); + }); + }); + + describe('clear', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('clear', function() { + done(); + }); + test.selectize.clear(); + }); + }); + + describe('optgroup_add', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('optgroup_add', function() { done(); }); + test.selectize.addOptionGroup('id', {label: 'Group'}); + }); + it('should contain optgroup id', function(done) { + var test = setup_test('', {}); + test.selectize.on('optgroup_add', function(id, data) { + expect(id).to.be.equal('id'); + done(); + }); + test.selectize.addOptionGroup('id', {label: 'Group'}); + }); + it('should contain outgroup data', function(done) { + var test = setup_test('', {}); + var optgroup = {label: 'Group'}; + test.selectize.on('optgroup_add', function(id, data) { + expect(data).to.eql(optgroup); + done(); + }); + test.selectize.addOptionGroup('id', optgroup); + }); + }); + + describe('option_add', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('option_add', function() { + done(); + }); + test.selectize.addOption({value: 'e'}); + }); + it('should contain option value', function(done) { + var test = setup_test('', {}); + test.selectize.on('option_add', function(value, data) { + expect(value).to.be.equal('e'); + done(); + }); + test.selectize.addOption({value: 'e'}); + }); + it('should contain option data', function(done) { + var test = setup_test('', {}); + var option = {value: 'e'}; + test.selectize.on('option_add', function(value, data) { + expect(option).to.eql(data); + done(); + }); + test.selectize.addOption(option); + }); + }); + + describe('option_remove', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('option_remove', function() { + done(); + }); + test.selectize.removeOption('a'); + }); + it('should contain option value', function(done) { + var test = setup_test('', {}); + test.selectize.on('option_remove', function(value) { + expect(value).to.be.equal('a'); + done(); + }); + test.selectize.removeOption('a'); + }); + }); + + describe('option_clear', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('option_clear', function() { + done(); + }); + test.selectize.clearOptions(); + }); + }); + + describe('dropdown_open', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('dropdown_open', function() { + done(); + }); + test.selectize.open(); + }); + }); + + describe('dropdown_close', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('dropdown_close', function() { + done(); + }); + test.selectize.open(); + test.selectize.close(); + }); + }); + + describe('destroy', function() { + it('should be triggered', function(done) { + var test = setup_test('', {}); + test.selectize.on('destroy', function() { + done(); + }); + test.selectize.destroy(); + }); + }); + + describe('type', function() { + it('should be triggered', function(done) { + var test = setup_test('', {create: true}); + test.selectize.on('type', function() { + done(); + }); + Syn.click(test.selectize.$control).type('a', test.selectize.$control_input); + }); + it('should contain current value', function(done) { + var test = setup_test('', {create: true}); + test.selectize.on('type', function(value) { + expect(value).to.be.equal('a'); + done(); + }); + Syn.click(test.selectize.$control).type('a', test.selectize.$control_input); + }); + }); + +}); \ No newline at end of file diff --git a/test/events_dom.js b/test/events_dom.js new file mode 100644 index 000000000..845d07575 --- /dev/null +++ b/test/events_dom.js @@ -0,0 +1,64 @@ +describe('DOM Events', function() { + describe('"change"', function() { + it('should be triggered once by addItem()', function(done) { + var test = setup_test('', { + valueField: 'value', + labelField: 'value', + options: [ + {value: 'a'}, + {value: 'b'}, + ], + items: ['a','b'] + }); + + var counter = 0; + test.$select.on('change', function() { counter++; }); + test.selectize.removeItem('b'); + + window.setTimeout(function() { + expect(counter).to.be.equal(1); + done(); + }, 0); + }); + it('should be triggered once by clear()', function(done) { + var test = setup_test('' + + '' + + '' + + '', {}); + + Syn + .click(test.selectize.$control) + .delay(0, function() { + expect(test.selectize.isFocused).to.be.equal(true); + done(); + }); + }); + + it('should open dropdown menu', function(done) { + var test = setup_test('', {}); + + Syn + .click(test.selectize.$control) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(true); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); + done(); + }); + }); + + }); + + describe('clicking option', function() { + + it('should select it', function(done) { + var test = setup_test('', {}); + + Syn.click(test.selectize.$control).delay(0, function() { + Syn + .click($('[data-value="b"]', test.selectize.$dropdown)) + .delay(0, function() { + expect(test.selectize.$input.val()).to.be.equal('b'); + done(); + }); + }); + }); + + it('should close dropdown', function(done) { + var test = setup_test('', {}); + + Syn.click(test.selectize.$control).delay(0, function() { + Syn + .click($('[data-value="b"]', test.selectize.$dropdown)) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(false); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); + done(); + }); + }); + }); + + }); + + describe('typing in input', function() { + + it('should filter results', function(done) { + var test = setup_test('', {}); + + Syn + .click(test.selectize.$control) + .type('a', test.selectize.$control_input) + .delay(0, function() { + expect($('[data-value="a"]', test.selectize.$dropdown).length).to.be.equal(1); + expect($('[data-value="b"]', test.selectize.$dropdown).length).to.be.equal(0); + done(); + }); + }); + + it('should hide dropdown if no results present', function(done) { + var test = setup_test('', {}); + + Syn + .click(test.selectize.$control) + .type('awaw', test.selectize.$control_input) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(false); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); + done(); + }); + }); + + it('should not hide dropdown if "create" option enabled and no results present', function(done) { + var test = setup_test('', {create: true}); + + Syn + .click(test.selectize.$control) + .type('awaw', test.selectize.$control_input) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(true); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); + done(); + }); + }); + + it('should restore dropdown visibility when backing out of a query without results (backspace)', function(done) { + var test = setup_test('', {}); + + Syn + .click(test.selectize.$control) + .type('awf', test.selectize.$control_input) + .type('\b\b\b', test.selectize.$control_input) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(true); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); + done(); + }); + }); + + it('should move caret when [left] or [right] pressed', function(done) { + var test = setup_test('', {create: true}); + + Syn + .click(test.selectize.$control) + .type('[left][left]whatt', test.selectize.$control_input) + .delay(0, function() { + expect(test.selectize.caretPos).to.be.equal(2); + done(); + }); + }); + + }); + + describe('blurring the input', function() { + it('should close dropdown when createOnBlur is true', function(done) { + var test = setup_test('', { + createOnBlur: true, + create: function(value){ + return { + value: value, + text: value + }; + } + }); + + Syn + .click(test.selectize.$control) + .type('fooo', test.selectize.$control_input) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(true); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(true); + + Syn + .click($("#mocha")[0]) + .delay(0, function() { + expect(test.selectize.isOpen).to.be.equal(false); + expect(test.selectize.$dropdown.is(':visible')).to.be.equal(false); + done(); + }); + }); + + }); + }); + + }); + +})(); \ No newline at end of file diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 000000000..1754ee855 --- /dev/null +++ b/test/setup.js @@ -0,0 +1,223 @@ +(function() { + + describe('Setup', function() { + + it('should not allow duplicate initialization', function() { + var instance_before, instance_after, test; + + test = setup_test('', {}); + instance_before = test.$select[0].selectize; + test.$select.selectize(); + instance_after = test.$select[0].selectize; + + expect(instance_before).to.be.equal(instance_after); + }); + + describe('', function() { + it('should complete without exceptions', function() { + var test = setup_test('', {}); + }); + describe('getValue()', function() { + it('should return value as a string', function() { + var test = setup_test('', {delimiter: ','}); + expect(test.selectize.getValue()).to.be.a('string'); + }); + it('should return "" when empty', function() { + var test = setup_test('', {delimiter: ','}); + expect(test.selectize.getValue()).to.be.equal(''); + }); + it('should return proper value when not empty', function() { + var test = setup_test('', {delimiter: ','}); + expect(test.selectize.getValue()).to.be.equal('a,b'); + }); + }); + describe('', function() { + it('should propagate original input attributes to the generated input', function() { + var test = setup_test('', {}); + expect(test.selectize.$control_input.attr('autocorrect')).to.be.equal('off'); + expect(test.selectize.$control_input.attr('autocapitalize')).to.be.equal('none'); + }); + it('should not add attributes if not present in the original', function() { + var test = setup_test('', {}); + expect(test.selectize.$control_input.attr('autocorrect')).to.be.equal(undefined); + expect(test.selectize.$control_input.attr('autocapitalize')).to.be.equal(undefined); + }); + }); + }); + + describe('', {}); + }); + it('should add options in text form (no html entities)', function() { + var test = setup_test('', {}); + expect(test.selectize.options['a'].text).to.be.equal(''); + }); + it('should keep options in original order if no sort given', function(done) { + var test = setup_test([ + '' + ].join(), {}); + + var order_expected = ['AL','AK','AZ','AR','CO','CT','DE','DC','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','01','10']; + var order_actual = []; + + test.selectize.refreshOptions(true); + window.setTimeout(function() { + test.selectize.$dropdown.find('[data-value]').each(function(i, el) { + order_actual.push($(el).attr('data-value')); + }); + + expect(order_actual).to.eql(order_expected); + done(); + }, 0); + }); + describe('getValue()', function() { + it('should return "" when empty', function() { + var test = setup_test('', {}); + expect(test.selectize.getValue()).to.be.equal('a'); + }); + }); + }); + + describe('', {}); + }); + describe('getValue()', function() { + it('should return [] when empty', function() { + var test = setup_test('', {}); + expect(test.selectize.getValue()).to.deep.equal(['a']); + }); + }); + }); + + describe('', {}); + }); + it('should have "disabled" class', function() { + expect(test.selectize.$control.hasClass('disabled')).to.be.equal(true); + }); + it('should have isDisabled property set to true', function() { + expect(test.selectize.isDisabled).to.be.equal(true); + }); + }); + + describe('' + + '' + + '' + + '', {}); + $form = test.$select.parents('form'); + $button = $('