select2-rails 4.0.3 → 4.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +8 -2
  3. data/lib/select2-rails/version.rb +1 -1
  4. data/select2-rails.gemspec +1 -1
  5. data/vendor/assets/javascripts/select2-full.js +337 -170
  6. data/vendor/assets/javascripts/select2.js +333 -167
  7. data/vendor/assets/javascripts/select2_locale_af.js +3 -0
  8. data/vendor/assets/javascripts/select2_locale_ar.js +2 -2
  9. data/vendor/assets/javascripts/select2_locale_az.js +2 -2
  10. data/vendor/assets/javascripts/select2_locale_bg.js +2 -2
  11. data/vendor/assets/javascripts/select2_locale_bn.js +3 -0
  12. data/vendor/assets/javascripts/select2_locale_bs.js +3 -0
  13. data/vendor/assets/javascripts/select2_locale_ca.js +2 -2
  14. data/vendor/assets/javascripts/select2_locale_cs.js +2 -2
  15. data/vendor/assets/javascripts/select2_locale_da.js +2 -2
  16. data/vendor/assets/javascripts/select2_locale_de.js +2 -2
  17. data/vendor/assets/javascripts/select2_locale_dsb.js +3 -0
  18. data/vendor/assets/javascripts/select2_locale_el.js +2 -2
  19. data/vendor/assets/javascripts/select2_locale_en.js +2 -2
  20. data/vendor/assets/javascripts/select2_locale_es.js +2 -2
  21. data/vendor/assets/javascripts/select2_locale_et.js +2 -2
  22. data/vendor/assets/javascripts/select2_locale_eu.js +2 -2
  23. data/vendor/assets/javascripts/select2_locale_fa.js +2 -2
  24. data/vendor/assets/javascripts/select2_locale_fi.js +2 -2
  25. data/vendor/assets/javascripts/select2_locale_fr.js +2 -2
  26. data/vendor/assets/javascripts/select2_locale_gl.js +2 -2
  27. data/vendor/assets/javascripts/select2_locale_he.js +2 -2
  28. data/vendor/assets/javascripts/select2_locale_hi.js +2 -2
  29. data/vendor/assets/javascripts/select2_locale_hr.js +2 -2
  30. data/vendor/assets/javascripts/select2_locale_hsb.js +3 -0
  31. data/vendor/assets/javascripts/select2_locale_hu.js +2 -2
  32. data/vendor/assets/javascripts/select2_locale_hy.js +3 -0
  33. data/vendor/assets/javascripts/select2_locale_id.js +2 -2
  34. data/vendor/assets/javascripts/select2_locale_is.js +2 -2
  35. data/vendor/assets/javascripts/select2_locale_it.js +2 -2
  36. data/vendor/assets/javascripts/select2_locale_ja.js +2 -2
  37. data/vendor/assets/javascripts/select2_locale_ka.js +3 -0
  38. data/vendor/assets/javascripts/select2_locale_km.js +2 -2
  39. data/vendor/assets/javascripts/select2_locale_ko.js +2 -2
  40. data/vendor/assets/javascripts/select2_locale_lt.js +2 -2
  41. data/vendor/assets/javascripts/select2_locale_lv.js +2 -2
  42. data/vendor/assets/javascripts/select2_locale_mk.js +2 -2
  43. data/vendor/assets/javascripts/select2_locale_ms.js +2 -2
  44. data/vendor/assets/javascripts/select2_locale_nb.js +2 -2
  45. data/vendor/assets/javascripts/select2_locale_ne.js +3 -0
  46. data/vendor/assets/javascripts/select2_locale_nl.js +2 -2
  47. data/vendor/assets/javascripts/select2_locale_pl.js +2 -2
  48. data/vendor/assets/javascripts/select2_locale_ps.js +3 -0
  49. data/vendor/assets/javascripts/select2_locale_pt-BR.js +2 -2
  50. data/vendor/assets/javascripts/select2_locale_pt.js +2 -2
  51. data/vendor/assets/javascripts/select2_locale_ro.js +2 -2
  52. data/vendor/assets/javascripts/select2_locale_ru.js +2 -2
  53. data/vendor/assets/javascripts/select2_locale_sk.js +2 -2
  54. data/vendor/assets/javascripts/select2_locale_sl.js +3 -0
  55. data/vendor/assets/javascripts/select2_locale_sq.js +3 -0
  56. data/vendor/assets/javascripts/select2_locale_sr-Cyrl.js +2 -2
  57. data/vendor/assets/javascripts/select2_locale_sr.js +2 -2
  58. data/vendor/assets/javascripts/select2_locale_sv.js +2 -2
  59. data/vendor/assets/javascripts/select2_locale_th.js +2 -2
  60. data/vendor/assets/javascripts/select2_locale_tk.js +3 -0
  61. data/vendor/assets/javascripts/select2_locale_tr.js +2 -2
  62. data/vendor/assets/javascripts/select2_locale_uk.js +2 -2
  63. data/vendor/assets/javascripts/select2_locale_vi.js +2 -2
  64. data/vendor/assets/javascripts/select2_locale_zh-CN.js +2 -2
  65. data/vendor/assets/javascripts/select2_locale_zh-TW.js +2 -2
  66. data/vendor/assets/stylesheets/select2.css +6 -10
  67. metadata +18 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d128112240be89bfb1d73d73f957f94d983edb61
4
- data.tar.gz: dfdda950dd61f0fa042db94f1ab74914e7fc5b29
2
+ SHA256:
3
+ metadata.gz: 0e62325c4b81af2fab18f200949ff8e4df173d9d95e34fa4c988bfb5e1afef5e
4
+ data.tar.gz: cb301034bc178d7a151fa2c5c8d63b9d1cec33581c8df44c6ce2825fb87c5101
5
5
  SHA512:
6
- metadata.gz: ee533ad76c7a28de7f3365beba124c8d1810b7be557a2ffc5ac2474bbf262f1dead42b3f36cbeb5b09c597873f4def72e6a17a6b50cf8ebfb13244ebed0669ef
7
- data.tar.gz: 76db3585d883fce0d6d0047ce8aa32b48766fb4f0dea49dd21de862f3759939f054ec10c06dcfee7fe2ce1b1eda3188c2e24ebd26739be7088f0528a8598ab4d
6
+ metadata.gz: 6c4d09f316619c53667e77ec1c7ae37b2fda4b3d9d9b112befb70982db33783ae52636bb53ad0d5805991e9aa4c310e37a3c09ffeb037f15ad9616ed24ccccfc
7
+ data.tar.gz: 957a70bf102744fc67255486c8a6c0a6de8be278932d542f95b149b79fed2774ed46ebca23265acaeb614ac6405b04929573d3592dbcb5dfc76cac2c3888d9fe
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #Select2 for rails asset pipeline
1
+ # Select2 for rails asset pipeline
2
2
 
3
3
  [Select2](https://github.com/select2/select2) is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.
4
4
 
@@ -48,9 +48,15 @@ Add the following to your `app/assets/javascripts/application.js`:
48
48
 
49
49
  //= require select2_locale_"any possible language"
50
50
 
51
+ To apply the language, pass whatever language you'd like to use to the [`language`](https://select2.github.io/examples.html#language) option when initializing Select2:
52
+
53
+ $( "#dropdown" ).select2({
54
+ language: "zh-TW"
55
+ });
56
+
51
57
  Possible languages:
52
58
 
53
- ar, az, bg, ca, cs, da, de, el, en, es, et, eu, fa, fi, fr, gl, he, hi, hr, hu, id, is, it, ja, km, ko, lt, lv, mk, ms, nb, nl, pl, pt, pt-BR, ro, ru, sk, sr, sr-Cyrl, sv, th, tr, uk, vi, zh-CN, zh-TW
59
+ af, ar, az, bg, bn, bs, ca, cs, da, de, dsb, el, en, es, et, eu, fa, fi, fr, gl, he, hi, hr, hsb, hu, hy, id, is, it, ja, ka, km, ko, lt, lv, mk, ms, nb, ne, nl, pl, ps, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-Cyrl, sv, th, tk, tr, uk, vi, zh-CN, zh-TW
54
60
 
55
61
  ## Example
56
62
  Code [here](https://github.com/argerim/select_2_example)
@@ -1,5 +1,5 @@
1
1
  module Select2
2
2
  module Rails
3
- VERSION = '4.0.3'
3
+ VERSION = '4.0.8'
4
4
  end
5
5
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ["lib"]
17
17
 
18
- s.add_dependency "thor", "~> 0.14"
18
+ s.add_development_dependency "thor", "~> 1"
19
19
  s.add_development_dependency "bundler", "~> 1.0"
20
20
  s.add_development_dependency "rails", ">= 3.0"
21
21
  s.add_development_dependency "httpclient", "~> 2.2"
@@ -1,27 +1,41 @@
1
1
  /*!
2
- * Select2 4.0.3
2
+ * Select2 4.0.8
3
3
  * https://select2.github.io
4
4
  *
5
5
  * Released under the MIT license
6
6
  * https://github.com/select2/select2/blob/master/LICENSE.md
7
7
  */
8
- (function (factory) {
8
+ ;(function (factory) {
9
9
  if (typeof define === 'function' && define.amd) {
10
10
  // AMD. Register as an anonymous module.
11
11
  define(['jquery'], factory);
12
- } else if (typeof exports === 'object') {
12
+ } else if (typeof module === 'object' && module.exports) {
13
13
  // Node/CommonJS
14
- factory(require('jquery'));
14
+ module.exports = function (root, jQuery) {
15
+ if (jQuery === undefined) {
16
+ // require('jQuery') returns a factory that requires window to
17
+ // build a jQuery instance, we normalize how we use modules
18
+ // that require this pattern but the window provided is a noop
19
+ // if it's defined (how jquery works)
20
+ if (typeof window !== 'undefined') {
21
+ jQuery = require('jquery');
22
+ }
23
+ else {
24
+ jQuery = require('jquery')(root);
25
+ }
26
+ }
27
+ factory(jQuery);
28
+ return jQuery;
29
+ };
15
30
  } else {
16
31
  // Browser globals
17
32
  factory(jQuery);
18
33
  }
19
- }(function (jQuery) {
34
+ } (function (jQuery) {
20
35
  // This is needed so we can catch the AMD loader configuration and use it
21
36
  // The inner file should be wrapped (by `banner.start.js`) in a function that
22
37
  // returns the AMD loader references.
23
- var S2 =
24
- (function () {
38
+ var S2 =(function () {
25
39
  // Restore the Select2 AMD loader so it can be used
26
40
  // Needed mostly in the language files, where the loader is not inserted
27
41
  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
@@ -30,13 +44,11 @@
30
44
  var S2;(function () { if (!S2 || !S2.requirejs) {
31
45
  if (!S2) { S2 = {}; } else { require = S2; }
32
46
  /**
33
- * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
34
- * Available via the MIT or new BSD license.
35
- * see: http://github.com/jrburke/almond for details
47
+ * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
48
+ * Released under MIT license, http://github.com/requirejs/almond/LICENSE
36
49
  */
37
50
  //Going sloppy to avoid 'use strict' string cost, but strict practices should
38
51
  //be followed.
39
- /*jslint sloppy: true */
40
52
  /*global setTimeout: false */
41
53
 
42
54
  var requirejs, require, define;
@@ -64,60 +76,58 @@ var requirejs, require, define;
64
76
  */
65
77
  function normalize(name, baseName) {
66
78
  var nameParts, nameSegment, mapValue, foundMap, lastIndex,
67
- foundI, foundStarMap, starI, i, j, part,
79
+ foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
68
80
  baseParts = baseName && baseName.split("/"),
69
81
  map = config.map,
70
82
  starMap = (map && map['*']) || {};
71
83
 
72
84
  //Adjust any relative paths.
73
- if (name && name.charAt(0) === ".") {
74
- //If have a base name, try to normalize against it,
75
- //otherwise, assume it is a top-level require that will
76
- //be relative to baseUrl in the end.
77
- if (baseName) {
78
- name = name.split('/');
79
- lastIndex = name.length - 1;
80
-
81
- // Node .js allowance:
82
- if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
83
- name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
84
- }
85
+ if (name) {
86
+ name = name.split('/');
87
+ lastIndex = name.length - 1;
88
+
89
+ // If wanting node ID compatibility, strip .js from end
90
+ // of IDs. Have to do this here, and not in nameToUrl
91
+ // because node allows either .js or non .js to map
92
+ // to same file.
93
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
94
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
95
+ }
85
96
 
86
- //Lop off the last part of baseParts, so that . matches the
87
- //"directory" and not name of the baseName's module. For instance,
88
- //baseName of "one/two/three", maps to "one/two/three.js", but we
89
- //want the directory, "one/two" for this normalization.
90
- name = baseParts.slice(0, baseParts.length - 1).concat(name);
91
-
92
- //start trimDots
93
- for (i = 0; i < name.length; i += 1) {
94
- part = name[i];
95
- if (part === ".") {
96
- name.splice(i, 1);
97
- i -= 1;
98
- } else if (part === "..") {
99
- if (i === 1 && (name[2] === '..' || name[0] === '..')) {
100
- //End of the line. Keep at least one non-dot
101
- //path segment at the front so it can be mapped
102
- //correctly to disk. Otherwise, there is likely
103
- //no path mapping for a path starting with '..'.
104
- //This can still fail, but catches the most reasonable
105
- //uses of ..
106
- break;
107
- } else if (i > 0) {
108
- name.splice(i - 1, 2);
109
- i -= 2;
110
- }
97
+ // Starts with a '.' so need the baseName
98
+ if (name[0].charAt(0) === '.' && baseParts) {
99
+ //Convert baseName to array, and lop off the last part,
100
+ //so that . matches that 'directory' and not name of the baseName's
101
+ //module. For instance, baseName of 'one/two/three', maps to
102
+ //'one/two/three.js', but we want the directory, 'one/two' for
103
+ //this normalization.
104
+ normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
105
+ name = normalizedBaseParts.concat(name);
106
+ }
107
+
108
+ //start trimDots
109
+ for (i = 0; i < name.length; i++) {
110
+ part = name[i];
111
+ if (part === '.') {
112
+ name.splice(i, 1);
113
+ i -= 1;
114
+ } else if (part === '..') {
115
+ // If at the start, or previous value is still ..,
116
+ // keep them so that when converted to a path it may
117
+ // still work when converted to a path, even though
118
+ // as an ID it is less than ideal. In larger point
119
+ // releases, may be better to just kick out an error.
120
+ if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
121
+ continue;
122
+ } else if (i > 0) {
123
+ name.splice(i - 1, 2);
124
+ i -= 2;
111
125
  }
112
126
  }
113
- //end trimDots
114
-
115
- name = name.join("/");
116
- } else if (name.indexOf('./') === 0) {
117
- // No baseName, so this is ID is resolved relative
118
- // to baseUrl, pull off the leading dot.
119
- name = name.substring(2);
120
127
  }
128
+ //end trimDots
129
+
130
+ name = name.join('/');
121
131
  }
122
132
 
123
133
  //Apply map config if available.
@@ -230,32 +240,39 @@ var requirejs, require, define;
230
240
  return [prefix, name];
231
241
  }
232
242
 
243
+ //Creates a parts array for a relName where first part is plugin ID,
244
+ //second part is resource ID. Assumes relName has already been normalized.
245
+ function makeRelParts(relName) {
246
+ return relName ? splitPrefix(relName) : [];
247
+ }
248
+
233
249
  /**
234
250
  * Makes a name map, normalizing the name, and using a plugin
235
251
  * for normalization if necessary. Grabs a ref to plugin
236
252
  * too, as an optimization.
237
253
  */
238
- makeMap = function (name, relName) {
254
+ makeMap = function (name, relParts) {
239
255
  var plugin,
240
256
  parts = splitPrefix(name),
241
- prefix = parts[0];
257
+ prefix = parts[0],
258
+ relResourceName = relParts[1];
242
259
 
243
260
  name = parts[1];
244
261
 
245
262
  if (prefix) {
246
- prefix = normalize(prefix, relName);
263
+ prefix = normalize(prefix, relResourceName);
247
264
  plugin = callDep(prefix);
248
265
  }
249
266
 
250
267
  //Normalize according
251
268
  if (prefix) {
252
269
  if (plugin && plugin.normalize) {
253
- name = plugin.normalize(name, makeNormalize(relName));
270
+ name = plugin.normalize(name, makeNormalize(relResourceName));
254
271
  } else {
255
- name = normalize(name, relName);
272
+ name = normalize(name, relResourceName);
256
273
  }
257
274
  } else {
258
- name = normalize(name, relName);
275
+ name = normalize(name, relResourceName);
259
276
  parts = splitPrefix(name);
260
277
  prefix = parts[0];
261
278
  name = parts[1];
@@ -302,13 +319,14 @@ var requirejs, require, define;
302
319
  };
303
320
 
304
321
  main = function (name, deps, callback, relName) {
305
- var cjsModule, depName, ret, map, i,
322
+ var cjsModule, depName, ret, map, i, relParts,
306
323
  args = [],
307
324
  callbackType = typeof callback,
308
325
  usingExports;
309
326
 
310
327
  //Use name if no relName
311
328
  relName = relName || name;
329
+ relParts = makeRelParts(relName);
312
330
 
313
331
  //Call the callback to define the module, if necessary.
314
332
  if (callbackType === 'undefined' || callbackType === 'function') {
@@ -317,7 +335,7 @@ var requirejs, require, define;
317
335
  //Default to [require, exports, module] if no deps
318
336
  deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
319
337
  for (i = 0; i < deps.length; i += 1) {
320
- map = makeMap(deps[i], relName);
338
+ map = makeMap(deps[i], relParts);
321
339
  depName = map.f;
322
340
 
323
341
  //Fast path CommonJS standard dependencies.
@@ -373,7 +391,7 @@ var requirejs, require, define;
373
391
  //deps arg is the module name, and second arg (if passed)
374
392
  //is just the relName.
375
393
  //Normalize module name, if it contains . or ..
376
- return callDep(makeMap(deps, callback).f);
394
+ return callDep(makeMap(deps, makeRelParts(callback)).f);
377
395
  } else if (!deps.splice) {
378
396
  //deps is a config object, not an array.
379
397
  config = deps;
@@ -556,10 +574,10 @@ S2.define('select2/utils',[
556
574
  DecoratedClass.prototype = new ctr();
557
575
 
558
576
  for (var m = 0; m < superMethods.length; m++) {
559
- var superMethod = superMethods[m];
577
+ var superMethod = superMethods[m];
560
578
 
561
- DecoratedClass.prototype[superMethod] =
562
- SuperClass.prototype[superMethod];
579
+ DecoratedClass.prototype[superMethod] =
580
+ SuperClass.prototype[superMethod];
563
581
  }
564
582
 
565
583
  var calledMethod = function (methodName) {
@@ -754,6 +772,68 @@ S2.define('select2/utils',[
754
772
  $element.append($nodes);
755
773
  };
756
774
 
775
+ // Cache objects in Utils.__cache instead of $.data (see #4346)
776
+ Utils.__cache = {};
777
+
778
+ var id = 0;
779
+ Utils.GetUniqueElementId = function (element) {
780
+ // Get a unique element Id. If element has no id,
781
+ // creates a new unique number, stores it in the id
782
+ // attribute and returns the new id.
783
+ // If an id already exists, it simply returns it.
784
+
785
+ var select2Id = element.getAttribute('data-select2-id');
786
+ if (select2Id == null) {
787
+ // If element has id, use it.
788
+ if (element.id) {
789
+ select2Id = element.id;
790
+ element.setAttribute('data-select2-id', select2Id);
791
+ } else {
792
+ element.setAttribute('data-select2-id', ++id);
793
+ select2Id = id.toString();
794
+ }
795
+ }
796
+ return select2Id;
797
+ };
798
+
799
+ Utils.StoreData = function (element, name, value) {
800
+ // Stores an item in the cache for a specified element.
801
+ // name is the cache key.
802
+ var id = Utils.GetUniqueElementId(element);
803
+ if (!Utils.__cache[id]) {
804
+ Utils.__cache[id] = {};
805
+ }
806
+
807
+ Utils.__cache[id][name] = value;
808
+ };
809
+
810
+ Utils.GetData = function (element, name) {
811
+ // Retrieves a value from the cache by its key (name)
812
+ // name is optional. If no name specified, return
813
+ // all cache items for the specified element.
814
+ // and for a specified element.
815
+ var id = Utils.GetUniqueElementId(element);
816
+ if (name) {
817
+ if (Utils.__cache[id]) {
818
+ if (Utils.__cache[id][name] != null) {
819
+ return Utils.__cache[id][name];
820
+ }
821
+ return $(element).data(name); // Fallback to HTML5 data attribs.
822
+ }
823
+ return $(element).data(name); // Fallback to HTML5 data attribs.
824
+ } else {
825
+ return Utils.__cache[id];
826
+ }
827
+ };
828
+
829
+ Utils.RemoveData = function (element) {
830
+ // Removes all cached items for a specified element.
831
+ var id = Utils.GetUniqueElementId(element);
832
+ if (Utils.__cache[id] != null) {
833
+ delete Utils.__cache[id];
834
+ }
835
+ };
836
+
757
837
  return Utils;
758
838
  });
759
839
 
@@ -889,7 +969,7 @@ S2.define('select2/results',[
889
969
  $options.each(function () {
890
970
  var $option = $(this);
891
971
 
892
- var item = $.data(this, 'data');
972
+ var item = Utils.GetData(this, 'data');
893
973
 
894
974
  // id needs to be converted to a string when comparing
895
975
  var id = '' + item.id;
@@ -934,7 +1014,12 @@ S2.define('select2/results',[
934
1014
  'aria-selected': 'false'
935
1015
  };
936
1016
 
937
- if (data.disabled) {
1017
+ var matches = window.Element.prototype.matches ||
1018
+ window.Element.prototype.msMatchesSelector ||
1019
+ window.Element.prototype.webkitMatchesSelector;
1020
+
1021
+ if ((data.element != null && matches.call(data.element, ':disabled')) ||
1022
+ (data.element == null && data.disabled)) {
938
1023
  delete attrs['aria-selected'];
939
1024
  attrs['aria-disabled'] = 'true';
940
1025
  }
@@ -994,7 +1079,7 @@ S2.define('select2/results',[
994
1079
  this.template(data, option);
995
1080
  }
996
1081
 
997
- $.data(option, 'data', data);
1082
+ Utils.StoreData(option, 'data', data);
998
1083
 
999
1084
  return option;
1000
1085
  };
@@ -1035,7 +1120,10 @@ S2.define('select2/results',[
1035
1120
  }
1036
1121
 
1037
1122
  self.setClasses();
1038
- self.highlightFirstItem();
1123
+
1124
+ if (self.options.get('scrollAfterSelect')) {
1125
+ self.highlightFirstItem();
1126
+ }
1039
1127
  });
1040
1128
 
1041
1129
  container.on('unselect', function () {
@@ -1044,7 +1132,10 @@ S2.define('select2/results',[
1044
1132
  }
1045
1133
 
1046
1134
  self.setClasses();
1047
- self.highlightFirstItem();
1135
+
1136
+ if (self.options.get('scrollAfterSelect')) {
1137
+ self.highlightFirstItem();
1138
+ }
1048
1139
  });
1049
1140
 
1050
1141
  container.on('open', function () {
@@ -1080,7 +1171,7 @@ S2.define('select2/results',[
1080
1171
  return;
1081
1172
  }
1082
1173
 
1083
- var data = $highlighted.data('data');
1174
+ var data = Utils.GetData($highlighted[0], 'data');
1084
1175
 
1085
1176
  if ($highlighted.attr('aria-selected') == 'true') {
1086
1177
  self.trigger('close', {});
@@ -1098,8 +1189,9 @@ S2.define('select2/results',[
1098
1189
 
1099
1190
  var currentIndex = $options.index($highlighted);
1100
1191
 
1101
- // If we are already at te top, don't move further
1102
- if (currentIndex === 0) {
1192
+ // If we are already at the top, don't move further
1193
+ // If no options, currentIndex will be -1
1194
+ if (currentIndex <= 0) {
1103
1195
  return;
1104
1196
  }
1105
1197
 
@@ -1192,7 +1284,7 @@ S2.define('select2/results',[
1192
1284
  function (evt) {
1193
1285
  var $this = $(this);
1194
1286
 
1195
- var data = $this.data('data');
1287
+ var data = Utils.GetData(this, 'data');
1196
1288
 
1197
1289
  if ($this.attr('aria-selected') === 'true') {
1198
1290
  if (self.options.get('multiple')) {
@@ -1215,7 +1307,7 @@ S2.define('select2/results',[
1215
1307
 
1216
1308
  this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1217
1309
  function (evt) {
1218
- var data = $(this).data('data');
1310
+ var data = Utils.GetData(this, 'data');
1219
1311
 
1220
1312
  self.getHighlightedResults()
1221
1313
  .removeClass('select2-results__option--highlighted');
@@ -1330,8 +1422,8 @@ S2.define('select2/selection/base',[
1330
1422
 
1331
1423
  this._tabindex = 0;
1332
1424
 
1333
- if (this.$element.data('old-tabindex') != null) {
1334
- this._tabindex = this.$element.data('old-tabindex');
1425
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
1426
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
1335
1427
  } else if (this.$element.attr('tabindex') != null) {
1336
1428
  this._tabindex = this.$element.attr('tabindex');
1337
1429
  }
@@ -1390,7 +1482,7 @@ S2.define('select2/selection/base',[
1390
1482
  self.$selection.removeAttr('aria-activedescendant');
1391
1483
  self.$selection.removeAttr('aria-owns');
1392
1484
 
1393
- self.$selection.focus();
1485
+ self.$selection.trigger('focus');
1394
1486
 
1395
1487
  self._detachCloseHandler(container);
1396
1488
  });
@@ -1439,7 +1531,7 @@ S2.define('select2/selection/base',[
1439
1531
  return;
1440
1532
  }
1441
1533
 
1442
- var $element = $this.data('element');
1534
+ var $element = Utils.GetData(this, 'element');
1443
1535
 
1444
1536
  $element.select2('close');
1445
1537
  });
@@ -1500,7 +1592,10 @@ S2.define('select2/selection/single',[
1500
1592
 
1501
1593
  var id = container.id + '-container';
1502
1594
 
1503
- this.$selection.find('.select2-selection__rendered').attr('id', id);
1595
+ this.$selection.find('.select2-selection__rendered')
1596
+ .attr('id', id)
1597
+ .attr('role', 'textbox')
1598
+ .attr('aria-readonly', 'true');
1504
1599
  this.$selection.attr('aria-labelledby', id);
1505
1600
 
1506
1601
  this.$selection.on('mousedown', function (evt) {
@@ -1524,17 +1619,15 @@ S2.define('select2/selection/single',[
1524
1619
 
1525
1620
  container.on('focus', function (evt) {
1526
1621
  if (!container.isOpen()) {
1527
- self.$selection.focus();
1622
+ self.$selection.trigger('focus');
1528
1623
  }
1529
1624
  });
1530
-
1531
- container.on('selection:update', function (params) {
1532
- self.update(params.data);
1533
- });
1534
1625
  };
1535
1626
 
1536
1627
  SingleSelection.prototype.clear = function () {
1537
- this.$selection.find('.select2-selection__rendered').empty();
1628
+ var $rendered = this.$selection.find('.select2-selection__rendered');
1629
+ $rendered.empty();
1630
+ $rendered.removeAttr('title'); // clear tooltip on empty
1538
1631
  };
1539
1632
 
1540
1633
  SingleSelection.prototype.display = function (data, container) {
@@ -1560,7 +1653,7 @@ S2.define('select2/selection/single',[
1560
1653
  var formatted = this.display(selection, $rendered);
1561
1654
 
1562
1655
  $rendered.empty().append(formatted);
1563
- $rendered.prop('title', selection.title || selection.text);
1656
+ $rendered.attr('title', selection.title || selection.text);
1564
1657
  };
1565
1658
 
1566
1659
  return SingleSelection;
@@ -1612,7 +1705,7 @@ S2.define('select2/selection/multiple',[
1612
1705
  var $remove = $(this);
1613
1706
  var $selection = $remove.parent();
1614
1707
 
1615
- var data = $selection.data('data');
1708
+ var data = Utils.GetData($selection[0], 'data');
1616
1709
 
1617
1710
  self.trigger('unselect', {
1618
1711
  originalEvent: evt,
@@ -1623,7 +1716,9 @@ S2.define('select2/selection/multiple',[
1623
1716
  };
1624
1717
 
1625
1718
  MultipleSelection.prototype.clear = function () {
1626
- this.$selection.find('.select2-selection__rendered').empty();
1719
+ var $rendered = this.$selection.find('.select2-selection__rendered');
1720
+ $rendered.empty();
1721
+ $rendered.removeAttr('title');
1627
1722
  };
1628
1723
 
1629
1724
  MultipleSelection.prototype.display = function (data, container) {
@@ -1661,9 +1756,9 @@ S2.define('select2/selection/multiple',[
1661
1756
  var formatted = this.display(selection, $selection);
1662
1757
 
1663
1758
  $selection.append(formatted);
1664
- $selection.prop('title', selection.title || selection.text);
1759
+ $selection.attr('title', selection.title || selection.text);
1665
1760
 
1666
- $selection.data('data', selection);
1761
+ Utils.StoreData($selection[0], 'data', selection);
1667
1762
 
1668
1763
  $selections.push($selection);
1669
1764
  }
@@ -1728,8 +1823,9 @@ S2.define('select2/selection/placeholder',[
1728
1823
 
1729
1824
  S2.define('select2/selection/allowClear',[
1730
1825
  'jquery',
1731
- '../keys'
1732
- ], function ($, KEYS) {
1826
+ '../keys',
1827
+ '../utils'
1828
+ ], function ($, KEYS, Utils) {
1733
1829
  function AllowClear () { }
1734
1830
 
1735
1831
  AllowClear.prototype.bind = function (decorated, container, $container) {
@@ -1771,10 +1867,22 @@ S2.define('select2/selection/allowClear',[
1771
1867
 
1772
1868
  evt.stopPropagation();
1773
1869
 
1774
- var data = $clear.data('data');
1870
+ var data = Utils.GetData($clear[0], 'data');
1871
+
1872
+ var previousVal = this.$element.val();
1873
+ this.$element.val(this.placeholder.id);
1874
+
1875
+ var unselectData = {
1876
+ data: data
1877
+ };
1878
+ this.trigger('clear', unselectData);
1879
+ if (unselectData.prevented) {
1880
+ this.$element.val(previousVal);
1881
+ return;
1882
+ }
1775
1883
 
1776
1884
  for (var d = 0; d < data.length; d++) {
1777
- var unselectData = {
1885
+ unselectData = {
1778
1886
  data: data[d]
1779
1887
  };
1780
1888
 
@@ -1784,11 +1892,12 @@ S2.define('select2/selection/allowClear',[
1784
1892
 
1785
1893
  // If the event was prevented, don't clear it out.
1786
1894
  if (unselectData.prevented) {
1895
+ this.$element.val(previousVal);
1787
1896
  return;
1788
1897
  }
1789
1898
  }
1790
1899
 
1791
- this.$element.val(this.placeholder.id).trigger('change');
1900
+ this.$element.trigger('change');
1792
1901
 
1793
1902
  this.trigger('toggle', {});
1794
1903
  };
@@ -1811,12 +1920,14 @@ S2.define('select2/selection/allowClear',[
1811
1920
  return;
1812
1921
  }
1813
1922
 
1923
+ var removeAll = this.options.get('translations').get('removeAllItems');
1924
+
1814
1925
  var $remove = $(
1815
- '<span class="select2-selection__clear">' +
1926
+ '<span class="select2-selection__clear" title="' + removeAll() +'">' +
1816
1927
  '&times;' +
1817
1928
  '</span>'
1818
1929
  );
1819
- $remove.data('data', data);
1930
+ Utils.StoreData($remove[0], 'data', data);
1820
1931
 
1821
1932
  this.$selection.find('.select2-selection__rendered').prepend($remove);
1822
1933
  };
@@ -1837,7 +1948,7 @@ S2.define('select2/selection/search',[
1837
1948
  var $search = $(
1838
1949
  '<li class="select2-search select2-search--inline">' +
1839
1950
  '<input class="select2-search__field" type="search" tabindex="-1"' +
1840
- ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
1951
+ ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1841
1952
  ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
1842
1953
  '</li>'
1843
1954
  );
@@ -1907,7 +2018,7 @@ S2.define('select2/selection/search',[
1907
2018
  .prev('.select2-selection__choice');
1908
2019
 
1909
2020
  if ($previousChoice.length > 0) {
1910
- var item = $previousChoice.data('data');
2021
+ var item = Utils.GetData($previousChoice[0], 'data');
1911
2022
 
1912
2023
  self.searchRemoveChoice(item);
1913
2024
 
@@ -2001,7 +2112,7 @@ S2.define('select2/selection/search',[
2001
2112
 
2002
2113
  this.resizeSearch();
2003
2114
  if (searchHadFocus) {
2004
- this.$search.focus();
2115
+ this.$search.trigger('focus');
2005
2116
  }
2006
2117
  };
2007
2118
 
@@ -2058,10 +2169,13 @@ S2.define('select2/selection/eventRelay',[
2058
2169
  'open', 'opening',
2059
2170
  'close', 'closing',
2060
2171
  'select', 'selecting',
2061
- 'unselect', 'unselecting'
2172
+ 'unselect', 'unselecting',
2173
+ 'clear', 'clearing'
2062
2174
  ];
2063
2175
 
2064
- var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
2176
+ var preventableEvents = [
2177
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
2178
+ ];
2065
2179
 
2066
2180
  decorated.call(this, container, $container);
2067
2181
 
@@ -2394,6 +2508,7 @@ S2.define('select2/diacritics',[
2394
2508
  '\u019F': 'O',
2395
2509
  '\uA74A': 'O',
2396
2510
  '\uA74C': 'O',
2511
+ '\u0152': 'OE',
2397
2512
  '\u01A2': 'OI',
2398
2513
  '\uA74E': 'OO',
2399
2514
  '\u0222': 'OU',
@@ -2803,6 +2918,7 @@ S2.define('select2/diacritics',[
2803
2918
  '\uA74B': 'o',
2804
2919
  '\uA74D': 'o',
2805
2920
  '\u0275': 'o',
2921
+ '\u0153': 'oe',
2806
2922
  '\u01A3': 'oi',
2807
2923
  '\u0223': 'ou',
2808
2924
  '\uA74F': 'oo',
@@ -2971,8 +3087,9 @@ S2.define('select2/diacritics',[
2971
3087
  '\u03CD': '\u03C5',
2972
3088
  '\u03CB': '\u03C5',
2973
3089
  '\u03B0': '\u03C5',
2974
- '\u03C9': '\u03C9',
2975
- '\u03C2': '\u03C3'
3090
+ '\u03CE': '\u03C9',
3091
+ '\u03C2': '\u03C3',
3092
+ '\u2019': '\''
2976
3093
  };
2977
3094
 
2978
3095
  return diacritics;
@@ -3140,7 +3257,7 @@ S2.define('select2/data/select',[
3140
3257
  // Remove anything added to child elements
3141
3258
  this.$element.find('*').each(function () {
3142
3259
  // Remove any custom data set by Select2
3143
- $.removeData(this, 'data');
3260
+ Utils.RemoveData(this);
3144
3261
  });
3145
3262
  };
3146
3263
 
@@ -3191,7 +3308,7 @@ S2.define('select2/data/select',[
3191
3308
  }
3192
3309
  }
3193
3310
 
3194
- if (data.id) {
3311
+ if (data.id !== undefined) {
3195
3312
  option.value = data.id;
3196
3313
  }
3197
3314
 
@@ -3213,7 +3330,7 @@ S2.define('select2/data/select',[
3213
3330
  normalizedData.element = option;
3214
3331
 
3215
3332
  // Override the option's data with the combined data
3216
- $.data(option, 'data', normalizedData);
3333
+ Utils.StoreData(option, 'data', normalizedData);
3217
3334
 
3218
3335
  return $option;
3219
3336
  };
@@ -3221,7 +3338,7 @@ S2.define('select2/data/select',[
3221
3338
  SelectAdapter.prototype.item = function ($option) {
3222
3339
  var data = {};
3223
3340
 
3224
- data = $.data($option[0], 'data');
3341
+ data = Utils.GetData($option[0], 'data');
3225
3342
 
3226
3343
  if (data != null) {
3227
3344
  return data;
@@ -3259,13 +3376,13 @@ S2.define('select2/data/select',[
3259
3376
  data = this._normalizeItem(data);
3260
3377
  data.element = $option[0];
3261
3378
 
3262
- $.data($option[0], 'data', data);
3379
+ Utils.StoreData($option[0], 'data', data);
3263
3380
 
3264
3381
  return data;
3265
3382
  };
3266
3383
 
3267
3384
  SelectAdapter.prototype._normalizeItem = function (item) {
3268
- if (!$.isPlainObject(item)) {
3385
+ if (item !== Object(item)) {
3269
3386
  item = {
3270
3387
  id: item,
3271
3388
  text: item
@@ -3469,7 +3586,8 @@ S2.define('select2/data/ajax',[
3469
3586
  }, function () {
3470
3587
  // Attempt to detect if a request was aborted
3471
3588
  // Only works if the transport exposes a status property
3472
- if ($request.status && $request.status === '0') {
3589
+ if ('status' in $request &&
3590
+ ($request.status === 0 || $request.status === '0')) {
3473
3591
  return;
3474
3592
  }
3475
3593
 
@@ -3550,7 +3668,10 @@ S2.define('select2/data/tags',[
3550
3668
  }, true)
3551
3669
  );
3552
3670
 
3553
- var checkText = option.text === params.term;
3671
+ var optionText = (option.text || '').toUpperCase();
3672
+ var paramsTerm = (params.term || '').toUpperCase();
3673
+
3674
+ var checkText = optionText === paramsTerm;
3554
3675
 
3555
3676
  if (checkText || checkChildren) {
3556
3677
  if (child) {
@@ -3681,7 +3802,7 @@ S2.define('select2/data/tokenizer',[
3681
3802
  // Replace the search term if we have the search box
3682
3803
  if (this.$search.length) {
3683
3804
  this.$search.val(tokenData.term);
3684
- this.$search.focus();
3805
+ this.$search.trigger('focus');
3685
3806
  }
3686
3807
 
3687
3808
  params.term = tokenData.term;
@@ -3865,7 +3986,7 @@ S2.define('select2/dropdown',[
3865
3986
  };
3866
3987
 
3867
3988
  Dropdown.prototype.position = function ($dropdown, $container) {
3868
- // Should be implmented in subclasses
3989
+ // Should be implemented in subclasses
3869
3990
  };
3870
3991
 
3871
3992
  Dropdown.prototype.destroy = function () {
@@ -3888,7 +4009,7 @@ S2.define('select2/dropdown/search',[
3888
4009
  var $search = $(
3889
4010
  '<span class="select2-search select2-search--dropdown">' +
3890
4011
  '<input class="select2-search__field" type="search" tabindex="-1"' +
3891
- ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
4012
+ ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
3892
4013
  ' spellcheck="false" role="textbox" />' +
3893
4014
  '</span>'
3894
4015
  );
@@ -3927,10 +4048,10 @@ S2.define('select2/dropdown/search',[
3927
4048
  container.on('open', function () {
3928
4049
  self.$search.attr('tabindex', 0);
3929
4050
 
3930
- self.$search.focus();
4051
+ self.$search.trigger('focus');
3931
4052
 
3932
4053
  window.setTimeout(function () {
3933
- self.$search.focus();
4054
+ self.$search.trigger('focus');
3934
4055
  }, 0);
3935
4056
  });
3936
4057
 
@@ -3938,11 +4059,12 @@ S2.define('select2/dropdown/search',[
3938
4059
  self.$search.attr('tabindex', -1);
3939
4060
 
3940
4061
  self.$search.val('');
4062
+ self.$search.trigger('blur');
3941
4063
  });
3942
4064
 
3943
4065
  container.on('focus', function () {
3944
- if (container.isOpen()) {
3945
- self.$search.focus();
4066
+ if (!container.isOpen()) {
4067
+ self.$search.trigger('focus');
3946
4068
  }
3947
4069
  });
3948
4070
 
@@ -4041,6 +4163,7 @@ S2.define('select2/dropdown/infiniteScroll',[
4041
4163
 
4042
4164
  if (this.showLoadingMore(data)) {
4043
4165
  this.$results.append(this.$loadingMore);
4166
+ this.loadMoreIfNeeded();
4044
4167
  }
4045
4168
  };
4046
4169
 
@@ -4059,25 +4182,27 @@ S2.define('select2/dropdown/infiniteScroll',[
4059
4182
  self.loading = true;
4060
4183
  });
4061
4184
 
4062
- this.$results.on('scroll', function () {
4063
- var isLoadMoreVisible = $.contains(
4064
- document.documentElement,
4065
- self.$loadingMore[0]
4066
- );
4185
+ this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
4186
+ };
4067
4187
 
4068
- if (self.loading || !isLoadMoreVisible) {
4069
- return;
4070
- }
4188
+ InfiniteScroll.prototype.loadMoreIfNeeded = function () {
4189
+ var isLoadMoreVisible = $.contains(
4190
+ document.documentElement,
4191
+ this.$loadingMore[0]
4192
+ );
4071
4193
 
4072
- var currentOffset = self.$results.offset().top +
4073
- self.$results.outerHeight(false);
4074
- var loadingMoreOffset = self.$loadingMore.offset().top +
4075
- self.$loadingMore.outerHeight(false);
4194
+ if (this.loading || !isLoadMoreVisible) {
4195
+ return;
4196
+ }
4076
4197
 
4077
- if (currentOffset + 50 >= loadingMoreOffset) {
4078
- self.loadMore();
4079
- }
4080
- });
4198
+ var currentOffset = this.$results.offset().top +
4199
+ this.$results.outerHeight(false);
4200
+ var loadingMoreOffset = this.$loadingMore.offset().top +
4201
+ this.$loadingMore.outerHeight(false);
4202
+
4203
+ if (currentOffset + 50 >= loadingMoreOffset) {
4204
+ this.loadMore();
4205
+ }
4081
4206
  };
4082
4207
 
4083
4208
  InfiniteScroll.prototype.loadMore = function () {
@@ -4203,14 +4328,14 @@ S2.define('select2/dropdown/attachBody',[
4203
4328
 
4204
4329
  var $watchers = this.$container.parents().filter(Utils.hasScroll);
4205
4330
  $watchers.each(function () {
4206
- $(this).data('select2-scroll-position', {
4331
+ Utils.StoreData(this, 'select2-scroll-position', {
4207
4332
  x: $(this).scrollLeft(),
4208
4333
  y: $(this).scrollTop()
4209
4334
  });
4210
4335
  });
4211
4336
 
4212
4337
  $watchers.on(scrollEvent, function (ev) {
4213
- var position = $(this).data('select2-scroll-position');
4338
+ var position = Utils.GetData(this, 'select2-scroll-position');
4214
4339
  $(this).scrollTop(position.y);
4215
4340
  });
4216
4341
 
@@ -4269,10 +4394,10 @@ S2.define('select2/dropdown/attachBody',[
4269
4394
  top: container.bottom
4270
4395
  };
4271
4396
 
4272
- // Determine what the parent element is to use for calciulating the offset
4397
+ // Determine what the parent element is to use for calculating the offset
4273
4398
  var $offsetParent = this.$dropdownParent;
4274
4399
 
4275
- // For statically positoned elements, we need to get the element
4400
+ // For statically positioned elements, we need to get the element
4276
4401
  // that is determining the offset
4277
4402
  if ($offsetParent.css('position') === 'static') {
4278
4403
  $offsetParent = $offsetParent.offsetParent();
@@ -4375,8 +4500,8 @@ S2.define('select2/dropdown/minimumResultsForSearch',[
4375
4500
  });
4376
4501
 
4377
4502
  S2.define('select2/dropdown/selectOnClose',[
4378
-
4379
- ], function () {
4503
+ '../utils'
4504
+ ], function (Utils) {
4380
4505
  function SelectOnClose () { }
4381
4506
 
4382
4507
  SelectOnClose.prototype.bind = function (decorated, container, $container) {
@@ -4407,7 +4532,7 @@ S2.define('select2/dropdown/selectOnClose',[
4407
4532
  return;
4408
4533
  }
4409
4534
 
4410
- var data = $highlightedResults.data('data');
4535
+ var data = Utils.GetData($highlightedResults[0], 'data');
4411
4536
 
4412
4537
  // Don't re-select already selected resulte
4413
4538
  if (
@@ -4448,7 +4573,7 @@ S2.define('select2/dropdown/closeOnSelect',[
4448
4573
  var originalEvent = evt.originalEvent;
4449
4574
 
4450
4575
  // Don't close if the control key is being held
4451
- if (originalEvent && originalEvent.ctrlKey) {
4576
+ if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
4452
4577
  return;
4453
4578
  }
4454
4579
 
@@ -4502,6 +4627,9 @@ S2.define('select2/i18n/en',[],function () {
4502
4627
  },
4503
4628
  searching: function () {
4504
4629
  return 'Searching…';
4630
+ },
4631
+ removeAllItems: function () {
4632
+ return 'Remove all items';
4505
4633
  }
4506
4634
  };
4507
4635
  });
@@ -4873,6 +5001,7 @@ S2.define('select2/defaults',[
4873
5001
  maximumSelectionLength: 0,
4874
5002
  minimumResultsForSearch: 0,
4875
5003
  selectOnClose: false,
5004
+ scrollAfterSelect: false,
4876
5005
  sorter: function (data) {
4877
5006
  return data;
4878
5007
  },
@@ -4895,7 +5024,7 @@ S2.define('select2/defaults',[
4895
5024
 
4896
5025
  var convertedData = Utils._convertData(data);
4897
5026
 
4898
- $.extend(this.defaults, convertedData);
5027
+ $.extend(true, this.defaults, convertedData);
4899
5028
  };
4900
5029
 
4901
5030
  var defaults = new Defaults();
@@ -4960,7 +5089,7 @@ S2.define('select2/options',[
4960
5089
  $e.prop('disabled', this.options.disabled);
4961
5090
  $e.prop('multiple', this.options.multiple);
4962
5091
 
4963
- if ($e.data('select2Tags')) {
5092
+ if (Utils.GetData($e[0], 'select2Tags')) {
4964
5093
  if (this.options.debug && window.console && console.warn) {
4965
5094
  console.warn(
4966
5095
  'Select2: The `data-select2-tags` attribute has been changed to ' +
@@ -4969,11 +5098,11 @@ S2.define('select2/options',[
4969
5098
  );
4970
5099
  }
4971
5100
 
4972
- $e.data('data', $e.data('select2Tags'));
4973
- $e.data('tags', true);
5101
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
5102
+ Utils.StoreData($e[0], 'tags', true);
4974
5103
  }
4975
5104
 
4976
- if ($e.data('ajaxUrl')) {
5105
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
4977
5106
  if (this.options.debug && window.console && console.warn) {
4978
5107
  console.warn(
4979
5108
  'Select2: The `data-ajax-url` attribute has been changed to ' +
@@ -4982,21 +5111,45 @@ S2.define('select2/options',[
4982
5111
  );
4983
5112
  }
4984
5113
 
4985
- $e.attr('ajax--url', $e.data('ajaxUrl'));
4986
- $e.data('ajax--url', $e.data('ajaxUrl'));
5114
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
5115
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
4987
5116
  }
4988
5117
 
4989
5118
  var dataset = {};
4990
5119
 
5120
+ function upperCaseLetter(_, letter) {
5121
+ return letter.toUpperCase();
5122
+ }
5123
+
5124
+ // Pre-load all of the attributes which are prefixed with `data-`
5125
+ for (var attr = 0; attr < $e[0].attributes.length; attr++) {
5126
+ var attributeName = $e[0].attributes[attr].name;
5127
+ var prefix = 'data-';
5128
+
5129
+ if (attributeName.substr(0, prefix.length) == prefix) {
5130
+ // Get the contents of the attribute after `data-`
5131
+ var dataName = attributeName.substring(prefix.length);
5132
+
5133
+ // Get the data contents from the consistent source
5134
+ // This is more than likely the jQuery data helper
5135
+ var dataValue = Utils.GetData($e[0], dataName);
5136
+
5137
+ // camelCase the attribute name to match the spec
5138
+ var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
5139
+
5140
+ // Store the data attribute contents into the dataset since
5141
+ dataset[camelDataName] = dataValue;
5142
+ }
5143
+ }
5144
+
4991
5145
  // Prefer the element's `dataset` attribute if it exists
4992
5146
  // jQuery 1.x does not correctly handle data attributes with multiple dashes
4993
5147
  if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
4994
- dataset = $.extend(true, {}, $e[0].dataset, $e.data());
4995
- } else {
4996
- dataset = $e.data();
5148
+ dataset = $.extend(true, {}, $e[0].dataset, dataset);
4997
5149
  }
4998
5150
 
4999
- var data = $.extend(true, {}, dataset);
5151
+ // Prefer our internal data cache if it exists
5152
+ var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
5000
5153
 
5001
5154
  data = Utils._convertData(data);
5002
5155
 
@@ -5033,8 +5186,8 @@ S2.define('select2/core',[
5033
5186
  './keys'
5034
5187
  ], function ($, Options, Utils, KEYS) {
5035
5188
  var Select2 = function ($element, options) {
5036
- if ($element.data('select2') != null) {
5037
- $element.data('select2').destroy();
5189
+ if (Utils.GetData($element[0], 'select2') != null) {
5190
+ Utils.GetData($element[0], 'select2').destroy();
5038
5191
  }
5039
5192
 
5040
5193
  this.$element = $element;
@@ -5050,7 +5203,7 @@ S2.define('select2/core',[
5050
5203
  // Set up the tabindex
5051
5204
 
5052
5205
  var tabindex = $element.attr('tabindex') || 0;
5053
- $element.data('old-tabindex', tabindex);
5206
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
5054
5207
  $element.attr('tabindex', '-1');
5055
5208
 
5056
5209
  // Set up containers and adapters
@@ -5111,6 +5264,9 @@ S2.define('select2/core',[
5111
5264
  // Synchronize any monitored attributes
5112
5265
  this._syncAttributes();
5113
5266
 
5267
+ Utils.StoreData($element[0], 'select2', this);
5268
+
5269
+ // Ensure backwards compatibility with $element.data('select2').
5114
5270
  $element.data('select2', this);
5115
5271
  };
5116
5272
 
@@ -5187,6 +5343,12 @@ S2.define('select2/core',[
5187
5343
  return null;
5188
5344
  }
5189
5345
 
5346
+ if (method == 'computedstyle') {
5347
+ var computedStyle = window.getComputedStyle($element[0]);
5348
+
5349
+ return computedStyle.width;
5350
+ }
5351
+
5190
5352
  return method;
5191
5353
  };
5192
5354
 
@@ -5445,7 +5607,8 @@ S2.define('select2/core',[
5445
5607
  'open': 'opening',
5446
5608
  'close': 'closing',
5447
5609
  'select': 'selecting',
5448
- 'unselect': 'unselecting'
5610
+ 'unselect': 'unselecting',
5611
+ 'clear': 'clearing'
5449
5612
  };
5450
5613
 
5451
5614
  if (args === undefined) {
@@ -5600,10 +5763,12 @@ S2.define('select2/core',[
5600
5763
  this._syncS = null;
5601
5764
 
5602
5765
  this.$element.off('.select2');
5603
- this.$element.attr('tabindex', this.$element.data('old-tabindex'));
5766
+ this.$element.attr('tabindex',
5767
+ Utils.GetData(this.$element[0], 'old-tabindex'));
5604
5768
 
5605
5769
  this.$element.removeClass('select2-hidden-accessible');
5606
5770
  this.$element.attr('aria-hidden', 'false');
5771
+ Utils.RemoveData(this.$element[0]);
5607
5772
  this.$element.removeData('select2');
5608
5773
 
5609
5774
  this.dataAdapter.destroy();
@@ -5631,7 +5796,7 @@ S2.define('select2/core',[
5631
5796
 
5632
5797
  this.$container.addClass('select2-container--' + this.options.get('theme'));
5633
5798
 
5634
- $container.data('element', this.$element);
5799
+ Utils.StoreData($container[0], 'element', this.$element);
5635
5800
 
5636
5801
  return $container;
5637
5802
  };
@@ -5841,8 +6006,9 @@ S2.define('select2/compat/initSelection',[
5841
6006
  });
5842
6007
 
5843
6008
  S2.define('select2/compat/inputData',[
5844
- 'jquery'
5845
- ], function ($) {
6009
+ 'jquery',
6010
+ '../utils'
6011
+ ], function ($, Utils) {
5846
6012
  function InputData (decorated, $element, options) {
5847
6013
  this._currentData = [];
5848
6014
  this._valueSeparator = options.get('valueSeparator') || ',';
@@ -5959,7 +6125,7 @@ S2.define('select2/compat/inputData',[
5959
6125
 
5960
6126
  InputData.prototype.addOptions = function (_, $options) {
5961
6127
  var options = $.map($options, function ($option) {
5962
- return $.data($option[0], 'data');
6128
+ return Utils.GetData($option[0], 'data');
5963
6129
  });
5964
6130
 
5965
6131
  this._currentData.push.apply(this._currentData, options);
@@ -6362,8 +6528,9 @@ S2.define('jquery.select2',[
6362
6528
  'jquery-mousewheel',
6363
6529
 
6364
6530
  './select2/core',
6365
- './select2/defaults'
6366
- ], function ($, _, Select2, Defaults) {
6531
+ './select2/defaults',
6532
+ './select2/utils'
6533
+ ], function ($, _, Select2, Defaults, Utils) {
6367
6534
  if ($.fn.select2 == null) {
6368
6535
  // All methods that should return the element
6369
6536
  var thisMethods = ['open', 'close', 'destroy'];
@@ -6384,7 +6551,7 @@ S2.define('jquery.select2',[
6384
6551
  var args = Array.prototype.slice.call(arguments, 1);
6385
6552
 
6386
6553
  this.each(function () {
6387
- var instance = $(this).data('select2');
6554
+ var instance = Utils.GetData(this, 'select2');
6388
6555
 
6389
6556
  if (instance == null && window.console && console.error) {
6390
6557
  console.error(