stimulus-library 0.7.3 → 0.8.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/README.md +1 -1
  2. package/dist/controllers/ajax/async_block_controller.js +30 -0
  3. package/dist/controllers/ajax/{index.d.ts → index.js} +0 -1
  4. package/dist/controllers/ajax/lazy_block_controller.js +37 -0
  5. package/dist/controllers/ajax/load_block_controller.js +63 -0
  6. package/dist/controllers/ajax/poll_block_controller.js +35 -0
  7. package/dist/controllers/anchor_spy_controller.js +47 -0
  8. package/dist/controllers/back_link_controller.js +25 -0
  9. package/dist/controllers/clipboard_controller.js +35 -0
  10. package/dist/controllers/confirm_controller.js +33 -0
  11. package/dist/controllers/confirm_navigation_controller.js +29 -0
  12. package/dist/controllers/debug_controller.js +7 -0
  13. package/dist/controllers/disable_with_controller.js +66 -0
  14. package/dist/controllers/dismissable_controller.js +8 -0
  15. package/dist/controllers/element_save_controller.js +80 -0
  16. package/dist/controllers/empty_dom_controller.js +42 -0
  17. package/dist/controllers/equalize_controller.js +39 -0
  18. package/dist/controllers/forms/auto_submit_form_controller.js +62 -0
  19. package/dist/controllers/forms/autosize_controller.js +32 -0
  20. package/dist/controllers/forms/char_count_controller.js +37 -0
  21. package/dist/controllers/forms/checkbox_disable_inputs_controller.js +32 -0
  22. package/dist/controllers/forms/checkbox_enable_inputs_controller.js +32 -0
  23. package/dist/controllers/forms/checkbox_select_all_controller.js +35 -0
  24. package/dist/controllers/forms/checkbox_xor_controller.js +24 -0
  25. package/dist/controllers/forms/detect_dirty_controller.js +98 -0
  26. package/dist/controllers/forms/detect_dirty_form_controller.js +107 -0
  27. package/dist/controllers/forms/enable_inputs_controller.js +21 -0
  28. package/dist/controllers/forms/focus_steal_controller.js +28 -0
  29. package/dist/controllers/forms/form_rc_controller.js +47 -0
  30. package/dist/controllers/forms/form_save_controller.js +109 -0
  31. package/dist/controllers/forms/{index.d.ts → index.js} +0 -1
  32. package/dist/controllers/forms/limited_selection_checkboxes_controller.js +28 -0
  33. package/dist/controllers/forms/navigate_form_errors_controller.js +154 -0
  34. package/dist/controllers/forms/nested_form_controller.js +49 -0
  35. package/dist/controllers/forms/password_confirm_controller.js +26 -0
  36. package/dist/controllers/forms/password_peek_controller.js +21 -0
  37. package/dist/controllers/forms/remote_form_controller.js +26 -0
  38. package/dist/controllers/forms/sync_inputs_controller.js +67 -0
  39. package/dist/controllers/forms/value_warn_controller.js +45 -0
  40. package/dist/controllers/forms/word_count_controller.js +37 -0
  41. package/dist/controllers/{index.d.ts → index.js} +3 -1
  42. package/dist/controllers/media/fallback_image_controller.js +44 -0
  43. package/dist/controllers/media/{index.d.ts → index.js} +0 -1
  44. package/dist/controllers/media/lightbox_image_controller.js +71 -0
  45. package/dist/controllers/media/media_player_controller.js +31 -0
  46. package/dist/controllers/prefetch_controller.js +74 -0
  47. package/dist/controllers/print_button_controller.js +18 -0
  48. package/dist/controllers/responsive_iframe_controller.js +35 -0
  49. package/dist/controllers/scroll/{index.d.ts → index.js} +0 -1
  50. package/dist/controllers/scroll/scroll_container_controller.js +81 -0
  51. package/dist/controllers/scroll/scroll_into_focus_controller.js +20 -0
  52. package/dist/controllers/scroll/scroll_to_bottom_controller.js +37 -0
  53. package/dist/controllers/scroll/scroll_to_controller.js +22 -0
  54. package/dist/controllers/scroll/scroll_to_top_controller.js +37 -0
  55. package/dist/controllers/self_destruct_controller.js +11 -0
  56. package/dist/controllers/signal/events.js +12 -0
  57. package/dist/controllers/signal/expressions.js +54 -0
  58. package/dist/controllers/signal/{index.d.ts → index.js} +0 -1
  59. package/dist/controllers/signal/signal_action_controller.js +31 -0
  60. package/dist/controllers/signal/signal_dom_children_controller.js +40 -0
  61. package/dist/controllers/signal/signal_input_controller.js +36 -0
  62. package/dist/controllers/signal/signal_visibility_controller.js +44 -0
  63. package/dist/controllers/sticky_controller.js +44 -0
  64. package/dist/controllers/tables/{index.d.ts → index.js} +0 -1
  65. package/dist/controllers/tables/table_sort_controller.js +97 -0
  66. package/dist/controllers/tables/table_truncate_controller.js +81 -0
  67. package/dist/controllers/teleport_controller.js +48 -0
  68. package/dist/controllers/temporary_state_controller.js +65 -0
  69. package/dist/controllers/toggle_class_controller.js +115 -0
  70. package/dist/controllers/trix_modifier_controller.js +121 -0
  71. package/dist/controllers/turbo_frame_rc_controller.js +65 -0
  72. package/dist/controllers/turbo_frame_refresh_controller.js +32 -0
  73. package/dist/controllers/utility/alert_controller.js +7 -0
  74. package/dist/controllers/utility/fullscreen_controller.js +10 -0
  75. package/dist/controllers/utility/{index.d.ts → index.js} +0 -1
  76. package/dist/controllers/utility/intersection_controller.js +25 -0
  77. package/dist/controllers/utility/interval_controller.js +16 -0
  78. package/dist/controllers/utility/presence_controller.js +19 -0
  79. package/dist/controllers/utility/print_controller.js +7 -0
  80. package/dist/controllers/utility/timeout_controller.js +13 -0
  81. package/dist/controllers/utility/user_focus_controller.js +23 -0
  82. package/dist/controllers/visual/clock_controller.js +51 -0
  83. package/dist/controllers/visual/countdown_controller.js +116 -0
  84. package/dist/controllers/visual/duration_controller.js +79 -0
  85. package/dist/controllers/visual/{index.d.ts → index.js} +0 -1
  86. package/dist/controllers/visual/tabs_controller.js +79 -0
  87. package/dist/controllers/visual/time_distance_controller.js +50 -0
  88. package/dist/controllers/visual/tree_view_controller.js +92 -0
  89. package/dist/{index.d.ts → index.js} +3 -1
  90. package/dist/mixins/create_mixin.js +11 -0
  91. package/dist/mixins/{index.d.ts → index.js} +0 -1
  92. package/dist/mixins/install_class_methods.js +28 -0
  93. package/dist/mixins/use_click_outside.js +17 -0
  94. package/dist/mixins/use_event_bus.js +19 -0
  95. package/dist/mixins/use_event_listener.js +34 -0
  96. package/dist/mixins/use_fullscreen.js +42 -0
  97. package/dist/mixins/use_geolocation.js +62 -0
  98. package/dist/mixins/use_hover.js +29 -0
  99. package/dist/mixins/use_injected_html.js +37 -0
  100. package/dist/mixins/use_intersection.js +45 -0
  101. package/dist/mixins/use_interval.js +13 -0
  102. package/dist/mixins/use_localstorage.js +122 -0
  103. package/dist/mixins/use_mutation_observer.js +9 -0
  104. package/dist/mixins/use_temporary_content.js +38 -0
  105. package/dist/mixins/use_timeout.js +20 -0
  106. package/dist/mixins/use_trix_modifiers.js +71 -0
  107. package/dist/polyfills/string.replaceAll.js +13 -0
  108. package/dist/utilities/arrays.js +3 -0
  109. package/dist/utilities/base_controller.js +56 -0
  110. package/dist/utilities/elements.js +102 -0
  111. package/dist/utilities/ephemeral_controller.js +42 -0
  112. package/dist/utilities/event_bus.js +2 -0
  113. package/dist/utilities/events.js +10 -0
  114. package/dist/utilities/fetchRetry.js +22 -0
  115. package/dist/utilities/{index.d.ts → index.js} +0 -1
  116. package/dist/utilities/logging.js +82 -0
  117. package/dist/utilities/reactive.js +23 -0
  118. package/dist/utilities/request_submit.js +20 -0
  119. package/dist/utilities/scroll.js +89 -0
  120. package/dist/utilities/stimulus.js +13 -0
  121. package/dist/utilities/strings.js +5 -0
  122. package/dist/utilities/turbo.js +3 -0
  123. package/package.json +8 -18
  124. package/CHANGELOG.md +0 -499
  125. package/dist/controllers/ajax/async_block_controller.d.ts +0 -18
  126. package/dist/controllers/ajax/async_block_controller.d.ts.map +0 -1
  127. package/dist/controllers/ajax/index.d.ts.map +0 -1
  128. package/dist/controllers/ajax/lazy_block_controller.d.ts +0 -10
  129. package/dist/controllers/ajax/lazy_block_controller.d.ts.map +0 -1
  130. package/dist/controllers/ajax/load_block_controller.d.ts +0 -24
  131. package/dist/controllers/ajax/load_block_controller.d.ts.map +0 -1
  132. package/dist/controllers/ajax/poll_block_controller.d.ts +0 -16
  133. package/dist/controllers/ajax/poll_block_controller.d.ts.map +0 -1
  134. package/dist/controllers/anchor_spy_controller.d.ts +0 -21
  135. package/dist/controllers/anchor_spy_controller.d.ts.map +0 -1
  136. package/dist/controllers/back_link_controller.d.ts +0 -17
  137. package/dist/controllers/back_link_controller.d.ts.map +0 -1
  138. package/dist/controllers/clipboard_controller.d.ts +0 -19
  139. package/dist/controllers/clipboard_controller.d.ts.map +0 -1
  140. package/dist/controllers/confirm_controller.d.ts +0 -13
  141. package/dist/controllers/confirm_controller.d.ts.map +0 -1
  142. package/dist/controllers/confirm_navigation_controller.d.ts +0 -15
  143. package/dist/controllers/confirm_navigation_controller.d.ts.map +0 -1
  144. package/dist/controllers/debug_controller.d.ts +0 -7
  145. package/dist/controllers/debug_controller.d.ts.map +0 -1
  146. package/dist/controllers/disable_with_controller.d.ts +0 -20
  147. package/dist/controllers/disable_with_controller.d.ts.map +0 -1
  148. package/dist/controllers/dismissable_controller.d.ts +0 -7
  149. package/dist/controllers/dismissable_controller.d.ts.map +0 -1
  150. package/dist/controllers/element_save_controller.d.ts +0 -31
  151. package/dist/controllers/element_save_controller.d.ts.map +0 -1
  152. package/dist/controllers/empty_dom_controller.d.ts +0 -22
  153. package/dist/controllers/empty_dom_controller.d.ts.map +0 -1
  154. package/dist/controllers/forms/auto_submit_form_controller.d.ts +0 -23
  155. package/dist/controllers/forms/auto_submit_form_controller.d.ts.map +0 -1
  156. package/dist/controllers/forms/autosize_controller.d.ts +0 -9
  157. package/dist/controllers/forms/autosize_controller.d.ts.map +0 -1
  158. package/dist/controllers/forms/char_count_controller.d.ts +0 -21
  159. package/dist/controllers/forms/char_count_controller.d.ts.map +0 -1
  160. package/dist/controllers/forms/checkbox_disable_inputs_controller.d.ts +0 -17
  161. package/dist/controllers/forms/checkbox_disable_inputs_controller.d.ts.map +0 -1
  162. package/dist/controllers/forms/checkbox_enable_inputs_controller.d.ts +0 -17
  163. package/dist/controllers/forms/checkbox_enable_inputs_controller.d.ts.map +0 -1
  164. package/dist/controllers/forms/checkbox_select_all_controller.d.ts +0 -14
  165. package/dist/controllers/forms/checkbox_select_all_controller.d.ts.map +0 -1
  166. package/dist/controllers/forms/checkbox_xor_controller.d.ts +0 -9
  167. package/dist/controllers/forms/checkbox_xor_controller.d.ts.map +0 -1
  168. package/dist/controllers/forms/detect_dirty_controller.d.ts +0 -15
  169. package/dist/controllers/forms/detect_dirty_controller.d.ts.map +0 -1
  170. package/dist/controllers/forms/detect_dirty_form_controller.d.ts +0 -18
  171. package/dist/controllers/forms/detect_dirty_form_controller.d.ts.map +0 -1
  172. package/dist/controllers/forms/enable_inputs_controller.d.ts +0 -14
  173. package/dist/controllers/forms/enable_inputs_controller.d.ts.map +0 -1
  174. package/dist/controllers/forms/focus_steal_controller.d.ts +0 -12
  175. package/dist/controllers/forms/focus_steal_controller.d.ts.map +0 -1
  176. package/dist/controllers/forms/form_rc_controller.d.ts +0 -18
  177. package/dist/controllers/forms/form_rc_controller.d.ts.map +0 -1
  178. package/dist/controllers/forms/form_save_controller.d.ts +0 -32
  179. package/dist/controllers/forms/form_save_controller.d.ts.map +0 -1
  180. package/dist/controllers/forms/index.d.ts.map +0 -1
  181. package/dist/controllers/forms/limited_selection_checkboxes_controller.d.ts +0 -17
  182. package/dist/controllers/forms/limited_selection_checkboxes_controller.d.ts.map +0 -1
  183. package/dist/controllers/forms/navigate_form_errors_controller.d.ts +0 -41
  184. package/dist/controllers/forms/navigate_form_errors_controller.d.ts.map +0 -1
  185. package/dist/controllers/forms/nested_form_controller.d.ts +0 -22
  186. package/dist/controllers/forms/nested_form_controller.d.ts.map +0 -1
  187. package/dist/controllers/forms/password_confirm_controller.d.ts +0 -12
  188. package/dist/controllers/forms/password_confirm_controller.d.ts.map +0 -1
  189. package/dist/controllers/forms/password_peek_controller.d.ts +0 -9
  190. package/dist/controllers/forms/password_peek_controller.d.ts.map +0 -1
  191. package/dist/controllers/forms/remote_form_controller.d.ts +0 -14
  192. package/dist/controllers/forms/remote_form_controller.d.ts.map +0 -1
  193. package/dist/controllers/forms/sync_inputs_controller.d.ts +0 -20
  194. package/dist/controllers/forms/sync_inputs_controller.d.ts.map +0 -1
  195. package/dist/controllers/forms/value_warn_controller.d.ts +0 -31
  196. package/dist/controllers/forms/value_warn_controller.d.ts.map +0 -1
  197. package/dist/controllers/forms/word_count_controller.d.ts +0 -21
  198. package/dist/controllers/forms/word_count_controller.d.ts.map +0 -1
  199. package/dist/controllers/index.d.ts.map +0 -1
  200. package/dist/controllers/media/fallback_image_controller.d.ts +0 -20
  201. package/dist/controllers/media/fallback_image_controller.d.ts.map +0 -1
  202. package/dist/controllers/media/index.d.ts.map +0 -1
  203. package/dist/controllers/media/lightbox_image_controller.d.ts +0 -31
  204. package/dist/controllers/media/lightbox_image_controller.d.ts.map +0 -1
  205. package/dist/controllers/media/media_player_controller.d.ts +0 -10
  206. package/dist/controllers/media/media_player_controller.d.ts.map +0 -1
  207. package/dist/controllers/prefetch_controller.d.ts +0 -17
  208. package/dist/controllers/prefetch_controller.d.ts.map +0 -1
  209. package/dist/controllers/print_button_controller.d.ts +0 -8
  210. package/dist/controllers/print_button_controller.d.ts.map +0 -1
  211. package/dist/controllers/responsive_iframe_controller.d.ts +0 -17
  212. package/dist/controllers/responsive_iframe_controller.d.ts.map +0 -1
  213. package/dist/controllers/scroll/index.d.ts.map +0 -1
  214. package/dist/controllers/scroll/scroll_container_controller.d.ts +0 -22
  215. package/dist/controllers/scroll/scroll_container_controller.d.ts.map +0 -1
  216. package/dist/controllers/scroll/scroll_into_focus_controller.d.ts +0 -16
  217. package/dist/controllers/scroll/scroll_into_focus_controller.d.ts.map +0 -1
  218. package/dist/controllers/scroll/scroll_to_bottom_controller.d.ts +0 -12
  219. package/dist/controllers/scroll/scroll_to_bottom_controller.d.ts.map +0 -1
  220. package/dist/controllers/scroll/scroll_to_controller.d.ts +0 -18
  221. package/dist/controllers/scroll/scroll_to_controller.d.ts.map +0 -1
  222. package/dist/controllers/scroll/scroll_to_top_controller.d.ts +0 -12
  223. package/dist/controllers/scroll/scroll_to_top_controller.d.ts.map +0 -1
  224. package/dist/controllers/self_destruct_controller.d.ts +0 -9
  225. package/dist/controllers/self_destruct_controller.d.ts.map +0 -1
  226. package/dist/controllers/signal/events.d.ts +0 -5
  227. package/dist/controllers/signal/events.d.ts.map +0 -1
  228. package/dist/controllers/signal/expressions.d.ts +0 -2
  229. package/dist/controllers/signal/expressions.d.ts.map +0 -1
  230. package/dist/controllers/signal/index.d.ts.map +0 -1
  231. package/dist/controllers/signal/signal_action_controller.d.ts +0 -15
  232. package/dist/controllers/signal/signal_action_controller.d.ts.map +0 -1
  233. package/dist/controllers/signal/signal_dom_children_controller.d.ts +0 -17
  234. package/dist/controllers/signal/signal_dom_children_controller.d.ts.map +0 -1
  235. package/dist/controllers/signal/signal_input_controller.d.ts +0 -20
  236. package/dist/controllers/signal/signal_input_controller.d.ts.map +0 -1
  237. package/dist/controllers/signal/signal_visibility_controller.d.ts +0 -18
  238. package/dist/controllers/signal/signal_visibility_controller.d.ts.map +0 -1
  239. package/dist/controllers/sticky_controller.d.ts +0 -16
  240. package/dist/controllers/sticky_controller.d.ts.map +0 -1
  241. package/dist/controllers/tables/index.d.ts.map +0 -1
  242. package/dist/controllers/tables/table_sort_controller.d.ts +0 -20
  243. package/dist/controllers/tables/table_sort_controller.d.ts.map +0 -1
  244. package/dist/controllers/tables/table_truncate_controller.d.ts +0 -26
  245. package/dist/controllers/tables/table_truncate_controller.d.ts.map +0 -1
  246. package/dist/controllers/teleport_controller.d.ts +0 -16
  247. package/dist/controllers/teleport_controller.d.ts.map +0 -1
  248. package/dist/controllers/temporary_state_controller.d.ts +0 -27
  249. package/dist/controllers/temporary_state_controller.d.ts.map +0 -1
  250. package/dist/controllers/toggle_class_controller.d.ts +0 -36
  251. package/dist/controllers/toggle_class_controller.d.ts.map +0 -1
  252. package/dist/controllers/trix_modifier_controller.d.ts +0 -88
  253. package/dist/controllers/trix_modifier_controller.d.ts.map +0 -1
  254. package/dist/controllers/turbo_frame_rc_controller.d.ts +0 -21
  255. package/dist/controllers/turbo_frame_rc_controller.d.ts.map +0 -1
  256. package/dist/controllers/turbo_frame_refresh_controller.d.ts +0 -14
  257. package/dist/controllers/turbo_frame_refresh_controller.d.ts.map +0 -1
  258. package/dist/controllers/utility/alert_controller.d.ts +0 -9
  259. package/dist/controllers/utility/alert_controller.d.ts.map +0 -1
  260. package/dist/controllers/utility/fullscreen_controller.d.ts +0 -8
  261. package/dist/controllers/utility/fullscreen_controller.d.ts.map +0 -1
  262. package/dist/controllers/utility/index.d.ts.map +0 -1
  263. package/dist/controllers/utility/intersection_controller.d.ts +0 -14
  264. package/dist/controllers/utility/intersection_controller.d.ts.map +0 -1
  265. package/dist/controllers/utility/interval_controller.d.ts +0 -11
  266. package/dist/controllers/utility/interval_controller.d.ts.map +0 -1
  267. package/dist/controllers/utility/presence_controller.d.ts +0 -14
  268. package/dist/controllers/utility/presence_controller.d.ts.map +0 -1
  269. package/dist/controllers/utility/print_controller.d.ts +0 -5
  270. package/dist/controllers/utility/print_controller.d.ts.map +0 -1
  271. package/dist/controllers/utility/timeout_controller.d.ts +0 -10
  272. package/dist/controllers/utility/timeout_controller.d.ts.map +0 -1
  273. package/dist/controllers/utility/user_focus_controller.d.ts +0 -9
  274. package/dist/controllers/utility/user_focus_controller.d.ts.map +0 -1
  275. package/dist/controllers/visual/clock_controller.d.ts +0 -16
  276. package/dist/controllers/visual/clock_controller.d.ts.map +0 -1
  277. package/dist/controllers/visual/countdown_controller.d.ts +0 -46
  278. package/dist/controllers/visual/countdown_controller.d.ts.map +0 -1
  279. package/dist/controllers/visual/duration_controller.d.ts +0 -26
  280. package/dist/controllers/visual/duration_controller.d.ts.map +0 -1
  281. package/dist/controllers/visual/index.d.ts.map +0 -1
  282. package/dist/controllers/visual/tabs_controller.d.ts +0 -30
  283. package/dist/controllers/visual/tabs_controller.d.ts.map +0 -1
  284. package/dist/controllers/visual/time_distance_controller.d.ts +0 -16
  285. package/dist/controllers/visual/time_distance_controller.d.ts.map +0 -1
  286. package/dist/controllers/visual/tree_view_controller.d.ts +0 -26
  287. package/dist/controllers/visual/tree_view_controller.d.ts.map +0 -1
  288. package/dist/index.d.ts.map +0 -1
  289. package/dist/mixins/create_mixin.d.ts +0 -3
  290. package/dist/mixins/create_mixin.d.ts.map +0 -1
  291. package/dist/mixins/index.d.ts.map +0 -1
  292. package/dist/mixins/install_class_methods.d.ts +0 -6
  293. package/dist/mixins/install_class_methods.d.ts.map +0 -1
  294. package/dist/mixins/use_click_outside.d.ts +0 -5
  295. package/dist/mixins/use_click_outside.d.ts.map +0 -1
  296. package/dist/mixins/use_event_bus.d.ts +0 -8
  297. package/dist/mixins/use_event_bus.d.ts.map +0 -1
  298. package/dist/mixins/use_event_listener.d.ts +0 -20
  299. package/dist/mixins/use_event_listener.d.ts.map +0 -1
  300. package/dist/mixins/use_fullscreen.d.ts +0 -9
  301. package/dist/mixins/use_fullscreen.d.ts.map +0 -1
  302. package/dist/mixins/use_geolocation.d.ts +0 -19
  303. package/dist/mixins/use_geolocation.d.ts.map +0 -1
  304. package/dist/mixins/use_hover.d.ts +0 -5
  305. package/dist/mixins/use_hover.d.ts.map +0 -1
  306. package/dist/mixins/use_injected_html.d.ts +0 -11
  307. package/dist/mixins/use_injected_html.d.ts.map +0 -1
  308. package/dist/mixins/use_intersection.d.ts +0 -14
  309. package/dist/mixins/use_intersection.d.ts.map +0 -1
  310. package/dist/mixins/use_interval.d.ts +0 -3
  311. package/dist/mixins/use_interval.d.ts.map +0 -1
  312. package/dist/mixins/use_localstorage.d.ts +0 -21
  313. package/dist/mixins/use_localstorage.d.ts.map +0 -1
  314. package/dist/mixins/use_mutation_observer.d.ts +0 -3
  315. package/dist/mixins/use_mutation_observer.d.ts.map +0 -1
  316. package/dist/mixins/use_temporary_content.d.ts +0 -6
  317. package/dist/mixins/use_temporary_content.d.ts.map +0 -1
  318. package/dist/mixins/use_timeout.d.ts +0 -3
  319. package/dist/mixins/use_timeout.d.ts.map +0 -1
  320. package/dist/mixins/use_trix_modifiers.d.ts +0 -11
  321. package/dist/mixins/use_trix_modifiers.d.ts.map +0 -1
  322. package/dist/stimulus-library.cjs.js +0 -2
  323. package/dist/stimulus-library.cjs.js.map +0 -1
  324. package/dist/stimulus-library.es.js +0 -4719
  325. package/dist/stimulus-library.es.js.map +0 -1
  326. package/dist/stimulus-library.umd.js +0 -2
  327. package/dist/stimulus-library.umd.js.map +0 -1
  328. package/dist/utilities/arrays.d.ts +0 -2
  329. package/dist/utilities/arrays.d.ts.map +0 -1
  330. package/dist/utilities/base_controller.d.ts +0 -11
  331. package/dist/utilities/base_controller.d.ts.map +0 -1
  332. package/dist/utilities/elements.d.ts +0 -49
  333. package/dist/utilities/elements.d.ts.map +0 -1
  334. package/dist/utilities/ephemeral_controller.d.ts +0 -6
  335. package/dist/utilities/ephemeral_controller.d.ts.map +0 -1
  336. package/dist/utilities/event_bus.d.ts +0 -4
  337. package/dist/utilities/event_bus.d.ts.map +0 -1
  338. package/dist/utilities/events.d.ts +0 -3
  339. package/dist/utilities/events.d.ts.map +0 -1
  340. package/dist/utilities/fetchRetry.d.ts +0 -2
  341. package/dist/utilities/fetchRetry.d.ts.map +0 -1
  342. package/dist/utilities/index.d.ts.map +0 -1
  343. package/dist/utilities/logging.d.ts +0 -6
  344. package/dist/utilities/logging.d.ts.map +0 -1
  345. package/dist/utilities/reactive.d.ts +0 -2
  346. package/dist/utilities/reactive.d.ts.map +0 -1
  347. package/dist/utilities/request_submit.d.ts +0 -3
  348. package/dist/utilities/request_submit.d.ts.map +0 -1
  349. package/dist/utilities/scroll.d.ts +0 -11
  350. package/dist/utilities/scroll.d.ts.map +0 -1
  351. package/dist/utilities/stimulus.d.ts +0 -3
  352. package/dist/utilities/stimulus.d.ts.map +0 -1
  353. package/dist/utilities/strings.d.ts +0 -2
  354. package/dist/utilities/strings.d.ts.map +0 -1
  355. package/dist/utilities/turbo.d.ts +0 -2
  356. package/dist/utilities/turbo.d.ts.map +0 -1
@@ -1,4719 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
- var __publicField = (obj, key, value) => {
18
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
19
- return value;
20
- };
21
- import { Controller } from "stimulus";
22
- import { camelCase, debounce, upperFirst, clamp, get, set } from "lodash-es";
23
- import { isPast, intervalToDuration, formatDuration, toDate, formatDistanceToNow } from "date-fns";
24
- function logProperty(prop) {
25
- switch (prop) {
26
- case "application":
27
- case "el":
28
- case "element":
29
- case "constructor":
30
- case "initialize":
31
- case "log":
32
- case "logEvent":
33
- case "dispatch":
34
- case "data":
35
- case "valueDescriptorMap":
36
- case "mutate":
37
- case "identifier":
38
- return false;
39
- }
40
- if (/^_.*?$/.test(prop)) {
41
- return false;
42
- }
43
- if (/^.*?Target(s)?$/.test(prop)) {
44
- return false;
45
- }
46
- if (/^.*?Value$/.test(prop)) {
47
- return false;
48
- }
49
- if (/^.*?ValueChanged$/.test(prop)) {
50
- return false;
51
- }
52
- if (/^.*?Class$/.test(prop)) {
53
- return false;
54
- }
55
- if (/^.*?Classes$/.test(prop)) {
56
- return false;
57
- }
58
- if (/^.*?ClassesPresent$/.test(prop)) {
59
- return false;
60
- }
61
- return true;
62
- }
63
- function log(controller, functionName, args = {}) {
64
- if (!controller.application.debug) {
65
- return;
66
- }
67
- let logger = console;
68
- logger.groupCollapsed(...colorize(controller.identifier, "#3B82F6"), `#${functionName}`);
69
- logger.log(__spreadValues({
70
- element: controller.element,
71
- controller
72
- }, args));
73
- logger.groupEnd();
74
- }
75
- function warn(controller, warning, args = {}) {
76
- if (!controller.application.debug) {
77
- return;
78
- }
79
- let logger = console;
80
- logger.groupCollapsed(...colorize(controller.identifier, "#F39B1AFF"), `!! ${warning} !!`);
81
- logger.warn(__spreadValues({
82
- element: controller.element,
83
- controller
84
- }, args));
85
- logger.groupEnd();
86
- }
87
- function logEvent(controller, eventName, event, element) {
88
- if (!controller.application.debug) {
89
- return;
90
- }
91
- let logger = console;
92
- logger.groupCollapsed(...colorizeMany([
93
- { text: controller.identifier, color: "#3B82F6" },
94
- { text: eventName, color: "#0be000" }
95
- ]), event.detail);
96
- logger.log(...colorize("Dispatched on", "#3b82f6"), element);
97
- logger.log(...colorize("event", "#3b82f6"), event);
98
- logger.log(...colorize("event details", "#3b82f6"), event.detail);
99
- logger.groupEnd();
100
- }
101
- function colorize(text, color) {
102
- return colorizeMany([{ text, color }]);
103
- }
104
- function colorizeMany(texts) {
105
- let str = "";
106
- let colors = texts.flatMap((x) => {
107
- str += `%c${x.text}%c `;
108
- return [`color: ${x.color}`, "color: unset"];
109
- });
110
- return [str, ...colors];
111
- }
112
- function dispatchEvent(controller, element, eventName, options = {}) {
113
- let mergedOptions = Object.assign({}, { bubbles: true, cancelable: true, detail: { target: element } }, options);
114
- if (!mergedOptions.detail.target) {
115
- mergedOptions.detail.target = element;
116
- }
117
- let event = new CustomEvent(eventName, mergedOptions);
118
- logEvent(controller, eventName, event, element);
119
- element.dispatchEvent(event);
120
- }
121
- class BaseController extends Controller {
122
- constructor(context) {
123
- super(context);
124
- if (!this.application.debug) {
125
- return this;
126
- }
127
- return new Proxy(this, {
128
- get: (obj, prop) => {
129
- let returnVal = Reflect.get(obj, prop);
130
- let self = this;
131
- if ("logFormattedMessage" in this.application) {
132
- return returnVal;
133
- }
134
- if (logProperty(prop.toString())) {
135
- if (typeof returnVal == "function") {
136
- return new Proxy(returnVal, {
137
- apply(target, thisArg, argArray) {
138
- log(self, prop.toString(), {
139
- args: argArray
140
- });
141
- return Reflect.apply(target, thisArg, argArray);
142
- }
143
- });
144
- } else {
145
- log(this, prop.toString());
146
- }
147
- }
148
- return returnVal;
149
- }
150
- });
151
- }
152
- get el() {
153
- return this.element;
154
- }
155
- get isTurboPreview() {
156
- return document.documentElement.hasAttribute("data-turbo-preview") || document.documentElement.hasAttribute("data-turbolinks-preview");
157
- }
158
- get isTurbolinksPreview() {
159
- return this.isTurboPreview;
160
- }
161
- get csrfToken() {
162
- return this.metaValue("csrf-token");
163
- }
164
- metaValue(name) {
165
- const element = document.head.querySelector(`meta[name="${name}"]`);
166
- return (element == null ? void 0 : element.getAttribute("content")) || null;
167
- }
168
- dispatchEvent(element, eventName, options = {}) {
169
- dispatchEvent(this, element, eventName, options);
170
- }
171
- }
172
- class EphemeralController extends BaseController {
173
- _cleanupSelf() {
174
- this.cleanup(this.el);
175
- }
176
- cleanup(element) {
177
- var _a, _b, _c;
178
- element.dataset.controller = ((_a = element.dataset.controller) == null ? void 0 : _a.replaceAll(new RegExp(`(\\s|^)${this.identifier}(\\s|$)`, "g"), "")) || "";
179
- if (element.dataset.controller == "") {
180
- delete element.dataset.controller;
181
- }
182
- let substringIdentifierValueRegex = new RegExp(`(\\s|^)${this.identifier}\\..+?(\\s|$)`, "g");
183
- element.dataset.target = ((_b = element.dataset.target) == null ? void 0 : _b.replaceAll(substringIdentifierValueRegex, "")) || "";
184
- delete element.dataset[camelCase(`${this.identifier}-target`)];
185
- if (element.dataset.target == "") {
186
- delete element.dataset.target;
187
- }
188
- element.dataset.action = ((_c = element.dataset.target) == null ? void 0 : _c.replaceAll(substringIdentifierValueRegex, "")) || "";
189
- delete element.dataset[camelCase(`${this.identifier}-action`)];
190
- if (element.dataset.action == "") {
191
- delete element.dataset.action;
192
- }
193
- let values = this.constructor.values;
194
- if (values) {
195
- Object.keys(values).forEach((val) => delete element.dataset[camelCase(`${this.identifier}-${val}-value`)]);
196
- }
197
- let classes = this.constructor.classes;
198
- if (classes) {
199
- Object.keys(classes).forEach((val) => delete element.dataset[camelCase(`${this.identifier}-${val}-class`)]);
200
- }
201
- }
202
- }
203
- const smoothSupported = "scrollBehavior" in document.documentElement.style;
204
- let smoothPolyfilled;
205
- async function scrollToElement(element, { behavior = "smooth", block = "start", inline = "nearest" } = {}) {
206
- if (behavior == "smooth" && !smoothSupported) {
207
- await polyfillSmooth();
208
- }
209
- element.scrollIntoView({ behavior, block, inline });
210
- }
211
- async function scrollAbsoluteTop(element, { behavior = "smooth" } = {}) {
212
- if (behavior == "smooth" && !smoothSupported) {
213
- await polyfillSmooth();
214
- }
215
- element.scrollTo({ top: 0, left: 0, behavior });
216
- }
217
- async function scrollAbsoluteBottom(element, { behavior = "smooth" } = {}) {
218
- if (behavior == "smooth" && !smoothSupported) {
219
- await polyfillSmooth();
220
- }
221
- if (element == window) {
222
- element.scrollTo({ top: document.body.scrollHeight, left: 0, behavior });
223
- } else {
224
- element.scrollTo({ top: element.scrollHeight, left: 0, behavior });
225
- }
226
- }
227
- async function scrollAbsoluteLeft(element, { behavior = "smooth" } = {}) {
228
- if (behavior == "smooth" && !smoothSupported) {
229
- await polyfillSmooth();
230
- }
231
- element.scrollTo({ left: 0, behavior });
232
- }
233
- async function scrollAbsoluteRight(element, { behavior = "smooth" } = {}) {
234
- if (behavior == "smooth" && !smoothSupported) {
235
- await polyfillSmooth();
236
- }
237
- if (element == window) {
238
- element.scrollTo({ left: document.body.scrollWidth, behavior });
239
- } else {
240
- element.scrollTo({ left: element.scrollWidth, behavior });
241
- }
242
- }
243
- async function scrollUp(element, amount, { behavior = "smooth" } = {}) {
244
- if (behavior == "smooth" && !smoothSupported) {
245
- await polyfillSmooth();
246
- }
247
- element.scrollBy({ top: -amount, left: 0, behavior });
248
- }
249
- async function scrollDown(element, amount, { behavior = "smooth" } = {}) {
250
- if (behavior == "smooth" && !smoothSupported) {
251
- await polyfillSmooth();
252
- }
253
- element.scrollBy({ top: amount, left: 0, behavior });
254
- }
255
- async function scrollLeft(element, amount, { behavior = "smooth" } = {}) {
256
- if (behavior == "smooth" && !smoothSupported) {
257
- await polyfillSmooth();
258
- }
259
- element.scrollBy({ top: 0, left: -amount, behavior });
260
- }
261
- async function scrollRight(element, amount, { behavior = "smooth" } = {}) {
262
- if (behavior == "smooth" && !smoothSupported) {
263
- await polyfillSmooth();
264
- }
265
- element.scrollBy({ top: 0, left: amount, behavior });
266
- }
267
- async function polyfillSmooth() {
268
- const { polyfill } = await import(
269
- /* webpackChunkName: "smoothscroll-polyfill" */
270
- "smoothscroll-polyfill"
271
- );
272
- if (smoothPolyfilled) {
273
- return;
274
- }
275
- smoothPolyfilled = true;
276
- polyfill();
277
- }
278
- function getScrollParent(node) {
279
- if (!node) {
280
- return null;
281
- }
282
- if (node == document.body) {
283
- return window;
284
- }
285
- const overflowY = getComputedStyle(node).overflowY;
286
- const isScrollable = overflowY !== "visible" && overflowY !== "hidden";
287
- if (isScrollable && node.scrollHeight >= node.clientHeight) {
288
- return node;
289
- }
290
- return getScrollParent(node.parentElement) || document.body;
291
- }
292
- function isTurboFrame(element) {
293
- return element.nodeName == "TURBO-FRAME";
294
- }
295
- function mitt(n) {
296
- return { all: n = n || new Map(), on: function(t, e) {
297
- var i = n.get(t);
298
- i ? i.push(e) : n.set(t, [e]);
299
- }, off: function(t, e) {
300
- var i = n.get(t);
301
- i && (e ? i.splice(i.indexOf(e) >>> 0, 1) : n.set(t, []));
302
- }, emit: function(t, e) {
303
- var i = n.get(t);
304
- i && i.slice().map(function(n2) {
305
- n2(e);
306
- }), (i = n.get("*")) && i.slice().map(function(n2) {
307
- n2(t, e);
308
- });
309
- } };
310
- }
311
- const EventBus = mitt();
312
- function isHTMLLinkElement(element) {
313
- return element.nodeName == "LINK";
314
- }
315
- function isHTMLAnchorElement(element) {
316
- return element.nodeName == "A";
317
- }
318
- function isHTMLFormElement(element) {
319
- return element.nodeName == "FORM";
320
- }
321
- function isHTMLInputElement(element) {
322
- return element.nodeName == "INPUT";
323
- }
324
- function isHTMLLabelElement(element) {
325
- return element.nodeName == "LABEL";
326
- }
327
- function isHTMLTextAreaElement(element) {
328
- return element.nodeName == "TEXTAREA";
329
- }
330
- function isHTMLButtonElement(element) {
331
- return element.nodeName == "BUTTON";
332
- }
333
- function isHTMLSelectElement(element) {
334
- return element.nodeName == "SELECT";
335
- }
336
- function isHTMLImageElement(element) {
337
- return element.nodeName == "IMG";
338
- }
339
- function isHTMLButtonInputElement(element) {
340
- return element.nodeName == "INPUT" && element.type == "button";
341
- }
342
- function isHTMLSubmitInputElement(element) {
343
- return element.nodeName == "INPUT" && element.type == "submit";
344
- }
345
- function isHTMLResetInputElement(element) {
346
- return element.nodeName == "INPUT" && element.type == "reset";
347
- }
348
- function isHTMLButtonButtonElement(element) {
349
- return element.nodeName == "BUTTON" && element.type == "button";
350
- }
351
- function isHTMLSubmitButtonElement(element) {
352
- return element.nodeName == "BUTTON" && element.type == "submit";
353
- }
354
- function isHTMLResetButtonElement(element) {
355
- return element.nodeName == "BUTTON" && element.type == "reset";
356
- }
357
- function isTypeOfResetButtonElement(element) {
358
- return isHTMLResetButtonElement(element) || isHTMLResetInputElement(element);
359
- }
360
- function isTypeOfSubmitButtonElement(element) {
361
- return isHTMLSubmitButtonElement(element) || isHTMLSubmitInputElement(element);
362
- }
363
- function isTypeOfButtonableElement(element) {
364
- return isTypeOfResetButtonElement(element) || isTypeOfSubmitButtonElement(element) || isHTMLButtonButtonElement(element);
365
- }
366
- function isElementCheckable(element) {
367
- return isHTMLInputElement(element) && (element.type === "radio" || element.type === "checkbox");
368
- }
369
- function isTypeOfFormInputElement(element) {
370
- return isHTMLInputElement(element) || isHTMLSelectElement(element) || isHTMLTextAreaElement(element);
371
- }
372
- function createHiddenButton(type) {
373
- let button = document.createElement("button");
374
- button.type = type;
375
- button.style.display = "none";
376
- button.dataset.sythentic = "true";
377
- return button;
378
- }
379
- function createHiddenInput(name, value) {
380
- let input = document.createElement("input");
381
- input.type = "hidden";
382
- input.name = name;
383
- input.value = value;
384
- return input;
385
- }
386
- function insertElement(targetElement, insertPosition, element) {
387
- let createdElement = targetElement.insertAdjacentElement(insertPosition, element);
388
- if (!createdElement) {
389
- throw new Error(`Failed to insert element ${element.nodeName} into ${targetElement.nodeName}`);
390
- }
391
- return createdElement;
392
- }
393
- function insertHiddenInput(name, value, targetElement, insertPosition) {
394
- return insertElement(targetElement, insertPosition, createHiddenInput(name, value));
395
- }
396
- function insertHiddenButton(type, targetElement, insertPosition) {
397
- return insertElement(targetElement, insertPosition, createHiddenButton(type));
398
- }
399
- function getAllRadiosInGroup(radio) {
400
- let parent = radio.form || document;
401
- return Array.from(parent.querySelectorAll(`input[type="radio"][name="${radio.name}"]`));
402
- }
403
- function getOtherRadiosInGroup(radio) {
404
- return getAllRadiosInGroup(radio).filter((r) => r !== radio);
405
- }
406
- function isElementInViewport(el) {
407
- const rect = el.getBoundingClientRect();
408
- const windowHeight = window.innerHeight || document.documentElement.clientHeight;
409
- const windowWidth = window.innerWidth || document.documentElement.clientWidth;
410
- const vertInView = rect.top <= windowHeight && rect.top + rect.height >= 0;
411
- const horInView = rect.left <= windowWidth && rect.left + rect.width >= 0;
412
- return vertInView && horInView;
413
- }
414
- function requestSubmit(form) {
415
- if (form.requestSubmit) {
416
- form.requestSubmit();
417
- } else {
418
- let button = form.querySelector('button[type="submit"]');
419
- if (!button) {
420
- button = insertHiddenButton("submit", form, "beforeend");
421
- }
422
- button.click();
423
- }
424
- }
425
- function requestReset(form) {
426
- let button = form.querySelector('button[type="reset"]');
427
- if (!button) {
428
- button = insertHiddenButton("reset", form, "beforeend");
429
- }
430
- button.click();
431
- }
432
- function wrapArray(x) {
433
- return Array.isArray(x) ? x : [x];
434
- }
435
- function useMixin(controller, setup, teardown) {
436
- const controllerDisconnect = controller.disconnect.bind(controller);
437
- setup();
438
- Object.assign(controller, {
439
- disconnect() {
440
- teardown();
441
- controllerDisconnect();
442
- }
443
- });
444
- return controllerDisconnect;
445
- }
446
- function useEventListener(controller, element, eventNameOrNames, handler, opts) {
447
- if (opts == null ? void 0 : opts.debounce) {
448
- handler = debounce(handler.bind(controller), opts.debounce);
449
- delete opts.debounce;
450
- } else {
451
- handler = handler.bind(controller);
452
- }
453
- let eventNames = wrapArray(eventNameOrNames);
454
- let setup = () => eventNames.forEach((eventName) => element.addEventListener(eventName, handler, opts));
455
- let teardown = () => eventNames.forEach((eventName) => element.removeEventListener(eventName, handler));
456
- useMixin(controller, setup, teardown);
457
- return { setup, teardown };
458
- }
459
- function useEventListeners(controller, element, eventNameOrNames, handler, opts) {
460
- return useEventListener(controller, element, eventNameOrNames, handler, opts);
461
- }
462
- function useCollectionEventListener(controller, elements, eventNameOrNames, handler, opts) {
463
- let handlers = [];
464
- elements.forEach((el) => {
465
- let { setup, teardown } = useEventListener(controller, el, eventNameOrNames, handler, opts);
466
- handlers.push({ setup, teardown });
467
- });
468
- return [
469
- () => handlers.forEach((h) => h.setup()),
470
- () => handlers.forEach((h) => h.teardown())
471
- ];
472
- }
473
- function useCollectionEventListeners(controller, elements, eventNameOrNames, handler, opts) {
474
- return useCollectionEventListener(controller, elements, eventNameOrNames, handler, opts);
475
- }
476
- function useFullscreen(controller, el) {
477
- let element = el || document.documentElement;
478
- let fullscreenOpen = document.fullscreenElement !== null;
479
- const updateFullscreenState = () => fullscreenOpen = document.fullscreenElement !== null;
480
- const isFullscreen = () => fullscreenOpen;
481
- const toggle = async () => fullscreenOpen ? await exit() : await enter();
482
- let setup = () => document.addEventListener("fullscreenchange", updateFullscreenState);
483
- let teardown = () => document.removeEventListener("fullscreenchange", updateFullscreenState);
484
- const exit = async () => {
485
- if (document.exitFullscreen) {
486
- fullscreenOpen = false;
487
- await document.exitFullscreen();
488
- }
489
- };
490
- const enter = async () => {
491
- if (fullscreenOpen) {
492
- await exit();
493
- }
494
- if (element.requestFullscreen) {
495
- await element.requestFullscreen();
496
- fullscreenOpen = true;
497
- }
498
- };
499
- useMixin(controller, setup, teardown);
500
- return {
501
- isFullscreen,
502
- enter,
503
- exit,
504
- toggle,
505
- teardown
506
- };
507
- }
508
- function reactive(object) {
509
- if (object === null || typeof object !== "object") {
510
- return object;
511
- }
512
- for (const property in object) {
513
- if (Object.getOwnPropertyDescriptor(object, property) == void 0) {
514
- continue;
515
- }
516
- object[property] = reactive(object[property]);
517
- }
518
- return new Proxy(object, {
519
- get(target, property) {
520
- return target[property];
521
- },
522
- set(target, property, value) {
523
- target[property] = reactive(value);
524
- return true;
525
- }
526
- });
527
- }
528
- function useGeolocation(controller, options = {}, update, error) {
529
- if (update) {
530
- update = update.bind(controller);
531
- }
532
- if (error) {
533
- error = error.bind(controller);
534
- }
535
- const {
536
- enableHighAccuracy = true,
537
- maximumAge = 3e4,
538
- timeout = 27e3
539
- } = options;
540
- const isSupported = navigator && "geolocation" in navigator;
541
- const values = reactive({
542
- locatedAt: null,
543
- error: null,
544
- coords: {
545
- accuracy: 0,
546
- latitude: Infinity,
547
- longitude: Infinity,
548
- altitude: null,
549
- altitudeAccuracy: null,
550
- heading: null,
551
- speed: null
552
- },
553
- teardown: () => {
554
- if (watcher) {
555
- navigator.geolocation.clearWatch(watcher);
556
- watcher = null;
557
- }
558
- }
559
- });
560
- let setup = () => {
561
- if (isSupported) {
562
- watcher = navigator.geolocation.watchPosition((position) => {
563
- values.locatedAt = position.timestamp;
564
- values.coords = position.coords;
565
- values.error = null;
566
- if (update) {
567
- update(position);
568
- }
569
- }, (err) => {
570
- values.error = err;
571
- if (error) {
572
- error(err);
573
- }
574
- }, {
575
- enableHighAccuracy,
576
- maximumAge,
577
- timeout
578
- });
579
- }
580
- };
581
- let watcher = null;
582
- useMixin(controller, setup, values.teardown);
583
- return values;
584
- }
585
- function useInjectedFragment(controller, targetElement, insertPosition, fragment, options = {}) {
586
- let nodes = Array.from(fragment.childNodes);
587
- let setup = () => {
588
- let parent = targetElement.parentElement;
589
- if (["beforebegin", "afterend"].includes(insertPosition) && parent == null) {
590
- throw new Error("Cannot insert beforebegin into a node with no parent");
591
- }
592
- switch (insertPosition) {
593
- case "beforeend":
594
- targetElement.append(fragment);
595
- break;
596
- case "afterbegin":
597
- targetElement.prepend(fragment);
598
- break;
599
- case "beforebegin":
600
- parent.insertBefore(fragment, targetElement);
601
- break;
602
- case "afterend":
603
- parent.insertBefore(fragment, targetElement);
604
- break;
605
- }
606
- };
607
- let teardown = options.cleanup ? () => nodes.forEach((node) => node.remove()) : () => void 0;
608
- useMixin(controller, setup, teardown);
609
- return [nodes, teardown];
610
- }
611
- function useInjectedHTML(controller, targetElement, insertPosition, html, options = {}) {
612
- const fragment = document.createRange().createContextualFragment(html);
613
- return useInjectedFragment(controller, targetElement, insertPosition, fragment, options);
614
- }
615
- function useInjectedElement(controller, targetElement, insertPosition, element, options = {}) {
616
- const fragment = new DocumentFragment();
617
- fragment.append(element);
618
- let [nodes, teardown] = useInjectedFragment(controller, targetElement, insertPosition, fragment, options);
619
- return [nodes[0], teardown];
620
- }
621
- function useInterval(controller, handler, interval) {
622
- handler = handler.bind(controller);
623
- let intervalHandle = null;
624
- let setup = () => intervalHandle = setInterval(handler, interval);
625
- let teardown = () => {
626
- if (intervalHandle !== null) {
627
- clearInterval(intervalHandle);
628
- }
629
- };
630
- useMixin(controller, setup, teardown);
631
- return teardown;
632
- }
633
- const StorageSerializers = {
634
- boolean: {
635
- deserialize: (v) => v === "true",
636
- serialize: (v) => String(v),
637
- isEmpty: (v) => v === "" || v === null
638
- },
639
- object: {
640
- deserialize: (v) => JSON.parse(v),
641
- serialize: (v) => JSON.stringify(v),
642
- isEmpty: (v) => {
643
- const values = Object.values(JSON.parse(v));
644
- return values.length === 0 || values.every((v2) => v2 === "" || v2 === null);
645
- }
646
- },
647
- number: {
648
- deserialize: (v) => Number.parseFloat(v),
649
- serialize: (v) => String(v),
650
- isEmpty: (v) => v === "" || v === null
651
- },
652
- any: {
653
- deserialize: (v) => v,
654
- serialize: (v) => String(v),
655
- isEmpty: (v) => v === "" || v === null
656
- },
657
- string: {
658
- deserialize: (v) => v,
659
- serialize: (v) => String(v),
660
- isEmpty: (v) => v === "" || v === null
661
- },
662
- map: {
663
- deserialize: (v) => new Map(JSON.parse(v)),
664
- serialize: (v) => JSON.stringify(Array.from(v.entries())),
665
- isEmpty: (v) => {
666
- const values = Array.from(v.values());
667
- return values.length === 0 || values.every((v2) => v2 === "" || v2 === null);
668
- }
669
- },
670
- set: {
671
- deserialize: (v) => new Set(JSON.parse(v)),
672
- serialize: (v) => JSON.stringify(Array.from(v.entries())),
673
- isEmpty: (v) => {
674
- const values = Array.from(v.values());
675
- return values.length === 0 || values.every((v2) => v2 === "" || v2 === null);
676
- }
677
- }
678
- };
679
- function useLocalStorage(controller, key, defaultValue, opts = { writeDefaults: true }) {
680
- let type;
681
- let { writeDefaults } = opts;
682
- if (defaultValue == null) {
683
- type = "any";
684
- } else if (defaultValue instanceof Set) {
685
- type = "set";
686
- } else if (defaultValue instanceof Map) {
687
- type = "map";
688
- } else if (typeof defaultValue === "boolean") {
689
- type = "boolean";
690
- } else if (typeof defaultValue === "string") {
691
- type = "string";
692
- } else if (typeof defaultValue === "object") {
693
- type = "object";
694
- } else if (Array.isArray(defaultValue)) {
695
- type = "object";
696
- } else if (!Number.isNaN(defaultValue)) {
697
- type = "number";
698
- } else {
699
- type = "any";
700
- }
701
- let data = reactive({
702
- value: defaultValue
703
- });
704
- let storage = localStorage;
705
- const serializer = StorageSerializers[type];
706
- const read = () => {
707
- const rawValue = storage.getItem(key);
708
- if (rawValue == null) {
709
- data.value = defaultValue;
710
- if (writeDefaults && defaultValue !== null) {
711
- storage.setItem(key, serializer.serialize(defaultValue));
712
- }
713
- } else {
714
- data.value = serializer.deserialize(rawValue);
715
- }
716
- return data.value;
717
- };
718
- const write = (value) => {
719
- storage.setItem(key, serializer.serialize(value));
720
- data.value = value;
721
- };
722
- const clear = () => {
723
- storage.removeItem(key);
724
- data.value = defaultValue;
725
- return data.value;
726
- };
727
- const isEmpty = () => {
728
- let rawValue = storage.getItem(key);
729
- return serializer.isEmpty(rawValue);
730
- };
731
- read();
732
- return {
733
- get value() {
734
- return read();
735
- },
736
- set value(value) {
737
- write(value);
738
- },
739
- read,
740
- clear,
741
- write,
742
- isEmpty
743
- };
744
- }
745
- function useTimeout(controller, handler, timeout) {
746
- let controllerDisconnect;
747
- let timeoutHandle = null;
748
- handler = handler.bind(controller);
749
- let newHandler = () => {
750
- handler();
751
- timeoutHandle = null;
752
- Object.assign(controller, { disconnect: controllerDisconnect });
753
- };
754
- let setup = () => timeoutHandle = setTimeout(newHandler, timeout);
755
- let teardown = () => {
756
- if (timeoutHandle !== null) {
757
- clearTimeout(timeoutHandle);
758
- timeoutHandle = null;
759
- }
760
- };
761
- controllerDisconnect = useMixin(controller, setup, teardown);
762
- return teardown;
763
- }
764
- function useTemporaryContent(controller, target, content, timeout, teardownCallback) {
765
- const setContent = (element, text) => {
766
- if (isHTMLInputElement(element)) {
767
- element.value = text;
768
- } else {
769
- element.textContent = text;
770
- }
771
- };
772
- const getContent = (element) => {
773
- return isHTMLInputElement(element) ? element.value : element.innerHTML;
774
- };
775
- let cleanupTimeout = () => void 0;
776
- let originalText = getContent(target);
777
- const teardown = () => {
778
- setContent(target, originalText);
779
- cleanupTimeout();
780
- if (teardownCallback) {
781
- teardownCallback.call(controller);
782
- }
783
- };
784
- const setup = () => {
785
- setContent(target, content);
786
- if (timeout !== void 0) {
787
- cleanupTimeout = useTimeout(controller, teardown, timeout);
788
- }
789
- };
790
- useMixin(controller, setup, teardown);
791
- return {
792
- teardown,
793
- update(newContent) {
794
- setContent(target, newContent);
795
- }
796
- };
797
- }
798
- async function fetchRetry(n, input, init) {
799
- try {
800
- return await fetch(input, init);
801
- } catch (err) {
802
- if (n === 1) {
803
- throw err;
804
- }
805
- return await fetchRetry(n - 1, input, init);
806
- }
807
- }
808
- class LoadBlockController extends BaseController {
809
- get _errorMessage() {
810
- return this.hasErrorMessageValue ? this.errorMessageValue : "This content failed to load";
811
- }
812
- get _maxRetries() {
813
- return this.hasMaxRetriesValue ? this.maxRetriesValue : 1;
814
- }
815
- connect() {
816
- }
817
- async loadContent(event = null) {
818
- event == null ? void 0 : event.preventDefault();
819
- let self = this;
820
- let el = this.hasReplaceTarget ? this.replaceTarget : this.el;
821
- let failure = () => {
822
- el.replaceWith(this._errorMessage);
823
- self.dispatchEvent(el, "ajax:error");
824
- };
825
- try {
826
- let response = await fetchRetry(this._maxRetries, this.endpointValue);
827
- if (!response.ok) {
828
- failure();
829
- }
830
- let text = await response.text();
831
- let newEl = document.createElement("div");
832
- newEl.innerHTML = text;
833
- if (this.hasSelectorValue) {
834
- let selectedContent = newEl.querySelectorAll(this.selectorValue);
835
- el.replaceWith(...selectedContent);
836
- } else {
837
- el.replaceWith(...newEl.children);
838
- }
839
- self.dispatchEvent(el, "ajax:success");
840
- } catch (e) {
841
- failure();
842
- } finally {
843
- self.dispatchEvent(el, "ajax:complete");
844
- }
845
- }
846
- }
847
- __publicField(LoadBlockController, "targets", ["replace"]);
848
- __publicField(LoadBlockController, "values", {
849
- endpoint: String,
850
- errorMessage: String,
851
- selector: String,
852
- maxRetries: Number
853
- });
854
- class AsyncBlockController extends LoadBlockController {
855
- get _errorMessage() {
856
- return this.hasErrorMessageValue ? this.errorMessageValue : "This content failed to load";
857
- }
858
- async connect() {
859
- await this.loadContent();
860
- }
861
- }
862
- __publicField(AsyncBlockController, "targets", ["replace"]);
863
- __publicField(AsyncBlockController, "values", {
864
- endpoint: String,
865
- errorMessage: String,
866
- selector: String,
867
- maxRetries: Number
868
- });
869
- function useIntersectionObserver(controller, handler, options) {
870
- handler = handler.bind(controller);
871
- let observer = new IntersectionObserver(handler, options);
872
- let teardown = () => {
873
- observer == null ? void 0 : observer.disconnect();
874
- observer = null;
875
- };
876
- let observe = (element) => observer == null ? void 0 : observer.observe(element);
877
- let unobserve = (element) => observer == null ? void 0 : observer.unobserve(element);
878
- return {
879
- observer,
880
- teardown,
881
- observe,
882
- unobserve
883
- };
884
- }
885
- function useIntersection(controller, element, appear, disappear, options) {
886
- if (appear) {
887
- appear = appear.bind(controller);
888
- }
889
- if (disappear) {
890
- disappear = disappear.bind(controller);
891
- }
892
- let opts = options != null ? options : {};
893
- let processEntries = (entries) => {
894
- entries.forEach((entry) => {
895
- if (entry.isIntersecting) {
896
- appear && appear(entry);
897
- } else {
898
- disappear && disappear(entry);
899
- }
900
- });
901
- };
902
- let { observer, observe, unobserve, teardown } = useIntersectionObserver(controller, processEntries, opts);
903
- let setup = () => observe(element);
904
- useMixin(controller, setup, teardown);
905
- return {
906
- observer,
907
- observe: () => observe(element),
908
- unobserve: () => unobserve(element),
909
- teardown
910
- };
911
- }
912
- class LazyBlockController extends LoadBlockController {
913
- async connect() {
914
- let element = this.el;
915
- if ("IntersectionObserver" in window) {
916
- let { observe, unobserve } = useIntersection(this, element, this.appear, null, { threshold: 0.3 });
917
- this.observe = observe;
918
- this.unobserve = unobserve;
919
- } else {
920
- await this.loadContent();
921
- }
922
- }
923
- async appear(entry) {
924
- if (entry.target === this.el && entry.isIntersecting) {
925
- await this.loadContent();
926
- if (this.unobserve) {
927
- this.unobserve();
928
- }
929
- }
930
- }
931
- }
932
- class PollBlockController extends LoadBlockController {
933
- connect() {
934
- if (!this.hasSecondsValue) {
935
- throw new Error("Required value `seconds` is missing");
936
- }
937
- requestAnimationFrame(() => {
938
- this._timeout();
939
- useInterval(this, this._timeout, this.secondsValue * 1e3);
940
- });
941
- }
942
- async _timeout() {
943
- await this.loadContent();
944
- }
945
- }
946
- __publicField(PollBlockController, "targets", ["replace"]);
947
- __publicField(PollBlockController, "values", {
948
- endpoint: String,
949
- errorMessage: String,
950
- selector: String,
951
- maxRetries: Number,
952
- seconds: Number
953
- });
954
- class AutoSubmitFormController extends BaseController {
955
- get _eventModes() {
956
- if (this.hasEventModeValue) {
957
- let modes = this.eventModeValue.split(" ").map((mode) => mode.trim());
958
- if (modes.length === 1 && modes[0] === "debounced") {
959
- return ["change", "input"];
960
- }
961
- if (!modes.every((mode) => ["change", "input"].includes(mode))) {
962
- throw new Error(`The modeValue provided '${this.eventModeValue}' is not one of the recognised configuration options`);
963
- }
964
- return modes;
965
- } else {
966
- return ["change"];
967
- }
968
- }
969
- get _debounceTimeout() {
970
- return this.hasDebounceIntervalValue ? this.debounceIntervalValue : -1;
971
- }
972
- get _mode() {
973
- if (this.hasSubmitModeValue) {
974
- if (!["direct", "request"].includes(this.submitModeValue)) {
975
- throw new Error(`The modeValue provided '${this.submitModeValue}' is not one of the recognised configuration options`);
976
- }
977
- return this.submitModeValue;
978
- } else {
979
- return "request";
980
- }
981
- }
982
- get _cssSelector() {
983
- let inputTypes = ["input", "textarea", "select"];
984
- let ignore = ":not([data-no-autosubmit])";
985
- return inputTypes.map((type) => type.concat(ignore)).join(",");
986
- }
987
- get inputElements() {
988
- let subElements = Array.from(this.element.querySelectorAll(this._cssSelector));
989
- subElements = subElements.filter((el) => !this._ancestorIsTrix(el));
990
- return subElements;
991
- }
992
- connect() {
993
- this.inputElements.forEach((el) => {
994
- return useEventListener(this, el, this._eventModes, this.submit, { debounce: this._debounceTimeout && this._debounceTimeout > 0 ? this._debounceTimeout : void 0 });
995
- });
996
- }
997
- _ancestorIsTrix(element) {
998
- return element.closest("trix-toolbar") !== null && element.closest("trix-editor") !== null;
999
- }
1000
- submit() {
1001
- let el = this.el;
1002
- if (this._mode == "request") {
1003
- requestSubmit(el);
1004
- } else {
1005
- el.submit();
1006
- }
1007
- }
1008
- }
1009
- __publicField(AutoSubmitFormController, "values", { submitMode: String, eventMode: String, debounceInterval: Number });
1010
- class AutosizeController extends BaseController {
1011
- connect() {
1012
- let { teardown } = useIntersection(this, this.el, this.appear);
1013
- this._unobserveIntersection = teardown;
1014
- if (!isHTMLTextAreaElement(this.el)) {
1015
- throw new Error(`Expected controller to be attached to a textarea, but was a '${this.el.tagName}'`);
1016
- }
1017
- requestAnimationFrame(() => {
1018
- this.el.style.resize = "none";
1019
- this.el.style.boxSizing = "border-box";
1020
- this._handler();
1021
- useEventListener(this, window, ["resize"], this._handler);
1022
- useEventListener(this, this.el, ["input", "change", "focus"], this._handler, { debounce: 100 });
1023
- });
1024
- }
1025
- appear(_entry) {
1026
- this.autosize(this.el);
1027
- this._unobserveIntersection();
1028
- }
1029
- _handler() {
1030
- this.autosize(this.el);
1031
- }
1032
- autosize(element) {
1033
- let offset = element.offsetHeight - element.clientHeight;
1034
- element.style.height = "auto";
1035
- element.style.height = element.scrollHeight + offset + "px";
1036
- }
1037
- }
1038
- function controllerMethod(controller, methodName) {
1039
- const method = controller[methodName];
1040
- if (typeof method == "function") {
1041
- return method;
1042
- } else if (method != void 0) {
1043
- return () => method;
1044
- } else {
1045
- return () => void 0;
1046
- }
1047
- }
1048
- function pascalCase(str) {
1049
- return upperFirst(camelCase(str));
1050
- }
1051
- function addMethodsForClassDefinition(controller, name) {
1052
- let defaultElement = controller.element;
1053
- let hasClass = () => controller[`has${pascalCase(name)}Class`] == true;
1054
- let classes = () => controller[`${name}Classes`];
1055
- let defaultClasses = () => controllerMethod(controller, `default${pascalCase(name)}Classes`).call(controller) || [];
1056
- let classOrDefault = () => hasClass() ? classes() : defaultClasses();
1057
- if (controller[`${name}Classes`] == void 0) {
1058
- Object.defineProperty(controller, `${name}Classes`, {
1059
- get: () => hasClass() ? controller[`${name}Class`].split(" ") : defaultClasses()
1060
- });
1061
- }
1062
- let methods = {
1063
- [`add${pascalCase(name)}Classes`]: (element = defaultElement) => element.classList.add(...classOrDefault()),
1064
- [`remove${pascalCase(name)}Classes`]: (element = defaultElement) => element.classList.remove(...classOrDefault()),
1065
- [`${name}ClassesPresent`]: (element = defaultElement) => classOrDefault().every((klass) => element.classList.contains(klass))
1066
- };
1067
- Object.assign(controller, methods);
1068
- }
1069
- function installClassMethods(controller) {
1070
- let classes = controller.constructor.classes || [];
1071
- classes.forEach((classDefinition) => addMethodsForClassDefinition(controller, classDefinition));
1072
- }
1073
- class CharCountController extends BaseController {
1074
- connect() {
1075
- installClassMethods(this);
1076
- requestAnimationFrame(() => {
1077
- useEventListener(this, this.inputTarget, "input", this._updateCharCount);
1078
- this._updateCharCount();
1079
- });
1080
- }
1081
- _updateCharCount() {
1082
- let charCount = this.inputTarget.value.length;
1083
- this.outputTarget.innerText = charCount.toString();
1084
- if (this._isValidCount(charCount)) {
1085
- this.removeErrorClasses(this.outputTarget);
1086
- } else {
1087
- this.addErrorClasses(this.outputTarget);
1088
- }
1089
- }
1090
- _isValidCount(count) {
1091
- let min = 0;
1092
- let max = 99999;
1093
- if (this.hasMinValue) {
1094
- min = this.minValue;
1095
- }
1096
- if (this.hasMaxValue) {
1097
- max = this.maxValue;
1098
- }
1099
- return count >= min && count <= max;
1100
- }
1101
- }
1102
- __publicField(CharCountController, "targets", ["input", "output"]);
1103
- __publicField(CharCountController, "values", { min: Number, max: Number });
1104
- __publicField(CharCountController, "classes", ["error"]);
1105
- class CheckboxDisableInputsController extends BaseController {
1106
- connect() {
1107
- this.toggle();
1108
- }
1109
- toggle() {
1110
- if (this.hasDisablerTarget && this.disablerTarget.checked) {
1111
- this.disable();
1112
- } else {
1113
- this.enable();
1114
- }
1115
- }
1116
- disable() {
1117
- let shouldClear = this.hasClearValue && this.clearValue;
1118
- this.disableTargets.forEach((el, _) => {
1119
- if (shouldClear) {
1120
- el.value = "";
1121
- }
1122
- el.disabled = true;
1123
- });
1124
- }
1125
- enable() {
1126
- this.disableTargets.forEach((el, _) => {
1127
- el.disabled = false;
1128
- });
1129
- }
1130
- }
1131
- __publicField(CheckboxDisableInputsController, "targets", ["disabler", "disable"]);
1132
- __publicField(CheckboxDisableInputsController, "values", {
1133
- clear: Boolean
1134
- });
1135
- class CheckboxEnableInputsController extends BaseController {
1136
- connect() {
1137
- this.toggle();
1138
- }
1139
- toggle() {
1140
- if (this.hasEnablerTarget && this.enablerTarget.checked) {
1141
- this.enable();
1142
- } else {
1143
- this.disable();
1144
- }
1145
- }
1146
- disable() {
1147
- let shouldClear = this.hasClearValue && this.clearValue;
1148
- this.enableTargets.forEach((el, _) => {
1149
- if (shouldClear) {
1150
- el.value = "";
1151
- }
1152
- el.disabled = true;
1153
- });
1154
- }
1155
- enable() {
1156
- this.enableTargets.forEach((el, _) => {
1157
- el.disabled = false;
1158
- });
1159
- }
1160
- }
1161
- __publicField(CheckboxEnableInputsController, "targets", ["enabler", "enable"]);
1162
- __publicField(CheckboxEnableInputsController, "values", {
1163
- clear: Boolean
1164
- });
1165
- class CheckboxSelectAllController extends BaseController {
1166
- get _checked() {
1167
- return this._enabled.filter((checkbox) => checkbox.checked);
1168
- }
1169
- get _enabled() {
1170
- return this.checkboxTargets.filter((checkbox) => !checkbox.disabled && !checkbox.readOnly);
1171
- }
1172
- get _unchecked() {
1173
- return this._enabled.filter((checkbox) => !checkbox.checked);
1174
- }
1175
- connect() {
1176
- requestAnimationFrame(() => {
1177
- if (!this.hasSelectAllTarget) {
1178
- return;
1179
- }
1180
- useEventListener(this, this.selectAllTarget, "change", this._toggle);
1181
- useCollectionEventListener(this, this.checkboxTargets, "change", this._refresh);
1182
- this._refresh();
1183
- });
1184
- }
1185
- _toggle(event) {
1186
- event.preventDefault();
1187
- let target = event.target;
1188
- this._enabled.forEach((checkbox) => checkbox.checked = checkbox.disabled || checkbox.readOnly ? checkbox.checked : target.checked);
1189
- }
1190
- _refresh() {
1191
- const checkboxesCount = this._enabled.length;
1192
- const checkboxesCheckedCount = this._checked.length;
1193
- this.selectAllTarget.checked = checkboxesCheckedCount > 0;
1194
- this.selectAllTarget.indeterminate = checkboxesCheckedCount > 0 && checkboxesCheckedCount < checkboxesCount;
1195
- }
1196
- }
1197
- __publicField(CheckboxSelectAllController, "targets", ["selectAll", "checkbox"]);
1198
- class CheckboxXORController extends BaseController {
1199
- connect() {
1200
- useCollectionEventListener(this, this.checkboxTargets, "change", this._update);
1201
- }
1202
- _otherCheckboxes(el) {
1203
- return Array.from(this.checkboxTargets).filter((field) => field !== el);
1204
- }
1205
- _update(event) {
1206
- const target = event.target;
1207
- if (!target) {
1208
- throw new Error("No target found on event");
1209
- }
1210
- let others = this._otherCheckboxes(target);
1211
- if (target.checked) {
1212
- others.forEach((checkbox) => {
1213
- checkbox.checked = false;
1214
- this.dispatchEvent(this.el, "change");
1215
- });
1216
- }
1217
- }
1218
- }
1219
- __publicField(CheckboxXORController, "targets", ["checkbox"]);
1220
- class DetectDirtyController extends BaseController {
1221
- get _cacheAttrName() {
1222
- return "detect-dirty-load-value";
1223
- }
1224
- connect() {
1225
- let element = this.el;
1226
- this._cacheLoadValues();
1227
- this._checkDirty();
1228
- useEventListener(this, element, ["input", "change"], this._checkDirty, { debounce: 10 });
1229
- }
1230
- restore(event) {
1231
- event == null ? void 0 : event.preventDefault();
1232
- this._restoreElementFromLoadValue();
1233
- }
1234
- _getElementValue() {
1235
- let element = this.el;
1236
- return isElementCheckable(element) ? element.checked : element.value;
1237
- }
1238
- _getElementLoadValue() {
1239
- let element = this.el;
1240
- let value = element.getAttribute(this._cacheAttrName);
1241
- if (isElementCheckable(element)) {
1242
- return value == null ? element.defaultChecked : value == "true";
1243
- } else if (isHTMLSelectElement(element)) {
1244
- let options = Array.from(element.options);
1245
- options.forEach((option) => {
1246
- if (option.defaultSelected) {
1247
- element.value = option.value;
1248
- return option.value;
1249
- }
1250
- });
1251
- } else if (value !== null) {
1252
- return value;
1253
- }
1254
- return value;
1255
- }
1256
- _elementHasCachedLoadValue() {
1257
- let element = this.el;
1258
- return element.hasAttribute(this._cacheAttrName);
1259
- }
1260
- _checkDirty() {
1261
- let element = this.el;
1262
- if (isHTMLInputElement(element) && element.type == "radio") {
1263
- getOtherRadiosInGroup(element).forEach((radio) => radio.removeAttribute("data-dirty"));
1264
- }
1265
- if (this._isElementDirty()) {
1266
- element.setAttribute("data-dirty", "true");
1267
- } else {
1268
- element.removeAttribute("data-dirty");
1269
- }
1270
- }
1271
- _isElementDirty() {
1272
- return this._getElementValue() !== this._getElementLoadValue();
1273
- }
1274
- _restoreElementFromLoadValue() {
1275
- let element = this.el;
1276
- let cacheValue = element.getAttribute(this._cacheAttrName);
1277
- if (isElementCheckable(element)) {
1278
- element.setAttribute(this._cacheAttrName, element.checked.toString());
1279
- element.checked = cacheValue == null ? element.defaultChecked : cacheValue == "true";
1280
- } else if (isHTMLSelectElement(element)) {
1281
- if (cacheValue == null) {
1282
- let options = Array.from(element.options);
1283
- options.forEach((option) => {
1284
- if (option.defaultSelected) {
1285
- element.value = option.value;
1286
- return;
1287
- }
1288
- });
1289
- } else {
1290
- element.value = cacheValue;
1291
- }
1292
- } else {
1293
- element.value = cacheValue == null ? element.defaultValue : cacheValue;
1294
- }
1295
- }
1296
- _cacheLoadValues() {
1297
- let element = this.el;
1298
- if (!this._elementHasCachedLoadValue() && isElementCheckable(element)) {
1299
- element.setAttribute(this._cacheAttrName, element.checked.toString());
1300
- } else {
1301
- element.setAttribute(this._cacheAttrName, element.value.toString());
1302
- }
1303
- }
1304
- }
1305
- function isDirty(element) {
1306
- return element.hasAttribute("data-dirty");
1307
- }
1308
- class DetectDirtyFormController extends BaseController {
1309
- get _formElements() {
1310
- return Array.from(this.el.querySelectorAll("input, select, textarea"));
1311
- }
1312
- get _cacheAttrName() {
1313
- return "detect-dirty-load-value";
1314
- }
1315
- connect() {
1316
- let element = this.el;
1317
- this._cacheLoadValues();
1318
- this._checkDirty();
1319
- useEventListener(this, element, ["input", "change"], this._checkDirty, { debounce: 10 });
1320
- }
1321
- restore(event) {
1322
- event == null ? void 0 : event.preventDefault();
1323
- this._formElements.forEach((element) => this._restoreElementFromLoadValue(element));
1324
- }
1325
- _getElementValue(element) {
1326
- return isElementCheckable(element) ? element.checked : element.value;
1327
- }
1328
- _getElementLoadValue(element) {
1329
- let value = element.getAttribute(this._cacheAttrName);
1330
- if (isElementCheckable(element)) {
1331
- return value == null ? element.defaultChecked : value == "true";
1332
- } else if (isHTMLSelectElement(element)) {
1333
- let options = Array.from(element.options);
1334
- options.forEach((option) => {
1335
- if (option.defaultSelected) {
1336
- element.value = option.value;
1337
- return option.value;
1338
- }
1339
- });
1340
- } else if (value !== null) {
1341
- return value;
1342
- }
1343
- return value;
1344
- }
1345
- _elementHasCachedLoadValue(element) {
1346
- return element.hasAttribute(this._cacheAttrName);
1347
- }
1348
- _checkElementDirty(element) {
1349
- if (isHTMLInputElement(element) && element.type == "radio") {
1350
- getOtherRadiosInGroup(element).forEach((radio) => radio.removeAttribute("data-dirty"));
1351
- }
1352
- if (this._isElementDirty(element)) {
1353
- element.setAttribute("data-dirty", "true");
1354
- } else {
1355
- element.removeAttribute("data-dirty");
1356
- }
1357
- }
1358
- _isElementDirty(element) {
1359
- return this._getElementValue(element) !== this._getElementLoadValue(element);
1360
- }
1361
- _cacheElementLoadValue(element) {
1362
- if (!this._elementHasCachedLoadValue(element) && isElementCheckable(element)) {
1363
- element.setAttribute(this._cacheAttrName, element.checked.toString());
1364
- } else {
1365
- element.setAttribute(this._cacheAttrName, element.value.toString());
1366
- }
1367
- }
1368
- _restoreElementFromLoadValue(element) {
1369
- let cacheValue = element.getAttribute(this._cacheAttrName);
1370
- if (isElementCheckable(element)) {
1371
- element.setAttribute(this._cacheAttrName, element.checked.toString());
1372
- element.checked = cacheValue == null ? element.defaultChecked : cacheValue == "true";
1373
- } else if (isHTMLSelectElement(element)) {
1374
- if (cacheValue == null) {
1375
- let options = Array.from(element.options);
1376
- options.forEach((option) => {
1377
- if (option.defaultSelected) {
1378
- element.value = option.value;
1379
- return;
1380
- }
1381
- });
1382
- } else {
1383
- element.value = cacheValue;
1384
- }
1385
- } else {
1386
- element.value = cacheValue == null ? element.defaultValue : cacheValue;
1387
- }
1388
- }
1389
- _cacheLoadValues() {
1390
- this._formElements.forEach((el) => this._cacheElementLoadValue(el));
1391
- }
1392
- _checkDirty() {
1393
- this._formElements.forEach((el) => this._checkElementDirty(el));
1394
- if (this._formElements.some((el) => isFormDirty(el))) {
1395
- this.el.setAttribute("data-dirty", "true");
1396
- } else {
1397
- this.el.removeAttribute("data-dirty");
1398
- }
1399
- }
1400
- }
1401
- function isFormDirty(element) {
1402
- return element.hasAttribute("data-dirty");
1403
- }
1404
- class EnableInputsController extends BaseController {
1405
- connect() {
1406
- }
1407
- disable() {
1408
- let shouldClear = this.hasClearValue && this.clearValue;
1409
- this.inputTargets.forEach((el, _) => {
1410
- if (shouldClear) {
1411
- el.value = "";
1412
- }
1413
- el.disabled = true;
1414
- });
1415
- }
1416
- enable() {
1417
- this.inputTargets.forEach((el, _) => el.disabled = false);
1418
- }
1419
- }
1420
- __publicField(EnableInputsController, "targets", ["input"]);
1421
- __publicField(EnableInputsController, "values", {
1422
- clear: Boolean
1423
- });
1424
- class FocusStealController extends BaseController {
1425
- get _mode() {
1426
- const MODES = ["immediate", "wait"];
1427
- if (this.hasModeValue) {
1428
- if (!MODES.includes(this.modeValue)) {
1429
- throw new Error(`The given modeValue '${this.modeValue}' is not one of the supported modes: "${MODES.join('", "')}"`);
1430
- } else {
1431
- return this.modeValue;
1432
- }
1433
- } else {
1434
- return MODES[0];
1435
- }
1436
- }
1437
- connect() {
1438
- if (this._mode == "immediate") {
1439
- this.steal();
1440
- }
1441
- }
1442
- steal() {
1443
- this.el.focus();
1444
- }
1445
- }
1446
- __publicField(FocusStealController, "values", {
1447
- mode: String
1448
- });
1449
- class FormRcController extends BaseController {
1450
- get _mode() {
1451
- if (this.hasSubmitModeValue) {
1452
- if (!["direct", "request"].includes(this.submitModeValue)) {
1453
- throw new Error(`The modeValue provided '${this.submitModeValue}' is not one of the recognised configuration options`);
1454
- }
1455
- return this.submitModeValue;
1456
- } else {
1457
- return "request";
1458
- }
1459
- }
1460
- get form() {
1461
- let form;
1462
- if (this.hasFormSelectorValue) {
1463
- form = document.querySelector(this.formSelectorValue);
1464
- if (!form) {
1465
- throw new Error(`Could not find a form on the page that matches selector '${this.formSelectorValue}'`);
1466
- }
1467
- } else {
1468
- form = this.formTarget;
1469
- }
1470
- return form;
1471
- }
1472
- submit(event) {
1473
- event == null ? void 0 : event.preventDefault();
1474
- let el = this.formTarget;
1475
- if (this._mode == "request") {
1476
- requestSubmit(el);
1477
- } else {
1478
- el.submit();
1479
- }
1480
- }
1481
- reset(event) {
1482
- event == null ? void 0 : event.preventDefault();
1483
- requestReset(this.form);
1484
- }
1485
- }
1486
- __publicField(FormRcController, "targets", ["form"]);
1487
- __publicField(FormRcController, "values", {
1488
- formSelector: String,
1489
- submitMode: String
1490
- });
1491
- class FormSaveController extends BaseController {
1492
- get _formID() {
1493
- if (this.hasIdValue) {
1494
- return this.idValue;
1495
- }
1496
- let elementID = this.el.id;
1497
- if (elementID !== "") {
1498
- return elementID;
1499
- } else {
1500
- throw new Error(`No ID value to uniquely identify this form. Please either specify data-${this.identifier}-id-value or give this form an 'id' attribute. `);
1501
- }
1502
- }
1503
- get _formIdentifier() {
1504
- const url = location.href;
1505
- return `${url} ${this._formID}`;
1506
- }
1507
- get _formElements() {
1508
- return this.el.elements;
1509
- }
1510
- get _formData() {
1511
- let data = { [this._formIdentifier]: {} };
1512
- for (const element of this._formElements) {
1513
- let el = element;
1514
- if (el.name.length > 0) {
1515
- if (isHTMLInputElement(el) && el.type == "checkbox") {
1516
- data[this._formIdentifier][el.name] = el.checked;
1517
- } else if (isHTMLInputElement(el) && el.type == "radio") {
1518
- if (el.checked) {
1519
- data[this._formIdentifier][el.name] = el.value;
1520
- }
1521
- } else {
1522
- data[this._formIdentifier][el.name] = el.value;
1523
- }
1524
- }
1525
- }
1526
- return data;
1527
- }
1528
- get _restoreOnLoad() {
1529
- return this.hasRestoreOnLoadValue ? this.restoreOnLoadValue : true;
1530
- }
1531
- get _clearOnSubmit() {
1532
- return this.hasClearOnSubmitValue ? this.clearOnSubmitValue : true;
1533
- }
1534
- connect() {
1535
- requestAnimationFrame(() => {
1536
- let element = this.el;
1537
- if (!isHTMLFormElement(element)) {
1538
- throw new Error("Expected controller to be mounted on a form element.");
1539
- }
1540
- if (this._restoreOnLoad) {
1541
- this.restore();
1542
- }
1543
- if (this._clearOnSubmit) {
1544
- useEventListener(this, this.el, "submit", this._clear);
1545
- }
1546
- });
1547
- }
1548
- _clear() {
1549
- localStorage.removeItem(this._formIdentifier);
1550
- this.dispatchEvent(this.el, `form-save:cleared`);
1551
- }
1552
- clear(event) {
1553
- event == null ? void 0 : event.preventDefault();
1554
- this._clear();
1555
- }
1556
- save(event) {
1557
- event.preventDefault();
1558
- let data = this._formData;
1559
- localStorage.setItem(this._formIdentifier, JSON.stringify(data[this._formIdentifier]));
1560
- this.dispatchEvent(this.el, `form-save:save:success`);
1561
- }
1562
- restore(event) {
1563
- event == null ? void 0 : event.preventDefault();
1564
- if (localStorage.getItem(this._formIdentifier)) {
1565
- const savedData = JSON.parse(localStorage.getItem(this._formIdentifier));
1566
- for (const element of this._formElements) {
1567
- let el = element;
1568
- if (el.name in savedData) {
1569
- if (isHTMLInputElement(el) && el.type == "checkbox") {
1570
- el.checked = savedData[el.name];
1571
- } else if (isHTMLInputElement(el) && el.type == "radio") {
1572
- if (el.value == savedData[el.name]) {
1573
- el.checked = true;
1574
- }
1575
- } else {
1576
- el.value = savedData[el.name];
1577
- }
1578
- }
1579
- }
1580
- this.dispatchEvent(this.el, `form-save:restore:success`);
1581
- } else {
1582
- this.dispatchEvent(this.el, `form-save:restore:empty`);
1583
- }
1584
- }
1585
- }
1586
- __publicField(FormSaveController, "values", {
1587
- id: String,
1588
- restoreOnLoad: Boolean,
1589
- clearOnSubmit: Boolean
1590
- });
1591
- class LimitedSelectionCheckboxesController extends BaseController {
1592
- connect() {
1593
- useCollectionEventListener(this, this.inputTargets, "change", this._handleInputs);
1594
- }
1595
- _handleInputs(event) {
1596
- let tickedInputs = this.inputTargets.reduce((previousValue, el) => el.checked ? previousValue + 1 : previousValue, 0);
1597
- let target = event.target;
1598
- if (tickedInputs > this.maxValue) {
1599
- event.preventDefault();
1600
- target.checked = false;
1601
- this.dispatchEvent(target, "change");
1602
- this.dispatchEvent(target, "limited-selection:too-many");
1603
- if (this.hasErrorTarget && this.hasMessageValue) {
1604
- this.errorTarget.innerHTML = this.messageValue;
1605
- }
1606
- } else {
1607
- this.dispatchEvent(target, "limited-selection:selection");
1608
- if (this.hasErrorTarget) {
1609
- this.errorTarget.innerHTML = "";
1610
- }
1611
- }
1612
- }
1613
- }
1614
- __publicField(LimitedSelectionCheckboxesController, "targets", ["input", "error"]);
1615
- __publicField(LimitedSelectionCheckboxesController, "values", { max: Number, message: String });
1616
- class NavigateFormErrorsController extends BaseController {
1617
- constructor() {
1618
- super(...arguments);
1619
- __publicField(this, "_errors", []);
1620
- __publicField(this, "_firstClick", false);
1621
- }
1622
- get defaultCurrentClasses() {
1623
- return ["currentError"];
1624
- }
1625
- get _errorCount() {
1626
- return this._errors.length;
1627
- }
1628
- get _previousIndex() {
1629
- let index = this._index - 1;
1630
- if (index < 0) {
1631
- return 0;
1632
- }
1633
- return index;
1634
- }
1635
- get _nextIndex() {
1636
- let index = this._index + 1;
1637
- if (index > this._errors.length - 1) {
1638
- return this._errors.length - 1;
1639
- }
1640
- return index;
1641
- }
1642
- get _index() {
1643
- return clamp(this.hasIndexValue ? this.indexValue : 0, 0, this._errors.length);
1644
- }
1645
- get _selector() {
1646
- if (this.hasSelectorValue) {
1647
- return this.selectorValue;
1648
- } else {
1649
- throw new Error("Expected `selectorValue` to be present");
1650
- }
1651
- }
1652
- get _currentError() {
1653
- return this._errors[this._index];
1654
- }
1655
- get _otherErrors() {
1656
- return this._errors.filter((error, index) => index !== this._index);
1657
- }
1658
- connect() {
1659
- installClassMethods(this);
1660
- requestAnimationFrame(() => {
1661
- this._firstClick = true;
1662
- this._toggleButtons();
1663
- this._toggleVisibility();
1664
- });
1665
- }
1666
- async current(event) {
1667
- event == null ? void 0 : event.preventDefault();
1668
- if (this._firstClick) {
1669
- this._firstClick = false;
1670
- this._toggleButtons();
1671
- }
1672
- await scrollToElement(this._currentError, { behavior: "smooth", block: "center", inline: "center" });
1673
- this._updateClasses();
1674
- }
1675
- async next(event) {
1676
- event == null ? void 0 : event.preventDefault();
1677
- if (this._firstClick) {
1678
- this._firstClick = false;
1679
- this._toggleButtons();
1680
- } else {
1681
- this.indexValue = this._nextIndex;
1682
- }
1683
- await scrollToElement(this._currentError, { behavior: "smooth", block: "center", inline: "center" });
1684
- this._updateClasses();
1685
- }
1686
- async previous(event) {
1687
- event == null ? void 0 : event.preventDefault();
1688
- if (this._firstClick) {
1689
- this._firstClick = false;
1690
- this._toggleButtons();
1691
- } else {
1692
- this.indexValue = this._previousIndex;
1693
- }
1694
- await scrollToElement(this._currentError, { behavior: "smooth", block: "center", inline: "center" });
1695
- this._updateClasses();
1696
- }
1697
- indexValueChanged() {
1698
- this._toggleButtons();
1699
- }
1700
- selectorValueChanged() {
1701
- this._errors = Array.from(document.querySelectorAll(this._selector));
1702
- this.indexValue = 0;
1703
- this._toggleButtons();
1704
- this._toggleVisibility();
1705
- }
1706
- _updateClasses() {
1707
- this.addCurrentClasses(this._currentError);
1708
- this._otherErrors.forEach((error) => this.removeCurrentClasses(error));
1709
- }
1710
- _toggleVisibility() {
1711
- if (this._errorCount === 0) {
1712
- this.el.style.display = "none";
1713
- } else {
1714
- this.el.style.display = "";
1715
- }
1716
- }
1717
- _toggleButtons() {
1718
- if (this.hasNextTarget) {
1719
- if (!this.hasCurrentTarget && this._firstClick && this.indexValue == this._errorCount - 1) {
1720
- this.nextTarget.removeAttribute("disabled");
1721
- return;
1722
- } else if (this.indexValue >= this._errorCount - 1) {
1723
- this.nextTarget.setAttribute("disabled", "true");
1724
- } else {
1725
- this.nextTarget.removeAttribute("disabled");
1726
- }
1727
- }
1728
- if (this.hasPreviousTarget) {
1729
- if (this.indexValue <= 0) {
1730
- this.previousTarget.setAttribute("disabled", "true");
1731
- } else {
1732
- this.previousTarget.removeAttribute("disabled");
1733
- }
1734
- }
1735
- }
1736
- }
1737
- __publicField(NavigateFormErrorsController, "values", {
1738
- selector: String,
1739
- index: Number
1740
- });
1741
- __publicField(NavigateFormErrorsController, "classes", ["current"]);
1742
- __publicField(NavigateFormErrorsController, "targets", ["next", "current", "previous"]);
1743
- class NestedFormController extends BaseController {
1744
- get _wrapperClass() {
1745
- return this.hasWrapperSelectorValue ? this.wrapperClassValue : "nested-fields";
1746
- }
1747
- get _insertMode() {
1748
- return this.hasInsertModeValue ? this.insertModeValue : "beforeend";
1749
- }
1750
- connect() {
1751
- this._checkStructure();
1752
- }
1753
- add(event) {
1754
- event == null ? void 0 : event.preventDefault();
1755
- const content = this.templateTarget.innerHTML.replace(/NEW_RECORD/g, this._generateID());
1756
- this.targetTarget.insertAdjacentHTML(this._insertMode, content);
1757
- }
1758
- remove(event) {
1759
- event.preventDefault();
1760
- const wrapper = event.target.closest(`.${this._wrapperClass}`);
1761
- if (wrapper == null) {
1762
- throw new Error(`#remove was clicked from outside of a child record. Could not find an ancestor with class .${this._wrapperClass}`);
1763
- }
1764
- if (wrapper.dataset.newRecord === "true") {
1765
- wrapper.remove();
1766
- } else {
1767
- wrapper.style.display = "none";
1768
- let destroyInput = wrapper.querySelector("input[name*='_destroy']");
1769
- if (destroyInput == null) {
1770
- throw new Error(`Could not find a hidden input with name '_destroy'. NestedForm cannot remove an already persisted record without it.`);
1771
- }
1772
- destroyInput.value = "1";
1773
- }
1774
- }
1775
- _generateID() {
1776
- return new Date().getTime().toString() + Math.random().toString().slice(2);
1777
- }
1778
- _checkStructure() {
1779
- let template = this.templateTarget.innerHTML;
1780
- if (template.indexOf("NEW_RECORD")) {
1781
- throw new Error("Could not find 'NEW_RECORD' in the provided template. Please make sure you've passed `child_index: 'NEW_RECORD'` to `fields_for`");
1782
- }
1783
- }
1784
- }
1785
- __publicField(NestedFormController, "targets", ["target", "template"]);
1786
- __publicField(NestedFormController, "values", {
1787
- insertMode: String,
1788
- wrapperClass: String
1789
- });
1790
- class PasswordConfirmController extends BaseController {
1791
- connect() {
1792
- installClassMethods(this);
1793
- useCollectionEventListener(this, this.passwordTargets, "change", this._checkPasswordsMatch);
1794
- }
1795
- _allPasswordsMatch() {
1796
- let values = new Set(this.passwordTargets.map((el) => el.value));
1797
- return values.has("") || values.size == 1;
1798
- }
1799
- _checkPasswordsMatch() {
1800
- let element = this.el;
1801
- if (this._allPasswordsMatch()) {
1802
- this.dispatchEvent(element, "password-confirm:match");
1803
- this.passwordTargets.forEach((el) => this.removeErrorClasses(el));
1804
- } else {
1805
- this.dispatchEvent(element, "password-confirm:no-match");
1806
- this.passwordTargets.forEach((el) => this.addErrorClasses(el));
1807
- }
1808
- }
1809
- }
1810
- __publicField(PasswordConfirmController, "targets", ["password"]);
1811
- __publicField(PasswordConfirmController, "classes", ["error"]);
1812
- class PasswordPeekController extends BaseController {
1813
- peak(event) {
1814
- event == null ? void 0 : event.preventDefault();
1815
- this.passwordTarget.type = "text";
1816
- }
1817
- hide(event) {
1818
- event == null ? void 0 : event.preventDefault();
1819
- this.passwordTarget.type = "password";
1820
- }
1821
- toggle(event) {
1822
- event == null ? void 0 : event.preventDefault();
1823
- if (this.passwordTarget.type === "password") {
1824
- this.peak();
1825
- } else {
1826
- this.hide();
1827
- }
1828
- }
1829
- }
1830
- __publicField(PasswordPeekController, "targets", ["password"]);
1831
- class RemoteFormController extends BaseController {
1832
- get _selector() {
1833
- return this.hasSelectorValue ? this.selectorValue : `[data-controller~="${this.identifier}"]`;
1834
- }
1835
- replace(event) {
1836
- const [data, status, xhr] = event.detail;
1837
- if (data instanceof Node) {
1838
- let newElement = data.querySelector(this._selector);
1839
- if (newElement == null) {
1840
- throw new Error(`expected new form DOM with [data-controller="${this.identifier}"] to be present in returned payload`);
1841
- }
1842
- let parentNode = this.el.parentNode;
1843
- if (parentNode == null) {
1844
- throw new Error("expected form to have a DOM parent, could not execute replaceChild");
1845
- }
1846
- parentNode.replaceChild(newElement, this.el);
1847
- this.dispatchEvent(newElement, "remote-form:replace");
1848
- } else {
1849
- console.log("Unknown", data);
1850
- }
1851
- }
1852
- }
1853
- __publicField(RemoteFormController, "targets", []);
1854
- __publicField(RemoteFormController, "values", { selector: String });
1855
- function useEventBus(controller, eventNameOrNames, handler, opts) {
1856
- let options = opts;
1857
- if (options == null ? void 0 : options.debounce) {
1858
- handler = debounce(handler.bind(controller), options.debounce);
1859
- delete options.debounce;
1860
- } else {
1861
- handler = handler.bind(controller);
1862
- }
1863
- let eventNames = wrapArray(eventNameOrNames);
1864
- let setup = () => eventNames.forEach((eventName) => EventBus.on(eventName, handler));
1865
- let teardown = () => eventNames.forEach((eventName) => EventBus.off(eventName, handler));
1866
- useMixin(controller, setup, teardown);
1867
- return { setup, teardown };
1868
- }
1869
- class SyncInputsController extends BaseController {
1870
- get _eventName() {
1871
- return `sync:${this._key}`;
1872
- }
1873
- get _key() {
1874
- if (this.hasKeyValue) {
1875
- return this.keyValue;
1876
- }
1877
- throw new Error("Expected `keyValue` to be present");
1878
- }
1879
- get _value() {
1880
- let el = this.el;
1881
- if (isHTMLInputElement(el) && el.type === "checkbox") {
1882
- return el.checked;
1883
- } else if (isHTMLInputElement(el) && el.type === "radio") {
1884
- return el.checked ? el.value : "";
1885
- } else {
1886
- return el.value;
1887
- }
1888
- }
1889
- set _value(val) {
1890
- let el = this.el;
1891
- if (isHTMLInputElement(el) && el.type === "checkbox") {
1892
- el.checked = val.toString() === "true";
1893
- } else if (isHTMLInputElement(el) && el.type === "radio") {
1894
- el.checked = el.value === val;
1895
- } else if (isHTMLInputElement(el) || isHTMLTextAreaElement(el) || isHTMLSelectElement(el)) {
1896
- el.value = val.toString();
1897
- } else {
1898
- el.innerHTML = val.toString();
1899
- }
1900
- }
1901
- connect() {
1902
- useEventBus(this, this._eventName, this._read);
1903
- requestAnimationFrame(() => {
1904
- if (isTypeOfFormInputElement(this.el)) {
1905
- this._emit();
1906
- useEventListener(this, this.el, "input", this._emit);
1907
- }
1908
- });
1909
- }
1910
- _emit() {
1911
- EventBus.emit(this._eventName, { value: this._value, dispatcher: this.el });
1912
- }
1913
- _read(payload) {
1914
- if (payload === void 0) {
1915
- throw new Error("No payload received");
1916
- }
1917
- let { dispatcher, value } = payload;
1918
- if (dispatcher !== this.el) {
1919
- this._value = value;
1920
- }
1921
- }
1922
- }
1923
- __publicField(SyncInputsController, "values", {
1924
- key: String
1925
- });
1926
- class ValueWarnController extends BaseController {
1927
- get _maxMessage() {
1928
- return this.hasMaxMessageValue ? this.maxMessageValue : `Value must be less than ${this.maxValue}`;
1929
- }
1930
- get _minMessage() {
1931
- return this.hasMinMessageValue ? this.minMessageValue : `Value must be greater than ${this.minValue}`;
1932
- }
1933
- get defaultWarningHideClasses() {
1934
- return ["hide"];
1935
- }
1936
- connect() {
1937
- installClassMethods(this);
1938
- this.addWarningHideClasses(this.warningTarget);
1939
- useEventListener(this, this.inputTarget, "input", this._check);
1940
- this._check();
1941
- }
1942
- _check() {
1943
- if (this.hasMinValue && Number.parseFloat(this.inputTarget.value) < this.minValue) {
1944
- this.removeWarningHideClasses(this.warningTarget);
1945
- this.addInputWarningClasses(this.inputTarget);
1946
- this.warningTarget.innerText = this._minMessage;
1947
- } else if (this.hasMaxValue && Number.parseFloat(this.inputTarget.value) > this.maxValue) {
1948
- this.removeWarningHideClasses(this.warningTarget);
1949
- this.addInputWarningClasses(this.inputTarget);
1950
- this.warningTarget.innerText = this._maxMessage;
1951
- } else {
1952
- this.addWarningHideClasses(this.warningTarget);
1953
- this.removeInputWarningClasses(this.inputTarget);
1954
- this.warningTarget.innerText = "";
1955
- }
1956
- }
1957
- }
1958
- __publicField(ValueWarnController, "classes", ["inputWarning", "warningHide"]);
1959
- __publicField(ValueWarnController, "targets", ["input", "warning"]);
1960
- __publicField(ValueWarnController, "values", {
1961
- max: Number,
1962
- min: Number,
1963
- minMessage: String,
1964
- maxMessage: String
1965
- });
1966
- class WordCountController extends BaseController {
1967
- connect() {
1968
- installClassMethods(this);
1969
- this._updateWordCount();
1970
- useEventListener(this, this.inputTarget, "input", this._updateWordCount);
1971
- }
1972
- _updateWordCount() {
1973
- let wordCount = 0;
1974
- let textAreaValue = this.inputTarget.value;
1975
- let matches = textAreaValue.match(/\S+/g);
1976
- wordCount = matches && matches.length || 0;
1977
- this.outputTarget.innerText = wordCount.toString();
1978
- if (this._isValidCount(wordCount)) {
1979
- this.removeErrorClasses(this.outputTarget);
1980
- } else {
1981
- this.addErrorClasses(this.outputTarget);
1982
- }
1983
- }
1984
- _isValidCount(count) {
1985
- let min = 0;
1986
- let max = 99999;
1987
- if (this.hasMinValue) {
1988
- min = this.minValue;
1989
- }
1990
- if (this.hasMaxValue) {
1991
- max = this.maxValue;
1992
- }
1993
- return count >= min && count <= max;
1994
- }
1995
- }
1996
- __publicField(WordCountController, "targets", ["input", "output"]);
1997
- __publicField(WordCountController, "values", { min: Number, max: Number });
1998
- __publicField(WordCountController, "classes", ["error"]);
1999
- class FallbackImageController extends BaseController {
2000
- initialize() {
2001
- this._hasLoadedSuccessfully = this._hasLoadedSuccessfully.bind(this);
2002
- this._success = this._success.bind(this);
2003
- this._fail = this._fail.bind(this);
2004
- }
2005
- connect() {
2006
- let element = this.el;
2007
- element.onerror = this._fail;
2008
- if (element.complete && !this._hasLoadedSuccessfully()) {
2009
- this._fail();
2010
- } else {
2011
- this._success();
2012
- }
2013
- }
2014
- disconnect() {
2015
- this.removeSuccessClasses();
2016
- this.removeFailClasses();
2017
- }
2018
- _success() {
2019
- this.addSuccessClasses();
2020
- }
2021
- _fail() {
2022
- let element = this.el;
2023
- this.addFailClasses();
2024
- if (this.hasPlaceholderValue && element.src !== this.placeholderValue) {
2025
- this.dispatchEvent(element, "fallback-image:placeholder");
2026
- element.src = this.placeholderValue;
2027
- element.onerror = this._fail;
2028
- } else {
2029
- this.dispatchEvent(element, "fallback-image:fail");
2030
- element.style.display = "none";
2031
- }
2032
- }
2033
- _hasLoadedSuccessfully() {
2034
- let element = this.el;
2035
- return element.naturalHeight > 0 && element.naturalWidth > 0;
2036
- }
2037
- }
2038
- __publicField(FallbackImageController, "values", { placeholder: String });
2039
- __publicField(FallbackImageController, "classes", ["success", "fail"]);
2040
- var supportCustomEvent = window.CustomEvent;
2041
- if (!supportCustomEvent || typeof supportCustomEvent === "object") {
2042
- supportCustomEvent = function CustomEvent2(event, x) {
2043
- x = x || {};
2044
- var ev = document.createEvent("CustomEvent");
2045
- ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
2046
- return ev;
2047
- };
2048
- supportCustomEvent.prototype = window.Event.prototype;
2049
- }
2050
- function safeDispatchEvent(target, event) {
2051
- var check = "on" + event.type.toLowerCase();
2052
- if (typeof target[check] === "function") {
2053
- target[check](event);
2054
- }
2055
- return target.dispatchEvent(event);
2056
- }
2057
- function createsStackingContext(el) {
2058
- while (el && el !== document.body) {
2059
- var s = window.getComputedStyle(el);
2060
- var invalid = function(k, ok) {
2061
- return !(s[k] === void 0 || s[k] === ok);
2062
- };
2063
- if (s.opacity < 1 || invalid("zIndex", "auto") || invalid("transform", "none") || invalid("mixBlendMode", "normal") || invalid("filter", "none") || invalid("perspective", "none") || s["isolation"] === "isolate" || s.position === "fixed" || s.webkitOverflowScrolling === "touch") {
2064
- return true;
2065
- }
2066
- el = el.parentElement;
2067
- }
2068
- return false;
2069
- }
2070
- function findNearestDialog(el) {
2071
- while (el) {
2072
- if (el.localName === "dialog") {
2073
- return el;
2074
- }
2075
- if (el.parentElement) {
2076
- el = el.parentElement;
2077
- } else if (el.parentNode) {
2078
- el = el.parentNode.host;
2079
- } else {
2080
- el = null;
2081
- }
2082
- }
2083
- return null;
2084
- }
2085
- function safeBlur(el) {
2086
- while (el && el.shadowRoot && el.shadowRoot.activeElement) {
2087
- el = el.shadowRoot.activeElement;
2088
- }
2089
- if (el && el.blur && el !== document.body) {
2090
- el.blur();
2091
- }
2092
- }
2093
- function inNodeList(nodeList, node) {
2094
- for (var i = 0; i < nodeList.length; ++i) {
2095
- if (nodeList[i] === node) {
2096
- return true;
2097
- }
2098
- }
2099
- return false;
2100
- }
2101
- function isFormMethodDialog(el) {
2102
- if (!el || !el.hasAttribute("method")) {
2103
- return false;
2104
- }
2105
- return el.getAttribute("method").toLowerCase() === "dialog";
2106
- }
2107
- function findFocusableElementWithin(hostElement) {
2108
- var opts = ["button", "input", "keygen", "select", "textarea"];
2109
- var query = opts.map(function(el) {
2110
- return el + ":not([disabled])";
2111
- });
2112
- query.push('[tabindex]:not([disabled]):not([tabindex=""])');
2113
- var target = hostElement.querySelector(query.join(", "));
2114
- if (!target && "attachShadow" in Element.prototype) {
2115
- var elems = hostElement.querySelectorAll("*");
2116
- for (var i = 0; i < elems.length; i++) {
2117
- if (elems[i].tagName && elems[i].shadowRoot) {
2118
- target = findFocusableElementWithin(elems[i].shadowRoot);
2119
- if (target) {
2120
- break;
2121
- }
2122
- }
2123
- }
2124
- }
2125
- return target;
2126
- }
2127
- function isConnected(element) {
2128
- return element.isConnected || document.body.contains(element);
2129
- }
2130
- function findFormSubmitter(event) {
2131
- if (event.submitter) {
2132
- return event.submitter;
2133
- }
2134
- var form = event.target;
2135
- if (!(form instanceof HTMLFormElement)) {
2136
- return null;
2137
- }
2138
- var submitter = dialogPolyfill.formSubmitter;
2139
- if (!submitter) {
2140
- var target = event.target;
2141
- var root = "getRootNode" in target && target.getRootNode() || document;
2142
- submitter = root.activeElement;
2143
- }
2144
- if (!submitter || submitter.form !== form) {
2145
- return null;
2146
- }
2147
- return submitter;
2148
- }
2149
- function maybeHandleSubmit(event) {
2150
- if (event.defaultPrevented) {
2151
- return;
2152
- }
2153
- var form = event.target;
2154
- var value = dialogPolyfill.imagemapUseValue;
2155
- var submitter = findFormSubmitter(event);
2156
- if (value === null && submitter) {
2157
- value = submitter.value;
2158
- }
2159
- var dialog = findNearestDialog(form);
2160
- if (!dialog) {
2161
- return;
2162
- }
2163
- var formmethod = submitter && submitter.getAttribute("formmethod") || form.getAttribute("method");
2164
- if (formmethod !== "dialog") {
2165
- return;
2166
- }
2167
- event.preventDefault();
2168
- if (value != null) {
2169
- dialog.close(value);
2170
- } else {
2171
- dialog.close();
2172
- }
2173
- }
2174
- function dialogPolyfillInfo(dialog) {
2175
- this.dialog_ = dialog;
2176
- this.replacedStyleTop_ = false;
2177
- this.openAsModal_ = false;
2178
- if (!dialog.hasAttribute("role")) {
2179
- dialog.setAttribute("role", "dialog");
2180
- }
2181
- dialog.show = this.show.bind(this);
2182
- dialog.showModal = this.showModal.bind(this);
2183
- dialog.close = this.close.bind(this);
2184
- dialog.addEventListener("submit", maybeHandleSubmit, false);
2185
- if (!("returnValue" in dialog)) {
2186
- dialog.returnValue = "";
2187
- }
2188
- if ("MutationObserver" in window) {
2189
- var mo = new MutationObserver(this.maybeHideModal.bind(this));
2190
- mo.observe(dialog, { attributes: true, attributeFilter: ["open"] });
2191
- } else {
2192
- var removed = false;
2193
- var cb = function() {
2194
- removed ? this.downgradeModal() : this.maybeHideModal();
2195
- removed = false;
2196
- }.bind(this);
2197
- var timeout;
2198
- var delayModel = function(ev) {
2199
- if (ev.target !== dialog) {
2200
- return;
2201
- }
2202
- var cand = "DOMNodeRemoved";
2203
- removed |= ev.type.substr(0, cand.length) === cand;
2204
- window.clearTimeout(timeout);
2205
- timeout = window.setTimeout(cb, 0);
2206
- };
2207
- ["DOMAttrModified", "DOMNodeRemoved", "DOMNodeRemovedFromDocument"].forEach(function(name) {
2208
- dialog.addEventListener(name, delayModel);
2209
- });
2210
- }
2211
- Object.defineProperty(dialog, "open", {
2212
- set: this.setOpen.bind(this),
2213
- get: dialog.hasAttribute.bind(dialog, "open")
2214
- });
2215
- this.backdrop_ = document.createElement("div");
2216
- this.backdrop_.className = "backdrop";
2217
- this.backdrop_.addEventListener("mouseup", this.backdropMouseEvent_.bind(this));
2218
- this.backdrop_.addEventListener("mousedown", this.backdropMouseEvent_.bind(this));
2219
- this.backdrop_.addEventListener("click", this.backdropMouseEvent_.bind(this));
2220
- }
2221
- dialogPolyfillInfo.prototype = {
2222
- get dialog() {
2223
- return this.dialog_;
2224
- },
2225
- maybeHideModal: function() {
2226
- if (this.dialog_.hasAttribute("open") && isConnected(this.dialog_)) {
2227
- return;
2228
- }
2229
- this.downgradeModal();
2230
- },
2231
- downgradeModal: function() {
2232
- if (!this.openAsModal_) {
2233
- return;
2234
- }
2235
- this.openAsModal_ = false;
2236
- this.dialog_.style.zIndex = "";
2237
- if (this.replacedStyleTop_) {
2238
- this.dialog_.style.top = "";
2239
- this.replacedStyleTop_ = false;
2240
- }
2241
- this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);
2242
- dialogPolyfill.dm.removeDialog(this);
2243
- },
2244
- setOpen: function(value) {
2245
- if (value) {
2246
- this.dialog_.hasAttribute("open") || this.dialog_.setAttribute("open", "");
2247
- } else {
2248
- this.dialog_.removeAttribute("open");
2249
- this.maybeHideModal();
2250
- }
2251
- },
2252
- backdropMouseEvent_: function(e) {
2253
- if (!this.dialog_.hasAttribute("tabindex")) {
2254
- var fake = document.createElement("div");
2255
- this.dialog_.insertBefore(fake, this.dialog_.firstChild);
2256
- fake.tabIndex = -1;
2257
- fake.focus();
2258
- this.dialog_.removeChild(fake);
2259
- } else {
2260
- this.dialog_.focus();
2261
- }
2262
- var redirectedEvent = document.createEvent("MouseEvents");
2263
- redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
2264
- this.dialog_.dispatchEvent(redirectedEvent);
2265
- e.stopPropagation();
2266
- },
2267
- focus_: function() {
2268
- var target = this.dialog_.querySelector("[autofocus]:not([disabled])");
2269
- if (!target && this.dialog_.tabIndex >= 0) {
2270
- target = this.dialog_;
2271
- }
2272
- if (!target) {
2273
- target = findFocusableElementWithin(this.dialog_);
2274
- }
2275
- safeBlur(document.activeElement);
2276
- target && target.focus();
2277
- },
2278
- updateZIndex: function(dialogZ, backdropZ) {
2279
- if (dialogZ < backdropZ) {
2280
- throw new Error("dialogZ should never be < backdropZ");
2281
- }
2282
- this.dialog_.style.zIndex = dialogZ;
2283
- this.backdrop_.style.zIndex = backdropZ;
2284
- },
2285
- show: function() {
2286
- if (!this.dialog_.open) {
2287
- this.setOpen(true);
2288
- this.focus_();
2289
- }
2290
- },
2291
- showModal: function() {
2292
- if (this.dialog_.hasAttribute("open")) {
2293
- throw new Error("Failed to execute 'showModal' on dialog: The element is already open, and therefore cannot be opened modally.");
2294
- }
2295
- if (!isConnected(this.dialog_)) {
2296
- throw new Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");
2297
- }
2298
- if (!dialogPolyfill.dm.pushDialog(this)) {
2299
- throw new Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");
2300
- }
2301
- if (createsStackingContext(this.dialog_.parentElement)) {
2302
- console.warn("A dialog is being shown inside a stacking context. This may cause it to be unusable. For more information, see this link: https://github.com/GoogleChrome/dialog-polyfill/#stacking-context");
2303
- }
2304
- this.setOpen(true);
2305
- this.openAsModal_ = true;
2306
- if (dialogPolyfill.needsCentering(this.dialog_)) {
2307
- dialogPolyfill.reposition(this.dialog_);
2308
- this.replacedStyleTop_ = true;
2309
- } else {
2310
- this.replacedStyleTop_ = false;
2311
- }
2312
- this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling);
2313
- this.focus_();
2314
- },
2315
- close: function(opt_returnValue) {
2316
- if (!this.dialog_.hasAttribute("open")) {
2317
- throw new Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");
2318
- }
2319
- this.setOpen(false);
2320
- if (opt_returnValue !== void 0) {
2321
- this.dialog_.returnValue = opt_returnValue;
2322
- }
2323
- var closeEvent = new supportCustomEvent("close", {
2324
- bubbles: false,
2325
- cancelable: false
2326
- });
2327
- safeDispatchEvent(this.dialog_, closeEvent);
2328
- }
2329
- };
2330
- var dialogPolyfill = {};
2331
- dialogPolyfill.reposition = function(element) {
2332
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
2333
- var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
2334
- element.style.top = Math.max(scrollTop, topValue) + "px";
2335
- };
2336
- dialogPolyfill.isInlinePositionSetByStylesheet = function(element) {
2337
- for (var i = 0; i < document.styleSheets.length; ++i) {
2338
- var styleSheet = document.styleSheets[i];
2339
- var cssRules = null;
2340
- try {
2341
- cssRules = styleSheet.cssRules;
2342
- } catch (e) {
2343
- }
2344
- if (!cssRules) {
2345
- continue;
2346
- }
2347
- for (var j = 0; j < cssRules.length; ++j) {
2348
- var rule = cssRules[j];
2349
- var selectedNodes = null;
2350
- try {
2351
- selectedNodes = document.querySelectorAll(rule.selectorText);
2352
- } catch (e) {
2353
- }
2354
- if (!selectedNodes || !inNodeList(selectedNodes, element)) {
2355
- continue;
2356
- }
2357
- var cssTop = rule.style.getPropertyValue("top");
2358
- var cssBottom = rule.style.getPropertyValue("bottom");
2359
- if (cssTop && cssTop !== "auto" || cssBottom && cssBottom !== "auto") {
2360
- return true;
2361
- }
2362
- }
2363
- }
2364
- return false;
2365
- };
2366
- dialogPolyfill.needsCentering = function(dialog) {
2367
- var computedStyle = window.getComputedStyle(dialog);
2368
- if (computedStyle.position !== "absolute") {
2369
- return false;
2370
- }
2371
- if (dialog.style.top !== "auto" && dialog.style.top !== "" || dialog.style.bottom !== "auto" && dialog.style.bottom !== "") {
2372
- return false;
2373
- }
2374
- return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
2375
- };
2376
- dialogPolyfill.forceRegisterDialog = function(element) {
2377
- if (window.HTMLDialogElement || element.showModal) {
2378
- console.warn("This browser already supports <dialog>, the polyfill may not work correctly", element);
2379
- }
2380
- if (element.localName !== "dialog") {
2381
- throw new Error("Failed to register dialog: The element is not a dialog.");
2382
- }
2383
- new dialogPolyfillInfo(element);
2384
- };
2385
- dialogPolyfill.registerDialog = function(element) {
2386
- if (!element.showModal) {
2387
- dialogPolyfill.forceRegisterDialog(element);
2388
- }
2389
- };
2390
- dialogPolyfill.DialogManager = function() {
2391
- this.pendingDialogStack = [];
2392
- var checkDOM = this.checkDOM_.bind(this);
2393
- this.overlay = document.createElement("div");
2394
- this.overlay.className = "_dialog_overlay";
2395
- this.overlay.addEventListener("click", function(e) {
2396
- this.forwardTab_ = void 0;
2397
- e.stopPropagation();
2398
- checkDOM([]);
2399
- }.bind(this));
2400
- this.handleKey_ = this.handleKey_.bind(this);
2401
- this.handleFocus_ = this.handleFocus_.bind(this);
2402
- this.zIndexLow_ = 1e5;
2403
- this.zIndexHigh_ = 1e5 + 150;
2404
- this.forwardTab_ = void 0;
2405
- if ("MutationObserver" in window) {
2406
- this.mo_ = new MutationObserver(function(records) {
2407
- var removed = [];
2408
- records.forEach(function(rec) {
2409
- for (var i = 0, c; c = rec.removedNodes[i]; ++i) {
2410
- if (!(c instanceof Element)) {
2411
- continue;
2412
- } else if (c.localName === "dialog") {
2413
- removed.push(c);
2414
- }
2415
- removed = removed.concat(c.querySelectorAll("dialog"));
2416
- }
2417
- });
2418
- removed.length && checkDOM(removed);
2419
- });
2420
- }
2421
- };
2422
- dialogPolyfill.DialogManager.prototype.blockDocument = function() {
2423
- document.documentElement.addEventListener("focus", this.handleFocus_, true);
2424
- document.addEventListener("keydown", this.handleKey_);
2425
- this.mo_ && this.mo_.observe(document, { childList: true, subtree: true });
2426
- };
2427
- dialogPolyfill.DialogManager.prototype.unblockDocument = function() {
2428
- document.documentElement.removeEventListener("focus", this.handleFocus_, true);
2429
- document.removeEventListener("keydown", this.handleKey_);
2430
- this.mo_ && this.mo_.disconnect();
2431
- };
2432
- dialogPolyfill.DialogManager.prototype.updateStacking = function() {
2433
- var zIndex = this.zIndexHigh_;
2434
- for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
2435
- dpi.updateZIndex(--zIndex, --zIndex);
2436
- if (i === 0) {
2437
- this.overlay.style.zIndex = --zIndex;
2438
- }
2439
- }
2440
- var last = this.pendingDialogStack[0];
2441
- if (last) {
2442
- var p = last.dialog.parentNode || document.body;
2443
- p.appendChild(this.overlay);
2444
- } else if (this.overlay.parentNode) {
2445
- this.overlay.parentNode.removeChild(this.overlay);
2446
- }
2447
- };
2448
- dialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function(candidate) {
2449
- while (candidate = findNearestDialog(candidate)) {
2450
- for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
2451
- if (dpi.dialog === candidate) {
2452
- return i === 0;
2453
- }
2454
- }
2455
- candidate = candidate.parentElement;
2456
- }
2457
- return false;
2458
- };
2459
- dialogPolyfill.DialogManager.prototype.handleFocus_ = function(event) {
2460
- var target = event.composedPath ? event.composedPath()[0] : event.target;
2461
- if (this.containedByTopDialog_(target)) {
2462
- return;
2463
- }
2464
- if (document.activeElement === document.documentElement) {
2465
- return;
2466
- }
2467
- event.preventDefault();
2468
- event.stopPropagation();
2469
- safeBlur(target);
2470
- if (this.forwardTab_ === void 0) {
2471
- return;
2472
- }
2473
- var dpi = this.pendingDialogStack[0];
2474
- var dialog = dpi.dialog;
2475
- var position = dialog.compareDocumentPosition(target);
2476
- if (position & Node.DOCUMENT_POSITION_PRECEDING) {
2477
- if (this.forwardTab_) {
2478
- dpi.focus_();
2479
- } else if (target !== document.documentElement) {
2480
- document.documentElement.focus();
2481
- }
2482
- }
2483
- return false;
2484
- };
2485
- dialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {
2486
- this.forwardTab_ = void 0;
2487
- if (event.keyCode === 27) {
2488
- event.preventDefault();
2489
- event.stopPropagation();
2490
- var cancelEvent = new supportCustomEvent("cancel", {
2491
- bubbles: false,
2492
- cancelable: true
2493
- });
2494
- var dpi = this.pendingDialogStack[0];
2495
- if (dpi && safeDispatchEvent(dpi.dialog, cancelEvent)) {
2496
- dpi.dialog.close();
2497
- }
2498
- } else if (event.keyCode === 9) {
2499
- this.forwardTab_ = !event.shiftKey;
2500
- }
2501
- };
2502
- dialogPolyfill.DialogManager.prototype.checkDOM_ = function(removed) {
2503
- var clone = this.pendingDialogStack.slice();
2504
- clone.forEach(function(dpi) {
2505
- if (removed.indexOf(dpi.dialog) !== -1) {
2506
- dpi.downgradeModal();
2507
- } else {
2508
- dpi.maybeHideModal();
2509
- }
2510
- });
2511
- };
2512
- dialogPolyfill.DialogManager.prototype.pushDialog = function(dpi) {
2513
- var allowed = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;
2514
- if (this.pendingDialogStack.length >= allowed) {
2515
- return false;
2516
- }
2517
- if (this.pendingDialogStack.unshift(dpi) === 1) {
2518
- this.blockDocument();
2519
- }
2520
- this.updateStacking();
2521
- return true;
2522
- };
2523
- dialogPolyfill.DialogManager.prototype.removeDialog = function(dpi) {
2524
- var index = this.pendingDialogStack.indexOf(dpi);
2525
- if (index === -1) {
2526
- return;
2527
- }
2528
- this.pendingDialogStack.splice(index, 1);
2529
- if (this.pendingDialogStack.length === 0) {
2530
- this.unblockDocument();
2531
- }
2532
- this.updateStacking();
2533
- };
2534
- dialogPolyfill.dm = new dialogPolyfill.DialogManager();
2535
- dialogPolyfill.formSubmitter = null;
2536
- dialogPolyfill.imagemapUseValue = null;
2537
- if (window.HTMLDialogElement === void 0) {
2538
- var testForm = document.createElement("form");
2539
- testForm.setAttribute("method", "dialog");
2540
- if (testForm.method !== "dialog") {
2541
- var methodDescriptor = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, "method");
2542
- if (methodDescriptor) {
2543
- var realGet = methodDescriptor.get;
2544
- methodDescriptor.get = function() {
2545
- if (isFormMethodDialog(this)) {
2546
- return "dialog";
2547
- }
2548
- return realGet.call(this);
2549
- };
2550
- var realSet = methodDescriptor.set;
2551
- methodDescriptor.set = function(v) {
2552
- if (typeof v === "string" && v.toLowerCase() === "dialog") {
2553
- return this.setAttribute("method", v);
2554
- }
2555
- return realSet.call(this, v);
2556
- };
2557
- Object.defineProperty(HTMLFormElement.prototype, "method", methodDescriptor);
2558
- }
2559
- }
2560
- document.addEventListener("click", function(ev) {
2561
- dialogPolyfill.formSubmitter = null;
2562
- dialogPolyfill.imagemapUseValue = null;
2563
- if (ev.defaultPrevented) {
2564
- return;
2565
- }
2566
- var target = ev.target;
2567
- if ("composedPath" in ev) {
2568
- var path = ev.composedPath();
2569
- target = path.shift() || target;
2570
- }
2571
- if (!target || !isFormMethodDialog(target.form)) {
2572
- return;
2573
- }
2574
- var valid = target.type === "submit" && ["button", "input"].indexOf(target.localName) > -1;
2575
- if (!valid) {
2576
- if (!(target.localName === "input" && target.type === "image")) {
2577
- return;
2578
- }
2579
- dialogPolyfill.imagemapUseValue = ev.offsetX + "," + ev.offsetY;
2580
- }
2581
- var dialog = findNearestDialog(target);
2582
- if (!dialog) {
2583
- return;
2584
- }
2585
- dialogPolyfill.formSubmitter = target;
2586
- }, false);
2587
- document.addEventListener("submit", function(ev) {
2588
- var form = ev.target;
2589
- var dialog = findNearestDialog(form);
2590
- if (dialog) {
2591
- return;
2592
- }
2593
- var submitter = findFormSubmitter(ev);
2594
- var formmethod = submitter && submitter.getAttribute("formmethod") || form.getAttribute("method");
2595
- if (formmethod === "dialog") {
2596
- ev.preventDefault();
2597
- }
2598
- });
2599
- var nativeFormSubmit = HTMLFormElement.prototype.submit;
2600
- var replacementFormSubmit = function() {
2601
- if (!isFormMethodDialog(this)) {
2602
- return nativeFormSubmit.call(this);
2603
- }
2604
- var dialog = findNearestDialog(this);
2605
- dialog && dialog.close();
2606
- };
2607
- HTMLFormElement.prototype.submit = replacementFormSubmit;
2608
- }
2609
- class LightboxImageController extends BaseController {
2610
- constructor() {
2611
- super(...arguments);
2612
- __publicField(this, "_dialog", null);
2613
- }
2614
- get _src() {
2615
- return this.hasSrcValue ? this.srcValue : this.el.src;
2616
- }
2617
- get _srcSet() {
2618
- return this.hasSrcSetValue ? this.srcSetValue : this.el.srcset;
2619
- }
2620
- get _sizes() {
2621
- return this.hasSizesValue ? this.sizesValue : this.el.sizes;
2622
- }
2623
- get _modalClassName() {
2624
- return this.hasModalClass ? this.modalClass : "image-lightbox-dialog";
2625
- }
2626
- get _imageClassName() {
2627
- return this.hasImageClass ? this.imageClass : "image-lightbox-image";
2628
- }
2629
- initialize() {
2630
- this.open = this.open.bind(this);
2631
- this.close = this.close.bind(this);
2632
- }
2633
- connect() {
2634
- }
2635
- disconnect() {
2636
- this.close();
2637
- }
2638
- open() {
2639
- let element = this.el;
2640
- if (this._dialog) {
2641
- return;
2642
- }
2643
- this._dialog = document.createElement("dialog");
2644
- let image = document.createElement("img");
2645
- image.className = this._imageClassName;
2646
- image.src = this._src;
2647
- image.srcset = this._srcSet;
2648
- image.sizes = this._sizes;
2649
- this._dialog.appendChild(image);
2650
- element.insertAdjacentElement("afterend", this._dialog);
2651
- dialogPolyfill.registerDialog(this._dialog);
2652
- this._dialog.className = this._modalClassName;
2653
- this._dialog.showModal();
2654
- scrollToElement(this._dialog, { behavior: "smooth", block: "end" }).catch(() => this._dialog.scrollIntoView(false));
2655
- useEventListener(this, this._dialog, "click", this.close);
2656
- useEventListener(this, this._dialog, "cancel", this.close);
2657
- useEventListener(this, this._dialog, "close", this.close);
2658
- }
2659
- close() {
2660
- if (this._dialog) {
2661
- this._dialog.close();
2662
- this._dialog.remove();
2663
- this._dialog = null;
2664
- scrollToElement(this.el, { behavior: "smooth", block: "end" }).catch(() => this.el.scrollIntoView(false));
2665
- }
2666
- }
2667
- }
2668
- __publicField(LightboxImageController, "values", {
2669
- src: String,
2670
- srcSet: String,
2671
- sizes: String
2672
- });
2673
- __publicField(LightboxImageController, "classes", ["modal", "image"]);
2674
- class MediaPlayerController extends BaseController {
2675
- async play(event) {
2676
- event == null ? void 0 : event.preventDefault();
2677
- await this.mediaTarget.play();
2678
- }
2679
- pause(event) {
2680
- event == null ? void 0 : event.preventDefault();
2681
- this.mediaTarget.pause();
2682
- }
2683
- restart(event) {
2684
- event == null ? void 0 : event.preventDefault();
2685
- this.mediaTarget.currentTime = 0;
2686
- }
2687
- seek(event) {
2688
- event == null ? void 0 : event.preventDefault();
2689
- this.mediaTarget.currentTime += 5;
2690
- }
2691
- }
2692
- __publicField(MediaPlayerController, "targets", ["media"]);
2693
- class ScrollContainerController extends BaseController {
2694
- get _increment() {
2695
- return this.hasIncrementValue ? this.incrementValue : 50;
2696
- }
2697
- get _behaviour() {
2698
- if (this.hasBehaviourValue) {
2699
- if (["auto", "smooth"].includes(this.behaviourValue)) {
2700
- return this.behaviourValue;
2701
- } else {
2702
- throw new Error(`'${this.behaviourValue}' is not a recognised scroll behaviour`);
2703
- }
2704
- } else {
2705
- return "auto";
2706
- }
2707
- }
2708
- async scrollTop(event) {
2709
- event == null ? void 0 : event.preventDefault();
2710
- await scrollAbsoluteTop(this.el, { behavior: this._behaviour });
2711
- }
2712
- async scrollBottom(event) {
2713
- event == null ? void 0 : event.preventDefault();
2714
- await scrollAbsoluteBottom(this.el, { behavior: this._behaviour });
2715
- }
2716
- async scrollLeft(event) {
2717
- event == null ? void 0 : event.preventDefault();
2718
- await scrollAbsoluteLeft(this.el, { behavior: this._behaviour });
2719
- }
2720
- async scrollRight(event) {
2721
- event == null ? void 0 : event.preventDefault();
2722
- await scrollAbsoluteLeft(this.el, { behavior: this._behaviour });
2723
- }
2724
- async up(event) {
2725
- event == null ? void 0 : event.preventDefault();
2726
- await scrollUp(this.el, this._increment, { behavior: this._behaviour });
2727
- }
2728
- async down(event) {
2729
- event == null ? void 0 : event.preventDefault();
2730
- await scrollDown(this.el, this._increment, { behavior: this._behaviour });
2731
- }
2732
- async left(event) {
2733
- event == null ? void 0 : event.preventDefault();
2734
- await scrollLeft(this.el, this._increment, { behavior: this._behaviour });
2735
- }
2736
- async right(event) {
2737
- event == null ? void 0 : event.preventDefault();
2738
- await scrollRight(this.el, this._increment, { behavior: this._behaviour });
2739
- }
2740
- }
2741
- __publicField(ScrollContainerController, "values", {
2742
- behaviour: String,
2743
- increment: Number
2744
- });
2745
- class ScrollIntoFocusController extends EphemeralController {
2746
- connect() {
2747
- requestAnimationFrame(() => {
2748
- scrollToElement(this.el, {
2749
- behavior: this.hasBehaviorValue ? this.behaviorValue : "smooth",
2750
- block: this.hasBlockValue ? this.blockValue : "center",
2751
- inline: this.hasInlineValue ? this.inlineValue : "center"
2752
- }).catch(() => this.el.scrollIntoView());
2753
- this._cleanupSelf();
2754
- });
2755
- }
2756
- }
2757
- __publicField(ScrollIntoFocusController, "values", {
2758
- behavior: String,
2759
- block: String,
2760
- inline: String
2761
- });
2762
- class ScrollToBottomController extends BaseController {
2763
- get _mode() {
2764
- return this.hasModeValue ? this.modeValue : "document";
2765
- }
2766
- get _scrollTarget() {
2767
- let target;
2768
- if (this._mode == "document") {
2769
- target = window;
2770
- } else {
2771
- target = getScrollParent(this.el);
2772
- }
2773
- return target;
2774
- }
2775
- async scroll(event) {
2776
- event == null ? void 0 : event.preventDefault();
2777
- if (this._scrollTarget) {
2778
- await scrollAbsoluteBottom(this._scrollTarget);
2779
- }
2780
- }
2781
- }
2782
- __publicField(ScrollToBottomController, "values", {
2783
- mode: String
2784
- });
2785
- class ScrollToController extends BaseController {
2786
- scroll() {
2787
- let target = document.querySelector(this.selectorValue);
2788
- if (!target) {
2789
- console.warn(`Could not find target for '${this.selectorValue}'`);
2790
- return;
2791
- }
2792
- scrollToElement(target, {
2793
- behavior: this.hasBehaviorValue ? this.behaviorValue : "smooth",
2794
- block: this.hasBlockValue ? this.blockValue : "center",
2795
- inline: this.hasInlineValue ? this.inlineValue : "center"
2796
- }).catch(() => target.scrollIntoView());
2797
- }
2798
- }
2799
- __publicField(ScrollToController, "values", {
2800
- selector: String,
2801
- behavior: String,
2802
- block: String,
2803
- inline: String
2804
- });
2805
- class ScrollToTopController extends BaseController {
2806
- get _mode() {
2807
- return this.hasModeValue ? this.modeValue : "document";
2808
- }
2809
- get _scrollTarget() {
2810
- let target;
2811
- if (this._mode == "document") {
2812
- target = window;
2813
- } else {
2814
- target = getScrollParent(this.el);
2815
- }
2816
- return target;
2817
- }
2818
- async scroll(event) {
2819
- event == null ? void 0 : event.preventDefault();
2820
- if (this._scrollTarget) {
2821
- await scrollAbsoluteTop(this._scrollTarget);
2822
- }
2823
- }
2824
- }
2825
- __publicField(ScrollToTopController, "values", {
2826
- mode: String
2827
- });
2828
- function extractPredicates(expressionString) {
2829
- expressionString = expressionString.trim();
2830
- let andExpression = expressionString.includes("&&");
2831
- let orExpression = expressionString.includes("||");
2832
- let groupings = expressionString.includes("(") || expressionString.includes(")");
2833
- if (andExpression && orExpression) {
2834
- throw new Error("Cannot have both && and || in the same expression.");
2835
- }
2836
- if (groupings) {
2837
- throw new Error("Cannot have logical groupings `(>3 && <= 9) || (>1 && <2)` in the expression. Only supports simple expressions like `>1 && <3`");
2838
- }
2839
- let expressions = expressionString.split(andExpression ? "&&" : "||");
2840
- if (andExpression) {
2841
- return expressions.map((ex) => _predicateForExpression(ex));
2842
- } else if (orExpression) {
2843
- return expressions.map((ex) => _predicateForExpression(ex));
2844
- } else {
2845
- return [_predicateForExpression(expressionString)];
2846
- }
2847
- }
2848
- function _predicateForExpression(expression) {
2849
- let operators = [">=", "<=", "==", "!=", ">", "<"];
2850
- let operator = operators.find((part) => expression.includes(part));
2851
- if (!operator) {
2852
- throw new Error(`Could not find operator in expression: ${expression}`);
2853
- }
2854
- let expressionValue = expression.split(operator)[1].trim();
2855
- let isNumber = /^-?\d*(\.\d+)?$/.test(expressionValue);
2856
- if (isNumber) {
2857
- expressionValue = parseFloat(expressionValue);
2858
- }
2859
- if (expressionValue === "") {
2860
- throw new Error(`Could not find a value in expression: ${expression}`);
2861
- }
2862
- let notEmpty = (signalValue) => signalValue !== "";
2863
- switch (operator) {
2864
- case ">":
2865
- return (signalValue) => isNumber && notEmpty(signalValue) && signalValue > expressionValue;
2866
- case "<":
2867
- return (signalValue) => isNumber && notEmpty(signalValue) && signalValue < expressionValue;
2868
- case ">=":
2869
- return (signalValue) => isNumber && notEmpty(signalValue) && signalValue >= expressionValue;
2870
- case "<=":
2871
- return (signalValue) => isNumber && notEmpty(signalValue) && signalValue <= expressionValue;
2872
- case "==":
2873
- return (signalValue) => notEmpty(signalValue) && signalValue == expressionValue;
2874
- case "!=":
2875
- return (signalValue) => notEmpty(signalValue) && signalValue != expressionValue;
2876
- default:
2877
- throw new Error(`Unknown operator ${operator}`);
2878
- }
2879
- }
2880
- function signalEventName(name, type) {
2881
- return `signal:${type}:${name}`;
2882
- }
2883
- function signalConnectEvent(name) {
2884
- return signalEventName(name, "connect");
2885
- }
2886
- function signalValueEvent(name) {
2887
- return signalEventName(name, "value");
2888
- }
2889
- function signalVisibilityEvent(name, action) {
2890
- return signalEventName(`${name}:${action}`, "visibility");
2891
- }
2892
- class SignalActionController extends BaseController {
2893
- get _predicates() {
2894
- return extractPredicates(this.whenValue);
2895
- }
2896
- connect() {
2897
- EventBus.emit(signalConnectEvent(this.nameValue));
2898
- useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
2899
- }
2900
- _onSignal(payload) {
2901
- let value = payload.value;
2902
- if (!this.hasWhenValue) {
2903
- this.dispatchEvent(this.el, signalEventName(this.nameValue, "match"));
2904
- return;
2905
- }
2906
- if (this._predicates.every((predicate) => predicate(value))) {
2907
- this.dispatchEvent(this.el, signalEventName(this.nameValue, "match"), { detail: { element: this.el, value } });
2908
- } else {
2909
- this.dispatchEvent(this.el, signalEventName(this.nameValue, "no-match"), { detail: { element: this.el, value } });
2910
- }
2911
- }
2912
- }
2913
- __publicField(SignalActionController, "values", {
2914
- name: String,
2915
- when: String
2916
- });
2917
- function useMutationObserver(controller, element, handler, options) {
2918
- handler = handler.bind(controller);
2919
- let observer = new MutationObserver(handler);
2920
- let setup = () => observer.observe(element, options);
2921
- let teardown = () => observer.disconnect();
2922
- useMixin(controller, setup, teardown);
2923
- return teardown;
2924
- }
2925
- class SignalDomChildrenController extends BaseController {
2926
- get _children() {
2927
- if (this.hasScopeSelectorValue) {
2928
- return Array.from(this.el.querySelectorAll(this.scopeSelectorValue));
2929
- } else {
2930
- return Array.from(this.el.children);
2931
- }
2932
- }
2933
- get _name() {
2934
- if (this.hasNameValue) {
2935
- return this.nameValue;
2936
- } else {
2937
- throw new Error("SignalEmptyDomController requires a nameValue to be provided");
2938
- }
2939
- }
2940
- connect() {
2941
- useEventBus(this, signalConnectEvent(this._name), this.emitChildCount);
2942
- EventBus.emit(signalConnectEvent(this._name));
2943
- useMutationObserver(this, this.el, this.mutate, { childList: true });
2944
- this.emitChildCount();
2945
- }
2946
- mutate(entries) {
2947
- this.emitChildCount();
2948
- }
2949
- emitChildCount() {
2950
- let childCount = this._children.length;
2951
- EventBus.emit(signalValueEvent(this._name), { element: this.el, value: childCount.toString() });
2952
- }
2953
- }
2954
- __publicField(SignalDomChildrenController, "values", {
2955
- name: String,
2956
- scopeSelector: String
2957
- });
2958
- class SignalInputController extends BaseController {
2959
- get _debounceTimeout() {
2960
- return this.hasDebounceIntervalValue ? this.debounceIntervalValue : 1;
2961
- }
2962
- get _name() {
2963
- return this.hasNameValue ? this.nameValue : this.element.name;
2964
- }
2965
- connect() {
2966
- useEventBus(this, signalConnectEvent(this._name), () => this.emitValue());
2967
- useEventListeners(this, this.el, ["input", "change"], this.emitValue, { debounce: this._debounceTimeout || void 0 });
2968
- requestAnimationFrame(() => this.emitValue());
2969
- }
2970
- emitValue() {
2971
- var _a;
2972
- let value = this.el.value;
2973
- if (isHTMLInputElement(this.el) && this.el.type === "checkbox") {
2974
- value = this.el.checked ? "true" : "false";
2975
- } else if (isHTMLInputElement(this.el) && this.el.type === "radio") {
2976
- let selectedValue = (_a = getAllRadiosInGroup(this.el).find((el) => el.checked)) == null ? void 0 : _a.value;
2977
- value = selectedValue ? selectedValue : "";
2978
- }
2979
- this.dispatchEvent(this.el, signalValueEvent(this._name), { detail: { value } });
2980
- EventBus.emit(signalValueEvent(this._name), { element: this.el, value });
2981
- }
2982
- }
2983
- __publicField(SignalInputController, "values", {
2984
- name: String,
2985
- debounceInterval: Number
2986
- });
2987
- class SignalVisibilityController extends BaseController {
2988
- get _predicates() {
2989
- return extractPredicates(this.showValue);
2990
- }
2991
- get defaultHideClasses() {
2992
- return ["hide"];
2993
- }
2994
- connect() {
2995
- installClassMethods(this);
2996
- EventBus.emit(signalConnectEvent(this.nameValue));
2997
- useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
2998
- }
2999
- _onSignal(payload) {
3000
- let value = payload.value;
3001
- if (this.showValue == "default") {
3002
- if (value == "") {
3003
- this.removeHideClasses(this.el);
3004
- } else {
3005
- this.addHideClasses(this.el);
3006
- }
3007
- return;
3008
- }
3009
- if (this._predicates.every((predicate) => predicate(value))) {
3010
- this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "show"), { detail: { predicate: this.showValue, value } });
3011
- this.removeHideClasses(this.el);
3012
- } else {
3013
- this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "hide"), { detail: { predicate: this.showValue, value } });
3014
- this.addHideClasses(this.el);
3015
- }
3016
- }
3017
- }
3018
- __publicField(SignalVisibilityController, "values", {
3019
- name: String,
3020
- show: String
3021
- });
3022
- __publicField(SignalVisibilityController, "classes", ["hide"]);
3023
- class TableSortController extends BaseController {
3024
- constructor() {
3025
- super(...arguments);
3026
- __publicField(this, "_lastIndex", null);
3027
- __publicField(this, "_reverse", false);
3028
- }
3029
- get _tableHead() {
3030
- let head = this.el.tHead;
3031
- if (head == null) {
3032
- throw new Error("Expected table to have a <thead> element.");
3033
- }
3034
- return head;
3035
- }
3036
- get _tableHeaders() {
3037
- let rows = this._tableHead.rows;
3038
- if (rows.length == 0) {
3039
- throw new Error("Expected table to have a <thead> element with at least one row.");
3040
- }
3041
- return Array.from(rows[0].cells);
3042
- }
3043
- get _tableBody() {
3044
- return this.el.tBodies[0];
3045
- }
3046
- get _tableRows() {
3047
- return Array.from(this._tableBody.rows);
3048
- }
3049
- connect() {
3050
- requestAnimationFrame(() => {
3051
- useCollectionEventListener(this, this._tableHeaders, "click", this.sort);
3052
- if (this.hasStartSortValue) {
3053
- this._sortByColumn(this.startSortValue);
3054
- }
3055
- });
3056
- }
3057
- sort(event) {
3058
- event.preventDefault();
3059
- let headerCell = event.target;
3060
- let headerCellIndex = this._indexOfHeaderCell(headerCell);
3061
- if (headerCell.dataset.sortable == "false") {
3062
- return;
3063
- }
3064
- if (headerCell.dataset.sort == "asc") {
3065
- this._reverse = true;
3066
- this._otherHeaderCells(headerCell).forEach((cell) => delete cell.dataset.sort);
3067
- headerCell.dataset.sort = "desc";
3068
- this._sortByColumn(headerCellIndex);
3069
- } else {
3070
- this._reverse = false;
3071
- this._otherHeaderCells(headerCell).forEach((cell) => delete cell.dataset.sort);
3072
- headerCell.dataset.sort = "asc";
3073
- this._sortByColumn(headerCellIndex);
3074
- }
3075
- }
3076
- _indexOfHeaderCell(cell) {
3077
- return this._tableHeaders.indexOf(cell);
3078
- }
3079
- _otherHeaderCells(cell) {
3080
- return Array.from(this._tableHeaders).filter((otherCell) => otherCell != cell);
3081
- }
3082
- _sortByColumn(index) {
3083
- let frag = document.createDocumentFragment();
3084
- let rows = this._tableRows;
3085
- let newRows = rows.sort((row, otherRow) => {
3086
- var _a, _b;
3087
- let cells = Array.from(row.cells);
3088
- let otherCells = Array.from(otherRow.cells);
3089
- let x = ((_a = cells[index]) == null ? void 0 : _a.innerText) || "";
3090
- let y = ((_b = otherCells[index]) == null ? void 0 : _b.innerText) || "";
3091
- let sortVal = x.localeCompare(y, "en", { sensitivity: "base", numeric: true, caseFirst: "upper" });
3092
- if (row.dataset.sortTop || otherRow.dataset.sortBottom) {
3093
- if (row.dataset.sortTop && otherRow.dataset.sortTop) {
3094
- return sortVal;
3095
- }
3096
- return -1;
3097
- }
3098
- if (row.dataset.sortBottom || otherRow.dataset.sortTop) {
3099
- if (row.dataset.sortBottom && otherRow.dataset.sortBottom) {
3100
- return sortVal;
3101
- }
3102
- return 1;
3103
- }
3104
- if (this._reverse) {
3105
- return sortVal > 0 ? -1 : 1;
3106
- }
3107
- return sortVal;
3108
- });
3109
- newRows.forEach((row) => frag.appendChild(row));
3110
- this._tableBody.innerHTML = "";
3111
- this._tableBody.appendChild(frag);
3112
- this._lastIndex = index;
3113
- }
3114
- }
3115
- __publicField(TableSortController, "values", { startSort: Number });
3116
- class TableTruncateController extends BaseController {
3117
- get _truncated() {
3118
- return this.hasTruncatedValue ? this.truncatedValue : false;
3119
- }
3120
- set _truncated(value) {
3121
- this.truncatedValue = value;
3122
- }
3123
- get _tableBody() {
3124
- return this.el.tBodies[0];
3125
- }
3126
- get _tableRows() {
3127
- return Array.from(this._tableBody.rows);
3128
- }
3129
- get _limit() {
3130
- return this.hasLimitValue ? this.limitValue : 20;
3131
- }
3132
- connect() {
3133
- useMutationObserver(this, this._tableBody, this.mutate, { childList: true });
3134
- requestAnimationFrame(() => {
3135
- this.truncate();
3136
- useEventListener(this, this.showMoreTarget, "click", this.expand);
3137
- });
3138
- }
3139
- truncate(event) {
3140
- event == null ? void 0 : event.preventDefault();
3141
- this._truncated = true;
3142
- if (this._tableRows.length >= this._limit) {
3143
- this._tableRows.slice(this._limit).forEach((el) => {
3144
- if (el !== this.showMoreTarget) {
3145
- this._hideElement(el);
3146
- }
3147
- });
3148
- this._showElement(this.showMoreTarget);
3149
- } else {
3150
- this._hideElement(this.showMoreTarget);
3151
- }
3152
- }
3153
- expand(event) {
3154
- this._truncated = false;
3155
- event == null ? void 0 : event.preventDefault();
3156
- this._tableRows.slice(this._limit).forEach((el) => {
3157
- if (el !== this.showMoreTarget) {
3158
- this._showElement(el);
3159
- }
3160
- });
3161
- this._hideElement(this.showMoreTarget);
3162
- }
3163
- mutate(entries) {
3164
- if (this._truncated) {
3165
- this._reTruncate();
3166
- }
3167
- }
3168
- _showElement(el) {
3169
- el.style.display = "";
3170
- }
3171
- _hideElement(el) {
3172
- el.style.display = "none";
3173
- }
3174
- _reTruncate() {
3175
- this._tableRows.slice(0, this._limit).forEach((el) => {
3176
- if (el !== this.showMoreTarget) {
3177
- this._showElement(el);
3178
- }
3179
- });
3180
- this._tableRows.slice(this._limit).forEach((el) => {
3181
- if (el !== this.showMoreTarget) {
3182
- this._hideElement(el);
3183
- }
3184
- });
3185
- this._showElement(this.showMoreTarget);
3186
- }
3187
- }
3188
- __publicField(TableTruncateController, "targets", ["showMore"]);
3189
- __publicField(TableTruncateController, "values", {
3190
- limit: Number,
3191
- truncated: Boolean
3192
- });
3193
- class AlertController extends BaseController {
3194
- alert() {
3195
- alert(this.messageValue);
3196
- }
3197
- }
3198
- __publicField(AlertController, "values", { message: String });
3199
- class FullscreenController extends BaseController {
3200
- connect() {
3201
- let { enter, exit, toggle } = useFullscreen(this);
3202
- this.enter = enter;
3203
- this.exit = exit;
3204
- this.toggle = toggle;
3205
- }
3206
- }
3207
- class IntersectionController extends BaseController {
3208
- get _threshold() {
3209
- if (this.hasThresholdValue) {
3210
- return this.thresholdValue.split(",").map((val) => Number.parseFloat(val.trim())).filter((val) => val >= 0 && val <= 1);
3211
- } else {
3212
- return [0, 1];
3213
- }
3214
- }
3215
- connect() {
3216
- useIntersection(this, this.el, this.appear, this.disappear, { threshold: this._threshold });
3217
- }
3218
- appear(entry) {
3219
- dispatchEvent(this, this.el, "intersection:appear");
3220
- }
3221
- disappear(entry) {
3222
- dispatchEvent(this, this.el, "intersection:disappear");
3223
- }
3224
- }
3225
- __publicField(IntersectionController, "values", { threshold: String });
3226
- class IntervalController extends BaseController {
3227
- connect() {
3228
- if (!this.hasSecondsValue) {
3229
- throw new Error("Expected `secondsValue` to be present");
3230
- }
3231
- requestAnimationFrame(() => {
3232
- useInterval(this, this._interval, this.secondsValue * 1e3);
3233
- });
3234
- }
3235
- _interval() {
3236
- this.dispatchEvent(this.el, "interval:action");
3237
- }
3238
- }
3239
- __publicField(IntervalController, "values", { seconds: Number });
3240
- class PresenceController extends BaseController {
3241
- get name() {
3242
- return this.hasNameValue ? this.nameValue : ``;
3243
- }
3244
- get _addedEventName() {
3245
- return [this.name, "presence", "added"].filter((el) => !!el).join(":");
3246
- }
3247
- get _removedEventName() {
3248
- return [this.name, "presence", "removed"].filter((el) => !!el).join(":");
3249
- }
3250
- connect() {
3251
- this.dispatchEvent(this.el, this._addedEventName);
3252
- }
3253
- disconnect() {
3254
- this.dispatchEvent(this.el, this._removedEventName);
3255
- }
3256
- }
3257
- __publicField(PresenceController, "values", { name: String });
3258
- class PrintController extends BaseController {
3259
- print(event) {
3260
- event == null ? void 0 : event.preventDefault();
3261
- window.print();
3262
- }
3263
- }
3264
- class TimeoutController extends BaseController {
3265
- connect() {
3266
- requestAnimationFrame(() => {
3267
- useTimeout(this, this._timeout, this.secondsValue * 1e3);
3268
- });
3269
- }
3270
- _timeout() {
3271
- this.dispatchEvent(this.el, "timeout");
3272
- }
3273
- }
3274
- __publicField(TimeoutController, "values", { seconds: Number });
3275
- class UserFocusController extends BaseController {
3276
- connect() {
3277
- useEventListener(this, window, ["focus", "blur"], this._handleVisibility);
3278
- useEventListener(this, document, "visibilitychange", this._handleVisibility);
3279
- requestAnimationFrame(() => {
3280
- this._handleVisibility();
3281
- });
3282
- }
3283
- appear() {
3284
- this.dispatchEvent(this.el, "user-focus:active");
3285
- }
3286
- away() {
3287
- this.dispatchEvent(this.el, "user-focus:away");
3288
- }
3289
- _handleVisibility() {
3290
- this._documentIsActive() ? this.appear() : this.away();
3291
- }
3292
- _documentIsActive() {
3293
- return document.visibilityState == "visible" && document.hasFocus();
3294
- }
3295
- }
3296
- class ClockController extends BaseController {
3297
- get _tickInterval() {
3298
- if (this.hasMillisecondsTarget) {
3299
- return 1;
3300
- } else if (this.hasSecondsTarget) {
3301
- return 1e3;
3302
- } else if (this.hasMinutesTarget) {
3303
- return 15e3;
3304
- } else {
3305
- return 3e5;
3306
- }
3307
- }
3308
- connect() {
3309
- requestAnimationFrame(() => {
3310
- useInterval(this, this._tick, this._tickInterval);
3311
- });
3312
- }
3313
- _tick() {
3314
- let current = new Date();
3315
- if (this.hasHoursTarget) {
3316
- this.hoursTarget.innerHTML = current.getHours().toString().padStart(2, "0");
3317
- }
3318
- if (this.hasMinutesTarget) {
3319
- this.minutesTarget.innerHTML = current.getMinutes().toString().padStart(2, "0");
3320
- }
3321
- if (this.hasSecondsTarget) {
3322
- this.secondsTarget.innerHTML = current.getSeconds().toString().padStart(2, "0");
3323
- }
3324
- if (this.hasMillisecondsTarget) {
3325
- this.millisecondsTarget.innerHTML = current.getMilliseconds().toString().padStart(3, "0");
3326
- }
3327
- }
3328
- }
3329
- __publicField(ClockController, "targets", ["hours", "minutes", "seconds", "milliseconds"]);
3330
- class CountdownController extends BaseController {
3331
- constructor() {
3332
- super(...arguments);
3333
- __publicField(this, "_interval", null);
3334
- }
3335
- get _removeUnused() {
3336
- return this.hasRemoveUnusedValue ? this.removeUnusedValue : false;
3337
- }
3338
- get _deadlineDate() {
3339
- return new Date(this.deadlineValue);
3340
- }
3341
- connect() {
3342
- this._interval = setInterval(this._tick.bind(this), 1e3);
3343
- this.addCountingDownClasses();
3344
- }
3345
- disconnect() {
3346
- this._clearTick();
3347
- this.removeCountingDownClasses();
3348
- this.removeEndedClasses();
3349
- }
3350
- deadlineValueChanged() {
3351
- if (this._interval == null) {
3352
- this._interval = setInterval(this._tick.bind(this), 1e3);
3353
- }
3354
- }
3355
- _tick() {
3356
- try {
3357
- const now = new Date();
3358
- let distance = {};
3359
- if (isPast(this._deadlineDate)) {
3360
- distance = { years: 0, months: 0, days: 0, hours: 0, minutes: 0, seconds: 0 };
3361
- this._clearTick();
3362
- this.removeCountingDownClasses();
3363
- this.addEndedClasses();
3364
- this.dispatchEvent(this.el, "countdown:ended");
3365
- } else {
3366
- distance = intervalToDuration({ start: this._deadlineDate, end: now });
3367
- }
3368
- if (this.hasYearsTarget) {
3369
- this._updateTarget(this.yearsTarget, this._years(distance));
3370
- }
3371
- if (this.hasMonthsTarget) {
3372
- this._updateTarget(this.monthsTarget, this._months(distance));
3373
- }
3374
- if (this.hasDaysTarget) {
3375
- this._updateTarget(this.daysTarget, this._days(distance));
3376
- }
3377
- if (this.hasHoursTarget) {
3378
- this._updateTarget(this.hoursTarget, this._hours(distance));
3379
- }
3380
- if (this.hasMinutesTarget) {
3381
- this._updateTarget(this.minutesTarget, this._minutes(distance));
3382
- }
3383
- if (this.hasSecondsTarget) {
3384
- this._updateTarget(this.secondsTarget, this._seconds(distance));
3385
- }
3386
- } catch (e) {
3387
- console.error(e);
3388
- this._clearTick();
3389
- }
3390
- }
3391
- _clearTick() {
3392
- if (this._interval) {
3393
- clearInterval(this._interval);
3394
- this._interval = null;
3395
- }
3396
- }
3397
- _updateTarget(target, value) {
3398
- this._removeTargetIfUnused(target, value);
3399
- target.innerHTML = value.toString();
3400
- }
3401
- _removeTargetIfUnused(target, value) {
3402
- if (this._removeUnused) {
3403
- if (value === 0 && target.dataset.unused) {
3404
- if (Number.parseInt(target.dataset.unused) > Date.now() + 1500) {
3405
- target.remove();
3406
- }
3407
- } else if (value == 0) {
3408
- target.dataset.unused = Date.now().toString();
3409
- } else {
3410
- target.dataset.unused = void 0;
3411
- }
3412
- }
3413
- }
3414
- _years(duration) {
3415
- return duration.years || 0;
3416
- }
3417
- _months(duration) {
3418
- return duration.months || 0;
3419
- }
3420
- _days(duration) {
3421
- return duration.days || 0;
3422
- }
3423
- _hours(duration) {
3424
- return duration.hours || 0;
3425
- }
3426
- _minutes(duration) {
3427
- return duration.minutes || 0;
3428
- }
3429
- _seconds(duration) {
3430
- return duration.seconds || 0;
3431
- }
3432
- }
3433
- __publicField(CountdownController, "values", { deadline: String, removeUnused: Boolean });
3434
- __publicField(CountdownController, "targets", ["years", "months", "days", "hours", "minutes", "seconds"]);
3435
- __publicField(CountdownController, "classes", ["countingDown", "ended"]);
3436
- class DurationController extends BaseController {
3437
- get _format() {
3438
- return [
3439
- "years",
3440
- "months",
3441
- "weeks",
3442
- "days",
3443
- "hours",
3444
- ...this._minutes ? ["minutes"] : [],
3445
- ...this._seconds ? ["seconds"] : []
3446
- ];
3447
- }
3448
- get _output() {
3449
- let { years, months, weeks, days, hours, minutes, seconds } = this._duration;
3450
- years || (years = 0);
3451
- months || (months = 0);
3452
- weeks || (weeks = 0);
3453
- days || (days = 0);
3454
- hours || (hours = 0);
3455
- minutes || (minutes = 0);
3456
- seconds || (seconds = 0);
3457
- let largeDenominators = [years, months, weeks, days, hours];
3458
- if (!this._minutes && !this._seconds && largeDenominators.every((x) => x === 0)) {
3459
- minutes = minutes + seconds / 60;
3460
- return `${(minutes / 60).toFixed(1)} hours`;
3461
- }
3462
- return formatDuration(this._duration, { format: this._format, delimiter: ", " });
3463
- }
3464
- get _seconds() {
3465
- return this.hasSecondsValue ? this.secondsValue : true;
3466
- }
3467
- get _minutes() {
3468
- return this.hasMinutesValue ? this.minutesValue : true;
3469
- }
3470
- get _timestamp() {
3471
- if (this.hasTimestampValue) {
3472
- return toDate(this.timestampValue * 1e3);
3473
- } else {
3474
- throw new Error("Expected `timestampValue` to be present");
3475
- }
3476
- }
3477
- get _duration() {
3478
- return intervalToDuration({ start: new Date(), end: this._timestamp });
3479
- }
3480
- get _tickInterval() {
3481
- if (this._seconds) {
3482
- return 1e3;
3483
- } else if (this._minutes) {
3484
- return 15e3;
3485
- } else {
3486
- return 12e4;
3487
- }
3488
- }
3489
- connect() {
3490
- this._clearInterval = useInterval(this, this._update, this._tickInterval);
3491
- this._update();
3492
- }
3493
- _update() {
3494
- try {
3495
- this.el.innerHTML = this._output;
3496
- } catch {
3497
- this._clearInterval();
3498
- }
3499
- }
3500
- }
3501
- __publicField(DurationController, "values", {
3502
- timestamp: Number,
3503
- minutes: Boolean,
3504
- seconds: Boolean
3505
- });
3506
- class TabsController extends BaseController {
3507
- get defaultHideClasses() {
3508
- return ["hide"];
3509
- }
3510
- get defaultActiveClasses() {
3511
- return ["is-active"];
3512
- }
3513
- get _currentTab() {
3514
- return this.hasCurrentTabValue ? this.currentTabValue : 0;
3515
- }
3516
- get _equalize() {
3517
- return this.hasEqualizeValue ? this.equalizeValue : false;
3518
- }
3519
- connect() {
3520
- useCollectionEventListener(this, this.linkTargets, "click", this.switchTabs);
3521
- if (this._equalize) {
3522
- this._setMinHeight();
3523
- }
3524
- this.currentTabValue = this._currentTab;
3525
- }
3526
- switchTabs(event) {
3527
- event.preventDefault();
3528
- this.currentTabValue = this.linkTargets.indexOf(event.currentTarget);
3529
- }
3530
- currentTabValueChanged() {
3531
- let index = this._currentTab;
3532
- index = this._clampIndex(index);
3533
- this._selectTab(index);
3534
- }
3535
- _selectTab(index) {
3536
- index = this._clampIndex(index);
3537
- let links = this.linkTargets;
3538
- let panels = this.contentTargets;
3539
- let activePanel = panels[index];
3540
- let activeLink = links[index];
3541
- let otherPanels = [...panels.slice(0, index), ...panels.slice(index + 1)];
3542
- let otherLinks = [...links.slice(0, index), ...links.slice(index + 1)];
3543
- this.addActiveClasses(activeLink);
3544
- activeLink.setAttribute("aria-selected", "true");
3545
- this.addActiveClasses(activePanel);
3546
- this.removeHideClasses(activePanel);
3547
- otherLinks.forEach((link) => {
3548
- link.removeAttribute("aria-selected");
3549
- this.removeActiveClasses(link);
3550
- });
3551
- otherPanels.forEach((panel) => {
3552
- this.removeActiveClasses(panel);
3553
- this.addHideClasses(panel);
3554
- });
3555
- }
3556
- _clampIndex(index) {
3557
- return clamp(index, 0, this.contentTargets.length - 1);
3558
- }
3559
- _setMinHeight() {
3560
- let minHeight = 0;
3561
- this.contentTargets.forEach((content) => {
3562
- let hidden = content.hasAttribute("tab-hidden");
3563
- if (hidden) {
3564
- this.removeHideClasses(content);
3565
- }
3566
- let height = content.offsetHeight;
3567
- if (height > minHeight) {
3568
- minHeight = height;
3569
- }
3570
- if (hidden) {
3571
- this.addHideClasses(content);
3572
- }
3573
- });
3574
- this.contentTargets.forEach((content) => content.style.minHeight = minHeight + "px");
3575
- }
3576
- }
3577
- __publicField(TabsController, "values", { currentTab: Number, equalize: Boolean });
3578
- __publicField(TabsController, "targets", ["link", "content"]);
3579
- __publicField(TabsController, "classes", ["active", "hide"]);
3580
- class TimeDistanceController extends BaseController {
3581
- get _duration() {
3582
- return isPast(this._timestamp) ? intervalToDuration({ start: this._timestamp, end: new Date() }) : intervalToDuration({ start: new Date(), end: this._timestamp });
3583
- }
3584
- get _nextUpdate() {
3585
- let duration = this._duration;
3586
- if (duration.years && duration.years > 0) {
3587
- return null;
3588
- } else if (duration.months && duration.months > 0) {
3589
- return null;
3590
- } else if (duration.days && duration.days > 0) {
3591
- return null;
3592
- } else if (duration.hours && duration.hours > 0) {
3593
- return 18e5;
3594
- } else {
3595
- return 3e4;
3596
- }
3597
- }
3598
- timestampValueChanged() {
3599
- this._timestamp = toDate(this.timestampValue * 1e3);
3600
- }
3601
- connect() {
3602
- if (!this.hasTimestampValue) {
3603
- throw new Error("Expected `timestampValue` to be present");
3604
- }
3605
- this._update();
3606
- }
3607
- _update() {
3608
- this.el.innerHTML = formatDistanceToNow(this._timestamp, {
3609
- addSuffix: true,
3610
- includeSeconds: true
3611
- });
3612
- if (this._nextUpdate) {
3613
- useTimeout(this, this._update, this._nextUpdate);
3614
- }
3615
- }
3616
- }
3617
- __publicField(TimeDistanceController, "values", {
3618
- timestamp: Number
3619
- });
3620
- class TreeViewController extends BaseController {
3621
- get defaultActiveClasses() {
3622
- return ["active"];
3623
- }
3624
- get defaultCollapsedClasses() {
3625
- return ["collapsed"];
3626
- }
3627
- initialize() {
3628
- this._nodeClicked = this._nodeClicked.bind(this);
3629
- }
3630
- connect() {
3631
- installClassMethods(this);
3632
- useMutationObserver(this, this.el, this.mutate, { subtree: true, childList: true });
3633
- this._setup();
3634
- }
3635
- disconnect() {
3636
- this._teardown();
3637
- }
3638
- _setup() {
3639
- this._setupNode(this.el);
3640
- }
3641
- _setupNode(el) {
3642
- const process = (e) => {
3643
- let parent = e.parentElement;
3644
- if (parent) {
3645
- if (!this._nodeActive(parent)) {
3646
- this._hideNode(parent);
3647
- }
3648
- parent.removeEventListener("click", this._nodeClicked);
3649
- parent.addEventListener("click", this._nodeClicked);
3650
- }
3651
- };
3652
- if (el.tagName === "UL" || el.tagName === "OL") {
3653
- process(el);
3654
- }
3655
- el.querySelectorAll("ul, ol").forEach((e) => process(e));
3656
- }
3657
- _teardown() {
3658
- this.el.querySelectorAll("ul, ol, li").forEach((el) => this._teardownNode(el));
3659
- }
3660
- _teardownNode(el) {
3661
- [el, ...Array.from(el.querySelectorAll("ul, ol, li"))].forEach((x) => {
3662
- x.removeEventListener("click", this._nodeClicked);
3663
- this.removeActiveClasses(x);
3664
- this.removeCollapsedClasses(x);
3665
- });
3666
- }
3667
- _nodeClicked(event) {
3668
- if (event) {
3669
- event.stopImmediatePropagation();
3670
- }
3671
- let el = event.target;
3672
- if (!el || !this._hasNested(el)) {
3673
- return;
3674
- }
3675
- if (this._nodeActive(el)) {
3676
- this._hideNode(el);
3677
- } else {
3678
- this._showNode(el);
3679
- }
3680
- }
3681
- _nodeActive(el) {
3682
- return this.activeClassesPresent(el);
3683
- }
3684
- _showNode(el) {
3685
- this.removeCollapsedClasses(el);
3686
- this.addActiveClasses(el);
3687
- }
3688
- _hideNode(el) {
3689
- this.removeActiveClasses(el);
3690
- this.addCollapsedClasses(el);
3691
- }
3692
- _hasNested(el) {
3693
- return el.querySelectorAll("ul, ol").length > 0;
3694
- }
3695
- mutate(entries) {
3696
- for (const mutation of entries) {
3697
- if (mutation.type === "childList") {
3698
- Array.from(mutation.addedNodes || []).forEach((el) => this._setupNode(el));
3699
- Array.from(mutation.removedNodes || []).forEach((el) => this._teardownNode(el));
3700
- }
3701
- }
3702
- }
3703
- }
3704
- __publicField(TreeViewController, "classes", [
3705
- "active",
3706
- "collapsed"
3707
- ]);
3708
- class AnchorSpyController extends BaseController {
3709
- get defaultActiveClasses() {
3710
- return ["active"];
3711
- }
3712
- get defaultInactiveClasses() {
3713
- return ["inactive"];
3714
- }
3715
- get _key() {
3716
- return this.keyValue.replaceAll("#", "");
3717
- }
3718
- get _anchor() {
3719
- return window.location.hash.substr(1);
3720
- }
3721
- set _anchor(value) {
3722
- window.location.hash = value;
3723
- }
3724
- connect() {
3725
- installClassMethods(this);
3726
- requestAnimationFrame(() => {
3727
- this._checkAnchor();
3728
- useEventListener(this, window, "hashchange", this._checkAnchor);
3729
- });
3730
- }
3731
- write(event) {
3732
- event == null ? void 0 : event.preventDefault();
3733
- this._anchor = this._key;
3734
- }
3735
- _checkAnchor() {
3736
- if (this._key === this._anchor) {
3737
- this.dispatchEvent(this.el, "anchor-spy:active");
3738
- this.addActiveClasses(this.el);
3739
- this.removeInactiveClasses(this.el);
3740
- } else {
3741
- this.dispatchEvent(this.el, "anchor-spy:inactive");
3742
- this.addInactiveClasses(this.el);
3743
- this.removeActiveClasses(this.el);
3744
- }
3745
- }
3746
- }
3747
- __publicField(AnchorSpyController, "values", { key: String });
3748
- __publicField(AnchorSpyController, "classes", ["active", "inactive"]);
3749
- class BackLinkController extends BaseController {
3750
- get _pages() {
3751
- return this.hasPagesValue ? Math.abs(this.pagesValue) : 1;
3752
- }
3753
- get _timeout() {
3754
- return this.hasTimeoutValue ? this.timeoutValue : 1500;
3755
- }
3756
- connect() {
3757
- useEventListener(this, this.el, "click", this.goBack);
3758
- }
3759
- goBack(event) {
3760
- event == null ? void 0 : event.preventDefault();
3761
- history.go(-this._pages);
3762
- if (this.el.href) {
3763
- useTimeout(this, this.fallback, this._timeout);
3764
- }
3765
- }
3766
- fallback() {
3767
- window.location.href = this.el.href;
3768
- }
3769
- }
3770
- __publicField(BackLinkController, "values", { timeout: Number, pages: Number });
3771
- class ClipboardController extends BaseController {
3772
- constructor() {
3773
- super(...arguments);
3774
- __publicField(this, "_supported", false);
3775
- }
3776
- connect() {
3777
- this._supported = document.queryCommandSupported("copy");
3778
- if (this.hasRemoveUnusedValue && this.removeUnusedValue) {
3779
- if (this._supported && this.hasFallbackTarget) {
3780
- this.fallbackTarget.remove();
3781
- } else if (this.hasCopyTarget) {
3782
- this.copyTarget.remove();
3783
- }
3784
- }
3785
- }
3786
- select(event) {
3787
- if (event) {
3788
- event.preventDefault();
3789
- }
3790
- this.sourceTarget.select();
3791
- }
3792
- copy(event) {
3793
- if (event) {
3794
- event.preventDefault();
3795
- }
3796
- this.sourceTarget.select();
3797
- if (this._supported) {
3798
- document.execCommand("copy");
3799
- }
3800
- }
3801
- }
3802
- __publicField(ClipboardController, "targets", ["source", "button", "copy", "fallback"]);
3803
- __publicField(ClipboardController, "values", { removeUnused: Boolean });
3804
- class ConfirmController extends BaseController {
3805
- get _message() {
3806
- return this.hasMessageValue ? this.messageValue : "Are you sure?";
3807
- }
3808
- get _eventType() {
3809
- if (isHTMLFormElement(this.el)) {
3810
- return "submit";
3811
- } else if (isHTMLAnchorElement(this.el)) {
3812
- return "click";
3813
- } else {
3814
- throw new Error("Can't handle confirmation on attached element");
3815
- }
3816
- }
3817
- connect() {
3818
- requestAnimationFrame(() => {
3819
- useEventListener(this, this.el, this._eventType, this.confirm);
3820
- });
3821
- }
3822
- confirm(event) {
3823
- if (!window.confirm(this._message)) {
3824
- event.preventDefault();
3825
- this.dispatchEvent(this.el, "confirm:cancelled");
3826
- }
3827
- }
3828
- }
3829
- __publicField(ConfirmController, "values", {
3830
- message: String
3831
- });
3832
- class ConfirmNavigationController extends BaseController {
3833
- get _message() {
3834
- return this.hasMessageValue ? this.messageValue : "Do you want to leave this page? Changes you made may not be saved";
3835
- }
3836
- connect() {
3837
- window.onbeforeunload = () => this._message;
3838
- useEventListener(this, window, "popstate", this.confirmNavigation);
3839
- useEventListener(this, window, "submit", this.allowSubmit);
3840
- useEventListener(this, window, ["turbolinks:before-visit", "turbo:before-visit"], this.confirmTurboNavigation);
3841
- }
3842
- disconnect() {
3843
- window.onbeforeunload = null;
3844
- }
3845
- allowSubmit(_event) {
3846
- window.removeEventListener("popstate", this.confirmNavigation);
3847
- window.onbeforeunload = null;
3848
- }
3849
- confirmNavigation(_event) {
3850
- return false;
3851
- }
3852
- confirmTurboNavigation(event) {
3853
- if (!confirm(this._message)) {
3854
- event.preventDefault();
3855
- }
3856
- }
3857
- }
3858
- __publicField(ConfirmNavigationController, "values", { message: String });
3859
- class DebugController extends BaseController {
3860
- connect() {
3861
- console.log("Debug Controller", this, this.testTargets);
3862
- }
3863
- }
3864
- __publicField(DebugController, "targets", ["test"]);
3865
- class DisableWithController extends BaseController {
3866
- get _message() {
3867
- return this.hasMessageValue ? this.messageValue : "Submitting...";
3868
- }
3869
- get _timeout() {
3870
- return this.hasTimeoutValue ? this.timeoutValue : 1e3;
3871
- }
3872
- connect() {
3873
- requestAnimationFrame(() => {
3874
- useEventListener(this, this.el, ["click"], this.disable);
3875
- useEventListener(this, window, ["turbo:load", "turbolinks:load"], this._enable);
3876
- });
3877
- }
3878
- disable(event) {
3879
- let element = this.el;
3880
- if (this._isDisabled(element)) {
3881
- event == null ? void 0 : event.preventDefault();
3882
- event == null ? void 0 : event.stopImmediatePropagation();
3883
- } else {
3884
- this._disable();
3885
- useTemporaryContent(this, element, this._message, this._timeout, this._enable);
3886
- }
3887
- }
3888
- enable(event) {
3889
- event == null ? void 0 : event.preventDefault();
3890
- let element = this.el;
3891
- if (this._isDisabled(element)) {
3892
- this._enable();
3893
- }
3894
- }
3895
- _isDisabled(el) {
3896
- if (isTypeOfButtonableElement(el)) {
3897
- return el.disabled;
3898
- } else {
3899
- return el.dataset.disabled == "true";
3900
- }
3901
- }
3902
- _disable() {
3903
- let el = this.el;
3904
- if (isTypeOfButtonableElement(el)) {
3905
- el.disabled = true;
3906
- } else {
3907
- el.dataset.disabled = "true";
3908
- }
3909
- }
3910
- _enable() {
3911
- let el = this.el;
3912
- if (isTypeOfButtonableElement(el)) {
3913
- el.disabled = false;
3914
- } else {
3915
- el.dataset.disabled = void 0;
3916
- }
3917
- }
3918
- }
3919
- __publicField(DisableWithController, "values", {
3920
- message: String,
3921
- timeout: Number
3922
- });
3923
- class DismissableController extends BaseController {
3924
- dismiss() {
3925
- this.el.remove();
3926
- }
3927
- }
3928
- class RemoveController extends DismissableController {
3929
- }
3930
- class ElementSaveController extends BaseController {
3931
- get _id() {
3932
- if (this.hasIdValue) {
3933
- return this.idValue;
3934
- }
3935
- let elementID = this.el.id;
3936
- if (elementID !== "") {
3937
- return elementID;
3938
- } else {
3939
- throw new Error(`No ID value to uniquely identify this element. Please either specify data-${this.identifier}-id-value or give this element an 'id' attribute. `);
3940
- }
3941
- }
3942
- get _uniqueIdentifier() {
3943
- const url = location.href;
3944
- return `${url} ${this._id}`;
3945
- }
3946
- get _restoreOnLoad() {
3947
- return this.hasRestoreOnLoadValue ? this.restoreOnLoadValue : true;
3948
- }
3949
- get _element() {
3950
- return this.hasElementTarget ? this.elementTarget : this.el;
3951
- }
3952
- initialize() {
3953
- this.save = debounce(this.save.bind(this), 300);
3954
- }
3955
- connect() {
3956
- this._store = useLocalStorage(this, this._uniqueIdentifier, {});
3957
- requestAnimationFrame(() => {
3958
- if (this._restoreOnLoad) {
3959
- this.restore();
3960
- }
3961
- });
3962
- }
3963
- clear(event) {
3964
- if (event) {
3965
- event.preventDefault();
3966
- }
3967
- this._store.clear();
3968
- this.dispatchEvent(this._element, `element-save:cleared`);
3969
- }
3970
- save(event) {
3971
- if (event) {
3972
- event.preventDefault();
3973
- }
3974
- let element = this._element;
3975
- let attributes = this.attributesValue.split(" ");
3976
- let data = {};
3977
- attributes.forEach((attr) => data[attr] = get(element, attr));
3978
- this._store.value = data;
3979
- this.dispatchEvent(element, `element-save:save:success`);
3980
- }
3981
- restore(event) {
3982
- if (event) {
3983
- event.preventDefault();
3984
- }
3985
- let element = this._element;
3986
- if (!this._store.isEmpty()) {
3987
- const savedData = this._store.value;
3988
- Object.keys(savedData).forEach((attr) => set(element, attr, savedData[attr]));
3989
- this.dispatchEvent(element, `element-save:restore:success`);
3990
- } else {
3991
- this.dispatchEvent(element, `element-save:restore:empty`);
3992
- }
3993
- }
3994
- }
3995
- __publicField(ElementSaveController, "targets", [
3996
- "element"
3997
- ]);
3998
- __publicField(ElementSaveController, "values", {
3999
- id: String,
4000
- attributes: String,
4001
- restoreOnLoad: Boolean
4002
- });
4003
- class EmptyDomController extends BaseController {
4004
- get _container() {
4005
- return this.hasContainerTarget ? this.containerTarget : this.el;
4006
- }
4007
- get _children() {
4008
- let element = this._container;
4009
- if (this.hasScopeSelectorValue) {
4010
- return Array.from(element.querySelectorAll(this.scopeSelectorValue));
4011
- } else {
4012
- return Array.from(element.children);
4013
- }
4014
- }
4015
- connect() {
4016
- installClassMethods(this);
4017
- useMutationObserver(this, this._container, this.mutate, { childList: true });
4018
- this.checkEmpty();
4019
- }
4020
- mutate(entries) {
4021
- this.checkEmpty();
4022
- }
4023
- checkEmpty() {
4024
- let element = this._container;
4025
- let children = this._children;
4026
- if (children.length === 0) {
4027
- this.removeNotEmptyClasses();
4028
- this.addEmptyClasses();
4029
- this.dispatchEvent(element, "dom:empty");
4030
- } else {
4031
- this.addNotEmptyClasses();
4032
- this.removeEmptyClasses();
4033
- this.dispatchEvent(element, "dom:not-empty", { detail: { count: children.length } });
4034
- }
4035
- }
4036
- }
4037
- __publicField(EmptyDomController, "targets", ["container"]);
4038
- __publicField(EmptyDomController, "classes", ["empty", "notEmpty"]);
4039
- __publicField(EmptyDomController, "values", { scopeSelector: String });
4040
- class PrefetchController extends BaseController {
4041
- get _mode() {
4042
- return this.hasModeValue ? this.modeValue : "mouseover";
4043
- }
4044
- get _supportsPrefetch() {
4045
- var _a, _b;
4046
- const link = document.createElement("link");
4047
- return ((_a = link.relList) == null ? void 0 : _a.supports) && ((_b = link.relList) == null ? void 0 : _b.supports("prefetch"));
4048
- }
4049
- get _href() {
4050
- return this.el.href;
4051
- }
4052
- get _existingPrefetch() {
4053
- return (document.head.querySelectorAll(`link[rel="prefetch"][href="${this._href}"]`) || []).length > 0;
4054
- }
4055
- get _connectionSuitable() {
4056
- const connection = navigator.connection;
4057
- if (!connection) {
4058
- return true;
4059
- }
4060
- if (connection) {
4061
- if (connection.saveData) {
4062
- warn(this, "Data Saving is enabled");
4063
- return false;
4064
- }
4065
- if (/2g/.test(connection.effectiveType)) {
4066
- warn(this, "Network is too slow");
4067
- return false;
4068
- }
4069
- }
4070
- return true;
4071
- }
4072
- connect() {
4073
- if (!this._supportsPrefetch) {
4074
- return;
4075
- }
4076
- switch (this._mode) {
4077
- case "intersect":
4078
- this._setupObserver();
4079
- break;
4080
- case "mouseover":
4081
- useEventListener(this, this.el, "mouseover", this.prefetch, { once: true });
4082
- break;
4083
- default:
4084
- throw new Error(`'${this._mode}' is not a supported prefetch mode`);
4085
- }
4086
- }
4087
- _setupObserver() {
4088
- const observer = new IntersectionObserver(([entry], observer2) => {
4089
- if (entry.isIntersecting) {
4090
- this.prefetch();
4091
- observer2.unobserve(entry.target);
4092
- }
4093
- });
4094
- observer.observe(this.element);
4095
- }
4096
- prefetch() {
4097
- if (this._existingPrefetch || !this._connectionSuitable) {
4098
- return;
4099
- }
4100
- const link = document.createElement("link");
4101
- Object.assign(link, { rel: "prefetch", href: this._href, as: "document" });
4102
- document.head.appendChild(link);
4103
- }
4104
- }
4105
- __publicField(PrefetchController, "values", { mode: String });
4106
- class PrintButtonController extends PrintController {
4107
- get defaultUnsupportedClasses() {
4108
- return ["unsupported"];
4109
- }
4110
- connect() {
4111
- installClassMethods(this);
4112
- if (!("print" in window)) {
4113
- this.addUnsupportedClasses();
4114
- }
4115
- useEventListener(this, this.el, "click", this.print);
4116
- }
4117
- }
4118
- __publicField(PrintButtonController, "classes", [
4119
- "unsupported"
4120
- ]);
4121
- class ResponsiveIframeWrapperController extends BaseController {
4122
- connect() {
4123
- useEventListener(this, window, "message", this.messageReceived);
4124
- }
4125
- messageReceived(message) {
4126
- let data = message.data;
4127
- if (data.hasOwnProperty("name") && data.name === "iframe-body" && data.hasOwnProperty("height")) {
4128
- this.resize(data.height);
4129
- }
4130
- }
4131
- resize(height) {
4132
- this.el.style.height = `${height}px`;
4133
- }
4134
- }
4135
- class ResponsiveIframeBodyController extends BaseController {
4136
- connect() {
4137
- if (window.self !== window.top) {
4138
- useEventListener(this, window, "resize", this.postUpdate, { debounce: 200 });
4139
- this.postUpdate();
4140
- }
4141
- }
4142
- postUpdate() {
4143
- let payload = { name: "iframe-body", height: this.getHeight() };
4144
- window.parent.postMessage(payload, "*");
4145
- }
4146
- getHeight() {
4147
- const body = document.body;
4148
- const html = document.documentElement;
4149
- return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
4150
- }
4151
- }
4152
- class SelfDestructController extends BaseController {
4153
- connect() {
4154
- requestAnimationFrame(() => {
4155
- useTimeout(this, () => this.el.remove(), this.secondsValue * 1e3);
4156
- });
4157
- }
4158
- }
4159
- __publicField(SelfDestructController, "values", { seconds: Number });
4160
- class StickyController extends BaseController {
4161
- constructor() {
4162
- super(...arguments);
4163
- __publicField(this, "_magicElement", null);
4164
- }
4165
- get defaultStuckClasses() {
4166
- return ["stuck"];
4167
- }
4168
- get _mode() {
4169
- if (this.hasModeValue) {
4170
- if (!["top", "bottom"].includes(this.modeValue)) {
4171
- throw new Error(`The modeValue provided '${this.modeValue}' is not one of the recognised configuration options`);
4172
- }
4173
- if (this.modeValue === "top") {
4174
- return "beforebegin";
4175
- }
4176
- }
4177
- return "afterend";
4178
- }
4179
- connect() {
4180
- this._magicElement = document.createElement("div");
4181
- useInjectedElement(this, this.el, this._mode, this._magicElement);
4182
- const observer = new IntersectionObserver((entries) => {
4183
- entries.forEach((entry) => {
4184
- if (entry.target !== this._magicElement) {
4185
- return;
4186
- }
4187
- if (entry.intersectionRatio === 0) {
4188
- this.addStuckClasses();
4189
- } else if (entry.intersectionRatio === 1) {
4190
- this.removeStuckClasses();
4191
- }
4192
- });
4193
- }, {
4194
- threshold: [0, 1]
4195
- });
4196
- observer.observe(this._magicElement);
4197
- }
4198
- }
4199
- __publicField(StickyController, "classes", ["stuck"]);
4200
- __publicField(StickyController, "values", { mode: String });
4201
- class TeleportController extends EphemeralController {
4202
- connect() {
4203
- if (!this.hasInsertValue) {
4204
- throw new Error("`insert` value was not specified");
4205
- }
4206
- requestAnimationFrame(() => {
4207
- if (this.hasImmediateValue && this.immediateValue) {
4208
- this.execute();
4209
- }
4210
- });
4211
- }
4212
- execute(event) {
4213
- event == null ? void 0 : event.preventDefault();
4214
- let element = this.el;
4215
- let destination = document.querySelector(this.targetValue);
4216
- if (destination == null) {
4217
- this.dispatchEvent(element, "teleport:error");
4218
- return;
4219
- }
4220
- let copy = element.cloneNode(true);
4221
- this.cleanup(copy);
4222
- switch (this.insertValue) {
4223
- case "beforebegin":
4224
- case "beforeend":
4225
- case "afterend":
4226
- case "afterbegin":
4227
- destination.insertAdjacentHTML(this.insertValue, copy.outerHTML);
4228
- break;
4229
- case "replaceOuter":
4230
- destination.outerHTML = copy.outerHTML;
4231
- break;
4232
- case "replaceInner":
4233
- destination.innerHTML = copy.outerHTML;
4234
- break;
4235
- case "prepend":
4236
- destination.insertAdjacentHTML("afterbegin", copy.outerHTML);
4237
- break;
4238
- case "append":
4239
- destination.insertAdjacentHTML("beforeend", copy.outerHTML);
4240
- break;
4241
- default:
4242
- throw new Error("`insert` value was not specified");
4243
- }
4244
- element.remove();
4245
- }
4246
- }
4247
- __publicField(TeleportController, "values", { target: String, insert: String, immediate: Boolean });
4248
- class TemporaryStateController extends EphemeralController {
4249
- constructor() {
4250
- super(...arguments);
4251
- __publicField(this, "_previousState", {});
4252
- }
4253
- get _value() {
4254
- if (this.hasValueValue) {
4255
- return this.valueValue;
4256
- }
4257
- throw new Error("Expected `valueValue` to be present");
4258
- }
4259
- get _attribute() {
4260
- if (this.hasAttributeValue) {
4261
- return this.attributeValue;
4262
- }
4263
- throw new Error("Expected `attributeValue` to be present");
4264
- }
4265
- get _seconds() {
4266
- if (this.hasSecondsValue) {
4267
- return this.secondsValue * 1e3;
4268
- }
4269
- throw new Error("Expected `secondsValue` to be present");
4270
- }
4271
- connect() {
4272
- this.setState();
4273
- useTimeout(this, this.removeState, this._seconds);
4274
- }
4275
- disconnect() {
4276
- this.removeState();
4277
- }
4278
- setState() {
4279
- this._previousState[this._attribute] = get(this.el, this._attribute);
4280
- set(this.el, this._attribute, this.valueValue);
4281
- }
4282
- removeState() {
4283
- set(this.el, this._attribute, this._previousState[this._attribute]);
4284
- }
4285
- }
4286
- __publicField(TemporaryStateController, "values", {
4287
- attribute: String,
4288
- seconds: Number,
4289
- value: String
4290
- });
4291
- function applyTemporaryState(element, propertyString, value, seconds, controllerIdentifier = "temporary-state") {
4292
- var _a;
4293
- if (!element.dataset.controller || !((_a = element.dataset.controller) == null ? void 0 : _a.includes(controllerIdentifier))) {
4294
- element.dataset.controller = (element.dataset.controller || ` ${controllerIdentifier} `).trim().replaceAll(" ", " ");
4295
- }
4296
- element[camelCase(`${controllerIdentifier}-attribute-value`)] = propertyString;
4297
- element[camelCase(`${controllerIdentifier}-seconds-value`)] = seconds.toString();
4298
- }
4299
- function applyTemporaryClass(element, value, seconds) {
4300
- applyTemporaryState(element, "className", value, seconds);
4301
- }
4302
- function useClickOutside(controller, element, callback) {
4303
- callback = callback.bind(controller);
4304
- const handler = (event) => {
4305
- if (element.contains(event.target) || !isElementInViewport(element)) {
4306
- return;
4307
- }
4308
- callback(event);
4309
- };
4310
- let { teardown } = useEventListener(controller, window, ["click", "touchend"], handler);
4311
- useMixin(controller, () => void 0, teardown);
4312
- return {
4313
- teardown
4314
- };
4315
- }
4316
- function useHover(controller, element, enter, leave) {
4317
- let teardownEnter = null;
4318
- let teardownLeave = null;
4319
- if (enter) {
4320
- enter = enter.bind(controller);
4321
- let { teardown: _teardownEnter } = useEventListener(controller, element, "mouseenter", enter);
4322
- teardownEnter = _teardownEnter;
4323
- }
4324
- if (leave) {
4325
- leave = leave.bind(controller);
4326
- let { teardown: _teardownLeave } = useEventListener(controller, element, "mouseleave", leave);
4327
- teardownLeave = _teardownLeave;
4328
- }
4329
- let setup = () => void 0;
4330
- let teardown = () => {
4331
- if (teardownEnter) {
4332
- teardownEnter();
4333
- }
4334
- if (teardownLeave) {
4335
- teardownLeave();
4336
- }
4337
- };
4338
- useMixin(controller, setup, teardown);
4339
- return {
4340
- teardown
4341
- };
4342
- }
4343
- class ToggleClassController extends BaseController {
4344
- connect() {
4345
- if (!this.hasClassValue) {
4346
- throw new Error("data-toggle-class-class-value must not be empty");
4347
- }
4348
- if (this.hasMouseEnterValue || this.hasMouseLeaveValue) {
4349
- useHover(this, this.el, this.mouseEnter, this.mouseLeave);
4350
- }
4351
- if (this.hasClickAwayValue && this.clickAwayValue) {
4352
- useClickOutside(this, this.el, this.clickOutside);
4353
- }
4354
- requestAnimationFrame(() => {
4355
- if (this.hasInitialValue) {
4356
- if (this.initialValue === "on") {
4357
- this.toggleTargets.forEach((target) => this._elementOn(target));
4358
- } else {
4359
- this.toggleTargets.forEach((target) => this._elementOff(target));
4360
- }
4361
- }
4362
- });
4363
- }
4364
- clickOutside() {
4365
- this.toggleTargets.forEach((target) => {
4366
- if (this._elementWasToggled(target)) {
4367
- this._elementToggleStatus(target);
4368
- this._elementToggle(target);
4369
- }
4370
- });
4371
- }
4372
- mouseEnter() {
4373
- if (this.hasMouseEnterValue) {
4374
- switch (this.mouseEnterValue) {
4375
- case "on":
4376
- this.on();
4377
- break;
4378
- case "off":
4379
- this.off();
4380
- break;
4381
- case "toggle":
4382
- this.toggle();
4383
- break;
4384
- }
4385
- }
4386
- return {};
4387
- }
4388
- mouseLeave() {
4389
- if (this.hasMouseLeaveValue) {
4390
- switch (this.mouseLeaveValue) {
4391
- case "on":
4392
- this.on();
4393
- break;
4394
- case "off":
4395
- this.off();
4396
- break;
4397
- case "toggle":
4398
- this.toggle();
4399
- break;
4400
- }
4401
- }
4402
- return {};
4403
- }
4404
- on(event) {
4405
- this.toggleTargets.forEach((target) => {
4406
- this._elementToggleStatus(target);
4407
- this._elementOn(target);
4408
- });
4409
- }
4410
- off(event) {
4411
- this.toggleTargets.forEach((target) => {
4412
- this._elementToggleStatus(target);
4413
- this._elementOff(target);
4414
- });
4415
- }
4416
- toggle(event) {
4417
- this.toggleTargets.forEach((target) => {
4418
- this._elementToggleStatus(target);
4419
- this._elementToggle(target);
4420
- });
4421
- }
4422
- _elementWasToggled(el) {
4423
- return el.dataset.toggled == "true";
4424
- }
4425
- _elementToggleStatus(el) {
4426
- if (this._elementWasToggled(el)) {
4427
- delete el.dataset.toggled;
4428
- } else {
4429
- el.dataset.toggled = "true";
4430
- }
4431
- }
4432
- _elementToggle(el) {
4433
- let classes = this.classValue.split(" ");
4434
- classes.forEach((klass) => el.classList.toggle(klass));
4435
- }
4436
- _elementOn(el) {
4437
- let classes = this.classValue.split(" ");
4438
- classes.forEach((klass) => el.classList.toggle(klass, true));
4439
- }
4440
- _elementOff(el) {
4441
- let classes = this.classValue.split(" ");
4442
- classes.forEach((klass) => el.classList.toggle(klass, false));
4443
- }
4444
- }
4445
- __publicField(ToggleClassController, "targets", ["toggle"]);
4446
- __publicField(ToggleClassController, "values", {
4447
- class: String,
4448
- mouseEnter: String,
4449
- mouseLeave: String,
4450
- clickAway: Boolean,
4451
- initial: String
4452
- });
4453
- function useTrixModifiers(controller) {
4454
- const controllerDisconnect = controller.disconnect.bind(controller);
4455
- let observing = false;
4456
- let observerCallback = (entries, observer2) => {
4457
- entries.forEach((mutation) => {
4458
- if (mutation.type === "childList" && Array.from(mutation.addedNodes).some((el) => el.tagName === "TRIX-TOOLBAR")) {
4459
- attemptSetup();
4460
- observer2.disconnect();
4461
- }
4462
- });
4463
- };
4464
- let pasteHandler = (event) => controllerMethod(controller, "pasteEvent").call(controller, event);
4465
- let observer = new MutationObserver(observerCallback);
4466
- let attemptSetup = () => {
4467
- if (controller.element.tagName !== "TRIX-EDITOR") {
4468
- throw new Error("Expected controller to be mounted on an instance of <trix-editor>");
4469
- }
4470
- let editor = controller.element;
4471
- let editorParent = controller.element.parentElement;
4472
- if (editorParent == null) {
4473
- throw new Error("Could not traverse DOM tree from <trix-editor>");
4474
- }
4475
- editor.addEventListener("trix-paste", pasteHandler);
4476
- let toolbar2 = editorParent.querySelector("trix-toolbar");
4477
- if (!observing && !toolbar2) {
4478
- observing = true;
4479
- observer.observe(editorParent, { childList: true });
4480
- return;
4481
- } else if (!toolbar2) {
4482
- throw new Error("Could not find an instance of <trix-toolbar> that is a sibling of this <trix-editor>");
4483
- } else {
4484
- observer.disconnect();
4485
- }
4486
- controllerMethod(controller, "install").call(controller, { toolbar: toolbar2, editor });
4487
- };
4488
- let teardown = () => {
4489
- if (controller.element.tagName !== "TRIX-EDITOR") {
4490
- throw new Error("Expected controller to be mounted on an instance of <trix-editor>");
4491
- }
4492
- let editor = controller.element;
4493
- let editorParent = controller.element.parentElement;
4494
- if (editorParent == null) {
4495
- throw new Error("Could not traverse DOM tree from <trix-editor>");
4496
- }
4497
- editor.removeEventListener("trix-paste", pasteHandler);
4498
- let toolbar2 = editorParent.querySelector("trix-toolbar");
4499
- if (!toolbar2) {
4500
- throw new Error("Could not find <trix-toolbar> that is a sibling of this <trix-editor> element");
4501
- }
4502
- controllerMethod(controller, "uninstall").call(controller, { toolbar: toolbar2, editor });
4503
- };
4504
- attemptSetup();
4505
- Object.assign(controller, {
4506
- disconnect() {
4507
- observer.disconnect();
4508
- teardown();
4509
- controllerMethod(controller, "uninstall").call({ toolbar, editor: controller.element });
4510
- controllerDisconnect();
4511
- }
4512
- });
4513
- }
4514
- class TrixModifierController extends BaseController {
4515
- get enabledBehaviours() {
4516
- let enabled = (datasetProp) => datasetProp !== void 0 && datasetProp !== "false";
4517
- let behaviourIfEnabled = (datasetProp, trixInstallable) => enabled(datasetProp) ? [trixInstallable] : [];
4518
- return [
4519
- ...behaviourIfEnabled(this.el.dataset.noBold, this.bold),
4520
- ...behaviourIfEnabled(this.el.dataset.noBulletList, this.bulletList),
4521
- ...behaviourIfEnabled(this.el.dataset.noCode, this.code),
4522
- ...behaviourIfEnabled(this.el.dataset.noHeading, this.heading),
4523
- ...behaviourIfEnabled(this.el.dataset.noItalic, this.italic),
4524
- ...behaviourIfEnabled(this.el.dataset.noStrikethrough, this.strikethrough),
4525
- ...behaviourIfEnabled(this.el.dataset.noLink, this.link),
4526
- ...behaviourIfEnabled(this.el.dataset.noIndents, this.indents),
4527
- ...behaviourIfEnabled(this.el.dataset.noNumberList, this.numberList),
4528
- ...behaviourIfEnabled(this.el.dataset.noQuote, this.quote),
4529
- ...behaviourIfEnabled(this.el.dataset.noFileUploads, this.fileUploads)
4530
- ];
4531
- }
4532
- get bold() {
4533
- return this.formattingHandlers(".trix-button--icon-bold", "bold");
4534
- }
4535
- get bulletList() {
4536
- return this.formattingHandlers(".trix-button--icon-bullet-list", "bullet-list");
4537
- }
4538
- get code() {
4539
- return this.formattingHandlers(".trix-button--icon-code", "code");
4540
- }
4541
- get heading() {
4542
- return this.formattingHandlers(".trix-button--icon-heading-1", "heading");
4543
- }
4544
- get italic() {
4545
- return this.formattingHandlers(".trix-button--icon-italic", "italic");
4546
- }
4547
- get strikethrough() {
4548
- return this.formattingHandlers(".trix-button--icon-strike", "strike");
4549
- }
4550
- get link() {
4551
- return this.formattingHandlers(".trix-button--icon-link", "href");
4552
- }
4553
- get indents() {
4554
- return this.simpleHideShowHandlers([
4555
- ".trix-button--icon-decrease-nesting-level, .trix-button--icon-increase-nesting-level",
4556
- ".trix-button--icon-decrease-nesting-level, .trix-button--icon-increase-nesting-level"
4557
- ].join(", "));
4558
- }
4559
- get numberList() {
4560
- return this.simpleHideShowHandlers(".trix-button--icon-number-list");
4561
- }
4562
- get quote() {
4563
- return this.simpleHideShowHandlers(".trix-button--icon-quote");
4564
- }
4565
- get fileUploads() {
4566
- let selector = ".trix-button-group.trix-button-group--file-tools";
4567
- let preventUploads = (e) => e == null ? void 0 : e.preventDefault();
4568
- let self = this;
4569
- let element = this.el;
4570
- return {
4571
- install(elements) {
4572
- self.simpleHideShowHandlers(selector).install(elements);
4573
- self.el.addEventListener("trix-file-accept", preventUploads);
4574
- },
4575
- pasteEvent(event) {
4576
- let { dataTransfer, html } = event.paste;
4577
- let { editor } = element;
4578
- if (dataTransfer.files.length > 0 || html.includes("<img")) {
4579
- alert("The content you pasted contains images and/or files. File uploads are not supported.");
4580
- editor.undo();
4581
- }
4582
- },
4583
- uninstall(elements) {
4584
- self.simpleHideShowHandlers(selector).uninstall(elements);
4585
- self.el.removeEventListener("trix-file-accept", preventUploads);
4586
- }
4587
- };
4588
- }
4589
- connect() {
4590
- useTrixModifiers(this);
4591
- }
4592
- install(elements) {
4593
- this.enabledBehaviours.forEach((behaviour) => behaviour.install(elements));
4594
- }
4595
- pasteEvent(event) {
4596
- this.enabledBehaviours.forEach((behaviour) => behaviour.pasteEvent && behaviour.pasteEvent(event));
4597
- }
4598
- uninstall(elements) {
4599
- this.enabledBehaviours.forEach((behaviour) => behaviour.uninstall(elements));
4600
- }
4601
- simpleHideShowHandlers(selector) {
4602
- return {
4603
- install: ({ toolbar: toolbar2 }) => this.hideToolbarSelector(toolbar2, selector),
4604
- uninstall: ({ toolbar: toolbar2 }) => this.showToolbarSelector(toolbar2, selector)
4605
- };
4606
- }
4607
- formattingHandlers(selector, trixAttribute) {
4608
- let element = this.el;
4609
- let { editor } = element;
4610
- return {
4611
- install: (elements) => {
4612
- this.simpleHideShowHandlers(selector).install(elements);
4613
- },
4614
- pasteEvent(pasteEvent) {
4615
- let { range } = pasteEvent.paste;
4616
- let prevRange = element.editor.getSelectedRange();
4617
- editor.setSelectedRange(range);
4618
- editor.deactivateAttribute(trixAttribute);
4619
- editor.setSelectedRange(prevRange);
4620
- },
4621
- uninstall: (elements) => {
4622
- this.simpleHideShowHandlers(selector).uninstall(elements);
4623
- }
4624
- };
4625
- }
4626
- showToolbarSelector(toolbar2, selector) {
4627
- toolbar2.querySelectorAll(selector).forEach((el) => el.style.display = "");
4628
- }
4629
- hideToolbarSelector(toolbar2, selector) {
4630
- toolbar2.querySelectorAll(selector).forEach((el) => el.style.display = "none");
4631
- }
4632
- }
4633
- class TurboFrameRCController extends BaseController {
4634
- toggle(event) {
4635
- event == null ? void 0 : event.preventDefault();
4636
- let frame = this._getFrame();
4637
- let frameSrc = frame.src;
4638
- if (frameSrc == null || frameSrc !== this._getSrc()) {
4639
- this._setSrc();
4640
- } else {
4641
- this._clear();
4642
- }
4643
- }
4644
- setSrc(event) {
4645
- event == null ? void 0 : event.preventDefault();
4646
- this._setSrc();
4647
- }
4648
- clear(event) {
4649
- event == null ? void 0 : event.preventDefault();
4650
- this._clear();
4651
- }
4652
- _setSrc() {
4653
- let frame = this._getFrame();
4654
- if (this.hasLoadingMessageValue) {
4655
- frame.innerHTML = this.loadingMessageValue;
4656
- }
4657
- frame.src = this._getSrc();
4658
- }
4659
- _clear() {
4660
- let frame = this._getFrame();
4661
- frame.src = "";
4662
- frame.innerHTML = "";
4663
- }
4664
- _getFrame() {
4665
- let frame = document.getElementById(`${this.frameIdValue}`);
4666
- if (frame == null) {
4667
- throw new Error(`Could not find frame with ID '${this.frameIdValue}'`);
4668
- }
4669
- if (!isTurboFrame(frame)) {
4670
- throw new Error(`Element targeted by ID '${this.frameIdValue}'`);
4671
- } else {
4672
- return frame;
4673
- }
4674
- }
4675
- _getSrc() {
4676
- let element = this.el;
4677
- if (this.hasSrcValue) {
4678
- return this.srcValue;
4679
- } else if (isHTMLAnchorElement(element)) {
4680
- return element.href;
4681
- } else {
4682
- throw new Error("No link given to drive frame to");
4683
- }
4684
- }
4685
- }
4686
- __publicField(TurboFrameRCController, "values", {
4687
- frameId: String,
4688
- src: String,
4689
- loadingMessage: String
4690
- });
4691
- class TurboFrameRefreshController extends BaseController {
4692
- get _poll() {
4693
- return this.hasPollValue ? this.pollValue : false;
4694
- }
4695
- connect() {
4696
- let element = this.el;
4697
- if (isTurboFrame(element)) {
4698
- if (!!element.src) {
4699
- throw new Error("The provided <turbo-frame> element has no `src` attribute.");
4700
- }
4701
- } else {
4702
- throw new Error("Expected controller to be mounted on a <turbo-frame> element.");
4703
- }
4704
- if (this._poll) {
4705
- requestAnimationFrame(() => useTimeout(this, this.refresh, this.intervalValue));
4706
- }
4707
- }
4708
- refresh(event) {
4709
- event == null ? void 0 : event.preventDefault();
4710
- let element = this.el;
4711
- element.src = element.src;
4712
- }
4713
- }
4714
- __publicField(TurboFrameRefreshController, "values", {
4715
- interval: Number,
4716
- poll: Boolean
4717
- });
4718
- export { AlertController, AnchorSpyController, AsyncBlockController, AutoSubmitFormController, AutosizeController, BackLinkController, BaseController, CharCountController, CheckboxDisableInputsController, CheckboxEnableInputsController, CheckboxSelectAllController, CheckboxXORController, ClipboardController, ClockController, ConfirmController, ConfirmNavigationController, CountdownController, DebugController, DetectDirtyController, DetectDirtyFormController, DisableWithController, DismissableController, DurationController, ElementSaveController, EmptyDomController, EnableInputsController, EphemeralController, EventBus, FallbackImageController, FocusStealController, FormRcController, FormSaveController, FullscreenController, IntersectionController, IntervalController, LazyBlockController, LightboxImageController, LimitedSelectionCheckboxesController, LoadBlockController, MediaPlayerController, NavigateFormErrorsController, NestedFormController, PasswordConfirmController, PasswordPeekController, PollBlockController, PrefetchController, PresenceController, PrintButtonController, PrintController, RemoteFormController, RemoveController, ResponsiveIframeBodyController, ResponsiveIframeWrapperController, ScrollContainerController, ScrollIntoFocusController, ScrollToBottomController, ScrollToController, ScrollToTopController, SelfDestructController, SignalActionController, SignalDomChildrenController, SignalInputController, SignalVisibilityController, StickyController, StorageSerializers, SyncInputsController, TableSortController, TableTruncateController, TabsController, TeleportController, TemporaryStateController, TimeDistanceController, TimeoutController, ToggleClassController, TreeViewController, TrixModifierController, TurboFrameRCController, TurboFrameRefreshController, UserFocusController, ValueWarnController, WordCountController, applyTemporaryClass, applyTemporaryState, createHiddenButton, createHiddenInput, getAllRadiosInGroup, getOtherRadiosInGroup, getScrollParent, insertElement, insertHiddenButton, insertHiddenInput, isDirty, isElementCheckable, isElementInViewport, isFormDirty, isHTMLAnchorElement, isHTMLButtonButtonElement, isHTMLButtonElement, isHTMLButtonInputElement, isHTMLFormElement, isHTMLImageElement, isHTMLInputElement, isHTMLLabelElement, isHTMLLinkElement, isHTMLResetButtonElement, isHTMLResetInputElement, isHTMLSelectElement, isHTMLSubmitButtonElement, isHTMLSubmitInputElement, isHTMLTextAreaElement, isTurboFrame, isTypeOfButtonableElement, isTypeOfFormInputElement, isTypeOfResetButtonElement, isTypeOfSubmitButtonElement, requestReset, requestSubmit, scrollAbsoluteBottom, scrollAbsoluteLeft, scrollAbsoluteRight, scrollAbsoluteTop, scrollDown, scrollLeft, scrollRight, scrollToElement, scrollUp, useCollectionEventListener, useCollectionEventListeners, useEventListener, useEventListeners, useFullscreen, useGeolocation, useInjectedElement, useInjectedFragment, useInjectedHTML, useInterval, useLocalStorage, useTemporaryContent, useTimeout };
4719
- //# sourceMappingURL=stimulus-library.es.js.map