@internetarchive/bookreader 5.0.0-3 → 5.0.0-30-a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (389) hide show
  1. package/.eslintrc.js +17 -5
  2. package/.github/dependabot.yml +8 -0
  3. package/.github/workflows/node.js.yml +10 -1
  4. package/.husky/_/husky.sh +30 -0
  5. package/.testcaferc.js +10 -0
  6. package/BookReader/BookReader.css +75 -323
  7. package/BookReader/BookReader.js +1 -1
  8. package/BookReader/BookReader.js.LICENSE.txt +45 -0
  9. package/BookReader/BookReader.js.map +1 -1
  10. package/BookReader/ia-bookreader-bundle.js +1458 -0
  11. package/BookReader/{bookreader-component-bundle.js.LICENSE.txt → ia-bookreader-bundle.js.LICENSE.txt} +10 -9
  12. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  13. package/BookReader/icons/close-circle-dark.svg +1 -0
  14. package/BookReader/icons/voice.svg +1 -0
  15. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  16. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  17. package/BookReader/plugins/plugin.autoplay.js +1 -1
  18. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  19. package/BookReader/plugins/plugin.chapters.js +1 -1
  20. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  21. package/BookReader/plugins/plugin.iframe.js +1 -1
  22. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  23. package/BookReader/plugins/plugin.mobile_nav.js +1 -1
  24. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  25. package/BookReader/plugins/plugin.resume.js +1 -1
  26. package/BookReader/plugins/plugin.resume.js.map +1 -1
  27. package/BookReader/plugins/plugin.search.js +1 -1
  28. package/BookReader/plugins/plugin.search.js.map +1 -1
  29. package/BookReader/plugins/plugin.text_selection.js +1 -1
  30. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  31. package/BookReader/plugins/plugin.tts.js +1 -1
  32. package/BookReader/plugins/plugin.tts.js.map +1 -1
  33. package/BookReader/plugins/plugin.url.js +1 -1
  34. package/BookReader/plugins/plugin.url.js.map +1 -1
  35. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  36. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  37. package/BookReader/webcomponents-bundle.js +3 -0
  38. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  39. package/BookReader/webcomponents-bundle.js.map +1 -0
  40. package/BookReaderDemo/BookReaderDemo.css +14 -1
  41. package/BookReaderDemo/IADemoBr.js +107 -0
  42. package/BookReaderDemo/demo-advanced.html +1 -1
  43. package/BookReaderDemo/demo-autoplay.html +1 -0
  44. package/BookReaderDemo/demo-embed-iframe-src.html +1 -0
  45. package/BookReaderDemo/demo-fullscreen-mobile.html +1 -0
  46. package/BookReaderDemo/demo-fullscreen.html +1 -0
  47. package/BookReaderDemo/demo-iiif.html +1 -0
  48. package/BookReaderDemo/demo-internetarchive.html +66 -18
  49. package/BookReaderDemo/demo-multiple.html +1 -0
  50. package/BookReaderDemo/demo-preview-pages.html +1 -0
  51. package/BookReaderDemo/demo-simple.html +1 -0
  52. package/BookReaderDemo/demo-vendor-fullscreen.html +1 -0
  53. package/BookReaderDemo/immersion-1up.html +1 -0
  54. package/BookReaderDemo/immersion-mode.html +1 -0
  55. package/BookReaderDemo/toggle_controls.html +1 -0
  56. package/BookReaderDemo/view_mode.html +1 -0
  57. package/BookReaderDemo/viewmode-cycle.html +1 -2
  58. package/CHANGELOG.md +114 -0
  59. package/babel.config.js +18 -0
  60. package/index.html +3 -0
  61. package/jsconfig.json +19 -0
  62. package/package.json +45 -27
  63. package/src/BookNavigator/assets/button-base.js +8 -1
  64. package/src/BookNavigator/assets/ia-logo.js +17 -0
  65. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  66. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  67. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  68. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  69. package/src/BookNavigator/book-navigator.js +528 -0
  70. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  71. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -1
  72. package/src/BookNavigator/bookmarks/bookmarks-list.js +1 -0
  73. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
  74. package/src/BookNavigator/bookmarks/bookmarks-provider.js +32 -11
  75. package/src/BookNavigator/bookmarks/ia-bookmarks.js +88 -43
  76. package/src/BookNavigator/downloads/downloads-provider.js +22 -16
  77. package/src/BookNavigator/downloads/downloads.js +16 -23
  78. package/src/BookNavigator/search/a-search-result.js +1 -0
  79. package/src/BookNavigator/search/search-provider.js +54 -20
  80. package/src/BookNavigator/search/search-results.js +7 -18
  81. package/src/BookNavigator/sharing.js +27 -0
  82. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +10 -12
  83. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +1 -0
  84. package/src/BookNavigator/volumes/volumes-provider.js +114 -0
  85. package/src/BookNavigator/volumes/volumes.js +189 -0
  86. package/src/BookReader/DebugConsole.js +3 -3
  87. package/src/BookReader/DragScrollable.js +233 -0
  88. package/src/BookReader/Mode1Up.js +50 -351
  89. package/src/BookReader/Mode1UpLit.js +434 -0
  90. package/src/BookReader/Mode2Up.js +94 -72
  91. package/src/BookReader/ModeSmoothZoom.js +177 -0
  92. package/src/BookReader/ModeThumb.js +16 -8
  93. package/src/BookReader/Navbar/Navbar.js +2 -31
  94. package/src/BookReader/PageContainer.js +47 -2
  95. package/src/BookReader/ReduceSet.js +1 -1
  96. package/src/BookReader/Toolbar/Toolbar.js +5 -5
  97. package/src/BookReader/options.js +10 -0
  98. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  99. package/src/BookReader/utils.js +68 -13
  100. package/src/BookReader.js +316 -232
  101. package/src/assets/icons/close-circle-dark.svg +1 -0
  102. package/src/assets/icons/voice.svg +1 -0
  103. package/src/css/BookReader.scss +0 -12
  104. package/src/css/_BRComponent.scss +1 -1
  105. package/src/css/_BRmain.scss +19 -24
  106. package/src/css/_BRnav.scss +4 -26
  107. package/src/css/_BRpages.scss +35 -0
  108. package/src/css/_BRsearch.scss +11 -215
  109. package/src/css/_TextSelection.scss +1 -17
  110. package/src/css/_controls.scss +16 -3
  111. package/src/css/_icons.scss +6 -0
  112. package/src/ia-bookreader/ia-bookreader.js +205 -0
  113. package/src/plugins/plugin.chapters.js +15 -18
  114. package/src/plugins/plugin.mobile_nav.js +11 -10
  115. package/src/plugins/plugin.resume.js +3 -3
  116. package/src/plugins/plugin.text_selection.js +17 -29
  117. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  118. package/src/plugins/search/plugin.search.js +113 -104
  119. package/src/plugins/search/view.js +48 -163
  120. package/src/plugins/tts/AbstractTTSEngine.js +7 -0
  121. package/src/plugins/tts/FestivalTTSEngine.js +2 -2
  122. package/src/plugins/tts/WebTTSEngine.js +5 -0
  123. package/src/plugins/tts/plugin.tts.js +67 -102
  124. package/src/plugins/url/UrlPlugin.js +184 -0
  125. package/src/plugins/url/plugin.url.js +220 -0
  126. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  127. package/{src → stat}/BookNavigator/BookNavigator.js +151 -104
  128. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  129. package/stat/BookNavigator/assets/button-base.js +61 -0
  130. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  131. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  132. package/stat/BookNavigator/assets/icon_close.js +3 -0
  133. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  134. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  135. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  136. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  137. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  138. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  139. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  140. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  141. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  142. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  143. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  144. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  145. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  146. package/stat/BookNavigator/downloads/downloads.js +139 -0
  147. package/stat/BookNavigator/provider-config.js +0 -0
  148. package/stat/BookNavigator/search/a-search-result.js +55 -0
  149. package/stat/BookNavigator/search/search-provider.js +180 -0
  150. package/stat/BookNavigator/search/search-results.js +360 -0
  151. package/stat/BookNavigator/sharing.js +31 -0
  152. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  153. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  154. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  155. package/stat/BookNavigator/volumes/volumes.js +178 -0
  156. package/stat/BookReader/BookModel.js +518 -0
  157. package/stat/BookReader/DebugConsole.js +54 -0
  158. package/stat/BookReader/DragScrollable.js +233 -0
  159. package/stat/BookReader/ImageCache.js +116 -0
  160. package/stat/BookReader/Mode1Up.js +102 -0
  161. package/stat/BookReader/Mode1UpLit.js +434 -0
  162. package/stat/BookReader/Mode2Up.js +1372 -0
  163. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  164. package/stat/BookReader/ModeThumb.js +344 -0
  165. package/stat/BookReader/Navbar/Navbar.js +310 -0
  166. package/stat/BookReader/PageContainer.js +120 -0
  167. package/stat/BookReader/ReduceSet.js +26 -0
  168. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  169. package/stat/BookReader/events.js +20 -0
  170. package/stat/BookReader/options.js +324 -0
  171. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  172. package/stat/BookReader/utils/classes.js +36 -0
  173. package/stat/BookReader/utils.js +240 -0
  174. package/stat/BookReader.js +2550 -0
  175. package/{src → stat}/BookReaderComponent/BookReaderComponent.js +16 -11
  176. package/stat/assets/icons/1up.svg +12 -0
  177. package/stat/assets/icons/2up.svg +15 -0
  178. package/stat/assets/icons/advance.svg +26 -0
  179. package/stat/assets/icons/chevron-right.svg +1 -0
  180. package/stat/assets/icons/close-circle-dark.svg +1 -0
  181. package/stat/assets/icons/close-circle.svg +1 -0
  182. package/stat/assets/icons/fullscreen.svg +17 -0
  183. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  184. package/stat/assets/icons/hamburger.svg +15 -0
  185. package/stat/assets/icons/left-arrow.svg +12 -0
  186. package/stat/assets/icons/magnify-minus.svg +16 -0
  187. package/stat/assets/icons/magnify-plus.svg +17 -0
  188. package/stat/assets/icons/magnify.svg +15 -0
  189. package/stat/assets/icons/pause.svg +23 -0
  190. package/stat/assets/icons/play.svg +22 -0
  191. package/stat/assets/icons/playback-speed.svg +34 -0
  192. package/stat/assets/icons/read-aloud.svg +22 -0
  193. package/stat/assets/icons/review.svg +22 -0
  194. package/stat/assets/icons/thumbnails.svg +17 -0
  195. package/stat/assets/icons/voice.svg +1 -0
  196. package/stat/assets/icons/volume-full.svg +22 -0
  197. package/stat/assets/images/BRicons.png +0 -0
  198. package/stat/assets/images/BRicons.svg +94 -0
  199. package/stat/assets/images/BRicons_ia.png +0 -0
  200. package/stat/assets/images/back_pages.png +0 -0
  201. package/stat/assets/images/book_bottom_icon.png +0 -0
  202. package/stat/assets/images/book_down_icon.png +0 -0
  203. package/stat/assets/images/book_left_icon.png +0 -0
  204. package/stat/assets/images/book_leftmost_icon.png +0 -0
  205. package/stat/assets/images/book_right_icon.png +0 -0
  206. package/stat/assets/images/book_rightmost_icon.png +0 -0
  207. package/stat/assets/images/book_top_icon.png +0 -0
  208. package/stat/assets/images/book_up_icon.png +0 -0
  209. package/stat/assets/images/books_graphic.svg +177 -0
  210. package/stat/assets/images/booksplit.png +0 -0
  211. package/stat/assets/images/control_pause_icon.png +0 -0
  212. package/stat/assets/images/control_play_icon.png +0 -0
  213. package/stat/assets/images/embed_icon.png +0 -0
  214. package/stat/assets/images/icon-home-ia.png +0 -0
  215. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  216. package/stat/assets/images/icon_alert-xs.png +0 -0
  217. package/stat/assets/images/icon_book.svg +12 -0
  218. package/stat/assets/images/icon_bookmark.svg +12 -0
  219. package/stat/assets/images/icon_close-pop.png +0 -0
  220. package/stat/assets/images/icon_download.png +0 -0
  221. package/stat/assets/images/icon_gear.svg +14 -0
  222. package/stat/assets/images/icon_hamburger.svg +20 -0
  223. package/stat/assets/images/icon_home.png +0 -0
  224. package/stat/assets/images/icon_home.svg +21 -0
  225. package/stat/assets/images/icon_home_ia.png +0 -0
  226. package/stat/assets/images/icon_indicator.png +0 -0
  227. package/stat/assets/images/icon_info.svg +11 -0
  228. package/stat/assets/images/icon_one_page.svg +8 -0
  229. package/stat/assets/images/icon_pause.svg +1 -0
  230. package/stat/assets/images/icon_play.svg +1 -0
  231. package/stat/assets/images/icon_playback-rate.svg +15 -0
  232. package/stat/assets/images/icon_return.png +0 -0
  233. package/stat/assets/images/icon_search_button.svg +8 -0
  234. package/stat/assets/images/icon_share.svg +9 -0
  235. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  236. package/stat/assets/images/icon_skip-back.svg +13 -0
  237. package/stat/assets/images/icon_speaker.svg +18 -0
  238. package/stat/assets/images/icon_speaker_open.svg +10 -0
  239. package/stat/assets/images/icon_thumbnails.svg +12 -0
  240. package/stat/assets/images/icon_toc.svg +5 -0
  241. package/stat/assets/images/icon_two_pages.svg +9 -0
  242. package/stat/assets/images/icon_zoomer.png +0 -0
  243. package/stat/assets/images/loading.gif +0 -0
  244. package/stat/assets/images/logo_icon.png +0 -0
  245. package/stat/assets/images/marker_chap-off.png +0 -0
  246. package/stat/assets/images/marker_chap-off.svg +11 -0
  247. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  248. package/stat/assets/images/marker_chap-on.png +0 -0
  249. package/stat/assets/images/marker_chap-on.svg +11 -0
  250. package/stat/assets/images/marker_srch-on.svg +11 -0
  251. package/stat/assets/images/marker_srchchap-off.png +0 -0
  252. package/stat/assets/images/marker_srchchap-on.png +0 -0
  253. package/stat/assets/images/nav_control-dn.png +0 -0
  254. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  255. package/stat/assets/images/nav_control-up.png +0 -0
  256. package/stat/assets/images/nav_control-up_ia.png +0 -0
  257. package/stat/assets/images/nav_control.png +0 -0
  258. package/stat/assets/images/one_page_mode_icon.png +0 -0
  259. package/stat/assets/images/paper-badge.png +0 -0
  260. package/stat/assets/images/print_icon.png +0 -0
  261. package/stat/assets/images/progressbar.gif +0 -0
  262. package/stat/assets/images/right_edges.png +0 -0
  263. package/stat/assets/images/slider.png +0 -0
  264. package/stat/assets/images/slider_ia.png +0 -0
  265. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  266. package/stat/assets/images/transparent.png +0 -0
  267. package/stat/assets/images/two_page_mode_icon.png +0 -0
  268. package/stat/assets/images/zoom_in_icon.png +0 -0
  269. package/stat/assets/images/zoom_out_icon.png +0 -0
  270. package/stat/css/BookReader.scss +89 -0
  271. package/stat/css/_BRBookmarks.scss +29 -0
  272. package/stat/css/_BRComponent.scss +13 -0
  273. package/stat/css/_BRfloat.scss +197 -0
  274. package/stat/css/_BRicon.scss +48 -0
  275. package/stat/css/_BRmain.scss +251 -0
  276. package/stat/css/_BRnav.scss +359 -0
  277. package/stat/css/_BRpages.scss +139 -0
  278. package/stat/css/_BRsearch.scss +226 -0
  279. package/stat/css/_BRtoolbar.scss +84 -0
  280. package/stat/css/_BRvendor.scss +5 -0
  281. package/stat/css/_MobileNav.scss +194 -0
  282. package/stat/css/_TextSelection.scss +32 -0
  283. package/stat/css/_colorbox.scss +52 -0
  284. package/stat/css/_controls.scss +253 -0
  285. package/stat/css/_icons.scss +121 -0
  286. package/stat/jquery-wrapper.js +4 -0
  287. package/stat/plugins/plugin.archive_analytics.js +86 -0
  288. package/stat/plugins/plugin.autoplay.js +129 -0
  289. package/stat/plugins/plugin.chapters.js +248 -0
  290. package/stat/plugins/plugin.iframe.js +48 -0
  291. package/stat/plugins/plugin.mobile_nav.js +288 -0
  292. package/stat/plugins/plugin.resume.js +68 -0
  293. package/stat/plugins/plugin.text_selection.js +291 -0
  294. package/{src → stat}/plugins/plugin.url.js +4 -4
  295. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  296. package/stat/plugins/search/plugin.search.js +439 -0
  297. package/stat/plugins/search/view.js +439 -0
  298. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  299. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  300. package/stat/plugins/tts/PageChunk.js +107 -0
  301. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  302. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  303. package/stat/plugins/tts/plugin.tts.js +357 -0
  304. package/stat/plugins/tts/tooltip_dict.js +15 -0
  305. package/stat/plugins/tts/utils.js +91 -0
  306. package/stat/util/browserSniffing.js +30 -0
  307. package/stat/util/debouncer.js +26 -0
  308. package/stat/util/docCookies.js +67 -0
  309. package/stat/util/strings.js +34 -0
  310. package/tests/e2e/README.md +37 -0
  311. package/tests/e2e/autoplay.test.js +2 -2
  312. package/tests/e2e/base.test.js +5 -7
  313. package/tests/e2e/helpers/base.js +8 -3
  314. package/tests/e2e/helpers/debug.js +1 -1
  315. package/tests/e2e/helpers/desktopSearch.js +1 -1
  316. package/tests/e2e/helpers/mobileSearch.js +3 -3
  317. package/tests/e2e/helpers/params.js +17 -0
  318. package/tests/e2e/rightToLeft.test.js +4 -5
  319. package/tests/e2e/viewmode.test.js +30 -31
  320. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +3 -3
  321. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  322. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  323. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  324. package/tests/jest/BookReader/Mode1UpLit.test.js +87 -0
  325. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +5 -7
  326. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  327. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  328. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  329. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +74 -2
  330. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  331. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  332. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  333. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  334. package/tests/jest/BookReader/utils.test.js +136 -0
  335. package/tests/jest/BookReader.keyboard.test.js +190 -0
  336. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  337. package/tests/{BookReader.test.js → jest/BookReader.test.js} +20 -4
  338. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  339. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +2 -2
  340. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +8 -8
  341. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  342. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  343. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  344. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +14 -24
  345. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  346. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +12 -5
  347. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +6 -6
  348. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +3 -3
  349. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  350. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  351. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  352. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  353. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -3
  354. package/tests/jest/plugins/url/UrlPlugin.test.js +175 -0
  355. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  356. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  357. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  358. package/tests/{util → jest/util}/strings.test.js +1 -1
  359. package/tests/{utils.js → jest/utils.js} +38 -0
  360. package/tests/karma/BookNavigator/book-navigator.test.js +485 -0
  361. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  362. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +1 -3
  363. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +1 -2
  364. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +67 -0
  365. package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
  366. package/tests/karma/BookNavigator/search/search-provider.test.js +123 -0
  367. package/tests/karma/BookNavigator/{search-results.test.js → search/search-results.test.js} +1 -4
  368. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +49 -0
  369. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -2
  370. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +184 -0
  371. package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
  372. package/webpack.config.js +10 -4
  373. package/.babelrc +0 -12
  374. package/.dependabot/config.yml +0 -6
  375. package/.testcaferc.json +0 -5
  376. package/BookReader/bookreader-component-bundle.js +0 -1450
  377. package/BookReader/bookreader-component-bundle.js.map +0 -1
  378. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  379. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  380. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  381. package/src/BookNavigator/assets/book-loader.js +0 -27
  382. package/src/ItemNavigator/ItemNavigator.js +0 -372
  383. package/src/ItemNavigator/providers/sharing.js +0 -29
  384. package/src/dragscrollable-br.js +0 -261
  385. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  386. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  387. package/tests/BookReader/Mode1Up.test.js +0 -164
  388. package/tests/BookReader/utils.test.js +0 -109
  389. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -0,0 +1,528 @@
1
+ // eslint-disable-next-line no-unused-vars
2
+ import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
3
+ // eslint-disable-next-line no-unused-vars
4
+ import { ModalManager } from '@internetarchive/modal-manager';
5
+ import { css, html, LitElement } from 'lit-element';
6
+ import SearchProvider from './search/search-provider.js';
7
+ import DownloadProvider from './downloads/downloads-provider.js';
8
+ import VisualAdjustmentProvider from './visual-adjustments/visual-adjustments-provider.js';
9
+ import BookmarksProvider from './bookmarks/bookmarks-provider.js';
10
+ import SharingProvider from './sharing.js';
11
+ import VolumesProvider from './volumes/volumes-provider.js';
12
+ import iaLogo from './assets/ia-logo.js';
13
+
14
+ const events = {
15
+ menuUpdated: 'menuUpdated',
16
+ updateSideMenu: 'updateSideMenu',
17
+ PostInit: 'PostInit',
18
+ ViewportInFullScreen: 'ViewportInFullScreen',
19
+ };
20
+ export class BookNavigator extends LitElement {
21
+ static get properties() {
22
+ return {
23
+ itemMD: { type: Object },
24
+ bookReaderLoaded: { type: Boolean },
25
+ bookreader: { type: Object },
26
+ bookIsRestricted: { type: Boolean },
27
+ downloadableTypes: { type: Array },
28
+ isAdmin: { type: Boolean },
29
+ lendingInitialized: { type: Boolean },
30
+ lendingStatus: { type: Object },
31
+ menuProviders: { type: Object },
32
+ menuShortcuts: { type: Array },
33
+ signedIn: { type: Boolean },
34
+ loaded: { type: Boolean },
35
+ sharedObserver: { type: Object, attribute: false },
36
+ modal: { type: Object, attribute: false },
37
+ fullscreenBranding: { type: Object },
38
+ };
39
+ }
40
+
41
+ constructor() {
42
+ super();
43
+ this.itemMD = undefined;
44
+ this.loaded = false;
45
+ this.bookReaderCannotLoad = false;
46
+ this.bookReaderLoaded = false;
47
+ this.bookreader = null;
48
+ this.bookIsRestricted = false;
49
+ this.downloadableTypes = [];
50
+ this.isAdmin = false;
51
+ this.lendingInitialized = false;
52
+ this.lendingStatus = {};
53
+ this.menuProviders = {};
54
+ this.menuShortcuts = [];
55
+ this.signedIn = false;
56
+ /** @type {ModalManager} */
57
+ this.modal = undefined;
58
+ /** @type {SharedResizeObserver} */
59
+ this.sharedObserver = undefined;
60
+ this.fullscreenBranding = iaLogo;
61
+ // Untracked properties
62
+ this.sharedObserverHandler = undefined;
63
+ this.brWidth = 0;
64
+ this.brHeight = 0;
65
+ this.shortcutOrder = [
66
+ /**
67
+ * sets exit FS button (`this.fullscreenBranding1)
68
+ * when `br.options.enableFSLogoShortcut`
69
+ */
70
+ 'fullscreen',
71
+ 'volumes',
72
+ 'search',
73
+ 'bookmarks'
74
+ ];
75
+ }
76
+
77
+ disconnectedCallback() {
78
+ this.sharedObserver.removeObserver({
79
+ target: this.mainBRContainer,
80
+ handler: this.sharedObserverHandler
81
+ });
82
+ }
83
+
84
+ firstUpdated() {
85
+ this.bindEventListeners();
86
+ this.emitPostInit();
87
+ this.loaded = true;
88
+ }
89
+
90
+ updated(changed) {
91
+ if (!this.bookreader || !this.itemMD || !this.bookReaderLoaded) {
92
+ return;
93
+ }
94
+
95
+ const reload = changed.has('loaded') && this.loaded;
96
+ if (reload
97
+ || changed.has('itemMD')
98
+ || changed.has('bookreader')
99
+ || changed.has('signedIn')
100
+ || changed.has('isAdmin')
101
+ || changed.has('modal')) {
102
+ this.initializeBookSubmenus();
103
+ }
104
+
105
+ if (changed.has('sharedObserver') && this.bookreader) {
106
+ this.loadSharedObserver();
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Global event emitter for when Book Navigator loads
112
+ */
113
+ emitPostInit() {
114
+ // emit global event when book nav has loaded with current bookreader selector
115
+ this.dispatchEvent(new CustomEvent(`BrBookNav:${events.PostInit}`, {
116
+ detail: { brSelector: this.bookreader?.el },
117
+ bubbles: true,
118
+ composed: true,
119
+ }));
120
+ }
121
+
122
+ /**
123
+ * @typedef {{
124
+ * baseHost: string,
125
+ * modal: ModalManager,
126
+ * sharedObserver: SharedResizeObserver,
127
+ * bookreader: BookReader,
128
+ * item: Item,
129
+ * signedIn: boolean,
130
+ * isAdmin: boolean,
131
+ * onProviderChange: (BookReader, object) => void,
132
+ * }} baseProviderConfig
133
+ *
134
+ * @return {baseProviderConfig}
135
+ */
136
+ get baseProviderConfig() {
137
+ return {
138
+ baseHost: this.baseHost,
139
+ modal: this.modal,
140
+ sharedObserver: this.sharedObserver,
141
+ bookreader: this.bookreader,
142
+ item: this.itemMD,
143
+ signedIn: this.signedIn,
144
+ isAdmin: this.isAdmin,
145
+ onProviderChange: () => {}
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Instantiates books submenus & their update callbacks
151
+ *
152
+ * NOTE: we are doing our best to scope bookreader's instance.
153
+ * If your submenu provider uses a bookreader instance to read, manually
154
+ * manipulate BookReader, please update the navigator's instance of it
155
+ * to keep it in sync.
156
+ */
157
+ initializeBookSubmenus() {
158
+ const providers = {
159
+ downloads: new DownloadProvider(this.baseProviderConfig),
160
+ share: new SharingProvider(this.baseProviderConfig),
161
+ visualAdjustments: new VisualAdjustmentProvider({
162
+ ...this.baseProviderConfig,
163
+ /** Update menu contents */
164
+ onProviderChange: () => {
165
+ this.updateMenuContents();
166
+ },
167
+ }),
168
+ };
169
+
170
+ if (this.bookreader.options.enableSearch) {
171
+ providers.search = new SearchProvider({
172
+ ...this.baseProviderConfig,
173
+ /**
174
+ * Search specific menu updates
175
+ * @param {BookReader} brInstance
176
+ * @param {{ searchCanceled: boolean }} searchUpdates
177
+ */
178
+ onProviderChange: (brInstance = null, searchUpdates = {}) => {
179
+ if (brInstance) {
180
+ /* refresh br instance reference */
181
+ this.bookreader = brInstance;
182
+ }
183
+ const wideEnoughToOpenMenu = this.brWidth >= 640;
184
+ if (wideEnoughToOpenMenu && !searchUpdates?.searchCanceled) {
185
+ /* open side search menu */
186
+ setTimeout(() => {
187
+ this.updateSideMenu('search', 'open');
188
+ }, 0);
189
+ }
190
+ this.updateMenuContents();
191
+ },
192
+ });
193
+ }
194
+
195
+ if (this.bookreader.options.enableBookmarks) {
196
+ providers.bookmarks = new BookmarksProvider({
197
+ ...this.baseProviderConfig,
198
+ onProviderChange: (bookmarks) => {
199
+ const method = Object.keys(bookmarks).length ? 'add' : 'remove';
200
+ this[`${method}MenuShortcut`]('bookmarks');
201
+ this.updateMenuContents();
202
+ }
203
+ });
204
+ }
205
+
206
+ // add shortcut for volumes if multipleBooksList exists
207
+ if (this.bookreader.options.enableMultipleBooks) {
208
+ providers.volumes = new VolumesProvider({
209
+ ...this.baseProviderConfig,
210
+ onProviderChange: (brInstance = null, volumesUpdates = {}) => {
211
+ if (brInstance) {
212
+ /* refresh br instance reference */
213
+ this.bookreader = brInstance;
214
+ }
215
+ this.updateMenuContents();
216
+ this.updateSideMenu('volumes', 'open');
217
+ }
218
+ });
219
+ }
220
+
221
+ this.menuProviders = providers;
222
+ this.addMenuShortcut('search');
223
+ this.addMenuShortcut('volumes');
224
+ this.updateMenuContents();
225
+ }
226
+
227
+ /** gets element that houses the bookreader in light dom */
228
+ get mainBRContainer() {
229
+ return document.querySelector(this.bookreader?.el);
230
+ }
231
+
232
+ /** Fullscreen Shortcut */
233
+ addFullscreenShortcut() {
234
+ const closeFS = {
235
+ icon: this.fullscreenShortcut,
236
+ id: 'fullscreen',
237
+ };
238
+ this.menuShortcuts.push(closeFS);
239
+ this.sortMenuShortcuts();
240
+ this.emitMenuShortcutsUpdated();
241
+ }
242
+
243
+ deleteFullscreenShortcut() {
244
+ const updatedShortcuts = this.menuShortcuts.filter(({ id }) => {
245
+ return id !== 'fullscreen';
246
+ });
247
+ this.menuShortcuts = updatedShortcuts;
248
+ this.sortMenuShortcuts();
249
+ this.emitMenuShortcutsUpdated();
250
+ }
251
+
252
+ closeFullscreen() {
253
+ this.bookreader.exitFullScreen();
254
+ }
255
+
256
+ get fullscreenShortcut() {
257
+ return html`
258
+ <button
259
+ @click=${() => this.closeFullscreen()}
260
+ title="Exit fullscreen view"
261
+ >${this.fullscreenBranding}</button>
262
+ `;
263
+ }
264
+ /** End Fullscreen Shortcut */
265
+
266
+ /**
267
+ * Open side menu
268
+ * @param {string} menuId
269
+ * @param {('open'|'close'|'toggle')} action
270
+ */
271
+ updateSideMenu(menuId = '', action = 'open') {
272
+ if (!menuId) {
273
+ return;
274
+ }
275
+ const event = new CustomEvent(
276
+ events.updateSideMenu, {
277
+ detail: { menuId, action },
278
+ },
279
+ );
280
+ this.dispatchEvent(event);
281
+ }
282
+
283
+ /**
284
+ * Sets order of menu and emits custom event when done
285
+ */
286
+ updateMenuContents() {
287
+ const {
288
+ search, downloads, visualAdjustments, share, bookmarks, volumes
289
+ } = this.menuProviders;
290
+ const availableMenus = [volumes, search, bookmarks, visualAdjustments, share].filter((menu) => !!menu);
291
+
292
+ if (this.shouldShowDownloadsMenu()) {
293
+ downloads?.update(this.downloadableTypes);
294
+ availableMenus.splice(1, 0, downloads);
295
+ }
296
+
297
+ const event = new CustomEvent(
298
+ events.menuUpdated, {
299
+ detail: availableMenus,
300
+ },
301
+ );
302
+ this.dispatchEvent(event);
303
+ }
304
+
305
+ /**
306
+ * Confirms if we should show the downloads menu
307
+ * @returns {bool}
308
+ */
309
+ shouldShowDownloadsMenu() {
310
+ if (this.bookIsRestricted === false) { return true; }
311
+ if (this.isAdmin) { return true; }
312
+ const { user_loan_record = {} } = this.lendingStatus;
313
+ const hasNoLoanRecord = Array.isArray(user_loan_record); /* (bc PHP assoc. arrays) */
314
+
315
+ if (hasNoLoanRecord) { return false; }
316
+
317
+ const hasValidLoan = user_loan_record.type && (user_loan_record.type !== 'SESSION_LOAN');
318
+ return hasValidLoan;
319
+ }
320
+
321
+ /**
322
+ * Adds a provider object to the menuShortcuts array property if it isn't
323
+ * already added. menuShortcuts are then sorted by shortcutOrder and
324
+ * a menuShortcutsUpdated event is emitted.
325
+ *
326
+ * @param {string} menuId - a string matching the id property of a provider
327
+ */
328
+ addMenuShortcut(menuId) {
329
+ if (this.menuShortcuts.find((m) => m.id === menuId)) {
330
+ // menu is already there
331
+ return;
332
+ }
333
+
334
+ if (!this.menuProviders[menuId]) {
335
+ // no provider for this menu
336
+ return;
337
+ }
338
+
339
+ this.menuShortcuts.push(this.menuProviders[menuId]);
340
+
341
+ this.sortMenuShortcuts();
342
+ this.emitMenuShortcutsUpdated();
343
+ }
344
+
345
+ /**
346
+ * Removes a provider object from the menuShortcuts array and emits a
347
+ * menuShortcutsUpdated event.
348
+ *
349
+ * @param {string} menuId - a string matching the id property of a provider
350
+ */
351
+ removeMenuShortcut(menuId) {
352
+ this.menuShortcuts = this.menuShortcuts.filter((m) => m.id !== menuId);
353
+ this.emitMenuShortcutsUpdated();
354
+ }
355
+
356
+ /**
357
+ * Sorts the menuShortcuts property by comparing each provider's id to
358
+ * the id in each iteration over the shortcutOrder array.
359
+ */
360
+ sortMenuShortcuts() {
361
+ this.menuShortcuts = this.shortcutOrder.reduce((shortcuts, id) => {
362
+ const menu = this.menuShortcuts.find((m) => m.id === id);
363
+ if (menu) { shortcuts.push(menu); }
364
+ return shortcuts;
365
+ }, []);
366
+ }
367
+
368
+ emitMenuShortcutsUpdated() {
369
+ const event = new CustomEvent('menuShortcutsUpdated', {
370
+ detail: this.menuShortcuts,
371
+ });
372
+ this.dispatchEvent(event);
373
+ }
374
+
375
+ emitLoadingStatusUpdate(loaded) {
376
+ const event = new CustomEvent('loadingStateUpdated', {
377
+ detail: { loaded },
378
+ });
379
+ this.dispatchEvent(event);
380
+ }
381
+
382
+ /**
383
+ * Core bookreader event handler registry
384
+ *
385
+ * NOTE: we are trying to keep bookreader's instance in scope
386
+ * Please update Book Navigator's instance reference of it to keep it current
387
+ */
388
+ bindEventListeners() {
389
+ window.addEventListener('BookReader:PostInit', (e) => {
390
+ this.bookreader = e.detail.props;
391
+ this.bookReaderLoaded = true;
392
+ this.bookReaderCannotLoad = false;
393
+ this.emitLoadingStatusUpdate(true);
394
+ this.loadSharedObserver();
395
+ setTimeout(() => {
396
+ this.bookreader.resize();
397
+ }, 0);
398
+ });
399
+ window.addEventListener('BookReader:fullscreenToggled', (event) => {
400
+ const { detail: { props: brInstance = null } } = event;
401
+ if (brInstance) {
402
+ this.bookreader = brInstance;
403
+ }
404
+ this.manageFullScreenBehavior();
405
+ }, { passive: true });
406
+ window.addEventListener('BookReader:ToggleSearchMenu', (event) => {
407
+ this.dispatchEvent(new CustomEvent(events.updateSideMenu, {
408
+ detail: { menuId: 'search', action: 'toggle' },
409
+ }));
410
+ });
411
+ window.addEventListener('LendingFlow:PostInit', ({ detail }) => {
412
+ const {
413
+ downloadTypesAvailable, lendingStatus, isAdmin, previewType,
414
+ } = detail;
415
+ this.lendingInitialized = true;
416
+ this.downloadableTypes = downloadTypesAvailable;
417
+ this.lendingStatus = lendingStatus;
418
+ this.isAdmin = isAdmin;
419
+ this.bookReaderCannotLoad = previewType === 'singlePagePreview';
420
+ });
421
+ window.addEventListener('BRJSIA:PostInit', ({ detail }) => {
422
+ const { isRestricted, downloadURLs } = detail;
423
+ this.bookReaderLoaded = true;
424
+ this.downloadableTypes = downloadURLs;
425
+ this.bookIsRestricted = isRestricted;
426
+ });
427
+ }
428
+
429
+ loadSharedObserver() {
430
+ this.sharedObserverHandler = { handleResize: this.handleResize.bind(this) };
431
+ this.sharedObserver?.addObserver({
432
+ target: this.mainBRContainer,
433
+ handler: this.sharedObserverHandler
434
+ });
435
+ }
436
+
437
+ /**
438
+ * Uses resize observer to fire BookReader's `resize` functionality
439
+ * We do not want to trigger resize IF:
440
+ * - book animation is happening
441
+ * - book is in fullscreen (fullscreen is handled separately)
442
+ *
443
+ * @param { target: HTMLElement, contentRect: DOMRectReadOnly } entry
444
+ */
445
+ handleResize({ contentRect, target }) {
446
+ const startBrWidth = this.brWidth;
447
+ const startBrHeight = this.brHeight;
448
+ const { animating } = this.bookreader;
449
+
450
+ if (target === this.mainBRContainer) {
451
+ this.brWidth = contentRect.width;
452
+ this.brHeight = contentRect.height;
453
+ }
454
+
455
+ const widthChange = startBrWidth !== this.brWidth;
456
+ const heightChange = startBrHeight !== this.brHeight;
457
+
458
+ if (!animating && (widthChange || heightChange)) {
459
+ this.bookreader.resize();
460
+ }
461
+ }
462
+
463
+ /**
464
+ * Manages Fullscreen behavior
465
+ * This makes sure that controls are _always_ in view
466
+ * We need this to accommodate LOAN BAR during fullscreen
467
+ */
468
+ manageFullScreenBehavior() {
469
+ this.emitFullScreenState();
470
+
471
+ if (!this.bookreader.options.enableFSLogoShortcut) {
472
+ return;
473
+ }
474
+
475
+ const isFullScreen = this.bookreader.isFullscreen();
476
+ if (isFullScreen) {
477
+ this.addFullscreenShortcut();
478
+ } else {
479
+ this.deleteFullscreenShortcut();
480
+ }
481
+ }
482
+
483
+ /**
484
+ * Relays fullscreen toggle events
485
+ */
486
+ emitFullScreenState() {
487
+ const isFullScreen = this.bookreader.isFullscreen();
488
+ const event = new CustomEvent('ViewportInFullScreen', {
489
+ detail: { isFullScreen },
490
+ });
491
+ this.dispatchEvent(event);
492
+ }
493
+
494
+ get loadingClass() {
495
+ return !this.bookReaderLoaded ? 'loading' : '';
496
+ }
497
+
498
+ get itemImage() {
499
+ const url = `https://${this.baseHost}/services/img/${this.item.metadata.identifier}`;
500
+ return html`<img class="cover-img" src=${url} alt="cover image for ${this.item.metadata.identifier}">`;
501
+ }
502
+
503
+ render() {
504
+ const placeholder = this.bookReaderCannotLoad ? this.itemImage : this.loader;
505
+ return html`<div id="book-navigator" class="${this.loadingClass}">
506
+ ${placeholder}
507
+ <slot name="theater-main"></slot>
508
+ </div>
509
+ `;
510
+ }
511
+
512
+ static get styles() {
513
+ return css`
514
+ :host,
515
+ #book-navigator,
516
+ slot,
517
+ slot > * {
518
+ display: block;
519
+ height: inherit;
520
+ }
521
+ .cover-img {
522
+ max-height: 300px;
523
+ }
524
+ `;
525
+ }
526
+ }
527
+
528
+ customElements.define('book-navigator', BookNavigator);
@@ -12,7 +12,7 @@ export default class BookmarkButton extends LitElement {
12
12
  height: 4rem;
13
13
  width: 4rem;
14
14
  background: transparent;
15
- cursor: url('/images/bookreader/bookmark-add.png'), pointer;
15
+ cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24' viewBox='0 0 16 24' width='16'%3E%3Cg fill='%23333' fill-rule='evenodd'%3E%3Cpath d='m15 0c.5522847 0 1 .44771525 1 1v23l-8-5.4545455-8 5.4545455v-23c0-.55228475.44771525-1 1-1zm-2 2h-10c-.51283584 0-.93550716.38604019-.99327227.88337887l-.00672773.11662113v18l6-4.3181818 6 4.3181818v-18c0-.51283584-.3860402-.93550716-.8833789-.99327227z'/%3E%3Cpath d='m8.75 6v2.25h2.25v1.5h-2.25v2.25h-1.5v-2.25h-2.25v-1.5h2.25v-2.25z' fill-rule='nonzero'/%3E%3C/g%3E%3C/svg%3E"), pointer;
16
16
  position: relative;
17
17
  }
18
18
  button > * {
@@ -40,6 +40,7 @@ export default class BookmarkButton extends LitElement {
40
40
  constructor() {
41
41
  super();
42
42
  this.state = 'hollow';
43
+ this.side = undefined;
43
44
  }
44
45
 
45
46
  handleClick(e) {
@@ -208,7 +208,8 @@ export class IABookmarkEdit extends LitElement {
208
208
  grid-gap: 0 1rem;
209
209
  justify-items: stretch;
210
210
  }
211
- `
211
+ `;
212
212
  return [buttonCSS, bookmarkColorsCSS, bookmarkEditCSS];
213
213
  }
214
214
  }
215
+ customElements.define('ia-bookmark-edit', IABookmarkEdit);
@@ -282,3 +282,4 @@ export class IABookmarksList extends LitElement {
282
282
  return [main, bookmarkColorsCSS];
283
283
  }
284
284
  }
285
+ customElements.define('ia-bookmarks-list', IABookmarksList);
@@ -1,20 +1,15 @@
1
- import { LitElement, html, css } from 'lit-element';
1
+ import { LitElement, html } from 'lit-element';
2
2
  import buttonStyles from '../assets/button-base.js';
3
3
 
4
4
  class BookmarksLogin extends LitElement {
5
5
  static get properties() {
6
6
  return {
7
7
  url: { type: String }
8
- }
8
+ };
9
9
  }
10
10
 
11
11
  static get styles() {
12
- const mainCss = css`
13
- a {
14
- text-decoration: none;
15
- }
16
- `;
17
- return [buttonStyles, mainCss];
12
+ return buttonStyles;
18
13
  }
19
14
 
20
15
  constructor() {
@@ -25,7 +20,7 @@ class BookmarksLogin extends LitElement {
25
20
 
26
21
  return html`
27
22
  <p>A free account is required to save and access bookmarks.</p>
28
- <a class="ia-button link primary" href=${this.url}>Log in</a>
23
+ <a class="ia-button link primary" href="${this.url}">Log in</a>
29
24
  `;
30
25
  }
31
26
  }
@@ -3,26 +3,39 @@ import '../delete-modal-actions.js';
3
3
  import './bookmark-button.js';
4
4
  import './ia-bookmarks.js';
5
5
 
6
- import { IABookmarkEdit } from './bookmark-edit.js';
7
- import { IABookmarksList } from './bookmarks-list.js';
6
+ import './bookmark-edit.js';
7
+ import './bookmarks-list.js';
8
8
  import { IAIconBookmark } from '@internetarchive/icon-bookmark';
9
9
 
10
- customElements.define('ia-bookmark-edit', IABookmarkEdit);
11
- customElements.define('ia-bookmarks-list', IABookmarksList);
12
10
  customElements.define('icon-bookmark', IAIconBookmark);
13
11
 
14
12
  export default class BookmarksProvider {
15
- constructor(options, bookreader) {
16
- const boundOptions = Object.assign(this, options);
13
+ constructor(options) {
14
+ const {
15
+ baseHost,
16
+ signedIn,
17
+ bookreader,
18
+ modal,
19
+ onProviderChange
20
+ } = options;
21
+
22
+ const referrerStr = `referer=${encodeURIComponent(location.href)}`;
23
+ const loginUrl = `https://${baseHost}/account/login?${referrerStr}`;
24
+
17
25
  this.component = document.createElement('ia-bookmarks');
18
26
  this.component.bookreader = bookreader;
19
- this.component.options = boundOptions;
20
-
27
+ this.component.displayMode = signedIn ? 'bookmarks' : 'login';
28
+ this.component.modal = modal;
29
+ this.component.loginOptions = {
30
+ loginClicked: this.bookmarksLoginClicked,
31
+ loginUrl
32
+ };
21
33
  this.bindEvents();
22
34
 
23
35
  this.icon = html`<icon-bookmark state="hollow" style="--iconWidth: 16px; --iconHeight: 24px;"></icon-bookmark>`;
24
36
  this.label = 'Bookmarks';
25
37
  this.id = 'bookmarks';
38
+ this.onProviderChange = onProviderChange;
26
39
  this.component.setup();
27
40
  this.updateMenu(this.component.bookmarks.length);
28
41
  }
@@ -33,13 +46,21 @@ export default class BookmarksProvider {
33
46
 
34
47
  bindEvents() {
35
48
  this.component.addEventListener('bookmarksChanged', this.bookmarksChanged.bind(this));
36
- this.component.addEventListener('showItemNavigatorModal', this.showItemNavigatorModal);
37
- this.component.addEventListener('closeItemNavigatorModal', this.closeItemNavigatorModal);
38
49
  }
39
50
 
40
51
  bookmarksChanged({ detail }) {
41
52
  const bookmarksLength = Object.keys(detail.bookmarks).length;
42
53
  this.updateMenu(bookmarksLength);
43
- this.onBookmarksChanged(detail.bookmarks);
54
+ this.onProviderChange(detail.bookmarks, detail.showSidePanel);
55
+ }
56
+
57
+ bookmarksLoginClicked() {
58
+ if (window.archive_analytics) {
59
+ window.archive_analytics?.send_event_no_sampling(
60
+ 'BookReader',
61
+ `BookmarksLogin`,
62
+ window.location.path,
63
+ );
64
+ }
44
65
  }
45
66
  }