blacklight 7.18.1 → 7.20.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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -1
  3. data/.github/workflows/ruby.yml +19 -1
  4. data/.rubocop.yml +4 -0
  5. data/README.md +1 -1
  6. data/VERSION +1 -1
  7. data/app/assets/javascripts/blacklight/blacklight.js +8 -4
  8. data/app/assets/stylesheets/blacklight/_balanced_list.scss +2 -2
  9. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +1 -1
  10. data/app/assets/stylesheets/blacklight/_constraints.scss +8 -5
  11. data/app/assets/stylesheets/blacklight/_controls.scss +9 -1
  12. data/app/assets/stylesheets/blacklight/_facets.scss +5 -3
  13. data/app/assets/stylesheets/blacklight/_header.scss +6 -1
  14. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -1
  15. data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +1 -0
  16. data/app/components/blacklight/constraint_layout_component.html.erb +1 -1
  17. data/app/components/blacklight/constraints_component.html.erb +2 -2
  18. data/app/components/blacklight/constraints_component.rb +6 -2
  19. data/app/components/blacklight/content_areas_shim.rb +2 -1
  20. data/app/components/blacklight/document_component.rb +10 -10
  21. data/app/components/blacklight/facet_field_component.html.erb +3 -1
  22. data/app/components/blacklight/facet_field_no_layout_component.rb +1 -1
  23. data/app/components/blacklight/facet_item_component.rb +4 -4
  24. data/app/components/blacklight/facet_item_pivot_component.rb +2 -2
  25. data/app/components/blacklight/metadata_field_layout_component.rb +2 -2
  26. data/app/components/blacklight/response/facet_group_component.html.erb +2 -0
  27. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  28. data/app/components/blacklight/response/view_type_component.html.erb +1 -1
  29. data/app/components/blacklight/search_bar_component.html.erb +3 -3
  30. data/app/components/blacklight/system/dropdown_component.rb +1 -1
  31. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  32. data/app/components/blacklight/system/modal_component.html.erb +1 -1
  33. data/app/controllers/concerns/blacklight/bookmarks.rb +0 -3
  34. data/app/controllers/concerns/blacklight/catalog.rb +3 -0
  35. data/app/controllers/concerns/blacklight/controller.rb +9 -5
  36. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  37. data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -3
  38. data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
  39. data/app/helpers/blacklight/render_partials_helper_behavior.rb +5 -1
  40. data/app/javascript/blacklight/core.js +5 -1
  41. data/app/javascript/blacklight/modal.js +1 -1
  42. data/app/javascript/blacklight/search_context.js +5 -2
  43. data/app/views/blacklight/nav/_bookmark.html.erb +1 -1
  44. data/app/views/bookmarks/index.html.erb +1 -1
  45. data/app/views/catalog/_constraints.html.erb +2 -2
  46. data/app/views/catalog/_document.html.erb +4 -3
  47. data/app/views/catalog/_document_list.html.erb +3 -2
  48. data/app/views/catalog/_home_text.html.erb +3 -3
  49. data/app/views/catalog/_paginate_compact.html.erb +1 -0
  50. data/app/views/catalog/_per_page_widget.html.erb +1 -1
  51. data/app/views/catalog/_search_results.html.erb +2 -2
  52. data/app/views/search_history/index.html.erb +1 -1
  53. data/app/views/shared/_header_navbar.html.erb +3 -3
  54. data/blacklight.gemspec +4 -2
  55. data/config/locales/blacklight.ar.yml +2 -2
  56. data/config/locales/blacklight.ca.yml +2 -2
  57. data/config/locales/blacklight.de.yml +6 -4
  58. data/config/locales/blacklight.en.yml +8 -4
  59. data/config/locales/blacklight.es.yml +5 -3
  60. data/config/locales/blacklight.fr.yml +5 -3
  61. data/config/locales/blacklight.hu.yml +2 -2
  62. data/config/locales/blacklight.it.yml +5 -3
  63. data/config/locales/blacklight.nl.yml +2 -2
  64. data/config/locales/blacklight.pt-BR.yml +1 -1
  65. data/config/locales/blacklight.sq.yml +2 -2
  66. data/config/locales/blacklight.zh.yml +2 -2
  67. data/lib/blacklight/configuration/view_config.rb +3 -1
  68. data/lib/blacklight/configuration.rb +7 -1
  69. data/lib/blacklight/nested_open_struct_with_hash_access.rb +14 -11
  70. data/lib/blacklight/open_struct_with_hash_access.rb +1 -1
  71. data/lib/blacklight/search_builder.rb +1 -1
  72. data/lib/blacklight/search_state/filter_field.rb +9 -0
  73. data/lib/blacklight/solr/request.rb +10 -7
  74. data/lib/blacklight/solr/response/group_response.rb +3 -2
  75. data/lib/blacklight/solr/response/pagination_methods.rb +1 -1
  76. data/lib/blacklight/solr/search_builder_behavior.rb +38 -18
  77. data/lib/blacklight.rb +5 -1
  78. data/lib/generators/blacklight/assets_generator.rb +4 -2
  79. data/lib/generators/blacklight/install_generator.rb +4 -1
  80. data/lib/generators/blacklight/user_generator.rb +1 -1
  81. data/package.json +2 -2
  82. data/spec/components/blacklight/constraint_layout_component_spec.rb +3 -7
  83. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +3 -7
  84. data/spec/components/blacklight/facet_field_list_component_spec.rb +3 -7
  85. data/spec/components/blacklight/facet_item_component_spec.rb +8 -8
  86. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +3 -7
  87. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -8
  88. data/spec/components/blacklight/metadata_field_component_spec.rb +4 -8
  89. data/spec/features/axe_spec.rb +34 -0
  90. data/spec/features/facet_missing_spec.rb +59 -0
  91. data/spec/features/facets_spec.rb +3 -3
  92. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +3 -3
  93. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
  94. data/spec/helpers/blacklight_helper_spec.rb +18 -0
  95. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +23 -1
  96. data/spec/lib/blacklight/search_state/filter_field_spec.rb +27 -0
  97. data/spec/models/blacklight/configuration_spec.rb +10 -0
  98. data/spec/models/blacklight/solr/request_spec.rb +0 -1
  99. data/spec/models/blacklight/solr/response/group_response_spec.rb +3 -2
  100. data/spec/models/blacklight/solr/search_builder_spec.rb +27 -1
  101. data/spec/spec_helper.rb +16 -9
  102. data/spec/support/view_component_capybara_test_helpers.rb +8 -0
  103. data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -3
  104. data/spec/views/catalog/_document.html.erb_spec.rb +9 -0
  105. data/spec/views/catalog/_document_list.html.erb_spec.rb +1 -1
  106. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +2 -2
  107. metadata +45 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a5a489af479cba41b095c127d35112702c19436855e558a727b9b6667455d2d
4
- data.tar.gz: 199b0847364f2f8c5d5d2fd2cd86d0d969b1a802144127df77141f42da97a316
3
+ metadata.gz: 514bb2df051f28fda2f7b1a2f4b309bd20cf79843dbaa74b519232543f36bc70
4
+ data.tar.gz: 0bbb3de22863a1e3b9e0aa55d0b9e501550f955fcc2630685e78572b7baf3d05
5
5
  SHA512:
6
- metadata.gz: d900379c48b0118bc87a6711989cce5cafb84fc13e4fae4c300ea9d1ec34278634fe69195179231c5c167f01170b95b493171d668e21a37bf4cf7b2e40301f3e
7
- data.tar.gz: '089e1155d4a910bdc6657775cc5c4e8e0cc27b02307f36c15123f92cb55429d958d987ed202ff8a0ec9022cfc371ab0b8a769908c549ec784b11e956c25e00ba'
6
+ metadata.gz: c8a023e934c9d2b1365f71104047b53d60d51073f53fecf80d8e159a66edf9dbb5148db8be095b522d04e9d5939cf623fe824fa9607bfc6ed123c3e5cb08dfb7
7
+ data.tar.gz: e04a8a63ca946e9d31696ecc76c8da4fca3495687174dba352f613f64388a7802df446d2c902507d99f767b163acea71d2dd021f90f60f2aebe97ae8b115e0d4
data/.env CHANGED
@@ -1,5 +1,5 @@
1
1
  ALPINE_RUBY_VERSION=2.6.5
2
- RAILS_VERSION=5.2.4.1
2
+ RAILS_VERSION=5.2.5
3
3
  SOLR_PORT=8983
4
4
  SOLR_URL=http://solr:8983/solr/blacklight-core
5
5
  SOLR_VERSION=latest
@@ -43,6 +43,24 @@ jobs:
43
43
  run: bundle exec rake ci
44
44
  env:
45
45
  ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
46
+ test_bootstrap5:
47
+ runs-on: ubuntu-latest
48
+ strategy:
49
+ matrix:
50
+ ruby: [3.0]
51
+ steps:
52
+ - uses: actions/checkout@v2
53
+ - name: Set up Ruby
54
+ uses: ruby/setup-ruby@v1
55
+ with:
56
+ ruby-version: ${{ matrix.ruby }}
57
+ - name: Install dependencies
58
+ run: bundle install
59
+ - name: Run tests
60
+ run: bundle exec rake ci
61
+ env:
62
+ BOOTSTRAP_VERSION: '~> 5.0'
63
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
46
64
  test_rails6_0:
47
65
  runs-on: ubuntu-latest
48
66
  strategy:
@@ -87,7 +105,7 @@ jobs:
87
105
  runs-on: ubuntu-latest
88
106
  strategy:
89
107
  matrix:
90
- ruby: [2.7]
108
+ ruby: [2.7, 3.0]
91
109
  steps:
92
110
  - uses: actions/checkout@v2
93
111
  - name: Set up Ruby
data/.rubocop.yml CHANGED
@@ -50,6 +50,10 @@ Metrics/ModuleLength:
50
50
  - 'app/controllers/concerns/blacklight/catalog.rb'
51
51
  - 'lib/blacklight/solr/search_builder_behavior.rb'
52
52
 
53
+ Metrics/AbcSize:
54
+ Exclude:
55
+ - "lib/blacklight/search_state/filter_field.rb"
56
+
53
57
  Naming/HeredocDelimiterNaming:
54
58
  Enabled: false
55
59
 
data/README.md CHANGED
@@ -35,7 +35,7 @@ rails generate blacklight:install
35
35
 
36
36
  * Ruby 2.2+
37
37
  * Bundler
38
- * Rails 5.1+
38
+ * Rails 5.2+
39
39
 
40
40
  ## Contributing Code
41
41
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.18.1
1
+ 7.20.0
@@ -36,7 +36,11 @@ Blacklight.listeners().forEach(function (listener) {
36
36
  Blacklight.activate();
37
37
  });
38
38
  });
39
- $('.no-js').removeClass('no-js').addClass('js');
39
+ Blacklight.onLoad(function () {
40
+ const elem = document.querySelector('.no-js');
41
+ elem.classList.remove('no-js');
42
+ elem.classList.add('js');
43
+ });
40
44
  /*global Bloodhound */
41
45
 
42
46
  Blacklight.onLoad(function () {
@@ -352,7 +356,7 @@ Blacklight.modal.modalCloseSelector = '[data-blacklight-modal~=close]'; // Calle
352
356
 
353
357
  Blacklight.modal.onFailure = function (jqXHR, textStatus, errorThrown) {
354
358
  console.error('Server error:', this.url, jqXHR.status, errorThrown);
355
- var contents = '<div class="modal-header">' + '<div class="modal-title">There was a problem with your request.</div>' + '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button></div>' + ' <div class="modal-body"><p>Expected a successful response from the server, but got an error</p>' + '<pre>' + this.type + ' ' + this.url + "\n" + jqXHR.status + ': ' + errorThrown + '</pre></div>';
359
+ var contents = '<div class="modal-header">' + '<div class="modal-title">There was a problem with your request.</div>' + '<button type="button" class="blacklight-modal-close btn-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button></div>' + ' <div class="modal-body"><p>Expected a successful response from the server, but got an error</p>' + '<pre>' + this.type + ' ' + this.url + "\n" + jqXHR.status + ': ' + errorThrown + '</pre></div>';
356
360
  $(Blacklight.modal.modalSelector).find('.modal-content').html(contents);
357
361
  $(Blacklight.modal.modalSelector).modal('show');
358
362
  };
@@ -460,8 +464,8 @@ Blacklight.handleSearchContextMethod = function (event) {
460
464
 
461
465
  let href = link.getAttribute('data-context-href');
462
466
  let target = link.getAttribute('target');
463
- let csrfToken = Rails.csrfToken();
464
- let csrfParam = Rails.csrfParam();
467
+ let csrfToken = document.querySelector('meta[name=csrf-token]')?.content
468
+ let csrfParam = document.querySelector('meta[name=csrf-param]')?.content
465
469
  let form = document.createElement('form');
466
470
  form.method = 'post';
467
471
  form.action = href;
@@ -2,11 +2,11 @@
2
2
  dt {
3
3
  font-weight: normal;
4
4
  color: $field_name_color;
5
- @media (max-width: breakpoint-max(sm)) {
5
+ @media (max-width: breakpoint-min(md)) {
6
6
  text-align: left;
7
7
  }
8
8
 
9
- @media (min-width: breakpoint-max(sm)) {
9
+ @media (min-width: breakpoint-min(md)) {
10
10
  text-align: right;
11
11
  }
12
12
  }
@@ -5,7 +5,7 @@
5
5
  // Facet field headings and buttons
6
6
  .facet-field-heading {
7
7
  border-bottom: 0;
8
-
8
+
9
9
  button {
10
10
  font-weight: $headings-font-weight;
11
11
 
@@ -1,27 +1,30 @@
1
1
  .constraints-container {
2
2
  @extend .mb-2;
3
+ @extend .d-flex;
3
4
  }
4
5
 
5
6
  .applied-filter {
7
+ @extend .mx-1;
8
+
6
9
  .constraint-value {
7
10
  cursor: default;
8
11
  text-overflow: ellipsis;
9
12
  overflow: hidden;
10
13
 
11
- @media (max-width: breakpoint-max(xs)) {
12
- max-width: breakpoint-max(xs) / 2;
14
+ @media (max-width: breakpoint-min(sm)) {
15
+ max-width: breakpoint-min(sm) * .5;
13
16
  }
14
17
 
15
18
  @media (min-width: breakpoint-min(sm)) and (max-width: breakpoint-max(sm)) {
16
- max-width: breakpoint-min(sm) / 2;
19
+ max-width: breakpoint-min(sm) * .5;
17
20
  }
18
21
 
19
22
  @media (min-width: breakpoint-min(md)) and (max-width: breakpoint-max(md)) {
20
- max-width: breakpoint-min(md) / 2;
23
+ max-width: breakpoint-min(md) * .5;
21
24
  }
22
25
 
23
26
  @media (min-width: breakpoint-min(lg)) {
24
- max-width: breakpoint-min(lg) / 2;
27
+ max-width: breakpoint-min(lg) * .5;
25
28
  }
26
29
 
27
30
  &:hover, &:active {
@@ -1,3 +1,10 @@
1
+ .search-widgets {
2
+ @extend .d-flex;
3
+ > * {
4
+ @extend .mx-1;
5
+ }
6
+ }
7
+
1
8
  .sort-pagination,
2
9
  .pagination-search-widgets {
3
10
  border-bottom: $pagination-border-width solid $pagination-border-color;
@@ -34,7 +41,8 @@
34
41
  display: inline-block;
35
42
 
36
43
  .caption {
37
- @extend .sr-only;
44
+ @extend .sr-only !optional;
45
+ @extend .visually-hidden !optional;
38
46
  }
39
47
  }
40
48
 
@@ -3,7 +3,8 @@
3
3
  border-color: $navbar-light-toggler-border-color;
4
4
  color: $navbar-light-active-color;
5
5
 
6
- @include hover-focus {
6
+ &:hover,
7
+ &:focus {
7
8
  color: $navbar-light-active-color;
8
9
  }
9
10
  }
@@ -82,7 +83,8 @@
82
83
  .remove {
83
84
  color: $text-muted;
84
85
  font-weight: bold;
85
- padding-left: $spacer / 2;
86
+ padding-left: $spacer * .5;
87
+ text-decoration: none;
86
88
 
87
89
  &:hover {
88
90
  color: theme-color("danger");
@@ -102,7 +104,7 @@
102
104
  padding-right: 1em;
103
105
  text-indent: -15px;
104
106
  padding-left: 15px;
105
- padding-bottom: $spacer / 2;
107
+ padding-bottom: $spacer * .5;
106
108
  @include hyphens-auto;
107
109
  }
108
110
 
@@ -44,7 +44,12 @@
44
44
  .submit-search-text {
45
45
  // hide 'search' label at very small screens
46
46
  @media screen and (max-width: breakpoint-max(xs)) {
47
- @include sr-only();
47
+ @if mixin-exists(sr-only) {
48
+ @include sr-only();
49
+ }
50
+ @if mixin-exists(visually-hidden) {
51
+ @include visually-hidden();
52
+ }
48
53
  }
49
54
  }
50
55
  }
@@ -6,7 +6,7 @@
6
6
  }
7
7
 
8
8
  .record-padding {
9
- margin-top: $spacer / 2;
9
+ margin-top: $spacer * .5;
10
10
  }
11
11
 
12
12
  .pagination {
@@ -1,4 +1,5 @@
1
1
  .twitter-typeahead {
2
+ display: inline-flex !important;
2
3
  flex-grow: 2;
3
4
  z-index: $zindex-typeahead;
4
5
 
@@ -10,7 +10,7 @@
10
10
  <% if @remove_path.present? %>
11
11
  <%= link_to(@remove_path, class: 'btn btn-outline-secondary remove') do %>
12
12
  <span class="remove-icon" aria-hidden="true">✖</span>
13
- <span class="sr-only">
13
+ <span class="sr-only visually-hidden">
14
14
  <%= if @label.blank?
15
15
  t('blacklight.search.filters.remove.value', value: @value)
16
16
  else
@@ -1,9 +1,9 @@
1
1
  <%= content_tag :div, id: @id, class: @classes do %>
2
- <h2 class="sr-only"><%= t('blacklight.search.search_constraints_header') %></h2>
2
+ <h2 class="sr-only visually-hidden"><%= t('blacklight.search.search_constraints_header') %></h2>
3
3
 
4
4
  <%= link_to t('blacklight.search.start_over'), start_over_path, class: "catalog_startOverLink btn btn-primary" %>
5
5
 
6
- <span class="constraints-label sr-only"><%= t('blacklight.search.filters.title') %></span>
6
+ <span class="constraints-label sr-only visually-hidden"><%= t('blacklight.search.filters.title') %></span>
7
7
  <% if query_constraints_area.present? %>
8
8
  <% query_constraints_area.each do |constraint| %>
9
9
  <%= constraint %>
@@ -63,10 +63,14 @@ module Blacklight
63
63
 
64
64
  Deprecation.silence(Blacklight::SearchState) do
65
65
  @search_state.filters.map do |facet|
66
+ missing_facet = @search_state.params.dig("f", "-#{facet.key}:").present?
66
67
  facet.values.map do |val|
67
- next if val.blank? # skip empty string
68
+ next if val.blank? && !missing_facet
68
69
 
69
- if val.is_a?(Array)
70
+ if missing_facet && val.blank?
71
+ missing = I18n.t("blacklight.search.facets.missing")
72
+ yield facet_item_presenter(facet.config, missing, facet.key)
73
+ elsif val.is_a?(Array)
70
74
  yield inclusive_facet_item_presenter(facet.config, val, facet.key) if val.any?(&:present?)
71
75
  else
72
76
  yield facet_item_presenter(facet.config, val, facet.key)
@@ -5,7 +5,8 @@ module Blacklight
5
5
  module ContentAreasShim
6
6
  # Shim the `with` helper to write content into slots instead
7
7
  def with(slot_name, *args, **kwargs, &block)
8
- Deprecation.warn('ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
8
+ Deprecation.warn(Blacklight::ContentAreasShim,
9
+ 'ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
9
10
  public_send(slot_name, *args, **kwargs, &block)
10
11
  end
11
12
  end
@@ -25,7 +25,7 @@ module Blacklight
25
25
  next static_content if static_content.present?
26
26
  next unless component
27
27
 
28
- Deprecation.warn('Pass the presenter to the DocumentComponent') if @presenter.nil?
28
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if @presenter.nil?
29
29
 
30
30
  component.new(*args, document: @document, presenter: @presenter, document_counter: @document_counter, **kwargs)
31
31
  end)
@@ -34,7 +34,7 @@ module Blacklight
34
34
  renders_one :metadata, (lambda do |static_content = nil, *args, component: nil, fields: nil, **kwargs|
35
35
  next static_content if static_content.present?
36
36
 
37
- Deprecation.warn('Pass the presenter to the DocumentComponent') if !fields && @presenter.nil?
37
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !fields && @presenter.nil?
38
38
 
39
39
  component ||= Blacklight::DocumentMetadataComponent
40
40
 
@@ -48,7 +48,7 @@ module Blacklight
48
48
  next image_options_or_static_content if image_options_or_static_content.is_a? String
49
49
 
50
50
  component ||= @presenter&.view_config&.thumbnail_component || Blacklight::Document::ThumbnailComponent
51
- Deprecation.warn('Pass the presenter to the DocumentComponent') if !component && @presenter.nil?
51
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !component && @presenter.nil?
52
52
 
53
53
  component.new(*args, document: @document, presenter: @presenter, counter: @counter, image_options: image_options_or_static_content, **kwargs)
54
54
  end)
@@ -93,13 +93,13 @@ module Blacklight
93
93
  @id = id || ('document' if show)
94
94
  @classes = classes
95
95
 
96
- Deprecation.warn('Passing embed_component is deprecated') if @embed_component.present?
96
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing embed_component is deprecated') if @embed_component.present?
97
97
  @embed_component = embed_component
98
98
 
99
- Deprecation.warn('Passing metadata_component is deprecated') if @metadata_component.present?
99
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing metadata_component is deprecated') if @metadata_component.present?
100
100
  @metadata_component = metadata_component || Blacklight::DocumentMetadataComponent
101
101
 
102
- Deprecation.warn('Passing thumbnail_component is deprecated') if @thumbnail_component.present?
102
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing thumbnail_component is deprecated') if @thumbnail_component.present?
103
103
  @thumbnail_component = thumbnail_component || Blacklight::Document::ThumbnailComponent
104
104
 
105
105
  @document_counter = document_counter
@@ -121,10 +121,10 @@ module Blacklight
121
121
  end
122
122
 
123
123
  def before_render
124
- set_slot(:title) unless title
125
- set_slot(:thumbnail, component: @thumbnail_component || presenter.view_config&.thumbnail_component) unless thumbnail || show?
126
- set_slot(:metadata, component: @metadata_component, fields: presenter.field_presenters) unless metadata
127
- set_slot(:embed, component: @embed_component || presenter.view_config&.embed_component) unless embed
124
+ set_slot(:title, nil) unless title
125
+ set_slot(:thumbnail, nil, component: @thumbnail_component || presenter.view_config&.thumbnail_component) unless thumbnail || show?
126
+ set_slot(:metadata, nil, component: @metadata_component, fields: presenter.field_presenters) unless metadata
127
+ set_slot(:embed, nil, component: @embed_component || presenter.view_config&.embed_component) unless embed
128
128
  end
129
129
 
130
130
  private
@@ -2,9 +2,11 @@
2
2
  <h3 class="card-header p-0 facet-field-heading" id="<%= @facet_field.html_id %>-header">
3
3
  <button
4
4
  type="button"
5
- class="btn btn-block p-2 text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
5
+ class="btn w-100 d-block btn-block p-2 text-start text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
6
6
  data-toggle="collapse"
7
+ data-bs-toggle="collapse"
7
8
  data-target="#<%= @facet_field.html_id %>"
9
+ data-bs-target="#<%= @facet_field.html_id %>"
8
10
  aria-expanded="<%= @facet_field.collapsed? ? 'false' : 'true' %>"
9
11
  >
10
12
  <%= label %>
@@ -10,7 +10,7 @@ module Blacklight
10
10
  def initialize(**); end
11
11
 
12
12
  def call
13
- body
13
+ body.to_s
14
14
  end
15
15
  end
16
16
  end
@@ -27,7 +27,7 @@ module Blacklight
27
27
  render_facet_value
28
28
  end
29
29
 
30
- return if content.blank?
30
+ return '' if content.blank?
31
31
  return content unless @wrapping_element
32
32
 
33
33
  content_tag @wrapping_element, content
@@ -72,7 +72,7 @@ module Blacklight
72
72
  # @private
73
73
  def render_facet_value
74
74
  tag.span(class: "facet-label") do
75
- link_to_unless(@suppress_link, @label, @href, class: "facet-select")
75
+ link_to_unless(@suppress_link, @label, @href, class: "facet-select", rel: "nofollow")
76
76
  end + render_facet_count
77
77
  end
78
78
 
@@ -85,9 +85,9 @@ module Blacklight
85
85
  tag.span(class: "facet-label") do
86
86
  tag.span(@label, class: "selected") +
87
87
  # remove link
88
- link_to(@href, class: "remove") do
88
+ link_to(@href, class: "remove", rel: "nofollow") do
89
89
  tag.span('✖', class: "remove-icon", aria: { hidden: true }) +
90
- tag.span(@view_context.t(:'blacklight.search.facets.selected.remove'), class: 'sr-only')
90
+ tag.span(@view_context.t(:'blacklight.search.facets.selected.remove'), class: 'sr-only visually-hidden')
91
91
  end
92
92
  end + render_facet_count(classes: ["selected"])
93
93
  end
@@ -56,7 +56,7 @@ module Blacklight
56
56
 
57
57
  def facet_toggle_button(id)
58
58
  content_tag 'button', class: 'btn facet-toggle-handle collapsed',
59
- data: { toggle: 'collapse', target: "##{id}" },
59
+ data: { toggle: 'collapse', 'bs-toggle': 'collapse', target: "##{id}", 'bs-target': "##{id}" },
60
60
  aria: { expanded: false, controls: id, describedby: "#{id}_label" } do
61
61
  concat toggle_icon(:show)
62
62
  concat toggle_icon(:hide)
@@ -66,7 +66,7 @@ module Blacklight
66
66
  def toggle_icon(type)
67
67
  content_tag 'span', class: type do
68
68
  concat @icons[type]
69
- concat content_tag('span', t(type, scope: 'blacklight.search.facets.pivot'), class: 'sr-only')
69
+ concat content_tag('span', t(type, scope: 'blacklight.search.facets.pivot'), class: 'sr-only visually-hidden')
70
70
  end
71
71
  end
72
72
 
@@ -23,9 +23,9 @@ module Blacklight
23
23
  end
24
24
 
25
25
  def value(*args, **kwargs, &block)
26
- return set_slot(:values, *args, **kwargs, &block) if block_given?
26
+ return set_slot(:values, nil, *args, **kwargs, &block) if block_given?
27
27
 
28
- Deprecation.warn('The `value` content area is deprecated; render from the values slot instead')
28
+ Deprecation.warn(Blacklight::MetadataFieldLayoutComponent, 'The `value` content area is deprecated; render from the values slot instead')
29
29
 
30
30
  values.first
31
31
  end
@@ -9,6 +9,8 @@
9
9
  data: {
10
10
  toggle: 'collapse',
11
11
  target: "##{@panel_id}",
12
+ 'bs-toggle': 'collapse',
13
+ 'bs-target': "##{@panel_id}"
12
14
  },
13
15
  aria: {
14
16
  controls: @panel_id,
@@ -1,3 +1,3 @@
1
- <%= content_tag :nav, class: 'pagination', role: 'region', **@html_attr do %>
1
+ <%= content_tag :section, class: 'pagination', **@html_attr do %>
2
2
  <%= pagination %>
3
3
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <div class="view-type">
2
- <span class="sr-only"><%= t('blacklight.search.view_title') %></span>
2
+ <span class="sr-only visually-hidden"><%= t('blacklight.search.view_title') %></span>
3
3
  <div class="view-type-group btn-group">
4
4
  <% views.each do |view| %>
5
5
  <%= view %>
@@ -1,7 +1,7 @@
1
1
  <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => scoped_t('submit') do %>
2
2
  <%= render_hash_as_hidden_fields(@params) %>
3
3
  <% if @search_fields.length > 1 %>
4
- <label for="search_field" class="sr-only"><%= scoped_t('search_field.label') %></label>
4
+ <label for="search_field" class="sr-only visually-hidden"><%= scoped_t('search_field.label') %></label>
5
5
  <% end %>
6
6
  <div class="input-group">
7
7
  <%= prepend %>
@@ -11,12 +11,12 @@
11
11
  options_for_select(@search_fields, h(@search_field)),
12
12
  title: scoped_t('search_field.title'),
13
13
  id: "#{@prefix}search_field",
14
- class: "custom-select search-field") %>
14
+ class: "custom-select form-select search-field") %>
15
15
  <% elsif @search_fields.length == 1 %>
16
16
  <%= hidden_field_tag :search_field, @search_fields.first.last %>
17
17
  <% end %>
18
18
 
19
- <label for="<%= @prefix %><%= @query_param %>" class="sr-only"><%= scoped_t('search.label') %></label>
19
+ <label for="<%= @prefix %><%= @query_param %>" class="sr-only visually-hidden"><%= scoped_t('search.label') %></label>
20
20
  <%= text_field_tag @query_param, @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control rounded-#{@search_fields.length > 1 ? '0' : 'left'}", id: "#{@prefix}q", autocomplete: autocomplete_path.present? ? "off" : "", autofocus: @autofocus, data: { autocomplete_enabled: autocomplete_path.present?, autocomplete_path: autocomplete_path } %>
21
21
 
22
22
  <span class="input-group-append">
@@ -4,7 +4,7 @@ module Blacklight
4
4
  module System
5
5
  class DropdownComponent < ViewComponent::Base
6
6
  renders_one :button, (lambda do |classes:, label:|
7
- button_tag class: classes, aria: { expanded: false }, data: { toggle: 'dropdown' } do
7
+ button_tag class: classes, aria: { expanded: false }, data: { toggle: 'dropdown', 'bs-toggle': 'dropdown' } do
8
8
  safe_join([label, content_tag(:span, '', class: 'caret')])
9
9
  end
10
10
  end)
@@ -1,4 +1,4 @@
1
1
  <div class="alert <%= @classes %>">
2
2
  <%= message %>
3
- <a class="close" data-dismiss="alert" href="#">&times;</a>
3
+ <a class="btn-close close" data-dismiss="alert" href="#">&times;</a>
4
4
  </div>
@@ -6,7 +6,7 @@
6
6
  <h1 class="modal-title"><%= title %></h1>
7
7
  <% end) %>
8
8
 
9
- <button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="<%= t('blacklight.modal.close') %>">
9
+ <button type="button" class="blacklight-modal-close btn-close close" data-dismiss="modal" aria-label="<%= t('blacklight.modal.close') %>">
10
10
  <span aria-hidden="true">&times;</span>
11
11
  </button>
12
12
  </div>
@@ -48,9 +48,6 @@ module Blacklight::Bookmarks
48
48
  format.html {}
49
49
  format.rss { render layout: false }
50
50
  format.atom { render layout: false }
51
- format.json do
52
- render json: render_search_results_as_json
53
- end
54
51
 
55
52
  additional_response_formats(format)
56
53
  document_export_formats(format)
@@ -2,6 +2,9 @@
2
2
  module Blacklight::Catalog
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ # MimeResponds is part of ActionController::Base, but not ActionController::API
6
+ include ActionController::MimeResponds
7
+
5
8
  include Blacklight::Base
6
9
  include Blacklight::Facet
7
10
  include Blacklight::Searchable
@@ -3,6 +3,7 @@
3
3
  # as this module is mixed-in to the application controller in the hosting app on installation.
4
4
  module Blacklight::Controller
5
5
  extend ActiveSupport::Concern
6
+ extend Deprecation
6
7
 
7
8
  included do
8
9
  include Blacklight::SearchFields
@@ -38,11 +39,6 @@ module Blacklight::Controller
38
39
  # TODO: move to Searchable
39
40
  class_attribute :search_service_class
40
41
  self.search_service_class = Blacklight::SearchService
41
-
42
- # This callback runs when a user first logs in
43
-
44
- define_callbacks :logging_in_user
45
- set_callback :logging_in_user, :before, :transfer_guest_user_actions_to_current_user
46
42
  end
47
43
 
48
44
  # @private
@@ -136,6 +132,13 @@ module Blacklight::Controller
136
132
 
137
133
  ##
138
134
  # When a user logs in, transfer any saved searches or bookmarks to the current_user
135
+ def transfer_guest_to_user
136
+ Deprecation.silence(Blacklight::Controller) do
137
+ transfer_guest_user_actions_to_current_user
138
+ end
139
+ end
140
+
141
+ # @deprecated use canonical `transfer_guest_to_user` method instead
139
142
  def transfer_guest_user_actions_to_current_user
140
143
  return unless respond_to?(:current_user) && respond_to?(:guest_user) && current_user && guest_user
141
144
 
@@ -155,6 +158,7 @@ module Blacklight::Controller
155
158
  # let guest_user know we've moved some bookmarks from under it
156
159
  guest_user.reload if guest_user.persisted?
157
160
  end
161
+ deprecation_deprecate :transfer_guest_user_actions_to_current_user
158
162
 
159
163
  ##
160
164
  # To handle failed authorization attempts, redirect the user to the
@@ -73,7 +73,7 @@ module Blacklight::SearchContext
73
73
  #
74
74
  def agent_is_crawler?
75
75
  crawler_proc = blacklight_config.crawler_detector
76
- return false if crawler_proc.nil? || current_user.present?
76
+ return false if crawler_proc.nil? || (defined?(current_user) && current_user.present?)
77
77
 
78
78
  crawler_proc.call(request)
79
79
  end
@@ -47,11 +47,9 @@ module Blacklight::CatalogHelperBehavior
47
47
  entry_name = if entry_name
48
48
  entry_name.pluralize(collection.size, I18n.locale)
49
49
  else
50
- collection.entry_name(count: collection.size).to_s.downcase
50
+ collection.entry_name(count: collection.size).to_s
51
51
  end
52
52
 
53
- entry_name = entry_name.pluralize unless collection.total_count == 1
54
-
55
53
  # grouped response objects need special handling
56
54
  end_num = if collection.respond_to?(:groups) && render_grouped_response?(collection)
57
55
  collection.groups.length
@@ -14,7 +14,7 @@ module Blacklight
14
14
  if action_opts.path
15
15
  send(action_opts.path, url_opts)
16
16
  elsif url_opts[:id].class.respond_to?(:model_name)
17
- url_for([action_opts.key, url_opts[:id]])
17
+ url_for([action_opts.key.to_sym, url_opts[:id]])
18
18
  else
19
19
  send("#{action_opts.key}_#{controller_name}_path", url_opts)
20
20
  end