blacklight 8.0.0.beta1 → 8.0.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.
- checksums.yaml +4 -4
- data/.env +1 -0
- data/.github/workflows/ruby.yml +6 -0
- data/.gitignore +1 -0
- data/.rubocop_todo.yml +3 -1
- data/README.md +1 -1
- data/Rakefile +18 -0
- data/VERSION +1 -1
- data/app/assets/config/blacklight/manifest.js +3 -0
- data/app/assets/javascripts/blacklight/blacklight.esm.js +132 -140
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +132 -140
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +1 -1
- data/app/assets/stylesheets/blacklight/_facets.scss +32 -5
- data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +1 -1
- data/app/components/blacklight/advanced_search_form_component.rb +3 -3
- data/app/components/blacklight/document/actions_component.rb +1 -1
- data/app/components/blacklight/document/show_tools_component.html.erb +12 -0
- data/app/components/blacklight/document/show_tools_component.rb +23 -0
- data/app/components/blacklight/document_component.rb +48 -20
- data/app/components/blacklight/document_metadata_component.html.erb +4 -2
- data/app/components/blacklight/document_metadata_component.rb +8 -2
- data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
- data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
- data/app/components/blacklight/metadata_field_component.html.erb +2 -2
- data/app/components/blacklight/metadata_field_layout_component.rb +7 -4
- data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +17 -0
- data/app/components/blacklight/response/facet_group_component.html.erb +2 -1
- data/app/components/blacklight/response/facet_group_component.rb +1 -1
- data/app/components/blacklight/response/sort_component.rb +1 -1
- data/app/components/blacklight/response/spellcheck_component.rb +1 -1
- data/app/components/blacklight/response/view_type_button_component.rb +1 -1
- data/app/components/blacklight/response/view_type_component.rb +2 -2
- data/app/components/blacklight/search/sidebar_component.html.erb +1 -1
- data/app/components/blacklight/search_context/server_applied_params_component.html.erb +4 -0
- data/app/components/blacklight/search_context/server_applied_params_component.rb +13 -0
- data/app/components/blacklight/search_context/server_item_pagination_component.rb +71 -0
- data/app/components/blacklight/system/dropdown_component.rb +3 -3
- data/app/components/blacklight/system/flash_message_component.rb +2 -2
- data/app/components/blacklight/system/modal_component.rb +1 -1
- data/app/components/blacklight/top_navbar_component.html.erb +1 -1
- data/app/components/blacklight/top_navbar_component.rb +4 -0
- data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
- data/app/controllers/concerns/blacklight/search_context.rb +46 -6
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -101
- data/app/helpers/blacklight/catalog_helper_behavior.rb +27 -54
- data/app/helpers/blacklight/component_helper_behavior.rb +0 -11
- data/app/helpers/blacklight/document_helper_behavior.rb +76 -0
- data/app/helpers/blacklight/layout_helper_behavior.rb +59 -0
- data/app/helpers/blacklight/render_partials_helper_behavior.rb +1 -0
- data/app/helpers/blacklight/url_helper_behavior.rb +11 -3
- data/app/javascript/blacklight/bookmark_toggle.js +8 -15
- data/app/javascript/blacklight/button_focus.js +10 -10
- data/app/javascript/blacklight/index.js +6 -5
- data/app/javascript/blacklight/modal.js +24 -24
- data/app/javascript/blacklight/search_context.js +51 -57
- data/app/models/concerns/blacklight/document.rb +11 -0
- data/app/models/record_mailer.rb +19 -15
- data/app/presenters/blacklight/document_presenter.rb +13 -11
- data/app/presenters/blacklight/index_presenter.rb +1 -1
- data/app/presenters/blacklight/rendering/abstract_step.rb +4 -0
- data/app/presenters/blacklight/rendering/join.rb +7 -1
- data/app/presenters/blacklight/rendering/link_to_facet.rb +1 -1
- data/app/presenters/blacklight/rendering/microdata.rb +1 -1
- data/app/services/blacklight/search_service.rb +2 -1
- data/app/views/catalog/_document.atom.builder +1 -1
- data/app/views/catalog/_document.html.erb +3 -8
- data/app/views/catalog/_document_list.html.erb +2 -1
- data/app/views/catalog/_facet_layout.html.erb +2 -2
- data/app/views/catalog/_show_main_content.html.erb +5 -11
- data/app/views/catalog/_show_tools.html.erb +1 -14
- data/app/views/catalog/facet.html.erb +3 -3
- data/app/views/catalog/index.html.erb +3 -0
- data/app/views/catalog/show.html.erb +1 -6
- data/app/views/layouts/blacklight/base.html.erb +4 -5
- data/app/views/record_mailer/email_record.text.erb +4 -3
- data/app/views/record_mailer/sms_record.text.erb +4 -4
- data/blacklight.gemspec +2 -2
- data/config/importmap.rb +1 -1
- data/config/locales/blacklight.ar.yml +209 -232
- data/config/locales/blacklight.ca.yml +0 -6
- data/config/locales/blacklight.de.yml +197 -215
- data/config/locales/blacklight.en.yml +2 -6
- data/config/locales/blacklight.es.yml +196 -215
- data/config/locales/blacklight.fr.yml +196 -219
- data/config/locales/blacklight.hu.yml +193 -212
- data/config/locales/blacklight.it.yml +197 -215
- data/config/locales/blacklight.nl.yml +193 -212
- data/config/locales/blacklight.pt-BR.yml +195 -215
- data/config/locales/blacklight.sq.yml +193 -212
- data/config/locales/blacklight.zh.yml +194 -213
- data/docker-compose.yml +1 -0
- data/lib/blacklight/configuration/session_tracking_config.rb +45 -0
- data/lib/blacklight/configuration/view_config.rb +0 -4
- data/lib/blacklight/configuration.rb +8 -4
- data/lib/blacklight/engine.rb +6 -7
- data/lib/blacklight/routes/searchable.rb +1 -0
- data/lib/generators/blacklight/assets/importmap_generator.rb +9 -8
- data/lib/generators/blacklight/assets/propshaft_generator.rb +11 -2
- data/lib/generators/blacklight/assets/sprockets_generator.rb +2 -0
- data/lib/generators/blacklight/assets_generator.rb +3 -1
- data/lib/generators/blacklight/install_generator.rb +3 -1
- data/lib/generators/blacklight/templates/solr_document.rb +0 -6
- data/package.json +7 -4
- data/rollup.config.js +11 -1
- data/spec/components/blacklight/document_component_spec.rb +66 -15
- data/spec/components/blacklight/header_component_spec.rb +20 -0
- data/spec/components/blacklight/response/view_type_component_spec.rb +17 -0
- data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
- data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +29 -0
- data/spec/components/blacklight/{search_context_component_spec.rb → search_context/server_item_pagination_component_spec.rb} +15 -4
- data/spec/controllers/bookmarks_controller_spec.rb +1 -1
- data/spec/controllers/catalog_controller_spec.rb +18 -6
- data/spec/features/component_template_override_spec.rb +8 -0
- data/spec/features/modal_spec.rb +12 -0
- data/spec/features/sitelinks_search_box_spec.rb +13 -0
- data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -1
- data/spec/helpers/blacklight_helper_spec.rb +0 -56
- data/spec/helpers/catalog_helper_spec.rb +56 -0
- data/spec/lib/blacklight/configuration/session_tracking_config_spec.rb +38 -0
- data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +2 -2
- data/spec/models/blacklight/configuration_spec.rb +2 -2
- data/spec/models/blacklight/icon_spec.rb +0 -2
- data/spec/models/blacklight/search_builder_spec.rb +3 -3
- data/spec/models/blacklight/solr/request_spec.rb +2 -2
- data/spec/models/record_mailer_spec.rb +36 -23
- data/spec/presenters/blacklight/document_presenter_spec.rb +1 -0
- data/spec/presenters/blacklight/field_presenter_spec.rb +2 -2
- data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
- data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
- data/spec/presenters/pipeline_spec.rb +13 -2
- data/spec/routing/catalog_routing_spec.rb +4 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/view_component_test_helpers.rb +21 -0
- data/spec/test_app_templates/Gemfile.extra +4 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +8 -0
- data/spec/views/catalog/_document.html.erb_spec.rb +22 -1
- data/spec/views/catalog/_document_list.html.erb_spec.rb +7 -2
- data/spec/views/catalog/_show_tools.html.erb_spec.rb +2 -2
- data/spec/views/catalog/index.json.jbuilder_spec.rb +1 -1
- data/tasks/blacklight.rake +1 -1
- metadata +39 -21
- data/app/components/blacklight/search_context_component.rb +0 -68
- data/app/models/concerns/blacklight/document/email.rb +0 -27
- data/app/models/concerns/blacklight/document/sms.rb +0 -25
- data/spec/features/sitelinks_search_box.rb +0 -13
- data/spec/models/blacklight/document/email_spec.rb +0 -57
- data/spec/models/blacklight/document/sms_spec.rb +0 -58
- data/spec/support/view_component_capybara_test_helpers.rb +0 -8
- /data/app/components/blacklight/{search_context_component.html.erb → search_context/server_item_pagination_component.html.erb} +0 -0
|
@@ -6,8 +6,6 @@ module Blacklight::BlacklightHelperBehavior
|
|
|
6
6
|
include Blacklight::LayoutHelperBehavior
|
|
7
7
|
include Blacklight::IconHelperBehavior
|
|
8
8
|
|
|
9
|
-
# @!group Layout helpers
|
|
10
|
-
|
|
11
9
|
##
|
|
12
10
|
# Get the name of this application from an i18n string
|
|
13
11
|
# key: blacklight.application_name
|
|
@@ -23,63 +21,6 @@ module Blacklight::BlacklightHelperBehavior
|
|
|
23
21
|
end
|
|
24
22
|
end
|
|
25
23
|
|
|
26
|
-
##
|
|
27
|
-
# Get the page's HTML title
|
|
28
|
-
#
|
|
29
|
-
# @return [String]
|
|
30
|
-
def render_page_title
|
|
31
|
-
(content_for(:page_title) if content_for?(:page_title)) || @page_title || application_name
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
##
|
|
35
|
-
# Create <link rel="alternate"> links from a documents dynamically
|
|
36
|
-
# provided export formats.
|
|
37
|
-
#
|
|
38
|
-
# Returns empty string if no links available.
|
|
39
|
-
#
|
|
40
|
-
# @param [SolrDocument] document
|
|
41
|
-
# @param [Hash] options
|
|
42
|
-
# @option options [Boolean] :unique ensures only one link is output for every
|
|
43
|
-
# content type, e.g. as required by atom
|
|
44
|
-
# @option options [Array<String>] :exclude array of format shortnames to not include in the output
|
|
45
|
-
# @return [String]
|
|
46
|
-
def render_link_rel_alternates(document = @document, options = {})
|
|
47
|
-
return if document.nil?
|
|
48
|
-
|
|
49
|
-
document_presenter(document).link_rel_alternates(options)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
##
|
|
53
|
-
# Render classes for the <body> element
|
|
54
|
-
# @return [String]
|
|
55
|
-
def render_body_class
|
|
56
|
-
extra_body_classes.join " "
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
##
|
|
60
|
-
# List of classes to be applied to the <body> element
|
|
61
|
-
# @see render_body_class
|
|
62
|
-
# @return [Array<String>]
|
|
63
|
-
def extra_body_classes
|
|
64
|
-
@extra_body_classes ||= ["blacklight-#{controller.controller_name}", "blacklight-#{[controller.controller_name, controller.action_name].join('-')}"]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
##
|
|
68
|
-
# Get the current "view type" (and ensure it is a valid type)
|
|
69
|
-
#
|
|
70
|
-
# @param [Hash] query_params the query parameters to check
|
|
71
|
-
# @return [Symbol]
|
|
72
|
-
def document_index_view_type query_params = params
|
|
73
|
-
view_param = query_params[:view]
|
|
74
|
-
view_param ||= session[:preferred_view]
|
|
75
|
-
if view_param && document_index_views.key?(view_param.to_sym)
|
|
76
|
-
view_param.to_sym
|
|
77
|
-
else
|
|
78
|
-
default_document_index_view_type
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# @!group Search result helpers
|
|
83
24
|
##
|
|
84
25
|
# Render a partial of an arbitrary format inside a
|
|
85
26
|
# template of a different format. (e.g. render an HTML
|
|
@@ -96,46 +37,4 @@ module Blacklight::BlacklightHelperBehavior
|
|
|
96
37
|
self.formats = old_formats
|
|
97
38
|
nil
|
|
98
39
|
end
|
|
99
|
-
|
|
100
|
-
##
|
|
101
|
-
# Should we render a grouped response (because the response
|
|
102
|
-
# contains a grouped response instead of the normal response)
|
|
103
|
-
#
|
|
104
|
-
# Default to false if there's no response object available (sometimes the case
|
|
105
|
-
# for tests, but might happen in other circumstances too..)
|
|
106
|
-
# @return [Boolean]
|
|
107
|
-
def render_grouped_response? response = @response
|
|
108
|
-
response&.grouped?
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
##
|
|
112
|
-
# Returns a document presenter for the given document
|
|
113
|
-
def document_presenter(document)
|
|
114
|
-
document_presenter_class(document).new(document, self)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
##
|
|
118
|
-
# Override this method if you want to use a differnet presenter for your documents
|
|
119
|
-
# @param [Blacklight::Document] _document optional, here for extension + backwards compatibility only
|
|
120
|
-
def document_presenter_class(_document = nil)
|
|
121
|
-
case action_name
|
|
122
|
-
when 'show', 'citation'
|
|
123
|
-
blacklight_config.view_config(:show, action_name: action_name).document_presenter_class
|
|
124
|
-
else
|
|
125
|
-
blacklight_config.view_config(document_index_view_type, action_name: action_name).document_presenter_class
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# @return [Class]
|
|
130
|
-
def search_bar_presenter_class
|
|
131
|
-
blacklight_config.view_config(action_name: :index).search_bar_presenter_class
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# @!group Layout helpers
|
|
135
|
-
##
|
|
136
|
-
# Open Search discovery tag for HTML <head> links
|
|
137
|
-
# @return [String]
|
|
138
|
-
def opensearch_description_tag title, href
|
|
139
|
-
tag :link, href: href, title: title, type: "application/opensearchdescription+xml", rel: "search"
|
|
140
|
-
end
|
|
141
40
|
end
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
module Blacklight::CatalogHelperBehavior
|
|
5
5
|
include Blacklight::ConfigurationHelperBehavior
|
|
6
6
|
include Blacklight::ComponentHelperBehavior
|
|
7
|
+
include Blacklight::DocumentHelperBehavior
|
|
7
8
|
include Blacklight::FacetsHelperBehavior
|
|
8
9
|
include Blacklight::RenderPartialsHelperBehavior
|
|
9
10
|
|
|
@@ -113,40 +114,6 @@ module Blacklight::CatalogHelperBehavior
|
|
|
113
114
|
(@response.rows if @response && @response.rows > 0) || params.fetch(:per_page, blacklight_config.default_per_page).to_i
|
|
114
115
|
end
|
|
115
116
|
|
|
116
|
-
##
|
|
117
|
-
# Get the classes to add to a document's div
|
|
118
|
-
#
|
|
119
|
-
# @param [Blacklight::Document] document
|
|
120
|
-
# @return [String]
|
|
121
|
-
def render_document_class(document = @document)
|
|
122
|
-
types = document_presenter(document).display_type
|
|
123
|
-
return if types.blank?
|
|
124
|
-
|
|
125
|
-
Array(types).compact.map do |t|
|
|
126
|
-
"#{document_class_prefix}#{t.try(:parameterize) || t}"
|
|
127
|
-
end.join(' ')
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
##
|
|
131
|
-
# Return a prefix for the document classes infered from the document
|
|
132
|
-
# @see #render_document_class
|
|
133
|
-
# @return [String]
|
|
134
|
-
def document_class_prefix
|
|
135
|
-
'blacklight-'
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
##
|
|
139
|
-
# Render the sidebar partial for a document
|
|
140
|
-
# This is used as an integration point by downstream apps to add to the
|
|
141
|
-
# default sidebar.
|
|
142
|
-
# See: https://github.com/geoblacklight/geoblacklight/blob/7d3c31c7af3362879b97e2c1351a2496c728c59c/app/helpers/blacklight_helper.rb#L7
|
|
143
|
-
#
|
|
144
|
-
# @param [SolrDocument] document
|
|
145
|
-
# @return [String]
|
|
146
|
-
def render_document_sidebar_partial(document)
|
|
147
|
-
render 'show_sidebar', document: document
|
|
148
|
-
end
|
|
149
|
-
|
|
150
117
|
##
|
|
151
118
|
# Should we display the sort and per page widget?
|
|
152
119
|
#
|
|
@@ -167,26 +134,6 @@ module Blacklight::CatalogHelperBehavior
|
|
|
167
134
|
response.limit_value > 0
|
|
168
135
|
end
|
|
169
136
|
|
|
170
|
-
##
|
|
171
|
-
# return the Bookmarks on a set of documents (all bookmarks on the page)
|
|
172
|
-
# @private
|
|
173
|
-
# @return [Enumerable<Bookmark>]
|
|
174
|
-
def current_bookmarks
|
|
175
|
-
@current_bookmarks ||= begin
|
|
176
|
-
documents = @document.presence || @response.documents
|
|
177
|
-
current_or_guest_user.bookmarks_for_documents(Array(documents)).to_a
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
private :current_bookmarks
|
|
181
|
-
|
|
182
|
-
##
|
|
183
|
-
# Check if the document is in the user's bookmarks
|
|
184
|
-
# @param [Blacklight::Document] document
|
|
185
|
-
# @return [Boolean]
|
|
186
|
-
def bookmarked? document
|
|
187
|
-
current_bookmarks.any? { |x| x.document_id == document.id && x.document_type == document.class }
|
|
188
|
-
end
|
|
189
|
-
|
|
190
137
|
# Render an html <title> appropriate string for a selected facet field and values
|
|
191
138
|
#
|
|
192
139
|
# @see #render_search_to_page_title
|
|
@@ -233,6 +180,32 @@ module Blacklight::CatalogHelperBehavior
|
|
|
233
180
|
constraints.join(' / ')
|
|
234
181
|
end
|
|
235
182
|
|
|
183
|
+
##
|
|
184
|
+
# Should we render a grouped response (because the response
|
|
185
|
+
# contains a grouped response instead of the normal response)
|
|
186
|
+
#
|
|
187
|
+
# Default to false if there's no response object available (sometimes the case
|
|
188
|
+
# for tests, but might happen in other circumstances too..)
|
|
189
|
+
# @return [Boolean]
|
|
190
|
+
def render_grouped_response? response = @response
|
|
191
|
+
response&.grouped?
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
##
|
|
195
|
+
# Get the current "view type" (and ensure it is a valid type)
|
|
196
|
+
#
|
|
197
|
+
# @param [Hash] query_params the query parameters to check
|
|
198
|
+
# @return [Symbol]
|
|
199
|
+
def document_index_view_type query_params = params || {}
|
|
200
|
+
view_param = query_params[:view]
|
|
201
|
+
view_param ||= session[:preferred_view] if respond_to?(:session)
|
|
202
|
+
if view_param && document_index_views.key?(view_param.to_sym)
|
|
203
|
+
view_param.to_sym
|
|
204
|
+
else
|
|
205
|
+
default_document_index_view_type
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
236
209
|
private
|
|
237
210
|
|
|
238
211
|
# @param [String] format
|
|
@@ -2,17 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Blacklight
|
|
4
4
|
module ComponentHelperBehavior
|
|
5
|
-
##
|
|
6
|
-
# Render "document actions" area for navigation header
|
|
7
|
-
# (normally renders "Saved Searches", "History", "Bookmarks")
|
|
8
|
-
# These things are added by add_nav_action
|
|
9
|
-
#
|
|
10
|
-
# @param [Hash] options
|
|
11
|
-
# @return [String]
|
|
12
|
-
def render_nav_actions(options = {}, &block)
|
|
13
|
-
render_filtered_partials(blacklight_config.navbar.partials, options, &block)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
5
|
##
|
|
17
6
|
# Render "document actions" area for search results view
|
|
18
7
|
# (normally renders next to title in the list view)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Helper methods for catalog-like controllers that work with documents
|
|
4
|
+
module Blacklight::DocumentHelperBehavior
|
|
5
|
+
##
|
|
6
|
+
# Get the classes to add to a document's div
|
|
7
|
+
#
|
|
8
|
+
# @param [Blacklight::Document] document
|
|
9
|
+
# @return [String]
|
|
10
|
+
def render_document_class(document = @document)
|
|
11
|
+
types = document_presenter(document).display_type
|
|
12
|
+
return if types.blank?
|
|
13
|
+
|
|
14
|
+
Array(types).compact.map do |t|
|
|
15
|
+
"#{document_class_prefix}#{t.try(:parameterize) || t}"
|
|
16
|
+
end.join(' ')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Return a prefix for the document classes infered from the document
|
|
21
|
+
# @see #render_document_class
|
|
22
|
+
# @return [String]
|
|
23
|
+
def document_class_prefix
|
|
24
|
+
'blacklight-'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Render the sidebar partial for a document
|
|
29
|
+
# This is used as an integration point by downstream apps to add to the
|
|
30
|
+
# default sidebar.
|
|
31
|
+
# See: https://github.com/geoblacklight/geoblacklight/blob/7d3c31c7af3362879b97e2c1351a2496c728c59c/app/helpers/blacklight_helper.rb#L7
|
|
32
|
+
#
|
|
33
|
+
# @param [SolrDocument] document
|
|
34
|
+
# @return [String]
|
|
35
|
+
def render_document_sidebar_partial(document)
|
|
36
|
+
render 'show_sidebar', document: document
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# return the Bookmarks on a set of documents (all bookmarks on the page)
|
|
41
|
+
# @private
|
|
42
|
+
# @return [Enumerable<Bookmark>]
|
|
43
|
+
def current_bookmarks
|
|
44
|
+
@current_bookmarks ||= begin
|
|
45
|
+
documents = @document.presence || @response.documents
|
|
46
|
+
current_or_guest_user.bookmarks_for_documents(Array(documents)).to_a
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
private :current_bookmarks
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Check if the document is in the user's bookmarks
|
|
53
|
+
# @param [Blacklight::Document] document
|
|
54
|
+
# @return [Boolean]
|
|
55
|
+
def bookmarked? document
|
|
56
|
+
current_bookmarks.any? { |x| x.document_id == document.id && x.document_type == document.class }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Returns a document presenter for the given document
|
|
61
|
+
def document_presenter(document)
|
|
62
|
+
document_presenter_class(document).new(document, self)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Override this method if you want to use a differnet presenter for your documents
|
|
67
|
+
# @param [Blacklight::Document] _document optional, here for extension + backwards compatibility only
|
|
68
|
+
def document_presenter_class(_document = nil)
|
|
69
|
+
case action_name
|
|
70
|
+
when 'show', 'citation'
|
|
71
|
+
blacklight_config.view_config(:show, action_name: action_name).document_presenter_class
|
|
72
|
+
else
|
|
73
|
+
blacklight_config.view_config(document_index_view_type, action_name: action_name).document_presenter_class
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -47,5 +47,64 @@ module Blacklight
|
|
|
47
47
|
def container_classes
|
|
48
48
|
'container'
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Render "document actions" area for navigation header
|
|
53
|
+
# (normally renders "Saved Searches", "History", "Bookmarks")
|
|
54
|
+
# These things are added by add_nav_action
|
|
55
|
+
#
|
|
56
|
+
# @param [Hash] options
|
|
57
|
+
# @return [String]
|
|
58
|
+
def render_nav_actions(options = {}, &block)
|
|
59
|
+
render_filtered_partials(blacklight_config.navbar.partials, options, &block)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Open Search discovery tag for HTML <head> links
|
|
64
|
+
# @return [String]
|
|
65
|
+
def opensearch_description_tag title, href
|
|
66
|
+
tag :link, href: href, title: title, type: "application/opensearchdescription+xml", rel: "search"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Get the page's HTML title
|
|
71
|
+
#
|
|
72
|
+
# @return [String]
|
|
73
|
+
def render_page_title
|
|
74
|
+
(content_for(:page_title) if content_for?(:page_title)) || @page_title || application_name
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
##
|
|
78
|
+
# Create <link rel="alternate"> links from a documents dynamically
|
|
79
|
+
# provided export formats.
|
|
80
|
+
#
|
|
81
|
+
# Returns empty string if no links available.
|
|
82
|
+
#
|
|
83
|
+
# @param [SolrDocument] document
|
|
84
|
+
# @param [Hash] options
|
|
85
|
+
# @option options [Boolean] :unique ensures only one link is output for every
|
|
86
|
+
# content type, e.g. as required by atom
|
|
87
|
+
# @option options [Array<String>] :exclude array of format shortnames to not include in the output
|
|
88
|
+
# @return [String]
|
|
89
|
+
def render_link_rel_alternates(document = @document, options = {})
|
|
90
|
+
return if document.nil?
|
|
91
|
+
|
|
92
|
+
document_presenter(document).link_rel_alternates(options)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Render classes for the <body> element
|
|
97
|
+
# @return [String]
|
|
98
|
+
def render_body_class
|
|
99
|
+
extra_body_classes.join " "
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
# List of classes to be applied to the <body> element
|
|
104
|
+
# @see render_body_class
|
|
105
|
+
# @return [Array<String>]
|
|
106
|
+
def extra_body_classes
|
|
107
|
+
@extra_body_classes ||= ["blacklight-#{controller.controller_name}", "blacklight-#{[controller.controller_name, controller.action_name].join('-')}"]
|
|
108
|
+
end
|
|
50
109
|
end
|
|
51
110
|
end
|
|
@@ -59,6 +59,7 @@ render document_component.new(presenter: document_presenter(document), component
|
|
|
59
59
|
if template
|
|
60
60
|
template.render(self, locals.merge(document: doc))
|
|
61
61
|
else
|
|
62
|
+
logger.warn("No template was found for base_name: '#{base_name}', view_type: '#{view_type}' in render_document_partial")
|
|
62
63
|
''
|
|
63
64
|
end
|
|
64
65
|
end
|
|
@@ -43,16 +43,22 @@ module Blacklight::UrlHelperBehavior
|
|
|
43
43
|
# session_tracking_params(SolrDocument.new(id: 123), 7)
|
|
44
44
|
# => { data: { context_href: '/catalog/123/track?counter=7&search_id=999' } }
|
|
45
45
|
def session_tracking_params document, counter, per_page: search_session['per_page'], search_id: current_search_session&.id
|
|
46
|
-
|
|
46
|
+
path_params = { per_page: params.fetch(:per_page, per_page), counter: counter, search_id: search_id }
|
|
47
|
+
if blacklight_config.track_search_session.storage == 'server'
|
|
48
|
+
path_params[:document_id] = document&.id
|
|
49
|
+
path_params[:search_id] = search_id
|
|
50
|
+
end
|
|
51
|
+
path = session_tracking_path(document, path_params)
|
|
47
52
|
return {} if path.nil?
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
context_method = blacklight_config.track_search_session.storage == 'client' ? 'get' : 'post'
|
|
55
|
+
{ data: { context_href: path, context_method: context_method } }
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
##
|
|
53
59
|
# Get the URL for tracking search sessions across pages using polymorphic routing
|
|
54
60
|
def session_tracking_path document, params = {}
|
|
55
|
-
return if document.nil? || !blacklight_config
|
|
61
|
+
return if document.nil? || !blacklight_config.track_search_session.storage
|
|
56
62
|
|
|
57
63
|
if main_app.respond_to?(controller_tracking_method)
|
|
58
64
|
return main_app.public_send(controller_tracking_method, params.merge(id: document))
|
|
@@ -63,6 +69,8 @@ module Blacklight::UrlHelperBehavior
|
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def controller_tracking_method
|
|
72
|
+
return blacklight_config.track_search_session.url_helper if blacklight_config.track_search_session.url_helper
|
|
73
|
+
|
|
66
74
|
"track_#{controller_name}_path"
|
|
67
75
|
end
|
|
68
76
|
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import CheckboxSubmit from './checkbox_submit'
|
|
1
|
+
import CheckboxSubmit from 'blacklight/checkbox_submit'
|
|
3
2
|
|
|
4
|
-
const BookmarkToggle = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (form) new CheckboxSubmit(form).clicked(e);
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
Blacklight.doBookmarkToggleBehavior.selector = 'form.bookmark-toggle';
|
|
3
|
+
const BookmarkToggle = (e) => {
|
|
4
|
+
if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) {
|
|
5
|
+
const form = e.target.closest('form')
|
|
6
|
+
if (form) new CheckboxSubmit(form).clicked(e);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
})()
|
|
10
|
+
document.addEventListener('click', BookmarkToggle);
|
|
18
11
|
|
|
19
12
|
export default BookmarkToggle
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const ButtonFocus = (
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const ButtonFocus = (e) => {
|
|
2
|
+
// Button clicks should change focus. As of 10/3/19, Firefox for Mac and
|
|
3
|
+
// Safari both do not set focus to a button on button click.
|
|
4
|
+
// See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
|
|
5
|
+
if (e.target.matches('[data-toggle="collapse"]') || e.target.matches('[data-bs-toggle="collapse"]')) {
|
|
6
|
+
e.target.focus()
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
document.addEventListener('click', ButtonFocus)
|
|
11
11
|
|
|
12
12
|
export default ButtonFocus
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import BookmarkToggle from '
|
|
2
|
-
import ButtonFocus from '
|
|
3
|
-
import Modal from '
|
|
4
|
-
import SearchContext from '
|
|
5
|
-
import Core from '
|
|
1
|
+
import BookmarkToggle from 'blacklight/bookmark_toggle'
|
|
2
|
+
import ButtonFocus from 'blacklight/button_focus'
|
|
3
|
+
import Modal from 'blacklight/modal'
|
|
4
|
+
import SearchContext from 'blacklight/search_context'
|
|
5
|
+
import Core from 'blacklight/core'
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
BookmarkToggle,
|
|
9
9
|
ButtonFocus,
|
|
10
10
|
Modal,
|
|
11
11
|
SearchContext,
|
|
12
|
+
Core,
|
|
12
13
|
onLoad: Core.onLoad
|
|
13
14
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
<div data-blacklight-modal="container">
|
|
34
34
|
<div class="modal-header">
|
|
35
|
-
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
35
|
+
<button type="button" class="close" data-bl-dismiss="modal" aria-hidden="true">×</button>
|
|
36
36
|
<h3 class="modal-title">Request Placed</h3>
|
|
37
37
|
</div>
|
|
38
38
|
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
<div class="modal-footer">
|
|
46
|
-
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
46
|
+
<button type="button" class="btn btn-secondary" data-bl-dismiss="modal">Close</button>
|
|
47
47
|
</div>
|
|
48
48
|
</div>
|
|
49
49
|
|
|
@@ -52,17 +52,10 @@
|
|
|
52
52
|
can be a turbo-stream that defines some HTML fragementsand where on the page to put them:
|
|
53
53
|
https://turbo.hotwired.dev/handbook/streams
|
|
54
54
|
*/
|
|
55
|
-
import
|
|
56
|
-
import ModalForm from './modalForm'
|
|
55
|
+
import ModalForm from 'blacklight/modalForm'
|
|
57
56
|
|
|
58
57
|
const Modal = (() => {
|
|
59
|
-
|
|
60
|
-
// Create lazily if someone else created first.
|
|
61
|
-
if (Blacklight.modal === undefined) {
|
|
62
|
-
Blacklight.modal = {};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const modal = Blacklight.modal
|
|
58
|
+
const modal = {}
|
|
66
59
|
|
|
67
60
|
// a Bootstrap modal div that should be already on the page hidden
|
|
68
61
|
modal.modalSelector = '#blacklight-modal';
|
|
@@ -83,20 +76,19 @@ const Modal = (() => {
|
|
|
83
76
|
modal.containerSelector = '[data-blacklight-modal~=container]';
|
|
84
77
|
|
|
85
78
|
// Called on fatal failure of ajax load, function returns content
|
|
86
|
-
// to show to user in modal. Right now called only for
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console.error('Server error:', this.url, jqXHR.status, errorThrown);
|
|
79
|
+
// to show to user in modal. Right now called only for network errors.
|
|
80
|
+
modal.onFailure = function (error) {
|
|
81
|
+
console.error('Server error:', this.url, error);
|
|
90
82
|
|
|
91
83
|
const contents = `<div class="modal-header">
|
|
92
84
|
<div class="modal-title">There was a problem with your request.</div>
|
|
93
|
-
<button type="button" class="blacklight-modal-close btn-close close" data-
|
|
94
|
-
<span aria-hidden="true">×</span>
|
|
85
|
+
<button type="button" class="blacklight-modal-close btn-close close" data-bl-dismiss="modal" aria-label="Close">
|
|
86
|
+
<span aria-hidden="true" class="visually-hidden">×</span>
|
|
95
87
|
</button>
|
|
96
88
|
</div>
|
|
97
89
|
<div class="modal-body">
|
|
98
90
|
<p>Expected a successful response from the server, but got an error</p>
|
|
99
|
-
<pre>${this.
|
|
91
|
+
<pre>${this.url}\n${error}</pre>
|
|
100
92
|
</div>`
|
|
101
93
|
|
|
102
94
|
document.querySelector(`${modal.modalSelector} .modal-content`).innerHTML = contents
|
|
@@ -105,10 +97,16 @@ const Modal = (() => {
|
|
|
105
97
|
}
|
|
106
98
|
|
|
107
99
|
// Add the passed in contents to the modal and display it.
|
|
108
|
-
modal.receiveAjax = function (contents) {
|
|
100
|
+
modal.receiveAjax = function (contents) {
|
|
109
101
|
const domparser = new DOMParser();
|
|
110
102
|
const dom = domparser.parseFromString(contents, "text/html")
|
|
111
|
-
|
|
103
|
+
// If there is a containerSelector on the document, use its children.
|
|
104
|
+
let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)
|
|
105
|
+
if (elements.length == 0) {
|
|
106
|
+
// If the containerSelector wasn't found, use the whole document
|
|
107
|
+
elements = dom.body.childNodes
|
|
108
|
+
}
|
|
109
|
+
|
|
112
110
|
document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(...elements)
|
|
113
111
|
|
|
114
112
|
modal.show();
|
|
@@ -134,28 +132,30 @@ modal.receiveAjax = function (contents) {
|
|
|
134
132
|
// into one selector with a comma, so if something matches BOTH selectors, it
|
|
135
133
|
// still only gets the event handler called once.
|
|
136
134
|
document.addEventListener('click', (e) => {
|
|
137
|
-
if (e.target.
|
|
135
|
+
if (e.target.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))
|
|
138
136
|
modal.modalAjaxLinkClick(e)
|
|
139
|
-
else if (e.target.
|
|
137
|
+
else if (e.target.closest('[data-bl-dismiss="modal"]'))
|
|
140
138
|
modal.hide()
|
|
141
139
|
})
|
|
142
140
|
};
|
|
143
141
|
|
|
144
142
|
modal.hide = function (el) {
|
|
145
|
-
const dom = document.querySelector(
|
|
143
|
+
const dom = document.querySelector(modal.modalSelector)
|
|
146
144
|
|
|
147
145
|
if (!dom.open) return
|
|
148
146
|
dom.close()
|
|
149
147
|
}
|
|
150
148
|
|
|
151
149
|
modal.show = function(el) {
|
|
152
|
-
const dom = document.querySelector(
|
|
150
|
+
const dom = document.querySelector(modal.modalSelector)
|
|
153
151
|
|
|
154
152
|
if (dom.open) return
|
|
155
153
|
dom.showModal()
|
|
156
154
|
}
|
|
157
155
|
|
|
158
156
|
modal.setupModal()
|
|
157
|
+
|
|
158
|
+
return modal;
|
|
159
159
|
})()
|
|
160
160
|
|
|
161
161
|
export default Modal
|