select2-rails 3.5.11 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +1 -1
  3. data/Rakefile +1 -2
  4. data/lib/select2-rails/engine.rb +0 -4
  5. data/lib/select2-rails/source_file.rb +6 -19
  6. data/lib/select2-rails/version.rb +1 -1
  7. data/select2-rails.gemspec +2 -2
  8. data/vendor/assets/javascripts/select2.js +4854 -3180
  9. data/vendor/assets/javascripts/select2_locale_az.js +2 -19
  10. data/vendor/assets/javascripts/select2_locale_bg.js +2 -19
  11. data/vendor/assets/javascripts/select2_locale_ca.js +2 -18
  12. data/vendor/assets/javascripts/select2_locale_cs.js +2 -50
  13. data/vendor/assets/javascripts/select2_locale_da.js +2 -18
  14. data/vendor/assets/javascripts/select2_locale_de.js +2 -17
  15. data/vendor/assets/javascripts/select2_locale_en.js +3 -0
  16. data/vendor/assets/javascripts/select2_locale_es.js +2 -18
  17. data/vendor/assets/javascripts/select2_locale_et.js +2 -18
  18. data/vendor/assets/javascripts/select2_locale_eu.js +2 -44
  19. data/vendor/assets/javascripts/select2_locale_fa.js +2 -20
  20. data/vendor/assets/javascripts/select2_locale_fi.js +2 -29
  21. data/vendor/assets/javascripts/select2_locale_fr.js +2 -17
  22. data/vendor/assets/javascripts/select2_locale_gl.js +2 -44
  23. data/vendor/assets/javascripts/select2_locale_he.js +2 -18
  24. data/vendor/assets/javascripts/select2_locale_hi.js +3 -0
  25. data/vendor/assets/javascripts/select2_locale_hr.js +2 -23
  26. data/vendor/assets/javascripts/select2_locale_hu.js +2 -16
  27. data/vendor/assets/javascripts/select2_locale_id.js +2 -20
  28. data/vendor/assets/javascripts/select2_locale_is.js +2 -16
  29. data/vendor/assets/javascripts/select2_locale_it.js +2 -16
  30. data/vendor/assets/javascripts/select2_locale_ko.js +2 -18
  31. data/vendor/assets/javascripts/select2_locale_lt.js +2 -25
  32. data/vendor/assets/javascripts/select2_locale_lv.js +2 -18
  33. data/vendor/assets/javascripts/select2_locale_mk.js +2 -18
  34. data/vendor/assets/javascripts/select2_locale_nb.js +2 -21
  35. data/vendor/assets/javascripts/select2_locale_nl.js +2 -16
  36. data/vendor/assets/javascripts/select2_locale_pl.js +2 -53
  37. data/vendor/assets/javascripts/select2_locale_pt-BR.js +2 -17
  38. data/vendor/assets/javascripts/select2_locale_pt.js +3 -0
  39. data/vendor/assets/javascripts/select2_locale_ro.js +2 -16
  40. data/vendor/assets/javascripts/select2_locale_ru.js +2 -22
  41. data/vendor/assets/javascripts/select2_locale_sk.js +2 -49
  42. data/vendor/assets/javascripts/select2_locale_sr.js +3 -0
  43. data/vendor/assets/javascripts/select2_locale_sv.js +2 -18
  44. data/vendor/assets/javascripts/select2_locale_th.js +2 -18
  45. data/vendor/assets/javascripts/select2_locale_tr.js +2 -19
  46. data/vendor/assets/javascripts/select2_locale_uk.js +2 -24
  47. data/vendor/assets/javascripts/select2_locale_vi.js +2 -19
  48. data/vendor/assets/javascripts/select2_locale_zh-CN.js +2 -15
  49. data/vendor/assets/javascripts/select2_locale_zh-TW.js +2 -15
  50. data/vendor/assets/stylesheets/select2-bootstrap.css +542 -65
  51. data/vendor/assets/stylesheets/select2.css +431 -0
  52. metadata +15 -23
  53. data/vendor/assets/images/select2-spinner.gif +0 -0
  54. data/vendor/assets/images/select2.png +0 -0
  55. data/vendor/assets/images/select2x2.png +0 -0
  56. data/vendor/assets/javascripts/select2_locale_ar.js +0 -19
  57. data/vendor/assets/javascripts/select2_locale_el.js +0 -19
  58. data/vendor/assets/javascripts/select2_locale_ja.js +0 -17
  59. data/vendor/assets/javascripts/select2_locale_ka.js +0 -19
  60. data/vendor/assets/javascripts/select2_locale_ms.js +0 -21
  61. data/vendor/assets/javascripts/select2_locale_no.js +0 -20
  62. data/vendor/assets/javascripts/select2_locale_pt-PT.js +0 -17
  63. data/vendor/assets/javascripts/select2_locale_rs.js +0 -19
  64. data/vendor/assets/javascripts/select2_locale_ug-CN.js +0 -16
  65. data/vendor/assets/stylesheets/select2.scss +0 -692
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 30d5b3dbf2ae9e41f53ee07277e7c82c38c2027794774fd66324e62085909be7
4
- data.tar.gz: 7e601365f397a46f842cdc107d31dddb1098749c8f3348d73e854552ffd72053
2
+ SHA1:
3
+ metadata.gz: 35dee159738ab03828527d0362c979fae5885a92
4
+ data.tar.gz: e034756a968b0628b747e05af1e400e2aeb3dc2d
5
5
  SHA512:
6
- metadata.gz: f4ae4f7ae03c84e2d9c334f630ca2b0199344bd9e4b1646045ebd3b7dd3db3f23f6e8a751b871e17b516d79f31c28c9b1d3dfa893cbdf7f4378003911f9ffd7d
7
- data.tar.gz: 4b399313ad2d0e5c2a38110e2a80731c322cc98f5614c8d7e0f6d56e65f57ae07de137c686f704a200b0e251b484dec886cf38fd553c9458454e768b28c01580
6
+ metadata.gz: 1fbb76bad647c33d14560523a4854b948f71170b683f4d93df0e8779357caf8104eaa5d65f0740d63e3c4a33f215751aef11db585814cd2c1254597631a3581b
7
+ data.tar.gz: 7e7aa3ee1986954f196a64dac6d84340f2212ee60f7f87fb805e854fa618049ebaff20e7a49ed14ca8e739201efface9d7bb65f02f222b18bd4011cc300b1231
data/README.md CHANGED
@@ -40,7 +40,7 @@ Add the following to your `app/assets/javascripts/application.js`:
40
40
 
41
41
  Possible languages:
42
42
 
43
- ar, ca, cs, da, de, el, es, et, eu, fi, fr, gl, he, hr, hu, id, is, it, ja, ka, ko, lt, lv, mk, ms, nl, no, pl, pt-BR, pt-PT, ro, rs, ru, sk, sv, tr, uk, vi, zh-CN, zh-TW
43
+ az, bg, ca, cs, da, de, en, es, et, eu, fi, fr, gl, hi, hr, hu, id, is, it, lt, lv, mk, nb, nl, pl, pt-BR, pt, ro, ru, sk, sr, sv, th, tr, uk, vi, zh-CN, zh-TW
44
44
 
45
45
  ## Example
46
46
  Code [here](https://github.com/argerim/select_2_example)
data/Rakefile CHANGED
@@ -6,5 +6,4 @@ desc "Update with Ivaynberg's select2 Library"
6
6
  task "update-select2" do
7
7
  files = SourceFile.new
8
8
  files.fetch
9
- files.convert
10
- end
9
+ end
@@ -1,10 +1,6 @@
1
1
  module Select2
2
2
  module Rails
3
3
  class Engine < ::Rails::Engine
4
- initializer :images do |app|
5
- app.config.assets.precompile +=
6
- %w(select2.png select2-spinner.gif select2x2.png)
7
- end
8
4
  end
9
5
  end
10
6
  end
@@ -11,22 +11,10 @@ class SourceFile < Thor
11
11
  tag = select("Which tag do you want to fetch?", filtered_tags)
12
12
  self.destination_root = "vendor/assets"
13
13
  remote = "https://github.com/select2/select2"
14
- get "#{remote}/raw/#{tag}/select2.png", "images/select2.png"
15
- get "#{remote}/raw/#{tag}/select2x2.png", "images/select2x2.png"
16
- get "#{remote}/raw/#{tag}/select2-spinner.gif", "images/select2-spinner.gif"
17
- get "#{remote}/raw/#{tag}/select2.css", "stylesheets/select2.scss"
18
- get "#{remote}/raw/#{tag}/select2-bootstrap.css", "stylesheets/select2-bootstrap.css"
19
- get "#{remote}/raw/#{tag}/select2.js", "javascripts/select2.js"
14
+ get "#{remote}/raw/#{tag}/dist/css/select2.css", "stylesheets/select2.css"
15
+ get "#{remote}/raw/#{tag}/dist/js/select2.js", "javascripts/select2.js"
20
16
  languages.each do |lang|
21
- get "#{remote}/raw/#{tag}/select2_locale_#{lang}.js", "javascripts/select2_locale_#{lang}.js"
22
- end
23
- end
24
-
25
- desc "convert css to use rails paths", "make css use rails paths"
26
- def convert
27
- self.destination_root = "vendor/assets"
28
- inside destination_root do
29
- gsub_file 'stylesheets/select2.scss', %r/url\(([^\)]*)\)/, 'image-url(\1)'
17
+ get "#{remote}/raw/#{tag}/dist/js/i18n/#{lang}.js", "javascripts/select2_locale_#{lang}.js"
30
18
  end
31
19
  end
32
20
 
@@ -34,15 +22,14 @@ class SourceFile < Thor
34
22
 
35
23
  def fetch_tags
36
24
  http = HTTPClient.new
37
- #http.ssl_config.ssl_version = :SSLv23
38
25
  response = JSON.parse(http.get("https://api.github.com/repos/select2/select2/tags").body)
39
26
  response.map{|tag| tag["name"]}.sort
40
27
  end
41
28
 
42
29
  def languages
43
- [ "ar", "az", "bg", "ca", "cs", "da", "de", "el", "es", "et", "eu", "fa", "fi", "fr", "gl", "he", "hr",
44
- "hu", "id", "is", "it", "ja", "ka", "ko", "lt", "lv", "mk", "ms", "nb", "nl", "pl", "pt-BR",
45
- "pt-PT", "ro", "rs", "ru", "sk", "sv", "th", "tr", "ug-CN", "uk", "vi", "zh-CN", "zh-TW"
30
+ [ "az", "bg", "ca", "cs", "da", "de", "en", "es", "et", "eu", "fa", "fi", "fr", "gl", "he", "hi", "hr", "hu",
31
+ "id", "is", "it", "ko", "lt", "lv", "mk", "nb", "nl", "pl", "pt-BR", "pt", "ro", "ru", "sk", "sr",
32
+ "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-TW"
46
33
  ].sort
47
34
  end
48
35
 
@@ -1,5 +1,5 @@
1
1
  module Select2
2
2
  module Rails
3
- VERSION = "3.5.11"
3
+ VERSION = "4.0.0"
4
4
  end
5
5
  end
@@ -15,8 +15,8 @@ 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_development_dependency "thor", "~> 0.14"
19
- s.add_development_dependency "bundler", "~> 2.0"
18
+ s.add_dependency "thor", "~> 0.14"
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"
22
22
  end
@@ -1,3729 +1,5403 @@
1
- /*
2
- Copyright 2012 Igor Vaynberg
3
-
4
- Version: 3.5.4 Timestamp: Sun Aug 30 13:30:32 EDT 2015
5
-
6
- This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
7
- General Public License version 2 (the "GPL License"). You may choose either license to govern your
8
- use of this software only upon the condition that you accept all of the terms of either the Apache
9
- License or the GPL License.
10
-
11
- You may obtain a copy of the Apache License and the GPL License at:
12
-
13
- http://www.apache.org/licenses/LICENSE-2.0
14
- http://www.gnu.org/licenses/gpl-2.0.html
15
-
16
- Unless required by applicable law or agreed to in writing, software distributed under the
17
- Apache License or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
- CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
19
- the specific language governing permissions and limitations under the Apache License and the GPL License.
20
- */
21
- (function ($) {
22
- if(typeof $.fn.each2 == "undefined") {
23
- $.extend($.fn, {
24
- /*
25
- * 4-10 times faster .each replacement
26
- * use it carefully, as it overrides jQuery context of element on each iteration
27
- */
28
- each2 : function (c) {
29
- var j = $([0]), i = -1, l = this.length;
30
- while (
31
- ++i < l
32
- && (j.context = j[0] = this[i])
33
- && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
34
- );
35
- return this;
36
- }
37
- });
1
+ /*!
2
+ * Select2 4.0.0
3
+ * https://select2.github.io
4
+ *
5
+ * Released under the MIT license
6
+ * https://github.com/select2/select2/blob/master/LICENSE.md
7
+ */
8
+ (function (factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD. Register as an anonymous module.
11
+ define(['jquery'], factory);
12
+ } else if (typeof exports === 'object') {
13
+ // Node/CommonJS
14
+ factory(require('jquery'));
15
+ } else {
16
+ // Browser globals
17
+ factory(jQuery);
18
+ }
19
+ }(function (jQuery) {
20
+ // This is needed so we can catch the AMD loader configuration and use it
21
+ // The inner file should be wrapped (by `banner.start.js`) in a function that
22
+ // returns the AMD loader references.
23
+ var S2 =
24
+ (function () {
25
+ // Restore the Select2 AMD loader so it can be used
26
+ // Needed mostly in the language files, where the loader is not inserted
27
+ if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
28
+ var S2 = jQuery.fn.select2.amd;
29
+ }
30
+ var S2;(function () { if (!S2 || !S2.requirejs) {
31
+ if (!S2) { S2 = {}; } else { require = S2; }
32
+ /**
33
+ * @license almond 0.2.9 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
36
+ */
37
+ //Going sloppy to avoid 'use strict' string cost, but strict practices should
38
+ //be followed.
39
+ /*jslint sloppy: true */
40
+ /*global setTimeout: false */
41
+
42
+ var requirejs, require, define;
43
+ (function (undef) {
44
+ var main, req, makeMap, handlers,
45
+ defined = {},
46
+ waiting = {},
47
+ config = {},
48
+ defining = {},
49
+ hasOwn = Object.prototype.hasOwnProperty,
50
+ aps = [].slice,
51
+ jsSuffixRegExp = /\.js$/;
52
+
53
+ function hasProp(obj, prop) {
54
+ return hasOwn.call(obj, prop);
38
55
  }
39
- })(jQuery);
40
56
 
41
- (function ($, undefined) {
42
- "use strict";
43
- /*global document, window, jQuery, console */
57
+ /**
58
+ * Given a relative module name, like ./something, normalize it to
59
+ * a real name that can be mapped to a path.
60
+ * @param {String} name the relative name
61
+ * @param {String} baseName a real name that the name arg is relative
62
+ * to.
63
+ * @returns {String} normalized name
64
+ */
65
+ function normalize(name, baseName) {
66
+ var nameParts, nameSegment, mapValue, foundMap, lastIndex,
67
+ foundI, foundStarMap, starI, i, j, part,
68
+ baseParts = baseName && baseName.split("/"),
69
+ map = config.map,
70
+ starMap = (map && map['*']) || {};
71
+
72
+ //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
+ //Convert baseName to array, and lop off the last part,
79
+ //so that . matches that "directory" and not name of the baseName's
80
+ //module. For instance, baseName of "one/two/three", maps to
81
+ //"one/two/three.js", but we want the directory, "one/two" for
82
+ //this normalization.
83
+ baseParts = baseParts.slice(0, baseParts.length - 1);
84
+ name = name.split('/');
85
+ lastIndex = name.length - 1;
86
+
87
+ // Node .js allowance:
88
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
89
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
90
+ }
44
91
 
45
- if (window.Select2 !== undefined) {
46
- return;
47
- }
92
+ name = baseParts.concat(name);
93
+
94
+ //start trimDots
95
+ for (i = 0; i < name.length; i += 1) {
96
+ part = name[i];
97
+ if (part === ".") {
98
+ name.splice(i, 1);
99
+ i -= 1;
100
+ } else if (part === "..") {
101
+ if (i === 1 && (name[2] === '..' || name[0] === '..')) {
102
+ //End of the line. Keep at least one non-dot
103
+ //path segment at the front so it can be mapped
104
+ //correctly to disk. Otherwise, there is likely
105
+ //no path mapping for a path starting with '..'.
106
+ //This can still fail, but catches the most reasonable
107
+ //uses of ..
108
+ break;
109
+ } else if (i > 0) {
110
+ name.splice(i - 1, 2);
111
+ i -= 2;
112
+ }
113
+ }
114
+ }
115
+ //end trimDots
48
116
 
49
- var AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
50
- lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,
51
-
52
- KEY = {
53
- TAB: 9,
54
- ENTER: 13,
55
- ESC: 27,
56
- SPACE: 32,
57
- LEFT: 37,
58
- UP: 38,
59
- RIGHT: 39,
60
- DOWN: 40,
61
- SHIFT: 16,
62
- CTRL: 17,
63
- ALT: 18,
64
- PAGE_UP: 33,
65
- PAGE_DOWN: 34,
66
- HOME: 36,
67
- END: 35,
68
- BACKSPACE: 8,
69
- DELETE: 46,
70
- isArrow: function (k) {
71
- k = k.which ? k.which : k;
72
- switch (k) {
73
- case KEY.LEFT:
74
- case KEY.RIGHT:
75
- case KEY.UP:
76
- case KEY.DOWN:
77
- return true;
78
- }
79
- return false;
80
- },
81
- isControl: function (e) {
82
- var k = e.which;
83
- switch (k) {
84
- case KEY.SHIFT:
85
- case KEY.CTRL:
86
- case KEY.ALT:
87
- return true;
117
+ name = name.join("/");
118
+ } else if (name.indexOf('./') === 0) {
119
+ // No baseName, so this is ID is resolved relative
120
+ // to baseUrl, pull off the leading dot.
121
+ name = name.substring(2);
88
122
  }
89
-
90
- if (e.metaKey) return true;
91
-
92
- return false;
93
- },
94
- isFunctionKey: function (k) {
95
- k = k.which ? k.which : k;
96
- return k >= 112 && k <= 123;
97
123
  }
98
- },
99
- MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>",
100
-
101
- DIACRITICS = {"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038A":"\u0399","\u03AA":"\u0399","\u038C":"\u039F","\u038E":"\u03A5","\u03AB":"\u03A5","\u038F":"\u03A9","\u03AC":"\u03B1","\u03AD":"\u03B5","\u03AE":"\u03B7","\u03AF":"\u03B9","\u03CA":"\u03B9","\u0390":"\u03B9","\u03CC":"\u03BF","\u03CD":"\u03C5","\u03CB":"\u03C5","\u03B0":"\u03C5","\u03C9":"\u03C9","\u03C2":"\u03C3"};
102
-
103
- $document = $(document);
104
124
 
105
- nextUid=(function() { var counter=1; return function() { return counter++; }; }());
125
+ //Apply map config if available.
126
+ if ((baseParts || starMap) && map) {
127
+ nameParts = name.split('/');
128
+
129
+ for (i = nameParts.length; i > 0; i -= 1) {
130
+ nameSegment = nameParts.slice(0, i).join("/");
131
+
132
+ if (baseParts) {
133
+ //Find the longest baseName segment match in the config.
134
+ //So, do joins on the biggest to smallest lengths of baseParts.
135
+ for (j = baseParts.length; j > 0; j -= 1) {
136
+ mapValue = map[baseParts.slice(0, j).join('/')];
137
+
138
+ //baseName segment has config, find if it has one for
139
+ //this name.
140
+ if (mapValue) {
141
+ mapValue = mapValue[nameSegment];
142
+ if (mapValue) {
143
+ //Match, update name to the new value.
144
+ foundMap = mapValue;
145
+ foundI = i;
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ }
106
151
 
152
+ if (foundMap) {
153
+ break;
154
+ }
107
155
 
108
- function reinsertElement(element) {
109
- var placeholder = $(document.createTextNode(''));
156
+ //Check for a star map match, but just hold on to it,
157
+ //if there is a shorter segment match later in a matching
158
+ //config, then favor over this star map.
159
+ if (!foundStarMap && starMap && starMap[nameSegment]) {
160
+ foundStarMap = starMap[nameSegment];
161
+ starI = i;
162
+ }
163
+ }
110
164
 
111
- element.before(placeholder);
112
- placeholder.before(element);
113
- placeholder.remove();
114
- }
165
+ if (!foundMap && foundStarMap) {
166
+ foundMap = foundStarMap;
167
+ foundI = starI;
168
+ }
115
169
 
116
- function stripDiacritics(str) {
117
- // Used 'uni range + named function' from http://jsperf.com/diacritics/18
118
- function match(a) {
119
- return DIACRITICS[a] || a;
170
+ if (foundMap) {
171
+ nameParts.splice(0, foundI, foundMap);
172
+ name = nameParts.join('/');
173
+ }
120
174
  }
121
175
 
122
- return str.replace(/[^\u0000-\u007E]/g, match);
176
+ return name;
123
177
  }
124
178
 
125
- function indexOf(value, array) {
126
- var i = 0, l = array.length;
127
- for (; i < l; i = i + 1) {
128
- if (equal(value, array[i])) return i;
129
- }
130
- return -1;
179
+ function makeRequire(relName, forceSync) {
180
+ return function () {
181
+ //A version of a require function that passes a moduleName
182
+ //value for items that may need to
183
+ //look up paths relative to the moduleName
184
+ return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
185
+ };
131
186
  }
132
187
 
133
- function measureScrollbar () {
134
- var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
135
- $template.appendTo(document.body);
188
+ function makeNormalize(relName) {
189
+ return function (name) {
190
+ return normalize(name, relName);
191
+ };
192
+ }
136
193
 
137
- var dim = {
138
- width: $template.width() - $template[0].clientWidth,
139
- height: $template.height() - $template[0].clientHeight
194
+ function makeLoad(depName) {
195
+ return function (value) {
196
+ defined[depName] = value;
140
197
  };
141
- $template.remove();
198
+ }
199
+
200
+ function callDep(name) {
201
+ if (hasProp(waiting, name)) {
202
+ var args = waiting[name];
203
+ delete waiting[name];
204
+ defining[name] = true;
205
+ main.apply(undef, args);
206
+ }
142
207
 
143
- return dim;
208
+ if (!hasProp(defined, name) && !hasProp(defining, name)) {
209
+ throw new Error('No ' + name);
210
+ }
211
+ return defined[name];
144
212
  }
145
213
 
146
- /**
147
- * Compares equality of a and b
148
- * @param a
149
- * @param b
150
- */
151
- function equal(a, b) {
152
- if (a === b) return true;
153
- if (a === undefined || b === undefined) return false;
154
- if (a === null || b === null) return false;
155
- // Check whether 'a' or 'b' is a string (primitive or object).
156
- // The concatenation of an empty string (+'') converts its argument to a string's primitive.
157
- if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object
158
- if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object
159
- return false;
214
+ //Turns a plugin!resource to [plugin, resource]
215
+ //with the plugin being undefined if the name
216
+ //did not have a plugin prefix.
217
+ function splitPrefix(name) {
218
+ var prefix,
219
+ index = name ? name.indexOf('!') : -1;
220
+ if (index > -1) {
221
+ prefix = name.substring(0, index);
222
+ name = name.substring(index + 1, name.length);
223
+ }
224
+ return [prefix, name];
160
225
  }
161
226
 
162
227
  /**
163
- * Splits the string into an array of values, transforming each value. An empty array is returned for nulls or empty
164
- * strings
165
- * @param string
166
- * @param separator
228
+ * Makes a name map, normalizing the name, and using a plugin
229
+ * for normalization if necessary. Grabs a ref to plugin
230
+ * too, as an optimization.
167
231
  */
168
- function splitVal(string, separator, transform) {
169
- var val, i, l;
170
- if (string === null || string.length < 1) return [];
171
- val = string.split(separator);
172
- for (i = 0, l = val.length; i < l; i = i + 1) val[i] = transform(val[i]);
173
- return val;
174
- }
232
+ makeMap = function (name, relName) {
233
+ var plugin,
234
+ parts = splitPrefix(name),
235
+ prefix = parts[0];
175
236
 
176
- function getSideBorderPadding(element) {
177
- return element.outerWidth(false) - element.width();
178
- }
237
+ name = parts[1];
238
+
239
+ if (prefix) {
240
+ prefix = normalize(prefix, relName);
241
+ plugin = callDep(prefix);
242
+ }
179
243
 
180
- function installKeyUpChangeEvent(element) {
181
- var key="keyup-change-value";
182
- element.on("keydown", function () {
183
- if ($.data(element, key) === undefined) {
184
- $.data(element, key, element.val());
244
+ //Normalize according
245
+ if (prefix) {
246
+ if (plugin && plugin.normalize) {
247
+ name = plugin.normalize(name, makeNormalize(relName));
248
+ } else {
249
+ name = normalize(name, relName);
185
250
  }
186
- });
187
- element.on("keyup", function () {
188
- var val= $.data(element, key);
189
- if (val !== undefined && element.val() !== val) {
190
- $.removeData(element, key);
191
- element.trigger("keyup-change");
251
+ } else {
252
+ name = normalize(name, relName);
253
+ parts = splitPrefix(name);
254
+ prefix = parts[0];
255
+ name = parts[1];
256
+ if (prefix) {
257
+ plugin = callDep(prefix);
192
258
  }
193
- });
194
- }
195
-
259
+ }
196
260
 
197
- /**
198
- * filters mouse events so an event is fired only if the mouse moved.
199
- *
200
- * filters out mouse events that occur when mouse is stationary but
201
- * the elements under the pointer are scrolled.
202
- */
203
- function installFilteredMouseMove(element) {
204
- element.on("mousemove", function (e) {
205
- var lastpos = lastMousePosition;
206
- if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
207
- $(e.target).trigger("mousemove-filtered", e);
208
- }
209
- });
210
- }
261
+ //Using ridiculous property names for space reasons
262
+ return {
263
+ f: prefix ? prefix + '!' + name : name, //fullName
264
+ n: name,
265
+ pr: prefix,
266
+ p: plugin
267
+ };
268
+ };
211
269
 
212
- /**
213
- * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made
214
- * within the last quietMillis milliseconds.
215
- *
216
- * @param quietMillis number of milliseconds to wait before invoking fn
217
- * @param fn function to be debounced
218
- * @param ctx object to be used as this reference within fn
219
- * @return debounced version of fn
220
- */
221
- function debounce(quietMillis, fn, ctx) {
222
- ctx = ctx || undefined;
223
- var timeout;
270
+ function makeConfig(name) {
224
271
  return function () {
225
- var args = arguments;
226
- window.clearTimeout(timeout);
227
- timeout = window.setTimeout(function() {
228
- fn.apply(ctx, args);
229
- }, quietMillis);
272
+ return (config && config.config && config.config[name]) || {};
230
273
  };
231
274
  }
232
275
 
233
- function installDebouncedScroll(threshold, element) {
234
- var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);});
235
- element.on("scroll", function (e) {
236
- if (indexOf(e.target, element.get()) >= 0) notify(e);
237
- });
238
- }
239
-
240
- function focus($el) {
241
- if ($el[0] === document.activeElement) return;
242
-
243
- /* set the focus in a 0 timeout - that way the focus is set after the processing
244
- of the current event has finished - which seems like the only reliable way
245
- to set focus */
246
- window.setTimeout(function() {
247
- var el=$el[0], pos=$el.val().length, range;
276
+ handlers = {
277
+ require: function (name) {
278
+ return makeRequire(name);
279
+ },
280
+ exports: function (name) {
281
+ var e = defined[name];
282
+ if (typeof e !== 'undefined') {
283
+ return e;
284
+ } else {
285
+ return (defined[name] = {});
286
+ }
287
+ },
288
+ module: function (name) {
289
+ return {
290
+ id: name,
291
+ uri: '',
292
+ exports: defined[name],
293
+ config: makeConfig(name)
294
+ };
295
+ }
296
+ };
248
297
 
249
- $el.focus();
298
+ main = function (name, deps, callback, relName) {
299
+ var cjsModule, depName, ret, map, i,
300
+ args = [],
301
+ callbackType = typeof callback,
302
+ usingExports;
303
+
304
+ //Use name if no relName
305
+ relName = relName || name;
306
+
307
+ //Call the callback to define the module, if necessary.
308
+ if (callbackType === 'undefined' || callbackType === 'function') {
309
+ //Pull out the defined dependencies and pass the ordered
310
+ //values to the callback.
311
+ //Default to [require, exports, module] if no deps
312
+ deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
313
+ for (i = 0; i < deps.length; i += 1) {
314
+ map = makeMap(deps[i], relName);
315
+ depName = map.f;
316
+
317
+ //Fast path CommonJS standard dependencies.
318
+ if (depName === "require") {
319
+ args[i] = handlers.require(name);
320
+ } else if (depName === "exports") {
321
+ //CommonJS module spec 1.1
322
+ args[i] = handlers.exports(name);
323
+ usingExports = true;
324
+ } else if (depName === "module") {
325
+ //CommonJS module spec 1.1
326
+ cjsModule = args[i] = handlers.module(name);
327
+ } else if (hasProp(defined, depName) ||
328
+ hasProp(waiting, depName) ||
329
+ hasProp(defining, depName)) {
330
+ args[i] = callDep(depName);
331
+ } else if (map.p) {
332
+ map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
333
+ args[i] = defined[depName];
334
+ } else {
335
+ throw new Error(name + ' missing ' + depName);
336
+ }
337
+ }
250
338
 
251
- /* make sure el received focus so we do not error out when trying to manipulate the caret.
252
- sometimes modals or others listeners may steal it after its set */
253
- var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0);
254
- if (isVisible && el === document.activeElement) {
339
+ ret = callback ? callback.apply(defined[name], args) : undefined;
255
340
 
256
- /* after the focus is set move the caret to the end, necessary when we val()
257
- just before setting focus */
258
- if(el.setSelectionRange)
259
- {
260
- el.setSelectionRange(pos, pos);
261
- }
262
- else if (el.createTextRange) {
263
- range = el.createTextRange();
264
- range.collapse(false);
265
- range.select();
341
+ if (name) {
342
+ //If setting exports via "module" is in play,
343
+ //favor that over return value and exports. After that,
344
+ //favor a non-undefined return value over exports use.
345
+ if (cjsModule && cjsModule.exports !== undef &&
346
+ cjsModule.exports !== defined[name]) {
347
+ defined[name] = cjsModule.exports;
348
+ } else if (ret !== undef || !usingExports) {
349
+ //Use the return value from the function.
350
+ defined[name] = ret;
266
351
  }
267
352
  }
268
- }, 0);
269
- }
270
-
271
- function getCursorInfo(el) {
272
- el = $(el)[0];
273
- var offset = 0;
274
- var length = 0;
275
- if ('selectionStart' in el) {
276
- offset = el.selectionStart;
277
- length = el.selectionEnd - offset;
278
- } else if ('selection' in document) {
279
- el.focus();
280
- var sel = document.selection.createRange();
281
- length = document.selection.createRange().text.length;
282
- sel.moveStart('character', -el.value.length);
283
- offset = sel.text.length - length;
284
- }
285
- return { offset: offset, length: length };
286
- }
287
-
288
- function killEvent(event) {
289
- event.preventDefault();
290
- event.stopPropagation();
291
- }
292
- function killEventImmediately(event) {
293
- event.preventDefault();
294
- event.stopImmediatePropagation();
295
- }
296
-
297
- function measureTextWidth(e) {
298
- if (!sizer){
299
- var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
300
- sizer = $(document.createElement("div")).css({
301
- position: "absolute",
302
- left: "-10000px",
303
- top: "-10000px",
304
- display: "none",
305
- fontSize: style.fontSize,
306
- fontFamily: style.fontFamily,
307
- fontStyle: style.fontStyle,
308
- fontWeight: style.fontWeight,
309
- letterSpacing: style.letterSpacing,
310
- textTransform: style.textTransform,
311
- whiteSpace: "nowrap"
312
- });
313
- sizer.attr("class","select2-sizer");
314
- $(document.body).append(sizer);
353
+ } else if (name) {
354
+ //May just be an object definition for the module. Only
355
+ //worry about defining if have a module name.
356
+ defined[name] = callback;
315
357
  }
316
- sizer.text(e.val());
317
- return sizer.width();
318
- }
358
+ };
319
359
 
320
- function syncCssClasses(dest, src, adapter) {
321
- var classes, replacements = [], adapted;
360
+ requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
361
+ if (typeof deps === "string") {
362
+ if (handlers[deps]) {
363
+ //callback in this case is really relName
364
+ return handlers[deps](callback);
365
+ }
366
+ //Just return the module wanted. In this scenario, the
367
+ //deps arg is the module name, and second arg (if passed)
368
+ //is just the relName.
369
+ //Normalize module name, if it contains . or ..
370
+ return callDep(makeMap(deps, callback).f);
371
+ } else if (!deps.splice) {
372
+ //deps is a config object, not an array.
373
+ config = deps;
374
+ if (config.deps) {
375
+ req(config.deps, config.callback);
376
+ }
377
+ if (!callback) {
378
+ return;
379
+ }
380
+
381
+ if (callback.splice) {
382
+ //callback is an array, which means it is a dependency list.
383
+ //Adjust args if there are dependencies
384
+ deps = callback;
385
+ callback = relName;
386
+ relName = null;
387
+ } else {
388
+ deps = undef;
389
+ }
390
+ }
322
391
 
323
- classes = $.trim(dest.attr("class"));
392
+ //Support require(['a'])
393
+ callback = callback || function () {};
324
394
 
325
- if (classes) {
326
- classes = '' + classes; // for IE which returns object
395
+ //If relName is a function, it is an errback handler,
396
+ //so remove it.
397
+ if (typeof relName === 'function') {
398
+ relName = forceSync;
399
+ forceSync = alt;
400
+ }
327
401
 
328
- $(classes.split(/\s+/)).each2(function() {
329
- if (this.indexOf("select2-") === 0) {
330
- replacements.push(this);
331
- }
332
- });
402
+ //Simulate async callback;
403
+ if (forceSync) {
404
+ main(undef, deps, callback, relName);
405
+ } else {
406
+ //Using a non-zero value because of concern for what old browsers
407
+ //do, and latest browsers "upgrade" to 4 if lower value is used:
408
+ //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
409
+ //If want a value immediately, use require('id') instead -- something
410
+ //that works in almond on the global level, but not guaranteed and
411
+ //unlikely to work in other AMD implementations.
412
+ setTimeout(function () {
413
+ main(undef, deps, callback, relName);
414
+ }, 4);
333
415
  }
334
416
 
335
- classes = $.trim(src.attr("class"));
417
+ return req;
418
+ };
336
419
 
337
- if (classes) {
338
- classes = '' + classes; // for IE which returns object
420
+ /**
421
+ * Just drops the config on the floor, but returns req in case
422
+ * the config return value is used.
423
+ */
424
+ req.config = function (cfg) {
425
+ return req(cfg);
426
+ };
339
427
 
340
- $(classes.split(/\s+/)).each2(function() {
341
- if (this.indexOf("select2-") !== 0) {
342
- adapted = adapter(this);
428
+ /**
429
+ * Expose module registry for debugging and tooling
430
+ */
431
+ requirejs._defined = defined;
343
432
 
344
- if (adapted) {
345
- replacements.push(adapted);
346
- }
347
- }
348
- });
433
+ define = function (name, deps, callback) {
434
+
435
+ //This module may not have dependencies
436
+ if (!deps.splice) {
437
+ //deps is not an array, so probably means
438
+ //an object literal or factory function for
439
+ //the value. Adjust args.
440
+ callback = deps;
441
+ deps = [];
442
+ }
443
+
444
+ if (!hasProp(defined, name) && !hasProp(waiting, name)) {
445
+ waiting[name] = [name, deps, callback];
349
446
  }
447
+ };
350
448
 
351
- dest.attr("class", replacements.join(" "));
449
+ define.amd = {
450
+ jQuery: true
451
+ };
452
+ }());
453
+
454
+ S2.requirejs = requirejs;S2.require = require;S2.define = define;
455
+ }
456
+ }());
457
+ S2.define("almond", function(){});
458
+
459
+ /* global jQuery:false, $:false */
460
+ S2.define('jquery',[],function () {
461
+ var _$ = jQuery || $;
462
+
463
+ if (_$ == null && console && console.error) {
464
+ console.error(
465
+ 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
466
+ 'found. Make sure that you are including jQuery before Select2 on your ' +
467
+ 'web page.'
468
+ );
469
+ }
470
+
471
+ return _$;
472
+ });
473
+
474
+ S2.define('select2/utils',[
475
+ 'jquery'
476
+ ], function ($) {
477
+ var Utils = {};
478
+
479
+ Utils.Extend = function (ChildClass, SuperClass) {
480
+ var __hasProp = {}.hasOwnProperty;
481
+
482
+ function BaseConstructor () {
483
+ this.constructor = ChildClass;
352
484
  }
353
485
 
486
+ for (var key in SuperClass) {
487
+ if (__hasProp.call(SuperClass, key)) {
488
+ ChildClass[key] = SuperClass[key];
489
+ }
490
+ }
354
491
 
355
- function markMatch(text, term, markup, escapeMarkup) {
356
- var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),
357
- tl=term.length;
492
+ BaseConstructor.prototype = SuperClass.prototype;
493
+ ChildClass.prototype = new BaseConstructor();
494
+ ChildClass.__super__ = SuperClass.prototype;
358
495
 
359
- if (match<0) {
360
- markup.push(escapeMarkup(text));
361
- return;
362
- }
496
+ return ChildClass;
497
+ };
363
498
 
364
- markup.push(escapeMarkup(text.substring(0, match)));
365
- markup.push("<span class='select2-match'>");
366
- markup.push(escapeMarkup(text.substring(match, match + tl)));
367
- markup.push("</span>");
368
- markup.push(escapeMarkup(text.substring(match + tl, text.length)));
369
- }
370
-
371
- function defaultEscapeMarkup(markup) {
372
- var replace_map = {
373
- '\\': '&#92;',
374
- '&': '&amp;',
375
- '<': '&lt;',
376
- '>': '&gt;',
377
- '"': '&quot;',
378
- "'": '&#39;',
379
- "/": '&#47;'
380
- };
499
+ function getMethods (theClass) {
500
+ var proto = theClass.prototype;
381
501
 
382
- return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
383
- return replace_map[match];
384
- });
385
- }
502
+ var methods = [];
386
503
 
387
- /**
388
- * Produces an ajax-based query function
389
- *
390
- * @param options object containing configuration parameters
391
- * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax
392
- * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
393
- * @param options.url url for the data
394
- * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
395
- * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified
396
- * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
397
- * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
398
- * The expected format is an object containing the following keys:
399
- * results array of objects that will be used as choices
400
- * more (optional) boolean indicating whether there are more results available
401
- * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
402
- */
403
- function ajax(options) {
404
- var timeout, // current scheduled but not yet executed request
405
- handler = null,
406
- quietMillis = options.quietMillis || 100,
407
- ajaxUrl = options.url,
408
- self = this;
409
-
410
- return function (query) {
411
- window.clearTimeout(timeout);
412
- timeout = window.setTimeout(function () {
413
- var data = options.data, // ajax data function
414
- url = ajaxUrl, // ajax url string or function
415
- transport = options.transport || $.fn.select2.ajaxDefaults.transport,
416
- // deprecated - to be removed in 4.0 - use params instead
417
- deprecated = {
418
- type: options.type || 'GET', // set type of request (GET or POST)
419
- cache: options.cache || false,
420
- jsonpCallback: options.jsonpCallback||undefined,
421
- dataType: options.dataType||"json"
422
- },
423
- params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
424
-
425
- data = data ? data.call(self, query.term, query.page, query.context) : null;
426
- url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
427
-
428
- if (handler && typeof handler.abort === "function") { handler.abort(); }
429
-
430
- if (options.params) {
431
- if ($.isFunction(options.params)) {
432
- $.extend(params, options.params.call(self));
433
- } else {
434
- $.extend(params, options.params);
435
- }
436
- }
504
+ for (var methodName in proto) {
505
+ var m = proto[methodName];
437
506
 
438
- $.extend(params, {
439
- url: url,
440
- dataType: options.dataType,
441
- data: data,
442
- success: function (data) {
443
- // TODO - replace query.page with query so users have access to term, page, etc.
444
- // added query as third paramter to keep backwards compatibility
445
- var results = options.results(data, query.page, query);
446
- query.callback(results);
447
- },
448
- error: function(jqXHR, textStatus, errorThrown){
449
- var results = {
450
- hasError: true,
451
- jqXHR: jqXHR,
452
- textStatus: textStatus,
453
- errorThrown: errorThrown
454
- };
455
-
456
- query.callback(results);
457
- }
458
- });
459
- handler = transport.call(self, params);
460
- }, quietMillis);
461
- };
507
+ if (typeof m !== 'function') {
508
+ continue;
509
+ }
510
+
511
+ if (methodName === 'constructor') {
512
+ continue;
513
+ }
514
+
515
+ methods.push(methodName);
462
516
  }
463
517
 
464
- /**
465
- * Produces a query function that works with a local array
466
- *
467
- * @param options object containing configuration parameters. The options parameter can either be an array or an
468
- * object.
469
- *
470
- * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.
471
- *
472
- * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain
473
- * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'
474
- * key can either be a String in which case it is expected that each element in the 'data' array has a key with the
475
- * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract
476
- * the text.
477
- */
478
- function local(options) {
479
- var data = options, // data elements
480
- dataText,
481
- tmp,
482
- text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
483
-
484
- if ($.isArray(data)) {
485
- tmp = data;
486
- data = { results: tmp };
487
- }
518
+ return methods;
519
+ }
488
520
 
489
- if ($.isFunction(data) === false) {
490
- tmp = data;
491
- data = function() { return tmp; };
492
- }
521
+ Utils.Decorate = function (SuperClass, DecoratorClass) {
522
+ var decoratedMethods = getMethods(DecoratorClass);
523
+ var superMethods = getMethods(SuperClass);
493
524
 
494
- var dataItem = data();
495
- if (dataItem.text) {
496
- text = dataItem.text;
497
- // if text is not a function we assume it to be a key name
498
- if (!$.isFunction(text)) {
499
- dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
500
- text = function (item) { return item[dataText]; };
501
- }
502
- }
525
+ function DecoratedClass () {
526
+ var unshift = Array.prototype.unshift;
503
527
 
504
- return function (query) {
505
- var t = query.term, filtered = { results: [] }, process;
506
- if (t === "") {
507
- query.callback(data());
508
- return;
509
- }
528
+ var argCount = DecoratorClass.prototype.constructor.length;
510
529
 
511
- process = function(datum, collection) {
512
- var group, attr;
513
- datum = datum[0];
514
- if (datum.children) {
515
- group = {};
516
- for (attr in datum) {
517
- if (datum.hasOwnProperty(attr)) group[attr]=datum[attr];
518
- }
519
- group.children=[];
520
- $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });
521
- if (group.children.length || query.matcher(t, text(group), datum)) {
522
- collection.push(group);
523
- }
524
- } else {
525
- if (query.matcher(t, text(datum), datum)) {
526
- collection.push(datum);
527
- }
528
- }
529
- };
530
+ var calledConstructor = SuperClass.prototype.constructor;
530
531
 
531
- $(data().results).each2(function(i, datum) { process(datum, filtered.results); });
532
- query.callback(filtered);
533
- };
534
- }
532
+ if (argCount > 0) {
533
+ unshift.call(arguments, SuperClass.prototype.constructor);
535
534
 
536
- // TODO javadoc
537
- function tags(data) {
538
- var isFunc = $.isFunction(data);
539
- return function (query) {
540
- var t = query.term, filtered = {results: []};
541
- var result = isFunc ? data(query) : data;
542
- if ($.isArray(result)) {
543
- $(result).each(function () {
544
- var isObject = this.text !== undefined,
545
- text = isObject ? this.text : this;
546
- if (t === "" || query.matcher(t, text)) {
547
- filtered.results.push(isObject ? this : {id: this, text: this});
548
- }
549
- });
550
- query.callback(filtered);
551
- }
552
- };
535
+ calledConstructor = DecoratorClass.prototype.constructor;
536
+ }
537
+
538
+ calledConstructor.apply(this, arguments);
553
539
  }
554
540
 
555
- /**
556
- * Checks if the formatter function should be used.
557
- *
558
- * Throws an error if it is not a function. Returns true if it should be used,
559
- * false if no formatting should be performed.
560
- *
561
- * @param formatter
562
- */
563
- function checkFormatter(formatter, formatterName) {
564
- if ($.isFunction(formatter)) return true;
565
- if (!formatter) return false;
566
- if (typeof(formatter) === 'string') return true;
567
- throw new Error(formatterName +" must be a string, function, or falsy value");
541
+ DecoratorClass.displayName = SuperClass.displayName;
542
+
543
+ function ctr () {
544
+ this.constructor = DecoratedClass;
568
545
  }
569
546
 
570
- /**
571
- * Returns a given value
572
- * If given a function, returns its output
573
- *
574
- * @param val string|function
575
- * @param context value of "this" to be passed to function
576
- * @returns {*}
577
- */
578
- function evaluate(val, context) {
579
- if ($.isFunction(val)) {
580
- var args = Array.prototype.slice.call(arguments, 2);
581
- return val.apply(context, args);
582
- }
583
- return val;
547
+ DecoratedClass.prototype = new ctr();
548
+
549
+ for (var m = 0; m < superMethods.length; m++) {
550
+ var superMethod = superMethods[m];
551
+
552
+ DecoratedClass.prototype[superMethod] =
553
+ SuperClass.prototype[superMethod];
584
554
  }
585
555
 
586
- function countResults(results) {
587
- var count = 0;
588
- $.each(results, function(i, item) {
589
- if (item.children) {
590
- count += countResults(item.children);
591
- } else {
592
- count++;
593
- }
594
- });
595
- return count;
556
+ var calledMethod = function (methodName) {
557
+ // Stub out the original method if it's not decorating an actual method
558
+ var originalMethod = function () {};
559
+
560
+ if (methodName in DecoratedClass.prototype) {
561
+ originalMethod = DecoratedClass.prototype[methodName];
562
+ }
563
+
564
+ var decoratedMethod = DecoratorClass.prototype[methodName];
565
+
566
+ return function () {
567
+ var unshift = Array.prototype.unshift;
568
+
569
+ unshift.call(arguments, originalMethod);
570
+
571
+ return decoratedMethod.apply(this, arguments);
572
+ };
573
+ };
574
+
575
+ for (var d = 0; d < decoratedMethods.length; d++) {
576
+ var decoratedMethod = decoratedMethods[d];
577
+
578
+ DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
596
579
  }
597
580
 
598
- /**
599
- * Default tokenizer. This function uses breaks the input on substring match of any string from the
600
- * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those
601
- * two options have to be defined in order for the tokenizer to work.
602
- *
603
- * @param input text user has typed so far or pasted into the search field
604
- * @param selection currently selected choices
605
- * @param selectCallback function(choice) callback tho add the choice to selection
606
- * @param opts select2's opts
607
- * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value
608
- */
609
- function defaultTokenizer(input, selection, selectCallback, opts) {
610
- var original = input, // store the original so we can compare and know if we need to tell the search to update its text
611
- dupe = false, // check for whether a token we extracted represents a duplicate selected choice
612
- token, // token
613
- index, // position at which the separator was found
614
- i, l, // looping variables
615
- separator; // the matched separator
616
-
617
- if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
618
-
619
- while (true) {
620
- index = -1;
621
-
622
- for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
623
- separator = opts.tokenSeparators[i];
624
- index = input.indexOf(separator);
625
- if (index >= 0) break;
626
- }
581
+ return DecoratedClass;
582
+ };
627
583
 
628
- if (index < 0) break; // did not find any token separator in the input string, bail
584
+ var Observable = function () {
585
+ this.listeners = {};
586
+ };
629
587
 
630
- token = input.substring(0, index);
631
- input = input.substring(index + separator.length);
588
+ Observable.prototype.on = function (event, callback) {
589
+ this.listeners = this.listeners || {};
632
590
 
633
- if (token.length > 0) {
634
- token = opts.createSearchChoice.call(this, token, selection);
635
- if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
636
- dupe = false;
637
- for (i = 0, l = selection.length; i < l; i++) {
638
- if (equal(opts.id(token), opts.id(selection[i]))) {
639
- dupe = true; break;
640
- }
641
- }
591
+ if (event in this.listeners) {
592
+ this.listeners[event].push(callback);
593
+ } else {
594
+ this.listeners[event] = [callback];
595
+ }
596
+ };
642
597
 
643
- if (!dupe) selectCallback(token);
644
- }
645
- }
646
- }
598
+ Observable.prototype.trigger = function (event) {
599
+ var slice = Array.prototype.slice;
647
600
 
648
- if (original!==input) return input;
601
+ this.listeners = this.listeners || {};
602
+
603
+ if (event in this.listeners) {
604
+ this.invoke(this.listeners[event], slice.call(arguments, 1));
649
605
  }
650
606
 
651
- function cleanupJQueryElements() {
652
- var self = this;
607
+ if ('*' in this.listeners) {
608
+ this.invoke(this.listeners['*'], arguments);
609
+ }
610
+ };
653
611
 
654
- $.each(arguments, function (i, element) {
655
- self[element].remove();
656
- self[element] = null;
657
- });
612
+ Observable.prototype.invoke = function (listeners, params) {
613
+ for (var i = 0, len = listeners.length; i < len; i++) {
614
+ listeners[i].apply(this, params);
658
615
  }
616
+ };
659
617
 
660
- /**
661
- * Creates a new class
662
- *
663
- * @param superClass
664
- * @param methods
665
- */
666
- function clazz(SuperClass, methods) {
667
- var constructor = function () {};
668
- constructor.prototype = new SuperClass;
669
- constructor.prototype.constructor = constructor;
670
- constructor.prototype.parent = SuperClass.prototype;
671
- constructor.prototype = $.extend(constructor.prototype, methods);
672
- return constructor;
673
- }
674
-
675
- AbstractSelect2 = clazz(Object, {
676
-
677
- // abstract
678
- bind: function (func) {
679
- var self = this;
680
- return function () {
681
- func.apply(self, arguments);
682
- };
683
- },
618
+ Utils.Observable = Observable;
684
619
 
685
- // abstract
686
- init: function (opts) {
687
- var results, search, resultsSelector = ".select2-results";
620
+ Utils.generateChars = function (length) {
621
+ var chars = '';
688
622
 
689
- // prepare options
690
- this.opts = opts = this.prepareOpts(opts);
623
+ for (var i = 0; i < length; i++) {
624
+ var randomChar = Math.floor(Math.random() * 36);
625
+ chars += randomChar.toString(36);
626
+ }
691
627
 
692
- this.id=opts.id;
628
+ return chars;
629
+ };
693
630
 
694
- // destroy if called on an existing component
695
- if (opts.element.data("select2") !== undefined &&
696
- opts.element.data("select2") !== null) {
697
- opts.element.data("select2").destroy();
698
- }
631
+ Utils.bind = function (func, context) {
632
+ return function () {
633
+ func.apply(context, arguments);
634
+ };
635
+ };
699
636
 
700
- this.container = this.createContainer();
637
+ Utils._convertData = function (data) {
638
+ for (var originalKey in data) {
639
+ var keys = originalKey.split('-');
701
640
 
702
- this.liveRegion = $('.select2-hidden-accessible');
703
- if (this.liveRegion.length == 0) {
704
- this.liveRegion = $("<span>", {
705
- role: "status",
706
- "aria-live": "polite"
707
- })
708
- .addClass("select2-hidden-accessible")
709
- .appendTo(document.body);
710
- }
641
+ var dataLevel = data;
711
642
 
712
- this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
713
- this.containerEventName= this.containerId
714
- .replace(/([.])/g, '_')
715
- .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
716
- this.container.attr("id", this.containerId);
643
+ if (keys.length === 1) {
644
+ continue;
645
+ }
717
646
 
718
- this.container.attr("title", opts.element.attr("title"));
647
+ for (var k = 0; k < keys.length; k++) {
648
+ var key = keys[k];
719
649
 
720
- this.body = $(document.body);
650
+ // Lowercase the first letter
651
+ // By default, dash-separated becomes camelCase
652
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
721
653
 
722
- syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
654
+ if (!(key in dataLevel)) {
655
+ dataLevel[key] = {};
656
+ }
723
657
 
724
- this.container.attr("style", opts.element.attr("style"));
725
- this.container.css(evaluate(opts.containerCss, this.opts.element));
726
- this.container.addClass(evaluate(opts.containerCssClass, this.opts.element));
658
+ if (k == keys.length - 1) {
659
+ dataLevel[key] = data[originalKey];
660
+ }
727
661
 
728
- this.elementTabIndex = this.opts.element.attr("tabindex");
662
+ dataLevel = dataLevel[key];
663
+ }
729
664
 
730
- // swap container for the element
731
- this.opts.element
732
- .data("select2", this)
733
- .attr("tabindex", "-1")
734
- .before(this.container)
735
- .on("click.select2", killEvent); // do not leak click events
665
+ delete data[originalKey];
666
+ }
736
667
 
737
- this.container.data("select2", this);
668
+ return data;
669
+ };
738
670
 
739
- this.dropdown = this.container.find(".select2-drop");
671
+ Utils.hasScroll = function (index, el) {
672
+ // Adapted from the function created by @ShadowScripter
673
+ // and adapted by @BillBarry on the Stack Exchange Code Review website.
674
+ // The original code can be found at
675
+ // http://codereview.stackexchange.com/q/13338
676
+ // and was designed to be used with the Sizzle selector engine.
740
677
 
741
- syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
678
+ var $el = $(el);
679
+ var overflowX = el.style.overflowX;
680
+ var overflowY = el.style.overflowY;
742
681
 
743
- this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element));
744
- this.dropdown.data("select2", this);
745
- this.dropdown.on("click", killEvent);
682
+ //Check both x and y declarations
683
+ if (overflowX === overflowY &&
684
+ (overflowY === 'hidden' || overflowY === 'visible')) {
685
+ return false;
686
+ }
746
687
 
747
- this.results = results = this.container.find(resultsSelector);
748
- this.search = search = this.container.find("input.select2-input");
688
+ if (overflowX === 'scroll' || overflowY === 'scroll') {
689
+ return true;
690
+ }
749
691
 
750
- this.queryCount = 0;
751
- this.resultsPage = 0;
752
- this.context = null;
692
+ return ($el.innerHeight() < el.scrollHeight ||
693
+ $el.innerWidth() < el.scrollWidth);
694
+ };
695
+
696
+ Utils.escapeMarkup = function (markup) {
697
+ var replaceMap = {
698
+ '\\': '&#92;',
699
+ '&': '&amp;',
700
+ '<': '&lt;',
701
+ '>': '&gt;',
702
+ '"': '&quot;',
703
+ '\'': '&#39;',
704
+ '/': '&#47;'
705
+ };
753
706
 
754
- // initialize the container
755
- this.initContainer();
707
+ // Do not try to escape the markup if it's not a string
708
+ if (typeof markup !== 'string') {
709
+ return markup;
710
+ }
756
711
 
757
- this.container.on("click", killEvent);
712
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
713
+ return replaceMap[match];
714
+ });
715
+ };
758
716
 
759
- installFilteredMouseMove(this.results);
717
+ // Append an array of jQuery nodes to a given element.
718
+ Utils.appendMany = function ($element, $nodes) {
719
+ // jQuery 1.7.x does not support $.fn.append() with an array
720
+ // Fall back to a jQuery object collection using $.fn.add()
721
+ if ($.fn.jquery.substr(0, 3) === '1.7') {
722
+ var $jqNodes = $();
760
723
 
761
- this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent));
762
- this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function (event) {
763
- this._touchEvent = true;
764
- this.highlightUnderEvent(event);
765
- }));
766
- this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved));
767
- this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved));
724
+ $.map($nodes, function (node) {
725
+ $jqNodes = $jqNodes.add(node);
726
+ });
768
727
 
769
- // Waiting for a click event on touch devices to select option and hide dropdown
770
- // otherwise click will be triggered on an underlying element
771
- this.dropdown.on('click', this.bind(function (event) {
772
- if (this._touchEvent) {
773
- this._touchEvent = false;
774
- this.selectHighlighted();
775
- }
776
- }));
777
-
778
- installDebouncedScroll(80, this.results);
779
- this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
780
-
781
- // do not propagate change event from the search field out of the component
782
- $(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();});
783
- $(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();});
784
-
785
- // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
786
- if ($.fn.mousewheel) {
787
- results.mousewheel(function (e, delta, deltaX, deltaY) {
788
- var top = results.scrollTop();
789
- if (deltaY > 0 && top - deltaY <= 0) {
790
- results.scrollTop(0);
791
- killEvent(e);
792
- } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
793
- results.scrollTop(results.get(0).scrollHeight - results.height());
794
- killEvent(e);
795
- }
796
- });
797
- }
728
+ $nodes = $jqNodes;
729
+ }
798
730
 
799
- installKeyUpChangeEvent(search);
800
- search.on("keyup-change input paste", this.bind(this.updateResults));
801
- search.on("focus", function () { search.addClass("select2-focused"); });
802
- search.on("blur", function () { search.removeClass("select2-focused");});
731
+ $element.append($nodes);
732
+ };
803
733
 
804
- this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
805
- if ($(e.target).closest(".select2-result-selectable").length > 0) {
806
- this.highlightUnderEvent(e);
807
- this.selectHighlighted(e);
808
- }
809
- }));
734
+ return Utils;
735
+ });
810
736
 
811
- // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
812
- // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
813
- // dom it will trigger the popup close, which is not what we want
814
- // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.
815
- this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); });
737
+ S2.define('select2/results',[
738
+ 'jquery',
739
+ './utils'
740
+ ], function ($, Utils) {
741
+ function Results ($element, options, dataAdapter) {
742
+ this.$element = $element;
743
+ this.data = dataAdapter;
744
+ this.options = options;
816
745
 
817
- this.lastSearchTerm = undefined;
746
+ Results.__super__.constructor.call(this);
747
+ }
818
748
 
819
- if ($.isFunction(this.opts.initSelection)) {
820
- // initialize selection based on the current value of the source element
821
- this.initSelection();
749
+ Utils.Extend(Results, Utils.Observable);
822
750
 
823
- // if the user has provided a function that can set selection based on the value of the source element
824
- // we monitor the change event on the element and trigger it, allowing for two way synchronization
825
- this.monitorSource();
826
- }
751
+ Results.prototype.render = function () {
752
+ var $results = $(
753
+ '<ul class="select2-results__options" role="tree"></ul>'
754
+ );
827
755
 
828
- if (opts.maximumInputLength !== null) {
829
- this.search.attr("maxlength", opts.maximumInputLength);
830
- }
756
+ if (this.options.get('multiple')) {
757
+ $results.attr('aria-multiselectable', 'true');
758
+ }
831
759
 
832
- var disabled = opts.element.prop("disabled");
833
- if (disabled === undefined) disabled = false;
834
- this.enable(!disabled);
760
+ this.$results = $results;
835
761
 
836
- var readonly = opts.element.prop("readonly");
837
- if (readonly === undefined) readonly = false;
838
- this.readonly(readonly);
762
+ return $results;
763
+ };
839
764
 
840
- // Calculate size of scrollbar
841
- scrollBarDimensions = scrollBarDimensions || measureScrollbar();
765
+ Results.prototype.clear = function () {
766
+ this.$results.empty();
767
+ };
842
768
 
843
- this.autofocus = opts.element.prop("autofocus");
844
- opts.element.prop("autofocus", false);
845
- if (this.autofocus) this.focus();
769
+ Results.prototype.displayMessage = function (params) {
770
+ var escapeMarkup = this.options.get('escapeMarkup');
846
771
 
847
- this.search.attr("placeholder", opts.searchInputPlaceholder);
848
- },
772
+ this.clear();
773
+ this.hideLoading();
849
774
 
850
- // abstract
851
- destroy: function () {
852
- var element=this.opts.element, select2 = element.data("select2"), self = this;
775
+ var $message = $(
776
+ '<li role="treeitem" class="select2-results__option"></li>'
777
+ );
853
778
 
854
- this.close();
779
+ var message = this.options.get('translations').get(params.message);
855
780
 
856
- if (element.length && element[0].detachEvent && self._sync) {
857
- element.each(function () {
858
- if (self._sync) {
859
- this.detachEvent("onpropertychange", self._sync);
860
- }
861
- });
862
- }
863
- if (this.propertyObserver) {
864
- this.propertyObserver.disconnect();
865
- this.propertyObserver = null;
866
- }
867
- this._sync = null;
868
-
869
- if (select2 !== undefined) {
870
- select2.container.remove();
871
- select2.liveRegion.remove();
872
- select2.dropdown.remove();
873
- element.removeData("select2")
874
- .off(".select2");
875
- if (!element.is("input[type='hidden']")) {
876
- element
877
- .show()
878
- .prop("autofocus", this.autofocus || false);
879
- if (this.elementTabIndex) {
880
- element.attr({tabindex: this.elementTabIndex});
881
- } else {
882
- element.removeAttr("tabindex");
883
- }
884
- element.show();
885
- } else {
886
- element.css("display", "");
887
- }
888
- }
781
+ $message.append(
782
+ escapeMarkup(
783
+ message(params.args)
784
+ )
785
+ );
889
786
 
890
- cleanupJQueryElements.call(this,
891
- "container",
892
- "liveRegion",
893
- "dropdown",
894
- "results",
895
- "search"
896
- );
897
- },
787
+ this.$results.append($message);
788
+ };
898
789
 
899
- // abstract
900
- optionToData: function(element) {
901
- if (element.is("option")) {
902
- return {
903
- id:element.prop("value"),
904
- text:element.text(),
905
- element: element.get(),
906
- css: element.attr("class"),
907
- disabled: element.prop("disabled"),
908
- locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true)
909
- };
910
- } else if (element.is("optgroup")) {
911
- return {
912
- text:element.attr("label"),
913
- children:[],
914
- element: element.get(),
915
- css: element.attr("class")
916
- };
917
- }
918
- },
790
+ Results.prototype.append = function (data) {
791
+ this.hideLoading();
919
792
 
920
- // abstract
921
- prepareOpts: function (opts) {
922
- var element, select, idKey, ajaxUrl, self = this;
793
+ var $options = [];
923
794
 
924
- element = opts.element;
795
+ if (data.results == null || data.results.length === 0) {
796
+ if (this.$results.children().length === 0) {
797
+ this.trigger('results:message', {
798
+ message: 'noResults'
799
+ });
800
+ }
925
801
 
926
- if (element.get(0).tagName.toLowerCase() === "select") {
927
- this.select = select = opts.element;
928
- }
802
+ return;
803
+ }
929
804
 
930
- if (select) {
931
- // these options are not allowed when attached to a select because they are picked up off the element itself
932
- $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
933
- if (this in opts) {
934
- throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
935
- }
936
- });
937
- }
805
+ data.results = this.sort(data.results);
938
806
 
939
- opts.debug = opts.debug || $.fn.select2.defaults.debug;
940
-
941
- // Warnings for options renamed/removed in Select2 4.0.0
942
- // Only when it's enabled through debug mode
943
- if (opts.debug && console && console.warn) {
944
- // id was removed
945
- if (opts.id != null) {
946
- console.warn(
947
- 'Select2: The `id` option has been removed in Select2 4.0.0, ' +
948
- 'consider renaming your `id` property or mapping the property before your data makes it to Select2. ' +
949
- 'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
950
- );
951
- }
807
+ for (var d = 0; d < data.results.length; d++) {
808
+ var item = data.results[d];
952
809
 
953
- // text was removed
954
- if (opts.text != null) {
955
- console.warn(
956
- 'Select2: The `text` option has been removed in Select2 4.0.0, ' +
957
- 'consider renaming your `text` property or mapping the property before your data makes it to Select2. ' +
958
- 'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
959
- );
960
- }
810
+ var $option = this.option(item);
961
811
 
962
- // sortResults was renamed to results
963
- if (opts.sortResults != null) {
964
- console.warn(
965
- 'Select2: the `sortResults` option has been renamed to `sorter` in Select2 4.0.0. '
966
- );
967
- }
812
+ $options.push($option);
813
+ }
968
814
 
969
- // selectOnBlur was renamed to selectOnClose
970
- if (opts.selectOnBlur != null) {
971
- console.warn(
972
- 'Select2: The `selectOnBlur` option has been renamed to `selectOnClose` in Select2 4.0.0.'
973
- );
974
- }
815
+ this.$results.append($options);
816
+ };
975
817
 
976
- // ajax.results was renamed to ajax.processResults
977
- if (opts.ajax != null && opts.ajax.results != null) {
978
- console.warn(
979
- 'Select2: The `ajax.results` option has been renamed to `ajax.processResults` in Select2 4.0.0.'
980
- );
981
- }
818
+ Results.prototype.position = function ($results, $dropdown) {
819
+ var $resultsContainer = $dropdown.find('.select2-results');
820
+ $resultsContainer.append($results);
821
+ };
982
822
 
983
- // format* options were renamed to language.*
984
- if (opts.formatNoResults != null) {
985
- console.warn(
986
- 'Select2: The `formatNoResults` option has been renamed to `language.noResults` in Select2 4.0.0.'
987
- );
988
- }
989
- if (opts.formatSearching != null) {
990
- console.warn(
991
- 'Select2: The `formatSearching` option has been renamed to `language.searching` in Select2 4.0.0.'
992
- );
993
- }
994
- if (opts.formatInputTooShort != null) {
995
- console.warn(
996
- 'Select2: The `formatInputTooShort` option has been renamed to `language.inputTooShort` in Select2 4.0.0.'
997
- );
998
- }
999
- if (opts.formatInputTooLong != null) {
1000
- console.warn(
1001
- 'Select2: The `formatInputTooLong` option has been renamed to `language.inputTooLong` in Select2 4.0.0.'
1002
- );
1003
- }
1004
- if (opts.formatLoading != null) {
1005
- console.warn(
1006
- 'Select2: The `formatLoading` option has been renamed to `language.loadingMore` in Select2 4.0.0.'
1007
- );
1008
- }
1009
- if (opts.formatSelectionTooBig != null) {
1010
- console.warn(
1011
- 'Select2: The `formatSelectionTooBig` option has been renamed to `language.maximumSelected` in Select2 4.0.0.'
1012
- );
1013
- }
823
+ Results.prototype.sort = function (data) {
824
+ var sorter = this.options.get('sorter');
1014
825
 
1015
- if (opts.element.data('select2Tags')) {
1016
- console.warn(
1017
- 'Select2: The `data-select2-tags` attribute has been renamed to `data-tags` in Select2 4.0.0.'
1018
- );
1019
- }
1020
- }
826
+ return sorter(data);
827
+ };
1021
828
 
1022
- // Aliasing options renamed in Select2 4.0.0
829
+ Results.prototype.setClasses = function () {
830
+ var self = this;
1023
831
 
1024
- // data-select2-tags -> data-tags
1025
- if (opts.element.data('tags') != null) {
1026
- var elemTags = opts.element.data('tags');
832
+ this.data.current(function (selected) {
833
+ var selectedIds = $.map(selected, function (s) {
834
+ return s.id.toString();
835
+ });
1027
836
 
1028
- // data-tags should actually be a boolean
1029
- if (!$.isArray(elemTags)) {
1030
- elemTags = [];
1031
- }
837
+ var $options = self.$results
838
+ .find('.select2-results__option[aria-selected]');
1032
839
 
1033
- opts.element.data('select2Tags', elemTags);
1034
- }
840
+ $options.each(function () {
841
+ var $option = $(this);
1035
842
 
1036
- // sortResults -> sorter
1037
- if (opts.sorter != null) {
1038
- opts.sortResults = opts.sorter;
1039
- }
843
+ var item = $.data(this, 'data');
1040
844
 
1041
- // selectOnBlur -> selectOnClose
1042
- if (opts.selectOnClose != null) {
1043
- opts.selectOnBlur = opts.selectOnClose;
1044
- }
845
+ // id needs to be converted to a string when comparing
846
+ var id = '' + item.id;
1045
847
 
1046
- // ajax.results -> ajax.processResults
1047
- if (opts.ajax != null) {
1048
- if ($.isFunction(opts.ajax.processResults)) {
1049
- opts.ajax.results = opts.ajax.processResults;
1050
- }
1051
- }
848
+ if ((item.element != null && item.element.selected) ||
849
+ (item.element == null && $.inArray(id, selectedIds) > -1)) {
850
+ $option.attr('aria-selected', 'true');
851
+ } else {
852
+ $option.attr('aria-selected', 'false');
853
+ }
854
+ });
855
+
856
+ var $selected = $options.filter('[aria-selected=true]');
857
+
858
+ // Check if there are any selected options
859
+ if ($selected.length > 0) {
860
+ // If there are selected options, highlight the first
861
+ $selected.first().trigger('mouseenter');
862
+ } else {
863
+ // If there are no selected options, highlight the first option
864
+ // in the dropdown
865
+ $options.first().trigger('mouseenter');
866
+ }
867
+ });
868
+ };
1052
869
 
1053
- // Formatters/language options
1054
- if (opts.language != null) {
1055
- var lang = opts.language;
870
+ Results.prototype.showLoading = function (params) {
871
+ this.hideLoading();
1056
872
 
1057
- // formatNoMatches -> language.noMatches
1058
- if ($.isFunction(lang.noMatches)) {
1059
- opts.formatNoMatches = lang.noMatches;
1060
- }
873
+ var loadingMore = this.options.get('translations').get('searching');
1061
874
 
1062
- // formatSearching -> language.searching
1063
- if ($.isFunction(lang.searching)) {
1064
- opts.formatSearching = lang.searching;
1065
- }
875
+ var loading = {
876
+ disabled: true,
877
+ loading: true,
878
+ text: loadingMore(params)
879
+ };
880
+ var $loading = this.option(loading);
881
+ $loading.className += ' loading-results';
1066
882
 
1067
- // formatInputTooShort -> language.inputTooShort
1068
- if ($.isFunction(lang.inputTooShort)) {
1069
- opts.formatInputTooShort = lang.inputTooShort;
1070
- }
883
+ this.$results.prepend($loading);
884
+ };
1071
885
 
1072
- // formatInputTooLong -> language.inputTooLong
1073
- if ($.isFunction(lang.inputTooLong)) {
1074
- opts.formatInputTooLong = lang.inputTooLong;
1075
- }
886
+ Results.prototype.hideLoading = function () {
887
+ this.$results.find('.loading-results').remove();
888
+ };
1076
889
 
1077
- // formatLoading -> language.loadingMore
1078
- if ($.isFunction(lang.loadingMore)) {
1079
- opts.formatLoading = lang.loadingMore;
1080
- }
890
+ Results.prototype.option = function (data) {
891
+ var option = document.createElement('li');
892
+ option.className = 'select2-results__option';
1081
893
 
1082
- // formatSelectionTooBig -> language.maximumSelected
1083
- if ($.isFunction(lang.maximumSelected)) {
1084
- opts.formatSelectionTooBig = lang.maximumSelected;
1085
- }
1086
- }
894
+ var attrs = {
895
+ 'role': 'treeitem',
896
+ 'aria-selected': 'false'
897
+ };
1087
898
 
1088
- opts = $.extend({}, {
1089
- populateResults: function(container, results, query) {
1090
- var populate, id=this.opts.id, liveRegion=this.liveRegion;
899
+ if (data.disabled) {
900
+ delete attrs['aria-selected'];
901
+ attrs['aria-disabled'] = 'true';
902
+ }
1091
903
 
1092
- populate=function(results, container, depth) {
904
+ if (data.id == null) {
905
+ delete attrs['aria-selected'];
906
+ }
1093
907
 
1094
- var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
908
+ if (data._resultId != null) {
909
+ option.id = data._resultId;
910
+ }
1095
911
 
1096
- results = opts.sortResults(results, container, query);
912
+ if (data.title) {
913
+ option.title = data.title;
914
+ }
1097
915
 
1098
- // collect the created nodes for bulk append
1099
- var nodes = [];
1100
- for (i = 0, l = results.length; i < l; i = i + 1) {
916
+ if (data.children) {
917
+ attrs.role = 'group';
918
+ attrs['aria-label'] = data.text;
919
+ delete attrs['aria-selected'];
920
+ }
1101
921
 
1102
- result=results[i];
922
+ for (var attr in attrs) {
923
+ var val = attrs[attr];
1103
924
 
1104
- disabled = (result.disabled === true);
1105
- selectable = (!disabled) && (id(result) !== undefined);
925
+ option.setAttribute(attr, val);
926
+ }
1106
927
 
1107
- compound=result.children && result.children.length > 0;
928
+ if (data.children) {
929
+ var $option = $(option);
1108
930
 
1109
- node=$("<li></li>");
1110
- node.addClass("select2-results-dept-"+depth);
1111
- node.addClass("select2-result");
1112
- node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
1113
- if (disabled) { node.addClass("select2-disabled"); }
1114
- if (compound) { node.addClass("select2-result-with-children"); }
1115
- node.addClass(self.opts.formatResultCssClass(result));
1116
- node.attr("role", "presentation");
931
+ var label = document.createElement('strong');
932
+ label.className = 'select2-results__group';
1117
933
 
1118
- label=$(document.createElement("div"));
1119
- label.addClass("select2-result-label");
1120
- label.attr("id", "select2-result-label-" + nextUid());
1121
- label.attr("role", "option");
934
+ var $label = $(label);
935
+ this.template(data, label);
1122
936
 
1123
- formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);
1124
- if (formatted!==undefined) {
1125
- label.html(formatted);
1126
- node.append(label);
1127
- }
937
+ var $children = [];
1128
938
 
939
+ for (var c = 0; c < data.children.length; c++) {
940
+ var child = data.children[c];
1129
941
 
1130
- if (compound) {
1131
- innerContainer=$("<ul></ul>");
1132
- innerContainer.addClass("select2-result-sub");
1133
- populate(result.children, innerContainer, depth+1);
1134
- node.append(innerContainer);
1135
- }
942
+ var $child = this.option(child);
1136
943
 
1137
- node.data("select2-data", result);
1138
- nodes.push(node[0]);
1139
- }
944
+ $children.push($child);
945
+ }
1140
946
 
1141
- // bulk append the created nodes
1142
- container.append(nodes);
1143
- liveRegion.text(opts.formatMatches(results.length));
1144
- };
947
+ var $childrenContainer = $('<ul></ul>', {
948
+ 'class': 'select2-results__options select2-results__options--nested'
949
+ });
1145
950
 
1146
- populate(results, container, 0);
1147
- }
1148
- }, $.fn.select2.defaults, opts);
951
+ $childrenContainer.append($children);
1149
952
 
1150
- if (typeof(opts.id) !== "function") {
1151
- idKey = opts.id;
1152
- opts.id = function (e) { return e[idKey]; };
1153
- }
953
+ $option.append(label);
954
+ $option.append($childrenContainer);
955
+ } else {
956
+ this.template(data, option);
957
+ }
1154
958
 
1155
- if ($.isArray(opts.element.data("select2Tags"))) {
1156
- if ("tags" in opts) {
1157
- throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
1158
- }
1159
- opts.tags=opts.element.data("select2Tags");
1160
- }
959
+ $.data(option, 'data', data);
1161
960
 
1162
- if (select) {
1163
- opts.query = this.bind(function (query) {
1164
- var data = { results: [], more: false },
1165
- term = query.term,
1166
- children, placeholderOption, process;
1167
-
1168
- process=function(element, collection) {
1169
- var group;
1170
- if (element.is("option")) {
1171
- if (query.matcher(term, element.text(), element)) {
1172
- collection.push(self.optionToData(element));
1173
- }
1174
- } else if (element.is("optgroup")) {
1175
- group=self.optionToData(element);
1176
- element.children().each2(function(i, elm) { process(elm, group.children); });
1177
- if (group.children.length>0) {
1178
- collection.push(group);
1179
- }
1180
- }
1181
- };
961
+ return option;
962
+ };
1182
963
 
1183
- children=element.children();
964
+ Results.prototype.bind = function (container, $container) {
965
+ var self = this;
1184
966
 
1185
- // ignore the placeholder option if there is one
1186
- if (this.getPlaceholder() !== undefined && children.length > 0) {
1187
- placeholderOption = this.getPlaceholderOption();
1188
- if (placeholderOption) {
1189
- children=children.not(placeholderOption);
1190
- }
1191
- }
967
+ var id = container.id + '-results';
1192
968
 
1193
- children.each2(function(i, elm) { process(elm, data.results); });
969
+ this.$results.attr('id', id);
1194
970
 
1195
- query.callback(data);
1196
- });
1197
- // this is needed because inside val() we construct choices from options and their id is hardcoded
1198
- opts.id=function(e) { return e.id; };
1199
- } else {
1200
- if (!("query" in opts)) {
1201
- if ("ajax" in opts) {
1202
- ajaxUrl = opts.element.data("ajax-url");
1203
- if (ajaxUrl && ajaxUrl.length > 0) {
1204
- opts.ajax.url = ajaxUrl;
1205
- }
1206
- opts.query = ajax.call(opts.element, opts.ajax);
1207
- } else if ("data" in opts) {
1208
- opts.query = local(opts.data);
1209
- } else if ("tags" in opts) {
1210
- opts.query = tags(opts.tags);
1211
- if (opts.createSearchChoice === undefined) {
1212
- opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; };
1213
- }
1214
- if (opts.initSelection === undefined) {
1215
- opts.initSelection = function (element, callback) {
1216
- var data = [];
1217
- $(splitVal(element.val(), opts.separator, opts.transformVal)).each(function () {
1218
- var obj = { id: this, text: this },
1219
- tags = opts.tags;
1220
- if ($.isFunction(tags)) tags=tags();
1221
- $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } });
1222
- data.push(obj);
1223
- });
1224
-
1225
- callback(data);
1226
- };
1227
- }
1228
- }
1229
- }
1230
- }
1231
- if (typeof(opts.query) !== "function") {
1232
- throw "query function not defined for Select2 " + opts.element.attr("id");
1233
- }
971
+ container.on('results:all', function (params) {
972
+ self.clear();
973
+ self.append(params.data);
1234
974
 
1235
- if (opts.createSearchChoicePosition === 'top') {
1236
- opts.createSearchChoicePosition = function(list, item) { list.unshift(item); };
1237
- }
1238
- else if (opts.createSearchChoicePosition === 'bottom') {
1239
- opts.createSearchChoicePosition = function(list, item) { list.push(item); };
1240
- }
1241
- else if (typeof(opts.createSearchChoicePosition) !== "function") {
1242
- throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";
1243
- }
975
+ if (container.isOpen()) {
976
+ self.setClasses();
977
+ }
978
+ });
1244
979
 
1245
- return opts;
1246
- },
980
+ container.on('results:append', function (params) {
981
+ self.append(params.data);
1247
982
 
1248
- /**
1249
- * Monitor the original element for changes and update select2 accordingly
1250
- */
1251
- // abstract
1252
- monitorSource: function () {
1253
- var el = this.opts.element, observer, self = this;
983
+ if (container.isOpen()) {
984
+ self.setClasses();
985
+ }
986
+ });
1254
987
 
1255
- el.on("change.select2", this.bind(function (e) {
1256
- if (this.opts.element.data("select2-change-triggered") !== true) {
1257
- this.initSelection();
1258
- }
1259
- }));
988
+ container.on('query', function (params) {
989
+ self.showLoading(params);
990
+ });
1260
991
 
1261
- this._sync = this.bind(function () {
992
+ container.on('select', function () {
993
+ if (!container.isOpen()) {
994
+ return;
995
+ }
1262
996
 
1263
- // sync enabled state
1264
- var disabled = el.prop("disabled");
1265
- if (disabled === undefined) disabled = false;
1266
- this.enable(!disabled);
997
+ self.setClasses();
998
+ });
1267
999
 
1268
- var readonly = el.prop("readonly");
1269
- if (readonly === undefined) readonly = false;
1270
- this.readonly(readonly);
1000
+ container.on('unselect', function () {
1001
+ if (!container.isOpen()) {
1002
+ return;
1003
+ }
1271
1004
 
1272
- if (this.container) {
1273
- syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
1274
- this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element));
1275
- }
1005
+ self.setClasses();
1006
+ });
1276
1007
 
1277
- if (this.dropdown) {
1278
- syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
1279
-