tom-select-rails 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tom-select-rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js +168 -84
  4. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js.map +1 -1
  5. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js +132 -59
  6. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js.map +1 -1
  7. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js +140 -65
  8. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js.map +1 -1
  9. data/vendor/assets/javascripts/tom-select-rails/cjs/utils.js +1 -1
  10. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js +3 -3
  11. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js.map +1 -1
  12. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/change_listener/plugin.js +1 -1
  13. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js +9 -7
  14. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js.map +1 -1
  15. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js +3 -3
  16. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js.map +1 -1
  17. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/drag_drop/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js +3 -3
  19. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js.map +1 -1
  20. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js +6 -4
  21. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js.map +1 -1
  22. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js +3 -7
  23. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js.map +1 -1
  24. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_active_items/plugin.js +1 -1
  25. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_backspace_delete/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js +4 -3
  27. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js.map +1 -1
  28. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js +8 -8
  29. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js.map +1 -1
  30. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/restore_on_backspace/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js +22 -12
  32. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js.map +1 -1
  33. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js +168 -84
  34. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js.map +1 -1
  35. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js +132 -59
  36. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js.map +1 -1
  37. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js +140 -65
  38. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js.map +1 -1
  39. data/vendor/assets/javascripts/tom-select-rails/esm/utils.js +1 -1
  40. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js +3 -3
  41. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js.map +1 -1
  42. data/vendor/assets/javascripts/tom-select-rails/js/plugins/change_listener.js +1 -1
  43. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js +9 -7
  44. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js.map +1 -1
  45. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js +3 -3
  46. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js.map +1 -1
  47. data/vendor/assets/javascripts/tom-select-rails/js/plugins/drag_drop.js +1 -1
  48. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js +3 -3
  49. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js.map +1 -1
  50. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js +6 -4
  51. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js.map +1 -1
  52. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js +3 -7
  53. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js.map +1 -1
  54. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_active_items.js +1 -1
  55. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_backspace_delete.js +1 -1
  56. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js +4 -3
  57. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js.map +1 -1
  58. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js +8 -8
  59. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js.map +1 -1
  60. data/vendor/assets/javascripts/tom-select-rails/js/plugins/restore_on_backspace.js +1 -1
  61. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js +22 -12
  62. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js.map +1 -1
  63. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js +132 -59
  64. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js.map +1 -1
  65. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js +142 -142
  66. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js.map +1 -1
  67. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js +168 -84
  68. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js.map +1 -1
  69. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js +157 -156
  70. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js.map +1 -1
  71. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js +140 -65
  72. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js.map +1 -1
  73. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js +142 -143
  74. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js.map +1 -1
  75. data/vendor/assets/javascripts/tom-select-rails/types/tom-select.d.ts +20 -3
  76. data/vendor/assets/javascripts/tom-select-rails/types/types/core.d.ts +2 -1
  77. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css +3 -7
  78. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css.map +1 -1
  79. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css +1 -1
  80. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css.map +1 -1
  81. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css +3 -7
  82. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css.map +1 -1
  83. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css +1 -1
  84. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css.map +1 -1
  85. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css +7 -11
  86. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css.map +1 -1
  87. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css +3 -7
  88. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css.map +1 -1
  89. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css +1 -1
  90. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css.map +1 -1
  91. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css +1 -1
  92. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css.map +1 -1
  93. data/vendor/assets/stylesheets/tom-select-rails/scss/_dropdown.scss +0 -2
  94. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.scss +4 -4
  95. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 231e3258e61b1031bb0bdc51591296466f00d73c50045af6797026dfc083b41c
4
- data.tar.gz: 81d4cd624faab6229846e51fef1438729a1c9fad6e344f7cabbac7219177c7e4
3
+ metadata.gz: 1b3cc20dc49ea2de80dfdfe939c1b4b32aabf86d74fbd188907b0de731129a87
4
+ data.tar.gz: 7c7e09dfa447bec81857c137f3ba82084a94fc20c44e62bdae1cc5ad8ac44068
5
5
  SHA512:
6
- metadata.gz: 07016fd5c972592fe25603b904e139daa660def15f3ce15599edc39f48dd63570b611f8a15e6862531850169420792b5fcca9fa2b119e5428c9f47d9552e3d99
7
- data.tar.gz: eb42bd93be577d053bbfb018af2ed5d8eb7a09af39cc90ca03fbc8a3dc606fee251aa6ba14df0efa59a064764ec954924682da8984ac59eae0039e8a2efc467f
6
+ metadata.gz: c62aeb791ae593fa5428acd0a0b76587abd77c505b2c34110acbb3be9228b15ce61395e2e214e5da5a136f6d0d401a74c1b479787fc1c91a5b347ff30cc20741
7
+ data.tar.gz: 789659f7b13407003b2b99bf993b37017030278c87da2389455547d14d56c55b126a27f2ecc1177980e7d3a6f12ba77da2f9044ad0d9f707121edfa97fcf9f29
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TomSelect
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tom Select v2.0.3
2
+ * Tom Select v2.1.0
3
3
  * Licensed under the Apache License, Version 2.0 (the "License");
4
4
  */
5
5
 
@@ -189,24 +189,20 @@ function MicroPlugin(Interface) {
189
189
  };
190
190
  }
191
191
 
192
+ // @ts-ignore TS2691 "An import path cannot end with a '.ts' extension"
192
193
  // https://github.com/andrewrk/node-diacritics/blob/master/index.js
193
194
  var latin_pat;
194
195
  const accent_pat = '[\u0300-\u036F\u{b7}\u{2be}]'; // \u{2bc}
195
196
 
196
- const accent_reg = new RegExp(accent_pat, 'g');
197
+ const accent_reg = new RegExp(accent_pat, 'gu');
197
198
  var diacritic_patterns;
198
199
  const latin_convert = {
199
200
  'æ': 'ae',
200
201
  'ⱥ': 'a',
201
202
  'ø': 'o'
202
203
  };
203
- const convert_pat = new RegExp(Object.keys(latin_convert).join('|'), 'g');
204
- /**
205
- * code points generated from toCodePoints();
206
- * removed 65339 to 65345
207
- */
208
-
209
- const code_points = [[67, 67], [160, 160], [192, 438], [452, 652], [961, 961], [1019, 1019], [1083, 1083], [1281, 1289], [1984, 1984], [5095, 5095], [7429, 7441], [7545, 7549], [7680, 7935], [8580, 8580], [9398, 9449], [11360, 11391], [42792, 42793], [42802, 42851], [42873, 42897], [42912, 42922], [64256, 64260], [65313, 65338], [65345, 65370]];
204
+ const convert_pat = new RegExp(Object.keys(latin_convert).join('|'), 'gu');
205
+ const code_points = [[0, 65535]];
210
206
  /**
211
207
  * Remove accents
212
208
  * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703
@@ -225,7 +221,6 @@ const asciifold = str => {
225
221
  *
226
222
  */
227
223
 
228
-
229
224
  const arrayToPattern = (chars, glue = '|') => {
230
225
  if (chars.length == 1) {
231
226
  return chars[0];
@@ -242,6 +237,10 @@ const arrayToPattern = (chars, glue = '|') => {
242
237
 
243
238
  return '(?:' + chars.join(glue) + ')';
244
239
  };
240
+ const escapeToPattern = chars => {
241
+ const escaped = chars.map(diacritic => escape_regex(diacritic));
242
+ return arrayToPattern(escaped);
243
+ };
245
244
  /**
246
245
  * Get all possible combinations of substrings that add up to the given string
247
246
  * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string
@@ -266,7 +265,7 @@ const allSubstrings = input => {
266
265
  *
267
266
  */
268
267
 
269
- const generateDiacritics = () => {
268
+ const generateDiacritics = code_points => {
270
269
  var diacritics = {};
271
270
  code_points.forEach(code_range => {
272
271
  for (let i = code_range[0]; i <= code_range[1]; i++) {
@@ -275,13 +274,22 @@ const generateDiacritics = () => {
275
274
 
276
275
  if (latin == diacritic.toLowerCase()) {
277
276
  continue;
277
+ } // skip when latin is a string longer than 3 characters long
278
+ // bc the resulting regex patterns will be long
279
+ // eg:
280
+ // latin صلى الله عليه وسلم length 18 code point 65018
281
+ // latin جل جلاله length 8 code point 65019
282
+
283
+
284
+ if (latin.length > 3) {
285
+ continue;
278
286
  }
279
287
 
280
288
  if (!(latin in diacritics)) {
281
289
  diacritics[latin] = [latin];
282
290
  }
283
291
 
284
- var patt = new RegExp(arrayToPattern(diacritics[latin]), 'iu');
292
+ var patt = new RegExp(escapeToPattern(diacritics[latin]), 'iu');
285
293
 
286
294
  if (diacritic.match(patt)) {
287
295
  continue;
@@ -289,13 +297,23 @@ const generateDiacritics = () => {
289
297
 
290
298
  diacritics[latin].push(diacritic);
291
299
  }
292
- });
293
- var latin_chars = Object.keys(diacritics); // latin character pattern
300
+ }); // filter out if there's only one character in the list
301
+
302
+ let latin_chars = Object.keys(diacritics);
303
+
304
+ for (let i = 0; i < latin_chars.length; i++) {
305
+ const latin = latin_chars[i];
306
+
307
+ if (diacritics[latin].length < 2) {
308
+ delete diacritics[latin];
309
+ }
310
+ } // latin character pattern
294
311
  // match longer substrings first
295
312
 
296
- latin_chars = latin_chars.sort((a, b) => b.length - a.length);
297
- latin_pat = new RegExp('(' + arrayToPattern(latin_chars) + accent_pat + '*)', 'g'); // build diacritic patterns
298
- // ae needs:
313
+
314
+ latin_chars = Object.keys(diacritics).sort((a, b) => b.length - a.length);
315
+ latin_pat = new RegExp('(' + escapeToPattern(latin_chars) + accent_pat + '*)', 'gu'); // build diacritic patterns
316
+ // ae needs:
299
317
  // (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))
300
318
 
301
319
  var diacritic_patterns = {};
@@ -304,7 +322,7 @@ const generateDiacritics = () => {
304
322
  var pattern = substrings.map(sub_pat => {
305
323
  sub_pat = sub_pat.map(l => {
306
324
  if (diacritics.hasOwnProperty(l)) {
307
- return arrayToPattern(diacritics[l]);
325
+ return escapeToPattern(diacritics[l]);
308
326
  }
309
327
 
310
328
  return l;
@@ -323,27 +341,20 @@ const generateDiacritics = () => {
323
341
 
324
342
  const diacriticRegexPoints = regex => {
325
343
  if (diacritic_patterns === undefined) {
326
- diacritic_patterns = generateDiacritics();
344
+ diacritic_patterns = generateDiacritics(code_points);
327
345
  }
328
346
 
329
347
  const decomposed = regex.normalize('NFKD').toLowerCase();
330
348
  return decomposed.split(latin_pat).map(part => {
331
- if (part == '') {
332
- return '';
333
- } // "ffl" or "ffl"
334
-
335
-
349
+ // "ffl" or "ffl"
336
350
  const no_accent = asciifold(part);
337
351
 
352
+ if (no_accent == '') {
353
+ return '';
354
+ }
355
+
338
356
  if (diacritic_patterns.hasOwnProperty(no_accent)) {
339
357
  return diacritic_patterns[no_accent];
340
- } // 'أهلا' (\u{623}\u{647}\u{644}\u{627}) or 'أهلا' (\u{627}\u{654}\u{647}\u{644}\u{627})
341
-
342
-
343
- const composed_part = part.normalize('NFC');
344
-
345
- if (composed_part != part) {
346
- return arrayToPattern([part, composed_part]);
347
358
  }
348
359
 
349
360
  return part;
@@ -509,10 +520,10 @@ class Sifter {
509
520
  }
510
521
 
511
522
  if (word.length > 0) {
512
- regex = escape_regex(word);
513
-
514
523
  if (this.settings.diacritics) {
515
- regex = diacriticRegexPoints(regex);
524
+ regex = diacriticRegexPoints(word);
525
+ } else {
526
+ regex = escape_regex(word);
516
527
  }
517
528
 
518
529
  if (respect_word_boundaries) regex = "\\b" + regex;
@@ -1528,6 +1539,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1528
1539
  this.isInputHidden = false;
1529
1540
  this.isSetup = false;
1530
1541
  this.ignoreFocus = false;
1542
+ this.ignoreHover = false;
1531
1543
  this.hasOptions = false;
1532
1544
  this.currentResults = void 0;
1533
1545
  this.lastValue = '';
@@ -1726,7 +1738,13 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1726
1738
  settings.load = loadDebounce(settings.load, settings.loadThrottle);
1727
1739
  }
1728
1740
 
1729
- self.control_input.type = input.type; // clicking on an option should select it
1741
+ self.control_input.type = input.type;
1742
+ addEvent(dropdown, 'mouseenter', e => {
1743
+ var target_match = parentMatch(e.target, '[data-selectable]', dropdown);
1744
+ if (target_match) self.onOptionHover(e, target_match);
1745
+ }, {
1746
+ capture: true
1747
+ }); // clicking on an option should select it
1730
1748
 
1731
1749
  addEvent(dropdown, 'click', evt => {
1732
1750
  const option = parentMatch(evt.target, '[data-selectable]');
@@ -1760,7 +1778,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1760
1778
  addEvent(focus_node, 'resize', () => self.positionDropdown(), passive_event);
1761
1779
  addEvent(focus_node, 'blur', e => self.onBlur(e));
1762
1780
  addEvent(focus_node, 'focus', e => self.onFocus(e));
1763
- addEvent(focus_node, 'paste', e => self.onPaste(e));
1781
+ addEvent(control_input, 'paste', e => self.onPaste(e));
1764
1782
 
1765
1783
  const doc_mousedown = evt => {
1766
1784
  // blur if target is outside of this instance
@@ -1787,18 +1805,24 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1787
1805
  }
1788
1806
  };
1789
1807
 
1790
- var win_scroll = () => {
1808
+ const win_scroll = () => {
1791
1809
  if (self.isOpen) {
1792
1810
  self.positionDropdown();
1793
1811
  }
1794
1812
  };
1795
1813
 
1814
+ const win_hover = () => {
1815
+ self.ignoreHover = false;
1816
+ };
1817
+
1796
1818
  addEvent(document, 'mousedown', doc_mousedown);
1797
1819
  addEvent(window, 'scroll', win_scroll, passive_event);
1798
1820
  addEvent(window, 'resize', win_scroll, passive_event);
1821
+ addEvent(window, 'mousemove', win_hover, passive_event);
1799
1822
 
1800
1823
  this._destroy = () => {
1801
1824
  document.removeEventListener('mousedown', doc_mousedown);
1825
+ window.removeEventListener('mousemove', win_hover);
1802
1826
  window.removeEventListener('scroll', win_scroll);
1803
1827
  window.removeEventListener('resize', win_scroll);
1804
1828
  if (label) label.removeEventListener('click', label_click);
@@ -2004,21 +2028,29 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2004
2028
  // input and create Items for each separate value
2005
2029
 
2006
2030
 
2007
- if (self.settings.splitOn) {
2008
- // Wait for pasted text to be recognized in value
2009
- setTimeout(() => {
2010
- var pastedText = self.inputValue();
2031
+ if (!self.settings.splitOn) {
2032
+ return;
2033
+ } // Wait for pasted text to be recognized in value
2011
2034
 
2012
- if (!pastedText.match(self.settings.splitOn)) {
2013
- return;
2014
- }
2015
2035
 
2016
- var splitInput = pastedText.trim().split(self.settings.splitOn);
2017
- iterate(splitInput, piece => {
2036
+ setTimeout(() => {
2037
+ var pastedText = self.inputValue();
2038
+
2039
+ if (!pastedText.match(self.settings.splitOn)) {
2040
+ return;
2041
+ }
2042
+
2043
+ var splitInput = pastedText.trim().split(self.settings.splitOn);
2044
+ iterate(splitInput, piece => {
2045
+ piece = hash_key(piece);
2046
+
2047
+ if (this.options[piece]) {
2048
+ self.addItem(piece);
2049
+ } else {
2018
2050
  self.createItem(piece);
2019
- });
2020
- }, 0);
2021
- }
2051
+ }
2052
+ });
2053
+ }, 0);
2022
2054
  }
2023
2055
  /**
2024
2056
  * Triggered on <input> keypress.
@@ -2050,6 +2082,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2050
2082
 
2051
2083
  onKeyDown(e) {
2052
2084
  var self = this;
2085
+ self.ignoreHover = true;
2053
2086
 
2054
2087
  if (self.isLocked) {
2055
2088
  if (e.keyCode !== KEY_TAB) {
@@ -2110,6 +2143,8 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2110
2143
  self.onOptionSelect(e, self.activeOption);
2111
2144
  preventDefault(e); // if the option_create=null, the dropdown might be closed
2112
2145
  } else if (self.settings.create && self.createItem()) {
2146
+ preventDefault(e); // don't submit form when searching for a value
2147
+ } else if (document.activeElement == self.control_input && self.isOpen) {
2113
2148
  preventDefault(e);
2114
2149
  }
2115
2150
 
@@ -2180,6 +2215,17 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2180
2215
  self.trigger('type', value);
2181
2216
  }
2182
2217
  }
2218
+ /**
2219
+ * Triggered when the user rolls over
2220
+ * an option in the autocomplete dropdown menu.
2221
+ *
2222
+ */
2223
+
2224
+
2225
+ onOptionHover(evt, option) {
2226
+ if (this.ignoreHover) return;
2227
+ this.setActiveOption(option, false);
2228
+ }
2183
2229
  /**
2184
2230
  * Triggered on <input> focus.
2185
2231
  *
@@ -2534,7 +2580,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2534
2580
  */
2535
2581
 
2536
2582
 
2537
- setActiveOption(option) {
2583
+ setActiveOption(option, scroll = true) {
2538
2584
  if (option === this.activeOption) {
2539
2585
  return;
2540
2586
  }
@@ -2549,7 +2595,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2549
2595
  'aria-selected': 'true'
2550
2596
  });
2551
2597
  addClasses(option, 'active');
2552
- this.scrollToOption(option);
2598
+ if (scroll) this.scrollToOption(option);
2553
2599
  }
2554
2600
  /**
2555
2601
  * Sets the dropdown_content scrollTop to display the option
@@ -3182,13 +3228,14 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3182
3228
  */
3183
3229
 
3184
3230
 
3185
- clearOptions() {
3231
+ clearOptions(filter) {
3232
+ const boundFilter = (filter || this.clearFilter).bind(this);
3186
3233
  this.loadedSearches = {};
3187
3234
  this.userOptions = {};
3188
3235
  this.clearCache();
3189
- var selected = {};
3236
+ const selected = {};
3190
3237
  iterate(this.options, (option, key) => {
3191
- if (this.items.indexOf(key) >= 0) {
3238
+ if (boundFilter(option, key)) {
3192
3239
  selected[key] = this.options[key];
3193
3240
  }
3194
3241
  });
@@ -3196,6 +3243,20 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3196
3243
  this.lastQuery = null;
3197
3244
  this.trigger('option_clear');
3198
3245
  }
3246
+ /**
3247
+ * Used by clearOptions() to decide whether or not an option should be removed
3248
+ * Return true to keep an option, false to remove
3249
+ *
3250
+ */
3251
+
3252
+
3253
+ clearFilter(option, value) {
3254
+ if (this.items.indexOf(value) >= 0) {
3255
+ return true;
3256
+ }
3257
+
3258
+ return false;
3259
+ }
3199
3260
  /**
3200
3261
  * Returns the dom element of the option
3201
3262
  * matching the given value.
@@ -3515,11 +3576,11 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3515
3576
  refreshValidityState() {
3516
3577
  var self = this;
3517
3578
 
3518
- if (!self.input.checkValidity) {
3579
+ if (!self.input.validity) {
3519
3580
  return;
3520
3581
  }
3521
3582
 
3522
- self.isValid = self.input.checkValidity();
3583
+ self.isValid = self.input.validity.valid;
3523
3584
  self.isInvalid = !self.isValid;
3524
3585
  }
3525
3586
  /**
@@ -3746,9 +3807,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3746
3807
  }
3747
3808
  }
3748
3809
 
3749
- const values = rm_items.map(item => item.dataset.value); // allow the callback to abort
3750
-
3751
- if (!values.length || typeof self.settings.onDelete === 'function' && self.settings.onDelete.call(self, values, e) === false) {
3810
+ if (!self.shouldDelete(rm_items, e)) {
3752
3811
  return false;
3753
3812
  }
3754
3813
 
@@ -3767,6 +3826,20 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3767
3826
  self.refreshOptions(false);
3768
3827
  return true;
3769
3828
  }
3829
+ /**
3830
+ * Return true if the items should be deleted
3831
+ */
3832
+
3833
+
3834
+ shouldDelete(items, evt) {
3835
+ const values = items.map(item => item.dataset.value); // allow the callback to abort
3836
+
3837
+ if (!values.length || typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false) {
3838
+ return false;
3839
+ }
3840
+
3841
+ return true;
3842
+ }
3770
3843
  /**
3771
3844
  * Selects the previous / next item (depending on the `direction` argument).
3772
3845
  *
@@ -4124,10 +4197,12 @@ function checkbox_options () {
4124
4197
  setTimeout(() => {
4125
4198
  var checkbox = option.querySelector('input');
4126
4199
 
4127
- if (option.classList.contains('selected')) {
4128
- checkbox.checked = true;
4129
- } else {
4130
- checkbox.checked = false;
4200
+ if (checkbox instanceof HTMLInputElement) {
4201
+ if (option.classList.contains('selected')) {
4202
+ checkbox.checked = true;
4203
+ } else {
4204
+ checkbox.checked = false;
4205
+ }
4131
4206
  }
4132
4207
  }, 1);
4133
4208
  }; // add checkbox to option template
@@ -4454,7 +4529,9 @@ function dropdown_input () {
4454
4529
 
4455
4530
  self.hook('before', 'close', () => {
4456
4531
  if (!self.isOpen) return;
4457
- self.focus_node.focus();
4532
+ self.focus_node.focus({
4533
+ preventScroll: true
4534
+ });
4458
4535
  });
4459
4536
  });
4460
4537
  }
@@ -4492,12 +4569,8 @@ function input_autogrow () {
4492
4569
 
4493
4570
 
4494
4571
  var resize = () => {
4495
- if (self.items.length > 0) {
4496
- test_input.textContent = control.value;
4497
- control.style.width = test_input.clientWidth + 'px';
4498
- } else {
4499
- control.style.width = '';
4500
- }
4572
+ test_input.textContent = control.value;
4573
+ control.style.width = test_input.clientWidth + 'px';
4501
4574
  };
4502
4575
 
4503
4576
  resize();
@@ -4576,6 +4649,7 @@ function optgroup_columns () {
4576
4649
  return orig_keydown.call(self, evt);
4577
4650
  }
4578
4651
 
4652
+ self.ignoreHover = true;
4579
4653
  optgroup = parentMatch(self.activeOption, '[data-group]');
4580
4654
  index = nodeIndex(self.activeOption, '[data-selectable]');
4581
4655
 
@@ -4635,9 +4709,9 @@ function remove_button (userOptions) {
4635
4709
  var orig_render_item = self.settings.render.item;
4636
4710
 
4637
4711
  self.settings.render.item = (data, escape) => {
4638
- var rendered = getDom(orig_render_item.call(self, data, escape));
4712
+ var item = getDom(orig_render_item.call(self, data, escape));
4639
4713
  var close_button = getDom(html);
4640
- rendered.appendChild(close_button);
4714
+ item.appendChild(close_button);
4641
4715
  addEvent(close_button, 'mousedown', evt => {
4642
4716
  preventDefault(evt, true);
4643
4717
  });
@@ -4645,12 +4719,12 @@ function remove_button (userOptions) {
4645
4719
  // propagating will trigger the dropdown to show for single mode
4646
4720
  preventDefault(evt, true);
4647
4721
  if (self.isLocked) return;
4648
- var value = rendered.dataset.value;
4649
- self.removeItem(value);
4722
+ if (!self.shouldDelete([item], evt)) return;
4723
+ self.removeItem(item);
4650
4724
  self.refreshOptions(false);
4651
4725
  self.inputState();
4652
4726
  });
4653
- return rendered;
4727
+ return item;
4654
4728
  };
4655
4729
  });
4656
4730
  }
@@ -4714,10 +4788,11 @@ function virtual_scroll () {
4714
4788
  var dropdown_content;
4715
4789
  var loading_more = false;
4716
4790
  var load_more_opt;
4791
+ var default_values = [];
4717
4792
 
4718
4793
  if (!self.settings.shouldLoadMore) {
4719
4794
  // return true if additional results should be loaded
4720
- self.settings.shouldLoadMore = function () {
4795
+ self.settings.shouldLoadMore = () => {
4721
4796
  const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);
4722
4797
 
4723
4798
  if (scroll_percent > 0.9) {
@@ -4749,7 +4824,7 @@ function virtual_scroll () {
4749
4824
  field: '$score'
4750
4825
  }]; // can we load more results for given query?
4751
4826
 
4752
- function canLoadMore(query) {
4827
+ const canLoadMore = query => {
4753
4828
  if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {
4754
4829
  return false;
4755
4830
  }
@@ -4759,15 +4834,23 @@ function virtual_scroll () {
4759
4834
  }
4760
4835
 
4761
4836
  return false;
4762
- } // set the next url that will be
4837
+ };
4838
+
4839
+ const clearFilter = (option, value) => {
4840
+ if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {
4841
+ return true;
4842
+ }
4843
+
4844
+ return false;
4845
+ }; // set the next url that will be
4763
4846
 
4764
4847
 
4765
- self.setNextUrl = function (value, next_url) {
4848
+ self.setNextUrl = (value, next_url) => {
4766
4849
  pagination[value] = next_url;
4767
4850
  }; // getUrl() to be used in settings.load()
4768
4851
 
4769
4852
 
4770
- self.getUrl = function (query) {
4853
+ self.getUrl = query => {
4771
4854
  if (query in pagination) {
4772
4855
  const next_url = pagination[query];
4773
4856
  pagination[query] = false;
@@ -4801,7 +4884,7 @@ function virtual_scroll () {
4801
4884
 
4802
4885
  self.hook('instead', 'loadCallback', (options, optgroups) => {
4803
4886
  if (!loading_more) {
4804
- self.clearOptions();
4887
+ self.clearOptions(clearFilter);
4805
4888
  } else if (load_more_opt && options.length > 0) {
4806
4889
  load_more_opt.dataset.value = options[0][self.settings.valueField];
4807
4890
  }
@@ -4839,18 +4922,19 @@ function virtual_scroll () {
4839
4922
  }); // add scroll listener and default templates
4840
4923
 
4841
4924
  self.on('initialize', () => {
4925
+ default_values = Object.keys(self.options);
4842
4926
  dropdown_content = self.dropdown_content; // default templates
4843
4927
 
4844
4928
  self.settings.render = Object.assign({}, {
4845
- loading_more: function () {
4929
+ loading_more: () => {
4846
4930
  return `<div class="loading-more-results">Loading more results ... </div>`;
4847
4931
  },
4848
- no_more_results: function () {
4932
+ no_more_results: () => {
4849
4933
  return `<div class="no-more-results">No more results</div>`;
4850
4934
  }
4851
4935
  }, self.settings.render); // watch dropdown content scroll position
4852
4936
 
4853
- dropdown_content.addEventListener('scroll', function () {
4937
+ dropdown_content.addEventListener('scroll', () => {
4854
4938
  if (!self.settings.shouldLoadMore.call(self)) {
4855
4939
  return;
4856
4940
  } // !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true