fomantic-ui 2.10.0-beta.2 → 2.10.0-beta.20

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 (293) hide show
  1. package/.all-contributorsrc +9 -0
  2. package/.eslintrc.js +0 -10
  3. package/CHANGELOG.md +5289 -2325
  4. package/CONTRIBUTING.md +4 -1
  5. package/CONTRIBUTORS.md +1 -0
  6. package/FAQ.md +7 -2
  7. package/README.md +5 -9
  8. package/ROADMAP.md +4 -4
  9. package/SECURITY.md +8 -7
  10. package/changelog-setup.js +85 -69
  11. package/changelog-template.hbs +256 -251
  12. package/dist/components/accordion.css +1 -1
  13. package/dist/components/accordion.js +103 -142
  14. package/dist/components/accordion.min.css +1 -1
  15. package/dist/components/accordion.min.js +2 -2
  16. package/dist/components/ad.css +1 -1
  17. package/dist/components/ad.min.css +1 -1
  18. package/dist/components/api.js +157 -210
  19. package/dist/components/api.min.js +2 -2
  20. package/dist/components/breadcrumb.css +1 -1
  21. package/dist/components/breadcrumb.min.css +1 -1
  22. package/dist/components/button.css +1 -2
  23. package/dist/components/button.min.css +2 -2
  24. package/dist/components/calendar.css +1 -2
  25. package/dist/components/calendar.js +314 -352
  26. package/dist/components/calendar.min.css +2 -2
  27. package/dist/components/calendar.min.js +2 -2
  28. package/dist/components/card.css +1 -1
  29. package/dist/components/card.min.css +1 -1
  30. package/dist/components/checkbox.css +1 -2
  31. package/dist/components/checkbox.js +85 -135
  32. package/dist/components/checkbox.min.css +2 -2
  33. package/dist/components/checkbox.min.js +2 -2
  34. package/dist/components/comment.css +1 -1
  35. package/dist/components/comment.min.css +1 -1
  36. package/dist/components/container.css +2 -4
  37. package/dist/components/container.min.css +2 -2
  38. package/dist/components/dimmer.css +1 -11
  39. package/dist/components/dimmer.js +61 -94
  40. package/dist/components/dimmer.min.css +2 -2
  41. package/dist/components/dimmer.min.js +2 -2
  42. package/dist/components/divider.css +1 -2
  43. package/dist/components/divider.min.css +2 -2
  44. package/dist/components/dropdown.css +30 -51
  45. package/dist/components/dropdown.js +754 -1096
  46. package/dist/components/dropdown.min.css +2 -2
  47. package/dist/components/dropdown.min.js +2 -2
  48. package/dist/components/embed.css +1 -1
  49. package/dist/components/embed.js +84 -114
  50. package/dist/components/embed.min.css +1 -1
  51. package/dist/components/embed.min.js +2 -2
  52. package/dist/components/emoji.css +3809 -7617
  53. package/dist/components/emoji.min.css +2 -2
  54. package/dist/components/feed.css +1 -1
  55. package/dist/components/feed.min.css +1 -1
  56. package/dist/components/flag.css +1 -1
  57. package/dist/components/flag.min.css +1 -1
  58. package/dist/components/flyout.css +2 -3
  59. package/dist/components/flyout.js +225 -355
  60. package/dist/components/flyout.min.css +2 -2
  61. package/dist/components/flyout.min.js +2 -2
  62. package/dist/components/form.css +5 -95
  63. package/dist/components/form.js +335 -444
  64. package/dist/components/form.min.css +2 -2
  65. package/dist/components/form.min.js +2 -2
  66. package/dist/components/grid.css +2 -58
  67. package/dist/components/grid.min.css +2 -2
  68. package/dist/components/header.css +1 -1
  69. package/dist/components/header.min.css +1 -1
  70. package/dist/components/icon.css +4 -4
  71. package/dist/components/icon.min.css +2 -2
  72. package/dist/components/image.css +1 -1
  73. package/dist/components/image.min.css +1 -1
  74. package/dist/components/input.css +1 -536
  75. package/dist/components/input.min.css +2 -2
  76. package/dist/components/item.css +1 -1
  77. package/dist/components/item.min.css +1 -1
  78. package/dist/components/label.css +1 -1
  79. package/dist/components/label.min.css +1 -1
  80. package/dist/components/list.css +1 -3
  81. package/dist/components/list.min.css +2 -2
  82. package/dist/components/loader.css +1 -1
  83. package/dist/components/loader.min.css +1 -1
  84. package/dist/components/menu.css +40 -48
  85. package/dist/components/menu.min.css +2 -2
  86. package/dist/components/message.css +1 -1
  87. package/dist/components/message.min.css +1 -1
  88. package/dist/components/modal.css +5 -9
  89. package/dist/components/modal.js +260 -384
  90. package/dist/components/modal.min.css +2 -2
  91. package/dist/components/modal.min.js +2 -2
  92. package/dist/components/nag.css +1 -1
  93. package/dist/components/nag.js +68 -98
  94. package/dist/components/nag.min.css +1 -1
  95. package/dist/components/nag.min.js +2 -2
  96. package/dist/components/placeholder.css +1 -1
  97. package/dist/components/placeholder.min.css +1 -1
  98. package/dist/components/popup.css +1 -2
  99. package/dist/components/popup.js +197 -271
  100. package/dist/components/popup.min.css +2 -2
  101. package/dist/components/popup.min.js +2 -2
  102. package/dist/components/progress.css +1 -1
  103. package/dist/components/progress.js +109 -144
  104. package/dist/components/progress.min.css +1 -1
  105. package/dist/components/progress.min.js +2 -2
  106. package/dist/components/rail.css +1 -1
  107. package/dist/components/rail.min.css +1 -1
  108. package/dist/components/rating.css +1 -1
  109. package/dist/components/rating.js +90 -123
  110. package/dist/components/rating.min.css +1 -1
  111. package/dist/components/rating.min.js +2 -2
  112. package/dist/components/reset.css +1 -1
  113. package/dist/components/reset.min.css +1 -1
  114. package/dist/components/reveal.css +1 -1
  115. package/dist/components/reveal.min.css +1 -1
  116. package/dist/components/search.css +2 -9
  117. package/dist/components/search.js +276 -379
  118. package/dist/components/search.min.css +2 -2
  119. package/dist/components/search.min.js +2 -2
  120. package/dist/components/segment.css +2 -7
  121. package/dist/components/segment.min.css +2 -2
  122. package/dist/components/shape.css +1 -2
  123. package/dist/components/shape.js +158 -224
  124. package/dist/components/shape.min.css +2 -2
  125. package/dist/components/shape.min.js +2 -2
  126. package/dist/components/sidebar.css +2 -3
  127. package/dist/components/sidebar.js +124 -206
  128. package/dist/components/sidebar.min.css +2 -2
  129. package/dist/components/sidebar.min.js +2 -2
  130. package/dist/components/site.css +9 -25
  131. package/dist/components/site.js +38 -57
  132. package/dist/components/site.min.css +2 -2
  133. package/dist/components/site.min.js +2 -2
  134. package/dist/components/slider.css +1 -1
  135. package/dist/components/slider.js +246 -329
  136. package/dist/components/slider.min.css +1 -1
  137. package/dist/components/slider.min.js +2 -2
  138. package/dist/components/state.js +70 -100
  139. package/dist/components/state.min.js +2 -2
  140. package/dist/components/statistic.css +1 -1
  141. package/dist/components/statistic.min.css +1 -1
  142. package/dist/components/step.css +1 -1
  143. package/dist/components/step.min.css +1 -1
  144. package/dist/components/sticky.css +1 -1
  145. package/dist/components/sticky.js +135 -180
  146. package/dist/components/sticky.min.css +1 -1
  147. package/dist/components/sticky.min.js +2 -2
  148. package/dist/components/tab.css +1 -1
  149. package/dist/components/tab.js +176 -241
  150. package/dist/components/tab.min.css +1 -1
  151. package/dist/components/tab.min.js +2 -2
  152. package/dist/components/table.css +3 -37
  153. package/dist/components/table.min.css +2 -2
  154. package/dist/components/text.css +1 -1
  155. package/dist/components/text.min.css +1 -1
  156. package/dist/components/toast.css +1 -3
  157. package/dist/components/toast.js +108 -147
  158. package/dist/components/toast.min.css +1 -1
  159. package/dist/components/toast.min.js +2 -2
  160. package/dist/components/transition.css +1 -1
  161. package/dist/components/transition.js +91 -146
  162. package/dist/components/transition.min.css +1 -1
  163. package/dist/components/transition.min.js +2 -2
  164. package/dist/components/visibility.js +146 -224
  165. package/dist/components/visibility.min.js +2 -2
  166. package/dist/semantic.css +3945 -8759
  167. package/dist/semantic.js +4408 -6193
  168. package/dist/semantic.min.css +2 -2
  169. package/dist/semantic.min.js +2 -2
  170. package/examples/assets/show-examples.js +2 -4
  171. package/examples/attached.html +1 -1
  172. package/examples/components/menu.html +1 -1
  173. package/gulpfile.js +5 -7
  174. package/package.json +3 -6
  175. package/scripts/nightly-version.js +7 -10
  176. package/src/README.md +3 -3
  177. package/src/definitions/behaviors/api.js +156 -209
  178. package/src/definitions/behaviors/form.js +334 -443
  179. package/src/definitions/behaviors/state.js +69 -99
  180. package/src/definitions/behaviors/visibility.js +145 -223
  181. package/src/definitions/collections/form.less +1 -13
  182. package/src/definitions/collections/grid.less +1 -61
  183. package/src/definitions/collections/menu.less +101 -107
  184. package/src/definitions/collections/table.less +1 -35
  185. package/src/definitions/elements/input.less +1 -61
  186. package/src/definitions/elements/segment.less +0 -6
  187. package/src/definitions/globals/site.js +37 -56
  188. package/src/definitions/globals/site.less +2 -18
  189. package/src/definitions/modules/accordion.js +102 -141
  190. package/src/definitions/modules/calendar.js +313 -351
  191. package/src/definitions/modules/checkbox.js +84 -134
  192. package/src/definitions/modules/dimmer.js +60 -93
  193. package/src/definitions/modules/dimmer.less +0 -9
  194. package/src/definitions/modules/dropdown.js +753 -1095
  195. package/src/definitions/modules/dropdown.less +31 -47
  196. package/src/definitions/modules/embed.js +83 -113
  197. package/src/definitions/modules/flyout.js +224 -354
  198. package/src/definitions/modules/modal.js +259 -383
  199. package/src/definitions/modules/modal.less +1 -1
  200. package/src/definitions/modules/nag.js +67 -97
  201. package/src/definitions/modules/popup.js +196 -270
  202. package/src/definitions/modules/progress.js +108 -143
  203. package/src/definitions/modules/rating.js +89 -122
  204. package/src/definitions/modules/search.js +275 -378
  205. package/src/definitions/modules/search.less +0 -3
  206. package/src/definitions/modules/shape.js +157 -223
  207. package/src/definitions/modules/sidebar.js +123 -205
  208. package/src/definitions/modules/slider.js +245 -328
  209. package/src/definitions/modules/slider.less +1 -1
  210. package/src/definitions/modules/sticky.js +134 -179
  211. package/src/definitions/modules/tab.js +175 -240
  212. package/src/definitions/modules/toast.js +107 -146
  213. package/src/definitions/modules/toast.less +1 -1
  214. package/src/definitions/modules/transition.js +90 -145
  215. package/src/theme.less +0 -13
  216. package/src/themes/basic/elements/icon.variables +1 -1
  217. package/src/themes/chubby/collections/menu.variables +1 -1
  218. package/src/themes/default/collections/grid.variables +0 -30
  219. package/src/themes/default/collections/menu.variables +23 -23
  220. package/src/themes/default/collections/table.variables +1 -5
  221. package/src/themes/default/elements/icon.variables +3 -3
  222. package/src/themes/default/globals/site.variables +8 -15
  223. package/src/themes/default/globals/variation.variables +3 -3
  224. package/src/themes/default/modules/dropdown.variables +1 -0
  225. package/src/themes/default/modules/slider.variables +1 -1
  226. package/src/themes/github/elements/icon.variables +1 -1
  227. package/src/themes/material/elements/icon.variables +1 -1
  228. package/tasks/README.md +1 -1
  229. package/tasks/admin/components/create.js +89 -122
  230. package/tasks/admin/components/init.js +34 -65
  231. package/tasks/admin/components/update.js +50 -61
  232. package/tasks/admin/distributions/create.js +71 -111
  233. package/tasks/admin/distributions/init.js +32 -63
  234. package/tasks/admin/distributions/update.js +49 -57
  235. package/tasks/admin/publish.js +1 -1
  236. package/tasks/admin/register.js +14 -19
  237. package/tasks/admin/release.js +2 -2
  238. package/tasks/build/assets.js +14 -18
  239. package/tasks/build/css.js +59 -68
  240. package/tasks/build/javascript.js +48 -56
  241. package/tasks/build.js +4 -6
  242. package/tasks/check-install.js +5 -8
  243. package/tasks/clean.js +5 -7
  244. package/tasks/collections/admin.js +14 -16
  245. package/tasks/collections/build.js +6 -8
  246. package/tasks/collections/docs.js +4 -6
  247. package/tasks/collections/install.js +2 -4
  248. package/tasks/collections/rtl.js +2 -4
  249. package/tasks/collections/various.js +2 -4
  250. package/tasks/config/admin/github.js +9 -19
  251. package/tasks/config/admin/templates/README.md +2 -2
  252. package/tasks/config/admin/templates/bower.json +2 -4
  253. package/tasks/config/admin/templates/composer.json +1 -1
  254. package/tasks/config/admin/templates/css-package.js +1 -4
  255. package/tasks/config/admin/templates/less-package.js +1 -3
  256. package/tasks/config/defaults.js +0 -1
  257. package/tasks/config/npm/gulpfile.js +4 -6
  258. package/tasks/config/project/config.js +27 -35
  259. package/tasks/config/project/install.js +64 -82
  260. package/tasks/config/project/release.js +7 -9
  261. package/tasks/config/tasks.js +10 -21
  262. package/tasks/config/user.js +14 -20
  263. package/tasks/docs/build.js +26 -31
  264. package/tasks/docs/metadata.js +30 -39
  265. package/tasks/docs/serve.js +23 -27
  266. package/tasks/install.js +94 -128
  267. package/tasks/rtl/build.js +2 -4
  268. package/tasks/rtl/watch.js +3 -5
  269. package/tasks/watch.js +13 -13
  270. package/test/meteor/fonts.js +1 -2
  271. package/test/modules/module.spec.js +16 -18
  272. package/types/fomantic-ui-calendar.d.ts +1 -1
  273. package/types/fomantic-ui-dropdown.d.ts +45 -1
  274. package/types/fomantic-ui-embed.d.ts +1 -1
  275. package/types/fomantic-ui-flyout.d.ts +1 -1
  276. package/types/fomantic-ui-form.d.ts +0 -7
  277. package/types/fomantic-ui-modal.d.ts +1 -1
  278. package/types/fomantic-ui-search.d.ts +12 -6
  279. package/types/fomantic-ui-toast.d.ts +1 -1
  280. package/src/themes/basic/assets/fonts/icons.woff +0 -0
  281. package/src/themes/default/assets/fonts/Lato-Bold.woff +0 -0
  282. package/src/themes/default/assets/fonts/Lato-BoldItalic.woff +0 -0
  283. package/src/themes/default/assets/fonts/Lato-Italic.woff +0 -0
  284. package/src/themes/default/assets/fonts/Lato-Regular.woff +0 -0
  285. package/src/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  286. package/src/themes/default/assets/fonts/LatoLatin-BoldItalic.woff +0 -0
  287. package/src/themes/default/assets/fonts/LatoLatin-Italic.woff +0 -0
  288. package/src/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  289. package/src/themes/default/assets/fonts/brand-icons.woff +0 -0
  290. package/src/themes/default/assets/fonts/icons.woff +0 -0
  291. package/src/themes/default/assets/fonts/outline-icons.woff +0 -0
  292. package/src/themes/github/assets/fonts/octicons.woff +0 -0
  293. package/src/themes/material/assets/fonts/icons.woff +0 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * # Fomantic-UI 2.10.0-beta.2+d30ebd7 - Dropdown
2
+ * # Fomantic-UI 2.10.0-beta.20+2afb021 - Dropdown
3
3
  * https://github.com/fomantic/Fomantic-UI/
4
4
  *
5
5
  *
@@ -20,91 +20,87 @@
20
20
  : globalThis;
21
21
 
22
22
  $.fn.dropdown = function (parameters) {
23
- var
24
- $allModules = $(this),
25
- $document = $(document),
26
-
27
- time = Date.now(),
28
- performance = [],
29
-
30
- query = arguments[0],
31
- methodInvoked = typeof query === 'string',
32
- queryArguments = [].slice.call(arguments, 1),
33
- contextCheck = function (context, win) {
34
- var $context;
35
- if ([window, document].indexOf(context) >= 0) {
36
- $context = $(context);
37
- } else {
38
- $context = $(win.document).find(context);
39
- if ($context.length === 0) {
40
- $context = win.frameElement ? contextCheck(context, win.parent) : window;
41
- }
23
+ let $allModules = $(this);
24
+ let $document = $(document);
25
+
26
+ let time = Date.now();
27
+ let performance = [];
28
+
29
+ let query = arguments[0];
30
+ let methodInvoked = typeof query === 'string';
31
+ let queryArguments = [].slice.call(arguments, 1);
32
+ let contextCheck = function (context, win) {
33
+ let $context;
34
+ if ([window, document].indexOf(context) >= 0) {
35
+ $context = $(context);
36
+ } else {
37
+ $context = $(win.document).find(context);
38
+ if ($context.length === 0) {
39
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
42
40
  }
41
+ }
43
42
 
44
- return $context;
45
- },
46
- returnedValue
47
- ;
43
+ return $context;
44
+ };
45
+ let returnedValue;
48
46
 
49
47
  $allModules.each(function (elementIndex) {
50
- var
51
- settings = $.isPlainObject(parameters)
52
- ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
53
- : $.extend({}, $.fn.dropdown.settings),
54
-
55
- className = settings.className,
56
- message = settings.message,
57
- fields = settings.fields,
58
- keys = settings.keys,
59
- metadata = settings.metadata,
60
- namespace = settings.namespace,
61
- regExp = settings.regExp,
62
- selector = settings.selector,
63
- error = settings.error,
64
- templates = settings.templates,
65
-
66
- eventNamespace = '.' + namespace,
67
- moduleNamespace = 'module-' + namespace,
68
-
69
- $module = $(this),
70
- $context = contextCheck(settings.context, window),
71
- $text = $module.find(selector.text),
72
- $search = $module.find(selector.search),
73
- $sizer = $module.find(selector.sizer),
74
- $input = $module.find(selector.input),
75
- $icon = $module.find(selector.icon),
76
- $clear = $module.find(selector.clearIcon),
77
-
78
- $combo = $module.prev().find(selector.text).length > 0
79
- ? $module.prev().find(selector.text)
80
- : $module.prev(),
81
-
82
- $menu = $module.children(selector.menu),
83
- $item = $menu.find(selector.item),
84
- $divider = settings.hideDividers
85
- ? $item.parent().children(selector.divider)
86
- : $(),
87
-
88
- activated = false,
89
- itemActivated = false,
90
- internalChange = false,
91
- iconClicked = false,
92
- element = this,
93
- focused = false,
94
- instance = $module.data(moduleNamespace),
95
-
96
- selectActionActive,
97
- initialLoad,
98
- pageLostFocus,
99
- willRefocus,
100
- elementNamespace,
101
- id,
102
- selectObserver,
103
- menuObserver,
104
- classObserver,
105
- module,
106
- tempDisableApiCache = false
107
- ;
48
+ let settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
50
+ : $.extend({}, $.fn.dropdown.settings);
51
+
52
+ let className = settings.className;
53
+ let message = settings.message;
54
+ let fields = settings.fields;
55
+ let keys = settings.keys;
56
+ let metadata = settings.metadata;
57
+ let namespace = settings.namespace;
58
+ let regExp = settings.regExp;
59
+ let selector = settings.selector;
60
+ let error = settings.error;
61
+ let templates = settings.templates;
62
+
63
+ let eventNamespace = '.' + namespace;
64
+ let moduleNamespace = 'module-' + namespace;
65
+
66
+ let $module = $(this);
67
+ let $context = contextCheck(settings.context, window);
68
+ let $text = $module.find(selector.text);
69
+ let $search = $module.find(selector.search);
70
+ let $sizer = $module.find(selector.sizer);
71
+ let $input = $module.find(selector.input);
72
+ let $icon = $module.find(selector.icon);
73
+ let $clear = $module.find(selector.clearIcon);
74
+
75
+ let $combo = $module.prev().find(selector.text).length > 0
76
+ ? $module.prev().find(selector.text)
77
+ : $module.prev();
78
+
79
+ let $menu = $module.children(selector.menu);
80
+ let $item = $menu.find(selector.item);
81
+ let $divider = settings.hideDividers
82
+ ? $item.parent().children(selector.divider)
83
+ : $();
84
+
85
+ let activated = false;
86
+ let itemActivated = false;
87
+ let internalChange = false;
88
+ let iconClicked = false;
89
+ let element = this;
90
+ let focused = false;
91
+ let instance = $module.data(moduleNamespace);
92
+
93
+ let selectActionActive;
94
+ let initialLoad;
95
+ let pageLostFocus;
96
+ let willRefocus;
97
+ let elementNamespace;
98
+ let id;
99
+ let selectObserver;
100
+ let menuObserver;
101
+ let classObserver;
102
+ let module;
103
+ let tempDisableApiCache = false;
108
104
 
109
105
  module = {
110
106
 
@@ -114,11 +110,6 @@
114
110
  if (module.is.alreadySetup()) {
115
111
  module.setup.reference();
116
112
  } else {
117
- if (settings.ignoreDiacritics && !String.prototype.normalize) {
118
- settings.ignoreDiacritics = false;
119
- module.error(error.noNormalize, element);
120
- }
121
-
122
113
  module.create.id();
123
114
  module.setup.layout();
124
115
 
@@ -147,8 +138,7 @@
147
138
  module.verbose('Storing instance of dropdown', module);
148
139
  instance = module;
149
140
  $module
150
- .data(moduleNamespace, module)
151
- ;
141
+ .data(moduleNamespace, module);
152
142
  },
153
143
 
154
144
  destroy: function () {
@@ -159,29 +149,24 @@
159
149
  $menu.removeClass(className.visible).addClass(className.hidden);
160
150
  $module
161
151
  .off(eventNamespace)
162
- .removeData(moduleNamespace)
163
- ;
152
+ .removeData(moduleNamespace);
164
153
  $menu
165
- .off(eventNamespace)
166
- ;
154
+ .off(eventNamespace);
167
155
  $document
168
- .off(elementNamespace)
169
- ;
156
+ .off(elementNamespace);
170
157
  module.disconnect.menuObserver();
171
158
  module.disconnect.selectObserver();
172
159
  module.disconnect.classObserver();
173
160
  },
174
161
 
175
162
  observeChanges: function () {
176
- if ('MutationObserver' in window) {
177
- selectObserver = new MutationObserver(module.event.select.mutation);
178
- menuObserver = new MutationObserver(module.event.menu.mutation);
179
- classObserver = new MutationObserver(module.event.class.mutation);
180
- module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
181
- module.observe.select();
182
- module.observe.menu();
183
- module.observe.class();
184
- }
163
+ selectObserver = new MutationObserver(module.event.select.mutation);
164
+ menuObserver = new MutationObserver(module.event.menu.mutation);
165
+ classObserver = new MutationObserver(module.event.class.mutation);
166
+ module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
167
+ module.observe.select();
168
+ module.observe.menu();
169
+ module.observe.class();
185
170
  },
186
171
 
187
172
  disconnect: {
@@ -235,11 +220,9 @@
235
220
  module.verbose('Creating unique id for element', id);
236
221
  },
237
222
  userChoice: function (values) {
238
- var
239
- $userChoices,
240
- $userChoice,
241
- html
242
- ;
223
+ let $userChoices;
224
+ let $userChoice;
225
+ let html;
243
226
  values = values || module.get.userValues();
244
227
  if (!values) {
245
228
  return false;
@@ -249,14 +232,13 @@
249
232
  : [values];
250
233
  $.each(values, function (index, value) {
251
234
  if (module.get.item(value) === false) {
252
- html = settings.templates.addition(module.add.variables(message.addResult, value));
235
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
253
236
  $userChoice = $('<div />')
254
237
  .html(html)
255
238
  .attr('data-' + metadata.value, value)
256
239
  .attr('data-' + metadata.text, value)
257
240
  .addClass(className.addition)
258
- .addClass(className.item)
259
- ;
241
+ .addClass(className.item);
260
242
  if (settings.hideAdditions) {
261
243
  $userChoice.addClass(className.hidden);
262
244
  }
@@ -270,9 +252,7 @@
270
252
  return $userChoices;
271
253
  },
272
254
  userLabels: function (value) {
273
- var
274
- userValues = module.get.userValues()
275
- ;
255
+ let userValues = module.get.userValues();
276
256
  if (userValues) {
277
257
  module.debug('Adding user labels', userValues);
278
258
  $.each(userValues, function (index, value) {
@@ -284,14 +264,12 @@
284
264
  menu: function () {
285
265
  $menu = $('<div />')
286
266
  .addClass(className.menu)
287
- .appendTo($module)
288
- ;
267
+ .appendTo($module);
289
268
  },
290
269
  sizer: function () {
291
270
  $sizer = $('<span />')
292
271
  .addClass(className.sizer)
293
- .insertAfter($search)
294
- ;
272
+ .insertAfter($search);
295
273
  },
296
274
  },
297
275
 
@@ -317,16 +295,13 @@
317
295
  .not(selector.unselectable)
318
296
  .not(selector.addition + selector.hidden)
319
297
  .eq(0)
320
- .addClass(className.selected)
321
- ;
298
+ .addClass(className.selected);
322
299
  },
323
300
  nextAvailable: function ($selected) {
324
301
  $selected = $selected.eq(0);
325
- var
326
- $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
327
- $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
328
- hasNext = $nextAvailable.length > 0
329
- ;
302
+ let $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0);
303
+ let $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0);
304
+ let hasNext = $nextAvailable.length > 0;
330
305
  if (hasNext) {
331
306
  module.verbose('Moving selection to', $nextAvailable);
332
307
  $nextAvailable.addClass(className.selected);
@@ -339,20 +314,17 @@
339
314
 
340
315
  setup: {
341
316
  api: function () {
342
- var
343
- apiSettings = {
344
- debug: settings.debug,
345
- urlData: {
346
- value: module.get.value(),
347
- query: module.get.query(),
348
- },
349
- on: false,
350
- }
351
- ;
317
+ let apiSettings = {
318
+ debug: settings.debug,
319
+ urlData: {
320
+ value: module.get.value(),
321
+ query: module.get.query(),
322
+ },
323
+ on: false,
324
+ };
352
325
  module.verbose('First request, initializing API');
353
326
  $module
354
- .api(apiSettings)
355
- ;
327
+ .api(apiSettings);
356
328
  },
357
329
  layout: function () {
358
330
  if ($module.is('select')) {
@@ -366,18 +338,14 @@
366
338
  module.verbose('Adding clear icon');
367
339
  $clear = $('<i />')
368
340
  .addClass('remove icon')
369
- .insertAfter($icon)
370
- ;
341
+ .insertAfter($icon);
371
342
  }
372
343
  if (module.is.search() && !module.has.search()) {
373
344
  module.verbose('Adding search input');
374
- var
375
- labelNode = $module.prev('label')
376
- ;
345
+ let labelNode = $module.prev('label');
377
346
  $search = $('<input />')
378
347
  .addClass(className.search)
379
- .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off')
380
- ;
348
+ .prop('autocomplete', module.is.chrome() ? 'fomantic-search' : 'off');
381
349
  if (labelNode.length > 0) {
382
350
  if (!labelNode.attr('id')) {
383
351
  labelNode.attr('id', '_' + module.get.id() + '_formLabel');
@@ -394,9 +362,7 @@
394
362
  }
395
363
  },
396
364
  select: function () {
397
- var
398
- selectValues = module.get.selectValues()
399
- ;
365
+ let selectValues = module.get.selectValues();
400
366
  module.debug('Dropdown initialized on a select', selectValues);
401
367
  if ($module.is('select')) {
402
368
  $input = $module;
@@ -416,9 +382,8 @@
416
382
  .attr('class', $input.attr('class'))
417
383
  .addClass(className.selection)
418
384
  .addClass(className.dropdown)
419
- .html(templates.dropdown(selectValues, fields, settings.preserveHTML, settings.className))
420
- .insertBefore($input)
421
- ;
385
+ .html(templates.dropdown(selectValues, settings))
386
+ .insertBefore($input);
422
387
  if ($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
423
388
  module.error(error.missingMultiple);
424
389
  $input.prop('multiple', true);
@@ -440,13 +405,12 @@
440
405
  .prop('required', false)
441
406
  .removeAttr('class')
442
407
  .detach()
443
- .prependTo($module)
444
- ;
408
+ .prependTo($module);
445
409
  }
446
410
  module.refresh();
447
411
  },
448
412
  menu: function (values) {
449
- $menu.html(templates.menu(values, fields, settings.preserveHTML, settings.className));
413
+ $menu.html(templates.menu(values, settings));
450
414
  $item = $menu.find(selector.item);
451
415
  $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $();
452
416
  },
@@ -460,11 +424,9 @@
460
424
  module.setup.returnedObject();
461
425
  },
462
426
  returnedObject: function () {
463
- var
464
- $firstModules = $allModules.slice(0, elementIndex),
465
- $lastModules = $allModules.slice(elementIndex + 1)
466
- ;
467
- // adjust all modules to use correct reference
427
+ let $firstModules = $allModules.slice(0, elementIndex);
428
+ let $lastModules = $allModules.slice(elementIndex + 1);
429
+ // adjust all modules to use the correct reference
468
430
  $allModules = $firstModules.add($module).add($lastModules);
469
431
  },
470
432
  },
@@ -497,21 +459,18 @@
497
459
  module.verbose('Refreshing cached metadata');
498
460
  $item
499
461
  .removeData(metadata.text)
500
- .removeData(metadata.value)
501
- ;
462
+ .removeData(metadata.value);
502
463
  },
503
464
 
504
465
  clearData: function () {
505
466
  module.verbose('Clearing metadata');
506
467
  $item
507
468
  .removeData(metadata.text)
508
- .removeData(metadata.value)
509
- ;
469
+ .removeData(metadata.value);
510
470
  $module
511
471
  .removeData(metadata.defaultText)
512
472
  .removeData(metadata.defaultValue)
513
- .removeData(metadata.placeholderText)
514
- ;
473
+ .removeData(metadata.placeholderText);
515
474
  },
516
475
 
517
476
  clearItems: function () {
@@ -578,11 +537,11 @@
578
537
  });
579
538
  // Hide submenus explicitly. On some browsers (esp. mobile), they will not automatically receive a
580
539
  // mouseleave event
581
- var $subMenu = $module.find(selector.menu);
540
+ let $subMenu = $module.find(selector.menu);
582
541
  if ($subMenu.length > 0) {
583
542
  module.verbose('Hiding sub-menu', $subMenu);
584
543
  $subMenu.each(function () {
585
- var $sub = $(this);
544
+ let $sub = $(this);
586
545
  if (!module.is.animating($sub)) {
587
546
  module.animate.hide(false, $sub);
588
547
  }
@@ -601,8 +560,7 @@
601
560
  $allModules
602
561
  .not($module)
603
562
  .has(selector.menu + '.' + className.visible)
604
- .dropdown('hide')
605
- ;
563
+ .dropdown('hide');
606
564
  },
607
565
 
608
566
  hideMenu: function () {
@@ -613,9 +571,7 @@
613
571
  },
614
572
 
615
573
  hideSubMenus: function () {
616
- var
617
- $subMenus = $menu.children(selector.item).find(selector.menu)
618
- ;
574
+ let $subMenus = $menu.children(selector.item).find(selector.menu);
619
575
  module.verbose('Hiding sub menus', $subMenus);
620
576
  $subMenus.transition('hide');
621
577
  },
@@ -629,28 +585,23 @@
629
585
  keyboardEvents: function () {
630
586
  module.verbose('Binding keyboard events');
631
587
  $module
632
- .on('keydown' + eventNamespace, module.event.keydown)
633
- ;
588
+ .on('keydown' + eventNamespace, module.event.keydown);
634
589
  if (module.has.search()) {
635
590
  $module
636
- .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
637
- ;
591
+ .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input);
638
592
  }
639
593
  if (module.is.multiple()) {
640
594
  $document
641
- .on('keydown' + elementNamespace, module.event.document.keydown)
642
- ;
595
+ .on('keydown' + elementNamespace, module.event.document.keydown);
643
596
  }
644
597
  },
645
598
  inputEvents: function () {
646
599
  module.verbose('Binding input change events');
647
600
  $module
648
- .on('change' + eventNamespace, selector.input, module.event.change)
649
- ;
601
+ .on('change' + eventNamespace, selector.input, module.event.change);
650
602
  if (module.is.multiple() && module.is.searchSelection()) {
651
603
  $module
652
- .on('paste' + eventNamespace, selector.search, module.event.paste)
653
- ;
604
+ .on('paste' + eventNamespace, selector.search, module.event.paste);
654
605
  }
655
606
  },
656
607
  mouseEvents: function () {
@@ -658,8 +609,7 @@
658
609
  if (module.is.multiple()) {
659
610
  $module
660
611
  .on('click' + eventNamespace, selector.label, module.event.label.click)
661
- .on('click' + eventNamespace, selector.remove, module.event.remove.click)
662
- ;
612
+ .on('click' + eventNamespace, selector.remove, module.event.remove.click);
663
613
  }
664
614
  if (module.is.searchSelection()) {
665
615
  $module
@@ -672,60 +622,50 @@
672
622
  .on('focus' + eventNamespace, selector.search, module.event.search.focus)
673
623
  .on('click' + eventNamespace, selector.search, module.event.search.focus)
674
624
  .on('blur' + eventNamespace, selector.search, module.event.search.blur)
675
- .on('click' + eventNamespace, selector.text, module.event.text.focus)
676
- ;
625
+ .on('click' + eventNamespace, selector.text, module.event.text.focus);
677
626
  if (module.is.multiple()) {
678
627
  $module
679
628
  .on('click' + eventNamespace, module.event.click)
680
- .on('click' + eventNamespace, module.event.search.focus)
681
- ;
629
+ .on('click' + eventNamespace, module.event.search.focus);
682
630
  }
683
631
  } else {
684
632
  if (settings.on === 'click') {
685
633
  $module
686
634
  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
687
- .on('click' + eventNamespace, module.event.test.toggle)
688
- ;
635
+ .on('click' + eventNamespace, module.event.test.toggle);
689
636
  } else if (settings.on === 'hover') {
690
637
  $module
691
638
  .on('mouseenter' + eventNamespace, module.delay.show)
692
639
  .on('mouseleave' + eventNamespace, module.delay.hide)
693
640
  .on('touchstart' + eventNamespace, module.event.test.toggle)
694
- .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click)
695
- ;
641
+ .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click);
696
642
  } else {
697
643
  $module
698
- .on(settings.on + eventNamespace, module.toggle)
699
- ;
644
+ .on(settings.on + eventNamespace, module.toggle);
700
645
  }
701
646
  $module
702
647
  .on('mousedown' + eventNamespace, module.event.mousedown)
703
648
  .on('mouseup' + eventNamespace, module.event.mouseup)
704
649
  .on('focus' + eventNamespace, module.event.focus)
705
- .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click)
706
- ;
650
+ .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click);
707
651
  if (module.has.menuSearch()) {
708
652
  $module
709
- .on('blur' + eventNamespace, selector.search, module.event.search.blur)
710
- ;
653
+ .on('blur' + eventNamespace, selector.search, module.event.search.blur);
711
654
  } else {
712
655
  $module
713
- .on('blur' + eventNamespace, module.event.blur)
714
- ;
656
+ .on('blur' + eventNamespace, module.event.blur);
715
657
  }
716
658
  }
717
659
  $menu
718
660
  .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
719
661
  .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
720
662
  .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
721
- .on('click' + eventNamespace, selector.item, module.event.item.click)
722
- ;
663
+ .on('click' + eventNamespace, selector.item, module.event.item.click);
723
664
  },
724
665
  intent: function () {
725
666
  module.verbose('Binding hide intent event to document');
726
667
  $document
727
- .on('click' + elementNamespace, module.event.test.hide)
728
- ;
668
+ .on('click' + elementNamespace, module.event.test.hide);
729
669
  },
730
670
  },
731
671
 
@@ -733,52 +673,51 @@
733
673
  intent: function () {
734
674
  module.verbose('Removing hide intent event from document');
735
675
  $document
736
- .off('click' + elementNamespace)
737
- ;
676
+ .off('click' + elementNamespace);
738
677
  },
739
678
  },
740
679
 
741
680
  filter: function (query) {
742
- var
743
- searchTerm = query !== undefined
744
- ? query
745
- : module.get.query(),
746
- afterFiltered = function () {
747
- if (module.is.multiple()) {
748
- module.filterActive();
749
- }
750
- if (query || (!query && module.get.activeItem().length === 0)) {
751
- module.select.firstUnfiltered();
752
- }
753
- if (module.has.allResultsFiltered()) {
754
- if (settings.onNoResults.call(element, searchTerm)) {
755
- if (settings.allowAdditions) {
756
- if (settings.hideAdditions) {
757
- module.verbose('User addition with no menu, setting empty style');
758
- module.set.empty();
759
- module.hideMenu();
760
- }
761
- } else {
762
- module.verbose('All items filtered, showing message', searchTerm);
763
- module.add.message(message.noResults);
681
+ let searchTerm = query !== undefined
682
+ ? query
683
+ : module.get.query();
684
+ let afterFiltered = function () {
685
+ if (module.is.multiple()) {
686
+ module.filterActive();
687
+ }
688
+ if (query || (!query && module.get.activeItem().length === 0)) {
689
+ module.select.firstUnfiltered();
690
+ }
691
+ if (module.has.allResultsFiltered()) {
692
+ if (settings.onNoResults.call(element, searchTerm)) {
693
+ if (settings.allowAdditions) {
694
+ if (settings.hideAdditions) {
695
+ module.verbose('User addition with no menu, setting empty style');
696
+ module.set.empty();
697
+ module.hideMenu();
764
698
  }
765
699
  } else {
766
- module.verbose('All items filtered, hiding dropdown', searchTerm);
767
- module.set.empty();
768
- module.hideMenu();
700
+ module.verbose('All items filtered, showing message', searchTerm);
701
+ module.add.message(message.noResults);
769
702
  }
770
703
  } else {
771
- module.remove.empty();
772
- module.remove.message();
773
- }
774
- if (settings.allowAdditions) {
775
- module.add.userSuggestion(module.escape.htmlEntities(query));
776
- }
777
- if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
778
- module.show();
704
+ module.verbose('All items filtered, hiding dropdown', searchTerm);
705
+ module.set.empty();
706
+ module.hideMenu();
779
707
  }
708
+ } else {
709
+ module.remove.empty();
710
+ module.remove.message();
780
711
  }
781
- ;
712
+ if (settings.allowAdditions) {
713
+ module.add.userSuggestion(settings.preserveHTML
714
+ ? settings.templates.escape(query)
715
+ : query);
716
+ }
717
+ if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
718
+ module.show();
719
+ }
720
+ };
782
721
  if (settings.useLabels && module.has.maxSelections()) {
783
722
  module.show();
784
723
 
@@ -790,15 +729,14 @@
790
729
  if (settings.filterRemoteData) {
791
730
  module.filterItems(searchTerm);
792
731
  }
793
- var preSelected = $input.val();
732
+ let preSelected = $input.val();
794
733
  if (!Array.isArray(preSelected)) {
795
734
  preSelected = preSelected && preSelected !== '' ? preSelected.split(settings.delimiter) : [];
796
735
  }
797
736
  if (module.is.multiple()) {
798
737
  $.each(preSelected, function (index, value) {
799
- $item.filter('[data-' + metadata.value + '="' + value + '"]')
800
- .addClass(className.filtered)
801
- ;
738
+ $item.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]')
739
+ .addClass(className.filtered);
802
740
  });
803
741
  }
804
742
  module.focusSearch(true);
@@ -817,88 +755,81 @@
817
755
  if (!Array.isArray(callbackParameters)) {
818
756
  callbackParameters = [callbackParameters];
819
757
  }
820
- var
821
- apiSettings = {
822
- errorDuration: false,
823
- cache: 'local',
824
- throttle: settings.throttle,
825
- urlData: {
826
- query: query,
827
- },
758
+ let apiSettings = {
759
+ errorDuration: false,
760
+ cache: 'local',
761
+ throttle: settings.throttle,
762
+ urlData: {
763
+ query: query,
828
764
  },
829
- apiCallbacks = {
830
- onError: function (errorMessage, $module, xhr) {
831
- module.add.message(message.serverError);
832
- iconClicked = false;
833
- focused = false;
834
- callback.apply(null, callbackParameters);
835
- if (typeof settings.apiSettings.onError === 'function') {
836
- settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
837
- }
838
- },
839
- onFailure: function (response, $module, xhr) {
840
- module.add.message(message.serverError);
841
- iconClicked = false;
842
- focused = false;
843
- callback.apply(null, callbackParameters);
844
- if (typeof settings.apiSettings.onFailure === 'function') {
845
- settings.apiSettings.onFailure.call(this, response, $module, xhr);
846
- }
847
- },
848
- onSuccess: function (response, $module, xhr) {
849
- var
850
- values = response[fields.remoteValues]
851
- ;
852
- if (!Array.isArray(values)) {
853
- values = [];
854
- }
855
- module.remove.message();
856
- var menuConfig = {};
857
- menuConfig[fields.values] = values;
858
- module.setup.menu(menuConfig);
765
+ };
766
+ let apiCallbacks = {
767
+ onError: function (errorMessage, $module, xhr) {
768
+ module.add.message(message.serverError);
769
+ iconClicked = false;
770
+ focused = false;
771
+ callback.apply(null, callbackParameters);
772
+ if (typeof settings.apiSettings.onError === 'function') {
773
+ settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
774
+ }
775
+ },
776
+ onFailure: function (response, $module, xhr) {
777
+ module.add.message(message.serverError);
778
+ iconClicked = false;
779
+ focused = false;
780
+ callback.apply(null, callbackParameters);
781
+ if (typeof settings.apiSettings.onFailure === 'function') {
782
+ settings.apiSettings.onFailure.call(this, response, $module, xhr);
783
+ }
784
+ },
785
+ onSuccess: function (response, $module, xhr) {
786
+ let values = response[fields.remoteValues];
787
+ if (!Array.isArray(values)) {
788
+ values = [];
789
+ }
790
+ module.remove.message();
791
+ let menuConfig = {};
792
+ menuConfig[fields.values] = values;
793
+ module.setup.menu(menuConfig);
859
794
 
860
- if (values.length === 0 && !settings.allowAdditions) {
861
- module.add.message(message.noResults);
862
- } else {
863
- var value = module.is.multiple() ? module.get.values() : module.get.value();
864
- if (value !== '') {
865
- module.verbose('Value(s) present after click icon, select value(s) in items');
866
- module.set.selected(value, null, true, true);
867
- }
868
- }
869
- iconClicked = false;
870
- focused = false;
871
- callback.apply(null, callbackParameters);
872
- if (typeof settings.apiSettings.onSuccess === 'function') {
873
- settings.apiSettings.onSuccess.call(this, response, $module, xhr);
795
+ if (values.length === 0 && !settings.allowAdditions) {
796
+ module.add.message(message.noResults);
797
+ } else {
798
+ let value = module.is.multiple() ? module.get.values() : module.get.value();
799
+ if (value !== '') {
800
+ module.verbose('Value(s) present after click icon, select value(s) in items');
801
+ module.set.selected(value, null, true, true);
874
802
  }
875
- },
876
- }
877
- ;
803
+ }
804
+ iconClicked = false;
805
+ focused = false;
806
+ callback.apply(null, callbackParameters);
807
+ if (typeof settings.apiSettings.onSuccess === 'function') {
808
+ settings.apiSettings.onSuccess.call(this, response, $module, xhr);
809
+ }
810
+ },
811
+ };
878
812
  if (!$module.api('get request')) {
879
813
  module.setup.api();
880
814
  }
881
815
  apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings, apiCallbacks, tempDisableApiCache ? { cache: false } : {});
882
816
  $module
883
817
  .api('setting', apiSettings)
884
- .api('query')
885
- ;
818
+ .api('query');
886
819
  tempDisableApiCache = false;
887
820
  },
888
821
 
889
822
  filterItems: function (query) {
890
- var
891
- searchTerm = module.remove.diacritics(
892
- query !== undefined
893
- ? query
894
- : module.get.query()
895
- ),
896
- results = null,
897
- escapedTerm = module.escape.string(searchTerm),
898
- regExpIgnore = settings.ignoreSearchCase ? 'i' : '',
899
- regExpFlags = regExpIgnore + 'gm',
900
- beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags)
901
- ;
823
+ let searchTerm = module.remove.diacritics(
824
+ query !== undefined
825
+ ? query
826
+ : module.get.query()
827
+ );
828
+ let results = null;
829
+ let escapedTerm = module.escape.string(searchTerm);
830
+ let regExpIgnore = settings.ignoreSearchCase ? 'i' : '';
831
+ let regExpFlags = regExpIgnore + 'gm';
832
+ let beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags);
902
833
  module.remove.filteredItem();
903
834
  // avoid loop if we're matching nothing
904
835
  if (module.has.query()) {
@@ -907,11 +838,9 @@
907
838
  module.verbose('Searching for matching values', searchTerm);
908
839
  $item
909
840
  .each(function () {
910
- var
911
- $choice = $(this),
912
- text,
913
- value
914
- ;
841
+ let $choice = $(this);
842
+ let text;
843
+ let value;
915
844
  if ($choice.hasClass(className.unfilterable)) {
916
845
  results.push(this);
917
846
 
@@ -939,32 +868,28 @@
939
868
  return true;
940
869
  }
941
870
  }
942
- })
943
- ;
871
+ });
944
872
  }
945
873
  module.debug('Showing only matched items', searchTerm);
946
874
  if (results) {
947
875
  $item
948
876
  .not(results)
949
- .addClass(className.filtered)
950
- ;
877
+ .addClass(className.filtered);
951
878
  if (settings.highlightMatches && (settings.match === 'both' || settings.match === 'text')) {
952
- var querySplit = query.split(''),
953
- diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '',
954
- htmlReg = '(?![^<]*>)',
955
- markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore),
956
- markedReplacer = function () {
957
- var args = [].slice.call(arguments, 1, querySplit.length * 2).map(function (x, i) {
958
- return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
959
- });
879
+ let querySplit = query.split('');
880
+ let diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '';
881
+ let htmlReg = '(?![^<]*>)';
882
+ let markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore);
883
+ let markedReplacer = function () {
884
+ let args = [].slice.call(arguments, 1, querySplit.length * 2).map(function (x, i) {
885
+ return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
886
+ });
960
887
 
961
- return args.join('');
962
- }
963
- ;
888
+ return args.join('');
889
+ };
964
890
  $.each(results, function (index, result) {
965
- var $result = $(result),
966
- markedHTML = module.get.choiceText($result, true)
967
- ;
891
+ let $result = $(result);
892
+ let markedHTML = module.get.choiceText($result, true);
968
893
  if (settings.ignoreDiacritics) {
969
894
  markedHTML = markedHTML.normalize('NFD');
970
895
  }
@@ -975,19 +900,17 @@
975
900
 
976
901
  if (!module.has.query()) {
977
902
  $divider
978
- .removeClass(className.hidden)
979
- ;
903
+ .removeClass(className.hidden);
980
904
  } else if (settings.hideDividers === true) {
981
905
  $divider
982
- .addClass(className.hidden)
983
- ;
906
+ .addClass(className.hidden);
984
907
  } else if (settings.hideDividers === 'empty') {
985
908
  $divider
986
909
  .removeClass(className.hidden)
987
910
  .filter(function () {
988
911
  // First find the last divider in this divider group
989
912
  // Dividers which are direct siblings are considered a group
990
- var $lastDivider = $(this).nextUntil(selector.item);
913
+ let $lastDivider = $(this).nextUntil(selector.item);
991
914
 
992
915
  return ($lastDivider.length > 0 ? $lastDivider : $(this))
993
916
  // Count all non-filtered items until the next divider (or end of the dropdown)
@@ -996,16 +919,13 @@
996
919
  // Hide divider if no items are found
997
920
  .length === 0;
998
921
  })
999
- .addClass(className.hidden)
1000
- ;
922
+ .addClass(className.hidden);
1001
923
  }
1002
924
  },
1003
925
 
1004
926
  fuzzySearch: function (query, term) {
1005
- var
1006
- termLength = term.length,
1007
- queryLength = query.length
1008
- ;
927
+ let termLength = term.length;
928
+ let queryLength = query.length;
1009
929
  if (settings.ignoreSearchCase) {
1010
930
  query = query.toLowerCase();
1011
931
  term = term.toLowerCase();
@@ -1016,11 +936,9 @@
1016
936
  if (queryLength === termLength) {
1017
937
  return query === term;
1018
938
  }
1019
- for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
1020
- var
1021
- continueSearch = false,
1022
- queryCharacter = query.charCodeAt(characterIndex)
1023
- ;
939
+ for (let characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
940
+ let continueSearch = false;
941
+ let queryCharacter = query.charCodeAt(characterIndex);
1024
942
  while (nextCharacterIndex < termLength) {
1025
943
  if (term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
1026
944
  continueSearch = true;
@@ -1045,8 +963,7 @@
1045
963
  filterActive: function () {
1046
964
  if (settings.useLabels) {
1047
965
  $item.filter('.' + className.active)
1048
- .addClass(className.filtered)
1049
- ;
966
+ .addClass(className.filtered);
1050
967
  }
1051
968
  },
1052
969
 
@@ -1069,14 +986,12 @@
1069
986
  },
1070
987
 
1071
988
  forceSelection: function () {
1072
- var
1073
- $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
1074
- $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0),
1075
- $selectedItem = $currentlySelected.length > 0
1076
- ? $currentlySelected
1077
- : $activeItem,
1078
- hasSelected = $selectedItem.length > 0
1079
- ;
989
+ let $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0);
990
+ let $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0);
991
+ let $selectedItem = $currentlySelected.length > 0
992
+ ? $currentlySelected
993
+ : $activeItem;
994
+ let hasSelected = $selectedItem.length > 0;
1080
995
  if (settings.allowAdditions || (hasSelected && !module.is.multiple())) {
1081
996
  module.debug('Forcing partial selection to selected item', $selectedItem);
1082
997
  module.event.item.click.call($selectedItem, {}, true);
@@ -1091,7 +1006,7 @@
1091
1006
  module.clear();
1092
1007
  }
1093
1008
  module.debug('Creating dropdown with specified values', values);
1094
- var menuConfig = {};
1009
+ let menuConfig = {};
1095
1010
  menuConfig[fields.values] = values;
1096
1011
  module.setup.menu(menuConfig);
1097
1012
  $.each(values, function (index, item) {
@@ -1109,14 +1024,9 @@
1109
1024
  $input.html('');
1110
1025
  $input.append('<option disabled selected value></option>');
1111
1026
  $.each(values, function (index, item) {
1112
- var
1113
- value = settings.templates.deQuote(item[fields.value]),
1114
- name = settings.templates.escape(
1115
- item[fields.name] || '',
1116
- settings.preserveHTML
1117
- )
1118
- ;
1119
- $input.append('<option value="' + value + '"' + (item.selected === true ? ' selected' : '') + '>' + name + '</option>');
1027
+ let value = item[fields.value];
1028
+ let name = item[fields.name] || '';
1029
+ $input.append('<option value="' + settings.templates.escape(value) + '"' + (item.selected === true ? ' selected' : '') + '>' + settings.templates.escape(name, settings) + '</option>');
1120
1030
  });
1121
1031
  module.observe.select();
1122
1032
  }
@@ -1125,25 +1035,26 @@
1125
1035
 
1126
1036
  event: {
1127
1037
  paste: function (event) {
1128
- var
1129
- pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text'),
1130
- tokens = pasteValue.split(settings.delimiter),
1131
- notFoundTokens = []
1132
- ;
1038
+ let pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text');
1039
+ let tokens = pasteValue.split(settings.delimiter);
1040
+ let notFoundTokens = [];
1133
1041
  tokens.forEach(function (value) {
1134
- if (module.set.selected(module.escape.htmlEntities(value.trim()), null, false, true) === false) {
1135
- notFoundTokens.push(value.trim());
1042
+ value = value.trim();
1043
+ const valueTrimmed = settings.preserveHTML
1044
+ ? settings.templates.escape(value)
1045
+ : value;
1046
+ if (module.set.selected(valueTrimmed, null, false, true) === false) {
1047
+ notFoundTokens.push(valueTrimmed);
1136
1048
  }
1137
1049
  });
1138
1050
  event.preventDefault();
1139
1051
  if (notFoundTokens.length > 0) {
1140
- var searchEl = $search[0],
1141
- startPos = searchEl.selectionStart,
1142
- endPos = searchEl.selectionEnd,
1143
- orgText = searchEl.value,
1144
- pasteText = notFoundTokens.join(settings.delimiter),
1145
- newEndPos = startPos + pasteText.length
1146
- ;
1052
+ let searchEl = $search[0];
1053
+ let startPos = searchEl.selectionStart;
1054
+ let endPos = searchEl.selectionEnd;
1055
+ let orgText = searchEl.value;
1056
+ let pasteText = notFoundTokens.join(settings.delimiter);
1057
+ let newEndPos = startPos + pasteText.length;
1147
1058
  $search.val(orgText.slice(0, startPos) + pasteText + orgText.slice(endPos));
1148
1059
  searchEl.selectionStart = newEndPos;
1149
1060
  searchEl.selectionEnd = newEndPos;
@@ -1171,7 +1082,7 @@
1171
1082
  },
1172
1083
  mousedown: function () {
1173
1084
  if (module.is.searchSelection(true)) {
1174
- // prevent menu hiding on immediate re-focus
1085
+ // prevent the menu hiding on immediate re-focus
1175
1086
  willRefocus = true;
1176
1087
  } else {
1177
1088
  // prevents focus callback from occurring on mousedown
@@ -1180,16 +1091,14 @@
1180
1091
  },
1181
1092
  mouseup: function () {
1182
1093
  if (module.is.searchSelection(true)) {
1183
- // prevent menu hiding on immediate re-focus
1094
+ // prevent the menu hiding on immediate re-focus
1184
1095
  willRefocus = false;
1185
1096
  } else {
1186
1097
  activated = false;
1187
1098
  }
1188
1099
  },
1189
1100
  click: function (event) {
1190
- var
1191
- $target = $(event.target)
1192
- ;
1101
+ let $target = $(event.target);
1193
1102
  // focus search
1194
1103
  if ($target.is($module)) {
1195
1104
  if (!module.is.focusedOnSearch()) {
@@ -1273,16 +1182,14 @@
1273
1182
  },
1274
1183
  label: {
1275
1184
  click: function (event) {
1276
- var
1277
- $label = $(this),
1278
- $labels = $module.find(selector.label),
1279
- $activeLabels = $labels.filter('.' + className.active),
1280
- $nextActive = $label.nextAll('.' + className.active),
1281
- $prevActive = $label.prevAll('.' + className.active),
1282
- $range = $nextActive.length > 0
1283
- ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1284
- : $label.prevUntil($prevActive).add($activeLabels).add($label)
1285
- ;
1185
+ let $label = $(this);
1186
+ let $labels = $module.find(selector.label);
1187
+ let $activeLabels = $labels.filter('.' + className.active);
1188
+ let $nextActive = $label.nextAll('.' + className.active);
1189
+ let $prevActive = $label.prevAll('.' + className.active);
1190
+ let $range = $nextActive.length > 0
1191
+ ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1192
+ : $label.prevUntil($prevActive).add($activeLabels).add($label);
1286
1193
  if (event.shiftKey) {
1287
1194
  $activeLabels.removeClass(className.active);
1288
1195
  $range.addClass(className.active);
@@ -1298,9 +1205,7 @@
1298
1205
  },
1299
1206
  remove: {
1300
1207
  click: function (event) {
1301
- var
1302
- $label = $(this).parent()
1303
- ;
1208
+ let $label = $(this).parent();
1304
1209
  if ($label.hasClass(className.active)) {
1305
1210
  // remove all selected labels
1306
1211
  module.remove.activeLabels();
@@ -1313,11 +1218,9 @@
1313
1218
  },
1314
1219
  test: {
1315
1220
  toggle: function (event) {
1316
- var
1317
- toggleBehavior = module.is.multiple()
1318
- ? module.show
1319
- : module.toggle
1320
- ;
1221
+ let toggleBehavior = module.is.multiple()
1222
+ ? module.show
1223
+ : module.toggle;
1321
1224
  if (module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
1322
1225
  return;
1323
1226
  }
@@ -1361,18 +1264,16 @@
1361
1264
  },
1362
1265
  menu: {
1363
1266
  mutation: function (mutations) {
1364
- var
1365
- mutation = mutations[0],
1366
- $addedNode = mutation.addedNodes
1367
- ? $(mutation.addedNodes[0])
1368
- : $(false),
1369
- $removedNode = mutation.removedNodes
1370
- ? $(mutation.removedNodes[0])
1371
- : $(false),
1372
- $changedNodes = $addedNode.add($removedNode),
1373
- isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0,
1374
- isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0
1375
- ;
1267
+ let mutation = mutations[0];
1268
+ let $addedNode = mutation.addedNodes
1269
+ ? $(mutation.addedNodes[0])
1270
+ : $(false);
1271
+ let $removedNode = mutation.removedNodes
1272
+ ? $(mutation.removedNodes[0])
1273
+ : $(false);
1274
+ let $changedNodes = $addedNode.add($removedNode);
1275
+ let isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0;
1276
+ let isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0;
1376
1277
  if (isUserAddition || isMessage) {
1377
1278
  module.debug('Updating item selector cache');
1378
1279
  module.refreshItems();
@@ -1390,14 +1291,12 @@
1390
1291
  },
1391
1292
  item: {
1392
1293
  mouseenter: function (event) {
1393
- var
1394
- $target = $(event.target),
1395
- $item = $(this),
1396
- $subMenu = $item.children(selector.menu),
1397
- $otherMenus = $item.siblings(selector.item).children(selector.menu),
1398
- hasSubMenu = $subMenu.length > 0,
1399
- isBubbledEvent = $subMenu.find($target).length > 0
1400
- ;
1294
+ let $target = $(event.target);
1295
+ let $item = $(this);
1296
+ let $subMenu = $item.children(selector.menu);
1297
+ let $otherMenus = $item.siblings(selector.item).children(selector.menu);
1298
+ let hasSubMenu = $subMenu.length > 0;
1299
+ let isBubbledEvent = $subMenu.find($target).length > 0;
1401
1300
  if (!isBubbledEvent && hasSubMenu) {
1402
1301
  clearTimeout(module.itemTimer);
1403
1302
  module.itemTimer = setTimeout(function () {
@@ -1411,9 +1310,7 @@
1411
1310
  }
1412
1311
  },
1413
1312
  mouseleave: function (event) {
1414
- var
1415
- $subMenu = $(this).find(selector.menu)
1416
- ;
1313
+ let $subMenu = $(this).find(selector.menu);
1417
1314
  if ($subMenu.length > 0) {
1418
1315
  clearTimeout(module.itemTimer);
1419
1316
  module.itemTimer = setTimeout(function () {
@@ -1425,18 +1322,15 @@
1425
1322
  }
1426
1323
  },
1427
1324
  click: function (event, skipRefocus) {
1428
- var
1429
- $choice = $(this),
1430
- $target = event
1431
- ? $(event.target || '')
1432
- : $(''),
1433
- $subMenu = $choice.find(selector.menu),
1434
- text = module.get.choiceText($choice),
1435
- value = module.get.choiceValue($choice, text),
1436
- hasSubMenu = $subMenu.length > 0,
1437
- isBubbledEvent = $subMenu.find($target).length > 0
1438
- ;
1439
- // prevents IE11 bug where menu receives focus even though `tabindex=-1`
1325
+ let $choice = $(this);
1326
+ let $target = event
1327
+ ? $(event.target || '')
1328
+ : $('');
1329
+ let $subMenu = $choice.find(selector.menu);
1330
+ let text = module.get.choiceText($choice);
1331
+ let value = module.get.choiceValue($choice, text);
1332
+ let hasSubMenu = $subMenu.length > 0;
1333
+ let isBubbledEvent = $subMenu.find($target).length > 0;
1440
1334
  if (document.activeElement.tagName.toLowerCase() !== 'input') {
1441
1335
  $(document.activeElement).trigger('blur');
1442
1336
  }
@@ -1468,29 +1362,25 @@
1468
1362
  },
1469
1363
 
1470
1364
  document: {
1471
- // label selection should occur even when element has no focus
1365
+ // label selection should occur even when the element has no focus
1472
1366
  keydown: function (event) {
1473
- var
1474
- pressedKey = event.which,
1475
- isShortcutKey = module.is.inObject(pressedKey, keys)
1476
- ;
1367
+ let pressedKey = event.which;
1368
+ let isShortcutKey = module.is.inObject(pressedKey, keys);
1477
1369
  if (isShortcutKey) {
1478
- var
1479
- $label = $module.find(selector.label),
1480
- $activeLabel = $label.filter('.' + className.active),
1481
- activeValue = $activeLabel.data(metadata.value),
1482
- labelIndex = $label.index($activeLabel),
1483
- labelCount = $label.length,
1484
- hasActiveLabel = $activeLabel.length > 0,
1485
- hasMultipleActive = $activeLabel.length > 1,
1486
- isFirstLabel = labelIndex === 0,
1487
- isLastLabel = labelIndex + 1 === labelCount,
1488
- isSearch = module.is.searchSelection(),
1489
- isFocusedOnSearch = module.is.focusedOnSearch(),
1490
- isFocused = module.is.focused(),
1491
- caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0,
1492
- isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0
1493
- ;
1370
+ let $label = $module.find(selector.label);
1371
+ let $activeLabel = $label.filter('.' + className.active);
1372
+ let activeValue = $activeLabel.data(metadata.value);
1373
+ let labelIndex = $label.index($activeLabel);
1374
+ let labelCount = $label.length;
1375
+ let hasActiveLabel = $activeLabel.length > 0;
1376
+ let hasMultipleActive = $activeLabel.length > 1;
1377
+ let isFirstLabel = labelIndex === 0;
1378
+ let isLastLabel = labelIndex + 1 === labelCount;
1379
+ let isSearch = module.is.searchSelection();
1380
+ let isFocusedOnSearch = module.is.focusedOnSearch();
1381
+ let isFocused = module.is.focused();
1382
+ let caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0;
1383
+ let isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0;
1494
1384
  if (isSearch && !hasActiveLabel && !isFocusedOnSearch) {
1495
1385
  return;
1496
1386
  }
@@ -1513,8 +1403,7 @@
1513
1403
  } else {
1514
1404
  $activeLabel.prev(selector.siblingLabel)
1515
1405
  .addClass(className.active)
1516
- .end()
1517
- ;
1406
+ .end();
1518
1407
  }
1519
1408
  event.preventDefault();
1520
1409
  }
@@ -1589,32 +1478,28 @@
1589
1478
  },
1590
1479
 
1591
1480
  keydown: function (event) {
1592
- var
1593
- pressedKey = event.which,
1594
- isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter
1595
- ;
1481
+ let pressedKey = event.which;
1482
+ let isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter;
1596
1483
  if (isShortcutKey) {
1597
- var
1598
- $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
1599
- $activeItem = $menu.children('.' + className.active).eq(0),
1600
- $selectedItem = $currentlySelected.length > 0
1601
- ? $currentlySelected
1602
- : $activeItem,
1603
- $visibleItems = $selectedItem.length > 0
1604
- ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1605
- : $menu.children(':not(.' + className.filtered + ')'),
1606
- $subMenu = $selectedItem.children(selector.menu),
1607
- $parentMenu = $selectedItem.closest(selector.menu),
1608
- inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0,
1609
- hasSubMenu = $subMenu.length > 0,
1610
- hasSelectedItem = $selectedItem.length > 0,
1611
- selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0,
1612
- delimiterPressed = event.key === settings.delimiter && module.is.multiple(),
1613
- isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed),
1614
- $nextItem,
1615
- isSubMenuItem
1616
- ;
1617
- // allow selection with menu closed
1484
+ let $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0);
1485
+ let $activeItem = $menu.children('.' + className.active).eq(0);
1486
+ let $selectedItem = $currentlySelected.length > 0
1487
+ ? $currentlySelected
1488
+ : $activeItem;
1489
+ let $visibleItems = $selectedItem.length > 0
1490
+ ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1491
+ : $menu.children(':not(.' + className.filtered + ')');
1492
+ let $subMenu = $selectedItem.children(selector.menu);
1493
+ let $parentMenu = $selectedItem.closest(selector.menu);
1494
+ let inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0;
1495
+ let hasSubMenu = $subMenu.length > 0;
1496
+ let hasSelectedItem = $selectedItem.length > 0;
1497
+ let selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0;
1498
+ let delimiterPressed = event.key === settings.delimiter && module.is.multiple();
1499
+ let isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed);
1500
+ let $nextItem;
1501
+ let isSubMenuItem;
1502
+ // allow selection with the menu closed
1618
1503
  if (isAdditionWithoutMenu) {
1619
1504
  if (selectedIsSelectable && settings.hideAdditions) {
1620
1505
  module.verbose('Selecting item from keyboard shortcut', $selectedItem);
@@ -1630,7 +1515,7 @@
1630
1515
 
1631
1516
  // visible menu keyboard shortcuts
1632
1517
  if (module.is.visible()) {
1633
- // enter (select or open sub-menu)
1518
+ // enter (select or open submenu)
1634
1519
  if (pressedKey === keys.enter || delimiterPressed) {
1635
1520
  if (pressedKey === keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
1636
1521
  module.verbose('Pressed enter on unselectable category, opening sub menu');
@@ -1659,28 +1544,24 @@
1659
1544
  module.verbose('Left key pressed, closing sub-menu');
1660
1545
  module.animate.hide(false, $parentMenu);
1661
1546
  $selectedItem
1662
- .removeClass(className.selected)
1663
- ;
1547
+ .removeClass(className.selected);
1664
1548
  $parentMenu
1665
1549
  .closest(selector.item)
1666
- .addClass(className.selected)
1667
- ;
1550
+ .addClass(className.selected);
1668
1551
  event.preventDefault();
1669
1552
  }
1670
1553
  }
1671
1554
 
1672
- // right arrow (show sub-menu)
1555
+ // right arrow (show submenu)
1673
1556
  if (pressedKey === keys.rightArrow) {
1674
1557
  if (hasSubMenu) {
1675
1558
  module.verbose('Right key pressed, opening sub-menu');
1676
1559
  module.animate.show(false, $subMenu);
1677
1560
  $selectedItem
1678
- .removeClass(className.selected)
1679
- ;
1561
+ .removeClass(className.selected);
1680
1562
  $subMenu
1681
1563
  .find(selector.item).eq(0)
1682
- .addClass(className.selected)
1683
- ;
1564
+ .addClass(className.selected);
1684
1565
  event.preventDefault();
1685
1566
  }
1686
1567
  }
@@ -1700,11 +1581,9 @@
1700
1581
 
1701
1582
  module.verbose('Up key pressed, changing active item');
1702
1583
  $selectedItem
1703
- .removeClass(className.selected)
1704
- ;
1584
+ .removeClass(className.selected);
1705
1585
  $nextItem
1706
- .addClass(className.selected)
1707
- ;
1586
+ .addClass(className.selected);
1708
1587
  module.set.scrollPosition($nextItem);
1709
1588
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1710
1589
  module.set.selectedItem($nextItem);
@@ -1727,11 +1606,9 @@
1727
1606
 
1728
1607
  module.verbose('Down key pressed, changing active item');
1729
1608
  $item
1730
- .removeClass(className.selected)
1731
- ;
1609
+ .removeClass(className.selected);
1732
1610
  $nextItem
1733
- .addClass(className.selected)
1734
- ;
1611
+ .addClass(className.selected);
1735
1612
  module.set.scrollPosition($nextItem);
1736
1613
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1737
1614
  module.set.selectedItem($nextItem);
@@ -1763,6 +1640,7 @@
1763
1640
  }
1764
1641
  // down arrow (open menu)
1765
1642
  if (pressedKey === keys.downArrow && !module.is.visible()) {
1643
+ focused = true;
1766
1644
  module.verbose('Down key pressed, showing dropdown');
1767
1645
  module.show();
1768
1646
  event.preventDefault();
@@ -1778,11 +1656,9 @@
1778
1656
 
1779
1657
  trigger: {
1780
1658
  change: function () {
1781
- var
1782
- inputElement = $input[0]
1783
- ;
1659
+ let inputElement = $input[0];
1784
1660
  if (inputElement) {
1785
- var events = document.createEvent('HTMLEvents');
1661
+ let events = document.createEvent('HTMLEvents');
1786
1662
  module.verbose('Triggering native change event');
1787
1663
  events.initEvent('change', true, false);
1788
1664
  inputElement.dispatchEvent(events);
@@ -1806,11 +1682,9 @@
1806
1682
  selectActionActive = false;
1807
1683
  },
1808
1684
  eventInModule: function (event, callback) {
1809
- var
1810
- $target = $(event.target),
1811
- inDocument = $target.closest(document.documentElement).length > 0,
1812
- inModule = $target.closest($module).length > 0
1813
- ;
1685
+ let $target = $(event.target);
1686
+ let inDocument = $target.closest(document.documentElement).length > 0;
1687
+ let inModule = $target.closest($module).length > 0;
1814
1688
  callback = isFunction(callback)
1815
1689
  ? callback
1816
1690
  : function () {};
@@ -1826,13 +1700,11 @@
1826
1700
  return false;
1827
1701
  },
1828
1702
  eventOnElement: function (event, callback) {
1829
- var
1830
- $target = $(event.target),
1831
- $label = $target.closest(selector.siblingLabel),
1832
- inVisibleDOM = document.body.contains(event.target),
1833
- notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels),
1834
- notInMenu = $target.closest($menu).length === 0
1835
- ;
1703
+ let $target = $(event.target);
1704
+ let $label = $target.closest(selector.siblingLabel);
1705
+ let inVisibleDOM = document.body.contains(event.target);
1706
+ let notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels);
1707
+ let notInMenu = $target.closest($menu).length === 0;
1836
1708
  callback = isFunction(callback)
1837
1709
  ? callback
1838
1710
  : function () {};
@@ -1910,7 +1782,9 @@
1910
1782
  return $module.data(metadata.placeholderText) || '';
1911
1783
  },
1912
1784
  text: function () {
1913
- return settings.preserveHTML ? $text.html() : $text.text();
1785
+ return settings.preserveHTML
1786
+ ? $text.html()
1787
+ : $text.text();
1914
1788
  },
1915
1789
  query: function () {
1916
1790
  return String($search.val()).trim();
@@ -1922,13 +1796,11 @@
1922
1796
  $sizer.text(value);
1923
1797
 
1924
1798
  // prevent rounding issues
1925
- return Math.ceil($sizer.width() + (module.is.edge() ? 3 : 1));
1799
+ return Math.ceil($sizer.width() + 1);
1926
1800
  },
1927
1801
  selectionCount: function () {
1928
- var
1929
- values = module.get.values(),
1930
- count
1931
- ;
1802
+ let values = module.get.values();
1803
+ let count;
1932
1804
  count = module.is.multiple()
1933
1805
  ? (Array.isArray(values) ? values.length : 0)
1934
1806
  : (module.get.value() !== '' ? 1 : 0);
@@ -1941,9 +1813,7 @@
1941
1813
  : settings.transition;
1942
1814
  },
1943
1815
  userValues: function () {
1944
- var
1945
- values = module.get.values(true)
1946
- ;
1816
+ let values = module.get.values();
1947
1817
  if (!values) {
1948
1818
  return false;
1949
1819
  }
@@ -1961,11 +1831,9 @@
1961
1831
  });
1962
1832
  },
1963
1833
  caretPosition: function (returnEndPos) {
1964
- var
1965
- input = $search[0],
1966
- range,
1967
- rangeLength
1968
- ;
1834
+ let input = $search[0];
1835
+ let range;
1836
+ let rangeLength;
1969
1837
  if (returnEndPos && 'selectionEnd' in input) {
1970
1838
  return input.selectionEnd;
1971
1839
  }
@@ -1985,47 +1853,37 @@
1985
1853
  }
1986
1854
  },
1987
1855
  value: function () {
1988
- var
1989
- value = $input.length > 0
1990
- ? $input.val()
1991
- : $module.data(metadata.value),
1992
- isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === ''
1993
- ;
1994
-
1995
- // prevents placeholder element from being selected when multiple
1856
+ let value = $input.length > 0
1857
+ ? $input.val()
1858
+ : $module.data(metadata.value);
1859
+ let isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === '';
1860
+
1861
+ // prevents the placeholder element from being selected when multiple
1996
1862
  return value === undefined || isEmptyMultiselect
1997
1863
  ? ''
1998
1864
  : value;
1999
1865
  },
2000
- values: function (raw) {
2001
- var
2002
- value = module.get.value()
2003
- ;
1866
+ values: function () {
1867
+ let value = module.get.value();
2004
1868
  if (value === '') {
2005
1869
  return '';
2006
1870
  }
2007
1871
 
2008
1872
  return !module.has.selectInput() && module.is.multiple()
2009
1873
  ? (typeof value === 'string' // delimited string
2010
- ? (raw
2011
- ? value
2012
- : module.escape.htmlEntities(value)).split(settings.delimiter)
1874
+ ? value.split(settings.delimiter)
2013
1875
  : '')
2014
1876
  : value;
2015
1877
  },
2016
1878
  remoteValues: function () {
2017
- var
2018
- values = module.get.values(),
2019
- remoteValues = false
2020
- ;
1879
+ let values = module.get.values();
1880
+ let remoteValues = false;
2021
1881
  if (values) {
2022
1882
  if (typeof values === 'string') {
2023
1883
  values = [values];
2024
1884
  }
2025
1885
  $.each(values, function (index, value) {
2026
- var
2027
- name = module.read.remoteData(value)
2028
- ;
1886
+ let name = module.read.remoteData(value);
2029
1887
  module.verbose('Restoring value from session data', name, value);
2030
1888
  if (name) {
2031
1889
  if (!remoteValues) {
@@ -2074,9 +1932,7 @@
2074
1932
  : String(choiceText));
2075
1933
  },
2076
1934
  inputEvent: function () {
2077
- var
2078
- input = $search[0]
2079
- ;
1935
+ let input = $search[0];
2080
1936
  if (input) {
2081
1937
  return input.oninput !== undefined
2082
1938
  ? 'input'
@@ -2088,26 +1944,22 @@
2088
1944
  return false;
2089
1945
  },
2090
1946
  selectValues: function () {
2091
- var
2092
- select = {},
2093
- oldGroup = [],
2094
- values = []
2095
- ;
1947
+ let select = {};
1948
+ let oldGroup = [];
1949
+ let values = [];
2096
1950
  $module
2097
1951
  .find('option')
2098
1952
  .each(function () {
2099
- var
2100
- $option = $(this),
2101
- name = $option.html(),
2102
- disabled = $option.attr('disabled'),
2103
- value = $option.attr('value') !== undefined
2104
- ? $option.attr('value')
2105
- : name,
2106
- text = $option.data(metadata.text) !== undefined
2107
- ? $option.data(metadata.text)
2108
- : name,
2109
- group = $option.parent('optgroup')
2110
- ;
1953
+ let $option = $(this);
1954
+ let name = module.escape.assumeUnescapedAmpLtGt($option.html());
1955
+ let disabled = $option.attr('disabled');
1956
+ let value = $option.attr('value') !== undefined
1957
+ ? $option.attr('value')
1958
+ : name;
1959
+ let text = $option.data(metadata.text) !== undefined
1960
+ ? $option.data(metadata.text)
1961
+ : name;
1962
+ let group = $option.parent('optgroup');
2111
1963
  if (settings.placeholder === 'auto' && value === '') {
2112
1964
  select.placeholder = name;
2113
1965
  } else {
@@ -2122,12 +1974,11 @@
2122
1974
  values.push({
2123
1975
  name: name,
2124
1976
  value: value,
2125
- text: module.escape.htmlEntities(text, true),
1977
+ text: text,
2126
1978
  disabled: disabled,
2127
1979
  });
2128
1980
  }
2129
- })
2130
- ;
1981
+ });
2131
1982
  if (settings.placeholder && settings.placeholder !== 'auto') {
2132
1983
  module.debug('Setting placeholder value to', settings.placeholder);
2133
1984
  select.placeholder = settings.placeholder;
@@ -2157,20 +2008,16 @@
2157
2008
  return $item.filter('.' + className.active);
2158
2009
  },
2159
2010
  selectedItem: function () {
2160
- var
2161
- $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
2162
- ;
2011
+ let $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected);
2163
2012
 
2164
2013
  return $selectedItem.length > 0
2165
2014
  ? $selectedItem
2166
2015
  : $item.eq(0);
2167
2016
  },
2168
2017
  itemWithAdditions: function (value) {
2169
- var
2170
- $items = module.get.item(value),
2171
- $userItems = module.create.userChoice(value),
2172
- hasUserItems = $userItems && $userItems.length > 0
2173
- ;
2018
+ let $items = module.get.item(value);
2019
+ let $userItems = module.create.userChoice(value);
2020
+ let hasUserItems = $userItems && $userItems.length > 0;
2174
2021
  if (hasUserItems) {
2175
2022
  $items = $items.length > 0
2176
2023
  ? $items.add($userItems)
@@ -2180,11 +2027,9 @@
2180
2027
  return $items;
2181
2028
  },
2182
2029
  item: function (value, strict) {
2183
- var
2184
- $selectedItem = false,
2185
- shouldSearch,
2186
- isMultiple
2187
- ;
2030
+ let $selectedItem = false;
2031
+ let shouldSearch;
2032
+ let isMultiple;
2188
2033
  value = value !== undefined
2189
2034
  ? value
2190
2035
  : (module.get.values() !== undefined
@@ -2200,17 +2045,15 @@
2200
2045
  if (shouldSearch) {
2201
2046
  $item
2202
2047
  .each(function () {
2203
- var
2204
- $choice = $(this),
2205
- optionText = module.get.choiceText($choice),
2206
- optionValue = module.get.choiceValue($choice, optionText)
2207
- ;
2048
+ let $choice = $(this);
2049
+ let optionText = module.get.choiceText($choice);
2050
+ let optionValue = module.get.choiceValue($choice, optionText);
2208
2051
  // safe early exit
2209
2052
  if (optionValue === null || optionValue === undefined) {
2210
2053
  return;
2211
2054
  }
2212
2055
  if (isMultiple) {
2213
- if ($.inArray(module.escape.htmlEntities(String(optionValue)), value.map(String).map(module.escape.htmlEntities)) !== -1) {
2056
+ if ($.inArray(String(optionValue), value.map(String)) !== -1) {
2214
2057
  $selectedItem = $selectedItem
2215
2058
  ? $selectedItem.add($choice)
2216
2059
  : $choice;
@@ -2227,15 +2070,14 @@
2227
2070
  optionValue = optionValue.toLowerCase();
2228
2071
  value = value.toLowerCase();
2229
2072
  }
2230
- if (module.escape.htmlEntities(String(optionValue)) === module.escape.htmlEntities(String(value))) {
2073
+ if (String(optionValue) === String(value)) {
2231
2074
  module.verbose('Found select item by value', optionValue, value);
2232
2075
  $selectedItem = $choice;
2233
2076
 
2234
2077
  return true;
2235
2078
  }
2236
2079
  }
2237
- })
2238
- ;
2080
+ });
2239
2081
  }
2240
2082
 
2241
2083
  return $selectedItem;
@@ -2285,10 +2127,8 @@
2285
2127
  module.restore.defaultValue();
2286
2128
  },
2287
2129
  defaultText: function () {
2288
- var
2289
- defaultText = module.get.defaultText(),
2290
- placeholderText = module.get.placeholderText
2291
- ;
2130
+ let defaultText = module.get.defaultText();
2131
+ let placeholderText = module.get.placeholderText;
2292
2132
  if (defaultText === placeholderText) {
2293
2133
  module.debug('Restoring default placeholder text', defaultText);
2294
2134
  module.set.placeholderText(defaultText);
@@ -2301,9 +2141,7 @@
2301
2141
  module.set.placeholderText();
2302
2142
  },
2303
2143
  defaultValue: function () {
2304
- var
2305
- defaultValue = module.get.defaultValue()
2306
- ;
2144
+ let defaultValue = module.get.defaultValue();
2307
2145
  if (defaultValue !== undefined) {
2308
2146
  module.debug('Restoring default value', defaultValue);
2309
2147
  if (defaultValue !== '') {
@@ -2336,14 +2174,14 @@
2336
2174
  }
2337
2175
  },
2338
2176
  values: function () {
2339
- // prevents callbacks from occurring on initial load
2177
+ // prevents callbacks from occurring on the initial load
2340
2178
  module.set.initialLoad();
2341
2179
  if (settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) {
2342
2180
  module.restore.remoteValues();
2343
2181
  } else {
2344
2182
  module.set.selected();
2345
2183
  }
2346
- var value = module.get.value();
2184
+ let value = module.get.value();
2347
2185
  if (value && value !== '' && !(Array.isArray(value) && value.length === 0)) {
2348
2186
  $input.removeClass(className.noselection);
2349
2187
  } else {
@@ -2352,9 +2190,7 @@
2352
2190
  module.remove.initialLoad();
2353
2191
  },
2354
2192
  remoteValues: function () {
2355
- var
2356
- values = module.get.remoteValues()
2357
- ;
2193
+ let values = module.get.remoteValues();
2358
2194
  module.debug('Recreating selected from session data', values);
2359
2195
  if (values) {
2360
2196
  if (module.is.single()) {
@@ -2372,9 +2208,7 @@
2372
2208
 
2373
2209
  read: {
2374
2210
  remoteData: function (value) {
2375
- var
2376
- name
2377
- ;
2211
+ let name;
2378
2212
  if (window.Storage === undefined) {
2379
2213
  module.error(error.noStorage);
2380
2214
 
@@ -2395,23 +2229,17 @@
2395
2229
  module.save.defaultValue();
2396
2230
  },
2397
2231
  defaultValue: function () {
2398
- var
2399
- value = module.get.value()
2400
- ;
2232
+ let value = module.get.value();
2401
2233
  module.verbose('Saving default value as', value);
2402
2234
  $module.data(metadata.defaultValue, value);
2403
2235
  },
2404
2236
  defaultText: function () {
2405
- var
2406
- text = module.get.text()
2407
- ;
2237
+ let text = module.get.text();
2408
2238
  module.verbose('Saving default text as', text);
2409
2239
  $module.data(metadata.defaultText, text);
2410
2240
  },
2411
2241
  placeholderText: function () {
2412
- var
2413
- text
2414
- ;
2242
+ let text;
2415
2243
  if (settings.placeholder !== false && $text.hasClass(className.placeholder)) {
2416
2244
  text = module.get.text();
2417
2245
  module.verbose('Saving placeholder text as', text);
@@ -2451,21 +2279,19 @@
2451
2279
  },
2452
2280
 
2453
2281
  scrollPage: function (direction, $selectedItem) {
2454
- var
2455
- $currentItem = $selectedItem || module.get.selectedItem(),
2456
- $menu = $currentItem.closest(selector.menu),
2457
- menuHeight = $menu.outerHeight(),
2458
- currentScroll = $menu.scrollTop(),
2459
- itemHeight = $item.eq(0).outerHeight(),
2460
- itemsPerPage = Math.floor(menuHeight / itemHeight),
2461
- newScroll = direction === 'up'
2462
- ? currentScroll - (itemHeight * itemsPerPage)
2463
- : currentScroll + (itemHeight * itemsPerPage),
2464
- $selectableItem = $item.not(selector.unselectable),
2465
- isWithinRange,
2466
- $nextSelectedItem,
2467
- elementIndex
2468
- ;
2282
+ let $currentItem = $selectedItem || module.get.selectedItem();
2283
+ let $menu = $currentItem.closest(selector.menu);
2284
+ let menuHeight = $menu.outerHeight();
2285
+ let currentScroll = $menu.scrollTop();
2286
+ let itemHeight = $item.eq(0).outerHeight();
2287
+ let itemsPerPage = Math.floor(menuHeight / itemHeight);
2288
+ let newScroll = direction === 'up'
2289
+ ? currentScroll - (itemHeight * itemsPerPage)
2290
+ : currentScroll + (itemHeight * itemsPerPage);
2291
+ let $selectableItem = $item.not(selector.unselectable);
2292
+ let isWithinRange;
2293
+ let $nextSelectedItem;
2294
+ let elementIndex;
2469
2295
  elementIndex = direction === 'up'
2470
2296
  ? $selectableItem.index($currentItem) - itemsPerPage
2471
2297
  : $selectableItem.index($currentItem) + itemsPerPage;
@@ -2480,33 +2306,28 @@
2480
2306
  if ($nextSelectedItem.length > 0) {
2481
2307
  module.debug('Scrolling page', direction, $nextSelectedItem);
2482
2308
  $currentItem
2483
- .removeClass(className.selected)
2484
- ;
2309
+ .removeClass(className.selected);
2485
2310
  $nextSelectedItem
2486
- .addClass(className.selected)
2487
- ;
2311
+ .addClass(className.selected);
2488
2312
  if (settings.selectOnKeydown && module.is.single() && !$nextSelectedItem.hasClass(className.actionable)) {
2489
2313
  module.set.selectedItem($nextSelectedItem);
2490
2314
  }
2491
2315
  $menu
2492
- .scrollTop(newScroll)
2493
- ;
2316
+ .scrollTop(newScroll);
2494
2317
  }
2495
2318
  },
2496
2319
 
2497
2320
  set: {
2498
2321
  filtered: function () {
2499
- var
2500
- isMultiple = module.is.multiple(),
2501
- isSearch = module.is.searchSelection(),
2502
- isSearchMultiple = isMultiple && isSearch,
2503
- searchValue = isSearch
2504
- ? module.get.query()
2505
- : '',
2506
- hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0,
2507
- searchWidth = module.get.searchWidth(),
2508
- valueIsSet = searchValue !== ''
2509
- ;
2322
+ let isMultiple = module.is.multiple();
2323
+ let isSearch = module.is.searchSelection();
2324
+ let isSearchMultiple = isMultiple && isSearch;
2325
+ let searchValue = isSearch
2326
+ ? module.get.query()
2327
+ : '';
2328
+ let hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0;
2329
+ let searchWidth = module.get.searchWidth();
2330
+ let valueIsSet = searchValue !== '';
2510
2331
  if (isMultiple && hasSearchValue) {
2511
2332
  module.verbose('Adjusting input width', searchWidth);
2512
2333
  $search.css('width', searchWidth + 'px');
@@ -2535,21 +2356,17 @@
2535
2356
  if (module.is.searchSelection()) {
2536
2357
  module.debug('Added tabindex to searchable dropdown');
2537
2358
  $search
2538
- .val('')
2539
- ;
2359
+ .val('');
2540
2360
  module.check.disabled();
2541
2361
  $menu
2542
- .attr('tabindex', -1)
2543
- ;
2362
+ .attr('tabindex', -1);
2544
2363
  } else {
2545
2364
  module.debug('Added tabindex to dropdown');
2546
2365
  if ($module.attr('tabindex') === undefined) {
2547
2366
  $module
2548
- .attr('tabindex', $input.attr('tabindex') || 0)
2549
- ;
2367
+ .attr('tabindex', $input.attr('tabindex') || 0);
2550
2368
  $menu
2551
- .attr('tabindex', -1)
2552
- ;
2369
+ .attr('tabindex', -1);
2553
2370
  }
2554
2371
  }
2555
2372
  $input.removeAttr('tabindex');
@@ -2566,24 +2383,20 @@
2566
2383
  }
2567
2384
  },
2568
2385
  partialSearch: function (text) {
2569
- var
2570
- length = module.get.query().length
2571
- ;
2386
+ let length = module.get.query().length;
2572
2387
  $search.val(text.slice(0, length));
2573
2388
  },
2574
2389
  scrollPosition: function ($item, forceScroll) {
2575
- var
2576
- edgeTolerance = 5,
2577
- $menu,
2578
- hasActive,
2579
- offset,
2580
- itemOffset,
2581
- menuOffset,
2582
- menuScroll,
2583
- menuHeight,
2584
- abovePage,
2585
- belowPage
2586
- ;
2390
+ let edgeTolerance = 5;
2391
+ let $menu;
2392
+ let hasActive;
2393
+ let offset;
2394
+ let itemOffset;
2395
+ let menuOffset;
2396
+ let menuScroll;
2397
+ let menuHeight;
2398
+ let abovePage;
2399
+ let belowPage;
2587
2400
 
2588
2401
  $item = $item || module.get.selectedItem();
2589
2402
  $menu = $item.closest(selector.menu);
@@ -2628,8 +2441,7 @@
2628
2441
  }
2629
2442
  module.debug('Changing text', text, $text);
2630
2443
  $text
2631
- .removeClass(className.filtered)
2632
- ;
2444
+ .removeClass(className.filtered);
2633
2445
  if (settings.preserveHTML) {
2634
2446
  $text.html(text);
2635
2447
  } else {
@@ -2638,11 +2450,9 @@
2638
2450
  }
2639
2451
  },
2640
2452
  selectedItem: function ($item) {
2641
- var
2642
- value = module.get.choiceValue($item),
2643
- searchText = module.get.choiceText($item, false),
2644
- text = module.get.choiceText($item)
2645
- ;
2453
+ let value = module.get.choiceValue($item);
2454
+ let searchText = module.get.choiceText($item, false);
2455
+ let text = module.get.choiceText($item);
2646
2456
  module.debug('Setting user selection to item', $item);
2647
2457
  module.remove.activeItem();
2648
2458
  module.set.partialSearch(searchText);
@@ -2651,13 +2461,11 @@
2651
2461
  module.set.text(text);
2652
2462
  },
2653
2463
  selectedLetter: function (letter) {
2654
- var
2655
- $selectedItem = $item.filter('.' + className.selected),
2656
- alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
2657
- $nextValue = false,
2658
- $nextItem
2659
- ;
2660
- // check next of same letter
2464
+ let $selectedItem = $item.filter('.' + className.selected);
2465
+ let alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter);
2466
+ let $nextValue = false;
2467
+ let $nextItem;
2468
+ // check next of the same letter
2661
2469
  if (alreadySelectedLetter) {
2662
2470
  $nextItem = $selectedItem.nextAll($item).eq(0);
2663
2471
  if (module.has.firstLetter($nextItem, letter)) {
@@ -2673,10 +2481,9 @@
2673
2481
 
2674
2482
  return false;
2675
2483
  }
2676
- })
2677
- ;
2484
+ });
2678
2485
  }
2679
- // set next value
2486
+ // set the next value
2680
2487
  if ($nextValue) {
2681
2488
  module.verbose('Scrolling to next value with letter', letter);
2682
2489
  module.set.scrollPosition($nextValue);
@@ -2693,7 +2500,7 @@
2693
2500
  if (!$menu) {
2694
2501
  module.remove.upward();
2695
2502
  } else if (module.is.upward($menu)) {
2696
- // we need make sure when make assertion openDownward for $menu, $menu does not have upward class
2503
+ // we need to make sure when make assertion openDownward for $menu, $menu does not have upward class
2697
2504
  module.remove.upward($menu);
2698
2505
  }
2699
2506
 
@@ -2710,11 +2517,11 @@
2710
2517
  }
2711
2518
  },
2712
2519
  upward: function ($currentMenu) {
2713
- var $element = $currentMenu || $module;
2520
+ let $element = $currentMenu || $module;
2714
2521
  $element.addClass(className.upward);
2715
2522
  },
2716
2523
  leftward: function ($currentMenu) {
2717
- var $element = $currentMenu || $menu;
2524
+ let $element = $currentMenu || $menu;
2718
2525
  $element.addClass(className.leftward);
2719
2526
  },
2720
2527
  value: function (value, text, $selected, preventChangeTrigger) {
@@ -2728,14 +2535,11 @@
2728
2535
  } else {
2729
2536
  $input.addClass(className.noselection);
2730
2537
  }
2731
- var
2732
- escapedValue = module.escape.value(value),
2733
- hasInput = $input.length > 0,
2734
- currentValue = module.get.values(),
2735
- stringValue = value !== undefined
2736
- ? String(value)
2737
- : value
2738
- ;
2538
+ let hasInput = $input.length > 0;
2539
+ let currentValue = module.get.values();
2540
+ let stringValue = value !== undefined
2541
+ ? String(value)
2542
+ : value;
2739
2543
  if (hasInput) {
2740
2544
  if (!settings.allowReselection && stringValue == currentValue) {
2741
2545
  module.verbose('Skipping value update already same value', value, currentValue);
@@ -2748,11 +2552,10 @@
2748
2552
  module.debug('Adding user option', value);
2749
2553
  module.add.optionValue(value);
2750
2554
  }
2751
- module.debug('Updating input value', escapedValue, currentValue);
2555
+ module.debug('Updating input value', value, currentValue);
2752
2556
  internalChange = true;
2753
2557
  $input
2754
- .val(escapedValue)
2755
- ;
2558
+ .val(value);
2756
2559
  if (settings.fireOnInit === false && module.is.initialLoad()) {
2757
2560
  module.debug('Input native change event ignored on initial load');
2758
2561
  } else if (preventChangeTrigger !== true) {
@@ -2760,8 +2563,8 @@
2760
2563
  }
2761
2564
  internalChange = false;
2762
2565
  } else {
2763
- module.verbose('Storing value in metadata', escapedValue, $input);
2764
- if (escapedValue !== currentValue) {
2566
+ module.verbose('Storing value in metadata', value, $input);
2567
+ if (value !== currentValue) {
2765
2568
  $module.data(metadata.value, stringValue);
2766
2569
  }
2767
2570
  }
@@ -2773,8 +2576,7 @@
2773
2576
  },
2774
2577
  active: function () {
2775
2578
  $module
2776
- .addClass(className.active)
2777
- ;
2579
+ .addClass(className.active);
2778
2580
  },
2779
2581
  multiple: function () {
2780
2582
  $module.addClass(className.multiple);
@@ -2797,9 +2599,7 @@
2797
2599
  preventChangeTrigger = $selectedItem;
2798
2600
  $selectedItem = undefined;
2799
2601
  }
2800
- var
2801
- isMultiple = module.is.multiple()
2802
- ;
2602
+ let isMultiple = module.is.multiple();
2803
2603
  $selectedItem = settings.allowAdditions
2804
2604
  ? $selectedItem || module.get.itemWithAdditions(value)
2805
2605
  : $selectedItem || module.get.item(value);
@@ -2827,17 +2627,15 @@
2827
2627
  // select each item
2828
2628
  $selectedItem
2829
2629
  .each(function () {
2830
- var
2831
- $selected = $(this),
2832
- selectedText = module.get.choiceText($selected),
2833
- selectedValue = module.get.choiceValue($selected, selectedText),
2834
-
2835
- isFiltered = $selected.hasClass(className.filtered),
2836
- isActive = $selected.hasClass(className.active),
2837
- isActionable = $selected.hasClass(className.actionable),
2838
- isUserValue = $selected.hasClass(className.addition),
2839
- shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1
2840
- ;
2630
+ let $selected = $(this);
2631
+ let selectedText = module.get.choiceText($selected);
2632
+ let selectedValue = module.get.choiceValue($selected, selectedText);
2633
+
2634
+ let isFiltered = $selected.hasClass(className.filtered);
2635
+ let isActive = $selected.hasClass(className.active);
2636
+ let isActionable = $selected.hasClass(className.actionable);
2637
+ let isUserValue = $selected.hasClass(className.addition);
2638
+ let shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1;
2841
2639
  if (isActionable) {
2842
2640
  if ((!isMultiple || (!isActive || isUserValue)) && settings.apiSettings && settings.saveRemoteData) {
2843
2641
  module.save.remoteData(selectedText, selectedValue);
@@ -2873,11 +2671,9 @@
2873
2671
  module.set.value(selectedValue, selectedText, $selected, preventChangeTrigger);
2874
2672
  $selected
2875
2673
  .addClass(className.active)
2876
- .addClass(className.selected)
2877
- ;
2674
+ .addClass(className.selected);
2878
2675
  }
2879
- })
2880
- ;
2676
+ });
2881
2677
  if (!keepSearchTerm) {
2882
2678
  module.remove.searchTerm();
2883
2679
  }
@@ -2890,25 +2686,21 @@
2890
2686
 
2891
2687
  add: {
2892
2688
  label: function (value, text, shouldAnimate) {
2893
- var
2894
- $next = module.is.searchSelection()
2895
- ? $search
2896
- : $text,
2897
- escapedValue = module.escape.value(value),
2898
- $label
2899
- ;
2689
+ let $next = module.is.searchSelection()
2690
+ ? $search
2691
+ : $text;
2692
+ let $label;
2900
2693
  if (settings.ignoreCase) {
2901
- escapedValue = escapedValue.toLowerCase();
2694
+ value = value.toLowerCase();
2902
2695
  }
2903
2696
  $label = $('<a />')
2904
2697
  .addClass(className.label)
2905
- .attr('data-' + metadata.value, escapedValue)
2906
- .html(templates.label(escapedValue, text, settings.preserveHTML, settings.className))
2907
- ;
2908
- $label = settings.onLabelCreate.call($label, escapedValue, text);
2698
+ .attr('data-' + metadata.value, value)
2699
+ .html(templates.label(value, text, settings));
2700
+ $label = settings.onLabelCreate.call($label, value, text);
2909
2701
 
2910
2702
  if (module.has.label(value)) {
2911
- module.debug('User selection already exists, skipping', escapedValue);
2703
+ module.debug('User selection already exists, skipping', value);
2912
2704
 
2913
2705
  return;
2914
2706
  }
@@ -2926,38 +2718,29 @@
2926
2718
  verbose: settings.verbose,
2927
2719
  silent: settings.silent,
2928
2720
  duration: settings.label.duration,
2929
- })
2930
- ;
2721
+ });
2931
2722
  } else {
2932
2723
  module.debug('Adding selection label', $label);
2933
2724
  $label
2934
- .insertBefore($next)
2935
- ;
2725
+ .insertBefore($next);
2936
2726
  }
2937
2727
  },
2938
2728
  message: function (message) {
2939
- var
2940
- $message = $menu.children(selector.message),
2941
- html = settings.templates.message(module.add.variables(message))
2942
- ;
2729
+ let $message = $menu.children(selector.message);
2730
+ let html = settings.templates.message(module.add.variables(message));
2943
2731
  if ($message.length > 0) {
2944
2732
  $message
2945
- .html(html)
2946
- ;
2733
+ .html(html);
2947
2734
  } else {
2948
2735
  $('<div/>')
2949
2736
  .html(html)
2950
2737
  .addClass(className.message)
2951
- .appendTo($menu)
2952
- ;
2738
+ .appendTo($menu);
2953
2739
  }
2954
2740
  },
2955
2741
  optionValue: function (value) {
2956
- var
2957
- escapedValue = module.escape.value(value),
2958
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
2959
- hasOption = $option.length > 0
2960
- ;
2742
+ let $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2743
+ let hasOption = $option.length > 0;
2961
2744
  if (hasOption) {
2962
2745
  return;
2963
2746
  }
@@ -2968,22 +2751,19 @@
2968
2751
  $input.find('option.' + className.addition).remove();
2969
2752
  }
2970
2753
  $('<option/>')
2971
- .prop('value', escapedValue)
2754
+ .prop('value', value)
2972
2755
  .addClass(className.addition)
2973
2756
  .text(value)
2974
- .appendTo($input)
2975
- ;
2757
+ .appendTo($input);
2976
2758
  module.verbose('Adding user addition as an <option>', value);
2977
2759
  module.observe.select();
2978
2760
  },
2979
2761
  userSuggestion: function (value) {
2980
- var
2981
- $addition = $menu.children(selector.addition),
2982
- $existingItem = module.get.item(value),
2983
- alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0,
2984
- hasUserSuggestion = $addition.length > 0,
2985
- html
2986
- ;
2762
+ let $addition = $menu.children(selector.addition);
2763
+ let $existingItem = module.get.item(value);
2764
+ let alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0;
2765
+ let hasUserSuggestion = $addition.length > 0;
2766
+ let html;
2987
2767
  if (settings.useLabels && module.has.maxSelections()) {
2988
2768
  return;
2989
2769
  }
@@ -2998,38 +2778,32 @@
2998
2778
  .data(metadata.text, value)
2999
2779
  .attr('data-' + metadata.value, value)
3000
2780
  .attr('data-' + metadata.text, value)
3001
- .removeClass(className.filtered)
3002
- ;
2781
+ .removeClass(className.filtered);
3003
2782
  if (!settings.hideAdditions) {
3004
- html = settings.templates.addition(module.add.variables(message.addResult, value));
2783
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
3005
2784
  $addition
3006
- .html(html)
3007
- ;
2785
+ .html(html);
3008
2786
  }
3009
2787
  module.verbose('Replacing user suggestion with new value', $addition);
3010
2788
  } else {
3011
2789
  $addition = module.create.userChoice(value);
3012
2790
  $addition
3013
- .prependTo($menu)
3014
- ;
2791
+ .prependTo($menu);
3015
2792
  module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
3016
2793
  }
3017
2794
  if (!settings.hideAdditions || module.is.allFiltered()) {
3018
2795
  $addition
3019
2796
  .addClass(className.selected)
3020
2797
  .siblings()
3021
- .removeClass(className.selected)
3022
- ;
2798
+ .removeClass(className.selected);
3023
2799
  }
3024
2800
  module.refreshItems();
3025
2801
  },
3026
2802
  variables: function (message, term) {
3027
- var
3028
- hasCount = message.search('{count}') !== -1,
3029
- hasMaxCount = message.search('{maxCount}') !== -1,
3030
- hasTerm = message.search('{term}') !== -1,
3031
- query
3032
- ;
2803
+ let hasCount = message.search('{count}') !== -1;
2804
+ let hasMaxCount = message.search('{maxCount}') !== -1;
2805
+ let hasTerm = message.search('{term}') !== -1;
2806
+ let query;
3033
2807
  module.verbose('Adding templated variables to message', message);
3034
2808
  if (hasCount) {
3035
2809
  message = message.replace('{count}', module.get.selectionCount());
@@ -3050,10 +2824,8 @@
3050
2824
  $selectedItem = undefined;
3051
2825
  addedText = undefined;
3052
2826
  }
3053
- var
3054
- currentValue = module.get.values(true),
3055
- newValue
3056
- ;
2827
+ let currentValue = module.get.values();
2828
+ let newValue;
3057
2829
  if (module.has.value(addedValue)) {
3058
2830
  module.debug('Value already selected');
3059
2831
 
@@ -3066,7 +2838,9 @@
3066
2838
  }
3067
2839
  // extend current array
3068
2840
  if (Array.isArray(currentValue)) {
3069
- newValue = $selectedItem && $selectedItem.hasClass(className.actionable) ? currentValue : currentValue.concat([addedValue]);
2841
+ newValue = $selectedItem && $selectedItem.hasClass(className.actionable)
2842
+ ? currentValue
2843
+ : currentValue.concat([addedValue]);
3070
2844
  newValue = module.get.uniqueArray(newValue);
3071
2845
  } else {
3072
2846
  newValue = [addedValue];
@@ -3109,11 +2883,11 @@
3109
2883
  initialLoad = false;
3110
2884
  },
3111
2885
  upward: function ($currentMenu) {
3112
- var $element = $currentMenu || $module;
2886
+ let $element = $currentMenu || $module;
3113
2887
  $element.removeClass(className.upward);
3114
2888
  },
3115
2889
  leftward: function ($currentMenu) {
3116
- var $element = $currentMenu || $menu;
2890
+ let $element = $currentMenu || $menu;
3117
2891
  $element.removeClass(className.leftward);
3118
2892
  },
3119
2893
  visible: function () {
@@ -3125,7 +2899,7 @@
3125
2899
  filteredItem: function () {
3126
2900
  if (settings.highlightMatches) {
3127
2901
  $.each($item, function (index, item) {
3128
- var $markItem = $(item);
2902
+ let $markItem = $(item);
3129
2903
  $markItem.html($markItem.html().replace(/<\/?mark>/g, ''));
3130
2904
  });
3131
2905
  }
@@ -3143,18 +2917,15 @@
3143
2917
  module.remove.empty();
3144
2918
  },
3145
2919
  optionValue: function (value) {
3146
- var
3147
- escapedValue = module.escape.value(value),
3148
- $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
3149
- hasOption = $option.length > 0
3150
- ;
2920
+ let $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2921
+ let hasOption = $option.length > 0;
3151
2922
  if (!hasOption || !$option.hasClass(className.addition)) {
3152
2923
  return;
3153
2924
  }
3154
2925
  // temporarily disconnect observer
3155
2926
  module.disconnect.selectObserver();
3156
2927
  $option.remove();
3157
- module.verbose('Removing user addition as an <option>', escapedValue);
2928
+ module.verbose('Removing user addition as an <option>', value);
3158
2929
  module.observe.select();
3159
2930
  },
3160
2931
  message: function () {
@@ -3182,11 +2953,9 @@
3182
2953
 
3183
2954
  $selectedItem
3184
2955
  .each(function () {
3185
- var
3186
- $selected = $(this),
3187
- selectedText = module.get.choiceText($selected),
3188
- selectedValue = module.get.choiceValue($selected, selectedText)
3189
- ;
2956
+ let $selected = $(this);
2957
+ let selectedText = module.get.choiceText($selected);
2958
+ let selectedValue = module.get.choiceValue($selected, selectedText);
3190
2959
  if (module.is.multiple()) {
3191
2960
  if (settings.useLabels) {
3192
2961
  module.remove.value(selectedValue, selectedText, $selected, preventChangeTrigger);
@@ -3204,22 +2973,18 @@
3204
2973
  }
3205
2974
  $selected
3206
2975
  .removeClass(className.filtered)
3207
- .removeClass(className.active)
3208
- ;
2976
+ .removeClass(className.active);
3209
2977
  if (settings.useLabels) {
3210
2978
  $selected.removeClass(className.selected);
3211
2979
  }
3212
- })
3213
- ;
2980
+ });
3214
2981
  },
3215
2982
  selectedItem: function () {
3216
2983
  $item.removeClass(className.selected);
3217
2984
  },
3218
2985
  value: function (removedValue, removedText, $removedItem, preventChangeTrigger) {
3219
- var
3220
- values = module.get.values(true),
3221
- newValue
3222
- ;
2986
+ let values = module.get.values();
2987
+ let newValue;
3223
2988
  if (module.has.selectInput()) {
3224
2989
  module.verbose('Input is <select> removing selected option', removedValue);
3225
2990
  newValue = module.remove.arrayValue(removedValue, values);
@@ -3249,11 +3014,8 @@
3249
3014
  return values;
3250
3015
  },
3251
3016
  label: function (value, shouldAnimate) {
3252
- var
3253
- escapedValue = module.escape.value(value),
3254
- $labels = $module.find(selector.label),
3255
- $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(settings.ignoreCase ? escapedValue.toLowerCase() : escapedValue) + '"]')
3256
- ;
3017
+ let $labels = $module.find(selector.label);
3018
+ let $removedLabel = $labels.filter('[data-' + metadata.value + '="' + CSS.escape(settings.ignoreCase ? value.toLowerCase() : value) + '"]');
3257
3019
  module.verbose('Removing label', $removedLabel);
3258
3020
  $removedLabel.remove();
3259
3021
  },
@@ -3267,14 +3029,12 @@
3267
3029
  module.verbose('Removing labels', $labels);
3268
3030
  $labels
3269
3031
  .each(function () {
3270
- var
3271
- $label = $(this),
3272
- value = $label.data(metadata.value),
3273
- stringValue = value !== undefined
3274
- ? String(value)
3275
- : value,
3276
- isUserValue = module.is.userValue(stringValue)
3277
- ;
3032
+ let $label = $(this);
3033
+ let value = $label.data(metadata.value);
3034
+ let stringValue = value !== undefined
3035
+ ? String(value)
3036
+ : value;
3037
+ let isUserValue = module.is.userValue(stringValue);
3278
3038
  if (settings.onLabelRemove.call($label, value) === false) {
3279
3039
  module.debug('Label remove callback cancelled removal');
3280
3040
 
@@ -3288,26 +3048,21 @@
3288
3048
  // selected will also remove label
3289
3049
  module.remove.selected(stringValue, false, preventChangeTrigger);
3290
3050
  }
3291
- })
3292
- ;
3051
+ });
3293
3052
  },
3294
3053
  tabbable: function () {
3295
3054
  if (module.is.searchSelection()) {
3296
3055
  module.debug('Searchable dropdown initialized');
3297
3056
  $search
3298
- .removeAttr('tabindex')
3299
- ;
3057
+ .removeAttr('tabindex');
3300
3058
  $menu
3301
- .removeAttr('tabindex')
3302
- ;
3059
+ .removeAttr('tabindex');
3303
3060
  } else {
3304
3061
  module.debug('Simple selection dropdown initialized');
3305
3062
  $module
3306
- .removeAttr('tabindex')
3307
- ;
3063
+ .removeAttr('tabindex');
3308
3064
  $menu
3309
- .removeAttr('tabindex')
3310
- ;
3065
+ .removeAttr('tabindex');
3311
3066
  }
3312
3067
  },
3313
3068
  diacritics: function (text) {
@@ -3344,10 +3099,8 @@
3344
3099
  return true;
3345
3100
  },
3346
3101
  firstLetter: function ($item, letter) {
3347
- var
3348
- text,
3349
- firstLetter
3350
- ;
3102
+ let text;
3103
+ let firstLetter;
3351
3104
  if (!$item || $item.length === 0 || typeof letter !== 'string') {
3352
3105
  return false;
3353
3106
  }
@@ -3373,23 +3126,18 @@
3373
3126
  return $menu.children(selector.message).length > 0;
3374
3127
  },
3375
3128
  label: function (value) {
3376
- var
3377
- escapedValue = module.escape.value(value),
3378
- $labels = $module.find(selector.label)
3379
- ;
3129
+ let $labels = $module.find(selector.label);
3380
3130
  if (settings.ignoreCase) {
3381
- escapedValue = escapedValue.toLowerCase();
3131
+ value = value.toLowerCase();
3382
3132
  }
3383
3133
 
3384
- return $labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) + '"]').length > 0;
3134
+ return $labels.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]').length > 0;
3385
3135
  },
3386
3136
  maxSelections: function () {
3387
3137
  return settings.maxSelections && module.get.selectionCount() >= settings.maxSelections;
3388
3138
  },
3389
3139
  allResultsFiltered: function () {
3390
- var
3391
- $normalResults = $item.not(selector.addition)
3392
- ;
3140
+ let $normalResults = $item.not(selector.addition);
3393
3141
 
3394
3142
  return $normalResults.filter(selector.unselectable).length === $normalResults.length;
3395
3143
  },
@@ -3405,20 +3153,16 @@
3405
3153
  : module.has.valueMatchingCase(value);
3406
3154
  },
3407
3155
  valueMatchingCase: function (value) {
3408
- var
3409
- values = module.get.values(true),
3410
- hasValue = Array.isArray(values)
3411
- ? values && ($.inArray(value, values) !== -1)
3412
- : values == value
3413
- ;
3156
+ let values = module.get.values();
3157
+ let hasValue = Array.isArray(values)
3158
+ ? values && ($.inArray(value, values) !== -1)
3159
+ : values == value;
3414
3160
 
3415
3161
  return !!hasValue;
3416
3162
  },
3417
3163
  valueIgnoringCase: function (value) {
3418
- var
3419
- values = module.get.values(true),
3420
- hasValue = false
3421
- ;
3164
+ let values = module.get.values();
3165
+ let hasValue = false;
3422
3166
  if (!Array.isArray(values)) {
3423
3167
  values = [values];
3424
3168
  }
@@ -3450,9 +3194,6 @@
3450
3194
  bubbledIconClick: function (event) {
3451
3195
  return $(event.target).closest($icon).length > 0;
3452
3196
  },
3453
- edge: function () {
3454
- return !!window.chrome && !!window.StyleMedia;
3455
- },
3456
3197
  empty: function () {
3457
3198
  return $module.hasClass(className.empty);
3458
3199
  },
@@ -3468,12 +3209,12 @@
3468
3209
  : $menu.transition && $menu.transition('is animating');
3469
3210
  },
3470
3211
  leftward: function ($subMenu) {
3471
- var $selectedMenu = $subMenu || $menu;
3212
+ let $selectedMenu = $subMenu || $menu;
3472
3213
 
3473
3214
  return $selectedMenu.hasClass(className.leftward);
3474
3215
  },
3475
3216
  clearable: function () {
3476
- var hasClearableClass = $module.hasClass(className.clearable);
3217
+ let hasClearableClass = $module.hasClass(className.clearable);
3477
3218
  if (!hasClearableClass && settings.clearable) {
3478
3219
  $module.addClass(className.clearable);
3479
3220
  }
@@ -3499,9 +3240,7 @@
3499
3240
  return initialLoad;
3500
3241
  },
3501
3242
  inObject: function (needle, object) {
3502
- var
3503
- found = false
3504
- ;
3243
+ let found = false;
3505
3244
  $.each(object, function (index, property) {
3506
3245
  if (property == needle) {
3507
3246
  found = true;
@@ -3525,9 +3264,7 @@
3525
3264
  return !module.is.multiple();
3526
3265
  },
3527
3266
  selectMutation: function (mutations) {
3528
- var
3529
- selectChanged = false
3530
- ;
3267
+ let selectChanged = false;
3531
3268
  $.each(mutations, function (index, mutation) {
3532
3269
  if ($(mutation.target).is('option, optgroup') || $(mutation.addedNodes).is('select') || ($(mutation.target).is('select') && mutation.type !== 'attributes')) {
3533
3270
  selectChanged = true;
@@ -3551,7 +3288,7 @@
3551
3288
  return $.inArray(value, module.get.userValues()) !== -1;
3552
3289
  },
3553
3290
  upward: function ($menu) {
3554
- var $element = $menu || $module;
3291
+ let $element = $menu || $module;
3555
3292
 
3556
3293
  return $element.hasClass(className.upward);
3557
3294
  },
@@ -3561,20 +3298,16 @@
3561
3298
  : $menu.hasClass(className.visible);
3562
3299
  },
3563
3300
  verticallyScrollableContext: function () {
3564
- var
3565
- overflowY = $context[0] !== window
3566
- ? $context.css('overflow-y')
3567
- : false
3568
- ;
3301
+ let overflowY = $context[0] !== window
3302
+ ? $context.css('overflow-y')
3303
+ : false;
3569
3304
 
3570
3305
  return overflowY === 'auto' || overflowY === 'scroll';
3571
3306
  },
3572
3307
  horizontallyScrollableContext: function () {
3573
- var
3574
- overflowX = $context[0] !== window
3575
- ? $context.css('overflow-X')
3576
- : false
3577
- ;
3308
+ let overflowX = $context[0] !== window
3309
+ ? $context.css('overflow-X')
3310
+ : false;
3578
3311
 
3579
3312
  return overflowX === 'auto' || overflowX === 'scroll';
3580
3313
  },
@@ -3589,15 +3322,12 @@
3589
3322
  );
3590
3323
  },
3591
3324
  openDownward: function ($subMenu) {
3592
- var
3593
- $currentMenu = $subMenu || $menu,
3594
- canOpenDownward,
3595
- onScreen,
3596
- calculations
3597
- ;
3325
+ let $currentMenu = $subMenu || $menu;
3326
+ let canOpenDownward;
3327
+ let onScreen;
3328
+ let calculations;
3598
3329
  $currentMenu
3599
- .addClass(className.loading)
3600
- ;
3330
+ .addClass(className.loading);
3601
3331
  calculations = {
3602
3332
  context: {
3603
3333
  offset: $context[0] === window
@@ -3636,15 +3366,12 @@
3636
3366
  return canOpenDownward;
3637
3367
  },
3638
3368
  openRightward: function ($subMenu) {
3639
- var
3640
- $currentMenu = $subMenu || $menu,
3641
- canOpenRightward = true,
3642
- isOffscreenRight = false,
3643
- calculations
3644
- ;
3369
+ let $currentMenu = $subMenu || $menu;
3370
+ let canOpenRightward = true;
3371
+ let isOffscreenRight = false;
3372
+ let calculations;
3645
3373
  $currentMenu
3646
- .addClass(className.loading)
3647
- ;
3374
+ .addClass(className.loading);
3648
3375
  calculations = {
3649
3376
  context: {
3650
3377
  offset: $context[0] === window
@@ -3691,17 +3418,15 @@
3691
3418
 
3692
3419
  animate: {
3693
3420
  show: function (callback, $subMenu) {
3694
- var
3695
- $currentMenu = $subMenu || $menu,
3696
- start = $subMenu
3697
- ? function () {}
3698
- : function () {
3699
- module.hideSubMenus();
3700
- module.hideOthers();
3701
- module.set.active();
3702
- },
3703
- transition
3704
- ;
3421
+ let $currentMenu = $subMenu || $menu;
3422
+ let start = $subMenu
3423
+ ? function () {}
3424
+ : function () {
3425
+ module.hideSubMenus();
3426
+ module.hideOthers();
3427
+ module.set.active();
3428
+ };
3429
+ let transition;
3705
3430
  callback = isFunction(callback)
3706
3431
  ? callback
3707
3432
  : function () {};
@@ -3732,22 +3457,19 @@
3732
3457
  onComplete: function () {
3733
3458
  callback.call(element);
3734
3459
  },
3735
- })
3736
- ;
3460
+ });
3737
3461
  }
3738
3462
  }
3739
3463
  },
3740
3464
  hide: function (callback, $subMenu) {
3741
- var
3742
- $currentMenu = $subMenu || $menu,
3743
- start = $subMenu
3744
- ? function () {}
3745
- : function () {
3746
- module.unbind.intent();
3747
- module.remove.active();
3748
- },
3749
- transition = settings.transition.hideMethod || module.get.transition($subMenu)
3750
- ;
3465
+ let $currentMenu = $subMenu || $menu;
3466
+ let start = $subMenu
3467
+ ? function () {}
3468
+ : function () {
3469
+ module.unbind.intent();
3470
+ module.remove.active();
3471
+ };
3472
+ let transition = settings.transition.hideMethod || module.get.transition($subMenu);
3751
3473
  callback = isFunction(callback)
3752
3474
  ? callback
3753
3475
  : function () {};
@@ -3774,8 +3496,7 @@
3774
3496
  onComplete: function () {
3775
3497
  callback.call(element);
3776
3498
  },
3777
- })
3778
- ;
3499
+ });
3779
3500
  } else {
3780
3501
  module.error(error.transition);
3781
3502
  }
@@ -3815,55 +3536,26 @@
3815
3536
  },
3816
3537
 
3817
3538
  escape: {
3818
- value: function (value) {
3819
- var
3820
- multipleValues = Array.isArray(value),
3821
- stringValue = typeof value === 'string',
3822
- isUnparsable = !stringValue && !multipleValues,
3823
- hasQuotes = stringValue && value.search(regExp.quote) !== -1,
3824
- values = []
3825
- ;
3826
- if (isUnparsable || !hasQuotes) {
3827
- return value;
3828
- }
3829
- module.debug('Encoding quote values for use in select', value);
3830
- if (multipleValues) {
3831
- $.each(value, function (index, value) {
3832
- values.push(value.replace(regExp.quote, '&quot;'));
3833
- });
3834
-
3835
- return values;
3836
- }
3837
-
3838
- return value.replace(regExp.quote, '&quot;');
3839
- },
3840
3539
  string: function (text) {
3841
3540
  text = String(text);
3842
3541
 
3843
3542
  return text.replace(regExp.escape, '\\$&');
3844
3543
  },
3845
- htmlEntities: function (string, forceAmpersand) {
3846
- forceAmpersand = typeof forceAmpersand === 'number' ? false : forceAmpersand;
3847
- var
3848
- badChars = /["'<>`]/g,
3849
- shouldEscape = /["&'<>`]/,
3850
- escape = {
3851
- '<': '&lt;',
3852
- '>': '&gt;',
3853
- '"': '&quot;',
3854
- "'": '&#x27;',
3855
- '`': '&#x60;',
3856
- },
3857
- escapedChar = function (chr) {
3858
- return escape[chr];
3859
- }
3860
- ;
3861
- if (shouldEscape.test(string)) {
3862
- string = string.replace(forceAmpersand ? /&/g : /&(?![\d#a-z]{1,12};)/gi, '&amp;');
3863
- string = string.replace(badChars, escapedChar);
3544
+
3545
+ // https://github.com/fomantic/Fomantic-UI/issues/2782
3546
+ // https://jsfiddle.net/3efL7jnt/
3547
+ assumeUnescapedAmpLtGt: function (string) {
3548
+ if (settings.preserveHTML) {
3549
+ return string;
3864
3550
  }
3865
3551
 
3866
- return string;
3552
+ const unescapeMap = {
3553
+ '&amp;': '&',
3554
+ '&lt;': '<',
3555
+ '&gt;': '>',
3556
+ };
3557
+
3558
+ return string.replace(/&(?:amp|lt|gt);/g, (v) => unescapeMap[v]);
3867
3559
  },
3868
3560
  },
3869
3561
 
@@ -3918,11 +3610,9 @@
3918
3610
  },
3919
3611
  performance: {
3920
3612
  log: function (message) {
3921
- var
3922
- currentTime,
3923
- executionTime,
3924
- previousTime
3925
- ;
3613
+ let currentTime;
3614
+ let executionTime;
3615
+ let previousTime;
3926
3616
  if (settings.performance) {
3927
3617
  currentTime = Date.now();
3928
3618
  previousTime = time || currentTime;
@@ -3941,10 +3631,8 @@
3941
3631
  }, 500);
3942
3632
  },
3943
3633
  display: function () {
3944
- var
3945
- title = settings.name + ':',
3946
- totalTime = 0
3947
- ;
3634
+ let title = settings.name + ':';
3635
+ let totalTime = 0;
3948
3636
  time = false;
3949
3637
  clearTimeout(module.performance.timer);
3950
3638
  $.each(performance, function (index, data) {
@@ -3966,22 +3654,19 @@
3966
3654
  },
3967
3655
  },
3968
3656
  invoke: function (query, passedArguments, context) {
3969
- var
3970
- object = instance,
3971
- maxDepth,
3972
- found,
3973
- response
3974
- ;
3657
+ let object = instance;
3658
+ let maxDepth;
3659
+ let found;
3660
+ let response;
3975
3661
  passedArguments = passedArguments || queryArguments;
3976
3662
  context = context || element;
3977
3663
  if (typeof query === 'string' && object !== undefined) {
3978
3664
  query = query.split(/[ .]/);
3979
3665
  maxDepth = query.length - 1;
3980
3666
  $.each(query, function (depth, value) {
3981
- var camelCaseValue = depth !== maxDepth
3667
+ let camelCaseValue = depth !== maxDepth
3982
3668
  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3983
- : query
3984
- ;
3669
+ : query;
3985
3670
  if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
3986
3671
  object = object[camelCaseValue];
3987
3672
  } else if (object[camelCaseValue] !== undefined) {
@@ -4066,33 +3751,33 @@
4066
3751
  match: 'both', // what to match against with search selection (both, text, or label)
4067
3752
  fullTextSearch: 'exact', // search anywhere in value (set to 'exact' to require exact matches)
4068
3753
  highlightMatches: false, // Whether search result should highlight matching strings
4069
- ignoreDiacritics: false, // match results also if they contain diacritics of the same base character (for example searching for "a" will also match "á" or "â" or "à", etc...)
3754
+ ignoreDiacritics: false, // match results also if they contain diacritics of the same base character (for example, searching for "a" will also match "á" or "â" or "à", etc...)
4070
3755
  hideDividers: false, // Whether to hide any divider elements (specified in selector.divider) that are sibling to any items when searched (set to true will hide all dividers, set to 'empty' will hide them when they are not followed by a visible item)
4071
3756
 
4072
- placeholder: 'auto', // whether to convert blank <select> values to placeholder text
4073
- preserveHTML: true, // preserve html when selecting value
3757
+ placeholder: 'auto', // whether to convert blank <select> values to the placeholder text
3758
+ preserveHTML: false, // preserve HTML when selecting value
4074
3759
  sortSelect: false, // sort selection on init
4075
3760
 
4076
3761
  forceSelection: false, // force a choice on blur with search selection
4077
3762
 
4078
3763
  allowAdditions: false, // whether multiple select should allow user added values
4079
- keepSearchTerm: false, // whether the search value should be kept and menu stays filtered on item selection
3764
+ keepSearchTerm: false, // whether the search value should be kept, and the menu stays filtered on item selection
4080
3765
  ignoreCase: false, // whether to consider case sensitivity when creating labels
4081
3766
  ignoreSearchCase: true, // whether to consider case sensitivity when filtering items
4082
- hideAdditions: true, // whether or not to hide special message prompting a user they can enter a value
3767
+ hideAdditions: true, // whether to hide a special message prompting a user, they can enter a value
4083
3768
 
4084
- maxSelections: false, // When set to a number limits the number of selections to this count
3769
+ maxSelections: false, // When set to a number, limits the number of selections to this count
4085
3770
  useLabels: true, // whether multiple select should filter currently active selections from choices
4086
- delimiter: ',', // when multiselect uses normal <input> the values will be delimited with this character
3771
+ delimiter: ',', // when multiselect uses normal <input>, the values will be delimited with this character
4087
3772
 
4088
- showOnFocus: false, // show menu on focus
3773
+ showOnFocus: false, // show the menu on focus
4089
3774
  allowReselection: false, // whether current value should trigger callbacks when reselected
4090
- allowTab: true, // add tabindex to element
4091
- allowCategorySelection: false, // allow elements with sub-menus to be selected
3775
+ allowTab: true, // add tabindex to the element
3776
+ allowCategorySelection: false, // allow elements with submenus to be selected
4092
3777
 
4093
3778
  fireOnInit: false, // Whether callbacks should fire when initializing dropdown values
4094
3779
 
4095
- transition: 'auto', // auto transition will slide down or up based on direction
3780
+ transition: 'auto', // auto transition will slide down or up based on the direction
4096
3781
  duration: 200, // duration of transition
4097
3782
  displayType: false, // displayType of transition
4098
3783
 
@@ -4156,12 +3841,10 @@
4156
3841
  noAPI: 'The API module is required to load resources remotely',
4157
3842
  noStorage: 'Saving remote data requires session storage',
4158
3843
  noElement: 'This module requires ui {element}',
4159
- noNormalize: '"ignoreDiacritics" setting will be ignored. Browser does not support String().normalize(). You may consider including <https://cdn.jsdelivr.net/npm/unorm@1.4.1/lib/unorm.min.js> as a polyfill.',
4160
3844
  },
4161
3845
 
4162
3846
  regExp: {
4163
3847
  escape: /[\s#$()*+,.:=?@[\\\]^{|}-]/g,
4164
- quote: /"/g,
4165
3848
  },
4166
3849
 
4167
3850
  metadata: {
@@ -4172,23 +3855,23 @@
4172
3855
  value: 'value',
4173
3856
  },
4174
3857
 
4175
- // property names for remote query
3858
+ // property names for the remote query
4176
3859
  fields: {
4177
3860
  remoteValues: 'results', // grouping for api results
4178
3861
  values: 'values', // grouping for all dropdown values
4179
3862
  disabled: 'disabled', // whether value should be disabled
4180
- name: 'name', // displayed dropdown text
3863
+ name: 'name', // the displayed dropdown text
4181
3864
  description: 'description', // displayed dropdown description
4182
3865
  descriptionVertical: 'descriptionVertical', // whether description should be vertical
4183
3866
  value: 'value', // actual dropdown value
4184
- text: 'text', // displayed text when selected
3867
+ text: 'text', // the displayed text when selected
4185
3868
  data: 'data', // custom data attributes
4186
3869
  type: 'type', // type of dropdown element
4187
3870
  image: 'image', // optional image path
4188
3871
  imageClass: 'imageClass', // optional individual class for image
4189
3872
  alt: 'alt', // optional alt text for image
4190
3873
  icon: 'icon', // optional icon name
4191
- iconClass: 'iconClass', // optional individual class for icon (for example to use flag instead)
3874
+ iconClass: 'iconClass', // optional individual class for icon (for example, to use a flag instead)
4192
3875
  class: 'class', // optional individual class for item/header
4193
3876
  divider: 'divider', // optional divider append for group headers
4194
3877
  actionable: 'actionable', // optional actionable item
@@ -4270,137 +3953,114 @@
4270
3953
 
4271
3954
  /* Templates */
4272
3955
  $.fn.dropdown.settings.templates = {
4273
- deQuote: function (string, encode) {
4274
- return String(string).replace(/"/g, encode ? '&quot;' : '');
4275
- },
4276
- escape: function (string, preserveHTML) {
4277
- if (preserveHTML) {
3956
+ escape: function (string, settings) {
3957
+ if (settings !== undefined && settings.preserveHTML) {
4278
3958
  return string;
4279
3959
  }
4280
- var
4281
- badChars = /["'<>`]/g,
4282
- shouldEscape = /["&'<>`]/,
4283
- escape = {
4284
- '<': '&lt;',
4285
- '>': '&gt;',
4286
- '"': '&quot;',
4287
- "'": '&#x27;',
4288
- '`': '&#x60;',
4289
- },
4290
- escapedChar = function (chr) {
4291
- return escape[chr];
4292
- }
4293
- ;
4294
- if (shouldEscape.test(string)) {
4295
- string = string.replace(/&(?![\d#a-z]{1,12};)/gi, '&amp;');
4296
- string = string.replace(badChars, escapedChar);
4297
- }
4298
3960
 
4299
- return string;
3961
+ const escapeMap = {
3962
+ '"': '&quot;',
3963
+ '&': '&amp;',
3964
+ "'": '&apos;',
3965
+ '<': '&lt;',
3966
+ '>': '&gt;',
3967
+ };
3968
+
3969
+ return String(string).replace(/["&'<>]/g, (chr) => escapeMap[chr]);
4300
3970
  },
4301
3971
  // generates dropdown from select values
4302
- dropdown: function (select, fields, preserveHTML, className) {
4303
- var
4304
- placeholder = select.placeholder || false,
4305
- html = '',
4306
- escape = $.fn.dropdown.settings.templates.escape,
4307
- deQuote = $.fn.dropdown.settings.templates.deQuote
4308
- ;
3972
+ dropdown: function (select, settings) {
3973
+ let placeholder = select.placeholder || false;
3974
+ let html = '';
3975
+ let className = settings.className;
3976
+ let escape = settings.templates.escape;
4309
3977
  html += '<i class="dropdown icon"></i>';
4310
3978
  html += placeholder
4311
- ? '<div class="default text">' + escape(placeholder, preserveHTML) + '</div>'
3979
+ ? '<div class="default text">' + escape(placeholder, settings) + '</div>'
4312
3980
  : '<div class="text"></div>';
4313
- html += '<div class="' + deQuote(className.menu) + '">';
4314
- html += $.fn.dropdown.settings.templates.menu(select, fields, preserveHTML, className);
3981
+ html += '<div class="' + escape(className.menu) + '">';
3982
+ html += settings.templates.menu(select, settings);
4315
3983
  html += '</div>';
4316
3984
 
4317
3985
  return html;
4318
3986
  },
4319
3987
 
4320
3988
  // generates just menu from select
4321
- menu: function (response, fields, preserveHTML, className) {
4322
- var
4323
- values = response[fields.values] || [],
4324
- html = '',
4325
- escape = $.fn.dropdown.settings.templates.escape,
4326
- deQuote = $.fn.dropdown.settings.templates.deQuote
4327
- ;
3989
+ menu: function (response, settings) {
3990
+ let fields = settings.fields;
3991
+ let values = response[fields.values] || [];
3992
+ let html = '';
3993
+ let className = settings.className;
3994
+ let escape = settings.templates.escape;
4328
3995
  $.each(values, function (index, option) {
4329
- var
4330
- itemType = option[fields.type] || 'item',
4331
- isMenu = itemType.indexOf('menu') !== -1,
4332
- maybeData = '',
4333
- dataObject = option[fields.data]
4334
- ;
3996
+ let itemType = option[fields.type] || 'item';
3997
+ let isMenu = itemType.indexOf('menu') !== -1;
3998
+ let maybeData = '';
3999
+ let dataObject = option[fields.data];
4335
4000
  if (dataObject) {
4336
- var dataKey,
4337
- dataKeyEscaped
4338
- ;
4001
+ let dataKey;
4002
+ let dataKeyEscaped;
4339
4003
  for (dataKey in dataObject) {
4340
4004
  dataKeyEscaped = String(dataKey).replace(/\W/g, '');
4341
4005
  if (Object.prototype.hasOwnProperty.call(dataObject, dataKey) && ['text', 'value'].indexOf(dataKeyEscaped.toLowerCase()) === -1) {
4342
- maybeData += ' data-' + dataKeyEscaped + '="' + deQuote(String(dataObject[dataKey])) + '"';
4006
+ maybeData += ' data-' + dataKeyEscaped + '="' + escape(String(dataObject[dataKey])) + '"';
4343
4007
  }
4344
4008
  }
4345
4009
  }
4346
4010
  if (itemType === 'item' || isMenu) {
4347
- var
4348
- maybeText = option[fields.text]
4349
- ? ' data-text="' + deQuote(option[fields.text], true) + '"'
4350
- : '',
4351
- maybeActionable = option[fields.actionable]
4352
- ? className.actionable + ' '
4353
- : '',
4354
- maybeDisabled = option[fields.disabled]
4355
- ? className.disabled + ' '
4356
- : '',
4357
- maybeDescriptionVertical = option[fields.descriptionVertical]
4358
- ? className.descriptionVertical + ' '
4359
- : '',
4360
- hasDescription = escape(option[fields.description] || '', preserveHTML) !== ''
4361
- ;
4362
- html += '<div class="' + deQuote(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + deQuote(option[fields.value], true) + '"' + maybeText + maybeData + '>';
4011
+ let maybeText = option[fields.text]
4012
+ ? ' data-text="' + escape(option[fields.text]) + '"'
4013
+ : '';
4014
+ let maybeActionable = option[fields.actionable]
4015
+ ? className.actionable + ' '
4016
+ : '';
4017
+ let maybeDisabled = option[fields.disabled]
4018
+ ? className.disabled + ' '
4019
+ : '';
4020
+ let maybeDescriptionVertical = option[fields.descriptionVertical]
4021
+ ? className.descriptionVertical + ' '
4022
+ : '';
4023
+ let hasDescription = escape(option[fields.description] || '', settings) !== '';
4024
+ html += '<div class="' + escape(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + escape(option[fields.value]) + '"' + maybeText + maybeData + '>';
4363
4025
  if (isMenu) {
4364
4026
  html += '<i class="' + (itemType.indexOf('left') !== -1 ? 'left' : '') + ' dropdown icon"></i>';
4365
4027
  }
4366
4028
  if (option[fields.image]) {
4367
- html += '<img class="' + deQuote(option[fields.imageClass] || className.image) + '" src="' + deQuote(option[fields.image]) + (option[fields.alt] ? '" alt="' + deQuote(option[fields.alt]) : '') + '">';
4029
+ html += '<img class="' + escape(option[fields.imageClass] || className.image) + '" src="' + escape(option[fields.image]) + '"' + (option[fields.alt] ? ' alt="' + escape(option[fields.alt]) + '"' : '') + '>';
4368
4030
  }
4369
4031
  if (option[fields.icon]) {
4370
- html += '<i class="' + deQuote(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4032
+ html += '<i class="' + escape(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4371
4033
  }
4372
4034
  if (hasDescription) {
4373
- html += '<span class="' + deQuote(className.description) + '">' + escape(option[fields.description] || '', preserveHTML) + '</span>';
4374
- html += !isMenu ? '<span class="' + deQuote(className.text) + '">' : '';
4035
+ html += '<span class="' + escape(className.description) + '">' + escape(option[fields.description] || '', settings) + '</span>';
4036
+ html += !isMenu ? '<span class="' + escape(className.text) + '">' : '';
4375
4037
  }
4376
4038
  if (isMenu) {
4377
- html += '<span class="' + deQuote(className.text) + '">';
4039
+ html += '<span class="' + escape(className.text) + '">';
4378
4040
  }
4379
- html += escape(option[fields.name] || '', preserveHTML);
4041
+ html += escape(option[fields.name] || '', settings);
4380
4042
  if (isMenu) {
4381
4043
  html += '</span>';
4382
- html += '<div class="' + deQuote(itemType) + '">';
4383
- html += $.fn.dropdown.settings.templates.menu(option, fields, preserveHTML, className);
4044
+ html += '<div class="' + escape(itemType) + '">';
4045
+ html += settings.templates.menu(option, settings);
4384
4046
  html += '</div>';
4385
4047
  } else if (hasDescription) {
4386
4048
  html += '</span>';
4387
4049
  }
4388
4050
  html += '</div>';
4389
4051
  } else if (itemType === 'header') {
4390
- var
4391
- groupName = escape(option[fields.name] || '', preserveHTML),
4392
- groupIcon = deQuote(option[fields.icon] || className.groupIcon)
4393
- ;
4052
+ let groupName = option[fields.name] || '';
4053
+ let groupIcon = option[fields.icon] || className.groupIcon;
4394
4054
  if (groupName !== '' || groupIcon !== '') {
4395
- html += '<div class="' + deQuote(option[fields.class] || className.header) + '">';
4055
+ html += '<div class="' + escape(option[fields.class] || className.header) + '">';
4396
4056
  if (groupIcon !== '') {
4397
- html += '<i class="' + deQuote(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4057
+ html += '<i class="' + escape(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4398
4058
  }
4399
- html += groupName;
4059
+ html += escape(groupName, settings);
4400
4060
  html += '</div>';
4401
4061
  }
4402
4062
  if (option[fields.divider]) {
4403
- html += '<div class="' + deQuote(className.divider) + '"></div>';
4063
+ html += '<div class="' + escape(className.divider) + '"></div>';
4404
4064
  }
4405
4065
  }
4406
4066
  });
@@ -4409,13 +4069,11 @@
4409
4069
  },
4410
4070
 
4411
4071
  // generates label for multiselect
4412
- label: function (value, text, preserveHTML, className) {
4413
- var
4414
- escape = $.fn.dropdown.settings.templates.escape,
4415
- deQuote = $.fn.dropdown.settings.templates.deQuote
4416
- ;
4072
+ label: function (value, text, settings) {
4073
+ let className = settings.className;
4074
+ let escape = settings.templates.escape;
4417
4075
 
4418
- return escape(text, preserveHTML) + '<i class="' + deQuote(className.delete) + ' icon"></i>';
4076
+ return escape(text, settings) + '<i class="' + escape(className.delete) + ' icon"></i>';
4419
4077
  },
4420
4078
 
4421
4079
  // generates messages like "No results"
@@ -4423,7 +4081,7 @@
4423
4081
  return message;
4424
4082
  },
4425
4083
 
4426
- // generates user addition to selection menu
4084
+ // generates user addition to the selection menu
4427
4085
  addition: function (choice) {
4428
4086
  return choice;
4429
4087
  },