blacklight 7.19.2 → 7.21.1

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.babelrc +11 -0
  3. data/.env +1 -1
  4. data/.github/workflows/ruby.yml +21 -3
  5. data/.rubocop.yml +4 -0
  6. data/Gemfile +1 -1
  7. data/README.md +2 -2
  8. data/VERSION +1 -1
  9. data/app/assets/javascripts/blacklight/blacklight.js +50 -27
  10. data/app/assets/stylesheets/blacklight/_constraints.scss +7 -4
  11. data/app/assets/stylesheets/blacklight/_controls.scss +8 -0
  12. data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
  13. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -1
  14. data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +1 -0
  15. data/app/components/blacklight/constraints_component.rb +1 -1
  16. data/app/components/blacklight/document_component.rb +4 -4
  17. data/app/components/blacklight/facet_item_component.rb +2 -2
  18. data/app/components/blacklight/metadata_field_layout_component.rb +1 -1
  19. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  20. data/app/components/blacklight/system/modal_component.html.erb +2 -2
  21. data/app/controllers/concerns/blacklight/bookmarks.rb +0 -3
  22. data/app/controllers/concerns/blacklight/catalog.rb +5 -2
  23. data/app/controllers/concerns/blacklight/controller.rb +9 -5
  24. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  25. data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -3
  26. data/app/javascript/blacklight/core.js +14 -3
  27. data/app/javascript/blacklight/modal.js +1 -1
  28. data/app/javascript/blacklight/search_context.js +5 -2
  29. data/app/models/concerns/blacklight/document/email.rb +18 -6
  30. data/app/models/concerns/blacklight/document/sms.rb +16 -4
  31. data/app/models/record_mailer.rb +9 -1
  32. data/app/presenters/blacklight/facet_item_presenter.rb +2 -0
  33. data/app/views/catalog/_home_text.html.erb +2 -2
  34. data/app/views/catalog/_paginate_compact.html.erb +1 -0
  35. data/app/views/record_mailer/sms_record.text.erb +1 -1
  36. data/app/views/shared/_header_navbar.html.erb +2 -2
  37. data/blacklight.gemspec +4 -2
  38. data/config/locales/blacklight.de.yml +4 -2
  39. data/config/locales/blacklight.en.yml +6 -2
  40. data/config/locales/blacklight.es.yml +3 -1
  41. data/config/locales/blacklight.fr.yml +3 -1
  42. data/config/locales/blacklight.it.yml +3 -1
  43. data/lib/blacklight/configuration.rb +9 -0
  44. data/lib/blacklight/engine.rb +2 -0
  45. data/lib/blacklight/search_state/filter_field.rb +35 -11
  46. data/lib/blacklight/solr/response/facets.rb +2 -1
  47. data/lib/blacklight/solr/response/group_response.rb +3 -2
  48. data/lib/blacklight/solr/response/pagination_methods.rb +1 -1
  49. data/lib/blacklight/solr/search_builder_behavior.rb +2 -0
  50. data/lib/blacklight.rb +5 -1
  51. data/lib/generators/blacklight/assets_generator.rb +4 -2
  52. data/lib/generators/blacklight/install_generator.rb +4 -1
  53. data/lib/generators/blacklight/user_generator.rb +1 -1
  54. data/package.json +5 -3
  55. data/spec/components/blacklight/facet_item_component_spec.rb +6 -2
  56. data/spec/controllers/catalog_controller_spec.rb +14 -2
  57. data/spec/features/axe_spec.rb +33 -0
  58. data/spec/features/facet_missing_spec.rb +67 -0
  59. data/spec/features/facets_spec.rb +1 -1
  60. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
  61. data/spec/lib/blacklight/search_state/filter_field_spec.rb +13 -0
  62. data/spec/models/blacklight/configuration_spec.rb +92 -0
  63. data/spec/models/blacklight/document/email_spec.rb +32 -0
  64. data/spec/models/blacklight/document/sms_spec.rb +33 -0
  65. data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
  66. data/spec/models/blacklight/solr/response/group_response_spec.rb +3 -2
  67. data/spec/models/record_mailer_spec.rb +30 -2
  68. data/spec/spec_helper.rb +18 -12
  69. data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -3
  70. metadata +44 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f48da02e969e0c163d09760d711066ce9c0b4d5078636c8f50e19699ec58e8e
4
- data.tar.gz: 77da2b86854e93f08a79ba9e28c86c7c91116b9f6934229eb6936cc6872bfdc6
3
+ metadata.gz: ca8e0f469ef3139ac8bc06f0fbb2d4e54631dbf845a1997d88af3ef9f67c48b1
4
+ data.tar.gz: b8b43f4594c8d0a1fc2359aff9ee7f655eab4d3ee1ce7bb41c370b494641fa87
5
5
  SHA512:
6
- metadata.gz: a42155551ab05fa25e433a7aad6e40078ce7cbc2918de03f6ede94aef53ade03b4b16f4411a915b737b1233a631d9cb2baddc9d560aa70b67df237776c01e7f6
7
- data.tar.gz: 6430192899c4db45277e988217aecc04e954d856645941773176e36ecefd3ddda3c2a9988caffb7bde50f8aa76702a10cd00da67216f17c6fb49a2802a678dfe
6
+ metadata.gz: a883ed83bd85c66be0e4234085a24cca6a921b8962e934e018b40e70065e0323db43e1ecb033801dae79b506de5172030a20c5f481b0fe9f5c0476993902db72
7
+ data.tar.gz: b4234d29c467782346278cc832899ac580a4d0dd06fa3a7831288fbcdba783e9fb1897126dd4ddc267671a59c1712bfc8ad05602ef687c658b9a5507d6665304
data/.babelrc ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ "useBuiltIns": "entry",
7
+ "corejs": "2.0"
8
+ }
9
+ ]
10
+ ]
11
+ }
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
@@ -9,9 +9,9 @@ name: CI
9
9
 
10
10
  on:
11
11
  push:
12
- branches: [ master ]
12
+ branches: [ main ]
13
13
  pull_request:
14
- branches: [ master ]
14
+ branches: [ main ]
15
15
 
16
16
  jobs:
17
17
  lint:
@@ -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/Gemfile CHANGED
@@ -27,7 +27,7 @@ else
27
27
  if ENV['RAILS_VERSION']
28
28
  if ENV['RAILS_VERSION'] == 'edge'
29
29
  gem 'rails', github: 'rails/rails'
30
- ENV['ENGINE_CART_RAILS_OPTIONS'] = '--edge --skip-turbolinks'
30
+ ENV['ENGINE_CART_RAILS_OPTIONS'] = '--edge'
31
31
  else
32
32
  gem 'rails', ENV['RAILS_VERSION']
33
33
  end
data/README.md CHANGED
@@ -35,11 +35,11 @@ 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
 
42
- Code contributions are always welcome, instructions for contributing can be found at [CONTRIBUTING.md](https://github.com/projectblacklight/blacklight/blob/master/CONTRIBUTING.md).
42
+ Code contributions are always welcome, instructions for contributing can be found at [CONTRIBUTING.md](https://github.com/projectblacklight/blacklight/blob/main/CONTRIBUTING.md).
43
43
 
44
44
  ## Configuring Apache Solr
45
45
  You'll also want some information about how Blacklight expects [Apache Solr](http://lucene.apache.org/solr ) to run, which you can find in [README_SOLR](https://github.com/projectblacklight/blacklight/wiki/README_SOLR)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.19.2
1
+ 7.21.1
@@ -1,18 +1,22 @@
1
- Blacklight = function () {
1
+ "use strict";
2
+
3
+ var Blacklight = function () {
2
4
  var buffer = new Array();
3
5
  return {
4
- onLoad: function (func) {
6
+ onLoad: function onLoad(func) {
5
7
  buffer.push(func);
6
8
  },
7
- activate: function () {
9
+ activate: function activate() {
8
10
  for (var i = 0; i < buffer.length; i++) {
9
11
  buffer[i].call();
10
12
  }
11
13
  },
12
- listeners: function () {
14
+ listeners: function listeners() {
13
15
  var listeners = [];
14
16
 
15
- if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
17
+ if (typeof Turbo !== 'undefined') {
18
+ listeners.push('turbo:load');
19
+ } else if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
16
20
  // Turbolinks 5
17
21
  if (Turbolinks.BrowserAdapter) {
18
22
  listeners.push('turbolinks:load');
@@ -36,7 +40,14 @@ Blacklight.listeners().forEach(function (listener) {
36
40
  Blacklight.activate();
37
41
  });
38
42
  });
39
- $('.no-js').removeClass('no-js').addClass('js');
43
+ Blacklight.onLoad(function () {
44
+ var elem = document.querySelector('.no-js'); // The "no-js" class may already have been removed because this function is
45
+ // run on every turbo:load event, in that case, it won't find an element.
46
+
47
+ if (!elem) return;
48
+ elem.classList.remove('no-js');
49
+ elem.classList.add('js');
50
+ });
40
51
  /*global Bloodhound */
41
52
 
42
53
  Blacklight.onLoad(function () {
@@ -82,7 +93,7 @@ Blacklight.onLoad(function () {
82
93
  $(Blacklight.doBookmarkToggleBehavior.selector).blCheckboxSubmit({
83
94
  // cssClass is added to elements added, plus used for id base
84
95
  cssClass: 'toggle-bookmark',
85
- success: function (checked, response) {
96
+ success: function success(checked, response) {
86
97
  if (response.bookmarks) {
87
98
  $('[data-role=bookmark-counter]').text(response.bookmarks.count);
88
99
  }
@@ -100,8 +111,8 @@ Blacklight.onLoad(function () {
100
111
  // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
101
112
  // Safari both do not set focus to a button on button click.
102
113
  // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
103
- document.querySelectorAll('button.collapse-toggle').forEach(button => {
104
- button.addEventListener('click', () => {
114
+ document.querySelectorAll('button.collapse-toggle').forEach(function (button) {
115
+ button.addEventListener('click', function () {
105
116
  event.target.focus();
106
117
  });
107
118
  });
@@ -188,12 +199,12 @@ Blacklight.onLoad(function () {
188
199
  dataType: 'json',
189
200
  type: form.attr('method').toUpperCase(),
190
201
  data: form.serialize(),
191
- error: function () {
202
+ error: function error() {
192
203
  label.removeAttr('disabled');
193
204
  checkbox.removeAttr('disabled');
194
205
  options.error.call();
195
206
  },
196
- success: function (data, status, xhr) {
207
+ success: function success(data, status, xhr) {
197
208
  //if app isn't running at all, xhr annoyingly
198
209
  //reports success with status 0.
199
210
  if (xhr.status != 0) {
@@ -219,10 +230,10 @@ Blacklight.onLoad(function () {
219
230
  $.fn.blCheckboxSubmit.defaults = {
220
231
  //cssClass is added to elements added, plus used for id base
221
232
  cssClass: 'blCheckboxSubmit',
222
- error: function () {
233
+ error: function error() {
223
234
  alert("Error");
224
235
  },
225
- success: function () {} //callback
236
+ success: function success() {} //callback
226
237
 
227
238
  };
228
239
  })(jQuery);
@@ -238,12 +249,12 @@ Blacklight.doResizeFacetLabelsAndCounts = function () {
238
249
  }
239
250
 
240
251
  document.querySelectorAll('.facet-values, .pivot-facet').forEach(function (elem) {
241
- const nodes = elem.querySelectorAll('.facet-count'); // TODO: when we drop ie11 support, this can become the spread operator:
252
+ var nodes = elem.querySelectorAll('.facet-count'); // TODO: when we drop ie11 support, this can become the spread operator:
242
253
 
243
- const longest = Array.from(nodes).sort(longer)[0];
254
+ var longest = Array.from(nodes).sort(longer)[0];
244
255
 
245
256
  if (longest && longest.textContent) {
246
- const width = longest.textContent.length + 1 + 'ch';
257
+ var width = longest.textContent.length + 1 + 'ch';
247
258
  elem.querySelector('.facet-count').style.width = width;
248
259
  }
249
260
  });
@@ -360,7 +371,7 @@ Blacklight.modal.onFailure = function (jqXHR, textStatus, errorThrown) {
360
371
  Blacklight.modal.receiveAjax = function (contents) {
361
372
  // does it have a data- selector for container?
362
373
  // important we don't execute script tags, we shouldn't.
363
- // code modelled off of JQuery ajax.load. https://github.com/jquery/jquery/blob/master/src/ajax/load.js?source=c#L62
374
+ // code modelled off of JQuery ajax.load. https://github.com/jquery/jquery/blob/main/src/ajax/load.js?source=c#L62
364
375
  var container = $('<div>').append(jQuery.parseHTML(contents)).find(Blacklight.modal.containerSelector).first();
365
376
 
366
377
  if (container.length !== 0) {
@@ -438,14 +449,26 @@ Blacklight.doSearchContextBehavior = function () {
438
449
  return Blacklight.do_search_context_behavior();
439
450
  }
440
451
 
441
- const elements = document.querySelectorAll('a[data-context-href]'); // Equivalent to Array.from(), but supports ie11
452
+ var elements = document.querySelectorAll('a[data-context-href]'); // Equivalent to Array.from(), but supports ie11
442
453
 
443
- const nodes = Array.prototype.slice.call(elements);
454
+ var nodes = Array.prototype.slice.call(elements);
444
455
  nodes.forEach(function (element) {
445
456
  element.addEventListener('click', function (e) {
446
457
  Blacklight.handleSearchContextMethod.call(e.currentTarget, e);
447
458
  });
448
459
  });
460
+ };
461
+
462
+ Blacklight.csrfToken = function () {
463
+ var _document$querySelect;
464
+
465
+ return (_document$querySelect = document.querySelector('meta[name=csrf-token]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.content;
466
+ };
467
+
468
+ Blacklight.csrfParam = function () {
469
+ var _document$querySelect2;
470
+
471
+ return (_document$querySelect2 = document.querySelector('meta[name=csrf-param]')) === null || _document$querySelect2 === void 0 ? void 0 : _document$querySelect2.content;
449
472
  }; // this is the Rails.handleMethod with a couple adjustments, described inline:
450
473
  // first, we're attaching this directly to the event handler, so we can check for meta-keys
451
474
 
@@ -458,22 +481,21 @@ Blacklight.handleSearchContextMethod = function (event) {
458
481
 
459
482
  var link = this; // instead of using the normal href, we need to use the context href instead
460
483
 
461
- let href = link.getAttribute('data-context-href');
462
- let target = link.getAttribute('target');
463
- let csrfToken = Rails.csrfToken();
464
- let csrfParam = Rails.csrfParam();
465
- let form = document.createElement('form');
484
+ var href = link.getAttribute('data-context-href');
485
+ var target = link.getAttribute('target');
486
+ var csrfToken = Blacklight.csrfToken();
487
+ var csrfParam = Blacklight.csrfParam();
488
+ var form = document.createElement('form');
466
489
  form.method = 'post';
467
490
  form.action = href;
468
- let formContent = `<input name="_method" value="post" type="hidden" />
469
- <input name="redirect" value="${link.getAttribute('href')}" type="hidden" />`; // check for meta keys.. if set, we should open in a new tab
491
+ var formContent = "<input name=\"_method\" value=\"post\" type=\"hidden\" />\n <input name=\"redirect\" value=\"".concat(link.getAttribute('href'), "\" type=\"hidden\" />"); // check for meta keys.. if set, we should open in a new tab
470
492
 
471
493
  if (event.metaKey || event.ctrlKey) {
472
494
  target = '_blank';
473
495
  }
474
496
 
475
497
  if (csrfParam !== undefined && csrfToken !== undefined) {
476
- formContent += `<input name="${csrfParam}" value="${csrfToken}" type="hidden" />`;
498
+ formContent += "<input name=\"".concat(csrfParam, "\" value=\"").concat(csrfToken, "\" type=\"hidden\" />");
477
499
  } // Must trigger submit by click on a button, else "submit" event handler won't work!
478
500
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
479
501
 
@@ -495,3 +517,4 @@ Blacklight.handleSearchContextMethod = function (event) {
495
517
  Blacklight.onLoad(function () {
496
518
  Blacklight.doSearchContextBehavior();
497
519
  });
520
+
@@ -1,27 +1,30 @@
1
1
  .constraints-container {
2
2
  @extend .mb-2;
3
+ display: 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
14
  @media (max-width: breakpoint-min(sm)) {
12
- max-width: breakpoint-min(sm) / 2;
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,11 @@
1
+ .search-widgets {
2
+ display: flex;
3
+
4
+ > * {
5
+ @extend .mx-1;
6
+ }
7
+ }
8
+
1
9
  .sort-pagination,
2
10
  .pagination-search-widgets {
3
11
  border-bottom: $pagination-border-width solid $pagination-border-color;
@@ -83,7 +83,7 @@
83
83
  .remove {
84
84
  color: $text-muted;
85
85
  font-weight: bold;
86
- padding-left: $spacer / 2;
86
+ padding-left: $spacer * .5;
87
87
  text-decoration: none;
88
88
 
89
89
  &:hover {
@@ -104,7 +104,7 @@
104
104
  padding-right: 1em;
105
105
  text-indent: -15px;
106
106
  padding-left: 15px;
107
- padding-bottom: $spacer / 2;
107
+ padding-bottom: $spacer * .5;
108
108
  @include hyphens-auto;
109
109
  }
110
110
 
@@ -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
 
@@ -64,7 +64,7 @@ module Blacklight
64
64
  Deprecation.silence(Blacklight::SearchState) do
65
65
  @search_state.filters.map do |facet|
66
66
  facet.values.map do |val|
67
- next if val.blank? # skip empty string
67
+ next if val.blank?
68
68
 
69
69
  if val.is_a?(Array)
70
70
  yield inclusive_facet_item_presenter(facet.config, val, facet.key) if val.any?(&:present?)
@@ -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
@@ -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,7 +85,7 @@ 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
90
  tag.span(@view_context.t(:'blacklight.search.facets.selected.remove'), class: 'sr-only visually-hidden')
91
91
  end
@@ -23,7 +23,7 @@ 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
28
  Deprecation.warn(Blacklight::MetadataFieldLayoutComponent, 'The `value` content area is deprecated; render from the values slot instead')
29
29
 
@@ -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 %>
@@ -6,8 +6,8 @@
6
6
  <h1 class="modal-title"><%= title %></h1>
7
7
  <% end) %>
8
8
 
9
- <button type="button" class="blacklight-modal-close btn-close close" data-dismiss="modal" aria-label="<%= t('blacklight.modal.close') %>">
10
- <span aria-hidden="true">&times;</span>
9
+ <button type="button" class="blacklight-modal-close btn-close close" data-bs-dismiss="modal" data-dismiss="modal" aria-label="<%= t('blacklight.modal.close') %>">
10
+ <span aria-hidden="true" class="visually-hidden">&times;</span>
11
11
  </button>
12
12
  </div>
13
13
 
@@ -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
@@ -257,7 +260,7 @@ module Blacklight::Catalog
257
260
 
258
261
  # Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
259
262
  def email_action documents
260
- mail = RecordMailer.email_record(documents, { to: params[:to], message: params[:message] }, url_options)
263
+ mail = RecordMailer.email_record(documents, { to: params[:to], message: params[:message], config: blacklight_config }, url_options)
261
264
  if mail.respond_to? :deliver_now
262
265
  mail.deliver_now
263
266
  else
@@ -268,7 +271,7 @@ module Blacklight::Catalog
268
271
  # SMS action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
269
272
  def sms_action documents
270
273
  to = "#{params[:to].gsub(/[^\d]/, '')}@#{params[:carrier]}"
271
- mail = RecordMailer.sms_record(documents, { to: to }, url_options)
274
+ mail = RecordMailer.sms_record(documents, { to: to, config: blacklight_config }, url_options)
272
275
  if mail.respond_to? :deliver_now
273
276
  mail.deliver_now
274
277
  else
@@ -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
@@ -1,4 +1,4 @@
1
- Blacklight = function() {
1
+ const Blacklight = function() {
2
2
  var buffer = new Array;
3
3
  return {
4
4
  onLoad: function(func) {
@@ -13,7 +13,9 @@ Blacklight = function() {
13
13
 
14
14
  listeners: function () {
15
15
  var listeners = [];
16
- if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
16
+ if (typeof Turbo !== 'undefined') {
17
+ listeners.push('turbo:load');
18
+ } else if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
17
19
  // Turbolinks 5
18
20
  if (Turbolinks.BrowserAdapter) {
19
21
  listeners.push('turbolinks:load');
@@ -38,4 +40,13 @@ Blacklight.listeners().forEach(function(listener) {
38
40
  })
39
41
  })
40
42
 
41
- $('.no-js').removeClass('no-js').addClass('js');
43
+ Blacklight.onLoad(function () {
44
+ const elem = document.querySelector('.no-js');
45
+
46
+ // The "no-js" class may already have been removed because this function is
47
+ // run on every turbo:load event, in that case, it won't find an element.
48
+ if (!elem) return;
49
+
50
+ elem.classList.remove('no-js')
51
+ elem.classList.add('js')
52
+ })
@@ -120,7 +120,7 @@ Blacklight.modal.onFailure = function(jqXHR, textStatus, errorThrown) {
120
120
  Blacklight.modal.receiveAjax = function (contents) {
121
121
  // does it have a data- selector for container?
122
122
  // important we don't execute script tags, we shouldn't.
123
- // code modelled off of JQuery ajax.load. https://github.com/jquery/jquery/blob/master/src/ajax/load.js?source=c#L62
123
+ // code modelled off of JQuery ajax.load. https://github.com/jquery/jquery/blob/main/src/ajax/load.js?source=c#L62
124
124
  var container = $('<div>').
125
125
  append( jQuery.parseHTML(contents) ).find( Blacklight.modal.containerSelector ).first();
126
126
  if (container.length !== 0) {
@@ -15,6 +15,9 @@ Blacklight.doSearchContextBehavior = function() {
15
15
  })
16
16
  };
17
17
 
18
+ Blacklight.csrfToken = () => document.querySelector('meta[name=csrf-token]')?.content
19
+ Blacklight.csrfParam = () => document.querySelector('meta[name=csrf-param]')?.content
20
+
18
21
  // this is the Rails.handleMethod with a couple adjustments, described inline:
19
22
  // first, we're attaching this directly to the event handler, so we can check for meta-keys
20
23
  Blacklight.handleSearchContextMethod = function(event) {
@@ -27,8 +30,8 @@ Blacklight.handleSearchContextMethod = function(event) {
27
30
  // instead of using the normal href, we need to use the context href instead
28
31
  let href = link.getAttribute('data-context-href')
29
32
  let target = link.getAttribute('target')
30
- let csrfToken = Rails.csrfToken()
31
- let csrfParam = Rails.csrfParam()
33
+ let csrfToken = Blacklight.csrfToken()
34
+ let csrfParam = Blacklight.csrfParam()
32
35
  let form = document.createElement('form')
33
36
  form.method = 'post'
34
37
  form.action = href