Merge branch 'master' of https://github.com/NadeemAfana/select2 into develop
This commit is contained in:
commit
62c4f6332b
@ -3,8 +3,9 @@ define([
|
||||
'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'];
|
||||
@ -25,7 +26,7 @@ define([
|
||||
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(
|
||||
|
7
src/js/select2/compat/inputData.js
vendored
7
src/js/select2/compat/inputData.js
vendored
@ -1,6 +1,7 @@
|
||||
define([
|
||||
'jquery'
|
||||
], function ($) {
|
||||
'jquery',
|
||||
'../utils'
|
||||
], function ($, Utils) {
|
||||
function InputData (decorated, $element, options) {
|
||||
this._currentData = [];
|
||||
this._valueSeparator = options.get('valueSeparator') || ',';
|
||||
@ -117,7 +118,7 @@ define([
|
||||
|
||||
InputData.prototype.addOptions = function (_, $options) {
|
||||
var options = $.map($options, function ($option) {
|
||||
return $.data($option[0], 'data');
|
||||
return Utils.GetData($option[0], 'data');
|
||||
});
|
||||
|
||||
this._currentData.push.apply(this._currentData, options);
|
||||
|
15
src/js/select2/core.js
vendored
15
src/js/select2/core.js
vendored
@ -5,8 +5,8 @@ define([
|
||||
'./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;
|
||||
@ -22,7 +22,7 @@ define([
|
||||
// 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
|
||||
@ -83,7 +83,7 @@ define([
|
||||
// Synchronize any monitored attributes
|
||||
this._syncAttributes();
|
||||
|
||||
$element.data('select2', this);
|
||||
Utils.StoreData($element[0], 'select2', this);
|
||||
};
|
||||
|
||||
Utils.Extend(Select2, Utils.Observable);
|
||||
@ -573,11 +573,12 @@ define([
|
||||
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');
|
||||
this.$element.removeData('select2');
|
||||
Utils.RemoveData(this.$element[0]);
|
||||
|
||||
this.dataAdapter.destroy();
|
||||
this.selection.destroy();
|
||||
@ -604,7 +605,7 @@ define([
|
||||
|
||||
this.$container.addClass('select2-container--' + this.options.get('theme'));
|
||||
|
||||
$container.data('element', this.$element);
|
||||
Utils.StoreData($container[0], 'element', this.$element);
|
||||
|
||||
return $container;
|
||||
};
|
||||
|
8
src/js/select2/data/select.js
vendored
8
src/js/select2/data/select.js
vendored
@ -119,7 +119,7 @@ define([
|
||||
// Remove anything added to child elements
|
||||
this.$element.find('*').each(function () {
|
||||
// Remove any custom data set by Select2
|
||||
$.removeData(this, 'data');
|
||||
Utils.RemoveData(this);
|
||||
});
|
||||
};
|
||||
|
||||
@ -192,7 +192,7 @@ define([
|
||||
normalizedData.element = option;
|
||||
|
||||
// Override the option's data with the combined data
|
||||
$.data(option, 'data', normalizedData);
|
||||
Utils.StoreData(option, 'data', normalizedData);
|
||||
|
||||
return $option;
|
||||
};
|
||||
@ -200,7 +200,7 @@ define([
|
||||
SelectAdapter.prototype.item = function ($option) {
|
||||
var data = {};
|
||||
|
||||
data = $.data($option[0], 'data');
|
||||
data = Utils.GetData($option[0], 'data');
|
||||
|
||||
if (data != null) {
|
||||
return data;
|
||||
@ -238,7 +238,7 @@ define([
|
||||
data = this._normalizeItem(data);
|
||||
data.element = $option[0];
|
||||
|
||||
$.data($option[0], 'data', data);
|
||||
Utils.StoreData($option[0], 'data', data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
4
src/js/select2/dropdown/attachBody.js
vendored
4
src/js/select2/dropdown/attachBody.js
vendored
@ -90,14 +90,14 @@ define([
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
|
6
src/js/select2/dropdown/selectOnClose.js
vendored
6
src/js/select2/dropdown/selectOnClose.js
vendored
@ -1,6 +1,6 @@
|
||||
define([
|
||||
|
||||
], function () {
|
||||
'../utils'
|
||||
], function (Utils) {
|
||||
function SelectOnClose () { }
|
||||
|
||||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||||
@ -31,7 +31,7 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
var data = $highlightedResults.data('data');
|
||||
var data = Utils.GetData($highlightedResults[0], 'data');
|
||||
|
||||
// Don't re-select already selected resulte
|
||||
if (
|
||||
|
17
src/js/select2/options.js
vendored
17
src/js/select2/options.js
vendored
@ -55,7 +55,7 @@ define([
|
||||
$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 ' +
|
||||
@ -64,11 +64,11 @@ define([
|
||||
);
|
||||
}
|
||||
|
||||
$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 ' +
|
||||
@ -77,8 +77,9 @@ define([
|
||||
);
|
||||
}
|
||||
|
||||
$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 = {};
|
||||
@ -86,9 +87,9 @@ define([
|
||||
// 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);
|
||||
|
10
src/js/select2/results.js
vendored
10
src/js/select2/results.js
vendored
@ -130,7 +130,7 @@ define([
|
||||
$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;
|
||||
@ -235,7 +235,7 @@ define([
|
||||
this.template(data, option);
|
||||
}
|
||||
|
||||
$.data(option, 'data', data);
|
||||
Utils.StoreData(option, 'data', data);
|
||||
|
||||
return option;
|
||||
};
|
||||
@ -321,7 +321,7 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
var data = $highlighted.data('data');
|
||||
var data = Utils.GetData($highlighted[0], 'data');
|
||||
|
||||
if ($highlighted.attr('aria-selected') == 'true') {
|
||||
self.trigger('close', {});
|
||||
@ -433,7 +433,7 @@ define([
|
||||
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')) {
|
||||
@ -456,7 +456,7 @@ define([
|
||||
|
||||
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');
|
||||
|
9
src/js/select2/selection/allowClear.js
vendored
9
src/js/select2/selection/allowClear.js
vendored
@ -1,7 +1,8 @@
|
||||
define([
|
||||
'jquery',
|
||||
'../keys'
|
||||
], function ($, KEYS) {
|
||||
'../keys',
|
||||
'../utils'
|
||||
], function ($, KEYS, Utils) {
|
||||
function AllowClear () { }
|
||||
|
||||
AllowClear.prototype.bind = function (decorated, container, $container) {
|
||||
@ -43,7 +44,7 @@ define([
|
||||
|
||||
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);
|
||||
@ -101,7 +102,7 @@ define([
|
||||
'×' +
|
||||
'</span>'
|
||||
);
|
||||
$remove.data('data', data);
|
||||
Utils.StoreData($remove[0], 'data', data);
|
||||
|
||||
this.$selection.find('.select2-selection__rendered').prepend($remove);
|
||||
};
|
||||
|
6
src/js/select2/selection/base.js
vendored
6
src/js/select2/selection/base.js
vendored
@ -21,8 +21,8 @@ define([
|
||||
|
||||
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');
|
||||
}
|
||||
@ -130,7 +130,7 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
var $element = $this.data('element');
|
||||
var $element = Utils.GetData(this, 'element');
|
||||
|
||||
$element.select2('close');
|
||||
});
|
||||
|
4
src/js/select2/selection/multiple.js
vendored
4
src/js/select2/selection/multiple.js
vendored
@ -44,7 +44,7 @@ define([
|
||||
var $remove = $(this);
|
||||
var $selection = $remove.parent();
|
||||
|
||||
var data = $selection.data('data');
|
||||
var data = Utils.GetData($selection[0], 'data');
|
||||
|
||||
self.trigger('unselect', {
|
||||
originalEvent: evt,
|
||||
@ -97,7 +97,7 @@ define([
|
||||
$selection.append(formatted);
|
||||
$selection.attr('title', selection.title || selection.text);
|
||||
|
||||
$selection.data('data', selection);
|
||||
Utils.StoreData($selection[0], 'data', selection);
|
||||
|
||||
$selections.push($selection);
|
||||
}
|
||||
|
2
src/js/select2/selection/search.js
vendored
2
src/js/select2/selection/search.js
vendored
@ -81,7 +81,7 @@ define([
|
||||
.prev('.select2-selection__choice');
|
||||
|
||||
if ($previousChoice.length > 0) {
|
||||
var item = $previousChoice.data('data');
|
||||
var item = Utils.GetData($previousChoice[0], 'data');
|
||||
|
||||
self.searchRemoveChoice(item);
|
||||
|
||||
|
63
src/js/select2/utils.js
vendored
63
src/js/select2/utils.js
vendored
@ -272,5 +272,68 @@ define([
|
||||
$element.append($nodes);
|
||||
};
|
||||
|
||||
// Cache objects in Utils.__cache instead of $.data
|
||||
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;
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ module('Data adapters - Array');
|
||||
var ArrayData = require('select2/data/array');
|
||||
var $ = require('jquery');
|
||||
var Options = require('select2/options');
|
||||
var Utils = require('select2/utils');
|
||||
|
||||
var UserDefinedType = function (id, text) {
|
||||
var self = this;
|
||||
@ -247,7 +248,7 @@ test('option tags can receive new data', function(assert) {
|
||||
});
|
||||
|
||||
assert.ok(
|
||||
$select.find(':selected').data('data').extra,
|
||||
Utils.GetData($select.find(':selected')[0], 'data').extra,
|
||||
'<option> default should have new data'
|
||||
);
|
||||
|
||||
@ -256,7 +257,7 @@ test('option tags can receive new data', function(assert) {
|
||||
});
|
||||
|
||||
assert.ok(
|
||||
$select.find(':selected').data('data').extra,
|
||||
Utils.GetData($select.find(':selected')[0], 'data').extra,
|
||||
'<option> One should have new data'
|
||||
);
|
||||
});
|
||||
|
29
tests/integration/jquery-calls.js
vendored
29
tests/integration/jquery-calls.js
vendored
@ -28,3 +28,32 @@ test('multiple elements with arguments works', function (assert) {
|
||||
'The call should also change the value on the second element'
|
||||
);
|
||||
});
|
||||
|
||||
test('initializes when jQuery $.data contains' +
|
||||
' cyclic reference', function (assert) {
|
||||
var $ = require('jquery');
|
||||
require('jquery.select2');
|
||||
|
||||
var $select = $(
|
||||
'<select>' +
|
||||
'<option>One</option>' +
|
||||
'<option>Two</option>' +
|
||||
'<option value="3" selected>Three</option>' +
|
||||
'</select>'
|
||||
);
|
||||
|
||||
// Add a circular reference object using jQuery.
|
||||
var recursiveObject = {};
|
||||
|
||||
recursiveObject.same = recursiveObject;
|
||||
|
||||
$select.data('same', recursiveObject);
|
||||
|
||||
$select.select2();
|
||||
|
||||
assert.equal(
|
||||
$select.val(),
|
||||
'3',
|
||||
'The option value should be pulled correctly'
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user