blacklight 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/.env +3 -3
  3. data/.github/matrix.json +12 -18
  4. data/.github/workflows/lint.yml +1 -1
  5. data/.github/workflows/test.yml +4 -3
  6. data/.rubocop.yml +72 -7
  7. data/.rubocop_todo.yml +142 -268
  8. data/Gemfile +1 -1
  9. data/README.md +2 -9
  10. data/VERSION +1 -1
  11. data/app/assets/builds/blacklight.css +37 -23
  12. data/app/assets/images/blacklight/logo-dark.svg +184 -0
  13. data/app/assets/images/blacklight/logo.svg +184 -0
  14. data/app/assets/javascripts/blacklight/blacklight.esm.js +128 -45
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  16. data/app/assets/javascripts/blacklight/blacklight.js +128 -45
  17. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  18. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -1
  19. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +17 -0
  20. data/app/assets/stylesheets/blacklight/_constraints.scss +2 -2
  21. data/app/assets/stylesheets/blacklight/_facets.scss +14 -10
  22. data/app/assets/stylesheets/blacklight/_header.scss +0 -4
  23. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -9
  24. data/app/components/blacklight/facets/inclusive_constraint_component.html.erb +1 -1
  25. data/app/components/blacklight/icons/checkmark_component.rb +16 -0
  26. data/app/components/blacklight/icons/circle_half_component.rb +16 -0
  27. data/app/components/blacklight/icons/moon_stars_component.rb +17 -0
  28. data/app/components/blacklight/icons/sun_component.rb +16 -0
  29. data/app/components/blacklight/metadata_field_component.rb +1 -1
  30. data/app/components/blacklight/search_navbar_component.html.erb +1 -1
  31. data/app/components/blacklight/theme_switcher_component.html.erb +31 -0
  32. data/app/components/blacklight/theme_switcher_component.rb +6 -0
  33. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  34. data/app/controllers/concerns/blacklight/bookmarks.rb +8 -14
  35. data/app/controllers/concerns/blacklight/catalog.rb +9 -10
  36. data/app/controllers/concerns/blacklight/controller.rb +54 -11
  37. data/app/controllers/concerns/blacklight/guest_user.rb +51 -0
  38. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  39. data/app/controllers/concerns/blacklight/search_history.rb +3 -1
  40. data/app/controllers/concerns/blacklight/searchable.rb +18 -0
  41. data/app/helpers/blacklight/layout_helper_behavior.rb +7 -0
  42. data/app/javascript/blacklight-frontend/color_theme_switcher.js +85 -0
  43. data/app/javascript/blacklight-frontend/index.js +2 -0
  44. data/app/models/concerns/blacklight/document/dublin_core.rb +2 -2
  45. data/app/models/concerns/blacklight/document.rb +1 -1
  46. data/app/models/concerns/blacklight/user.rb +36 -0
  47. data/app/presenters/blacklight/field_presenter.rb +1 -1
  48. data/app/presenters/blacklight/rendering/microdata.rb +1 -0
  49. data/app/services/blacklight/bookmarks_search_builder.rb +4 -4
  50. data/app/services/blacklight/search_service.rb +46 -33
  51. data/app/values/blacklight/types.rb +1 -1
  52. data/app/views/catalog/_email_form.html.erb +3 -3
  53. data/app/views/catalog/_home_text.html.erb +1 -1
  54. data/app/views/catalog/_sms_form.html.erb +4 -4
  55. data/app/views/catalog/index.rss.builder +4 -4
  56. data/app/views/catalog/opensearch.json.jbuilder +3 -0
  57. data/app/views/catalog/opensearch.xml.builder +2 -2
  58. data/app/views/layouts/blacklight/base.html.erb +13 -1
  59. data/app/views/shared/_user_util_links.html.erb +18 -5
  60. data/blacklight.gemspec +3 -3
  61. data/config/locales/blacklight.ar.yml +5 -0
  62. data/config/locales/blacklight.ca.yml +5 -0
  63. data/config/locales/blacklight.de.yml +6 -2
  64. data/config/locales/blacklight.en.yml +5 -0
  65. data/config/locales/blacklight.es.yml +5 -0
  66. data/config/locales/blacklight.fr.yml +5 -0
  67. data/config/locales/blacklight.hu.yml +5 -0
  68. data/config/locales/blacklight.it.yml +6 -2
  69. data/config/locales/blacklight.nl.yml +5 -0
  70. data/config/locales/blacklight.pt-BR.yml +6 -2
  71. data/config/locales/blacklight.sq.yml +5 -0
  72. data/config/locales/blacklight.zh.yml +5 -0
  73. data/lib/blacklight/component.rb +1 -1
  74. data/lib/blacklight/configuration/action_config_map_entry.rb +31 -0
  75. data/lib/blacklight/configuration/display_field.rb +1 -0
  76. data/lib/blacklight/configuration/field.rb +6 -6
  77. data/lib/blacklight/configuration/fields.rb +1 -1
  78. data/lib/blacklight/configuration/sort_field.rb +2 -2
  79. data/lib/blacklight/configuration.rb +30 -19
  80. data/lib/blacklight/parameters.rb +1 -1
  81. data/lib/blacklight/search_builder.rb +58 -19
  82. data/lib/blacklight/search_state.rb +4 -0
  83. data/lib/blacklight/solr/request.rb +8 -1
  84. data/lib/blacklight/solr/response/group_response.rb +1 -1
  85. data/lib/blacklight/solr/response/spelling.rb +8 -8
  86. data/lib/blacklight/solr/response.rb +2 -21
  87. data/lib/blacklight/solr/search_builder_behavior.rb +3 -9
  88. data/lib/blacklight.rb +2 -2
  89. data/lib/generators/blacklight/assets/importmap_generator.rb +2 -2
  90. data/lib/generators/blacklight/assets_generator.rb +1 -1
  91. data/lib/generators/blacklight/controller_generator.rb +1 -1
  92. data/lib/generators/blacklight/document_generator.rb +1 -1
  93. data/lib/generators/blacklight/install_generator.rb +6 -4
  94. data/lib/generators/blacklight/models_generator.rb +1 -1
  95. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  96. data/lib/generators/blacklight/solr_generator.rb +1 -1
  97. data/lib/generators/blacklight/templates/catalog_controller.rb +20 -1
  98. data/lib/generators/blacklight/templates/solr/conf/schema.xml +264 -178
  99. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +6 -14
  100. data/lib/generators/blacklight/test_support_generator.rb +1 -1
  101. data/lib/generators/blacklight/user_generator.rb +66 -5
  102. data/lib/railties/blacklight.rake +4 -4
  103. data/package.json +2 -2
  104. data/spec/components/blacklight/document/action_component_spec.rb +1 -1
  105. data/spec/components/blacklight/document/group_component_spec.rb +1 -1
  106. data/spec/components/blacklight/document_component_spec.rb +9 -9
  107. data/spec/components/blacklight/facet_component_spec.rb +2 -2
  108. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +1 -2
  109. data/spec/components/blacklight/facets/list_component_spec.rb +1 -1
  110. data/spec/components/blacklight/facets/suggest_component_spec.rb +1 -2
  111. data/spec/components/blacklight/metadata_field_component_spec.rb +26 -0
  112. data/spec/components/blacklight/skip_link_component_spec.rb +2 -2
  113. data/spec/controllers/application_controller_spec.rb +71 -0
  114. data/spec/controllers/bookmarks_controller_spec.rb +18 -5
  115. data/spec/controllers/catalog_controller_spec.rb +7 -5
  116. data/spec/features/advanced_search_spec.rb +29 -16
  117. data/spec/features/alternate_controller_spec.rb +4 -4
  118. data/spec/features/axe_spec.rb +34 -22
  119. data/spec/features/bookmarks_spec.rb +13 -13
  120. data/spec/features/dark_mode_spec.rb +42 -0
  121. data/spec/features/did_you_mean_spec.rb +27 -27
  122. data/spec/features/facet_missing_spec.rb +3 -3
  123. data/spec/features/record_view_spec.rb +14 -14
  124. data/spec/features/search_context_spec.rb +8 -8
  125. data/spec/features/search_filters_spec.rb +16 -16
  126. data/spec/features/search_formats_spec.rb +2 -2
  127. data/spec/features/search_history_spec.rb +11 -11
  128. data/spec/features/search_pagination_spec.rb +17 -17
  129. data/spec/features/search_results_spec.rb +3 -3
  130. data/spec/features/search_sort_spec.rb +4 -4
  131. data/spec/features/search_spec.rb +20 -20
  132. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +15 -15
  133. data/spec/helpers/blacklight_helper_spec.rb +1 -1
  134. data/spec/helpers/catalog_helper_spec.rb +7 -7
  135. data/spec/integration/generators/blacklight/user_generator_spec.rb +60 -0
  136. data/spec/lib/blacklight/search_state/pivot_filter_field_spec.rb +1 -1
  137. data/spec/models/blacklight/configurable_spec.rb +1 -1
  138. data/spec/models/blacklight/configuration_spec.rb +0 -19
  139. data/spec/models/blacklight/document/dublin_core_spec.rb +2 -2
  140. data/spec/models/blacklight/facet_paginator_spec.rb +1 -1
  141. data/spec/models/blacklight/search_builder_spec.rb +15 -3
  142. data/spec/models/blacklight/solr/repository_spec.rb +10 -2
  143. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +3 -5
  144. data/spec/models/blacklight/user_spec.rb +32 -5
  145. data/spec/models/bookmark_spec.rb +1 -1
  146. data/spec/models/record_mailer_spec.rb +8 -8
  147. data/spec/models/search_spec.rb +1 -1
  148. data/spec/models/solr_document_spec.rb +4 -0
  149. data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
  150. data/spec/presenters/blacklight/rendering/pipeline_spec.rb +1 -0
  151. data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
  152. data/spec/presenters/blacklight/thumbnail_presenter_spec.rb +1 -0
  153. data/spec/services/blacklight/search_service_spec.rb +7 -7
  154. data/spec/spec_helper.rb +3 -12
  155. data/spec/support/features/session_helpers.rb +13 -4
  156. data/spec/support/features/turbo_helpers.rb +13 -0
  157. data/spec/support/features.rb +2 -0
  158. data/spec/support/user_helpers.rb +24 -0
  159. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  160. data/spec/views/catalog/_document.html.erb_spec.rb +4 -4
  161. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -2
  162. data/spec/views/catalog/_sort_and_per_page.html.erb_spec.rb +5 -5
  163. data/spec/views/catalog/index.html.erb_spec.rb +2 -2
  164. data/spec/views/catalog/show.html.erb_spec.rb +3 -4
  165. data/spec/views/shared/_user_util_links.html.erb_spec.rb +56 -0
  166. data/template.demo.rb +2 -1
  167. metadata +30 -22
  168. data/.hound.yml +0 -4
  169. data/.jshintrc +0 -22
  170. data/app/assets/images/blacklight/logo.png +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"blacklight.js","sources":["../../../javascript/blacklight-frontend/checkbox_submit.js","../../../javascript/blacklight-frontend/bookmark_toggle.js","../../../javascript/blacklight-frontend/button_focus.js","../../../javascript/blacklight-frontend/debounce.js","../../../javascript/blacklight-frontend/facet_suggest.js","../../../javascript/blacklight-frontend/modal.js","../../../javascript/blacklight-frontend/search_context.js","../../../javascript/blacklight-frontend/core.js","../../../javascript/blacklight-frontend/index.js"],"sourcesContent":["/* 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.\n new CheckboxSubmit(document.querySelector('form.something')).render()\n*/\nexport default class CheckboxSubmit {\n constructor(form) {\n this.form = form\n }\n\n clicked(evt) {\n this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress')\n this.labelTarget.setAttribute('disabled', 'disabled');\n this.checkboxTarget.setAttribute('disabled', 'disabled');\n 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 }).then((response) => {\n if (response.ok) return response.json();\n return Promise.reject('response was not ok')\n }).then((json) => {\n this.labelTarget.removeAttribute('disabled')\n this.checkboxTarget.removeAttribute('disabled')\n // For accessibility return keyboard focus\n // back to the checkbox after form submission\n this.checkboxTarget.focus()\n this.updateStateFor(!this.checked)\n this.bookmarksCounter().forEach(counter => {\n counter.innerHTML = json.bookmarks.count;\n });\n\n var e = new CustomEvent('bookmark.blacklight', { detail: { checked: this.checked }, bubbles: true });\n this.formTarget.dispatchEvent(e)\n }).catch((error) => {\n this.handleError(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 bookmarksCounter() {\n return document.querySelectorAll('[data-role=\"bookmark-counter\"]')\n }\n\n handleError() {\n alert(\"Unable to save the bookmark at this time.\")\n }\n\n updateStateFor(state) {\n if (state) { this.checkboxTarget.setAttribute('checked', state) }\n else { this.checkboxTarget.removeAttribute('checked') }\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 CheckboxSubmit from 'blacklight-frontend/checkbox_submit'\n\nconst BookmarkToggle = (e) => {\n const elementType = e.target.getAttribute('data-checkboxsubmit-target');\n if (elementType == 'checkbox' || elementType == 'label') {\n const form = e.target.closest('form');\n if (form) new CheckboxSubmit(form).clicked(e);\n if (e.code == 'Space') e.preventDefault();\n }\n};\n\ndocument.addEventListener('click', BookmarkToggle);\ndocument.addEventListener('keydown', function (e) {\n if (e.key === 'Enter' || e.code == 'Space') { BookmarkToggle(e); } }\n);\n\nexport default BookmarkToggle\n","const ButtonFocus = (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-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\n\nexport default ButtonFocus\n","// Usage:\n// ```\n// const basicFunction = (entry) => console.log(entry)\n// const debounced = debounce(basicFunction(\"I should only be called once\"));\n//\n// debounced // does NOT print to the screen because it is invoked again less than 200 milliseconds later\n// debounced // does print to the screen\n// ```\nexport default function debounce(func, timeout = 200) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => { func.apply(this, args); }, timeout);\n };\n}\n","import debounce from \"blacklight-frontend/debounce\";\n\nconst FacetSuggest = async (e) => {\n if (e.target.matches('.facet-suggest')) {\n const queryFragment = e.target.value?.trim();\n const facetField = e.target.dataset.facetField;\n const facetArea = document.querySelector('.facet-extended-list');\n const prevNextLinks = document.querySelectorAll('.prev_next_links');\n\n if (!facetField) { return; }\n\n // Get the search params from the current query so the facet suggestions\n // can retain that context.\n const facetSearchContext = e.target.dataset.facetSearchContext;\n const url = new URL(facetSearchContext, window.location.origin);\n\n // Drop facet.page so a filtered suggestion list will always start on page 1\n url.searchParams.delete('facet.page');\n // add our queryFragment for facet filtering\n url.searchParams.append('query_fragment', queryFragment);\n\n const facetSearchParams = url.searchParams.toString();\n const basePathComponent = url.pathname.split('/')[1];\n\n const urlToFetch = `/${basePathComponent}/facet_suggest/${facetField}?${facetSearchParams}`;\n\n const response = await fetch(urlToFetch);\n if (response.ok) {\n const blob = await response.blob()\n const text = await blob.text()\n\n if (text && facetArea) {\n facetArea.innerHTML = text\n }\n }\n\n // Hide the prev/next links when a user enters text in the facet\n // suggestion input. They don't work with a filtered list.\n prevNextLinks.forEach(element => {\n element.classList.toggle('invisible', !!queryFragment);\n });\n\n // Add a class to distinguish suggested facet values vs. regular.\n facetArea.classList.toggle('facet-suggestions', !!queryFragment);\n }\n};\n\ndocument.addEventListener('input', debounce(FacetSuggest));\n\nexport default FacetSuggest\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=\"btn-close\" data-bl-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-bl-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*/\n\nconst Modal = (() => {\n const 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 network errors.\n modal.onFailure = function (error) {\n console.error('Server error:', this.url, error);\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\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\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.url}\\n${error}</pre>\n </div>`\n\n modal.target().querySelector('.modal-content').innerHTML = contents\n\n modal.show();\n }\n\n // Add the passed in contents to the modal and display it.\n // We have specific handling so that scripts returned from the ajax call are executed.\n // This enables adding a script like recaptcha to prevent bots from sending emails.\n modal.receiveAjax = function (contents) {\n const domparser = new DOMParser();\n const dom = domparser.parseFromString(contents, \"text/html\")\n // If there is a containerSelector on the document, use its children.\n let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)\n const frag = document.createDocumentFragment()\n if (elements.length == 0) {\n // If the containerSelector wasn't found, use the whole document\n elements = dom.body.childNodes\n }\n elements.forEach((el) => frag.appendChild(el))\n modal.activateScripts(frag)\n\n modal.target().querySelector('.modal-content').replaceChildren(frag)\n\n // send custom event with the modal dialog div as the target\n var e = new CustomEvent('loaded.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n modal.target().dispatchEvent(e)\n\n // if they did preventDefault, don't show the dialog\n if (e.defaultPrevented) return;\n modal.show();\n };\n\n // DOMParser doesn't allow scripts to be executed. This fixes that.\n modal.activateScripts = function (frag) {\n frag.querySelectorAll('script').forEach((script) => {\n const fixedScript = document.createElement('script')\n fixedScript.src = script.src\n fixedScript.async = false\n script.parentNode.replaceChild(fixedScript, script)\n })\n }\n\n modal.modalAjaxLinkClick = function(e) {\n e.preventDefault();\n const href = e.target.closest('a').getAttribute('href')\n fetch(href, { headers: { 'X-Requested-With': 'XMLHttpRequest' }})\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 several click handlers in ONE event handler for efficiency\n //\n // * close button OR click on backdrop (modal.modalSelector) closes modal\n // * trigger and preserve link in modal functionality -- if somethign matches both trigger and\n // preserve, still only called once.\n document.addEventListener('click', (e) => {\n if (e.target.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.matches(`${modal.modalSelector}`) || e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n\n // Make sure user-agent dismissal of html 'dialog', etc `esc` key, triggers\n // our hide logic, including events and scroll restoration.\n const modalDom = modal.target();\n if (modalDom) {\n modal.target().addEventListener('cancel', (e) => {\n e.preventDefault(); // 'hide' will close the modal unless cancelled\n\n modal.hide();\n });\n }\n };\n\n modal.hide = function (el) {\n const dom = modal.target();\n\n if (!dom.open) return\n\n var e = new CustomEvent('hide.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n dom.dispatchEvent(e)\n\n dom.close()\n\n // Turn body scrolling back to what it was\n document.body.style[\"overflow\"] = modal.originalBodyOverflow;\n document.body.style[\"padding-right\"] = modal.originalBodyPaddingRight;\n modal.originalBodyOverflow = undefined;\n modal.originalBodyPaddingRight = undefined;\n }\n\n modal.show = function(el) {\n const dom = modal.target();\n\n if (dom.open) return\n\n var e = new CustomEvent('show.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n dom.dispatchEvent(e)\n\n dom.showModal()\n\n // Turn off body scrolling\n modal.originalBodyOverflow = document.body.style['overflow'];\n modal.originalBodyPaddingRight = document.body.style['padding-right'];\n document.body.style[\"overflow\"] = \"hidden\"\n document.body.style[\"padding-right\"] = \"0px\"\n }\n\n modal.target = function() {\n return document.querySelector(modal.modalSelector);\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n const contextLink = e.target.closest('[data-context-href]')\n if (contextLink) {\n SearchContext.handleSearchContextMethod.call(contextLink, e)\n }\n}\n\nSearchContext.csrfToken = () => document.querySelector('meta[name=csrf-token]')?.content\nSearchContext.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\nSearchContext.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 = SearchContext.csrfToken()\n let csrfParam = SearchContext.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 form.dataset.turbo = \"false\";\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\ndocument.addEventListener('click', SearchContext)\n\nexport default SearchContext\n","const Core = 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 {\n listeners.push('DOMContentLoaded');\n }\n\n return listeners;\n }\n };\n}();\n\n// turbo triggers turbo:load events on page transition\n// If app isn't using turbo, this event will never be triggered, no prob.\nCore.listeners().forEach(function(listener) {\n document.addEventListener(listener, function() {\n Core.activate()\n })\n})\n\nCore.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 Core\n","import BookmarkToggle from 'blacklight-frontend/bookmark_toggle'\nimport ButtonFocus from 'blacklight-frontend/button_focus'\nimport FacetSuggest from 'blacklight-frontend/facet_suggest'\nimport Modal from 'blacklight-frontend/modal'\nimport SearchContext from 'blacklight-frontend/search_context'\nimport Core from 'blacklight-frontend/core'\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n FacetSuggest,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blacklight.js","sources":["../../../javascript/blacklight-frontend/checkbox_submit.js","../../../javascript/blacklight-frontend/bookmark_toggle.js","../../../javascript/blacklight-frontend/button_focus.js","../../../javascript/blacklight-frontend/core.js","../../../javascript/blacklight-frontend/color_theme_switcher.js","../../../javascript/blacklight-frontend/debounce.js","../../../javascript/blacklight-frontend/facet_suggest.js","../../../javascript/blacklight-frontend/modal.js","../../../javascript/blacklight-frontend/search_context.js","../../../javascript/blacklight-frontend/index.js"],"sourcesContent":["/* 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.\n new CheckboxSubmit(document.querySelector('form.something')).render()\n*/\nexport default class CheckboxSubmit {\n constructor(form) {\n this.form = form\n }\n\n clicked(evt) {\n this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress')\n this.labelTarget.setAttribute('disabled', 'disabled');\n this.checkboxTarget.setAttribute('disabled', 'disabled');\n 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 }).then((response) => {\n if (response.ok) return response.json();\n return Promise.reject('response was not ok')\n }).then((json) => {\n this.labelTarget.removeAttribute('disabled')\n this.checkboxTarget.removeAttribute('disabled')\n // For accessibility return keyboard focus\n // back to the checkbox after form submission\n this.checkboxTarget.focus()\n this.updateStateFor(!this.checked)\n this.bookmarksCounter().forEach(counter => {\n counter.innerHTML = json.bookmarks.count;\n });\n\n var e = new CustomEvent('bookmark.blacklight', { detail: { checked: this.checked }, bubbles: true });\n this.formTarget.dispatchEvent(e)\n }).catch((error) => {\n this.handleError(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 bookmarksCounter() {\n return document.querySelectorAll('[data-role=\"bookmark-counter\"]')\n }\n\n handleError() {\n alert(\"Unable to save the bookmark at this time.\")\n }\n\n updateStateFor(state) {\n if (state) { this.checkboxTarget.setAttribute('checked', state) }\n else { this.checkboxTarget.removeAttribute('checked') }\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 CheckboxSubmit from 'blacklight-frontend/checkbox_submit'\n\nconst BookmarkToggle = (e) => {\n const elementType = e.target.getAttribute('data-checkboxsubmit-target');\n if (elementType == 'checkbox' || elementType == 'label') {\n const form = e.target.closest('form');\n if (form) new CheckboxSubmit(form).clicked(e);\n if (e.code == 'Space') e.preventDefault();\n }\n};\n\ndocument.addEventListener('click', BookmarkToggle);\ndocument.addEventListener('keydown', function (e) {\n if (e.key === 'Enter' || e.code == 'Space') { BookmarkToggle(e); } }\n);\n\nexport default BookmarkToggle\n","const ButtonFocus = (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-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\n\nexport default ButtonFocus\n","const Core = 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 {\n listeners.push('DOMContentLoaded');\n }\n\n return listeners;\n }\n };\n}();\n\n// turbo triggers turbo:load events on page transition\n// If app isn't using turbo, this event will never be triggered, no prob.\nCore.listeners().forEach(function(listener) {\n document.addEventListener(listener, function() {\n Core.activate()\n })\n})\n\nCore.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 Core\n","/*!\n * Color mode toggler for Blacklight\n * Based on Bootstrap's color mode toggler (https://getbootstrap.com/docs/5.3/customize/color-modes/#javascript)\n */\n\nimport Core from 'blacklight-frontend/core'\n\nconst ColorThemeSwitcher = (() => {\n 'use strict'\n\n const getStoredTheme = () => localStorage.getItem('theme')\n const setStoredTheme = theme => localStorage.setItem('theme', theme)\n\n const getPreferredTheme = () => {\n const storedTheme = getStoredTheme()\n if (storedTheme) {\n return storedTheme\n }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n\n const setTheme = theme => {\n if (theme === 'auto') {\n document.documentElement.setAttribute('data-bs-theme', window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')\n } else {\n document.documentElement.setAttribute('data-bs-theme', theme)\n }\n }\n\n const showActiveTheme = (theme, focus = false) => {\n const themeSwitcher = document.querySelector('#bl-theme-switcher')\n if (!themeSwitcher) return\n\n // Reset all dropdown items\n document.querySelectorAll('[data-bs-theme-value]').forEach(element => {\n element.classList.remove('active')\n element.setAttribute('aria-pressed', 'false')\n const check = element.querySelector('.bl-theme-check')\n if (check) check.classList.add('d-none')\n })\n\n // Activate the selected item\n const btnToActive = document.querySelector(`[data-bs-theme-value=\"${theme}\"]`)\n if (btnToActive) {\n btnToActive.classList.add('active')\n btnToActive.setAttribute('aria-pressed', 'true')\n const check = btnToActive.querySelector('.bl-theme-check')\n if (check) check.classList.remove('d-none')\n }\n\n // Swap the toggle button icon\n themeSwitcher.querySelectorAll('.bl-theme-icon').forEach(icon => icon.classList.add('d-none'))\n const activeIcon = themeSwitcher.querySelector(`.bl-theme-icon[data-bl-theme-icon=\"${theme}\"]`)\n if (activeIcon) activeIcon.classList.remove('d-none')\n\n themeSwitcher.setAttribute('aria-label', `Toggle theme (${theme})`)\n\n if (focus) {\n themeSwitcher.focus()\n }\n }\n\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n const storedTheme = getStoredTheme()\n if (storedTheme !== 'light' && storedTheme !== 'dark') {\n setTheme(getPreferredTheme())\n }\n })\n\n document.addEventListener('click', e => {\n const btn = e.target.closest('[data-bs-theme-value]')\n if (!btn) return\n\n const theme = btn.getAttribute('data-bs-theme-value')\n setStoredTheme(theme)\n setTheme(theme)\n showActiveTheme(theme, true)\n })\n\n Core.onLoad(() => showActiveTheme(getPreferredTheme()))\n\n return { setTheme, getPreferredTheme, showActiveTheme }\n})()\n\nexport default ColorThemeSwitcher\n","// Usage:\n// ```\n// const basicFunction = (entry) => console.log(entry)\n// const debounced = debounce(basicFunction(\"I should only be called once\"));\n//\n// debounced // does NOT print to the screen because it is invoked again less than 200 milliseconds later\n// debounced // does print to the screen\n// ```\nexport default function debounce(func, timeout = 200) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => { func.apply(this, args); }, timeout);\n };\n}\n","import debounce from \"blacklight-frontend/debounce\";\n\nconst FacetSuggest = async (e) => {\n if (e.target.matches('.facet-suggest')) {\n const queryFragment = e.target.value?.trim();\n const facetField = e.target.dataset.facetField;\n const facetArea = document.querySelector('.facet-extended-list');\n const prevNextLinks = document.querySelectorAll('.prev_next_links');\n\n if (!facetField) { return; }\n\n // Get the search params from the current query so the facet suggestions\n // can retain that context.\n const facetSearchContext = e.target.dataset.facetSearchContext;\n const url = new URL(facetSearchContext, window.location.origin);\n\n // Drop facet.page so a filtered suggestion list will always start on page 1\n url.searchParams.delete('facet.page');\n // add our queryFragment for facet filtering\n url.searchParams.append('query_fragment', queryFragment);\n\n const facetSearchParams = url.searchParams.toString();\n const basePathComponent = url.pathname.split('/')[1];\n\n const urlToFetch = `/${basePathComponent}/facet_suggest/${facetField}?${facetSearchParams}`;\n\n const response = await fetch(urlToFetch);\n if (response.ok) {\n const blob = await response.blob()\n const text = await blob.text()\n\n if (text && facetArea) {\n facetArea.innerHTML = text\n }\n }\n\n // Hide the prev/next links when a user enters text in the facet\n // suggestion input. They don't work with a filtered list.\n prevNextLinks.forEach(element => {\n element.classList.toggle('invisible', !!queryFragment);\n });\n\n // Add a class to distinguish suggested facet values vs. regular.\n facetArea.classList.toggle('facet-suggestions', !!queryFragment);\n }\n};\n\ndocument.addEventListener('input', debounce(FacetSuggest));\n\nexport default FacetSuggest\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=\"btn-close\" data-bl-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-bl-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*/\n\nconst Modal = (() => {\n const 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 network errors.\n modal.onFailure = function (error) {\n console.error('Server error:', this.url, error);\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\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\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.url}\\n${error}</pre>\n </div>`\n\n modal.target().querySelector('.modal-content').innerHTML = contents\n\n modal.show();\n }\n\n // Add the passed in contents to the modal and display it.\n // We have specific handling so that scripts returned from the ajax call are executed.\n // This enables adding a script like recaptcha to prevent bots from sending emails.\n modal.receiveAjax = function (contents) {\n const domparser = new DOMParser();\n const dom = domparser.parseFromString(contents, \"text/html\")\n // If there is a containerSelector on the document, use its children.\n let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)\n const frag = document.createDocumentFragment()\n if (elements.length == 0) {\n // If the containerSelector wasn't found, use the whole document\n elements = dom.body.childNodes\n }\n elements.forEach((el) => frag.appendChild(el))\n modal.activateScripts(frag)\n\n modal.target().querySelector('.modal-content').replaceChildren(frag)\n\n // send custom event with the modal dialog div as the target\n var e = new CustomEvent('loaded.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n modal.target().dispatchEvent(e)\n\n // if they did preventDefault, don't show the dialog\n if (e.defaultPrevented) return;\n modal.show();\n };\n\n // DOMParser doesn't allow scripts to be executed. This fixes that.\n modal.activateScripts = function (frag) {\n frag.querySelectorAll('script').forEach((script) => {\n const fixedScript = document.createElement('script')\n fixedScript.src = script.src\n fixedScript.async = false\n script.parentNode.replaceChild(fixedScript, script)\n })\n }\n\n modal.modalAjaxLinkClick = function(e) {\n e.preventDefault();\n const href = e.target.closest('a').getAttribute('href')\n fetch(href, { headers: { 'X-Requested-With': 'XMLHttpRequest' }})\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 several click handlers in ONE event handler for efficiency\n //\n // * close button OR click on backdrop (modal.modalSelector) closes modal\n // * trigger and preserve link in modal functionality -- if somethign matches both trigger and\n // preserve, still only called once.\n document.addEventListener('click', (e) => {\n if (e.target.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.matches(`${modal.modalSelector}`) || e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n\n // Make sure user-agent dismissal of html 'dialog', etc `esc` key, triggers\n // our hide logic, including events and scroll restoration.\n const modalDom = modal.target();\n if (modalDom) {\n modal.target().addEventListener('cancel', (e) => {\n e.preventDefault(); // 'hide' will close the modal unless cancelled\n\n modal.hide();\n });\n }\n };\n\n modal.hide = function (el) {\n const dom = modal.target();\n\n if (!dom.open) return\n\n var e = new CustomEvent('hide.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n dom.dispatchEvent(e)\n\n dom.close()\n\n // Turn body scrolling back to what it was\n document.body.style[\"overflow\"] = modal.originalBodyOverflow;\n document.body.style[\"padding-right\"] = modal.originalBodyPaddingRight;\n modal.originalBodyOverflow = undefined;\n modal.originalBodyPaddingRight = undefined;\n }\n\n modal.show = function(el) {\n const dom = modal.target();\n\n if (dom.open) return\n\n var e = new CustomEvent('show.blacklight.blacklight-modal', { bubbles: true, cancelable: true });\n dom.dispatchEvent(e)\n\n dom.showModal()\n\n // Turn off body scrolling\n modal.originalBodyOverflow = document.body.style['overflow'];\n modal.originalBodyPaddingRight = document.body.style['padding-right'];\n document.body.style[\"overflow\"] = \"hidden\"\n document.body.style[\"padding-right\"] = \"0px\"\n }\n\n modal.target = function() {\n return document.querySelector(modal.modalSelector);\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n const contextLink = e.target.closest('[data-context-href]')\n if (contextLink) {\n SearchContext.handleSearchContextMethod.call(contextLink, e)\n }\n}\n\nSearchContext.csrfToken = () => document.querySelector('meta[name=csrf-token]')?.content\nSearchContext.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\nSearchContext.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 = SearchContext.csrfToken()\n let csrfParam = SearchContext.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 form.dataset.turbo = \"false\";\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\ndocument.addEventListener('click', SearchContext)\n\nexport default SearchContext\n","import BookmarkToggle from 'blacklight-frontend/bookmark_toggle'\nimport ButtonFocus from 'blacklight-frontend/button_focus'\nimport ColorThemeSwitcher from 'blacklight-frontend/color_theme_switcher'\nimport FacetSuggest from 'blacklight-frontend/facet_suggest'\nimport Modal from 'blacklight-frontend/modal'\nimport SearchContext from 'blacklight-frontend/search_context'\nimport Core from 'blacklight-frontend/core'\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n ColorThemeSwitcher,\n FacetSuggest,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  .dl-invert {
2
2
  dt {
3
3
  font-weight: normal;
4
- color: var(--bl-field-name-color);
4
+ color: var(--bs-secondary-color);
5
5
 
6
6
  @media (min-width: breakpoint-min(md)) {
7
7
  text-align: end;
@@ -19,3 +19,20 @@ dialog.modal[open] {
19
19
  background-color: var(--bl-modal-backdrop-bg);
20
20
  }
21
21
  }
22
+
23
+ /* Contrast fix for Bootstrap's btn-outline-secondary in dark mode */
24
+ [data-bs-theme="dark"] .btn-outline-secondary {
25
+ --bs-btn-color: #848D94;
26
+ --bs-btn-border-color: #848D94;
27
+ }
28
+
29
+ /* Contrast fix for Bootstrap's text success color in dark mode */
30
+ [data-bs-theme="dark"] .facets {
31
+ --bl-facet-active-item-color: #1D9F63;
32
+ }
33
+
34
+ /* Contrast fix for Bootstrap's accordion icon on success background in dark mode */
35
+ [data-bs-theme="dark"] .accordion-button::after {
36
+ --bs-accordion-btn-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-linecap='round' stroke-linejoin='round'><path d='m2 5 6 6 6-6'/></svg>");
37
+ --bs-accordion-btn-active-icon: var(--bs-accordion-btn-icon);
38
+ }
@@ -23,8 +23,8 @@
23
23
  height: 1.1rem;
24
24
  width: 1.25rem;
25
25
  vertical-align: text-bottom;
26
- margin-right: -0.2rem;
27
- margin-left: 0.25rem;
26
+ margin-inline-end: -0.2rem;
27
+ margin-inline-start: 0.25rem;
28
28
  transition: background-color 0.15s ease-in-out;
29
29
  }
30
30
  }
@@ -63,7 +63,7 @@
63
63
  }
64
64
 
65
65
  .facet-limit {
66
- --bs-accordion-btn-bg: var(--bs-gray-100);
66
+ --bs-accordion-btn-bg: var(--bs-tertiary-bg);
67
67
  --bs-btn-active-bg: var(--bs-accordion-btn-bg);
68
68
  --bs-btn-hover-bg: var(--bs-accordion-btn-bg);
69
69
  --bs-accordion-active-bg: var(--bs-accordion-btn-bg);
@@ -124,7 +124,7 @@
124
124
  }
125
125
 
126
126
  .facet-count {
127
- margin-left: auto;
127
+ margin-inline-start: auto;
128
128
  }
129
129
 
130
130
  .facet-checkbox {
@@ -134,11 +134,11 @@
134
134
 
135
135
  .facet-extended-list {
136
136
  .sort-options {
137
- text-align: right;
137
+ text-align: end;
138
138
  }
139
139
 
140
140
  .prev-next-links {
141
- float: left;
141
+ float: start;
142
142
  }
143
143
  }
144
144
 
@@ -164,7 +164,9 @@
164
164
  // If the item has no expand button, we align it with its siblings that do
165
165
  // by giving it left margin equal to the sum of the button's width & margin
166
166
  li.treeitem:not(:has(button.facet-toggle-handle)) {
167
- margin-left: calc(var(--bl-facet-toggle-width) + var(--bl-facet-toggle-margin));
167
+ margin-inline-start: calc(
168
+ var(--bl-facet-toggle-width) + var(--bl-facet-toggle-margin)
169
+ );
168
170
  }
169
171
  }
170
172
 
@@ -177,7 +179,7 @@
177
179
  border: 0;
178
180
  width: var(--bl-facet-toggle-width);
179
181
  height: var(--bl-facet-toggle-height);
180
- margin-right: var(--bl-facet-toggle-margin);
182
+ margin-inline-end: var(--bl-facet-toggle-margin);
181
183
 
182
184
  &.collapsed {
183
185
  .show {
@@ -204,12 +206,14 @@
204
206
  }
205
207
 
206
208
  .show .icon {
207
- background: transparent escape-svg(var(--bl-facet-toggle-show-icon)) center /
208
- var(--bl-facet-toggle-width) auto no-repeat;
209
+ background-color: currentColor;
210
+ mask: var(--bl-facet-toggle-show-icon) center / var(--bl-facet-toggle-width) auto no-repeat;
211
+ -webkit-mask: var(--bl-facet-toggle-show-icon) center / var(--bl-facet-toggle-width) auto no-repeat;
209
212
  }
210
213
 
211
214
  .hide .icon {
212
- background: transparent escape-svg(var(--bl-facet-toggle-hide-icon)) center /
213
- var(--bl-facet-toggle-width) auto no-repeat;
215
+ background-color: currentColor;
216
+ mask: var(--bl-facet-toggle-hide-icon) center / var(--bl-facet-toggle-width) auto no-repeat;
217
+ -webkit-mask: var(--bl-facet-toggle-hide-icon) center / var(--bl-facet-toggle-width) auto no-repeat;
214
218
  }
215
219
  }
@@ -2,10 +2,6 @@
2
2
  Header bar at top (Bootstrap nav-bar)
3
3
  */
4
4
 
5
- .navbar.bg-dark {
6
- --bs-emphasis-color-rgb: 255, 255, 255;
7
- }
8
-
9
5
  .navbar-logo {
10
6
  /* The main logo image for the Blacklight instance */
11
7
  background: transparent var(--bl-logo-image) no-repeat top left;
@@ -1,21 +1,17 @@
1
1
  :root {
2
- --bl-logo-image: url("blacklight/logo.png");
2
+ --bl-logo-image: url("blacklight/logo.svg");
3
3
  --bl-logo-width: 150px;
4
4
  --bl-logo-height: 50px;
5
- --bs-secondary-color: rgba(
6
- 33,
7
- 37,
8
- 41,
9
- 0.75
10
- ); /* for compatability with BS < 5.3 */
11
5
 
12
6
  --bl-main-padding-y: 0.5rem;
13
7
 
14
8
  --bl-constraint-remove-hover-bg: #bb2d3b;
15
9
  --bl-constraint-remove-hover-border-color: #bb2d3b;
16
10
 
17
- --bl-field-name-color: var(--bs-secondary-color);
18
-
19
11
  /* emulate Bootstrap backdrop bg & opacity */
20
12
  --bl-modal-backdrop-bg: rgba(0, 0, 0, 0.5);
21
13
  }
14
+
15
+ [data-bs-theme="dark"] {
16
+ --bl-logo-image: url("blacklight/logo-dark.svg");
17
+ }
@@ -1,4 +1,4 @@
1
- <div class="inclusive_or card card-body bg-light mb-3">
1
+ <div class="inclusive_or card card-body bg-body-tertiary mb-3">
2
2
  <h5><%= t('blacklight.advanced_search.any_of') %></h5>
3
3
  <ul class="list-unstyled facet-values">
4
4
  <%= render Blacklight::Facets::ItemComponent.with_collection(presenters.to_a) %>
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # Checkmark icon (Bootstrap Icons bi-check2) used to indicate the active selection.
6
+ # You can override the default svg by setting:
7
+ # Blacklight::Icons::Check2Component.svg = '<svg>your SVG here</svg>'
8
+ class CheckmarkComponent < Blacklight::Icons::IconComponent
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2" viewBox="0 0 16 16">
11
+ <path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0"/>
12
+ </svg>
13
+ SVG
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # Circle-half icon (Bootstrap Icons bi-circle-half) representing the auto/system theme.
6
+ # You can override the default svg by setting:
7
+ # Blacklight::Icons::CircleHalfComponent.svg = '<svg>your SVG here</svg>'
8
+ class CircleHalfComponent < Blacklight::Icons::IconComponent
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-circle-half" viewBox="0 0 16 16">
11
+ <path d="M8 15A7 7 0 1 0 8 1zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16"/>
12
+ </svg>
13
+ SVG
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # Moon-and-stars icon (Bootstrap Icons bi-moon-stars-fill) representing the dark theme.
6
+ # You can override the default svg by setting:
7
+ # Blacklight::Icons::MoonStarsFillComponent.svg = '<svg>your SVG here</svg>'
8
+ class MoonStarsComponent < Blacklight::Icons::IconComponent
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-moon-stars-fill" viewBox="0 0 16 16">
11
+ <path d="M6 .278a.77.77 0 0 1 .08.858 7.2 7.2 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277q.792-.001 1.533-.16a.79.79 0 0 1 .81.316.73.73 0 0 1-.031.893A8.35 8.35 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.75.75 0 0 1 6 .278"/>
12
+ <path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.73 1.73 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.73 1.73 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.73 1.73 0 0 0 1.097-1.097zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.16 1.16 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.16 1.16 0 0 0-.732-.732L12.1 1.137a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732z"/>
13
+ </svg>
14
+ SVG
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # Sun icon (Bootstrap Icons bi-sun-fill) representing the light theme.
6
+ # You can override the default svg by setting:
7
+ # Blacklight::Icons::SunFillComponent.svg = '<svg>your SVG here</svg>'
8
+ class SunComponent < Blacklight::Icons::IconComponent
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sun-fill" viewBox="0 0 16 16">
11
+ <path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0m9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708"/>
12
+ </svg>
13
+ SVG
14
+ end
15
+ end
16
+ end
@@ -9,7 +9,7 @@ module Blacklight
9
9
  # @param show [Boolean] are we showing only a single document (vs a list of search results); used for backwards-compatibility
10
10
  def initialize(field:, layout: nil, show: false, view_type: nil)
11
11
  @field = field
12
- @layout = layout || Blacklight::MetadataFieldLayoutComponent
12
+ @layout = layout || field.layout_component || Blacklight::MetadataFieldLayoutComponent
13
13
  @view_type = view_type
14
14
  @show = show
15
15
  end
@@ -1,4 +1,4 @@
1
- <%= tag.div class: 'navbar-search navbar navbar-light bg-light', role: 'navigation', aria: { label: t('blacklight.search.header') } do %>
1
+ <%= tag.div class: 'navbar navbar-search bg-body-tertiary border-bottom', role: 'navigation', aria: { label: t('blacklight.search.header') } do %>
2
2
  <div class="<%= container_classes %>">
3
3
  <%= search_bar %>
4
4
  </div>
@@ -0,0 +1,31 @@
1
+ <li class="nav-item dropdown">
2
+ <button class="btn btn-link nav-link dropdown-toggle d-flex px-0 px-md-2 py-2 align-items-center" id="bl-theme-switcher" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Toggle theme (auto)">
3
+ <%= render Blacklight::Icons::SunComponent.new(classes: %w[bl-theme-icon d-none], aria_hidden: true, data: { bl_theme_icon: 'light' }) %>
4
+ <%= render Blacklight::Icons::MoonStarsComponent.new(classes: %w[bl-theme-icon d-none], aria_hidden: true, data: { bl_theme_icon: 'dark' }) %>
5
+ <%= render Blacklight::Icons::CircleHalfComponent.new(classes: %w[bl-theme-icon d-none], aria_hidden: true, data: { bl_theme_icon: 'auto' }) %>
6
+ <span class="d-md-none ms-2" id="bl-theme-text"><%= t('blacklight.theme.toggle') %></span>
7
+ </button>
8
+ <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bl-theme-text">
9
+ <li>
10
+ <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
11
+ <%= render Blacklight::Icons::SunComponent.new(classes: %w[me-2 opacity-50], aria_hidden: true) %>
12
+ <%= t('blacklight.theme.light') %>
13
+ <%= render Blacklight::Icons::CheckmarkComponent.new(classes: %w[ms-auto d-none bl-theme-check], aria_hidden: true) %>
14
+ </button>
15
+ </li>
16
+ <li>
17
+ <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
18
+ <%= render Blacklight::Icons::MoonStarsComponent.new(classes: %w[me-2 opacity-50], aria_hidden: true) %>
19
+ <%= t('blacklight.theme.dark') %>
20
+ <%= render Blacklight::Icons::CheckmarkComponent.new(classes: %w[ms-auto d-none bl-theme-check], aria_hidden: true) %>
21
+ </button>
22
+ </li>
23
+ <li>
24
+ <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="auto" aria-pressed="false">
25
+ <%= render Blacklight::Icons::CircleHalfComponent.new(classes: %w[me-2 opacity-50], aria_hidden: true) %>
26
+ <%= t('blacklight.theme.auto') %>
27
+ <%= render Blacklight::Icons::CheckmarkComponent.new(classes: %w[ms-auto d-none bl-theme-check], aria_hidden: true) %>
28
+ </button>
29
+ </li>
30
+ </ul>
31
+ </li>
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class ThemeSwitcherComponent < Blacklight::Component
5
+ end
6
+ end
@@ -1,4 +1,4 @@
1
- <nav class="navbar navbar-expand-md bg-dark topbar" aria-label="<%= aria_label %>">
1
+ <nav class="navbar navbar-expand-md bg-body-tertiary topbar" aria-label="<%= aria_label %>">
2
2
  <div class="<%= container_classes %>">
3
3
  <%= logo_link %>
4
4
  <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#user-util-collapse" aria-controls="user-util-collapse" aria-expanded="false" aria-label="Toggle navigation">
@@ -13,6 +13,8 @@ module Blacklight::Bookmarks
13
13
 
14
14
  copy_blacklight_config_from(CatalogController)
15
15
 
16
+ allow_unauthenticated_access raise: false if respond_to?(:allow_unauthenticated_access)
17
+
16
18
  before_action :verify_user
17
19
 
18
20
  blacklight_config.track_search_session.storage = false
@@ -27,7 +29,7 @@ module Blacklight::Bookmarks
27
29
  def action_documents
28
30
  bookmarks = token_or_current_or_guest_user.bookmarks
29
31
  bookmark_ids = bookmarks.collect { |b| b.document_id.to_s }
30
- search_service.fetch(bookmark_ids, rows: bookmark_ids.count)
32
+ search_service.fetch(bookmark_ids)
31
33
  end
32
34
 
33
35
  def action_success_redirect_path
@@ -47,16 +49,8 @@ module Blacklight::Bookmarks
47
49
 
48
50
  def index
49
51
  @bookmarks = token_or_current_or_guest_user.bookmarks
50
- @response = search_service.search_results
51
-
52
- respond_to do |format|
53
- format.html {}
54
- format.rss { render layout: false }
55
- format.atom { render layout: false }
56
52
 
57
- additional_response_formats(format)
58
- document_export_formats(format)
59
- end
53
+ super
60
54
  end
61
55
 
62
56
  def update
@@ -99,7 +93,7 @@ module Blacklight::Bookmarks
99
93
  flash[:error] = I18n.t('blacklight.bookmarks.add.failure', count: @bookmarks.length)
100
94
  end
101
95
 
102
- redirect_back fallback_location: bookmarks_path
96
+ redirect_back_or_to(bookmarks_path)
103
97
  end
104
98
  end
105
99
 
@@ -127,12 +121,12 @@ module Blacklight::Bookmarks
127
121
  if request.xhr?
128
122
  render(json: { bookmarks: { count: current_or_guest_user.bookmarks.count } })
129
123
  else
130
- redirect_back fallback_location: bookmarks_path, notice: I18n.t('blacklight.bookmarks.remove.success')
124
+ redirect_back_or_to(bookmarks_path, notice: I18n.t('blacklight.bookmarks.remove.success'))
131
125
  end
132
126
  elsif request.xhr?
133
127
  head :internal_server_error # ajaxy request needs no redirect and should not have flash set
134
128
  else
135
- redirect_back fallback_location: bookmarks_path, flash: { error: I18n.t('blacklight.bookmarks.remove.failure') }
129
+ redirect_back_or_to(bookmarks_path, flash: { error: I18n.t('blacklight.bookmarks.remove.failure') })
136
130
  end
137
131
  end
138
132
 
@@ -148,7 +142,7 @@ module Blacklight::Bookmarks
148
142
  private
149
143
 
150
144
  def verify_user
151
- unless current_or_guest_user || (action == "index" && token_or_current_or_guest_user)
145
+ unless current_or_guest_user || (action_name == "index" && token_or_current_or_guest_user)
152
146
  flash[:notice] = I18n.t('blacklight.bookmarks.need_login')
153
147
  raise Blacklight::Exceptions::AccessDenied
154
148
  end
@@ -13,6 +13,8 @@ module Blacklight::Catalog
13
13
  # The following code is executed when someone includes blacklight::catalog in their
14
14
  # own controller.
15
15
  included do
16
+ allow_unauthenticated_access raise: false if respond_to?(:allow_unauthenticated_access)
17
+
16
18
  if respond_to? :helper_method
17
19
  helper_method :sms_mappings, :has_search_parameters?
18
20
  end
@@ -37,7 +39,7 @@ module Blacklight::Catalog
37
39
  # get a single document from the index
38
40
  # to add responses for formats other than html or json see _Blacklight::Document::Export_
39
41
  def show
40
- @document = search_service.fetch(params[:id])
42
+ @document = retrieve_document(params[:id])
41
43
 
42
44
  respond_to do |format|
43
45
  format.html { @search_context = setup_next_and_previous_documents }
@@ -54,7 +56,7 @@ module Blacklight::Catalog
54
56
  def raw
55
57
  raise(ActionController::RoutingError, 'Not Found') unless blacklight_config.raw_endpoint.enabled
56
58
 
57
- @document = search_service.fetch(params[:id])
59
+ @document = retrieve_document(params[:id])
58
60
  render json: @document
59
61
  end
60
62
 
@@ -107,7 +109,10 @@ module Blacklight::Catalog
107
109
  def opensearch
108
110
  respond_to do |format|
109
111
  format.xml { render layout: false }
110
- format.json { render json: search_service.opensearch_response }
112
+ format.json do
113
+ @response = retrieve_search_results
114
+ @presenter = json_presenter(@response)
115
+ end
111
116
  end
112
117
  end
113
118
 
@@ -120,7 +125,7 @@ module Blacklight::Catalog
120
125
  # @return [Array] first value is a Blacklight::Solr::Response and the second
121
126
  # is a list of documents
122
127
  def action_documents
123
- @documents = search_service.fetch(Array(params[:id]))
128
+ @documents = retrieve_documents(params[:id])
124
129
  raise Blacklight::Exceptions::RecordNotFound if @documents.blank?
125
130
 
126
131
  @documents
@@ -145,12 +150,6 @@ module Blacklight::Catalog
145
150
  blacklight_config.index.json_presenter_class.new(repository_response, blacklight_config)
146
151
  end
147
152
 
148
- # This method may be overridden to customize search behavior.
149
- # @return [Blacklight::Solr::Response] the solr response object
150
- def retrieve_search_results
151
- search_service.search_results
152
- end
153
-
154
153
  #
155
154
  # non-routable methods ->
156
155
  #