umlaut 4.0.3 → 4.1.0.pre.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +6 -0
  3. data/app/assets/javascripts/umlaut/update_html.js +81 -23
  4. data/app/assets/stylesheets/umlaut/_misc.scss +1 -2
  5. data/app/assets/stylesheets/umlaut/_resolve.scss +44 -10
  6. data/app/controllers/export_email_controller.rb +2 -2
  7. data/app/controllers/feedback_controller.rb +1 -1
  8. data/app/controllers/umlaut/controller_behavior.rb +14 -0
  9. data/app/controllers/umlaut_configurable.rb +52 -21
  10. data/app/helpers/open_search_helper.rb +1 -1
  11. data/app/helpers/resolve_helper.rb +36 -35
  12. data/app/helpers/umlaut/section_highlights.rb +85 -0
  13. data/app/mixin_logic/metadata_helper.rb +11 -5
  14. data/app/models/collection.rb +129 -96
  15. data/app/models/dispatched_service.rb +4 -0
  16. data/app/models/referent.rb +7 -1
  17. data/app/models/request.rb +21 -0
  18. data/app/models/service_store.rb +16 -3
  19. data/app/presentation/section_renderer.rb +16 -17
  20. data/app/service_adaptors/blacklight.rb +11 -4
  21. data/app/service_adaptors/internet_archive.rb +58 -25
  22. data/app/service_adaptors/isi.rb +14 -4
  23. data/app/service_adaptors/jcr.rb +13 -4
  24. data/app/views/resolve/_fulltext.html.erb +1 -1
  25. data/app/views/resolve/_section_display.html.erb +1 -1
  26. data/app/views/resolve/_service_errors.html.erb +3 -3
  27. data/app/views/search/books.html.erb +1 -1
  28. data/app/views/search/journal_search.html.erb +2 -1
  29. data/app/views/search/journals.html.erb +2 -1
  30. data/db/orig_fixed_data/service_type_values.yml +15 -37
  31. data/lib/aws_product_sign.rb +1 -1
  32. data/lib/generators/templates/umlaut_services.yml +5 -2
  33. data/lib/generators/umlaut/install_generator.rb +1 -0
  34. data/{app/models → lib}/service_type_value.rb +36 -22
  35. data/lib/umlaut/routes.rb +34 -5
  36. data/lib/umlaut/test_help.rb +159 -0
  37. data/lib/umlaut/version.rb +2 -2
  38. data/lib/umlaut.rb +44 -9
  39. metadata +10 -8
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjMzYmMzYzc5YjVjOTY2MDYzZjZmOGVlOThhZTZkYTZhZWY4ZTA4Mw==
4
+ NThjZGZmNjFlZTgwNGVjMjg0MjJkODAwNWI4NjRiYzRjNmNlNGY5OQ==
5
5
  data.tar.gz: !binary |-
6
- YzMzNzA4Y2FhOTViZDBmYjFiNGM4N2UxNDhmOTU0MjdhN2VmYWI3OQ==
6
+ OGQ0MGRlYzJiNmViZTQxMDQ4Y2U4MWYzOWY3MjljOWQwMWVjYmRlZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MTE4MWM0YjNkYzdkYTE3NWVmNmJhNmUyYTkxNDRkNTVjNDAyYTlkYTc5Y2M5
10
- N2YyNzNmMzAzZDc5YzEyM2Q4YzhlMjM0ZTk4Y2RhOGYxNzQzODcxNDIzMTQz
11
- YWQwZjQyNjMyMDQwOGZhZWQ1ZDRjNWZlZWQ0M2NiZjE5ZDYxODE=
9
+ ZGI4Njk3ZmExYzljNDcwMTMzZjA5YWQ3NTYyOGY1YWYyYTZmZjNlNTAxNDAz
10
+ MWYyNmZkYmJiNGEwYWViNTQ4ZDA4OWY2OGQ2MTA4ZGZiYjZkYzU5ZDEzZWQx
11
+ YWY3OTYwOGJiZmU4MzU5ZTJhODgzMThjOTRjNmNlMmZhOGI0NjA=
12
12
  data.tar.gz: !binary |-
13
- ZDQ0Nzk0NDkwNGQ2NmU1Y2I1ZjdmMDE4OGRhN2RlZDdkNDY5MjUwMTAxNjcw
14
- NWI2ZDI3NzMzZjc2MTE2Yjc5NDMyNTJjYmJhOWQzMTQyYWVlN2U4M2Y0YTMx
15
- MWJiNzEwNGJhYWUzZjA1OTlmOTE4NjY1NGQxNDE3MGEwNjM0MDg=
13
+ NTlkNWFhNDgxMjk1MWFkYWJiZGE1ZjQ5OGE2YWJkNzc2YmIwODhiODNjMTRk
14
+ NmU5ODU2YTIwMWFmMDQwNGQxNTRhOGNmODFmNzVkMmU5MzcxMDM0OGYxODgx
15
+ ZTQ0ZGI1MjE0ZmQ3ZmIzMzFmNWMyMDNhZjgyMzhhOWNmY2I2ODI=
data/README.md CHANGED
@@ -81,6 +81,12 @@ Tests use the vcr gem where appropriate. See `./test/support/test_with_cassette`
81
81
  gem skeleton was created with `rails plugin new`, which creates a dummy app
82
82
  that tests are run in context of, at `./test/dummy`.
83
83
 
84
+ The vcr gem is used to record HTTP transactions for tests.
85
+
86
+ There are some helpful methods for setting up and asserting in tests in
87
+ Umlaut::TestHelp, which are used in Umlaut itself and can also be used
88
+ in local apps or Umlaut plugins.
89
+
84
90
  See also: https://github.com/team-umlaut/umlaut/wiki/Developing
85
91
 
86
92
  ## Source
@@ -1,4 +1,12 @@
1
- /* update_html.js: Provide functions to update content on page with background responses from Umlaut. Used by Umlaut itself, as well as by third party callers.*/
1
+ /* update_html.js:
2
+ * Provide functions to update content on page with background responses from Umlaut.
3
+ * Used by Umlaut itself, as well as by third party callers.
4
+ *
5
+ * This is compiled into a standalone top-level JS file, for src'ing by third
6
+ * party callers.
7
+ *
8
+ * More information on use at https://github.com/team-umlaut/umlaut/wiki/JQuery-Content-Utility
9
+ */
2
10
  (function($) {
3
11
 
4
12
  function SectionTarget(config) {
@@ -6,11 +14,14 @@
6
14
  $.extend(this, config);
7
15
 
8
16
  //Defaults
9
- if (this.selector == undefined)
17
+ if (typeof(this.selector) == 'undefined')
10
18
  this.selector = "#" + this.umlaut_section_id;
11
- if (this.position == undefined)
19
+ if (typeof(this.position) == 'undefined')
12
20
  this.position = "html";
13
-
21
+ // Container must be a JQuery object, if it's not
22
+ // passed in, use $(document)
23
+ if (typeof(this.container) == 'undefined')
24
+ this.container = $(document); // default container is document
14
25
  }
15
26
  //Callback default to no-op function please.
16
27
  var noop = function() {};
@@ -19,53 +30,100 @@
19
30
  SectionTarget.prototype.complete = noop;
20
31
 
21
32
  SectionTarget.prototype.ensure_placement_destination = function() {
22
- if ( this.selector == undefined) {
33
+ if ( typeof(this.selector) == 'undefined') {
23
34
  return null;
24
35
  }
25
36
 
26
37
  //Already have it cached?
27
38
  if ( this.host_div_element ) {
28
39
  return this.host_div_element;
29
- }
40
+ }
30
41
 
31
- var new_div = $('<div class="umlaut" style="display:none"></div>');
42
+ // Create an empty div to hold our content
43
+ var new_div = $('<div class="umlaut" style="display:none"></div>');
44
+
32
45
  // Find the first thing matched by selector, and call the
33
- // method specified in "action" string on it, giving it our
46
+ // method specified in "position" string on it, giving it our
34
47
  // HTML to replace. This works because our actions are
35
48
  // all arguments that will take one method: html, before, after, append,
36
49
  // prepend.
37
- $(this.selector).eq(0)[ this.position ]( new_div );
50
+ this.container.find(this.selector).eq(0)[ this.position ]( new_div );
38
51
 
39
52
  //Cache for later
40
53
  this.host_div_element = new_div;
41
54
  return this.host_div_element;
42
55
  };
43
-
44
56
 
45
57
  // Define an object constructor on the global window object
46
58
  // For our UmlautHtmlUpdater object.
47
59
  //
48
- // Third 'locale' arg is optional locale string eg 'en', 'de'
60
+ // You need to pass the Umlaut Base URL, as well as an OpenURL kev context
61
+ // object. There are additional optional parameters.
62
+ //
63
+ // There are two argument formats you can call `new HTMLUpdater` with.
64
+ // Positional allows you to pass umlaut base and OpenURL:
65
+ // var updater = new Umlaut.HtmlUpdater("http://umlaut.example.edu", "au=Smith&ti=Book")
66
+ //
67
+ // Or named argument style allows you to pass additional parameters,
68
+ // including locale and container.
69
+ //
70
+ // var updater = new Umlaut.HtmlUpdater({
71
+ // umlaut_base: "http://umlaut.example.edu",
72
+ // context_object: "au=Smith&ti=Book",
73
+ // locale: "de",
74
+ // container: "#selector"
75
+ // });
76
+ //
77
+ //
78
+ //
79
+ // The optional 'locale' arg is a locale string eg 'en', 'de'
80
+ //
81
+ // The optional 'container' argument is a selector, DOM element, OR
82
+ // jQuery object. The container limits the updater's content
83
+ // replacements (controlled by selectors on individual sections) to within
84
+ // the container given.
49
85
  //
50
86
  // Note this object is used by external sites as part of the JQuery updater
51
87
  // javascript API. This is API, which has to be callable by non-Umlaut sites.
52
88
  // Try not to change the method signature in incompatible ways.
53
- function HtmlUpdater(umlaut_base, context_object, locale) {
54
- if (context_object == undefined)
55
- context_object = "";
89
+ function HtmlUpdater(first_arg, second_arg, third_arg) {
90
+ if (typeof(first_arg) == "object") {
91
+ // Simply merge arguments object as properties on ourselves.
92
+ $.extend(this, first_arg);
93
+ } else {
94
+ // positional args
95
+ this.umlaut_base = first_arg;
96
+ this.context_object = second_arg;
97
+ this.locale = third_arg;
98
+ }
99
+
100
+ // Argument checking
101
+ if (typeof(this.umlaut_base) == "undefined") {
102
+ throw new Error("new Umlaut.HtmlUpdater: missing umlaut_base (String) argument");
103
+ }
104
+ if (typeof(this.context_object) == "undefined") {
105
+ throw new Error("new Umlaut.HtmlUpdater: missing context_object (String) argument");
106
+ }
107
+
108
+
56
109
 
57
110
  // Remove query string (if present)
58
- umlaut_base = umlaut_base.replace(/\?.*$/, '')
111
+ this.umlaut_base = this.umlaut_base.replace(/\?.*$/, '')
59
112
  // Remove trailing slash
60
- umlaut_base = umlaut_base.replace(/\/$/,'');
61
- this.umlaut_uri = umlaut_base + '/resolve/partial_html_sections?umlaut.response_format=json&' + context_object;
62
- if (locale)
63
- this.umlaut_uri += "&umlaut.locale=" + locale;
113
+ this.umlaut_base = this.umlaut_base.replace(/\/$/,'');
114
+ this.umlaut_uri = this.umlaut_base + '/resolve/partial_html_sections?umlaut.response_format=json&' + this.context_object;
115
+ if (this.locale)
116
+ this.umlaut_uri += "&umlaut.locale=" + this.locale;
64
117
 
65
118
  this.section_targets = [];
66
119
 
67
120
  this.add_section_target = function(config) {
68
- this.section_targets.push( new SectionTarget(config) );
121
+ var target = new SectionTarget(config);
122
+ if (typeof(this.container) !== "undefined") {
123
+ // Turn it into a JQuery object if it wasn't already.
124
+ target.container = $(this.container);
125
+ }
126
+ this.section_targets.push( target );
69
127
  };
70
128
 
71
129
  //default no-op call-backs
@@ -99,11 +157,11 @@
99
157
 
100
158
  var umlaut_html_section = myself.find_umlaut_response_section(umlaut_response, section_target.umlaut_section_id);
101
159
 
102
- if (umlaut_html_section == undefined) {
160
+ if (typeof(umlaut_html_section) == 'undefined') {
103
161
  continue;
104
162
  }
105
163
  var count = null;
106
- if (typeof umlaut_html_section.response_count != "undefined") {
164
+ if (typeof(umlaut_html_section.response_count) != "undefined") {
107
165
  count = parseInt(umlaut_html_section.response_count.value);
108
166
  }
109
167
  var existing_element = section_target.ensure_placement_destination();
@@ -162,7 +220,7 @@
162
220
  };
163
221
 
164
222
  //Put it in a global object, leave space for other things in "Umlaut" later.
165
- if (window.Umlaut == undefined)
223
+ if (typeof(window.Umlaut) == 'undefined')
166
224
  window.Umlaut = new Object();
167
225
  window.Umlaut.HtmlUpdater = HtmlUpdater;
168
226
 
@@ -9,8 +9,7 @@
9
9
  }
10
10
  }
11
11
 
12
- .alert {
13
- font-size: 125%;
12
+ .alert {
14
13
  li {
15
14
  margin-top: 1em;
16
15
  }
@@ -19,6 +19,10 @@
19
19
  padding-left: $umlautIndent;
20
20
  text-indent: -$umlautIndent;
21
21
  }
22
+ // default bold response link if it's in the main section
23
+ .umlaut-main & .response_link {
24
+ font-weight: bold;
25
+ }
22
26
  }
23
27
 
24
28
  .umlaut-section {
@@ -34,24 +38,30 @@
34
38
  @extend .text-muted;
35
39
  }
36
40
 
37
-
41
+ /* In the sidebar, search_inside heading looks better without
42
+ bottom margin, cause of spacing needed for form, it just does. */
43
+ .umlaut-sidebar &.search_inside {
44
+ .section_heading h3 {
45
+ margin-bottom: 0;
46
+ }
47
+ }
38
48
 
39
49
  // Special looks for particular sections
40
- &.fulltext {
50
+ &.fulltext, .page-icons {
41
51
  @include iconed-response;
42
52
  .response_item i {
43
53
  @extend .umlaut_icons-famfamfam-page-text;
44
54
  }
45
55
  }
46
56
 
47
- &.audio {
57
+ &.audio, .sound-icons {
48
58
  @include iconed-response;
49
59
  .response_item i {
50
60
  @extend .umlaut_icons-famfamfam-page-sound;
51
61
  }
52
62
  }
53
63
 
54
- &.excerpts {
64
+ &.excerpts, .book-open-icons {
55
65
  @include iconed-response;
56
66
  .response_item i {
57
67
  @extend .umlaut_icons-famfamfam-book-open;
@@ -62,13 +72,15 @@
62
72
  border: none;
63
73
  }
64
74
 
65
- &.document_delivery {
75
+ &.document_delivery, .book-go-icons {
66
76
  @include iconed-response;
67
77
  .response_item i {
68
78
  @extend .umlaut_icons-famfamfam-book-go;
69
79
  }
70
80
  }
71
81
 
82
+ .response_item
83
+
72
84
  &.related_items {
73
85
  // Margin between the 'cited by' and 'similar' lists
74
86
  .response_list + .response_list {
@@ -77,7 +89,7 @@
77
89
 
78
90
  }
79
91
 
80
- &.holding {
92
+ &.holding, &.book-icons {
81
93
  .response_item i {
82
94
  @extend .umlaut_icons-famfamfam-book;
83
95
  }
@@ -132,8 +144,34 @@
132
144
  .umlaut-section-highlighted {
133
145
  @include umlaut-well($umlautHighlightedSectionBackgroundColor, $umlautHighlightedSectionBorderColor);
134
146
  border-radius: $umlautBorderRadiusExtraLarge;
147
+
148
+ // If a p.alert is in a highlighted section, give it special styling
149
+ // as a ribbon, not a box-in-box.
150
+ .alert {
151
+ margin-left: -12px;
152
+ margin-right: -12px;
153
+
154
+ border-radius: 0;
155
+ border-left: 0;
156
+ border-right: 0;
157
+ }
158
+ // If it's the LAST thing in the highlighted section, do better and merge
159
+ // it with the box itself
160
+ .umlaut_section_content > .alert:last-child {
161
+ margin-bottom: -12px;
162
+ border-bottom-right-radius: $umlautBorderRadiusExtraLarge;
163
+ border-bottom-left-radius: $umlautBorderRadiusExtraLarge;
164
+ }
165
+ .umlaut_section_content > hr {
166
+ border-color: $umlautHighlightedSectionBorderColor;
167
+ margin-left: -12px;
168
+ margin-right: -12px;
169
+ }
170
+
135
171
  }
136
172
 
173
+
174
+
137
175
  .section_prompt {
138
176
  @extend .text-muted;
139
177
  }
@@ -291,10 +329,6 @@
291
329
  font-size: $font-size-base;
292
330
  }
293
331
 
294
- // Resolve Errors
295
- #service_errors_content {
296
- @include umlaut-well($umlautResolveErrorBackgroundColor, $umlautResolveErrorBorderColor);
297
- }
298
332
 
299
333
  a:not(:hover) .coverage_summary {
300
334
  /* even though it's part of a hyperlink, we make it black for distinction */
@@ -11,7 +11,7 @@ class ExportEmailController < UmlautController
11
11
  @fulltexts = @user_request.get_service_type('fulltext', { :refresh=>true })
12
12
  @holdings = @user_request.get_service_type('holding', { :refresh=>true })
13
13
  if valid_email?
14
- Emailer.citation(@email, @user_request, @fulltexts, @holdings).deliver
14
+ action_mailer_deliver Emailer.citation(@email, @user_request, @fulltexts, @holdings)
15
15
  else
16
16
  flash[:alert] = email_validation_error
17
17
  render :email and return
@@ -29,7 +29,7 @@ class ExportEmailController < UmlautController
29
29
  @email = "#{@number}@#{@provider}" unless @number.nil? or @provider.nil?
30
30
  @holding = params[:holding]
31
31
  if valid_txt_number? && valid_txt_holding?
32
- Emailer.short_citation(@email, @user_request, holding_location(@holding), call_number(@holding)).deliver
32
+ action_mailer_deliver Emailer.short_citation(@email, @user_request, holding_location(@holding), call_number(@holding))
33
33
  else
34
34
  flash[:alert] = txt_validation_error
35
35
  render :txt and return
@@ -15,7 +15,7 @@ class FeedbackController < UmlautController
15
15
  )
16
16
  end
17
17
 
18
- FeedbackMailer.feedback(request.host_with_port, to_address, options).deliver
18
+ action_mailer_deliver FeedbackMailer.feedback(request.host_with_port, to_address, options)
19
19
 
20
20
  flash[:alert_success] = "Thanks, your message has been sent."
21
21
 
@@ -87,6 +87,20 @@ module Umlaut::ControllerBehavior
87
87
  end
88
88
  protected :specified_service_groups
89
89
 
90
+ # Call an ActionMailer::Base without deprecation warnings in Rails 4.3,
91
+ # but still work in earlier rails without deliver_later
92
+ #
93
+ # Calls with deliver_later in Rails 4.3. If no ActiveJob queue
94
+ # is set up, no problem default is immediate executor anyway.
95
+ def action_mailer_deliver(mailer)
96
+ if mailer.respond_to?(:deliver_later)
97
+ mailer.deliver_later
98
+ else
99
+ mailer.deliver
100
+ end
101
+ end
102
+ protected :action_mailer_deliver
103
+
90
104
 
91
105
 
92
106
  end
@@ -234,13 +234,12 @@ module UmlautConfigurable
234
234
  # We add a custom method into the resolve_sections array,
235
235
  # ensure_order!.
236
236
  resolve_sections [].extend Module.new do
237
- # Convenience method for re-ordering sections
238
- # Swaps elements if necessary to ensure they are in the specified order.
239
- # For example, make sure holding comes before document_delivery:
240
- # resolve_sections.ensure_order!("holding", "document_delivery")
241
- # Maybe in the future we'll expand this to take variable arguments.
237
+
238
+ # Deprecated. This was a silly confusing way to do this.
239
+ # See #remove and #insert below instead.
242
240
  def self.ensure_order!(first, second)
243
-
241
+ $stderr.puts "resolve_sections.ensure_order! is deprecated, please see resolve_sections.remove and resolve_sections.insert"
242
+
244
243
  list = self
245
244
 
246
245
  index1 = list.index {|s| s[:div_id].to_s == first.to_s}
@@ -250,8 +249,40 @@ module UmlautConfigurable
250
249
 
251
250
  list
252
251
  end
252
+
253
+ # Insert a section_config hash before or after an existing
254
+ # section, by the existing section's div_id
255
+ #
256
+ # resolve_sections.insert_section({:div_id => "new"}, :after => "fulltext")
257
+ # resolve_sections.insert_section( resolve_sections.remove_section("document_deliver"), :before => "fulltext")
258
+ def self.insert_section(section_config, options = {})
259
+ list = self
260
+
261
+ if options[:before]
262
+ i = (list.find_index {|s| s[:div_id].to_s == options[:before].to_s}) || 0
263
+ list.insert(i, section_config)
264
+ elsif options[:after]
265
+ i = (list.find_index {|s| s[:div_id].to_s == options[:after].to_s}) || (list.length - 1)
266
+ list.insert(i + 1, section_config)
267
+ else
268
+ # just add at end of list
269
+ list << section_config
270
+ end
271
+ end
272
+
273
+ # Remove a configuration block with a certain div_id from the configuration entirely,
274
+ # returning the removed configuration block (or nil if none exists).
275
+ # You can re-insert it with #insert if you like.
276
+ def self.remove_section(div_id)
277
+ list = self
278
+ i = list.find_index {|s| s[:div_id].to_s == div_id.to_s}
279
+ return list.delete_at(i) if i
280
+ end
281
+
253
282
  end
254
283
 
284
+
285
+
255
286
  ##########
256
287
  #
257
288
  # Names of these sections can be given in Rails i18n, under key
@@ -277,21 +308,7 @@ module UmlautConfigurable
277
308
  html_area :main
278
309
  partial :fulltext
279
310
  show_partial_only true
280
- end
281
-
282
- add_resolve_sections! do
283
- div_id "search_inside"
284
- html_area :main
285
- partial "search_inside"
286
- show_partial_only true
287
- end
288
-
289
- add_resolve_sections! do
290
- div_id "excerpts"
291
- html_area :main
292
- list_visible_limit 5
293
- visibility :responses_exist
294
- end
311
+ end
295
312
 
296
313
  add_resolve_sections! do
297
314
  div_id "audio"
@@ -351,6 +368,20 @@ module UmlautConfigurable
351
368
  html_area :sidebar
352
369
  visibility :in_progress
353
370
  end
371
+
372
+ add_resolve_sections! do
373
+ div_id "search_inside"
374
+ html_area :sidebar
375
+ partial "search_inside"
376
+ show_partial_only true
377
+ end
378
+
379
+ add_resolve_sections! do
380
+ div_id "excerpts"
381
+ html_area :sidebar
382
+ list_visible_limit 5
383
+ visibility :responses_exist
384
+ end
354
385
 
355
386
  add_resolve_sections! do
356
387
  div_id "related_items"
@@ -1,6 +1,6 @@
1
1
  module OpenSearchHelper
2
2
 
3
3
  def opensearch_template_url
4
- url_for(:controller => "search", :action => "journal_search", :rfr_id => umlaut_config.lookup('rfr_id.opensearch'), :'umlaut.title_search_type' => 'contains', :only_path => false ) + '&amp;rft.jtitle={searchTerms}'
4
+ url_for(:controller => "search", :action => "journal_search", :rfr_id => umlaut_config.lookup!('rfr_ids.opensearch'), :'umlaut.title_search_type' => 'contains', :only_path => false ) + '&amp;rft.jtitle={searchTerms}'
5
5
  end
6
6
  end
@@ -39,45 +39,29 @@ module ResolveHelper
39
39
  # * current Umlaut Request object
40
40
  # * string section id
41
41
  # * array of umlaut ServiceResponses already fetched for this section.
42
- def section_css_classes(umlaut_request, section_id, response_list)
42
+ #
43
+ # third paramter used to exist but was not used, deprecated but left there
44
+ # for now for backwards compat. TODO.
45
+ def section_css_classes(umlaut_request, section_id, unused = nil)
43
46
  classes = ["umlaut-section", section_id]
44
- classes << 'umlaut-section-highlighted' if should_highlight_section?(umlaut_request, section_id, response_list)
47
+ classes << 'umlaut-section-highlighted' if section_highlights(umlaut_request).should_highlight_section?(section_id)
45
48
  return classes
46
49
  end
47
50
 
48
- # Called by #section_css_classes. Decides if a section should get
49
- # highlight styles. Default logic highlights fulltext if present,
50
- # otherwise holdings/docdel sections (in some cases both even if holdings present,
51
- # in some cases just docdel, depending on nature of resource.) This is
52
- # something local institutions may want to supply custom logic for,
53
- # over-ride this method.
54
- #
55
- # This is VERY tricky to get right, BOTH becuase of local policy differences,
56
- # AND becuase umlaut's concurrent service handling means things are changing
57
- # all the time. Umlaut used to just highlight fulltext with responses, that's it.
58
- # But we're trying something more sophisticated. You may want to over-ride with
59
- # something simpler, or something better suited to local policies and conditions.
60
- def should_highlight_section?(umlaut_request, section_id, response_list)
61
- case section_id
62
- when "fulltext"
63
- umlaut_request.get_service_type("fulltext").present?
64
- when "holding"
65
- umlaut_request.get_service_type("holding").present? && umlaut_request.get_service_type("fulltext").empty?
66
- when "document_delivery"
67
- # Only once fulltext and holdings are done being fetched.
68
- # If there's no fulltext or holdings, OR there's holdings, but
69
- # it's a journal type thing, where we probably don't know if the
70
- # particular volume/issue wanted is present.
71
- umlaut_request.get_service_type("fulltext").empty? &&
72
- (! umlaut_request.service_types_in_progress?(["fulltext", "holding"])) && (
73
- umlaut_request.get_service_type("holding").empty? ||
74
- umlaut_request.referent.format == "journal"
75
- )
76
- end
51
+ # Deprecated!
52
+ # Left for backwards compat. TODO.
53
+ def should_highlight_section?(umlaut_request, section_id)
54
+ $stderr.warn "should_highlight_section? is deprecated, use `section_highlighter(umlaut_request).should_highlight_section?(section_id)`"
55
+ highlighted_sections(umlaut_request).include? section_id.to_s
77
56
  end
78
57
 
79
- def app_name
80
- return umlaut_config.app_name
58
+ # Returns a section highlighter for the current umlaut request.
59
+ # (Cached for given @umlaut_request)
60
+ def section_highlights(umlaut_request = @umlaut_request)
61
+ # Need to cache for efficiency, need to cache by request id since we take
62
+ # it as an arg.
63
+ @_section_highlighters ||= {}
64
+ return @_section_highlighters[umlaut_request.id] ||= Umlaut::SectionHighlights.new(umlaut_request)
81
65
  end
82
66
 
83
67
  # size can be 'small', 'medium', or 'large.
@@ -95,7 +79,7 @@ module ResolveHelper
95
79
  def user_entered_citation?(uml_request)
96
80
  return false unless uml_request && uml_request.referrer_id
97
81
  id = uml_request.referrer_id
98
- return id == 'info:sid/sfxit.com:citation' || id == umlaut_config.lookup("rfr_ids.citation") || id == umlaut_config.lookup('rfr_ids.opensearch')
82
+ return id == 'info:sid/sfxit.com:citation' || id == umlaut_config.lookup!("rfr_ids.citation") || id == umlaut_config.lookup!('rfr_ids.opensearch')
99
83
  end
100
84
 
101
85
  def display_not_found_warning?(uml_request)
@@ -235,11 +219,28 @@ module ResolveHelper
235
219
  # in application config resolve_sections list for a specific
236
220
  # part of the page. :main, :sidebar, or :resource_info.
237
221
  def html_sections(area)
238
- umlaut_config.lookup!("resolve_sections", []).find_all do |section|
222
+ config_resolve_sections.find_all do |section|
239
223
  section[:html_area] == area
240
224
  end
241
225
  end
242
226
 
227
+ # Looks up umlaut_config.lookup!("resolve_sections"), then passes it through
228
+ # resolve_sections_filter config if available -- caches result in an iVar, for this
229
+ # action.
230
+ def config_resolve_sections
231
+ unless defined? @_config_resolve_sections
232
+ @_config_resolve_sections = umlaut_config.lookup!("resolve_sections", [])
233
+
234
+ umlaut_config.lookup!("resolve_sections_filter", []).each do |reorder_proc|
235
+ # clone it, so we aren't reordering the original
236
+ @_config_resolve_sections = @_config_resolve_sections.clone
237
+ reorder_proc.call(@user_request, @_config_resolve_sections)
238
+ end
239
+ end
240
+
241
+ return @_config_resolve_sections
242
+ end
243
+
243
244
  def html_section_by_div_id(div_id)
244
245
  umlaut_config.lookup!("resolve_sections", []).find do |defn|
245
246
  defn[:div_id] == div_id