blacklight 7.37.0 → 8.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (400) hide show
  1. checksums.yaml +4 -4
  2. data/.env +2 -3
  3. data/.github/workflows/ruby.yml +33 -133
  4. data/.rubocop.yml +241 -2
  5. data/.rubocop_todo.yml +214 -270
  6. data/Gemfile +7 -10
  7. data/README.md +11 -3
  8. data/VERSION +1 -1
  9. data/app/assets/javascripts/blacklight/blacklight.esm.js +384 -0
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -0
  11. data/app/assets/javascripts/blacklight/blacklight.js +374 -493
  12. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -0
  13. data/app/assets/stylesheets/blacklight/_autocomplete.scss +25 -0
  14. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +1 -1
  15. data/app/assets/stylesheets/blacklight/_bookmark.scss +16 -0
  16. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +8 -0
  17. data/app/assets/stylesheets/blacklight/_facets.scss +72 -44
  18. data/app/assets/stylesheets/blacklight/_header.scss +0 -15
  19. data/app/assets/stylesheets/blacklight/_icons.scss +0 -14
  20. data/app/assets/stylesheets/blacklight/_mixins.scss +20 -0
  21. data/app/assets/stylesheets/blacklight/_modal.scss +8 -2
  22. data/app/assets/stylesheets/blacklight/_search_form.scss +30 -3
  23. data/app/assets/stylesheets/blacklight/_search_history.scss +10 -1
  24. data/app/assets/stylesheets/blacklight/_search_results.scss +6 -2
  25. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +4 -1
  26. data/app/builders/blacklight/action_builder.rb +18 -9
  27. data/app/components/blacklight/advanced_search_form_component.html.erb +2 -2
  28. data/app/components/blacklight/advanced_search_form_component.rb +8 -10
  29. data/app/components/blacklight/constraints_component.rb +27 -37
  30. data/app/components/blacklight/document/action_component.rb +9 -9
  31. data/app/components/blacklight/document/actions_component.rb +2 -2
  32. data/app/components/blacklight/document/bookmark_component.html.erb +9 -0
  33. data/app/components/blacklight/document/bookmark_component.rb +4 -2
  34. data/app/components/blacklight/document/citation_component.rb +5 -3
  35. data/app/components/blacklight/document/group_component.rb +7 -3
  36. data/app/components/blacklight/document/sidebar_component.html.erb +2 -0
  37. data/app/components/blacklight/document/sidebar_component.rb +16 -0
  38. data/app/components/blacklight/document/thumbnail_component.html.erb +2 -7
  39. data/app/components/blacklight/document/thumbnail_component.rb +1 -9
  40. data/app/components/blacklight/document_component.html.erb +4 -0
  41. data/app/components/blacklight/document_component.rb +14 -53
  42. data/app/components/blacklight/document_metadata_component.html.erb +2 -4
  43. data/app/components/blacklight/document_metadata_component.rb +5 -10
  44. data/app/components/blacklight/document_title_component.rb +4 -1
  45. data/app/components/blacklight/facet_component.rb +1 -1
  46. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +3 -3
  47. data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
  48. data/app/components/blacklight/facet_field_component.html.erb +4 -5
  49. data/app/components/blacklight/facet_field_component.rb +9 -2
  50. data/app/components/blacklight/facet_field_list_component.html.erb +3 -3
  51. data/app/components/blacklight/facet_field_list_component.rb +37 -5
  52. data/app/components/blacklight/facet_field_no_layout_component.rb +0 -2
  53. data/app/components/blacklight/facet_item_component.rb +1 -43
  54. data/app/components/blacklight/facet_item_pivot_component.rb +21 -23
  55. data/app/components/blacklight/header_component.rb +1 -1
  56. data/app/components/blacklight/hidden_search_state_component.rb +1 -2
  57. data/app/components/blacklight/icons/legacy_icon_component.rb +30 -0
  58. data/app/components/blacklight/icons/list_component.rb +16 -0
  59. data/app/components/blacklight/icons/search_component.rb +16 -0
  60. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  61. data/app/components/blacklight/metadata_field_component.rb +24 -8
  62. data/app/components/blacklight/metadata_field_layout_component.rb +4 -25
  63. data/app/components/blacklight/response/facet_group_component.html.erb +3 -5
  64. data/app/components/blacklight/response/facet_group_component.rb +29 -8
  65. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  66. data/app/components/blacklight/response/pagination_component.rb +1 -5
  67. data/app/components/blacklight/response/sort_component.rb +1 -1
  68. data/app/components/blacklight/response/spellcheck_component.rb +17 -6
  69. data/app/components/blacklight/response/view_type_button_component.rb +2 -6
  70. data/app/components/blacklight/response/view_type_component.rb +3 -5
  71. data/app/components/blacklight/search/sidebar_component.html.erb +8 -0
  72. data/app/components/blacklight/search/sidebar_component.rb +17 -0
  73. data/app/components/blacklight/search_bar_component.html.erb +20 -15
  74. data/app/components/blacklight/search_bar_component.rb +2 -16
  75. data/app/components/blacklight/search_button_component.rb +3 -3
  76. data/app/components/blacklight/search_context_component.rb +43 -9
  77. data/app/components/blacklight/search_header_component.html.erb +2 -0
  78. data/app/components/blacklight/search_header_component.rb +6 -0
  79. data/app/components/blacklight/start_over_button_component.rb +5 -3
  80. data/app/components/blacklight/system/dropdown_component.rb +2 -2
  81. data/app/components/blacklight/system/flash_message_component.html.erb +3 -1
  82. data/app/components/blacklight/system/flash_message_component.rb +11 -2
  83. data/app/components/blacklight/system/modal_component.html.erb +1 -1
  84. data/app/components/blacklight/system/modal_component.rb +0 -2
  85. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  86. data/app/components/blacklight/top_navbar_component.rb +0 -4
  87. data/app/controllers/bookmarks_controller.rb +1 -0
  88. data/app/controllers/catalog_controller.rb +1 -0
  89. data/app/controllers/concerns/blacklight/bookmarks.rb +10 -9
  90. data/app/controllers/concerns/blacklight/catalog.rb +21 -83
  91. data/app/controllers/concerns/blacklight/controller.rb +3 -41
  92. data/app/controllers/concerns/blacklight/search_context.rb +25 -7
  93. data/app/controllers/concerns/blacklight/search_history.rb +2 -0
  94. data/app/controllers/concerns/blacklight/searchable.rb +12 -1
  95. data/app/controllers/concerns/blacklight/token_based_user.rb +13 -1
  96. data/app/controllers/search_history_controller.rb +1 -0
  97. data/app/helpers/blacklight/blacklight_helper_behavior.rb +12 -310
  98. data/app/helpers/blacklight/catalog_helper_behavior.rb +22 -137
  99. data/app/helpers/blacklight/component_helper_behavior.rb +2 -53
  100. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -117
  101. data/app/helpers/blacklight/facets_helper_behavior.rb +4 -321
  102. data/app/helpers/blacklight/icon_helper_behavior.rb +5 -4
  103. data/app/helpers/blacklight/layout_helper_behavior.rb +1 -0
  104. data/app/helpers/blacklight/render_partials_helper_behavior.rb +11 -31
  105. data/app/helpers/blacklight/url_helper_behavior.rb +13 -97
  106. data/app/helpers/blacklight_helper.rb +1 -0
  107. data/app/helpers/catalog_helper.rb +1 -0
  108. data/app/javascript/blacklight/bookmark_toggle.js +13 -19
  109. data/app/javascript/blacklight/button_focus.js +12 -10
  110. data/app/javascript/blacklight/checkbox_submit.js +68 -123
  111. data/app/javascript/blacklight/core.js +5 -7
  112. data/app/javascript/blacklight/index.js +13 -0
  113. data/app/javascript/blacklight/modal.js +99 -164
  114. data/app/javascript/blacklight/modalForm.js +60 -0
  115. data/app/javascript/blacklight/search_context.js +46 -54
  116. data/app/models/blacklight/facet_paginator.rb +3 -2
  117. data/app/models/blacklight/icon.rb +4 -2
  118. data/app/models/bookmark.rb +0 -2
  119. data/app/models/concerns/blacklight/configurable.rb +5 -4
  120. data/app/models/concerns/blacklight/document/active_model_shim.rb +1 -10
  121. data/app/models/concerns/blacklight/document/cache_key.rb +1 -0
  122. data/app/models/concerns/blacklight/document/dublin_core.rb +2 -1
  123. data/app/models/concerns/blacklight/document/email.rb +1 -0
  124. data/app/models/concerns/blacklight/document/export.rb +2 -1
  125. data/app/models/concerns/blacklight/document/extensions.rb +1 -0
  126. data/app/models/concerns/blacklight/document/schema_org.rb +1 -0
  127. data/app/models/concerns/blacklight/document/semantic_fields.rb +1 -0
  128. data/app/models/concerns/blacklight/document/sms.rb +1 -0
  129. data/app/models/concerns/blacklight/suggest/response.rb +1 -0
  130. data/app/models/concerns/blacklight/user.rb +17 -8
  131. data/app/models/record_mailer.rb +13 -12
  132. data/app/models/search.rb +1 -7
  133. data/app/models/solr_document.rb +1 -0
  134. data/app/presenters/blacklight/clause_presenter.rb +1 -1
  135. data/app/presenters/blacklight/document_presenter.rb +13 -21
  136. data/app/presenters/blacklight/facet_field_presenter.rb +39 -14
  137. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +1 -5
  138. data/app/presenters/blacklight/facet_item_pivot_presenter.rb +60 -0
  139. data/app/presenters/blacklight/facet_item_presenter.rb +3 -9
  140. data/app/presenters/blacklight/field_presenter.rb +1 -0
  141. data/app/presenters/blacklight/index_presenter.rb +2 -40
  142. data/app/presenters/blacklight/json_presenter.rb +7 -5
  143. data/app/presenters/blacklight/rendering/link_to_facet.rb +2 -5
  144. data/app/presenters/blacklight/show_presenter.rb +1 -9
  145. data/app/presenters/blacklight/thumbnail_presenter.rb +1 -1
  146. data/app/services/blacklight/bookmarks_search_builder.rb +22 -0
  147. data/app/services/blacklight/field_retriever.rb +12 -21
  148. data/app/services/blacklight/search_service.rb +8 -7
  149. data/app/values/blacklight/types.rb +0 -18
  150. data/app/views/bookmarks/_clear_bookmarks_widget.html.erb +8 -1
  151. data/app/views/bookmarks/_tools.html.erb +7 -12
  152. data/app/views/catalog/_advanced_search_form.html.erb +0 -1
  153. data/app/views/catalog/_bookmark_control.html.erb +1 -1
  154. data/app/views/catalog/_citation.html.erb +1 -1
  155. data/app/views/catalog/_constraints.html.erb +1 -14
  156. data/app/views/catalog/_document.atom.builder +12 -14
  157. data/app/views/catalog/_document.html.erb +5 -3
  158. data/app/views/catalog/_document.rss.builder +2 -4
  159. data/app/views/catalog/_facet_layout.html.erb +2 -2
  160. data/app/views/catalog/_facets.html.erb +5 -4
  161. data/app/views/catalog/_home_text.html.erb +2 -14
  162. data/app/views/catalog/_search_form.html.erb +2 -2
  163. data/app/views/catalog/_search_header.html.erb +1 -2
  164. data/app/views/catalog/_search_results.html.erb +2 -2
  165. data/app/views/catalog/_search_sidebar.html.erb +5 -1
  166. data/app/views/catalog/_show_main_content.html.erb +11 -16
  167. data/app/views/catalog/_show_sidebar.html.erb +2 -2
  168. data/app/views/catalog/_show_tools.html.erb +8 -14
  169. data/app/views/catalog/_view_type_group.html.erb +1 -1
  170. data/app/views/catalog/email.html.erb +2 -2
  171. data/app/views/catalog/email_success.html.erb +5 -6
  172. data/app/views/catalog/facet.html.erb +7 -5
  173. data/app/views/catalog/index.atom.builder +12 -14
  174. data/app/views/catalog/index.html.erb +4 -1
  175. data/app/views/catalog/index.json.jbuilder +19 -19
  176. data/app/views/catalog/index.rss.builder +1 -1
  177. data/app/views/catalog/opensearch.xml.builder +1 -1
  178. data/app/views/catalog/sms.html.erb +2 -2
  179. data/app/views/catalog/sms_success.html.erb +5 -6
  180. data/app/views/catalog/suggest.html.erb +3 -0
  181. data/app/views/layouts/blacklight/base.html.erb +13 -2
  182. data/app/views/search_history/index.html.erb +6 -2
  183. data/app/views/shared/_modal.html.erb +3 -3
  184. data/blacklight.gemspec +8 -9
  185. data/config/importmap.rb +3 -0
  186. data/config/locales/blacklight.ar.yml +0 -1
  187. data/config/locales/blacklight.ca.yml +0 -1
  188. data/config/locales/blacklight.de.yml +0 -1
  189. data/config/locales/blacklight.en.yml +0 -2
  190. data/config/locales/blacklight.es.yml +0 -1
  191. data/config/locales/blacklight.fr.yml +0 -1
  192. data/config/locales/blacklight.hu.yml +0 -1
  193. data/config/locales/blacklight.it.yml +0 -1
  194. data/config/locales/blacklight.nl.yml +0 -1
  195. data/config/locales/blacklight.pt-BR.yml +0 -1
  196. data/config/locales/blacklight.sq.yml +0 -1
  197. data/config/locales/blacklight.zh.yml +0 -1
  198. data/config/routes.rb +3 -2
  199. data/db/migrate/20140202020201_create_searches.rb +1 -0
  200. data/db/migrate/20140202020202_create_bookmarks.rb +1 -0
  201. data/db/migrate/20140320000000_add_polymorphic_type_to_bookmarks.rb +1 -0
  202. data/docker-compose.yml +0 -1
  203. data/lib/blacklight/abstract_repository.rb +1 -0
  204. data/lib/blacklight/configuration/context.rb +4 -4
  205. data/lib/blacklight/configuration/display_field.rb +7 -9
  206. data/lib/blacklight/configuration/facet_field.rb +17 -11
  207. data/lib/blacklight/configuration/field.rb +1 -0
  208. data/lib/blacklight/configuration/fields.rb +12 -15
  209. data/lib/blacklight/configuration/index_field.rb +1 -0
  210. data/lib/blacklight/configuration/null_display_field.rb +17 -0
  211. data/lib/blacklight/configuration/search_field.rb +1 -0
  212. data/lib/blacklight/configuration/show_field.rb +1 -0
  213. data/lib/blacklight/configuration/sort_field.rb +1 -0
  214. data/lib/blacklight/configuration/tool_config.rb +1 -0
  215. data/lib/blacklight/configuration/view_config.rb +16 -6
  216. data/lib/blacklight/configuration.rb +294 -358
  217. data/lib/blacklight/engine.rb +8 -24
  218. data/lib/blacklight/exceptions.rb +2 -2
  219. data/lib/blacklight/nested_open_struct_with_hash_access.rb +6 -12
  220. data/lib/blacklight/open_struct_with_hash_access.rb +19 -17
  221. data/lib/blacklight/parameters.rb +7 -21
  222. data/lib/blacklight/routes/exportable.rb +1 -0
  223. data/lib/blacklight/routes/searchable.rb +2 -1
  224. data/lib/blacklight/routes.rb +1 -0
  225. data/lib/blacklight/search_builder.rb +10 -10
  226. data/lib/blacklight/search_state/filter_field.rb +8 -25
  227. data/lib/blacklight/search_state/pivot_filter_field.rb +144 -0
  228. data/lib/blacklight/search_state.rb +23 -79
  229. data/lib/blacklight/solr/document.rb +1 -0
  230. data/lib/blacklight/solr/facet_paginator.rb +1 -0
  231. data/lib/blacklight/solr/repository.rb +3 -14
  232. data/lib/blacklight/solr/request.rb +1 -0
  233. data/lib/blacklight/solr/response/facets.rb +21 -5
  234. data/lib/blacklight/solr/response/group.rb +1 -0
  235. data/lib/blacklight/solr/response/group_response.rb +1 -0
  236. data/lib/blacklight/solr/response/more_like_this.rb +1 -0
  237. data/lib/blacklight/solr/response/pagination_methods.rb +4 -3
  238. data/lib/blacklight/solr/response/params.rb +5 -4
  239. data/lib/blacklight/solr/response/response.rb +1 -0
  240. data/lib/blacklight/solr/response/spelling.rb +1 -0
  241. data/lib/blacklight/solr/response.rb +4 -3
  242. data/lib/blacklight/solr/search_builder_behavior.rb +17 -34
  243. data/lib/blacklight/solr.rb +1 -0
  244. data/lib/blacklight/version.rb +1 -0
  245. data/lib/blacklight.rb +7 -10
  246. data/lib/generators/blacklight/assets/importmap_generator.rb +55 -0
  247. data/lib/generators/blacklight/assets/propshaft_generator.rb +25 -0
  248. data/lib/generators/blacklight/assets/sprockets_generator.rb +66 -0
  249. data/lib/generators/blacklight/assets_generator.rb +13 -89
  250. data/lib/generators/blacklight/controller_generator.rb +3 -2
  251. data/lib/generators/blacklight/document_generator.rb +1 -0
  252. data/lib/generators/blacklight/install_generator.rb +4 -3
  253. data/lib/generators/blacklight/models_generator.rb +1 -0
  254. data/lib/generators/blacklight/search_builder_generator.rb +1 -0
  255. data/lib/generators/blacklight/solr_generator.rb +1 -1
  256. data/lib/generators/blacklight/templates/catalog_controller.rb +34 -8
  257. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -69
  258. data/lib/generators/blacklight/test_support_generator.rb +4 -2
  259. data/lib/generators/blacklight/user_generator.rb +7 -9
  260. data/lib/railties/blacklight.rake +6 -7
  261. data/package.json +10 -13
  262. data/rollup.config.js +27 -0
  263. data/spec/components/blacklight/constraints_component_spec.rb +17 -13
  264. data/spec/components/blacklight/document_component_spec.rb +23 -82
  265. data/spec/components/blacklight/facet_component_spec.rb +3 -18
  266. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +1 -2
  267. data/spec/components/blacklight/facet_field_list_component_spec.rb +7 -6
  268. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +10 -9
  269. data/spec/components/blacklight/response/view_type_component_spec.rb +66 -0
  270. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  271. data/spec/components/blacklight/search_context_component_spec.rb +40 -0
  272. data/spec/controllers/blacklight/catalog/component_configuration_spec.rb +1 -6
  273. data/spec/controllers/blacklight/{base_spec.rb → catalog_spec.rb} +2 -2
  274. data/spec/controllers/bookmarks_controller_spec.rb +2 -3
  275. data/spec/controllers/catalog_controller_spec.rb +13 -135
  276. data/spec/features/advanced_search_spec.rb +0 -56
  277. data/spec/features/autocomplete_spec.rb +1 -1
  278. data/spec/features/axe_spec.rb +1 -6
  279. data/spec/features/bookmarks_spec.rb +1 -1
  280. data/spec/features/facets_spec.rb +1 -1
  281. data/spec/features/search_context_spec.rb +4 -10
  282. data/spec/features/search_results_spec.rb +0 -33
  283. data/spec/features/sitelinks_search_box.rb +13 -0
  284. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +2 -138
  285. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +0 -387
  286. data/spec/helpers/blacklight/icon_helper_behavior_spec.rb +8 -0
  287. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +5 -7
  288. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +9 -131
  289. data/spec/helpers/blacklight_helper_spec.rb +8 -252
  290. data/spec/helpers/catalog_helper_spec.rb +7 -118
  291. data/spec/i18n_spec.rb +1 -0
  292. data/spec/integration/generators/blacklight/solr_generator_spec.rb +1 -1
  293. data/spec/lib/blacklight/configuration/facet_field_spec.rb +27 -16
  294. data/spec/lib/blacklight/configuration/field_spec.rb +1 -1
  295. data/spec/lib/blacklight/configuration/view_config_spec.rb +1 -1
  296. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +2 -2
  297. data/spec/lib/blacklight/parameters_spec.rb +1 -4
  298. data/spec/lib/blacklight/search_state/filter_field_spec.rb +4 -4
  299. data/spec/lib/blacklight/search_state/pivot_filter_field_spec.rb +117 -0
  300. data/spec/lib/blacklight/search_state_spec.rb +80 -198
  301. data/spec/lib/tasks/blacklight_task_spec.rb +1 -0
  302. data/spec/models/blacklight/configuration_spec.rb +17 -51
  303. data/spec/models/blacklight/document/active_model_shim_spec.rb +2 -2
  304. data/spec/models/blacklight/icon_spec.rb +31 -15
  305. data/spec/models/blacklight/search_builder_spec.rb +9 -9
  306. data/spec/models/blacklight/solr/document_spec.rb +3 -3
  307. data/spec/models/blacklight/solr/repository_spec.rb +0 -27
  308. data/spec/models/blacklight/solr/response/facets_spec.rb +27 -27
  309. data/spec/models/blacklight/solr/response/group_response_spec.rb +1 -0
  310. data/spec/models/blacklight/solr/response/group_spec.rb +1 -0
  311. data/spec/models/blacklight/solr/response_spec.rb +9 -2
  312. data/spec/models/blacklight/solr/search_builder_spec.rb +24 -31
  313. data/spec/models/blacklight/user_spec.rb +22 -0
  314. data/spec/models/solr_document_spec.rb +2 -6
  315. data/spec/presenters/blacklight/clause_presenter_spec.rb +1 -0
  316. data/spec/presenters/blacklight/document_presenter_spec.rb +2 -2
  317. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +85 -12
  318. data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +1 -0
  319. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +14 -13
  320. data/spec/presenters/blacklight/field_presenter_spec.rb +0 -14
  321. data/spec/presenters/blacklight/index_presenter_spec.rb +2 -4
  322. data/spec/presenters/blacklight/json_presenter_spec.rb +1 -0
  323. data/spec/presenters/blacklight/link_alternate_presenter_spec.rb +3 -2
  324. data/spec/presenters/blacklight/show_presenter_spec.rb +20 -29
  325. data/spec/presenters/thumbnail_presenter_spec.rb +1 -1
  326. data/spec/requests/load_suggestions_spec.rb +16 -0
  327. data/spec/routing/catalog_routing_spec.rb +2 -1
  328. data/spec/services/blacklight/search_service_spec.rb +31 -68
  329. data/spec/spec_helper.rb +6 -32
  330. data/spec/support/controller_level_helpers.rb +1 -2
  331. data/spec/support/features/search_helpers.rb +39 -0
  332. data/spec/support/features/session_helpers.rb +1 -0
  333. data/spec/support/features.rb +3 -0
  334. data/spec/support/view_component_capybara_test_helpers.rb +8 -0
  335. data/spec/test_app_templates/lib/generators/test_app_generator.rb +9 -2
  336. data/spec/views/catalog/_document.html.erb_spec.rb +3 -34
  337. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +1 -1
  338. data/spec/views/catalog/_search_header.erb_spec.rb +1 -0
  339. data/spec/views/catalog/_show_sidebar.erb_spec.rb +1 -0
  340. data/spec/views/catalog/_show_tools.html.erb_spec.rb +5 -66
  341. data/spec/views/catalog/_view_type_group.html.erb_spec.rb +17 -9
  342. data/spec/views/catalog/email_success.html.erb_spec.rb +2 -2
  343. data/spec/views/catalog/facet.html.erb_spec.rb +6 -3
  344. data/spec/views/catalog/index.atom.builder_spec.rb +18 -11
  345. data/spec/views/catalog/index.html.erb_spec.rb +5 -6
  346. data/spec/views/catalog/index.json.jbuilder_spec.rb +2 -2
  347. data/spec/views/catalog/show.html.erb_spec.rb +3 -25
  348. data/spec/views/catalog/sms_success.html.erb_spec.rb +2 -2
  349. data/tasks/blacklight.rake +6 -4
  350. metadata +81 -134
  351. data/.babelrc +0 -11
  352. data/app/assets/images/blacklight/list.svg +0 -1
  353. data/app/assets/images/blacklight/search.svg +0 -1
  354. data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +0 -37
  355. data/app/components/blacklight/content_areas_shim.rb +0 -13
  356. data/app/controllers/concerns/blacklight/base.rb +0 -12
  357. data/app/controllers/concerns/blacklight/default_component_configuration.rb +0 -64
  358. data/app/controllers/concerns/blacklight/facet.rb +0 -69
  359. data/app/controllers/concerns/blacklight/search_fields.rb +0 -46
  360. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +0 -27
  361. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +0 -188
  362. data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +0 -97
  363. data/app/helpers/blacklight/suggest_helper_behavior.rb +0 -13
  364. data/app/javascript/blacklight/autocomplete.js +0 -36
  365. data/app/javascript/blacklight/facet_load.js +0 -22
  366. data/app/presenters/blacklight/search_bar_presenter.rb +0 -47
  367. data/app/views/catalog/_constraints_element.html.erb +0 -14
  368. data/app/views/catalog/_document_action.html.erb +0 -5
  369. data/app/views/catalog/_facet_group.html.erb +0 -5
  370. data/app/views/catalog/_facet_limit.html.erb +0 -3
  371. data/app/views/catalog/_index.html.erb +0 -1
  372. data/app/views/catalog/_index_header.html.erb +0 -22
  373. data/app/views/catalog/_previous_next_doc.html.erb +0 -2
  374. data/app/views/catalog/_show.html.erb +0 -6
  375. data/app/views/catalog/_show_header.html.erb +0 -2
  376. data/app/views/catalog/_thumbnail.html.erb +0 -1
  377. data/lib/blacklight/deprecations/engine_configuration.rb +0 -66
  378. data/lib/blacklight/deprecations/search_state_normalization.rb +0 -52
  379. data/spec/components/blacklight/header_component_spec.rb +0 -20
  380. data/spec/controllers/blacklight/facet_spec.rb +0 -33
  381. data/spec/controllers/blacklight/search_fields_spec.rb +0 -62
  382. data/spec/features/citation_spec.rb +0 -10
  383. data/spec/features/sitelinks_search_box_spec.rb +0 -13
  384. data/spec/features/sms_spec.rb +0 -12
  385. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +0 -26
  386. data/spec/helpers/blacklight/render_constraints_helper_behavior_spec.rb +0 -92
  387. data/spec/helpers/blacklight/search_history_constraints_helper_behavior_spec.rb +0 -101
  388. data/spec/helpers/blacklight/suggest_helper_behavior_spec.rb +0 -48
  389. data/spec/lib/blacklight/engine_spec.rb +0 -41
  390. data/spec/presenters/blacklight/search_bar_presenter_spec.rb +0 -94
  391. data/spec/services/blacklight/field_retriever_spec.rb +0 -17
  392. data/spec/support/view_component_test_helpers.rb +0 -35
  393. data/spec/views/catalog/_constraints.html.erb_spec.rb +0 -33
  394. data/spec/views/catalog/_facet_group.html.erb_spec.rb +0 -84
  395. data/spec/views/catalog/_facets.html.erb_spec.rb +0 -15
  396. data/spec/views/catalog/_index.html.erb_spec.rb +0 -62
  397. data/spec/views/catalog/_index_header.html.erb_spec.rb +0 -35
  398. data/spec/views/catalog/_previous_next_doc.html.erb_spec.rb +0 -22
  399. data/spec/views/catalog/_show.html.erb_spec.rb +0 -62
  400. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +0 -38
data/Gemfile CHANGED
@@ -10,10 +10,10 @@ group :test do
10
10
  end
11
11
 
12
12
  # BEGIN ENGINE_CART BLOCK
13
- # engine_cart: 0.10.0
14
- # engine_cart stanza: 0.10.0
13
+ # engine_cart: 2.5.0
14
+ # engine_cart stanza: 2.5.0
15
15
  # the below comes from engine_cart, a gem used to test this Rails engine gem in the context of a Rails app.
16
- file = File.expand_path('Gemfile', ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path('.internal_test_app', File.dirname(__FILE__)))
16
+ file = File.expand_path('Gemfile', ENV.fetch('ENGINE_CART_DESTINATION') { ENV.fetch('RAILS_ROOT') { File.expand_path('.internal_test_app', File.dirname(__FILE__)) } })
17
17
  if File.exist?(file)
18
18
  begin
19
19
  eval_gemfile file
@@ -23,7 +23,6 @@ if File.exist?(file)
23
23
  end
24
24
  else
25
25
  Bundler.ui.warn "[EngineCart] Unable to find test application dependencies in #{file}, using placeholder dependencies"
26
-
27
26
  if ENV['RAILS_VERSION']
28
27
  if ENV['RAILS_VERSION'] == 'edge'
29
28
  gem 'rails', github: 'rails/rails'
@@ -33,16 +32,14 @@ else
33
32
  end
34
33
  end
35
34
 
36
- unless ENV['VIEW_COMPONENT_VERSION'].to_s == ""
37
- gem 'view_component', ENV.fetch('VIEW_COMPONENT_VERSION')
38
- end
39
-
40
- case ENV['RAILS_VERSION']
41
- when /^6.0/
35
+ case ENV['RAILS_VERSION'].to_s
36
+ when /^(~> ?)?6\.0/
42
37
  gem 'sass-rails', '>= 6'
43
38
  gem 'webpacker', '~> 4.0'
44
39
  when /^5.[12]/
45
40
  gem 'sass-rails', '~> 5.0'
41
+ gem 'sprockets', '~> 3.7'
42
+ gem 'thor', '~> 0.20'
46
43
  end
47
44
  end
48
45
  # END ENGINE_CART BLOCK
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Blacklight
2
2
 
3
+ ![CI Workflow](https://github.com/projectblacklight/blacklight/actions/workflows/ruby.yml/badge.svg)
4
+
5
+
3
6
  Blacklight is an open source Solr user interface discovery platform.
4
7
  You can use Blacklight to enable searching and browsing of your collections.
5
8
  Blacklight uses the [Apache Solr](http://lucene.apache.org/solr) search engine
@@ -31,11 +34,16 @@ rails generate blacklight:install
31
34
  * [Issue Tracker](https://github.com/projectblacklight/blacklight/issues)
32
35
  * [Support](https://github.com/projectblacklight/blacklight/wiki/Support)
33
36
 
37
+ ## Browser Compatibility
38
+
39
+ Blacklight assumes a modern browser with support for ES6. This means we explicitly do not support Internet Explorer 11.
40
+
34
41
  ## Dependencies
35
42
 
36
- * Ruby 2.2+
37
- * Bundler
38
- * Rails 5.2+
43
+ * [Ruby](https://www.ruby-lang.org/) 2.7+
44
+ * [Ruby on Rails](https://rubyonrails.org/) 6.1+
45
+
46
+ Blacklight aims to support the currently [supported versions of Ruby](https://www.ruby-lang.org/en/downloads/branches/) and the [supported versions of Ruby on Rails](https://guides.rubyonrails.org/maintenance_policy.html). We aim to keep our [test configuration](blob/main/.github/workflows/ruby.yml) up to date with these supported versions.
39
47
 
40
48
  ## Contributing Code
41
49
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.37.0
1
+ 8.0.0.beta1
@@ -0,0 +1,384 @@
1
+ const Blacklight = function() {
2
+ const buffer = new Array;
3
+ return {
4
+ onLoad: function(func) {
5
+ buffer.push(func);
6
+ },
7
+
8
+ activate: function() {
9
+ for(let i = 0; i < buffer.length; i++) {
10
+ buffer[i].call();
11
+ }
12
+ },
13
+
14
+ listeners: function () {
15
+ const listeners = [];
16
+ if (typeof Turbo !== 'undefined') {
17
+ listeners.push('turbo:load', 'turbo:frame-load');
18
+ } else if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
19
+ // Turbolinks 5
20
+ if (Turbolinks.BrowserAdapter) {
21
+ listeners.push('turbolinks:load');
22
+ } else {
23
+ // Turbolinks < 5
24
+ listeners.push('page:load', 'DOMContentLoaded');
25
+ }
26
+ } else {
27
+ listeners.push('DOMContentLoaded');
28
+ }
29
+
30
+ return listeners;
31
+ }
32
+ };
33
+ }();
34
+
35
+ // turbolinks triggers page:load events on page transition
36
+ // If app isn't using turbolinks, this event will never be triggered, no prob.
37
+ Blacklight.listeners().forEach(function(listener) {
38
+ document.addEventListener(listener, function() {
39
+ Blacklight.activate();
40
+ });
41
+ });
42
+
43
+ Blacklight.onLoad(function () {
44
+ const elem = document.querySelector('.no-js');
45
+
46
+ // The "no-js" class may already have been removed because this function is
47
+ // run on every turbo:load event, in that case, it won't find an element.
48
+ if (!elem) return;
49
+
50
+ elem.classList.remove('no-js');
51
+ elem.classList.add('js');
52
+ });
53
+
54
+ /* Converts a "toggle" form, with single submit button to add/remove
55
+ something, like used for Bookmarks, into an AJAXy checkbox instead.
56
+ Apply to a form. Does require certain assumption about the form:
57
+ 1) The same form 'action' href must be used for both ADD and REMOVE
58
+ actions, with the different being the hidden input name="_method"
59
+ being set to "put" or "delete" -- that's the Rails method to pretend
60
+ to be doing a certain HTTP verb. So same URL, PUT to add, DELETE
61
+ to remove. This plugin assumes that.
62
+ Plus, the form this is applied to should provide a data-doc-id
63
+ attribute (HTML5-style doc-*) that contains the id/primary key
64
+ of the object in question -- used by plugin for a unique value for
65
+ DOM id's.
66
+ Uses HTML for a checkbox compatible with Bootstrap 4.
67
+ new CheckboxSubmit(document.querySelector('form.something')).render()
68
+ */
69
+ class CheckboxSubmit {
70
+ constructor(form) {
71
+ this.form = form;
72
+ }
73
+
74
+ async clicked(evt) {
75
+ this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress');
76
+ this.labelTarget.setAttribute('disabled', 'disabled');
77
+ this.checkboxTarget.setAttribute('disabled', 'disabled');
78
+ const response = await fetch(this.formTarget.getAttribute('action'), {
79
+ body: new FormData(this.formTarget),
80
+ method: this.formTarget.getAttribute('method').toUpperCase(),
81
+ headers: {
82
+ 'Accept': 'application/json',
83
+ 'X-Requested-With': 'XMLHttpRequest',
84
+ 'X-CSRF-Token': document.querySelector('meta[name=csrf-token]')?.content
85
+ }
86
+ });
87
+ this.labelTarget.removeAttribute('disabled');
88
+ this.checkboxTarget.removeAttribute('disabled');
89
+ if (response.ok) {
90
+ const json = await response.json();
91
+ this.updateStateFor(!this.checked);
92
+ document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count;
93
+ } else {
94
+ alert('Error');
95
+ }
96
+ }
97
+
98
+ get checked() {
99
+ return (this.form.querySelectorAll('input[name=_method][value=delete]').length != 0)
100
+ }
101
+
102
+ get formTarget() {
103
+ return this.form
104
+ }
105
+
106
+ get labelTarget() {
107
+ return this.form.querySelector('[data-checkboxsubmit-target="label"]')
108
+ }
109
+
110
+ get checkboxTarget() {
111
+ return this.form.querySelector('[data-checkboxsubmit-target="checkbox"]')
112
+ }
113
+
114
+ get spanTarget() {
115
+ return this.form.querySelector('[data-checkboxsubmit-target="span"]')
116
+ }
117
+
118
+ updateStateFor(state) {
119
+ this.checkboxTarget.checked = state;
120
+
121
+ if (state) {
122
+ this.labelTarget.classList.add('checked');
123
+ //Set the Rails hidden field that fakes an HTTP verb
124
+ //properly for current state action.
125
+ this.formTarget.querySelector('input[name=_method]').value = 'delete';
126
+ this.spanTarget.innerHTML = this.form.getAttribute('data-present');
127
+ } else {
128
+ this.labelTarget.classList.remove('checked');
129
+ this.formTarget.querySelector('input[name=_method]').value = 'put';
130
+ this.spanTarget.innerHTML = this.form.getAttribute('data-absent');
131
+ }
132
+ }
133
+ }
134
+
135
+ const BookmarkToggle = (() => {
136
+ // change form submit toggle to checkbox
137
+ Blacklight.doBookmarkToggleBehavior = function() {
138
+ document.addEventListener('click', (e) => {
139
+ if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) {
140
+ const form = e.target.closest('form');
141
+ if (form) new CheckboxSubmit(form).clicked(e);
142
+ }
143
+ });
144
+ };
145
+ Blacklight.doBookmarkToggleBehavior.selector = 'form.bookmark-toggle';
146
+
147
+ Blacklight.doBookmarkToggleBehavior();
148
+ })();
149
+
150
+ const ButtonFocus = (() => {
151
+ document.addEventListener('click', (e) => {
152
+ // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
153
+ // Safari both do not set focus to a button on button click.
154
+ // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
155
+ if (e.target.matches('[data-toggle="collapse"]') || e.target.matches('[data-bs-toggle="collapse"]')) {
156
+ e.target.focus();
157
+ }
158
+ });
159
+ })();
160
+
161
+ /*
162
+ The blacklight modal plugin can display some interactions inside a Bootstrap
163
+ modal window, including some multi-page interactions.
164
+
165
+ It supports unobtrusive Javascript, where a link or form that would have caused
166
+ a new page load is changed to display it's results inside a modal dialog,
167
+ by this plugin. The plugin assumes there is a Bootstrap modal div
168
+ on the page with id #blacklight-modal to use as the modal -- the standard Blacklight
169
+ layout provides this.
170
+
171
+ To make a link or form have their results display inside a modal, add
172
+ `data-blacklight-modal="trigger"` to the link or form. (Note, form itself not submit input)
173
+ With Rails link_to helper, you'd do that like:
174
+
175
+ link_to something, link, data: { blacklight_modal: "trigger" }
176
+
177
+ The results of the link href or form submit will be displayed inside
178
+ a modal -- they should include the proper HTML markup for a bootstrap modal's
179
+ contents. Also, you ordinarily won't want the Rails template with wrapping
180
+ navigational elements to be used. The Rails controller could suppress
181
+ the layout when a JS AJAX request is detected, OR the response
182
+ can include a `<div data-blacklight-modal="container">` -- only the contents
183
+ of the container will be placed inside the modal, the rest of the
184
+ page will be ignored.
185
+
186
+ Link or forms inside the modal will ordinarily cause page loads
187
+ when they are triggered. However, if you'd like their results
188
+ to stay within the modal, just add `data-blacklight-modal="preserve"`
189
+ to the link or form.
190
+
191
+ Here's an example of what might be returned, demonstrating most of the devices available:
192
+
193
+ <div data-blacklight-modal="container">
194
+ <div class="modal-header">
195
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
196
+ <h3 class="modal-title">Request Placed</h3>
197
+ </div>
198
+
199
+ <div class="modal-body">
200
+ <p>Some message</p>
201
+ <%= link_to "This result will still be within modal", some_link, data: { blacklight_modal: "preserve" } %>
202
+ </div>
203
+
204
+
205
+ <div class="modal-footer">
206
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
207
+ </div>
208
+ </div>
209
+
210
+
211
+ One additional feature. If the content returned from the AJAX form submission
212
+ can be a turbo-stream that defines some HTML fragementsand where on the page to put them:
213
+ https://turbo.hotwired.dev/handbook/streams
214
+ */
215
+
216
+ const Modal = (() => {
217
+ // We keep all our data in Blacklight.modal object.
218
+ // Create lazily if someone else created first.
219
+ if (Blacklight.modal === undefined) {
220
+ Blacklight.modal = {};
221
+ }
222
+
223
+ const modal = Blacklight.modal;
224
+
225
+ // a Bootstrap modal div that should be already on the page hidden
226
+ modal.modalSelector = '#blacklight-modal';
227
+
228
+ // Trigger selectors identify forms or hyperlinks that should open
229
+ // inside a modal dialog.
230
+ modal.triggerLinkSelector = 'a[data-blacklight-modal~=trigger]';
231
+
232
+ // preserve selectors identify forms or hyperlinks that, if activated already
233
+ // inside a modal dialog, should have destinations remain inside the modal -- but
234
+ // won't trigger a modal if not already in one.
235
+ //
236
+ // No need to repeat selectors from trigger selectors, those will already
237
+ // be preserved. MUST be manually prefixed with the modal selector,
238
+ // so they only apply to things inside a modal.
239
+ modal.preserveLinkSelector = modal.modalSelector + ' a[data-blacklight-modal~=preserve]';
240
+
241
+ modal.containerSelector = '[data-blacklight-modal~=container]';
242
+
243
+ // Called on fatal failure of ajax load, function returns content
244
+ // to show to user in modal. Right now called only for extreme
245
+ // network errors.
246
+ modal.onFailure = function (jqXHR, textStatus, errorThrown) {
247
+ console.error('Server error:', this.url, jqXHR.status, errorThrown);
248
+
249
+ const contents = `<div class="modal-header">
250
+ <div class="modal-title">There was a problem with your request.</div>
251
+ <button type="button" class="blacklight-modal-close btn-close close" data-dismiss="modal" data-bs-dismiss="modal" aria-label="Close">
252
+ <span aria-hidden="true">&times;</span>
253
+ </button>
254
+ </div>
255
+ <div class="modal-body">
256
+ <p>Expected a successful response from the server, but got an error</p>
257
+ <pre>${this.type} ${this.url}\n${jqXHR.status}: ${errorThrown}</pre>
258
+ </div>`;
259
+
260
+ document.querySelector(`${modal.modalSelector} .modal-content`).innerHTML = contents;
261
+
262
+ modal.show();
263
+ };
264
+
265
+ // Add the passed in contents to the modal and display it.
266
+ modal.receiveAjax = function (contents) {
267
+ const domparser = new DOMParser();
268
+ const dom = domparser.parseFromString(contents, "text/html");
269
+ const elements = dom.querySelectorAll(`${modal.containerSelector} > *`);
270
+ document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(...elements);
271
+
272
+ modal.show();
273
+ };
274
+
275
+
276
+ modal.modalAjaxLinkClick = function(e) {
277
+ e.preventDefault();
278
+ const href = e.target.getAttribute('href');
279
+ fetch(href)
280
+ .then(response => {
281
+ if (!response.ok) {
282
+ throw new TypeError("Request failed");
283
+ }
284
+ return response.text();
285
+ })
286
+ .then(data => modal.receiveAjax(data))
287
+ .catch(error => modal.onFailure(error));
288
+ };
289
+
290
+ modal.setupModal = function() {
291
+ // Register both trigger and preserve selectors in ONE event handler, combining
292
+ // into one selector with a comma, so if something matches BOTH selectors, it
293
+ // still only gets the event handler called once.
294
+ document.addEventListener('click', (e) => {
295
+ if (e.target.matches(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))
296
+ modal.modalAjaxLinkClick(e);
297
+ else if (e.target.matches('[data-bl-dismiss="modal"]'))
298
+ modal.hide();
299
+ });
300
+ };
301
+
302
+ modal.hide = function (el) {
303
+ const dom = document.querySelector(Blacklight.modal.modalSelector);
304
+
305
+ if (!dom.open) return
306
+ dom.close();
307
+ };
308
+
309
+ modal.show = function(el) {
310
+ const dom = document.querySelector(Blacklight.modal.modalSelector);
311
+
312
+ if (dom.open) return
313
+ dom.showModal();
314
+ };
315
+
316
+ modal.setupModal();
317
+ })();
318
+
319
+ const SearchContext = (() => {
320
+ Blacklight.doSearchContextBehavior = function() {
321
+ document.addEventListener('click', (e) => {
322
+ if (e.target.matches('[data-context-href]')) {
323
+ Blacklight.handleSearchContextMethod.call(e.target, e);
324
+ }
325
+ });
326
+ };
327
+
328
+ Blacklight.csrfToken = () => document.querySelector('meta[name=csrf-token]')?.content;
329
+ Blacklight.csrfParam = () => document.querySelector('meta[name=csrf-param]')?.content;
330
+
331
+ // this is the Rails.handleMethod with a couple adjustments, described inline:
332
+ // first, we're attaching this directly to the event handler, so we can check for meta-keys
333
+ Blacklight.handleSearchContextMethod = function(event) {
334
+ const link = this;
335
+
336
+ // instead of using the normal href, we need to use the context href instead
337
+ let href = link.getAttribute('data-context-href');
338
+ let target = link.getAttribute('target');
339
+ let csrfToken = Blacklight.csrfToken();
340
+ let csrfParam = Blacklight.csrfParam();
341
+ let form = document.createElement('form');
342
+ form.method = 'post';
343
+ form.action = href;
344
+
345
+
346
+ let formContent = `<input name="_method" value="post" type="hidden" />
347
+ <input name="redirect" value="${link.getAttribute('href')}" type="hidden" />`;
348
+
349
+ // check for meta keys.. if set, we should open in a new tab
350
+ if(event.metaKey || event.ctrlKey) {
351
+ target = '_blank';
352
+ }
353
+
354
+ if (csrfParam !== undefined && csrfToken !== undefined) {
355
+ formContent += `<input name="${csrfParam}" value="${csrfToken}" type="hidden" />`;
356
+ }
357
+
358
+ // Must trigger submit by click on a button, else "submit" event handler won't work!
359
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
360
+ formContent += '<input type="submit" />';
361
+
362
+ if (target) { form.setAttribute('target', target); }
363
+
364
+ form.style.display = 'none';
365
+ form.innerHTML = formContent;
366
+ document.body.appendChild(form);
367
+ form.querySelector('[type="submit"]').click();
368
+
369
+ event.preventDefault();
370
+ };
371
+
372
+ Blacklight.doSearchContextBehavior();
373
+ })();
374
+
375
+ const index = {
376
+ BookmarkToggle,
377
+ ButtonFocus,
378
+ Modal,
379
+ SearchContext,
380
+ onLoad: Blacklight.onLoad
381
+ };
382
+
383
+ export { index as default };
384
+ //# sourceMappingURL=blacklight.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blacklight.esm.js","sources":["../../../javascript/blacklight/core.js","../../../javascript/blacklight/checkbox_submit.js","../../../javascript/blacklight/bookmark_toggle.js","../../../javascript/blacklight/button_focus.js","../../../javascript/blacklight/modal.js","../../../javascript/blacklight/search_context.js","../../../javascript/blacklight/index.js"],"sourcesContent":["const Blacklight = function() {\n const buffer = new Array;\n return {\n onLoad: function(func) {\n buffer.push(func);\n },\n\n activate: function() {\n for(let i = 0; i < buffer.length; i++) {\n buffer[i].call();\n }\n },\n\n listeners: function () {\n const listeners = [];\n if (typeof Turbo !== 'undefined') {\n listeners.push('turbo:load', 'turbo:frame-load');\n } else if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {\n // Turbolinks 5\n if (Turbolinks.BrowserAdapter) {\n listeners.push('turbolinks:load');\n } else {\n // Turbolinks < 5\n listeners.push('page:load', 'DOMContentLoaded');\n }\n } else {\n listeners.push('DOMContentLoaded');\n }\n\n return listeners;\n }\n };\n}();\n\n// turbolinks triggers page:load events on page transition\n// If app isn't using turbolinks, this event will never be triggered, no prob.\nBlacklight.listeners().forEach(function(listener) {\n document.addEventListener(listener, function() {\n Blacklight.activate()\n })\n})\n\nBlacklight.onLoad(function () {\n const elem = document.querySelector('.no-js');\n\n // The \"no-js\" class may already have been removed because this function is\n // run on every turbo:load event, in that case, it won't find an element.\n if (!elem) return;\n\n elem.classList.remove('no-js')\n elem.classList.add('js')\n})\n\n\nexport default Blacklight\n","/* Converts a \"toggle\" form, with single submit button to add/remove\n something, like used for Bookmarks, into an AJAXy checkbox instead.\n Apply to a form. Does require certain assumption about the form:\n 1) The same form 'action' href must be used for both ADD and REMOVE\n actions, with the different being the hidden input name=\"_method\"\n being set to \"put\" or \"delete\" -- that's the Rails method to pretend\n to be doing a certain HTTP verb. So same URL, PUT to add, DELETE\n to remove. This plugin assumes that.\n Plus, the form this is applied to should provide a data-doc-id\n attribute (HTML5-style doc-*) that contains the id/primary key\n of the object in question -- used by plugin for a unique value for\n DOM id's.\n Uses HTML for a checkbox compatible with Bootstrap 4.\n new CheckboxSubmit(document.querySelector('form.something')).render()\n*/\nexport default class CheckboxSubmit {\n constructor(form) {\n this.form = form\n }\n\n async clicked(evt) {\n this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress')\n this.labelTarget.setAttribute('disabled', 'disabled');\n this.checkboxTarget.setAttribute('disabled', 'disabled');\n const response = await fetch(this.formTarget.getAttribute('action'), {\n body: new FormData(this.formTarget),\n method: this.formTarget.getAttribute('method').toUpperCase(),\n headers: {\n 'Accept': 'application/json',\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-CSRF-Token': document.querySelector('meta[name=csrf-token]')?.content\n }\n })\n this.labelTarget.removeAttribute('disabled')\n this.checkboxTarget.removeAttribute('disabled')\n if (response.ok) {\n const json = await response.json()\n this.updateStateFor(!this.checked)\n document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count\n } else {\n alert('Error')\n }\n }\n\n get checked() {\n return (this.form.querySelectorAll('input[name=_method][value=delete]').length != 0)\n }\n\n get formTarget() {\n return this.form\n }\n\n get labelTarget() {\n return this.form.querySelector('[data-checkboxsubmit-target=\"label\"]')\n }\n\n get checkboxTarget() {\n return this.form.querySelector('[data-checkboxsubmit-target=\"checkbox\"]')\n }\n\n get spanTarget() {\n return this.form.querySelector('[data-checkboxsubmit-target=\"span\"]')\n }\n\n updateStateFor(state) {\n this.checkboxTarget.checked = state\n\n if (state) {\n this.labelTarget.classList.add('checked')\n //Set the Rails hidden field that fakes an HTTP verb\n //properly for current state action.\n this.formTarget.querySelector('input[name=_method]').value = 'delete'\n this.spanTarget.innerHTML = this.form.getAttribute('data-present')\n } else {\n this.labelTarget.classList.remove('checked')\n this.formTarget.querySelector('input[name=_method]').value = 'put'\n this.spanTarget.innerHTML = this.form.getAttribute('data-absent')\n }\n }\n}\n","import Blacklight from './core'\nimport CheckboxSubmit from './checkbox_submit'\n\nconst BookmarkToggle = (() => {\n // change form submit toggle to checkbox\n Blacklight.doBookmarkToggleBehavior = function() {\n document.addEventListener('click', (e) => {\n if (e.target.matches('[data-checkboxsubmit-target=\"checkbox\"]')) {\n const form = e.target.closest('form')\n if (form) new CheckboxSubmit(form).clicked(e);\n }\n });\n };\n Blacklight.doBookmarkToggleBehavior.selector = 'form.bookmark-toggle';\n\n Blacklight.doBookmarkToggleBehavior();\n})()\n\nexport default BookmarkToggle\n","const ButtonFocus = (() => {\n document.addEventListener('click', (e) => {\n // Button clicks should change focus. As of 10/3/19, Firefox for Mac and\n // Safari both do not set focus to a button on button click.\n // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information\n if (e.target.matches('[data-toggle=\"collapse\"]') || e.target.matches('[data-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n })\n})()\n\nexport default ButtonFocus\n","/*\n The blacklight modal plugin can display some interactions inside a Bootstrap\n modal window, including some multi-page interactions.\n\n It supports unobtrusive Javascript, where a link or form that would have caused\n a new page load is changed to display it's results inside a modal dialog,\n by this plugin. The plugin assumes there is a Bootstrap modal div\n on the page with id #blacklight-modal to use as the modal -- the standard Blacklight\n layout provides this.\n\n To make a link or form have their results display inside a modal, add\n `data-blacklight-modal=\"trigger\"` to the link or form. (Note, form itself not submit input)\n With Rails link_to helper, you'd do that like:\n\n link_to something, link, data: { blacklight_modal: \"trigger\" }\n\n The results of the link href or form submit will be displayed inside\n a modal -- they should include the proper HTML markup for a bootstrap modal's\n contents. Also, you ordinarily won't want the Rails template with wrapping\n navigational elements to be used. The Rails controller could suppress\n the layout when a JS AJAX request is detected, OR the response\n can include a `<div data-blacklight-modal=\"container\">` -- only the contents\n of the container will be placed inside the modal, the rest of the\n page will be ignored.\n\n Link or forms inside the modal will ordinarily cause page loads\n when they are triggered. However, if you'd like their results\n to stay within the modal, just add `data-blacklight-modal=\"preserve\"`\n to the link or form.\n\n Here's an example of what might be returned, demonstrating most of the devices available:\n\n <div data-blacklight-modal=\"container\">\n <div class=\"modal-header\">\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n <h3 class=\"modal-title\">Request Placed</h3>\n </div>\n\n <div class=\"modal-body\">\n <p>Some message</p>\n <%= link_to \"This result will still be within modal\", some_link, data: { blacklight_modal: \"preserve\" } %>\n </div>\n\n\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n\n\n One additional feature. If the content returned from the AJAX form submission\n can be a turbo-stream that defines some HTML fragementsand where on the page to put them:\n https://turbo.hotwired.dev/handbook/streams\n*/\nimport Blacklight from './core'\nimport ModalForm from './modalForm'\n\nconst Modal = (() => {\n // We keep all our data in Blacklight.modal object.\n // Create lazily if someone else created first.\n if (Blacklight.modal === undefined) {\n Blacklight.modal = {};\n }\n\n const modal = Blacklight.modal\n\n // a Bootstrap modal div that should be already on the page hidden\n modal.modalSelector = '#blacklight-modal';\n\n // Trigger selectors identify forms or hyperlinks that should open\n // inside a modal dialog.\n modal.triggerLinkSelector = 'a[data-blacklight-modal~=trigger]';\n\n // preserve selectors identify forms or hyperlinks that, if activated already\n // inside a modal dialog, should have destinations remain inside the modal -- but\n // won't trigger a modal if not already in one.\n //\n // No need to repeat selectors from trigger selectors, those will already\n // be preserved. MUST be manually prefixed with the modal selector,\n // so they only apply to things inside a modal.\n modal.preserveLinkSelector = modal.modalSelector + ' a[data-blacklight-modal~=preserve]';\n\n modal.containerSelector = '[data-blacklight-modal~=container]';\n\n // Called on fatal failure of ajax load, function returns content\n // to show to user in modal. Right now called only for extreme\n // network errors.\n modal.onFailure = function (jqXHR, textStatus, errorThrown) {\n console.error('Server error:', this.url, jqXHR.status, errorThrown);\n\n const contents = `<div class=\"modal-header\">\n <div class=\"modal-title\">There was a problem with your request.</div>\n <button type=\"button\" class=\"blacklight-modal-close btn-close close\" data-dismiss=\"modal\" data-bs-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Expected a successful response from the server, but got an error</p>\n <pre>${this.type} ${this.url}\\n${jqXHR.status}: ${errorThrown}</pre>\n </div>`\n\n document.querySelector(`${modal.modalSelector} .modal-content`).innerHTML = contents\n\n modal.show();\n }\n\n // Add the passed in contents to the modal and display it.\nmodal.receiveAjax = function (contents) {\n const domparser = new DOMParser();\n const dom = domparser.parseFromString(contents, \"text/html\")\n const elements = dom.querySelectorAll(`${modal.containerSelector} > *`)\n document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(...elements)\n\n modal.show();\n };\n\n\n modal.modalAjaxLinkClick = function(e) {\n e.preventDefault();\n const href = e.target.getAttribute('href')\n fetch(href)\n .then(response => {\n if (!response.ok) {\n throw new TypeError(\"Request failed\");\n }\n return response.text();\n })\n .then(data => modal.receiveAjax(data))\n .catch(error => modal.onFailure(error))\n };\n\n modal.setupModal = function() {\n // Register both trigger and preserve selectors in ONE event handler, combining\n // into one selector with a comma, so if something matches BOTH selectors, it\n // still only gets the event handler called once.\n document.addEventListener('click', (e) => {\n if (e.target.matches(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.matches('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n };\n\n modal.hide = function (el) {\n const dom = document.querySelector(Blacklight.modal.modalSelector)\n\n if (!dom.open) return\n dom.close()\n }\n\n modal.show = function(el) {\n const dom = document.querySelector(Blacklight.modal.modalSelector)\n\n if (dom.open) return\n dom.showModal()\n }\n\n modal.setupModal()\n})()\n\nexport default Modal\n","import Blacklight from './core'\n\nconst SearchContext = (() => {\n Blacklight.doSearchContextBehavior = function() {\n document.addEventListener('click', (e) => {\n if (e.target.matches('[data-context-href]')) {\n Blacklight.handleSearchContextMethod.call(e.target, e)\n }\n })\n };\n\n Blacklight.csrfToken = () => document.querySelector('meta[name=csrf-token]')?.content\n Blacklight.csrfParam = () => document.querySelector('meta[name=csrf-param]')?.content\n\n // this is the Rails.handleMethod with a couple adjustments, described inline:\n // first, we're attaching this directly to the event handler, so we can check for meta-keys\n Blacklight.handleSearchContextMethod = function(event) {\n const link = this\n\n // instead of using the normal href, we need to use the context href instead\n let href = link.getAttribute('data-context-href')\n let target = link.getAttribute('target')\n let csrfToken = Blacklight.csrfToken()\n let csrfParam = Blacklight.csrfParam()\n let form = document.createElement('form')\n form.method = 'post'\n form.action = href\n\n\n let formContent = `<input name=\"_method\" value=\"post\" type=\"hidden\" />\n <input name=\"redirect\" value=\"${link.getAttribute('href')}\" type=\"hidden\" />`\n\n // check for meta keys.. if set, we should open in a new tab\n if(event.metaKey || event.ctrlKey) {\n target = '_blank';\n }\n\n if (csrfParam !== undefined && csrfToken !== undefined) {\n formContent += `<input name=\"${csrfParam}\" value=\"${csrfToken}\" type=\"hidden\" />`\n }\n\n // Must trigger submit by click on a button, else \"submit\" event handler won't work!\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit\n formContent += '<input type=\"submit\" />'\n\n if (target) { form.setAttribute('target', target); }\n\n form.style.display = 'none'\n form.innerHTML = formContent\n document.body.appendChild(form)\n form.querySelector('[type=\"submit\"]').click()\n\n event.preventDefault()\n };\n\n Blacklight.doSearchContextBehavior();\n})()\n\nexport default SearchContext\n","import BookmarkToggle from './bookmark_toggle'\nimport ButtonFocus from './button_focus'\nimport Modal from './modal'\nimport SearchContext from './search_context'\nimport Core from './core'\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n Modal,\n SearchContext,\n onLoad: Core.onLoad\n}\n"],"names":["Core"],"mappings":"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"}