@northdata/fomantic-ui 2.9.413 → 2.9.415

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.
@@ -19,94 +19,89 @@
19
19
  ? window
20
20
  : globalThis;
21
21
 
22
- $.fn.dropdown = function (parameters) {
23
- var
24
- $allModules = $(this),
25
- $document = $(document),
26
-
27
- time = Date.now(),
28
- performance = [],
29
-
30
- query = arguments[0],
31
- methodInvoked = typeof query === 'string',
32
- queryArguments = [].slice.call(arguments, 1),
33
- contextCheck = function (context, win) {
34
- var $context;
35
- if ([window, document].indexOf(context) >= 0) {
36
- $context = $(context);
37
- } else {
38
- $context = $(win.document).find(context);
39
- if ($context.length === 0) {
40
- $context = win.frameElement ? contextCheck(context, win.parent) : window;
41
- }
22
+ $.fn.dropdown = function (...args) {
23
+ let $allModules = $(this);
24
+ const $document = $(document);
25
+
26
+ let time = Date.now();
27
+ let performance = [];
28
+
29
+ const parameters = args[0];
30
+ const methodInvoked = typeof parameters === 'string';
31
+ const queryArguments = args.slice(1);
32
+ const contextCheck = function (context, win) {
33
+ let $context;
34
+ if ([window, document].includes(context)) {
35
+ $context = $(context);
36
+ } else {
37
+ $context = $(win.document).find(context);
38
+ if ($context.length === 0) {
39
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
42
40
  }
41
+ }
43
42
 
44
- return $context;
45
- },
46
- returnedValue
47
- ;
43
+ return $context;
44
+ };
45
+ let returnedValue;
48
46
 
49
47
  $allModules.each(function (elementIndex) {
50
- var
51
- settings = $.isPlainObject(parameters)
52
- ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
53
- : $.extend({}, $.fn.dropdown.settings),
54
-
55
- className = settings.className,
56
- message = settings.message,
57
- fields = settings.fields,
58
- keys = settings.keys,
59
- metadata = settings.metadata,
60
- namespace = settings.namespace,
61
- regExp = settings.regExp,
62
- selector = settings.selector,
63
- error = settings.error,
64
- templates = settings.templates,
65
-
66
- eventNamespace = '.' + namespace,
67
- moduleNamespace = 'module-' + namespace,
68
-
69
- $module = $(this),
70
- $context = contextCheck(settings.context, window),
71
- $text = $module.find(selector.text),
72
- $search = $module.find(selector.search),
73
- $sizer = $module.find(selector.sizer),
74
- $input = $module.find(selector.input),
75
- $icon = $module.find(selector.icon),
76
- $clear = $module.find(selector.clearIcon),
77
-
78
- $combo = $module.prev().find(selector.text).length > 0
79
- ? $module.prev().find(selector.text)
80
- : $module.prev(),
81
-
82
- $menu = $module.children(selector.menu),
83
- $item = $menu.find(selector.item),
84
- $divider = settings.hideDividers
85
- ? $item.parent().children(selector.divider)
86
- : $(),
87
-
88
- activated = false,
89
- itemActivated = false,
90
- internalChange = false,
91
- iconClicked = false,
92
- element = this,
93
- focused = false,
94
- instance = $module.data(moduleNamespace),
95
-
96
- selectActionActive,
97
- initialLoad,
98
- pageLostFocus,
99
- willRefocus,
100
- elementNamespace,
101
- id,
102
- selectObserver,
103
- menuObserver,
104
- classObserver,
105
- module,
106
- tempDisableApiCache = false
107
- ;
108
-
109
- module = {
48
+ const settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
50
+ : $.extend({}, $.fn.dropdown.settings);
51
+
52
+ const className = settings.className;
53
+ const message = settings.message;
54
+ const fields = settings.fields;
55
+ const keys = settings.keys;
56
+ const metadata = settings.metadata;
57
+ const namespace = settings.namespace;
58
+ const regExp = settings.regExp;
59
+ const selector = settings.selector;
60
+ const error = settings.error;
61
+ const templates = settings.templates;
62
+
63
+ const eventNamespace = '.' + namespace;
64
+ const moduleNamespace = 'module-' + namespace;
65
+
66
+ let $module = $(this);
67
+ const $context = contextCheck(settings.context, window);
68
+ let $text = $module.find(selector.text);
69
+ let $search = $module.find(selector.search);
70
+ let $sizer = $module.find(selector.sizer);
71
+ let $input = $module.find(selector.input);
72
+ let $icon = $module.find(selector.icon);
73
+ let $clear = $module.find(selector.clearIcon);
74
+
75
+ let $combo = $module.prev().find(selector.text).length > 0
76
+ ? $module.prev().find(selector.text)
77
+ : $module.prev();
78
+
79
+ let $menu = $module.children(selector.menu);
80
+ let $item = $menu.find(selector.item);
81
+ let $divider = settings.hideDividers
82
+ ? $item.parent().children(selector.divider)
83
+ : $();
84
+
85
+ let activated = false;
86
+ let itemActivated = false;
87
+ let internalChange = false;
88
+ let iconClicked = false;
89
+ let element = this;
90
+ let focused = false;
91
+ let instance = $module.data(moduleNamespace);
92
+
93
+ let selectActionActive;
94
+ let initialLoad;
95
+ let pageLostFocus;
96
+ let willRefocus;
97
+ let elementNamespace;
98
+ let id;
99
+ let selectObserver;
100
+ let menuObserver;
101
+ let classObserver;
102
+ let tempDisableApiCache = false;
103
+
104
+ const module = {
110
105
 
111
106
  initialize: function () {
112
107
  module.debug('Initializing dropdown', settings);
@@ -114,11 +109,6 @@
114
109
  if (module.is.alreadySetup()) {
115
110
  module.setup.reference();
116
111
  } else {
117
- if (settings.ignoreDiacritics && !String.prototype.normalize) {
118
- settings.ignoreDiacritics = false;
119
- module.error(error.noNormalize, element);
120
- }
121
-
122
112
  module.create.id();
123
113
  module.setup.layout();
124
114
 
@@ -147,8 +137,7 @@
147
137
  module.verbose('Storing instance of dropdown', module);
148
138
  instance = module;
149
139
  $module
150
- .data(moduleNamespace, module)
151
- ;
140
+ .data(moduleNamespace, module);
152
141
  },
153
142
 
154
143
  destroy: function () {
@@ -159,29 +148,24 @@
159
148
  $menu.removeClass(className.visible).addClass(className.hidden);
160
149
  $module
161
150
  .off(eventNamespace)
162
- .removeData(moduleNamespace)
163
- ;
151
+ .removeData(moduleNamespace);
164
152
  $menu
165
- .off(eventNamespace)
166
- ;
153
+ .off(eventNamespace);
167
154
  $document
168
- .off(elementNamespace)
169
- ;
155
+ .off(elementNamespace);
170
156
  module.disconnect.menuObserver();
171
157
  module.disconnect.selectObserver();
172
158
  module.disconnect.classObserver();
173
159
  },
174
160
 
175
161
  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
- }
162
+ selectObserver = new MutationObserver(module.event.select.mutation);
163
+ menuObserver = new MutationObserver(module.event.menu.mutation);
164
+ classObserver = new MutationObserver(module.event.class.mutation);
165
+ module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver);
166
+ module.observe.select();
167
+ module.observe.menu();
168
+ module.observe.class();
185
169
  },
186
170
 
187
171
  disconnect: {
@@ -234,13 +218,10 @@
234
218
  elementNamespace = '.' + id;
235
219
  module.verbose('Creating unique id for element', id);
236
220
  },
237
- userChoice: function (values) {
238
- var
239
- $userChoices,
240
- $userChoice,
241
- html
242
- ;
243
- values = values || module.get.userValues();
221
+ userChoice: function (values = module.get.userValues()) {
222
+ let $userChoices;
223
+ let $userChoice;
224
+ let html;
244
225
  if (!values) {
245
226
  return false;
246
227
  }
@@ -249,14 +230,13 @@
249
230
  : [values];
250
231
  $.each(values, function (index, value) {
251
232
  if (module.get.item(value) === false) {
252
- html = settings.templates.addition(module.add.variables(message.addResult, value));
233
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
253
234
  $userChoice = $('<div />')
254
235
  .html(html)
255
236
  .attr('data-' + metadata.value, value)
256
237
  .attr('data-' + metadata.text, value)
257
238
  .addClass(className.addition)
258
- .addClass(className.item)
259
- ;
239
+ .addClass(className.item);
260
240
  if (settings.hideAdditions) {
261
241
  $userChoice.addClass(className.hidden);
262
242
  }
@@ -270,9 +250,7 @@
270
250
  return $userChoices;
271
251
  },
272
252
  userLabels: function (value) {
273
- var
274
- userValues = module.get.userValues()
275
- ;
253
+ const userValues = module.get.userValues();
276
254
  if (userValues) {
277
255
  module.debug('Adding user labels', userValues);
278
256
  $.each(userValues, function (index, value) {
@@ -284,21 +262,16 @@
284
262
  menu: function () {
285
263
  $menu = $('<div />')
286
264
  .addClass(className.menu)
287
- .appendTo($module)
288
- ;
265
+ .appendTo($module);
289
266
  },
290
267
  sizer: function () {
291
268
  $sizer = $('<span />')
292
269
  .addClass(className.sizer)
293
- .insertAfter($search)
294
- ;
270
+ .insertAfter($search);
295
271
  },
296
272
  },
297
273
 
298
- search: function (query) {
299
- query = query !== undefined
300
- ? query
301
- : module.get.query();
274
+ search: function (query = module.get.query()) {
302
275
  module.verbose('Searching for query', query);
303
276
  if (settings.fireOnInit === false && module.is.initialLoad()) {
304
277
  module.verbose('Skipping callback on initial load', settings.onSearch);
@@ -317,16 +290,13 @@
317
290
  .not(selector.unselectable)
318
291
  .not(selector.addition + selector.hidden)
319
292
  .eq(0)
320
- .addClass(className.selected)
321
- ;
293
+ .addClass(className.selected);
322
294
  },
323
295
  nextAvailable: function ($selected) {
324
296
  $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
- ;
297
+ const $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0);
298
+ const $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0);
299
+ const hasNext = $nextAvailable.length > 0;
330
300
  if (hasNext) {
331
301
  module.verbose('Moving selection to', $nextAvailable);
332
302
  $nextAvailable.addClass(className.selected);
@@ -339,20 +309,17 @@
339
309
 
340
310
  setup: {
341
311
  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
- ;
312
+ const apiSettings = {
313
+ debug: settings.debug,
314
+ urlData: {
315
+ value: module.get.value(),
316
+ query: module.get.query(),
317
+ },
318
+ on: false,
319
+ };
352
320
  module.verbose('First request, initializing API');
353
321
  $module
354
- .api(apiSettings)
355
- ;
322
+ .api(apiSettings);
356
323
  },
357
324
  layout: function () {
358
325
  if ($module.is('select')) {
@@ -366,18 +333,14 @@
366
333
  module.verbose('Adding clear icon');
367
334
  $clear = $('<i />')
368
335
  .addClass('remove icon')
369
- .insertAfter($icon)
370
- ;
336
+ .insertAfter($icon);
371
337
  }
372
338
  if (module.is.search() && !module.has.search()) {
373
339
  module.verbose('Adding search input');
374
- var
375
- labelNode = $module.prev('label')
376
- ;
340
+ const labelNode = $module.prev('label');
377
341
  $search = $('<input />')
378
342
  .addClass(className.search)
379
- .prop('autocomplete', 'off')
380
- ;
343
+ .prop('autocomplete', 'off');
381
344
  if (labelNode.length > 0) {
382
345
  if (!labelNode.attr('id')) {
383
346
  labelNode.attr('id', '_' + module.get.id() + '_formLabel');
@@ -394,9 +357,7 @@
394
357
  }
395
358
  },
396
359
  select: function () {
397
- var
398
- selectValues = module.get.selectValues()
399
- ;
360
+ const selectValues = module.get.selectValues();
400
361
  module.debug('Dropdown initialized on a select', selectValues);
401
362
  if ($module.is('select')) {
402
363
  $input = $module;
@@ -416,9 +377,8 @@
416
377
  .attr('class', $input.attr('class'))
417
378
  .addClass(className.selection)
418
379
  .addClass(className.dropdown)
419
- .html(templates.dropdown(selectValues, fields, settings.preserveHTML, settings.className))
420
- .insertBefore($input)
421
- ;
380
+ .html(templates.dropdown(selectValues, settings))
381
+ .insertBefore($input);
422
382
  if ($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
423
383
  module.error(error.missingMultiple);
424
384
  $input.prop('multiple', true);
@@ -440,13 +400,12 @@
440
400
  .prop('required', false)
441
401
  .removeAttr('class')
442
402
  .detach()
443
- .prependTo($module)
444
- ;
403
+ .prependTo($module);
445
404
  }
446
405
  module.refresh();
447
406
  },
448
407
  menu: function (values) {
449
- $menu.html(templates.menu(values, fields, settings.preserveHTML, settings.className));
408
+ $menu.html(templates.menu(values, settings));
450
409
  $item = $menu.find(selector.item);
451
410
  $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $();
452
411
  },
@@ -460,11 +419,9 @@
460
419
  module.setup.returnedObject();
461
420
  },
462
421
  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
422
+ const $firstModules = $allModules.slice(0, elementIndex);
423
+ const $lastModules = $allModules.slice(elementIndex + 1);
424
+ // adjust all modules to use the correct reference
468
425
  $allModules = $firstModules.add($module).add($lastModules);
469
426
  },
470
427
  },
@@ -497,21 +454,18 @@
497
454
  module.verbose('Refreshing cached metadata');
498
455
  $item
499
456
  .removeData(metadata.text)
500
- .removeData(metadata.value)
501
- ;
457
+ .removeData(metadata.value);
502
458
  },
503
459
 
504
460
  clearData: function () {
505
461
  module.verbose('Clearing metadata');
506
462
  $item
507
463
  .removeData(metadata.text)
508
- .removeData(metadata.value)
509
- ;
464
+ .removeData(metadata.value);
510
465
  $module
511
466
  .removeData(metadata.defaultText)
512
467
  .removeData(metadata.defaultValue)
513
- .removeData(metadata.placeholderText)
514
- ;
468
+ .removeData(metadata.placeholderText);
515
469
  },
516
470
 
517
471
  clearItems: function () {
@@ -578,11 +532,11 @@
578
532
  });
579
533
  // Hide submenus explicitly. On some browsers (esp. mobile), they will not automatically receive a
580
534
  // mouseleave event
581
- var $subMenu = $module.find(selector.menu);
535
+ const $subMenu = $module.find(selector.menu);
582
536
  if ($subMenu.length > 0) {
583
537
  module.verbose('Hiding sub-menu', $subMenu);
584
538
  $subMenu.each(function () {
585
- var $sub = $(this);
539
+ const $sub = $(this);
586
540
  if (!module.is.animating($sub)) {
587
541
  module.animate.hide(false, $sub);
588
542
  }
@@ -601,8 +555,7 @@
601
555
  $allModules
602
556
  .not($module)
603
557
  .has(selector.menu + '.' + className.visible)
604
- .dropdown('hide')
605
- ;
558
+ .dropdown('hide');
606
559
  },
607
560
 
608
561
  hideMenu: function () {
@@ -613,9 +566,7 @@
613
566
  },
614
567
 
615
568
  hideSubMenus: function () {
616
- var
617
- $subMenus = $menu.children(selector.item).find(selector.menu)
618
- ;
569
+ const $subMenus = $menu.children(selector.item).find(selector.menu);
619
570
  module.verbose('Hiding sub menus', $subMenus);
620
571
  $subMenus.transition('hide');
621
572
  },
@@ -629,28 +580,23 @@
629
580
  keyboardEvents: function () {
630
581
  module.verbose('Binding keyboard events');
631
582
  $module
632
- .on('keydown' + eventNamespace, module.event.keydown)
633
- ;
583
+ .on('keydown' + eventNamespace, module.event.keydown);
634
584
  if (module.has.search()) {
635
585
  $module
636
- .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
637
- ;
586
+ .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input);
638
587
  }
639
588
  if (module.is.multiple()) {
640
589
  $document
641
- .on('keydown' + elementNamespace, module.event.document.keydown)
642
- ;
590
+ .on('keydown' + elementNamespace, module.event.document.keydown);
643
591
  }
644
592
  },
645
593
  inputEvents: function () {
646
594
  module.verbose('Binding input change events');
647
595
  $module
648
- .on('change' + eventNamespace, selector.input, module.event.change)
649
- ;
596
+ .on('change' + eventNamespace, selector.input, module.event.change);
650
597
  if (module.is.multiple() && module.is.searchSelection()) {
651
598
  $module
652
- .on('paste' + eventNamespace, selector.search, module.event.paste)
653
- ;
599
+ .on('paste' + eventNamespace, selector.search, module.event.paste);
654
600
  }
655
601
  },
656
602
  mouseEvents: function () {
@@ -658,8 +604,7 @@
658
604
  if (module.is.multiple()) {
659
605
  $module
660
606
  .on('click' + eventNamespace, selector.label, module.event.label.click)
661
- .on('click' + eventNamespace, selector.remove, module.event.remove.click)
662
- ;
607
+ .on('click' + eventNamespace, selector.remove, module.event.remove.click);
663
608
  }
664
609
  if (module.is.searchSelection()) {
665
610
  $module
@@ -672,60 +617,50 @@
672
617
  .on('focus' + eventNamespace, selector.search, module.event.search.focus)
673
618
  .on('click' + eventNamespace, selector.search, module.event.search.focus)
674
619
  .on('blur' + eventNamespace, selector.search, module.event.search.blur)
675
- .on('click' + eventNamespace, selector.text, module.event.text.focus)
676
- ;
620
+ .on('click' + eventNamespace, selector.text, module.event.text.focus);
677
621
  if (module.is.multiple()) {
678
622
  $module
679
623
  .on('click' + eventNamespace, module.event.click)
680
- .on('click' + eventNamespace, module.event.search.focus)
681
- ;
624
+ .on('click' + eventNamespace, module.event.search.focus);
682
625
  }
683
626
  } else {
684
627
  if (settings.on === 'click') {
685
628
  $module
686
629
  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
687
- .on('click' + eventNamespace, module.event.test.toggle)
688
- ;
630
+ .on('click' + eventNamespace, module.event.test.toggle);
689
631
  } else if (settings.on === 'hover') {
690
632
  $module
691
633
  .on('mouseenter' + eventNamespace, module.delay.show)
692
634
  .on('mouseleave' + eventNamespace, module.delay.hide)
693
635
  .on('touchstart' + eventNamespace, module.event.test.toggle)
694
- .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click)
695
- ;
636
+ .on('touchstart' + eventNamespace, selector.icon, module.event.icon.click);
696
637
  } else {
697
638
  $module
698
- .on(settings.on + eventNamespace, module.toggle)
699
- ;
639
+ .on(settings.on + eventNamespace, module.toggle);
700
640
  }
701
641
  $module
702
642
  .on('mousedown' + eventNamespace, module.event.mousedown)
703
643
  .on('mouseup' + eventNamespace, module.event.mouseup)
704
644
  .on('focus' + eventNamespace, module.event.focus)
705
- .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click)
706
- ;
645
+ .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click);
707
646
  if (module.has.menuSearch()) {
708
647
  $module
709
- .on('blur' + eventNamespace, selector.search, module.event.search.blur)
710
- ;
648
+ .on('blur' + eventNamespace, selector.search, module.event.search.blur);
711
649
  } else {
712
650
  $module
713
- .on('blur' + eventNamespace, module.event.blur)
714
- ;
651
+ .on('blur' + eventNamespace, module.event.blur);
715
652
  }
716
653
  }
717
654
  $menu
718
655
  .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
719
656
  .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
720
657
  .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
721
- .on('click' + eventNamespace, selector.item, module.event.item.click)
722
- ;
658
+ .on('click' + eventNamespace, selector.item, module.event.item.click);
723
659
  },
724
660
  intent: function () {
725
661
  module.verbose('Binding hide intent event to document');
726
662
  $document
727
- .on('click' + elementNamespace, module.event.test.hide)
728
- ;
663
+ .on('click' + elementNamespace, module.event.test.hide);
729
664
  },
730
665
  },
731
666
 
@@ -733,52 +668,51 @@
733
668
  intent: function () {
734
669
  module.verbose('Removing hide intent event from document');
735
670
  $document
736
- .off('click' + elementNamespace)
737
- ;
671
+ .off('click' + elementNamespace);
738
672
  },
739
673
  },
740
674
 
741
675
  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);
676
+ const searchTerm = query !== undefined
677
+ ? query
678
+ : module.get.query();
679
+ const afterFiltered = function () {
680
+ if (module.is.multiple()) {
681
+ module.filterActive();
682
+ }
683
+ if (query || (!query && module.get.activeItem().length === 0)) {
684
+ module.select.firstUnfiltered();
685
+ }
686
+ if (module.has.allResultsFiltered()) {
687
+ if (settings.onNoResults.call(element, searchTerm)) {
688
+ if (settings.allowAdditions) {
689
+ if (settings.hideAdditions) {
690
+ module.verbose('User addition with no menu, setting empty style');
691
+ module.set.empty();
692
+ module.hideMenu();
764
693
  }
765
694
  } else {
766
- module.verbose('All items filtered, hiding dropdown', searchTerm);
767
- module.set.empty();
768
- module.hideMenu();
695
+ module.verbose('All items filtered, showing message', searchTerm);
696
+ module.add.message(message.noResults);
769
697
  }
770
698
  } 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();
699
+ module.verbose('All items filtered, hiding dropdown', searchTerm);
700
+ module.set.empty();
701
+ module.hideMenu();
779
702
  }
703
+ } else {
704
+ module.remove.empty();
705
+ module.remove.message();
706
+ }
707
+ if (settings.allowAdditions) {
708
+ module.add.userSuggestion(settings.preserveHTML
709
+ ? settings.templates.escape(query)
710
+ : query);
780
711
  }
781
- ;
712
+ if (module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() && !module.is.empty()) {
713
+ module.show();
714
+ }
715
+ };
782
716
  if (settings.useLabels && module.has.maxSelections()) {
783
717
  module.show();
784
718
 
@@ -790,15 +724,14 @@
790
724
  if (settings.filterRemoteData) {
791
725
  module.filterItems(searchTerm);
792
726
  }
793
- var preSelected = $input.val();
727
+ let preSelected = $input.val();
794
728
  if (!Array.isArray(preSelected)) {
795
729
  preSelected = preSelected && preSelected !== '' ? preSelected.split(settings.delimiter) : [];
796
730
  }
797
731
  if (module.is.multiple()) {
798
732
  $.each(preSelected, function (index, value) {
799
- $item.filter('[data-' + metadata.value + '="' + value + '"]')
800
- .addClass(className.filtered)
801
- ;
733
+ $item.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]')
734
+ .addClass(className.filtered);
802
735
  });
803
736
  }
804
737
  module.focusSearch(true);
@@ -817,88 +750,81 @@
817
750
  if (!Array.isArray(callbackParameters)) {
818
751
  callbackParameters = [callbackParameters];
819
752
  }
820
- var
821
- apiSettings = {
822
- errorDuration: false,
823
- cache: 'local',
824
- throttle: settings.throttle,
825
- urlData: {
826
- query: query,
827
- },
753
+ let apiSettings = {
754
+ errorDuration: false,
755
+ cache: 'local',
756
+ throttle: settings.throttle,
757
+ urlData: {
758
+ query: query,
828
759
  },
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);
760
+ };
761
+ const apiCallbacks = {
762
+ onError: function (errorMessage, $module, xhr) {
763
+ module.add.message(message.serverError);
764
+ iconClicked = false;
765
+ focused = false;
766
+ callback(...callbackParameters);
767
+ if (typeof settings.apiSettings.onError === 'function') {
768
+ settings.apiSettings.onError.call(this, errorMessage, $module, xhr);
769
+ }
770
+ },
771
+ onFailure: function (response, $module, xhr) {
772
+ module.add.message(message.serverError);
773
+ iconClicked = false;
774
+ focused = false;
775
+ callback(...callbackParameters);
776
+ if (typeof settings.apiSettings.onFailure === 'function') {
777
+ settings.apiSettings.onFailure.call(this, response, $module, xhr);
778
+ }
779
+ },
780
+ onSuccess: function (response, $module, xhr) {
781
+ let values = response[fields.remoteValues];
782
+ if (!Array.isArray(values)) {
783
+ values = [];
784
+ }
785
+ module.remove.message();
786
+ const menuConfig = {};
787
+ menuConfig[fields.values] = values;
788
+ module.setup.menu(menuConfig);
859
789
 
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);
790
+ if (values.length === 0 && !settings.allowAdditions) {
791
+ module.add.message(message.noResults);
792
+ } else {
793
+ const value = module.is.multiple() ? module.get.values() : module.get.value();
794
+ if (value !== '') {
795
+ module.verbose('Value(s) present after click icon, select value(s) in items');
796
+ module.set.selected(value, null, true, true);
874
797
  }
875
- },
876
- }
877
- ;
798
+ }
799
+ iconClicked = false;
800
+ focused = false;
801
+ callback(...callbackParameters);
802
+ if (typeof settings.apiSettings.onSuccess === 'function') {
803
+ settings.apiSettings.onSuccess.call(this, response, $module, xhr);
804
+ }
805
+ },
806
+ };
878
807
  if (!$module.api('get request')) {
879
808
  module.setup.api();
880
809
  }
881
810
  apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings, apiCallbacks, tempDisableApiCache ? { cache: false } : {});
882
811
  $module
883
812
  .api('setting', apiSettings)
884
- .api('query')
885
- ;
813
+ .api('query');
886
814
  tempDisableApiCache = false;
887
815
  },
888
816
 
889
817
  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
- ;
818
+ const searchTerm = module.remove.diacritics(
819
+ query !== undefined
820
+ ? query
821
+ : module.get.query()
822
+ );
823
+ let results = null;
824
+ const escapedTerm = module.escape.string(searchTerm);
825
+ const regExpIgnore = settings.ignoreSearchCase ? 'i' : '';
826
+ const regExpFlags = regExpIgnore + 'gm';
827
+ const beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags);
902
828
  module.remove.filteredItem();
903
829
  // avoid loop if we're matching nothing
904
830
  if (module.has.query()) {
@@ -907,11 +833,9 @@
907
833
  module.verbose('Searching for matching values', searchTerm);
908
834
  $item
909
835
  .each(function () {
910
- var
911
- $choice = $(this),
912
- text,
913
- value
914
- ;
836
+ const $choice = $(this);
837
+ let text;
838
+ let value;
915
839
  if ($choice.hasClass(className.unfilterable)) {
916
840
  results.push(this);
917
841
 
@@ -939,32 +863,28 @@
939
863
  return true;
940
864
  }
941
865
  }
942
- })
943
- ;
866
+ });
944
867
  }
945
868
  module.debug('Showing only matched items', searchTerm);
946
869
  if (results) {
947
870
  $item
948
871
  .not(results)
949
- .addClass(className.filtered)
950
- ;
872
+ .addClass(className.filtered);
951
873
  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
- });
874
+ const querySplit = [...query];
875
+ const diacriticReg = settings.ignoreDiacritics ? '[\u0300-\u036F]?' : '';
876
+ const htmlReg = '(?![^<]*>)';
877
+ const markedRegExp = new RegExp(htmlReg + '(' + querySplit.join(diacriticReg + ')(.*?)' + htmlReg + '(') + diacriticReg + ')', regExpIgnore);
878
+ const markedReplacer = function (...args) {
879
+ args = args.slice(1, querySplit.length * 2).map(function (x, i) {
880
+ return i & 1 ? x : '<mark>' + x + '</mark>'; // eslint-disable-line no-bitwise
881
+ });
960
882
 
961
- return args.join('');
962
- }
963
- ;
883
+ return args.join('');
884
+ };
964
885
  $.each(results, function (index, result) {
965
- var $result = $(result),
966
- markedHTML = module.get.choiceText($result, true)
967
- ;
886
+ const $result = $(result);
887
+ let markedHTML = module.get.choiceText($result, true);
968
888
  if (settings.ignoreDiacritics) {
969
889
  markedHTML = markedHTML.normalize('NFD');
970
890
  }
@@ -975,19 +895,17 @@
975
895
 
976
896
  if (!module.has.query()) {
977
897
  $divider
978
- .removeClass(className.hidden)
979
- ;
898
+ .removeClass(className.hidden);
980
899
  } else if (settings.hideDividers === true) {
981
900
  $divider
982
- .addClass(className.hidden)
983
- ;
901
+ .addClass(className.hidden);
984
902
  } else if (settings.hideDividers === 'empty') {
985
903
  $divider
986
904
  .removeClass(className.hidden)
987
905
  .filter(function () {
988
906
  // First find the last divider in this divider group
989
907
  // Dividers which are direct siblings are considered a group
990
- var $lastDivider = $(this).nextUntil(selector.item);
908
+ const $lastDivider = $(this).nextUntil(selector.item);
991
909
 
992
910
  return ($lastDivider.length > 0 ? $lastDivider : $(this))
993
911
  // Count all non-filtered items until the next divider (or end of the dropdown)
@@ -996,16 +914,13 @@
996
914
  // Hide divider if no items are found
997
915
  .length === 0;
998
916
  })
999
- .addClass(className.hidden)
1000
- ;
917
+ .addClass(className.hidden);
1001
918
  }
1002
919
  },
1003
920
 
1004
921
  fuzzySearch: function (query, term) {
1005
- var
1006
- termLength = term.length,
1007
- queryLength = query.length
1008
- ;
922
+ const termLength = term.length;
923
+ const queryLength = query.length;
1009
924
  if (settings.ignoreSearchCase) {
1010
925
  query = query.toLowerCase();
1011
926
  term = term.toLowerCase();
@@ -1016,13 +931,11 @@
1016
931
  if (queryLength === termLength) {
1017
932
  return query === term;
1018
933
  }
1019
- for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
1020
- var
1021
- continueSearch = false,
1022
- queryCharacter = query.charCodeAt(characterIndex)
1023
- ;
934
+ for (let characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
935
+ let continueSearch = false;
936
+ const queryCharacter = query.codePointAt(characterIndex);
1024
937
  while (nextCharacterIndex < termLength) {
1025
- if (term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
938
+ if (term.codePointAt(nextCharacterIndex++) === queryCharacter) {
1026
939
  continueSearch = true;
1027
940
 
1028
941
  break;
@@ -1040,13 +953,12 @@
1040
953
  query = settings.ignoreSearchCase ? query.toLowerCase() : query;
1041
954
  term = settings.ignoreSearchCase ? term.toLowerCase() : term;
1042
955
 
1043
- return term.indexOf(query) > -1;
956
+ return term.includes(query);
1044
957
  },
1045
958
  filterActive: function () {
1046
959
  if (settings.useLabels) {
1047
960
  $item.filter('.' + className.active)
1048
- .addClass(className.filtered)
1049
- ;
961
+ .addClass(className.filtered);
1050
962
  }
1051
963
  },
1052
964
 
@@ -1069,14 +981,12 @@
1069
981
  },
1070
982
 
1071
983
  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
- ;
984
+ const $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0);
985
+ const $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0);
986
+ const $selectedItem = $currentlySelected.length > 0
987
+ ? $currentlySelected
988
+ : $activeItem;
989
+ const hasSelected = $selectedItem.length > 0;
1080
990
  if (settings.allowAdditions || (hasSelected && !module.is.multiple())) {
1081
991
  module.debug('Forcing partial selection to selected item', $selectedItem);
1082
992
  module.event.item.click.call($selectedItem, {}, true);
@@ -1091,32 +1001,38 @@
1091
1001
  module.clear();
1092
1002
  }
1093
1003
  module.debug('Creating dropdown with specified values', values);
1094
- var menuConfig = {};
1004
+ const menuConfig = {};
1095
1005
  menuConfig[fields.values] = values;
1096
1006
  module.setup.menu(menuConfig);
1097
- $.each(values, function (index, item) {
1098
- if (item.selected === true) {
1099
- module.debug('Setting initial selection to', item[fields.value]);
1100
- module.set.selected(item[fields.value]);
1101
- if (!module.is.multiple()) {
1102
- return false;
1007
+ const findSelected = function (values) {
1008
+ let hasMultiple = true;
1009
+ $.each(values, function (index, item) {
1010
+ const itemType = item.type || 'item';
1011
+ if (item.selected === true) {
1012
+ module.debug('Setting initial selection to', item[fields.value]);
1013
+ module.set.selected(item[fields.value]);
1014
+ if (!module.is.multiple()) {
1015
+ hasMultiple = false;
1016
+ }
1017
+ } else if (itemType.includes('menu')) {
1018
+ hasMultiple = findSelected(item.values || []);
1103
1019
  }
1104
- }
1105
- });
1020
+
1021
+ return hasMultiple;
1022
+ });
1023
+
1024
+ return hasMultiple;
1025
+ };
1026
+ findSelected(values);
1106
1027
 
1107
1028
  if (module.has.selectInput()) {
1108
1029
  module.disconnect.selectObserver();
1109
1030
  $input.html('');
1110
1031
  $input.append('<option disabled selected value></option>');
1111
1032
  $.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>');
1033
+ const value = item[fields.value];
1034
+ const name = item[fields.name] || '';
1035
+ $input.append('<option value="' + settings.templates.escape(value) + '"' + (item.selected === true ? ' selected' : '') + '>' + settings.templates.escape(name, settings) + '</option>');
1120
1036
  });
1121
1037
  module.observe.select();
1122
1038
  }
@@ -1125,25 +1041,26 @@
1125
1041
 
1126
1042
  event: {
1127
1043
  paste: function (event) {
1128
- var
1129
- pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text'),
1130
- tokens = pasteValue.split(settings.delimiter),
1131
- notFoundTokens = []
1132
- ;
1133
- tokens.forEach(function (value) {
1134
- if (module.set.selected(module.escape.htmlEntities(value.trim()), null, false, true) === false) {
1135
- notFoundTokens.push(value.trim());
1044
+ const pasteValue = (event.originalEvent.clipboardData || window.clipboardData).getData('text');
1045
+ const tokens = pasteValue.split(settings.delimiter);
1046
+ const notFoundTokens = [];
1047
+ for (let value of tokens) {
1048
+ value = value.trim();
1049
+ const valueTrimmed = settings.preserveHTML
1050
+ ? settings.templates.escape(value)
1051
+ : value;
1052
+ if (module.set.selected(valueTrimmed, null, false, true) === false) {
1053
+ notFoundTokens.push(valueTrimmed);
1136
1054
  }
1137
- });
1055
+ }
1138
1056
  event.preventDefault();
1139
1057
  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
- ;
1058
+ const searchEl = $search[0];
1059
+ const startPos = searchEl.selectionStart;
1060
+ const endPos = searchEl.selectionEnd;
1061
+ const orgText = searchEl.value;
1062
+ const pasteText = notFoundTokens.join(settings.delimiter);
1063
+ const newEndPos = startPos + pasteText.length;
1147
1064
  $search.val(orgText.slice(0, startPos) + pasteText + orgText.slice(endPos));
1148
1065
  searchEl.selectionStart = newEndPos;
1149
1066
  searchEl.selectionEnd = newEndPos;
@@ -1171,7 +1088,7 @@
1171
1088
  },
1172
1089
  mousedown: function () {
1173
1090
  if (module.is.searchSelection(true)) {
1174
- // prevent menu hiding on immediate re-focus
1091
+ // prevent the menu hiding on immediate re-focus
1175
1092
  willRefocus = true;
1176
1093
  } else {
1177
1094
  // prevents focus callback from occurring on mousedown
@@ -1180,16 +1097,14 @@
1180
1097
  },
1181
1098
  mouseup: function () {
1182
1099
  if (module.is.searchSelection(true)) {
1183
- // prevent menu hiding on immediate re-focus
1100
+ // prevent the menu hiding on immediate re-focus
1184
1101
  willRefocus = false;
1185
1102
  } else {
1186
1103
  activated = false;
1187
1104
  }
1188
1105
  },
1189
1106
  click: function (event) {
1190
- var
1191
- $target = $(event.target)
1192
- ;
1107
+ const $target = $(event.target);
1193
1108
  // focus search
1194
1109
  if ($target.is($module)) {
1195
1110
  if (!module.is.focusedOnSearch()) {
@@ -1212,15 +1127,13 @@
1212
1127
  },
1213
1128
  blur: function (event) {
1214
1129
  pageLostFocus = document.activeElement === this;
1215
- if (module.is.searchSelection(true) && !willRefocus) {
1216
- if (!itemActivated && !pageLostFocus) {
1217
- if (settings.forceSelection) {
1218
- module.forceSelection();
1219
- } else if (!settings.allowAdditions && !settings.keepSearchTerm && !module.has.menuSearch()) {
1220
- module.remove.searchTerm();
1221
- }
1222
- module.hide();
1130
+ if (module.is.searchSelection(true) && !willRefocus && !itemActivated && !pageLostFocus) {
1131
+ if (settings.forceSelection) {
1132
+ module.forceSelection();
1133
+ } else if (!settings.allowAdditions && !settings.keepSearchTerm && !module.has.menuSearch()) {
1134
+ module.remove.searchTerm();
1223
1135
  }
1136
+ module.hide();
1224
1137
  }
1225
1138
  willRefocus = false;
1226
1139
  },
@@ -1273,16 +1186,14 @@
1273
1186
  },
1274
1187
  label: {
1275
1188
  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
- ;
1189
+ const $label = $(this);
1190
+ const $labels = $module.find(selector.label);
1191
+ const $activeLabels = $labels.filter('.' + className.active);
1192
+ const $nextActive = $label.nextAll('.' + className.active);
1193
+ const $prevActive = $label.prevAll('.' + className.active);
1194
+ const $range = $nextActive.length > 0
1195
+ ? $label.nextUntil($nextActive).add($activeLabels).add($label)
1196
+ : $label.prevUntil($prevActive).add($activeLabels).add($label);
1286
1197
  if (event.shiftKey) {
1287
1198
  $activeLabels.removeClass(className.active);
1288
1199
  $range.addClass(className.active);
@@ -1292,15 +1203,13 @@
1292
1203
  $activeLabels.removeClass(className.active);
1293
1204
  $label.addClass(className.active);
1294
1205
  }
1295
- settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
1206
+ settings.onLabelSelect.call(this, $labels.filter('.' + className.active));
1296
1207
  event.stopPropagation();
1297
1208
  },
1298
1209
  },
1299
1210
  remove: {
1300
1211
  click: function (event) {
1301
- var
1302
- $label = $(this).parent()
1303
- ;
1212
+ const $label = $(this).parent();
1304
1213
  if ($label.hasClass(className.active)) {
1305
1214
  // remove all selected labels
1306
1215
  module.remove.activeLabels();
@@ -1313,11 +1222,9 @@
1313
1222
  },
1314
1223
  test: {
1315
1224
  toggle: function (event) {
1316
- var
1317
- toggleBehavior = module.is.multiple()
1318
- ? module.show
1319
- : module.toggle
1320
- ;
1225
+ const toggleBehavior = module.is.multiple()
1226
+ ? module.show
1227
+ : module.toggle;
1321
1228
  if (module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
1322
1229
  return;
1323
1230
  }
@@ -1331,20 +1238,18 @@
1331
1238
  }
1332
1239
  },
1333
1240
  hide: function (event) {
1334
- if (module.determine.eventInModule(event, module.hide)) {
1335
- if (element.id && $(event.target).attr('for') === element.id) {
1336
- event.preventDefault();
1337
- }
1241
+ if (module.determine.eventInModule(event, module.hide) && element.id && $(event.target).attr('for') === element.id) {
1242
+ event.preventDefault();
1338
1243
  }
1339
1244
  },
1340
1245
  },
1341
1246
  class: {
1342
1247
  mutation: function (mutations) {
1343
- mutations.forEach(function (mutation) {
1248
+ for (const mutation of mutations) {
1344
1249
  if (mutation.attributeName === 'class') {
1345
1250
  module.check.disabled();
1346
1251
  }
1347
- });
1252
+ }
1348
1253
  },
1349
1254
  },
1350
1255
  select: {
@@ -1361,18 +1266,10 @@
1361
1266
  },
1362
1267
  menu: {
1363
1268
  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
- ;
1269
+ const mutation = mutations[0];
1270
+ const $changedNodes = $([...mutation.addedNodes, ...mutation.removedNodes]);
1271
+ const isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0;
1272
+ const isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0;
1376
1273
  if (isUserAddition || isMessage) {
1377
1274
  module.debug('Updating item selector cache');
1378
1275
  module.refreshItems();
@@ -1390,14 +1287,12 @@
1390
1287
  },
1391
1288
  item: {
1392
1289
  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
- ;
1290
+ const $target = $(event.target);
1291
+ const $item = $(this);
1292
+ const $subMenu = $item.children(selector.menu);
1293
+ const $otherMenus = $item.siblings(selector.item).children(selector.menu);
1294
+ const hasSubMenu = $subMenu.length > 0;
1295
+ const isBubbledEvent = $subMenu.find($target).length > 0;
1401
1296
  if (!isBubbledEvent && hasSubMenu) {
1402
1297
  clearTimeout(module.itemTimer);
1403
1298
  module.itemTimer = setTimeout(function () {
@@ -1411,9 +1306,7 @@
1411
1306
  }
1412
1307
  },
1413
1308
  mouseleave: function (event) {
1414
- var
1415
- $subMenu = $(this).find(selector.menu)
1416
- ;
1309
+ const $subMenu = $(this).find(selector.menu);
1417
1310
  if ($subMenu.length > 0) {
1418
1311
  clearTimeout(module.itemTimer);
1419
1312
  module.itemTimer = setTimeout(function () {
@@ -1425,18 +1318,15 @@
1425
1318
  }
1426
1319
  },
1427
1320
  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`
1321
+ const $choice = $(this);
1322
+ const $target = event
1323
+ ? $(event.target || '')
1324
+ : $('');
1325
+ const $subMenu = $choice.find(selector.menu);
1326
+ const text = module.get.choiceText($choice);
1327
+ const value = module.get.choiceValue($choice, text);
1328
+ const hasSubMenu = $subMenu.length > 0;
1329
+ const isBubbledEvent = $subMenu.find($target).length > 0;
1440
1330
  if (document.activeElement.tagName.toLowerCase() !== 'input') {
1441
1331
  $(document.activeElement).trigger('blur');
1442
1332
  }
@@ -1468,29 +1358,25 @@
1468
1358
  },
1469
1359
 
1470
1360
  document: {
1471
- // label selection should occur even when element has no focus
1361
+ // label selection should occur even when the element has no focus
1472
1362
  keydown: function (event) {
1473
- var
1474
- pressedKey = event.which,
1475
- isShortcutKey = module.is.inObject(pressedKey, keys)
1476
- ;
1363
+ const pressedKey = event.which;
1364
+ const isShortcutKey = module.is.inObject(pressedKey, keys);
1477
1365
  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
- ;
1366
+ const $label = $module.find(selector.label);
1367
+ let $activeLabel = $label.filter('.' + className.active);
1368
+ const activeValue = $activeLabel.data(metadata.value);
1369
+ const labelIndex = $label.index($activeLabel);
1370
+ const labelCount = $label.length;
1371
+ const hasActiveLabel = $activeLabel.length > 0;
1372
+ const hasMultipleActive = $activeLabel.length > 1;
1373
+ const isFirstLabel = labelIndex === 0;
1374
+ const isLastLabel = labelIndex + 1 === labelCount;
1375
+ const isSearch = module.is.searchSelection();
1376
+ const isFocusedOnSearch = module.is.focusedOnSearch();
1377
+ const isFocused = module.is.focused();
1378
+ const caretAtStart = isFocusedOnSearch && module.get.caretPosition(false) === 0;
1379
+ const isSelectedSearch = caretAtStart && module.get.caretPosition(true) !== 0;
1494
1380
  if (isSearch && !hasActiveLabel && !isFocusedOnSearch) {
1495
1381
  return;
1496
1382
  }
@@ -1513,8 +1399,7 @@
1513
1399
  } else {
1514
1400
  $activeLabel.prev(selector.siblingLabel)
1515
1401
  .addClass(className.active)
1516
- .end()
1517
- ;
1402
+ .end();
1518
1403
  }
1519
1404
  event.preventDefault();
1520
1405
  }
@@ -1558,10 +1443,8 @@
1558
1443
  case keys.backspace: {
1559
1444
  if (hasActiveLabel) {
1560
1445
  module.verbose('Removing active labels');
1561
- if (isLastLabel) {
1562
- if (isSearch && !isFocusedOnSearch) {
1563
- module.focusSearch();
1564
- }
1446
+ if (isLastLabel && isSearch && !isFocusedOnSearch) {
1447
+ module.focusSearch();
1565
1448
  }
1566
1449
  $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
1567
1450
  module.remove.activeLabels($activeLabel);
@@ -1589,32 +1472,28 @@
1589
1472
  },
1590
1473
 
1591
1474
  keydown: function (event) {
1592
- var
1593
- pressedKey = event.which,
1594
- isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter
1595
- ;
1475
+ let pressedKey = event.which;
1476
+ const isShortcutKey = module.is.inObject(pressedKey, keys) || event.key === settings.delimiter;
1596
1477
  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
1478
+ const $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0);
1479
+ const $activeItem = $menu.children('.' + className.active).eq(0);
1480
+ const $selectedItem = $currentlySelected.length > 0
1481
+ ? $currentlySelected
1482
+ : $activeItem;
1483
+ const $visibleItems = $selectedItem.length > 0
1484
+ ? $selectedItem.siblings(':not(.' + className.filtered + ')').addBack()
1485
+ : $menu.children(':not(.' + className.filtered + ')');
1486
+ const $subMenu = $selectedItem.children(selector.menu);
1487
+ const $parentMenu = $selectedItem.closest(selector.menu);
1488
+ const inVisibleMenu = $parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0;
1489
+ const hasSubMenu = $subMenu.length > 0;
1490
+ const hasSelectedItem = $selectedItem.length > 0;
1491
+ const selectedIsSelectable = $selectedItem.not(selector.unselectable).length > 0;
1492
+ const delimiterPressed = event.key === settings.delimiter && module.is.multiple();
1493
+ const isAdditionWithoutMenu = settings.allowAdditions && (pressedKey === keys.enter || delimiterPressed);
1494
+ let $nextItem;
1495
+ let isSubMenuItem;
1496
+ // allow selection with the menu closed
1618
1497
  if (isAdditionWithoutMenu) {
1619
1498
  if (selectedIsSelectable && settings.hideAdditions) {
1620
1499
  module.verbose('Selecting item from keyboard shortcut', $selectedItem);
@@ -1630,7 +1509,7 @@
1630
1509
 
1631
1510
  // visible menu keyboard shortcuts
1632
1511
  if (module.is.visible()) {
1633
- // enter (select or open sub-menu)
1512
+ // enter (select or open submenu)
1634
1513
  if (pressedKey === keys.enter || delimiterPressed) {
1635
1514
  if (pressedKey === keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
1636
1515
  module.verbose('Pressed enter on unselectable category, opening sub menu');
@@ -1659,30 +1538,24 @@
1659
1538
  module.verbose('Left key pressed, closing sub-menu');
1660
1539
  module.animate.hide(false, $parentMenu);
1661
1540
  $selectedItem
1662
- .removeClass(className.selected)
1663
- ;
1541
+ .removeClass(className.selected);
1664
1542
  $parentMenu
1665
1543
  .closest(selector.item)
1666
- .addClass(className.selected)
1667
- ;
1544
+ .addClass(className.selected);
1668
1545
  event.preventDefault();
1669
1546
  }
1670
1547
  }
1671
1548
 
1672
- // right arrow (show sub-menu)
1673
- if (pressedKey === keys.rightArrow) {
1674
- if (hasSubMenu) {
1675
- module.verbose('Right key pressed, opening sub-menu');
1676
- module.animate.show(false, $subMenu);
1677
- $selectedItem
1678
- .removeClass(className.selected)
1679
- ;
1680
- $subMenu
1681
- .find(selector.item).eq(0)
1682
- .addClass(className.selected)
1683
- ;
1684
- event.preventDefault();
1685
- }
1549
+ // right arrow (show submenu)
1550
+ if (pressedKey === keys.rightArrow && hasSubMenu) {
1551
+ module.verbose('Right key pressed, opening sub-menu');
1552
+ module.animate.show(false, $subMenu);
1553
+ $selectedItem
1554
+ .removeClass(className.selected);
1555
+ $subMenu
1556
+ .find(selector.item).eq(0)
1557
+ .addClass(className.selected);
1558
+ event.preventDefault();
1686
1559
  }
1687
1560
  }
1688
1561
 
@@ -1700,11 +1573,9 @@
1700
1573
 
1701
1574
  module.verbose('Up key pressed, changing active item');
1702
1575
  $selectedItem
1703
- .removeClass(className.selected)
1704
- ;
1576
+ .removeClass(className.selected);
1705
1577
  $nextItem
1706
- .addClass(className.selected)
1707
- ;
1578
+ .addClass(className.selected);
1708
1579
  module.set.scrollPosition($nextItem);
1709
1580
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1710
1581
  module.set.selectedItem($nextItem);
@@ -1727,11 +1598,9 @@
1727
1598
 
1728
1599
  module.verbose('Down key pressed, changing active item');
1729
1600
  $item
1730
- .removeClass(className.selected)
1731
- ;
1601
+ .removeClass(className.selected);
1732
1602
  $nextItem
1733
- .addClass(className.selected)
1734
- ;
1603
+ .addClass(className.selected);
1735
1604
  module.set.scrollPosition($nextItem);
1736
1605
  if (settings.selectOnKeydown && module.is.single() && !$nextItem.hasClass(className.actionable)) {
1737
1606
  module.set.selectedItem($nextItem);
@@ -1763,29 +1632,25 @@
1763
1632
  }
1764
1633
  // down arrow (open menu)
1765
1634
  if (pressedKey === keys.downArrow && !module.is.visible()) {
1635
+ focused = true;
1766
1636
  module.verbose('Down key pressed, showing dropdown');
1767
1637
  module.show();
1768
1638
  event.preventDefault();
1769
1639
  }
1770
1640
  }
1771
- } else {
1772
- if (!module.has.search()) {
1773
- module.set.selectedLetter(String.fromCharCode(pressedKey));
1774
- }
1641
+ } else if (!module.has.search()) {
1642
+ module.set.selectedLetter(String.fromCodePoint(pressedKey));
1775
1643
  }
1776
1644
  },
1777
1645
  },
1778
1646
 
1779
1647
  trigger: {
1780
1648
  change: function () {
1781
- var
1782
- inputElement = $input[0]
1783
- ;
1649
+ const inputElement = $input[0];
1784
1650
  if (inputElement) {
1785
- var events = document.createEvent('HTMLEvents');
1651
+ const event = new Event('change', { bubbles: true });
1786
1652
  module.verbose('Triggering native change event');
1787
- events.initEvent('change', true, false);
1788
- inputElement.dispatchEvent(events);
1653
+ inputElement.dispatchEvent(event);
1789
1654
  }
1790
1655
  },
1791
1656
  },
@@ -1806,11 +1671,9 @@
1806
1671
  selectActionActive = false;
1807
1672
  },
1808
1673
  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
- ;
1674
+ const $target = $(event.target);
1675
+ const inDocument = $target.closest(document.documentElement).length > 0;
1676
+ const inModule = $target.closest($module).length > 0;
1814
1677
  callback = isFunction(callback)
1815
1678
  ? callback
1816
1679
  : function () {};
@@ -1826,13 +1689,11 @@
1826
1689
  return false;
1827
1690
  },
1828
1691
  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
- ;
1692
+ const $target = $(event.target);
1693
+ const $label = $target.closest(selector.siblingLabel);
1694
+ const inVisibleDOM = document.body.contains(event.target);
1695
+ const notOnLabel = $module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels);
1696
+ const notInMenu = $target.closest($menu).length === 0;
1836
1697
  callback = isFunction(callback)
1837
1698
  ? callback
1838
1699
  : function () {};
@@ -1853,10 +1714,7 @@
1853
1714
 
1854
1715
  nothing: function () {},
1855
1716
 
1856
- activate: function (text, value, element) {
1857
- value = value !== undefined
1858
- ? value
1859
- : text;
1717
+ activate: function (text, value = text, element = '') {
1860
1718
  if (module.can.activate($(element))) {
1861
1719
  module.set.selected(value, $(element), false, settings.keepSearchTerm);
1862
1720
  if (!module.is.multiple() && !(!settings.collapseOnActionable && $(element).hasClass(className.actionable))) {
@@ -1865,10 +1723,7 @@
1865
1723
  }
1866
1724
  },
1867
1725
 
1868
- select: function (text, value, element) {
1869
- value = value !== undefined
1870
- ? value
1871
- : text;
1726
+ select: function (text, value = text, element = '') {
1872
1727
  if (module.can.activate($(element))) {
1873
1728
  module.set.value(value, text, $(element));
1874
1729
  if (!module.is.multiple() && !(!settings.collapseOnActionable && $(element).hasClass(className.actionable))) {
@@ -1877,10 +1732,7 @@
1877
1732
  }
1878
1733
  },
1879
1734
 
1880
- combo: function (text, value, element) {
1881
- value = value !== undefined
1882
- ? value
1883
- : text;
1735
+ combo: function (text, value = text, element = '') {
1884
1736
  module.set.selected(value, $(element));
1885
1737
  module.hideAndClear();
1886
1738
  },
@@ -1910,30 +1762,25 @@
1910
1762
  return $module.data(metadata.placeholderText) || '';
1911
1763
  },
1912
1764
  text: function () {
1913
- return settings.preserveHTML ? $text.html() : $text.text();
1765
+ return settings.preserveHTML
1766
+ ? $text.html()
1767
+ : $text.text();
1914
1768
  },
1915
1769
  query: function () {
1916
1770
  return String($search.val()).trim();
1917
1771
  },
1918
- searchWidth: function (value) {
1919
- value = value !== undefined
1920
- ? value
1921
- : $search.val();
1772
+ searchWidth: function (value = $search.val()) {
1922
1773
  $sizer.text(value);
1923
1774
 
1924
1775
  // prevent rounding issues
1925
- return Math.ceil($sizer.width() + (module.is.edge() ? 3 : 1));
1776
+ return Math.ceil($sizer.width() + 1);
1926
1777
  },
1927
1778
  selectionCount: function () {
1928
- var
1929
- values = module.get.values(),
1930
- count
1931
- ;
1932
- count = module.is.multiple()
1779
+ const values = module.get.values();
1780
+
1781
+ return module.is.multiple()
1933
1782
  ? (Array.isArray(values) ? values.length : 0)
1934
1783
  : (module.get.value() !== '' ? 1 : 0);
1935
-
1936
- return count;
1937
1784
  },
1938
1785
  transition: function ($subMenu) {
1939
1786
  return settings.transition === 'auto'
@@ -1941,9 +1788,7 @@
1941
1788
  : settings.transition;
1942
1789
  },
1943
1790
  userValues: function () {
1944
- var
1945
- values = module.get.values(true)
1946
- ;
1791
+ let values = module.get.values();
1947
1792
  if (!values) {
1948
1793
  return false;
1949
1794
  }
@@ -1956,16 +1801,12 @@
1956
1801
  });
1957
1802
  },
1958
1803
  uniqueArray: function (array) {
1959
- return $.grep(array, function (value, index) {
1960
- return $.inArray(value, array) === index;
1961
- });
1804
+ return [...new Set(array)];
1962
1805
  },
1963
1806
  caretPosition: function (returnEndPos) {
1964
- var
1965
- input = $search[0],
1966
- range,
1967
- rangeLength
1968
- ;
1807
+ const input = $search[0];
1808
+ let range;
1809
+ let rangeLength;
1969
1810
  if (returnEndPos && 'selectionEnd' in input) {
1970
1811
  return input.selectionEnd;
1971
1812
  }
@@ -1985,47 +1826,37 @@
1985
1826
  }
1986
1827
  },
1987
1828
  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
1829
+ const value = $input.length > 0
1830
+ ? $input.val()
1831
+ : $module.data(metadata.value);
1832
+ const isEmptyMultiselect = Array.isArray(value) && value.length === 1 && value[0] === '';
1833
+
1834
+ // prevents the placeholder element from being selected when multiple
1996
1835
  return value === undefined || isEmptyMultiselect
1997
1836
  ? ''
1998
1837
  : value;
1999
1838
  },
2000
- values: function (raw) {
2001
- var
2002
- value = module.get.value()
2003
- ;
1839
+ values: function () {
1840
+ const value = module.get.value();
2004
1841
  if (value === '') {
2005
1842
  return '';
2006
1843
  }
2007
1844
 
2008
1845
  return !module.has.selectInput() && module.is.multiple()
2009
1846
  ? (typeof value === 'string' // delimited string
2010
- ? (raw
2011
- ? value
2012
- : module.escape.htmlEntities(value)).split(settings.delimiter)
1847
+ ? value.split(settings.delimiter)
2013
1848
  : '')
2014
1849
  : value;
2015
1850
  },
2016
1851
  remoteValues: function () {
2017
- var
2018
- values = module.get.values(),
2019
- remoteValues = false
2020
- ;
1852
+ let values = module.get.values();
1853
+ let remoteValues = false;
2021
1854
  if (values) {
2022
1855
  if (typeof values === 'string') {
2023
1856
  values = [values];
2024
1857
  }
2025
1858
  $.each(values, function (index, value) {
2026
- var
2027
- name = module.read.remoteData(value)
2028
- ;
1859
+ const name = module.read.remoteData(value);
2029
1860
  module.verbose('Restoring value from session data', name, value);
2030
1861
  if (name) {
2031
1862
  if (!remoteValues) {
@@ -2038,10 +1869,7 @@
2038
1869
 
2039
1870
  return remoteValues;
2040
1871
  },
2041
- choiceText: function ($choice, preserveHTML) {
2042
- preserveHTML = preserveHTML !== undefined
2043
- ? preserveHTML
2044
- : settings.preserveHTML;
1872
+ choiceText: function ($choice, preserveHTML = settings.preserveHTML) {
2045
1873
  if ($choice) {
2046
1874
  if ($choice.find(selector.menu).length > 0) {
2047
1875
  module.verbose('Retrieving text of element with sub-menu');
@@ -2057,8 +1885,7 @@
2057
1885
  : $choice.text() && $choice.text().trim());
2058
1886
  }
2059
1887
  },
2060
- choiceValue: function ($choice, choiceText) {
2061
- choiceText = choiceText || module.get.choiceText($choice);
1888
+ choiceValue: function ($choice, choiceText = module.get.choiceText($choice)) {
2062
1889
  if (!$choice) {
2063
1890
  return false;
2064
1891
  }
@@ -2074,9 +1901,7 @@
2074
1901
  : String(choiceText));
2075
1902
  },
2076
1903
  inputEvent: function () {
2077
- var
2078
- input = $search[0]
2079
- ;
1904
+ const input = $search[0];
2080
1905
  if (input) {
2081
1906
  return input.oninput !== undefined
2082
1907
  ? 'input'
@@ -2088,26 +1913,22 @@
2088
1913
  return false;
2089
1914
  },
2090
1915
  selectValues: function () {
2091
- var
2092
- select = {},
2093
- oldGroup = [],
2094
- values = []
2095
- ;
1916
+ const select = {};
1917
+ let oldGroup = [];
1918
+ const values = [];
2096
1919
  $module
2097
1920
  .find('option')
2098
1921
  .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
- ;
1922
+ const $option = $(this);
1923
+ const name = module.escape.assumeUnescapedAmpLtGt($option.html());
1924
+ const disabled = $option.attr('disabled');
1925
+ const value = $option.attr('value') !== undefined
1926
+ ? $option.attr('value')
1927
+ : name;
1928
+ const text = $option.data(metadata.text) !== undefined
1929
+ ? $option.data(metadata.text)
1930
+ : name;
1931
+ const group = $option.parent('optgroup');
2111
1932
  if (settings.placeholder === 'auto' && value === '') {
2112
1933
  select.placeholder = name;
2113
1934
  } else {
@@ -2122,12 +1943,11 @@
2122
1943
  values.push({
2123
1944
  name: name,
2124
1945
  value: value,
2125
- text: module.escape.htmlEntities(text, true),
1946
+ text: text,
2126
1947
  disabled: disabled,
2127
1948
  });
2128
1949
  }
2129
- })
2130
- ;
1950
+ });
2131
1951
  if (settings.placeholder && settings.placeholder !== 'auto') {
2132
1952
  module.debug('Setting placeholder value to', settings.placeholder);
2133
1953
  select.placeholder = settings.placeholder;
@@ -2157,20 +1977,16 @@
2157
1977
  return $item.filter('.' + className.active);
2158
1978
  },
2159
1979
  selectedItem: function () {
2160
- var
2161
- $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
2162
- ;
1980
+ const $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected);
2163
1981
 
2164
1982
  return $selectedItem.length > 0
2165
1983
  ? $selectedItem
2166
1984
  : $item.eq(0);
2167
1985
  },
2168
1986
  itemWithAdditions: function (value) {
2169
- var
2170
- $items = module.get.item(value),
2171
- $userItems = module.create.userChoice(value),
2172
- hasUserItems = $userItems && $userItems.length > 0
2173
- ;
1987
+ let $items = module.get.item(value);
1988
+ const $userItems = module.create.userChoice(value);
1989
+ const hasUserItems = $userItems && $userItems.length > 0;
2174
1990
  if (hasUserItems) {
2175
1991
  $items = $items.length > 0
2176
1992
  ? $items.add($userItems)
@@ -2180,18 +1996,14 @@
2180
1996
  return $items;
2181
1997
  },
2182
1998
  item: function (value, strict) {
2183
- var
2184
- $selectedItem = false,
2185
- shouldSearch,
2186
- isMultiple
2187
- ;
1999
+ let $selectedItem = false;
2188
2000
  value = value !== undefined
2189
2001
  ? value
2190
2002
  : (module.get.values() !== undefined
2191
2003
  ? module.get.values()
2192
2004
  : module.get.text());
2193
- isMultiple = module.is.multiple() && Array.isArray(value);
2194
- shouldSearch = isMultiple
2005
+ const isMultiple = module.is.multiple() && Array.isArray(value);
2006
+ const shouldSearch = isMultiple
2195
2007
  ? value.length > 0
2196
2008
  : value !== undefined && value !== null;
2197
2009
  strict = value === '' || value === false || value === true
@@ -2200,17 +2012,15 @@
2200
2012
  if (shouldSearch) {
2201
2013
  $item
2202
2014
  .each(function () {
2203
- var
2204
- $choice = $(this),
2205
- optionText = module.get.choiceText($choice),
2206
- optionValue = module.get.choiceValue($choice, optionText)
2207
- ;
2015
+ const $choice = $(this);
2016
+ const optionText = module.get.choiceText($choice);
2017
+ let optionValue = module.get.choiceValue($choice, optionText);
2208
2018
  // safe early exit
2209
2019
  if (optionValue === null || optionValue === undefined) {
2210
2020
  return;
2211
2021
  }
2212
2022
  if (isMultiple) {
2213
- if ($.inArray(module.escape.htmlEntities(String(optionValue)), value.map(String).map(module.escape.htmlEntities)) !== -1) {
2023
+ if (value.map(String).includes(String(optionValue))) {
2214
2024
  $selectedItem = $selectedItem
2215
2025
  ? $selectedItem.add($choice)
2216
2026
  : $choice;
@@ -2227,15 +2037,14 @@
2227
2037
  optionValue = optionValue.toLowerCase();
2228
2038
  value = value.toLowerCase();
2229
2039
  }
2230
- if (module.escape.htmlEntities(String(optionValue)) === module.escape.htmlEntities(String(value))) {
2040
+ if (String(optionValue) === String(value)) {
2231
2041
  module.verbose('Found select item by value', optionValue, value);
2232
2042
  $selectedItem = $choice;
2233
2043
 
2234
2044
  return true;
2235
2045
  }
2236
2046
  }
2237
- })
2238
- ;
2047
+ });
2239
2048
  }
2240
2049
 
2241
2050
  return $selectedItem;
@@ -2246,11 +2055,8 @@
2246
2055
  },
2247
2056
 
2248
2057
  check: {
2249
- maxSelections: function (selectionCount) {
2058
+ maxSelections: function (selectionCount = module.get.selectionCount()) {
2250
2059
  if (settings.maxSelections) {
2251
- selectionCount = selectionCount !== undefined
2252
- ? selectionCount
2253
- : module.get.selectionCount();
2254
2060
  if (selectionCount >= settings.maxSelections) {
2255
2061
  module.debug('Maximum selection count reached');
2256
2062
  if (settings.useLabels) {
@@ -2285,10 +2091,8 @@
2285
2091
  module.restore.defaultValue();
2286
2092
  },
2287
2093
  defaultText: function () {
2288
- var
2289
- defaultText = module.get.defaultText(),
2290
- placeholderText = module.get.placeholderText
2291
- ;
2094
+ const defaultText = module.get.defaultText();
2095
+ const placeholderText = module.get.placeholderText;
2292
2096
  if (defaultText === placeholderText) {
2293
2097
  module.debug('Restoring default placeholder text', defaultText);
2294
2098
  module.set.placeholderText(defaultText);
@@ -2301,9 +2105,7 @@
2301
2105
  module.set.placeholderText();
2302
2106
  },
2303
2107
  defaultValue: function () {
2304
- var
2305
- defaultValue = module.get.defaultValue()
2306
- ;
2108
+ const defaultValue = module.get.defaultValue();
2307
2109
  if (defaultValue !== undefined) {
2308
2110
  module.debug('Restoring default value', defaultValue);
2309
2111
  if (defaultValue !== '') {
@@ -2336,14 +2138,14 @@
2336
2138
  }
2337
2139
  },
2338
2140
  values: function () {
2339
- // prevents callbacks from occurring on initial load
2141
+ // prevents callbacks from occurring on the initial load
2340
2142
  module.set.initialLoad();
2341
2143
  if (settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) {
2342
2144
  module.restore.remoteValues();
2343
2145
  } else {
2344
2146
  module.set.selected();
2345
2147
  }
2346
- var value = module.get.value();
2148
+ const value = module.get.value();
2347
2149
  if (value && value !== '' && !(Array.isArray(value) && value.length === 0)) {
2348
2150
  $input.removeClass(className.noselection);
2349
2151
  } else {
@@ -2352,9 +2154,7 @@
2352
2154
  module.remove.initialLoad();
2353
2155
  },
2354
2156
  remoteValues: function () {
2355
- var
2356
- values = module.get.remoteValues()
2357
- ;
2157
+ const values = module.get.remoteValues();
2358
2158
  module.debug('Recreating selected from session data', values);
2359
2159
  if (values) {
2360
2160
  if (module.is.single()) {
@@ -2372,15 +2172,7 @@
2372
2172
 
2373
2173
  read: {
2374
2174
  remoteData: function (value) {
2375
- var
2376
- name
2377
- ;
2378
- if (window.Storage === undefined) {
2379
- module.error(error.noStorage);
2380
-
2381
- return;
2382
- }
2383
- name = sessionStorage.getItem(value + elementNamespace);
2175
+ const name = window.sessionStorage.getItem(value + elementNamespace);
2384
2176
 
2385
2177
  return name !== undefined
2386
2178
  ? name
@@ -2395,23 +2187,17 @@
2395
2187
  module.save.defaultValue();
2396
2188
  },
2397
2189
  defaultValue: function () {
2398
- var
2399
- value = module.get.value()
2400
- ;
2190
+ const value = module.get.value();
2401
2191
  module.verbose('Saving default value as', value);
2402
2192
  $module.data(metadata.defaultValue, value);
2403
2193
  },
2404
2194
  defaultText: function () {
2405
- var
2406
- text = module.get.text()
2407
- ;
2195
+ const text = module.get.text();
2408
2196
  module.verbose('Saving default text as', text);
2409
2197
  $module.data(metadata.defaultText, text);
2410
2198
  },
2411
2199
  placeholderText: function () {
2412
- var
2413
- text
2414
- ;
2200
+ let text;
2415
2201
  if (settings.placeholder !== false && $text.hasClass(className.placeholder)) {
2416
2202
  text = module.get.text();
2417
2203
  module.verbose('Saving placeholder text as', text);
@@ -2419,13 +2205,8 @@
2419
2205
  }
2420
2206
  },
2421
2207
  remoteData: function (name, value) {
2422
- if (window.Storage === undefined) {
2423
- module.error(error.noStorage);
2424
-
2425
- return;
2426
- }
2427
2208
  module.verbose('Saving remote data to session storage', value, name);
2428
- sessionStorage.setItem(value + elementNamespace, name);
2209
+ window.sessionStorage.setItem(value + elementNamespace, name);
2429
2210
  },
2430
2211
  },
2431
2212
 
@@ -2451,28 +2232,23 @@
2451
2232
  },
2452
2233
 
2453
2234
  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
- ;
2469
- elementIndex = direction === 'up'
2235
+ const $currentItem = $selectedItem || module.get.selectedItem();
2236
+ const $menu = $currentItem.closest(selector.menu);
2237
+ const menuHeight = $menu.outerHeight();
2238
+ const currentScroll = $menu.scrollTop();
2239
+ const itemHeight = $item.eq(0).outerHeight();
2240
+ const itemsPerPage = Math.floor(menuHeight / itemHeight);
2241
+ const newScroll = direction === 'up'
2242
+ ? currentScroll - (itemHeight * itemsPerPage)
2243
+ : currentScroll + (itemHeight * itemsPerPage);
2244
+ const $selectableItem = $item.not(selector.unselectable);
2245
+ const elementIndex = direction === 'up'
2470
2246
  ? $selectableItem.index($currentItem) - itemsPerPage
2471
2247
  : $selectableItem.index($currentItem) + itemsPerPage;
2472
- isWithinRange = direction === 'up'
2248
+ const isWithinRange = direction === 'up'
2473
2249
  ? elementIndex >= 0
2474
2250
  : elementIndex < $selectableItem.length;
2475
- $nextSelectedItem = isWithinRange
2251
+ const $nextSelectedItem = isWithinRange
2476
2252
  ? $selectableItem.eq(elementIndex)
2477
2253
  : (direction === 'up'
2478
2254
  ? $selectableItem.first()
@@ -2480,33 +2256,28 @@
2480
2256
  if ($nextSelectedItem.length > 0) {
2481
2257
  module.debug('Scrolling page', direction, $nextSelectedItem);
2482
2258
  $currentItem
2483
- .removeClass(className.selected)
2484
- ;
2259
+ .removeClass(className.selected);
2485
2260
  $nextSelectedItem
2486
- .addClass(className.selected)
2487
- ;
2261
+ .addClass(className.selected);
2488
2262
  if (settings.selectOnKeydown && module.is.single() && !$nextSelectedItem.hasClass(className.actionable)) {
2489
2263
  module.set.selectedItem($nextSelectedItem);
2490
2264
  }
2491
2265
  $menu
2492
- .scrollTop(newScroll)
2493
- ;
2266
+ .scrollTop(newScroll);
2494
2267
  }
2495
2268
  },
2496
2269
 
2497
2270
  set: {
2498
2271
  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
- ;
2272
+ const isMultiple = module.is.multiple();
2273
+ const isSearch = module.is.searchSelection();
2274
+ const isSearchMultiple = isMultiple && isSearch;
2275
+ const searchValue = isSearch
2276
+ ? module.get.query()
2277
+ : '';
2278
+ const hasSearchValue = typeof searchValue === 'string' && searchValue.length > 0;
2279
+ const searchWidth = module.get.searchWidth();
2280
+ const valueIsSet = searchValue !== '';
2510
2281
  if (isMultiple && hasSearchValue) {
2511
2282
  module.verbose('Adjusting input width', searchWidth);
2512
2283
  $search.css('width', searchWidth + 'px');
@@ -2525,8 +2296,7 @@
2525
2296
  loading: function () {
2526
2297
  $module.addClass(className.loading);
2527
2298
  },
2528
- placeholderText: function (text) {
2529
- text = text || module.get.placeholderText();
2299
+ placeholderText: function (text = module.get.placeholderText()) {
2530
2300
  module.debug('Setting placeholder text', text);
2531
2301
  module.set.text(text);
2532
2302
  $text.addClass(className.placeholder);
@@ -2535,21 +2305,17 @@
2535
2305
  if (module.is.searchSelection()) {
2536
2306
  module.debug('Added tabindex to searchable dropdown');
2537
2307
  $search
2538
- .val('')
2539
- ;
2308
+ .val('');
2540
2309
  module.check.disabled();
2541
2310
  $menu
2542
- .attr('tabindex', -1)
2543
- ;
2311
+ .attr('tabindex', -1);
2544
2312
  } else {
2545
2313
  module.debug('Added tabindex to dropdown');
2546
2314
  if ($module.attr('tabindex') === undefined) {
2547
2315
  $module
2548
- .attr('tabindex', $input.attr('tabindex') || 0)
2549
- ;
2316
+ .attr('tabindex', $input.attr('tabindex') || 0);
2550
2317
  $menu
2551
- .attr('tabindex', -1)
2552
- ;
2318
+ .attr('tabindex', -1);
2553
2319
  }
2554
2320
  }
2555
2321
  $input.removeAttr('tabindex');
@@ -2566,31 +2332,22 @@
2566
2332
  }
2567
2333
  },
2568
2334
  partialSearch: function (text) {
2569
- var
2570
- length = module.get.query().length
2571
- ;
2335
+ const length = module.get.query().length;
2572
2336
  $search.val(text.slice(0, length));
2573
2337
  },
2574
- 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
- ;
2338
+ scrollPosition: function ($item, forceScroll = false) {
2339
+ const edgeTolerance = 5;
2340
+ let offset;
2341
+ let itemOffset;
2342
+ let menuOffset;
2343
+ let menuScroll;
2344
+ let menuHeight;
2345
+ let abovePage;
2346
+ let belowPage;
2587
2347
 
2588
2348
  $item = $item || module.get.selectedItem();
2589
- $menu = $item.closest(selector.menu);
2590
- hasActive = $item && $item.length > 0;
2591
- forceScroll = forceScroll !== undefined
2592
- ? forceScroll
2593
- : false;
2349
+ const $menu = $item.closest(selector.menu);
2350
+ const hasActive = $item && $item.length > 0;
2594
2351
  if (module.get.activeItem().length === 0) {
2595
2352
  forceScroll = false;
2596
2353
  }
@@ -2628,8 +2385,7 @@
2628
2385
  }
2629
2386
  module.debug('Changing text', text, $text);
2630
2387
  $text
2631
- .removeClass(className.filtered)
2632
- ;
2388
+ .removeClass(className.filtered);
2633
2389
  if (settings.preserveHTML) {
2634
2390
  $text.html(text);
2635
2391
  } else {
@@ -2638,11 +2394,9 @@
2638
2394
  }
2639
2395
  },
2640
2396
  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
- ;
2397
+ const value = module.get.choiceValue($item);
2398
+ const searchText = module.get.choiceText($item, false);
2399
+ const text = module.get.choiceText($item);
2646
2400
  module.debug('Setting user selection to item', $item);
2647
2401
  module.remove.activeItem();
2648
2402
  module.set.partialSearch(searchText);
@@ -2651,13 +2405,11 @@
2651
2405
  module.set.text(text);
2652
2406
  },
2653
2407
  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
2408
+ const $selectedItem = $item.filter('.' + className.selected);
2409
+ const alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter);
2410
+ let $nextValue = false;
2411
+ let $nextItem;
2412
+ // check next of the same letter
2661
2413
  if (alreadySelectedLetter) {
2662
2414
  $nextItem = $selectedItem.nextAll($item).eq(0);
2663
2415
  if (module.has.firstLetter($nextItem, letter)) {
@@ -2673,10 +2425,9 @@
2673
2425
 
2674
2426
  return false;
2675
2427
  }
2676
- })
2677
- ;
2428
+ });
2678
2429
  }
2679
- // set next value
2430
+ // set the next value
2680
2431
  if ($nextValue) {
2681
2432
  module.verbose('Scrolling to next value with letter', letter);
2682
2433
  module.set.scrollPosition($nextValue);
@@ -2693,7 +2444,7 @@
2693
2444
  if (!$menu) {
2694
2445
  module.remove.upward();
2695
2446
  } else if (module.is.upward($menu)) {
2696
- // we need make sure when make assertion openDownward for $menu, $menu does not have upward class
2447
+ // we need to make sure when make assertion openDownward for $menu, $menu does not have upward class
2697
2448
  module.remove.upward($menu);
2698
2449
  }
2699
2450
 
@@ -2710,11 +2461,11 @@
2710
2461
  }
2711
2462
  },
2712
2463
  upward: function ($currentMenu) {
2713
- var $element = $currentMenu || $module;
2464
+ const $element = $currentMenu || $module;
2714
2465
  $element.addClass(className.upward);
2715
2466
  },
2716
2467
  leftward: function ($currentMenu) {
2717
- var $element = $currentMenu || $menu;
2468
+ const $element = $currentMenu || $menu;
2718
2469
  $element.addClass(className.leftward);
2719
2470
  },
2720
2471
  value: function (value, text, $selected, preventChangeTrigger) {
@@ -2728,14 +2479,11 @@
2728
2479
  } else {
2729
2480
  $input.addClass(className.noselection);
2730
2481
  }
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
- ;
2482
+ const hasInput = $input.length > 0;
2483
+ const currentValue = module.get.values();
2484
+ const stringValue = value !== undefined
2485
+ ? String(value)
2486
+ : value;
2739
2487
  if (hasInput) {
2740
2488
  if (!settings.allowReselection && stringValue == currentValue) {
2741
2489
  module.verbose('Skipping value update already same value', value, currentValue);
@@ -2748,11 +2496,10 @@
2748
2496
  module.debug('Adding user option', value);
2749
2497
  module.add.optionValue(value);
2750
2498
  }
2751
- module.debug('Updating input value', escapedValue, currentValue);
2499
+ module.debug('Updating input value', value, currentValue);
2752
2500
  internalChange = true;
2753
2501
  $input
2754
- .val(escapedValue)
2755
- ;
2502
+ .val(value);
2756
2503
  if (settings.fireOnInit === false && module.is.initialLoad()) {
2757
2504
  module.debug('Input native change event ignored on initial load');
2758
2505
  } else if (preventChangeTrigger !== true) {
@@ -2760,8 +2507,8 @@
2760
2507
  }
2761
2508
  internalChange = false;
2762
2509
  } else {
2763
- module.verbose('Storing value in metadata', escapedValue, $input);
2764
- if (escapedValue !== currentValue) {
2510
+ module.verbose('Storing value in metadata', value, $input);
2511
+ if (value !== currentValue) {
2765
2512
  $module.data(metadata.value, stringValue);
2766
2513
  }
2767
2514
  }
@@ -2773,8 +2520,7 @@
2773
2520
  },
2774
2521
  active: function () {
2775
2522
  $module
2776
- .addClass(className.active)
2777
- ;
2523
+ .addClass(className.active);
2778
2524
  },
2779
2525
  multiple: function () {
2780
2526
  $module.addClass(className.multiple);
@@ -2797,9 +2543,7 @@
2797
2543
  preventChangeTrigger = $selectedItem;
2798
2544
  $selectedItem = undefined;
2799
2545
  }
2800
- var
2801
- isMultiple = module.is.multiple()
2802
- ;
2546
+ const isMultiple = module.is.multiple();
2803
2547
  $selectedItem = settings.allowAdditions
2804
2548
  ? $selectedItem || module.get.itemWithAdditions(value)
2805
2549
  : $selectedItem || module.get.item(value);
@@ -2813,7 +2557,11 @@
2813
2557
  if (settings.useLabels) {
2814
2558
  module.remove.selectedItem();
2815
2559
  if (value === undefined) {
2816
- module.remove.labels($module.find(selector.label), true);
2560
+ const existingLabels = $module.find(selector.label);
2561
+ if (existingLabels.length > 0) {
2562
+ preventChangeTrigger = true;
2563
+ module.remove.labels(existingLabels, true);
2564
+ }
2817
2565
  }
2818
2566
  }
2819
2567
  } else {
@@ -2827,17 +2575,15 @@
2827
2575
  // select each item
2828
2576
  $selectedItem
2829
2577
  .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
- ;
2578
+ const $selected = $(this);
2579
+ const selectedText = module.get.choiceText($selected);
2580
+ const selectedValue = module.get.choiceValue($selected, selectedText);
2581
+
2582
+ const isFiltered = $selected.hasClass(className.filtered);
2583
+ const isActive = $selected.hasClass(className.active);
2584
+ const isActionable = $selected.hasClass(className.actionable);
2585
+ const isUserValue = $selected.hasClass(className.addition);
2586
+ const shouldAnimate = isMultiple && $selectedItem && $selectedItem.length === 1;
2841
2587
  if (isActionable) {
2842
2588
  if ((!isMultiple || (!isActive || isUserValue)) && settings.apiSettings && settings.saveRemoteData) {
2843
2589
  module.save.remoteData(selectedText, selectedValue);
@@ -2873,11 +2619,9 @@
2873
2619
  module.set.value(selectedValue, selectedText, $selected, preventChangeTrigger);
2874
2620
  $selected
2875
2621
  .addClass(className.active)
2876
- .addClass(className.selected)
2877
- ;
2622
+ .addClass(className.selected);
2878
2623
  }
2879
- })
2880
- ;
2624
+ });
2881
2625
  if (!keepSearchTerm) {
2882
2626
  module.remove.searchTerm();
2883
2627
  }
@@ -2890,25 +2634,21 @@
2890
2634
 
2891
2635
  add: {
2892
2636
  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
- ;
2637
+ const $next = module.is.searchSelection()
2638
+ ? $search
2639
+ : $text;
2640
+ let $label;
2900
2641
  if (settings.ignoreCase) {
2901
- escapedValue = escapedValue.toLowerCase();
2642
+ value = value.toLowerCase();
2902
2643
  }
2903
2644
  $label = $('<a />')
2904
2645
  .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);
2646
+ .attr('data-' + metadata.value, value)
2647
+ .html(templates.label(value, text, settings));
2648
+ $label = settings.onLabelCreate.call($label, value, text);
2909
2649
 
2910
2650
  if (module.has.label(value)) {
2911
- module.debug('User selection already exists, skipping', escapedValue);
2651
+ module.debug('User selection already exists, skipping', value);
2912
2652
 
2913
2653
  return;
2914
2654
  }
@@ -2926,38 +2666,29 @@
2926
2666
  verbose: settings.verbose,
2927
2667
  silent: settings.silent,
2928
2668
  duration: settings.label.duration,
2929
- })
2930
- ;
2669
+ });
2931
2670
  } else {
2932
2671
  module.debug('Adding selection label', $label);
2933
2672
  $label
2934
- .insertBefore($next)
2935
- ;
2673
+ .insertBefore($next);
2936
2674
  }
2937
2675
  },
2938
2676
  message: function (message) {
2939
- var
2940
- $message = $menu.children(selector.message),
2941
- html = settings.templates.message(module.add.variables(message))
2942
- ;
2677
+ const $message = $menu.children(selector.message);
2678
+ const html = settings.templates.message(module.add.variables(message));
2943
2679
  if ($message.length > 0) {
2944
2680
  $message
2945
- .html(html)
2946
- ;
2681
+ .html(html);
2947
2682
  } else {
2948
2683
  $('<div/>')
2949
2684
  .html(html)
2950
2685
  .addClass(className.message)
2951
- .appendTo($menu)
2952
- ;
2686
+ .appendTo($menu);
2953
2687
  }
2954
2688
  },
2955
2689
  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
- ;
2690
+ const $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2691
+ const hasOption = $option.length > 0;
2961
2692
  if (hasOption) {
2962
2693
  return;
2963
2694
  }
@@ -2968,22 +2699,19 @@
2968
2699
  $input.find('option.' + className.addition).remove();
2969
2700
  }
2970
2701
  $('<option/>')
2971
- .prop('value', escapedValue)
2702
+ .prop('value', value)
2972
2703
  .addClass(className.addition)
2973
2704
  .text(value)
2974
- .appendTo($input)
2975
- ;
2705
+ .appendTo($input);
2976
2706
  module.verbose('Adding user addition as an <option>', value);
2977
2707
  module.observe.select();
2978
2708
  },
2979
2709
  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
- ;
2710
+ let $addition = $menu.children(selector.addition);
2711
+ const $existingItem = module.get.item(value);
2712
+ const alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length > 0;
2713
+ const hasUserSuggestion = $addition.length > 0;
2714
+ let html;
2987
2715
  if (settings.useLabels && module.has.maxSelections()) {
2988
2716
  return;
2989
2717
  }
@@ -2998,38 +2726,31 @@
2998
2726
  .data(metadata.text, value)
2999
2727
  .attr('data-' + metadata.value, value)
3000
2728
  .attr('data-' + metadata.text, value)
3001
- .removeClass(className.filtered)
3002
- ;
2729
+ .removeClass(className.filtered);
3003
2730
  if (!settings.hideAdditions) {
3004
- html = settings.templates.addition(module.add.variables(message.addResult, value));
2731
+ html = settings.templates.addition(module.add.variables(message.addResult, settings.templates.escape(value, settings)));
3005
2732
  $addition
3006
- .html(html)
3007
- ;
2733
+ .html(html);
3008
2734
  }
3009
2735
  module.verbose('Replacing user suggestion with new value', $addition);
3010
2736
  } else {
3011
2737
  $addition = module.create.userChoice(value);
3012
2738
  $addition
3013
- .prependTo($menu)
3014
- ;
2739
+ .prependTo($menu);
3015
2740
  module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
3016
2741
  }
3017
2742
  if (!settings.hideAdditions || module.is.allFiltered()) {
3018
2743
  $addition
3019
2744
  .addClass(className.selected)
3020
2745
  .siblings()
3021
- .removeClass(className.selected)
3022
- ;
2746
+ .removeClass(className.selected);
3023
2747
  }
3024
2748
  module.refreshItems();
3025
2749
  },
3026
- 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
- ;
2750
+ variables: function (message = '', term = module.get.query()) {
2751
+ const hasCount = message.search('{count}') !== -1;
2752
+ const hasMaxCount = message.search('{maxCount}') !== -1;
2753
+ const hasTerm = message.search('{term}') !== -1;
3033
2754
  module.verbose('Adding templated variables to message', message);
3034
2755
  if (hasCount) {
3035
2756
  message = message.replace('{count}', module.get.selectionCount());
@@ -3038,8 +2759,7 @@
3038
2759
  message = message.replace('{maxCount}', settings.maxSelections);
3039
2760
  }
3040
2761
  if (hasTerm) {
3041
- query = term || module.get.query();
3042
- message = message.replace('{term}', query);
2762
+ message = message.replace('{term}', term);
3043
2763
  }
3044
2764
 
3045
2765
  return message;
@@ -3050,10 +2770,8 @@
3050
2770
  $selectedItem = undefined;
3051
2771
  addedText = undefined;
3052
2772
  }
3053
- var
3054
- currentValue = module.get.values(true),
3055
- newValue
3056
- ;
2773
+ const currentValue = module.get.values();
2774
+ let newValue;
3057
2775
  if (module.has.value(addedValue)) {
3058
2776
  module.debug('Value already selected');
3059
2777
 
@@ -3066,7 +2784,9 @@
3066
2784
  }
3067
2785
  // extend current array
3068
2786
  if (Array.isArray(currentValue)) {
3069
- newValue = $selectedItem && $selectedItem.hasClass(className.actionable) ? currentValue : currentValue.concat([addedValue]);
2787
+ newValue = $selectedItem && $selectedItem.hasClass(className.actionable)
2788
+ ? currentValue
2789
+ : [...currentValue, addedValue];
3070
2790
  newValue = module.get.uniqueArray(newValue);
3071
2791
  } else {
3072
2792
  newValue = [addedValue];
@@ -3109,11 +2829,11 @@
3109
2829
  initialLoad = false;
3110
2830
  },
3111
2831
  upward: function ($currentMenu) {
3112
- var $element = $currentMenu || $module;
2832
+ const $element = $currentMenu || $module;
3113
2833
  $element.removeClass(className.upward);
3114
2834
  },
3115
2835
  leftward: function ($currentMenu) {
3116
- var $element = $currentMenu || $menu;
2836
+ const $element = $currentMenu || $menu;
3117
2837
  $element.removeClass(className.leftward);
3118
2838
  },
3119
2839
  visible: function () {
@@ -3125,7 +2845,7 @@
3125
2845
  filteredItem: function () {
3126
2846
  if (settings.highlightMatches) {
3127
2847
  $.each($item, function (index, item) {
3128
- var $markItem = $(item);
2848
+ const $markItem = $(item);
3129
2849
  $markItem.html($markItem.html().replace(/<\/?mark>/g, ''));
3130
2850
  });
3131
2851
  }
@@ -3143,18 +2863,15 @@
3143
2863
  module.remove.empty();
3144
2864
  },
3145
2865
  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
- ;
2866
+ const $option = $input.find('option[value="' + CSS.escape(value) + '"]');
2867
+ const hasOption = $option.length > 0;
3151
2868
  if (!hasOption || !$option.hasClass(className.addition)) {
3152
2869
  return;
3153
2870
  }
3154
2871
  // temporarily disconnect observer
3155
2872
  module.disconnect.selectObserver();
3156
2873
  $option.remove();
3157
- module.verbose('Removing user addition as an <option>', escapedValue);
2874
+ module.verbose('Removing user addition as an <option>', value);
3158
2875
  module.observe.select();
3159
2876
  },
3160
2877
  message: function () {
@@ -3182,11 +2899,9 @@
3182
2899
 
3183
2900
  $selectedItem
3184
2901
  .each(function () {
3185
- var
3186
- $selected = $(this),
3187
- selectedText = module.get.choiceText($selected),
3188
- selectedValue = module.get.choiceValue($selected, selectedText)
3189
- ;
2902
+ const $selected = $(this);
2903
+ const selectedText = module.get.choiceText($selected);
2904
+ const selectedValue = module.get.choiceValue($selected, selectedText);
3190
2905
  if (module.is.multiple()) {
3191
2906
  if (settings.useLabels) {
3192
2907
  module.remove.value(selectedValue, selectedText, $selected, preventChangeTrigger);
@@ -3204,22 +2919,18 @@
3204
2919
  }
3205
2920
  $selected
3206
2921
  .removeClass(className.filtered)
3207
- .removeClass(className.active)
3208
- ;
2922
+ .removeClass(className.active);
3209
2923
  if (settings.useLabels) {
3210
2924
  $selected.removeClass(className.selected);
3211
2925
  }
3212
- })
3213
- ;
2926
+ });
3214
2927
  },
3215
2928
  selectedItem: function () {
3216
2929
  $item.removeClass(className.selected);
3217
2930
  },
3218
2931
  value: function (removedValue, removedText, $removedItem, preventChangeTrigger) {
3219
- var
3220
- values = module.get.values(true),
3221
- newValue
3222
- ;
2932
+ const values = module.get.values();
2933
+ let newValue;
3223
2934
  if (module.has.selectInput()) {
3224
2935
  module.verbose('Input is <select> removing selected option', removedValue);
3225
2936
  newValue = module.remove.arrayValue(removedValue, values);
@@ -3249,11 +2960,8 @@
3249
2960
  return values;
3250
2961
  },
3251
2962
  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
- ;
2963
+ const $labels = $module.find(selector.label);
2964
+ const $removedLabel = $labels.filter('[data-' + metadata.value + '="' + CSS.escape(settings.ignoreCase ? value.toLowerCase() : value) + '"]');
3257
2965
  module.verbose('Removing label', $removedLabel);
3258
2966
  $removedLabel.remove();
3259
2967
  },
@@ -3267,14 +2975,12 @@
3267
2975
  module.verbose('Removing labels', $labels);
3268
2976
  $labels
3269
2977
  .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
- ;
2978
+ const $label = $(this);
2979
+ const value = $label.data(metadata.value);
2980
+ const stringValue = value !== undefined
2981
+ ? String(value)
2982
+ : value;
2983
+ const isUserValue = module.is.userValue(stringValue);
3278
2984
  if (settings.onLabelRemove.call($label, value) === false) {
3279
2985
  module.debug('Label remove callback cancelled removal');
3280
2986
 
@@ -3288,26 +2994,21 @@
3288
2994
  // selected will also remove label
3289
2995
  module.remove.selected(stringValue, false, preventChangeTrigger);
3290
2996
  }
3291
- })
3292
- ;
2997
+ });
3293
2998
  },
3294
2999
  tabbable: function () {
3295
3000
  if (module.is.searchSelection()) {
3296
3001
  module.debug('Searchable dropdown initialized');
3297
3002
  $search
3298
- .removeAttr('tabindex')
3299
- ;
3003
+ .removeAttr('tabindex');
3300
3004
  $menu
3301
- .removeAttr('tabindex')
3302
- ;
3005
+ .removeAttr('tabindex');
3303
3006
  } else {
3304
3007
  module.debug('Simple selection dropdown initialized');
3305
3008
  $module
3306
- .removeAttr('tabindex')
3307
- ;
3009
+ .removeAttr('tabindex');
3308
3010
  $menu
3309
- .removeAttr('tabindex')
3310
- ;
3011
+ .removeAttr('tabindex');
3311
3012
  }
3312
3013
  },
3313
3014
  diacritics: function (text) {
@@ -3331,29 +3032,21 @@
3331
3032
  selectInput: function () {
3332
3033
  return $input.is('select');
3333
3034
  },
3334
- minCharacters: function (searchTerm) {
3035
+ minCharacters: function (searchTerm = module.get.query()) {
3335
3036
  if (settings.minCharacters && !iconClicked) {
3336
- searchTerm = searchTerm !== undefined
3337
- ? String(searchTerm)
3338
- : String(module.get.query());
3339
-
3340
- return searchTerm.length >= settings.minCharacters;
3037
+ return String(searchTerm).length >= settings.minCharacters;
3341
3038
  }
3342
3039
  iconClicked = false;
3343
3040
 
3344
3041
  return true;
3345
3042
  },
3346
3043
  firstLetter: function ($item, letter) {
3347
- var
3348
- text,
3349
- firstLetter
3350
- ;
3351
3044
  if (!$item || $item.length === 0 || typeof letter !== 'string') {
3352
3045
  return false;
3353
3046
  }
3354
- text = module.get.choiceText($item, false);
3047
+ const text = module.get.choiceText($item, false);
3355
3048
  letter = letter.toLowerCase();
3356
- firstLetter = String(text).charAt(0).toLowerCase();
3049
+ const firstLetter = String(text).charAt(0).toLowerCase();
3357
3050
 
3358
3051
  return letter == firstLetter;
3359
3052
  },
@@ -3373,23 +3066,18 @@
3373
3066
  return $menu.children(selector.message).length > 0;
3374
3067
  },
3375
3068
  label: function (value) {
3376
- var
3377
- escapedValue = module.escape.value(value),
3378
- $labels = $module.find(selector.label)
3379
- ;
3069
+ const $labels = $module.find(selector.label);
3380
3070
  if (settings.ignoreCase) {
3381
- escapedValue = escapedValue.toLowerCase();
3071
+ value = value.toLowerCase();
3382
3072
  }
3383
3073
 
3384
- return $labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) + '"]').length > 0;
3074
+ return $labels.filter('[data-' + metadata.value + '="' + CSS.escape(value) + '"]').length > 0;
3385
3075
  },
3386
3076
  maxSelections: function () {
3387
3077
  return settings.maxSelections && module.get.selectionCount() >= settings.maxSelections;
3388
3078
  },
3389
3079
  allResultsFiltered: function () {
3390
- var
3391
- $normalResults = $item.not(selector.addition)
3392
- ;
3080
+ const $normalResults = $item.not(selector.addition);
3393
3081
 
3394
3082
  return $normalResults.filter(selector.unselectable).length === $normalResults.length;
3395
3083
  },
@@ -3405,20 +3093,16 @@
3405
3093
  : module.has.valueMatchingCase(value);
3406
3094
  },
3407
3095
  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
- ;
3096
+ const values = module.get.values();
3097
+ const hasValue = Array.isArray(values)
3098
+ ? values && values.includes(value)
3099
+ : values == value;
3414
3100
 
3415
3101
  return !!hasValue;
3416
3102
  },
3417
3103
  valueIgnoringCase: function (value) {
3418
- var
3419
- values = module.get.values(true),
3420
- hasValue = false
3421
- ;
3104
+ let values = module.get.values();
3105
+ let hasValue = false;
3422
3106
  if (!Array.isArray(values)) {
3423
3107
  values = [values];
3424
3108
  }
@@ -3450,9 +3134,6 @@
3450
3134
  bubbledIconClick: function (event) {
3451
3135
  return $(event.target).closest($icon).length > 0;
3452
3136
  },
3453
- edge: function () {
3454
- return !!window.chrome && !!window.StyleMedia;
3455
- },
3456
3137
  empty: function () {
3457
3138
  return $module.hasClass(className.empty);
3458
3139
  },
@@ -3468,12 +3149,12 @@
3468
3149
  : $menu.transition && $menu.transition('is animating');
3469
3150
  },
3470
3151
  leftward: function ($subMenu) {
3471
- var $selectedMenu = $subMenu || $menu;
3152
+ const $selectedMenu = $subMenu || $menu;
3472
3153
 
3473
3154
  return $selectedMenu.hasClass(className.leftward);
3474
3155
  },
3475
3156
  clearable: function () {
3476
- var hasClearableClass = $module.hasClass(className.clearable);
3157
+ const hasClearableClass = $module.hasClass(className.clearable);
3477
3158
  if (!hasClearableClass && settings.clearable) {
3478
3159
  $module.addClass(className.clearable);
3479
3160
  }
@@ -3499,9 +3180,7 @@
3499
3180
  return initialLoad;
3500
3181
  },
3501
3182
  inObject: function (needle, object) {
3502
- var
3503
- found = false
3504
- ;
3183
+ let found = false;
3505
3184
  $.each(object, function (index, property) {
3506
3185
  if (property == needle) {
3507
3186
  found = true;
@@ -3525,9 +3204,7 @@
3525
3204
  return !module.is.multiple();
3526
3205
  },
3527
3206
  selectMutation: function (mutations) {
3528
- var
3529
- selectChanged = false
3530
- ;
3207
+ let selectChanged = false;
3531
3208
  $.each(mutations, function (index, mutation) {
3532
3209
  if ($(mutation.target).is('option, optgroup') || $(mutation.addedNodes).is('select') || ($(mutation.target).is('select') && mutation.type !== 'attributes')) {
3533
3210
  selectChanged = true;
@@ -3548,10 +3225,10 @@
3548
3225
  return $module.hasClass(className.selection);
3549
3226
  },
3550
3227
  userValue: function (value) {
3551
- return $.inArray(value, module.get.userValues()) !== -1;
3228
+ return (module.get.userValues() || []).includes(value);
3552
3229
  },
3553
3230
  upward: function ($menu) {
3554
- var $element = $menu || $module;
3231
+ const $element = $menu || $module;
3555
3232
 
3556
3233
  return $element.hasClass(className.upward);
3557
3234
  },
@@ -3561,20 +3238,16 @@
3561
3238
  : $menu.hasClass(className.visible);
3562
3239
  },
3563
3240
  verticallyScrollableContext: function () {
3564
- var
3565
- overflowY = $context[0] !== window
3566
- ? $context.css('overflow-y')
3567
- : false
3568
- ;
3241
+ const overflowY = $context[0] !== window
3242
+ ? $context.css('overflow-y')
3243
+ : false;
3569
3244
 
3570
3245
  return overflowY === 'auto' || overflowY === 'scroll';
3571
3246
  },
3572
3247
  horizontallyScrollableContext: function () {
3573
- var
3574
- overflowX = $context[0] !== window
3575
- ? $context.css('overflow-X')
3576
- : false
3577
- ;
3248
+ const overflowX = $context[0] !== window
3249
+ ? $context.css('overflow-X')
3250
+ : false;
3578
3251
 
3579
3252
  return overflowX === 'auto' || overflowX === 'scroll';
3580
3253
  },
@@ -3589,16 +3262,11 @@
3589
3262
  );
3590
3263
  },
3591
3264
  openDownward: function ($subMenu) {
3592
- var
3593
- $currentMenu = $subMenu || $menu,
3594
- canOpenDownward,
3595
- onScreen,
3596
- calculations
3597
- ;
3265
+ const $currentMenu = $subMenu || $menu;
3266
+ let canOpenDownward;
3598
3267
  $currentMenu
3599
- .addClass(className.loading)
3600
- ;
3601
- calculations = {
3268
+ .addClass(className.loading);
3269
+ const calculations = {
3602
3270
  context: {
3603
3271
  offset: $context[0] === window
3604
3272
  ? { top: 0, left: 0 }
@@ -3617,7 +3285,7 @@
3617
3285
  if (module.has.subMenu($currentMenu)) {
3618
3286
  calculations.menu.height += $currentMenu.find(selector.menu).first().outerHeight();
3619
3287
  }
3620
- onScreen = {
3288
+ const onScreen = {
3621
3289
  above: calculations.context.scrollTop <= calculations.menu.offset.top - calculations.context.offset.top - calculations.menu.height,
3622
3290
  below: (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top - calculations.context.offset.top + calculations.menu.height,
3623
3291
  };
@@ -3636,16 +3304,12 @@
3636
3304
  return canOpenDownward;
3637
3305
  },
3638
3306
  openRightward: function ($subMenu) {
3639
- var
3640
- $currentMenu = $subMenu || $menu,
3641
- canOpenRightward = true,
3642
- isOffscreenRight = false,
3643
- calculations
3644
- ;
3307
+ const $currentMenu = $subMenu || $menu;
3308
+ let canOpenRightward = true;
3309
+ let isOffscreenRight = false;
3645
3310
  $currentMenu
3646
- .addClass(className.loading)
3647
- ;
3648
- calculations = {
3311
+ .addClass(className.loading);
3312
+ const calculations = {
3649
3313
  context: {
3650
3314
  offset: $context[0] === window
3651
3315
  ? { top: 0, left: 0 }
@@ -3691,23 +3355,20 @@
3691
3355
 
3692
3356
  animate: {
3693
3357
  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
- ;
3358
+ const $currentMenu = $subMenu || $menu;
3359
+ const start = $subMenu
3360
+ ? function () {}
3361
+ : function () {
3362
+ module.hideSubMenus();
3363
+ module.hideOthers();
3364
+ module.set.active();
3365
+ };
3705
3366
  callback = isFunction(callback)
3706
3367
  ? callback
3707
3368
  : function () {};
3708
3369
  module.verbose('Doing menu show animation', $currentMenu);
3709
3370
  module.set.direction($subMenu);
3710
- transition = settings.transition.showMethod || module.get.transition($subMenu);
3371
+ const transition = settings.transition.showMethod || module.get.transition($subMenu);
3711
3372
  if (module.is.selection()) {
3712
3373
  module.set.scrollPosition(module.get.selectedItem(), true);
3713
3374
  }
@@ -3732,22 +3393,19 @@
3732
3393
  onComplete: function () {
3733
3394
  callback.call(element);
3734
3395
  },
3735
- })
3736
- ;
3396
+ });
3737
3397
  }
3738
3398
  }
3739
3399
  },
3740
3400
  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
- ;
3401
+ const $currentMenu = $subMenu || $menu;
3402
+ const start = $subMenu
3403
+ ? function () {}
3404
+ : function () {
3405
+ module.unbind.intent();
3406
+ module.remove.active();
3407
+ };
3408
+ const transition = settings.transition.hideMethod || module.get.transition($subMenu);
3751
3409
  callback = isFunction(callback)
3752
3410
  ? callback
3753
3411
  : function () {};
@@ -3774,8 +3432,7 @@
3774
3432
  onComplete: function () {
3775
3433
  callback.call(element);
3776
3434
  },
3777
- })
3778
- ;
3435
+ });
3779
3436
  } else {
3780
3437
  module.error(error.transition);
3781
3438
  }
@@ -3815,55 +3472,26 @@
3815
3472
  },
3816
3473
 
3817
3474
  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
3475
  string: function (text) {
3841
3476
  text = String(text);
3842
3477
 
3843
3478
  return text.replace(regExp.escape, '\\$&');
3844
3479
  },
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);
3480
+
3481
+ // https://github.com/fomantic/Fomantic-UI/issues/2782
3482
+ // https://jsfiddle.net/3efL7jnt/
3483
+ assumeUnescapedAmpLtGt: function (string) {
3484
+ if (settings.preserveHTML) {
3485
+ return string;
3864
3486
  }
3865
3487
 
3866
- return string;
3488
+ const unescapeMap = {
3489
+ '&amp;': '&',
3490
+ '&lt;': '<',
3491
+ '&gt;': '>',
3492
+ };
3493
+
3494
+ return string.replace(/&(?:amp|lt|gt);/g, (v) => unescapeMap[v]);
3867
3495
  },
3868
3496
  },
3869
3497
 
@@ -3890,39 +3518,37 @@
3890
3518
  return module[name];
3891
3519
  }
3892
3520
  },
3893
- debug: function () {
3521
+ debug: function (...args) {
3894
3522
  if (!settings.silent && settings.debug) {
3895
3523
  if (settings.performance) {
3896
- module.performance.log(arguments);
3524
+ module.performance.log(args);
3897
3525
  } else {
3898
3526
  module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
3899
- module.debug.apply(console, arguments);
3527
+ module.debug.apply(console, args);
3900
3528
  }
3901
3529
  }
3902
3530
  },
3903
- verbose: function () {
3531
+ verbose: function (...args) {
3904
3532
  if (!settings.silent && settings.verbose && settings.debug) {
3905
3533
  if (settings.performance) {
3906
- module.performance.log(arguments);
3534
+ module.performance.log(args);
3907
3535
  } else {
3908
3536
  module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
3909
- module.verbose.apply(console, arguments);
3537
+ module.verbose.apply(console, args);
3910
3538
  }
3911
3539
  }
3912
3540
  },
3913
- error: function () {
3541
+ error: function (...args) {
3914
3542
  if (!settings.silent) {
3915
3543
  module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
3916
- module.error.apply(console, arguments);
3544
+ module.error.apply(console, args);
3917
3545
  }
3918
3546
  },
3919
3547
  performance: {
3920
3548
  log: function (message) {
3921
- var
3922
- currentTime,
3923
- executionTime,
3924
- previousTime
3925
- ;
3549
+ let currentTime;
3550
+ let executionTime;
3551
+ let previousTime;
3926
3552
  if (settings.performance) {
3927
3553
  currentTime = Date.now();
3928
3554
  previousTime = time || currentTime;
@@ -3930,7 +3556,7 @@
3930
3556
  time = currentTime;
3931
3557
  performance.push({
3932
3558
  Name: message[0],
3933
- Arguments: [].slice.call(message, 1) || '',
3559
+ Arguments: message.slice(1),
3934
3560
  Element: element,
3935
3561
  'Execution Time': executionTime,
3936
3562
  });
@@ -3941,10 +3567,8 @@
3941
3567
  }, 500);
3942
3568
  },
3943
3569
  display: function () {
3944
- var
3945
- title = settings.name + ':',
3946
- totalTime = 0
3947
- ;
3570
+ let title = settings.name + ':';
3571
+ let totalTime = 0;
3948
3572
  time = false;
3949
3573
  clearTimeout(module.performance.timer);
3950
3574
  $.each(performance, function (index, data) {
@@ -3953,35 +3577,24 @@
3953
3577
  title += ' ' + totalTime + 'ms';
3954
3578
  if (performance.length > 0) {
3955
3579
  console.groupCollapsed(title);
3956
- if (console.table) {
3957
- console.table(performance);
3958
- } else {
3959
- $.each(performance, function (index, data) {
3960
- console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
3961
- });
3962
- }
3580
+ console.table(performance);
3963
3581
  console.groupEnd();
3964
3582
  }
3965
3583
  performance = [];
3966
3584
  },
3967
3585
  },
3968
- invoke: function (query, passedArguments, context) {
3969
- var
3970
- object = instance,
3971
- maxDepth,
3972
- found,
3973
- response
3974
- ;
3975
- passedArguments = passedArguments || queryArguments;
3976
- context = context || element;
3586
+ invoke: function (query, passedArguments = queryArguments, context = element) {
3587
+ let object = instance;
3588
+ let maxDepth;
3589
+ let found;
3590
+ let response;
3977
3591
  if (typeof query === 'string' && object !== undefined) {
3978
3592
  query = query.split(/[ .]/);
3979
3593
  maxDepth = query.length - 1;
3980
3594
  $.each(query, function (depth, value) {
3981
- var camelCaseValue = depth !== maxDepth
3595
+ const camelCaseValue = depth !== maxDepth
3982
3596
  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3983
- : query
3984
- ;
3597
+ : query;
3985
3598
  if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
3986
3599
  object = object[camelCaseValue];
3987
3600
  } else if (object[camelCaseValue] !== undefined) {
@@ -4022,7 +3635,7 @@
4022
3635
  if (instance === undefined) {
4023
3636
  module.initialize();
4024
3637
  }
4025
- module.invoke(query);
3638
+ module.invoke(parameters);
4026
3639
  } else {
4027
3640
  if (instance !== undefined) {
4028
3641
  instance.invoke('destroy');
@@ -4066,33 +3679,33 @@
4066
3679
  match: 'both', // what to match against with search selection (both, text, or label)
4067
3680
  fullTextSearch: 'exact', // search anywhere in value (set to 'exact' to require exact matches)
4068
3681
  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...)
3682
+ 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
3683
  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
3684
 
4072
- placeholder: 'auto', // whether to convert blank <select> values to placeholder text
4073
- preserveHTML: true, // preserve html when selecting value
3685
+ placeholder: 'auto', // whether to convert blank <select> values to the placeholder text
3686
+ preserveHTML: true, // preserve HTML when selecting value
4074
3687
  sortSelect: false, // sort selection on init
4075
3688
 
4076
3689
  forceSelection: false, // force a choice on blur with search selection
4077
3690
 
4078
3691
  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
3692
+ keepSearchTerm: false, // whether the search value should be kept, and the menu stays filtered on item selection
4080
3693
  ignoreCase: false, // whether to consider case sensitivity when creating labels
4081
3694
  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
3695
+ hideAdditions: true, // whether to hide a special message prompting a user, they can enter a value
4083
3696
 
4084
- maxSelections: false, // When set to a number limits the number of selections to this count
3697
+ maxSelections: false, // When set to a number, limits the number of selections to this count
4085
3698
  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
3699
+ delimiter: ',', // when multiselect uses normal <input>, the values will be delimited with this character
4087
3700
 
4088
- showOnFocus: false, // show menu on focus
3701
+ showOnFocus: false, // show the menu on focus
4089
3702
  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
3703
+ allowTab: true, // add tabindex to the element
3704
+ allowCategorySelection: false, // allow elements with submenus to be selected
4092
3705
 
4093
3706
  fireOnInit: false, // Whether callbacks should fire when initializing dropdown values
4094
3707
 
4095
- transition: 'auto', // auto transition will slide down or up based on direction
3708
+ transition: 'auto', // auto transition will slide down or up based on the direction
4096
3709
  duration: 200, // duration of transition
4097
3710
  displayType: false, // displayType of transition
4098
3711
 
@@ -4154,14 +3767,11 @@
4154
3767
  missingMultiple: '<select> requires multiple property to be set to correctly preserve multiple values',
4155
3768
  method: 'The method you called is not defined.',
4156
3769
  noAPI: 'The API module is required to load resources remotely',
4157
- noStorage: 'Saving remote data requires session storage',
4158
3770
  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
3771
  },
4161
3772
 
4162
3773
  regExp: {
4163
3774
  escape: /[\s#$()*+,.:=?@[\\\]^{|}-]/g,
4164
- quote: /"/g,
4165
3775
  },
4166
3776
 
4167
3777
  metadata: {
@@ -4172,23 +3782,23 @@
4172
3782
  value: 'value',
4173
3783
  },
4174
3784
 
4175
- // property names for remote query
3785
+ // property names for the remote query
4176
3786
  fields: {
4177
3787
  remoteValues: 'results', // grouping for api results
4178
3788
  values: 'values', // grouping for all dropdown values
4179
3789
  disabled: 'disabled', // whether value should be disabled
4180
- name: 'name', // displayed dropdown text
3790
+ name: 'name', // the displayed dropdown text
4181
3791
  description: 'description', // displayed dropdown description
4182
3792
  descriptionVertical: 'descriptionVertical', // whether description should be vertical
4183
3793
  value: 'value', // actual dropdown value
4184
- text: 'text', // displayed text when selected
3794
+ text: 'text', // the displayed text when selected
4185
3795
  data: 'data', // custom data attributes
4186
3796
  type: 'type', // type of dropdown element
4187
3797
  image: 'image', // optional image path
4188
3798
  imageClass: 'imageClass', // optional individual class for image
4189
3799
  alt: 'alt', // optional alt text for image
4190
3800
  icon: 'icon', // optional icon name
4191
- iconClass: 'iconClass', // optional individual class for icon (for example to use flag instead)
3801
+ iconClass: 'iconClass', // optional individual class for icon (for example, to use a flag instead)
4192
3802
  class: 'class', // optional individual class for item/header
4193
3803
  divider: 'divider', // optional divider append for group headers
4194
3804
  actionable: 'actionable', // optional actionable item
@@ -4270,137 +3880,116 @@
4270
3880
 
4271
3881
  /* Templates */
4272
3882
  $.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) {
3883
+ escape: function (string, settings) {
3884
+ if (settings !== undefined && settings.preserveHTML) {
4278
3885
  return string;
4279
3886
  }
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
3887
 
4299
- return string;
3888
+ const escapeMap = {
3889
+ '"': '&quot;',
3890
+ '&': '&amp;',
3891
+ "'": '&apos;',
3892
+ '<': '&lt;',
3893
+ '>': '&gt;',
3894
+ };
3895
+
3896
+ return String(string).replace(/["&'<>]/g, (chr) => escapeMap[chr]);
4300
3897
  },
4301
3898
  // 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
- ;
3899
+ dropdown: function (select, settings) {
3900
+ const placeholder = select.placeholder || false;
3901
+ let html = '';
3902
+ const className = settings.className;
3903
+ const escape = settings.templates.escape;
4309
3904
  html += '<i class="dropdown icon"></i>';
4310
3905
  html += placeholder
4311
- ? '<div class="default text">' + escape(placeholder, preserveHTML) + '</div>'
3906
+ ? '<div class="default text">' + escape(placeholder, settings) + '</div>'
4312
3907
  : '<div class="text"></div>';
4313
- html += '<div class="' + deQuote(className.menu) + '">';
4314
- html += $.fn.dropdown.settings.templates.menu(select, fields, preserveHTML, className);
3908
+ html += '<div class="' + escape(className.menu) + '">';
3909
+ html += settings.templates.menu(select, settings);
4315
3910
  html += '</div>';
4316
3911
 
4317
3912
  return html;
4318
3913
  },
4319
3914
 
4320
3915
  // 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
- ;
3916
+ menu: function (response, settings) {
3917
+ const fields = settings.fields;
3918
+ const values = response[fields.values] || [];
3919
+ let html = '';
3920
+ const className = settings.className;
3921
+ const escape = settings.templates.escape;
4328
3922
  $.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
- ;
3923
+ const itemType = option[fields.type] || 'item';
3924
+ const isMenu = itemType.includes('menu');
3925
+ let maybeData = '';
3926
+ const dataObject = option[fields.data];
4335
3927
  if (dataObject) {
4336
- var dataKey,
4337
- dataKeyEscaped
4338
- ;
3928
+ let dataKey;
3929
+ let dataKeyEscaped;
4339
3930
  for (dataKey in dataObject) {
4340
- dataKeyEscaped = String(dataKey).replace(/\W/g, '');
4341
- if (Object.prototype.hasOwnProperty.call(dataObject, dataKey) && ['text', 'value'].indexOf(dataKeyEscaped.toLowerCase()) === -1) {
4342
- maybeData += ' data-' + dataKeyEscaped + '="' + deQuote(String(dataObject[dataKey])) + '"';
3931
+ if (Object.prototype.hasOwnProperty.call(dataObject, dataKey)) {
3932
+ dataKeyEscaped = String(dataKey).replace(/\W/g, '');
3933
+ if (!['text', 'value'].includes(dataKeyEscaped.toLowerCase())) {
3934
+ maybeData += ' data-' + dataKeyEscaped + '="' + escape(String(dataObject[dataKey])) + '"';
3935
+ }
4343
3936
  }
4344
3937
  }
4345
3938
  }
4346
3939
  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 + '>';
3940
+ const maybeText = option[fields.text]
3941
+ ? ' data-text="' + escape(option[fields.text]) + '"'
3942
+ : '';
3943
+ const maybeActionable = option[fields.actionable]
3944
+ ? className.actionable + ' '
3945
+ : '';
3946
+ const maybeDisabled = option[fields.disabled]
3947
+ ? className.disabled + ' '
3948
+ : '';
3949
+ const maybeDescriptionVertical = option[fields.descriptionVertical]
3950
+ ? className.descriptionVertical + ' '
3951
+ : '';
3952
+ const hasDescription = escape(option[fields.description] || '', settings) !== '';
3953
+ html += '<div class="' + escape(maybeActionable + maybeDisabled + maybeDescriptionVertical + (option[fields.class] || className.item)) + '" data-value="' + escape(option[fields.value]) + '"' + maybeText + maybeData + '>';
4363
3954
  if (isMenu) {
4364
- html += '<i class="' + (itemType.indexOf('left') !== -1 ? 'left' : '') + ' dropdown icon"></i>';
3955
+ html += '<i class="' + (itemType.includes('left') ? 'left' : '') + ' dropdown icon"></i>';
4365
3956
  }
4366
3957
  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]) : '') + '">';
3958
+ html += '<img class="' + escape(option[fields.imageClass] || className.image) + '" src="' + escape(option[fields.image]) + '"' + (option[fields.alt] ? ' alt="' + escape(option[fields.alt]) + '"' : '') + '>';
4368
3959
  }
4369
3960
  if (option[fields.icon]) {
4370
- html += '<i class="' + deQuote(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
3961
+ html += '<i class="' + escape(option[fields.icon] + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4371
3962
  }
4372
3963
  if (hasDescription) {
4373
- html += '<span class="' + deQuote(className.description) + '">' + escape(option[fields.description] || '', preserveHTML) + '</span>';
4374
- html += !isMenu ? '<span class="' + deQuote(className.text) + '">' : '';
3964
+ html += '<span class="' + escape(className.description) + '">' + escape(option[fields.description] || '', settings) + '</span>';
3965
+ html += !isMenu ? '<span class="' + escape(className.text) + '">' : '';
4375
3966
  }
4376
3967
  if (isMenu) {
4377
- html += '<span class="' + deQuote(className.text) + '">';
3968
+ html += '<span class="' + escape(className.text) + '">';
4378
3969
  }
4379
- html += escape(option[fields.name] || '', preserveHTML);
3970
+ html += escape(option[fields.name] || '', settings);
4380
3971
  if (isMenu) {
4381
3972
  html += '</span>';
4382
- html += '<div class="' + deQuote(itemType) + '">';
4383
- html += $.fn.dropdown.settings.templates.menu(option, fields, preserveHTML, className);
3973
+ html += '<div class="' + escape(itemType) + '">';
3974
+ html += settings.templates.menu(option, settings);
4384
3975
  html += '</div>';
4385
3976
  } else if (hasDescription) {
4386
3977
  html += '</span>';
4387
3978
  }
4388
3979
  html += '</div>';
4389
3980
  } else if (itemType === 'header') {
4390
- var
4391
- groupName = escape(option[fields.name] || '', preserveHTML),
4392
- groupIcon = deQuote(option[fields.icon] || className.groupIcon)
4393
- ;
3981
+ const groupName = option[fields.name] || '';
3982
+ const groupIcon = option[fields.icon] || className.groupIcon;
4394
3983
  if (groupName !== '' || groupIcon !== '') {
4395
- html += '<div class="' + deQuote(option[fields.class] || className.header) + '">';
3984
+ html += '<div class="' + escape(option[fields.class] || className.header) + '">';
4396
3985
  if (groupIcon !== '') {
4397
- html += '<i class="' + deQuote(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
3986
+ html += '<i class="' + escape(groupIcon + ' ' + (option[fields.iconClass] || className.icon)) + '"></i>';
4398
3987
  }
4399
- html += groupName;
3988
+ html += escape(groupName, settings);
4400
3989
  html += '</div>';
4401
3990
  }
4402
3991
  if (option[fields.divider]) {
4403
- html += '<div class="' + deQuote(className.divider) + '"></div>';
3992
+ html += '<div class="' + escape(className.divider) + '"></div>';
4404
3993
  }
4405
3994
  }
4406
3995
  });
@@ -4409,13 +3998,11 @@
4409
3998
  },
4410
3999
 
4411
4000
  // 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
- ;
4001
+ label: function (value, text, settings) {
4002
+ const className = settings.className;
4003
+ const escape = settings.templates.escape;
4417
4004
 
4418
- return escape(text, preserveHTML) + '<i class="' + deQuote(className.delete) + ' icon"></i>';
4005
+ return escape(text, settings) + '<i class="' + escape(className.delete) + ' icon"></i>';
4419
4006
  },
4420
4007
 
4421
4008
  // generates messages like "No results"
@@ -4423,7 +4010,7 @@
4423
4010
  return message;
4424
4011
  },
4425
4012
 
4426
- // generates user addition to selection menu
4013
+ // generates user addition to the selection menu
4427
4014
  addition: function (choice) {
4428
4015
  return choice;
4429
4016
  },