@internetarchive/collection-browser 3.4.1 → 3.5.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 (194) hide show
  1. package/.editorconfig +29 -29
  2. package/.github/workflows/ci.yml +27 -27
  3. package/.github/workflows/gh-pages-main.yml +39 -39
  4. package/.github/workflows/npm-publish.yml +39 -39
  5. package/.github/workflows/pr-preview.yml +38 -38
  6. package/.husky/pre-commit +4 -4
  7. package/.prettierignore +1 -1
  8. package/LICENSE +661 -661
  9. package/README.md +83 -83
  10. package/dist/src/app-root.js +19 -28
  11. package/dist/src/app-root.js.map +1 -1
  12. package/dist/src/collection-browser.d.ts +27 -4
  13. package/dist/src/collection-browser.js +973 -801
  14. package/dist/src/collection-browser.js.map +1 -1
  15. package/dist/src/collection-facets/facet-row.js +143 -143
  16. package/dist/src/collection-facets/facet-row.js.map +1 -1
  17. package/dist/src/collection-facets/more-facets-content.js +29 -40
  18. package/dist/src/collection-facets/more-facets-content.js.map +1 -1
  19. package/dist/src/collection-facets/more-facets-pagination.js +6 -10
  20. package/dist/src/collection-facets/more-facets-pagination.js.map +1 -1
  21. package/dist/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.js +16 -21
  22. package/dist/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.js.map +1 -1
  23. package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +7 -10
  24. package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -1
  25. package/dist/src/collection-facets/smart-facets/smart-facet-button.js +3 -2
  26. package/dist/src/collection-facets/smart-facets/smart-facet-button.js.map +1 -1
  27. package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js +9 -11
  28. package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js.map +1 -1
  29. package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js +7 -7
  30. package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js.map +1 -1
  31. package/dist/src/collection-facets/toggle-switch.js +4 -6
  32. package/dist/src/collection-facets/toggle-switch.js.map +1 -1
  33. package/dist/src/collection-facets.js +309 -310
  34. package/dist/src/collection-facets.js.map +1 -1
  35. package/dist/src/data-source/collection-browser-data-source-interface.d.ts +10 -1
  36. package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
  37. package/dist/src/data-source/collection-browser-data-source.d.ts +19 -1
  38. package/dist/src/data-source/collection-browser-data-source.js +71 -65
  39. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  40. package/dist/src/data-source/collection-browser-query-state.d.ts +1 -2
  41. package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
  42. package/dist/src/data-source/models.d.ts +11 -0
  43. package/dist/src/data-source/models.js.map +1 -1
  44. package/dist/src/empty-placeholder.js +19 -18
  45. package/dist/src/empty-placeholder.js.map +1 -1
  46. package/dist/src/expanded-date-picker.js +6 -10
  47. package/dist/src/expanded-date-picker.js.map +1 -1
  48. package/dist/src/language-code-handler/language-code-handler.js +2 -2
  49. package/dist/src/language-code-handler/language-code-handler.js.map +1 -1
  50. package/dist/src/manage/manage-bar.js +9 -15
  51. package/dist/src/manage/manage-bar.js.map +1 -1
  52. package/dist/src/manage/remove-items-modal-content.js +2 -2
  53. package/dist/src/manage/remove-items-modal-content.js.map +1 -1
  54. package/dist/src/models.d.ts +2 -6
  55. package/dist/src/models.js +44 -54
  56. package/dist/src/models.js.map +1 -1
  57. package/dist/src/restoration-state-handler.d.ts +1 -2
  58. package/dist/src/restoration-state-handler.js +12 -19
  59. package/dist/src/restoration-state-handler.js.map +1 -1
  60. package/dist/src/sort-filter-bar/alpha-bar.js +9 -14
  61. package/dist/src/sort-filter-bar/alpha-bar.js.map +1 -1
  62. package/dist/src/sort-filter-bar/sort-filter-bar.js +14 -24
  63. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  64. package/dist/src/tiles/base-tile-component.js +1 -2
  65. package/dist/src/tiles/base-tile-component.js.map +1 -1
  66. package/dist/src/tiles/grid/account-tile.js +5 -7
  67. package/dist/src/tiles/grid/account-tile.js.map +1 -1
  68. package/dist/src/tiles/grid/collection-tile.js +3 -6
  69. package/dist/src/tiles/grid/collection-tile.js.map +1 -1
  70. package/dist/src/tiles/grid/item-tile.js +23 -33
  71. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  72. package/dist/src/tiles/grid/search-tile.js +1 -2
  73. package/dist/src/tiles/grid/search-tile.js.map +1 -1
  74. package/dist/src/tiles/grid/tile-stats.js +2 -3
  75. package/dist/src/tiles/grid/tile-stats.js.map +1 -1
  76. package/dist/src/tiles/hover/hover-pane-controller.js +21 -28
  77. package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
  78. package/dist/src/tiles/hover/tile-hover-pane.js +3 -4
  79. package/dist/src/tiles/hover/tile-hover-pane.js.map +1 -1
  80. package/dist/src/tiles/image-block.js +5 -8
  81. package/dist/src/tiles/image-block.js.map +1 -1
  82. package/dist/src/tiles/item-image.js +12 -19
  83. package/dist/src/tiles/item-image.js.map +1 -1
  84. package/dist/src/tiles/list/tile-list-compact.js +17 -25
  85. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  86. package/dist/src/tiles/list/tile-list.js +34 -55
  87. package/dist/src/tiles/list/tile-list.js.map +1 -1
  88. package/dist/src/tiles/overlay/icon-overlay.js +1 -2
  89. package/dist/src/tiles/overlay/icon-overlay.js.map +1 -1
  90. package/dist/src/tiles/overlay/text-overlay.js +2 -4
  91. package/dist/src/tiles/overlay/text-overlay.js.map +1 -1
  92. package/dist/src/tiles/text-snippet-block.js +2 -4
  93. package/dist/src/tiles/text-snippet-block.js.map +1 -1
  94. package/dist/src/tiles/tile-dispatcher.js +22 -30
  95. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  96. package/dist/src/tiles/tile-display-value-provider.js +5 -9
  97. package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
  98. package/dist/src/tiles/tile-mediatype-icon.js +12 -19
  99. package/dist/src/tiles/tile-mediatype-icon.js.map +1 -1
  100. package/dist/src/utils/collapse-repeated-quotes.js +1 -1
  101. package/dist/src/utils/collapse-repeated-quotes.js.map +1 -1
  102. package/dist/src/utils/facet-utils.js +3 -5
  103. package/dist/src/utils/facet-utils.js.map +1 -1
  104. package/dist/src/utils/format-count.js +10 -10
  105. package/dist/src/utils/format-count.js.map +1 -1
  106. package/dist/src/utils/resolve-mediatype.js +2 -3
  107. package/dist/src/utils/resolve-mediatype.js.map +1 -1
  108. package/dist/test/collection-browser.test.js +336 -380
  109. package/dist/test/collection-browser.test.js.map +1 -1
  110. package/dist/test/collection-facets/facet-row.test.js +37 -52
  111. package/dist/test/collection-facets/facet-row.test.js.map +1 -1
  112. package/dist/test/collection-facets/facets-template.test.js +17 -23
  113. package/dist/test/collection-facets/facets-template.test.js.map +1 -1
  114. package/dist/test/collection-facets/more-facets-content.test.js +22 -32
  115. package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
  116. package/dist/test/collection-facets/more-facets-pagination.test.js +16 -22
  117. package/dist/test/collection-facets/more-facets-pagination.test.js.map +1 -1
  118. package/dist/test/collection-facets/toggle-switch.test.js +22 -19
  119. package/dist/test/collection-facets/toggle-switch.test.js.map +1 -1
  120. package/dist/test/collection-facets.test.js +60 -77
  121. package/dist/test/collection-facets.test.js.map +1 -1
  122. package/dist/test/empty-placeholder.test.js +11 -17
  123. package/dist/test/empty-placeholder.test.js.map +1 -1
  124. package/dist/test/expanded-date-picker.test.js +8 -14
  125. package/dist/test/expanded-date-picker.test.js.map +1 -1
  126. package/dist/test/icon-overlay.test.js +7 -6
  127. package/dist/test/icon-overlay.test.js.map +1 -1
  128. package/dist/test/image-block.test.js +16 -26
  129. package/dist/test/image-block.test.js.map +1 -1
  130. package/dist/test/item-image.test.js +23 -32
  131. package/dist/test/item-image.test.js.map +1 -1
  132. package/dist/test/manage/manage-bar.test.js +21 -33
  133. package/dist/test/manage/manage-bar.test.js.map +1 -1
  134. package/dist/test/manage/remove-items-modal-content.test.js +10 -15
  135. package/dist/test/manage/remove-items-modal-content.test.js.map +1 -1
  136. package/dist/test/mocks/mock-search-service.js +2 -3
  137. package/dist/test/mocks/mock-search-service.js.map +1 -1
  138. package/dist/test/restoration-state-handler.test.js +14 -54
  139. package/dist/test/restoration-state-handler.test.js.map +1 -1
  140. package/dist/test/review-block.test.js +16 -18
  141. package/dist/test/review-block.test.js.map +1 -1
  142. package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js +2 -3
  143. package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js.map +1 -1
  144. package/dist/test/sort-filter-bar/alpha-bar.test.js +18 -24
  145. package/dist/test/sort-filter-bar/alpha-bar.test.js.map +1 -1
  146. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +178 -180
  147. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
  148. package/dist/test/text-overlay.test.js +16 -15
  149. package/dist/test/text-overlay.test.js.map +1 -1
  150. package/dist/test/text-snippet-block.test.js +14 -19
  151. package/dist/test/text-snippet-block.test.js.map +1 -1
  152. package/dist/test/tile-stats.test.js +73 -34
  153. package/dist/test/tile-stats.test.js.map +1 -1
  154. package/dist/test/tiles/grid/account-tile.test.js +25 -25
  155. package/dist/test/tiles/grid/account-tile.test.js.map +1 -1
  156. package/dist/test/tiles/grid/collection-tile.test.js +13 -19
  157. package/dist/test/tiles/grid/collection-tile.test.js.map +1 -1
  158. package/dist/test/tiles/grid/item-tile.test.js +64 -91
  159. package/dist/test/tiles/grid/item-tile.test.js.map +1 -1
  160. package/dist/test/tiles/grid/search-tile.test.js +9 -13
  161. package/dist/test/tiles/grid/search-tile.test.js.map +1 -1
  162. package/dist/test/tiles/hover/hover-pane-controller.test.js +23 -35
  163. package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -1
  164. package/dist/test/tiles/hover/tile-hover-pane.test.js +12 -16
  165. package/dist/test/tiles/hover/tile-hover-pane.test.js.map +1 -1
  166. package/dist/test/tiles/list/tile-list-compact.test.js +34 -48
  167. package/dist/test/tiles/list/tile-list-compact.test.js.map +1 -1
  168. package/dist/test/tiles/list/tile-list.test.js +76 -105
  169. package/dist/test/tiles/list/tile-list.test.js.map +1 -1
  170. package/dist/test/tiles/tile-dispatcher.test.js +17 -30
  171. package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
  172. package/dist/test/tiles/tile-mediatype-icon.test.js +12 -24
  173. package/dist/test/tiles/tile-mediatype-icon.test.js.map +1 -1
  174. package/eslint.config.mjs +53 -53
  175. package/index.html +24 -24
  176. package/local.archive.org.cert +86 -86
  177. package/local.archive.org.key +27 -27
  178. package/package.json +119 -118
  179. package/renovate.json +6 -6
  180. package/src/collection-browser.ts +3071 -2829
  181. package/src/collection-facets/facet-row.ts +299 -296
  182. package/src/collection-facets.ts +1010 -995
  183. package/src/data-source/collection-browser-data-source-interface.ts +345 -333
  184. package/src/data-source/collection-browser-data-source.ts +1441 -1401
  185. package/src/data-source/collection-browser-query-state.ts +59 -65
  186. package/src/data-source/models.ts +56 -43
  187. package/src/models.ts +864 -870
  188. package/src/restoration-state-handler.ts +546 -544
  189. package/test/collection-browser.test.ts +2413 -2403
  190. package/test/restoration-state-handler.test.ts +480 -510
  191. package/tsconfig.json +25 -20
  192. package/vite.config.ts +29 -22
  193. package/web-dev-server.config.mjs +30 -30
  194. package/web-test-runner.config.mjs +41 -41
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\nimport { msg } from '@lit/localize';\nimport type { MediaType } from '@internetarchive/field-parsers';\nimport {\n AggregationSortType,\n HitType,\n SearchReview,\n SearchResult,\n SortDirection,\n} from '@internetarchive/search-service';\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\nimport { resolveMediatype } from './utils/resolve-mediatype';\n\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\nimport { restrictedIcon } from './assets/img/icons/restricted';\n\n/**\n * Flags that can affect the visibility of content on a tile\n */\ninterface TileFlags {\n loginRequired: boolean;\n contentWarning: boolean;\n}\n\n/**\n * Different types of tile overlays, corresponding to the above flags.\n */\nexport type TileOverlayType = 'login-required' | 'content-warning';\n\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\n 'login-required': msg('Log in to view this item'),\n 'content-warning': msg('Content may be inappropriate'),\n};\n\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\n 'login-required': loginRequiredIcon,\n 'content-warning': restrictedIcon,\n};\n\n/**\n * What type of request produced a given set of hits:\n * - `search_query`: Hits produced by an explicit user query and/or applied filters on any page\n * - `collection_members`: Hits produced for a collection page without any query or filters\n * - `profile_tab`: Hits produced for a tab of the profile page without any query or filters\n * - `unknown`: Hits produced via any other means\n */\nexport type HitRequestSource =\n | 'search_query'\n | 'collection_members'\n | 'profile_tab'\n | 'unknown';\n\n/**\n * Class for converting & storing raw search results in the correct format for UI tiles.\n */\nexport class TileModel {\n /** For TV hits. List of identifiers for any commercials contained. */\n adIds?: string[];\n\n averageRating?: number;\n\n /** For Web Archive hits on profile pages. List of capture dates for the current URL. */\n captureDates?: Date[];\n\n /** Whether this tile is currently checked for item management functions */\n checked: boolean;\n\n collectionIdentifier?: string;\n\n collectionName?: string;\n\n collectionFilesCount: number;\n\n collections: string[];\n\n collectionSize: number;\n\n commentCount: number;\n\n creator?: string;\n\n creators: string[];\n\n /** A string representation of the publication date, used strictly for passing preformatted dates to the parent */\n dateStr?: string;\n\n /** Date added to public search (software-defined) [from MD field: addeddate] */\n dateAdded?: Date;\n\n /** Date archived (software-defined) item created on archive.org [from MD field: publicdate] */\n dateArchived?: Date;\n\n /** Date work published in the world (user-defined) [from MD field: date] */\n datePublished?: Date;\n\n /** Date reviewed (user-created) most recent review [from MD field: reviewdate] */\n dateReviewed?: Date;\n\n description?: string;\n\n /** For TV hits. List of URLs for any fact-checks of the contained clips. */\n factChecks?: string[];\n\n favCount: number;\n\n hitRequestSource: HitRequestSource;\n\n hitType?: HitType;\n\n href?: string;\n\n identifier?: string;\n\n /** Whether this model represents a TV clip */\n isClip?: boolean;\n\n issue?: string;\n\n itemCount: number;\n\n mediatype: MediaType;\n\n review?: SearchReview;\n\n source?: string;\n\n snippets?: string[];\n\n subjects: string[];\n\n thumbnailUrl?: string;\n\n title: string;\n\n tvClipCount?: number;\n\n viewCount?: number;\n\n volume?: string;\n\n weeklyViewCount?: number;\n\n loginRequired: boolean;\n\n contentWarning: boolean;\n\n constructor(\n result: SearchResult,\n hitRequestSource: HitRequestSource = 'unknown',\n ) {\n const flags = this.getFlags(result);\n\n this.adIds = result.ad_id?.values;\n this.averageRating = result.avg_rating?.value;\n this.captureDates = result.capture_dates?.values;\n this.checked = false;\n this.collections = result.collection?.values ?? [];\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\n this.collectionSize = result.collection_size?.value ?? 0;\n this.commentCount = result.num_reviews?.value ?? 0;\n this.creator = result.creator?.value;\n this.creators = result.creator?.values ?? [];\n this.dateAdded = result.addeddate?.value;\n this.dateArchived = result.publicdate?.value;\n this.datePublished = result.date?.value;\n this.dateReviewed = result.reviewdate?.value;\n this.description = result.description?.values.join('\\n');\n this.factChecks = result.factcheck?.values;\n this.favCount = result.num_favorites?.value ?? 0;\n this.hitRequestSource = hitRequestSource;\n this.hitType = result.rawMetadata?.hit_type;\n this.href = collapseRepeatedQuotes(\n result.review?.__href__ ?? result.__href__?.value,\n );\n this.identifier = TileModel.cleanIdentifier(result.identifier);\n this.isClip = result.is_clip?.value;\n this.issue = result.issue?.value;\n this.itemCount = result.item_count?.value ?? 0;\n this.mediatype = resolveMediatype(result);\n this.review = result.review;\n this.snippets = result.highlight?.values ?? [];\n this.source = result.source?.value;\n this.subjects = result.subject?.values ?? [];\n this.thumbnailUrl = result.__img__?.value;\n this.title = result.title?.value ?? '';\n this.tvClipCount = result.num_clips?.value ?? 0;\n this.volume = result.volume?.value;\n this.viewCount = result.downloads?.value;\n this.weeklyViewCount = result.week?.value;\n this.loginRequired = flags.loginRequired;\n this.contentWarning = flags.contentWarning;\n }\n\n /**\n * Copies the contents of this TileModel onto a new instance\n */\n clone(): TileModel {\n const cloned = new TileModel({});\n cloned.adIds = this.adIds;\n cloned.averageRating = this.averageRating;\n cloned.captureDates = this.captureDates;\n cloned.checked = this.checked;\n cloned.collections = this.collections;\n cloned.collectionFilesCount = this.collectionFilesCount;\n cloned.collectionSize = this.collectionSize;\n cloned.commentCount = this.commentCount;\n cloned.creator = this.creator;\n cloned.creators = this.creators;\n cloned.dateStr = this.dateStr;\n cloned.dateAdded = this.dateAdded;\n cloned.dateArchived = this.dateArchived;\n cloned.datePublished = this.datePublished;\n cloned.dateReviewed = this.dateReviewed;\n cloned.description = this.description;\n cloned.factChecks = this.factChecks;\n cloned.favCount = this.favCount;\n cloned.hitRequestSource = this.hitRequestSource;\n cloned.hitType = this.hitType;\n cloned.href = this.href;\n cloned.identifier = this.identifier;\n cloned.isClip = this.isClip;\n cloned.issue = this.issue;\n cloned.itemCount = this.itemCount;\n cloned.mediatype = this.mediatype;\n cloned.snippets = this.snippets;\n cloned.source = this.source;\n cloned.subjects = this.subjects;\n cloned.thumbnailUrl = this.thumbnailUrl;\n cloned.title = this.title;\n cloned.tvClipCount = this.tvClipCount;\n cloned.volume = this.volume;\n cloned.viewCount = this.viewCount;\n cloned.weeklyViewCount = this.weeklyViewCount;\n cloned.loginRequired = this.loginRequired;\n cloned.contentWarning = this.contentWarning;\n return cloned;\n }\n\n /**\n * Whether this model represents the result of a TV search query.\n */\n get isTvSearchResult(): boolean {\n return (\n this.hitType === 'tv_clip' && this.hitRequestSource === 'search_query'\n );\n }\n\n /**\n * Determines the appropriate tile flags for the given search result\n * (login required and/or content warning)\n */\n private getFlags(result: SearchResult): TileFlags {\n const flags: TileFlags = {\n loginRequired: false,\n contentWarning: false,\n };\n\n // Check if item and item in \"modifying\" collection, setting above flags\n if (\n result.collection?.values.length &&\n result.mediatype?.value !== 'collection'\n ) {\n for (const collection of result.collection?.values ?? []) {\n if (collection === 'loggedin') {\n flags.loginRequired = true;\n if (flags.contentWarning) break;\n }\n if (collection === 'no-preview') {\n flags.contentWarning = true;\n if (flags.loginRequired) break;\n }\n }\n }\n\n return flags;\n }\n\n private static cleanIdentifier(\n identifier: string | undefined,\n ): string | undefined {\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\n // are suffixed with values that need to be stripped. Those values are separated\n // from the item identifier itself with '|'.\n const barIndex = identifier?.indexOf('|') ?? -1;\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\n return cleaned;\n }\n}\n\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\n\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\n\nexport type TileDisplayMode =\n | 'grid'\n | 'list-compact'\n | 'list-detail'\n | 'list-header';\n\n/**\n * This is mainly used to set the cookies for the collection display mode.\n *\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\n */\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\n\n/**\n * The sort fields shown in the sort filter bar\n */\nexport enum SortField {\n 'default' = 'default',\n 'unrecognized' = 'unrecognized',\n 'relevance' = 'relevance',\n 'alltimeview' = 'alltimeview',\n 'weeklyview' = 'weeklyview',\n 'title' = 'title',\n 'date' = 'date',\n 'datearchived' = 'datearchived',\n 'datereviewed' = 'datereviewed',\n 'dateadded' = 'dateadded',\n 'datefavorited' = 'datefavorited',\n 'creator' = 'creator',\n}\n\n/**\n * Views-related sort fields\n */\nexport const ALL_VIEWS_SORT_FIELDS = [\n SortField.weeklyview,\n SortField.alltimeview,\n] as const;\nexport type ViewsSortField = (typeof ALL_VIEWS_SORT_FIELDS)[number];\n\n/**\n * Date-related sort fields\n */\nexport const ALL_DATE_SORT_FIELDS = [\n SortField.datefavorited,\n SortField.date,\n SortField.datearchived,\n SortField.datereviewed,\n SortField.dateadded,\n] as const;\nexport type DateSortField = (typeof ALL_DATE_SORT_FIELDS)[number];\n\nexport interface SortOption {\n /**\n * The SortField enum member corresponding to this option.\n */\n field: SortField;\n\n /**\n * The default sort direction to apply when this sort option is first selected.\n */\n defaultSortDirection: SortDirection | null;\n\n /**\n * Whether this sort option allows its sort direction to be changed from the default.\n */\n canSetDirection: boolean;\n\n /**\n * Whether this sort option may appear in the sort bar.\n */\n shownInSortBar: boolean;\n\n /**\n * Whether this sort option should be saved to the URL.\n * If false, then no `sort` param will be added to the URL when this sort option\n * is selected.\n */\n shownInURL: boolean;\n\n /**\n * Whether this sort option is passed to the search service.\n * If false, then no sort param will be passed to the search service at all when\n * this sort option is selected.\n */\n handledBySearchService: boolean;\n\n /**\n * The string identifying this sort field to the search service & backend API.\n */\n searchServiceKey?: string;\n\n /**\n * The human-readable name to use for this option in the sort bar (if applicable).\n */\n displayName: string;\n\n /**\n * A list of URL param keys that should be mapped to this sort option.\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\n */\n urlNames: (string | null | undefined)[];\n}\n\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\n // In these cases, we defer to whatever sort the backend chooses.\n // For the search page, the default is always relevance sort.\n // For collection pages _without a query_, the default is usually weekly views, but this can be\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\n // default is again relevance sort.\n // For fav-* collections only, the default is instead sorting by date favorited.\n [SortField.default]: {\n field: SortField.default,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\n displayName: '',\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\n },\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\n // when searching, but they are not displayed in the sort bar and we do not actively manage\n // their URL param beyond flipping the direction as needed.\n [SortField.unrecognized]: {\n field: SortField.unrecognized,\n defaultSortDirection: null,\n canSetDirection: true,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\n displayName: '',\n urlNames: [],\n },\n // Relevance sort is unique in that it does not produce a URL param when it is set.\n // It is only available when there is a user-specified query that relevancy can be scored against.\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\n [SortField.relevance]: {\n field: SortField.relevance,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: true,\n shownInURL: false,\n handledBySearchService: false,\n displayName: 'Relevance',\n urlNames: ['_score'],\n },\n [SortField.alltimeview]: {\n field: SortField.alltimeview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'downloads',\n displayName: 'All-time views',\n urlNames: ['downloads'],\n },\n [SortField.weeklyview]: {\n field: SortField.weeklyview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'week',\n displayName: 'Weekly views',\n urlNames: ['week'],\n },\n [SortField.title]: {\n field: SortField.title,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'titleSorter',\n displayName: 'Title',\n urlNames: ['title', 'titleSorter'],\n },\n [SortField.date]: {\n field: SortField.date,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'date',\n displayName: 'Date published',\n urlNames: ['date'],\n },\n [SortField.datearchived]: {\n field: SortField.datearchived,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'publicdate',\n displayName: 'Date archived',\n urlNames: ['publicdate'],\n },\n [SortField.datereviewed]: {\n field: SortField.datereviewed,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'reviewdate',\n displayName: 'Date reviewed',\n urlNames: ['reviewdate'],\n },\n [SortField.dateadded]: {\n field: SortField.dateadded,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'addeddate',\n displayName: 'Date added',\n urlNames: ['addeddate'],\n },\n [SortField.datefavorited]: {\n field: SortField.datefavorited,\n defaultSortDirection: 'desc',\n canSetDirection: false,\n shownInSortBar: true, // But only when viewing fav-* collections\n shownInURL: false,\n handledBySearchService: false,\n searchServiceKey: 'favoritedate',\n displayName: 'Date favorited',\n urlNames: ['favoritedate'],\n },\n [SortField.creator]: {\n field: SortField.creator,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'creatorSorter',\n displayName: 'Creator',\n urlNames: ['creator', 'creatorSorter'],\n },\n};\n\n/**\n * Returns the SortOption corresponding to the given API sort name, or\n * the \"unrecognized\" SortOption if none matches.\n */\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\n return (\n Object.values(SORT_OPTIONS).find(opt =>\n opt.urlNames.some(name => sortName === name),\n ) ?? SORT_OPTIONS[SortField.unrecognized]\n );\n}\n\nexport const defaultSortAvailability: Record<SortField, boolean> = {\n [SortField.relevance]: true,\n [SortField.weeklyview]: true,\n [SortField.alltimeview]: true,\n [SortField.title]: true,\n [SortField.datefavorited]: false,\n [SortField.date]: true,\n [SortField.datearchived]: true,\n [SortField.datereviewed]: true,\n [SortField.dateadded]: true,\n [SortField.creator]: true,\n [SortField.default]: false,\n [SortField.unrecognized]: false,\n};\n\nexport const favoritesSortAvailability: Record<SortField, boolean> = {\n ...defaultSortAvailability,\n [SortField.datefavorited]: true,\n};\n\nexport const tvSortAvailability: Record<SortField, boolean> = {\n ...defaultSortAvailability,\n [SortField.date]: false,\n [SortField.datereviewed]: false,\n [SortField.dateadded]: false,\n};\n\nexport const defaultProfileElementSorts: Record<\n string,\n Exclude<SortField, SortField.default>\n> = {\n uploads: SortField.datearchived,\n reviews: SortField.datereviewed,\n collections: SortField.datearchived,\n web_archives: SortField.datearchived,\n};\n\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\nexport type PrefixFilterType = 'title' | 'creator';\n\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\nexport type PrefixFilterCounts = Record<string, number>;\n\n/**\n * A map from prefix filter types to the corresponding aggregation keys\n * that are needed to fetch the filter counts from the backend.\n */\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\n title: 'firstTitle',\n creator: 'firstCreator',\n};\n\n/**\n * Different facet loading strategies that can be used with collection browser.\n * - `eager`: Facet data is always loaded as soon as a search is performed\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\n * any logged in user.\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\n * In the mobile layout, functions exactly as `lazy-mobile`.\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\n * indicating that they are unavailable.\n */\nexport type FacetLoadStrategy =\n | 'eager'\n | 'lazy-mobile'\n | 'opt-in-or-login'\n | 'opt-in'\n | 'off';\n\n/**\n * Union of the facet types that are available in the sidebar.\n */\nexport type FacetOption =\n | 'subject'\n | 'lending'\n | 'mediatype'\n | 'language'\n | 'creator'\n | 'collection'\n | 'year'\n // TV-specific facet options:\n | 'program'\n | 'person'\n | 'sponsor';\n\nexport type SelectedFacetState = 'selected' | 'hidden';\n\nexport type FacetState = SelectedFacetState | 'none';\n\nexport interface FacetBucket {\n key: string;\n count: number;\n state: FacetState;\n // for some facets, we augment the key with a display value\n displayText?: string;\n // for TV channel facets, we add a parenthesized secondary name\n extraNote?: string;\n}\n\nexport interface FacetGroup {\n title: string;\n key: FacetOption;\n buckets: FacetBucket[];\n}\n\n/**\n * Information about a user interaction event on a facet.\n */\nexport type FacetEventDetails = {\n /**\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\n */\n facetType: FacetOption;\n /**\n * The bucket corresponding to the facet that was interacted with, including the\n * updated state of the facet after the interaction.\n */\n bucket: FacetBucket;\n /**\n * Whether the interaction occurred on a negative facet.\n */\n negative: boolean;\n};\n\nexport type FacetValue = string;\n\nexport type SelectedFacets = Partial<\n Record<FacetOption, Record<FacetValue, FacetBucket>>\n>;\n\nexport const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({\n subject: {},\n lending: {},\n mediatype: {},\n language: {},\n creator: {},\n collection: {},\n year: {},\n program: {},\n person: {},\n sponsor: {},\n});\n\n/**\n * For TV search results, what types of TV clips to restrict the results to.\n */\nexport type TvClipFilterType = 'all' | 'commercials' | 'factchecks' | 'quotes';\n\n/**\n * Map from TV clip filter types to their corresponding URL params\n */\nexport const tvClipFiltersToURLParams: Record<TvClipFilterType, string> = {\n all: '',\n commercials: 'only_commercials',\n factchecks: 'only_factchecks',\n quotes: 'only_quotes',\n};\n\n/**\n * Map from allowed TV filtering parameters in the URL to their corresponding filter type\n */\nexport const tvClipURLParamsToFilters: Record<string, TvClipFilterType> = {\n only_commercials: 'commercials',\n only_factchecks: 'factchecks',\n only_quotes: 'quotes',\n};\n\n/**\n * Facet display order when presenting results for all search types *except* TV (see below).\n */\nexport const defaultFacetDisplayOrder: FacetOption[] = [\n 'mediatype',\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\n 'year',\n 'subject',\n 'collection',\n 'creator',\n 'language',\n];\n\n/**\n * Specialized facet ordering when displaying TV search results\n */\nexport const tvFacetDisplayOrder: FacetOption[] = [\n 'program',\n 'creator',\n 'year',\n 'subject',\n 'collection',\n 'person',\n 'sponsor',\n 'language',\n];\n\n/**\n * Human-readable titles for each facet group.\n */\nexport const facetTitles: Record<FacetOption, string> = {\n subject: 'Subject',\n lending: 'Availability',\n mediatype: 'Media Type',\n language: 'Language',\n creator: 'Creator',\n collection: 'Collection',\n year: 'Year',\n program: 'Program',\n person: 'Person',\n sponsor: 'Sponsor',\n};\n\n/**\n * The default sort type to use for each facet type\n */\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.COUNT,\n lending: AggregationSortType.COUNT,\n mediatype: AggregationSortType.COUNT,\n language: AggregationSortType.COUNT,\n creator: AggregationSortType.COUNT,\n collection: AggregationSortType.COUNT,\n year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default\n program: AggregationSortType.COUNT,\n person: AggregationSortType.COUNT,\n sponsor: AggregationSortType.COUNT,\n};\n\n/**\n * The sort type corresponding to facet bucket values, for each facet type\n * (i.e., the opposite of \"sort by count\" for that type).\n */\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.ALPHABETICAL,\n lending: AggregationSortType.ALPHABETICAL,\n mediatype: AggregationSortType.ALPHABETICAL,\n language: AggregationSortType.ALPHABETICAL,\n creator: AggregationSortType.ALPHABETICAL,\n collection: AggregationSortType.ALPHABETICAL,\n year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)\n program: AggregationSortType.ALPHABETICAL,\n person: AggregationSortType.ALPHABETICAL,\n sponsor: AggregationSortType.ALPHABETICAL,\n};\n\nexport type LendingFacetKey =\n | 'is_lendable'\n | 'is_borrowable'\n | 'available_to_borrow'\n | 'is_browsable'\n | 'available_to_browse'\n | 'is_readable'\n | 'available_to_waitlist';\n\n/**\n * Maps valid lending keys to whether they should be visible in the facet sidebar\n */\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\n is_lendable: true,\n is_borrowable: false,\n available_to_borrow: true,\n is_browsable: false,\n available_to_browse: false,\n is_readable: true,\n available_to_waitlist: false,\n};\n\n/**\n * Maps valid, visible lending keys to their facet sidebar display text\n */\nexport const lendingFacetDisplayNames: Partial<\n Record<LendingFacetKey, string>\n> = {\n is_lendable: 'Lending Library',\n available_to_borrow: 'Borrow 14 Days',\n is_readable: 'Always Available',\n};\n\n/**\n * A record of which admin-only collections should be suppressed from being displayed\n * as facets or in an item's list of collections.\n */\nexport const suppressedCollections: Record<string, boolean> = {\n deemphasize: true,\n community: true,\n stream_only: true,\n samples_only: true,\n test_collection: true,\n printdisabled: true,\n 'openlibrary-ol': true,\n nationalemergencylibrary: true,\n china: true,\n americana: true,\n toronto: true,\n};\n\n/**\n * A record of manageable item\n */\nexport interface ManageableItem {\n identifier: string;\n title?: string;\n dateStr?: string;\n date?: string;\n}\n\n/**\n * Possible states for whether & how the user has overridden their user preference\n * for blurring behavior on tiles with sensitive content.\n * - `no-override`: The user has not overridden their user preference, so simply\n * respect the preference as given.\n * - `on`: The user has overridden their preference and wants tile blurring enabled.\n * - `off`: The user has overridden their preference and wants tile blurring disabled.\n */\nexport type TileBlurOverrideState = 'no-override' | 'on' | 'off';\n"]}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\r\nimport { msg } from '@lit/localize';\r\nimport type { MediaType } from '@internetarchive/field-parsers';\r\nimport {\r\n AggregationSortType,\r\n HitType,\r\n SearchReview,\r\n SearchResult,\r\n SortDirection,\r\n} from '@internetarchive/search-service';\r\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\r\nimport { resolveMediatype } from './utils/resolve-mediatype';\r\n\r\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\r\nimport { restrictedIcon } from './assets/img/icons/restricted';\r\n\r\n/**\r\n * Flags that can affect the visibility of content on a tile\r\n */\r\ninterface TileFlags {\r\n loginRequired: boolean;\r\n contentWarning: boolean;\r\n}\r\n\r\n/**\r\n * Different types of tile overlays, corresponding to the above flags.\r\n */\r\nexport type TileOverlayType = 'login-required' | 'content-warning';\r\n\r\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\r\n 'login-required': msg('Log in to view this item'),\r\n 'content-warning': msg('Content may be inappropriate'),\r\n};\r\n\r\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\r\n 'login-required': loginRequiredIcon,\r\n 'content-warning': restrictedIcon,\r\n};\r\n\r\n/**\r\n * What type of request produced a given set of hits:\r\n * - `search_query`: Hits produced by an explicit user query and/or applied filters on any page\r\n * - `collection_members`: Hits produced for a collection page without any query or filters\r\n * - `profile_tab`: Hits produced for a tab of the profile page without any query or filters\r\n * - `unknown`: Hits produced via any other means\r\n */\r\nexport type HitRequestSource =\r\n | 'search_query'\r\n | 'collection_members'\r\n | 'profile_tab'\r\n | 'unknown';\r\n\r\n/**\r\n * Class for converting & storing raw search results in the correct format for UI tiles.\r\n */\r\nexport class TileModel {\r\n /** For TV hits. List of identifiers for any commercials contained. */\r\n adIds?: string[];\r\n\r\n averageRating?: number;\r\n\r\n /** For Web Archive hits on profile pages. List of capture dates for the current URL. */\r\n captureDates?: Date[];\r\n\r\n /** Whether this tile is currently checked for item management functions */\r\n checked: boolean;\r\n\r\n collectionIdentifier?: string;\r\n\r\n collectionName?: string;\r\n\r\n collectionFilesCount: number;\r\n\r\n collections: string[];\r\n\r\n collectionSize: number;\r\n\r\n commentCount: number;\r\n\r\n creator?: string;\r\n\r\n creators: string[];\r\n\r\n /** A string representation of the publication date, used strictly for passing preformatted dates to the parent */\r\n dateStr?: string;\r\n\r\n /** Date added to public search (software-defined) [from MD field: addeddate] */\r\n dateAdded?: Date;\r\n\r\n /** Date archived (software-defined) item created on archive.org [from MD field: publicdate] */\r\n dateArchived?: Date;\r\n\r\n /** Date work published in the world (user-defined) [from MD field: date] */\r\n datePublished?: Date;\r\n\r\n /** Date reviewed (user-created) most recent review [from MD field: reviewdate] */\r\n dateReviewed?: Date;\r\n\r\n description?: string;\r\n\r\n /** For TV hits. List of URLs for any fact-checks of the contained clips. */\r\n factChecks?: string[];\r\n\r\n favCount: number;\r\n\r\n hitRequestSource: HitRequestSource;\r\n\r\n hitType?: HitType;\r\n\r\n href?: string;\r\n\r\n identifier?: string;\r\n\r\n /** Whether this model represents a TV clip */\r\n isClip?: boolean;\r\n\r\n issue?: string;\r\n\r\n itemCount: number;\r\n\r\n mediatype: MediaType;\r\n\r\n review?: SearchReview;\r\n\r\n source?: string;\r\n\r\n snippets?: string[];\r\n\r\n subjects: string[];\r\n\r\n thumbnailUrl?: string;\r\n\r\n title: string;\r\n\r\n tvClipCount?: number;\r\n\r\n viewCount?: number;\r\n\r\n volume?: string;\r\n\r\n weeklyViewCount?: number;\r\n\r\n loginRequired: boolean;\r\n\r\n contentWarning: boolean;\r\n\r\n constructor(\r\n result: SearchResult,\r\n hitRequestSource: HitRequestSource = 'unknown',\r\n ) {\r\n const flags = this.getFlags(result);\r\n\r\n this.adIds = result.ad_id?.values;\r\n this.averageRating = result.avg_rating?.value;\r\n this.captureDates = result.capture_dates?.values;\r\n this.checked = false;\r\n this.collections = result.collection?.values ?? [];\r\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\r\n this.collectionSize = result.collection_size?.value ?? 0;\r\n this.commentCount = result.num_reviews?.value ?? 0;\r\n this.creator = result.creator?.value;\r\n this.creators = result.creator?.values ?? [];\r\n this.dateAdded = result.addeddate?.value;\r\n this.dateArchived = result.publicdate?.value;\r\n this.datePublished = result.date?.value;\r\n this.dateReviewed = result.reviewdate?.value;\r\n this.description = result.description?.values.join('\\n');\r\n this.factChecks = result.factcheck?.values;\r\n this.favCount = result.num_favorites?.value ?? 0;\r\n this.hitRequestSource = hitRequestSource;\r\n this.hitType = result.rawMetadata?.hit_type;\r\n this.href = collapseRepeatedQuotes(\r\n result.review?.__href__ ?? result.__href__?.value,\r\n );\r\n this.identifier = TileModel.cleanIdentifier(result.identifier);\r\n this.isClip = result.is_clip?.value;\r\n this.issue = result.issue?.value;\r\n this.itemCount = result.item_count?.value ?? 0;\r\n this.mediatype = resolveMediatype(result);\r\n this.review = result.review;\r\n this.snippets = result.highlight?.values ?? [];\r\n this.source = result.source?.value;\r\n this.subjects = result.subject?.values ?? [];\r\n this.thumbnailUrl = result.__img__?.value;\r\n this.title = result.title?.value ?? '';\r\n this.tvClipCount = result.num_clips?.value ?? 0;\r\n this.volume = result.volume?.value;\r\n this.viewCount = result.downloads?.value;\r\n this.weeklyViewCount = result.week?.value;\r\n this.loginRequired = flags.loginRequired;\r\n this.contentWarning = flags.contentWarning;\r\n }\r\n\r\n /**\r\n * Copies the contents of this TileModel onto a new instance\r\n */\r\n clone(): TileModel {\r\n const cloned = new TileModel({});\r\n cloned.adIds = this.adIds;\r\n cloned.averageRating = this.averageRating;\r\n cloned.captureDates = this.captureDates;\r\n cloned.checked = this.checked;\r\n cloned.collections = this.collections;\r\n cloned.collectionFilesCount = this.collectionFilesCount;\r\n cloned.collectionSize = this.collectionSize;\r\n cloned.commentCount = this.commentCount;\r\n cloned.creator = this.creator;\r\n cloned.creators = this.creators;\r\n cloned.dateStr = this.dateStr;\r\n cloned.dateAdded = this.dateAdded;\r\n cloned.dateArchived = this.dateArchived;\r\n cloned.datePublished = this.datePublished;\r\n cloned.dateReviewed = this.dateReviewed;\r\n cloned.description = this.description;\r\n cloned.factChecks = this.factChecks;\r\n cloned.favCount = this.favCount;\r\n cloned.hitRequestSource = this.hitRequestSource;\r\n cloned.hitType = this.hitType;\r\n cloned.href = this.href;\r\n cloned.identifier = this.identifier;\r\n cloned.isClip = this.isClip;\r\n cloned.issue = this.issue;\r\n cloned.itemCount = this.itemCount;\r\n cloned.mediatype = this.mediatype;\r\n cloned.snippets = this.snippets;\r\n cloned.source = this.source;\r\n cloned.subjects = this.subjects;\r\n cloned.thumbnailUrl = this.thumbnailUrl;\r\n cloned.title = this.title;\r\n cloned.tvClipCount = this.tvClipCount;\r\n cloned.volume = this.volume;\r\n cloned.viewCount = this.viewCount;\r\n cloned.weeklyViewCount = this.weeklyViewCount;\r\n cloned.loginRequired = this.loginRequired;\r\n cloned.contentWarning = this.contentWarning;\r\n return cloned;\r\n }\r\n\r\n /**\r\n * Whether this model represents the result of a TV search query.\r\n */\r\n get isTvSearchResult(): boolean {\r\n return (\r\n this.hitType === 'tv_clip' && this.hitRequestSource === 'search_query'\r\n );\r\n }\r\n\r\n /**\r\n * Determines the appropriate tile flags for the given search result\r\n * (login required and/or content warning)\r\n */\r\n private getFlags(result: SearchResult): TileFlags {\r\n const flags: TileFlags = {\r\n loginRequired: false,\r\n contentWarning: false,\r\n };\r\n\r\n // Check if item and item in \"modifying\" collection, setting above flags\r\n if (\r\n result.collection?.values.length &&\r\n result.mediatype?.value !== 'collection'\r\n ) {\r\n for (const collection of result.collection?.values ?? []) {\r\n if (collection === 'loggedin') {\r\n flags.loginRequired = true;\r\n if (flags.contentWarning) break;\r\n }\r\n if (collection === 'no-preview') {\r\n flags.contentWarning = true;\r\n if (flags.loginRequired) break;\r\n }\r\n }\r\n }\r\n\r\n return flags;\r\n }\r\n\r\n private static cleanIdentifier(\r\n identifier: string | undefined,\r\n ): string | undefined {\r\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\r\n // are suffixed with values that need to be stripped. Those values are separated\r\n // from the item identifier itself with '|'.\r\n const barIndex = identifier?.indexOf('|') ?? -1;\r\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\r\n return cleaned;\r\n }\r\n}\r\n\r\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\r\n\r\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\r\n\r\nexport type TileDisplayMode =\r\n | 'grid'\r\n | 'list-compact'\r\n | 'list-detail'\r\n | 'list-header';\r\n\r\n/**\r\n * This is mainly used to set the cookies for the collection display mode.\r\n *\r\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\r\n */\r\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\r\n\r\n/**\r\n * The sort fields shown in the sort filter bar\r\n */\r\nexport enum SortField {\r\n 'default' = 'default',\r\n 'unrecognized' = 'unrecognized',\r\n 'relevance' = 'relevance',\r\n 'alltimeview' = 'alltimeview',\r\n 'weeklyview' = 'weeklyview',\r\n 'title' = 'title',\r\n 'date' = 'date',\r\n 'datearchived' = 'datearchived',\r\n 'datereviewed' = 'datereviewed',\r\n 'dateadded' = 'dateadded',\r\n 'datefavorited' = 'datefavorited',\r\n 'creator' = 'creator',\r\n}\r\n\r\n/**\r\n * Views-related sort fields\r\n */\r\nexport const ALL_VIEWS_SORT_FIELDS = [\r\n SortField.weeklyview,\r\n SortField.alltimeview,\r\n] as const;\r\nexport type ViewsSortField = (typeof ALL_VIEWS_SORT_FIELDS)[number];\r\n\r\n/**\r\n * Date-related sort fields\r\n */\r\nexport const ALL_DATE_SORT_FIELDS = [\r\n SortField.datefavorited,\r\n SortField.date,\r\n SortField.datearchived,\r\n SortField.datereviewed,\r\n SortField.dateadded,\r\n] as const;\r\nexport type DateSortField = (typeof ALL_DATE_SORT_FIELDS)[number];\r\n\r\nexport interface SortOption {\r\n /**\r\n * The SortField enum member corresponding to this option.\r\n */\r\n field: SortField;\r\n\r\n /**\r\n * The default sort direction to apply when this sort option is first selected.\r\n */\r\n defaultSortDirection: SortDirection | null;\r\n\r\n /**\r\n * Whether this sort option allows its sort direction to be changed from the default.\r\n */\r\n canSetDirection: boolean;\r\n\r\n /**\r\n * Whether this sort option may appear in the sort bar.\r\n */\r\n shownInSortBar: boolean;\r\n\r\n /**\r\n * Whether this sort option should be saved to the URL.\r\n * If false, then no `sort` param will be added to the URL when this sort option\r\n * is selected.\r\n */\r\n shownInURL: boolean;\r\n\r\n /**\r\n * Whether this sort option is passed to the search service.\r\n * If false, then no sort param will be passed to the search service at all when\r\n * this sort option is selected.\r\n */\r\n handledBySearchService: boolean;\r\n\r\n /**\r\n * The string identifying this sort field to the search service & backend API.\r\n */\r\n searchServiceKey?: string;\r\n\r\n /**\r\n * The human-readable name to use for this option in the sort bar (if applicable).\r\n */\r\n displayName: string;\r\n\r\n /**\r\n * A list of URL param keys that should be mapped to this sort option.\r\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\r\n */\r\n urlNames: (string | null | undefined)[];\r\n}\r\n\r\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\r\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\r\n // In these cases, we defer to whatever sort the backend chooses.\r\n // For the search page, the default is always relevance sort.\r\n // For collection pages _without a query_, the default is usually weekly views, but this can be\r\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\r\n // default is again relevance sort.\r\n // For fav-* collections only, the default is instead sorting by date favorited.\r\n [SortField.default]: {\r\n field: SortField.default,\r\n defaultSortDirection: null,\r\n canSetDirection: false,\r\n shownInSortBar: false,\r\n shownInURL: false,\r\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\r\n displayName: '',\r\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\r\n },\r\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\r\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\r\n // when searching, but they are not displayed in the sort bar and we do not actively manage\r\n // their URL param beyond flipping the direction as needed.\r\n [SortField.unrecognized]: {\r\n field: SortField.unrecognized,\r\n defaultSortDirection: null,\r\n canSetDirection: true,\r\n shownInSortBar: false,\r\n shownInURL: false,\r\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\r\n displayName: '',\r\n urlNames: [],\r\n },\r\n // Relevance sort is unique in that it does not produce a URL param when it is set.\r\n // It is only available when there is a user-specified query that relevancy can be scored against.\r\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\r\n [SortField.relevance]: {\r\n field: SortField.relevance,\r\n defaultSortDirection: null,\r\n canSetDirection: false,\r\n shownInSortBar: true,\r\n shownInURL: false,\r\n handledBySearchService: false,\r\n displayName: 'Relevance',\r\n urlNames: ['_score'],\r\n },\r\n [SortField.alltimeview]: {\r\n field: SortField.alltimeview,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'downloads',\r\n displayName: 'All-time views',\r\n urlNames: ['downloads'],\r\n },\r\n [SortField.weeklyview]: {\r\n field: SortField.weeklyview,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'week',\r\n displayName: 'Weekly views',\r\n urlNames: ['week'],\r\n },\r\n [SortField.title]: {\r\n field: SortField.title,\r\n defaultSortDirection: 'asc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'titleSorter',\r\n displayName: 'Title',\r\n urlNames: ['title', 'titleSorter'],\r\n },\r\n [SortField.date]: {\r\n field: SortField.date,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'date',\r\n displayName: 'Date published',\r\n urlNames: ['date'],\r\n },\r\n [SortField.datearchived]: {\r\n field: SortField.datearchived,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'publicdate',\r\n displayName: 'Date archived',\r\n urlNames: ['publicdate'],\r\n },\r\n [SortField.datereviewed]: {\r\n field: SortField.datereviewed,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'reviewdate',\r\n displayName: 'Date reviewed',\r\n urlNames: ['reviewdate'],\r\n },\r\n [SortField.dateadded]: {\r\n field: SortField.dateadded,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'addeddate',\r\n displayName: 'Date added',\r\n urlNames: ['addeddate'],\r\n },\r\n [SortField.datefavorited]: {\r\n field: SortField.datefavorited,\r\n defaultSortDirection: 'desc',\r\n canSetDirection: false,\r\n shownInSortBar: true, // But only when viewing fav-* collections\r\n shownInURL: false,\r\n handledBySearchService: false,\r\n searchServiceKey: 'favoritedate',\r\n displayName: 'Date favorited',\r\n urlNames: ['favoritedate'],\r\n },\r\n [SortField.creator]: {\r\n field: SortField.creator,\r\n defaultSortDirection: 'asc',\r\n canSetDirection: true,\r\n shownInSortBar: true,\r\n shownInURL: true,\r\n handledBySearchService: true,\r\n searchServiceKey: 'creatorSorter',\r\n displayName: 'Creator',\r\n urlNames: ['creator', 'creatorSorter'],\r\n },\r\n};\r\n\r\n/**\r\n * Returns the SortOption corresponding to the given API sort name, or\r\n * the \"unrecognized\" SortOption if none matches.\r\n */\r\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\r\n return (\r\n Object.values(SORT_OPTIONS).find(opt =>\r\n opt.urlNames.some(name => sortName === name),\r\n ) ?? SORT_OPTIONS[SortField.unrecognized]\r\n );\r\n}\r\n\r\nexport const defaultSortAvailability: Record<SortField, boolean> = {\r\n [SortField.relevance]: true,\r\n [SortField.weeklyview]: true,\r\n [SortField.alltimeview]: true,\r\n [SortField.title]: true,\r\n [SortField.datefavorited]: false,\r\n [SortField.date]: true,\r\n [SortField.datearchived]: true,\r\n [SortField.datereviewed]: true,\r\n [SortField.dateadded]: true,\r\n [SortField.creator]: true,\r\n [SortField.default]: false,\r\n [SortField.unrecognized]: false,\r\n};\r\n\r\nexport const favoritesSortAvailability: Record<SortField, boolean> = {\r\n ...defaultSortAvailability,\r\n [SortField.datefavorited]: true,\r\n};\r\n\r\nexport const tvSortAvailability: Record<SortField, boolean> = {\r\n ...defaultSortAvailability,\r\n [SortField.date]: false,\r\n [SortField.datereviewed]: false,\r\n [SortField.dateadded]: false,\r\n};\r\n\r\nexport const defaultProfileElementSorts: Record<\r\n string,\r\n Exclude<SortField, SortField.default>\r\n> = {\r\n uploads: SortField.datearchived,\r\n reviews: SortField.datereviewed,\r\n collections: SortField.datearchived,\r\n web_archives: SortField.datearchived,\r\n};\r\n\r\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\r\nexport type PrefixFilterType = 'title' | 'creator';\r\n\r\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\r\nexport type PrefixFilterCounts = Record<string, number>;\r\n\r\n/**\r\n * A map from prefix filter types to the corresponding aggregation keys\r\n * that are needed to fetch the filter counts from the backend.\r\n */\r\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\r\n title: 'firstTitle',\r\n creator: 'firstCreator',\r\n};\r\n\r\n/**\r\n * Different facet loading strategies that can be used with collection browser.\r\n * - `eager`: Facet data is always loaded as soon as a search is performed\r\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\r\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\r\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\r\n * any logged in user.\r\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\r\n * In the mobile layout, functions exactly as `lazy-mobile`.\r\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\r\n * indicating that they are unavailable.\r\n */\r\nexport type FacetLoadStrategy =\r\n | 'eager'\r\n | 'lazy-mobile'\r\n | 'opt-in-or-login'\r\n | 'opt-in'\r\n | 'off';\r\n\r\n/**\r\n * Union of the facet types that are available in the sidebar.\r\n */\r\nexport type FacetOption =\r\n | 'subject'\r\n | 'lending'\r\n | 'mediatype'\r\n | 'language'\r\n | 'creator'\r\n | 'collection'\r\n | 'year'\r\n // TV-specific facet options:\r\n | 'clip_type'\r\n | 'program'\r\n | 'person'\r\n | 'sponsor';\r\n\r\nexport type SelectedFacetState = 'selected' | 'hidden';\r\n\r\nexport type FacetState = SelectedFacetState | 'none';\r\n\r\nexport interface FacetBucket {\r\n key: string;\r\n count: number;\r\n state: FacetState;\r\n // for some facets, we augment the key with a display value\r\n displayText?: string;\r\n // for TV channel facets, we add a parenthesized secondary name\r\n extraNote?: string;\r\n}\r\n\r\nexport interface FacetGroup {\r\n title: string;\r\n key: FacetOption;\r\n buckets: FacetBucket[];\r\n}\r\n\r\n/**\r\n * Information about a user interaction event on a facet.\r\n */\r\nexport type FacetEventDetails = {\r\n /**\r\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\r\n */\r\n facetType: FacetOption;\r\n /**\r\n * The bucket corresponding to the facet that was interacted with, including the\r\n * updated state of the facet after the interaction.\r\n */\r\n bucket: FacetBucket;\r\n /**\r\n * Whether the interaction occurred on a negative facet.\r\n */\r\n negative: boolean;\r\n};\r\n\r\nexport type FacetValue = string;\r\n\r\nexport type SelectedFacets = Partial<\r\n Record<FacetOption, Record<FacetValue, FacetBucket>>\r\n>;\r\n\r\nexport const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({\r\n subject: {},\r\n lending: {},\r\n mediatype: {},\r\n language: {},\r\n creator: {},\r\n collection: {},\r\n year: {},\r\n clip_type: {},\r\n program: {},\r\n person: {},\r\n sponsor: {},\r\n});\r\n\r\n/**\r\n * For TV search results, what types of TV clips to restrict the results to.\r\n */\r\nexport type TvClipFilterType = 'commercial' | 'fact check' | 'quote';\r\n\r\n/**\r\n * Map from allowed TV filtering parameters in the URL to their corresponding filter type\r\n */\r\nexport const tvClipURLParamsToFilters: Record<string, TvClipFilterType> = {\r\n only_commercials: 'commercial',\r\n only_factchecks: 'fact check',\r\n only_quotes: 'quote',\r\n};\r\n\r\n/**\r\n * Facet display order when presenting results for all search types *except* TV (see below).\r\n */\r\nexport const defaultFacetDisplayOrder: FacetOption[] = [\r\n 'mediatype',\r\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\r\n 'year',\r\n 'subject',\r\n 'collection',\r\n 'creator',\r\n 'language',\r\n];\r\n\r\n/**\r\n * Specialized facet ordering when displaying TV search results\r\n */\r\nexport const tvFacetDisplayOrder: FacetOption[] = [\r\n 'program',\r\n 'creator',\r\n 'year',\r\n 'subject',\r\n 'person',\r\n 'language',\r\n 'clip_type',\r\n];\r\n\r\n/**\r\n * Human-readable titles for each facet group.\r\n */\r\nexport const facetTitles: Record<FacetOption, string> = {\r\n subject: 'Subject',\r\n lending: 'Availability',\r\n mediatype: 'Media Type',\r\n language: 'Language',\r\n creator: 'Creator',\r\n collection: 'Collection',\r\n year: 'Year',\r\n clip_type: 'Clip Type',\r\n program: 'Program',\r\n person: 'Person',\r\n sponsor: 'Sponsor',\r\n};\r\n\r\n/**\r\n * The default sort type to use for each facet type\r\n */\r\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\r\n subject: AggregationSortType.COUNT,\r\n lending: AggregationSortType.COUNT,\r\n mediatype: AggregationSortType.COUNT,\r\n language: AggregationSortType.COUNT,\r\n creator: AggregationSortType.COUNT,\r\n collection: AggregationSortType.COUNT,\r\n year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default\r\n clip_type: AggregationSortType.COUNT,\r\n program: AggregationSortType.COUNT,\r\n person: AggregationSortType.COUNT,\r\n sponsor: AggregationSortType.COUNT,\r\n};\r\n\r\n/**\r\n * The sort type corresponding to facet bucket values, for each facet type\r\n * (i.e., the opposite of \"sort by count\" for that type).\r\n */\r\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\r\n subject: AggregationSortType.ALPHABETICAL,\r\n lending: AggregationSortType.ALPHABETICAL,\r\n mediatype: AggregationSortType.ALPHABETICAL,\r\n language: AggregationSortType.ALPHABETICAL,\r\n creator: AggregationSortType.ALPHABETICAL,\r\n collection: AggregationSortType.ALPHABETICAL,\r\n year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)\r\n clip_type: AggregationSortType.ALPHABETICAL,\r\n program: AggregationSortType.ALPHABETICAL,\r\n person: AggregationSortType.ALPHABETICAL,\r\n sponsor: AggregationSortType.ALPHABETICAL,\r\n};\r\n\r\nexport type LendingFacetKey =\r\n | 'is_lendable'\r\n | 'is_borrowable'\r\n | 'available_to_borrow'\r\n | 'is_browsable'\r\n | 'available_to_browse'\r\n | 'is_readable'\r\n | 'available_to_waitlist';\r\n\r\n/**\r\n * Maps valid lending keys to whether they should be visible in the facet sidebar\r\n */\r\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\r\n is_lendable: true,\r\n is_borrowable: false,\r\n available_to_borrow: true,\r\n is_browsable: false,\r\n available_to_browse: false,\r\n is_readable: true,\r\n available_to_waitlist: false,\r\n};\r\n\r\n/**\r\n * Maps valid, visible lending keys to their facet sidebar display text\r\n */\r\nexport const lendingFacetDisplayNames: Partial<\r\n Record<LendingFacetKey, string>\r\n> = {\r\n is_lendable: 'Lending Library',\r\n available_to_borrow: 'Borrow 14 Days',\r\n is_readable: 'Always Available',\r\n};\r\n\r\n/**\r\n * A record of which admin-only collections should be suppressed from being displayed\r\n * as facets or in an item's list of collections.\r\n */\r\nexport const suppressedCollections: Record<string, boolean> = {\r\n deemphasize: true,\r\n community: true,\r\n stream_only: true,\r\n samples_only: true,\r\n test_collection: true,\r\n printdisabled: true,\r\n 'openlibrary-ol': true,\r\n nationalemergencylibrary: true,\r\n china: true,\r\n americana: true,\r\n toronto: true,\r\n};\r\n\r\n/**\r\n * A record of manageable item\r\n */\r\nexport interface ManageableItem {\r\n identifier: string;\r\n title?: string;\r\n dateStr?: string;\r\n date?: string;\r\n}\r\n\r\n/**\r\n * Possible states for whether & how the user has overridden their user preference\r\n * for blurring behavior on tiles with sensitive content.\r\n * - `no-override`: The user has not overridden their user preference, so simply\r\n * respect the preference as given.\r\n * - `on`: The user has overridden their preference and wants tile blurring enabled.\r\n * - `off`: The user has overridden their preference and wants tile blurring disabled.\r\n */\r\nexport type TileBlurOverrideState = 'no-override' | 'on' | 'off';\r\n"]}
@@ -1,5 +1,5 @@
1
1
  import { SearchType, SortDirection } from '@internetarchive/search-service';
2
- import { CollectionBrowserContext, CollectionDisplayMode, SelectedFacets, TvClipFilterType, SortField } from './models';
2
+ import { CollectionBrowserContext, CollectionDisplayMode, SelectedFacets, SortField } from './models';
3
3
  export interface RestorationState {
4
4
  displayMode?: CollectionDisplayMode;
5
5
  searchType?: SearchType;
@@ -14,7 +14,6 @@ export interface RestorationState {
14
14
  maxSelectedDate?: string;
15
15
  selectedTitleFilter?: string;
16
16
  selectedCreatorFilter?: string;
17
- tvClipFilter?: TvClipFilterType;
18
17
  }
19
18
  export interface RestorationStatePersistOptions {
20
19
  forceReplace?: boolean;
@@ -1,6 +1,6 @@
1
1
  import { SearchType } from '@internetarchive/search-service';
2
2
  import { getCookie, setCookie } from 'typescript-cookie';
3
- import { SortField, getDefaultSelectedFacets, sortOptionFromAPIString, SORT_OPTIONS, tvClipFiltersToURLParams, tvClipURLParamsToFilters, } from './models';
3
+ import { SortField, getDefaultSelectedFacets, sortOptionFromAPIString, SORT_OPTIONS, tvClipURLParamsToFilters, } from './models';
4
4
  import { arrayEquals } from './utils/array-equals';
5
5
  export class RestorationStateHandler {
6
6
  constructor(options) {
@@ -44,7 +44,6 @@ export class RestorationStateHandler {
44
44
  return 'list-compact';
45
45
  }
46
46
  persistQueryStateToUrl(state, options = {}) {
47
- var _a, _b, _c, _d, _e;
48
47
  const url = new URL(window.location.href);
49
48
  const oldParams = new URLSearchParams(url.searchParams);
50
49
  const newParams = this.removeRecognizedParams(url.searchParams);
@@ -85,9 +84,11 @@ export class RestorationStateHandler {
85
84
  if (state.selectedSort) {
86
85
  const sortOption = SORT_OPTIONS[state.selectedSort];
87
86
  let prefix = this.sortDirectionPrefix(state.sortDirection);
87
+ const isTVRelevanceSort = state.searchType === SearchType.TV &&
88
+ state.selectedSort === SortField.relevance;
88
89
  if (sortOption.field === SortField.unrecognized) {
89
90
  // For unrecognized sorts, use the existing param, possibly updating its direction
90
- const oldSortParam = (_a = oldParams.get('sort')) !== null && _a !== void 0 ? _a : '';
91
+ const oldSortParam = oldParams.get('sort') ?? '';
91
92
  const { field, direction } = this.getSortFieldAndDirection(oldSortParam);
92
93
  // Use the state-specified direction if available, or extract one from the param if not
93
94
  if (!state.sortDirection)
@@ -99,7 +100,7 @@ export class RestorationStateHandler {
99
100
  newParams.set('sort', oldSortParam);
100
101
  }
101
102
  }
102
- else if (sortOption.shownInURL) {
103
+ else if (sortOption.shownInURL || isTVRelevanceSort) {
103
104
  // Otherwise, use the canonical API form of the sort option
104
105
  const canonicalApiSort = sortOption.urlNames[0];
105
106
  newParams.set('sort', `${prefix}${canonicalApiSort}`);
@@ -122,8 +123,8 @@ export class RestorationStateHandler {
122
123
  }
123
124
  }
124
125
  }
125
- const dateField = ((_b = state.minSelectedDate) === null || _b === void 0 ? void 0 : _b.includes('-')) ||
126
- ((_c = state.maxSelectedDate) === null || _c === void 0 ? void 0 : _c.includes('-'))
126
+ const dateField = state.minSelectedDate?.includes('-') ||
127
+ state.maxSelectedDate?.includes('-')
127
128
  ? 'date'
128
129
  : 'year';
129
130
  if (state.minSelectedDate && state.maxSelectedDate) {
@@ -135,12 +136,6 @@ export class RestorationStateHandler {
135
136
  if (state.creatorQuery) {
136
137
  newParams.append('and[]', state.creatorQuery);
137
138
  }
138
- // TV clip special filters
139
- if (state.tvClipFilter) {
140
- const tvClipParam = tvClipFiltersToURLParams[state.tvClipFilter];
141
- if (tvClipParam)
142
- newParams.append(tvClipParam, '1');
143
- }
144
139
  // Ensure we aren't pushing consecutive identical states to the history stack.
145
140
  // - If the state has changed, we push a new history entry.
146
141
  // - If only the page number has changed, we replace the current history entry.
@@ -175,7 +170,7 @@ export class RestorationStateHandler {
175
170
  // we just want to overwrite it.
176
171
  historyMethod = 'replaceState';
177
172
  }
178
- (_e = (_d = window.history)[historyMethod]) === null || _e === void 0 ? void 0 : _e.call(_d, {
173
+ window.history[historyMethod]?.({
179
174
  query: state.baseQuery,
180
175
  searchType: state.searchType,
181
176
  page: state.currentPage,
@@ -186,7 +181,6 @@ export class RestorationStateHandler {
186
181
  }, '', url);
187
182
  }
188
183
  loadQueryStateFromUrl() {
189
- var _a;
190
184
  const url = new URL(window.location.href);
191
185
  const searchInside = url.searchParams.get('sin');
192
186
  const pageNumber = url.searchParams.get('page');
@@ -208,7 +202,7 @@ export class RestorationStateHandler {
208
202
  // of backwards-compatibility with old bookmarks, we recognize those here too.
209
203
  // (However, they still get upgraded to a `query` param when we persist our state
210
204
  // to the URL).
211
- const legacySearchQuery = (_a = url.searchParams.get('q')) !== null && _a !== void 0 ? _a : url.searchParams.get('search');
205
+ const legacySearchQuery = url.searchParams.get('q') ?? url.searchParams.get('search');
212
206
  const restorationState = {
213
207
  selectedFacets: getDefaultSelectedFacets(),
214
208
  };
@@ -298,9 +292,9 @@ export class RestorationStateHandler {
298
292
  });
299
293
  }
300
294
  // TV clip special filters (carryovers from legacy page)
301
- for (const [paramKey, filter] of Object.entries(tvClipURLParamsToFilters)) {
295
+ for (const [paramKey, facetKey] of Object.entries(tvClipURLParamsToFilters)) {
302
296
  if (url.searchParams.get(paramKey)) {
303
- restorationState.tvClipFilter = filter;
297
+ this.setSelectedFacetState(restorationState.selectedFacets, 'clip_type', facetKey, 'selected');
304
298
  break;
305
299
  }
306
300
  }
@@ -383,12 +377,11 @@ export class RestorationStateHandler {
383
377
  * creating any previously-undefined buckets as needed.
384
378
  */
385
379
  setSelectedFacetState(selectedFacets, field, value, state) {
386
- var _a;
387
380
  const facet = selectedFacets[field];
388
381
  if (!facet)
389
382
  return; // Unrecognized facet group, ignore it.
390
383
  const unQuotedValue = this.stripQuotes(value);
391
- (_a = facet[unQuotedValue]) !== null && _a !== void 0 ? _a : (facet[unQuotedValue] = this.getDefaultBucket(value));
384
+ facet[unQuotedValue] ??= this.getDefaultBucket(value);
392
385
  facet[unQuotedValue].state = state;
393
386
  }
394
387
  /** Returns a default bucket with the given key, count of 0, and state 'none'. */
@@ -1 +1 @@
1
- {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { SearchType, SortDirection } from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n TvClipFilterType,\n SortField,\n FacetBucket,\n FacetState,\n getDefaultSelectedFacets,\n sortOptionFromAPIString,\n SORT_OPTIONS,\n tvClipFiltersToURLParams,\n tvClipURLParamsToFilters,\n} from './models';\nimport { arrayEquals } from './utils/array-equals';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n tvClipFilter?: TvClipFilterType;\n}\n\nexport interface RestorationStatePersistOptions {\n forceReplace?: boolean;\n persistMetadataSearchType?: boolean;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(\n state: RestorationState,\n options?: RestorationStatePersistOptions,\n ): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state, options);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(\n state: RestorationState,\n options: RestorationStatePersistOptions = {},\n ) {\n const url = new URL(window.location.href);\n const oldParams = new URLSearchParams(url.searchParams);\n const newParams = this.removeRecognizedParams(url.searchParams);\n\n let replaceEmptySin = false;\n\n if (state.baseQuery) {\n newParams.set('query', state.baseQuery);\n }\n\n switch (state.searchType) {\n case SearchType.FULLTEXT:\n newParams.set('sin', 'TXT');\n break;\n case SearchType.RADIO:\n newParams.set('sin', 'RADIO');\n break;\n case SearchType.TV:\n newParams.set('sin', 'TV');\n break;\n case SearchType.METADATA:\n // Only write the param for metadata when it isn't already the default.\n // Currently this is only the case within TV collections.\n if (options.persistMetadataSearchType || oldParams.get('sin') === 'MD')\n newParams.set('sin', 'MD');\n break;\n }\n\n if (oldParams.get('sin') === '') {\n // Treat empty sin the same as no sin at all\n oldParams.delete('sin');\n replaceEmptySin = true;\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n newParams.set('page', state.currentPage.toString());\n } else {\n newParams.delete('page');\n }\n }\n\n if (state.selectedSort) {\n const sortOption = SORT_OPTIONS[state.selectedSort];\n let prefix = this.sortDirectionPrefix(state.sortDirection);\n\n if (sortOption.field === SortField.unrecognized) {\n // For unrecognized sorts, use the existing param, possibly updating its direction\n const oldSortParam = oldParams.get('sort') ?? '';\n const { field, direction } =\n this.getSortFieldAndDirection(oldSortParam);\n\n // Use the state-specified direction if available, or extract one from the param if not\n if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);\n\n if (field) {\n newParams.set('sort', `${prefix}${field}`);\n } else {\n newParams.set('sort', oldSortParam);\n }\n } else if (sortOption.shownInURL) {\n // Otherwise, use the canonical API form of the sort option\n const canonicalApiSort = sortOption.urlNames[0];\n newParams.set('sort', `${prefix}${canonicalApiSort}`);\n }\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets,\n )) {\n const facetEntries = Object.entries(facetValues);\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n newParams.append('not[]', paramValue);\n } else {\n newParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n const dateField =\n state.minSelectedDate?.includes('-') ||\n state.maxSelectedDate?.includes('-')\n ? 'date'\n : 'year';\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n newParams.append(\n 'and[]',\n `${dateField}:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`,\n );\n }\n\n if (state.titleQuery) {\n newParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n newParams.append('and[]', state.creatorQuery);\n }\n\n // TV clip special filters\n if (state.tvClipFilter) {\n const tvClipParam = tvClipFiltersToURLParams[state.tvClipFilter];\n if (tvClipParam) newParams.append(tvClipParam, '1');\n }\n\n // Ensure we aren't pushing consecutive identical states to the history stack.\n // - If the state has changed, we push a new history entry.\n // - If only the page number has changed, we replace the current history entry.\n // - If the state hasn't changed, then do nothing.\n let historyMethod: 'pushState' | 'replaceState' = options.forceReplace\n ? 'replaceState'\n : 'pushState';\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\n 'sin',\n 'sort',\n 'and[]',\n 'not[]',\n 'only_commercials',\n 'only_factchecks',\n 'only_quotes',\n ]);\n\n if (\n nonQueryParamsMatch &&\n this.paramsMatch(oldParams, newParams, ['query'])\n ) {\n if (replaceEmptySin) {\n // Get rid of any empty sin param\n newParams.delete('sin');\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\n // For page number, we want to replace the page state when it changes,\n // not push a new history entry. If it hasn't changed, then we're done.\n return;\n }\n historyMethod = 'replaceState';\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\n // Similarly, if the only non-matching param was a legacy query param, then\n // we just want to overwrite it.\n historyMethod = 'replaceState';\n }\n\n window.history[historyMethod]?.(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: { field: state.selectedSort, direction: state.sortDirection },\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url,\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n // We also need to check for the presence of params like 'and[0]', 'not[1]', etc.\n // since Facebook automatically converts URLs with [] into those forms.\n for (const [key, val] of url.searchParams.entries()) {\n if (/and\\[\\d+\\]/.test(key)) {\n facetAnds.push(val);\n } else if (/not\\[\\d+\\]/.test(key)) {\n facetNots.push(val);\n }\n }\n\n // Legacy search allowed `q` and `search` params for the query, so in the interest\n // of backwards-compatibility with old bookmarks, we recognize those here too.\n // (However, they still get upgraded to a `query` param when we persist our state\n // to the URL).\n const legacySearchQuery =\n url.searchParams.get('q') ?? url.searchParams.get('search');\n\n const restorationState: RestorationState = {\n selectedFacets: getDefaultSelectedFacets(),\n };\n\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n } else if (legacySearchQuery) {\n restorationState.baseQuery = legacySearchQuery;\n }\n\n switch (searchInside) {\n case 'TXT':\n restorationState.searchType = SearchType.FULLTEXT;\n break;\n case 'RADIO':\n restorationState.searchType = SearchType.RADIO;\n break;\n case 'TV':\n restorationState.searchType = SearchType.TV;\n break;\n case 'MD':\n restorationState.searchType = SearchType.METADATA;\n break;\n default:\n restorationState.searchType = SearchType.DEFAULT;\n break;\n }\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n\n if (sortQuery) {\n const { field, direction } = this.getSortFieldAndDirection(sortQuery);\n\n const sortOption = sortOptionFromAPIString(field);\n restorationState.selectedSort = sortOption.field;\n\n if (['asc', 'desc'].includes(direction)) {\n restorationState.sortDirection = direction as SortDirection;\n }\n }\n\n if (facetAnds) {\n facetAnds.forEach(and => {\n // eslint-disable-next-line prefer-const\n let [field, value] = and.split(':');\n\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\n field = field.replace(/Sorter$/, '');\n\n // Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`\n // which we want to normalize to a not[] param instead\n if (field.startsWith('-')) {\n facetNots.push(and.slice(1));\n return;\n }\n\n switch (field) {\n case 'date':\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length,\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1,\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected',\n );\n }\n });\n }\n\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden',\n );\n });\n }\n\n // TV clip special filters (carryovers from legacy page)\n for (const [paramKey, filter] of Object.entries(tvClipURLParamsToFilters)) {\n if (url.searchParams.get(paramKey)) {\n restorationState.tvClipFilter = filter;\n break;\n }\n }\n\n return restorationState;\n }\n\n /**\n * Converts a URL sort param into a field/direction pair, if possible.\n * Either or both may be undefined if the param is not in a recognized format.\n */\n private getSortFieldAndDirection(sortParam: string) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortParam.indexOf(' ') > -1;\n let field;\n let direction;\n if (hasSpace) {\n [field, direction] = sortParam.split(' ');\n } else {\n field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;\n direction = sortParam.startsWith('-') ? 'desc' : 'asc';\n }\n\n return { field, direction };\n }\n\n /** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */\n private sortDirectionPrefix(sortDirection?: string) {\n return sortDirection === 'desc' ? '-' : '';\n }\n\n /** Remove optional opening and closing quotes from a string */\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n\n return value;\n }\n\n /**\n * Returns whether the two given URLSearchParams objects have\n * identical values for all of the given param keys. If either\n * object contains more than one value for a given key, then\n * all of the values for that key must match (disregarding order).\n */\n private paramsMatch(\n searchParams1: URLSearchParams,\n searchParams2: URLSearchParams,\n keys: string[],\n ): boolean {\n return keys.every(key =>\n arrayEquals(\n searchParams1.getAll(key).sort(),\n searchParams2.getAll(key).sort(),\n ),\n );\n }\n\n /**\n * Deletes any params from the given URLSearchParams object that are recognized\n * when loading state from the URL.\n */\n private removeRecognizedParams(\n searchParams: URLSearchParams,\n ): URLSearchParams {\n // Remove all of our standard params\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n // Remove any and/not facet params that contain numbers in their square brackets\n for (const key of searchParams.keys()) {\n if (/(and|not)\\[\\d+\\]/.test(key)) {\n searchParams.delete(key);\n }\n }\n\n // Also remove some legacy params that should have been upgraded to the ones above\n searchParams.delete('q');\n searchParams.delete('search');\n searchParams.delete('only_commercials');\n searchParams.delete('only_factchecks');\n searchParams.delete('only_quotes');\n\n return searchParams;\n }\n\n /**\n * Returns whether the given URLSearchParams object contains a param that is\n * only recognized as a holdover from legacy search, and should not be\n * persisted to the URL.\n */\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\n return searchParams.has('q') || searchParams.has('search');\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState,\n ): void {\n const facet = selectedFacets[field];\n if (!facet) return; // Unrecognized facet group, ignore it.\n\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
1
+ {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { SearchType, SortDirection } from '@internetarchive/search-service';\r\nimport { getCookie, setCookie } from 'typescript-cookie';\r\nimport {\r\n FacetOption,\r\n CollectionBrowserContext,\r\n CollectionDisplayMode,\r\n SelectedFacets,\r\n SortField,\r\n FacetBucket,\r\n FacetState,\r\n getDefaultSelectedFacets,\r\n sortOptionFromAPIString,\r\n SORT_OPTIONS,\r\n tvClipURLParamsToFilters,\r\n} from './models';\r\nimport { arrayEquals } from './utils/array-equals';\r\n\r\nexport interface RestorationState {\r\n displayMode?: CollectionDisplayMode;\r\n searchType?: SearchType;\r\n selectedSort?: SortField;\r\n sortDirection?: SortDirection;\r\n selectedFacets: SelectedFacets;\r\n baseQuery?: string;\r\n currentPage?: number;\r\n titleQuery?: string;\r\n creatorQuery?: string;\r\n minSelectedDate?: string;\r\n maxSelectedDate?: string;\r\n selectedTitleFilter?: string;\r\n selectedCreatorFilter?: string;\r\n}\r\n\r\nexport interface RestorationStatePersistOptions {\r\n forceReplace?: boolean;\r\n persistMetadataSearchType?: boolean;\r\n}\r\n\r\nexport interface RestorationStateHandlerInterface {\r\n persistState(\r\n state: RestorationState,\r\n options?: RestorationStatePersistOptions,\r\n ): void;\r\n getRestorationState(): RestorationState;\r\n}\r\n\r\nexport class RestorationStateHandler\r\n implements RestorationStateHandlerInterface\r\n{\r\n private context: CollectionBrowserContext;\r\n\r\n private cookieDomain = '.archive.org';\r\n\r\n private cookieExpiration = 30;\r\n\r\n private cookiePath = '/';\r\n\r\n constructor(options: { context: CollectionBrowserContext }) {\r\n this.context = options.context;\r\n }\r\n\r\n persistState(\r\n state: RestorationState,\r\n options: RestorationStatePersistOptions = {},\r\n ): void {\r\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\r\n this.persistQueryStateToUrl(state, options);\r\n }\r\n\r\n getRestorationState(): RestorationState {\r\n const restorationState = this.loadQueryStateFromUrl();\r\n const displayMode = this.loadTileViewStateFromCookies();\r\n restorationState.displayMode = displayMode;\r\n return restorationState;\r\n }\r\n\r\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\r\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\r\n setCookie(`view-${this.context}`, gridState, {\r\n domain: this.cookieDomain,\r\n expires: this.cookieExpiration,\r\n path: this.cookiePath,\r\n });\r\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\r\n setCookie(`showdetails-${this.context}`, detailsState, {\r\n domain: this.cookieDomain,\r\n expires: this.cookieExpiration,\r\n path: this.cookiePath,\r\n });\r\n }\r\n\r\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\r\n const viewState = getCookie(`view-${this.context}`);\r\n const detailsState = getCookie(`showdetails-${this.context}`);\r\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\r\n if (detailsState === 'showdetails') return 'list-detail';\r\n return 'list-compact';\r\n }\r\n\r\n private persistQueryStateToUrl(\r\n state: RestorationState,\r\n options: RestorationStatePersistOptions = {},\r\n ) {\r\n const url = new URL(window.location.href);\r\n const oldParams = new URLSearchParams(url.searchParams);\r\n const newParams = this.removeRecognizedParams(url.searchParams);\r\n\r\n let replaceEmptySin = false;\r\n\r\n if (state.baseQuery) {\r\n newParams.set('query', state.baseQuery);\r\n }\r\n\r\n switch (state.searchType) {\r\n case SearchType.FULLTEXT:\r\n newParams.set('sin', 'TXT');\r\n break;\r\n case SearchType.RADIO:\r\n newParams.set('sin', 'RADIO');\r\n break;\r\n case SearchType.TV:\r\n newParams.set('sin', 'TV');\r\n break;\r\n case SearchType.METADATA:\r\n // Only write the param for metadata when it isn't already the default.\r\n // Currently this is only the case within TV collections.\r\n if (options.persistMetadataSearchType || oldParams.get('sin') === 'MD')\r\n newParams.set('sin', 'MD');\r\n break;\r\n }\r\n\r\n if (oldParams.get('sin') === '') {\r\n // Treat empty sin the same as no sin at all\r\n oldParams.delete('sin');\r\n replaceEmptySin = true;\r\n }\r\n\r\n if (state.currentPage) {\r\n if (state.currentPage > 1) {\r\n newParams.set('page', state.currentPage.toString());\r\n } else {\r\n newParams.delete('page');\r\n }\r\n }\r\n\r\n if (state.selectedSort) {\r\n const sortOption = SORT_OPTIONS[state.selectedSort];\r\n let prefix = this.sortDirectionPrefix(state.sortDirection);\r\n\r\n const isTVRelevanceSort =\r\n state.searchType === SearchType.TV &&\r\n state.selectedSort === SortField.relevance;\r\n\r\n if (sortOption.field === SortField.unrecognized) {\r\n // For unrecognized sorts, use the existing param, possibly updating its direction\r\n const oldSortParam = oldParams.get('sort') ?? '';\r\n const { field, direction } =\r\n this.getSortFieldAndDirection(oldSortParam);\r\n\r\n // Use the state-specified direction if available, or extract one from the param if not\r\n if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);\r\n\r\n if (field) {\r\n newParams.set('sort', `${prefix}${field}`);\r\n } else {\r\n newParams.set('sort', oldSortParam);\r\n }\r\n } else if (sortOption.shownInURL || isTVRelevanceSort) {\r\n // Otherwise, use the canonical API form of the sort option\r\n const canonicalApiSort = sortOption.urlNames[0];\r\n newParams.set('sort', `${prefix}${canonicalApiSort}`);\r\n }\r\n }\r\n\r\n if (state.selectedFacets) {\r\n for (const [facetName, facetValues] of Object.entries(\r\n state.selectedFacets,\r\n )) {\r\n const facetEntries = Object.entries(facetValues);\r\n if (facetEntries.length === 0) continue;\r\n for (const [key, data] of facetEntries) {\r\n const notValue = data.state === 'hidden';\r\n const paramValue = `${facetName}:\"${key}\"`;\r\n if (notValue) {\r\n newParams.append('not[]', paramValue);\r\n } else {\r\n newParams.append('and[]', paramValue);\r\n }\r\n }\r\n }\r\n }\r\n\r\n const dateField =\r\n state.minSelectedDate?.includes('-') ||\r\n state.maxSelectedDate?.includes('-')\r\n ? 'date'\r\n : 'year';\r\n\r\n if (state.minSelectedDate && state.maxSelectedDate) {\r\n newParams.append(\r\n 'and[]',\r\n `${dateField}:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`,\r\n );\r\n }\r\n\r\n if (state.titleQuery) {\r\n newParams.append('and[]', state.titleQuery);\r\n }\r\n\r\n if (state.creatorQuery) {\r\n newParams.append('and[]', state.creatorQuery);\r\n }\r\n\r\n // Ensure we aren't pushing consecutive identical states to the history stack.\r\n // - If the state has changed, we push a new history entry.\r\n // - If only the page number has changed, we replace the current history entry.\r\n // - If the state hasn't changed, then do nothing.\r\n let historyMethod: 'pushState' | 'replaceState' = options.forceReplace\r\n ? 'replaceState'\r\n : 'pushState';\r\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\r\n 'sin',\r\n 'sort',\r\n 'and[]',\r\n 'not[]',\r\n 'only_commercials',\r\n 'only_factchecks',\r\n 'only_quotes',\r\n ]);\r\n\r\n if (\r\n nonQueryParamsMatch &&\r\n this.paramsMatch(oldParams, newParams, ['query'])\r\n ) {\r\n if (replaceEmptySin) {\r\n // Get rid of any empty sin param\r\n newParams.delete('sin');\r\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\r\n // For page number, we want to replace the page state when it changes,\r\n // not push a new history entry. If it hasn't changed, then we're done.\r\n return;\r\n }\r\n historyMethod = 'replaceState';\r\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\r\n // Similarly, if the only non-matching param was a legacy query param, then\r\n // we just want to overwrite it.\r\n historyMethod = 'replaceState';\r\n }\r\n\r\n window.history[historyMethod]?.(\r\n {\r\n query: state.baseQuery,\r\n searchType: state.searchType,\r\n page: state.currentPage,\r\n sort: { field: state.selectedSort, direction: state.sortDirection },\r\n minDate: state.minSelectedDate,\r\n maxDate: state.maxSelectedDate,\r\n facets: state.selectedFacets,\r\n },\r\n '',\r\n url,\r\n );\r\n }\r\n\r\n private loadQueryStateFromUrl(): RestorationState {\r\n const url = new URL(window.location.href);\r\n const searchInside = url.searchParams.get('sin');\r\n const pageNumber = url.searchParams.get('page');\r\n const searchQuery = url.searchParams.get('query');\r\n const sortQuery = url.searchParams.get('sort');\r\n const facetAnds = url.searchParams.getAll('and[]');\r\n const facetNots = url.searchParams.getAll('not[]');\r\n\r\n // We also need to check for the presence of params like 'and[0]', 'not[1]', etc.\r\n // since Facebook automatically converts URLs with [] into those forms.\r\n for (const [key, val] of url.searchParams.entries()) {\r\n if (/and\\[\\d+\\]/.test(key)) {\r\n facetAnds.push(val);\r\n } else if (/not\\[\\d+\\]/.test(key)) {\r\n facetNots.push(val);\r\n }\r\n }\r\n\r\n // Legacy search allowed `q` and `search` params for the query, so in the interest\r\n // of backwards-compatibility with old bookmarks, we recognize those here too.\r\n // (However, they still get upgraded to a `query` param when we persist our state\r\n // to the URL).\r\n const legacySearchQuery =\r\n url.searchParams.get('q') ?? url.searchParams.get('search');\r\n\r\n const restorationState: RestorationState = {\r\n selectedFacets: getDefaultSelectedFacets(),\r\n };\r\n\r\n if (searchQuery) {\r\n restorationState.baseQuery = searchQuery;\r\n } else if (legacySearchQuery) {\r\n restorationState.baseQuery = legacySearchQuery;\r\n }\r\n\r\n switch (searchInside) {\r\n case 'TXT':\r\n restorationState.searchType = SearchType.FULLTEXT;\r\n break;\r\n case 'RADIO':\r\n restorationState.searchType = SearchType.RADIO;\r\n break;\r\n case 'TV':\r\n restorationState.searchType = SearchType.TV;\r\n break;\r\n case 'MD':\r\n restorationState.searchType = SearchType.METADATA;\r\n break;\r\n default:\r\n restorationState.searchType = SearchType.DEFAULT;\r\n break;\r\n }\r\n\r\n if (pageNumber) {\r\n const parsed = parseInt(pageNumber, 10);\r\n restorationState.currentPage = parsed;\r\n } else {\r\n restorationState.currentPage = 1;\r\n }\r\n\r\n if (sortQuery) {\r\n const { field, direction } = this.getSortFieldAndDirection(sortQuery);\r\n\r\n const sortOption = sortOptionFromAPIString(field);\r\n restorationState.selectedSort = sortOption.field;\r\n\r\n if (['asc', 'desc'].includes(direction)) {\r\n restorationState.sortDirection = direction as SortDirection;\r\n }\r\n }\r\n\r\n if (facetAnds) {\r\n facetAnds.forEach(and => {\r\n // eslint-disable-next-line prefer-const\r\n let [field, value] = and.split(':');\r\n\r\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\r\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\r\n field = field.replace(/Sorter$/, '');\r\n\r\n // Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`\r\n // which we want to normalize to a not[] param instead\r\n if (field.startsWith('-')) {\r\n facetNots.push(and.slice(1));\r\n return;\r\n }\r\n\r\n switch (field) {\r\n case 'date':\r\n case 'year': {\r\n const [minDate, maxDate] = value.split(' TO ');\r\n // we have two potential ways of filtering by date:\r\n // the range with \"date TO date\" or the single date with \"date\"\r\n // this is checking for the range case and if we don't have those, fall\r\n // back to the single date case\r\n if (minDate && maxDate) {\r\n restorationState.minSelectedDate = minDate.substring(\r\n 1,\r\n minDate.length,\r\n );\r\n restorationState.maxSelectedDate = maxDate.substring(\r\n 0,\r\n maxDate.length - 1,\r\n );\r\n } else {\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'selected',\r\n );\r\n }\r\n break;\r\n }\r\n case 'firstTitle':\r\n restorationState.selectedTitleFilter = value;\r\n break;\r\n case 'firstCreator':\r\n restorationState.selectedCreatorFilter = value;\r\n break;\r\n default:\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'selected',\r\n );\r\n }\r\n });\r\n }\r\n\r\n if (facetNots) {\r\n facetNots.forEach(not => {\r\n const [field, value] = not.split(':');\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'hidden',\r\n );\r\n });\r\n }\r\n\r\n // TV clip special filters (carryovers from legacy page)\r\n for (const [paramKey, facetKey] of Object.entries(\r\n tvClipURLParamsToFilters,\r\n )) {\r\n if (url.searchParams.get(paramKey)) {\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n 'clip_type',\r\n facetKey,\r\n 'selected',\r\n );\r\n break;\r\n }\r\n }\r\n\r\n return restorationState;\r\n }\r\n\r\n /**\r\n * Converts a URL sort param into a field/direction pair, if possible.\r\n * Either or both may be undefined if the param is not in a recognized format.\r\n */\r\n private getSortFieldAndDirection(sortParam: string) {\r\n // check for two different sort formats: `date desc` and `-date`\r\n const hasSpace = sortParam.indexOf(' ') > -1;\r\n let field;\r\n let direction;\r\n if (hasSpace) {\r\n [field, direction] = sortParam.split(' ');\r\n } else {\r\n field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;\r\n direction = sortParam.startsWith('-') ? 'desc' : 'asc';\r\n }\r\n\r\n return { field, direction };\r\n }\r\n\r\n /** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */\r\n private sortDirectionPrefix(sortDirection?: string) {\r\n return sortDirection === 'desc' ? '-' : '';\r\n }\r\n\r\n /** Remove optional opening and closing quotes from a string */\r\n private stripQuotes(value: string): string {\r\n if (value.startsWith('\"') && value.endsWith('\"')) {\r\n return value.substring(1, value.length - 1);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * Returns whether the two given URLSearchParams objects have\r\n * identical values for all of the given param keys. If either\r\n * object contains more than one value for a given key, then\r\n * all of the values for that key must match (disregarding order).\r\n */\r\n private paramsMatch(\r\n searchParams1: URLSearchParams,\r\n searchParams2: URLSearchParams,\r\n keys: string[],\r\n ): boolean {\r\n return keys.every(key =>\r\n arrayEquals(\r\n searchParams1.getAll(key).sort(),\r\n searchParams2.getAll(key).sort(),\r\n ),\r\n );\r\n }\r\n\r\n /**\r\n * Deletes any params from the given URLSearchParams object that are recognized\r\n * when loading state from the URL.\r\n */\r\n private removeRecognizedParams(\r\n searchParams: URLSearchParams,\r\n ): URLSearchParams {\r\n // Remove all of our standard params\r\n searchParams.delete('query');\r\n searchParams.delete('sin');\r\n searchParams.delete('page');\r\n searchParams.delete('sort');\r\n searchParams.delete('and[]');\r\n searchParams.delete('not[]');\r\n\r\n // Remove any and/not facet params that contain numbers in their square brackets\r\n for (const key of searchParams.keys()) {\r\n if (/(and|not)\\[\\d+\\]/.test(key)) {\r\n searchParams.delete(key);\r\n }\r\n }\r\n\r\n // Also remove some legacy params that should have been upgraded to the ones above\r\n searchParams.delete('q');\r\n searchParams.delete('search');\r\n searchParams.delete('only_commercials');\r\n searchParams.delete('only_factchecks');\r\n searchParams.delete('only_quotes');\r\n\r\n return searchParams;\r\n }\r\n\r\n /**\r\n * Returns whether the given URLSearchParams object contains a param that is\r\n * only recognized as a holdover from legacy search, and should not be\r\n * persisted to the URL.\r\n */\r\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\r\n return searchParams.has('q') || searchParams.has('search');\r\n }\r\n\r\n /**\r\n * Sets the facet state for the given field & value to the given state,\r\n * creating any previously-undefined buckets as needed.\r\n */\r\n private setSelectedFacetState(\r\n selectedFacets: SelectedFacets,\r\n field: FacetOption,\r\n value: string,\r\n state: FacetState,\r\n ): void {\r\n const facet = selectedFacets[field];\r\n if (!facet) return; // Unrecognized facet group, ignore it.\r\n\r\n const unQuotedValue = this.stripQuotes(value);\r\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\r\n facet[unQuotedValue].state = state;\r\n }\r\n\r\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\r\n private getDefaultBucket(key: string): FacetBucket {\r\n return {\r\n key,\r\n count: 0,\r\n state: 'none',\r\n };\r\n }\r\n}\r\n"]}
@@ -10,13 +10,11 @@ let AlphaBar = class AlphaBar extends LitElement {
10
10
  this.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
11
11
  }
12
12
  get selectedUppercaseLetter() {
13
- var _a;
14
- return (_a = this.selectedLetter) === null || _a === void 0 ? void 0 : _a.toUpperCase();
13
+ return this.selectedLetter?.toUpperCase();
15
14
  }
16
15
  render() {
17
- var _a;
18
16
  return html `
19
- <section id="container" aria-label=${(_a = this.ariaLandmarkLabel) !== null && _a !== void 0 ? _a : nothing}>
17
+ <section id="container" aria-label=${this.ariaLandmarkLabel ?? nothing}>
20
18
  <ul>
21
19
  ${this.alphabet.map(letter => html `
22
20
  <li
@@ -35,12 +33,11 @@ let AlphaBar = class AlphaBar extends LitElement {
35
33
  `;
36
34
  }
37
35
  letterButtonTemplate(letter) {
38
- var _a, _b, _c;
39
- const ariaLabel = `${letter}: ${(_b = (_a = this.letterCounts) === null || _a === void 0 ? void 0 : _a[letter]) !== null && _b !== void 0 ? _b : 0} results`;
36
+ const ariaLabel = `${letter}: ${this.letterCounts?.[letter] ?? 0} results`;
40
37
  return html `
41
38
  <button
42
39
  aria-label=${ariaLabel}
43
- ?disabled=${!((_c = this.letterCounts) === null || _c === void 0 ? void 0 : _c[letter])}
40
+ ?disabled=${!this.letterCounts?.[letter]}
44
41
  @click=${() => {
45
42
  this.letterClicked(letter);
46
43
  }}
@@ -50,13 +47,12 @@ let AlphaBar = class AlphaBar extends LitElement {
50
47
  `;
51
48
  }
52
49
  tooltipTemplate(letter) {
53
- var _a, _b;
54
50
  if (this.hoveredLetter !== letter)
55
51
  return nothing;
56
52
  return this.tooltipShown
57
53
  ? html `<alpha-bar-tooltip
58
54
  data-letter=${letter}
59
- .numResults=${(_b = (_a = this.letterCounts) === null || _a === void 0 ? void 0 : _a[this.hoveredLetter]) !== null && _b !== void 0 ? _b : 0}
55
+ .numResults=${this.letterCounts?.[this.hoveredLetter] ?? 0}
60
56
  ></alpha-bar-tooltip>`
61
57
  : nothing;
62
58
  }
@@ -72,10 +68,9 @@ let AlphaBar = class AlphaBar extends LitElement {
72
68
  }));
73
69
  }
74
70
  async handleMouseMove(e) {
75
- var _a, _b;
76
71
  const target = e.target;
77
72
  if (target && !this.tooltipShown) {
78
- const targetLetter = (_b = (_a = target.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : undefined;
73
+ const targetLetter = target.textContent?.trim() ?? undefined;
79
74
  this.tooltipShown = true;
80
75
  this.hoveredLetter = targetLetter;
81
76
  await this.updateComplete;
@@ -128,8 +123,7 @@ let AlphaBar = class AlphaBar extends LitElement {
128
123
  this.tooltip.style.left = `${left}px`;
129
124
  this.tooltip.classList.add('fade-in');
130
125
  }
131
- };
132
- AlphaBar.styles = css `
126
+ static { this.styles = css `
133
127
  h1 {
134
128
  font-size: 1.2rem;
135
129
  }
@@ -215,7 +209,8 @@ AlphaBar.styles = css `
215
209
  grid-template-columns: repeat(13, 1fr);
216
210
  }
217
211
  }
218
- `;
212
+ `; }
213
+ };
219
214
  __decorate([
220
215
  property({ type: String })
221
216
  ], AlphaBar.prototype, "selectedLetter", void 0);