blacklight 8.0.1 → 8.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.github/workflows/ruby.yml +17 -4
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +82 -73
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.esm.js +44 -21
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +44 -21
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_mixins.scss +1 -1
- data/app/builders/blacklight/action_builder.rb +1 -1
- data/app/components/blacklight/advanced_search_form_component.html.erb +3 -3
- data/app/components/blacklight/advanced_search_form_component.rb +3 -3
- data/app/components/blacklight/document/bookmark_component.html.erb +1 -6
- data/app/components/blacklight/facet_field_component.html.erb +2 -1
- data/app/components/blacklight/icons/legacy_icon_component.rb +1 -1
- data/app/components/blacklight/response/facet_group_component.html.erb +0 -1
- data/app/components/blacklight/response/pagination_component.html.erb +1 -1
- data/app/components/blacklight/response/pagination_component.rb +6 -1
- data/app/components/blacklight/search_bar_component.html.erb +2 -2
- data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
- data/app/controllers/concerns/blacklight/token_based_user.rb +5 -19
- data/app/helpers/blacklight/url_helper_behavior.rb +3 -2
- data/app/javascript/blacklight/bookmark_toggle.js +1 -1
- data/app/javascript/blacklight/checkbox_submit.js +15 -10
- data/app/javascript/blacklight/index.js +10 -5
- data/app/javascript/blacklight/modal.js +27 -13
- data/app/javascript/blacklight/search_context.js +1 -0
- data/app/models/concerns/blacklight/document/active_model_shim.rb +10 -0
- data/app/models/search.rb +6 -1
- data/app/services/blacklight/field_retriever.rb +13 -11
- data/app/values/blacklight/types.rb +14 -0
- data/app/views/catalog/_advanced_search_form.html.erb +1 -1
- data/app/views/catalog/_citation.html.erb +1 -1
- data/app/views/catalog/_show_tools.html.erb +1 -1
- data/app/views/catalog/email.html.erb +2 -2
- data/app/views/catalog/sms.html.erb +2 -2
- data/app/views/kaminari/blacklight/_page.html.erb +1 -1
- data/blacklight.gemspec +2 -3
- data/config/locales/blacklight.ar.yml +0 -1
- data/config/locales/blacklight.ca.yml +0 -2
- data/config/locales/blacklight.de.yml +0 -1
- data/config/locales/blacklight.en.yml +1 -1
- data/config/locales/blacklight.es.yml +0 -1
- data/config/locales/blacklight.fr.yml +0 -1
- data/config/locales/blacklight.hu.yml +0 -1
- data/config/locales/blacklight.it.yml +0 -1
- data/config/locales/blacklight.nl.yml +0 -1
- data/config/locales/blacklight.pt-BR.yml +0 -1
- data/config/locales/blacklight.sq.yml +0 -1
- data/config/locales/blacklight.zh.yml +0 -1
- data/docker-compose.yml +0 -2
- data/lib/blacklight/component.rb +1 -1
- data/lib/blacklight/configuration.rb +7 -1
- data/lib/blacklight/engine.rb +12 -0
- data/lib/blacklight/solr/repository.rb +16 -2
- data/lib/blacklight/solr/response/params.rb +1 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +3 -0
- data/lib/generators/blacklight/assets/importmap_generator.rb +2 -2
- data/lib/generators/blacklight/assets/sprockets_generator.rb +1 -1
- data/lib/generators/blacklight/assets_generator.rb +2 -4
- data/lib/generators/blacklight/install_generator.rb +1 -3
- data/lib/generators/blacklight/templates/catalog_controller.rb +1 -0
- data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +69 -0
- data/package.json +1 -1
- data/spec/components/blacklight/facet_component_spec.rb +11 -1
- data/spec/components/blacklight/facet_item_pivot_component_spec.rb +2 -2
- data/spec/components/blacklight/response/pagination_component_spec.rb +53 -0
- data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +11 -1
- data/spec/controllers/catalog_controller_spec.rb +2 -2
- data/spec/features/advanced_search_spec.rb +61 -0
- data/spec/features/axe_spec.rb +5 -0
- data/spec/features/citation_spec.rb +10 -0
- data/spec/features/sms_spec.rb +12 -0
- data/spec/helpers/blacklight_helper_spec.rb +10 -5
- data/spec/models/blacklight/configurable_spec.rb +1 -1
- data/spec/models/blacklight/solr/repository_spec.rb +27 -0
- data/spec/models/blacklight/solr/response_spec.rb +1 -1
- data/spec/models/blacklight/solr/search_builder_spec.rb +21 -0
- data/spec/models/solr_document_spec.rb +6 -2
- data/spec/services/blacklight/field_retriever_spec.rb +17 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/support/view_component_test_helpers.rb +14 -0
- data/spec/test_app_templates/Gemfile.extra +0 -1
- data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -0
- data/template.demo.rb +7 -7
- metadata +15 -21
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"blacklight.esm.js","sources":["../../../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/core.js","../../../javascript/blacklight/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 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 CheckboxSubmit from 'blacklight/checkbox_submit'\n\nconst BookmarkToggle = (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\ndocument.addEventListener('click', BookmarkToggle);\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-toggle=\"collapse\"]') || e.target.matches('[data-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\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-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*/\nimport ModalForm from 'blacklight/modalForm'\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 close\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\" class=\"visually-hidden\">×</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.url}\\n${error}</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.\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 if (elements.length == 0) {\n // If the containerSelector wasn't found, use the whole document\n elements = dom.body.childNodes\n }\n\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.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n };\n\n modal.hide = function (el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (!dom.open) return\n dom.close()\n }\n\n modal.show = function(el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (dom.open) return\n dom.showModal()\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n if (e.target.matches('[data-context-href]')) {\n SearchContext.handleSearchContextMethod.call(e.target, 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 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 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","import BookmarkToggle from 'blacklight/bookmark_toggle'\nimport ButtonFocus from 'blacklight/button_focus'\nimport Modal from 'blacklight/modal'\nimport SearchContext from 'blacklight/search_context'\nimport Core from 'blacklight/core'\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":["Core"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"blacklight.esm.js","sources":["../../../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/core.js","../../../javascript/blacklight/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 4.\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 this.updateStateFor(!this.checked)\n document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count\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 handleError() {\n alert(\"Unable to save the bookmark at this time.\")\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 CheckboxSubmit from './checkbox_submit.js'\n\nconst BookmarkToggle = (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\ndocument.addEventListener('click', BookmarkToggle);\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-toggle=\"collapse\"]') || e.target.matches('[data-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\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-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*/\nimport ModalForm from './modalForm.js'\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 close\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\" class=\"visually-hidden\">×</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.url}\\n${error}</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.\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 document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(frag)\n\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.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.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n };\n\n modal.hide = function (el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (!dom.open) return\n dom.close()\n }\n\n modal.show = function(el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (dom.open) return\n dom.showModal()\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n if (e.target.matches('[data-context-href]')) {\n SearchContext.handleSearchContextMethod.call(e.target, 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 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","// ALL imports in this dir, including in files imported, should be RELATIVE\n// paths to keep things working in the various ways these files get used, at\n// both compile time and npm package run time.\n\nimport BookmarkToggle from './bookmark_toggle.js'\nimport ButtonFocus from './button_focus.js'\nimport Modal from './modal.js'\nimport SearchContext from './search_context.js'\nimport Core from './core.js'\n\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":["Core"],"mappings":"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"}
|
@@ -24,11 +24,11 @@
|
|
24
24
|
this.form = form;
|
25
25
|
}
|
26
26
|
|
27
|
-
|
27
|
+
clicked(evt) {
|
28
28
|
this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress');
|
29
29
|
this.labelTarget.setAttribute('disabled', 'disabled');
|
30
30
|
this.checkboxTarget.setAttribute('disabled', 'disabled');
|
31
|
-
|
31
|
+
fetch(this.formTarget.getAttribute('action'), {
|
32
32
|
body: new FormData(this.formTarget),
|
33
33
|
method: this.formTarget.getAttribute('method').toUpperCase(),
|
34
34
|
headers: {
|
@@ -36,16 +36,17 @@
|
|
36
36
|
'X-Requested-With': 'XMLHttpRequest',
|
37
37
|
'X-CSRF-Token': document.querySelector('meta[name=csrf-token]')?.content
|
38
38
|
}
|
39
|
-
})
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
}).then((response) => {
|
40
|
+
if (response.ok) return response.json();
|
41
|
+
return Promise.reject('response was not ok')
|
42
|
+
}).then((json) => {
|
43
|
+
this.labelTarget.removeAttribute('disabled');
|
44
|
+
this.checkboxTarget.removeAttribute('disabled');
|
44
45
|
this.updateStateFor(!this.checked);
|
45
46
|
document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count;
|
46
|
-
}
|
47
|
-
|
48
|
-
}
|
47
|
+
}).catch((error) => {
|
48
|
+
this.handleError(error);
|
49
|
+
});
|
49
50
|
}
|
50
51
|
|
51
52
|
get checked() {
|
@@ -68,6 +69,10 @@
|
|
68
69
|
return this.form.querySelector('[data-checkboxsubmit-target="span"]')
|
69
70
|
}
|
70
71
|
|
72
|
+
handleError() {
|
73
|
+
alert("Unable to save the bookmark at this time.");
|
74
|
+
}
|
75
|
+
|
71
76
|
updateStateFor(state) {
|
72
77
|
this.checkboxTarget.checked = state;
|
73
78
|
|
@@ -203,21 +208,35 @@
|
|
203
208
|
};
|
204
209
|
|
205
210
|
// Add the passed in contents to the modal and display it.
|
211
|
+
// We have specific handling so that scripts returned from the ajax call are executed.
|
212
|
+
// This enables adding a script like recaptcha to prevent bots from sending emails.
|
206
213
|
modal.receiveAjax = function (contents) {
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
214
|
+
const domparser = new DOMParser();
|
215
|
+
const dom = domparser.parseFromString(contents, "text/html");
|
216
|
+
// If there is a containerSelector on the document, use its children.
|
217
|
+
let elements = dom.querySelectorAll(`${modal.containerSelector} > *`);
|
218
|
+
const frag = document.createDocumentFragment();
|
219
|
+
if (elements.length == 0) {
|
220
|
+
// If the containerSelector wasn't found, use the whole document
|
221
|
+
elements = dom.body.childNodes;
|
222
|
+
}
|
223
|
+
elements.forEach((el) => frag.appendChild(el));
|
224
|
+
modal.activateScripts(frag);
|
225
|
+
|
226
|
+
document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(frag);
|
217
227
|
|
218
|
-
|
228
|
+
modal.show();
|
219
229
|
};
|
220
230
|
|
231
|
+
// DOMParser doesn't allow scripts to be executed. This fixes that.
|
232
|
+
modal.activateScripts = function (frag) {
|
233
|
+
frag.querySelectorAll('script').forEach((script) => {
|
234
|
+
const fixedScript = document.createElement('script');
|
235
|
+
fixedScript.src = script.src;
|
236
|
+
fixedScript.async = false;
|
237
|
+
script.parentNode.replaceChild(fixedScript, script);
|
238
|
+
});
|
239
|
+
};
|
221
240
|
|
222
241
|
modal.modalAjaxLinkClick = function(e) {
|
223
242
|
e.preventDefault();
|
@@ -293,6 +312,7 @@
|
|
293
312
|
|
294
313
|
// check for meta keys.. if set, we should open in a new tab
|
295
314
|
if(event.metaKey || event.ctrlKey) {
|
315
|
+
form.dataset.turbo = "false";
|
296
316
|
target = '_blank';
|
297
317
|
}
|
298
318
|
|
@@ -369,6 +389,9 @@
|
|
369
389
|
elem.classList.add('js');
|
370
390
|
});
|
371
391
|
|
392
|
+
// ALL imports in this dir, including in files imported, should be RELATIVE
|
393
|
+
|
394
|
+
|
372
395
|
const index = {
|
373
396
|
BookmarkToggle,
|
374
397
|
ButtonFocus,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"blacklight.js","sources":["../../../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/core.js","../../../javascript/blacklight/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 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 CheckboxSubmit from 'blacklight/checkbox_submit'\n\nconst BookmarkToggle = (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\ndocument.addEventListener('click', BookmarkToggle);\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-toggle=\"collapse\"]') || e.target.matches('[data-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\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-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*/\nimport ModalForm from 'blacklight/modalForm'\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 close\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\" class=\"visually-hidden\">×</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.url}\\n${error}</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.\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 if (elements.length == 0) {\n // If the containerSelector wasn't found, use the whole document\n elements = dom.body.childNodes\n }\n\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.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n };\n\n modal.hide = function (el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (!dom.open) return\n dom.close()\n }\n\n modal.show = function(el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (dom.open) return\n dom.showModal()\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n if (e.target.matches('[data-context-href]')) {\n SearchContext.handleSearchContextMethod.call(e.target, 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 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 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","import BookmarkToggle from 'blacklight/bookmark_toggle'\nimport ButtonFocus from 'blacklight/button_focus'\nimport Modal from 'blacklight/modal'\nimport SearchContext from 'blacklight/search_context'\nimport Core from 'blacklight/core'\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":["Core"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"blacklight.js","sources":["../../../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/core.js","../../../javascript/blacklight/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 4.\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 this.updateStateFor(!this.checked)\n document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count\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 handleError() {\n alert(\"Unable to save the bookmark at this time.\")\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 CheckboxSubmit from './checkbox_submit.js'\n\nconst BookmarkToggle = (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\ndocument.addEventListener('click', BookmarkToggle);\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-toggle=\"collapse\"]') || e.target.matches('[data-bs-toggle=\"collapse\"]')) {\n e.target.focus()\n }\n}\n\ndocument.addEventListener('click', ButtonFocus)\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-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*/\nimport ModalForm from './modalForm.js'\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 close\" data-bl-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\" class=\"visually-hidden\">×</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.url}\\n${error}</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.\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 document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(frag)\n\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.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.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))\n modal.modalAjaxLinkClick(e)\n else if (e.target.closest('[data-bl-dismiss=\"modal\"]'))\n modal.hide()\n })\n };\n\n modal.hide = function (el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (!dom.open) return\n dom.close()\n }\n\n modal.show = function(el) {\n const dom = document.querySelector(modal.modalSelector)\n\n if (dom.open) return\n dom.showModal()\n }\n\n modal.setupModal()\n\n return modal;\n})()\n\nexport default Modal\n","const SearchContext = (e) => {\n if (e.target.matches('[data-context-href]')) {\n SearchContext.handleSearchContextMethod.call(e.target, 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 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","// ALL imports in this dir, including in files imported, should be RELATIVE\n// paths to keep things working in the various ways these files get used, at\n// both compile time and npm package run time.\n\nimport BookmarkToggle from './bookmark_toggle.js'\nimport ButtonFocus from './button_focus.js'\nimport Modal from './modal.js'\nimport SearchContext from './search_context.js'\nimport Core from './core.js'\n\n\nexport default {\n BookmarkToggle,\n ButtonFocus,\n Modal,\n SearchContext,\n Core,\n onLoad: Core.onLoad\n}\n"],"names":["Core"],"mappings":"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"}
|
@@ -15,7 +15,7 @@
|
|
15
15
|
}
|
16
16
|
|
17
17
|
// define a visually-hidden class that applies to a given breakpoint and below
|
18
|
-
// https://getbootstrap.com/docs/5.
|
18
|
+
// https://getbootstrap.com/docs/5.3/helpers/visually-hidden/
|
19
19
|
@if mixin-exists(visually-hidden) {
|
20
20
|
@each $infix, $breakpoint in $grid-breakpoints {
|
21
21
|
.visually-hidden-#{$infix} {
|
@@ -20,7 +20,7 @@ module Blacklight
|
|
20
20
|
|
21
21
|
# Define a simple action handler for the tool as long as the method
|
22
22
|
# doesn't already exist or the `:define_method` option is not `false`
|
23
|
-
def build
|
23
|
+
def build # rubocop:disable Metrics/MethodLength
|
24
24
|
return if skip?
|
25
25
|
|
26
26
|
callback = opts.fetch(:callback, nil).inspect
|
@@ -40,8 +40,8 @@
|
|
40
40
|
|
41
41
|
<% if sort_fields_select %>
|
42
42
|
<div class="form-group row mb-4">
|
43
|
-
<%= content_tag :h2, t('blacklight.advanced_search.form.sort_label'), class: 'col-md-3
|
44
|
-
<div class="col">
|
43
|
+
<%= content_tag :h2, t('blacklight.advanced_search.form.sort_label'), id: 'advanced-search-sort-label', class: 'col-md-3 text-md-right' %>
|
44
|
+
<div class="col-md-9">
|
45
45
|
<%= sort_fields_select %>
|
46
46
|
</div>
|
47
47
|
</div>
|
@@ -50,7 +50,7 @@
|
|
50
50
|
<div class="form-group row">
|
51
51
|
<div class="submit-buttons col-md-9 offset-md-3">
|
52
52
|
<%= submit_tag t('blacklight.advanced_search.form.search_btn_html'), class: 'btn btn-primary advanced-search-submit', id: "advanced-search-submit" %>
|
53
|
-
<%=
|
53
|
+
<%= link_to t('blacklight.advanced_search.form.start_over_html'), request.path, :class =>"btn btn-link advanced-search-start-over" %>
|
54
54
|
</div>
|
55
55
|
</div>
|
56
56
|
<% end %>
|
@@ -24,14 +24,14 @@ module Blacklight
|
|
24
24
|
|
25
25
|
def default_operator_menu
|
26
26
|
options_with_labels = [:must, :should].index_by { |op| t(op, scope: 'blacklight.advanced_search.op') }
|
27
|
-
select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
|
27
|
+
label_tag(:op, t('blacklight.advanced_search.op.label'), class: 'sr-only visually-hidden') + select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
|
28
28
|
end
|
29
29
|
|
30
30
|
def sort_fields_select
|
31
31
|
options = sort_fields.values.map { |field_config| [helpers.sort_field_label(field_config.key), field_config.key] }
|
32
32
|
return unless options.any?
|
33
33
|
|
34
|
-
select_tag(:sort, options_for_select(options, params[:sort]), class: "form-select custom-select sort-select w-auto")
|
34
|
+
select_tag(:sort, options_for_select(options, params[:sort]), class: "form-select custom-select sort-select w-auto", aria: { labelledby: 'advanced-search-sort-label' })
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
@@ -55,7 +55,7 @@ module Blacklight
|
|
55
55
|
def initialize_search_filter_controls
|
56
56
|
fields = blacklight_config.facet_fields.select { |_k, v| v.include_in_advanced_search || v.include_in_advanced_search.nil? }
|
57
57
|
|
58
|
-
fields.
|
58
|
+
fields.each_value do |config|
|
59
59
|
display_facet = @response.aggregations[config.field]
|
60
60
|
with_search_filter_control(config: config, display_facet: display_facet)
|
61
61
|
end
|
@@ -1,13 +1,9 @@
|
|
1
|
-
<%-
|
2
|
-
# the data-doc-id attribute is used by our JS that converts to a checkbox/label.
|
3
|
-
# we don't use the per-form csrf token
|
4
|
-
-%>
|
1
|
+
<%- # we don't use the per-form csrf token -%>
|
5
2
|
<%= form_tag(bookmark_path,
|
6
3
|
authenticity_token: false,
|
7
4
|
method: bookmarked? ? :delete : :put,
|
8
5
|
class: "bookmark-toggle",
|
9
6
|
data: {
|
10
|
-
'doc-id' => @document.id,
|
11
7
|
present: t('blacklight.search.bookmarks.present'),
|
12
8
|
absent: t('blacklight.search.bookmarks.absent'),
|
13
9
|
inprogress: t('blacklight.search.bookmarks.inprogress')
|
@@ -20,6 +16,5 @@
|
|
20
16
|
</div>
|
21
17
|
|
22
18
|
<%= submit_tag(t(bookmarked? ? 'remove.button' : 'add.button', scope: 'blacklight.bookmarks'),
|
23
|
-
id: "bookmark_toggle_#{@document.id.to_s.parameterize}",
|
24
19
|
class: "bookmark-#{bookmarked? ? 'remove' : 'add'} btn btn-outline-secondary") %>
|
25
20
|
<% end %>
|
@@ -8,11 +8,12 @@
|
|
8
8
|
data-target="#<%= html_id %>"
|
9
9
|
data-bs-target="#<%= html_id %>"
|
10
10
|
aria-expanded="<%= @facet_field.collapsed? ? 'false' : 'true' %>"
|
11
|
+
arial-controls="<%= html_id %>"
|
11
12
|
>
|
12
13
|
<%= label %>
|
13
14
|
</button>
|
14
15
|
</h3>
|
15
|
-
<div id="<%= html_id %>" aria-labelledby="<%= header_html_id %>" class="panel-collapse facet-content collapse <%= "show" unless @facet_field.collapsed? %>">
|
16
|
+
<div id="<%= html_id %>" role="region" aria-labelledby="<%= header_html_id %>" class="panel-collapse facet-content collapse <%= "show" unless @facet_field.collapsed? %>">
|
16
17
|
<div class="card-body">
|
17
18
|
<%= body %>
|
18
19
|
|
@@ -11,7 +11,7 @@ module Blacklight
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call
|
14
|
-
tag.span(svg&.html_safe || default_icon,
|
14
|
+
tag.span(svg&.html_safe || default_icon, # rubocop:disable Rails/OutputSafety
|
15
15
|
class: "blacklight-icons blacklight-icon-#{@name} #{@classes}".strip,
|
16
16
|
'aria-hidden': (true if @aria_hidden))
|
17
17
|
end
|
@@ -15,7 +15,6 @@
|
|
15
15
|
aria: {
|
16
16
|
controls: @panel_id,
|
17
17
|
expanded: 'false',
|
18
|
-
label: t('blacklight.search.facets.group.toggle'),
|
19
18
|
} do %>
|
20
19
|
<span data-show-label><%= t('blacklight.search.facets.group.open') %></span>
|
21
20
|
<span data-hide-label><%= t('blacklight.search.facets.group.close') %></span>
|
@@ -17,7 +17,12 @@ module Blacklight
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def pagination
|
20
|
-
|
20
|
+
args = configured_options.merge(@pagination_args).compact
|
21
|
+
helpers.paginate @response, **args
|
22
|
+
end
|
23
|
+
|
24
|
+
def configured_options
|
25
|
+
controller.blacklight_config.index.pagination_options
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= form_with url: @url, local: true, method: @method, class: @classes.join(' '), scope: @prefix, role: 'search',
|
1
|
+
<%= form_with url: @url, local: true, method: @method, class: @classes.join(' '), scope: @prefix, role: 'search', **@form_options do |f| %>
|
2
2
|
<%= render Blacklight::HiddenSearchStateComponent.new(params: @params) %>
|
3
3
|
<% if search_fields.length > 1 %>
|
4
4
|
<%= f.label :search_field, scoped_t('search_field.label'), class: 'sr-only visually-hidden' %>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<% if autocomplete_path.present? %>
|
24
24
|
<auto-complete src="<%= autocomplete_path %>" for="autocomplete-popup" class="search-autocomplete-wrapper">
|
25
25
|
<%= f.search_field @query_param, value: @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control rounded-#{search_fields.length > 1 ? '0' : 'left'}", autofocus: @autofocus, aria: { label: scoped_t('search.label'), autocomplete: 'list', controls: 'autocomplete-popup' } %>
|
26
|
-
<ul id="autocomplete-popup" role="listbox" aria-label="<%= scoped_t('search.label') %>"></ul>
|
26
|
+
<ul id="autocomplete-popup" role="listbox" aria-label="<%= scoped_t('search.label') %>" hidden></ul>
|
27
27
|
</auto-complete>
|
28
28
|
<% else %>
|
29
29
|
<%= f.search_field @query_param, value: @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control rounded-#{search_fields.length > 1 ? '0' : 'left'}", autofocus: @autofocus, aria: { label: scoped_t('search.label') } %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="alert <%= @classes %>">
|
2
2
|
<%= message %>
|
3
|
-
<%= tag.
|
3
|
+
<%= tag.button button_contents, type: "button", class: "btn-close",
|
4
4
|
data: { dismiss: "alert", bs_dismiss: "alert" },
|
5
5
|
aria: { label: "Close" } %>
|
6
6
|
</div>
|
@@ -86,7 +86,7 @@ module Blacklight::Bookmarks
|
|
86
86
|
end
|
87
87
|
|
88
88
|
if request.xhr?
|
89
|
-
success ? render(json: { bookmarks: { count: current_or_guest_user.bookmarks.count } }) : render(json: current_or_guest_user.errors.full_messages, status:
|
89
|
+
success ? render(json: { bookmarks: { count: current_or_guest_user.bookmarks.count } }) : render(json: current_or_guest_user.errors.full_messages, status: :internal_server_error)
|
90
90
|
else
|
91
91
|
if @bookmarks.any? && success
|
92
92
|
flash[:notice] = I18n.t('blacklight.bookmarks.add.success', count: @bookmarks.length)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# A controller mixin that allows users to share their bookmarks.
|
4
|
+
# This is used to create a callback from refworks in the bookmarks_export_url helper in blacklight-marc
|
3
5
|
module Blacklight::TokenBasedUser
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
@@ -45,34 +47,18 @@ module Blacklight::TokenBasedUser
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def export_secret_token
|
48
|
-
secret_key_generator.generate_key('encrypted user session key'
|
50
|
+
secret_key_generator.generate_key('encrypted user session key', key_len)
|
49
51
|
end
|
50
52
|
|
51
53
|
def secret_key_generator
|
52
|
-
@secret_key_generator ||=
|
53
|
-
app = Rails.application
|
54
|
-
|
55
|
-
secret_key_base = if app.respond_to?(:credentials)
|
56
|
-
# Rails 5.2+
|
57
|
-
app.credentials.secret_key_base
|
58
|
-
else
|
59
|
-
# Rails <= 5.1
|
60
|
-
app.secrets.secret_key_base
|
61
|
-
end
|
62
|
-
ActiveSupport::KeyGenerator.new(secret_key_base)
|
63
|
-
end
|
54
|
+
@secret_key_generator ||= ActiveSupport::KeyGenerator.new(Rails.application.secret_key_base)
|
64
55
|
end
|
65
56
|
|
66
57
|
def message_encryptor
|
67
58
|
ActiveSupport::MessageEncryptor.new(export_secret_token)
|
68
59
|
end
|
69
60
|
|
70
|
-
# Ruby 2.4 requires keys of very particular lengths
|
71
61
|
def key_len
|
72
|
-
|
73
|
-
ActiveSupport::MessageEncryptor.key_len
|
74
|
-
else
|
75
|
-
0
|
76
|
-
end
|
62
|
+
ActiveSupport::MessageEncryptor.key_len
|
77
63
|
end
|
78
64
|
end
|
@@ -36,7 +36,8 @@ module Blacklight::UrlHelperBehavior
|
|
36
36
|
private :document_link_params
|
37
37
|
|
38
38
|
##
|
39
|
-
# Attributes for a link that gives a URL we can use to track clicks for the current search session
|
39
|
+
# Attributes for a link that gives a URL we can use to track clicks for the current search session.
|
40
|
+
# We disable turbo prefetch (InstantClick), because since we replace the link with a form, it's just wasted.
|
40
41
|
# @param [SolrDocument] document
|
41
42
|
# @param [Integer] counter
|
42
43
|
# @example
|
@@ -52,7 +53,7 @@ module Blacklight::UrlHelperBehavior
|
|
52
53
|
return {} if path.nil?
|
53
54
|
|
54
55
|
context_method = blacklight_config.track_search_session.storage == 'client' ? 'get' : 'post'
|
55
|
-
{ data: { context_href: path, context_method: context_method } }
|
56
|
+
{ data: { context_href: path, context_method: context_method, turbo_prefetch: false } }
|
56
57
|
end
|
57
58
|
|
58
59
|
##
|