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