tom-select-rails 2.2.2 → 2.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) 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/constants.d.ts +12 -0
  4. data/vendor/assets/javascripts/tom-select-rails/cjs/constants.js +16 -0
  5. data/vendor/assets/javascripts/tom-select-rails/cjs/constants.js.map +1 -0
  6. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/highlight.d.ts +13 -0
  7. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/highlight.js +69 -0
  8. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/highlight.js.map +1 -0
  9. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microevent.d.ts +20 -0
  10. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microevent.js +64 -0
  11. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microevent.js.map +1 -0
  12. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microplugin.d.ts +71 -0
  13. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microplugin.js +112 -0
  14. data/vendor/assets/javascripts/tom-select-rails/cjs/contrib/microplugin.js.map +1 -0
  15. data/vendor/assets/javascripts/tom-select-rails/cjs/defaults.d.ts +52 -0
  16. data/vendor/assets/javascripts/tom-select-rails/cjs/defaults.js +84 -0
  17. data/vendor/assets/javascripts/tom-select-rails/cjs/defaults.js.map +1 -0
  18. data/vendor/assets/javascripts/tom-select-rails/cjs/getSettings.d.ts +3 -0
  19. data/vendor/assets/javascripts/tom-select-rails/cjs/getSettings.js +146 -0
  20. data/vendor/assets/javascripts/tom-select-rails/cjs/getSettings.js.map +1 -0
  21. data/vendor/assets/javascripts/tom-select-rails/cjs/package.json +1 -0
  22. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/caret_position/plugin.d.ts +16 -0
  23. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/caret_position/plugin.js +66 -0
  24. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/caret_position/plugin.js.map +1 -0
  25. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/change_listener/plugin.d.ts +16 -0
  26. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/change_listener/plugin.js +25 -0
  27. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/change_listener/plugin.js.map +1 -0
  28. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/plugin.d.ts +17 -0
  29. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/plugin.js +108 -0
  30. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/plugin.js.map +1 -0
  31. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/types.d.ts +14 -0
  32. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/types.js +3 -0
  33. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/checkbox_options/types.js.map +1 -0
  34. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/plugin.d.ts +17 -0
  35. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/plugin.js +44 -0
  36. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/plugin.js.map +1 -0
  37. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/types.d.ts +5 -0
  38. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/types.js +3 -0
  39. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/clear_button/types.js.map +1 -0
  40. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/drag_drop/plugin.d.ts +16 -0
  41. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/drag_drop/plugin.js +117 -0
  42. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/drag_drop/plugin.js.map +1 -0
  43. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/plugin.d.ts +17 -0
  44. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/plugin.js +50 -0
  45. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/plugin.js.map +1 -0
  46. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/types.d.ts +8 -0
  47. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/types.js +3 -0
  48. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_header/types.js.map +1 -0
  49. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_input/plugin.d.ts +16 -0
  50. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_input/plugin.js +77 -0
  51. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/dropdown_input/plugin.js.map +1 -0
  52. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/input_autogrow/plugin.d.ts +15 -0
  53. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/input_autogrow/plugin.js +47 -0
  54. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/input_autogrow/plugin.js.map +1 -0
  55. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_active_items/plugin.d.ts +15 -0
  56. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_active_items/plugin.js +22 -0
  57. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_active_items/plugin.js.map +1 -0
  58. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_backspace_delete/plugin.d.ts +15 -0
  59. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_backspace_delete/plugin.js +28 -0
  60. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/no_backspace_delete/plugin.js.map +1 -0
  61. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/optgroup_columns/plugin.d.ts +16 -0
  62. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/optgroup_columns/plugin.js +51 -0
  63. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/optgroup_columns/plugin.js.map +1 -0
  64. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/plugin.d.ts +17 -0
  65. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/plugin.js +61 -0
  66. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/plugin.js.map +1 -0
  67. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/types.d.ts +6 -0
  68. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/types.js +3 -0
  69. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/remove_button/types.js.map +1 -0
  70. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/restore_on_backspace/plugin.d.ts +21 -0
  71. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/restore_on_backspace/plugin.js +24 -0
  72. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/restore_on_backspace/plugin.js.map +1 -0
  73. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/virtual_scroll/plugin.d.ts +16 -0
  74. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/virtual_scroll/plugin.js +170 -0
  75. data/vendor/assets/javascripts/tom-select-rails/cjs/plugins/virtual_scroll/plugin.js.map +1 -0
  76. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.d.ts +2 -0
  77. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js +33 -5497
  78. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js.map +1 -1
  79. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.d.ts +594 -0
  80. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js +2147 -4555
  81. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js.map +1 -1
  82. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.d.ts +2 -0
  83. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js +15 -4934
  84. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js.map +1 -1
  85. data/vendor/assets/javascripts/tom-select-rails/cjs/types/core.d.ts +49 -0
  86. data/vendor/assets/javascripts/tom-select-rails/cjs/types/core.js +3 -0
  87. data/vendor/assets/javascripts/tom-select-rails/cjs/types/core.js.map +1 -0
  88. data/vendor/assets/javascripts/tom-select-rails/cjs/types/index.d.ts +2 -0
  89. data/vendor/assets/javascripts/tom-select-rails/cjs/types/index.js +19 -0
  90. data/vendor/assets/javascripts/tom-select-rails/cjs/types/index.js.map +1 -0
  91. data/vendor/assets/javascripts/tom-select-rails/cjs/types/settings.d.ts +79 -0
  92. data/vendor/assets/javascripts/tom-select-rails/cjs/types/settings.js +3 -0
  93. data/vendor/assets/javascripts/tom-select-rails/cjs/types/settings.js.map +1 -0
  94. data/vendor/assets/javascripts/tom-select-rails/cjs/utils.d.ts +95 -0
  95. data/vendor/assets/javascripts/tom-select-rails/cjs/utils.js +130 -114
  96. data/vendor/assets/javascripts/tom-select-rails/cjs/utils.js.map +1 -1
  97. data/vendor/assets/javascripts/tom-select-rails/cjs/vanilla.d.ts +76 -0
  98. data/vendor/assets/javascripts/tom-select-rails/cjs/vanilla.js +190 -0
  99. data/vendor/assets/javascripts/tom-select-rails/cjs/vanilla.js.map +1 -0
  100. data/vendor/assets/javascripts/tom-select-rails/esm/constants.d.ts +12 -0
  101. data/vendor/assets/javascripts/tom-select-rails/esm/constants.js +13 -0
  102. data/vendor/assets/javascripts/tom-select-rails/esm/constants.js.map +1 -0
  103. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/highlight.d.ts +13 -0
  104. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/highlight.js +64 -0
  105. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/highlight.js.map +1 -0
  106. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microevent.d.ts +20 -0
  107. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microevent.js +61 -0
  108. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microevent.js.map +1 -0
  109. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microplugin.d.ts +71 -0
  110. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microplugin.js +109 -0
  111. data/vendor/assets/javascripts/tom-select-rails/esm/contrib/microplugin.js.map +1 -0
  112. data/vendor/assets/javascripts/tom-select-rails/esm/defaults.d.ts +52 -0
  113. data/vendor/assets/javascripts/tom-select-rails/esm/defaults.js +82 -0
  114. data/vendor/assets/javascripts/tom-select-rails/esm/defaults.js.map +1 -0
  115. data/vendor/assets/javascripts/tom-select-rails/esm/getSettings.d.ts +3 -0
  116. data/vendor/assets/javascripts/tom-select-rails/esm/getSettings.js +143 -0
  117. data/vendor/assets/javascripts/tom-select-rails/esm/getSettings.js.map +1 -0
  118. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.d.ts +16 -0
  119. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js +26 -78
  120. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js.map +1 -1
  121. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/change_listener/plugin.d.ts +16 -0
  122. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/change_listener/plugin.js +3 -2
  123. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/change_listener/plugin.js.map +1 -1
  124. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.d.ts +17 -0
  125. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js +47 -96
  126. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js.map +1 -1
  127. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/types.d.ts +14 -0
  128. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/types.js +2 -0
  129. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/types.js.map +1 -0
  130. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.d.ts +17 -0
  131. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js +3 -75
  132. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js.map +1 -1
  133. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/types.d.ts +5 -0
  134. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/types.js +2 -0
  135. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/types.js.map +1 -0
  136. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/drag_drop/plugin.d.ts +16 -0
  137. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/drag_drop/plugin.js +187 -29
  138. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/drag_drop/plugin.js.map +1 -1
  139. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.d.ts +17 -0
  140. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js +27 -97
  141. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js.map +1 -1
  142. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/types.d.ts +8 -0
  143. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/types.js +2 -0
  144. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/types.js.map +1 -0
  145. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.d.ts +16 -0
  146. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js +46 -117
  147. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js.map +1 -1
  148. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.d.ts +15 -0
  149. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js +4 -6
  150. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js.map +1 -1
  151. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_active_items/plugin.d.ts +15 -0
  152. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_active_items/plugin.js +2 -1
  153. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_active_items/plugin.js.map +1 -1
  154. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_backspace_delete/plugin.d.ts +15 -0
  155. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_backspace_delete/plugin.js +2 -2
  156. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_backspace_delete/plugin.js.map +1 -1
  157. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.d.ts +16 -0
  158. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js +3 -80
  159. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js.map +1 -1
  160. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.d.ts +17 -0
  161. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js +38 -104
  162. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js.map +1 -1
  163. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/types.d.ts +6 -0
  164. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/types.js +2 -0
  165. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/types.js.map +1 -0
  166. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/restore_on_backspace/plugin.d.ts +21 -0
  167. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/restore_on_backspace/plugin.js +2 -3
  168. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/restore_on_backspace/plugin.js.map +1 -1
  169. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.d.ts +16 -0
  170. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js +56 -112
  171. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js.map +1 -1
  172. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.d.ts +2 -0
  173. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js +17 -5481
  174. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js.map +1 -1
  175. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.d.ts +594 -0
  176. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js +2127 -4536
  177. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js.map +1 -1
  178. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.d.ts +2 -0
  179. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js +8 -4927
  180. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js.map +1 -1
  181. data/vendor/assets/javascripts/tom-select-rails/esm/types/core.d.ts +49 -0
  182. data/vendor/assets/javascripts/tom-select-rails/esm/types/core.js +2 -0
  183. data/vendor/assets/javascripts/tom-select-rails/esm/types/core.js.map +1 -0
  184. data/vendor/assets/javascripts/tom-select-rails/esm/types/index.d.ts +2 -0
  185. data/vendor/assets/javascripts/tom-select-rails/esm/types/index.js +3 -0
  186. data/vendor/assets/javascripts/tom-select-rails/esm/types/index.js.map +1 -0
  187. data/vendor/assets/javascripts/tom-select-rails/esm/types/settings.d.ts +79 -0
  188. data/vendor/assets/javascripts/tom-select-rails/esm/types/settings.js +2 -0
  189. data/vendor/assets/javascripts/tom-select-rails/esm/types/settings.js.map +1 -0
  190. data/vendor/assets/javascripts/tom-select-rails/esm/utils.d.ts +95 -0
  191. data/vendor/assets/javascripts/tom-select-rails/esm/utils.js +121 -107
  192. data/vendor/assets/javascripts/tom-select-rails/esm/utils.js.map +1 -1
  193. data/vendor/assets/javascripts/tom-select-rails/esm/vanilla.d.ts +76 -0
  194. data/vendor/assets/javascripts/tom-select-rails/esm/vanilla.js +172 -0
  195. data/vendor/assets/javascripts/tom-select-rails/esm/vanilla.js.map +1 -0
  196. data/vendor/assets/javascripts/tom-select-rails/js/package.json +1 -0
  197. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js +161 -213
  198. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js.map +1 -1
  199. data/vendor/assets/javascripts/tom-select-rails/js/plugins/change_listener.js +3 -2
  200. data/vendor/assets/javascripts/tom-select-rails/js/plugins/change_listener.js.map +1 -1
  201. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js +47 -96
  202. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js.map +1 -1
  203. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js +71 -143
  204. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js.map +1 -1
  205. data/vendor/assets/javascripts/tom-select-rails/js/plugins/drag_drop.js +187 -29
  206. data/vendor/assets/javascripts/tom-select-rails/js/plugins/drag_drop.js.map +1 -1
  207. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js +100 -170
  208. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js.map +1 -1
  209. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js +212 -283
  210. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js.map +1 -1
  211. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js +4 -6
  212. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js.map +1 -1
  213. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_active_items.js +2 -1
  214. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_active_items.js.map +1 -1
  215. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_backspace_delete.js +2 -2
  216. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_backspace_delete.js.map +1 -1
  217. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js +84 -161
  218. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js.map +1 -1
  219. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js +132 -198
  220. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js.map +1 -1
  221. data/vendor/assets/javascripts/tom-select-rails/js/plugins/restore_on_backspace.js +2 -3
  222. data/vendor/assets/javascripts/tom-select-rails/js/plugins/restore_on_backspace.js.map +1 -1
  223. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js +270 -326
  224. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js.map +1 -1
  225. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js +1367 -1918
  226. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js.map +1 -1
  227. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js +186 -173
  228. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js.map +1 -1
  229. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js +1400 -1883
  230. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js.map +1 -1
  231. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js +366 -343
  232. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js.map +1 -1
  233. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js +1369 -1915
  234. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js.map +1 -1
  235. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js +339 -326
  236. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js.map +1 -1
  237. data/vendor/assets/javascripts/tom-select-rails/types/contrib/microevent.d.ts +1 -1
  238. data/vendor/assets/javascripts/tom-select-rails/types/contrib/microplugin.d.ts +4 -4
  239. data/vendor/assets/javascripts/tom-select-rails/types/defaults.d.ts +1 -0
  240. data/vendor/assets/javascripts/tom-select-rails/types/getSettings.d.ts +2 -2
  241. data/vendor/assets/javascripts/tom-select-rails/types/plugins/caret_position/plugin.d.ts +1 -1
  242. data/vendor/assets/javascripts/tom-select-rails/types/plugins/change_listener/plugin.d.ts +1 -1
  243. data/vendor/assets/javascripts/tom-select-rails/types/plugins/checkbox_options/plugin.d.ts +4 -3
  244. data/vendor/assets/javascripts/tom-select-rails/types/plugins/checkbox_options/types.d.ts +14 -0
  245. data/vendor/assets/javascripts/tom-select-rails/types/plugins/clear_button/plugin.d.ts +2 -2
  246. data/vendor/assets/javascripts/tom-select-rails/types/plugins/clear_button/types.d.ts +1 -1
  247. data/vendor/assets/javascripts/tom-select-rails/types/plugins/drag_drop/plugin.d.ts +1 -1
  248. data/vendor/assets/javascripts/tom-select-rails/types/plugins/dropdown_header/plugin.d.ts +2 -2
  249. data/vendor/assets/javascripts/tom-select-rails/types/plugins/dropdown_header/types.d.ts +1 -1
  250. data/vendor/assets/javascripts/tom-select-rails/types/plugins/dropdown_input/plugin.d.ts +1 -1
  251. data/vendor/assets/javascripts/tom-select-rails/types/plugins/input_autogrow/plugin.d.ts +1 -1
  252. data/vendor/assets/javascripts/tom-select-rails/types/plugins/no_active_items/plugin.d.ts +1 -1
  253. data/vendor/assets/javascripts/tom-select-rails/types/plugins/no_backspace_delete/plugin.d.ts +1 -1
  254. data/vendor/assets/javascripts/tom-select-rails/types/plugins/optgroup_columns/plugin.d.ts +1 -1
  255. data/vendor/assets/javascripts/tom-select-rails/types/plugins/remove_button/plugin.d.ts +2 -2
  256. data/vendor/assets/javascripts/tom-select-rails/types/plugins/remove_button/types.d.ts +1 -1
  257. data/vendor/assets/javascripts/tom-select-rails/types/plugins/restore_on_backspace/plugin.d.ts +3 -3
  258. data/vendor/assets/javascripts/tom-select-rails/types/plugins/virtual_scroll/plugin.d.ts +1 -1
  259. data/vendor/assets/javascripts/tom-select-rails/types/tom-select.complete.d.ts +1 -1
  260. data/vendor/assets/javascripts/tom-select-rails/types/tom-select.d.ts +12 -14
  261. data/vendor/assets/javascripts/tom-select-rails/types/tom-select.popular.d.ts +1 -1
  262. data/vendor/assets/javascripts/tom-select-rails/types/types/core.d.ts +17 -16
  263. data/vendor/assets/javascripts/tom-select-rails/types/types/index.d.ts +2 -2
  264. data/vendor/assets/javascripts/tom-select-rails/types/types/settings.d.ts +6 -5
  265. data/vendor/assets/javascripts/tom-select-rails/types/utils.d.ts +21 -2
  266. data/vendor/assets/javascripts/tom-select-rails/types/vanilla.d.ts +1 -1
  267. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css +227 -219
  268. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css.map +1 -1
  269. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css +1 -1
  270. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css.map +1 -1
  271. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css +247 -254
  272. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css.map +1 -1
  273. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css +1 -1
  274. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css.map +1 -1
  275. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css +213 -210
  276. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css.map +1 -1
  277. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css +223 -215
  278. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css.map +1 -1
  279. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css +1 -1
  280. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css.map +1 -1
  281. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css +1 -1
  282. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css.map +1 -1
  283. data/vendor/assets/stylesheets/tom-select-rails/scss/_dropdown.scss +7 -10
  284. data/vendor/assets/stylesheets/tom-select-rails/scss/_items.scss +7 -9
  285. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/checkbox_options.scss +8 -2
  286. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/clear_button.scss +16 -14
  287. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/drag_drop.scss +6 -12
  288. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/dropdown_header.scss +3 -2
  289. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/dropdown_input.scss +7 -11
  290. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/input_autogrow.scss +0 -3
  291. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/optgroup_columns.scss +7 -5
  292. data/vendor/assets/stylesheets/tom-select-rails/scss/plugins/remove_button.scss +20 -20
  293. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.bootstrap4.scss +33 -39
  294. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.bootstrap5.scss +54 -80
  295. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.default.scss +16 -14
  296. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.scss +52 -57
  297. metadata +154 -7
@@ -1,4934 +1,15 @@
1
- /**
2
- * Tom Select v2.2.2
3
- * Licensed under the Apache License, Version 2.0 (the "License");
4
- */
5
-
6
- 'use strict';
7
-
8
- /**
9
- * MicroEvent - to make any js object an event emitter
10
- *
11
- * - pure javascript - server compatible, browser compatible
12
- * - dont rely on the browser doms
13
- * - super simple - you get it immediatly, no mistery, no magic involved
14
- *
15
- * @author Jerome Etienne (https://github.com/jeromeetienne)
16
- */
17
-
18
- /**
19
- * Execute callback for each event in space separated list of event names
20
- *
21
- */
22
- function forEvents(events, callback) {
23
- events.split(/\s+/).forEach(event => {
24
- callback(event);
25
- });
26
- }
27
-
28
- class MicroEvent {
29
- constructor() {
30
- this._events = void 0;
31
- this._events = {};
32
- }
33
-
34
- on(events, fct) {
35
- forEvents(events, event => {
36
- const event_array = this._events[event] || [];
37
- event_array.push(fct);
38
- this._events[event] = event_array;
39
- });
40
- }
41
-
42
- off(events, fct) {
43
- var n = arguments.length;
44
-
45
- if (n === 0) {
46
- this._events = {};
47
- return;
48
- }
49
-
50
- forEvents(events, event => {
51
- if (n === 1) {
52
- delete this._events[event];
53
- return;
54
- }
55
-
56
- const event_array = this._events[event];
57
- if (event_array === undefined) return;
58
- event_array.splice(event_array.indexOf(fct), 1);
59
- this._events[event] = event_array;
60
- });
61
- }
62
-
63
- trigger(events, ...args) {
64
- var self = this;
65
- forEvents(events, event => {
66
- const event_array = self._events[event];
67
- if (event_array === undefined) return;
68
- event_array.forEach(fct => {
69
- fct.apply(self, args);
70
- });
71
- });
72
- }
73
-
74
- }
75
-
76
- /**
77
- * microplugin.js
78
- * Copyright (c) 2013 Brian Reavis & contributors
79
- *
80
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
81
- * file except in compliance with the License. You may obtain a copy of the License at:
82
- * http://www.apache.org/licenses/LICENSE-2.0
83
- *
84
- * Unless required by applicable law or agreed to in writing, software distributed under
85
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
86
- * ANY KIND, either express or implied. See the License for the specific language
87
- * governing permissions and limitations under the License.
88
- *
89
- * @author Brian Reavis <brian@thirdroute.com>
90
- */
91
- function MicroPlugin(Interface) {
92
- Interface.plugins = {};
93
- return class extends Interface {
94
- constructor(...args) {
95
- super(...args);
96
- this.plugins = {
97
- names: [],
98
- settings: {},
99
- requested: {},
100
- loaded: {}
101
- };
102
- }
103
-
104
- /**
105
- * Registers a plugin.
106
- *
107
- * @param {function} fn
108
- */
109
- static define(name, fn) {
110
- Interface.plugins[name] = {
111
- 'name': name,
112
- 'fn': fn
113
- };
114
- }
115
- /**
116
- * Initializes the listed plugins (with options).
117
- * Acceptable formats:
118
- *
119
- * List (without options):
120
- * ['a', 'b', 'c']
121
- *
122
- * List (with options):
123
- * [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
124
- *
125
- * Hash (with options):
126
- * {'a': { ... }, 'b': { ... }, 'c': { ... }}
127
- *
128
- * @param {array|object} plugins
129
- */
130
-
131
-
132
- initializePlugins(plugins) {
133
- var key, name;
134
- const self = this;
135
- const queue = [];
136
-
137
- if (Array.isArray(plugins)) {
138
- plugins.forEach(plugin => {
139
- if (typeof plugin === 'string') {
140
- queue.push(plugin);
141
- } else {
142
- self.plugins.settings[plugin.name] = plugin.options;
143
- queue.push(plugin.name);
144
- }
145
- });
146
- } else if (plugins) {
147
- for (key in plugins) {
148
- if (plugins.hasOwnProperty(key)) {
149
- self.plugins.settings[key] = plugins[key];
150
- queue.push(key);
151
- }
152
- }
153
- }
154
-
155
- while (name = queue.shift()) {
156
- self.require(name);
157
- }
158
- }
159
-
160
- loadPlugin(name) {
161
- var self = this;
162
- var plugins = self.plugins;
163
- var plugin = Interface.plugins[name];
164
-
165
- if (!Interface.plugins.hasOwnProperty(name)) {
166
- throw new Error('Unable to find "' + name + '" plugin');
167
- }
168
-
169
- plugins.requested[name] = true;
170
- plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
171
- plugins.names.push(name);
172
- }
173
- /**
174
- * Initializes a plugin.
175
- *
176
- */
177
-
178
-
179
- require(name) {
180
- var self = this;
181
- var plugins = self.plugins;
182
-
183
- if (!self.plugins.loaded.hasOwnProperty(name)) {
184
- if (plugins.requested[name]) {
185
- throw new Error('Plugin has circular dependency ("' + name + '")');
186
- }
187
-
188
- self.loadPlugin(name);
189
- }
190
-
191
- return plugins.loaded[name];
192
- }
193
-
194
- };
195
- }
196
-
197
- /*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
198
- /**
199
- * Convert array of strings to a regular expression
200
- * ex ['ab','a'] => (?:ab|a)
201
- * ex ['a','b'] => [ab]
202
- * @param {string[]} chars
203
- * @return {string}
204
- */
205
- const arrayToPattern = chars => {
206
- chars = chars.filter(Boolean);
207
-
208
- if (chars.length < 2) {
209
- return chars[0] || '';
210
- }
211
-
212
- return maxValueLength(chars) == 1 ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';
213
- };
214
- /**
215
- * @param {string[]} array
216
- * @return {string}
217
- */
218
-
219
- const sequencePattern = array => {
220
- if (!hasDuplicates(array)) {
221
- return array.join('');
222
- }
223
-
224
- let pattern = '';
225
- let prev_char_count = 0;
226
-
227
- const prev_pattern = () => {
228
- if (prev_char_count > 1) {
229
- pattern += '{' + prev_char_count + '}';
230
- }
231
- };
232
-
233
- array.forEach((char, i) => {
234
- if (char === array[i - 1]) {
235
- prev_char_count++;
236
- return;
237
- }
238
-
239
- prev_pattern();
240
- pattern += char;
241
- prev_char_count = 1;
242
- });
243
- prev_pattern();
244
- return pattern;
245
- };
246
- /**
247
- * Convert array of strings to a regular expression
248
- * ex ['ab','a'] => (?:ab|a)
249
- * ex ['a','b'] => [ab]
250
- * @param {Set<string>} chars
251
- * @return {string}
252
- */
253
-
254
- const setToPattern = chars => {
255
- let array = toArray(chars);
256
- return arrayToPattern(array);
257
- };
258
- /**
259
- *
260
- * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values
261
- * @param {any[]} array
262
- */
263
-
264
- const hasDuplicates = array => {
265
- return new Set(array).size !== array.length;
266
- };
267
- /**
268
- * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error
269
- * @param {string} str
270
- * @return {string}
271
- */
272
-
273
- const escape_regex = str => {
274
- return (str + '').replace(/([\$\(\)\*\+\.\?\[\]\^\{\|\}\\])/gu, '\\$1');
275
- };
276
- /**
277
- * Return the max length of array values
278
- * @param {string[]} array
279
- *
280
- */
281
-
282
- const maxValueLength = array => {
283
- return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);
284
- };
285
- /**
286
- * @param {string} str
287
- */
288
-
289
- const unicodeLength = str => {
290
- return toArray(str).length;
291
- };
292
- /**
293
- * @param {any} p
294
- * @return {any[]}
295
- */
296
-
297
- const toArray = p => Array.from(p);
298
-
299
- /*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
300
- /**
301
- * Get all possible combinations of substrings that add up to the given string
302
- * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string
303
- * @param {string} input
304
- * @return {string[][]}
305
- */
306
- const allSubstrings = input => {
307
- if (input.length === 1) return [[input]];
308
- /** @type {string[][]} */
309
-
310
- let result = [];
311
- const start = input.substring(1);
312
- const suba = allSubstrings(start);
313
- suba.forEach(function (subresult) {
314
- let tmp = subresult.slice(0);
315
- tmp[0] = input.charAt(0) + tmp[0];
316
- result.push(tmp);
317
- tmp = subresult.slice(0);
318
- tmp.unshift(input.charAt(0));
319
- result.push(tmp);
320
- });
321
- return result;
322
- };
323
-
324
- /*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
325
-
326
- /**
327
- * @typedef {{[key:string]:string}} TUnicodeMap
328
- * @typedef {{[key:string]:Set<string>}} TUnicodeSets
329
- * @typedef {[[number,number]]} TCodePoints
330
- * @typedef {{folded:string,composed:string,code_point:number}} TCodePointObj
331
- * @typedef {{start:number,end:number,length:number,substr:string}} TSequencePart
332
- */
333
- /** @type {TCodePoints} */
334
-
335
- const code_points = [[0, 65535]];
336
- const accent_pat = '[\u0300-\u036F\u{b7}\u{2be}\u{2bc}]';
337
- /** @type {TUnicodeMap} */
338
-
339
- let unicode_map;
340
- /** @type {RegExp} */
341
-
342
- let multi_char_reg;
343
- const max_char_length = 3;
344
- /** @type {TUnicodeMap} */
345
-
346
- const latin_convert = {};
347
- /** @type {TUnicodeMap} */
348
-
349
- const latin_condensed = {
350
- '/': '⁄∕',
351
- '0': '߀',
352
- "a": "ⱥɐɑ",
353
- "aa": "ꜳ",
354
- "ae": "æǽǣ",
355
- "ao": "ꜵ",
356
- "au": "ꜷ",
357
- "av": "ꜹꜻ",
358
- "ay": "ꜽ",
359
- "b": "ƀɓƃ",
360
- "c": "ꜿƈȼↄ",
361
- "d": "đɗɖᴅƌꮷԁɦ",
362
- "e": "ɛǝᴇɇ",
363
- "f": "ꝼƒ",
364
- "g": "ǥɠꞡᵹꝿɢ",
365
- "h": "ħⱨⱶɥ",
366
- "i": "ɨı",
367
- "j": "ɉȷ",
368
- "k": "ƙⱪꝁꝃꝅꞣ",
369
- "l": "łƚɫⱡꝉꝇꞁɭ",
370
- "m": "ɱɯϻ",
371
- "n": "ꞥƞɲꞑᴎлԉ",
372
- "o": "øǿɔɵꝋꝍᴑ",
373
- "oe": "œ",
374
- "oi": "ƣ",
375
- "oo": "ꝏ",
376
- "ou": "ȣ",
377
- "p": "ƥᵽꝑꝓꝕρ",
378
- "q": "ꝗꝙɋ",
379
- "r": "ɍɽꝛꞧꞃ",
380
- "s": "ßȿꞩꞅʂ",
381
- "t": "ŧƭʈⱦꞇ",
382
- "th": "þ",
383
- "tz": "ꜩ",
384
- "u": "ʉ",
385
- "v": "ʋꝟʌ",
386
- "vy": "ꝡ",
387
- "w": "ⱳ",
388
- "y": "ƴɏỿ",
389
- "z": "ƶȥɀⱬꝣ",
390
- "hv": "ƕ"
391
- };
392
-
393
- for (let latin in latin_condensed) {
394
- let unicode = latin_condensed[latin] || '';
395
-
396
- for (let i = 0; i < unicode.length; i++) {
397
- let char = unicode.substring(i, i + 1);
398
- latin_convert[char] = latin;
399
- }
400
- }
401
-
402
- const convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');
403
- /**
404
- * Initialize the unicode_map from the give code point ranges
405
- *
406
- * @param {TCodePoints=} _code_points
407
- */
408
-
409
- const initialize = _code_points => {
410
- if (unicode_map !== undefined) return;
411
- unicode_map = generateMap(_code_points || code_points);
412
- };
413
- /**
414
- * Helper method for normalize a string
415
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
416
- * @param {string} str
417
- * @param {string} form
418
- */
419
-
420
- const normalize = (str, form = 'NFKD') => str.normalize(form);
421
- /**
422
- * Remove accents without reordering string
423
- * calling str.normalize('NFKD') on \u{594}\u{595}\u{596} becomes \u{596}\u{594}\u{595}
424
- * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703
425
- * @param {string} str
426
- * @return {string}
427
- */
428
-
429
- const asciifold = str => {
430
- return toArray(str).reduce(
431
- /**
432
- * @param {string} result
433
- * @param {string} char
434
- */
435
- (result, char) => {
436
- return result + _asciifold(char);
437
- }, '');
438
- };
439
- /**
440
- * @param {string} str
441
- * @return {string}
442
- */
443
-
444
- const _asciifold = str => {
445
- str = normalize(str).toLowerCase().replace(convert_pat, (
446
- /** @type {string} */
447
- char) => {
448
- return latin_convert[char] || '';
449
- }); //return str;
450
-
451
- return normalize(str, 'NFC');
452
- };
453
- /**
454
- * Generate a list of unicode variants from the list of code points
455
- * @param {TCodePoints} code_points
456
- * @yield {TCodePointObj}
457
- */
458
-
459
- function* generator(code_points) {
460
- for (const [code_point_min, code_point_max] of code_points) {
461
- for (let i = code_point_min; i <= code_point_max; i++) {
462
- let composed = String.fromCharCode(i);
463
- let folded = asciifold(composed);
464
-
465
- if (folded == composed.toLowerCase()) {
466
- continue;
467
- } // skip when folded is a string longer than 3 characters long
468
- // bc the resulting regex patterns will be long
469
- // eg:
470
- // folded صلى الله عليه وسلم length 18 code point 65018
471
- // folded جل جلاله length 8 code point 65019
472
-
473
-
474
- if (folded.length > max_char_length) {
475
- continue;
476
- }
477
-
478
- if (folded.length == 0) {
479
- continue;
480
- }
481
-
482
- yield {
483
- folded: folded,
484
- composed: composed,
485
- code_point: i
486
- };
487
- }
488
- }
489
- }
490
- /**
491
- * Generate a unicode map from the list of code points
492
- * @param {TCodePoints} code_points
493
- * @return {TUnicodeSets}
494
- */
495
-
496
- const generateSets = code_points => {
497
- /** @type {{[key:string]:Set<string>}} */
498
- const unicode_sets = {};
499
- /**
500
- * @param {string} folded
501
- * @param {string} to_add
502
- */
503
-
504
- const addMatching = (folded, to_add) => {
505
- /** @type {Set<string>} */
506
- const folded_set = unicode_sets[folded] || new Set();
507
- const patt = new RegExp('^' + setToPattern(folded_set) + '$', 'iu');
508
-
509
- if (to_add.match(patt)) {
510
- return;
511
- }
512
-
513
- folded_set.add(escape_regex(to_add));
514
- unicode_sets[folded] = folded_set;
515
- };
516
-
517
- for (let value of generator(code_points)) {
518
- addMatching(value.folded, value.folded);
519
- addMatching(value.folded, value.composed);
520
- }
521
-
522
- return unicode_sets;
523
- };
524
- /**
525
- * Generate a unicode map from the list of code points
526
- * ae => (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))
527
- *
528
- * @param {TCodePoints} code_points
529
- * @return {TUnicodeMap}
530
- */
531
-
532
- const generateMap = code_points => {
533
- /** @type {TUnicodeSets} */
534
- const unicode_sets = generateSets(code_points);
535
- /** @type {TUnicodeMap} */
536
-
537
- const unicode_map = {};
538
- /** @type {string[]} */
539
-
540
- let multi_char = [];
541
-
542
- for (let folded in unicode_sets) {
543
- let set = unicode_sets[folded];
544
-
545
- if (set) {
546
- unicode_map[folded] = setToPattern(set);
547
- }
548
-
549
- if (folded.length > 1) {
550
- multi_char.push(escape_regex(folded));
551
- }
552
- }
553
-
554
- multi_char.sort((a, b) => b.length - a.length);
555
- const multi_char_patt = arrayToPattern(multi_char);
556
- multi_char_reg = new RegExp('^' + multi_char_patt, 'u');
557
- return unicode_map;
558
- };
559
- /**
560
- * Map each element of an array from it's folded value to all possible unicode matches
561
- * @param {string[]} strings
562
- * @param {number} min_replacement
563
- * @return {string}
564
- */
565
-
566
- const mapSequence = (strings, min_replacement = 1) => {
567
- let chars_replaced = 0;
568
- strings = strings.map(str => {
569
- if (unicode_map[str]) {
570
- chars_replaced += str.length;
571
- }
572
-
573
- return unicode_map[str] || str;
574
- });
575
-
576
- if (chars_replaced >= min_replacement) {
577
- return sequencePattern(strings);
578
- }
579
-
580
- return '';
581
- };
582
- /**
583
- * Convert a short string and split it into all possible patterns
584
- * Keep a pattern only if min_replacement is met
585
- *
586
- * 'abc'
587
- * => [['abc'],['ab','c'],['a','bc'],['a','b','c']]
588
- * => ['abc-pattern','ab-c-pattern'...]
589
- *
590
- *
591
- * @param {string} str
592
- * @param {number} min_replacement
593
- * @return {string}
594
- */
595
-
596
- const substringsToPattern = (str, min_replacement = 1) => {
597
- min_replacement = Math.max(min_replacement, str.length - 1);
598
- return arrayToPattern(allSubstrings(str).map(sub_pat => {
599
- return mapSequence(sub_pat, min_replacement);
600
- }));
601
- };
602
- /**
603
- * Convert an array of sequences into a pattern
604
- * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)
605
- *
606
- * @param {Sequence[]} sequences
607
- * @param {boolean} all
608
- */
609
-
610
- const sequencesToPattern = (sequences, all = true) => {
611
- let min_replacement = sequences.length > 1 ? 1 : 0;
612
- return arrayToPattern(sequences.map(sequence => {
613
- let seq = [];
614
- const len = all ? sequence.length() : sequence.length() - 1;
615
-
616
- for (let j = 0; j < len; j++) {
617
- seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));
618
- }
619
-
620
- return sequencePattern(seq);
621
- }));
622
- };
623
- /**
624
- * Return true if the sequence is already in the sequences
625
- * @param {Sequence} needle_seq
626
- * @param {Sequence[]} sequences
627
- */
628
-
629
-
630
- const inSequences = (needle_seq, sequences) => {
631
- for (const seq of sequences) {
632
- if (seq.start != needle_seq.start || seq.end != needle_seq.end) {
633
- continue;
634
- }
635
-
636
- if (seq.substrs.join('') !== needle_seq.substrs.join('')) {
637
- continue;
638
- }
639
-
640
- let needle_parts = needle_seq.parts;
641
- /**
642
- * @param {TSequencePart} part
643
- */
644
-
645
- const filter = part => {
646
- for (const needle_part of needle_parts) {
647
- if (needle_part.start === part.start && needle_part.substr === part.substr) {
648
- return false;
649
- }
650
-
651
- if (part.length == 1 || needle_part.length == 1) {
652
- continue;
653
- } // check for overlapping parts
654
- // a = ['::=','==']
655
- // b = ['::','===']
656
- // a = ['r','sm']
657
- // b = ['rs','m']
658
-
659
-
660
- if (part.start < needle_part.start && part.end > needle_part.start) {
661
- return true;
662
- }
663
-
664
- if (needle_part.start < part.start && needle_part.end > part.start) {
665
- return true;
666
- }
667
- }
668
-
669
- return false;
670
- };
671
-
672
- let filtered = seq.parts.filter(filter);
673
-
674
- if (filtered.length > 0) {
675
- continue;
676
- }
677
-
678
- return true;
679
- }
680
-
681
- return false;
682
- };
683
-
684
- class Sequence {
685
- constructor() {
686
- /** @type {TSequencePart[]} */
687
- this.parts = [];
688
- /** @type {string[]} */
689
-
690
- this.substrs = [];
691
- this.start = 0;
692
- this.end = 0;
693
- }
694
- /**
695
- * @param {TSequencePart|undefined} part
696
- */
697
-
698
-
699
- add(part) {
700
- if (part) {
701
- this.parts.push(part);
702
- this.substrs.push(part.substr);
703
- this.start = Math.min(part.start, this.start);
704
- this.end = Math.max(part.end, this.end);
705
- }
706
- }
707
-
708
- last() {
709
- return this.parts[this.parts.length - 1];
710
- }
711
-
712
- length() {
713
- return this.parts.length;
714
- }
715
- /**
716
- * @param {number} position
717
- * @param {TSequencePart} last_piece
718
- */
719
-
720
-
721
- clone(position, last_piece) {
722
- let clone = new Sequence();
723
- let parts = JSON.parse(JSON.stringify(this.parts));
724
- let last_part = parts.pop();
725
-
726
- for (const part of parts) {
727
- clone.add(part);
728
- }
729
-
730
- let last_substr = last_piece.substr.substring(0, position - last_part.start);
731
- let clone_last_len = last_substr.length;
732
- clone.add({
733
- start: last_part.start,
734
- end: last_part.start + clone_last_len,
735
- length: clone_last_len,
736
- substr: last_substr
737
- });
738
- return clone;
739
- }
740
-
741
- }
742
- /**
743
- * Expand a regular expression pattern to include unicode variants
744
- * eg /a/ becomes /aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐɑAⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ/
745
- *
746
- * Issue:
747
- * ﺊﺋ [ 'ﺊ = \\u{fe8a}', 'ﺋ = \\u{fe8b}' ]
748
- * becomes: ئئ [ 'ي = \\u{64a}', 'ٔ = \\u{654}', 'ي = \\u{64a}', 'ٔ = \\u{654}' ]
749
- *
750
- * İIJ = IIJ = ⅡJ
751
- *
752
- * 1/2/4
753
- *
754
- * @param {string} str
755
- * @return {string|undefined}
756
- */
757
-
758
-
759
- const getPattern = str => {
760
- initialize();
761
- str = asciifold(str);
762
- let pattern = '';
763
- let sequences = [new Sequence()];
764
-
765
- for (let i = 0; i < str.length; i++) {
766
- let substr = str.substring(i);
767
- let match = substr.match(multi_char_reg);
768
- const char = str.substring(i, i + 1);
769
- const match_str = match ? match[0] : null; // loop through sequences
770
- // add either the char or multi_match
771
-
772
- let overlapping = [];
773
- let added_types = new Set();
774
-
775
- for (const sequence of sequences) {
776
- const last_piece = sequence.last();
777
-
778
- if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {
779
- // if we have a multi match
780
- if (match_str) {
781
- const len = match_str.length;
782
- sequence.add({
783
- start: i,
784
- end: i + len,
785
- length: len,
786
- substr: match_str
787
- });
788
- added_types.add('1');
789
- } else {
790
- sequence.add({
791
- start: i,
792
- end: i + 1,
793
- length: 1,
794
- substr: char
795
- });
796
- added_types.add('2');
797
- }
798
- } else if (match_str) {
799
- let clone = sequence.clone(i, last_piece);
800
- const len = match_str.length;
801
- clone.add({
802
- start: i,
803
- end: i + len,
804
- length: len,
805
- substr: match_str
806
- });
807
- overlapping.push(clone);
808
- } else {
809
- // don't add char
810
- // adding would create invalid patterns: 234 => [2,34,4]
811
- added_types.add('3');
812
- }
813
- } // if we have overlapping
814
-
815
-
816
- if (overlapping.length > 0) {
817
- // ['ii','iii'] before ['i','i','iii']
818
- overlapping = overlapping.sort((a, b) => {
819
- return a.length() - b.length();
820
- });
821
-
822
- for (let clone of overlapping) {
823
- // don't add if we already have an equivalent sequence
824
- if (inSequences(clone, sequences)) {
825
- continue;
826
- }
827
-
828
- sequences.push(clone);
829
- }
830
-
831
- continue;
832
- } // if we haven't done anything unique
833
- // clean up the patterns
834
- // helps keep patterns smaller
835
- // if str = 'r₨㎧aarss', pattern will be 446 instead of 655
836
-
837
-
838
- if (i > 0 && added_types.size == 1 && !added_types.has('3')) {
839
- pattern += sequencesToPattern(sequences, false);
840
- let new_seq = new Sequence();
841
- const old_seq = sequences[0];
842
-
843
- if (old_seq) {
844
- new_seq.add(old_seq.last());
845
- }
846
-
847
- sequences = [new_seq];
848
- }
849
- }
850
-
851
- pattern += sequencesToPattern(sequences, true);
852
- return pattern;
853
- };
854
-
855
- /*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */
856
-
857
- /**
858
- * A property getter resolving dot-notation
859
- * @param {Object} obj The root object to fetch property on
860
- * @param {String} name The optionally dotted property name to fetch
861
- * @return {Object} The resolved property value
862
- */
863
- const getAttr = (obj, name) => {
864
- if (!obj) return;
865
- return obj[name];
866
- };
867
- /**
868
- * A property getter resolving dot-notation
869
- * @param {Object} obj The root object to fetch property on
870
- * @param {String} name The optionally dotted property name to fetch
871
- * @return {Object} The resolved property value
872
- */
873
-
874
- const getAttrNesting = (obj, name) => {
875
- if (!obj) return;
876
- var part,
877
- names = name.split(".");
878
-
879
- while ((part = names.shift()) && (obj = obj[part]));
880
-
881
- return obj;
882
- };
883
- /**
884
- * Calculates how close of a match the
885
- * given value is against a search token.
886
- *
887
- */
888
-
889
- const scoreValue = (value, token, weight) => {
890
- var score, pos;
891
- if (!value) return 0;
892
- value = value + '';
893
- if (token.regex == null) return 0;
894
- pos = value.search(token.regex);
895
- if (pos === -1) return 0;
896
- score = token.string.length / value.length;
897
- if (pos === 0) score += 0.5;
898
- return score * weight;
899
- };
900
- /**
901
- * Cast object property to an array if it exists and has a value
902
- *
903
- */
904
-
905
- const propToArray = (obj, key) => {
906
- var value = obj[key];
907
- if (typeof value == 'function') return value;
908
-
909
- if (value && !Array.isArray(value)) {
910
- obj[key] = [value];
911
- }
912
- };
913
- /**
914
- * Iterates over arrays and hashes.
915
- *
916
- * ```
917
- * iterate(this.items, function(item, id) {
918
- * // invoked for each item
919
- * });
920
- * ```
921
- *
922
- */
923
-
924
- const iterate$1 = (object, callback) => {
925
- if (Array.isArray(object)) {
926
- object.forEach(callback);
927
- } else {
928
- for (var key in object) {
929
- if (object.hasOwnProperty(key)) {
930
- callback(object[key], key);
931
- }
932
- }
933
- }
934
- };
935
- const cmp = (a, b) => {
936
- if (typeof a === 'number' && typeof b === 'number') {
937
- return a > b ? 1 : a < b ? -1 : 0;
938
- }
939
-
940
- a = asciifold(a + '').toLowerCase();
941
- b = asciifold(b + '').toLowerCase();
942
- if (a > b) return 1;
943
- if (b > a) return -1;
944
- return 0;
945
- };
946
-
947
- /*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */
948
-
949
- /**
950
- * sifter.js
951
- * Copyright (c) 2013–2020 Brian Reavis & contributors
952
- *
953
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
954
- * file except in compliance with the License. You may obtain a copy of the License at:
955
- * http://www.apache.org/licenses/LICENSE-2.0
956
- *
957
- * Unless required by applicable law or agreed to in writing, software distributed under
958
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
959
- * ANY KIND, either express or implied. See the License for the specific language
960
- * governing permissions and limitations under the License.
961
- *
962
- * @author Brian Reavis <brian@thirdroute.com>
963
- */
964
-
965
- class Sifter {
966
- // []|{};
967
-
968
- /**
969
- * Textually searches arrays and hashes of objects
970
- * by property (or multiple properties). Designed
971
- * specifically for autocomplete.
972
- *
973
- */
974
- constructor(items, settings) {
975
- this.items = void 0;
976
- this.settings = void 0;
977
- this.items = items;
978
- this.settings = settings || {
979
- diacritics: true
980
- };
981
- }
982
-
983
- /**
984
- * Splits a search string into an array of individual
985
- * regexps to be used to match results.
986
- *
987
- */
988
- tokenize(query, respect_word_boundaries, weights) {
989
- if (!query || !query.length) return [];
990
- const tokens = [];
991
- const words = query.split(/\s+/);
992
- var field_regex;
993
-
994
- if (weights) {
995
- field_regex = new RegExp('^(' + Object.keys(weights).map(escape_regex).join('|') + ')\:(.*)$');
996
- }
997
-
998
- words.forEach(word => {
999
- let field_match;
1000
- let field = null;
1001
- let regex = null; // look for "field:query" tokens
1002
-
1003
- if (field_regex && (field_match = word.match(field_regex))) {
1004
- field = field_match[1];
1005
- word = field_match[2];
1006
- }
1007
-
1008
- if (word.length > 0) {
1009
- if (this.settings.diacritics) {
1010
- regex = getPattern(word) || null;
1011
- } else {
1012
- regex = escape_regex(word);
1013
- }
1014
-
1015
- if (regex && respect_word_boundaries) regex = "\\b" + regex;
1016
- }
1017
-
1018
- tokens.push({
1019
- string: word,
1020
- regex: regex ? new RegExp(regex, 'iu') : null,
1021
- field: field
1022
- });
1023
- });
1024
- return tokens;
1025
- }
1026
-
1027
- /**
1028
- * Returns a function to be used to score individual results.
1029
- *
1030
- * Good matches will have a higher score than poor matches.
1031
- * If an item is not a match, 0 will be returned by the function.
1032
- *
1033
- * @returns {T.ScoreFn}
1034
- */
1035
- getScoreFunction(query, options) {
1036
- var search = this.prepareSearch(query, options);
1037
- return this._getScoreFunction(search);
1038
- }
1039
- /**
1040
- * @returns {T.ScoreFn}
1041
- *
1042
- */
1043
-
1044
-
1045
- _getScoreFunction(search) {
1046
- const tokens = search.tokens,
1047
- token_count = tokens.length;
1048
-
1049
- if (!token_count) {
1050
- return function () {
1051
- return 0;
1052
- };
1053
- }
1054
-
1055
- const fields = search.options.fields,
1056
- weights = search.weights,
1057
- field_count = fields.length,
1058
- getAttrFn = search.getAttrFn;
1059
-
1060
- if (!field_count) {
1061
- return function () {
1062
- return 1;
1063
- };
1064
- }
1065
- /**
1066
- * Calculates the score of an object
1067
- * against the search query.
1068
- *
1069
- */
1070
-
1071
-
1072
- const scoreObject = function () {
1073
- if (field_count === 1) {
1074
- return function (token, data) {
1075
- const field = fields[0].field;
1076
- return scoreValue(getAttrFn(data, field), token, weights[field] || 1);
1077
- };
1078
- }
1079
-
1080
- return function (token, data) {
1081
- var sum = 0; // is the token specific to a field?
1082
-
1083
- if (token.field) {
1084
- const value = getAttrFn(data, token.field);
1085
-
1086
- if (!token.regex && value) {
1087
- sum += 1 / field_count;
1088
- } else {
1089
- sum += scoreValue(value, token, 1);
1090
- }
1091
- } else {
1092
- iterate$1(weights, (weight, field) => {
1093
- sum += scoreValue(getAttrFn(data, field), token, weight);
1094
- });
1095
- }
1096
-
1097
- return sum / field_count;
1098
- };
1099
- }();
1100
-
1101
- if (token_count === 1) {
1102
- return function (data) {
1103
- return scoreObject(tokens[0], data);
1104
- };
1105
- }
1106
-
1107
- if (search.options.conjunction === 'and') {
1108
- return function (data) {
1109
- var score,
1110
- sum = 0;
1111
-
1112
- for (let token of tokens) {
1113
- score = scoreObject(token, data);
1114
- if (score <= 0) return 0;
1115
- sum += score;
1116
- }
1117
-
1118
- return sum / token_count;
1119
- };
1120
- } else {
1121
- return function (data) {
1122
- var sum = 0;
1123
- iterate$1(tokens, token => {
1124
- sum += scoreObject(token, data);
1125
- });
1126
- return sum / token_count;
1127
- };
1128
- }
1129
- }
1130
-
1131
- /**
1132
- * Returns a function that can be used to compare two
1133
- * results, for sorting purposes. If no sorting should
1134
- * be performed, `null` will be returned.
1135
- *
1136
- * @return function(a,b)
1137
- */
1138
- getSortFunction(query, options) {
1139
- var search = this.prepareSearch(query, options);
1140
- return this._getSortFunction(search);
1141
- }
1142
-
1143
- _getSortFunction(search) {
1144
- var implicit_score,
1145
- sort_flds = [];
1146
- const self = this,
1147
- options = search.options,
1148
- sort = !search.query && options.sort_empty ? options.sort_empty : options.sort;
1149
-
1150
- if (typeof sort == 'function') {
1151
- return sort.bind(this);
1152
- }
1153
- /**
1154
- * Fetches the specified sort field value
1155
- * from a search result item.
1156
- *
1157
- */
1158
-
1159
-
1160
- const get_field = function get_field(name, result) {
1161
- if (name === '$score') return result.score;
1162
- return search.getAttrFn(self.items[result.id], name);
1163
- }; // parse options
1164
-
1165
-
1166
- if (sort) {
1167
- for (let s of sort) {
1168
- if (search.query || s.field !== '$score') {
1169
- sort_flds.push(s);
1170
- }
1171
- }
1172
- } // the "$score" field is implied to be the primary
1173
- // sort field, unless it's manually specified
1174
-
1175
-
1176
- if (search.query) {
1177
- implicit_score = true;
1178
-
1179
- for (let fld of sort_flds) {
1180
- if (fld.field === '$score') {
1181
- implicit_score = false;
1182
- break;
1183
- }
1184
- }
1185
-
1186
- if (implicit_score) {
1187
- sort_flds.unshift({
1188
- field: '$score',
1189
- direction: 'desc'
1190
- });
1191
- } // without a search.query, all items will have the same score
1192
-
1193
- } else {
1194
- sort_flds = sort_flds.filter(fld => fld.field !== '$score');
1195
- } // build function
1196
-
1197
-
1198
- const sort_flds_count = sort_flds.length;
1199
-
1200
- if (!sort_flds_count) {
1201
- return null;
1202
- }
1203
-
1204
- return function (a, b) {
1205
- var result, field;
1206
-
1207
- for (let sort_fld of sort_flds) {
1208
- field = sort_fld.field;
1209
- let multiplier = sort_fld.direction === 'desc' ? -1 : 1;
1210
- result = multiplier * cmp(get_field(field, a), get_field(field, b));
1211
- if (result) return result;
1212
- }
1213
-
1214
- return 0;
1215
- };
1216
- }
1217
-
1218
- /**
1219
- * Parses a search query and returns an object
1220
- * with tokens and fields ready to be populated
1221
- * with results.
1222
- *
1223
- */
1224
- prepareSearch(query, optsUser) {
1225
- const weights = {};
1226
- var options = Object.assign({}, optsUser);
1227
- propToArray(options, 'sort');
1228
- propToArray(options, 'sort_empty'); // convert fields to new format
1229
-
1230
- if (options.fields) {
1231
- propToArray(options, 'fields');
1232
- const fields = [];
1233
- options.fields.forEach(field => {
1234
- if (typeof field == 'string') {
1235
- field = {
1236
- field: field,
1237
- weight: 1
1238
- };
1239
- }
1240
-
1241
- fields.push(field);
1242
- weights[field.field] = 'weight' in field ? field.weight : 1;
1243
- });
1244
- options.fields = fields;
1245
- }
1246
-
1247
- return {
1248
- options: options,
1249
- query: query.toLowerCase().trim(),
1250
- tokens: this.tokenize(query, options.respect_word_boundaries, weights),
1251
- total: 0,
1252
- items: [],
1253
- weights: weights,
1254
- getAttrFn: options.nesting ? getAttrNesting : getAttr
1255
- };
1256
- }
1257
-
1258
- /**
1259
- * Searches through all items and returns a sorted array of matches.
1260
- *
1261
- */
1262
- search(query, options) {
1263
- var self = this,
1264
- score,
1265
- search;
1266
- search = this.prepareSearch(query, options);
1267
- options = search.options;
1268
- query = search.query; // generate result scoring function
1269
-
1270
- const fn_score = options.score || self._getScoreFunction(search); // perform search and sort
1271
-
1272
-
1273
- if (query.length) {
1274
- iterate$1(self.items, (item, id) => {
1275
- score = fn_score(item);
1276
-
1277
- if (options.filter === false || score > 0) {
1278
- search.items.push({
1279
- 'score': score,
1280
- 'id': id
1281
- });
1282
- }
1283
- });
1284
- } else {
1285
- iterate$1(self.items, (_, id) => {
1286
- search.items.push({
1287
- 'score': 1,
1288
- 'id': id
1289
- });
1290
- });
1291
- }
1292
-
1293
- const fn_sort = self._getSortFunction(search);
1294
-
1295
- if (fn_sort) search.items.sort(fn_sort); // apply limits
1296
-
1297
- search.total = search.items.length;
1298
-
1299
- if (typeof options.limit === 'number') {
1300
- search.items = search.items.slice(0, options.limit);
1301
- }
1302
-
1303
- return search;
1304
- }
1305
-
1306
- }
1307
-
1308
- /**
1309
- * Iterates over arrays and hashes.
1310
- *
1311
- * ```
1312
- * iterate(this.items, function(item, id) {
1313
- * // invoked for each item
1314
- * });
1315
- * ```
1316
- *
1317
- */
1318
-
1319
- const iterate = (object, callback) => {
1320
- if (Array.isArray(object)) {
1321
- object.forEach(callback);
1322
- } else {
1323
- for (var key in object) {
1324
- if (object.hasOwnProperty(key)) {
1325
- callback(object[key], key);
1326
- }
1327
- }
1328
- }
1329
- };
1330
-
1331
- /**
1332
- * Return a dom element from either a dom query string, jQuery object, a dom element or html string
1333
- * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
1334
- *
1335
- * param query should be {}
1336
- */
1337
-
1338
- const getDom = query => {
1339
- if (query.jquery) {
1340
- return query[0];
1341
- }
1342
-
1343
- if (query instanceof HTMLElement) {
1344
- return query;
1345
- }
1346
-
1347
- if (isHtmlString(query)) {
1348
- var tpl = document.createElement('template');
1349
- tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
1350
-
1351
- return tpl.content.firstChild;
1352
- }
1353
-
1354
- return document.querySelector(query);
1355
- };
1356
- const isHtmlString = arg => {
1357
- if (typeof arg === 'string' && arg.indexOf('<') > -1) {
1358
- return true;
1359
- }
1360
-
1361
- return false;
1362
- };
1363
- const escapeQuery = query => {
1364
- return query.replace(/['"\\]/g, '\\$&');
1365
- };
1366
- /**
1367
- * Dispatch an event
1368
- *
1369
- */
1370
-
1371
- const triggerEvent = (dom_el, event_name) => {
1372
- var event = document.createEvent('HTMLEvents');
1373
- event.initEvent(event_name, true, false);
1374
- dom_el.dispatchEvent(event);
1375
- };
1376
- /**
1377
- * Apply CSS rules to a dom element
1378
- *
1379
- */
1380
-
1381
- const applyCSS = (dom_el, css) => {
1382
- Object.assign(dom_el.style, css);
1383
- };
1384
- /**
1385
- * Add css classes
1386
- *
1387
- */
1388
-
1389
- const addClasses = (elmts, ...classes) => {
1390
- var norm_classes = classesArray(classes);
1391
- elmts = castAsArray(elmts);
1392
- elmts.map(el => {
1393
- norm_classes.map(cls => {
1394
- el.classList.add(cls);
1395
- });
1396
- });
1397
- };
1398
- /**
1399
- * Remove css classes
1400
- *
1401
- */
1402
-
1403
- const removeClasses = (elmts, ...classes) => {
1404
- var norm_classes = classesArray(classes);
1405
- elmts = castAsArray(elmts);
1406
- elmts.map(el => {
1407
- norm_classes.map(cls => {
1408
- el.classList.remove(cls);
1409
- });
1410
- });
1411
- };
1412
- /**
1413
- * Return arguments
1414
- *
1415
- */
1416
-
1417
- const classesArray = args => {
1418
- var classes = [];
1419
- iterate(args, _classes => {
1420
- if (typeof _classes === 'string') {
1421
- _classes = _classes.trim().split(/[\11\12\14\15\40]/);
1422
- }
1423
-
1424
- if (Array.isArray(_classes)) {
1425
- classes = classes.concat(_classes);
1426
- }
1427
- });
1428
- return classes.filter(Boolean);
1429
- };
1430
- /**
1431
- * Create an array from arg if it's not already an array
1432
- *
1433
- */
1434
-
1435
- const castAsArray = arg => {
1436
- if (!Array.isArray(arg)) {
1437
- arg = [arg];
1438
- }
1439
-
1440
- return arg;
1441
- };
1442
- /**
1443
- * Get the closest node to the evt.target matching the selector
1444
- * Stops at wrapper
1445
- *
1446
- */
1447
-
1448
- const parentMatch = (target, selector, wrapper) => {
1449
- if (wrapper && !wrapper.contains(target)) {
1450
- return;
1451
- }
1452
-
1453
- while (target && target.matches) {
1454
- if (target.matches(selector)) {
1455
- return target;
1456
- }
1457
-
1458
- target = target.parentNode;
1459
- }
1460
- };
1461
- /**
1462
- * Get the first or last item from an array
1463
- *
1464
- * > 0 - right (last)
1465
- * <= 0 - left (first)
1466
- *
1467
- */
1468
-
1469
- const getTail = (list, direction = 0) => {
1470
- if (direction > 0) {
1471
- return list[list.length - 1];
1472
- }
1473
-
1474
- return list[0];
1475
- };
1476
- /**
1477
- * Return true if an object is empty
1478
- *
1479
- */
1480
-
1481
- const isEmptyObject = obj => {
1482
- return Object.keys(obj).length === 0;
1483
- };
1484
- /**
1485
- * Get the index of an element amongst sibling nodes of the same type
1486
- *
1487
- */
1488
-
1489
- const nodeIndex = (el, amongst) => {
1490
- if (!el) return -1;
1491
- amongst = amongst || el.nodeName;
1492
- var i = 0;
1493
-
1494
- while (el = el.previousElementSibling) {
1495
- if (el.matches(amongst)) {
1496
- i++;
1497
- }
1498
- }
1499
-
1500
- return i;
1501
- };
1502
- /**
1503
- * Set attributes of an element
1504
- *
1505
- */
1506
-
1507
- const setAttr = (el, attrs) => {
1508
- iterate(attrs, (val, attr) => {
1509
- if (val == null) {
1510
- el.removeAttribute(attr);
1511
- } else {
1512
- el.setAttribute(attr, '' + val);
1513
- }
1514
- });
1515
- };
1516
- /**
1517
- * Replace a node
1518
- */
1519
-
1520
- const replaceNode = (existing, replacement) => {
1521
- if (existing.parentNode) existing.parentNode.replaceChild(replacement, existing);
1522
- };
1523
-
1524
- /**
1525
- * highlight v3 | MIT license | Johann Burkard <jb@eaio.com>
1526
- * Highlights arbitrary terms in a node.
1527
- *
1528
- * - Modified by Marshal <beatgates@gmail.com> 2011-6-24 (added regex)
1529
- * - Modified by Brian Reavis <brian@thirdroute.com> 2012-8-27 (cleanup)
1530
- */
1531
- const highlight = (element, regex) => {
1532
- if (regex === null) return; // convet string to regex
1533
-
1534
- if (typeof regex === 'string') {
1535
- if (!regex.length) return;
1536
- regex = new RegExp(regex, 'i');
1537
- } // Wrap matching part of text node with highlighting <span>, e.g.
1538
- // Soccer -> <span class="highlight">Soc</span>cer for regex = /soc/i
1539
-
1540
-
1541
- const highlightText = node => {
1542
- var match = node.data.match(regex);
1543
-
1544
- if (match && node.data.length > 0) {
1545
- var spannode = document.createElement('span');
1546
- spannode.className = 'highlight';
1547
- var middlebit = node.splitText(match.index);
1548
- middlebit.splitText(match[0].length);
1549
- var middleclone = middlebit.cloneNode(true);
1550
- spannode.appendChild(middleclone);
1551
- replaceNode(middlebit, spannode);
1552
- return 1;
1553
- }
1554
-
1555
- return 0;
1556
- }; // Recurse element node, looking for child text nodes to highlight, unless element
1557
- // is childless, <script>, <style>, or already highlighted: <span class="hightlight">
1558
-
1559
-
1560
- const highlightChildren = node => {
1561
- if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {
1562
- Array.from(node.childNodes).forEach(element => {
1563
- highlightRecursive(element);
1564
- });
1565
- }
1566
- };
1567
-
1568
- const highlightRecursive = node => {
1569
- if (node.nodeType === 3) {
1570
- return highlightText(node);
1571
- }
1572
-
1573
- highlightChildren(node);
1574
- return 0;
1575
- };
1576
-
1577
- highlightRecursive(element);
1578
- };
1579
- /**
1580
- * removeHighlight fn copied from highlight v5 and
1581
- * edited to remove with(), pass js strict mode, and use without jquery
1582
- */
1583
-
1584
- const removeHighlight = el => {
1585
- var elements = el.querySelectorAll("span.highlight");
1586
- Array.prototype.forEach.call(elements, function (el) {
1587
- var parent = el.parentNode;
1588
- parent.replaceChild(el.firstChild, el);
1589
- parent.normalize();
1590
- });
1591
- };
1592
-
1593
- const KEY_A = 65;
1594
- const KEY_RETURN = 13;
1595
- const KEY_ESC = 27;
1596
- const KEY_LEFT = 37;
1597
- const KEY_UP = 38;
1598
- const KEY_RIGHT = 39;
1599
- const KEY_DOWN = 40;
1600
- const KEY_BACKSPACE = 8;
1601
- const KEY_DELETE = 46;
1602
- const KEY_TAB = 9;
1603
- const IS_MAC = typeof navigator === 'undefined' ? false : /Mac/.test(navigator.userAgent);
1604
- const KEY_SHORTCUT = IS_MAC ? 'metaKey' : 'ctrlKey'; // ctrl key or apple key for ma
1605
-
1606
- var defaults = {
1607
- options: [],
1608
- optgroups: [],
1609
- plugins: [],
1610
- delimiter: ',',
1611
- splitOn: null,
1612
- // regexp or string for splitting up values from a paste command
1613
- persist: true,
1614
- diacritics: true,
1615
- create: null,
1616
- createOnBlur: false,
1617
- createFilter: null,
1618
- highlight: true,
1619
- openOnFocus: true,
1620
- shouldOpen: null,
1621
- maxOptions: 50,
1622
- maxItems: null,
1623
- hideSelected: null,
1624
- duplicates: false,
1625
- addPrecedence: false,
1626
- selectOnTab: false,
1627
- preload: null,
1628
- allowEmptyOption: false,
1629
- //closeAfterSelect: false,
1630
- loadThrottle: 300,
1631
- loadingClass: 'loading',
1632
- dataAttr: null,
1633
- //'data-data',
1634
- optgroupField: 'optgroup',
1635
- valueField: 'value',
1636
- labelField: 'text',
1637
- disabledField: 'disabled',
1638
- optgroupLabelField: 'label',
1639
- optgroupValueField: 'value',
1640
- lockOptgroupOrder: false,
1641
- sortField: '$order',
1642
- searchField: ['text'],
1643
- searchConjunction: 'and',
1644
- mode: null,
1645
- wrapperClass: 'ts-wrapper',
1646
- controlClass: 'ts-control',
1647
- dropdownClass: 'ts-dropdown',
1648
- dropdownContentClass: 'ts-dropdown-content',
1649
- itemClass: 'item',
1650
- optionClass: 'option',
1651
- dropdownParent: null,
1652
- controlInput: '<input type="text" autocomplete="off" size="1" />',
1653
- copyClassesToDropdown: false,
1654
- placeholder: null,
1655
- hidePlaceholder: null,
1656
- shouldLoad: function (query) {
1657
- return query.length > 0;
1658
- },
1659
-
1660
- /*
1661
- load : null, // function(query, callback) { ... }
1662
- score : null, // function(search) { ... }
1663
- onInitialize : null, // function() { ... }
1664
- onChange : null, // function(value) { ... }
1665
- onItemAdd : null, // function(value, $item) { ... }
1666
- onItemRemove : null, // function(value) { ... }
1667
- onClear : null, // function() { ... }
1668
- onOptionAdd : null, // function(value, data) { ... }
1669
- onOptionRemove : null, // function(value) { ... }
1670
- onOptionClear : null, // function() { ... }
1671
- onOptionGroupAdd : null, // function(id, data) { ... }
1672
- onOptionGroupRemove : null, // function(id) { ... }
1673
- onOptionGroupClear : null, // function() { ... }
1674
- onDropdownOpen : null, // function(dropdown) { ... }
1675
- onDropdownClose : null, // function(dropdown) { ... }
1676
- onType : null, // function(str) { ... }
1677
- onDelete : null, // function(values) { ... }
1678
- */
1679
- render: {
1680
- /*
1681
- item: null,
1682
- optgroup: null,
1683
- optgroup_header: null,
1684
- option: null,
1685
- option_create: null
1686
- */
1687
- }
1688
- };
1689
-
1690
- /**
1691
- * Converts a scalar to its best string representation
1692
- * for hash keys and HTML attribute values.
1693
- *
1694
- * Transformations:
1695
- * 'str' -> 'str'
1696
- * null -> ''
1697
- * undefined -> ''
1698
- * true -> '1'
1699
- * false -> '0'
1700
- * 0 -> '0'
1701
- * 1 -> '1'
1702
- *
1703
- */
1704
- const hash_key = value => {
1705
- if (typeof value === 'undefined' || value === null) return null;
1706
- return get_hash(value);
1707
- };
1708
- const get_hash = value => {
1709
- if (typeof value === 'boolean') return value ? '1' : '0';
1710
- return value + '';
1711
- };
1712
- /**
1713
- * Escapes a string for use within HTML.
1714
- *
1715
- */
1716
-
1717
- const escape_html = str => {
1718
- return (str + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1719
- };
1720
- /**
1721
- * Debounce the user provided load function
1722
- *
1723
- */
1724
-
1725
- const loadDebounce = (fn, delay) => {
1726
- var timeout;
1727
- return function (value, callback) {
1728
- var self = this;
1729
-
1730
- if (timeout) {
1731
- self.loading = Math.max(self.loading - 1, 0);
1732
- clearTimeout(timeout);
1733
- }
1734
-
1735
- timeout = setTimeout(function () {
1736
- timeout = null;
1737
- self.loadedSearches[value] = true;
1738
- fn.call(self, value, callback);
1739
- }, delay);
1740
- };
1741
- };
1742
- /**
1743
- * Debounce all fired events types listed in `types`
1744
- * while executing the provided `fn`.
1745
- *
1746
- */
1747
-
1748
- const debounce_events = (self, types, fn) => {
1749
- var type;
1750
- var trigger = self.trigger;
1751
- var event_args = {}; // override trigger method
1752
-
1753
- self.trigger = function () {
1754
- var type = arguments[0];
1755
-
1756
- if (types.indexOf(type) !== -1) {
1757
- event_args[type] = arguments;
1758
- } else {
1759
- return trigger.apply(self, arguments);
1760
- }
1761
- }; // invoke provided function
1762
-
1763
-
1764
- fn.apply(self, []);
1765
- self.trigger = trigger; // trigger queued events
1766
-
1767
- for (type of types) {
1768
- if (type in event_args) {
1769
- trigger.apply(self, event_args[type]);
1770
- }
1771
- }
1772
- };
1773
- /**
1774
- * Determines the current selection within a text input control.
1775
- * Returns an object containing:
1776
- * - start
1777
- * - length
1778
- *
1779
- */
1780
-
1781
- const getSelection = input => {
1782
- return {
1783
- start: input.selectionStart || 0,
1784
- length: (input.selectionEnd || 0) - (input.selectionStart || 0)
1785
- };
1786
- };
1787
- /**
1788
- * Prevent default
1789
- *
1790
- */
1791
-
1792
- const preventDefault = (evt, stop = false) => {
1793
- if (evt) {
1794
- evt.preventDefault();
1795
-
1796
- if (stop) {
1797
- evt.stopPropagation();
1798
- }
1799
- }
1800
- };
1801
- /**
1802
- * Add event helper
1803
- *
1804
- */
1805
-
1806
- const addEvent = (target, type, callback, options) => {
1807
- target.addEventListener(type, callback, options);
1808
- };
1809
- /**
1810
- * Return true if the requested key is down
1811
- * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )
1812
- * The current evt may not always set ( eg calling advanceSelection() )
1813
- *
1814
- */
1815
-
1816
- const isKeyDown = (key_name, evt) => {
1817
- if (!evt) {
1818
- return false;
1819
- }
1820
-
1821
- if (!evt[key_name]) {
1822
- return false;
1823
- }
1824
-
1825
- var count = (evt.altKey ? 1 : 0) + (evt.ctrlKey ? 1 : 0) + (evt.shiftKey ? 1 : 0) + (evt.metaKey ? 1 : 0);
1826
-
1827
- if (count === 1) {
1828
- return true;
1829
- }
1830
-
1831
- return false;
1832
- };
1833
- /**
1834
- * Get the id of an element
1835
- * If the id attribute is not set, set the attribute with the given id
1836
- *
1837
- */
1838
-
1839
- const getId = (el, id) => {
1840
- const existing_id = el.getAttribute('id');
1841
-
1842
- if (existing_id) {
1843
- return existing_id;
1844
- }
1845
-
1846
- el.setAttribute('id', id);
1847
- return id;
1848
- };
1849
- /**
1850
- * Returns a string with backslashes added before characters that need to be escaped.
1851
- */
1852
-
1853
- const addSlashes = str => {
1854
- return str.replace(/[\\"']/g, '\\$&');
1855
- };
1856
- /**
1857
- *
1858
- */
1859
-
1860
- const append = (parent, node) => {
1861
- if (node) parent.append(node);
1862
- };
1863
-
1864
- function getSettings(input, settings_user) {
1865
- var settings = Object.assign({}, defaults, settings_user);
1866
- var attr_data = settings.dataAttr;
1867
- var field_label = settings.labelField;
1868
- var field_value = settings.valueField;
1869
- var field_disabled = settings.disabledField;
1870
- var field_optgroup = settings.optgroupField;
1871
- var field_optgroup_label = settings.optgroupLabelField;
1872
- var field_optgroup_value = settings.optgroupValueField;
1873
- var tag_name = input.tagName.toLowerCase();
1874
- var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');
1875
-
1876
- if (!placeholder && !settings.allowEmptyOption) {
1877
- let option = input.querySelector('option[value=""]');
1878
-
1879
- if (option) {
1880
- placeholder = option.textContent;
1881
- }
1882
- }
1883
-
1884
- var settings_element = {
1885
- placeholder: placeholder,
1886
- options: [],
1887
- optgroups: [],
1888
- items: [],
1889
- maxItems: null
1890
- };
1891
- /**
1892
- * Initialize from a <select> element.
1893
- *
1894
- */
1895
-
1896
- var init_select = () => {
1897
- var tagName;
1898
- var options = settings_element.options;
1899
- var optionsMap = {};
1900
- var group_count = 1;
1901
-
1902
- var readData = el => {
1903
- var data = Object.assign({}, el.dataset); // get plain object from DOMStringMap
1904
-
1905
- var json = attr_data && data[attr_data];
1906
-
1907
- if (typeof json === 'string' && json.length) {
1908
- data = Object.assign(data, JSON.parse(json));
1909
- }
1910
-
1911
- return data;
1912
- };
1913
-
1914
- var addOption = (option, group) => {
1915
- var value = hash_key(option.value);
1916
- if (value == null) return;
1917
- if (!value && !settings.allowEmptyOption) return; // if the option already exists, it's probably been
1918
- // duplicated in another optgroup. in this case, push
1919
- // the current group to the "optgroup" property on the
1920
- // existing option so that it's rendered in both places.
1921
-
1922
- if (optionsMap.hasOwnProperty(value)) {
1923
- if (group) {
1924
- var arr = optionsMap[value][field_optgroup];
1925
-
1926
- if (!arr) {
1927
- optionsMap[value][field_optgroup] = group;
1928
- } else if (!Array.isArray(arr)) {
1929
- optionsMap[value][field_optgroup] = [arr, group];
1930
- } else {
1931
- arr.push(group);
1932
- }
1933
- }
1934
- } else {
1935
- var option_data = readData(option);
1936
- option_data[field_label] = option_data[field_label] || option.textContent;
1937
- option_data[field_value] = option_data[field_value] || value;
1938
- option_data[field_disabled] = option_data[field_disabled] || option.disabled;
1939
- option_data[field_optgroup] = option_data[field_optgroup] || group;
1940
- option_data.$option = option;
1941
- optionsMap[value] = option_data;
1942
- options.push(option_data);
1943
- }
1944
-
1945
- if (option.selected) {
1946
- settings_element.items.push(value);
1947
- }
1948
- };
1949
-
1950
- var addGroup = optgroup => {
1951
- var id, optgroup_data;
1952
- optgroup_data = readData(optgroup);
1953
- optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';
1954
- optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;
1955
- optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;
1956
- settings_element.optgroups.push(optgroup_data);
1957
- id = optgroup_data[field_optgroup_value];
1958
- iterate(optgroup.children, option => {
1959
- addOption(option, id);
1960
- });
1961
- };
1962
-
1963
- settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;
1964
- iterate(input.children, child => {
1965
- tagName = child.tagName.toLowerCase();
1966
-
1967
- if (tagName === 'optgroup') {
1968
- addGroup(child);
1969
- } else if (tagName === 'option') {
1970
- addOption(child);
1971
- }
1972
- });
1973
- };
1974
- /**
1975
- * Initialize from a <input type="text"> element.
1976
- *
1977
- */
1978
-
1979
-
1980
- var init_textbox = () => {
1981
- const data_raw = input.getAttribute(attr_data);
1982
-
1983
- if (!data_raw) {
1984
- var value = input.value.trim() || '';
1985
- if (!settings.allowEmptyOption && !value.length) return;
1986
- const values = value.split(settings.delimiter);
1987
- iterate(values, value => {
1988
- const option = {};
1989
- option[field_label] = value;
1990
- option[field_value] = value;
1991
- settings_element.options.push(option);
1992
- });
1993
- settings_element.items = values;
1994
- } else {
1995
- settings_element.options = JSON.parse(data_raw);
1996
- iterate(settings_element.options, opt => {
1997
- settings_element.items.push(opt[field_value]);
1998
- });
1999
- }
2000
- };
2001
-
2002
- if (tag_name === 'select') {
2003
- init_select();
2004
- } else {
2005
- init_textbox();
2006
- }
2007
-
2008
- return Object.assign({}, defaults, settings_element, settings_user);
2009
- }
2010
-
2011
- var instance_i = 0;
2012
- class TomSelect extends MicroPlugin(MicroEvent) {
2013
- // @deprecated 1.8
2014
- constructor(input_arg, user_settings) {
2015
- super();
2016
- this.control_input = void 0;
2017
- this.wrapper = void 0;
2018
- this.dropdown = void 0;
2019
- this.control = void 0;
2020
- this.dropdown_content = void 0;
2021
- this.focus_node = void 0;
2022
- this.order = 0;
2023
- this.settings = void 0;
2024
- this.input = void 0;
2025
- this.tabIndex = void 0;
2026
- this.is_select_tag = void 0;
2027
- this.rtl = void 0;
2028
- this.inputId = void 0;
2029
- this._destroy = void 0;
2030
- this.sifter = void 0;
2031
- this.isOpen = false;
2032
- this.isDisabled = false;
2033
- this.isRequired = void 0;
2034
- this.isInvalid = false;
2035
- this.isValid = true;
2036
- this.isLocked = false;
2037
- this.isFocused = false;
2038
- this.isInputHidden = false;
2039
- this.isSetup = false;
2040
- this.ignoreFocus = false;
2041
- this.ignoreHover = false;
2042
- this.hasOptions = false;
2043
- this.currentResults = void 0;
2044
- this.lastValue = '';
2045
- this.caretPos = 0;
2046
- this.loading = 0;
2047
- this.loadedSearches = {};
2048
- this.activeOption = null;
2049
- this.activeItems = [];
2050
- this.optgroups = {};
2051
- this.options = {};
2052
- this.userOptions = {};
2053
- this.items = [];
2054
- instance_i++;
2055
- var dir;
2056
- var input = getDom(input_arg);
2057
-
2058
- if (input.tomselect) {
2059
- throw new Error('Tom Select already initialized on this element');
2060
- }
2061
-
2062
- input.tomselect = this; // detect rtl environment
2063
-
2064
- var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);
2065
- dir = computedStyle.getPropertyValue('direction'); // setup default state
2066
-
2067
- const settings = getSettings(input, user_settings);
2068
- this.settings = settings;
2069
- this.input = input;
2070
- this.tabIndex = input.tabIndex || 0;
2071
- this.is_select_tag = input.tagName.toLowerCase() === 'select';
2072
- this.rtl = /rtl/i.test(dir);
2073
- this.inputId = getId(input, 'tomselect-' + instance_i);
2074
- this.isRequired = input.required; // search system
2075
-
2076
- this.sifter = new Sifter(this.options, {
2077
- diacritics: settings.diacritics
2078
- }); // option-dependent defaults
2079
-
2080
- settings.mode = settings.mode || (settings.maxItems === 1 ? 'single' : 'multi');
2081
-
2082
- if (typeof settings.hideSelected !== 'boolean') {
2083
- settings.hideSelected = settings.mode === 'multi';
2084
- }
2085
-
2086
- if (typeof settings.hidePlaceholder !== 'boolean') {
2087
- settings.hidePlaceholder = settings.mode !== 'multi';
2088
- } // set up createFilter callback
2089
-
2090
-
2091
- var filter = settings.createFilter;
2092
-
2093
- if (typeof filter !== 'function') {
2094
- if (typeof filter === 'string') {
2095
- filter = new RegExp(filter);
2096
- }
2097
-
2098
- if (filter instanceof RegExp) {
2099
- settings.createFilter = input => filter.test(input);
2100
- } else {
2101
- settings.createFilter = value => {
2102
- return this.settings.duplicates || !this.options[value];
2103
- };
2104
- }
2105
- }
2106
-
2107
- this.initializePlugins(settings.plugins);
2108
- this.setupCallbacks();
2109
- this.setupTemplates(); // Create all elements
2110
-
2111
- const wrapper = getDom('<div>');
2112
- const control = getDom('<div>');
2113
-
2114
- const dropdown = this._render('dropdown');
2115
-
2116
- const dropdown_content = getDom(`<div role="listbox" tabindex="-1">`);
2117
- const classes = this.input.getAttribute('class') || '';
2118
- const inputMode = settings.mode;
2119
- var control_input;
2120
- addClasses(wrapper, settings.wrapperClass, classes, inputMode);
2121
- addClasses(control, settings.controlClass);
2122
- append(wrapper, control);
2123
- addClasses(dropdown, settings.dropdownClass, inputMode);
2124
-
2125
- if (settings.copyClassesToDropdown) {
2126
- addClasses(dropdown, classes);
2127
- }
2128
-
2129
- addClasses(dropdown_content, settings.dropdownContentClass);
2130
- append(dropdown, dropdown_content);
2131
- getDom(settings.dropdownParent || wrapper).appendChild(dropdown); // default controlInput
2132
-
2133
- if (isHtmlString(settings.controlInput)) {
2134
- control_input = getDom(settings.controlInput); // set attributes
2135
-
2136
- var attrs = ['autocorrect', 'autocapitalize', 'autocomplete'];
2137
- iterate$1(attrs, attr => {
2138
- if (input.getAttribute(attr)) {
2139
- setAttr(control_input, {
2140
- [attr]: input.getAttribute(attr)
2141
- });
2142
- }
2143
- });
2144
- control_input.tabIndex = -1;
2145
- control.appendChild(control_input);
2146
- this.focus_node = control_input; // dom element
2147
- } else if (settings.controlInput) {
2148
- control_input = getDom(settings.controlInput);
2149
- this.focus_node = control_input;
2150
- } else {
2151
- control_input = getDom('<input/>');
2152
- this.focus_node = control;
2153
- }
2154
-
2155
- this.wrapper = wrapper;
2156
- this.dropdown = dropdown;
2157
- this.dropdown_content = dropdown_content;
2158
- this.control = control;
2159
- this.control_input = control_input;
2160
- this.setup();
2161
- }
2162
- /**
2163
- * set up event bindings.
2164
- *
2165
- */
2166
-
2167
-
2168
- setup() {
2169
- const self = this;
2170
- const settings = self.settings;
2171
- const control_input = self.control_input;
2172
- const dropdown = self.dropdown;
2173
- const dropdown_content = self.dropdown_content;
2174
- const wrapper = self.wrapper;
2175
- const control = self.control;
2176
- const input = self.input;
2177
- const focus_node = self.focus_node;
2178
- const passive_event = {
2179
- passive: true
2180
- };
2181
- const listboxId = self.inputId + '-ts-dropdown';
2182
- setAttr(dropdown_content, {
2183
- id: listboxId
2184
- });
2185
- setAttr(focus_node, {
2186
- role: 'combobox',
2187
- 'aria-haspopup': 'listbox',
2188
- 'aria-expanded': 'false',
2189
- 'aria-controls': listboxId
2190
- });
2191
- const control_id = getId(focus_node, self.inputId + '-ts-control');
2192
- const query = "label[for='" + escapeQuery(self.inputId) + "']";
2193
- const label = document.querySelector(query);
2194
- const label_click = self.focus.bind(self);
2195
-
2196
- if (label) {
2197
- addEvent(label, 'click', label_click);
2198
- setAttr(label, {
2199
- for: control_id
2200
- });
2201
- const label_id = getId(label, self.inputId + '-ts-label');
2202
- setAttr(focus_node, {
2203
- 'aria-labelledby': label_id
2204
- });
2205
- setAttr(dropdown_content, {
2206
- 'aria-labelledby': label_id
2207
- });
2208
- }
2209
-
2210
- wrapper.style.width = input.style.width;
2211
-
2212
- if (self.plugins.names.length) {
2213
- const classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');
2214
- addClasses([wrapper, dropdown], classes_plugins);
2215
- }
2216
-
2217
- if ((settings.maxItems === null || settings.maxItems > 1) && self.is_select_tag) {
2218
- setAttr(input, {
2219
- multiple: 'multiple'
2220
- });
2221
- }
2222
-
2223
- if (settings.placeholder) {
2224
- setAttr(control_input, {
2225
- placeholder: settings.placeholder
2226
- });
2227
- } // if splitOn was not passed in, construct it from the delimiter to allow pasting universally
2228
-
2229
-
2230
- if (!settings.splitOn && settings.delimiter) {
2231
- settings.splitOn = new RegExp('\\s*' + escape_regex(settings.delimiter) + '+\\s*');
2232
- } // debounce user defined load() if loadThrottle > 0
2233
- // after initializePlugins() so plugins can create/modify user defined loaders
2234
-
2235
-
2236
- if (settings.load && settings.loadThrottle) {
2237
- settings.load = loadDebounce(settings.load, settings.loadThrottle);
2238
- }
2239
-
2240
- self.control_input.type = input.type;
2241
- addEvent(dropdown, 'mousemove', () => {
2242
- self.ignoreHover = false;
2243
- });
2244
- addEvent(dropdown, 'mouseenter', e => {
2245
- var target_match = parentMatch(e.target, '[data-selectable]', dropdown);
2246
- if (target_match) self.onOptionHover(e, target_match);
2247
- }, {
2248
- capture: true
2249
- }); // clicking on an option should select it
2250
-
2251
- addEvent(dropdown, 'click', evt => {
2252
- const option = parentMatch(evt.target, '[data-selectable]');
2253
-
2254
- if (option) {
2255
- self.onOptionSelect(evt, option);
2256
- preventDefault(evt, true);
2257
- }
2258
- });
2259
- addEvent(control, 'click', evt => {
2260
- var target_match = parentMatch(evt.target, '[data-ts-item]', control);
2261
-
2262
- if (target_match && self.onItemSelect(evt, target_match)) {
2263
- preventDefault(evt, true);
2264
- return;
2265
- } // retain focus (see control_input mousedown)
2266
-
2267
-
2268
- if (control_input.value != '') {
2269
- return;
2270
- }
2271
-
2272
- self.onClick();
2273
- preventDefault(evt, true);
2274
- }); // keydown on focus_node for arrow_down/arrow_up
2275
-
2276
- addEvent(focus_node, 'keydown', e => self.onKeyDown(e)); // keypress and input/keyup
2277
-
2278
- addEvent(control_input, 'keypress', e => self.onKeyPress(e));
2279
- addEvent(control_input, 'input', e => self.onInput(e));
2280
- addEvent(focus_node, 'blur', e => self.onBlur(e));
2281
- addEvent(focus_node, 'focus', e => self.onFocus(e));
2282
- addEvent(control_input, 'paste', e => self.onPaste(e));
2283
-
2284
- const doc_mousedown = evt => {
2285
- // blur if target is outside of this instance
2286
- // dropdown is not always inside wrapper
2287
- const target = evt.composedPath()[0];
2288
-
2289
- if (!wrapper.contains(target) && !dropdown.contains(target)) {
2290
- if (self.isFocused) {
2291
- self.blur();
2292
- }
2293
-
2294
- self.inputState();
2295
- return;
2296
- } // retain focus by preventing native handling. if the
2297
- // event target is the input it should not be modified.
2298
- // otherwise, text selection within the input won't work.
2299
- // Fixes bug #212 which is no covered by tests
2300
-
2301
-
2302
- if (target == control_input && self.isOpen) {
2303
- evt.stopPropagation(); // clicking anywhere in the control should not blur the control_input (which would close the dropdown)
2304
- } else {
2305
- preventDefault(evt, true);
2306
- }
2307
- };
2308
-
2309
- const win_scroll = () => {
2310
- if (self.isOpen) {
2311
- self.positionDropdown();
2312
- }
2313
- };
2314
-
2315
- addEvent(document, 'mousedown', doc_mousedown);
2316
- addEvent(window, 'scroll', win_scroll, passive_event);
2317
- addEvent(window, 'resize', win_scroll, passive_event);
2318
-
2319
- this._destroy = () => {
2320
- document.removeEventListener('mousedown', doc_mousedown);
2321
- window.removeEventListener('scroll', win_scroll);
2322
- window.removeEventListener('resize', win_scroll);
2323
- if (label) label.removeEventListener('click', label_click);
2324
- }; // store original html and tab index so that they can be
2325
- // restored when the destroy() method is called.
2326
-
2327
-
2328
- this.revertSettings = {
2329
- innerHTML: input.innerHTML,
2330
- tabIndex: input.tabIndex
2331
- };
2332
- input.tabIndex = -1;
2333
- input.insertAdjacentElement('afterend', self.wrapper);
2334
- self.sync(false);
2335
- settings.items = [];
2336
- delete settings.optgroups;
2337
- delete settings.options;
2338
- addEvent(input, 'invalid', () => {
2339
- if (self.isValid) {
2340
- self.isValid = false;
2341
- self.isInvalid = true;
2342
- self.refreshState();
2343
- }
2344
- });
2345
- self.updateOriginalInput();
2346
- self.refreshItems();
2347
- self.close(false);
2348
- self.inputState();
2349
- self.isSetup = true;
2350
-
2351
- if (input.disabled) {
2352
- self.disable();
2353
- } else {
2354
- self.enable(); //sets tabIndex
2355
- }
2356
-
2357
- self.on('change', this.onChange);
2358
- addClasses(input, 'tomselected', 'ts-hidden-accessible');
2359
- self.trigger('initialize'); // preload options
2360
-
2361
- if (settings.preload === true) {
2362
- self.preload();
2363
- }
2364
- }
2365
- /**
2366
- * Register options and optgroups
2367
- *
2368
- */
2369
-
2370
-
2371
- setupOptions(options = [], optgroups = []) {
2372
- // build options table
2373
- this.addOptions(options); // build optgroup table
2374
-
2375
- iterate$1(optgroups, optgroup => {
2376
- this.registerOptionGroup(optgroup);
2377
- });
2378
- }
2379
- /**
2380
- * Sets up default rendering functions.
2381
- */
2382
-
2383
-
2384
- setupTemplates() {
2385
- var self = this;
2386
- var field_label = self.settings.labelField;
2387
- var field_optgroup = self.settings.optgroupLabelField;
2388
- var templates = {
2389
- 'optgroup': data => {
2390
- let optgroup = document.createElement('div');
2391
- optgroup.className = 'optgroup';
2392
- optgroup.appendChild(data.options);
2393
- return optgroup;
2394
- },
2395
- 'optgroup_header': (data, escape) => {
2396
- return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>';
2397
- },
2398
- 'option': (data, escape) => {
2399
- return '<div>' + escape(data[field_label]) + '</div>';
2400
- },
2401
- 'item': (data, escape) => {
2402
- return '<div>' + escape(data[field_label]) + '</div>';
2403
- },
2404
- 'option_create': (data, escape) => {
2405
- return '<div class="create">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';
2406
- },
2407
- 'no_results': () => {
2408
- return '<div class="no-results">No results found</div>';
2409
- },
2410
- 'loading': () => {
2411
- return '<div class="spinner"></div>';
2412
- },
2413
- 'not_loading': () => {},
2414
- 'dropdown': () => {
2415
- return '<div></div>';
2416
- }
2417
- };
2418
- self.settings.render = Object.assign({}, templates, self.settings.render);
2419
- }
2420
- /**
2421
- * Maps fired events to callbacks provided
2422
- * in the settings used when creating the control.
2423
- */
2424
-
2425
-
2426
- setupCallbacks() {
2427
- var key, fn;
2428
- var callbacks = {
2429
- 'initialize': 'onInitialize',
2430
- 'change': 'onChange',
2431
- 'item_add': 'onItemAdd',
2432
- 'item_remove': 'onItemRemove',
2433
- 'item_select': 'onItemSelect',
2434
- 'clear': 'onClear',
2435
- 'option_add': 'onOptionAdd',
2436
- 'option_remove': 'onOptionRemove',
2437
- 'option_clear': 'onOptionClear',
2438
- 'optgroup_add': 'onOptionGroupAdd',
2439
- 'optgroup_remove': 'onOptionGroupRemove',
2440
- 'optgroup_clear': 'onOptionGroupClear',
2441
- 'dropdown_open': 'onDropdownOpen',
2442
- 'dropdown_close': 'onDropdownClose',
2443
- 'type': 'onType',
2444
- 'load': 'onLoad',
2445
- 'focus': 'onFocus',
2446
- 'blur': 'onBlur'
2447
- };
2448
-
2449
- for (key in callbacks) {
2450
- fn = this.settings[callbacks[key]];
2451
- if (fn) this.on(key, fn);
2452
- }
2453
- }
2454
- /**
2455
- * Sync the Tom Select instance with the original input or select
2456
- *
2457
- */
2458
-
2459
-
2460
- sync(get_settings = true) {
2461
- const self = this;
2462
- const settings = get_settings ? getSettings(self.input, {
2463
- delimiter: self.settings.delimiter
2464
- }) : self.settings;
2465
- self.setupOptions(settings.options, settings.optgroups);
2466
- self.setValue(settings.items || [], true); // silent prevents recursion
2467
-
2468
- self.lastQuery = null; // so updated options will be displayed in dropdown
2469
- }
2470
- /**
2471
- * Triggered when the main control element
2472
- * has a click event.
2473
- *
2474
- */
2475
-
2476
-
2477
- onClick() {
2478
- var self = this;
2479
-
2480
- if (self.activeItems.length > 0) {
2481
- self.clearActiveItems();
2482
- self.focus();
2483
- return;
2484
- }
2485
-
2486
- if (self.isFocused && self.isOpen) {
2487
- self.blur();
2488
- } else {
2489
- self.focus();
2490
- }
2491
- }
2492
- /**
2493
- * @deprecated v1.7
2494
- *
2495
- */
2496
-
2497
-
2498
- onMouseDown() {}
2499
- /**
2500
- * Triggered when the value of the control has been changed.
2501
- * This should propagate the event to the original DOM
2502
- * input / select element.
2503
- */
2504
-
2505
-
2506
- onChange() {
2507
- triggerEvent(this.input, 'input');
2508
- triggerEvent(this.input, 'change');
2509
- }
2510
- /**
2511
- * Triggered on <input> paste.
2512
- *
2513
- */
2514
-
2515
-
2516
- onPaste(e) {
2517
- var self = this;
2518
-
2519
- if (self.isInputHidden || self.isLocked) {
2520
- preventDefault(e);
2521
- return;
2522
- } // If a regex or string is included, this will split the pasted
2523
- // input and create Items for each separate value
2524
-
2525
-
2526
- if (!self.settings.splitOn) {
2527
- return;
2528
- } // Wait for pasted text to be recognized in value
2529
-
2530
-
2531
- setTimeout(() => {
2532
- var pastedText = self.inputValue();
2533
-
2534
- if (!pastedText.match(self.settings.splitOn)) {
2535
- return;
2536
- }
2537
-
2538
- var splitInput = pastedText.trim().split(self.settings.splitOn);
2539
- iterate$1(splitInput, piece => {
2540
- const hash = hash_key(piece);
2541
-
2542
- if (hash) {
2543
- if (this.options[piece]) {
2544
- self.addItem(piece);
2545
- } else {
2546
- self.createItem(piece);
2547
- }
2548
- }
2549
- });
2550
- }, 0);
2551
- }
2552
- /**
2553
- * Triggered on <input> keypress.
2554
- *
2555
- */
2556
-
2557
-
2558
- onKeyPress(e) {
2559
- var self = this;
2560
-
2561
- if (self.isLocked) {
2562
- preventDefault(e);
2563
- return;
2564
- }
2565
-
2566
- var character = String.fromCharCode(e.keyCode || e.which);
2567
-
2568
- if (self.settings.create && self.settings.mode === 'multi' && character === self.settings.delimiter) {
2569
- self.createItem();
2570
- preventDefault(e);
2571
- return;
2572
- }
2573
- }
2574
- /**
2575
- * Triggered on <input> keydown.
2576
- *
2577
- */
2578
-
2579
-
2580
- onKeyDown(e) {
2581
- var self = this;
2582
- self.ignoreHover = true;
2583
-
2584
- if (self.isLocked) {
2585
- if (e.keyCode !== KEY_TAB) {
2586
- preventDefault(e);
2587
- }
2588
-
2589
- return;
2590
- }
2591
-
2592
- switch (e.keyCode) {
2593
- // ctrl+A: select all
2594
- case KEY_A:
2595
- if (isKeyDown(KEY_SHORTCUT, e)) {
2596
- if (self.control_input.value == '') {
2597
- preventDefault(e);
2598
- self.selectAll();
2599
- return;
2600
- }
2601
- }
2602
-
2603
- break;
2604
- // esc: close dropdown
2605
-
2606
- case KEY_ESC:
2607
- if (self.isOpen) {
2608
- preventDefault(e, true);
2609
- self.close();
2610
- }
2611
-
2612
- self.clearActiveItems();
2613
- return;
2614
- // down: open dropdown or move selection down
2615
-
2616
- case KEY_DOWN:
2617
- if (!self.isOpen && self.hasOptions) {
2618
- self.open();
2619
- } else if (self.activeOption) {
2620
- let next = self.getAdjacent(self.activeOption, 1);
2621
- if (next) self.setActiveOption(next);
2622
- }
2623
-
2624
- preventDefault(e);
2625
- return;
2626
- // up: move selection up
2627
-
2628
- case KEY_UP:
2629
- if (self.activeOption) {
2630
- let prev = self.getAdjacent(self.activeOption, -1);
2631
- if (prev) self.setActiveOption(prev);
2632
- }
2633
-
2634
- preventDefault(e);
2635
- return;
2636
- // return: select active option
2637
-
2638
- case KEY_RETURN:
2639
- if (self.canSelect(self.activeOption)) {
2640
- self.onOptionSelect(e, self.activeOption);
2641
- preventDefault(e); // if the option_create=null, the dropdown might be closed
2642
- } else if (self.settings.create && self.createItem()) {
2643
- preventDefault(e); // don't submit form when searching for a value
2644
- } else if (document.activeElement == self.control_input && self.isOpen) {
2645
- preventDefault(e);
2646
- }
2647
-
2648
- return;
2649
- // left: modifiy item selection to the left
2650
-
2651
- case KEY_LEFT:
2652
- self.advanceSelection(-1, e);
2653
- return;
2654
- // right: modifiy item selection to the right
2655
-
2656
- case KEY_RIGHT:
2657
- self.advanceSelection(1, e);
2658
- return;
2659
- // tab: select active option and/or create item
2660
-
2661
- case KEY_TAB:
2662
- if (self.settings.selectOnTab) {
2663
- if (self.canSelect(self.activeOption)) {
2664
- self.onOptionSelect(e, self.activeOption); // prevent default [tab] behaviour of jump to the next field
2665
- // if select isFull, then the dropdown won't be open and [tab] will work normally
2666
-
2667
- preventDefault(e);
2668
- }
2669
-
2670
- if (self.settings.create && self.createItem()) {
2671
- preventDefault(e);
2672
- }
2673
- }
2674
-
2675
- return;
2676
- // delete|backspace: delete items
2677
-
2678
- case KEY_BACKSPACE:
2679
- case KEY_DELETE:
2680
- self.deleteSelection(e);
2681
- return;
2682
- } // don't enter text in the control_input when active items are selected
2683
-
2684
-
2685
- if (self.isInputHidden && !isKeyDown(KEY_SHORTCUT, e)) {
2686
- preventDefault(e);
2687
- }
2688
- }
2689
- /**
2690
- * Triggered on <input> keyup.
2691
- *
2692
- */
2693
-
2694
-
2695
- onInput(e) {
2696
- var self = this;
2697
-
2698
- if (self.isLocked) {
2699
- return;
2700
- }
2701
-
2702
- var value = self.inputValue();
2703
-
2704
- if (self.lastValue !== value) {
2705
- self.lastValue = value;
2706
-
2707
- if (self.settings.shouldLoad.call(self, value)) {
2708
- self.load(value);
2709
- }
2710
-
2711
- self.refreshOptions();
2712
- self.trigger('type', value);
2713
- }
2714
- }
2715
- /**
2716
- * Triggered when the user rolls over
2717
- * an option in the autocomplete dropdown menu.
2718
- *
2719
- */
2720
-
2721
-
2722
- onOptionHover(evt, option) {
2723
- if (this.ignoreHover) return;
2724
- this.setActiveOption(option, false);
2725
- }
2726
- /**
2727
- * Triggered on <input> focus.
2728
- *
2729
- */
2730
-
2731
-
2732
- onFocus(e) {
2733
- var self = this;
2734
- var wasFocused = self.isFocused;
2735
-
2736
- if (self.isDisabled) {
2737
- self.blur();
2738
- preventDefault(e);
2739
- return;
2740
- }
2741
-
2742
- if (self.ignoreFocus) return;
2743
- self.isFocused = true;
2744
- if (self.settings.preload === 'focus') self.preload();
2745
- if (!wasFocused) self.trigger('focus');
2746
-
2747
- if (!self.activeItems.length) {
2748
- self.showInput();
2749
- self.refreshOptions(!!self.settings.openOnFocus);
2750
- }
2751
-
2752
- self.refreshState();
2753
- }
2754
- /**
2755
- * Triggered on <input> blur.
2756
- *
2757
- */
2758
-
2759
-
2760
- onBlur(e) {
2761
- if (document.hasFocus() === false) return;
2762
- var self = this;
2763
- if (!self.isFocused) return;
2764
- self.isFocused = false;
2765
- self.ignoreFocus = false;
2766
-
2767
- var deactivate = () => {
2768
- self.close();
2769
- self.setActiveItem();
2770
- self.setCaret(self.items.length);
2771
- self.trigger('blur');
2772
- };
2773
-
2774
- if (self.settings.create && self.settings.createOnBlur) {
2775
- self.createItem(null, deactivate);
2776
- } else {
2777
- deactivate();
2778
- }
2779
- }
2780
- /**
2781
- * Triggered when the user clicks on an option
2782
- * in the autocomplete dropdown menu.
2783
- *
2784
- */
2785
-
2786
-
2787
- onOptionSelect(evt, option) {
2788
- var value,
2789
- self = this; // should not be possible to trigger a option under a disabled optgroup
2790
-
2791
- if (option.parentElement && option.parentElement.matches('[data-disabled]')) {
2792
- return;
2793
- }
2794
-
2795
- if (option.classList.contains('create')) {
2796
- self.createItem(null, () => {
2797
- if (self.settings.closeAfterSelect) {
2798
- self.close();
2799
- }
2800
- });
2801
- } else {
2802
- value = option.dataset.value;
2803
-
2804
- if (typeof value !== 'undefined') {
2805
- self.lastQuery = null;
2806
- self.addItem(value);
2807
-
2808
- if (self.settings.closeAfterSelect) {
2809
- self.close();
2810
- }
2811
-
2812
- if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {
2813
- self.setActiveOption(option);
2814
- }
2815
- }
2816
- }
2817
- }
2818
- /**
2819
- * Return true if the given option can be selected
2820
- *
2821
- */
2822
-
2823
-
2824
- canSelect(option) {
2825
- if (this.isOpen && option && this.dropdown_content.contains(option)) {
2826
- return true;
2827
- }
2828
-
2829
- return false;
2830
- }
2831
- /**
2832
- * Triggered when the user clicks on an item
2833
- * that has been selected.
2834
- *
2835
- */
2836
-
2837
-
2838
- onItemSelect(evt, item) {
2839
- var self = this;
2840
-
2841
- if (!self.isLocked && self.settings.mode === 'multi') {
2842
- preventDefault(evt);
2843
- self.setActiveItem(item, evt);
2844
- return true;
2845
- }
2846
-
2847
- return false;
2848
- }
2849
- /**
2850
- * Determines whether or not to invoke
2851
- * the user-provided option provider / loader
2852
- *
2853
- * Note, there is a subtle difference between
2854
- * this.canLoad() and this.settings.shouldLoad();
2855
- *
2856
- * - settings.shouldLoad() is a user-input validator.
2857
- * When false is returned, the not_loading template
2858
- * will be added to the dropdown
2859
- *
2860
- * - canLoad() is lower level validator that checks
2861
- * the Tom Select instance. There is no inherent user
2862
- * feedback when canLoad returns false
2863
- *
2864
- */
2865
-
2866
-
2867
- canLoad(value) {
2868
- if (!this.settings.load) return false;
2869
- if (this.loadedSearches.hasOwnProperty(value)) return false;
2870
- return true;
2871
- }
2872
- /**
2873
- * Invokes the user-provided option provider / loader.
2874
- *
2875
- */
2876
-
2877
-
2878
- load(value) {
2879
- const self = this;
2880
- if (!self.canLoad(value)) return;
2881
- addClasses(self.wrapper, self.settings.loadingClass);
2882
- self.loading++;
2883
- const callback = self.loadCallback.bind(self);
2884
- self.settings.load.call(self, value, callback);
2885
- }
2886
- /**
2887
- * Invoked by the user-provided option provider
2888
- *
2889
- */
2890
-
2891
-
2892
- loadCallback(options, optgroups) {
2893
- const self = this;
2894
- self.loading = Math.max(self.loading - 1, 0);
2895
- self.lastQuery = null;
2896
- self.clearActiveOption(); // when new results load, focus should be on first option
2897
-
2898
- self.setupOptions(options, optgroups);
2899
- self.refreshOptions(self.isFocused && !self.isInputHidden);
2900
-
2901
- if (!self.loading) {
2902
- removeClasses(self.wrapper, self.settings.loadingClass);
2903
- }
2904
-
2905
- self.trigger('load', options, optgroups);
2906
- }
2907
-
2908
- preload() {
2909
- var classList = this.wrapper.classList;
2910
- if (classList.contains('preloaded')) return;
2911
- classList.add('preloaded');
2912
- this.load('');
2913
- }
2914
- /**
2915
- * Sets the input field of the control to the specified value.
2916
- *
2917
- */
2918
-
2919
-
2920
- setTextboxValue(value = '') {
2921
- var input = this.control_input;
2922
- var changed = input.value !== value;
2923
-
2924
- if (changed) {
2925
- input.value = value;
2926
- triggerEvent(input, 'update');
2927
- this.lastValue = value;
2928
- }
2929
- }
2930
- /**
2931
- * Returns the value of the control. If multiple items
2932
- * can be selected (e.g. <select multiple>), this returns
2933
- * an array. If only one item can be selected, this
2934
- * returns a string.
2935
- *
2936
- */
2937
-
2938
-
2939
- getValue() {
2940
- if (this.is_select_tag && this.input.hasAttribute('multiple')) {
2941
- return this.items;
2942
- }
2943
-
2944
- return this.items.join(this.settings.delimiter);
2945
- }
2946
- /**
2947
- * Resets the selected items to the given value.
2948
- *
2949
- */
2950
-
2951
-
2952
- setValue(value, silent) {
2953
- var events = silent ? [] : ['change'];
2954
- debounce_events(this, events, () => {
2955
- this.clear(silent);
2956
- this.addItems(value, silent);
2957
- });
2958
- }
2959
- /**
2960
- * Resets the number of max items to the given value
2961
- *
2962
- */
2963
-
2964
-
2965
- setMaxItems(value) {
2966
- if (value === 0) value = null; //reset to unlimited items.
2967
-
2968
- this.settings.maxItems = value;
2969
- this.refreshState();
2970
- }
2971
- /**
2972
- * Sets the selected item.
2973
- *
2974
- */
2975
-
2976
-
2977
- setActiveItem(item, e) {
2978
- var self = this;
2979
- var eventName;
2980
- var i, begin, end, swap;
2981
- var last;
2982
- if (self.settings.mode === 'single') return; // clear the active selection
2983
-
2984
- if (!item) {
2985
- self.clearActiveItems();
2986
-
2987
- if (self.isFocused) {
2988
- self.showInput();
2989
- }
2990
-
2991
- return;
2992
- } // modify selection
2993
-
2994
-
2995
- eventName = e && e.type.toLowerCase();
2996
-
2997
- if (eventName === 'click' && isKeyDown('shiftKey', e) && self.activeItems.length) {
2998
- last = self.getLastActive();
2999
- begin = Array.prototype.indexOf.call(self.control.children, last);
3000
- end = Array.prototype.indexOf.call(self.control.children, item);
3001
-
3002
- if (begin > end) {
3003
- swap = begin;
3004
- begin = end;
3005
- end = swap;
3006
- }
3007
-
3008
- for (i = begin; i <= end; i++) {
3009
- item = self.control.children[i];
3010
-
3011
- if (self.activeItems.indexOf(item) === -1) {
3012
- self.setActiveItemClass(item);
3013
- }
3014
- }
3015
-
3016
- preventDefault(e);
3017
- } else if (eventName === 'click' && isKeyDown(KEY_SHORTCUT, e) || eventName === 'keydown' && isKeyDown('shiftKey', e)) {
3018
- if (item.classList.contains('active')) {
3019
- self.removeActiveItem(item);
3020
- } else {
3021
- self.setActiveItemClass(item);
3022
- }
3023
- } else {
3024
- self.clearActiveItems();
3025
- self.setActiveItemClass(item);
3026
- } // ensure control has focus
3027
-
3028
-
3029
- self.hideInput();
3030
-
3031
- if (!self.isFocused) {
3032
- self.focus();
3033
- }
3034
- }
3035
- /**
3036
- * Set the active and last-active classes
3037
- *
3038
- */
3039
-
3040
-
3041
- setActiveItemClass(item) {
3042
- const self = this;
3043
- const last_active = self.control.querySelector('.last-active');
3044
- if (last_active) removeClasses(last_active, 'last-active');
3045
- addClasses(item, 'active last-active');
3046
- self.trigger('item_select', item);
3047
-
3048
- if (self.activeItems.indexOf(item) == -1) {
3049
- self.activeItems.push(item);
3050
- }
3051
- }
3052
- /**
3053
- * Remove active item
3054
- *
3055
- */
3056
-
3057
-
3058
- removeActiveItem(item) {
3059
- var idx = this.activeItems.indexOf(item);
3060
- this.activeItems.splice(idx, 1);
3061
- removeClasses(item, 'active');
3062
- }
3063
- /**
3064
- * Clears all the active items
3065
- *
3066
- */
3067
-
3068
-
3069
- clearActiveItems() {
3070
- removeClasses(this.activeItems, 'active');
3071
- this.activeItems = [];
3072
- }
3073
- /**
3074
- * Sets the selected item in the dropdown menu
3075
- * of available options.
3076
- *
3077
- */
3078
-
3079
-
3080
- setActiveOption(option, scroll = true) {
3081
- if (option === this.activeOption) {
3082
- return;
3083
- }
3084
-
3085
- this.clearActiveOption();
3086
- if (!option) return;
3087
- this.activeOption = option;
3088
- setAttr(this.focus_node, {
3089
- 'aria-activedescendant': option.getAttribute('id')
3090
- });
3091
- setAttr(option, {
3092
- 'aria-selected': 'true'
3093
- });
3094
- addClasses(option, 'active');
3095
- if (scroll) this.scrollToOption(option);
3096
- }
3097
- /**
3098
- * Sets the dropdown_content scrollTop to display the option
3099
- *
3100
- */
3101
-
3102
-
3103
- scrollToOption(option, behavior) {
3104
- if (!option) return;
3105
- const content = this.dropdown_content;
3106
- const height_menu = content.clientHeight;
3107
- const scrollTop = content.scrollTop || 0;
3108
- const height_item = option.offsetHeight;
3109
- const y = option.getBoundingClientRect().top - content.getBoundingClientRect().top + scrollTop;
3110
-
3111
- if (y + height_item > height_menu + scrollTop) {
3112
- this.scroll(y - height_menu + height_item, behavior);
3113
- } else if (y < scrollTop) {
3114
- this.scroll(y, behavior);
3115
- }
3116
- }
3117
- /**
3118
- * Scroll the dropdown to the given position
3119
- *
3120
- */
3121
-
3122
-
3123
- scroll(scrollTop, behavior) {
3124
- const content = this.dropdown_content;
3125
-
3126
- if (behavior) {
3127
- content.style.scrollBehavior = behavior;
3128
- }
3129
-
3130
- content.scrollTop = scrollTop;
3131
- content.style.scrollBehavior = '';
3132
- }
3133
- /**
3134
- * Clears the active option
3135
- *
3136
- */
3137
-
3138
-
3139
- clearActiveOption() {
3140
- if (this.activeOption) {
3141
- removeClasses(this.activeOption, 'active');
3142
- setAttr(this.activeOption, {
3143
- 'aria-selected': null
3144
- });
3145
- }
3146
-
3147
- this.activeOption = null;
3148
- setAttr(this.focus_node, {
3149
- 'aria-activedescendant': null
3150
- });
3151
- }
3152
- /**
3153
- * Selects all items (CTRL + A).
3154
- */
3155
-
3156
-
3157
- selectAll() {
3158
- const self = this;
3159
- if (self.settings.mode === 'single') return;
3160
- const activeItems = self.controlChildren();
3161
- if (!activeItems.length) return;
3162
- self.hideInput();
3163
- self.close();
3164
- self.activeItems = activeItems;
3165
- iterate$1(activeItems, item => {
3166
- self.setActiveItemClass(item);
3167
- });
3168
- }
3169
- /**
3170
- * Determines if the control_input should be in a hidden or visible state
3171
- *
3172
- */
3173
-
3174
-
3175
- inputState() {
3176
- var self = this;
3177
- if (!self.control.contains(self.control_input)) return;
3178
- setAttr(self.control_input, {
3179
- placeholder: self.settings.placeholder
3180
- });
3181
-
3182
- if (self.activeItems.length > 0 || !self.isFocused && self.settings.hidePlaceholder && self.items.length > 0) {
3183
- self.setTextboxValue();
3184
- self.isInputHidden = true;
3185
- } else {
3186
- if (self.settings.hidePlaceholder && self.items.length > 0) {
3187
- setAttr(self.control_input, {
3188
- placeholder: ''
3189
- });
3190
- }
3191
-
3192
- self.isInputHidden = false;
3193
- }
3194
-
3195
- self.wrapper.classList.toggle('input-hidden', self.isInputHidden);
3196
- }
3197
- /**
3198
- * Hides the input element out of view, while
3199
- * retaining its focus.
3200
- * @deprecated 1.3
3201
- */
3202
-
3203
-
3204
- hideInput() {
3205
- this.inputState();
3206
- }
3207
- /**
3208
- * Restores input visibility.
3209
- * @deprecated 1.3
3210
- */
3211
-
3212
-
3213
- showInput() {
3214
- this.inputState();
3215
- }
3216
- /**
3217
- * Get the input value
3218
- */
3219
-
3220
-
3221
- inputValue() {
3222
- return this.control_input.value.trim();
3223
- }
3224
- /**
3225
- * Gives the control focus.
3226
- */
3227
-
3228
-
3229
- focus() {
3230
- var self = this;
3231
- if (self.isDisabled) return;
3232
- self.ignoreFocus = true;
3233
-
3234
- if (self.control_input.offsetWidth) {
3235
- self.control_input.focus();
3236
- } else {
3237
- self.focus_node.focus();
3238
- }
3239
-
3240
- setTimeout(() => {
3241
- self.ignoreFocus = false;
3242
- self.onFocus();
3243
- }, 0);
3244
- }
3245
- /**
3246
- * Forces the control out of focus.
3247
- *
3248
- */
3249
-
3250
-
3251
- blur() {
3252
- this.focus_node.blur();
3253
- this.onBlur();
3254
- }
3255
- /**
3256
- * Returns a function that scores an object
3257
- * to show how good of a match it is to the
3258
- * provided query.
3259
- *
3260
- * @return {function}
3261
- */
3262
-
3263
-
3264
- getScoreFunction(query) {
3265
- return this.sifter.getScoreFunction(query, this.getSearchOptions());
3266
- }
3267
- /**
3268
- * Returns search options for sifter (the system
3269
- * for scoring and sorting results).
3270
- *
3271
- * @see https://github.com/orchidjs/sifter.js
3272
- * @return {object}
3273
- */
3274
-
3275
-
3276
- getSearchOptions() {
3277
- var settings = this.settings;
3278
- var sort = settings.sortField;
3279
-
3280
- if (typeof settings.sortField === 'string') {
3281
- sort = [{
3282
- field: settings.sortField
3283
- }];
3284
- }
3285
-
3286
- return {
3287
- fields: settings.searchField,
3288
- conjunction: settings.searchConjunction,
3289
- sort: sort,
3290
- nesting: settings.nesting
3291
- };
3292
- }
3293
- /**
3294
- * Searches through available options and returns
3295
- * a sorted array of matches.
3296
- *
3297
- */
3298
-
3299
-
3300
- search(query) {
3301
- var result, calculateScore;
3302
- var self = this;
3303
- var options = this.getSearchOptions(); // validate user-provided result scoring function
3304
-
3305
- if (self.settings.score) {
3306
- calculateScore = self.settings.score.call(self, query);
3307
-
3308
- if (typeof calculateScore !== 'function') {
3309
- throw new Error('Tom Select "score" setting must be a function that returns a function');
3310
- }
3311
- } // perform search
3312
-
3313
-
3314
- if (query !== self.lastQuery) {
3315
- self.lastQuery = query;
3316
- result = self.sifter.search(query, Object.assign(options, {
3317
- score: calculateScore
3318
- }));
3319
- self.currentResults = result;
3320
- } else {
3321
- result = Object.assign({}, self.currentResults);
3322
- } // filter out selected items
3323
-
3324
-
3325
- if (self.settings.hideSelected) {
3326
- result.items = result.items.filter(item => {
3327
- let hashed = hash_key(item.id);
3328
- return !(hashed && self.items.indexOf(hashed) !== -1);
3329
- });
3330
- }
3331
-
3332
- return result;
3333
- }
3334
- /**
3335
- * Refreshes the list of available options shown
3336
- * in the autocomplete dropdown menu.
3337
- *
3338
- */
3339
-
3340
-
3341
- refreshOptions(triggerDropdown = true) {
3342
- var i, j, k, n, optgroup, optgroups, html, has_create_option, active_group;
3343
- var create;
3344
- const groups = {};
3345
- const groups_order = [];
3346
- var self = this;
3347
- var query = self.inputValue();
3348
- const same_query = query === self.lastQuery || query == '' && self.lastQuery == null;
3349
- var results = self.search(query);
3350
- var active_option = null;
3351
- var show_dropdown = self.settings.shouldOpen || false;
3352
- var dropdown_content = self.dropdown_content;
3353
-
3354
- if (same_query) {
3355
- active_option = self.activeOption;
3356
-
3357
- if (active_option) {
3358
- active_group = active_option.closest('[data-group]');
3359
- }
3360
- } // build markup
3361
-
3362
-
3363
- n = results.items.length;
3364
-
3365
- if (typeof self.settings.maxOptions === 'number') {
3366
- n = Math.min(n, self.settings.maxOptions);
3367
- }
3368
-
3369
- if (n > 0) {
3370
- show_dropdown = true;
3371
- } // render and group available options individually
3372
-
3373
-
3374
- for (i = 0; i < n; i++) {
3375
- // get option dom element
3376
- let item = results.items[i];
3377
- if (!item) continue;
3378
- let opt_value = item.id;
3379
- let option = self.options[opt_value];
3380
- if (option === undefined) continue;
3381
- let opt_hash = get_hash(opt_value);
3382
- let option_el = self.getOption(opt_hash, true); // toggle 'selected' class
3383
-
3384
- if (!self.settings.hideSelected) {
3385
- option_el.classList.toggle('selected', self.items.includes(opt_hash));
3386
- }
3387
-
3388
- optgroup = option[self.settings.optgroupField] || '';
3389
- optgroups = Array.isArray(optgroup) ? optgroup : [optgroup];
3390
-
3391
- for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
3392
- optgroup = optgroups[j];
3393
-
3394
- if (!self.optgroups.hasOwnProperty(optgroup)) {
3395
- optgroup = '';
3396
- }
3397
-
3398
- let group_fragment = groups[optgroup];
3399
-
3400
- if (group_fragment === undefined) {
3401
- group_fragment = document.createDocumentFragment();
3402
- groups_order.push(optgroup);
3403
- } // nodes can only have one parent, so if the option is in mutple groups, we need a clone
3404
-
3405
-
3406
- if (j > 0) {
3407
- option_el = option_el.cloneNode(true);
3408
- setAttr(option_el, {
3409
- id: option.$id + '-clone-' + j,
3410
- 'aria-selected': null
3411
- });
3412
- option_el.classList.add('ts-cloned');
3413
- removeClasses(option_el, 'active'); // make sure we keep the activeOption in the same group
3414
-
3415
- if (self.activeOption && self.activeOption.dataset.value == opt_value) {
3416
- if (active_group && active_group.dataset.group === optgroup.toString()) {
3417
- active_option = option_el;
3418
- }
3419
- }
3420
- }
3421
-
3422
- group_fragment.appendChild(option_el);
3423
- groups[optgroup] = group_fragment;
3424
- }
3425
- } // sort optgroups
3426
-
3427
-
3428
- if (self.settings.lockOptgroupOrder) {
3429
- groups_order.sort((a, b) => {
3430
- const grp_a = self.optgroups[a];
3431
- const grp_b = self.optgroups[b];
3432
- const a_order = grp_a && grp_a.$order || 0;
3433
- const b_order = grp_b && grp_b.$order || 0;
3434
- return a_order - b_order;
3435
- });
3436
- } // render optgroup headers & join groups
3437
-
3438
-
3439
- html = document.createDocumentFragment();
3440
- iterate$1(groups_order, optgroup => {
3441
- let group_fragment = groups[optgroup];
3442
- if (!group_fragment || !group_fragment.children.length) return;
3443
- let group_heading = self.optgroups[optgroup];
3444
-
3445
- if (group_heading !== undefined) {
3446
- let group_options = document.createDocumentFragment();
3447
- let header = self.render('optgroup_header', group_heading);
3448
- append(group_options, header);
3449
- append(group_options, group_fragment);
3450
- let group_html = self.render('optgroup', {
3451
- group: group_heading,
3452
- options: group_options
3453
- });
3454
- append(html, group_html);
3455
- } else {
3456
- append(html, group_fragment);
3457
- }
3458
- });
3459
- dropdown_content.innerHTML = '';
3460
- append(dropdown_content, html); // highlight matching terms inline
3461
-
3462
- if (self.settings.highlight) {
3463
- removeHighlight(dropdown_content);
3464
-
3465
- if (results.query.length && results.tokens.length) {
3466
- iterate$1(results.tokens, tok => {
3467
- highlight(dropdown_content, tok.regex);
3468
- });
3469
- }
3470
- } // helper method for adding templates to dropdown
3471
-
3472
-
3473
- var add_template = template => {
3474
- let content = self.render(template, {
3475
- input: query
3476
- });
3477
-
3478
- if (content) {
3479
- show_dropdown = true;
3480
- dropdown_content.insertBefore(content, dropdown_content.firstChild);
3481
- }
3482
-
3483
- return content;
3484
- }; // add loading message
3485
-
3486
-
3487
- if (self.loading) {
3488
- add_template('loading'); // invalid query
3489
- } else if (!self.settings.shouldLoad.call(self, query)) {
3490
- add_template('not_loading'); // add no_results message
3491
- } else if (results.items.length === 0) {
3492
- add_template('no_results');
3493
- } // add create option
3494
-
3495
-
3496
- has_create_option = self.canCreate(query);
3497
-
3498
- if (has_create_option) {
3499
- create = add_template('option_create');
3500
- } // activate
3501
-
3502
-
3503
- self.hasOptions = results.items.length > 0 || has_create_option;
3504
-
3505
- if (show_dropdown) {
3506
- if (results.items.length > 0) {
3507
- if (!active_option && self.settings.mode === 'single' && self.items[0] != undefined) {
3508
- active_option = self.getOption(self.items[0]);
3509
- }
3510
-
3511
- if (!dropdown_content.contains(active_option)) {
3512
- let active_index = 0;
3513
-
3514
- if (create && !self.settings.addPrecedence) {
3515
- active_index = 1;
3516
- }
3517
-
3518
- active_option = self.selectable()[active_index];
3519
- }
3520
- } else if (create) {
3521
- active_option = create;
3522
- }
3523
-
3524
- if (triggerDropdown && !self.isOpen) {
3525
- self.open();
3526
- self.scrollToOption(active_option, 'auto');
3527
- }
3528
-
3529
- self.setActiveOption(active_option);
3530
- } else {
3531
- self.clearActiveOption();
3532
-
3533
- if (triggerDropdown && self.isOpen) {
3534
- self.close(false); // if create_option=null, we want the dropdown to close but not reset the textbox value
3535
- }
3536
- }
3537
- }
3538
- /**
3539
- * Return list of selectable options
3540
- *
3541
- */
3542
-
3543
-
3544
- selectable() {
3545
- return this.dropdown_content.querySelectorAll('[data-selectable]');
3546
- }
3547
- /**
3548
- * Adds an available option. If it already exists,
3549
- * nothing will happen. Note: this does not refresh
3550
- * the options list dropdown (use `refreshOptions`
3551
- * for that).
3552
- *
3553
- * Usage:
3554
- *
3555
- * this.addOption(data)
3556
- *
3557
- */
3558
-
3559
-
3560
- addOption(data, user_created = false) {
3561
- const self = this; // @deprecated 1.7.7
3562
- // use addOptions( array, user_created ) for adding multiple options
3563
-
3564
- if (Array.isArray(data)) {
3565
- self.addOptions(data, user_created);
3566
- return false;
3567
- }
3568
-
3569
- const key = hash_key(data[self.settings.valueField]);
3570
-
3571
- if (key === null || self.options.hasOwnProperty(key)) {
3572
- return false;
3573
- }
3574
-
3575
- data.$order = data.$order || ++self.order;
3576
- data.$id = self.inputId + '-opt-' + data.$order;
3577
- self.options[key] = data;
3578
- self.lastQuery = null;
3579
-
3580
- if (user_created) {
3581
- self.userOptions[key] = user_created;
3582
- self.trigger('option_add', key, data);
3583
- }
3584
-
3585
- return key;
3586
- }
3587
- /**
3588
- * Add multiple options
3589
- *
3590
- */
3591
-
3592
-
3593
- addOptions(data, user_created = false) {
3594
- iterate$1(data, dat => {
3595
- this.addOption(dat, user_created);
3596
- });
3597
- }
3598
- /**
3599
- * @deprecated 1.7.7
3600
- */
3601
-
3602
-
3603
- registerOption(data) {
3604
- return this.addOption(data);
3605
- }
3606
- /**
3607
- * Registers an option group to the pool of option groups.
3608
- *
3609
- * @return {boolean|string}
3610
- */
3611
-
3612
-
3613
- registerOptionGroup(data) {
3614
- var key = hash_key(data[this.settings.optgroupValueField]);
3615
- if (key === null) return false;
3616
- data.$order = data.$order || ++this.order;
3617
- this.optgroups[key] = data;
3618
- return key;
3619
- }
3620
- /**
3621
- * Registers a new optgroup for options
3622
- * to be bucketed into.
3623
- *
3624
- */
3625
-
3626
-
3627
- addOptionGroup(id, data) {
3628
- var hashed_id;
3629
- data[this.settings.optgroupValueField] = id;
3630
-
3631
- if (hashed_id = this.registerOptionGroup(data)) {
3632
- this.trigger('optgroup_add', hashed_id, data);
3633
- }
3634
- }
3635
- /**
3636
- * Removes an existing option group.
3637
- *
3638
- */
3639
-
3640
-
3641
- removeOptionGroup(id) {
3642
- if (this.optgroups.hasOwnProperty(id)) {
3643
- delete this.optgroups[id];
3644
- this.clearCache();
3645
- this.trigger('optgroup_remove', id);
3646
- }
3647
- }
3648
- /**
3649
- * Clears all existing option groups.
3650
- */
3651
-
3652
-
3653
- clearOptionGroups() {
3654
- this.optgroups = {};
3655
- this.clearCache();
3656
- this.trigger('optgroup_clear');
3657
- }
3658
- /**
3659
- * Updates an option available for selection. If
3660
- * it is visible in the selected items or options
3661
- * dropdown, it will be re-rendered automatically.
3662
- *
3663
- */
3664
-
3665
-
3666
- updateOption(value, data) {
3667
- const self = this;
3668
- var item_new;
3669
- var index_item;
3670
- const value_old = hash_key(value);
3671
- const value_new = hash_key(data[self.settings.valueField]); // sanity checks
3672
-
3673
- if (value_old === null) return;
3674
- const data_old = self.options[value_old];
3675
- if (data_old == undefined) return;
3676
- if (typeof value_new !== 'string') throw new Error('Value must be set in option data');
3677
- const option = self.getOption(value_old);
3678
- const item = self.getItem(value_old);
3679
- data.$order = data.$order || data_old.$order;
3680
- delete self.options[value_old]; // invalidate render cache
3681
- // don't remove existing node yet, we'll remove it after replacing it
3682
-
3683
- self.uncacheValue(value_new);
3684
- self.options[value_new] = data; // update the option if it's in the dropdown
3685
-
3686
- if (option) {
3687
- if (self.dropdown_content.contains(option)) {
3688
- const option_new = self._render('option', data);
3689
-
3690
- replaceNode(option, option_new);
3691
-
3692
- if (self.activeOption === option) {
3693
- self.setActiveOption(option_new);
3694
- }
3695
- }
3696
-
3697
- option.remove();
3698
- } // update the item if we have one
3699
-
3700
-
3701
- if (item) {
3702
- index_item = self.items.indexOf(value_old);
3703
-
3704
- if (index_item !== -1) {
3705
- self.items.splice(index_item, 1, value_new);
3706
- }
3707
-
3708
- item_new = self._render('item', data);
3709
- if (item.classList.contains('active')) addClasses(item_new, 'active');
3710
- replaceNode(item, item_new);
3711
- } // invalidate last query because we might have updated the sortField
3712
-
3713
-
3714
- self.lastQuery = null;
3715
- }
3716
- /**
3717
- * Removes a single option.
3718
- *
3719
- */
3720
-
3721
-
3722
- removeOption(value, silent) {
3723
- const self = this;
3724
- value = get_hash(value);
3725
- self.uncacheValue(value);
3726
- delete self.userOptions[value];
3727
- delete self.options[value];
3728
- self.lastQuery = null;
3729
- self.trigger('option_remove', value);
3730
- self.removeItem(value, silent);
3731
- }
3732
- /**
3733
- * Clears all options.
3734
- */
3735
-
3736
-
3737
- clearOptions(filter) {
3738
- const boundFilter = (filter || this.clearFilter).bind(this);
3739
- this.loadedSearches = {};
3740
- this.userOptions = {};
3741
- this.clearCache();
3742
- const selected = {};
3743
- iterate$1(this.options, (option, key) => {
3744
- if (boundFilter(option, key)) {
3745
- selected[key] = option;
3746
- }
3747
- });
3748
- this.options = this.sifter.items = selected;
3749
- this.lastQuery = null;
3750
- this.trigger('option_clear');
3751
- }
3752
- /**
3753
- * Used by clearOptions() to decide whether or not an option should be removed
3754
- * Return true to keep an option, false to remove
3755
- *
3756
- */
3757
-
3758
-
3759
- clearFilter(option, value) {
3760
- if (this.items.indexOf(value) >= 0) {
3761
- return true;
3762
- }
3763
-
3764
- return false;
3765
- }
3766
- /**
3767
- * Returns the dom element of the option
3768
- * matching the given value.
3769
- *
3770
- */
3771
-
3772
-
3773
- getOption(value, create = false) {
3774
- const hashed = hash_key(value);
3775
- if (hashed === null) return null;
3776
- const option = this.options[hashed];
3777
-
3778
- if (option != undefined) {
3779
- if (option.$div) {
3780
- return option.$div;
3781
- }
3782
-
3783
- if (create) {
3784
- return this._render('option', option);
3785
- }
3786
- }
3787
-
3788
- return null;
3789
- }
3790
- /**
3791
- * Returns the dom element of the next or previous dom element of the same type
3792
- * Note: adjacent options may not be adjacent DOM elements (optgroups)
3793
- *
3794
- */
3795
-
3796
-
3797
- getAdjacent(option, direction, type = 'option') {
3798
- var self = this,
3799
- all;
3800
-
3801
- if (!option) {
3802
- return null;
3803
- }
3804
-
3805
- if (type == 'item') {
3806
- all = self.controlChildren();
3807
- } else {
3808
- all = self.dropdown_content.querySelectorAll('[data-selectable]');
3809
- }
3810
-
3811
- for (let i = 0; i < all.length; i++) {
3812
- if (all[i] != option) {
3813
- continue;
3814
- }
3815
-
3816
- if (direction > 0) {
3817
- return all[i + 1];
3818
- }
3819
-
3820
- return all[i - 1];
3821
- }
3822
-
3823
- return null;
3824
- }
3825
- /**
3826
- * Returns the dom element of the item
3827
- * matching the given value.
3828
- *
3829
- */
3830
-
3831
-
3832
- getItem(item) {
3833
- if (typeof item == 'object') {
3834
- return item;
3835
- }
3836
-
3837
- var value = hash_key(item);
3838
- return value !== null ? this.control.querySelector(`[data-value="${addSlashes(value)}"]`) : null;
3839
- }
3840
- /**
3841
- * "Selects" multiple items at once. Adds them to the list
3842
- * at the current caret position.
3843
- *
3844
- */
3845
-
3846
-
3847
- addItems(values, silent) {
3848
- var self = this;
3849
- var items = Array.isArray(values) ? values : [values];
3850
- items = items.filter(x => self.items.indexOf(x) === -1);
3851
- const last_item = items[items.length - 1];
3852
- items.forEach(item => {
3853
- self.isPending = item !== last_item;
3854
- self.addItem(item, silent);
3855
- });
3856
- }
3857
- /**
3858
- * "Selects" an item. Adds it to the list
3859
- * at the current caret position.
3860
- *
3861
- */
3862
-
3863
-
3864
- addItem(value, silent) {
3865
- var events = silent ? [] : ['change', 'dropdown_close'];
3866
- debounce_events(this, events, () => {
3867
- var item, wasFull;
3868
- const self = this;
3869
- const inputMode = self.settings.mode;
3870
- const hashed = hash_key(value);
3871
-
3872
- if (hashed && self.items.indexOf(hashed) !== -1) {
3873
- if (inputMode === 'single') {
3874
- self.close();
3875
- }
3876
-
3877
- if (inputMode === 'single' || !self.settings.duplicates) {
3878
- return;
3879
- }
3880
- }
3881
-
3882
- if (hashed === null || !self.options.hasOwnProperty(hashed)) return;
3883
- if (inputMode === 'single') self.clear(silent);
3884
- if (inputMode === 'multi' && self.isFull()) return;
3885
- item = self._render('item', self.options[hashed]);
3886
-
3887
- if (self.control.contains(item)) {
3888
- // duplicates
3889
- item = item.cloneNode(true);
3890
- }
3891
-
3892
- wasFull = self.isFull();
3893
- self.items.splice(self.caretPos, 0, hashed);
3894
- self.insertAtCaret(item);
3895
-
3896
- if (self.isSetup) {
3897
- // update menu / remove the option (if this is not one item being added as part of series)
3898
- if (!self.isPending && self.settings.hideSelected) {
3899
- let option = self.getOption(hashed);
3900
- let next = self.getAdjacent(option, 1);
3901
-
3902
- if (next) {
3903
- self.setActiveOption(next);
3904
- }
3905
- } // refreshOptions after setActiveOption(),
3906
- // otherwise setActiveOption() will be called by refreshOptions() with the wrong value
3907
-
3908
-
3909
- if (!self.isPending && !self.settings.closeAfterSelect) {
3910
- self.refreshOptions(self.isFocused && inputMode !== 'single');
3911
- } // hide the menu if the maximum number of items have been selected or no options are left
3912
-
3913
-
3914
- if (self.settings.closeAfterSelect != false && self.isFull()) {
3915
- self.close();
3916
- } else if (!self.isPending) {
3917
- self.positionDropdown();
3918
- }
3919
-
3920
- self.trigger('item_add', hashed, item);
3921
-
3922
- if (!self.isPending) {
3923
- self.updateOriginalInput({
3924
- silent: silent
3925
- });
3926
- }
3927
- }
3928
-
3929
- if (!self.isPending || !wasFull && self.isFull()) {
3930
- self.inputState();
3931
- self.refreshState();
3932
- }
3933
- });
3934
- }
3935
- /**
3936
- * Removes the selected item matching
3937
- * the provided value.
3938
- *
3939
- */
3940
-
3941
-
3942
- removeItem(item = null, silent) {
3943
- const self = this;
3944
- item = self.getItem(item);
3945
- if (!item) return;
3946
- var i, idx;
3947
- const value = item.dataset.value;
3948
- i = nodeIndex(item);
3949
- item.remove();
3950
-
3951
- if (item.classList.contains('active')) {
3952
- idx = self.activeItems.indexOf(item);
3953
- self.activeItems.splice(idx, 1);
3954
- removeClasses(item, 'active');
3955
- }
3956
-
3957
- self.items.splice(i, 1);
3958
- self.lastQuery = null;
3959
-
3960
- if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
3961
- self.removeOption(value, silent);
3962
- }
3963
-
3964
- if (i < self.caretPos) {
3965
- self.setCaret(self.caretPos - 1);
3966
- }
3967
-
3968
- self.updateOriginalInput({
3969
- silent: silent
3970
- });
3971
- self.refreshState();
3972
- self.positionDropdown();
3973
- self.trigger('item_remove', value, item);
3974
- }
3975
- /**
3976
- * Invokes the `create` method provided in the
3977
- * TomSelect options that should provide the data
3978
- * for the new item, given the user input.
3979
- *
3980
- * Once this completes, it will be added
3981
- * to the item list.
3982
- *
3983
- */
3984
-
3985
-
3986
- createItem(input = null, callback = () => {}) {
3987
- // triggerDropdown parameter @deprecated 2.1.1
3988
- if (arguments.length === 3) {
3989
- callback = arguments[2];
3990
- }
3991
-
3992
- if (typeof callback != 'function') {
3993
- callback = () => {};
3994
- }
3995
-
3996
- var self = this;
3997
- var caret = self.caretPos;
3998
- var output;
3999
- input = input || self.inputValue();
4000
-
4001
- if (!self.canCreate(input)) {
4002
- callback();
4003
- return false;
4004
- }
4005
-
4006
- self.lock();
4007
- var created = false;
4008
-
4009
- var create = data => {
4010
- self.unlock();
4011
- if (!data || typeof data !== 'object') return callback();
4012
- var value = hash_key(data[self.settings.valueField]);
4013
-
4014
- if (typeof value !== 'string') {
4015
- return callback();
4016
- }
4017
-
4018
- self.setTextboxValue();
4019
- self.addOption(data, true);
4020
- self.setCaret(caret);
4021
- self.addItem(value);
4022
- callback(data);
4023
- created = true;
4024
- };
4025
-
4026
- if (typeof self.settings.create === 'function') {
4027
- output = self.settings.create.call(this, input, create);
4028
- } else {
4029
- output = {
4030
- [self.settings.labelField]: input,
4031
- [self.settings.valueField]: input
4032
- };
4033
- }
4034
-
4035
- if (!created) {
4036
- create(output);
4037
- }
4038
-
4039
- return true;
4040
- }
4041
- /**
4042
- * Re-renders the selected item lists.
4043
- */
4044
-
4045
-
4046
- refreshItems() {
4047
- var self = this;
4048
- self.lastQuery = null;
4049
-
4050
- if (self.isSetup) {
4051
- self.addItems(self.items);
4052
- }
4053
-
4054
- self.updateOriginalInput();
4055
- self.refreshState();
4056
- }
4057
- /**
4058
- * Updates all state-dependent attributes
4059
- * and CSS classes.
4060
- */
4061
-
4062
-
4063
- refreshState() {
4064
- const self = this;
4065
- self.refreshValidityState();
4066
- const isFull = self.isFull();
4067
- const isLocked = self.isLocked;
4068
- self.wrapper.classList.toggle('rtl', self.rtl);
4069
- const wrap_classList = self.wrapper.classList;
4070
- wrap_classList.toggle('focus', self.isFocused);
4071
- wrap_classList.toggle('disabled', self.isDisabled);
4072
- wrap_classList.toggle('required', self.isRequired);
4073
- wrap_classList.toggle('invalid', !self.isValid);
4074
- wrap_classList.toggle('locked', isLocked);
4075
- wrap_classList.toggle('full', isFull);
4076
- wrap_classList.toggle('input-active', self.isFocused && !self.isInputHidden);
4077
- wrap_classList.toggle('dropdown-active', self.isOpen);
4078
- wrap_classList.toggle('has-options', isEmptyObject(self.options));
4079
- wrap_classList.toggle('has-items', self.items.length > 0);
4080
- }
4081
- /**
4082
- * Update the `required` attribute of both input and control input.
4083
- *
4084
- * The `required` property needs to be activated on the control input
4085
- * for the error to be displayed at the right place. `required` also
4086
- * needs to be temporarily deactivated on the input since the input is
4087
- * hidden and can't show errors.
4088
- */
4089
-
4090
-
4091
- refreshValidityState() {
4092
- var self = this;
4093
-
4094
- if (!self.input.validity) {
4095
- return;
4096
- }
4097
-
4098
- self.isValid = self.input.validity.valid;
4099
- self.isInvalid = !self.isValid;
4100
- }
4101
- /**
4102
- * Determines whether or not more items can be added
4103
- * to the control without exceeding the user-defined maximum.
4104
- *
4105
- * @returns {boolean}
4106
- */
4107
-
4108
-
4109
- isFull() {
4110
- return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;
4111
- }
4112
- /**
4113
- * Refreshes the original <select> or <input>
4114
- * element to reflect the current state.
4115
- *
4116
- */
4117
-
4118
-
4119
- updateOriginalInput(opts = {}) {
4120
- const self = this;
4121
- var option, label;
4122
- const empty_option = self.input.querySelector('option[value=""]');
4123
-
4124
- if (self.is_select_tag) {
4125
- const selected = [];
4126
- const has_selected = self.input.querySelectorAll('option:checked').length;
4127
-
4128
- function AddSelected(option_el, value, label) {
4129
- if (!option_el) {
4130
- option_el = getDom('<option value="' + escape_html(value) + '">' + escape_html(label) + '</option>');
4131
- } // don't move empty option from top of list
4132
- // fixes bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1725293
4133
-
4134
-
4135
- if (option_el != empty_option) {
4136
- self.input.append(option_el);
4137
- }
4138
-
4139
- selected.push(option_el); // marking empty option as selected can break validation
4140
- // fixes https://github.com/orchidjs/tom-select/issues/303
4141
-
4142
- if (option_el != empty_option || has_selected > 0) {
4143
- option_el.selected = true;
4144
- }
4145
-
4146
- return option_el;
4147
- } // unselect all selected options
4148
-
4149
-
4150
- self.input.querySelectorAll('option:checked').forEach(option_el => {
4151
- option_el.selected = false;
4152
- }); // nothing selected?
4153
-
4154
- if (self.items.length == 0 && self.settings.mode == 'single') {
4155
- AddSelected(empty_option, "", ""); // order selected <option> tags for values in self.items
4156
- } else {
4157
- self.items.forEach(value => {
4158
- option = self.options[value];
4159
- label = option[self.settings.labelField] || '';
4160
-
4161
- if (selected.includes(option.$option)) {
4162
- const reuse_opt = self.input.querySelector(`option[value="${addSlashes(value)}"]:not(:checked)`);
4163
- AddSelected(reuse_opt, value, label);
4164
- } else {
4165
- option.$option = AddSelected(option.$option, value, label);
4166
- }
4167
- });
4168
- }
4169
- } else {
4170
- self.input.value = self.getValue();
4171
- }
4172
-
4173
- if (self.isSetup) {
4174
- if (!opts.silent) {
4175
- self.trigger('change', self.getValue());
4176
- }
4177
- }
4178
- }
4179
- /**
4180
- * Shows the autocomplete dropdown containing
4181
- * the available options.
4182
- */
4183
-
4184
-
4185
- open() {
4186
- var self = this;
4187
- if (self.isLocked || self.isOpen || self.settings.mode === 'multi' && self.isFull()) return;
4188
- self.isOpen = true;
4189
- setAttr(self.focus_node, {
4190
- 'aria-expanded': 'true'
4191
- });
4192
- self.refreshState();
4193
- applyCSS(self.dropdown, {
4194
- visibility: 'hidden',
4195
- display: 'block'
4196
- });
4197
- self.positionDropdown();
4198
- applyCSS(self.dropdown, {
4199
- visibility: 'visible',
4200
- display: 'block'
4201
- });
4202
- self.focus();
4203
- self.trigger('dropdown_open', self.dropdown);
4204
- }
4205
- /**
4206
- * Closes the autocomplete dropdown menu.
4207
- */
4208
-
4209
-
4210
- close(setTextboxValue = true) {
4211
- var self = this;
4212
- var trigger = self.isOpen;
4213
-
4214
- if (setTextboxValue) {
4215
- // before blur() to prevent form onchange event
4216
- self.setTextboxValue();
4217
-
4218
- if (self.settings.mode === 'single' && self.items.length) {
4219
- self.hideInput();
4220
- }
4221
- }
4222
-
4223
- self.isOpen = false;
4224
- setAttr(self.focus_node, {
4225
- 'aria-expanded': 'false'
4226
- });
4227
- applyCSS(self.dropdown, {
4228
- display: 'none'
4229
- });
4230
-
4231
- if (self.settings.hideSelected) {
4232
- self.clearActiveOption();
4233
- }
4234
-
4235
- self.refreshState();
4236
- if (trigger) self.trigger('dropdown_close', self.dropdown);
4237
- }
4238
- /**
4239
- * Calculates and applies the appropriate
4240
- * position of the dropdown if dropdownParent = 'body'.
4241
- * Otherwise, position is determined by css
4242
- */
4243
-
4244
-
4245
- positionDropdown() {
4246
- if (this.settings.dropdownParent !== 'body') {
4247
- return;
4248
- }
4249
-
4250
- var context = this.control;
4251
- var rect = context.getBoundingClientRect();
4252
- var top = context.offsetHeight + rect.top + window.scrollY;
4253
- var left = rect.left + window.scrollX;
4254
- applyCSS(this.dropdown, {
4255
- width: rect.width + 'px',
4256
- top: top + 'px',
4257
- left: left + 'px'
4258
- });
4259
- }
4260
- /**
4261
- * Resets / clears all selected items
4262
- * from the control.
4263
- *
4264
- */
4265
-
4266
-
4267
- clear(silent) {
4268
- var self = this;
4269
- if (!self.items.length) return;
4270
- var items = self.controlChildren();
4271
- iterate$1(items, item => {
4272
- self.removeItem(item, true);
4273
- });
4274
- self.showInput();
4275
- if (!silent) self.updateOriginalInput();
4276
- self.trigger('clear');
4277
- }
4278
- /**
4279
- * A helper method for inserting an element
4280
- * at the current caret position.
4281
- *
4282
- */
4283
-
4284
-
4285
- insertAtCaret(el) {
4286
- const self = this;
4287
- const caret = self.caretPos;
4288
- const target = self.control;
4289
- target.insertBefore(el, target.children[caret] || null);
4290
- self.setCaret(caret + 1);
4291
- }
4292
- /**
4293
- * Removes the current selected item(s).
4294
- *
4295
- */
4296
-
4297
-
4298
- deleteSelection(e) {
4299
- var direction, selection, caret, tail;
4300
- var self = this;
4301
- direction = e && e.keyCode === KEY_BACKSPACE ? -1 : 1;
4302
- selection = getSelection(self.control_input); // determine items that will be removed
4303
-
4304
- const rm_items = [];
4305
-
4306
- if (self.activeItems.length) {
4307
- tail = getTail(self.activeItems, direction);
4308
- caret = nodeIndex(tail);
4309
-
4310
- if (direction > 0) {
4311
- caret++;
4312
- }
4313
-
4314
- iterate$1(self.activeItems, item => rm_items.push(item));
4315
- } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {
4316
- const items = self.controlChildren();
4317
- let rm_item;
4318
-
4319
- if (direction < 0 && selection.start === 0 && selection.length === 0) {
4320
- rm_item = items[self.caretPos - 1];
4321
- } else if (direction > 0 && selection.start === self.inputValue().length) {
4322
- rm_item = items[self.caretPos];
4323
- }
4324
-
4325
- if (rm_item !== undefined) {
4326
- rm_items.push(rm_item);
4327
- }
4328
- }
4329
-
4330
- if (!self.shouldDelete(rm_items, e)) {
4331
- return false;
4332
- }
4333
-
4334
- preventDefault(e, true); // perform removal
4335
-
4336
- if (typeof caret !== 'undefined') {
4337
- self.setCaret(caret);
4338
- }
4339
-
4340
- while (rm_items.length) {
4341
- self.removeItem(rm_items.pop());
4342
- }
4343
-
4344
- self.showInput();
4345
- self.positionDropdown();
4346
- self.refreshOptions(false);
4347
- return true;
4348
- }
4349
- /**
4350
- * Return true if the items should be deleted
4351
- */
4352
-
4353
-
4354
- shouldDelete(items, evt) {
4355
- const values = items.map(item => item.dataset.value); // allow the callback to abort
4356
-
4357
- if (!values.length || typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false) {
4358
- return false;
4359
- }
4360
-
4361
- return true;
4362
- }
4363
- /**
4364
- * Selects the previous / next item (depending on the `direction` argument).
4365
- *
4366
- * > 0 - right
4367
- * < 0 - left
4368
- *
4369
- */
4370
-
4371
-
4372
- advanceSelection(direction, e) {
4373
- var last_active,
4374
- adjacent,
4375
- self = this;
4376
- if (self.rtl) direction *= -1;
4377
- if (self.inputValue().length) return; // add or remove to active items
4378
-
4379
- if (isKeyDown(KEY_SHORTCUT, e) || isKeyDown('shiftKey', e)) {
4380
- last_active = self.getLastActive(direction);
4381
-
4382
- if (last_active) {
4383
- if (!last_active.classList.contains('active')) {
4384
- adjacent = last_active;
4385
- } else {
4386
- adjacent = self.getAdjacent(last_active, direction, 'item');
4387
- } // if no active item, get items adjacent to the control input
4388
-
4389
- } else if (direction > 0) {
4390
- adjacent = self.control_input.nextElementSibling;
4391
- } else {
4392
- adjacent = self.control_input.previousElementSibling;
4393
- }
4394
-
4395
- if (adjacent) {
4396
- if (adjacent.classList.contains('active')) {
4397
- self.removeActiveItem(last_active);
4398
- }
4399
-
4400
- self.setActiveItemClass(adjacent); // mark as last_active !! after removeActiveItem() on last_active
4401
- } // move caret to the left or right
4402
-
4403
- } else {
4404
- self.moveCaret(direction);
4405
- }
4406
- }
4407
-
4408
- moveCaret(direction) {}
4409
- /**
4410
- * Get the last active item
4411
- *
4412
- */
4413
-
4414
-
4415
- getLastActive(direction) {
4416
- let last_active = this.control.querySelector('.last-active');
4417
-
4418
- if (last_active) {
4419
- return last_active;
4420
- }
4421
-
4422
- var result = this.control.querySelectorAll('.active');
4423
-
4424
- if (result) {
4425
- return getTail(result, direction);
4426
- }
4427
- }
4428
- /**
4429
- * Moves the caret to the specified index.
4430
- *
4431
- * The input must be moved by leaving it in place and moving the
4432
- * siblings, due to the fact that focus cannot be restored once lost
4433
- * on mobile webkit devices
4434
- *
4435
- */
4436
-
4437
-
4438
- setCaret(new_pos) {
4439
- this.caretPos = this.items.length;
4440
- }
4441
- /**
4442
- * Return list of item dom elements
4443
- *
4444
- */
4445
-
4446
-
4447
- controlChildren() {
4448
- return Array.from(this.control.querySelectorAll('[data-ts-item]'));
4449
- }
4450
- /**
4451
- * Disables user input on the control. Used while
4452
- * items are being asynchronously created.
4453
- */
4454
-
4455
-
4456
- lock() {
4457
- this.isLocked = true;
4458
- this.refreshState();
4459
- }
4460
- /**
4461
- * Re-enables user input on the control.
4462
- */
4463
-
4464
-
4465
- unlock() {
4466
- this.isLocked = false;
4467
- this.refreshState();
4468
- }
4469
- /**
4470
- * Disables user input on the control completely.
4471
- * While disabled, it cannot receive focus.
4472
- */
4473
-
4474
-
4475
- disable() {
4476
- var self = this;
4477
- self.input.disabled = true;
4478
- self.control_input.disabled = true;
4479
- self.focus_node.tabIndex = -1;
4480
- self.isDisabled = true;
4481
- this.close();
4482
- self.lock();
4483
- }
4484
- /**
4485
- * Enables the control so that it can respond
4486
- * to focus and user input.
4487
- */
4488
-
4489
-
4490
- enable() {
4491
- var self = this;
4492
- self.input.disabled = false;
4493
- self.control_input.disabled = false;
4494
- self.focus_node.tabIndex = self.tabIndex;
4495
- self.isDisabled = false;
4496
- self.unlock();
4497
- }
4498
- /**
4499
- * Completely destroys the control and
4500
- * unbinds all event listeners so that it can
4501
- * be garbage collected.
4502
- */
4503
-
4504
-
4505
- destroy() {
4506
- var self = this;
4507
- var revertSettings = self.revertSettings;
4508
- self.trigger('destroy');
4509
- self.off();
4510
- self.wrapper.remove();
4511
- self.dropdown.remove();
4512
- self.input.innerHTML = revertSettings.innerHTML;
4513
- self.input.tabIndex = revertSettings.tabIndex;
4514
- removeClasses(self.input, 'tomselected', 'ts-hidden-accessible');
4515
-
4516
- self._destroy();
4517
-
4518
- delete self.input.tomselect;
4519
- }
4520
- /**
4521
- * A helper method for rendering "item" and
4522
- * "option" templates, given the data.
4523
- *
4524
- */
4525
-
4526
-
4527
- render(templateName, data) {
4528
- var id, html;
4529
- const self = this;
4530
-
4531
- if (typeof this.settings.render[templateName] !== 'function') {
4532
- return null;
4533
- } // render markup
4534
-
4535
-
4536
- html = self.settings.render[templateName].call(this, data, escape_html);
4537
-
4538
- if (!html) {
4539
- return null;
4540
- }
4541
-
4542
- html = getDom(html); // add mandatory attributes
4543
-
4544
- if (templateName === 'option' || templateName === 'option_create') {
4545
- if (data[self.settings.disabledField]) {
4546
- setAttr(html, {
4547
- 'aria-disabled': 'true'
4548
- });
4549
- } else {
4550
- setAttr(html, {
4551
- 'data-selectable': ''
4552
- });
4553
- }
4554
- } else if (templateName === 'optgroup') {
4555
- id = data.group[self.settings.optgroupValueField];
4556
- setAttr(html, {
4557
- 'data-group': id
4558
- });
4559
-
4560
- if (data.group[self.settings.disabledField]) {
4561
- setAttr(html, {
4562
- 'data-disabled': ''
4563
- });
4564
- }
4565
- }
4566
-
4567
- if (templateName === 'option' || templateName === 'item') {
4568
- const value = get_hash(data[self.settings.valueField]);
4569
- setAttr(html, {
4570
- 'data-value': value
4571
- }); // make sure we have some classes if a template is overwritten
4572
-
4573
- if (templateName === 'item') {
4574
- addClasses(html, self.settings.itemClass);
4575
- setAttr(html, {
4576
- 'data-ts-item': ''
4577
- });
4578
- } else {
4579
- addClasses(html, self.settings.optionClass);
4580
- setAttr(html, {
4581
- role: 'option',
4582
- id: data.$id
4583
- }); // update cache
4584
-
4585
- data.$div = html;
4586
- self.options[value] = data;
4587
- }
4588
- }
4589
-
4590
- return html;
4591
- }
4592
- /**
4593
- * Type guarded rendering
4594
- *
4595
- */
4596
-
4597
-
4598
- _render(templateName, data) {
4599
- const html = this.render(templateName, data);
4600
-
4601
- if (html == null) {
4602
- throw 'HTMLElement expected';
4603
- }
4604
-
4605
- return html;
4606
- }
4607
- /**
4608
- * Clears the render cache for a template. If
4609
- * no template is given, clears all render
4610
- * caches.
4611
- *
4612
- */
4613
-
4614
-
4615
- clearCache() {
4616
- iterate$1(this.options, option => {
4617
- if (option.$div) {
4618
- option.$div.remove();
4619
- delete option.$div;
4620
- }
4621
- });
4622
- }
4623
- /**
4624
- * Removes a value from item and option caches
4625
- *
4626
- */
4627
-
4628
-
4629
- uncacheValue(value) {
4630
- const option_el = this.getOption(value);
4631
- if (option_el) option_el.remove();
4632
- }
4633
- /**
4634
- * Determines whether or not to display the
4635
- * create item prompt, given a user input.
4636
- *
4637
- */
4638
-
4639
-
4640
- canCreate(input) {
4641
- return this.settings.create && input.length > 0 && this.settings.createFilter.call(this, input);
4642
- }
4643
- /**
4644
- * Wraps this.`method` so that `new_fn` can be invoked 'before', 'after', or 'instead' of the original method
4645
- *
4646
- * this.hook('instead','onKeyDown',function( arg1, arg2 ...){
4647
- *
4648
- * });
4649
- */
4650
-
4651
-
4652
- hook(when, method, new_fn) {
4653
- var self = this;
4654
- var orig_method = self[method];
4655
-
4656
- self[method] = function () {
4657
- var result, result_new;
4658
-
4659
- if (when === 'after') {
4660
- result = orig_method.apply(self, arguments);
4661
- }
4662
-
4663
- result_new = new_fn.apply(self, arguments);
4664
-
4665
- if (when === 'instead') {
4666
- return result_new;
4667
- }
4668
-
4669
- if (when === 'before') {
4670
- result = orig_method.apply(self, arguments);
4671
- }
4672
-
4673
- return result;
4674
- };
4675
- }
4676
-
4677
- }
4678
-
4679
- /**
4680
- * Plugin: "dropdown_input" (Tom Select)
4681
- * Copyright (c) contributors
4682
- *
4683
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4684
- * file except in compliance with the License. You may obtain a copy of the License at:
4685
- * http://www.apache.org/licenses/LICENSE-2.0
4686
- *
4687
- * Unless required by applicable law or agreed to in writing, software distributed under
4688
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4689
- * ANY KIND, either express or implied. See the License for the specific language
4690
- * governing permissions and limitations under the License.
4691
- *
4692
- */
4693
- function caret_position () {
4694
- var self = this;
4695
- /**
4696
- * Moves the caret to the specified index.
4697
- *
4698
- * The input must be moved by leaving it in place and moving the
4699
- * siblings, due to the fact that focus cannot be restored once lost
4700
- * on mobile webkit devices
4701
- *
4702
- */
4703
-
4704
- self.hook('instead', 'setCaret', new_pos => {
4705
- if (self.settings.mode === 'single' || !self.control.contains(self.control_input)) {
4706
- new_pos = self.items.length;
4707
- } else {
4708
- new_pos = Math.max(0, Math.min(self.items.length, new_pos));
4709
-
4710
- if (new_pos != self.caretPos && !self.isPending) {
4711
- self.controlChildren().forEach((child, j) => {
4712
- if (j < new_pos) {
4713
- self.control_input.insertAdjacentElement('beforebegin', child);
4714
- } else {
4715
- self.control.appendChild(child);
4716
- }
4717
- });
4718
- }
4719
- }
4720
-
4721
- self.caretPos = new_pos;
4722
- });
4723
- self.hook('instead', 'moveCaret', direction => {
4724
- if (!self.isFocused) return; // move caret before or after selected items
4725
-
4726
- const last_active = self.getLastActive(direction);
4727
-
4728
- if (last_active) {
4729
- const idx = nodeIndex(last_active);
4730
- self.setCaret(direction > 0 ? idx + 1 : idx);
4731
- self.setActiveItem();
4732
- removeClasses(last_active, 'last-active'); // move caret left or right of current position
4733
- } else {
4734
- self.setCaret(self.caretPos + direction);
4735
- }
4736
- });
4737
- }
4738
-
4739
- /**
4740
- * Plugin: "dropdown_input" (Tom Select)
4741
- * Copyright (c) contributors
4742
- *
4743
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4744
- * file except in compliance with the License. You may obtain a copy of the License at:
4745
- * http://www.apache.org/licenses/LICENSE-2.0
4746
- *
4747
- * Unless required by applicable law or agreed to in writing, software distributed under
4748
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4749
- * ANY KIND, either express or implied. See the License for the specific language
4750
- * governing permissions and limitations under the License.
4751
- *
4752
- */
4753
- function dropdown_input () {
4754
- const self = this;
4755
- self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown
4756
-
4757
- self.hook('before', 'setup', () => {
4758
- self.focus_node = self.control;
4759
- addClasses(self.control_input, 'dropdown-input');
4760
- const div = getDom('<div class="dropdown-input-wrap">');
4761
- div.append(self.control_input);
4762
- self.dropdown.insertBefore(div, self.dropdown.firstChild); // set a placeholder in the select control
4763
-
4764
- const placeholder = getDom('<input class="items-placeholder" tabindex="-1" />');
4765
- placeholder.placeholder = self.settings.placeholder || '';
4766
- self.control.append(placeholder);
4767
- });
4768
- self.on('initialize', () => {
4769
- // set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input
4770
- self.control_input.addEventListener('keydown', evt => {
4771
- //addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{
4772
- switch (evt.keyCode) {
4773
- case KEY_ESC:
4774
- if (self.isOpen) {
4775
- preventDefault(evt, true);
4776
- self.close();
4777
- }
4778
-
4779
- self.clearActiveItems();
4780
- return;
4781
-
4782
- case KEY_TAB:
4783
- self.focus_node.tabIndex = -1;
4784
- break;
4785
- }
4786
-
4787
- return self.onKeyDown.call(self, evt);
4788
- });
4789
- self.on('blur', () => {
4790
- self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;
4791
- }); // give the control_input focus when the dropdown is open
4792
-
4793
- self.on('dropdown_open', () => {
4794
- self.control_input.focus();
4795
- }); // prevent onBlur from closing when focus is on the control_input
4796
-
4797
- const orig_onBlur = self.onBlur;
4798
- self.hook('instead', 'onBlur', evt => {
4799
- if (evt && evt.relatedTarget == self.control_input) return;
4800
- return orig_onBlur.call(self);
4801
- });
4802
- addEvent(self.control_input, 'blur', () => self.onBlur()); // return focus to control to allow further keyboard input
4803
-
4804
- self.hook('before', 'close', () => {
4805
- if (!self.isOpen) return;
4806
- self.focus_node.focus({
4807
- preventScroll: true
4808
- });
4809
- });
4810
- });
4811
- }
4812
-
4813
- /**
4814
- * Plugin: "input_autogrow" (Tom Select)
4815
- *
4816
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4817
- * file except in compliance with the License. You may obtain a copy of the License at:
4818
- * http://www.apache.org/licenses/LICENSE-2.0
4819
- *
4820
- * Unless required by applicable law or agreed to in writing, software distributed under
4821
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4822
- * ANY KIND, either express or implied. See the License for the specific language
4823
- * governing permissions and limitations under the License.
4824
- *
4825
- */
4826
- function no_backspace_delete () {
4827
- var self = this;
4828
- var orig_deleteSelection = self.deleteSelection;
4829
- this.hook('instead', 'deleteSelection', evt => {
4830
- if (self.activeItems.length) {
4831
- return orig_deleteSelection.call(self, evt);
4832
- }
4833
-
4834
- return false;
4835
- });
4836
- }
4837
-
4838
- /**
4839
- * Plugin: "remove_button" (Tom Select)
4840
- * Copyright (c) contributors
4841
- *
4842
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4843
- * file except in compliance with the License. You may obtain a copy of the License at:
4844
- * http://www.apache.org/licenses/LICENSE-2.0
4845
- *
4846
- * Unless required by applicable law or agreed to in writing, software distributed under
4847
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4848
- * ANY KIND, either express or implied. See the License for the specific language
4849
- * governing permissions and limitations under the License.
4850
- *
4851
- */
4852
- function remove_button (userOptions) {
4853
- const options = Object.assign({
4854
- label: '&times;',
4855
- title: 'Remove',
4856
- className: 'remove',
4857
- append: true
4858
- }, userOptions); //options.className = 'remove-single';
4859
-
4860
- var self = this; // override the render method to add remove button to each item
4861
-
4862
- if (!options.append) {
4863
- return;
4864
- }
4865
-
4866
- var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
4867
- self.hook('after', 'setupTemplates', () => {
4868
- var orig_render_item = self.settings.render.item;
4869
-
4870
- self.settings.render.item = (data, escape) => {
4871
- var item = getDom(orig_render_item.call(self, data, escape));
4872
- var close_button = getDom(html);
4873
- item.appendChild(close_button);
4874
- addEvent(close_button, 'mousedown', evt => {
4875
- preventDefault(evt, true);
4876
- });
4877
- addEvent(close_button, 'click', evt => {
4878
- // propagating will trigger the dropdown to show for single mode
4879
- preventDefault(evt, true);
4880
- if (self.isLocked) return;
4881
- if (!self.shouldDelete([item], evt)) return;
4882
- self.removeItem(item);
4883
- self.refreshOptions(false);
4884
- self.inputState();
4885
- });
4886
- return item;
4887
- };
4888
- });
4889
- }
4890
-
4891
- /**
4892
- * Plugin: "restore_on_backspace" (Tom Select)
4893
- * Copyright (c) contributors
4894
- *
4895
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4896
- * file except in compliance with the License. You may obtain a copy of the License at:
4897
- * http://www.apache.org/licenses/LICENSE-2.0
4898
- *
4899
- * Unless required by applicable law or agreed to in writing, software distributed under
4900
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4901
- * ANY KIND, either express or implied. See the License for the specific language
4902
- * governing permissions and limitations under the License.
4903
- *
4904
- */
4905
- function restore_on_backspace (userOptions) {
4906
- const self = this;
4907
- const options = Object.assign({
4908
- text: option => {
4909
- return option[self.settings.labelField];
4910
- }
4911
- }, userOptions);
4912
- self.on('item_remove', function (value) {
4913
- if (!self.isFocused) {
4914
- return;
4915
- }
4916
-
4917
- if (self.control_input.value.trim() === '') {
4918
- var option = self.options[value];
4919
-
4920
- if (option) {
4921
- self.setTextboxValue(options.text.call(self, option));
4922
- }
4923
- }
4924
- });
4925
- }
4926
-
4927
- TomSelect.define('caret_position', caret_position);
4928
- TomSelect.define('dropdown_input', dropdown_input);
4929
- TomSelect.define('no_backspace_delete', no_backspace_delete);
4930
- TomSelect.define('remove_button', remove_button);
4931
- TomSelect.define('restore_on_backspace', restore_on_backspace);
4932
-
4933
- module.exports = TomSelect;
4934
- //# sourceMappingURL=tom-select.popular.js.map
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tom_select_ts_1 = require("./tom-select.js");
4
+ const plugin_ts_1 = require("./plugins/caret_position/plugin.js");
5
+ const plugin_ts_2 = require("./plugins/dropdown_input/plugin.js");
6
+ const plugin_ts_3 = require("./plugins/no_backspace_delete/plugin.js");
7
+ const plugin_ts_4 = require("./plugins/remove_button/plugin.js");
8
+ const plugin_ts_5 = require("./plugins/restore_on_backspace/plugin.js");
9
+ tom_select_ts_1.default.define('caret_position', plugin_ts_1.default);
10
+ tom_select_ts_1.default.define('dropdown_input', plugin_ts_2.default);
11
+ tom_select_ts_1.default.define('no_backspace_delete', plugin_ts_3.default);
12
+ tom_select_ts_1.default.define('remove_button', plugin_ts_4.default);
13
+ tom_select_ts_1.default.define('restore_on_backspace', plugin_ts_5.default);
14
+ exports.default = tom_select_ts_1.default;
15
+ //# sourceMappingURL=tom-select.popular.js.map