blacklight 7.19.2 → 7.21.1

Sign up to get free protection for your applications and to get access to all the features.
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