arclight 0.1.4 → 0.3.3

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 (166) hide show
  1. checksums.yaml +5 -5
  2. data/.all-contributorsrc +450 -0
  3. data/.babelrc +3 -0
  4. data/.codeclimate.yml +5 -0
  5. data/.eslintrc +3 -0
  6. data/.gitignore +1 -0
  7. data/.rubocop.yml +20 -42
  8. data/.rubocop_todo.yml +139 -0
  9. data/.travis.yml +24 -20
  10. data/CONTRIBUTORS.md +79 -0
  11. data/README.md +34 -23
  12. data/Rakefile +0 -1
  13. data/app/assets/images/blacklight/bookmark.svg +1 -0
  14. data/app/assets/images/blacklight/collection.svg +5 -0
  15. data/app/assets/images/blacklight/compact.svg +1 -25
  16. data/app/assets/images/blacklight/container.svg +5 -0
  17. data/app/assets/images/blacklight/ead.svg +1 -0
  18. data/app/assets/images/blacklight/file.svg +5 -0
  19. data/app/assets/images/blacklight/folder.svg +1 -0
  20. data/app/assets/images/blacklight/list.svg +1 -0
  21. data/app/assets/images/blacklight/minus.svg +1 -0
  22. data/app/assets/images/blacklight/online.svg +5 -0
  23. data/app/assets/images/blacklight/pdf.svg +1 -0
  24. data/app/assets/images/blacklight/plus.svg +1 -0
  25. data/app/assets/images/blacklight/repository.svg +1 -0
  26. data/app/assets/javascripts/arclight/arclight.js +1 -2
  27. data/app/assets/javascripts/arclight/collection_navigation.js +36 -50
  28. data/app/assets/javascripts/arclight/collection_scrollspy.js +1 -1
  29. data/app/assets/javascripts/arclight/context_navigation.js +386 -0
  30. data/app/assets/javascripts/arclight/oembed_viewer.js +11 -4
  31. data/app/assets/javascripts/arclight/truncator.js.erb +8 -2
  32. data/app/assets/stylesheets/arclight/application.scss +4 -1
  33. data/app/assets/stylesheets/arclight/bootstrap_overrides.scss +23 -0
  34. data/app/assets/stylesheets/arclight/modules/context_navigation.scss +75 -0
  35. data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +34 -38
  36. data/app/assets/stylesheets/arclight/modules/highlights.scss +2 -1
  37. data/app/assets/stylesheets/arclight/modules/icons.scss +4 -0
  38. data/app/assets/stylesheets/arclight/modules/layout.scss +149 -11
  39. data/app/assets/stylesheets/arclight/modules/mastheads.scss +60 -5
  40. data/app/assets/stylesheets/arclight/modules/repositories.scss +1 -5
  41. data/app/assets/stylesheets/arclight/modules/repository_card.scss +6 -7
  42. data/app/assets/stylesheets/arclight/modules/search_results.scss +145 -24
  43. data/app/assets/stylesheets/arclight/modules/show_collection.scss +38 -59
  44. data/app/assets/stylesheets/arclight/responsive.scss +13 -0
  45. data/app/assets/stylesheets/arclight/variables.scss +21 -1
  46. data/app/controllers/concerns/arclight/ead_format_helpers.rb +225 -0
  47. data/app/controllers/concerns/arclight/field_config_helpers.rb +23 -7
  48. data/app/factories/blacklight_field_configuration_factory.rb +1 -0
  49. data/app/helpers/arclight_helper.rb +198 -36
  50. data/app/models/arclight/document_downloads.rb +125 -0
  51. data/app/models/arclight/parent.rb +4 -2
  52. data/app/models/arclight/parents.rb +6 -4
  53. data/app/models/arclight/requests/aeon_external_request.rb +42 -0
  54. data/app/models/arclight/requests/aeon_web_ead.rb +47 -0
  55. data/app/models/arclight/requests/google_form.rb +2 -2
  56. data/app/models/concerns/arclight/catalog.rb +14 -2
  57. data/app/models/concerns/arclight/search_behavior.rb +27 -12
  58. data/app/models/concerns/arclight/solr_document.rb +29 -7
  59. data/app/views/arclight/_requests.html.erb +7 -0
  60. data/app/views/arclight/repositories/_in_person_repository.html.erb +2 -2
  61. data/app/views/arclight/repositories/_repository.html.erb +2 -2
  62. data/app/views/arclight/repositories/_repository_contact.html.erb +9 -0
  63. data/app/views/arclight/repositories/index.html.erb +3 -0
  64. data/app/views/arclight/repositories/show.html.erb +5 -4
  65. data/app/views/arclight/requests/_aeon_external_request_endpoint.html.erb +9 -0
  66. data/app/views/arclight/requests/_aeon_web_ead.html.erb +7 -0
  67. data/app/views/arclight/requests/_google_form.html.erb +2 -1
  68. data/app/views/arclight/viewers/_oembed.html.erb +2 -1
  69. data/app/views/catalog/_access_contents.html.erb +15 -0
  70. data/app/views/catalog/_arclight_abstract_or_scope.html.erb +5 -0
  71. data/app/views/catalog/_arclight_bookmark_control.html.erb +38 -0
  72. data/app/views/catalog/_arclight_document_header_icon.html.erb +1 -0
  73. data/app/views/catalog/_arclight_index_compact_default.html.erb +18 -11
  74. data/app/views/catalog/_arclight_index_default.html.erb +45 -0
  75. data/app/views/catalog/_arclight_index_group_document_compact_default.html.erb +19 -0
  76. data/app/views/catalog/_arclight_index_group_document_default.html.erb +18 -0
  77. data/app/views/catalog/_arclight_online_content_indicator.html.erb +1 -3
  78. data/app/views/catalog/_collection_contents.html.erb +2 -10
  79. data/app/views/catalog/_collection_context.html.erb +15 -0
  80. data/app/views/catalog/_collection_context_nav.html.erb +12 -0
  81. data/app/views/catalog/_collection_online_contents.html.erb +3 -3
  82. data/app/views/catalog/_component_context.html.erb +5 -0
  83. data/app/views/catalog/_containers.html.erb +3 -0
  84. data/app/views/catalog/_context_card.html.erb +1 -1
  85. data/app/views/catalog/_context_sidebar.html.erb +2 -2
  86. data/app/views/catalog/_custom_metadata.html.erb +1 -1
  87. data/app/views/catalog/_document_downloads.html.erb +14 -0
  88. data/app/views/catalog/_group.html.erb +21 -0
  89. data/app/views/catalog/_group_header_compact_default.html.erb +15 -0
  90. data/app/views/catalog/_group_header_default.html.erb +20 -0
  91. data/app/views/catalog/_group_toggle.html.erb +10 -0
  92. data/app/views/catalog/_home.html.erb +1 -1
  93. data/app/views/catalog/_index_breadcrumb_default.html.erb +5 -2
  94. data/app/views/catalog/_index_collection_context_default.html.erb +53 -0
  95. data/app/views/catalog/_index_default.html.erb +1 -1
  96. data/app/views/catalog/_index_header.html.erb +3 -3
  97. data/app/views/catalog/_index_online_contents_default.html.erb +1 -1
  98. data/app/views/catalog/_online_content_label.html.erb +5 -0
  99. data/app/views/catalog/_search_form.html.erb +34 -0
  100. data/app/views/catalog/_search_results.html.erb +1 -4
  101. data/app/views/catalog/_show_actions_box_default.html.erb +27 -0
  102. data/app/views/catalog/_show_breadcrumbs_default.html.erb +5 -6
  103. data/app/views/catalog/_show_collection.html.erb +42 -24
  104. data/app/views/catalog/_show_default.html.erb +64 -26
  105. data/app/views/catalog/_show_upper_metadata_collection.html.erb +1 -0
  106. data/app/views/catalog/_show_upper_metadata_default.html.erb +14 -0
  107. data/app/views/catalog/_sort_and_per_page.html.erb +8 -0
  108. data/app/views/catalog/_within_collection_dropdown.html.erb +26 -0
  109. data/app/views/shared/_breadcrumbs.html.erb +4 -4
  110. data/app/views/shared/_context_sidebar.html.erb +2 -2
  111. data/app/views/shared/_header_navbar.html.erb +51 -43
  112. data/app/views/shared/_main_menu_links.html.erb +1 -1
  113. data/app/views/shared/_show_breadcrumbs.html.erb +27 -0
  114. data/arclight.gemspec +15 -12
  115. data/config/i18n-tasks.yml +133 -0
  116. data/config/locales/arclight.en.yml +89 -55
  117. data/config/repositories.yml +0 -0
  118. data/lib/arclight/engine.rb +23 -12
  119. data/lib/arclight/hash_absolute_xpath.rb +61 -0
  120. data/lib/arclight/level_label.rb +46 -0
  121. data/lib/arclight/missing_id_strategy.rb +21 -0
  122. data/lib/arclight/normalized_date.rb +21 -12
  123. data/lib/arclight/normalized_id.rb +1 -0
  124. data/lib/arclight/normalized_title.rb +1 -0
  125. data/lib/arclight/repository.rb +61 -25
  126. data/lib/arclight/traject/ead2_config.rb +495 -0
  127. data/lib/arclight/traject/nokogiri_namespaceless_reader.rb +22 -0
  128. data/lib/arclight/version.rb +1 -1
  129. data/lib/arclight/viewers/oembed.rb +1 -0
  130. data/lib/arclight/year_range.rb +9 -1
  131. data/lib/generators/arclight/install_generator.rb +34 -3
  132. data/lib/generators/arclight/templates/catalog_controller.rb +162 -131
  133. data/lib/generators/arclight/templates/config/downloads.yml +12 -0
  134. data/lib/generators/arclight/templates/config/repositories.yml +20 -2
  135. data/lib/generators/arclight/update_generator.rb +1 -1
  136. data/lib/tasks/index.rake +19 -19
  137. data/package.json +8 -1
  138. data/solr/conf/schema.xml +56 -292
  139. data/solr/conf/solrconfig.xml +40 -125
  140. data/tasks/arclight.rake +6 -1
  141. data/template.rb +1 -1
  142. data/vendor/assets/javascripts/responsiveTruncator.js +2 -2
  143. metadata +159 -60
  144. data/app/assets/javascripts/arclight/collection_context.js +0 -18
  145. data/app/assets/javascripts/arclight/component_ancestors.js +0 -56
  146. data/app/assets/stylesheets/arclight/modules/sidebar.scss +0 -21
  147. data/app/views/catalog/_arclight_document_show_header.html.erb +0 -15
  148. data/app/views/catalog/_arclight_document_show_header_collection.html.erb +0 -12
  149. data/app/views/catalog/_collection_count.html.erb +0 -7
  150. data/app/views/catalog/_collection_downloads.html.erb +0 -15
  151. data/app/views/catalog/_collection_overview.html.erb +0 -7
  152. data/app/views/catalog/_component_overview.html.erb +0 -46
  153. data/app/views/catalog/_index_header_hierarchy_default.html.erb +0 -42
  154. data/app/views/catalog/_index_hierarchy_default.html.erb +0 -28
  155. data/app/views/catalog/_results_histogram.html.erb +0 -10
  156. data/app/views/catalog/_search_within_form.html.erb +0 -16
  157. data/app/views/catalog/_show_component_sidebar.html.erb +0 -12
  158. data/app/views/catalog/_show_header.html.erb +0 -5
  159. data/app/views/catalog/_show_sidebar.html.erb +0 -30
  160. data/lib/arclight/custom_component.rb +0 -99
  161. data/lib/arclight/custom_document.rb +0 -93
  162. data/lib/arclight/indexer.rb +0 -9
  163. data/lib/arclight/shared_indexing_behavior.rb +0 -97
  164. data/lib/arclight/shared_terminology_behavior.rb +0 -65
  165. data/lib/arclight/solr_ead_indexer_ext.rb +0 -159
  166. data/lib/generators/arclight/templates/arclight.js +0 -2
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" width="24" height="24" 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" width="24" height="24" 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" id="Line"></path>
10
- <path d="M1.43885093,4.44444444 L6.83349609,4.44444444" id="Line"></path>
11
- <path d="M1.43885093,6.44444444 L6.83349609,6.44444444" id="Line"></path>
12
- <path d="M1.43885093,8.44444444 L6.83349609,8.44444444" id="Line"></path>
13
- <path d="M1.43885093,10.4444444 L6.83349609,10.4444444" id="Line"></path>
14
- <path d="M1.43885093,12.4444444 L6.83349609,12.4444444" id="Line"></path>
15
- <path d="M1.43885093,14.4444444 L6.83349609,14.4444444" id="Line"></path>
16
- <path d="M9.43885093,2.44444444 L14.8334961,2.44444444" id="Line"></path>
17
- <path d="M9.43885093,4.44444444 L14.8334961,4.44444444" id="Line"></path>
18
- <path d="M9.43885093,6.44444444 L14.8334961,6.44444444" id="Line"></path>
19
- <path d="M9.43885093,8.44444444 L14.8334961,8.44444444" id="Line"></path>
20
- <path d="M9.43885093,10.4444444 L14.8334961,10.4444444" id="Line"></path>
21
- <path d="M9.43885093,12.4444444 L14.8334961,12.4444444" id="Line"></path>
22
- <path d="M9.43885093,14.4444444 L14.8334961,14.4444444" id="Line"></path>
23
- </g>
24
- </g>
25
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" 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" height="24" width="24" 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" height="24" width="24" 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" width="24" height="24" 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" height="24" width="24" 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 height="24" width="24" 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" height="24" width="24" 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" height="24" width="24" 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" height="24" width="24" 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,7 +1,6 @@
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
5
  //= require arclight/truncator
7
6
 
@@ -1,51 +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 header[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
- // We want to show 0-1 or 0-2 siblings depending on where highlighted component is
20
- $previousDocs = $currentDoc.prevUntil().slice(0, 2);
21
- $nextDocs = $currentDoc.nextUntil().slice(0, 2);
22
-
23
- if ($previousDocs.length > 0 && $nextDocs.length > 0) {
24
- // Case where there are siblings on both sides, show 1 each
25
- newDocs = $('<div>');
26
- newDocs.append($previousDocs.first());
27
- newDocs.append($currentDoc);
28
- newDocs.append($nextDocs.first());
29
- } else if ($previousDocs.length > 0) {
30
- // Case where there are only previous siblings, show 2 of them
31
- newDocs = $('<div>');
32
- newDocs.append($previousDocs.get().reverse()); // previous is not in the order we need
33
- newDocs.append($currentDoc);
34
- } else {
35
- // Case where there are only next siblings, show 2 of them
36
- newDocs = $('<div>');
37
- newDocs.append($currentDoc);
38
- newDocs.append($nextDocs);
39
- }
40
- // Cleanup to remove collapsible children stuff
41
- newDocs.find('.al-toggle-view-more').remove();
42
- newDocs.find('.collapse').remove();
43
- newDocs.find('hr').remove();
44
- return newDocs;
45
- }
46
3
 
47
4
  CollectionNavigation = {
48
- init: function (el) {
5
+ init: function (el, page = 1) {
49
6
  var $el = $(el);
50
7
  var data = $el.data();
51
8
  // Add a placeholder so flashes of text are not as significant
@@ -63,7 +20,8 @@
63
20
  'f[component_level_isim][]': data.arclight.level,
64
21
  'f[has_online_content_ssim][]': data.arclight.access,
65
22
  'f[collection_sim][]': data.arclight.name,
66
- 'f[parent_ssi][]': data.arclight.parent,
23
+ 'f[parent_ssim][]': data.arclight.parent,
24
+ page: page,
67
25
  search_field: data.arclight.search_field,
68
26
  view: data.arclight.view || 'hierarchy'
69
27
  }
@@ -72,13 +30,39 @@
72
30
  var $doc = $(resp);
73
31
  var showDocs = $doc.find('article.document');
74
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();
75
40
 
76
- // Add a highlight class for the article matching the highlight id
77
- if (data.arclight.highlightId) {
78
- 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
+ );
79
49
  }
80
50
 
81
- $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);
82
66
  if (showDocs.length > 0) {
83
67
  $el.trigger('navigation.contains.elements');
84
68
  }
@@ -99,8 +83,10 @@ Blacklight.onLoad(function () {
99
83
 
100
84
  $('.al-contents').on('navigation.contains.elements', function (e) {
101
85
  var toEnable = $('[data-hierarchy-enable-me]');
86
+ var srOnly = $('h2[data-sr-enable-me]');
102
87
  toEnable.removeClass('disabled');
103
- toEnable.text('Contents');
88
+ toEnable.text(srOnly.data('hasContents'));
89
+ srOnly.text(srOnly.data('hasContents'));
104
90
 
105
91
  $(e.target).find('.collapse').on('show.bs.collapse', function (ee) {
106
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,386 @@
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; // let originalParents stay null
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
+ if (this.originalParents && this.originalParents[this.data.arclight.level]) {
134
+ return `${this.eadid}${this.originalParents[this.data.arclight.level]}`;
135
+ }
136
+ return this.data.arclight.originalDocument;
137
+ }
138
+
139
+ get requestParent() {
140
+ // Cases where you're viewing a component page (use its ancestor trail)...
141
+ if (this.originalParents && this.originalParents[this.data.arclight.level - 1]) {
142
+ return this.originalParents[this.data.arclight.level - 1];
143
+ }
144
+ // Cases where there are no parents provided...
145
+ // 1) when on a top-level collection page
146
+ // 2) when +/- gets clicked
147
+ return this.data.arclight.originalDocument.replace(this.eadid, '');
148
+ }
149
+
150
+ getData() {
151
+ const that = this;
152
+ // Add a placeholder so flashes of text are not as significant
153
+ const placeholder = new Placeholder();
154
+ this.el.after(placeholder.$el);
155
+ $.ajax({
156
+ url: this.data.arclight.path,
157
+ data: {
158
+ 'f[component_level_isim][]': this.data.arclight.level,
159
+ 'f[has_online_content_ssim][]': this.data.arclight.access,
160
+ 'f[collection_sim][]': this.data.arclight.name,
161
+ 'f[parent_ssi][]': this.requestParent,
162
+ search_field: this.data.arclight.search_field,
163
+ original_parents: this.data.arclight.originalParents,
164
+ original_document: this.originalDocument,
165
+ view: 'collection_context'
166
+ }
167
+ }).done((response) => that.updateView(response));
168
+ }
169
+
170
+ /**
171
+ * Constructs a <ul> container element with an ElementButton instance appended
172
+ * within it
173
+ * @returns {jQuery}
174
+ */
175
+ buildExpandList() {
176
+ const $ul = $('<ul></ul>');
177
+ $ul.addClass('pl-0');
178
+ $ul.addClass('prev-siblings');
179
+ const button = new ExpandButton(this.data);
180
+ $ul.append(button.$el);
181
+ return $ul;
182
+ }
183
+
184
+ /**
185
+ * Highlights the <li> element for the current Document and appends <li> the
186
+ * sibling documents for a given Document element
187
+ * @param {NavigationDocument[]} newDocs - the NavigationDocument objects for
188
+ * each resulting Solr Document
189
+ * @param {number} originalDocumentIndex
190
+ */
191
+ updateSiblings(newDocs, originalDocumentIndex) {
192
+ newDocs[originalDocumentIndex].setAsHighlighted();
193
+
194
+ // Hide all but the first previous sibling
195
+ const prevSiblingDocs = newDocs.slice(0, originalDocumentIndex);
196
+ let nextSiblingDocs = [];
197
+
198
+ if (prevSiblingDocs.length > 1 && originalDocumentIndex > 0) {
199
+ const hiddenPrevSiblingDocs = prevSiblingDocs.slice(0, -1);
200
+ hiddenPrevSiblingDocs.forEach(siblingDoc => {
201
+ siblingDoc.collapse();
202
+ });
203
+
204
+ const prevSiblingList = this.buildExpandList();
205
+ const renderedPrevSiblingItems = prevSiblingDocs.map(doc => doc.render()).join('');
206
+
207
+ prevSiblingList.append(renderedPrevSiblingItems);
208
+ this.ul.append(prevSiblingList);
209
+
210
+ nextSiblingDocs = newDocs.slice(originalDocumentIndex);
211
+ } else {
212
+ nextSiblingDocs = newDocs;
213
+ }
214
+
215
+ const renderedNextSiblingItems = nextSiblingDocs.map(newDoc => newDoc.render()).join('');
216
+
217
+ // Insert the rendered sibling documents before the <li> elements
218
+ this.ul.append(renderedNextSiblingItems);
219
+ this.el.html(this.ul);
220
+ }
221
+
222
+ /**
223
+ * Inserts <li> elements for parents (e. g. components or collections) for the
224
+ * current Document and appends <li> for each of these
225
+ * @param {NavigationDocument[]} newDocs - the NavigationDocument objects for
226
+ * each resulting Solr Document
227
+ */
228
+ updateParents(newDocs) {
229
+ const that = this;
230
+ // Case where this is a parent list and needs to be filed correctly
231
+ //
232
+ // Otherwise, retrieve the parent...
233
+ let newDocIndex = newDocs.findIndex(doc => doc.id === this.targetId);
234
+
235
+ if (newDocIndex === -1) {
236
+ const renderedDocs = newDocs.map(newDoc => newDoc.render()).join('');
237
+ this.ul.append(renderedDocs);
238
+ this.el.html(this.ul);
239
+ return;
240
+ }
241
+ // Update the docs before the item
242
+ // Retrieves the documents up to and including the "new document"
243
+ const beforeDocs = newDocs.slice(0, newDocIndex);
244
+ let prevParentList = null;
245
+ let renderedBeforeDocs;
246
+ if (beforeDocs.length > 1) {
247
+ beforeDocs.forEach(function (parentDoc) {
248
+ parentDoc.collapse();
249
+ });
250
+ renderedBeforeDocs = beforeDocs.map(newDoc => newDoc.render()).join('');
251
+ prevParentList = this.buildExpandList();
252
+ prevParentList.append(renderedBeforeDocs);
253
+ } else {
254
+ renderedBeforeDocs = beforeDocs.map(newDoc => newDoc.render()).join('');
255
+ }
256
+
257
+ // Silly but works for now
258
+ this.ul.append(prevParentList || renderedBeforeDocs);
259
+
260
+ let itemDoc = newDocs.slice(newDocIndex, newDocIndex + 1);
261
+ let renderedItemDoc = itemDoc.map(doc => doc.render()).join('');
262
+
263
+ // Update the item
264
+ const $itemDoc = $(renderedItemDoc);
265
+ this.ul.append($itemDoc);
266
+
267
+ // Update the docs after the item
268
+ const afterDocs = newDocs.slice(newDocIndex + 1, newDocs.length);
269
+ const renderedAfterDocs = afterDocs.map(newDoc => newDoc.render()).join('');
270
+
271
+ // Insert the documents after the current
272
+ this.ul.append(renderedAfterDocs);
273
+ this.el.html(this.ul);
274
+
275
+ // Initialize additional things
276
+ $itemDoc.find('.context-navigator').each(function (i, e) {
277
+ const contextNavigation = new ContextNavigation(
278
+ e, that.originalParents, that.originalDocument
279
+ );
280
+ contextNavigation.getData();
281
+ });
282
+ }
283
+
284
+
285
+ /**
286
+ * Update the ancestors for <li> elements
287
+ * @param {jQuery} $li - the <li> element for the current, highlighted
288
+ * Document in the <ul> context list of collections, components, and
289
+ * containers
290
+ */
291
+ /* eslint-disable class-methods-use-this */
292
+ updateListSiblings($li) {
293
+ const prevSiblings = $li.prevAll('.al-collection-context');
294
+ if (prevSiblings.length > 1) {
295
+ const hiddenNextSiblings = prevSiblings.slice(0, -1);
296
+ hiddenNextSiblings.toggleClass('collapsed');
297
+
298
+ const button = new NestedExpandButton();
299
+
300
+ const lastHiddenNextSibling = hiddenNextSiblings[hiddenNextSiblings.length - 1];
301
+ button.$el.insertAfter(lastHiddenNextSibling);
302
+ }
303
+ }
304
+ /* eslint-enable class-methods-use-this */
305
+
306
+ /**
307
+ * This updates the elements in the View DOM using an AJAX response containing
308
+ * the HTML of a server-rendered View template.
309
+ * It is this which is primarily used to populate the <ul> element with
310
+ * children for the navigation context, containing <li> elements for
311
+ * collections, components, and containers.
312
+ * @param {string} response - the AJAX response body
313
+ */
314
+ updateView(response) {
315
+ const that = this;
316
+ var resp = $.parseHTML(response);
317
+ var $doc = $(resp);
318
+ var newDocs = $doc.find('#documents')
319
+ .find('article')
320
+ .toArray().map(el => new NavigationDocument(el));
321
+
322
+ // See if the original document is located in the returned documents
323
+ const originalDocumentIndex = newDocs
324
+ .findIndex(doc => doc.id === that.originalDocument);
325
+ that.parentLi.find('.al-hierarchy-placeholder').remove();
326
+
327
+ // If the original document in the results, update it. If not update with a
328
+ // more complex procedure
329
+ if (originalDocumentIndex !== -1) {
330
+ this.updateSiblings(newDocs, originalDocumentIndex);
331
+ } else {
332
+ this.updateParents(
333
+ newDocs,
334
+ that.data.arclight.originalParents,
335
+ that.data.arclight.parent,
336
+ that.parentLi
337
+ );
338
+ }
339
+ this.el.parent().data('resolved', true);
340
+ this.addListenersForPlusMinus();
341
+ this.enablebuttons();
342
+ Blacklight.doBookmarkToggleBehavior();
343
+ this.el.trigger('navigation.contains.elements');
344
+ }
345
+
346
+ // eslint-disable-next-line class-methods-use-this
347
+ enablebuttons() {
348
+ var toEnable = $('[data-hierarchy-enable-me]');
349
+ var srOnly = $('h2[data-sr-enable-me]');
350
+ toEnable.removeClass('disabled');
351
+ toEnable.text(srOnly.data('hasContents'));
352
+ srOnly.text(srOnly.data('hasContents'));
353
+ }
354
+
355
+ addListenersForPlusMinus() {
356
+ const that = this;
357
+ this.ul.find('.al-toggle-view-children').on('click', (e) => {
358
+ e.preventDefault();
359
+ const targetArea = $($(e.target).attr('href'));
360
+ if (!targetArea.data().resolved) {
361
+ targetArea.find('.context-navigator').each((i, ee) => {
362
+ const contextNavigation = new ContextNavigation(
363
+ // Send null for originalParents. We want to disregard the original
364
+ // component's ancestor trail and instead use the current ID as the
365
+ // parent in the query to populate the navigator.
366
+ ee, null, that.originalDocument
367
+ );
368
+ contextNavigation.getData();
369
+ });
370
+ }
371
+ });
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Integrate the behavior into the DOM using the Blacklight#onLoad callback
377
+ *
378
+ */
379
+ Blacklight.onLoad(function () {
380
+ $('.context-navigator').each(function (i, e) {
381
+ const contextNavigation = new ContextNavigation(
382
+ e, $(this).data('arclight').originalParents, $(this).data('arclight').originalDocument
383
+ );
384
+ contextNavigation.getData();
385
+ });
386
+ });