arclight 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/.all-contributorsrc +450 -0
  3. data/.babelrc +3 -0
  4. data/.codeclimate.yml +5 -0
  5. data/.eslintrc +3 -0
  6. data/.rubocop.yml +19 -0
  7. data/.rubocop_todo.yml +15 -135
  8. data/.travis.yml +2 -2
  9. data/CONTRIBUTORS.md +79 -0
  10. data/README.md +21 -24
  11. data/Rakefile +0 -1
  12. data/app/assets/images/blacklight/bookmark.svg +1 -0
  13. data/app/assets/images/blacklight/collection.svg +5 -0
  14. data/app/assets/images/blacklight/compact.svg +1 -25
  15. data/app/assets/images/blacklight/container.svg +5 -0
  16. data/app/assets/images/blacklight/ead.svg +1 -0
  17. data/app/assets/images/blacklight/file.svg +5 -0
  18. data/app/assets/images/blacklight/folder.svg +1 -0
  19. data/app/assets/images/blacklight/list.svg +1 -0
  20. data/app/assets/images/blacklight/minus.svg +1 -0
  21. data/app/assets/images/blacklight/online.svg +5 -0
  22. data/app/assets/images/blacklight/pdf.svg +1 -0
  23. data/app/assets/images/blacklight/plus.svg +1 -0
  24. data/app/assets/images/blacklight/repository.svg +1 -0
  25. data/app/assets/javascripts/arclight/arclight.js +1 -3
  26. data/app/assets/javascripts/arclight/collection_navigation.js +36 -53
  27. data/app/assets/javascripts/arclight/collection_scrollspy.js +1 -1
  28. data/app/assets/javascripts/arclight/context_navigation.js +374 -0
  29. data/app/assets/javascripts/arclight/truncator.js.erb +8 -2
  30. data/app/assets/stylesheets/arclight/application.scss +3 -1
  31. data/app/assets/stylesheets/arclight/bootstrap_overrides.scss +23 -0
  32. data/app/assets/stylesheets/arclight/modules/context_navigation.scss +75 -0
  33. data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +28 -35
  34. data/app/assets/stylesheets/arclight/modules/highlights.scss +2 -1
  35. data/app/assets/stylesheets/arclight/modules/layout.scss +128 -14
  36. data/app/assets/stylesheets/arclight/modules/mastheads.scss +27 -5
  37. data/app/assets/stylesheets/arclight/modules/repositories.scss +1 -5
  38. data/app/assets/stylesheets/arclight/modules/repository_card.scss +6 -7
  39. data/app/assets/stylesheets/arclight/modules/search_results.scss +145 -24
  40. data/app/assets/stylesheets/arclight/modules/show_collection.scss +38 -59
  41. data/app/assets/stylesheets/arclight/responsive.scss +13 -0
  42. data/app/assets/stylesheets/arclight/variables.scss +21 -1
  43. data/app/controllers/concerns/arclight/ead_format_helpers.rb +225 -0
  44. data/app/controllers/concerns/arclight/field_config_helpers.rb +23 -7
  45. data/app/factories/blacklight_field_configuration_factory.rb +1 -0
  46. data/app/helpers/arclight_helper.rb +197 -35
  47. data/app/models/arclight/document_downloads.rb +125 -0
  48. data/app/models/arclight/parent.rb +4 -2
  49. data/app/models/arclight/parents.rb +6 -4
  50. data/app/models/arclight/requests/aeon_external_request.rb +42 -0
  51. data/app/models/arclight/requests/aeon_web_ead.rb +47 -0
  52. data/app/models/arclight/requests/google_form.rb +2 -2
  53. data/app/models/concerns/arclight/catalog.rb +14 -2
  54. data/app/models/concerns/arclight/search_behavior.rb +27 -12
  55. data/app/models/concerns/arclight/solr_document.rb +29 -7
  56. data/app/views/arclight/_requests.html.erb +7 -0
  57. data/app/views/arclight/repositories/_in_person_repository.html.erb +1 -1
  58. data/app/views/arclight/repositories/_repository.html.erb +2 -2
  59. data/app/views/arclight/repositories/_repository_contact.html.erb +9 -0
  60. data/app/views/arclight/repositories/index.html.erb +3 -0
  61. data/app/views/arclight/repositories/show.html.erb +5 -4
  62. data/app/views/arclight/requests/_aeon_external_request_endpoint.html.erb +9 -0
  63. data/app/views/arclight/requests/_aeon_web_ead.html.erb +7 -0
  64. data/app/views/arclight/requests/_google_form.html.erb +2 -1
  65. data/app/views/arclight/viewers/_oembed.html.erb +2 -1
  66. data/app/views/catalog/_access_contents.html.erb +15 -0
  67. data/app/views/catalog/_arclight_abstract_or_scope.html.erb +5 -0
  68. data/app/views/catalog/_arclight_bookmark_control.html.erb +38 -0
  69. data/app/views/catalog/_arclight_document_header_icon.html.erb +1 -0
  70. data/app/views/catalog/_arclight_index_compact_default.html.erb +18 -11
  71. data/app/views/catalog/_arclight_index_default.html.erb +45 -0
  72. data/app/views/catalog/_arclight_index_group_document_compact_default.html.erb +19 -0
  73. data/app/views/catalog/_arclight_index_group_document_default.html.erb +18 -0
  74. data/app/views/catalog/_arclight_online_content_indicator.html.erb +1 -3
  75. data/app/views/catalog/_collection_contents.html.erb +2 -10
  76. data/app/views/catalog/_collection_context.html.erb +15 -0
  77. data/app/views/catalog/_collection_context_nav.html.erb +12 -0
  78. data/app/views/catalog/_collection_online_contents.html.erb +3 -3
  79. data/app/views/catalog/_component_context.html.erb +5 -0
  80. data/app/views/catalog/_containers.html.erb +3 -0
  81. data/app/views/catalog/_context_sidebar.html.erb +2 -2
  82. data/app/views/catalog/_document_downloads.html.erb +14 -0
  83. data/app/views/catalog/_group.html.erb +21 -0
  84. data/app/views/catalog/_group_header_compact_default.html.erb +15 -0
  85. data/app/views/catalog/_group_header_default.html.erb +20 -0
  86. data/app/views/catalog/_group_toggle.html.erb +10 -0
  87. data/app/views/catalog/_home.html.erb +1 -1
  88. data/app/views/catalog/_index_breadcrumb_default.html.erb +5 -2
  89. data/app/views/catalog/_index_collection_context_default.html.erb +53 -0
  90. data/app/views/catalog/_index_header.html.erb +3 -3
  91. data/app/views/catalog/_index_online_contents_default.html.erb +1 -1
  92. data/app/views/catalog/_online_content_label.html.erb +5 -0
  93. data/app/views/catalog/_search_form.html.erb +34 -0
  94. data/app/views/catalog/_search_results.html.erb +1 -4
  95. data/app/views/catalog/_show_actions_box_default.html.erb +27 -0
  96. data/app/views/catalog/_show_breadcrumbs_default.html.erb +5 -20
  97. data/app/views/catalog/_show_collection.html.erb +42 -24
  98. data/app/views/catalog/_show_default.html.erb +63 -35
  99. data/app/views/catalog/_show_upper_metadata_default.html.erb +1 -1
  100. data/app/views/catalog/_sort_and_per_page.html.erb +8 -0
  101. data/app/views/catalog/_within_collection_dropdown.html.erb +26 -0
  102. data/app/views/shared/_breadcrumbs.html.erb +4 -4
  103. data/app/views/shared/_context_sidebar.html.erb +2 -2
  104. data/app/views/shared/_header_navbar.html.erb +13 -17
  105. data/app/views/shared/_show_breadcrumbs.html.erb +27 -0
  106. data/arclight.gemspec +5 -6
  107. data/config/i18n-tasks.yml +2 -1
  108. data/config/locales/arclight.en.yml +54 -21
  109. data/config/repositories.yml +0 -0
  110. data/lib/arclight/engine.rb +22 -12
  111. data/lib/arclight/hash_absolute_xpath.rb +11 -7
  112. data/lib/arclight/level_label.rb +46 -0
  113. data/lib/arclight/normalized_date.rb +2 -2
  114. data/lib/arclight/normalized_id.rb +1 -0
  115. data/lib/arclight/normalized_title.rb +1 -0
  116. data/lib/arclight/repository.rb +58 -5
  117. data/lib/arclight/traject/ead2_config.rb +178 -159
  118. data/lib/arclight/traject/nokogiri_namespaceless_reader.rb +22 -0
  119. data/lib/arclight/version.rb +1 -1
  120. data/lib/arclight/viewers/oembed.rb +1 -0
  121. data/lib/arclight/year_range.rb +9 -1
  122. data/lib/generators/arclight/install_generator.rb +5 -1
  123. data/lib/generators/arclight/templates/catalog_controller.rb +128 -100
  124. data/lib/generators/arclight/templates/config/downloads.yml +12 -0
  125. data/lib/generators/arclight/templates/config/repositories.yml +20 -2
  126. data/lib/generators/arclight/update_generator.rb +1 -1
  127. data/lib/tasks/index.rake +18 -20
  128. data/package.json +8 -1
  129. data/solr/conf/schema.xml +51 -292
  130. data/solr/conf/solrconfig.xml +40 -125
  131. data/tasks/arclight.rake +1 -0
  132. data/vendor/assets/javascripts/responsiveTruncator.js +2 -2
  133. metadata +71 -44
  134. data/app/assets/javascripts/arclight/collection_context.js +0 -18
  135. data/app/assets/javascripts/arclight/component_ancestors.js +0 -56
  136. data/app/assets/javascripts/arclight/search_results.js +0 -15
  137. data/app/assets/stylesheets/arclight/modules/sidebar.scss +0 -21
  138. data/app/views/catalog/_collection_count.html.erb +0 -7
  139. data/app/views/catalog/_collection_downloads.html.erb +0 -15
  140. data/app/views/catalog/_collection_overview.html.erb +0 -7
  141. data/app/views/catalog/_component_contents.html.erb +0 -16
  142. data/app/views/catalog/_component_overview.html.erb +0 -40
  143. data/app/views/catalog/_index_header_hierarchy_default.html.erb +0 -42
  144. data/app/views/catalog/_index_hierarchy_default.html.erb +0 -28
  145. data/app/views/catalog/_results_histogram.html.erb +0 -15
  146. data/app/views/catalog/_show_component_sidebar.html.erb +0 -12
  147. data/app/views/catalog/_show_sidebar.html.erb +0 -22
  148. data/lib/arclight/custom_component.rb +0 -99
  149. data/lib/arclight/custom_document.rb +0 -93
  150. data/lib/arclight/indexer.rb +0 -9
  151. data/lib/arclight/shared_indexing_behavior.rb +0 -97
  152. data/lib/arclight/shared_terminology_behavior.rb +0 -65
  153. data/lib/arclight/solr_ead_indexer_ext.rb +0 -155
data/Rakefile CHANGED
@@ -12,6 +12,5 @@ Dir.glob('./tasks/*.rake').each { |f| load f }
12
12
  Dir.glob('./lib/tasks/*.rake').each { |f| load f }
13
13
 
14
14
  require 'engine_cart/rake_task'
15
- require 'solr_ead'
16
15
 
17
16
  task default: %i[rubocop eslint ci]
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"/></svg>
@@ -0,0 +1,5 @@
1
+ <!--
2
+ Used unmodified from https://fontawesome.com
3
+ CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
4
+ -->
5
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M32 448c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32V160H32v288zm160-212c0-6.6 5.4-12 12-12h104c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-8zM480 32H32C14.3 32 0 46.3 0 64v48c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16V64c0-17.7-14.3-32-32-32z"/></svg>
@@ -1,25 +1 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
- <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
4
- <title>Compact</title>
5
- <desc>Created with Sketch.</desc>
6
- <defs></defs>
7
- <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square">
8
- <g id="Compact" stroke="#000000">
9
- <path d="M1.43885093,2.44444444 L6.83349609,2.44444444"></path>
10
- <path d="M1.43885093,4.44444444 L6.83349609,4.44444444"></path>
11
- <path d="M1.43885093,6.44444444 L6.83349609,6.44444444"></path>
12
- <path d="M1.43885093,8.44444444 L6.83349609,8.44444444"></path>
13
- <path d="M1.43885093,10.4444444 L6.83349609,10.4444444"></path>
14
- <path d="M1.43885093,12.4444444 L6.83349609,12.4444444"></path>
15
- <path d="M1.43885093,14.4444444 L6.83349609,14.4444444"></path>
16
- <path d="M9.43885093,2.44444444 L14.8334961,2.44444444"></path>
17
- <path d="M9.43885093,4.44444444 L14.8334961,4.44444444"></path>
18
- <path d="M9.43885093,6.44444444 L14.8334961,6.44444444"></path>
19
- <path d="M9.43885093,8.44444444 L14.8334961,8.44444444"></path>
20
- <path d="M9.43885093,10.4444444 L14.8334961,10.4444444"></path>
21
- <path d="M9.43885093,12.4444444 L14.8334961,12.4444444"></path>
22
- <path d="M9.43885093,14.4444444 L14.8334961,14.4444444"></path>
23
- </g>
24
- </g>
25
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3,15H21V13H3Zm0,4H21V17H3Zm0-8H21V9H3ZM3,5V7H21V5Z"/></svg>
@@ -0,0 +1,5 @@
1
+ <!--
2
+ Used unmodified from https://fontawesome.com
3
+ CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
4
+ -->
5
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z"/></svg>
@@ -0,0 +1,5 @@
1
+ <!--
2
+ Used unmodified from https://fontawesome.com
3
+ CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
4
+ -->
5
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"/></svg>
@@ -0,0 +1 @@
1
+ <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>file</title><path d="M0,0H24V24H0Z" fill="none"/><path d="M3,19H21V13.45H3ZM3,5v5.61H21V5Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
@@ -0,0 +1,5 @@
1
+ <!--
2
+ Used unmodified from https://fontawesome.com
3
+ CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
4
+ -->
5
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M608 0H160a32 32 0 0 0-32 32v96h160V64h192v320h128a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zM232 103a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm352 208a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm-168 57H32a32 32 0 0 0-32 32v288a32 32 0 0 0 32 32h384a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32zM96 224a32 32 0 1 1-32 32 32 32 0 0 1 32-32zm288 224H64v-32l64-64 32 32 128-128 96 96z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"/></svg>
@@ -1,9 +1,7 @@
1
1
  //= require arclight/collection_scrollspy
2
2
  //= require arclight/collection_navigation
3
- //= require arclight/collection_context
4
- //= require arclight/component_ancestors
3
+ //= require arclight/context_navigation
5
4
  //= require arclight/oembed_viewer
6
- //= require arclight/search_results
7
5
  //= require arclight/truncator
8
6
 
9
7
  // Vendor Scripts
@@ -1,54 +1,8 @@
1
1
  (function (global) {
2
2
  var CollectionNavigation;
3
- /**
4
- * Converts documents that should be used in a hierarchy, to highlighted
5
- * localized siblings.
6
- */
7
- function convertDocsForContext(id, $doc) {
8
- var newDocs;
9
- var $currentDoc;
10
- var $previousDocs;
11
- var $nextDocs;
12
- var headers = $doc.find('article div[data-document-id="' + id + '"]');
13
- if (headers.length === 0) {
14
- $.error('Document is missing id=' + id);
15
- }
16
- $currentDoc = $(headers[0].parentNode); // need article element
17
- $currentDoc.addClass('al-hierarchy-highlight');
18
-
19
- // Unlink the current component - just show the title
20
- $currentDoc.find('a').contents().unwrap();
21
-
22
- // We want to show 0-1 or 0-2 siblings depending on where highlighted component is
23
- $previousDocs = $currentDoc.prevUntil().slice(0, 2);
24
- $nextDocs = $currentDoc.nextUntil().slice(0, 2);
25
-
26
- if ($previousDocs.length > 0 && $nextDocs.length > 0) {
27
- // Case where there are siblings on both sides, show 1 each
28
- newDocs = $('<div>');
29
- newDocs.append($previousDocs.first());
30
- newDocs.append($currentDoc);
31
- newDocs.append($nextDocs.first());
32
- } else if ($previousDocs.length > 0) {
33
- // Case where there are only previous siblings, show 2 of them
34
- newDocs = $('<div>');
35
- newDocs.append($previousDocs.get().reverse()); // previous is not in the order we need
36
- newDocs.append($currentDoc);
37
- } else {
38
- // Case where there are only next siblings, show 2 of them
39
- newDocs = $('<div>');
40
- newDocs.append($currentDoc);
41
- newDocs.append($nextDocs);
42
- }
43
- // Cleanup to remove collapsible children stuff
44
- newDocs.find('.al-toggle-view-more').remove();
45
- newDocs.find('.collapse').remove();
46
- newDocs.find('hr').remove();
47
- return newDocs;
48
- }
49
3
 
50
4
  CollectionNavigation = {
51
- init: function (el) {
5
+ init: function (el, page = 1) {
52
6
  var $el = $(el);
53
7
  var data = $el.data();
54
8
  // Add a placeholder so flashes of text are not as significant
@@ -66,7 +20,8 @@
66
20
  'f[component_level_isim][]': data.arclight.level,
67
21
  'f[has_online_content_ssim][]': data.arclight.access,
68
22
  'f[collection_sim][]': data.arclight.name,
69
- 'f[parent_ssi][]': data.arclight.parent,
23
+ 'f[parent_ssim][]': data.arclight.parent,
24
+ page: page,
70
25
  search_field: data.arclight.search_field,
71
26
  view: data.arclight.view || 'hierarchy'
72
27
  }
@@ -75,13 +30,39 @@
75
30
  var $doc = $(resp);
76
31
  var showDocs = $doc.find('article.document');
77
32
  var newDocs = $doc.find('#documents');
33
+ var sortPerPage = $doc.find('#sortAndPerPage');
34
+ var pageEntries = sortPerPage.find('.page-entries');
35
+ var numberEntries = parseInt(pageEntries.find('strong').last().text().replace(/,/g, ''), 10);
36
+
37
+ // Hide these until we re-enable in the future
38
+ sortPerPage.find('.result-type-group').hide();
39
+ sortPerPage.find('.search-widgets').hide();
78
40
 
79
- // Add a highlight class for the article matching the highlight id
80
- if (data.arclight.highlightId) {
81
- newDocs = convertDocsForContext(data.arclight.highlightId, $doc);
41
+ if (!isNaN(numberEntries)) {
42
+ $('[data-arclight-online-content-tab-count]').html(
43
+ $(
44
+ '<span class="badge badge-pill badge-secondary al-online-content-badge">'
45
+ + numberEntries
46
+ + '<span class="sr-only">components</span></span>'
47
+ )
48
+ );
82
49
  }
83
50
 
84
- $el.hide().html(newDocs).fadeIn(500);
51
+ sortPerPage.find('a').on('click', function (e) {
52
+ var pages = [];
53
+ var $target = $(e.target);
54
+ e.preventDefault();
55
+ pages = /page=(\d+)&/.exec($target.attr('href'));
56
+ if (pages) {
57
+ CollectionNavigation.init($el, pages[1]);
58
+ } else {
59
+ // Case where the "first" page
60
+ CollectionNavigation.init($el);
61
+ }
62
+ });
63
+
64
+ $el.hide().html('').append(sortPerPage).append(newDocs)
65
+ .fadeIn(500);
85
66
  if (showDocs.length > 0) {
86
67
  $el.trigger('navigation.contains.elements');
87
68
  }
@@ -102,8 +83,10 @@ Blacklight.onLoad(function () {
102
83
 
103
84
  $('.al-contents').on('navigation.contains.elements', function (e) {
104
85
  var toEnable = $('[data-hierarchy-enable-me]');
86
+ var srOnly = $('h2[data-sr-enable-me]');
105
87
  toEnable.removeClass('disabled');
106
- toEnable.text('Contents');
88
+ toEnable.text(srOnly.data('hasContents'));
89
+ srOnly.text(srOnly.data('hasContents'));
107
90
 
108
91
  $(e.target).find('.collapse').on('show.bs.collapse', function (ee) {
109
92
  var $newTarget = $(ee.target);
@@ -2,5 +2,5 @@ Blacklight.onLoad(function () {
2
2
  'use strict';
3
3
 
4
4
  $('.al-sticky-sidebar').Stickyfill();
5
- $('body').scrollspy({ target: '.al-sidebar-navigation-overview' });
5
+ $('body').scrollspy({ target: '.al-sidebar-navigation-context' });
6
6
  });
@@ -0,0 +1,374 @@
1
+ class NavigationDocument {
2
+ constructor(el) {
3
+ this.el = $(el);
4
+ }
5
+
6
+ get id() {
7
+ return this.el.find('[data-document-id]').data().documentId;
8
+ }
9
+
10
+ setAsHighlighted() {
11
+ this.el.find('li.al-collection-context').addClass('al-hierarchy-highlight');
12
+ }
13
+
14
+ collapse() {
15
+ this.el.find('li.al-collection-context').addClass('collapsed');
16
+ }
17
+
18
+ render() {
19
+ return this.el.html();
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Models the "Expand"/"Collapse" button, and provides an onClick event handler
25
+ * for the jQuery element
26
+ * @class
27
+ */
28
+ class ExpandButton {
29
+ /**
30
+ * This retrieves the <li> elements which are hidden/rendered in response to
31
+ * clicking the <button> element
32
+ * @param {jQuery} $li - the <button> element
33
+ * @return {jQuery} - a jQuery object containing the targeted <li>
34
+ */
35
+ findSiblings() {
36
+ const $siblings = this.$el.parent().children('li');
37
+ return $siblings.slice(0, -1);
38
+ }
39
+
40
+ /**
41
+ * This adds a "collapsed" class to all of the <li> children, as well as
42
+ * updates the text for the <button> element
43
+ * @param {Event} event - the event propagated in response to clicking on the
44
+ * <button> element
45
+ */
46
+ handleClick() {
47
+ const $targeted = this.findSiblings();
48
+
49
+ $targeted.toggleClass('collapsed');
50
+ this.$el.toggleClass('collapsed');
51
+
52
+ const containerText = this.$el.hasClass('collapsed') ? this.collapseText : this.expandText;
53
+ this.$el.text(containerText);
54
+ }
55
+
56
+ /**
57
+ * @constructor
58
+ */
59
+ constructor(data) {
60
+ this.collapseText = data.collapse;
61
+ this.expandText = data.expand;
62
+
63
+ this.$el = $(`<button class="my-3 btn btn-secondary btn-sm">${this.expandText}</button>`);
64
+ this.handleClick = this.handleClick.bind(this);
65
+ this.$el.click(this.handleClick);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Modeling <button> Elements which hide or retrieve <li> elements for sibling
71
+ * documents nested within the <li> elements of the <ul> tree
72
+ * @class
73
+ */
74
+ class NestedExpandButton extends ExpandButton {
75
+ /**
76
+ * This retrieves the <li> elements which are hidden/rendered in response to
77
+ * clicking the <button> element
78
+ * @param {jQuery} $li - the <button> element
79
+ * @return {jQuery} - a jQuery object containing the targeted <li>
80
+ */
81
+ findSiblings() {
82
+ const highlighted = this.$el.siblings('.al-hierarchy-highlight');
83
+ const $siblings = highlighted.prevAll('.al-collection-context');
84
+ return $siblings.slice(0, -1);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Models the placeholder display elements for content loading from AJAX
90
+ * requests
91
+ * @class
92
+ */
93
+ class Placeholder {
94
+ /*
95
+ * Builds the element set which contains the placeholder markup
96
+ * classes
97
+ */
98
+ /* eslint-disable class-methods-use-this */
99
+ buildElement() {
100
+ const elementMarkup = '<div class="al-hierarchy-placeholder">' +
101
+ '<h3 class="col-md-9"></h3>' +
102
+ '<p class="col-md-6"></p>' +
103
+ '<p class="col-md-12"></p>' +
104
+ '<p class="col-md-3"></p>' +
105
+ '</div>';
106
+ const markup = Array(3).join(elementMarkup);
107
+
108
+ return $(markup);
109
+ }
110
+ /* eslint-enable class-methods-use-this */
111
+
112
+ /*
113
+ * @constructor
114
+ */
115
+ constructor() {
116
+ this.$el = this.buildElement();
117
+ }
118
+ }
119
+
120
+ class ContextNavigation {
121
+ constructor(el, originalParents = null, originalDocument = null) {
122
+ this.el = $(el);
123
+ this.data = this.el.data();
124
+ this.parentLi = this.el.parent();
125
+ this.eadid = this.data.arclight.eadid;
126
+ this.originalParents = originalParents || this.data.arclight.originalParents;
127
+ this.originalDocument = originalDocument || this.data.arclight.originalDocument;
128
+ this.ul = $('<ul class="al-context-nav-parent"></ul>');
129
+ }
130
+
131
+ // Gets the targetId to select, based off of parents and current level
132
+ get targetId() {
133
+ return `${this.eadid}${this.originalParents[this.data.arclight.level]}`;
134
+ }
135
+
136
+ get requestParent() {
137
+ if (this.originalParents && this.originalParents[this.data.arclight.level - 1]) {
138
+ return this.originalParents[this.data.arclight.level - 1];
139
+ }
140
+ return this.data.arclight.originalDocument.replace(this.eadid, '');
141
+ }
142
+
143
+ getData() {
144
+ const that = this;
145
+ // Add a placeholder so flashes of text are not as significant
146
+ const placeholder = new Placeholder();
147
+ this.el.after(placeholder.$el);
148
+ $.ajax({
149
+ url: this.data.arclight.path,
150
+ data: {
151
+ 'f[component_level_isim][]': this.data.arclight.level,
152
+ 'f[has_online_content_ssim][]': this.data.arclight.access,
153
+ 'f[collection_sim][]': this.data.arclight.name,
154
+ 'f[parent_ssi][]': this.requestParent,
155
+ search_field: this.data.arclight.search_field,
156
+ original_parents: this.data.arclight.originalParents,
157
+ original_document: this.originalDocument,
158
+ view: 'collection_context'
159
+ }
160
+ }).done((response) => that.updateView(response));
161
+ }
162
+
163
+ /**
164
+ * Constructs a <ul> container element with an ElementButton instance appended
165
+ * within it
166
+ * @returns {jQuery}
167
+ */
168
+ buildExpandList() {
169
+ const $ul = $('<ul></ul>');
170
+ $ul.addClass('pl-0');
171
+ $ul.addClass('prev-siblings');
172
+ const button = new ExpandButton(this.data);
173
+ $ul.append(button.$el);
174
+ return $ul;
175
+ }
176
+
177
+ /**
178
+ * Highlights the <li> element for the current Document and appends <li> the
179
+ * sibling documents for a given Document element
180
+ * @param {NavigationDocument[]} newDocs - the NavigationDocument objects for
181
+ * each resulting Solr Document
182
+ * @param {number} originalDocumentIndex
183
+ */
184
+ updateSiblings(newDocs, originalDocumentIndex) {
185
+ newDocs[originalDocumentIndex].setAsHighlighted();
186
+
187
+ // Hide all but the first previous sibling
188
+ const prevSiblingDocs = newDocs.slice(0, originalDocumentIndex);
189
+ let nextSiblingDocs = [];
190
+
191
+ if (prevSiblingDocs.length > 1 && originalDocumentIndex > 0) {
192
+ const hiddenPrevSiblingDocs = prevSiblingDocs.slice(0, -1);
193
+ hiddenPrevSiblingDocs.forEach(siblingDoc => {
194
+ siblingDoc.collapse();
195
+ });
196
+
197
+ const prevSiblingList = this.buildExpandList();
198
+ const renderedPrevSiblingItems = prevSiblingDocs.map(doc => doc.render()).join('');
199
+
200
+ prevSiblingList.append(renderedPrevSiblingItems);
201
+ this.ul.append(prevSiblingList);
202
+
203
+ nextSiblingDocs = newDocs.slice(originalDocumentIndex);
204
+ } else {
205
+ nextSiblingDocs = newDocs;
206
+ }
207
+
208
+ const renderedNextSiblingItems = nextSiblingDocs.map(newDoc => newDoc.render()).join('');
209
+
210
+ // Insert the rendered sibling documents before the <li> elements
211
+ this.ul.append(renderedNextSiblingItems);
212
+ this.el.html(this.ul);
213
+ }
214
+
215
+ /**
216
+ * Inserts <li> elements for parents (e. g. components or collections) for the
217
+ * current Document and appends <li> for each of these
218
+ * @param {NavigationDocument[]} newDocs - the NavigationDocument objects for
219
+ * each resulting Solr Document
220
+ */
221
+ updateParents(newDocs) {
222
+ const that = this;
223
+ // Case where this is a parent list and needs to be filed correctly
224
+ //
225
+ // Otherwise, retrieve the parent...
226
+ let newDocIndex = newDocs.findIndex(doc => doc.id === this.targetId);
227
+
228
+ if (newDocIndex === -1) {
229
+ const renderedDocs = newDocs.map(newDoc => newDoc.render()).join('');
230
+ this.ul.append(renderedDocs);
231
+ this.el.html(this.ul);
232
+ return;
233
+ }
234
+ // Update the docs before the item
235
+ // Retrieves the documents up to and including the "new document"
236
+ const beforeDocs = newDocs.slice(0, newDocIndex);
237
+ let prevParentList = null;
238
+ let renderedBeforeDocs;
239
+ if (beforeDocs.length > 1) {
240
+ beforeDocs.forEach(function (parentDoc) {
241
+ parentDoc.collapse();
242
+ });
243
+ renderedBeforeDocs = beforeDocs.map(newDoc => newDoc.render()).join('');
244
+ prevParentList = this.buildExpandList();
245
+ prevParentList.append(renderedBeforeDocs);
246
+ } else {
247
+ renderedBeforeDocs = beforeDocs.map(newDoc => newDoc.render()).join('');
248
+ }
249
+
250
+ // Silly but works for now
251
+ this.ul.append(prevParentList || renderedBeforeDocs);
252
+
253
+ let itemDoc = newDocs.slice(newDocIndex, newDocIndex + 1);
254
+ let renderedItemDoc = itemDoc.map(doc => doc.render()).join('');
255
+
256
+ // Update the item
257
+ const $itemDoc = $(renderedItemDoc);
258
+ this.ul.append($itemDoc);
259
+
260
+ // Update the docs after the item
261
+ const afterDocs = newDocs.slice(newDocIndex + 1, newDocs.length);
262
+ const renderedAfterDocs = afterDocs.map(newDoc => newDoc.render()).join('');
263
+
264
+ // Insert the documents after the current
265
+ this.ul.append(renderedAfterDocs);
266
+ this.el.html(this.ul);
267
+
268
+ // Initialize additional things
269
+ $itemDoc.find('.context-navigator').each(function (i, e) {
270
+ const contextNavigation = new ContextNavigation(
271
+ e, that.originalParents, that.originalDocument
272
+ );
273
+ contextNavigation.getData();
274
+ });
275
+ }
276
+
277
+
278
+ /**
279
+ * Update the ancestors for <li> elements
280
+ * @param {jQuery} $li - the <li> element for the current, highlighted
281
+ * Document in the <ul> context list of collections, components, and
282
+ * containers
283
+ */
284
+ /* eslint-disable class-methods-use-this */
285
+ updateListSiblings($li) {
286
+ const prevSiblings = $li.prevAll('.al-collection-context');
287
+ if (prevSiblings.length > 1) {
288
+ const hiddenNextSiblings = prevSiblings.slice(0, -1);
289
+ hiddenNextSiblings.toggleClass('collapsed');
290
+
291
+ const button = new NestedExpandButton();
292
+
293
+ const lastHiddenNextSibling = hiddenNextSiblings[hiddenNextSiblings.length - 1];
294
+ button.$el.insertAfter(lastHiddenNextSibling);
295
+ }
296
+ }
297
+ /* eslint-enable class-methods-use-this */
298
+
299
+ /**
300
+ * This updates the elements in the View DOM using an AJAX response containing
301
+ * the HTML of a server-rendered View template.
302
+ * It is this which is primarily used to populate the <ul> element with
303
+ * children for the navigation context, containing <li> elements for
304
+ * collections, components, and containers.
305
+ * @param {string} response - the AJAX response body
306
+ */
307
+ updateView(response) {
308
+ const that = this;
309
+ var resp = $.parseHTML(response);
310
+ var $doc = $(resp);
311
+ var newDocs = $doc.find('#documents')
312
+ .find('article')
313
+ .toArray().map(el => new NavigationDocument(el));
314
+
315
+ // See if the original document is located in the returned documents
316
+ const originalDocumentIndex = newDocs
317
+ .findIndex(doc => doc.id === that.originalDocument);
318
+ that.parentLi.find('.al-hierarchy-placeholder').remove();
319
+
320
+ // If the original document in the results, update it. If not update with a
321
+ // more complex procedure
322
+ if (originalDocumentIndex !== -1) {
323
+ this.updateSiblings(newDocs, originalDocumentIndex);
324
+ } else {
325
+ this.updateParents(
326
+ newDocs,
327
+ that.data.arclight.originalParents,
328
+ that.data.arclight.parent,
329
+ that.parentLi
330
+ );
331
+ }
332
+ this.el.parent().data('resolved', true);
333
+ this.addListenersForPlusMinus();
334
+ this.enablebuttons();
335
+ Blacklight.doBookmarkToggleBehavior();
336
+ this.el.trigger('navigation.contains.elements');
337
+ }
338
+
339
+ // eslint-disable-next-line class-methods-use-this
340
+ enablebuttons() {
341
+ var toEnable = $('[data-hierarchy-enable-me]');
342
+ var srOnly = $('h2[data-sr-enable-me]');
343
+ toEnable.removeClass('disabled');
344
+ toEnable.text(srOnly.data('hasContents'));
345
+ srOnly.text(srOnly.data('hasContents'));
346
+ }
347
+
348
+ addListenersForPlusMinus() {
349
+ const that = this;
350
+ this.ul.find('.al-toggle-view-children').on('click', (e) => {
351
+ e.preventDefault();
352
+ const targetArea = $($(e.target).attr('href'));
353
+ if (!targetArea.data().resolved) {
354
+ targetArea.find('.context-navigator').each((i, ee) => {
355
+ const contextNavigation = new ContextNavigation(
356
+ ee, that.originalParents, that.originalDocument
357
+ );
358
+ contextNavigation.getData();
359
+ });
360
+ }
361
+ });
362
+ }
363
+ }
364
+
365
+ /**
366
+ * Integrate the behavior into the DOM using the Blacklight#onLoad callback
367
+ *
368
+ */
369
+ Blacklight.onLoad(function () {
370
+ $('.context-navigator').each(function (i, e) {
371
+ const contextNavigation = new ContextNavigation(e);
372
+ contextNavigation.getData();
373
+ });
374
+ });