mod/bootstrap/vendor/select2/dist/js/select2.js in card-1.94.1 vs mod/bootstrap/vendor/select2/dist/js/select2.js in card-1.95.0
- old
+ new
@@ -1,13 +1,13 @@
/*!
- * Select2 4.0.4
+ * Select2 4.0.6-rc.1
* https://select2.github.io
*
* Released under the MIT license
* https://github.com/select2/select2/blob/master/LICENSE.md
*/
-(function (factory) {
+;(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
@@ -572,14 +572,14 @@
}
DecoratedClass.prototype = new ctr();
for (var m = 0; m < superMethods.length; m++) {
- var superMethod = superMethods[m];
+ var superMethod = superMethods[m];
- DecoratedClass.prototype[superMethod] =
- SuperClass.prototype[superMethod];
+ DecoratedClass.prototype[superMethod] =
+ SuperClass.prototype[superMethod];
}
var calledMethod = function (methodName) {
// Stub out the original method if it's not decorating an actual method
var originalMethod = function () {};
@@ -770,10 +770,71 @@
}
$element.append($nodes);
};
+ // Cache objects in Utils.__cache instead of $.data (see #4346)
+ Utils.__cache = {};
+
+ var id = 0;
+ Utils.GetUniqueElementId = function (element) {
+ // Get a unique element Id. If element has no id,
+ // creates a new unique number, stores it in the id
+ // attribute and returns the new id.
+ // If an id already exists, it simply returns it.
+
+ var select2Id = element.getAttribute('data-select2-id');
+ if (select2Id == null) {
+ // If element has id, use it.
+ if (element.id) {
+ select2Id = element.id;
+ element.setAttribute('data-select2-id', select2Id);
+ } else {
+ element.setAttribute('data-select2-id', ++id);
+ select2Id = id.toString();
+ }
+ }
+ return select2Id;
+ };
+
+ Utils.StoreData = function (element, name, value) {
+ // Stores an item in the cache for a specified element.
+ // name is the cache key.
+ var id = Utils.GetUniqueElementId(element);
+ if (!Utils.__cache[id]) {
+ Utils.__cache[id] = {};
+ }
+
+ Utils.__cache[id][name] = value;
+ };
+
+ Utils.GetData = function (element, name) {
+ // Retrieves a value from the cache by its key (name)
+ // name is optional. If no name specified, return
+ // all cache items for the specified element.
+ // and for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (name) {
+ if (Utils.__cache[id]) {
+ return Utils.__cache[id][name] != null ?
+ Utils.__cache[id][name]:
+ $(element).data(name); // Fallback to HTML5 data attribs.
+ }
+ return $(element).data(name); // Fallback to HTML5 data attribs.
+ } else {
+ return Utils.__cache[id];
+ }
+ };
+
+ Utils.RemoveData = function (element) {
+ // Removes all cached items for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (Utils.__cache[id] != null) {
+ delete Utils.__cache[id];
+ }
+ };
+
return Utils;
});
S2.define('select2/results',[
'jquery',
@@ -905,11 +966,11 @@
.find('.select2-results__option[aria-selected]');
$options.each(function () {
var $option = $(this);
- var item = $.data(this, 'data');
+ var item = Utils.GetData(this, 'data');
// id needs to be converted to a string when comparing
var id = '' + item.id;
if ((item.element != null && item.element.selected) ||
@@ -1010,11 +1071,11 @@
$option.append($childrenContainer);
} else {
this.template(data, option);
}
- $.data(option, 'data', data);
+ Utils.StoreData(option, 'data', data);
return option;
};
Results.prototype.bind = function (container, $container) {
@@ -1096,11 +1157,11 @@
if ($highlighted.length === 0) {
return;
}
- var data = $highlighted.data('data');
+ var data = Utils.GetData($highlighted[0], 'data');
if ($highlighted.attr('aria-selected') == 'true') {
self.trigger('close', {});
} else {
self.trigger('select', {
@@ -1115,11 +1176,12 @@
var $options = self.$results.find('[aria-selected]');
var currentIndex = $options.index($highlighted);
// If we are already at te top, don't move further
- if (currentIndex === 0) {
+ // If no options, currentIndex will be -1
+ if (currentIndex <= 0) {
return;
}
var nextIndex = currentIndex - 1;
@@ -1208,11 +1270,11 @@
this.$results.on('mouseup', '.select2-results__option[aria-selected]',
function (evt) {
var $this = $(this);
- var data = $this.data('data');
+ var data = Utils.GetData(this, 'data');
if ($this.attr('aria-selected') === 'true') {
if (self.options.get('multiple')) {
self.trigger('unselect', {
originalEvent: evt,
@@ -1231,11 +1293,11 @@
});
});
this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
function (evt) {
- var data = $(this).data('data');
+ var data = Utils.GetData(this, 'data');
self.getHighlightedResults()
.removeClass('select2-results__option--highlighted');
self.trigger('results:focus', {
@@ -1346,12 +1408,12 @@
'</span>'
);
this._tabindex = 0;
- if (this.$element.data('old-tabindex') != null) {
- this._tabindex = this.$element.data('old-tabindex');
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
} else if (this.$element.attr('tabindex') != null) {
this._tabindex = this.$element.attr('tabindex');
}
$selection.attr('title', this.$element.attr('title'));
@@ -1407,10 +1469,13 @@
self.$selection.attr('aria-expanded', 'false');
self.$selection.removeAttr('aria-activedescendant');
self.$selection.removeAttr('aria-owns');
self.$selection.focus();
+ window.setTimeout(function () {
+ self.$selection.focus();
+ }, 0);
self._detachCloseHandler(container);
});
container.on('enable', function () {
@@ -1455,11 +1520,11 @@
if (this == $select[0]) {
return;
}
- var $element = $this.data('element');
+ var $element = Utils.GetData(this, 'element');
$element.select2('close');
});
});
};
@@ -1516,11 +1581,14 @@
SingleSelection.__super__.bind.apply(this, arguments);
var id = container.id + '-container';
- this.$selection.find('.select2-selection__rendered').attr('id', id);
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
this.$selection.attr('aria-labelledby', id);
this.$selection.on('mousedown', function (evt) {
// Only respond to left clicks
if (evt.which !== 1) {
@@ -1543,18 +1611,16 @@
container.on('focus', function (evt) {
if (!container.isOpen()) {
self.$selection.focus();
}
});
-
- container.on('selection:update', function (params) {
- self.update(params.data);
- });
};
SingleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title'); // clear tooltip on empty
};
SingleSelection.prototype.display = function (data, container) {
var template = this.options.get('templateSelection');
var escapeMarkup = this.options.get('escapeMarkup');
@@ -1576,11 +1642,11 @@
var $rendered = this.$selection.find('.select2-selection__rendered');
var formatted = this.display(selection, $rendered);
$rendered.empty().append(formatted);
- $rendered.prop('title', selection.title || selection.text);
+ $rendered.attr('title', selection.title || selection.text);
};
return SingleSelection;
});
@@ -1628,22 +1694,24 @@
}
var $remove = $(this);
var $selection = $remove.parent();
- var data = $selection.data('data');
+ var data = Utils.GetData($selection[0], 'data');
self.trigger('unselect', {
originalEvent: evt,
data: data
});
}
);
};
MultipleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title');
};
MultipleSelection.prototype.display = function (data, container) {
var template = this.options.get('templateSelection');
var escapeMarkup = this.options.get('escapeMarkup');
@@ -1677,13 +1745,13 @@
var $selection = this.selectionContainer();
var formatted = this.display(selection, $selection);
$selection.append(formatted);
- $selection.prop('title', selection.title || selection.text);
+ $selection.attr('title', selection.title || selection.text);
- $selection.data('data', selection);
+ Utils.StoreData($selection[0], 'data', selection);
$selections.push($selection);
}
var $rendered = this.$selection.find('.select2-selection__rendered');
@@ -1744,12 +1812,13 @@
return Placeholder;
});
S2.define('select2/selection/allowClear',[
'jquery',
- '../keys'
-], function ($, KEYS) {
+ '../keys',
+ '../utils'
+], function ($, KEYS, Utils) {
function AllowClear () { }
AllowClear.prototype.bind = function (decorated, container, $container) {
var self = this;
@@ -1787,28 +1856,41 @@
return;
}
evt.stopPropagation();
- var data = $clear.data('data');
+ var data = Utils.GetData($clear[0], 'data');
+ var previousVal = this.$element.val();
+ this.$element.val(this.placeholder.id);
+
+ var unselectData = {
+ data: data
+ };
+ this.trigger('clear', unselectData);
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
+
for (var d = 0; d < data.length; d++) {
- var unselectData = {
+ unselectData = {
data: data[d]
};
// Trigger the `unselect` event, so people can prevent it from being
// cleared.
this.trigger('unselect', unselectData);
// If the event was prevented, don't clear it out.
if (unselectData.prevented) {
+ this.$element.val(previousVal);
return;
}
}
- this.$element.val(this.placeholder.id).trigger('change');
+ this.$element.trigger('change');
this.trigger('toggle', {});
};
AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
@@ -1832,11 +1914,11 @@
var $remove = $(
'<span class="select2-selection__clear">' +
'×' +
'</span>'
);
- $remove.data('data', data);
+ Utils.StoreData($remove[0], 'data', data);
this.$selection.find('.select2-selection__rendered').prepend($remove);
};
return AllowClear;
@@ -1853,11 +1935,11 @@
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search select2-search--inline">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
- ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
+ ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
'</li>'
);
this.$searchContainer = $search;
@@ -1923,11 +2005,11 @@
if (key === KEYS.BACKSPACE && self.$search.val() === '') {
var $previousChoice = self.$searchContainer
.prev('.select2-selection__choice');
if ($previousChoice.length > 0) {
- var item = $previousChoice.data('data');
+ var item = Utils.GetData($previousChoice[0], 'data');
self.searchRemoveChoice(item);
evt.preventDefault();
}
@@ -2017,11 +2099,17 @@
this.$selection.find('.select2-selection__rendered')
.append(this.$searchContainer);
this.resizeSearch();
if (searchHadFocus) {
- this.$search.focus();
+ var isTagInput = this.$element.find('[data-select2-tag]').length;
+ if (isTagInput) {
+ // fix IE11 bug where tag input lost focus
+ this.$element.focus();
+ } else {
+ this.$search.focus();
+ }
}
};
Search.prototype.handleSearch = function () {
this.resizeSearch();
@@ -2074,14 +2162,17 @@
var self = this;
var relayEvents = [
'open', 'opening',
'close', 'closing',
'select', 'selecting',
- 'unselect', 'unselecting'
+ 'unselect', 'unselecting',
+ 'clear', 'clearing'
];
- var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
+ var preventableEvents = [
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
+ ];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
// Ignore events that should not be relayed
@@ -3156,11 +3247,11 @@
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
- $.removeData(this, 'data');
+ Utils.RemoveData(this);
});
};
SelectAdapter.prototype.query = function (params, callback) {
var data = [];
@@ -3229,19 +3320,19 @@
var normalizedData = this._normalizeItem(data);
normalizedData.element = option;
// Override the option's data with the combined data
- $.data(option, 'data', normalizedData);
+ Utils.StoreData(option, 'data', normalizedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = {};
- data = $.data($option[0], 'data');
+ data = Utils.GetData($option[0], 'data');
if (data != null) {
return data;
}
@@ -3275,17 +3366,17 @@
}
data = this._normalizeItem(data);
data.element = $option[0];
- $.data($option[0], 'data', data);
+ Utils.StoreData($option[0], 'data', data);
return data;
};
SelectAdapter.prototype._normalizeItem = function (item) {
- if (!$.isPlainObject(item)) {
+ if (item !== Object(item)) {
item = {
id: item,
text: item
};
}
@@ -3485,11 +3576,12 @@
callback(results);
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
- if ($request.status && $request.status === '0') {
+ if ('status' in $request &&
+ ($request.status === 0 || $request.status === '0')) {
return;
}
self.trigger('results:message', {
message: 'errorLoading'
@@ -3907,11 +3999,11 @@
var $rendered = decorated.call(this);
var $search = $(
'<span class="select2-search select2-search--dropdown">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
- ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
+ ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
' spellcheck="false" role="textbox" />' +
'</span>'
);
this.$searchContainer = $search;
@@ -3957,10 +4049,11 @@
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
+ self.$search.blur();
});
container.on('focus', function () {
if (!container.isOpen()) {
self.$search.focus();
@@ -4222,18 +4315,18 @@
var resizeEvent = 'resize.select2.' + container.id;
var orientationEvent = 'orientationchange.select2.' + container.id;
var $watchers = this.$container.parents().filter(Utils.hasScroll);
$watchers.each(function () {
- $(this).data('select2-scroll-position', {
+ Utils.StoreData(this, 'select2-scroll-position', {
x: $(this).scrollLeft(),
y: $(this).scrollTop()
});
});
$watchers.on(scrollEvent, function (ev) {
- var position = $(this).data('select2-scroll-position');
+ var position = Utils.GetData(this, 'select2-scroll-position');
$(this).scrollTop(position.y);
});
$(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
function (e) {
@@ -4394,12 +4487,12 @@
return MinimumResultsForSearch;
});
S2.define('select2/dropdown/selectOnClose',[
-
-], function () {
+ '../utils'
+], function (Utils) {
function SelectOnClose () { }
SelectOnClose.prototype.bind = function (decorated, container, $container) {
var self = this;
@@ -4426,11 +4519,11 @@
// Only select highlighted results
if ($highlightedResults.length < 1) {
return;
}
- var data = $highlightedResults.data('data');
+ var data = Utils.GetData($highlightedResults[0], 'data');
// Don't re-select already selected resulte
if (
(data.element != null && data.element.selected) ||
(data.element == null && data.selected)
@@ -4914,11 +5007,11 @@
var data = {};
data[camelKey] = value;
var convertedData = Utils._convertData(data);
- $.extend(this.defaults, convertedData);
+ $.extend(true, this.defaults, convertedData);
};
var defaults = new Defaults();
return defaults;
@@ -4979,44 +5072,45 @@
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
- if ($e.data('select2Tags')) {
+ if (Utils.GetData($e[0], 'select2Tags')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-select2-tags` attribute has been changed to ' +
'use the `data-data` and `data-tags="true"` attributes and will be ' +
'removed in future versions of Select2.'
);
}
- $e.data('data', $e.data('select2Tags'));
- $e.data('tags', true);
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
+ Utils.StoreData($e[0], 'tags', true);
}
- if ($e.data('ajaxUrl')) {
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-ajax-url` attribute has been changed to ' +
'`data-ajax--url` and support for the old attribute will be removed' +
' in future versions of Select2.'
);
}
- $e.attr('ajax--url', $e.data('ajaxUrl'));
- $e.data('ajax--url', $e.data('ajaxUrl'));
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
+
}
var dataset = {};
// Prefer the element's `dataset` attribute if it exists
// jQuery 1.x does not correctly handle data attributes with multiple dashes
if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
- dataset = $.extend(true, {}, $e[0].dataset, $e.data());
+ dataset = $.extend(true, {}, $e[0].dataset, Utils.GetData($e[0]));
} else {
- dataset = $e.data();
+ dataset = Utils.GetData($e[0]);
}
var data = $.extend(true, {}, dataset);
data = Utils._convertData(data);
@@ -5052,12 +5146,12 @@
'./options',
'./utils',
'./keys'
], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) {
- if ($element.data('select2') != null) {
- $element.data('select2').destroy();
+ if (Utils.GetData($element[0], 'select2') != null) {
+ Utils.GetData($element[0], 'select2').destroy();
}
this.$element = $element;
this.id = this._generateId($element);
@@ -5069,11 +5163,11 @@
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
- $element.data('old-tabindex', tabindex);
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@@ -5130,10 +5224,13 @@
$element.attr('aria-hidden', 'true');
// Synchronize any monitored attributes
this._syncAttributes();
+ Utils.StoreData($element[0], 'select2', this);
+
+ // Ensure backwards compatibility with $element.data('select2').
$element.data('select2', this);
};
Utils.Extend(Select2, Utils.Observable);
@@ -5464,11 +5561,12 @@
var actualTrigger = Select2.__super__.trigger;
var preTriggerMap = {
'open': 'opening',
'close': 'closing',
'select': 'selecting',
- 'unselect': 'unselecting'
+ 'unselect': 'unselecting',
+ 'clear': 'clearing'
};
if (args === undefined) {
args = {};
}
@@ -5619,14 +5717,16 @@
this._syncA = null;
this._syncS = null;
this.$element.off('.select2');
- this.$element.attr('tabindex', this.$element.data('old-tabindex'));
+ this.$element.attr('tabindex',
+ Utils.GetData(this.$element[0], 'old-tabindex'));
this.$element.removeClass('select2-hidden-accessible');
this.$element.attr('aria-hidden', 'false');
+ Utils.RemoveData(this.$element[0]);
this.$element.removeData('select2');
this.dataAdapter.destroy();
this.selection.destroy();
this.dropdown.destroy();
@@ -5650,11 +5750,11 @@
this.$container = $container;
this.$container.addClass('select2-container--' + this.options.get('theme'));
- $container.data('element', this.$element);
+ Utils.StoreData($container[0], 'element', this.$element);
return $container;
};
return Select2;
@@ -5670,12 +5770,13 @@
S2.define('jquery.select2',[
'jquery',
'jquery-mousewheel',
'./select2/core',
- './select2/defaults'
-], function ($, _, Select2, Defaults) {
+ './select2/defaults',
+ './select2/utils'
+], function ($, _, Select2, Defaults, Utils) {
if ($.fn.select2 == null) {
// All methods that should return the element
var thisMethods = ['open', 'close', 'destroy'];
$.fn.select2 = function (options) {
@@ -5692,10 +5793,10 @@
} else if (typeof options === 'string') {
var ret;
var args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
- var instance = $(this).data('select2');
+ var instance = Utils.GetData(this, 'select2');
if (instance == null && window.console && console.error) {
console.error(
'The select2(\'' + options + '\') method was called on an ' +
'element that is not using Select2.'