fomantic-ui 2.10.0-beta.7 → 2.10.0-beta.70

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 (362) hide show
  1. package/.eslintrc.js +6 -33
  2. package/.github/workflows/ci.yml +9 -9
  3. package/.github/workflows/depsreview.yml +1 -1
  4. package/.github/workflows/nightly.yml +7 -5
  5. package/.github/workflows/release.yml +2 -2
  6. package/.stylelintrc.js +1 -15
  7. package/CHANGELOG.md +5289 -2325
  8. package/README.md +11 -8
  9. package/changelog-setup.js +88 -72
  10. package/changelog-template.hbs +256 -251
  11. package/dist/components/accordion.css +1 -1
  12. package/dist/components/accordion.js +116 -164
  13. package/dist/components/accordion.min.css +1 -1
  14. package/dist/components/accordion.min.js +2 -2
  15. package/dist/components/ad.css +1 -1
  16. package/dist/components/ad.min.css +1 -1
  17. package/dist/components/api.js +190 -303
  18. package/dist/components/api.min.js +2 -2
  19. package/dist/components/breadcrumb.css +1 -1
  20. package/dist/components/breadcrumb.min.css +1 -1
  21. package/dist/components/button.css +5 -6
  22. package/dist/components/button.min.css +2 -2
  23. package/dist/components/calendar.css +3 -3
  24. package/dist/components/calendar.js +397 -482
  25. package/dist/components/calendar.min.css +2 -2
  26. package/dist/components/calendar.min.js +2 -2
  27. package/dist/components/card.css +1 -1
  28. package/dist/components/card.min.css +1 -1
  29. package/dist/components/checkbox.css +1 -1
  30. package/dist/components/checkbox.js +105 -166
  31. package/dist/components/checkbox.min.css +1 -1
  32. package/dist/components/checkbox.min.js +2 -2
  33. package/dist/components/comment.css +1 -1
  34. package/dist/components/comment.min.css +1 -1
  35. package/dist/components/container.css +1 -1
  36. package/dist/components/container.min.css +1 -1
  37. package/dist/components/dimmer.css +2 -2
  38. package/dist/components/dimmer.js +75 -121
  39. package/dist/components/dimmer.min.css +2 -2
  40. package/dist/components/dimmer.min.js +2 -2
  41. package/dist/components/divider.css +1 -1
  42. package/dist/components/divider.min.css +1 -1
  43. package/dist/components/dropdown.css +21 -35
  44. package/dist/components/dropdown.js +775 -1161
  45. package/dist/components/dropdown.min.css +2 -2
  46. package/dist/components/dropdown.min.js +2 -2
  47. package/dist/components/embed.css +1 -1
  48. package/dist/components/embed.js +95 -146
  49. package/dist/components/embed.min.css +1 -1
  50. package/dist/components/embed.min.js +2 -2
  51. package/dist/components/emoji.css +3809 -7617
  52. package/dist/components/emoji.min.css +2 -2
  53. package/dist/components/feed.css +1 -1
  54. package/dist/components/feed.min.css +1 -1
  55. package/dist/components/flag.css +1 -1
  56. package/dist/components/flag.min.css +1 -1
  57. package/dist/components/flyout.css +1 -1
  58. package/dist/components/flyout.js +242 -336
  59. package/dist/components/flyout.min.css +1 -1
  60. package/dist/components/flyout.min.js +2 -2
  61. package/dist/components/form.css +3 -5
  62. package/dist/components/form.js +425 -554
  63. package/dist/components/form.min.css +2 -2
  64. package/dist/components/form.min.js +2 -2
  65. package/dist/components/grid.css +2 -2
  66. package/dist/components/grid.min.css +2 -2
  67. package/dist/components/header.css +6 -6
  68. package/dist/components/header.min.css +2 -2
  69. package/dist/components/icon.css +10 -37
  70. package/dist/components/icon.min.css +2 -2
  71. package/dist/components/image.css +1 -1
  72. package/dist/components/image.min.css +1 -1
  73. package/dist/components/input.css +284 -12
  74. package/dist/components/input.min.css +2 -2
  75. package/dist/components/item.css +1 -1
  76. package/dist/components/item.min.css +1 -1
  77. package/dist/components/label.css +6 -14
  78. package/dist/components/label.min.css +2 -2
  79. package/dist/components/list.css +3 -3
  80. package/dist/components/list.min.css +2 -2
  81. package/dist/components/loader.css +53 -53
  82. package/dist/components/loader.min.css +2 -2
  83. package/dist/components/menu.css +45 -60
  84. package/dist/components/menu.min.css +2 -2
  85. package/dist/components/message.css +2 -2
  86. package/dist/components/message.min.css +2 -2
  87. package/dist/components/modal.css +5 -5
  88. package/dist/components/modal.js +274 -369
  89. package/dist/components/modal.min.css +2 -2
  90. package/dist/components/modal.min.js +2 -2
  91. package/dist/components/nag.css +1 -1
  92. package/dist/components/nag.js +109 -153
  93. package/dist/components/nag.min.css +1 -1
  94. package/dist/components/nag.min.js +2 -2
  95. package/dist/components/placeholder.css +2 -2
  96. package/dist/components/placeholder.min.css +2 -2
  97. package/dist/components/popup.css +19 -73
  98. package/dist/components/popup.js +210 -303
  99. package/dist/components/popup.min.css +2 -2
  100. package/dist/components/popup.min.js +2 -2
  101. package/dist/components/progress.css +4 -13
  102. package/dist/components/progress.js +128 -185
  103. package/dist/components/progress.min.css +2 -2
  104. package/dist/components/progress.min.js +2 -2
  105. package/dist/components/rail.css +1 -1
  106. package/dist/components/rail.min.css +1 -1
  107. package/dist/components/rating.css +1 -1
  108. package/dist/components/rating.js +92 -145
  109. package/dist/components/rating.min.css +1 -1
  110. package/dist/components/rating.min.js +2 -2
  111. package/dist/components/reset.css +48 -208
  112. package/dist/components/reset.min.css +2 -2
  113. package/dist/components/reveal.css +2 -5
  114. package/dist/components/reveal.min.css +2 -2
  115. package/dist/components/search.css +2 -3
  116. package/dist/components/search.js +311 -425
  117. package/dist/components/search.min.css +2 -2
  118. package/dist/components/search.min.js +2 -2
  119. package/dist/components/segment.css +6 -6
  120. package/dist/components/segment.min.css +2 -2
  121. package/dist/components/shape.css +1 -1
  122. package/dist/components/shape.js +173 -249
  123. package/dist/components/shape.min.css +1 -1
  124. package/dist/components/shape.min.js +2 -2
  125. package/dist/components/sidebar.css +1 -1
  126. package/dist/components/sidebar.js +138 -199
  127. package/dist/components/sidebar.min.css +1 -1
  128. package/dist/components/sidebar.min.js +2 -2
  129. package/dist/components/site.css +1 -1
  130. package/dist/components/site.js +59 -99
  131. package/dist/components/site.min.css +1 -1
  132. package/dist/components/site.min.js +2 -2
  133. package/dist/components/slider.css +1 -1
  134. package/dist/components/slider.js +267 -364
  135. package/dist/components/slider.min.css +1 -1
  136. package/dist/components/slider.min.js +2 -2
  137. package/dist/components/state.js +88 -132
  138. package/dist/components/state.min.js +2 -2
  139. package/dist/components/statistic.css +1 -1
  140. package/dist/components/statistic.min.css +1 -1
  141. package/dist/components/step.css +4 -4
  142. package/dist/components/step.min.css +2 -2
  143. package/dist/components/sticky.css +1 -1
  144. package/dist/components/sticky.js +163 -228
  145. package/dist/components/sticky.min.css +1 -1
  146. package/dist/components/sticky.min.js +2 -2
  147. package/dist/components/tab.css +1 -1
  148. package/dist/components/tab.js +192 -287
  149. package/dist/components/tab.min.css +1 -1
  150. package/dist/components/tab.min.js +2 -2
  151. package/dist/components/table.css +8 -8
  152. package/dist/components/table.min.css +2 -2
  153. package/dist/components/text.css +1 -1
  154. package/dist/components/text.min.css +1 -1
  155. package/dist/components/toast.css +1 -1
  156. package/dist/components/toast.js +118 -155
  157. package/dist/components/toast.min.css +1 -1
  158. package/dist/components/toast.min.js +2 -2
  159. package/dist/components/transition.css +1 -1
  160. package/dist/components/transition.js +114 -193
  161. package/dist/components/transition.min.css +1 -1
  162. package/dist/components/transition.min.js +2 -2
  163. package/dist/components/visibility.js +175 -271
  164. package/dist/components/visibility.min.js +2 -2
  165. package/dist/semantic.css +4479 -8221
  166. package/dist/semantic.js +5023 -7182
  167. package/dist/semantic.min.css +2 -2
  168. package/dist/semantic.min.js +2 -2
  169. package/examples/assets/show-examples.js +2 -4
  170. package/examples/attached.html +1 -1
  171. package/examples/components/menu.html +1 -1
  172. package/gulpfile.js +5 -7
  173. package/package.json +4 -5
  174. package/scripts/nightly-version.js +11 -14
  175. package/src/definitions/behaviors/api.js +189 -302
  176. package/src/definitions/behaviors/form.js +426 -555
  177. package/src/definitions/behaviors/state.js +87 -131
  178. package/src/definitions/behaviors/visibility.js +174 -270
  179. package/src/definitions/collections/breadcrumb.less +0 -1
  180. package/src/definitions/collections/form.less +3 -9
  181. package/src/definitions/collections/grid.less +1 -2
  182. package/src/definitions/collections/menu.less +106 -117
  183. package/src/definitions/collections/message.less +1 -2
  184. package/src/definitions/collections/table.less +7 -8
  185. package/src/definitions/elements/button.less +4 -6
  186. package/src/definitions/elements/container.less +0 -1
  187. package/src/definitions/elements/divider.less +1 -2
  188. package/src/definitions/elements/emoji.less +1 -1
  189. package/src/definitions/elements/flag.less +1 -1
  190. package/src/definitions/elements/header.less +4 -5
  191. package/src/definitions/elements/icon.less +10 -37
  192. package/src/definitions/elements/image.less +0 -1
  193. package/src/definitions/elements/input.less +4 -7
  194. package/src/definitions/elements/label.less +5 -14
  195. package/src/definitions/elements/list.less +2 -3
  196. package/src/definitions/elements/loader.less +10 -11
  197. package/src/definitions/elements/placeholder.less +1 -2
  198. package/src/definitions/elements/rail.less +0 -1
  199. package/src/definitions/elements/reveal.less +1 -5
  200. package/src/definitions/elements/segment.less +5 -6
  201. package/src/definitions/elements/step.less +3 -4
  202. package/src/definitions/elements/text.less +0 -1
  203. package/src/definitions/globals/reset.less +0 -1
  204. package/src/definitions/globals/site.js +58 -98
  205. package/src/definitions/globals/site.less +0 -1
  206. package/src/definitions/modules/accordion.js +115 -163
  207. package/src/definitions/modules/accordion.less +0 -1
  208. package/src/definitions/modules/calendar.js +396 -481
  209. package/src/definitions/modules/calendar.less +2 -3
  210. package/src/definitions/modules/checkbox.js +104 -165
  211. package/src/definitions/modules/checkbox.less +0 -1
  212. package/src/definitions/modules/dimmer.js +74 -120
  213. package/src/definitions/modules/dimmer.less +1 -2
  214. package/src/definitions/modules/dropdown.js +774 -1160
  215. package/src/definitions/modules/dropdown.less +27 -38
  216. package/src/definitions/modules/embed.js +94 -145
  217. package/src/definitions/modules/embed.less +0 -1
  218. package/src/definitions/modules/flyout.js +241 -335
  219. package/src/definitions/modules/flyout.less +0 -1
  220. package/src/definitions/modules/modal.js +273 -368
  221. package/src/definitions/modules/modal.less +3 -4
  222. package/src/definitions/modules/nag.js +108 -152
  223. package/src/definitions/modules/nag.less +0 -1
  224. package/src/definitions/modules/popup.js +209 -302
  225. package/src/definitions/modules/popup.less +18 -73
  226. package/src/definitions/modules/progress.js +127 -184
  227. package/src/definitions/modules/progress.less +3 -13
  228. package/src/definitions/modules/rating.js +93 -146
  229. package/src/definitions/modules/rating.less +0 -1
  230. package/src/definitions/modules/search.js +312 -426
  231. package/src/definitions/modules/search.less +2 -4
  232. package/src/definitions/modules/shape.js +172 -248
  233. package/src/definitions/modules/shape.less +0 -1
  234. package/src/definitions/modules/sidebar.js +137 -198
  235. package/src/definitions/modules/sidebar.less +0 -1
  236. package/src/definitions/modules/slider.js +266 -363
  237. package/src/definitions/modules/slider.less +0 -1
  238. package/src/definitions/modules/sticky.js +162 -227
  239. package/src/definitions/modules/sticky.less +0 -1
  240. package/src/definitions/modules/tab.js +191 -286
  241. package/src/definitions/modules/tab.less +0 -1
  242. package/src/definitions/modules/toast.js +117 -154
  243. package/src/definitions/modules/toast.less +0 -1
  244. package/src/definitions/modules/transition.js +113 -192
  245. package/src/definitions/modules/transition.less +1 -2
  246. package/src/definitions/views/ad.less +0 -1
  247. package/src/definitions/views/card.less +0 -1
  248. package/src/definitions/views/comment.less +0 -1
  249. package/src/definitions/views/feed.less +0 -1
  250. package/src/definitions/views/item.less +0 -1
  251. package/src/definitions/views/statistic.less +0 -1
  252. package/src/semantic.less +1 -1
  253. package/src/themes/amazon/elements/button.overrides +1 -1
  254. package/src/themes/amazon/elements/button.variables +5 -6
  255. package/src/themes/amazon/globals/site.variables +2 -3
  256. package/src/themes/bookish/elements/header.variables +2 -2
  257. package/src/themes/bootstrap3/elements/button.variables +4 -5
  258. package/src/themes/chubby/collections/menu.variables +1 -1
  259. package/src/themes/chubby/elements/button.overrides +4 -4
  260. package/src/themes/chubby/modules/accordion.overrides +1 -1
  261. package/src/themes/chubby/views/comment.overrides +2 -2
  262. package/src/themes/chubby/views/comment.variables +2 -2
  263. package/src/themes/classic/collections/table.variables +2 -2
  264. package/src/themes/classic/elements/button.variables +11 -11
  265. package/src/themes/classic/modules/progress.variables +2 -2
  266. package/src/themes/classic/views/card.variables +2 -2
  267. package/src/themes/default/collections/form.variables +2 -3
  268. package/src/themes/default/collections/menu.variables +28 -28
  269. package/src/themes/default/collections/message.variables +1 -1
  270. package/src/themes/default/collections/table.variables +4 -4
  271. package/src/themes/default/elements/button.variables +9 -10
  272. package/src/themes/default/elements/divider.variables +1 -1
  273. package/src/themes/default/elements/icon.variables +2 -2
  274. package/src/themes/default/elements/image.variables +1 -1
  275. package/src/themes/default/elements/input.variables +2 -2
  276. package/src/themes/default/elements/label.variables +4 -4
  277. package/src/themes/default/elements/list.variables +1 -1
  278. package/src/themes/default/elements/placeholder.variables +6 -6
  279. package/src/themes/default/elements/segment.variables +8 -8
  280. package/src/themes/default/globals/reset.overrides +45 -201
  281. package/src/themes/default/globals/site.variables +50 -50
  282. package/src/themes/default/globals/variation.variables +3 -2
  283. package/src/themes/default/modules/accordion.variables +0 -1
  284. package/src/themes/default/modules/checkbox.variables +1 -1
  285. package/src/themes/default/modules/dimmer.variables +12 -12
  286. package/src/themes/default/modules/dropdown.variables +17 -16
  287. package/src/themes/default/modules/embed.variables +2 -2
  288. package/src/themes/default/modules/flyout.variables +3 -3
  289. package/src/themes/default/modules/modal.variables +14 -14
  290. package/src/themes/default/modules/nag.variables +1 -1
  291. package/src/themes/default/modules/rating.variables +1 -1
  292. package/src/themes/default/modules/search.variables +1 -1
  293. package/src/themes/default/modules/shape.variables +1 -1
  294. package/src/themes/default/modules/sidebar.variables +2 -2
  295. package/src/themes/default/modules/toast.variables +4 -4
  296. package/src/themes/default/views/card.variables +6 -7
  297. package/src/themes/default/views/feed.variables +4 -4
  298. package/src/themes/default/views/item.variables +2 -3
  299. package/src/themes/flat/collections/form.variables +1 -1
  300. package/src/themes/flat/globals/site.variables +9 -9
  301. package/src/themes/github/collections/form.overrides +3 -3
  302. package/src/themes/github/collections/form.variables +3 -3
  303. package/src/themes/github/collections/menu.overrides +1 -1
  304. package/src/themes/github/collections/menu.variables +10 -10
  305. package/src/themes/github/collections/message.variables +6 -6
  306. package/src/themes/github/elements/button.variables +17 -17
  307. package/src/themes/github/elements/input.variables +3 -3
  308. package/src/themes/github/elements/segment.variables +2 -2
  309. package/src/themes/github/elements/step.overrides +4 -4
  310. package/src/themes/github/elements/step.variables +3 -3
  311. package/src/themes/github/globals/site.variables +2 -2
  312. package/src/themes/github/modules/dropdown.variables +1 -3
  313. package/src/themes/gmail/collections/message.variables +2 -2
  314. package/src/themes/material/collections/menu.variables +1 -1
  315. package/src/themes/material/elements/button.overrides +4 -4
  316. package/src/themes/material/elements/button.variables +5 -5
  317. package/src/themes/material/modules/dropdown.variables +1 -1
  318. package/src/themes/material/modules/modal.variables +1 -1
  319. package/src/themes/raised/elements/button.variables +1 -1
  320. package/src/themes/round/elements/button.variables +12 -12
  321. package/src/themes/striped/modules/progress.overrides +3 -3
  322. package/src/themes/timeline/views/feed.variables +2 -2
  323. package/src/themes/twitter/elements/button.overrides +1 -1
  324. package/src/themes/twitter/elements/button.variables +4 -5
  325. package/tasks/admin/components/create.js +87 -110
  326. package/tasks/admin/components/init.js +26 -33
  327. package/tasks/admin/components/update.js +46 -54
  328. package/tasks/admin/distributions/create.js +74 -125
  329. package/tasks/admin/distributions/init.js +27 -34
  330. package/tasks/admin/distributions/update.js +45 -53
  331. package/tasks/admin/register.js +11 -15
  332. package/tasks/build/assets.js +14 -18
  333. package/tasks/build/css.js +59 -68
  334. package/tasks/build/javascript.js +46 -54
  335. package/tasks/build.js +4 -6
  336. package/tasks/check-install.js +5 -7
  337. package/tasks/clean.js +2 -4
  338. package/tasks/collections/admin.js +13 -15
  339. package/tasks/collections/build.js +6 -8
  340. package/tasks/collections/docs.js +2 -4
  341. package/tasks/collections/install.js +2 -4
  342. package/tasks/collections/rtl.js +2 -4
  343. package/tasks/collections/various.js +2 -4
  344. package/tasks/config/admin/github.js +8 -10
  345. package/tasks/config/admin/templates/css-package.js +1 -3
  346. package/tasks/config/admin/templates/less-package.js +1 -3
  347. package/tasks/config/npm/gulpfile.js +4 -6
  348. package/tasks/config/project/config.js +26 -34
  349. package/tasks/config/project/install.js +58 -72
  350. package/tasks/config/project/release.js +7 -15
  351. package/tasks/config/tasks.js +23 -24
  352. package/tasks/config/user.js +9 -16
  353. package/tasks/docs/build.js +26 -31
  354. package/tasks/docs/metadata.js +35 -43
  355. package/tasks/docs/serve.js +20 -26
  356. package/tasks/install.js +77 -102
  357. package/tasks/rtl/build.js +2 -4
  358. package/tasks/rtl/watch.js +2 -4
  359. package/tasks/watch.js +9 -11
  360. package/test/meteor/assets.js +4 -4
  361. package/test/meteor/fonts.js +11 -13
  362. package/test/modules/module.spec.js +25 -27
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * # Fomantic-UI 2.10.0-beta.7+13b1bae - Dropdown
2
+ * # Fomantic-UI 2.10.0-beta.70+88a499a - Dropdown
3
3
  * https://github.com/fomantic/Fomantic-UI/
4
4
  *
5
5
  *
@@ -19,94 +19,89 @@
19
19
  ? window
20
20
  : globalThis;
21
21
 
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
- }
22
+ $.fn.dropdown = function (...args) {
23
+ let $allModules = $(this);
24
+ const $document = $(document);
25
+
26
+ let time = Date.now();
27
+ let performance = [];
28
+
29
+ const parameters = args[0];
30
+ const methodInvoked = typeof parameters === 'string';
31
+ const queryArguments = args.slice(1);
32
+ const contextCheck = function (context, win) {
33
+ let $context;
34
+ if ([window, document].includes(context)) {
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
- ;
108
-
109
- module = {
48
+ const settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
50
+ : $.extend({}, $.fn.dropdown.settings);
51
+
52
+ const className = settings.className;
53
+ const message = settings.message;
54
+ const fields = settings.fields;
55
+ const keys = settings.keys;
56
+ const metadata = settings.metadata;
57
+ const namespace = settings.namespace;
58
+ const regExp = settings.regExp;
59
+ const selector = settings.selector;
60
+ const error = settings.error;
61
+ const templates = settings.templates;
62
+
63
+ const eventNamespace = '.' + namespace;
64
+ const moduleNamespace = 'module-' + namespace;
65
+
66
+ let $module = $(this);
67
+ const $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 tempDisableApiCache = false;
103
+
104
+ const module = {
110
105
 
111
106
  initialize: function () {
112
107
  module.debug('Initializing dropdown', settings);
@@ -142,8 +137,7 @@
142
137
  module.verbose('Storing instance of dropdown', module);
143
138
  instance = module;
144
139
  $module
145
- .data(moduleNamespace, module)
146
- ;
140
+ .data(moduleNamespace, module);
147
141
  },
148
142
 
149
143
  destroy: function () {
@@ -154,29 +148,24 @@
154
148
  $menu.removeClass(className.visible).addClass(className.hidden);
155
149
  $module
156
150
  .off(eventNamespace)
157
- .removeData(moduleNamespace)
158
- ;
151
+ .removeData(moduleNamespace);
159
152
  $menu
160
- .off(eventNamespace)
161
- ;
153
+ .off(eventNamespace);
162
154
  $document
163
- .off(elementNamespace)
164
- ;
155
+ .off(elementNamespace);
165
156
  module.disconnect.menuObserver();
166
157
  module.disconnect.selectObserver();
167
158
  module.disconnect.classObserver();
168
159
  },
169
160
 
170
161
  observeChanges: function () {
171
- if ('MutationObserver' in window) {
172
- selectObserver = new MutationObserver(module.event.select.mutation);
173
- menuObserver = new MutationObserver(module.event.menu.mutation);
174
- classObserver = new MutationObserver(module.event.class.mutation);
175
- module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
176
- module.observe.select();
177
- module.observe.menu();
178
- module.observe.class();
179
- }
162
+ selectObserver = new MutationObserver(module.event.select.mutation);
163
+ menuObserver = new MutationObserver(module.event.menu.mutation);
164
+ classObserver = new MutationObserver(module.event.class.mutation);
165
+ module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
166
+ module.observe.select();
167
+ module.observe.menu();
168
+ module.observe.class();
180
169
  },
181
170
 
182
171
  disconnect: {
@@ -229,13 +218,10 @@
229
218
  elementNamespace = '.' + id;
230
219
  module.verbose('Creating unique id for element', id);
231
220
  },
232
- userChoice: function (values) {
233
- var
234
- $userChoices,
235
- $userChoice,
236
- html
237
- ;
238
- values = values || module.get.userValues();
221
+ userChoice: function (values = module.get.userValues()) {
222
+ let $userChoices;
223
+ let $userChoice;
224
+ let html;
239
225
  if (!values) {
240
226
  return false;
241
227
  }
@@ -244,14 +230,13 @@
244
230
  : [values];
245
231
  $.each(values, function (index, value) {
246
232
  if (module.get.item(value) === false) {
247
- html = settings.templates.addition(module.add.variables(message.addResult, value));
233
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
248
234
  $userChoice = $('<div />')
249
235
  .html(html)
250
236
  .attr('data-' + metadata.value, value)
251
237
  .attr('data-' + metadata.text, value)
252
238
  .addClass(className.addition)
253
- .addClass(className.item)
254
- ;
239
+ .addClass(className.item);
255
240
  if (settings.hideAdditions) {
256
241
  $userChoice.addClass(className.hidden);
257
242
  }
@@ -265,9 +250,7 @@
265
250
  return $userChoices;
266
251
  },
267
252
  userLabels: function (value) {
268
- var
269
- userValues = module.get.userValues()
270
- ;
253
+ const userValues = module.get.userValues();
271
254
  if (userValues) {
272
255
  module.debug('Adding user labels', userValues);
273
256
  $.each(userValues, function (index, value) {
@@ -279,21 +262,16 @@
279
262
  menu: function () {
280
263
  $menu = $('<div />')
281
264
  .addClass(className.menu)
282
- .appendTo($module)
283
- ;
265
+ .appendTo($module);
284
266
  },
285
267
  sizer: function () {
286
268
  $sizer = $('<span />')
287
269
  .addClass(className.sizer)
288
- .insertAfter($search)
289
- ;
270
+ .insertAfter($search);
290
271
  },
291
272
  },
292
273
 
293
- search: function (query) {
294
- query = query !== undefined
295
- ? query
296
- : module.get.query();
274
+ search: function (query = module.get.query()) {
297
275
  module.verbose('Searching for query', query);
298
276
  if (settings.fireOnInit === false && module.is.initialLoad()) {
299
277
  module.verbose('Skipping callback on initial load', settings.onSearch);
@@ -312,16 +290,13 @@
312
290
  .not(selector.unselectable)
313
291
  .not(selector.addition + selector.hidden)
314
292
  .eq(0)
315
- .addClass(className.selected)
316
- ;
293
+ .addClass(className.selected);
317
294
  },
318
295
  nextAvailable: function ($selected) {
319
296
  $selected = $selected.eq(0);
320
- var
321
- $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
322
- $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
323
- hasNext = $nextAvailable.length > 0
324
- ;
297
+ const $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0);
298
+ const $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0);
299
+ const hasNext = $nextAvailable.length > 0;
325
300
  if (hasNext) {
326
301
  module.verbose('Moving selection to', $nextAvailable);
327
302
  $nextAvailable.addClass(className.selected);
@@ -334,20 +309,17 @@
334
309
 
335
310
  setup: {
336
311
  api: function () {
337
- var
338
- apiSettings = {
339
- debug: settings.debug,
340
- urlData: {
341
- value: module.get.value(),
342
- query: module.get.query(),
343
- },
344
- on: false,
345
- }
346
- ;
312
+ const apiSettings = {
313
+ debug: settings.debug,
314
+ urlData: {
315
+ value: module.get.value(),
316
+ query: module.get.query(),
317
+ },
318
+ on: false,
319
+ };
347
320
  module.verbose('First request, initializing API');
348
321
  $module
349
- .api(apiSettings)
350
- ;
322
+ .api(apiSettings);
351
323
  },
352
324
  layout: function () {
353
325
  if ($module.is('select')) {
@@ -361,18 +333,14 @@
361
333
  module.verbose('Adding clear icon');
362
334
  $clear = $('<i />')
363
335
  .addClass('remove icon')
364
- .insertAfter($icon)
365
- ;
336
+ .insertAfter($icon);
366
337
  }
367
338
  if (module.is.search() && !module.has.search()) {
368
339
  module.verbose('Adding search input');
369
- var
370
- labelNode = $module.prev('label')
371
- ;
340
+ const labelNode = $module.prev('label');
372
341
  $search = $('<input />')
373
342
  .addClass(className.search)
374
- .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off')
375
- ;
343
+ .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off');
376
344
  if (labelNode.length > 0) {
377
345
  if (!labelNode.attr('id')) {
378
346
  labelNode.attr('id', '_' + module.get.id() + '_formLabel');
@@ -389,9 +357,7 @@
389
357
  }
390
358
  },
391
359
  select: function () {
392
- var
393
- selectValues = module.get.selectValues()
394
- ;
360
+ const selectValues = module.get.selectValues();
395
361
  module.debug('Dropdown initialized on a select', selectValues);
396
362
  if ($module.is('select')) {
397
363
  $input = $module;
@@ -412,8 +378,7 @@
412
378
  .addClass(className.selection)
413
379
  .addClass(className.dropdown)
414
380
  .html(templates.dropdown(selectValues, settings))
415
- .insertBefore($input)
416
- ;
381
+ .insertBefore($input);
417
382
  if ($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
418
383
  module.error(error.missingMultiple);
419
384
  $input.prop('multiple', true);
@@ -435,8 +400,7 @@
435
400
  .prop('required', false)
436
401
  .removeAttr('class')
437
402
  .detach()
438
- .prependTo($module)
439
- ;
403
+ .prependTo($module);
440
404
  }
441
405
  module.refresh();
442
406
  },
@@ -455,10 +419,8 @@
455
419
  module.setup.returnedObject();
456
420
  },
457
421
  returnedObject: function () {
458
- var
459
- $firstModules = $allModules.slice(0, elementIndex),
460
- $lastModules = $allModules.slice(elementIndex + 1)
461
- ;
422
+ const $firstModules = $allModules.slice(0, elementIndex);
423
+ const $lastModules = $allModules.slice(elementIndex + 1);
462
424
  // adjust all modules to use the correct reference
463
425
  $allModules = $firstModules.add($module).add($lastModules);
464
426
  },
@@ -492,21 +454,18 @@
492
454
  module.verbose('Refreshing cached metadata');
493
455
  $item
494
456
  .removeData(metadata.text)
495
- .removeData(metadata.value)
496
- ;
457
+ .removeData(metadata.value);
497
458
  },
498
459
 
499
460
  clearData: function () {
500
461
  module.verbose('Clearing metadata');
501
462
  $item
502
463
  .removeData(metadata.text)
503
- .removeData(metadata.value)
504
- ;
464
+ .removeData(metadata.value);
505
465
  $module
506
466
  .removeData(metadata.defaultText)
507
467
  .removeData(metadata.defaultValue)
508
- .removeData(metadata.placeholderText)
509
- ;
468
+ .removeData(metadata.placeholderText);
510
469
  },
511
470
 
512
471
  clearItems: function () {
@@ -573,11 +532,11 @@
573
532
  });
574
533
  // Hide submenus explicitly. On some browsers (esp. mobile), they will not automatically receive a
575
534
  // mouseleave event
576
- var $subMenu = $module.find(selector.menu);
535
+ const $subMenu = $module.find(selector.menu);
577
536
  if ($subMenu.length > 0) {
578
537
  module.verbose('Hiding sub-menu', $subMenu);
579
538
  $subMenu.each(function () {
580
- var $sub = $(this);
539
+ const $sub = $(this);
581
540
  if (!module.is.animating($sub)) {
582
541
  module.animate.hide(false, $sub);
583
542
  }
@@ -596,8 +555,7 @@
596
555
  $allModules
597
556
  .not($module)
598
557
  .has(selector.menu + '.' + className.visible)
599
- .dropdown('hide')
600
- ;
558
+ .dropdown('hide');
601
559
  },
602
560
 
603
561
  hideMenu: function () {
@@ -608,9 +566,7 @@
608
566
  },
609
567
 
610
568
  hideSubMenus: function () {
611
- var
612
- $subMenus = $menu.children(selector.item).find(selector.menu)
613
- ;
569
+ const $subMenus = $menu.children(selector.item).find(selector.menu);
614
570
  module.verbose('Hiding sub menus', $subMenus);
615
571
  $subMenus.transition('hide');
616
572
  },
@@ -624,28 +580,23 @@
624
580
  keyboardEvents: function () {
625
581
  module.verbose('Binding keyboard events');
626
582
  $module
627
- .on('keydown' + eventNamespace, module.event.keydown)
628
- ;
583
+ .on('keydown' + eventNamespace, module.event.keydown);
629
584
  if (module.has.search()) {
630
585
  $module
631
- .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
632
- ;
586
+ .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input);
633
587
  }
634
588
  if (module.is.multiple()) {
635
589
  $document
636
- .on('keydown' + elementNamespace, module.event.document.keydown)
637
- ;
590
+ .on('keydown' + elementNamespace, module.event.document.keydown);
638
591
  }
639
592
  },
640
593
  inputEvents: function () {
641
594
  module.verbose('Binding input change events');
642
595
  $module
643
- .on('change' + eventNamespace, selector.input, module.event.change)
644
- ;
596
+ .on('change' + eventNamespace, selector.input, module.event.change);
645
597
  if (module.is.multiple() && module.is.searchSelection()) {
646
598
  $module
647
- .on('paste' + eventNamespace, selector.search, module.event.paste)
648
- ;
599
+ .on('paste' + eventNamespace, selector.search, module.event.paste);
649
600
  }
650
601
  },
651
602
  mouseEvents: function () {
@@ -653,8 +604,7 @@
653
604
  if (module.is.multiple()) {
654
605
  $module
655
606
  .on('click' + eventNamespace, selector.label, module.event.label.click)
656
- .on('click' + eventNamespace, selector.remove, module.event.remove.click)
657
- ;
607
+ .on('click' + eventNamespace, selector.remove, module.event.remove.click);
658
608
  }
659
609
  if (module.is.searchSelection()) {
660
610
  $module
@@ -667,60 +617,50 @@
667
617
  .on('focus' + eventNamespace, selector.search, module.event.search.focus)
668
618
  .on('click' + eventNamespace, selector.search, module.event.search.focus)
669
619
  .on('blur' + eventNamespace, selector.search, module.event.search.blur)
670
- .on('click' + eventNamespace, selector.text, module.event.text.focus)
671
- ;
620
+ .on('click' + eventNamespace, selector.text, module.event.text.focus);
672
621
  if (module.is.multiple()) {
673
622
  $module
674
623
  .on('click' + eventNamespace, module.event.click)
675
- .on('click' + eventNamespace, module.event.search.focus)
676
- ;
624
+ .on('click' + eventNamespace, module.event.search.focus);
677
625
  }
678
626
  } else {
679
627
  if (settings.on === 'click') {
680
628
  $module
681
629
  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
682
- .on('click' + eventNamespace, module.event.test.toggle)
683
- ;
630
+ .on('click' + eventNamespace, module.event.test.toggle);
684
631
  } else if (settings.on === 'hover') {
685
632
  $module
686
633
  .on('mouseenter' + eventNamespace, module.delay.show)
687
634
  .on('mouseleave' + eventNamespace, module.delay.hide)
688
635
  .on('touchstart' + eventNamespace, module.event.test.toggle)
689
- .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click)
690
- ;
636
+ .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click);
691
637
  } else {
692
638
  $module
693
- .on(settings.on + eventNamespace, module.toggle)
694
- ;
639
+ .on(settings.on + eventNamespace, module.toggle);
695
640
  }
696
641
  $module
697
642
  .on('mousedown' + eventNamespace, module.event.mousedown)
698
643
  .on('mouseup' + eventNamespace, module.event.mouseup)
699
644
  .on('focus' + eventNamespace, module.event.focus)
700
- .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click)
701
- ;
645
+ .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click);
702
646
  if (module.has.menuSearch()) {
703
647
  $module
704
- .on('blur' + eventNamespace, selector.search, module.event.search.blur)
705
- ;
648
+ .on('blur' + eventNamespace, selector.search, module.event.search.blur);
706
649
  } else {
707
650
  $module
708
- .on('blur' + eventNamespace, module.event.blur)
709
- ;
651
+ .on('blur' + eventNamespace, module.event.blur);
710
652
  }
711
653
  }
712
654
  $menu
713
655
  .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
714
656
  .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
715
657
  .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
716
- .on('click' + eventNamespace, selector.item, module.event.item.click)
717
- ;
658
+ .on('click' + eventNamespace, selector.item, module.event.item.click);
718
659
  },
719
660
  intent: function () {
720
661
  module.verbose('Binding hide intent event to document');
721
662
  $document
722
- .on('click' + elementNamespace, module.event.test.hide)
723
- ;
663
+ .on('click' + elementNamespace, module.event.test.hide);
724
664
  },
725
665
  },
726
666
 
@@ -728,52 +668,51 @@
728
668
  intent: function () {
729
669
  module.verbose('Removing hide intent event from document');
730
670
  $document
731
- .off('click' + elementNamespace)
732
- ;
671
+ .off('click' + elementNamespace);
733
672
  },
734
673
  },
735
674
 
736
675
  filter: function (query) {
737
- var
738
- searchTerm = query !== undefined
739
- ? query
740
- : module.get.query(),
741
- afterFiltered = function () {
742
- if (module.is.multiple()) {
743
- module.filterActive();
744
- }
745
- if (query || (!query && module.get.activeItem().length === 0)) {
746
- module.select.firstUnfiltered();
747
- }
748
- if (module.has.allResultsFiltered()) {
749
- if (settings.onNoResults.call(element, searchTerm)) {
750
- if (settings.allowAdditions) {
751
- if (settings.hideAdditions) {
752
- module.verbose('User addition with no menu, setting empty style');
753
- module.set.empty();
754
- module.hideMenu();
755
- }
756
- } else {
757
- module.verbose('All items filtered, showing message', searchTerm);
758
- module.add.message(message.noResults);
676
+ const searchTerm = query !== undefined
677
+ ? query
678
+ : module.get.query();
679
+ const afterFiltered = function () {
680
+ if (module.is.multiple()) {
681
+ module.filterActive();
682
+ }
683
+ if (query || (!query && module.get.activeItem().length === 0)) {
684
+ module.select.firstUnfiltered();
685
+ }
686
+ if (module.has.allResultsFiltered()) {
687
+ if (settings.onNoResults.call(element, searchTerm)) {
688
+ if (settings.allowAdditions) {
689
+ if (settings.hideAdditions) {
690
+ module.verbose('User addition with no menu, setting empty style');
691
+ module.set.empty();
692
+ module.hideMenu();
759
693
  }
760
694
  } else {
761
- module.verbose('All items filtered, hiding dropdown', searchTerm);
762
- module.set.empty();
763
- module.hideMenu();
695
+ module.verbose('All items filtered, showing message', searchTerm);
696
+ module.add.message(message.noResults);
764
697
  }
765
698
  } else {
766
- module.remove.empty();
767
- module.remove.message();
768
- }
769
- if (settings.allowAdditions) {
770
- module.add.userSuggestion(module.escape.htmlEntities(query));
771
- }
772
- if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
773
- module.show();
699
+ module.verbose('All items filtered, hiding dropdown', searchTerm);
700
+ module.set.empty();
701
+ module.hideMenu();
774
702
  }
703
+ } else {
704
+ module.remove.empty();
705
+ module.remove.message();
775
706
  }
776
- ;
707
+ if (settings.allowAdditions) {
708
+ module.add.userSuggestion(settings.preserveHTML
709
+ ? settings.templates.escape(query)
710
+ : query);
711
+ }
712
+ if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
713
+ module.show();
714
+ }
715
+ };
777
716
  if (settings.useLabels && module.has.maxSelections()) {
778
717
  module.show();
779
718
 
@@ -785,15 +724,14 @@
785
724
  if (settings.filterRemoteData) {
786
725
  module.filterItems(searchTerm);
787
726
  }
788
- var preSelected = $input.val();
727
+ let preSelected = $input.val();
789
728
  if (!Array.isArray(preSelected)) {
790
729
  preSelected = preSelected && preSelected !== '' ? preSelected.split(settings.delimiter) : [];
791
730
  }
792
731
  if (module.is.multiple()) {
793
732
  $.each(preSelected, function (index, value) {
794
- $item.filter('[data-' + metadata.value + '="' + value + '"]')
795
- .addClass(className.filtered)
796
- ;
733
+ $item.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]')
734
+ .addClass(className.filtered);
797
735
  });
798
736
  }
799
737
  module.focusSearch(true);
@@ -812,88 +750,81 @@
812
750
  if (!Array.isArray(callbackParameters)) {
813
751
  callbackParameters = [callbackParameters];
814
752
  }
815
- var
816
- apiSettings = {
817
- errorDuration: false,
818
- cache: 'local',
819
- throttle: settings.throttle,
820
- urlData: {
821
- query: query,
822
- },
753
+ let apiSettings = {
754
+ errorDuration: false,
755
+ cache: 'local',
756
+ throttle: settings.throttle,
757
+ urlData: {
758
+ query: query,
823
759
  },
824
- apiCallbacks = {
825
- onError: function (errorMessage, $module, xhr) {
826
- module.add.message(message.serverError);
827
- iconClicked = false;
828
- focused = false;
829
- callback.apply(null, callbackParameters);
830
- if (typeof settings.apiSettings.onError === 'function') {
831
- settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
832
- }
833
- },
834
- onFailure: function (response, $module, xhr) {
835
- module.add.message(message.serverError);
836
- iconClicked = false;
837
- focused = false;
838
- callback.apply(null, callbackParameters);
839
- if (typeof settings.apiSettings.onFailure === 'function') {
840
- settings.apiSettings.onFailure.call(this, response, $module, xhr);
841
- }
842
- },
843
- onSuccess: function (response, $module, xhr) {
844
- var
845
- values = response[fields.remoteValues]
846
- ;
847
- if (!Array.isArray(values)) {
848
- values = [];
849
- }
850
- module.remove.message();
851
- var menuConfig = {};
852
- menuConfig[fields.values] = values;
853
- module.setup.menu(menuConfig);
760
+ };
761
+ const apiCallbacks = {
762
+ onError: function (errorMessage, $module, xhr) {
763
+ module.add.message(message.serverError);
764
+ iconClicked = false;
765
+ focused = false;
766
+ callback(...callbackParameters);
767
+ if (typeof settings.apiSettings.onError === 'function') {
768
+ settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
769
+ }
770
+ },
771
+ onFailure: function (response, $module, xhr) {
772
+ module.add.message(message.serverError);
773
+ iconClicked = false;
774
+ focused = false;
775
+ callback(...callbackParameters);
776
+ if (typeof settings.apiSettings.onFailure === 'function') {
777
+ settings.apiSettings.onFailure.call(this, response, $module, xhr);
778
+ }
779
+ },
780
+ onSuccess: function (response, $module, xhr) {
781
+ let values = response[fields.remoteValues];
782
+ if (!Array.isArray(values)) {
783
+ values = [];
784
+ }
785
+ module.remove.message();
786
+ const menuConfig = {};
787
+ menuConfig[fields.values] = values;
788
+ module.setup.menu(menuConfig);
854
789
 
855
- if (values.length === 0 && !settings.allowAdditions) {
856
- module.add.message(message.noResults);
857
- } else {
858
- var value = module.is.multiple() ? module.get.values() : module.get.value();
859
- if (value !== '') {
860
- module.verbose('Value(s) present after click icon, select value(s) in items');
861
- module.set.selected(value, null, true, true);
862
- }
863
- }
864
- iconClicked = false;
865
- focused = false;
866
- callback.apply(null, callbackParameters);
867
- if (typeof settings.apiSettings.onSuccess === 'function') {
868
- settings.apiSettings.onSuccess.call(this, response, $module, xhr);
790
+ if (values.length === 0 && !settings.allowAdditions) {
791
+ module.add.message(message.noResults);
792
+ } else {
793
+ const value = module.is.multiple() ? module.get.values() : module.get.value();
794
+ if (value !== '') {
795
+ module.verbose('Value(s) present after click icon, select value(s) in items');
796
+ module.set.selected(value, null, true, true);
869
797
  }
870
- },
871
- }
872
- ;
798
+ }
799
+ iconClicked = false;
800
+ focused = false;
801
+ callback(...callbackParameters);
802
+ if (typeof settings.apiSettings.onSuccess === 'function') {
803
+ settings.apiSettings.onSuccess.call(this, response, $module, xhr);
804
+ }
805
+ },
806
+ };
873
807
  if (!$module.api('get request')) {
874
808
  module.setup.api();
875
809
  }
876
810
  apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings, apiCallbacks, tempDisableApiCache ? { cache: false } : {});
877
811
  $module
878
812
  .api('setting', apiSettings)
879
- .api('query')
880
- ;
813
+ .api('query');
881
814
  tempDisableApiCache = false;
882
815
  },
883
816
 
884
817
  filterItems: function (query) {
885
- var
886
- searchTerm = module.remove.diacritics(
887
- query !== undefined
888
- ? query
889
- : module.get.query()
890
- ),
891
- results = null,
892
- escapedTerm = module.escape.string(searchTerm),
893
- regExpIgnore = settings.ignoreSearchCase ? 'i' : '',
894
- regExpFlags = regExpIgnore + 'gm',
895
- beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags)
896
- ;
818
+ const searchTerm = module.remove.diacritics(
819
+ query !== undefined
820
+ ? query
821
+ : module.get.query()
822
+ );
823
+ let results = null;
824
+ const escapedTerm = module.escape.string(searchTerm);
825
+ const regExpIgnore = settings.ignoreSearchCase ? 'i' : '';
826
+ const regExpFlags = regExpIgnore + 'gm';
827
+ const beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags);
897
828
  module.remove.filteredItem();
898
829
  // avoid loop if we're matching nothing
899
830
  if (module.has.query()) {
@@ -902,11 +833,9 @@
902
833
  module.verbose('Searching for matching values', searchTerm);
903
834
  $item
904
835
  .each(function () {
905
- var
906
- $choice = $(this),
907
- text,
908
- value
909
- ;
836
+ const $choice = $(this);
837
+ let text;
838
+ let value;
910
839
  if ($choice.hasClass(className.unfilterable)) {
911
840
  results.push(this);
912
841
 
@@ -934,32 +863,28 @@
934
863
  return true;
935
864
  }
936
865
  }
937
- })
938
- ;
866
+ });
939
867
  }
940
868
  module.debug('Showing only matched items', searchTerm);
941
869
  if (results) {
942
870
  $item
943
871
  .not(results)
944
- .addClass(className.filtered)
945
- ;
872
+ .addClass(className.filtered);
946
873
  if (settings.highlightMatches && (settings.match === 'both' || settings.match === 'text')) {
947
- var querySplit = query.split(''),
948
- diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '',
949
- htmlReg = '(?![^<]*>)',
950
- markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore),
951
- markedReplacer = function () {
952
- var args = [].slice.call(arguments, 1, querySplit.length * 2).map(function (x, i) {
953
- return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
954
- });
874
+ const querySplit = [...query];
875
+ const diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '';
876
+ const htmlReg = '(?![^<]*>)';
877
+ const markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore);
878
+ const markedReplacer = function (...args) {
879
+ args = args.slice(1, querySplit.length * 2).map(function (x, i) {
880
+ return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
881
+ });
955
882
 
956
- return args.join('');
957
- }
958
- ;
883
+ return args.join('');
884
+ };
959
885
  $.each(results, function (index, result) {
960
- var $result = $(result),
961
- markedHTML = module.get.choiceText($result, true)
962
- ;
886
+ const $result = $(result);
887
+ let markedHTML = module.get.choiceText($result, true);
963
888
  if (settings.ignoreDiacritics) {
964
889
  markedHTML = markedHTML.normalize('NFD');
965
890
  }
@@ -970,19 +895,17 @@
970
895
 
971
896
  if (!module.has.query()) {
972
897
  $divider
973
- .removeClass(className.hidden)
974
- ;
898
+ .removeClass(className.hidden);
975
899
  } else if (settings.hideDividers === true) {
976
900
  $divider
977
- .addClass(className.hidden)
978
- ;
901
+ .addClass(className.hidden);
979
902
  } else if (settings.hideDividers === 'empty') {
980
903
  $divider
981
904
  .removeClass(className.hidden)
982
905
  .filter(function () {
983
906
  // First find the last divider in this divider group
984
907
  // Dividers which are direct siblings are considered a group
985
- var $lastDivider = $(this).nextUntil(selector.item);
908
+ const $lastDivider = $(this).nextUntil(selector.item);
986
909
 
987
910
  return ($lastDivider.length > 0 ? $lastDivider : $(this))
988
911
  // Count all non-filtered items until the next divider (or end of the dropdown)
@@ -991,16 +914,13 @@
991
914
  // Hide divider if no items are found
992
915
  .length === 0;
993
916
  })
994
- .addClass(className.hidden)
995
- ;
917
+ .addClass(className.hidden);
996
918
  }
997
919
  },
998
920
 
999
921
  fuzzySearch: function (query, term) {
1000
- var
1001
- termLength = term.length,
1002
- queryLength = query.length
1003
- ;
922
+ const termLength = term.length;
923
+ const queryLength = query.length;
1004
924
  if (settings.ignoreSearchCase) {
1005
925
  query = query.toLowerCase();
1006
926
  term = term.toLowerCase();
@@ -1011,13 +931,11 @@
1011
931
  if (queryLength === termLength) {
1012
932
  return query === term;
1013
933
  }
1014
- for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
1015
- var
1016
- continueSearch = false,
1017
- queryCharacter = query.charCodeAt(characterIndex)
1018
- ;
934
+ for (let characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
935
+ let continueSearch = false;
936
+ const queryCharacter = query.codePointAt(characterIndex);
1019
937
  while (nextCharacterIndex < termLength) {
1020
- if (term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
938
+ if (term.codePointAt(nextCharacterIndex++) === queryCharacter) {
1021
939
  continueSearch = true;
1022
940
 
1023
941
  break;
@@ -1035,13 +953,12 @@
1035
953
  query = settings.ignoreSearchCase ? query.toLowerCase() : query;
1036
954
  term = settings.ignoreSearchCase ? term.toLowerCase() : term;
1037
955
 
1038
- return term.indexOf(query) > -1;
956
+ return term.includes(query);
1039
957
  },
1040
958
  filterActive: function () {
1041
959
  if (settings.useLabels) {
1042
960
  $item.filter('.' + className.active)
1043
- .addClass(className.filtered)
1044
- ;
961
+ .addClass(className.filtered);
1045
962
  }
1046
963
  },
1047
964
 
@@ -1064,14 +981,12 @@
1064
981
  },
1065
982
 
1066
983
  forceSelection: function () {
1067
- var
1068
- $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
1069
- $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0),
1070
- $selectedItem = $currentlySelected.length > 0
1071
- ? $currentlySelected
1072
- : $activeItem,
1073
- hasSelected = $selectedItem.length > 0
1074
- ;
984
+ const $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0);
985
+ const $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0);
986
+ const $selectedItem = $currentlySelected.length > 0
987
+ ? $currentlySelected
988
+ : $activeItem;
989
+ const hasSelected = $selectedItem.length > 0;
1075
990
  if (settings.allowAdditions || (hasSelected && !module.is.multiple())) {
1076
991
  module.debug('Forcing partial selection to selected item', $selectedItem);
1077
992
  module.event.item.click.call($selectedItem, {}, true);
@@ -1086,32 +1001,38 @@
1086
1001
  module.clear();
1087
1002
  }
1088
1003
  module.debug('Creating dropdown with specified values', values);
1089
- var menuConfig = {};
1004
+ const menuConfig = {};
1090
1005
  menuConfig[fields.values] = values;
1091
1006
  module.setup.menu(menuConfig);
1092
- $.each(values, function (index, item) {
1093
- if (item.selected === true) {
1094
- module.debug('Setting initial selection to', item[fields.value]);
1095
- module.set.selected(item[fields.value]);
1096
- if (!module.is.multiple()) {
1097
- return false;
1007
+ const findSelected = function (values) {
1008
+ let hasMultiple = true;
1009
+ $.each(values, function (index, item) {
1010
+ const itemType = item.type || 'item';
1011
+ if (item.selected === true) {
1012
+ module.debug('Setting initial selection to', item[fields.value]);
1013
+ module.set.selected(item[fields.value]);
1014
+ if (!module.is.multiple()) {
1015
+ hasMultiple = false;
1016
+ }
1017
+ } else if (itemType.includes('menu')) {
1018
+ hasMultiple = findSelected(item.values || []);
1098
1019
  }
1099
- }
1100
- });
1020
+
1021
+ return hasMultiple;
1022
+ });
1023
+
1024
+ return hasMultiple;
1025
+ };
1026
+ findSelected(values);
1101
1027
 
1102
1028
  if (module.has.selectInput()) {
1103
1029
  module.disconnect.selectObserver();
1104
1030
  $input.html('');
1105
1031
  $input.append('<option disabled selected value></option>');
1106
1032
  $.each(values, function (index, item) {
1107
- var
1108
- value = settings.templates.escape(item[fields.value]),
1109
- name = settings.templates.escape(
1110
- item[fields.name] || '',
1111
- settings
1112
- )
1113
- ;
1114
- $input.append('<option value="' + value + '"' + (item.selected === true ? ' selected' : '') + '>' + name + '</option>');
1033
+ const value = item[fields.value];
1034
+ const name = item[fields.name] || '';
1035
+ $input.append('<option value="' + settings.templates.escape(value) + '"' + (item.selected === true ? ' selected' : '') + '>' + settings.templates.escape(name, settings) + '</option>');
1115
1036
  });
1116
1037
  module.observe.select();
1117
1038
  }
@@ -1120,25 +1041,26 @@
1120
1041
 
1121
1042
  event: {
1122
1043
  paste: function (event) {
1123
- var
1124
- pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text'),
1125
- tokens = pasteValue.split(settings.delimiter),
1126
- notFoundTokens = []
1127
- ;
1128
- tokens.forEach(function (value) {
1129
- if (module.set.selected(module.escape.htmlEntities(value.trim()), null, false, true) === false) {
1130
- notFoundTokens.push(value.trim());
1044
+ const pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text');
1045
+ const tokens = pasteValue.split(settings.delimiter);
1046
+ const notFoundTokens = [];
1047
+ for (let value of tokens) {
1048
+ value = value.trim();
1049
+ const valueTrimmed = settings.preserveHTML
1050
+ ? settings.templates.escape(value)
1051
+ : value;
1052
+ if (module.set.selected(valueTrimmed, null, false, true) === false) {
1053
+ notFoundTokens.push(valueTrimmed);
1131
1054
  }
1132
- });
1055
+ }
1133
1056
  event.preventDefault();
1134
1057
  if (notFoundTokens.length > 0) {
1135
- var searchEl = $search[0],
1136
- startPos = searchEl.selectionStart,
1137
- endPos = searchEl.selectionEnd,
1138
- orgText = searchEl.value,
1139
- pasteText = notFoundTokens.join(settings.delimiter),
1140
- newEndPos = startPos + pasteText.length
1141
- ;
1058
+ const searchEl = $search[0];
1059
+ const startPos = searchEl.selectionStart;
1060
+ const endPos = searchEl.selectionEnd;
1061
+ const orgText = searchEl.value;
1062
+ const pasteText = notFoundTokens.join(settings.delimiter);
1063
+ const newEndPos = startPos + pasteText.length;
1142
1064
  $search.val(orgText.slice(0, startPos) + pasteText + orgText.slice(endPos));
1143
1065
  searchEl.selectionStart = newEndPos;
1144
1066
  searchEl.selectionEnd = newEndPos;
@@ -1182,9 +1104,7 @@
1182
1104
  }
1183
1105
  },
1184
1106
  click: function (event) {
1185
- var
1186
- $target = $(event.target)
1187
- ;
1107
+ const $target = $(event.target);
1188
1108
  // focus search
1189
1109
  if ($target.is($module)) {
1190
1110
  if (!module.is.focusedOnSearch()) {
@@ -1207,15 +1127,13 @@
1207
1127
  },
1208
1128
  blur: function (event) {
1209
1129
  pageLostFocus = document.activeElement === this;
1210
- if (module.is.searchSelection(true) && !willRefocus) {
1211
- if (!itemActivated && !pageLostFocus) {
1212
- if (settings.forceSelection) {
1213
- module.forceSelection();
1214
- } else if (!settings.allowAdditions && !settings.keepSearchTerm && !module.has.menuSearch()) {
1215
- module.remove.searchTerm();
1216
- }
1217
- module.hide();
1130
+ if (module.is.searchSelection(true) && !willRefocus && !itemActivated && !pageLostFocus) {
1131
+ if (settings.forceSelection) {
1132
+ module.forceSelection();
1133
+ } else if (!settings.allowAdditions && !settings.keepSearchTerm && !module.has.menuSearch()) {
1134
+ module.remove.searchTerm();
1218
1135
  }
1136
+ module.hide();
1219
1137
  }
1220
1138
  willRefocus = false;
1221
1139
  },
@@ -1268,16 +1186,14 @@
1268
1186
  },
1269
1187
  label: {
1270
1188
  click: function (event) {
1271
- var
1272
- $label = $(this),
1273
- $labels = $module.find(selector.label),
1274
- $activeLabels = $labels.filter('.' + className.active),
1275
- $nextActive = $label.nextAll('.' + className.active),
1276
- $prevActive = $label.prevAll('.' + className.active),
1277
- $range = $nextActive.length > 0
1278
- ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1279
- : $label.prevUntil($prevActive).add($activeLabels).add($label)
1280
- ;
1189
+ const $label = $(this);
1190
+ const $labels = $module.find(selector.label);
1191
+ const $activeLabels = $labels.filter('.' + className.active);
1192
+ const $nextActive = $label.nextAll('.' + className.active);
1193
+ const $prevActive = $label.prevAll('.' + className.active);
1194
+ const $range = $nextActive.length > 0
1195
+ ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1196
+ : $label.prevUntil($prevActive).add($activeLabels).add($label);
1281
1197
  if (event.shiftKey) {
1282
1198
  $activeLabels.removeClass(className.active);
1283
1199
  $range.addClass(className.active);
@@ -1287,15 +1203,13 @@
1287
1203
  $activeLabels.removeClass(className.active);
1288
1204
  $label.addClass(className.active);
1289
1205
  }
1290
- settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
1206
+ settings.onLabelSelect.call(this, $labels.filter('.' + className.active));
1291
1207
  event.stopPropagation();
1292
1208
  },
1293
1209
  },
1294
1210
  remove: {
1295
1211
  click: function (event) {
1296
- var
1297
- $label = $(this).parent()
1298
- ;
1212
+ const $label = $(this).parent();
1299
1213
  if ($label.hasClass(className.active)) {
1300
1214
  // remove all selected labels
1301
1215
  module.remove.activeLabels();
@@ -1308,11 +1222,9 @@
1308
1222
  },
1309
1223
  test: {
1310
1224
  toggle: function (event) {
1311
- var
1312
- toggleBehavior = module.is.multiple()
1313
- ? module.show
1314
- : module.toggle
1315
- ;
1225
+ const toggleBehavior = module.is.multiple()
1226
+ ? module.show
1227
+ : module.toggle;
1316
1228
  if (module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
1317
1229
  return;
1318
1230
  }
@@ -1326,20 +1238,18 @@
1326
1238
  }
1327
1239
  },
1328
1240
  hide: function (event) {
1329
- if (module.determine.eventInModule(event, module.hide)) {
1330
- if (element.id && $(event.target).attr('for') === element.id) {
1331
- event.preventDefault();
1332
- }
1241
+ if (module.determine.eventInModule(event, module.hide) && element.id && $(event.target).attr('for') === element.id) {
1242
+ event.preventDefault();
1333
1243
  }
1334
1244
  },
1335
1245
  },
1336
1246
  class: {
1337
1247
  mutation: function (mutations) {
1338
- mutations.forEach(function (mutation) {
1248
+ for (const mutation of mutations) {
1339
1249
  if (mutation.attributeName === 'class') {
1340
1250
  module.check.disabled();
1341
1251
  }
1342
- });
1252
+ }
1343
1253
  },
1344
1254
  },
1345
1255
  select: {
@@ -1356,18 +1266,10 @@
1356
1266
  },
1357
1267
  menu: {
1358
1268
  mutation: function (mutations) {
1359
- var
1360
- mutation = mutations[0],
1361
- $addedNode = mutation.addedNodes
1362
- ? $(mutation.addedNodes[0])
1363
- : $(false),
1364
- $removedNode = mutation.removedNodes
1365
- ? $(mutation.removedNodes[0])
1366
- : $(false),
1367
- $changedNodes = $addedNode.add($removedNode),
1368
- isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0,
1369
- isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0
1370
- ;
1269
+ const mutation = mutations[0];
1270
+ const $changedNodes = $([...mutation.addedNodes, ...mutation.removedNodes]);
1271
+ const isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0;
1272
+ const isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0;
1371
1273
  if (isUserAddition || isMessage) {
1372
1274
  module.debug('Updating item selector cache');
1373
1275
  module.refreshItems();
@@ -1385,14 +1287,12 @@
1385
1287
  },
1386
1288
  item: {
1387
1289
  mouseenter: function (event) {
1388
- var
1389
- $target = $(event.target),
1390
- $item = $(this),
1391
- $subMenu = $item.children(selector.menu),
1392
- $otherMenus = $item.siblings(selector.item).children(selector.menu),
1393
- hasSubMenu = $subMenu.length > 0,
1394
- isBubbledEvent = $subMenu.find($target).length > 0
1395
- ;
1290
+ const $target = $(event.target);
1291
+ const $item = $(this);
1292
+ const $subMenu = $item.children(selector.menu);
1293
+ const $otherMenus = $item.siblings(selector.item).children(selector.menu);
1294
+ const hasSubMenu = $subMenu.length > 0;
1295
+ const isBubbledEvent = $subMenu.find($target).length > 0;
1396
1296
  if (!isBubbledEvent && hasSubMenu) {
1397
1297
  clearTimeout(module.itemTimer);
1398
1298
  module.itemTimer = setTimeout(function () {
@@ -1406,9 +1306,7 @@
1406
1306
  }
1407
1307
  },
1408
1308
  mouseleave: function (event) {
1409
- var
1410
- $subMenu = $(this).find(selector.menu)
1411
- ;
1309
+ const $subMenu = $(this).find(selector.menu);
1412
1310
  if ($subMenu.length > 0) {
1413
1311
  clearTimeout(module.itemTimer);
1414
1312
  module.itemTimer = setTimeout(function () {
@@ -1420,17 +1318,15 @@
1420
1318
  }
1421
1319
  },
1422
1320
  click: function (event, skipRefocus) {
1423
- var
1424
- $choice = $(this),
1425
- $target = event
1426
- ? $(event.target || '')
1427
- : $(''),
1428
- $subMenu = $choice.find(selector.menu),
1429
- text = module.get.choiceText($choice),
1430
- value = module.get.choiceValue($choice, text),
1431
- hasSubMenu = $subMenu.length > 0,
1432
- isBubbledEvent = $subMenu.find($target).length > 0
1433
- ;
1321
+ const $choice = $(this);
1322
+ const $target = event
1323
+ ? $(event.target || '')
1324
+ : $('');
1325
+ const $subMenu = $choice.find(selector.menu);
1326
+ const text = module.get.choiceText($choice);
1327
+ const value = module.get.choiceValue($choice, text);
1328
+ const hasSubMenu = $subMenu.length > 0;
1329
+ const isBubbledEvent = $subMenu.find($target).length > 0;
1434
1330
  if (document.activeElement.tagName.toLowerCase() !== 'input') {
1435
1331
  $(document.activeElement).trigger('blur');
1436
1332
  }
@@ -1464,27 +1360,23 @@
1464
1360
  document: {
1465
1361
  // label selection should occur even when the element has no focus
1466
1362
  keydown: function (event) {
1467
- var
1468
- pressedKey = event.which,
1469
- isShortcutKey = module.is.inObject(pressedKey, keys)
1470
- ;
1363
+ const pressedKey = event.which;
1364
+ const isShortcutKey = module.is.inObject(pressedKey, keys);
1471
1365
  if (isShortcutKey) {
1472
- var
1473
- $label = $module.find(selector.label),
1474
- $activeLabel = $label.filter('.' + className.active),
1475
- activeValue = $activeLabel.data(metadata.value),
1476
- labelIndex = $label.index($activeLabel),
1477
- labelCount = $label.length,
1478
- hasActiveLabel = $activeLabel.length > 0,
1479
- hasMultipleActive = $activeLabel.length > 1,
1480
- isFirstLabel = labelIndex === 0,
1481
- isLastLabel = labelIndex + 1 === labelCount,
1482
- isSearch = module.is.searchSelection(),
1483
- isFocusedOnSearch = module.is.focusedOnSearch(),
1484
- isFocused = module.is.focused(),
1485
- caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0,
1486
- isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0
1487
- ;
1366
+ const $label = $module.find(selector.label);
1367
+ let $activeLabel = $label.filter('.' + className.active);
1368
+ const activeValue = $activeLabel.data(metadata.value);
1369
+ const labelIndex = $label.index($activeLabel);
1370
+ const labelCount = $label.length;
1371
+ const hasActiveLabel = $activeLabel.length > 0;
1372
+ const hasMultipleActive = $activeLabel.length > 1;
1373
+ const isFirstLabel = labelIndex === 0;
1374
+ const isLastLabel = labelIndex + 1 === labelCount;
1375
+ const isSearch = module.is.searchSelection();
1376
+ const isFocusedOnSearch = module.is.focusedOnSearch();
1377
+ const isFocused = module.is.focused();
1378
+ const caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0;
1379
+ const isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0;
1488
1380
  if (isSearch && !hasActiveLabel && !isFocusedOnSearch) {
1489
1381
  return;
1490
1382
  }
@@ -1507,8 +1399,7 @@
1507
1399
  } else {
1508
1400
  $activeLabel.prev(selector.siblingLabel)
1509
1401
  .addClass(className.active)
1510
- .end()
1511
- ;
1402
+ .end();
1512
1403
  }
1513
1404
  event.preventDefault();
1514
1405
  }
@@ -1552,10 +1443,8 @@
1552
1443
  case keys.backspace: {
1553
1444
  if (hasActiveLabel) {
1554
1445
  module.verbose('Removing active labels');
1555
- if (isLastLabel) {
1556
- if (isSearch && !isFocusedOnSearch) {
1557
- module.focusSearch();
1558
- }
1446
+ if (isLastLabel && isSearch && !isFocusedOnSearch) {
1447
+ module.focusSearch();
1559
1448
  }
1560
1449
  $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
1561
1450
  module.remove.activeLabels($activeLabel);
@@ -1583,31 +1472,27 @@
1583
1472
  },
1584
1473
 
1585
1474
  keydown: function (event) {
1586
- var
1587
- pressedKey = event.which,
1588
- isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter
1589
- ;
1475
+ let pressedKey = event.which;
1476
+ const isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter;
1590
1477
  if (isShortcutKey) {
1591
- var
1592
- $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
1593
- $activeItem = $menu.children('.' + className.active).eq(0),
1594
- $selectedItem = $currentlySelected.length > 0
1595
- ? $currentlySelected
1596
- : $activeItem,
1597
- $visibleItems = $selectedItem.length > 0
1598
- ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1599
- : $menu.children(':not(.' + className.filtered + ')'),
1600
- $subMenu = $selectedItem.children(selector.menu),
1601
- $parentMenu = $selectedItem.closest(selector.menu),
1602
- inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0,
1603
- hasSubMenu = $subMenu.length > 0,
1604
- hasSelectedItem = $selectedItem.length > 0,
1605
- selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0,
1606
- delimiterPressed = event.key === settings.delimiter && module.is.multiple(),
1607
- isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed),
1608
- $nextItem,
1609
- isSubMenuItem
1610
- ;
1478
+ const $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0);
1479
+ const $activeItem = $menu.children('.' + className.active).eq(0);
1480
+ const $selectedItem = $currentlySelected.length > 0
1481
+ ? $currentlySelected
1482
+ : $activeItem;
1483
+ const $visibleItems = $selectedItem.length > 0
1484
+ ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1485
+ : $menu.children(':not(.' + className.filtered + ')');
1486
+ const $subMenu = $selectedItem.children(selector.menu);
1487
+ const $parentMenu = $selectedItem.closest(selector.menu);
1488
+ const inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0;
1489
+ const hasSubMenu = $subMenu.length > 0;
1490
+ const hasSelectedItem = $selectedItem.length > 0;
1491
+ const selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0;
1492
+ const delimiterPressed = event.key === settings.delimiter && module.is.multiple();
1493
+ const isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed);
1494
+ let $nextItem;
1495
+ let isSubMenuItem;
1611
1496
  // allow selection with the menu closed
1612
1497
  if (isAdditionWithoutMenu) {
1613
1498
  if (selectedIsSelectable && settings.hideAdditions) {
@@ -1653,30 +1538,24 @@
1653
1538
  module.verbose('Left key pressed, closing sub-menu');
1654
1539
  module.animate.hide(false, $parentMenu);
1655
1540
  $selectedItem
1656
- .removeClass(className.selected)
1657
- ;
1541
+ .removeClass(className.selected);
1658
1542
  $parentMenu
1659
1543
  .closest(selector.item)
1660
- .addClass(className.selected)
1661
- ;
1544
+ .addClass(className.selected);
1662
1545
  event.preventDefault();
1663
1546
  }
1664
1547
  }
1665
1548
 
1666
1549
  // right arrow (show submenu)
1667
- if (pressedKey === keys.rightArrow) {
1668
- if (hasSubMenu) {
1669
- module.verbose('Right key pressed, opening sub-menu');
1670
- module.animate.show(false, $subMenu);
1671
- $selectedItem
1672
- .removeClass(className.selected)
1673
- ;
1674
- $subMenu
1675
- .find(selector.item).eq(0)
1676
- .addClass(className.selected)
1677
- ;
1678
- event.preventDefault();
1679
- }
1550
+ if (pressedKey === keys.rightArrow && hasSubMenu) {
1551
+ module.verbose('Right key pressed, opening sub-menu');
1552
+ module.animate.show(false, $subMenu);
1553
+ $selectedItem
1554
+ .removeClass(className.selected);
1555
+ $subMenu
1556
+ .find(selector.item).eq(0)
1557
+ .addClass(className.selected);
1558
+ event.preventDefault();
1680
1559
  }
1681
1560
  }
1682
1561
 
@@ -1694,11 +1573,9 @@
1694
1573
 
1695
1574
  module.verbose('Up key pressed, changing active item');
1696
1575
  $selectedItem
1697
- .removeClass(className.selected)
1698
- ;
1576
+ .removeClass(className.selected);
1699
1577
  $nextItem
1700
- .addClass(className.selected)
1701
- ;
1578
+ .addClass(className.selected);
1702
1579
  module.set.scrollPosition($nextItem);
1703
1580
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1704
1581
  module.set.selectedItem($nextItem);
@@ -1721,11 +1598,9 @@
1721
1598
 
1722
1599
  module.verbose('Down key pressed, changing active item');
1723
1600
  $item
1724
- .removeClass(className.selected)
1725
- ;
1601
+ .removeClass(className.selected);
1726
1602
  $nextItem
1727
- .addClass(className.selected)
1728
- ;
1603
+ .addClass(className.selected);
1729
1604
  module.set.scrollPosition($nextItem);
1730
1605
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1731
1606
  module.set.selectedItem($nextItem);
@@ -1763,24 +1638,19 @@
1763
1638
  event.preventDefault();
1764
1639
  }
1765
1640
  }
1766
- } else {
1767
- if (!module.has.search()) {
1768
- module.set.selectedLetter(String.fromCharCode(pressedKey));
1769
- }
1641
+ } else if (!module.has.search()) {
1642
+ module.set.selectedLetter(String.fromCodePoint(pressedKey));
1770
1643
  }
1771
1644
  },
1772
1645
  },
1773
1646
 
1774
1647
  trigger: {
1775
1648
  change: function () {
1776
- var
1777
- inputElement = $input[0]
1778
- ;
1649
+ const inputElement = $input[0];
1779
1650
  if (inputElement) {
1780
- var events = document.createEvent('HTMLEvents');
1651
+ const event = new Event('change', { bubbles: true });
1781
1652
  module.verbose('Triggering native change event');
1782
- events.initEvent('change', true, false);
1783
- inputElement.dispatchEvent(events);
1653
+ inputElement.dispatchEvent(event);
1784
1654
  }
1785
1655
  },
1786
1656
  },
@@ -1801,11 +1671,9 @@
1801
1671
  selectActionActive = false;
1802
1672
  },
1803
1673
  eventInModule: function (event, callback) {
1804
- var
1805
- $target = $(event.target),
1806
- inDocument = $target.closest(document.documentElement).length > 0,
1807
- inModule = $target.closest($module).length > 0
1808
- ;
1674
+ const $target = $(event.target);
1675
+ const inDocument = $target.closest(document.documentElement).length > 0;
1676
+ const inModule = $target.closest($module).length > 0;
1809
1677
  callback = isFunction(callback)
1810
1678
  ? callback
1811
1679
  : function () {};
@@ -1821,13 +1689,11 @@
1821
1689
  return false;
1822
1690
  },
1823
1691
  eventOnElement: function (event, callback) {
1824
- var
1825
- $target = $(event.target),
1826
- $label = $target.closest(selector.siblingLabel),
1827
- inVisibleDOM = document.body.contains(event.target),
1828
- notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels),
1829
- notInMenu = $target.closest($menu).length === 0
1830
- ;
1692
+ const $target = $(event.target);
1693
+ const $label = $target.closest(selector.siblingLabel);
1694
+ const inVisibleDOM = document.body.contains(event.target);
1695
+ const notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels);
1696
+ const notInMenu = $target.closest($menu).length === 0;
1831
1697
  callback = isFunction(callback)
1832
1698
  ? callback
1833
1699
  : function () {};
@@ -1848,10 +1714,7 @@
1848
1714
 
1849
1715
  nothing: function () {},
1850
1716
 
1851
- activate: function (text, value, element) {
1852
- value = value !== undefined
1853
- ? value
1854
- : text;
1717
+ activate: function (text, value = text, element = '') {
1855
1718
  if (module.can.activate($(element))) {
1856
1719
  module.set.selected(value, $(element), false, settings.keepSearchTerm);
1857
1720
  if (!module.is.multiple() && !(!settings.collapseOnActionable && $(element).hasClass(className.actionable))) {
@@ -1860,10 +1723,7 @@
1860
1723
  }
1861
1724
  },
1862
1725
 
1863
- select: function (text, value, element) {
1864
- value = value !== undefined
1865
- ? value
1866
- : text;
1726
+ select: function (text, value = text, element = '') {
1867
1727
  if (module.can.activate($(element))) {
1868
1728
  module.set.value(value, text, $(element));
1869
1729
  if (!module.is.multiple() && !(!settings.collapseOnActionable && $(element).hasClass(className.actionable))) {
@@ -1872,10 +1732,7 @@
1872
1732
  }
1873
1733
  },
1874
1734
 
1875
- combo: function (text, value, element) {
1876
- value = value !== undefined
1877
- ? value
1878
- : text;
1735
+ combo: function (text, value = text, element = '') {
1879
1736
  module.set.selected(value, $(element));
1880
1737
  module.hideAndClear();
1881
1738
  },
@@ -1905,30 +1762,25 @@
1905
1762
  return $module.data(metadata.placeholderText) || '';
1906
1763
  },
1907
1764
  text: function () {
1908
- return settings.preserveHTML ? $text.html() : $text.text();
1765
+ return settings.preserveHTML
1766
+ ? $text.html()
1767
+ : $text.text();
1909
1768
  },
1910
1769
  query: function () {
1911
1770
  return String($search.val()).trim();
1912
1771
  },
1913
- searchWidth: function (value) {
1914
- value = value !== undefined
1915
- ? value
1916
- : $search.val();
1772
+ searchWidth: function (value = $search.val()) {
1917
1773
  $sizer.text(value);
1918
1774
 
1919
1775
  // prevent rounding issues
1920
1776
  return Math.ceil($sizer.width() + 1);
1921
1777
  },
1922
1778
  selectionCount: function () {
1923
- var
1924
- values = module.get.values(),
1925
- count
1926
- ;
1927
- count = module.is.multiple()
1779
+ const values = module.get.values();
1780
+
1781
+ return module.is.multiple()
1928
1782
  ? (Array.isArray(values) ? values.length : 0)
1929
1783
  : (module.get.value() !== '' ? 1 : 0);
1930
-
1931
- return count;
1932
1784
  },
1933
1785
  transition: function ($subMenu) {
1934
1786
  return settings.transition === 'auto'
@@ -1936,9 +1788,7 @@
1936
1788
  : settings.transition;
1937
1789
  },
1938
1790
  userValues: function () {
1939
- var
1940
- values = module.get.values(true)
1941
- ;
1791
+ let values = module.get.values();
1942
1792
  if (!values) {
1943
1793
  return false;
1944
1794
  }
@@ -1951,16 +1801,12 @@
1951
1801
  });
1952
1802
  },
1953
1803
  uniqueArray: function (array) {
1954
- return $.grep(array, function (value, index) {
1955
- return $.inArray(value, array) === index;
1956
- });
1804
+ return [...new Set(array)];
1957
1805
  },
1958
1806
  caretPosition: function (returnEndPos) {
1959
- var
1960
- input = $search[0],
1961
- range,
1962
- rangeLength
1963
- ;
1807
+ const input = $search[0];
1808
+ let range;
1809
+ let rangeLength;
1964
1810
  if (returnEndPos && 'selectionEnd' in input) {
1965
1811
  return input.selectionEnd;
1966
1812
  }
@@ -1980,47 +1826,37 @@
1980
1826
  }
1981
1827
  },
1982
1828
  value: function () {
1983
- var
1984
- value = $input.length > 0
1985
- ? $input.val()
1986
- : $module.data(metadata.value),
1987
- isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === ''
1988
- ;
1829
+ const value = $input.length > 0
1830
+ ? $input.val()
1831
+ : $module.data(metadata.value);
1832
+ const isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === '';
1989
1833
 
1990
1834
  // prevents the placeholder element from being selected when multiple
1991
1835
  return value === undefined || isEmptyMultiselect
1992
1836
  ? ''
1993
1837
  : value;
1994
1838
  },
1995
- values: function (raw) {
1996
- var
1997
- value = module.get.value()
1998
- ;
1839
+ values: function () {
1840
+ const value = module.get.value();
1999
1841
  if (value === '') {
2000
1842
  return '';
2001
1843
  }
2002
1844
 
2003
1845
  return !module.has.selectInput() && module.is.multiple()
2004
1846
  ? (typeof value === 'string' // delimited string
2005
- ? (raw
2006
- ? value
2007
- : module.escape.htmlEntities(value)).split(settings.delimiter)
1847
+ ? value.split(settings.delimiter)
2008
1848
  : '')
2009
1849
  : value;
2010
1850
  },
2011
1851
  remoteValues: function () {
2012
- var
2013
- values = module.get.values(),
2014
- remoteValues = false
2015
- ;
1852
+ let values = module.get.values();
1853
+ let remoteValues = false;
2016
1854
  if (values) {
2017
1855
  if (typeof values === 'string') {
2018
1856
  values = [values];
2019
1857
  }
2020
1858
  $.each(values, function (index, value) {
2021
- var
2022
- name = module.read.remoteData(value)
2023
- ;
1859
+ const name = module.read.remoteData(value);
2024
1860
  module.verbose('Restoring value from session data', name, value);
2025
1861
  if (name) {
2026
1862
  if (!remoteValues) {
@@ -2033,10 +1869,7 @@
2033
1869
 
2034
1870
  return remoteValues;
2035
1871
  },
2036
- choiceText: function ($choice, preserveHTML) {
2037
- preserveHTML = preserveHTML !== undefined
2038
- ? preserveHTML
2039
- : settings.preserveHTML;
1872
+ choiceText: function ($choice, preserveHTML = settings.preserveHTML) {
2040
1873
  if ($choice) {
2041
1874
  if ($choice.find(selector.menu).length > 0) {
2042
1875
  module.verbose('Retrieving text of element with sub-menu');
@@ -2052,8 +1885,7 @@
2052
1885
  : $choice.text() && $choice.text().trim());
2053
1886
  }
2054
1887
  },
2055
- choiceValue: function ($choice, choiceText) {
2056
- choiceText = choiceText || module.get.choiceText($choice);
1888
+ choiceValue: function ($choice, choiceText = module.get.choiceText($choice)) {
2057
1889
  if (!$choice) {
2058
1890
  return false;
2059
1891
  }
@@ -2069,9 +1901,7 @@
2069
1901
  : String(choiceText));
2070
1902
  },
2071
1903
  inputEvent: function () {
2072
- var
2073
- input = $search[0]
2074
- ;
1904
+ const input = $search[0];
2075
1905
  if (input) {
2076
1906
  return input.oninput !== undefined
2077
1907
  ? 'input'
@@ -2083,26 +1913,22 @@
2083
1913
  return false;
2084
1914
  },
2085
1915
  selectValues: function () {
2086
- var
2087
- select = {},
2088
- oldGroup = [],
2089
- values = []
2090
- ;
1916
+ const select = {};
1917
+ let oldGroup = [];
1918
+ const values = [];
2091
1919
  $module
2092
1920
  .find('option')
2093
1921
  .each(function () {
2094
- var
2095
- $option = $(this),
2096
- name = $option.html(),
2097
- disabled = $option.attr('disabled'),
2098
- value = $option.attr('value') !== undefined
2099
- ? $option.attr('value')
2100
- : name,
2101
- text = $option.data(metadata.text) !== undefined
2102
- ? $option.data(metadata.text)
2103
- : name,
2104
- group = $option.parent('optgroup')
2105
- ;
1922
+ const $option = $(this);
1923
+ const name = module.escape.assumeUnescapedAmpLtGt($option.html());
1924
+ const disabled = $option.attr('disabled');
1925
+ const value = $option.attr('value') !== undefined
1926
+ ? $option.attr('value')
1927
+ : name;
1928
+ const text = $option.data(metadata.text) !== undefined
1929
+ ? $option.data(metadata.text)
1930
+ : name;
1931
+ const group = $option.parent('optgroup');
2106
1932
  if (settings.placeholder === 'auto' && value === '') {
2107
1933
  select.placeholder = name;
2108
1934
  } else {
@@ -2117,12 +1943,11 @@
2117
1943
  values.push({
2118
1944
  name: name,
2119
1945
  value: value,
2120
- text: module.escape.htmlEntities(text, true),
1946
+ text: text,
2121
1947
  disabled: disabled,
2122
1948
  });
2123
1949
  }
2124
- })
2125
- ;
1950
+ });
2126
1951
  if (settings.placeholder && settings.placeholder !== 'auto') {
2127
1952
  module.debug('Setting placeholder value to', settings.placeholder);
2128
1953
  select.placeholder = settings.placeholder;
@@ -2152,20 +1977,16 @@
2152
1977
  return $item.filter('.' + className.active);
2153
1978
  },
2154
1979
  selectedItem: function () {
2155
- var
2156
- $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
2157
- ;
1980
+ const $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected);
2158
1981
 
2159
1982
  return $selectedItem.length > 0
2160
1983
  ? $selectedItem
2161
1984
  : $item.eq(0);
2162
1985
  },
2163
1986
  itemWithAdditions: function (value) {
2164
- var
2165
- $items = module.get.item(value),
2166
- $userItems = module.create.userChoice(value),
2167
- hasUserItems = $userItems && $userItems.length > 0
2168
- ;
1987
+ let $items = module.get.item(value);
1988
+ const $userItems = module.create.userChoice(value);
1989
+ const hasUserItems = $userItems && $userItems.length > 0;
2169
1990
  if (hasUserItems) {
2170
1991
  $items = $items.length > 0
2171
1992
  ? $items.add($userItems)
@@ -2175,18 +1996,14 @@
2175
1996
  return $items;
2176
1997
  },
2177
1998
  item: function (value, strict) {
2178
- var
2179
- $selectedItem = false,
2180
- shouldSearch,
2181
- isMultiple
2182
- ;
1999
+ let $selectedItem = false;
2183
2000
  value = value !== undefined
2184
2001
  ? value
2185
2002
  : (module.get.values() !== undefined
2186
2003
  ? module.get.values()
2187
2004
  : module.get.text());
2188
- isMultiple = module.is.multiple() && Array.isArray(value);
2189
- shouldSearch = isMultiple
2005
+ const isMultiple = module.is.multiple() && Array.isArray(value);
2006
+ const shouldSearch = isMultiple
2190
2007
  ? value.length > 0
2191
2008
  : value !== undefined && value !== null;
2192
2009
  strict = value === '' || value === false || value === true
@@ -2195,17 +2012,15 @@
2195
2012
  if (shouldSearch) {
2196
2013
  $item
2197
2014
  .each(function () {
2198
- var
2199
- $choice = $(this),
2200
- optionText = module.get.choiceText($choice),
2201
- optionValue = module.get.choiceValue($choice, optionText)
2202
- ;
2015
+ const $choice = $(this);
2016
+ const optionText = module.get.choiceText($choice);
2017
+ let optionValue = module.get.choiceValue($choice, optionText);
2203
2018
  // safe early exit
2204
2019
  if (optionValue === null || optionValue === undefined) {
2205
2020
  return;
2206
2021
  }
2207
2022
  if (isMultiple) {
2208
- if ($.inArray(module.escape.htmlEntities(String(optionValue)), value.map(String).map(module.escape.htmlEntities)) !== -1) {
2023
+ if (value.map(String).includes(String(optionValue))) {
2209
2024
  $selectedItem = $selectedItem
2210
2025
  ? $selectedItem.add($choice)
2211
2026
  : $choice;
@@ -2222,15 +2037,14 @@
2222
2037
  optionValue = optionValue.toLowerCase();
2223
2038
  value = value.toLowerCase();
2224
2039
  }
2225
- if (module.escape.htmlEntities(String(optionValue)) === module.escape.htmlEntities(String(value))) {
2040
+ if (String(optionValue) === String(value)) {
2226
2041
  module.verbose('Found select item by value', optionValue, value);
2227
2042
  $selectedItem = $choice;
2228
2043
 
2229
2044
  return true;
2230
2045
  }
2231
2046
  }
2232
- })
2233
- ;
2047
+ });
2234
2048
  }
2235
2049
 
2236
2050
  return $selectedItem;
@@ -2241,11 +2055,8 @@
2241
2055
  },
2242
2056
 
2243
2057
  check: {
2244
- maxSelections: function (selectionCount) {
2058
+ maxSelections: function (selectionCount = module.get.selectionCount()) {
2245
2059
  if (settings.maxSelections) {
2246
- selectionCount = selectionCount !== undefined
2247
- ? selectionCount
2248
- : module.get.selectionCount();
2249
2060
  if (selectionCount >= settings.maxSelections) {
2250
2061
  module.debug('Maximum selection count reached');
2251
2062
  if (settings.useLabels) {
@@ -2280,10 +2091,8 @@
2280
2091
  module.restore.defaultValue();
2281
2092
  },
2282
2093
  defaultText: function () {
2283
- var
2284
- defaultText = module.get.defaultText(),
2285
- placeholderText = module.get.placeholderText
2286
- ;
2094
+ const defaultText = module.get.defaultText();
2095
+ const placeholderText = module.get.placeholderText;
2287
2096
  if (defaultText === placeholderText) {
2288
2097
  module.debug('Restoring default placeholder text', defaultText);
2289
2098
  module.set.placeholderText(defaultText);
@@ -2296,9 +2105,7 @@
2296
2105
  module.set.placeholderText();
2297
2106
  },
2298
2107
  defaultValue: function () {
2299
- var
2300
- defaultValue = module.get.defaultValue()
2301
- ;
2108
+ const defaultValue = module.get.defaultValue();
2302
2109
  if (defaultValue !== undefined) {
2303
2110
  module.debug('Restoring default value', defaultValue);
2304
2111
  if (defaultValue !== '') {
@@ -2338,7 +2145,7 @@
2338
2145
  } else {
2339
2146
  module.set.selected();
2340
2147
  }
2341
- var value = module.get.value();
2148
+ const value = module.get.value();
2342
2149
  if (value && value !== '' && !(Array.isArray(value) && value.length === 0)) {
2343
2150
  $input.removeClass(className.noselection);
2344
2151
  } else {
@@ -2347,9 +2154,7 @@
2347
2154
  module.remove.initialLoad();
2348
2155
  },
2349
2156
  remoteValues: function () {
2350
- var
2351
- values = module.get.remoteValues()
2352
- ;
2157
+ const values = module.get.remoteValues();
2353
2158
  module.debug('Recreating selected from session data', values);
2354
2159
  if (values) {
2355
2160
  if (module.is.single()) {
@@ -2367,15 +2172,7 @@
2367
2172
 
2368
2173
  read: {
2369
2174
  remoteData: function (value) {
2370
- var
2371
- name
2372
- ;
2373
- if (window.Storage === undefined) {
2374
- module.error(error.noStorage);
2375
-
2376
- return;
2377
- }
2378
- name = sessionStorage.getItem(value + elementNamespace);
2175
+ const name = window.sessionStorage.getItem(value + elementNamespace);
2379
2176
 
2380
2177
  return name !== undefined
2381
2178
  ? name
@@ -2390,23 +2187,17 @@
2390
2187
  module.save.defaultValue();
2391
2188
  },
2392
2189
  defaultValue: function () {
2393
- var
2394
- value = module.get.value()
2395
- ;
2190
+ const value = module.get.value();
2396
2191
  module.verbose('Saving default value as', value);
2397
2192
  $module.data(metadata.defaultValue, value);
2398
2193
  },
2399
2194
  defaultText: function () {
2400
- var
2401
- text = module.get.text()
2402
- ;
2195
+ const text = module.get.text();
2403
2196
  module.verbose('Saving default text as', text);
2404
2197
  $module.data(metadata.defaultText, text);
2405
2198
  },
2406
2199
  placeholderText: function () {
2407
- var
2408
- text
2409
- ;
2200
+ let text;
2410
2201
  if (settings.placeholder !== false && $text.hasClass(className.placeholder)) {
2411
2202
  text = module.get.text();
2412
2203
  module.verbose('Saving placeholder text as', text);
@@ -2414,13 +2205,8 @@
2414
2205
  }
2415
2206
  },
2416
2207
  remoteData: function (name, value) {
2417
- if (window.Storage === undefined) {
2418
- module.error(error.noStorage);
2419
-
2420
- return;
2421
- }
2422
2208
  module.verbose('Saving remote data to session storage', value, name);
2423
- sessionStorage.setItem(value + elementNamespace, name);
2209
+ window.sessionStorage.setItem(value + elementNamespace, name);
2424
2210
  },
2425
2211
  },
2426
2212
 
@@ -2446,28 +2232,23 @@
2446
2232
  },
2447
2233
 
2448
2234
  scrollPage: function (direction, $selectedItem) {
2449
- var
2450
- $currentItem = $selectedItem || module.get.selectedItem(),
2451
- $menu = $currentItem.closest(selector.menu),
2452
- menuHeight = $menu.outerHeight(),
2453
- currentScroll = $menu.scrollTop(),
2454
- itemHeight = $item.eq(0).outerHeight(),
2455
- itemsPerPage = Math.floor(menuHeight / itemHeight),
2456
- newScroll = direction === 'up'
2457
- ? currentScroll - (itemHeight * itemsPerPage)
2458
- : currentScroll + (itemHeight * itemsPerPage),
2459
- $selectableItem = $item.not(selector.unselectable),
2460
- isWithinRange,
2461
- $nextSelectedItem,
2462
- elementIndex
2463
- ;
2464
- elementIndex = direction === 'up'
2235
+ const $currentItem = $selectedItem || module.get.selectedItem();
2236
+ const $menu = $currentItem.closest(selector.menu);
2237
+ const menuHeight = $menu.outerHeight();
2238
+ const currentScroll = $menu.scrollTop();
2239
+ const itemHeight = $item.eq(0).outerHeight();
2240
+ const itemsPerPage = Math.floor(menuHeight / itemHeight);
2241
+ const newScroll = direction === 'up'
2242
+ ? currentScroll - (itemHeight * itemsPerPage)
2243
+ : currentScroll + (itemHeight * itemsPerPage);
2244
+ const $selectableItem = $item.not(selector.unselectable);
2245
+ const elementIndex = direction === 'up'
2465
2246
  ? $selectableItem.index($currentItem) - itemsPerPage
2466
2247
  : $selectableItem.index($currentItem) + itemsPerPage;
2467
- isWithinRange = direction === 'up'
2248
+ const isWithinRange = direction === 'up'
2468
2249
  ? elementIndex >= 0
2469
2250
  : elementIndex < $selectableItem.length;
2470
- $nextSelectedItem = isWithinRange
2251
+ const $nextSelectedItem = isWithinRange
2471
2252
  ? $selectableItem.eq(elementIndex)
2472
2253
  : (direction === 'up'
2473
2254
  ? $selectableItem.first()
@@ -2475,33 +2256,28 @@
2475
2256
  if ($nextSelectedItem.length > 0) {
2476
2257
  module.debug('Scrolling page', direction, $nextSelectedItem);
2477
2258
  $currentItem
2478
- .removeClass(className.selected)
2479
- ;
2259
+ .removeClass(className.selected);
2480
2260
  $nextSelectedItem
2481
- .addClass(className.selected)
2482
- ;
2261
+ .addClass(className.selected);
2483
2262
  if (settings.selectOnKeydown && module.is.single() && !$nextSelectedItem.hasClass(className.actionable)) {
2484
2263
  module.set.selectedItem($nextSelectedItem);
2485
2264
  }
2486
2265
  $menu
2487
- .scrollTop(newScroll)
2488
- ;
2266
+ .scrollTop(newScroll);
2489
2267
  }
2490
2268
  },
2491
2269
 
2492
2270
  set: {
2493
2271
  filtered: function () {
2494
- var
2495
- isMultiple = module.is.multiple(),
2496
- isSearch = module.is.searchSelection(),
2497
- isSearchMultiple = isMultiple && isSearch,
2498
- searchValue = isSearch
2499
- ? module.get.query()
2500
- : '',
2501
- hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0,
2502
- searchWidth = module.get.searchWidth(),
2503
- valueIsSet = searchValue !== ''
2504
- ;
2272
+ const isMultiple = module.is.multiple();
2273
+ const isSearch = module.is.searchSelection();
2274
+ const isSearchMultiple = isMultiple && isSearch;
2275
+ const searchValue = isSearch
2276
+ ? module.get.query()
2277
+ : '';
2278
+ const hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0;
2279
+ const searchWidth = module.get.searchWidth();
2280
+ const valueIsSet = searchValue !== '';
2505
2281
  if (isMultiple && hasSearchValue) {
2506
2282
  module.verbose('Adjusting input width', searchWidth);
2507
2283
  $search.css('width', searchWidth + 'px');
@@ -2520,8 +2296,7 @@
2520
2296
  loading: function () {
2521
2297
  $module.addClass(className.loading);
2522
2298
  },
2523
- placeholderText: function (text) {
2524
- text = text || module.get.placeholderText();
2299
+ placeholderText: function (text = module.get.placeholderText()) {
2525
2300
  module.debug('Setting placeholder text', text);
2526
2301
  module.set.text(text);
2527
2302
  $text.addClass(className.placeholder);
@@ -2530,21 +2305,17 @@
2530
2305
  if (module.is.searchSelection()) {
2531
2306
  module.debug('Added tabindex to searchable dropdown');
2532
2307
  $search
2533
- .val('')
2534
- ;
2308
+ .val('');
2535
2309
  module.check.disabled();
2536
2310
  $menu
2537
- .attr('tabindex', -1)
2538
- ;
2311
+ .attr('tabindex', -1);
2539
2312
  } else {
2540
2313
  module.debug('Added tabindex to dropdown');
2541
2314
  if ($module.attr('tabindex') === undefined) {
2542
2315
  $module
2543
- .attr('tabindex', $input.attr('tabindex') || 0)
2544
- ;
2316
+ .attr('tabindex', $input.attr('tabindex') || 0);
2545
2317
  $menu
2546
- .attr('tabindex', -1)
2547
- ;
2318
+ .attr('tabindex', -1);
2548
2319
  }
2549
2320
  }
2550
2321
  $input.removeAttr('tabindex');
@@ -2561,31 +2332,22 @@
2561
2332
  }
2562
2333
  },
2563
2334
  partialSearch: function (text) {
2564
- var
2565
- length = module.get.query().length
2566
- ;
2335
+ const length = module.get.query().length;
2567
2336
  $search.val(text.slice(0, length));
2568
2337
  },
2569
- scrollPosition: function ($item, forceScroll) {
2570
- var
2571
- edgeTolerance = 5,
2572
- $menu,
2573
- hasActive,
2574
- offset,
2575
- itemOffset,
2576
- menuOffset,
2577
- menuScroll,
2578
- menuHeight,
2579
- abovePage,
2580
- belowPage
2581
- ;
2338
+ scrollPosition: function ($item, forceScroll = false) {
2339
+ const edgeTolerance = 5;
2340
+ let offset;
2341
+ let itemOffset;
2342
+ let menuOffset;
2343
+ let menuScroll;
2344
+ let menuHeight;
2345
+ let abovePage;
2346
+ let belowPage;
2582
2347
 
2583
2348
  $item = $item || module.get.selectedItem();
2584
- $menu = $item.closest(selector.menu);
2585
- hasActive = $item && $item.length > 0;
2586
- forceScroll = forceScroll !== undefined
2587
- ? forceScroll
2588
- : false;
2349
+ const $menu = $item.closest(selector.menu);
2350
+ const hasActive = $item && $item.length > 0;
2589
2351
  if (module.get.activeItem().length === 0) {
2590
2352
  forceScroll = false;
2591
2353
  }
@@ -2623,8 +2385,7 @@
2623
2385
  }
2624
2386
  module.debug('Changing text', text, $text);
2625
2387
  $text
2626
- .removeClass(className.filtered)
2627
- ;
2388
+ .removeClass(className.filtered);
2628
2389
  if (settings.preserveHTML) {
2629
2390
  $text.html(text);
2630
2391
  } else {
@@ -2633,11 +2394,9 @@
2633
2394
  }
2634
2395
  },
2635
2396
  selectedItem: function ($item) {
2636
- var
2637
- value = module.get.choiceValue($item),
2638
- searchText = module.get.choiceText($item, false),
2639
- text = module.get.choiceText($item)
2640
- ;
2397
+ const value = module.get.choiceValue($item);
2398
+ const searchText = module.get.choiceText($item, false);
2399
+ const text = module.get.choiceText($item);
2641
2400
  module.debug('Setting user selection to item', $item);
2642
2401
  module.remove.activeItem();
2643
2402
  module.set.partialSearch(searchText);
@@ -2646,12 +2405,10 @@
2646
2405
  module.set.text(text);
2647
2406
  },
2648
2407
  selectedLetter: function (letter) {
2649
- var
2650
- $selectedItem = $item.filter('.' + className.selected),
2651
- alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
2652
- $nextValue = false,
2653
- $nextItem
2654
- ;
2408
+ const $selectedItem = $item.filter('.' + className.selected);
2409
+ const alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter);
2410
+ let $nextValue = false;
2411
+ let $nextItem;
2655
2412
  // check next of the same letter
2656
2413
  if (alreadySelectedLetter) {
2657
2414
  $nextItem = $selectedItem.nextAll($item).eq(0);
@@ -2668,8 +2425,7 @@
2668
2425
 
2669
2426
  return false;
2670
2427
  }
2671
- })
2672
- ;
2428
+ });
2673
2429
  }
2674
2430
  // set the next value
2675
2431
  if ($nextValue) {
@@ -2705,11 +2461,11 @@
2705
2461
  }
2706
2462
  },
2707
2463
  upward: function ($currentMenu) {
2708
- var $element = $currentMenu || $module;
2464
+ const $element = $currentMenu || $module;
2709
2465
  $element.addClass(className.upward);
2710
2466
  },
2711
2467
  leftward: function ($currentMenu) {
2712
- var $element = $currentMenu || $menu;
2468
+ const $element = $currentMenu || $menu;
2713
2469
  $element.addClass(className.leftward);
2714
2470
  },
2715
2471
  value: function (value, text, $selected, preventChangeTrigger) {
@@ -2723,14 +2479,11 @@
2723
2479
  } else {
2724
2480
  $input.addClass(className.noselection);
2725
2481
  }
2726
- var
2727
- escapedValue = module.escape.value(value),
2728
- hasInput = $input.length > 0,
2729
- currentValue = module.get.values(),
2730
- stringValue = value !== undefined
2731
- ? String(value)
2732
- : value
2733
- ;
2482
+ const hasInput = $input.length > 0;
2483
+ const currentValue = module.get.values();
2484
+ const stringValue = value !== undefined
2485
+ ? String(value)
2486
+ : value;
2734
2487
  if (hasInput) {
2735
2488
  if (!settings.allowReselection && stringValue == currentValue) {
2736
2489
  module.verbose('Skipping value update already same value', value, currentValue);
@@ -2743,11 +2496,10 @@
2743
2496
  module.debug('Adding user option', value);
2744
2497
  module.add.optionValue(value);
2745
2498
  }
2746
- module.debug('Updating input value', escapedValue, currentValue);
2499
+ module.debug('Updating input value', value, currentValue);
2747
2500
  internalChange = true;
2748
2501
  $input
2749
- .val(escapedValue)
2750
- ;
2502
+ .val(value);
2751
2503
  if (settings.fireOnInit === false && module.is.initialLoad()) {
2752
2504
  module.debug('Input native change event ignored on initial load');
2753
2505
  } else if (preventChangeTrigger !== true) {
@@ -2755,8 +2507,8 @@
2755
2507
  }
2756
2508
  internalChange = false;
2757
2509
  } else {
2758
- module.verbose('Storing value in metadata', escapedValue, $input);
2759
- if (escapedValue !== currentValue) {
2510
+ module.verbose('Storing value in metadata', value, $input);
2511
+ if (value !== currentValue) {
2760
2512
  $module.data(metadata.value, stringValue);
2761
2513
  }
2762
2514
  }
@@ -2768,8 +2520,7 @@
2768
2520
  },
2769
2521
  active: function () {
2770
2522
  $module
2771
- .addClass(className.active)
2772
- ;
2523
+ .addClass(className.active);
2773
2524
  },
2774
2525
  multiple: function () {
2775
2526
  $module.addClass(className.multiple);
@@ -2792,9 +2543,7 @@
2792
2543
  preventChangeTrigger = $selectedItem;
2793
2544
  $selectedItem = undefined;
2794
2545
  }
2795
- var
2796
- isMultiple = module.is.multiple()
2797
- ;
2546
+ const isMultiple = module.is.multiple();
2798
2547
  $selectedItem = settings.allowAdditions
2799
2548
  ? $selectedItem || module.get.itemWithAdditions(value)
2800
2549
  : $selectedItem || module.get.item(value);
@@ -2808,7 +2557,11 @@
2808
2557
  if (settings.useLabels) {
2809
2558
  module.remove.selectedItem();
2810
2559
  if (value === undefined) {
2811
- module.remove.labels($module.find(selector.label), true);
2560
+ const existingLabels = $module.find(selector.label);
2561
+ if (existingLabels.length > 0) {
2562
+ preventChangeTrigger = true;
2563
+ module.remove.labels(existingLabels, true);
2564
+ }
2812
2565
  }
2813
2566
  }
2814
2567
  } else {
@@ -2822,17 +2575,15 @@
2822
2575
  // select each item
2823
2576
  $selectedItem
2824
2577
  .each(function () {
2825
- var
2826
- $selected = $(this),
2827
- selectedText = module.get.choiceText($selected),
2828
- selectedValue = module.get.choiceValue($selected, selectedText),
2829
-
2830
- isFiltered = $selected.hasClass(className.filtered),
2831
- isActive = $selected.hasClass(className.active),
2832
- isActionable = $selected.hasClass(className.actionable),
2833
- isUserValue = $selected.hasClass(className.addition),
2834
- shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1
2835
- ;
2578
+ const $selected = $(this);
2579
+ const selectedText = module.get.choiceText($selected);
2580
+ const selectedValue = module.get.choiceValue($selected, selectedText);
2581
+
2582
+ const isFiltered = $selected.hasClass(className.filtered);
2583
+ const isActive = $selected.hasClass(className.active);
2584
+ const isActionable = $selected.hasClass(className.actionable);
2585
+ const isUserValue = $selected.hasClass(className.addition);
2586
+ const shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1;
2836
2587
  if (isActionable) {
2837
2588
  if ((!isMultiple || (!isActive || isUserValue)) && settings.apiSettings && settings.saveRemoteData) {
2838
2589
  module.save.remoteData(selectedText, selectedValue);
@@ -2868,11 +2619,9 @@
2868
2619
  module.set.value(selectedValue, selectedText, $selected, preventChangeTrigger);
2869
2620
  $selected
2870
2621
  .addClass(className.active)
2871
- .addClass(className.selected)
2872
- ;
2622
+ .addClass(className.selected);
2873
2623
  }
2874
- })
2875
- ;
2624
+ });
2876
2625
  if (!keepSearchTerm) {
2877
2626
  module.remove.searchTerm();
2878
2627
  }
@@ -2885,25 +2634,21 @@
2885
2634
 
2886
2635
  add: {
2887
2636
  label: function (value, text, shouldAnimate) {
2888
- var
2889
- $next = module.is.searchSelection()
2890
- ? $search
2891
- : $text,
2892
- escapedValue = module.escape.value(value),
2893
- $label
2894
- ;
2637
+ const $next = module.is.searchSelection()
2638
+ ? $search
2639
+ : $text;
2640
+ let $label;
2895
2641
  if (settings.ignoreCase) {
2896
- escapedValue = escapedValue.toLowerCase();
2642
+ value = value.toLowerCase();
2897
2643
  }
2898
2644
  $label = $('<a />')
2899
2645
  .addClass(className.label)
2900
- .attr('data-' + metadata.value, escapedValue)
2901
- .html(templates.label(escapedValue, text, settings))
2902
- ;
2903
- $label = settings.onLabelCreate.call($label, escapedValue, text);
2646
+ .attr('data-' + metadata.value, value)
2647
+ .html(templates.label(value, text, settings));
2648
+ $label = settings.onLabelCreate.call($label, value, text);
2904
2649
 
2905
2650
  if (module.has.label(value)) {
2906
- module.debug('User selection already exists, skipping', escapedValue);
2651
+ module.debug('User selection already exists, skipping', value);
2907
2652
 
2908
2653
  return;
2909
2654
  }
@@ -2921,38 +2666,29 @@
2921
2666
  verbose: settings.verbose,
2922
2667
  silent: settings.silent,
2923
2668
  duration: settings.label.duration,
2924
- })
2925
- ;
2669
+ });
2926
2670
  } else {
2927
2671
  module.debug('Adding selection label', $label);
2928
2672
  $label
2929
- .insertBefore($next)
2930
- ;
2673
+ .insertBefore($next);
2931
2674
  }
2932
2675
  },
2933
2676
  message: function (message) {
2934
- var
2935
- $message = $menu.children(selector.message),
2936
- html = settings.templates.message(module.add.variables(message))
2937
- ;
2677
+ const $message = $menu.children(selector.message);
2678
+ const html = settings.templates.message(module.add.variables(message));
2938
2679
  if ($message.length > 0) {
2939
2680
  $message
2940
- .html(html)
2941
- ;
2681
+ .html(html);
2942
2682
  } else {
2943
2683
  $('<div/>')
2944
2684
  .html(html)
2945
2685
  .addClass(className.message)
2946
- .appendTo($menu)
2947
- ;
2686
+ .appendTo($menu);
2948
2687
  }
2949
2688
  },
2950
2689
  optionValue: function (value) {
2951
- var
2952
- escapedValue = module.escape.value(value),
2953
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
2954
- hasOption = $option.length > 0
2955
- ;
2690
+ const $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2691
+ const hasOption = $option.length > 0;
2956
2692
  if (hasOption) {
2957
2693
  return;
2958
2694
  }
@@ -2963,22 +2699,19 @@
2963
2699
  $input.find('option.' + className.addition).remove();
2964
2700
  }
2965
2701
  $('<option/>')
2966
- .prop('value', escapedValue)
2702
+ .prop('value', value)
2967
2703
  .addClass(className.addition)
2968
2704
  .text(value)
2969
- .appendTo($input)
2970
- ;
2705
+ .appendTo($input);
2971
2706
  module.verbose('Adding user addition as an <option>', value);
2972
2707
  module.observe.select();
2973
2708
  },
2974
2709
  userSuggestion: function (value) {
2975
- var
2976
- $addition = $menu.children(selector.addition),
2977
- $existingItem = module.get.item(value),
2978
- alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0,
2979
- hasUserSuggestion = $addition.length > 0,
2980
- html
2981
- ;
2710
+ let $addition = $menu.children(selector.addition);
2711
+ const $existingItem = module.get.item(value);
2712
+ const alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0;
2713
+ const hasUserSuggestion = $addition.length > 0;
2714
+ let html;
2982
2715
  if (settings.useLabels && module.has.maxSelections()) {
2983
2716
  return;
2984
2717
  }
@@ -2993,38 +2726,31 @@
2993
2726
  .data(metadata.text, value)
2994
2727
  .attr('data-' + metadata.value, value)
2995
2728
  .attr('data-' + metadata.text, value)
2996
- .removeClass(className.filtered)
2997
- ;
2729
+ .removeClass(className.filtered);
2998
2730
  if (!settings.hideAdditions) {
2999
- html = settings.templates.addition(module.add.variables(message.addResult, value));
2731
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
3000
2732
  $addition
3001
- .html(html)
3002
- ;
2733
+ .html(html);
3003
2734
  }
3004
2735
  module.verbose('Replacing user suggestion with new value', $addition);
3005
2736
  } else {
3006
2737
  $addition = module.create.userChoice(value);
3007
2738
  $addition
3008
- .prependTo($menu)
3009
- ;
2739
+ .prependTo($menu);
3010
2740
  module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
3011
2741
  }
3012
2742
  if (!settings.hideAdditions || module.is.allFiltered()) {
3013
2743
  $addition
3014
2744
  .addClass(className.selected)
3015
2745
  .siblings()
3016
- .removeClass(className.selected)
3017
- ;
2746
+ .removeClass(className.selected);
3018
2747
  }
3019
2748
  module.refreshItems();
3020
2749
  },
3021
- variables: function (message, term) {
3022
- var
3023
- hasCount = message.search('{count}') !== -1,
3024
- hasMaxCount = message.search('{maxCount}') !== -1,
3025
- hasTerm = message.search('{term}') !== -1,
3026
- query
3027
- ;
2750
+ variables: function (message = '', term = module.get.query()) {
2751
+ const hasCount = message.search('{count}') !== -1;
2752
+ const hasMaxCount = message.search('{maxCount}') !== -1;
2753
+ const hasTerm = message.search('{term}') !== -1;
3028
2754
  module.verbose('Adding templated variables to message', message);
3029
2755
  if (hasCount) {
3030
2756
  message = message.replace('{count}', module.get.selectionCount());
@@ -3033,8 +2759,7 @@
3033
2759
  message = message.replace('{maxCount}', settings.maxSelections);
3034
2760
  }
3035
2761
  if (hasTerm) {
3036
- query = term || module.get.query();
3037
- message = message.replace('{term}', query);
2762
+ message = message.replace('{term}', term);
3038
2763
  }
3039
2764
 
3040
2765
  return message;
@@ -3045,10 +2770,8 @@
3045
2770
  $selectedItem = undefined;
3046
2771
  addedText = undefined;
3047
2772
  }
3048
- var
3049
- currentValue = module.get.values(true),
3050
- newValue
3051
- ;
2773
+ const currentValue = module.get.values();
2774
+ let newValue;
3052
2775
  if (module.has.value(addedValue)) {
3053
2776
  module.debug('Value already selected');
3054
2777
 
@@ -3061,7 +2784,9 @@
3061
2784
  }
3062
2785
  // extend current array
3063
2786
  if (Array.isArray(currentValue)) {
3064
- newValue = $selectedItem && $selectedItem.hasClass(className.actionable) ? currentValue : currentValue.concat([addedValue]);
2787
+ newValue = $selectedItem && $selectedItem.hasClass(className.actionable)
2788
+ ? currentValue
2789
+ : [...currentValue, addedValue];
3065
2790
  newValue = module.get.uniqueArray(newValue);
3066
2791
  } else {
3067
2792
  newValue = [addedValue];
@@ -3104,11 +2829,11 @@
3104
2829
  initialLoad = false;
3105
2830
  },
3106
2831
  upward: function ($currentMenu) {
3107
- var $element = $currentMenu || $module;
2832
+ const $element = $currentMenu || $module;
3108
2833
  $element.removeClass(className.upward);
3109
2834
  },
3110
2835
  leftward: function ($currentMenu) {
3111
- var $element = $currentMenu || $menu;
2836
+ const $element = $currentMenu || $menu;
3112
2837
  $element.removeClass(className.leftward);
3113
2838
  },
3114
2839
  visible: function () {
@@ -3120,7 +2845,7 @@
3120
2845
  filteredItem: function () {
3121
2846
  if (settings.highlightMatches) {
3122
2847
  $.each($item, function (index, item) {
3123
- var $markItem = $(item);
2848
+ const $markItem = $(item);
3124
2849
  $markItem.html($markItem.html().replace(/<\/?mark>/g, ''));
3125
2850
  });
3126
2851
  }
@@ -3138,18 +2863,15 @@
3138
2863
  module.remove.empty();
3139
2864
  },
3140
2865
  optionValue: function (value) {
3141
- var
3142
- escapedValue = module.escape.value(value),
3143
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
3144
- hasOption = $option.length > 0
3145
- ;
2866
+ const $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2867
+ const hasOption = $option.length > 0;
3146
2868
  if (!hasOption || !$option.hasClass(className.addition)) {
3147
2869
  return;
3148
2870
  }
3149
2871
  // temporarily disconnect observer
3150
2872
  module.disconnect.selectObserver();
3151
2873
  $option.remove();
3152
- module.verbose('Removing user addition as an <option>', escapedValue);
2874
+ module.verbose('Removing user addition as an <option>', value);
3153
2875
  module.observe.select();
3154
2876
  },
3155
2877
  message: function () {
@@ -3177,11 +2899,9 @@
3177
2899
 
3178
2900
  $selectedItem
3179
2901
  .each(function () {
3180
- var
3181
- $selected = $(this),
3182
- selectedText = module.get.choiceText($selected),
3183
- selectedValue = module.get.choiceValue($selected, selectedText)
3184
- ;
2902
+ const $selected = $(this);
2903
+ const selectedText = module.get.choiceText($selected);
2904
+ const selectedValue = module.get.choiceValue($selected, selectedText);
3185
2905
  if (module.is.multiple()) {
3186
2906
  if (settings.useLabels) {
3187
2907
  module.remove.value(selectedValue, selectedText, $selected, preventChangeTrigger);
@@ -3199,22 +2919,18 @@
3199
2919
  }
3200
2920
  $selected
3201
2921
  .removeClass(className.filtered)
3202
- .removeClass(className.active)
3203
- ;
2922
+ .removeClass(className.active);
3204
2923
  if (settings.useLabels) {
3205
2924
  $selected.removeClass(className.selected);
3206
2925
  }
3207
- })
3208
- ;
2926
+ });
3209
2927
  },
3210
2928
  selectedItem: function () {
3211
2929
  $item.removeClass(className.selected);
3212
2930
  },
3213
2931
  value: function (removedValue, removedText, $removedItem, preventChangeTrigger) {
3214
- var
3215
- values = module.get.values(true),
3216
- newValue
3217
- ;
2932
+ const values = module.get.values();
2933
+ let newValue;
3218
2934
  if (module.has.selectInput()) {
3219
2935
  module.verbose('Input is <select> removing selected option', removedValue);
3220
2936
  newValue = module.remove.arrayValue(removedValue, values);
@@ -3244,11 +2960,8 @@
3244
2960
  return values;
3245
2961
  },
3246
2962
  label: function (value, shouldAnimate) {
3247
- var
3248
- escapedValue = module.escape.value(value),
3249
- $labels = $module.find(selector.label),
3250
- $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(settings.ignoreCase ? escapedValue.toLowerCase() : escapedValue) + '"]')
3251
- ;
2963
+ const $labels = $module.find(selector.label);
2964
+ const $removedLabel = $labels.filter('[data-' + metadata.value + '="' + CSS.escape(settings.ignoreCase ? value.toLowerCase() : value) + '"]');
3252
2965
  module.verbose('Removing label', $removedLabel);
3253
2966
  $removedLabel.remove();
3254
2967
  },
@@ -3262,14 +2975,12 @@
3262
2975
  module.verbose('Removing labels', $labels);
3263
2976
  $labels
3264
2977
  .each(function () {
3265
- var
3266
- $label = $(this),
3267
- value = $label.data(metadata.value),
3268
- stringValue = value !== undefined
3269
- ? String(value)
3270
- : value,
3271
- isUserValue = module.is.userValue(stringValue)
3272
- ;
2978
+ const $label = $(this);
2979
+ const value = $label.data(metadata.value);
2980
+ const stringValue = value !== undefined
2981
+ ? String(value)
2982
+ : value;
2983
+ const isUserValue = module.is.userValue(stringValue);
3273
2984
  if (settings.onLabelRemove.call($label, value) === false) {
3274
2985
  module.debug('Label remove callback cancelled removal');
3275
2986
 
@@ -3283,26 +2994,21 @@
3283
2994
  // selected will also remove label
3284
2995
  module.remove.selected(stringValue, false, preventChangeTrigger);
3285
2996
  }
3286
- })
3287
- ;
2997
+ });
3288
2998
  },
3289
2999
  tabbable: function () {
3290
3000
  if (module.is.searchSelection()) {
3291
3001
  module.debug('Searchable dropdown initialized');
3292
3002
  $search
3293
- .removeAttr('tabindex')
3294
- ;
3003
+ .removeAttr('tabindex');
3295
3004
  $menu
3296
- .removeAttr('tabindex')
3297
- ;
3005
+ .removeAttr('tabindex');
3298
3006
  } else {
3299
3007
  module.debug('Simple selection dropdown initialized');
3300
3008
  $module
3301
- .removeAttr('tabindex')
3302
- ;
3009
+ .removeAttr('tabindex');
3303
3010
  $menu
3304
- .removeAttr('tabindex')
3305
- ;
3011
+ .removeAttr('tabindex');
3306
3012
  }
3307
3013
  },
3308
3014
  diacritics: function (text) {
@@ -3326,29 +3032,21 @@
3326
3032
  selectInput: function () {
3327
3033
  return $input.is('select');
3328
3034
  },
3329
- minCharacters: function (searchTerm) {
3035
+ minCharacters: function (searchTerm = module.get.query()) {
3330
3036
  if (settings.minCharacters && !iconClicked) {
3331
- searchTerm = searchTerm !== undefined
3332
- ? String(searchTerm)
3333
- : String(module.get.query());
3334
-
3335
- return searchTerm.length >= settings.minCharacters;
3037
+ return String(searchTerm).length >= settings.minCharacters;
3336
3038
  }
3337
3039
  iconClicked = false;
3338
3040
 
3339
3041
  return true;
3340
3042
  },
3341
3043
  firstLetter: function ($item, letter) {
3342
- var
3343
- text,
3344
- firstLetter
3345
- ;
3346
3044
  if (!$item || $item.length === 0 || typeof letter !== 'string') {
3347
3045
  return false;
3348
3046
  }
3349
- text = module.get.choiceText($item, false);
3047
+ const text = module.get.choiceText($item, false);
3350
3048
  letter = letter.toLowerCase();
3351
- firstLetter = String(text).charAt(0).toLowerCase();
3049
+ const firstLetter = String(text).charAt(0).toLowerCase();
3352
3050
 
3353
3051
  return letter == firstLetter;
3354
3052
  },
@@ -3368,23 +3066,18 @@
3368
3066
  return $menu.children(selector.message).length > 0;
3369
3067
  },
3370
3068
  label: function (value) {
3371
- var
3372
- escapedValue = module.escape.value(value),
3373
- $labels = $module.find(selector.label)
3374
- ;
3069
+ const $labels = $module.find(selector.label);
3375
3070
  if (settings.ignoreCase) {
3376
- escapedValue = escapedValue.toLowerCase();
3071
+ value = value.toLowerCase();
3377
3072
  }
3378
3073
 
3379
- return $labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) + '"]').length > 0;
3074
+ return $labels.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]').length > 0;
3380
3075
  },
3381
3076
  maxSelections: function () {
3382
3077
  return settings.maxSelections && module.get.selectionCount() >= settings.maxSelections;
3383
3078
  },
3384
3079
  allResultsFiltered: function () {
3385
- var
3386
- $normalResults = $item.not(selector.addition)
3387
- ;
3080
+ const $normalResults = $item.not(selector.addition);
3388
3081
 
3389
3082
  return $normalResults.filter(selector.unselectable).length === $normalResults.length;
3390
3083
  },
@@ -3400,20 +3093,16 @@
3400
3093
  : module.has.valueMatchingCase(value);
3401
3094
  },
3402
3095
  valueMatchingCase: function (value) {
3403
- var
3404
- values = module.get.values(true),
3405
- hasValue = Array.isArray(values)
3406
- ? values && ($.inArray(value, values) !== -1)
3407
- : values == value
3408
- ;
3096
+ const values = module.get.values();
3097
+ const hasValue = Array.isArray(values)
3098
+ ? values && values.includes(value)
3099
+ : values == value;
3409
3100
 
3410
3101
  return !!hasValue;
3411
3102
  },
3412
3103
  valueIgnoringCase: function (value) {
3413
- var
3414
- values = module.get.values(true),
3415
- hasValue = false
3416
- ;
3104
+ let values = module.get.values();
3105
+ let hasValue = false;
3417
3106
  if (!Array.isArray(values)) {
3418
3107
  values = [values];
3419
3108
  }
@@ -3460,12 +3149,12 @@
3460
3149
  : $menu.transition && $menu.transition('is animating');
3461
3150
  },
3462
3151
  leftward: function ($subMenu) {
3463
- var $selectedMenu = $subMenu || $menu;
3152
+ const $selectedMenu = $subMenu || $menu;
3464
3153
 
3465
3154
  return $selectedMenu.hasClass(className.leftward);
3466
3155
  },
3467
3156
  clearable: function () {
3468
- var hasClearableClass = $module.hasClass(className.clearable);
3157
+ const hasClearableClass = $module.hasClass(className.clearable);
3469
3158
  if (!hasClearableClass && settings.clearable) {
3470
3159
  $module.addClass(className.clearable);
3471
3160
  }
@@ -3491,9 +3180,7 @@
3491
3180
  return initialLoad;
3492
3181
  },
3493
3182
  inObject: function (needle, object) {
3494
- var
3495
- found = false
3496
- ;
3183
+ let found = false;
3497
3184
  $.each(object, function (index, property) {
3498
3185
  if (property == needle) {
3499
3186
  found = true;
@@ -3517,9 +3204,7 @@
3517
3204
  return !module.is.multiple();
3518
3205
  },
3519
3206
  selectMutation: function (mutations) {
3520
- var
3521
- selectChanged = false
3522
- ;
3207
+ let selectChanged = false;
3523
3208
  $.each(mutations, function (index, mutation) {
3524
3209
  if ($(mutation.target).is('option, optgroup') || $(mutation.addedNodes).is('select') || ($(mutation.target).is('select') && mutation.type !== 'attributes')) {
3525
3210
  selectChanged = true;
@@ -3540,10 +3225,10 @@
3540
3225
  return $module.hasClass(className.selection);
3541
3226
  },
3542
3227
  userValue: function (value) {
3543
- return $.inArray(value, module.get.userValues()) !== -1;
3228
+ return (module.get.userValues() || []).includes(value);
3544
3229
  },
3545
3230
  upward: function ($menu) {
3546
- var $element = $menu || $module;
3231
+ const $element = $menu || $module;
3547
3232
 
3548
3233
  return $element.hasClass(className.upward);
3549
3234
  },
@@ -3553,20 +3238,16 @@
3553
3238
  : $menu.hasClass(className.visible);
3554
3239
  },
3555
3240
  verticallyScrollableContext: function () {
3556
- var
3557
- overflowY = $context[0] !== window
3558
- ? $context.css('overflow-y')
3559
- : false
3560
- ;
3241
+ const overflowY = $context[0] !== window
3242
+ ? $context.css('overflow-y')
3243
+ : false;
3561
3244
 
3562
3245
  return overflowY === 'auto' || overflowY === 'scroll';
3563
3246
  },
3564
3247
  horizontallyScrollableContext: function () {
3565
- var
3566
- overflowX = $context[0] !== window
3567
- ? $context.css('overflow-X')
3568
- : false
3569
- ;
3248
+ const overflowX = $context[0] !== window
3249
+ ? $context.css('overflow-X')
3250
+ : false;
3570
3251
 
3571
3252
  return overflowX === 'auto' || overflowX === 'scroll';
3572
3253
  },
@@ -3581,16 +3262,11 @@
3581
3262
  );
3582
3263
  },
3583
3264
  openDownward: function ($subMenu) {
3584
- var
3585
- $currentMenu = $subMenu || $menu,
3586
- canOpenDownward,
3587
- onScreen,
3588
- calculations
3589
- ;
3265
+ const $currentMenu = $subMenu || $menu;
3266
+ let canOpenDownward;
3590
3267
  $currentMenu
3591
- .addClass(className.loading)
3592
- ;
3593
- calculations = {
3268
+ .addClass(className.loading);
3269
+ const calculations = {
3594
3270
  context: {
3595
3271
  offset: $context[0] === window
3596
3272
  ? { top: 0, left: 0 }
@@ -3609,7 +3285,7 @@
3609
3285
  if (module.has.subMenu($currentMenu)) {
3610
3286
  calculations.menu.height += $currentMenu.find(selector.menu).first().outerHeight();
3611
3287
  }
3612
- onScreen = {
3288
+ const onScreen = {
3613
3289
  above: calculations.context.scrollTop <= calculations.menu.offset.top - calculations.context.offset.top - calculations.menu.height,
3614
3290
  below: (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top - calculations.context.offset.top + calculations.menu.height,
3615
3291
  };
@@ -3628,16 +3304,12 @@
3628
3304
  return canOpenDownward;
3629
3305
  },
3630
3306
  openRightward: function ($subMenu) {
3631
- var
3632
- $currentMenu = $subMenu || $menu,
3633
- canOpenRightward = true,
3634
- isOffscreenRight = false,
3635
- calculations
3636
- ;
3307
+ const $currentMenu = $subMenu || $menu;
3308
+ let canOpenRightward = true;
3309
+ let isOffscreenRight = false;
3637
3310
  $currentMenu
3638
- .addClass(className.loading)
3639
- ;
3640
- calculations = {
3311
+ .addClass(className.loading);
3312
+ const calculations = {
3641
3313
  context: {
3642
3314
  offset: $context[0] === window
3643
3315
  ? { top: 0, left: 0 }
@@ -3683,23 +3355,20 @@
3683
3355
 
3684
3356
  animate: {
3685
3357
  show: function (callback, $subMenu) {
3686
- var
3687
- $currentMenu = $subMenu || $menu,
3688
- start = $subMenu
3689
- ? function () {}
3690
- : function () {
3691
- module.hideSubMenus();
3692
- module.hideOthers();
3693
- module.set.active();
3694
- },
3695
- transition
3696
- ;
3358
+ const $currentMenu = $subMenu || $menu;
3359
+ const start = $subMenu
3360
+ ? function () {}
3361
+ : function () {
3362
+ module.hideSubMenus();
3363
+ module.hideOthers();
3364
+ module.set.active();
3365
+ };
3697
3366
  callback = isFunction(callback)
3698
3367
  ? callback
3699
3368
  : function () {};
3700
3369
  module.verbose('Doing menu show animation', $currentMenu);
3701
3370
  module.set.direction($subMenu);
3702
- transition = settings.transition.showMethod || module.get.transition($subMenu);
3371
+ const transition = settings.transition.showMethod || module.get.transition($subMenu);
3703
3372
  if (module.is.selection()) {
3704
3373
  module.set.scrollPosition(module.get.selectedItem(), true);
3705
3374
  }
@@ -3724,22 +3393,19 @@
3724
3393
  onComplete: function () {
3725
3394
  callback.call(element);
3726
3395
  },
3727
- })
3728
- ;
3396
+ });
3729
3397
  }
3730
3398
  }
3731
3399
  },
3732
3400
  hide: function (callback, $subMenu) {
3733
- var
3734
- $currentMenu = $subMenu || $menu,
3735
- start = $subMenu
3736
- ? function () {}
3737
- : function () {
3738
- module.unbind.intent();
3739
- module.remove.active();
3740
- },
3741
- transition = settings.transition.hideMethod || module.get.transition($subMenu)
3742
- ;
3401
+ const $currentMenu = $subMenu || $menu;
3402
+ const start = $subMenu
3403
+ ? function () {}
3404
+ : function () {
3405
+ module.unbind.intent();
3406
+ module.remove.active();
3407
+ };
3408
+ const transition = settings.transition.hideMethod || module.get.transition($subMenu);
3743
3409
  callback = isFunction(callback)
3744
3410
  ? callback
3745
3411
  : function () {};
@@ -3766,8 +3432,7 @@
3766
3432
  onComplete: function () {
3767
3433
  callback.call(element);
3768
3434
  },
3769
- })
3770
- ;
3435
+ });
3771
3436
  } else {
3772
3437
  module.error(error.transition);
3773
3438
  }
@@ -3807,48 +3472,26 @@
3807
3472
  },
3808
3473
 
3809
3474
  escape: {
3810
- value: function (value) {
3811
- var
3812
- multipleValues = Array.isArray(value),
3813
- stringValue = typeof value === 'string',
3814
- isUnparsable = !stringValue && !multipleValues,
3815
- hasQuotes = stringValue && value.search(regExp.quote) !== -1,
3816
- values = []
3817
- ;
3818
- if (isUnparsable || !hasQuotes) {
3819
- return value;
3820
- }
3821
- module.debug('Encoding quote values for use in select', value);
3822
- if (multipleValues) {
3823
- $.each(value, function (index, value) {
3824
- values.push(value.replace(regExp.quote, '&quot;'));
3825
- });
3826
-
3827
- return values;
3828
- }
3829
-
3830
- return value.replace(regExp.quote, '&quot;');
3831
- },
3832
3475
  string: function (text) {
3833
3476
  text = String(text);
3834
3477
 
3835
3478
  return text.replace(regExp.escape, '\\$&');
3836
3479
  },
3837
- htmlEntities: function (string, forceAmpersand) {
3838
- forceAmpersand = typeof forceAmpersand === 'number' ? false : forceAmpersand;
3839
-
3840
- const badChars = forceAmpersand
3841
- ? /["&'<>]/g
3842
- : /["'<>]|&(?![\d#A-Za-z]{1,12};)/g;
3843
- const escape = {
3844
- '"': '&quot;',
3845
- '&': '&amp;',
3846
- "'": '&apos;',
3847
- '<': '&lt;',
3848
- '>': '&gt;',
3480
+
3481
+ // https://github.com/fomantic/Fomantic-UI/issues/2782
3482
+ // https://jsfiddle.net/3efL7jnt/
3483
+ assumeUnescapedAmpLtGt: function (string) {
3484
+ if (settings.preserveHTML) {
3485
+ return string;
3486
+ }
3487
+
3488
+ const unescapeMap = {
3489
+ '&amp;': '&',
3490
+ '&lt;': '<',
3491
+ '&gt;': '>',
3849
3492
  };
3850
3493
 
3851
- return string.replace(badChars, (chr) => escape[chr]);
3494
+ return string.replace(/&(?:amp|lt|gt);/g, (v) => unescapeMap[v]);
3852
3495
  },
3853
3496
  },
3854
3497
 
@@ -3875,39 +3518,37 @@
3875
3518
  return module[name];
3876
3519
  }
3877
3520
  },
3878
- debug: function () {
3521
+ debug: function (...args) {
3879
3522
  if (!settings.silent && settings.debug) {
3880
3523
  if (settings.performance) {
3881
- module.performance.log(arguments);
3524
+ module.performance.log(args);
3882
3525
  } else {
3883
3526
  module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
3884
- module.debug.apply(console, arguments);
3527
+ module.debug.apply(console, args);
3885
3528
  }
3886
3529
  }
3887
3530
  },
3888
- verbose: function () {
3531
+ verbose: function (...args) {
3889
3532
  if (!settings.silent && settings.verbose && settings.debug) {
3890
3533
  if (settings.performance) {
3891
- module.performance.log(arguments);
3534
+ module.performance.log(args);
3892
3535
  } else {
3893
3536
  module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
3894
- module.verbose.apply(console, arguments);
3537
+ module.verbose.apply(console, args);
3895
3538
  }
3896
3539
  }
3897
3540
  },
3898
- error: function () {
3541
+ error: function (...args) {
3899
3542
  if (!settings.silent) {
3900
3543
  module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
3901
- module.error.apply(console, arguments);
3544
+ module.error.apply(console, args);
3902
3545
  }
3903
3546
  },
3904
3547
  performance: {
3905
3548
  log: function (message) {
3906
- var
3907
- currentTime,
3908
- executionTime,
3909
- previousTime
3910
- ;
3549
+ let currentTime;
3550
+ let executionTime;
3551
+ let previousTime;
3911
3552
  if (settings.performance) {
3912
3553
  currentTime = Date.now();
3913
3554
  previousTime = time || currentTime;
@@ -3915,7 +3556,7 @@
3915
3556
  time = currentTime;
3916
3557
  performance.push({
3917
3558
  Name: message[0],
3918
- Arguments: [].slice.call(message, 1) || '',
3559
+ Arguments: message.slice(1),
3919
3560
  Element: element,
3920
3561
  'Execution Time': executionTime,
3921
3562
  });
@@ -3926,10 +3567,8 @@
3926
3567
  }, 500);
3927
3568
  },
3928
3569
  display: function () {
3929
- var
3930
- title = settings.name + ':',
3931
- totalTime = 0
3932
- ;
3570
+ let title = settings.name + ':';
3571
+ let totalTime = 0;
3933
3572
  time = false;
3934
3573
  clearTimeout(module.performance.timer);
3935
3574
  $.each(performance, function (index, data) {
@@ -3938,35 +3577,24 @@
3938
3577
  title += ' ' + totalTime + 'ms';
3939
3578
  if (performance.length > 0) {
3940
3579
  console.groupCollapsed(title);
3941
- if (console.table) {
3942
- console.table(performance);
3943
- } else {
3944
- $.each(performance, function (index, data) {
3945
- console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
3946
- });
3947
- }
3580
+ console.table(performance);
3948
3581
  console.groupEnd();
3949
3582
  }
3950
3583
  performance = [];
3951
3584
  },
3952
3585
  },
3953
- invoke: function (query, passedArguments, context) {
3954
- var
3955
- object = instance,
3956
- maxDepth,
3957
- found,
3958
- response
3959
- ;
3960
- passedArguments = passedArguments || queryArguments;
3961
- context = context || element;
3586
+ invoke: function (query, passedArguments = queryArguments, context = element) {
3587
+ let object = instance;
3588
+ let maxDepth;
3589
+ let found;
3590
+ let response;
3962
3591
  if (typeof query === 'string' && object !== undefined) {
3963
3592
  query = query.split(/[ .]/);
3964
3593
  maxDepth = query.length - 1;
3965
3594
  $.each(query, function (depth, value) {
3966
- var camelCaseValue = depth !== maxDepth
3595
+ const camelCaseValue = depth !== maxDepth
3967
3596
  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3968
- : query
3969
- ;
3597
+ : query;
3970
3598
  if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
3971
3599
  object = object[camelCaseValue];
3972
3600
  } else if (object[camelCaseValue] !== undefined) {
@@ -4007,7 +3635,7 @@
4007
3635
  if (instance === undefined) {
4008
3636
  module.initialize();
4009
3637
  }
4010
- module.invoke(query);
3638
+ module.invoke(parameters);
4011
3639
  } else {
4012
3640
  if (instance !== undefined) {
4013
3641
  instance.invoke('destroy');
@@ -4068,7 +3696,7 @@
4068
3696
 
4069
3697
  maxSelections: false, // When set to a number, limits the number of selections to this count
4070
3698
  useLabels: true, // whether multiple select should filter currently active selections from choices
4071
- delimiter: ',', // when multiselect uses normal <input >, the values will be delimited with this character
3699
+ delimiter: ',', // when multiselect uses normal <input>, the values will be delimited with this character
4072
3700
 
4073
3701
  showOnFocus: false, // show the menu on focus
4074
3702
  allowReselection: false, // whether current value should trigger callbacks when reselected
@@ -4139,13 +3767,11 @@
4139
3767
  missingMultiple: '<select> requires multiple property to be set to correctly preserve multiple values',
4140
3768
  method: 'The method you called is not defined.',
4141
3769
  noAPI: 'The API module is required to load resources remotely',
4142
- noStorage: 'Saving remote data requires session storage',
4143
3770
  noElement: 'This module requires ui {element}',
4144
3771
  },
4145
3772
 
4146
3773
  regExp: {
4147
3774
  escape: /[\s#$()*+,.:=?@[\\\]^{|}-]/g,
4148
- quote: /"/g,
4149
3775
  },
4150
3776
 
4151
3777
  metadata: {
@@ -4259,8 +3885,7 @@
4259
3885
  return string;
4260
3886
  }
4261
3887
 
4262
- const badChars = /["'<>]|&(?![\d#A-Za-z]{1,12};)/g;
4263
- const escape = {
3888
+ const escapeMap = {
4264
3889
  '"': '&quot;',
4265
3890
  '&': '&amp;',
4266
3891
  "'": '&apos;',
@@ -4268,16 +3893,14 @@
4268
3893
  '>': '&gt;',
4269
3894
  };
4270
3895
 
4271
- return string.replace(badChars, (chr) => escape[chr]);
3896
+ return String(string).replace(/["&'<>]/g, (chr) => escapeMap[chr]);
4272
3897
  },
4273
3898
  // generates dropdown from select values
4274
3899
  dropdown: function (select, settings) {
4275
- var
4276
- placeholder = select.placeholder || false,
4277
- html = '',
4278
- className = settings.className,
4279
- escape = settings.templates.escape
4280
- ;
3900
+ const placeholder = select.placeholder || false;
3901
+ let html = '';
3902
+ const className = settings.className;
3903
+ const escape = settings.templates.escape;
4281
3904
  html += '<i class="dropdown icon"></i>';
4282
3905
  html += placeholder
4283
3906
  ? '<div class="default text">' + escape(placeholder, settings) + '</div>'
@@ -4291,50 +3914,45 @@
4291
3914
 
4292
3915
  // generates just menu from select
4293
3916
  menu: function (response, settings) {
4294
- var
4295
- fields = settings.fields,
4296
- values = response[fields.values] || [],
4297
- html = '',
4298
- className = settings.className,
4299
- escape = settings.templates.escape
4300
- ;
3917
+ const fields = settings.fields;
3918
+ const values = response[fields.values] || [];
3919
+ let html = '';
3920
+ const className = settings.className;
3921
+ const escape = settings.templates.escape;
4301
3922
  $.each(values, function (index, option) {
4302
- var
4303
- itemType = option[fields.type] || 'item',
4304
- isMenu = itemType.indexOf('menu') !== -1,
4305
- maybeData = '',
4306
- dataObject = option[fields.data]
4307
- ;
3923
+ const itemType = option[fields.type] || 'item';
3924
+ const isMenu = itemType.includes('menu');
3925
+ let maybeData = '';
3926
+ const dataObject = option[fields.data];
4308
3927
  if (dataObject) {
4309
- var dataKey,
4310
- dataKeyEscaped
4311
- ;
3928
+ let dataKey;
3929
+ let dataKeyEscaped;
4312
3930
  for (dataKey in dataObject) {
4313
- dataKeyEscaped = String(dataKey).replace(/\W/g, '');
4314
- if (Object.prototype.hasOwnProperty.call(dataObject, dataKey) && ['text', 'value'].indexOf(dataKeyEscaped.toLowerCase()) === -1) {
4315
- maybeData += ' data-' + dataKeyEscaped + '="' + escape(String(dataObject[dataKey])) + '"';
3931
+ if (Object.prototype.hasOwnProperty.call(dataObject, dataKey)) {
3932
+ dataKeyEscaped = String(dataKey).replace(/\W/g, '');
3933
+ if (!['text', 'value'].includes(dataKeyEscaped.toLowerCase())) {
3934
+ maybeData += ' data-' + dataKeyEscaped + '="' + escape(String(dataObject[dataKey])) + '"';
3935
+ }
4316
3936
  }
4317
3937
  }
4318
3938
  }
4319
3939
  if (itemType === 'item' || isMenu) {
4320
- var
4321
- maybeText = option[fields.text]
4322
- ? ' data-text="' + escape(option[fields.text]) + '"'
4323
- : '',
4324
- maybeActionable = option[fields.actionable]
4325
- ? className.actionable + ' '
4326
- : '',
4327
- maybeDisabled = option[fields.disabled]
4328
- ? className.disabled + ' '
4329
- : '',
4330
- maybeDescriptionVertical = option[fields.descriptionVertical]
4331
- ? className.descriptionVertical + ' '
4332
- : '',
4333
- hasDescription = escape(option[fields.description] || '', settings) !== ''
4334
- ;
3940
+ const maybeText = option[fields.text]
3941
+ ? ' data-text="' + escape(option[fields.text]) + '"'
3942
+ : '';
3943
+ const maybeActionable = option[fields.actionable]
3944
+ ? className.actionable + ' '
3945
+ : '';
3946
+ const maybeDisabled = option[fields.disabled]
3947
+ ? className.disabled + ' '
3948
+ : '';
3949
+ const maybeDescriptionVertical = option[fields.descriptionVertical]
3950
+ ? className.descriptionVertical + ' '
3951
+ : '';
3952
+ const hasDescription = escape(option[fields.description] || '', settings) !== '';
4335
3953
  html += '<div class="' + escape(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + escape(option[fields.value]) + '"' + maybeText + maybeData + '>';
4336
3954
  if (isMenu) {
4337
- html += '<i class="' + (itemType.indexOf('left') !== -1 ? 'left' : '') + ' dropdown icon"></i>';
3955
+ html += '<i class="' + (itemType.includes('left') ? 'left' : '') + ' dropdown icon"></i>';
4338
3956
  }
4339
3957
  if (option[fields.image]) {
4340
3958
  html += '<img class="' + escape(option[fields.imageClass] || className.image) + '" src="' + escape(option[fields.image]) + '"' + (option[fields.alt] ? ' alt="' + escape(option[fields.alt]) + '"' : '') + '>';
@@ -4360,10 +3978,8 @@
4360
3978
  }
4361
3979
  html += '</div>';
4362
3980
  } else if (itemType === 'header') {
4363
- var
4364
- groupName = option[fields.name] || '',
4365
- groupIcon = option[fields.icon] || className.groupIcon
4366
- ;
3981
+ const groupName = option[fields.name] || '';
3982
+ const groupIcon = option[fields.icon] || className.groupIcon;
4367
3983
  if (groupName !== '' || groupIcon !== '') {
4368
3984
  html += '<div class="' + escape(option[fields.class] || className.header) + '">';
4369
3985
  if (groupIcon !== '') {
@@ -4383,10 +3999,8 @@
4383
3999
 
4384
4000
  // generates label for multiselect
4385
4001
  label: function (value, text, settings) {
4386
- var
4387
- className = settings.className,
4388
- escape = settings.templates.escape
4389
- ;
4002
+ const className = settings.className;
4003
+ const escape = settings.templates.escape;
4390
4004
 
4391
4005
  return escape(text, settings) + '<i class="' + escape(className.delete) + ' icon"></i>';
4392
4006
  },