fomantic-ui 2.10.0-beta.4 → 2.10.0-beta.41

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 (246) hide show
  1. package/.eslintrc.js +0 -10
  2. package/CHANGELOG.md +5289 -2325
  3. package/README.md +4 -5
  4. package/changelog-setup.js +85 -69
  5. package/changelog-template.hbs +256 -251
  6. package/dist/components/accordion.css +1 -1
  7. package/dist/components/accordion.js +103 -142
  8. package/dist/components/accordion.min.css +1 -1
  9. package/dist/components/accordion.min.js +2 -2
  10. package/dist/components/ad.css +1 -1
  11. package/dist/components/ad.min.css +1 -1
  12. package/dist/components/api.js +152 -205
  13. package/dist/components/api.min.js +2 -2
  14. package/dist/components/breadcrumb.css +1 -1
  15. package/dist/components/breadcrumb.min.css +1 -1
  16. package/dist/components/button.css +1 -2
  17. package/dist/components/button.min.css +2 -2
  18. package/dist/components/calendar.css +1 -1
  19. package/dist/components/calendar.js +308 -346
  20. package/dist/components/calendar.min.css +1 -1
  21. package/dist/components/calendar.min.js +2 -2
  22. package/dist/components/card.css +1 -1
  23. package/dist/components/card.min.css +1 -1
  24. package/dist/components/checkbox.css +1 -1
  25. package/dist/components/checkbox.js +85 -127
  26. package/dist/components/checkbox.min.css +1 -1
  27. package/dist/components/checkbox.min.js +2 -2
  28. package/dist/components/comment.css +1 -1
  29. package/dist/components/comment.min.css +1 -1
  30. package/dist/components/container.css +1 -1
  31. package/dist/components/container.min.css +1 -1
  32. package/dist/components/dimmer.css +1 -1
  33. package/dist/components/dimmer.js +58 -91
  34. package/dist/components/dimmer.min.css +1 -1
  35. package/dist/components/dimmer.min.js +2 -2
  36. package/dist/components/divider.css +1 -1
  37. package/dist/components/divider.min.css +1 -1
  38. package/dist/components/dropdown.css +7 -5
  39. package/dist/components/dropdown.js +744 -1071
  40. package/dist/components/dropdown.min.css +2 -2
  41. package/dist/components/dropdown.min.js +2 -2
  42. package/dist/components/embed.css +1 -1
  43. package/dist/components/embed.js +83 -113
  44. package/dist/components/embed.min.css +1 -1
  45. package/dist/components/embed.min.js +2 -2
  46. package/dist/components/emoji.css +3809 -7617
  47. package/dist/components/emoji.min.css +2 -2
  48. package/dist/components/feed.css +1 -1
  49. package/dist/components/feed.min.css +1 -1
  50. package/dist/components/flag.css +1 -1
  51. package/dist/components/flag.min.css +1 -1
  52. package/dist/components/flyout.css +1 -1
  53. package/dist/components/flyout.js +225 -314
  54. package/dist/components/flyout.min.css +1 -1
  55. package/dist/components/flyout.min.js +2 -2
  56. package/dist/components/form.css +1 -1
  57. package/dist/components/form.js +325 -429
  58. package/dist/components/form.min.css +1 -1
  59. package/dist/components/form.min.js +2 -2
  60. package/dist/components/grid.css +1 -1
  61. package/dist/components/grid.min.css +1 -1
  62. package/dist/components/header.css +1 -1
  63. package/dist/components/header.min.css +1 -1
  64. package/dist/components/icon.css +1 -1
  65. package/dist/components/icon.min.css +1 -1
  66. package/dist/components/image.css +1 -1
  67. package/dist/components/image.min.css +1 -1
  68. package/dist/components/input.css +1 -1
  69. package/dist/components/input.min.css +1 -1
  70. package/dist/components/item.css +1 -1
  71. package/dist/components/item.min.css +1 -1
  72. package/dist/components/label.css +2 -1
  73. package/dist/components/label.min.css +2 -2
  74. package/dist/components/list.css +1 -1
  75. package/dist/components/list.min.css +1 -1
  76. package/dist/components/loader.css +1 -1
  77. package/dist/components/loader.min.css +1 -1
  78. package/dist/components/menu.css +40 -40
  79. package/dist/components/menu.min.css +2 -2
  80. package/dist/components/message.css +1 -1
  81. package/dist/components/message.min.css +1 -1
  82. package/dist/components/modal.css +3 -3
  83. package/dist/components/modal.js +259 -358
  84. package/dist/components/modal.min.css +2 -2
  85. package/dist/components/modal.min.js +2 -2
  86. package/dist/components/nag.css +1 -1
  87. package/dist/components/nag.js +67 -97
  88. package/dist/components/nag.min.css +1 -1
  89. package/dist/components/nag.min.js +2 -2
  90. package/dist/components/placeholder.css +1 -1
  91. package/dist/components/placeholder.min.css +1 -1
  92. package/dist/components/popup.css +1 -1
  93. package/dist/components/popup.js +190 -264
  94. package/dist/components/popup.min.css +1 -1
  95. package/dist/components/popup.min.js +2 -2
  96. package/dist/components/progress.css +1 -1
  97. package/dist/components/progress.js +103 -138
  98. package/dist/components/progress.min.css +1 -1
  99. package/dist/components/progress.min.js +2 -2
  100. package/dist/components/rail.css +1 -1
  101. package/dist/components/rail.min.css +1 -1
  102. package/dist/components/rating.css +1 -1
  103. package/dist/components/rating.js +90 -123
  104. package/dist/components/rating.min.css +1 -1
  105. package/dist/components/rating.min.js +2 -2
  106. package/dist/components/reset.css +1 -1
  107. package/dist/components/reset.min.css +1 -1
  108. package/dist/components/reveal.css +1 -1
  109. package/dist/components/reveal.min.css +1 -1
  110. package/dist/components/search.css +1 -1
  111. package/dist/components/search.js +270 -373
  112. package/dist/components/search.min.css +1 -1
  113. package/dist/components/search.min.js +2 -2
  114. package/dist/components/segment.css +1 -1
  115. package/dist/components/segment.min.css +1 -1
  116. package/dist/components/shape.css +1 -1
  117. package/dist/components/shape.js +157 -223
  118. package/dist/components/shape.min.css +1 -1
  119. package/dist/components/shape.min.js +2 -2
  120. package/dist/components/sidebar.css +1 -1
  121. package/dist/components/sidebar.js +125 -165
  122. package/dist/components/sidebar.min.css +1 -1
  123. package/dist/components/sidebar.min.js +2 -2
  124. package/dist/components/site.css +1 -1
  125. package/dist/components/site.js +38 -57
  126. package/dist/components/site.min.css +1 -1
  127. package/dist/components/site.min.js +2 -2
  128. package/dist/components/slider.css +1 -1
  129. package/dist/components/slider.js +242 -325
  130. package/dist/components/slider.min.css +1 -1
  131. package/dist/components/slider.min.js +2 -2
  132. package/dist/components/state.js +68 -98
  133. package/dist/components/state.min.js +2 -2
  134. package/dist/components/statistic.css +1 -1
  135. package/dist/components/statistic.min.css +1 -1
  136. package/dist/components/step.css +1 -1
  137. package/dist/components/step.min.css +1 -1
  138. package/dist/components/sticky.css +1 -1
  139. package/dist/components/sticky.js +131 -176
  140. package/dist/components/sticky.min.css +1 -1
  141. package/dist/components/sticky.min.js +2 -2
  142. package/dist/components/tab.css +1 -1
  143. package/dist/components/tab.js +168 -233
  144. package/dist/components/tab.min.css +1 -1
  145. package/dist/components/tab.min.js +2 -2
  146. package/dist/components/table.css +8 -8
  147. package/dist/components/table.min.css +2 -2
  148. package/dist/components/text.css +1 -1
  149. package/dist/components/text.min.css +1 -1
  150. package/dist/components/toast.css +1 -1
  151. package/dist/components/toast.js +104 -143
  152. package/dist/components/toast.min.css +1 -1
  153. package/dist/components/toast.min.js +2 -2
  154. package/dist/components/transition.css +1 -1
  155. package/dist/components/transition.js +86 -141
  156. package/dist/components/transition.min.css +1 -1
  157. package/dist/components/transition.min.js +2 -2
  158. package/dist/components/visibility.js +145 -223
  159. package/dist/components/visibility.min.js +2 -2
  160. package/dist/semantic.css +3916 -7722
  161. package/dist/semantic.js +4324 -5973
  162. package/dist/semantic.min.css +2 -2
  163. package/dist/semantic.min.js +2 -2
  164. package/examples/assets/show-examples.js +2 -4
  165. package/examples/attached.html +1 -1
  166. package/examples/components/menu.html +1 -1
  167. package/gulpfile.js +5 -7
  168. package/package.json +1 -3
  169. package/scripts/nightly-version.js +7 -10
  170. package/src/definitions/behaviors/api.js +151 -204
  171. package/src/definitions/behaviors/form.js +324 -428
  172. package/src/definitions/behaviors/state.js +67 -97
  173. package/src/definitions/behaviors/visibility.js +144 -222
  174. package/src/definitions/collections/menu.less +101 -96
  175. package/src/definitions/collections/table.less +7 -7
  176. package/src/definitions/elements/button.less +0 -1
  177. package/src/definitions/elements/label.less +1 -0
  178. package/src/definitions/globals/site.js +37 -56
  179. package/src/definitions/modules/accordion.js +102 -141
  180. package/src/definitions/modules/calendar.js +307 -345
  181. package/src/definitions/modules/checkbox.js +84 -126
  182. package/src/definitions/modules/dimmer.js +57 -90
  183. package/src/definitions/modules/dropdown.js +743 -1070
  184. package/src/definitions/modules/dropdown.less +11 -5
  185. package/src/definitions/modules/embed.js +82 -112
  186. package/src/definitions/modules/flyout.js +224 -313
  187. package/src/definitions/modules/modal.js +258 -357
  188. package/src/definitions/modules/modal.less +1 -1
  189. package/src/definitions/modules/nag.js +66 -96
  190. package/src/definitions/modules/popup.js +189 -263
  191. package/src/definitions/modules/progress.js +102 -137
  192. package/src/definitions/modules/rating.js +89 -122
  193. package/src/definitions/modules/search.js +269 -372
  194. package/src/definitions/modules/shape.js +156 -222
  195. package/src/definitions/modules/sidebar.js +124 -164
  196. package/src/definitions/modules/slider.js +241 -324
  197. package/src/definitions/modules/sticky.js +130 -175
  198. package/src/definitions/modules/tab.js +167 -232
  199. package/src/definitions/modules/toast.js +103 -142
  200. package/src/definitions/modules/transition.js +85 -140
  201. package/src/themes/chubby/collections/menu.variables +1 -1
  202. package/src/themes/default/collections/menu.variables +23 -23
  203. package/src/themes/default/globals/variation.variables +3 -2
  204. package/src/themes/default/modules/dropdown.variables +1 -0
  205. package/src/themes/default/modules/modal.variables +1 -1
  206. package/tasks/admin/components/create.js +88 -108
  207. package/tasks/admin/components/init.js +26 -32
  208. package/tasks/admin/components/update.js +46 -53
  209. package/tasks/admin/distributions/create.js +71 -101
  210. package/tasks/admin/distributions/init.js +27 -33
  211. package/tasks/admin/distributions/update.js +45 -52
  212. package/tasks/admin/register.js +11 -15
  213. package/tasks/build/assets.js +14 -18
  214. package/tasks/build/css.js +54 -63
  215. package/tasks/build/javascript.js +45 -53
  216. package/tasks/build.js +4 -6
  217. package/tasks/check-install.js +5 -7
  218. package/tasks/clean.js +2 -4
  219. package/tasks/collections/admin.js +13 -15
  220. package/tasks/collections/build.js +6 -8
  221. package/tasks/collections/docs.js +2 -4
  222. package/tasks/collections/install.js +2 -4
  223. package/tasks/collections/rtl.js +2 -4
  224. package/tasks/collections/various.js +2 -4
  225. package/tasks/config/admin/github.js +7 -9
  226. package/tasks/config/admin/templates/css-package.js +1 -3
  227. package/tasks/config/admin/templates/less-package.js +1 -3
  228. package/tasks/config/defaults.js +0 -1
  229. package/tasks/config/npm/gulpfile.js +4 -6
  230. package/tasks/config/project/config.js +22 -30
  231. package/tasks/config/project/install.js +61 -78
  232. package/tasks/config/project/release.js +6 -8
  233. package/tasks/config/tasks.js +8 -12
  234. package/tasks/config/user.js +13 -17
  235. package/tasks/docs/build.js +26 -31
  236. package/tasks/docs/metadata.js +24 -30
  237. package/tasks/docs/serve.js +20 -26
  238. package/tasks/install.js +81 -109
  239. package/tasks/rtl/build.js +2 -4
  240. package/tasks/rtl/watch.js +2 -4
  241. package/tasks/watch.js +9 -11
  242. package/test/meteor/fonts.js +1 -2
  243. package/test/modules/module.spec.js +16 -18
  244. package/types/fomantic-ui-dropdown.d.ts +44 -0
  245. package/types/fomantic-ui-embed.d.ts +1 -1
  246. package/types/fomantic-ui-search.d.ts +6 -6
@@ -20,91 +20,87 @@
20
20
  : globalThis;
21
21
 
22
22
  $.fn.dropdown = function (parameters) {
23
- var
24
- $allModules = $(this),
25
- $document = $(document),
26
-
27
- time = Date.now(),
28
- performance = [],
29
-
30
- query = arguments[0],
31
- methodInvoked = typeof query === 'string',
32
- queryArguments = [].slice.call(arguments, 1),
33
- contextCheck = function (context, win) {
34
- var $context;
35
- if ([window, document].indexOf(context) >= 0) {
36
- $context = $(context);
37
- } else {
38
- $context = $(win.document).find(context);
39
- if ($context.length === 0) {
40
- $context = win.frameElement ? contextCheck(context, win.parent) : window;
41
- }
23
+ let $allModules = $(this);
24
+ let $document = $(document);
25
+
26
+ let time = Date.now();
27
+ let performance = [];
28
+
29
+ let query = arguments[0];
30
+ let methodInvoked = typeof query === 'string';
31
+ let queryArguments = [].slice.call(arguments, 1);
32
+ let contextCheck = function (context, win) {
33
+ let $context;
34
+ if ([window, document].indexOf(context) >= 0) {
35
+ $context = $(context);
36
+ } else {
37
+ $context = $(win.document).find(context);
38
+ if ($context.length === 0) {
39
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
42
40
  }
41
+ }
43
42
 
44
- return $context;
45
- },
46
- returnedValue
47
- ;
43
+ return $context;
44
+ };
45
+ let returnedValue;
48
46
 
49
47
  $allModules.each(function (elementIndex) {
50
- var
51
- settings = $.isPlainObject(parameters)
52
- ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
53
- : $.extend({}, $.fn.dropdown.settings),
54
-
55
- className = settings.className,
56
- message = settings.message,
57
- fields = settings.fields,
58
- keys = settings.keys,
59
- metadata = settings.metadata,
60
- namespace = settings.namespace,
61
- regExp = settings.regExp,
62
- selector = settings.selector,
63
- error = settings.error,
64
- templates = settings.templates,
65
-
66
- eventNamespace = '.' + namespace,
67
- moduleNamespace = 'module-' + namespace,
68
-
69
- $module = $(this),
70
- $context = contextCheck(settings.context, window),
71
- $text = $module.find(selector.text),
72
- $search = $module.find(selector.search),
73
- $sizer = $module.find(selector.sizer),
74
- $input = $module.find(selector.input),
75
- $icon = $module.find(selector.icon),
76
- $clear = $module.find(selector.clearIcon),
77
-
78
- $combo = $module.prev().find(selector.text).length > 0
79
- ? $module.prev().find(selector.text)
80
- : $module.prev(),
81
-
82
- $menu = $module.children(selector.menu),
83
- $item = $menu.find(selector.item),
84
- $divider = settings.hideDividers
85
- ? $item.parent().children(selector.divider)
86
- : $(),
87
-
88
- activated = false,
89
- itemActivated = false,
90
- internalChange = false,
91
- iconClicked = false,
92
- element = this,
93
- focused = false,
94
- instance = $module.data(moduleNamespace),
95
-
96
- selectActionActive,
97
- initialLoad,
98
- pageLostFocus,
99
- willRefocus,
100
- elementNamespace,
101
- id,
102
- selectObserver,
103
- menuObserver,
104
- classObserver,
105
- module,
106
- tempDisableApiCache = false
107
- ;
48
+ let settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
50
+ : $.extend({}, $.fn.dropdown.settings);
51
+
52
+ let className = settings.className;
53
+ let message = settings.message;
54
+ let fields = settings.fields;
55
+ let keys = settings.keys;
56
+ let metadata = settings.metadata;
57
+ let namespace = settings.namespace;
58
+ let regExp = settings.regExp;
59
+ let selector = settings.selector;
60
+ let error = settings.error;
61
+ let templates = settings.templates;
62
+
63
+ let eventNamespace = '.' + namespace;
64
+ let moduleNamespace = 'module-' + namespace;
65
+
66
+ let $module = $(this);
67
+ let $context = contextCheck(settings.context, window);
68
+ let $text = $module.find(selector.text);
69
+ let $search = $module.find(selector.search);
70
+ let $sizer = $module.find(selector.sizer);
71
+ let $input = $module.find(selector.input);
72
+ let $icon = $module.find(selector.icon);
73
+ let $clear = $module.find(selector.clearIcon);
74
+
75
+ let $combo = $module.prev().find(selector.text).length > 0
76
+ ? $module.prev().find(selector.text)
77
+ : $module.prev();
78
+
79
+ let $menu = $module.children(selector.menu);
80
+ let $item = $menu.find(selector.item);
81
+ let $divider = settings.hideDividers
82
+ ? $item.parent().children(selector.divider)
83
+ : $();
84
+
85
+ let activated = false;
86
+ let itemActivated = false;
87
+ let internalChange = false;
88
+ let iconClicked = false;
89
+ let element = this;
90
+ let focused = false;
91
+ let instance = $module.data(moduleNamespace);
92
+
93
+ let selectActionActive;
94
+ let initialLoad;
95
+ let pageLostFocus;
96
+ let willRefocus;
97
+ let elementNamespace;
98
+ let id;
99
+ let selectObserver;
100
+ let menuObserver;
101
+ let classObserver;
102
+ let module;
103
+ let tempDisableApiCache = false;
108
104
 
109
105
  module = {
110
106
 
@@ -114,11 +110,6 @@
114
110
  if (module.is.alreadySetup()) {
115
111
  module.setup.reference();
116
112
  } else {
117
- if (settings.ignoreDiacritics && !String.prototype.normalize) {
118
- settings.ignoreDiacritics = false;
119
- module.error(error.noNormalize, element);
120
- }
121
-
122
113
  module.create.id();
123
114
  module.setup.layout();
124
115
 
@@ -147,8 +138,7 @@
147
138
  module.verbose('Storing instance of dropdown', module);
148
139
  instance = module;
149
140
  $module
150
- .data(moduleNamespace, module)
151
- ;
141
+ .data(moduleNamespace, module);
152
142
  },
153
143
 
154
144
  destroy: function () {
@@ -159,29 +149,24 @@
159
149
  $menu.removeClass(className.visible).addClass(className.hidden);
160
150
  $module
161
151
  .off(eventNamespace)
162
- .removeData(moduleNamespace)
163
- ;
152
+ .removeData(moduleNamespace);
164
153
  $menu
165
- .off(eventNamespace)
166
- ;
154
+ .off(eventNamespace);
167
155
  $document
168
- .off(elementNamespace)
169
- ;
156
+ .off(elementNamespace);
170
157
  module.disconnect.menuObserver();
171
158
  module.disconnect.selectObserver();
172
159
  module.disconnect.classObserver();
173
160
  },
174
161
 
175
162
  observeChanges: function () {
176
- if ('MutationObserver' in window) {
177
- selectObserver = new MutationObserver(module.event.select.mutation);
178
- menuObserver = new MutationObserver(module.event.menu.mutation);
179
- classObserver = new MutationObserver(module.event.class.mutation);
180
- module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
181
- module.observe.select();
182
- module.observe.menu();
183
- module.observe.class();
184
- }
163
+ selectObserver = new MutationObserver(module.event.select.mutation);
164
+ menuObserver = new MutationObserver(module.event.menu.mutation);
165
+ classObserver = new MutationObserver(module.event.class.mutation);
166
+ module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
167
+ module.observe.select();
168
+ module.observe.menu();
169
+ module.observe.class();
185
170
  },
186
171
 
187
172
  disconnect: {
@@ -235,11 +220,9 @@
235
220
  module.verbose('Creating unique id for element', id);
236
221
  },
237
222
  userChoice: function (values) {
238
- var
239
- $userChoices,
240
- $userChoice,
241
- html
242
- ;
223
+ let $userChoices;
224
+ let $userChoice;
225
+ let html;
243
226
  values = values || module.get.userValues();
244
227
  if (!values) {
245
228
  return false;
@@ -249,14 +232,13 @@
249
232
  : [values];
250
233
  $.each(values, function (index, value) {
251
234
  if (module.get.item(value) === false) {
252
- html = settings.templates.addition(module.add.variables(message.addResult, value));
235
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
253
236
  $userChoice = $('<div />')
254
237
  .html(html)
255
238
  .attr('data-' + metadata.value, value)
256
239
  .attr('data-' + metadata.text, value)
257
240
  .addClass(className.addition)
258
- .addClass(className.item)
259
- ;
241
+ .addClass(className.item);
260
242
  if (settings.hideAdditions) {
261
243
  $userChoice.addClass(className.hidden);
262
244
  }
@@ -270,9 +252,7 @@
270
252
  return $userChoices;
271
253
  },
272
254
  userLabels: function (value) {
273
- var
274
- userValues = module.get.userValues()
275
- ;
255
+ let userValues = module.get.userValues();
276
256
  if (userValues) {
277
257
  module.debug('Adding user labels', userValues);
278
258
  $.each(userValues, function (index, value) {
@@ -284,14 +264,12 @@
284
264
  menu: function () {
285
265
  $menu = $('<div />')
286
266
  .addClass(className.menu)
287
- .appendTo($module)
288
- ;
267
+ .appendTo($module);
289
268
  },
290
269
  sizer: function () {
291
270
  $sizer = $('<span />')
292
271
  .addClass(className.sizer)
293
- .insertAfter($search)
294
- ;
272
+ .insertAfter($search);
295
273
  },
296
274
  },
297
275
 
@@ -317,16 +295,13 @@
317
295
  .not(selector.unselectable)
318
296
  .not(selector.addition + selector.hidden)
319
297
  .eq(0)
320
- .addClass(className.selected)
321
- ;
298
+ .addClass(className.selected);
322
299
  },
323
300
  nextAvailable: function ($selected) {
324
301
  $selected = $selected.eq(0);
325
- var
326
- $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
327
- $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
328
- hasNext = $nextAvailable.length > 0
329
- ;
302
+ let $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0);
303
+ let $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0);
304
+ let hasNext = $nextAvailable.length > 0;
330
305
  if (hasNext) {
331
306
  module.verbose('Moving selection to', $nextAvailable);
332
307
  $nextAvailable.addClass(className.selected);
@@ -339,20 +314,17 @@
339
314
 
340
315
  setup: {
341
316
  api: function () {
342
- var
343
- apiSettings = {
344
- debug: settings.debug,
345
- urlData: {
346
- value: module.get.value(),
347
- query: module.get.query(),
348
- },
349
- on: false,
350
- }
351
- ;
317
+ let apiSettings = {
318
+ debug: settings.debug,
319
+ urlData: {
320
+ value: module.get.value(),
321
+ query: module.get.query(),
322
+ },
323
+ on: false,
324
+ };
352
325
  module.verbose('First request, initializing API');
353
326
  $module
354
- .api(apiSettings)
355
- ;
327
+ .api(apiSettings);
356
328
  },
357
329
  layout: function () {
358
330
  if ($module.is('select')) {
@@ -366,18 +338,14 @@
366
338
  module.verbose('Adding clear icon');
367
339
  $clear = $('<i />')
368
340
  .addClass('remove icon')
369
- .insertAfter($icon)
370
- ;
341
+ .insertAfter($icon);
371
342
  }
372
343
  if (module.is.search() && !module.has.search()) {
373
344
  module.verbose('Adding search input');
374
- var
375
- labelNode = $module.prev('label')
376
- ;
345
+ let labelNode = $module.prev('label');
377
346
  $search = $('<input />')
378
347
  .addClass(className.search)
379
- .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off')
380
- ;
348
+ .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off');
381
349
  if (labelNode.length > 0) {
382
350
  if (!labelNode.attr('id')) {
383
351
  labelNode.attr('id', '_' + module.get.id() + '_formLabel');
@@ -394,9 +362,7 @@
394
362
  }
395
363
  },
396
364
  select: function () {
397
- var
398
- selectValues = module.get.selectValues()
399
- ;
365
+ let selectValues = module.get.selectValues();
400
366
  module.debug('Dropdown initialized on a select', selectValues);
401
367
  if ($module.is('select')) {
402
368
  $input = $module;
@@ -416,9 +382,8 @@
416
382
  .attr('class', $input.attr('class'))
417
383
  .addClass(className.selection)
418
384
  .addClass(className.dropdown)
419
- .html(templates.dropdown(selectValues, fields, settings.preserveHTML, settings.className))
420
- .insertBefore($input)
421
- ;
385
+ .html(templates.dropdown(selectValues, settings))
386
+ .insertBefore($input);
422
387
  if ($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
423
388
  module.error(error.missingMultiple);
424
389
  $input.prop('multiple', true);
@@ -440,13 +405,12 @@
440
405
  .prop('required', false)
441
406
  .removeAttr('class')
442
407
  .detach()
443
- .prependTo($module)
444
- ;
408
+ .prependTo($module);
445
409
  }
446
410
  module.refresh();
447
411
  },
448
412
  menu: function (values) {
449
- $menu.html(templates.menu(values, fields, settings.preserveHTML, settings.className));
413
+ $menu.html(templates.menu(values, settings));
450
414
  $item = $menu.find(selector.item);
451
415
  $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $();
452
416
  },
@@ -460,10 +424,8 @@
460
424
  module.setup.returnedObject();
461
425
  },
462
426
  returnedObject: function () {
463
- var
464
- $firstModules = $allModules.slice(0, elementIndex),
465
- $lastModules = $allModules.slice(elementIndex + 1)
466
- ;
427
+ let $firstModules = $allModules.slice(0, elementIndex);
428
+ let $lastModules = $allModules.slice(elementIndex + 1);
467
429
  // adjust all modules to use the correct reference
468
430
  $allModules = $firstModules.add($module).add($lastModules);
469
431
  },
@@ -497,21 +459,18 @@
497
459
  module.verbose('Refreshing cached metadata');
498
460
  $item
499
461
  .removeData(metadata.text)
500
- .removeData(metadata.value)
501
- ;
462
+ .removeData(metadata.value);
502
463
  },
503
464
 
504
465
  clearData: function () {
505
466
  module.verbose('Clearing metadata');
506
467
  $item
507
468
  .removeData(metadata.text)
508
- .removeData(metadata.value)
509
- ;
469
+ .removeData(metadata.value);
510
470
  $module
511
471
  .removeData(metadata.defaultText)
512
472
  .removeData(metadata.defaultValue)
513
- .removeData(metadata.placeholderText)
514
- ;
473
+ .removeData(metadata.placeholderText);
515
474
  },
516
475
 
517
476
  clearItems: function () {
@@ -578,11 +537,11 @@
578
537
  });
579
538
  // Hide submenus explicitly. On some browsers (esp. mobile), they will not automatically receive a
580
539
  // mouseleave event
581
- var $subMenu = $module.find(selector.menu);
540
+ let $subMenu = $module.find(selector.menu);
582
541
  if ($subMenu.length > 0) {
583
542
  module.verbose('Hiding sub-menu', $subMenu);
584
543
  $subMenu.each(function () {
585
- var $sub = $(this);
544
+ let $sub = $(this);
586
545
  if (!module.is.animating($sub)) {
587
546
  module.animate.hide(false, $sub);
588
547
  }
@@ -601,8 +560,7 @@
601
560
  $allModules
602
561
  .not($module)
603
562
  .has(selector.menu + '.' + className.visible)
604
- .dropdown('hide')
605
- ;
563
+ .dropdown('hide');
606
564
  },
607
565
 
608
566
  hideMenu: function () {
@@ -613,9 +571,7 @@
613
571
  },
614
572
 
615
573
  hideSubMenus: function () {
616
- var
617
- $subMenus = $menu.children(selector.item).find(selector.menu)
618
- ;
574
+ let $subMenus = $menu.children(selector.item).find(selector.menu);
619
575
  module.verbose('Hiding sub menus', $subMenus);
620
576
  $subMenus.transition('hide');
621
577
  },
@@ -629,28 +585,23 @@
629
585
  keyboardEvents: function () {
630
586
  module.verbose('Binding keyboard events');
631
587
  $module
632
- .on('keydown' + eventNamespace, module.event.keydown)
633
- ;
588
+ .on('keydown' + eventNamespace, module.event.keydown);
634
589
  if (module.has.search()) {
635
590
  $module
636
- .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
637
- ;
591
+ .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input);
638
592
  }
639
593
  if (module.is.multiple()) {
640
594
  $document
641
- .on('keydown' + elementNamespace, module.event.document.keydown)
642
- ;
595
+ .on('keydown' + elementNamespace, module.event.document.keydown);
643
596
  }
644
597
  },
645
598
  inputEvents: function () {
646
599
  module.verbose('Binding input change events');
647
600
  $module
648
- .on('change' + eventNamespace, selector.input, module.event.change)
649
- ;
601
+ .on('change' + eventNamespace, selector.input, module.event.change);
650
602
  if (module.is.multiple() && module.is.searchSelection()) {
651
603
  $module
652
- .on('paste' + eventNamespace, selector.search, module.event.paste)
653
- ;
604
+ .on('paste' + eventNamespace, selector.search, module.event.paste);
654
605
  }
655
606
  },
656
607
  mouseEvents: function () {
@@ -658,8 +609,7 @@
658
609
  if (module.is.multiple()) {
659
610
  $module
660
611
  .on('click' + eventNamespace, selector.label, module.event.label.click)
661
- .on('click' + eventNamespace, selector.remove, module.event.remove.click)
662
- ;
612
+ .on('click' + eventNamespace, selector.remove, module.event.remove.click);
663
613
  }
664
614
  if (module.is.searchSelection()) {
665
615
  $module
@@ -672,60 +622,50 @@
672
622
  .on('focus' + eventNamespace, selector.search, module.event.search.focus)
673
623
  .on('click' + eventNamespace, selector.search, module.event.search.focus)
674
624
  .on('blur' + eventNamespace, selector.search, module.event.search.blur)
675
- .on('click' + eventNamespace, selector.text, module.event.text.focus)
676
- ;
625
+ .on('click' + eventNamespace, selector.text, module.event.text.focus);
677
626
  if (module.is.multiple()) {
678
627
  $module
679
628
  .on('click' + eventNamespace, module.event.click)
680
- .on('click' + eventNamespace, module.event.search.focus)
681
- ;
629
+ .on('click' + eventNamespace, module.event.search.focus);
682
630
  }
683
631
  } else {
684
632
  if (settings.on === 'click') {
685
633
  $module
686
634
  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
687
- .on('click' + eventNamespace, module.event.test.toggle)
688
- ;
635
+ .on('click' + eventNamespace, module.event.test.toggle);
689
636
  } else if (settings.on === 'hover') {
690
637
  $module
691
638
  .on('mouseenter' + eventNamespace, module.delay.show)
692
639
  .on('mouseleave' + eventNamespace, module.delay.hide)
693
640
  .on('touchstart' + eventNamespace, module.event.test.toggle)
694
- .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click)
695
- ;
641
+ .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click);
696
642
  } else {
697
643
  $module
698
- .on(settings.on + eventNamespace, module.toggle)
699
- ;
644
+ .on(settings.on + eventNamespace, module.toggle);
700
645
  }
701
646
  $module
702
647
  .on('mousedown' + eventNamespace, module.event.mousedown)
703
648
  .on('mouseup' + eventNamespace, module.event.mouseup)
704
649
  .on('focus' + eventNamespace, module.event.focus)
705
- .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click)
706
- ;
650
+ .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click);
707
651
  if (module.has.menuSearch()) {
708
652
  $module
709
- .on('blur' + eventNamespace, selector.search, module.event.search.blur)
710
- ;
653
+ .on('blur' + eventNamespace, selector.search, module.event.search.blur);
711
654
  } else {
712
655
  $module
713
- .on('blur' + eventNamespace, module.event.blur)
714
- ;
656
+ .on('blur' + eventNamespace, module.event.blur);
715
657
  }
716
658
  }
717
659
  $menu
718
660
  .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
719
661
  .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
720
662
  .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
721
- .on('click' + eventNamespace, selector.item, module.event.item.click)
722
- ;
663
+ .on('click' + eventNamespace, selector.item, module.event.item.click);
723
664
  },
724
665
  intent: function () {
725
666
  module.verbose('Binding hide intent event to document');
726
667
  $document
727
- .on('click' + elementNamespace, module.event.test.hide)
728
- ;
668
+ .on('click' + elementNamespace, module.event.test.hide);
729
669
  },
730
670
  },
731
671
 
@@ -733,52 +673,51 @@
733
673
  intent: function () {
734
674
  module.verbose('Removing hide intent event from document');
735
675
  $document
736
- .off('click' + elementNamespace)
737
- ;
676
+ .off('click' + elementNamespace);
738
677
  },
739
678
  },
740
679
 
741
680
  filter: function (query) {
742
- var
743
- searchTerm = query !== undefined
744
- ? query
745
- : module.get.query(),
746
- afterFiltered = function () {
747
- if (module.is.multiple()) {
748
- module.filterActive();
749
- }
750
- if (query || (!query && module.get.activeItem().length === 0)) {
751
- module.select.firstUnfiltered();
752
- }
753
- if (module.has.allResultsFiltered()) {
754
- if (settings.onNoResults.call(element, searchTerm)) {
755
- if (settings.allowAdditions) {
756
- if (settings.hideAdditions) {
757
- module.verbose('User addition with no menu, setting empty style');
758
- module.set.empty();
759
- module.hideMenu();
760
- }
761
- } else {
762
- module.verbose('All items filtered, showing message', searchTerm);
763
- module.add.message(message.noResults);
681
+ let searchTerm = query !== undefined
682
+ ? query
683
+ : module.get.query();
684
+ let afterFiltered = function () {
685
+ if (module.is.multiple()) {
686
+ module.filterActive();
687
+ }
688
+ if (query || (!query && module.get.activeItem().length === 0)) {
689
+ module.select.firstUnfiltered();
690
+ }
691
+ if (module.has.allResultsFiltered()) {
692
+ if (settings.onNoResults.call(element, searchTerm)) {
693
+ if (settings.allowAdditions) {
694
+ if (settings.hideAdditions) {
695
+ module.verbose('User addition with no menu, setting empty style');
696
+ module.set.empty();
697
+ module.hideMenu();
764
698
  }
765
699
  } else {
766
- module.verbose('All items filtered, hiding dropdown', searchTerm);
767
- module.set.empty();
768
- module.hideMenu();
700
+ module.verbose('All items filtered, showing message', searchTerm);
701
+ module.add.message(message.noResults);
769
702
  }
770
703
  } else {
771
- module.remove.empty();
772
- module.remove.message();
773
- }
774
- if (settings.allowAdditions) {
775
- module.add.userSuggestion(module.escape.htmlEntities(query));
776
- }
777
- if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
778
- module.show();
704
+ module.verbose('All items filtered, hiding dropdown', searchTerm);
705
+ module.set.empty();
706
+ module.hideMenu();
779
707
  }
708
+ } else {
709
+ module.remove.empty();
710
+ module.remove.message();
711
+ }
712
+ if (settings.allowAdditions) {
713
+ module.add.userSuggestion(settings.preserveHTML
714
+ ? settings.templates.escape(query)
715
+ : query);
716
+ }
717
+ if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
718
+ module.show();
780
719
  }
781
- ;
720
+ };
782
721
  if (settings.useLabels && module.has.maxSelections()) {
783
722
  module.show();
784
723
 
@@ -790,15 +729,14 @@
790
729
  if (settings.filterRemoteData) {
791
730
  module.filterItems(searchTerm);
792
731
  }
793
- var preSelected = $input.val();
732
+ let preSelected = $input.val();
794
733
  if (!Array.isArray(preSelected)) {
795
734
  preSelected = preSelected && preSelected !== '' ? preSelected.split(settings.delimiter) : [];
796
735
  }
797
736
  if (module.is.multiple()) {
798
737
  $.each(preSelected, function (index, value) {
799
- $item.filter('[data-' + metadata.value + '="' + value + '"]')
800
- .addClass(className.filtered)
801
- ;
738
+ $item.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]')
739
+ .addClass(className.filtered);
802
740
  });
803
741
  }
804
742
  module.focusSearch(true);
@@ -817,88 +755,81 @@
817
755
  if (!Array.isArray(callbackParameters)) {
818
756
  callbackParameters = [callbackParameters];
819
757
  }
820
- var
821
- apiSettings = {
822
- errorDuration: false,
823
- cache: 'local',
824
- throttle: settings.throttle,
825
- urlData: {
826
- query: query,
827
- },
758
+ let apiSettings = {
759
+ errorDuration: false,
760
+ cache: 'local',
761
+ throttle: settings.throttle,
762
+ urlData: {
763
+ query: query,
828
764
  },
829
- apiCallbacks = {
830
- onError: function (errorMessage, $module, xhr) {
831
- module.add.message(message.serverError);
832
- iconClicked = false;
833
- focused = false;
834
- callback.apply(null, callbackParameters);
835
- if (typeof settings.apiSettings.onError === 'function') {
836
- settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
837
- }
838
- },
839
- onFailure: function (response, $module, xhr) {
840
- module.add.message(message.serverError);
841
- iconClicked = false;
842
- focused = false;
843
- callback.apply(null, callbackParameters);
844
- if (typeof settings.apiSettings.onFailure === 'function') {
845
- settings.apiSettings.onFailure.call(this, response, $module, xhr);
846
- }
847
- },
848
- onSuccess: function (response, $module, xhr) {
849
- var
850
- values = response[fields.remoteValues]
851
- ;
852
- if (!Array.isArray(values)) {
853
- values = [];
854
- }
855
- module.remove.message();
856
- var menuConfig = {};
857
- menuConfig[fields.values] = values;
858
- module.setup.menu(menuConfig);
765
+ };
766
+ let apiCallbacks = {
767
+ onError: function (errorMessage, $module, xhr) {
768
+ module.add.message(message.serverError);
769
+ iconClicked = false;
770
+ focused = false;
771
+ callback.apply(null, callbackParameters);
772
+ if (typeof settings.apiSettings.onError === 'function') {
773
+ settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
774
+ }
775
+ },
776
+ onFailure: function (response, $module, xhr) {
777
+ module.add.message(message.serverError);
778
+ iconClicked = false;
779
+ focused = false;
780
+ callback.apply(null, callbackParameters);
781
+ if (typeof settings.apiSettings.onFailure === 'function') {
782
+ settings.apiSettings.onFailure.call(this, response, $module, xhr);
783
+ }
784
+ },
785
+ onSuccess: function (response, $module, xhr) {
786
+ let values = response[fields.remoteValues];
787
+ if (!Array.isArray(values)) {
788
+ values = [];
789
+ }
790
+ module.remove.message();
791
+ let menuConfig = {};
792
+ menuConfig[fields.values] = values;
793
+ module.setup.menu(menuConfig);
859
794
 
860
- if (values.length === 0 && !settings.allowAdditions) {
861
- module.add.message(message.noResults);
862
- } else {
863
- var value = module.is.multiple() ? module.get.values() : module.get.value();
864
- if (value !== '') {
865
- module.verbose('Value(s) present after click icon, select value(s) in items');
866
- module.set.selected(value, null, true, true);
867
- }
868
- }
869
- iconClicked = false;
870
- focused = false;
871
- callback.apply(null, callbackParameters);
872
- if (typeof settings.apiSettings.onSuccess === 'function') {
873
- settings.apiSettings.onSuccess.call(this, response, $module, xhr);
795
+ if (values.length === 0 && !settings.allowAdditions) {
796
+ module.add.message(message.noResults);
797
+ } else {
798
+ let value = module.is.multiple() ? module.get.values() : module.get.value();
799
+ if (value !== '') {
800
+ module.verbose('Value(s) present after click icon, select value(s) in items');
801
+ module.set.selected(value, null, true, true);
874
802
  }
875
- },
876
- }
877
- ;
803
+ }
804
+ iconClicked = false;
805
+ focused = false;
806
+ callback.apply(null, callbackParameters);
807
+ if (typeof settings.apiSettings.onSuccess === 'function') {
808
+ settings.apiSettings.onSuccess.call(this, response, $module, xhr);
809
+ }
810
+ },
811
+ };
878
812
  if (!$module.api('get request')) {
879
813
  module.setup.api();
880
814
  }
881
815
  apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings, apiCallbacks, tempDisableApiCache ? { cache: false } : {});
882
816
  $module
883
817
  .api('setting', apiSettings)
884
- .api('query')
885
- ;
818
+ .api('query');
886
819
  tempDisableApiCache = false;
887
820
  },
888
821
 
889
822
  filterItems: function (query) {
890
- var
891
- searchTerm = module.remove.diacritics(
892
- query !== undefined
893
- ? query
894
- : module.get.query()
895
- ),
896
- results = null,
897
- escapedTerm = module.escape.string(searchTerm),
898
- regExpIgnore = settings.ignoreSearchCase ? 'i' : '',
899
- regExpFlags = regExpIgnore + 'gm',
900
- beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags)
901
- ;
823
+ let searchTerm = module.remove.diacritics(
824
+ query !== undefined
825
+ ? query
826
+ : module.get.query()
827
+ );
828
+ let results = null;
829
+ let escapedTerm = module.escape.string(searchTerm);
830
+ let regExpIgnore = settings.ignoreSearchCase ? 'i' : '';
831
+ let regExpFlags = regExpIgnore + 'gm';
832
+ let beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags);
902
833
  module.remove.filteredItem();
903
834
  // avoid loop if we're matching nothing
904
835
  if (module.has.query()) {
@@ -907,11 +838,9 @@
907
838
  module.verbose('Searching for matching values', searchTerm);
908
839
  $item
909
840
  .each(function () {
910
- var
911
- $choice = $(this),
912
- text,
913
- value
914
- ;
841
+ let $choice = $(this);
842
+ let text;
843
+ let value;
915
844
  if ($choice.hasClass(className.unfilterable)) {
916
845
  results.push(this);
917
846
 
@@ -939,32 +868,28 @@
939
868
  return true;
940
869
  }
941
870
  }
942
- })
943
- ;
871
+ });
944
872
  }
945
873
  module.debug('Showing only matched items', searchTerm);
946
874
  if (results) {
947
875
  $item
948
876
  .not(results)
949
- .addClass(className.filtered)
950
- ;
877
+ .addClass(className.filtered);
951
878
  if (settings.highlightMatches && (settings.match === 'both' || settings.match === 'text')) {
952
- var querySplit = query.split(''),
953
- diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '',
954
- htmlReg = '(?![^<]*>)',
955
- markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore),
956
- markedReplacer = function () {
957
- var args = [].slice.call(arguments, 1, querySplit.length * 2).map(function (x, i) {
958
- return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
959
- });
879
+ let querySplit = query.split('');
880
+ let diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '';
881
+ let htmlReg = '(?![^<]*>)';
882
+ let markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore);
883
+ let markedReplacer = function () {
884
+ let args = [].slice.call(arguments, 1, querySplit.length * 2).map(function (x, i) {
885
+ return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
886
+ });
960
887
 
961
- return args.join('');
962
- }
963
- ;
888
+ return args.join('');
889
+ };
964
890
  $.each(results, function (index, result) {
965
- var $result = $(result),
966
- markedHTML = module.get.choiceText($result, true)
967
- ;
891
+ let $result = $(result);
892
+ let markedHTML = module.get.choiceText($result, true);
968
893
  if (settings.ignoreDiacritics) {
969
894
  markedHTML = markedHTML.normalize('NFD');
970
895
  }
@@ -975,19 +900,17 @@
975
900
 
976
901
  if (!module.has.query()) {
977
902
  $divider
978
- .removeClass(className.hidden)
979
- ;
903
+ .removeClass(className.hidden);
980
904
  } else if (settings.hideDividers === true) {
981
905
  $divider
982
- .addClass(className.hidden)
983
- ;
906
+ .addClass(className.hidden);
984
907
  } else if (settings.hideDividers === 'empty') {
985
908
  $divider
986
909
  .removeClass(className.hidden)
987
910
  .filter(function () {
988
911
  // First find the last divider in this divider group
989
912
  // Dividers which are direct siblings are considered a group
990
- var $lastDivider = $(this).nextUntil(selector.item);
913
+ let $lastDivider = $(this).nextUntil(selector.item);
991
914
 
992
915
  return ($lastDivider.length > 0 ? $lastDivider : $(this))
993
916
  // Count all non-filtered items until the next divider (or end of the dropdown)
@@ -996,16 +919,13 @@
996
919
  // Hide divider if no items are found
997
920
  .length === 0;
998
921
  })
999
- .addClass(className.hidden)
1000
- ;
922
+ .addClass(className.hidden);
1001
923
  }
1002
924
  },
1003
925
 
1004
926
  fuzzySearch: function (query, term) {
1005
- var
1006
- termLength = term.length,
1007
- queryLength = query.length
1008
- ;
927
+ let termLength = term.length;
928
+ let queryLength = query.length;
1009
929
  if (settings.ignoreSearchCase) {
1010
930
  query = query.toLowerCase();
1011
931
  term = term.toLowerCase();
@@ -1016,11 +936,9 @@
1016
936
  if (queryLength === termLength) {
1017
937
  return query === term;
1018
938
  }
1019
- for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
1020
- var
1021
- continueSearch = false,
1022
- queryCharacter = query.charCodeAt(characterIndex)
1023
- ;
939
+ for (let characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
940
+ let continueSearch = false;
941
+ let queryCharacter = query.charCodeAt(characterIndex);
1024
942
  while (nextCharacterIndex < termLength) {
1025
943
  if (term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
1026
944
  continueSearch = true;
@@ -1045,8 +963,7 @@
1045
963
  filterActive: function () {
1046
964
  if (settings.useLabels) {
1047
965
  $item.filter('.' + className.active)
1048
- .addClass(className.filtered)
1049
- ;
966
+ .addClass(className.filtered);
1050
967
  }
1051
968
  },
1052
969
 
@@ -1069,14 +986,12 @@
1069
986
  },
1070
987
 
1071
988
  forceSelection: function () {
1072
- var
1073
- $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
1074
- $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0),
1075
- $selectedItem = $currentlySelected.length > 0
1076
- ? $currentlySelected
1077
- : $activeItem,
1078
- hasSelected = $selectedItem.length > 0
1079
- ;
989
+ let $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0);
990
+ let $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0);
991
+ let $selectedItem = $currentlySelected.length > 0
992
+ ? $currentlySelected
993
+ : $activeItem;
994
+ let hasSelected = $selectedItem.length > 0;
1080
995
  if (settings.allowAdditions || (hasSelected && !module.is.multiple())) {
1081
996
  module.debug('Forcing partial selection to selected item', $selectedItem);
1082
997
  module.event.item.click.call($selectedItem, {}, true);
@@ -1091,32 +1006,38 @@
1091
1006
  module.clear();
1092
1007
  }
1093
1008
  module.debug('Creating dropdown with specified values', values);
1094
- var menuConfig = {};
1009
+ let menuConfig = {};
1095
1010
  menuConfig[fields.values] = values;
1096
1011
  module.setup.menu(menuConfig);
1097
- $.each(values, function (index, item) {
1098
- if (item.selected === true) {
1099
- module.debug('Setting initial selection to', item[fields.value]);
1100
- module.set.selected(item[fields.value]);
1101
- if (!module.is.multiple()) {
1102
- return false;
1012
+ let findSelected = function (values) {
1013
+ let hasMultiple = true;
1014
+ $.each(values, function (index, item) {
1015
+ let itemType = item.type || 'item';
1016
+ if (item.selected === true) {
1017
+ module.debug('Setting initial selection to', item[fields.value]);
1018
+ module.set.selected(item[fields.value]);
1019
+ if (!module.is.multiple()) {
1020
+ hasMultiple = false;
1021
+ }
1022
+ } else if (itemType.indexOf('menu') !== -1) {
1023
+ hasMultiple = findSelected(item.values || []);
1103
1024
  }
1104
- }
1105
- });
1025
+
1026
+ return hasMultiple;
1027
+ });
1028
+
1029
+ return hasMultiple;
1030
+ };
1031
+ findSelected(values);
1106
1032
 
1107
1033
  if (module.has.selectInput()) {
1108
1034
  module.disconnect.selectObserver();
1109
1035
  $input.html('');
1110
1036
  $input.append('<option disabled selected value></option>');
1111
1037
  $.each(values, function (index, item) {
1112
- var
1113
- value = settings.templates.deQuote(item[fields.value]),
1114
- name = settings.templates.escape(
1115
- item[fields.name] || '',
1116
- settings.preserveHTML
1117
- )
1118
- ;
1119
- $input.append('<option value="' + value + '"' + (item.selected === true ? ' selected' : '') + '>' + name + '</option>');
1038
+ let value = item[fields.value];
1039
+ let name = item[fields.name] || '';
1040
+ $input.append('<option value="' + settings.templates.escape(value) + '"' + (item.selected === true ? ' selected' : '') + '>' + settings.templates.escape(name, settings) + '</option>');
1120
1041
  });
1121
1042
  module.observe.select();
1122
1043
  }
@@ -1125,25 +1046,26 @@
1125
1046
 
1126
1047
  event: {
1127
1048
  paste: function (event) {
1128
- var
1129
- pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text'),
1130
- tokens = pasteValue.split(settings.delimiter),
1131
- notFoundTokens = []
1132
- ;
1049
+ let pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text');
1050
+ let tokens = pasteValue.split(settings.delimiter);
1051
+ let notFoundTokens = [];
1133
1052
  tokens.forEach(function (value) {
1134
- if (module.set.selected(module.escape.htmlEntities(value.trim()), null, false, true) === false) {
1135
- notFoundTokens.push(value.trim());
1053
+ value = value.trim();
1054
+ const valueTrimmed = settings.preserveHTML
1055
+ ? settings.templates.escape(value)
1056
+ : value;
1057
+ if (module.set.selected(valueTrimmed, null, false, true) === false) {
1058
+ notFoundTokens.push(valueTrimmed);
1136
1059
  }
1137
1060
  });
1138
1061
  event.preventDefault();
1139
1062
  if (notFoundTokens.length > 0) {
1140
- var searchEl = $search[0],
1141
- startPos = searchEl.selectionStart,
1142
- endPos = searchEl.selectionEnd,
1143
- orgText = searchEl.value,
1144
- pasteText = notFoundTokens.join(settings.delimiter),
1145
- newEndPos = startPos + pasteText.length
1146
- ;
1063
+ let searchEl = $search[0];
1064
+ let startPos = searchEl.selectionStart;
1065
+ let endPos = searchEl.selectionEnd;
1066
+ let orgText = searchEl.value;
1067
+ let pasteText = notFoundTokens.join(settings.delimiter);
1068
+ let newEndPos = startPos + pasteText.length;
1147
1069
  $search.val(orgText.slice(0, startPos) + pasteText + orgText.slice(endPos));
1148
1070
  searchEl.selectionStart = newEndPos;
1149
1071
  searchEl.selectionEnd = newEndPos;
@@ -1187,9 +1109,7 @@
1187
1109
  }
1188
1110
  },
1189
1111
  click: function (event) {
1190
- var
1191
- $target = $(event.target)
1192
- ;
1112
+ let $target = $(event.target);
1193
1113
  // focus search
1194
1114
  if ($target.is($module)) {
1195
1115
  if (!module.is.focusedOnSearch()) {
@@ -1273,16 +1193,14 @@
1273
1193
  },
1274
1194
  label: {
1275
1195
  click: function (event) {
1276
- var
1277
- $label = $(this),
1278
- $labels = $module.find(selector.label),
1279
- $activeLabels = $labels.filter('.' + className.active),
1280
- $nextActive = $label.nextAll('.' + className.active),
1281
- $prevActive = $label.prevAll('.' + className.active),
1282
- $range = $nextActive.length > 0
1283
- ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1284
- : $label.prevUntil($prevActive).add($activeLabels).add($label)
1285
- ;
1196
+ let $label = $(this);
1197
+ let $labels = $module.find(selector.label);
1198
+ let $activeLabels = $labels.filter('.' + className.active);
1199
+ let $nextActive = $label.nextAll('.' + className.active);
1200
+ let $prevActive = $label.prevAll('.' + className.active);
1201
+ let $range = $nextActive.length > 0
1202
+ ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1203
+ : $label.prevUntil($prevActive).add($activeLabels).add($label);
1286
1204
  if (event.shiftKey) {
1287
1205
  $activeLabels.removeClass(className.active);
1288
1206
  $range.addClass(className.active);
@@ -1298,9 +1216,7 @@
1298
1216
  },
1299
1217
  remove: {
1300
1218
  click: function (event) {
1301
- var
1302
- $label = $(this).parent()
1303
- ;
1219
+ let $label = $(this).parent();
1304
1220
  if ($label.hasClass(className.active)) {
1305
1221
  // remove all selected labels
1306
1222
  module.remove.activeLabels();
@@ -1313,11 +1229,9 @@
1313
1229
  },
1314
1230
  test: {
1315
1231
  toggle: function (event) {
1316
- var
1317
- toggleBehavior = module.is.multiple()
1318
- ? module.show
1319
- : module.toggle
1320
- ;
1232
+ let toggleBehavior = module.is.multiple()
1233
+ ? module.show
1234
+ : module.toggle;
1321
1235
  if (module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
1322
1236
  return;
1323
1237
  }
@@ -1361,18 +1275,16 @@
1361
1275
  },
1362
1276
  menu: {
1363
1277
  mutation: function (mutations) {
1364
- var
1365
- mutation = mutations[0],
1366
- $addedNode = mutation.addedNodes
1367
- ? $(mutation.addedNodes[0])
1368
- : $(false),
1369
- $removedNode = mutation.removedNodes
1370
- ? $(mutation.removedNodes[0])
1371
- : $(false),
1372
- $changedNodes = $addedNode.add($removedNode),
1373
- isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0,
1374
- isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0
1375
- ;
1278
+ let mutation = mutations[0];
1279
+ let $addedNode = mutation.addedNodes
1280
+ ? $(mutation.addedNodes[0])
1281
+ : $(false);
1282
+ let $removedNode = mutation.removedNodes
1283
+ ? $(mutation.removedNodes[0])
1284
+ : $(false);
1285
+ let $changedNodes = $addedNode.add($removedNode);
1286
+ let isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0;
1287
+ let isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0;
1376
1288
  if (isUserAddition || isMessage) {
1377
1289
  module.debug('Updating item selector cache');
1378
1290
  module.refreshItems();
@@ -1390,14 +1302,12 @@
1390
1302
  },
1391
1303
  item: {
1392
1304
  mouseenter: function (event) {
1393
- var
1394
- $target = $(event.target),
1395
- $item = $(this),
1396
- $subMenu = $item.children(selector.menu),
1397
- $otherMenus = $item.siblings(selector.item).children(selector.menu),
1398
- hasSubMenu = $subMenu.length > 0,
1399
- isBubbledEvent = $subMenu.find($target).length > 0
1400
- ;
1305
+ let $target = $(event.target);
1306
+ let $item = $(this);
1307
+ let $subMenu = $item.children(selector.menu);
1308
+ let $otherMenus = $item.siblings(selector.item).children(selector.menu);
1309
+ let hasSubMenu = $subMenu.length > 0;
1310
+ let isBubbledEvent = $subMenu.find($target).length > 0;
1401
1311
  if (!isBubbledEvent && hasSubMenu) {
1402
1312
  clearTimeout(module.itemTimer);
1403
1313
  module.itemTimer = setTimeout(function () {
@@ -1411,9 +1321,7 @@
1411
1321
  }
1412
1322
  },
1413
1323
  mouseleave: function (event) {
1414
- var
1415
- $subMenu = $(this).find(selector.menu)
1416
- ;
1324
+ let $subMenu = $(this).find(selector.menu);
1417
1325
  if ($subMenu.length > 0) {
1418
1326
  clearTimeout(module.itemTimer);
1419
1327
  module.itemTimer = setTimeout(function () {
@@ -1425,17 +1333,15 @@
1425
1333
  }
1426
1334
  },
1427
1335
  click: function (event, skipRefocus) {
1428
- var
1429
- $choice = $(this),
1430
- $target = event
1431
- ? $(event.target || '')
1432
- : $(''),
1433
- $subMenu = $choice.find(selector.menu),
1434
- text = module.get.choiceText($choice),
1435
- value = module.get.choiceValue($choice, text),
1436
- hasSubMenu = $subMenu.length > 0,
1437
- isBubbledEvent = $subMenu.find($target).length > 0
1438
- ;
1336
+ let $choice = $(this);
1337
+ let $target = event
1338
+ ? $(event.target || '')
1339
+ : $('');
1340
+ let $subMenu = $choice.find(selector.menu);
1341
+ let text = module.get.choiceText($choice);
1342
+ let value = module.get.choiceValue($choice, text);
1343
+ let hasSubMenu = $subMenu.length > 0;
1344
+ let isBubbledEvent = $subMenu.find($target).length > 0;
1439
1345
  if (document.activeElement.tagName.toLowerCase() !== 'input') {
1440
1346
  $(document.activeElement).trigger('blur');
1441
1347
  }
@@ -1469,27 +1375,23 @@
1469
1375
  document: {
1470
1376
  // label selection should occur even when the element has no focus
1471
1377
  keydown: function (event) {
1472
- var
1473
- pressedKey = event.which,
1474
- isShortcutKey = module.is.inObject(pressedKey, keys)
1475
- ;
1378
+ let pressedKey = event.which;
1379
+ let isShortcutKey = module.is.inObject(pressedKey, keys);
1476
1380
  if (isShortcutKey) {
1477
- var
1478
- $label = $module.find(selector.label),
1479
- $activeLabel = $label.filter('.' + className.active),
1480
- activeValue = $activeLabel.data(metadata.value),
1481
- labelIndex = $label.index($activeLabel),
1482
- labelCount = $label.length,
1483
- hasActiveLabel = $activeLabel.length > 0,
1484
- hasMultipleActive = $activeLabel.length > 1,
1485
- isFirstLabel = labelIndex === 0,
1486
- isLastLabel = labelIndex + 1 === labelCount,
1487
- isSearch = module.is.searchSelection(),
1488
- isFocusedOnSearch = module.is.focusedOnSearch(),
1489
- isFocused = module.is.focused(),
1490
- caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0,
1491
- isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0
1492
- ;
1381
+ let $label = $module.find(selector.label);
1382
+ let $activeLabel = $label.filter('.' + className.active);
1383
+ let activeValue = $activeLabel.data(metadata.value);
1384
+ let labelIndex = $label.index($activeLabel);
1385
+ let labelCount = $label.length;
1386
+ let hasActiveLabel = $activeLabel.length > 0;
1387
+ let hasMultipleActive = $activeLabel.length > 1;
1388
+ let isFirstLabel = labelIndex === 0;
1389
+ let isLastLabel = labelIndex + 1 === labelCount;
1390
+ let isSearch = module.is.searchSelection();
1391
+ let isFocusedOnSearch = module.is.focusedOnSearch();
1392
+ let isFocused = module.is.focused();
1393
+ let caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0;
1394
+ let isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0;
1493
1395
  if (isSearch && !hasActiveLabel && !isFocusedOnSearch) {
1494
1396
  return;
1495
1397
  }
@@ -1512,8 +1414,7 @@
1512
1414
  } else {
1513
1415
  $activeLabel.prev(selector.siblingLabel)
1514
1416
  .addClass(className.active)
1515
- .end()
1516
- ;
1417
+ .end();
1517
1418
  }
1518
1419
  event.preventDefault();
1519
1420
  }
@@ -1588,31 +1489,27 @@
1588
1489
  },
1589
1490
 
1590
1491
  keydown: function (event) {
1591
- var
1592
- pressedKey = event.which,
1593
- isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter
1594
- ;
1492
+ let pressedKey = event.which;
1493
+ let isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter;
1595
1494
  if (isShortcutKey) {
1596
- var
1597
- $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
1598
- $activeItem = $menu.children('.' + className.active).eq(0),
1599
- $selectedItem = $currentlySelected.length > 0
1600
- ? $currentlySelected
1601
- : $activeItem,
1602
- $visibleItems = $selectedItem.length > 0
1603
- ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1604
- : $menu.children(':not(.' + className.filtered + ')'),
1605
- $subMenu = $selectedItem.children(selector.menu),
1606
- $parentMenu = $selectedItem.closest(selector.menu),
1607
- inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0,
1608
- hasSubMenu = $subMenu.length > 0,
1609
- hasSelectedItem = $selectedItem.length > 0,
1610
- selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0,
1611
- delimiterPressed = event.key === settings.delimiter && module.is.multiple(),
1612
- isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed),
1613
- $nextItem,
1614
- isSubMenuItem
1615
- ;
1495
+ let $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0);
1496
+ let $activeItem = $menu.children('.' + className.active).eq(0);
1497
+ let $selectedItem = $currentlySelected.length > 0
1498
+ ? $currentlySelected
1499
+ : $activeItem;
1500
+ let $visibleItems = $selectedItem.length > 0
1501
+ ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1502
+ : $menu.children(':not(.' + className.filtered + ')');
1503
+ let $subMenu = $selectedItem.children(selector.menu);
1504
+ let $parentMenu = $selectedItem.closest(selector.menu);
1505
+ let inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0;
1506
+ let hasSubMenu = $subMenu.length > 0;
1507
+ let hasSelectedItem = $selectedItem.length > 0;
1508
+ let selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0;
1509
+ let delimiterPressed = event.key === settings.delimiter && module.is.multiple();
1510
+ let isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed);
1511
+ let $nextItem;
1512
+ let isSubMenuItem;
1616
1513
  // allow selection with the menu closed
1617
1514
  if (isAdditionWithoutMenu) {
1618
1515
  if (selectedIsSelectable && settings.hideAdditions) {
@@ -1658,12 +1555,10 @@
1658
1555
  module.verbose('Left key pressed, closing sub-menu');
1659
1556
  module.animate.hide(false, $parentMenu);
1660
1557
  $selectedItem
1661
- .removeClass(className.selected)
1662
- ;
1558
+ .removeClass(className.selected);
1663
1559
  $parentMenu
1664
1560
  .closest(selector.item)
1665
- .addClass(className.selected)
1666
- ;
1561
+ .addClass(className.selected);
1667
1562
  event.preventDefault();
1668
1563
  }
1669
1564
  }
@@ -1674,12 +1569,10 @@
1674
1569
  module.verbose('Right key pressed, opening sub-menu');
1675
1570
  module.animate.show(false, $subMenu);
1676
1571
  $selectedItem
1677
- .removeClass(className.selected)
1678
- ;
1572
+ .removeClass(className.selected);
1679
1573
  $subMenu
1680
1574
  .find(selector.item).eq(0)
1681
- .addClass(className.selected)
1682
- ;
1575
+ .addClass(className.selected);
1683
1576
  event.preventDefault();
1684
1577
  }
1685
1578
  }
@@ -1699,11 +1592,9 @@
1699
1592
 
1700
1593
  module.verbose('Up key pressed, changing active item');
1701
1594
  $selectedItem
1702
- .removeClass(className.selected)
1703
- ;
1595
+ .removeClass(className.selected);
1704
1596
  $nextItem
1705
- .addClass(className.selected)
1706
- ;
1597
+ .addClass(className.selected);
1707
1598
  module.set.scrollPosition($nextItem);
1708
1599
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1709
1600
  module.set.selectedItem($nextItem);
@@ -1726,11 +1617,9 @@
1726
1617
 
1727
1618
  module.verbose('Down key pressed, changing active item');
1728
1619
  $item
1729
- .removeClass(className.selected)
1730
- ;
1620
+ .removeClass(className.selected);
1731
1621
  $nextItem
1732
- .addClass(className.selected)
1733
- ;
1622
+ .addClass(className.selected);
1734
1623
  module.set.scrollPosition($nextItem);
1735
1624
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1736
1625
  module.set.selectedItem($nextItem);
@@ -1762,6 +1651,7 @@
1762
1651
  }
1763
1652
  // down arrow (open menu)
1764
1653
  if (pressedKey === keys.downArrow && !module.is.visible()) {
1654
+ focused = true;
1765
1655
  module.verbose('Down key pressed, showing dropdown');
1766
1656
  module.show();
1767
1657
  event.preventDefault();
@@ -1777,11 +1667,9 @@
1777
1667
 
1778
1668
  trigger: {
1779
1669
  change: function () {
1780
- var
1781
- inputElement = $input[0]
1782
- ;
1670
+ let inputElement = $input[0];
1783
1671
  if (inputElement) {
1784
- var events = document.createEvent('HTMLEvents');
1672
+ let events = document.createEvent('HTMLEvents');
1785
1673
  module.verbose('Triggering native change event');
1786
1674
  events.initEvent('change', true, false);
1787
1675
  inputElement.dispatchEvent(events);
@@ -1805,11 +1693,9 @@
1805
1693
  selectActionActive = false;
1806
1694
  },
1807
1695
  eventInModule: function (event, callback) {
1808
- var
1809
- $target = $(event.target),
1810
- inDocument = $target.closest(document.documentElement).length > 0,
1811
- inModule = $target.closest($module).length > 0
1812
- ;
1696
+ let $target = $(event.target);
1697
+ let inDocument = $target.closest(document.documentElement).length > 0;
1698
+ let inModule = $target.closest($module).length > 0;
1813
1699
  callback = isFunction(callback)
1814
1700
  ? callback
1815
1701
  : function () {};
@@ -1825,13 +1711,11 @@
1825
1711
  return false;
1826
1712
  },
1827
1713
  eventOnElement: function (event, callback) {
1828
- var
1829
- $target = $(event.target),
1830
- $label = $target.closest(selector.siblingLabel),
1831
- inVisibleDOM = document.body.contains(event.target),
1832
- notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels),
1833
- notInMenu = $target.closest($menu).length === 0
1834
- ;
1714
+ let $target = $(event.target);
1715
+ let $label = $target.closest(selector.siblingLabel);
1716
+ let inVisibleDOM = document.body.contains(event.target);
1717
+ let notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels);
1718
+ let notInMenu = $target.closest($menu).length === 0;
1835
1719
  callback = isFunction(callback)
1836
1720
  ? callback
1837
1721
  : function () {};
@@ -1909,7 +1793,9 @@
1909
1793
  return $module.data(metadata.placeholderText) || '';
1910
1794
  },
1911
1795
  text: function () {
1912
- return settings.preserveHTML ? $text.html() : $text.text();
1796
+ return settings.preserveHTML
1797
+ ? $text.html()
1798
+ : $text.text();
1913
1799
  },
1914
1800
  query: function () {
1915
1801
  return String($search.val()).trim();
@@ -1924,10 +1810,8 @@
1924
1810
  return Math.ceil($sizer.width() + 1);
1925
1811
  },
1926
1812
  selectionCount: function () {
1927
- var
1928
- values = module.get.values(),
1929
- count
1930
- ;
1813
+ let values = module.get.values();
1814
+ let count;
1931
1815
  count = module.is.multiple()
1932
1816
  ? (Array.isArray(values) ? values.length : 0)
1933
1817
  : (module.get.value() !== '' ? 1 : 0);
@@ -1940,9 +1824,7 @@
1940
1824
  : settings.transition;
1941
1825
  },
1942
1826
  userValues: function () {
1943
- var
1944
- values = module.get.values(true)
1945
- ;
1827
+ let values = module.get.values();
1946
1828
  if (!values) {
1947
1829
  return false;
1948
1830
  }
@@ -1960,11 +1842,9 @@
1960
1842
  });
1961
1843
  },
1962
1844
  caretPosition: function (returnEndPos) {
1963
- var
1964
- input = $search[0],
1965
- range,
1966
- rangeLength
1967
- ;
1845
+ let input = $search[0];
1846
+ let range;
1847
+ let rangeLength;
1968
1848
  if (returnEndPos && 'selectionEnd' in input) {
1969
1849
  return input.selectionEnd;
1970
1850
  }
@@ -1984,47 +1864,37 @@
1984
1864
  }
1985
1865
  },
1986
1866
  value: function () {
1987
- var
1988
- value = $input.length > 0
1989
- ? $input.val()
1990
- : $module.data(metadata.value),
1991
- isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === ''
1992
- ;
1867
+ let value = $input.length > 0
1868
+ ? $input.val()
1869
+ : $module.data(metadata.value);
1870
+ let isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === '';
1993
1871
 
1994
1872
  // prevents the placeholder element from being selected when multiple
1995
1873
  return value === undefined || isEmptyMultiselect
1996
1874
  ? ''
1997
1875
  : value;
1998
1876
  },
1999
- values: function (raw) {
2000
- var
2001
- value = module.get.value()
2002
- ;
1877
+ values: function () {
1878
+ let value = module.get.value();
2003
1879
  if (value === '') {
2004
1880
  return '';
2005
1881
  }
2006
1882
 
2007
1883
  return !module.has.selectInput() && module.is.multiple()
2008
1884
  ? (typeof value === 'string' // delimited string
2009
- ? (raw
2010
- ? value
2011
- : module.escape.htmlEntities(value)).split(settings.delimiter)
1885
+ ? value.split(settings.delimiter)
2012
1886
  : '')
2013
1887
  : value;
2014
1888
  },
2015
1889
  remoteValues: function () {
2016
- var
2017
- values = module.get.values(),
2018
- remoteValues = false
2019
- ;
1890
+ let values = module.get.values();
1891
+ let remoteValues = false;
2020
1892
  if (values) {
2021
1893
  if (typeof values === 'string') {
2022
1894
  values = [values];
2023
1895
  }
2024
1896
  $.each(values, function (index, value) {
2025
- var
2026
- name = module.read.remoteData(value)
2027
- ;
1897
+ let name = module.read.remoteData(value);
2028
1898
  module.verbose('Restoring value from session data', name, value);
2029
1899
  if (name) {
2030
1900
  if (!remoteValues) {
@@ -2073,9 +1943,7 @@
2073
1943
  : String(choiceText));
2074
1944
  },
2075
1945
  inputEvent: function () {
2076
- var
2077
- input = $search[0]
2078
- ;
1946
+ let input = $search[0];
2079
1947
  if (input) {
2080
1948
  return input.oninput !== undefined
2081
1949
  ? 'input'
@@ -2087,26 +1955,22 @@
2087
1955
  return false;
2088
1956
  },
2089
1957
  selectValues: function () {
2090
- var
2091
- select = {},
2092
- oldGroup = [],
2093
- values = []
2094
- ;
1958
+ let select = {};
1959
+ let oldGroup = [];
1960
+ let values = [];
2095
1961
  $module
2096
1962
  .find('option')
2097
1963
  .each(function () {
2098
- var
2099
- $option = $(this),
2100
- name = $option.html(),
2101
- disabled = $option.attr('disabled'),
2102
- value = $option.attr('value') !== undefined
2103
- ? $option.attr('value')
2104
- : name,
2105
- text = $option.data(metadata.text) !== undefined
2106
- ? $option.data(metadata.text)
2107
- : name,
2108
- group = $option.parent('optgroup')
2109
- ;
1964
+ let $option = $(this);
1965
+ let name = module.escape.assumeUnescapedAmpLtGt($option.html());
1966
+ let disabled = $option.attr('disabled');
1967
+ let value = $option.attr('value') !== undefined
1968
+ ? $option.attr('value')
1969
+ : name;
1970
+ let text = $option.data(metadata.text) !== undefined
1971
+ ? $option.data(metadata.text)
1972
+ : name;
1973
+ let group = $option.parent('optgroup');
2110
1974
  if (settings.placeholder === 'auto' && value === '') {
2111
1975
  select.placeholder = name;
2112
1976
  } else {
@@ -2121,12 +1985,11 @@
2121
1985
  values.push({
2122
1986
  name: name,
2123
1987
  value: value,
2124
- text: module.escape.htmlEntities(text, true),
1988
+ text: text,
2125
1989
  disabled: disabled,
2126
1990
  });
2127
1991
  }
2128
- })
2129
- ;
1992
+ });
2130
1993
  if (settings.placeholder && settings.placeholder !== 'auto') {
2131
1994
  module.debug('Setting placeholder value to', settings.placeholder);
2132
1995
  select.placeholder = settings.placeholder;
@@ -2156,20 +2019,16 @@
2156
2019
  return $item.filter('.' + className.active);
2157
2020
  },
2158
2021
  selectedItem: function () {
2159
- var
2160
- $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
2161
- ;
2022
+ let $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected);
2162
2023
 
2163
2024
  return $selectedItem.length > 0
2164
2025
  ? $selectedItem
2165
2026
  : $item.eq(0);
2166
2027
  },
2167
2028
  itemWithAdditions: function (value) {
2168
- var
2169
- $items = module.get.item(value),
2170
- $userItems = module.create.userChoice(value),
2171
- hasUserItems = $userItems && $userItems.length > 0
2172
- ;
2029
+ let $items = module.get.item(value);
2030
+ let $userItems = module.create.userChoice(value);
2031
+ let hasUserItems = $userItems && $userItems.length > 0;
2173
2032
  if (hasUserItems) {
2174
2033
  $items = $items.length > 0
2175
2034
  ? $items.add($userItems)
@@ -2179,11 +2038,9 @@
2179
2038
  return $items;
2180
2039
  },
2181
2040
  item: function (value, strict) {
2182
- var
2183
- $selectedItem = false,
2184
- shouldSearch,
2185
- isMultiple
2186
- ;
2041
+ let $selectedItem = false;
2042
+ let shouldSearch;
2043
+ let isMultiple;
2187
2044
  value = value !== undefined
2188
2045
  ? value
2189
2046
  : (module.get.values() !== undefined
@@ -2199,17 +2056,15 @@
2199
2056
  if (shouldSearch) {
2200
2057
  $item
2201
2058
  .each(function () {
2202
- var
2203
- $choice = $(this),
2204
- optionText = module.get.choiceText($choice),
2205
- optionValue = module.get.choiceValue($choice, optionText)
2206
- ;
2059
+ let $choice = $(this);
2060
+ let optionText = module.get.choiceText($choice);
2061
+ let optionValue = module.get.choiceValue($choice, optionText);
2207
2062
  // safe early exit
2208
2063
  if (optionValue === null || optionValue === undefined) {
2209
2064
  return;
2210
2065
  }
2211
2066
  if (isMultiple) {
2212
- if ($.inArray(module.escape.htmlEntities(String(optionValue)), value.map(String).map(module.escape.htmlEntities)) !== -1) {
2067
+ if ($.inArray(String(optionValue), value.map(String)) !== -1) {
2213
2068
  $selectedItem = $selectedItem
2214
2069
  ? $selectedItem.add($choice)
2215
2070
  : $choice;
@@ -2226,15 +2081,14 @@
2226
2081
  optionValue = optionValue.toLowerCase();
2227
2082
  value = value.toLowerCase();
2228
2083
  }
2229
- if (module.escape.htmlEntities(String(optionValue)) === module.escape.htmlEntities(String(value))) {
2084
+ if (String(optionValue) === String(value)) {
2230
2085
  module.verbose('Found select item by value', optionValue, value);
2231
2086
  $selectedItem = $choice;
2232
2087
 
2233
2088
  return true;
2234
2089
  }
2235
2090
  }
2236
- })
2237
- ;
2091
+ });
2238
2092
  }
2239
2093
 
2240
2094
  return $selectedItem;
@@ -2284,10 +2138,8 @@
2284
2138
  module.restore.defaultValue();
2285
2139
  },
2286
2140
  defaultText: function () {
2287
- var
2288
- defaultText = module.get.defaultText(),
2289
- placeholderText = module.get.placeholderText
2290
- ;
2141
+ let defaultText = module.get.defaultText();
2142
+ let placeholderText = module.get.placeholderText;
2291
2143
  if (defaultText === placeholderText) {
2292
2144
  module.debug('Restoring default placeholder text', defaultText);
2293
2145
  module.set.placeholderText(defaultText);
@@ -2300,9 +2152,7 @@
2300
2152
  module.set.placeholderText();
2301
2153
  },
2302
2154
  defaultValue: function () {
2303
- var
2304
- defaultValue = module.get.defaultValue()
2305
- ;
2155
+ let defaultValue = module.get.defaultValue();
2306
2156
  if (defaultValue !== undefined) {
2307
2157
  module.debug('Restoring default value', defaultValue);
2308
2158
  if (defaultValue !== '') {
@@ -2342,7 +2192,7 @@
2342
2192
  } else {
2343
2193
  module.set.selected();
2344
2194
  }
2345
- var value = module.get.value();
2195
+ let value = module.get.value();
2346
2196
  if (value && value !== '' && !(Array.isArray(value) && value.length === 0)) {
2347
2197
  $input.removeClass(className.noselection);
2348
2198
  } else {
@@ -2351,9 +2201,7 @@
2351
2201
  module.remove.initialLoad();
2352
2202
  },
2353
2203
  remoteValues: function () {
2354
- var
2355
- values = module.get.remoteValues()
2356
- ;
2204
+ let values = module.get.remoteValues();
2357
2205
  module.debug('Recreating selected from session data', values);
2358
2206
  if (values) {
2359
2207
  if (module.is.single()) {
@@ -2371,9 +2219,7 @@
2371
2219
 
2372
2220
  read: {
2373
2221
  remoteData: function (value) {
2374
- var
2375
- name
2376
- ;
2222
+ let name;
2377
2223
  if (window.Storage === undefined) {
2378
2224
  module.error(error.noStorage);
2379
2225
 
@@ -2394,23 +2240,17 @@
2394
2240
  module.save.defaultValue();
2395
2241
  },
2396
2242
  defaultValue: function () {
2397
- var
2398
- value = module.get.value()
2399
- ;
2243
+ let value = module.get.value();
2400
2244
  module.verbose('Saving default value as', value);
2401
2245
  $module.data(metadata.defaultValue, value);
2402
2246
  },
2403
2247
  defaultText: function () {
2404
- var
2405
- text = module.get.text()
2406
- ;
2248
+ let text = module.get.text();
2407
2249
  module.verbose('Saving default text as', text);
2408
2250
  $module.data(metadata.defaultText, text);
2409
2251
  },
2410
2252
  placeholderText: function () {
2411
- var
2412
- text
2413
- ;
2253
+ let text;
2414
2254
  if (settings.placeholder !== false && $text.hasClass(className.placeholder)) {
2415
2255
  text = module.get.text();
2416
2256
  module.verbose('Saving placeholder text as', text);
@@ -2450,21 +2290,19 @@
2450
2290
  },
2451
2291
 
2452
2292
  scrollPage: function (direction, $selectedItem) {
2453
- var
2454
- $currentItem = $selectedItem || module.get.selectedItem(),
2455
- $menu = $currentItem.closest(selector.menu),
2456
- menuHeight = $menu.outerHeight(),
2457
- currentScroll = $menu.scrollTop(),
2458
- itemHeight = $item.eq(0).outerHeight(),
2459
- itemsPerPage = Math.floor(menuHeight / itemHeight),
2460
- newScroll = direction === 'up'
2461
- ? currentScroll - (itemHeight * itemsPerPage)
2462
- : currentScroll + (itemHeight * itemsPerPage),
2463
- $selectableItem = $item.not(selector.unselectable),
2464
- isWithinRange,
2465
- $nextSelectedItem,
2466
- elementIndex
2467
- ;
2293
+ let $currentItem = $selectedItem || module.get.selectedItem();
2294
+ let $menu = $currentItem.closest(selector.menu);
2295
+ let menuHeight = $menu.outerHeight();
2296
+ let currentScroll = $menu.scrollTop();
2297
+ let itemHeight = $item.eq(0).outerHeight();
2298
+ let itemsPerPage = Math.floor(menuHeight / itemHeight);
2299
+ let newScroll = direction === 'up'
2300
+ ? currentScroll - (itemHeight * itemsPerPage)
2301
+ : currentScroll + (itemHeight * itemsPerPage);
2302
+ let $selectableItem = $item.not(selector.unselectable);
2303
+ let isWithinRange;
2304
+ let $nextSelectedItem;
2305
+ let elementIndex;
2468
2306
  elementIndex = direction === 'up'
2469
2307
  ? $selectableItem.index($currentItem) - itemsPerPage
2470
2308
  : $selectableItem.index($currentItem) + itemsPerPage;
@@ -2479,33 +2317,28 @@
2479
2317
  if ($nextSelectedItem.length > 0) {
2480
2318
  module.debug('Scrolling page', direction, $nextSelectedItem);
2481
2319
  $currentItem
2482
- .removeClass(className.selected)
2483
- ;
2320
+ .removeClass(className.selected);
2484
2321
  $nextSelectedItem
2485
- .addClass(className.selected)
2486
- ;
2322
+ .addClass(className.selected);
2487
2323
  if (settings.selectOnKeydown && module.is.single() && !$nextSelectedItem.hasClass(className.actionable)) {
2488
2324
  module.set.selectedItem($nextSelectedItem);
2489
2325
  }
2490
2326
  $menu
2491
- .scrollTop(newScroll)
2492
- ;
2327
+ .scrollTop(newScroll);
2493
2328
  }
2494
2329
  },
2495
2330
 
2496
2331
  set: {
2497
2332
  filtered: function () {
2498
- var
2499
- isMultiple = module.is.multiple(),
2500
- isSearch = module.is.searchSelection(),
2501
- isSearchMultiple = isMultiple && isSearch,
2502
- searchValue = isSearch
2503
- ? module.get.query()
2504
- : '',
2505
- hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0,
2506
- searchWidth = module.get.searchWidth(),
2507
- valueIsSet = searchValue !== ''
2508
- ;
2333
+ let isMultiple = module.is.multiple();
2334
+ let isSearch = module.is.searchSelection();
2335
+ let isSearchMultiple = isMultiple && isSearch;
2336
+ let searchValue = isSearch
2337
+ ? module.get.query()
2338
+ : '';
2339
+ let hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0;
2340
+ let searchWidth = module.get.searchWidth();
2341
+ let valueIsSet = searchValue !== '';
2509
2342
  if (isMultiple && hasSearchValue) {
2510
2343
  module.verbose('Adjusting input width', searchWidth);
2511
2344
  $search.css('width', searchWidth + 'px');
@@ -2534,21 +2367,17 @@
2534
2367
  if (module.is.searchSelection()) {
2535
2368
  module.debug('Added tabindex to searchable dropdown');
2536
2369
  $search
2537
- .val('')
2538
- ;
2370
+ .val('');
2539
2371
  module.check.disabled();
2540
2372
  $menu
2541
- .attr('tabindex', -1)
2542
- ;
2373
+ .attr('tabindex', -1);
2543
2374
  } else {
2544
2375
  module.debug('Added tabindex to dropdown');
2545
2376
  if ($module.attr('tabindex') === undefined) {
2546
2377
  $module
2547
- .attr('tabindex', $input.attr('tabindex') || 0)
2548
- ;
2378
+ .attr('tabindex', $input.attr('tabindex') || 0);
2549
2379
  $menu
2550
- .attr('tabindex', -1)
2551
- ;
2380
+ .attr('tabindex', -1);
2552
2381
  }
2553
2382
  }
2554
2383
  $input.removeAttr('tabindex');
@@ -2565,24 +2394,20 @@
2565
2394
  }
2566
2395
  },
2567
2396
  partialSearch: function (text) {
2568
- var
2569
- length = module.get.query().length
2570
- ;
2397
+ let length = module.get.query().length;
2571
2398
  $search.val(text.slice(0, length));
2572
2399
  },
2573
2400
  scrollPosition: function ($item, forceScroll) {
2574
- var
2575
- edgeTolerance = 5,
2576
- $menu,
2577
- hasActive,
2578
- offset,
2579
- itemOffset,
2580
- menuOffset,
2581
- menuScroll,
2582
- menuHeight,
2583
- abovePage,
2584
- belowPage
2585
- ;
2401
+ let edgeTolerance = 5;
2402
+ let $menu;
2403
+ let hasActive;
2404
+ let offset;
2405
+ let itemOffset;
2406
+ let menuOffset;
2407
+ let menuScroll;
2408
+ let menuHeight;
2409
+ let abovePage;
2410
+ let belowPage;
2586
2411
 
2587
2412
  $item = $item || module.get.selectedItem();
2588
2413
  $menu = $item.closest(selector.menu);
@@ -2627,8 +2452,7 @@
2627
2452
  }
2628
2453
  module.debug('Changing text', text, $text);
2629
2454
  $text
2630
- .removeClass(className.filtered)
2631
- ;
2455
+ .removeClass(className.filtered);
2632
2456
  if (settings.preserveHTML) {
2633
2457
  $text.html(text);
2634
2458
  } else {
@@ -2637,11 +2461,9 @@
2637
2461
  }
2638
2462
  },
2639
2463
  selectedItem: function ($item) {
2640
- var
2641
- value = module.get.choiceValue($item),
2642
- searchText = module.get.choiceText($item, false),
2643
- text = module.get.choiceText($item)
2644
- ;
2464
+ let value = module.get.choiceValue($item);
2465
+ let searchText = module.get.choiceText($item, false);
2466
+ let text = module.get.choiceText($item);
2645
2467
  module.debug('Setting user selection to item', $item);
2646
2468
  module.remove.activeItem();
2647
2469
  module.set.partialSearch(searchText);
@@ -2650,12 +2472,10 @@
2650
2472
  module.set.text(text);
2651
2473
  },
2652
2474
  selectedLetter: function (letter) {
2653
- var
2654
- $selectedItem = $item.filter('.' + className.selected),
2655
- alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
2656
- $nextValue = false,
2657
- $nextItem
2658
- ;
2475
+ let $selectedItem = $item.filter('.' + className.selected);
2476
+ let alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter);
2477
+ let $nextValue = false;
2478
+ let $nextItem;
2659
2479
  // check next of the same letter
2660
2480
  if (alreadySelectedLetter) {
2661
2481
  $nextItem = $selectedItem.nextAll($item).eq(0);
@@ -2672,8 +2492,7 @@
2672
2492
 
2673
2493
  return false;
2674
2494
  }
2675
- })
2676
- ;
2495
+ });
2677
2496
  }
2678
2497
  // set the next value
2679
2498
  if ($nextValue) {
@@ -2709,11 +2528,11 @@
2709
2528
  }
2710
2529
  },
2711
2530
  upward: function ($currentMenu) {
2712
- var $element = $currentMenu || $module;
2531
+ let $element = $currentMenu || $module;
2713
2532
  $element.addClass(className.upward);
2714
2533
  },
2715
2534
  leftward: function ($currentMenu) {
2716
- var $element = $currentMenu || $menu;
2535
+ let $element = $currentMenu || $menu;
2717
2536
  $element.addClass(className.leftward);
2718
2537
  },
2719
2538
  value: function (value, text, $selected, preventChangeTrigger) {
@@ -2727,14 +2546,11 @@
2727
2546
  } else {
2728
2547
  $input.addClass(className.noselection);
2729
2548
  }
2730
- var
2731
- escapedValue = module.escape.value(value),
2732
- hasInput = $input.length > 0,
2733
- currentValue = module.get.values(),
2734
- stringValue = value !== undefined
2735
- ? String(value)
2736
- : value
2737
- ;
2549
+ let hasInput = $input.length > 0;
2550
+ let currentValue = module.get.values();
2551
+ let stringValue = value !== undefined
2552
+ ? String(value)
2553
+ : value;
2738
2554
  if (hasInput) {
2739
2555
  if (!settings.allowReselection && stringValue == currentValue) {
2740
2556
  module.verbose('Skipping value update already same value', value, currentValue);
@@ -2747,11 +2563,10 @@
2747
2563
  module.debug('Adding user option', value);
2748
2564
  module.add.optionValue(value);
2749
2565
  }
2750
- module.debug('Updating input value', escapedValue, currentValue);
2566
+ module.debug('Updating input value', value, currentValue);
2751
2567
  internalChange = true;
2752
2568
  $input
2753
- .val(escapedValue)
2754
- ;
2569
+ .val(value);
2755
2570
  if (settings.fireOnInit === false && module.is.initialLoad()) {
2756
2571
  module.debug('Input native change event ignored on initial load');
2757
2572
  } else if (preventChangeTrigger !== true) {
@@ -2759,8 +2574,8 @@
2759
2574
  }
2760
2575
  internalChange = false;
2761
2576
  } else {
2762
- module.verbose('Storing value in metadata', escapedValue, $input);
2763
- if (escapedValue !== currentValue) {
2577
+ module.verbose('Storing value in metadata', value, $input);
2578
+ if (value !== currentValue) {
2764
2579
  $module.data(metadata.value, stringValue);
2765
2580
  }
2766
2581
  }
@@ -2772,8 +2587,7 @@
2772
2587
  },
2773
2588
  active: function () {
2774
2589
  $module
2775
- .addClass(className.active)
2776
- ;
2590
+ .addClass(className.active);
2777
2591
  },
2778
2592
  multiple: function () {
2779
2593
  $module.addClass(className.multiple);
@@ -2796,9 +2610,7 @@
2796
2610
  preventChangeTrigger = $selectedItem;
2797
2611
  $selectedItem = undefined;
2798
2612
  }
2799
- var
2800
- isMultiple = module.is.multiple()
2801
- ;
2613
+ let isMultiple = module.is.multiple();
2802
2614
  $selectedItem = settings.allowAdditions
2803
2615
  ? $selectedItem || module.get.itemWithAdditions(value)
2804
2616
  : $selectedItem || module.get.item(value);
@@ -2826,17 +2638,15 @@
2826
2638
  // select each item
2827
2639
  $selectedItem
2828
2640
  .each(function () {
2829
- var
2830
- $selected = $(this),
2831
- selectedText = module.get.choiceText($selected),
2832
- selectedValue = module.get.choiceValue($selected, selectedText),
2833
-
2834
- isFiltered = $selected.hasClass(className.filtered),
2835
- isActive = $selected.hasClass(className.active),
2836
- isActionable = $selected.hasClass(className.actionable),
2837
- isUserValue = $selected.hasClass(className.addition),
2838
- shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1
2839
- ;
2641
+ let $selected = $(this);
2642
+ let selectedText = module.get.choiceText($selected);
2643
+ let selectedValue = module.get.choiceValue($selected, selectedText);
2644
+
2645
+ let isFiltered = $selected.hasClass(className.filtered);
2646
+ let isActive = $selected.hasClass(className.active);
2647
+ let isActionable = $selected.hasClass(className.actionable);
2648
+ let isUserValue = $selected.hasClass(className.addition);
2649
+ let shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1;
2840
2650
  if (isActionable) {
2841
2651
  if ((!isMultiple || (!isActive || isUserValue)) && settings.apiSettings && settings.saveRemoteData) {
2842
2652
  module.save.remoteData(selectedText, selectedValue);
@@ -2872,11 +2682,9 @@
2872
2682
  module.set.value(selectedValue, selectedText, $selected, preventChangeTrigger);
2873
2683
  $selected
2874
2684
  .addClass(className.active)
2875
- .addClass(className.selected)
2876
- ;
2685
+ .addClass(className.selected);
2877
2686
  }
2878
- })
2879
- ;
2687
+ });
2880
2688
  if (!keepSearchTerm) {
2881
2689
  module.remove.searchTerm();
2882
2690
  }
@@ -2889,25 +2697,21 @@
2889
2697
 
2890
2698
  add: {
2891
2699
  label: function (value, text, shouldAnimate) {
2892
- var
2893
- $next = module.is.searchSelection()
2894
- ? $search
2895
- : $text,
2896
- escapedValue = module.escape.value(value),
2897
- $label
2898
- ;
2700
+ let $next = module.is.searchSelection()
2701
+ ? $search
2702
+ : $text;
2703
+ let $label;
2899
2704
  if (settings.ignoreCase) {
2900
- escapedValue = escapedValue.toLowerCase();
2705
+ value = value.toLowerCase();
2901
2706
  }
2902
2707
  $label = $('<a />')
2903
2708
  .addClass(className.label)
2904
- .attr('data-' + metadata.value, escapedValue)
2905
- .html(templates.label(escapedValue, text, settings.preserveHTML, settings.className))
2906
- ;
2907
- $label = settings.onLabelCreate.call($label, escapedValue, text);
2709
+ .attr('data-' + metadata.value, value)
2710
+ .html(templates.label(value, text, settings));
2711
+ $label = settings.onLabelCreate.call($label, value, text);
2908
2712
 
2909
2713
  if (module.has.label(value)) {
2910
- module.debug('User selection already exists, skipping', escapedValue);
2714
+ module.debug('User selection already exists, skipping', value);
2911
2715
 
2912
2716
  return;
2913
2717
  }
@@ -2925,38 +2729,29 @@
2925
2729
  verbose: settings.verbose,
2926
2730
  silent: settings.silent,
2927
2731
  duration: settings.label.duration,
2928
- })
2929
- ;
2732
+ });
2930
2733
  } else {
2931
2734
  module.debug('Adding selection label', $label);
2932
2735
  $label
2933
- .insertBefore($next)
2934
- ;
2736
+ .insertBefore($next);
2935
2737
  }
2936
2738
  },
2937
2739
  message: function (message) {
2938
- var
2939
- $message = $menu.children(selector.message),
2940
- html = settings.templates.message(module.add.variables(message))
2941
- ;
2740
+ let $message = $menu.children(selector.message);
2741
+ let html = settings.templates.message(module.add.variables(message));
2942
2742
  if ($message.length > 0) {
2943
2743
  $message
2944
- .html(html)
2945
- ;
2744
+ .html(html);
2946
2745
  } else {
2947
2746
  $('<div/>')
2948
2747
  .html(html)
2949
2748
  .addClass(className.message)
2950
- .appendTo($menu)
2951
- ;
2749
+ .appendTo($menu);
2952
2750
  }
2953
2751
  },
2954
2752
  optionValue: function (value) {
2955
- var
2956
- escapedValue = module.escape.value(value),
2957
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
2958
- hasOption = $option.length > 0
2959
- ;
2753
+ let $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2754
+ let hasOption = $option.length > 0;
2960
2755
  if (hasOption) {
2961
2756
  return;
2962
2757
  }
@@ -2967,22 +2762,19 @@
2967
2762
  $input.find('option.' + className.addition).remove();
2968
2763
  }
2969
2764
  $('<option/>')
2970
- .prop('value', escapedValue)
2765
+ .prop('value', value)
2971
2766
  .addClass(className.addition)
2972
2767
  .text(value)
2973
- .appendTo($input)
2974
- ;
2768
+ .appendTo($input);
2975
2769
  module.verbose('Adding user addition as an <option>', value);
2976
2770
  module.observe.select();
2977
2771
  },
2978
2772
  userSuggestion: function (value) {
2979
- var
2980
- $addition = $menu.children(selector.addition),
2981
- $existingItem = module.get.item(value),
2982
- alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0,
2983
- hasUserSuggestion = $addition.length > 0,
2984
- html
2985
- ;
2773
+ let $addition = $menu.children(selector.addition);
2774
+ let $existingItem = module.get.item(value);
2775
+ let alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0;
2776
+ let hasUserSuggestion = $addition.length > 0;
2777
+ let html;
2986
2778
  if (settings.useLabels && module.has.maxSelections()) {
2987
2779
  return;
2988
2780
  }
@@ -2997,38 +2789,32 @@
2997
2789
  .data(metadata.text, value)
2998
2790
  .attr('data-' + metadata.value, value)
2999
2791
  .attr('data-' + metadata.text, value)
3000
- .removeClass(className.filtered)
3001
- ;
2792
+ .removeClass(className.filtered);
3002
2793
  if (!settings.hideAdditions) {
3003
- html = settings.templates.addition(module.add.variables(message.addResult, value));
2794
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
3004
2795
  $addition
3005
- .html(html)
3006
- ;
2796
+ .html(html);
3007
2797
  }
3008
2798
  module.verbose('Replacing user suggestion with new value', $addition);
3009
2799
  } else {
3010
2800
  $addition = module.create.userChoice(value);
3011
2801
  $addition
3012
- .prependTo($menu)
3013
- ;
2802
+ .prependTo($menu);
3014
2803
  module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
3015
2804
  }
3016
2805
  if (!settings.hideAdditions || module.is.allFiltered()) {
3017
2806
  $addition
3018
2807
  .addClass(className.selected)
3019
2808
  .siblings()
3020
- .removeClass(className.selected)
3021
- ;
2809
+ .removeClass(className.selected);
3022
2810
  }
3023
2811
  module.refreshItems();
3024
2812
  },
3025
2813
  variables: function (message, term) {
3026
- var
3027
- hasCount = message.search('{count}') !== -1,
3028
- hasMaxCount = message.search('{maxCount}') !== -1,
3029
- hasTerm = message.search('{term}') !== -1,
3030
- query
3031
- ;
2814
+ let hasCount = message.search('{count}') !== -1;
2815
+ let hasMaxCount = message.search('{maxCount}') !== -1;
2816
+ let hasTerm = message.search('{term}') !== -1;
2817
+ let query;
3032
2818
  module.verbose('Adding templated variables to message', message);
3033
2819
  if (hasCount) {
3034
2820
  message = message.replace('{count}', module.get.selectionCount());
@@ -3049,10 +2835,8 @@
3049
2835
  $selectedItem = undefined;
3050
2836
  addedText = undefined;
3051
2837
  }
3052
- var
3053
- currentValue = module.get.values(true),
3054
- newValue
3055
- ;
2838
+ let currentValue = module.get.values();
2839
+ let newValue;
3056
2840
  if (module.has.value(addedValue)) {
3057
2841
  module.debug('Value already selected');
3058
2842
 
@@ -3065,7 +2849,9 @@
3065
2849
  }
3066
2850
  // extend current array
3067
2851
  if (Array.isArray(currentValue)) {
3068
- newValue = $selectedItem && $selectedItem.hasClass(className.actionable) ? currentValue : currentValue.concat([addedValue]);
2852
+ newValue = $selectedItem && $selectedItem.hasClass(className.actionable)
2853
+ ? currentValue
2854
+ : currentValue.concat([addedValue]);
3069
2855
  newValue = module.get.uniqueArray(newValue);
3070
2856
  } else {
3071
2857
  newValue = [addedValue];
@@ -3108,11 +2894,11 @@
3108
2894
  initialLoad = false;
3109
2895
  },
3110
2896
  upward: function ($currentMenu) {
3111
- var $element = $currentMenu || $module;
2897
+ let $element = $currentMenu || $module;
3112
2898
  $element.removeClass(className.upward);
3113
2899
  },
3114
2900
  leftward: function ($currentMenu) {
3115
- var $element = $currentMenu || $menu;
2901
+ let $element = $currentMenu || $menu;
3116
2902
  $element.removeClass(className.leftward);
3117
2903
  },
3118
2904
  visible: function () {
@@ -3124,7 +2910,7 @@
3124
2910
  filteredItem: function () {
3125
2911
  if (settings.highlightMatches) {
3126
2912
  $.each($item, function (index, item) {
3127
- var $markItem = $(item);
2913
+ let $markItem = $(item);
3128
2914
  $markItem.html($markItem.html().replace(/<\/?mark>/g, ''));
3129
2915
  });
3130
2916
  }
@@ -3142,18 +2928,15 @@
3142
2928
  module.remove.empty();
3143
2929
  },
3144
2930
  optionValue: function (value) {
3145
- var
3146
- escapedValue = module.escape.value(value),
3147
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
3148
- hasOption = $option.length > 0
3149
- ;
2931
+ let $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2932
+ let hasOption = $option.length > 0;
3150
2933
  if (!hasOption || !$option.hasClass(className.addition)) {
3151
2934
  return;
3152
2935
  }
3153
2936
  // temporarily disconnect observer
3154
2937
  module.disconnect.selectObserver();
3155
2938
  $option.remove();
3156
- module.verbose('Removing user addition as an <option>', escapedValue);
2939
+ module.verbose('Removing user addition as an <option>', value);
3157
2940
  module.observe.select();
3158
2941
  },
3159
2942
  message: function () {
@@ -3181,11 +2964,9 @@
3181
2964
 
3182
2965
  $selectedItem
3183
2966
  .each(function () {
3184
- var
3185
- $selected = $(this),
3186
- selectedText = module.get.choiceText($selected),
3187
- selectedValue = module.get.choiceValue($selected, selectedText)
3188
- ;
2967
+ let $selected = $(this);
2968
+ let selectedText = module.get.choiceText($selected);
2969
+ let selectedValue = module.get.choiceValue($selected, selectedText);
3189
2970
  if (module.is.multiple()) {
3190
2971
  if (settings.useLabels) {
3191
2972
  module.remove.value(selectedValue, selectedText, $selected, preventChangeTrigger);
@@ -3203,22 +2984,18 @@
3203
2984
  }
3204
2985
  $selected
3205
2986
  .removeClass(className.filtered)
3206
- .removeClass(className.active)
3207
- ;
2987
+ .removeClass(className.active);
3208
2988
  if (settings.useLabels) {
3209
2989
  $selected.removeClass(className.selected);
3210
2990
  }
3211
- })
3212
- ;
2991
+ });
3213
2992
  },
3214
2993
  selectedItem: function () {
3215
2994
  $item.removeClass(className.selected);
3216
2995
  },
3217
2996
  value: function (removedValue, removedText, $removedItem, preventChangeTrigger) {
3218
- var
3219
- values = module.get.values(true),
3220
- newValue
3221
- ;
2997
+ let values = module.get.values();
2998
+ let newValue;
3222
2999
  if (module.has.selectInput()) {
3223
3000
  module.verbose('Input is <select> removing selected option', removedValue);
3224
3001
  newValue = module.remove.arrayValue(removedValue, values);
@@ -3248,11 +3025,8 @@
3248
3025
  return values;
3249
3026
  },
3250
3027
  label: function (value, shouldAnimate) {
3251
- var
3252
- escapedValue = module.escape.value(value),
3253
- $labels = $module.find(selector.label),
3254
- $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(settings.ignoreCase ? escapedValue.toLowerCase() : escapedValue) + '"]')
3255
- ;
3028
+ let $labels = $module.find(selector.label);
3029
+ let $removedLabel = $labels.filter('[data-' + metadata.value + '="' + CSS.escape(settings.ignoreCase ? value.toLowerCase() : value) + '"]');
3256
3030
  module.verbose('Removing label', $removedLabel);
3257
3031
  $removedLabel.remove();
3258
3032
  },
@@ -3266,14 +3040,12 @@
3266
3040
  module.verbose('Removing labels', $labels);
3267
3041
  $labels
3268
3042
  .each(function () {
3269
- var
3270
- $label = $(this),
3271
- value = $label.data(metadata.value),
3272
- stringValue = value !== undefined
3273
- ? String(value)
3274
- : value,
3275
- isUserValue = module.is.userValue(stringValue)
3276
- ;
3043
+ let $label = $(this);
3044
+ let value = $label.data(metadata.value);
3045
+ let stringValue = value !== undefined
3046
+ ? String(value)
3047
+ : value;
3048
+ let isUserValue = module.is.userValue(stringValue);
3277
3049
  if (settings.onLabelRemove.call($label, value) === false) {
3278
3050
  module.debug('Label remove callback cancelled removal');
3279
3051
 
@@ -3287,26 +3059,21 @@
3287
3059
  // selected will also remove label
3288
3060
  module.remove.selected(stringValue, false, preventChangeTrigger);
3289
3061
  }
3290
- })
3291
- ;
3062
+ });
3292
3063
  },
3293
3064
  tabbable: function () {
3294
3065
  if (module.is.searchSelection()) {
3295
3066
  module.debug('Searchable dropdown initialized');
3296
3067
  $search
3297
- .removeAttr('tabindex')
3298
- ;
3068
+ .removeAttr('tabindex');
3299
3069
  $menu
3300
- .removeAttr('tabindex')
3301
- ;
3070
+ .removeAttr('tabindex');
3302
3071
  } else {
3303
3072
  module.debug('Simple selection dropdown initialized');
3304
3073
  $module
3305
- .removeAttr('tabindex')
3306
- ;
3074
+ .removeAttr('tabindex');
3307
3075
  $menu
3308
- .removeAttr('tabindex')
3309
- ;
3076
+ .removeAttr('tabindex');
3310
3077
  }
3311
3078
  },
3312
3079
  diacritics: function (text) {
@@ -3343,10 +3110,8 @@
3343
3110
  return true;
3344
3111
  },
3345
3112
  firstLetter: function ($item, letter) {
3346
- var
3347
- text,
3348
- firstLetter
3349
- ;
3113
+ let text;
3114
+ let firstLetter;
3350
3115
  if (!$item || $item.length === 0 || typeof letter !== 'string') {
3351
3116
  return false;
3352
3117
  }
@@ -3372,23 +3137,18 @@
3372
3137
  return $menu.children(selector.message).length > 0;
3373
3138
  },
3374
3139
  label: function (value) {
3375
- var
3376
- escapedValue = module.escape.value(value),
3377
- $labels = $module.find(selector.label)
3378
- ;
3140
+ let $labels = $module.find(selector.label);
3379
3141
  if (settings.ignoreCase) {
3380
- escapedValue = escapedValue.toLowerCase();
3142
+ value = value.toLowerCase();
3381
3143
  }
3382
3144
 
3383
- return $labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) + '"]').length > 0;
3145
+ return $labels.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]').length > 0;
3384
3146
  },
3385
3147
  maxSelections: function () {
3386
3148
  return settings.maxSelections && module.get.selectionCount() >= settings.maxSelections;
3387
3149
  },
3388
3150
  allResultsFiltered: function () {
3389
- var
3390
- $normalResults = $item.not(selector.addition)
3391
- ;
3151
+ let $normalResults = $item.not(selector.addition);
3392
3152
 
3393
3153
  return $normalResults.filter(selector.unselectable).length === $normalResults.length;
3394
3154
  },
@@ -3404,20 +3164,16 @@
3404
3164
  : module.has.valueMatchingCase(value);
3405
3165
  },
3406
3166
  valueMatchingCase: function (value) {
3407
- var
3408
- values = module.get.values(true),
3409
- hasValue = Array.isArray(values)
3410
- ? values && ($.inArray(value, values) !== -1)
3411
- : values == value
3412
- ;
3167
+ let values = module.get.values();
3168
+ let hasValue = Array.isArray(values)
3169
+ ? values && ($.inArray(value, values) !== -1)
3170
+ : values == value;
3413
3171
 
3414
3172
  return !!hasValue;
3415
3173
  },
3416
3174
  valueIgnoringCase: function (value) {
3417
- var
3418
- values = module.get.values(true),
3419
- hasValue = false
3420
- ;
3175
+ let values = module.get.values();
3176
+ let hasValue = false;
3421
3177
  if (!Array.isArray(values)) {
3422
3178
  values = [values];
3423
3179
  }
@@ -3464,12 +3220,12 @@
3464
3220
  : $menu.transition && $menu.transition('is animating');
3465
3221
  },
3466
3222
  leftward: function ($subMenu) {
3467
- var $selectedMenu = $subMenu || $menu;
3223
+ let $selectedMenu = $subMenu || $menu;
3468
3224
 
3469
3225
  return $selectedMenu.hasClass(className.leftward);
3470
3226
  },
3471
3227
  clearable: function () {
3472
- var hasClearableClass = $module.hasClass(className.clearable);
3228
+ let hasClearableClass = $module.hasClass(className.clearable);
3473
3229
  if (!hasClearableClass && settings.clearable) {
3474
3230
  $module.addClass(className.clearable);
3475
3231
  }
@@ -3495,9 +3251,7 @@
3495
3251
  return initialLoad;
3496
3252
  },
3497
3253
  inObject: function (needle, object) {
3498
- var
3499
- found = false
3500
- ;
3254
+ let found = false;
3501
3255
  $.each(object, function (index, property) {
3502
3256
  if (property == needle) {
3503
3257
  found = true;
@@ -3521,9 +3275,7 @@
3521
3275
  return !module.is.multiple();
3522
3276
  },
3523
3277
  selectMutation: function (mutations) {
3524
- var
3525
- selectChanged = false
3526
- ;
3278
+ let selectChanged = false;
3527
3279
  $.each(mutations, function (index, mutation) {
3528
3280
  if ($(mutation.target).is('option, optgroup') || $(mutation.addedNodes).is('select') || ($(mutation.target).is('select') && mutation.type !== 'attributes')) {
3529
3281
  selectChanged = true;
@@ -3547,7 +3299,7 @@
3547
3299
  return $.inArray(value, module.get.userValues()) !== -1;
3548
3300
  },
3549
3301
  upward: function ($menu) {
3550
- var $element = $menu || $module;
3302
+ let $element = $menu || $module;
3551
3303
 
3552
3304
  return $element.hasClass(className.upward);
3553
3305
  },
@@ -3557,20 +3309,16 @@
3557
3309
  : $menu.hasClass(className.visible);
3558
3310
  },
3559
3311
  verticallyScrollableContext: function () {
3560
- var
3561
- overflowY = $context[0] !== window
3562
- ? $context.css('overflow-y')
3563
- : false
3564
- ;
3312
+ let overflowY = $context[0] !== window
3313
+ ? $context.css('overflow-y')
3314
+ : false;
3565
3315
 
3566
3316
  return overflowY === 'auto' || overflowY === 'scroll';
3567
3317
  },
3568
3318
  horizontallyScrollableContext: function () {
3569
- var
3570
- overflowX = $context[0] !== window
3571
- ? $context.css('overflow-X')
3572
- : false
3573
- ;
3319
+ let overflowX = $context[0] !== window
3320
+ ? $context.css('overflow-X')
3321
+ : false;
3574
3322
 
3575
3323
  return overflowX === 'auto' || overflowX === 'scroll';
3576
3324
  },
@@ -3585,15 +3333,12 @@
3585
3333
  );
3586
3334
  },
3587
3335
  openDownward: function ($subMenu) {
3588
- var
3589
- $currentMenu = $subMenu || $menu,
3590
- canOpenDownward,
3591
- onScreen,
3592
- calculations
3593
- ;
3336
+ let $currentMenu = $subMenu || $menu;
3337
+ let canOpenDownward;
3338
+ let onScreen;
3339
+ let calculations;
3594
3340
  $currentMenu
3595
- .addClass(className.loading)
3596
- ;
3341
+ .addClass(className.loading);
3597
3342
  calculations = {
3598
3343
  context: {
3599
3344
  offset: $context[0] === window
@@ -3632,15 +3377,12 @@
3632
3377
  return canOpenDownward;
3633
3378
  },
3634
3379
  openRightward: function ($subMenu) {
3635
- var
3636
- $currentMenu = $subMenu || $menu,
3637
- canOpenRightward = true,
3638
- isOffscreenRight = false,
3639
- calculations
3640
- ;
3380
+ let $currentMenu = $subMenu || $menu;
3381
+ let canOpenRightward = true;
3382
+ let isOffscreenRight = false;
3383
+ let calculations;
3641
3384
  $currentMenu
3642
- .addClass(className.loading)
3643
- ;
3385
+ .addClass(className.loading);
3644
3386
  calculations = {
3645
3387
  context: {
3646
3388
  offset: $context[0] === window
@@ -3687,17 +3429,15 @@
3687
3429
 
3688
3430
  animate: {
3689
3431
  show: function (callback, $subMenu) {
3690
- var
3691
- $currentMenu = $subMenu || $menu,
3692
- start = $subMenu
3693
- ? function () {}
3694
- : function () {
3695
- module.hideSubMenus();
3696
- module.hideOthers();
3697
- module.set.active();
3698
- },
3699
- transition
3700
- ;
3432
+ let $currentMenu = $subMenu || $menu;
3433
+ let start = $subMenu
3434
+ ? function () {}
3435
+ : function () {
3436
+ module.hideSubMenus();
3437
+ module.hideOthers();
3438
+ module.set.active();
3439
+ };
3440
+ let transition;
3701
3441
  callback = isFunction(callback)
3702
3442
  ? callback
3703
3443
  : function () {};
@@ -3728,22 +3468,19 @@
3728
3468
  onComplete: function () {
3729
3469
  callback.call(element);
3730
3470
  },
3731
- })
3732
- ;
3471
+ });
3733
3472
  }
3734
3473
  }
3735
3474
  },
3736
3475
  hide: function (callback, $subMenu) {
3737
- var
3738
- $currentMenu = $subMenu || $menu,
3739
- start = $subMenu
3740
- ? function () {}
3741
- : function () {
3742
- module.unbind.intent();
3743
- module.remove.active();
3744
- },
3745
- transition = settings.transition.hideMethod || module.get.transition($subMenu)
3746
- ;
3476
+ let $currentMenu = $subMenu || $menu;
3477
+ let start = $subMenu
3478
+ ? function () {}
3479
+ : function () {
3480
+ module.unbind.intent();
3481
+ module.remove.active();
3482
+ };
3483
+ let transition = settings.transition.hideMethod || module.get.transition($subMenu);
3747
3484
  callback = isFunction(callback)
3748
3485
  ? callback
3749
3486
  : function () {};
@@ -3770,8 +3507,7 @@
3770
3507
  onComplete: function () {
3771
3508
  callback.call(element);
3772
3509
  },
3773
- })
3774
- ;
3510
+ });
3775
3511
  } else {
3776
3512
  module.error(error.transition);
3777
3513
  }
@@ -3811,55 +3547,26 @@
3811
3547
  },
3812
3548
 
3813
3549
  escape: {
3814
- value: function (value) {
3815
- var
3816
- multipleValues = Array.isArray(value),
3817
- stringValue = typeof value === 'string',
3818
- isUnparsable = !stringValue && !multipleValues,
3819
- hasQuotes = stringValue && value.search(regExp.quote) !== -1,
3820
- values = []
3821
- ;
3822
- if (isUnparsable || !hasQuotes) {
3823
- return value;
3824
- }
3825
- module.debug('Encoding quote values for use in select', value);
3826
- if (multipleValues) {
3827
- $.each(value, function (index, value) {
3828
- values.push(value.replace(regExp.quote, '&quot;'));
3829
- });
3830
-
3831
- return values;
3832
- }
3833
-
3834
- return value.replace(regExp.quote, '&quot;');
3835
- },
3836
3550
  string: function (text) {
3837
3551
  text = String(text);
3838
3552
 
3839
3553
  return text.replace(regExp.escape, '\\$&');
3840
3554
  },
3841
- htmlEntities: function (string, forceAmpersand) {
3842
- forceAmpersand = typeof forceAmpersand === 'number' ? false : forceAmpersand;
3843
- var
3844
- badChars = /["'<>`]/g,
3845
- shouldEscape = /["&'<>`]/,
3846
- escape = {
3847
- '<': '&lt;',
3848
- '>': '&gt;',
3849
- '"': '&quot;',
3850
- "'": '&#x27;',
3851
- '`': '&#x60;',
3852
- },
3853
- escapedChar = function (chr) {
3854
- return escape[chr];
3855
- }
3856
- ;
3857
- if (shouldEscape.test(string)) {
3858
- string = string.replace(forceAmpersand ? /&/g : /&(?![\d#a-z]{1,12};)/gi, '&amp;');
3859
- string = string.replace(badChars, escapedChar);
3555
+
3556
+ // https://github.com/fomantic/Fomantic-UI/issues/2782
3557
+ // https://jsfiddle.net/3efL7jnt/
3558
+ assumeUnescapedAmpLtGt: function (string) {
3559
+ if (settings.preserveHTML) {
3560
+ return string;
3860
3561
  }
3861
3562
 
3862
- return string;
3563
+ const unescapeMap = {
3564
+ '&amp;': '&',
3565
+ '&lt;': '<',
3566
+ '&gt;': '>',
3567
+ };
3568
+
3569
+ return string.replace(/&(?:amp|lt|gt);/g, (v) => unescapeMap[v]);
3863
3570
  },
3864
3571
  },
3865
3572
 
@@ -3914,11 +3621,9 @@
3914
3621
  },
3915
3622
  performance: {
3916
3623
  log: function (message) {
3917
- var
3918
- currentTime,
3919
- executionTime,
3920
- previousTime
3921
- ;
3624
+ let currentTime;
3625
+ let executionTime;
3626
+ let previousTime;
3922
3627
  if (settings.performance) {
3923
3628
  currentTime = Date.now();
3924
3629
  previousTime = time || currentTime;
@@ -3937,10 +3642,8 @@
3937
3642
  }, 500);
3938
3643
  },
3939
3644
  display: function () {
3940
- var
3941
- title = settings.name + ':',
3942
- totalTime = 0
3943
- ;
3645
+ let title = settings.name + ':';
3646
+ let totalTime = 0;
3944
3647
  time = false;
3945
3648
  clearTimeout(module.performance.timer);
3946
3649
  $.each(performance, function (index, data) {
@@ -3962,22 +3665,19 @@
3962
3665
  },
3963
3666
  },
3964
3667
  invoke: function (query, passedArguments, context) {
3965
- var
3966
- object = instance,
3967
- maxDepth,
3968
- found,
3969
- response
3970
- ;
3668
+ let object = instance;
3669
+ let maxDepth;
3670
+ let found;
3671
+ let response;
3971
3672
  passedArguments = passedArguments || queryArguments;
3972
3673
  context = context || element;
3973
3674
  if (typeof query === 'string' && object !== undefined) {
3974
3675
  query = query.split(/[ .]/);
3975
3676
  maxDepth = query.length - 1;
3976
3677
  $.each(query, function (depth, value) {
3977
- var camelCaseValue = depth !== maxDepth
3678
+ let camelCaseValue = depth !== maxDepth
3978
3679
  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3979
- : query
3980
- ;
3680
+ : query;
3981
3681
  if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
3982
3682
  object = object[camelCaseValue];
3983
3683
  } else if (object[camelCaseValue] !== undefined) {
@@ -4079,7 +3779,7 @@
4079
3779
 
4080
3780
  maxSelections: false, // When set to a number, limits the number of selections to this count
4081
3781
  useLabels: true, // whether multiple select should filter currently active selections from choices
4082
- delimiter: ',', // when multiselect uses normal <input >, the values will be delimited with this character
3782
+ delimiter: ',', // when multiselect uses normal <input>, the values will be delimited with this character
4083
3783
 
4084
3784
  showOnFocus: false, // show the menu on focus
4085
3785
  allowReselection: false, // whether current value should trigger callbacks when reselected
@@ -4152,12 +3852,10 @@
4152
3852
  noAPI: 'The API module is required to load resources remotely',
4153
3853
  noStorage: 'Saving remote data requires session storage',
4154
3854
  noElement: 'This module requires ui {element}',
4155
- noNormalize: '"ignoreDiacritics" setting will be ignored. Browser does not support String().normalize(). You may consider including <https://cdn.jsdelivr.net/npm/unorm@1.4.1/lib/unorm.min.js> as a polyfill.',
4156
3855
  },
4157
3856
 
4158
3857
  regExp: {
4159
3858
  escape: /[\s#$()*+,.:=?@[\\\]^{|}-]/g,
4160
- quote: /"/g,
4161
3859
  },
4162
3860
 
4163
3861
  metadata: {
@@ -4266,137 +3964,114 @@
4266
3964
 
4267
3965
  /* Templates */
4268
3966
  $.fn.dropdown.settings.templates = {
4269
- deQuote: function (string, encode) {
4270
- return String(string).replace(/"/g, encode ? '&quot;' : '');
4271
- },
4272
- escape: function (string, preserveHTML) {
4273
- if (preserveHTML) {
3967
+ escape: function (string, settings) {
3968
+ if (settings !== undefined && settings.preserveHTML) {
4274
3969
  return string;
4275
3970
  }
4276
- var
4277
- badChars = /["'<>`]/g,
4278
- shouldEscape = /["&'<>`]/,
4279
- escape = {
4280
- '<': '&lt;',
4281
- '>': '&gt;',
4282
- '"': '&quot;',
4283
- "'": '&#x27;',
4284
- '`': '&#x60;',
4285
- },
4286
- escapedChar = function (chr) {
4287
- return escape[chr];
4288
- }
4289
- ;
4290
- if (shouldEscape.test(string)) {
4291
- string = string.replace(/&(?![\d#a-z]{1,12};)/gi, '&amp;');
4292
- string = string.replace(badChars, escapedChar);
4293
- }
4294
3971
 
4295
- return string;
3972
+ const escapeMap = {
3973
+ '"': '&quot;',
3974
+ '&': '&amp;',
3975
+ "'": '&apos;',
3976
+ '<': '&lt;',
3977
+ '>': '&gt;',
3978
+ };
3979
+
3980
+ return String(string).replace(/["&'<>]/g, (chr) => escapeMap[chr]);
4296
3981
  },
4297
3982
  // generates dropdown from select values
4298
- dropdown: function (select, fields, preserveHTML, className) {
4299
- var
4300
- placeholder = select.placeholder || false,
4301
- html = '',
4302
- escape = $.fn.dropdown.settings.templates.escape,
4303
- deQuote = $.fn.dropdown.settings.templates.deQuote
4304
- ;
3983
+ dropdown: function (select, settings) {
3984
+ let placeholder = select.placeholder || false;
3985
+ let html = '';
3986
+ let className = settings.className;
3987
+ let escape = settings.templates.escape;
4305
3988
  html += '<i class="dropdown icon"></i>';
4306
3989
  html += placeholder
4307
- ? '<div class="default text">' + escape(placeholder, preserveHTML) + '</div>'
3990
+ ? '<div class="default text">' + escape(placeholder, settings) + '</div>'
4308
3991
  : '<div class="text"></div>';
4309
- html += '<div class="' + deQuote(className.menu) + '">';
4310
- html += $.fn.dropdown.settings.templates.menu(select, fields, preserveHTML, className);
3992
+ html += '<div class="' + escape(className.menu) + '">';
3993
+ html += settings.templates.menu(select, settings);
4311
3994
  html += '</div>';
4312
3995
 
4313
3996
  return html;
4314
3997
  },
4315
3998
 
4316
3999
  // generates just menu from select
4317
- menu: function (response, fields, preserveHTML, className) {
4318
- var
4319
- values = response[fields.values] || [],
4320
- html = '',
4321
- escape = $.fn.dropdown.settings.templates.escape,
4322
- deQuote = $.fn.dropdown.settings.templates.deQuote
4323
- ;
4000
+ menu: function (response, settings) {
4001
+ let fields = settings.fields;
4002
+ let values = response[fields.values] || [];
4003
+ let html = '';
4004
+ let className = settings.className;
4005
+ let escape = settings.templates.escape;
4324
4006
  $.each(values, function (index, option) {
4325
- var
4326
- itemType = option[fields.type] || 'item',
4327
- isMenu = itemType.indexOf('menu') !== -1,
4328
- maybeData = '',
4329
- dataObject = option[fields.data]
4330
- ;
4007
+ let itemType = option[fields.type] || 'item';
4008
+ let isMenu = itemType.indexOf('menu') !== -1;
4009
+ let maybeData = '';
4010
+ let dataObject = option[fields.data];
4331
4011
  if (dataObject) {
4332
- var dataKey,
4333
- dataKeyEscaped
4334
- ;
4012
+ let dataKey;
4013
+ let dataKeyEscaped;
4335
4014
  for (dataKey in dataObject) {
4336
4015
  dataKeyEscaped = String(dataKey).replace(/\W/g, '');
4337
4016
  if (Object.prototype.hasOwnProperty.call(dataObject, dataKey) && ['text', 'value'].indexOf(dataKeyEscaped.toLowerCase()) === -1) {
4338
- maybeData += ' data-' + dataKeyEscaped + '="' + deQuote(String(dataObject[dataKey])) + '"';
4017
+ maybeData += ' data-' + dataKeyEscaped + '="' + escape(String(dataObject[dataKey])) + '"';
4339
4018
  }
4340
4019
  }
4341
4020
  }
4342
4021
  if (itemType === 'item' || isMenu) {
4343
- var
4344
- maybeText = option[fields.text]
4345
- ? ' data-text="' + deQuote(option[fields.text], true) + '"'
4346
- : '',
4347
- maybeActionable = option[fields.actionable]
4348
- ? className.actionable + ' '
4349
- : '',
4350
- maybeDisabled = option[fields.disabled]
4351
- ? className.disabled + ' '
4352
- : '',
4353
- maybeDescriptionVertical = option[fields.descriptionVertical]
4354
- ? className.descriptionVertical + ' '
4355
- : '',
4356
- hasDescription = escape(option[fields.description] || '', preserveHTML) !== ''
4357
- ;
4358
- html += '<div class="' + deQuote(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + deQuote(option[fields.value], true) + '"' + maybeText + maybeData + '>';
4022
+ let maybeText = option[fields.text]
4023
+ ? ' data-text="' + escape(option[fields.text]) + '"'
4024
+ : '';
4025
+ let maybeActionable = option[fields.actionable]
4026
+ ? className.actionable + ' '
4027
+ : '';
4028
+ let maybeDisabled = option[fields.disabled]
4029
+ ? className.disabled + ' '
4030
+ : '';
4031
+ let maybeDescriptionVertical = option[fields.descriptionVertical]
4032
+ ? className.descriptionVertical + ' '
4033
+ : '';
4034
+ let hasDescription = escape(option[fields.description] || '', settings) !== '';
4035
+ html += '<div class="' + escape(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + escape(option[fields.value]) + '"' + maybeText + maybeData + '>';
4359
4036
  if (isMenu) {
4360
4037
  html += '<i class="' + (itemType.indexOf('left') !== -1 ? 'left' : '') + ' dropdown icon"></i>';
4361
4038
  }
4362
4039
  if (option[fields.image]) {
4363
- html += '<img class="' + deQuote(option[fields.imageClass] || className.image) + '" src="' + deQuote(option[fields.image]) + (option[fields.alt] ? '" alt="' + deQuote(option[fields.alt]) : '') + '">';
4040
+ html += '<img class="' + escape(option[fields.imageClass] || className.image) + '" src="' + escape(option[fields.image]) + '"' + (option[fields.alt] ? ' alt="' + escape(option[fields.alt]) + '"' : '') + '>';
4364
4041
  }
4365
4042
  if (option[fields.icon]) {
4366
- html += '<i class="' + deQuote(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4043
+ html += '<i class="' + escape(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4367
4044
  }
4368
4045
  if (hasDescription) {
4369
- html += '<span class="' + deQuote(className.description) + '">' + escape(option[fields.description] || '', preserveHTML) + '</span>';
4370
- html += !isMenu ? '<span class="' + deQuote(className.text) + '">' : '';
4046
+ html += '<span class="' + escape(className.description) + '">' + escape(option[fields.description] || '', settings) + '</span>';
4047
+ html += !isMenu ? '<span class="' + escape(className.text) + '">' : '';
4371
4048
  }
4372
4049
  if (isMenu) {
4373
- html += '<span class="' + deQuote(className.text) + '">';
4050
+ html += '<span class="' + escape(className.text) + '">';
4374
4051
  }
4375
- html += escape(option[fields.name] || '', preserveHTML);
4052
+ html += escape(option[fields.name] || '', settings);
4376
4053
  if (isMenu) {
4377
4054
  html += '</span>';
4378
- html += '<div class="' + deQuote(itemType) + '">';
4379
- html += $.fn.dropdown.settings.templates.menu(option, fields, preserveHTML, className);
4055
+ html += '<div class="' + escape(itemType) + '">';
4056
+ html += settings.templates.menu(option, settings);
4380
4057
  html += '</div>';
4381
4058
  } else if (hasDescription) {
4382
4059
  html += '</span>';
4383
4060
  }
4384
4061
  html += '</div>';
4385
4062
  } else if (itemType === 'header') {
4386
- var
4387
- groupName = escape(option[fields.name] || '', preserveHTML),
4388
- groupIcon = deQuote(option[fields.icon] || className.groupIcon)
4389
- ;
4063
+ let groupName = option[fields.name] || '';
4064
+ let groupIcon = option[fields.icon] || className.groupIcon;
4390
4065
  if (groupName !== '' || groupIcon !== '') {
4391
- html += '<div class="' + deQuote(option[fields.class] || className.header) + '">';
4066
+ html += '<div class="' + escape(option[fields.class] || className.header) + '">';
4392
4067
  if (groupIcon !== '') {
4393
- html += '<i class="' + deQuote(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4068
+ html += '<i class="' + escape(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4394
4069
  }
4395
- html += groupName;
4070
+ html += escape(groupName, settings);
4396
4071
  html += '</div>';
4397
4072
  }
4398
4073
  if (option[fields.divider]) {
4399
- html += '<div class="' + deQuote(className.divider) + '"></div>';
4074
+ html += '<div class="' + escape(className.divider) + '"></div>';
4400
4075
  }
4401
4076
  }
4402
4077
  });
@@ -4405,13 +4080,11 @@
4405
4080
  },
4406
4081
 
4407
4082
  // generates label for multiselect
4408
- label: function (value, text, preserveHTML, className) {
4409
- var
4410
- escape = $.fn.dropdown.settings.templates.escape,
4411
- deQuote = $.fn.dropdown.settings.templates.deQuote
4412
- ;
4083
+ label: function (value, text, settings) {
4084
+ let className = settings.className;
4085
+ let escape = settings.templates.escape;
4413
4086
 
4414
- return escape(text, preserveHTML) + '<i class="' + deQuote(className.delete) + ' icon"></i>';
4087
+ return escape(text, settings) + '<i class="' + escape(className.delete) + ' icon"></i>';
4415
4088
  },
4416
4089
 
4417
4090
  // generates messages like "No results"