@internetarchive/bookreader 5.0.0-12-fixsorting-7 → 5.0.0-120

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 (420) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +670 -1190
  4. package/BookReader/bergamot-translator-worker.js +2966 -0
  5. package/BookReader/bergamot-translator-worker.wasm +0 -0
  6. package/BookReader/hypothesis/LICENSE +50 -0
  7. package/BookReader/hypothesis/README.md +55 -0
  8. package/BookReader/hypothesis/build/boot-template.js +1 -0
  9. package/BookReader/hypothesis/build/boot.js +1 -0
  10. package/BookReader/hypothesis/build/manifest.json +20 -0
  11. package/BookReader/hypothesis/build/scripts/annotator.bundle.js +199 -0
  12. package/BookReader/hypothesis/build/scripts/annotator.bundle.js.map +1 -0
  13. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js +811 -0
  14. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js.map +1 -0
  15. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js +437 -0
  16. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js.map +1 -0
  17. package/BookReader/hypothesis/build/styles/annotator.css +4 -0
  18. package/BookReader/hypothesis/build/styles/annotator.css.map +1 -0
  19. package/BookReader/hypothesis/build/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  20. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  21. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  22. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  23. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  24. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
  25. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  26. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
  27. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
  28. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  29. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
  30. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  31. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  32. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  33. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
  34. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  35. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  36. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  37. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  38. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  39. package/BookReader/hypothesis/build/styles/highlights.css +2 -0
  40. package/BookReader/hypothesis/build/styles/highlights.css.map +1 -0
  41. package/BookReader/hypothesis/build/styles/katex.min.css +3 -0
  42. package/BookReader/hypothesis/build/styles/katex.min.css.map +1 -0
  43. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css +14 -0
  44. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css.map +1 -0
  45. package/BookReader/hypothesis/build/styles/sidebar.css +4 -0
  46. package/BookReader/hypothesis/build/styles/sidebar.css.map +1 -0
  47. package/BookReader/hypothesis/build/styles/ui-playground.css +4 -0
  48. package/BookReader/hypothesis/build/styles/ui-playground.css.map +1 -0
  49. package/BookReader/hypothesis/package.json +126 -0
  50. package/BookReader/ia-bookreader.js +1886 -0
  51. package/BookReader/{BookReader.js.LICENSE.txt → ia-bookreader.js.LICENSE.txt} +26 -20
  52. package/BookReader/ia-bookreader.js.map +1 -0
  53. package/BookReader/icons/1up.svg +1 -12
  54. package/BookReader/icons/2up.svg +1 -15
  55. package/BookReader/icons/advance.svg +3 -26
  56. package/BookReader/icons/chevron-right.svg +1 -1
  57. package/BookReader/icons/close-circle-dark.svg +1 -1
  58. package/BookReader/icons/close-circle.svg +1 -1
  59. package/BookReader/icons/fullscreen.svg +1 -17
  60. package/BookReader/icons/fullscreen_exit.svg +1 -17
  61. package/BookReader/icons/hamburger.svg +1 -15
  62. package/BookReader/icons/left-arrow.svg +1 -12
  63. package/BookReader/icons/magnify-minus.svg +1 -16
  64. package/BookReader/icons/magnify-plus.svg +1 -17
  65. package/BookReader/icons/magnify.svg +1 -15
  66. package/BookReader/icons/pause.svg +1 -23
  67. package/BookReader/icons/play.svg +1 -22
  68. package/BookReader/icons/playback-speed.svg +1 -34
  69. package/BookReader/icons/read-aloud.svg +1 -22
  70. package/BookReader/icons/review.svg +3 -22
  71. package/BookReader/icons/slider-toggle.svg +1 -0
  72. package/BookReader/icons/thumbnails.svg +1 -17
  73. package/BookReader/icons/voice.svg +1 -0
  74. package/BookReader/icons/volume-full.svg +1 -22
  75. package/BookReader/images/BRicons.svg +5 -94
  76. package/BookReader/images/books_graphic.svg +1 -177
  77. package/BookReader/images/hypothesis.ico +0 -0
  78. package/BookReader/images/icon_book.svg +1 -12
  79. package/BookReader/images/icon_bookmark.svg +1 -12
  80. package/BookReader/images/icon_experiment.svg +1 -0
  81. package/BookReader/images/icon_gear.svg +1 -14
  82. package/BookReader/images/icon_hamburger.svg +1 -20
  83. package/BookReader/images/icon_home.svg +1 -21
  84. package/BookReader/images/icon_info.svg +1 -11
  85. package/BookReader/images/icon_one_page.svg +1 -8
  86. package/BookReader/images/icon_pause.svg +1 -1
  87. package/BookReader/images/icon_play.svg +1 -1
  88. package/BookReader/images/icon_playback-rate.svg +1 -15
  89. package/BookReader/images/icon_search_button.svg +1 -8
  90. package/BookReader/images/icon_share.svg +1 -9
  91. package/BookReader/images/icon_skip-ahead.svg +1 -6
  92. package/BookReader/images/icon_skip-back.svg +2 -13
  93. package/BookReader/images/icon_speaker.svg +1 -18
  94. package/BookReader/images/icon_speaker_open.svg +1 -10
  95. package/BookReader/images/icon_thumbnails.svg +1 -12
  96. package/BookReader/images/icon_toc.svg +1 -5
  97. package/BookReader/images/icon_two_pages.svg +1 -9
  98. package/BookReader/images/marker_chap-off.svg +1 -11
  99. package/BookReader/images/marker_chap-on.svg +1 -11
  100. package/BookReader/images/marker_srch-on.svg +1 -11
  101. package/BookReader/images/translate.svg +1 -0
  102. package/BookReader/images/unviewable_page.png +0 -0
  103. package/BookReader/jquery-3.js +2 -0
  104. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  105. package/BookReader/plugins/plugin.archive_analytics.js +1 -172
  106. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  107. package/BookReader/plugins/plugin.autoplay.js +1 -165
  108. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  109. package/BookReader/plugins/plugin.chapters.js +19 -301
  110. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  111. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  112. package/BookReader/plugins/plugin.experiments.js +3 -0
  113. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  114. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  115. package/BookReader/plugins/plugin.iframe.js +1 -74
  116. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  117. package/BookReader/plugins/plugin.iiif.js +2 -0
  118. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  119. package/BookReader/plugins/plugin.resume.js +1 -368
  120. package/BookReader/plugins/plugin.resume.js.map +1 -1
  121. package/BookReader/plugins/plugin.search.js +2 -1385
  122. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  123. package/BookReader/plugins/plugin.search.js.map +1 -1
  124. package/BookReader/plugins/plugin.text_selection.js +2 -1080
  125. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  126. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  127. package/BookReader/plugins/plugin.translate.js +3 -0
  128. package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
  129. package/BookReader/plugins/plugin.translate.js.map +1 -0
  130. package/BookReader/plugins/plugin.tts.js +2 -9193
  131. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  132. package/BookReader/plugins/plugin.tts.js.map +1 -1
  133. package/BookReader/plugins/plugin.url.js +1 -269
  134. package/BookReader/plugins/plugin.url.js.map +1 -1
  135. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
  136. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  137. package/BookReader/plugins/translator-worker.js +2 -0
  138. package/BookReader/plugins/translator-worker.js.map +1 -0
  139. package/BookReader/silence.mp3 +0 -0
  140. package/BookReader/translator-worker.js +475 -0
  141. package/BookReader/webcomponents-bundle.js +3 -0
  142. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  143. package/BookReader/webcomponents-bundle.js.map +1 -0
  144. package/README.md +17 -4
  145. package/dist/esm/ia-bookreader.js +3 -0
  146. package/dist/esm/ia-bookreader.js.LICENSE.txt +17 -0
  147. package/dist/esm/ia-bookreader.js.map +1 -0
  148. package/dist/esm/plugins/plugin.archive_analytics.js +2 -0
  149. package/dist/esm/plugins/plugin.archive_analytics.js.map +1 -0
  150. package/dist/esm/plugins/plugin.autoplay.js +2 -0
  151. package/dist/esm/plugins/plugin.autoplay.js.map +1 -0
  152. package/dist/esm/plugins/plugin.chapters.js +2 -0
  153. package/dist/esm/plugins/plugin.chapters.js.map +1 -0
  154. package/dist/esm/plugins/plugin.experiments.js +2 -0
  155. package/dist/esm/plugins/plugin.experiments.js.map +1 -0
  156. package/dist/esm/plugins/plugin.iframe.js +2 -0
  157. package/dist/esm/plugins/plugin.iframe.js.map +1 -0
  158. package/dist/esm/plugins/plugin.iiif.js +2 -0
  159. package/dist/esm/plugins/plugin.iiif.js.map +1 -0
  160. package/dist/esm/plugins/plugin.resume.js +2 -0
  161. package/dist/esm/plugins/plugin.resume.js.map +1 -0
  162. package/dist/esm/plugins/plugin.search.js +2 -0
  163. package/dist/esm/plugins/plugin.search.js.map +1 -0
  164. package/dist/esm/plugins/plugin.text_selection.js +2 -0
  165. package/dist/esm/plugins/plugin.text_selection.js.map +1 -0
  166. package/dist/esm/plugins/plugin.translate.js +2 -0
  167. package/dist/esm/plugins/plugin.translate.js.map +1 -0
  168. package/dist/esm/plugins/plugin.tts.js +2 -0
  169. package/dist/esm/plugins/plugin.tts.js.map +1 -0
  170. package/dist/esm/plugins/plugin.url.js +2 -0
  171. package/dist/esm/plugins/plugin.url.js.map +1 -0
  172. package/dist/esm/plugins/plugin.vendor-fullscreen.js +2 -0
  173. package/dist/esm/plugins/plugin.vendor-fullscreen.js.map +1 -0
  174. package/jsconfig.json +18 -0
  175. package/package.json +113 -71
  176. package/src/BookReader/BookModel.js +92 -46
  177. package/src/BookReader/DragScrollable.js +233 -0
  178. package/src/BookReader/ImageCache.js +49 -16
  179. package/src/BookReader/Mode1Up.js +66 -365
  180. package/src/BookReader/Mode1UpLit.js +392 -0
  181. package/src/BookReader/Mode2Up.js +87 -1315
  182. package/src/BookReader/Mode2UpLit.js +786 -0
  183. package/src/BookReader/ModeAbstract.js +43 -0
  184. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  185. package/src/BookReader/ModeSmoothZoom.js +312 -0
  186. package/src/BookReader/ModeThumb.js +29 -15
  187. package/src/BookReader/Navbar/Navbar.js +204 -84
  188. package/src/BookReader/PageContainer.js +120 -23
  189. package/src/BookReader/ReduceSet.js +2 -2
  190. package/src/BookReader/Toolbar/Toolbar.js +18 -40
  191. package/src/BookReader/events.js +3 -3
  192. package/src/BookReader/options.js +105 -18
  193. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  194. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  195. package/src/BookReader/utils/SelectionObserver.js +72 -0
  196. package/src/BookReader/utils/classes.js +1 -1
  197. package/src/BookReader/utils.js +136 -12
  198. package/src/BookReader.js +732 -1231
  199. package/src/BookReaderPlugin.js +52 -0
  200. package/src/assets/icons/magnify-minus.svg +3 -7
  201. package/src/assets/icons/magnify-plus.svg +3 -7
  202. package/src/assets/icons/slider-toggle.svg +1 -0
  203. package/src/assets/icons/voice.svg +1 -0
  204. package/src/assets/images/hypothesis.ico +0 -0
  205. package/src/assets/images/icon_experiment.svg +1 -0
  206. package/src/assets/images/translate.svg +1 -0
  207. package/src/assets/images/unviewable_page.png +0 -0
  208. package/src/assets/silence.mp3 +0 -0
  209. package/src/css/BookReader.scss +1 -5
  210. package/src/css/_BRBookmarks.scss +1 -1
  211. package/src/css/_BRComponent.scss +1 -1
  212. package/src/css/_BRicon.scss +8 -2
  213. package/src/css/_BRmain.scss +16 -3
  214. package/src/css/_BRnav.scss +74 -70
  215. package/src/css/_BRpages.scss +174 -42
  216. package/src/css/_BRsearch.scss +69 -30
  217. package/src/css/_BRtoolbar.scss +5 -5
  218. package/src/css/_TextSelection.scss +249 -25
  219. package/src/css/_colorbox.scss +2 -2
  220. package/src/css/_controls.scss +24 -7
  221. package/src/css/_icons.scss +8 -1
  222. package/src/{BookNavigator/assets → css}/button-base.js +2 -2
  223. package/src/css/icon_checkmark.js +9 -0
  224. package/src/css/sharedStyles.js +15 -0
  225. package/src/ia-bookreader/downloads/downloads-provider.js +81 -0
  226. package/src/{BookNavigator → ia-bookreader}/downloads/downloads.js +25 -5
  227. package/src/ia-bookreader/ia-bookreader.js +686 -0
  228. package/src/ia-bookreader/sharing.js +27 -0
  229. package/src/ia-bookreader/viewable-files.js +98 -0
  230. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments-provider.js +17 -17
  231. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments.js +75 -67
  232. package/src/{BookNavigator → plugins}/bookmarks/bookmark-button.js +4 -3
  233. package/src/{BookNavigator/assets → plugins/bookmarks}/bookmark-colors.js +1 -1
  234. package/src/{BookNavigator → plugins}/bookmarks/bookmark-edit.js +43 -31
  235. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
  236. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +3 -3
  237. package/src/plugins/bookmarks/bookmarks-provider.js +63 -0
  238. package/src/{BookNavigator → plugins/bookmarks}/delete-modal-actions.js +1 -1
  239. package/src/{BookNavigator → plugins}/bookmarks/ia-bookmarks.js +117 -68
  240. package/src/plugins/plugin.archive_analytics.js +84 -78
  241. package/src/plugins/plugin.autoplay.js +99 -104
  242. package/src/plugins/plugin.chapters.js +323 -205
  243. package/src/plugins/plugin.experiments.js +375 -0
  244. package/src/plugins/plugin.iframe.js +36 -37
  245. package/src/plugins/plugin.iiif.js +147 -0
  246. package/src/plugins/plugin.resume.js +54 -51
  247. package/src/plugins/plugin.text_selection.js +464 -219
  248. package/src/plugins/plugin.vendor-fullscreen.js +5 -5
  249. package/src/plugins/search/plugin.search.js +347 -397
  250. package/src/{BookNavigator → plugins}/search/search-provider.js +59 -27
  251. package/src/{BookNavigator → plugins}/search/search-results.js +105 -76
  252. package/src/plugins/search/utils.js +50 -0
  253. package/src/plugins/search/view.js +51 -69
  254. package/src/plugins/translate/TranslationManager.js +164 -0
  255. package/src/plugins/translate/plugin.translate.js +559 -0
  256. package/src/plugins/tts/AbstractTTSEngine.js +78 -49
  257. package/src/plugins/tts/FestivalTTSEngine.js +20 -30
  258. package/src/plugins/tts/PageChunk.js +117 -23
  259. package/src/plugins/tts/PageChunkIterator.js +11 -17
  260. package/src/plugins/tts/WebTTSEngine.js +132 -92
  261. package/src/plugins/tts/plugin.tts.js +341 -351
  262. package/src/plugins/tts/utils.js +76 -67
  263. package/src/plugins/url/UrlPlugin.js +213 -0
  264. package/src/plugins/{plugin.url.js → url/plugin.url.js} +54 -18
  265. package/src/util/TextSelectionManager.js +1464 -0
  266. package/src/util/browserSniffing.js +42 -1
  267. package/src/util/cache.js +20 -0
  268. package/src/util/docCookies.js +21 -2
  269. package/src/util/dom.js +88 -0
  270. package/src/util/generators.js +89 -0
  271. package/src/util/lit.js +15 -0
  272. package/src/util/strings.js +11 -0
  273. package/.babelrc +0 -12
  274. package/.dependabot/config.yml +0 -6
  275. package/.eslintrc.js +0 -50
  276. package/.gitattributes +0 -2
  277. package/.github/ISSUE_TEMPLATE/bug.md +0 -32
  278. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
  279. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
  280. package/.github/workflows/node.js.yml +0 -37
  281. package/.github/workflows/npm-publish.yml +0 -47
  282. package/.testcaferc.json +0 -5
  283. package/BookReader/BookReader.js +0 -21613
  284. package/BookReader/BookReader.js.map +0 -1
  285. package/BookReader/bookreader-component-bundle.js +0 -14497
  286. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  287. package/BookReader/bookreader-component-bundle.js.map +0 -1
  288. package/BookReader/jquery-1.10.1.js +0 -108
  289. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  290. package/BookReader/plugins/plugin.menu_toggle.js +0 -369
  291. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  292. package/BookReader/plugins/plugin.mobile_nav.js +0 -335
  293. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  294. package/BookReaderDemo/BookReaderDemo.css +0 -41
  295. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
  296. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  297. package/BookReaderDemo/BookReaderJSSimple.js +0 -55
  298. package/BookReaderDemo/IIIFBookReader.js +0 -207
  299. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
  300. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
  301. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  302. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  303. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  304. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
  305. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
  306. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  307. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  308. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  309. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  310. package/BookReaderDemo/demo-advanced.html +0 -33
  311. package/BookReaderDemo/demo-autoplay.html +0 -38
  312. package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
  313. package/BookReaderDemo/demo-embed.html +0 -26
  314. package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
  315. package/BookReaderDemo/demo-fullscreen.html +0 -33
  316. package/BookReaderDemo/demo-iiif.html +0 -34
  317. package/BookReaderDemo/demo-iiif.js +0 -26
  318. package/BookReaderDemo/demo-internetarchive.html +0 -74
  319. package/BookReaderDemo/demo-multiple.html +0 -43
  320. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  321. package/BookReaderDemo/demo-preview-pages.html +0 -1092
  322. package/BookReaderDemo/demo-simple.html +0 -34
  323. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
  324. package/BookReaderDemo/immersion-1up.html +0 -64
  325. package/BookReaderDemo/immersion-mode.html +0 -35
  326. package/BookReaderDemo/toggle_controls.html +0 -53
  327. package/BookReaderDemo/view_mode.html +0 -39
  328. package/BookReaderDemo/viewmode-cycle.html +0 -41
  329. package/CHANGELOG.md +0 -499
  330. package/CONTRIBUTING.md +0 -7
  331. package/codecov.yml +0 -17
  332. package/index.html +0 -31
  333. package/karma.conf.js +0 -23
  334. package/screenshot.png +0 -0
  335. package/scripts/postversion.js +0 -10
  336. package/scripts/preversion.js +0 -14
  337. package/scripts/version.js +0 -26
  338. package/src/BookNavigator/BookModel.js +0 -14
  339. package/src/BookNavigator/BookNavigator.js +0 -459
  340. package/src/BookNavigator/assets/book-loader.js +0 -27
  341. package/src/BookNavigator/assets/icon_checkmark.js +0 -6
  342. package/src/BookNavigator/assets/icon_close.js +0 -3
  343. package/src/BookNavigator/assets/icon_sort_ascending.js +0 -5
  344. package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
  345. package/src/BookNavigator/assets/icon_sort_neutral.js +0 -5
  346. package/src/BookNavigator/assets/icon_volumes.js +0 -11
  347. package/src/BookNavigator/bookmarks/bookmarks-provider.js +0 -53
  348. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  349. package/src/BookNavigator/downloads/downloads-provider.js +0 -66
  350. package/src/BookNavigator/search/a-search-result.js +0 -55
  351. package/src/BookNavigator/volumes/volumes-provider.js +0 -83
  352. package/src/BookNavigator/volumes/volumes.js +0 -178
  353. package/src/BookReader/DebugConsole.js +0 -54
  354. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  355. package/src/ItemNavigator/ItemNavigator.js +0 -376
  356. package/src/ItemNavigator/providers/sharing.js +0 -33
  357. package/src/css/_MobileNav.scss +0 -194
  358. package/src/dragscrollable-br.js +0 -261
  359. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  360. package/src/plugins/plugin.mobile_nav.js +0 -287
  361. package/tests/BookReader/BookModel.test.js +0 -312
  362. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  363. package/tests/BookReader/DebugConsole.test.js +0 -25
  364. package/tests/BookReader/ImageCache.test.js +0 -150
  365. package/tests/BookReader/Mode1Up.test.js +0 -164
  366. package/tests/BookReader/Mode2Up.test.js +0 -247
  367. package/tests/BookReader/Navbar/Navbar.test.js +0 -169
  368. package/tests/BookReader/PageContainer.test.js +0 -115
  369. package/tests/BookReader/ReduceSet.test.js +0 -38
  370. package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
  371. package/tests/BookReader/utils/classes.test.js +0 -88
  372. package/tests/BookReader/utils.test.js +0 -109
  373. package/tests/BookReader.options.test.js +0 -39
  374. package/tests/BookReader.test.js +0 -301
  375. package/tests/e2e/README.md +0 -75
  376. package/tests/e2e/autoplay.test.js +0 -13
  377. package/tests/e2e/base.test.js +0 -35
  378. package/tests/e2e/helpers/base.js +0 -263
  379. package/tests/e2e/helpers/debug.js +0 -13
  380. package/tests/e2e/helpers/desktopSearch.js +0 -72
  381. package/tests/e2e/helpers/mobileSearch.js +0 -85
  382. package/tests/e2e/helpers/mockSearch.js +0 -93
  383. package/tests/e2e/helpers/rightToLeft.js +0 -29
  384. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  385. package/tests/e2e/models/BookReader.js +0 -11
  386. package/tests/e2e/models/Navigation.js +0 -56
  387. package/tests/e2e/rightToLeft.test.js +0 -20
  388. package/tests/e2e/viewmode.test.js +0 -37
  389. package/tests/karma/BookNavigator/book-navigator.test.js +0 -139
  390. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
  391. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
  392. package/tests/karma/BookNavigator/search/search-provider.test.js +0 -23
  393. package/tests/karma/BookNavigator/search/search-results.test.js +0 -240
  394. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +0 -40
  395. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  396. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +0 -141
  397. package/tests/karma/BookNavigator/volumes/volumes.test.js +0 -98
  398. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  399. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  400. package/tests/plugins/plugin.autoplay.test.js +0 -52
  401. package/tests/plugins/plugin.chapters.test.js +0 -130
  402. package/tests/plugins/plugin.iframe.test.js +0 -42
  403. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  404. package/tests/plugins/plugin.resume.test.js +0 -98
  405. package/tests/plugins/plugin.text_selection.test.js +0 -203
  406. package/tests/plugins/plugin.url.test.js +0 -129
  407. package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
  408. package/tests/plugins/search/plugin.search.test.js +0 -173
  409. package/tests/plugins/search/plugin.search.view.test.js +0 -106
  410. package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
  411. package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
  412. package/tests/plugins/tts/PageChunk.test.js +0 -57
  413. package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
  414. package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
  415. package/tests/plugins/tts/utils.test.js +0 -133
  416. package/tests/util/browserSniffing.test.js +0 -56
  417. package/tests/util/docCookies.test.js +0 -15
  418. package/tests/util/strings.test.js +0 -63
  419. package/tests/utils.js +0 -42
  420. package/webpack.config.js +0 -86
@@ -0,0 +1,375 @@
1
+ // @ts-check
2
+ import { css, html, LitElement } from 'lit';
3
+ import { BookReaderPlugin } from '../BookReaderPlugin.js';
4
+ import { customElement, property, state } from 'lit/decorators.js';
5
+ import { sleep } from '../BookReader/utils.js';
6
+
7
+ // @ts-ignore
8
+ const BookReader = /** @type {typeof import('@/src/BookReader.js').default} */(window.BookReader);
9
+
10
+ /** @typedef {'copyLinkToHighlight' | 'annotateHighlight' | 'translate' | 'hypothesis'} ExperimentName */
11
+
12
+ class ExperimentModel {
13
+ /** @type {ExperimentName} */
14
+ name;
15
+ /** @type {string} */
16
+ title;
17
+ /** @type {string} */
18
+ description;
19
+ /** @type {string} */
20
+ icon;
21
+ /** @type {boolean} */
22
+ enabled;
23
+ /** @type {string} */
24
+ learnMore;
25
+
26
+ /** @type {import("@/src/BookReader.js").default} */
27
+ br;
28
+
29
+ assetRoot = '/BookReader/';
30
+
31
+ enabledLoading = false;
32
+
33
+ /**
34
+ * @param {string} path
35
+ */
36
+ buildAssetPath(path) {
37
+ return `${this.assetRoot}${path}`;
38
+ }
39
+
40
+ /**
41
+ * @param {object} param0
42
+ * @param {boolean} param0.manual Whether the experiment was enabled manually
43
+ */
44
+ async enable({ manual }) { }
45
+ async disable() { }
46
+ }
47
+
48
+ export class ExperimentsPlugin extends BookReaderPlugin {
49
+ options = {
50
+ enabled: true,
51
+
52
+ /** Where the state of this plugin is saved in localStorage */
53
+ localStorageKey: 'BrExperiments',
54
+
55
+ /** @type {ExperimentName[]} Experiments shown in the experiments panel */
56
+ availableExperiments: ['translate', 'copyLinkToHighlight'],
57
+
58
+ /** @type {ExperimentName[]} Experiments enabled by default */
59
+ autoEnabledExperiments: [],
60
+ }
61
+
62
+ /** @type {ExperimentModel[]} */
63
+ allExperiments = [
64
+ new class extends ExperimentModel {
65
+ name = 'copyLinkToHighlight';
66
+ title = 'Copy Link to Highlight';
67
+ description = 'Shareable link to a text selection';
68
+ icon = null;
69
+ enabled = false;
70
+ async enable ({ manual = false }) {
71
+ if (manual) {
72
+ this.br.plugins.textSelection.textSelectionManager.selectMenu.copyLinkToHighlightEnabled = true;
73
+ }
74
+ }
75
+ async disable() {
76
+ this.br.plugins.textSelection.textSelectionManager.selectMenu.copyLinkToHighlightEnabled = false;
77
+ }
78
+ }(),
79
+ new class extends ExperimentModel {
80
+ name = 'annotateHighlight';
81
+ title = 'Highlight and annotate';
82
+ description = 'Create private highlights and annotations for this book';
83
+ icon = null;
84
+ enabled = false;
85
+ async enable ({ manual = false }) {
86
+ if (manual) {
87
+ this.br.plugins.textSelection.textSelectionManager.selectMenu.highlightAnnotationEnabled = true;
88
+ }
89
+ }
90
+ async disable() {
91
+ sleep(0).then(() => {
92
+ window.location.reload();
93
+ });
94
+ }
95
+ }(),
96
+ new class extends ExperimentModel {
97
+ name = 'translate';
98
+ title = 'Translate Plugin';
99
+ description = "Translate books directly in your browser.";
100
+ learnMore = 'https://mozilla.github.io/translations/';
101
+ icon = 'images/translate.svg';
102
+ enabled = false;
103
+ async enable({ manual = false}) {
104
+ if (BookReader.PLUGINS.translate) return;
105
+
106
+ await importAsScript(this.buildAssetPath('plugins/plugin.translate.js'));
107
+ this.br.initializePlugin('translate');
108
+ }
109
+ async disable() {
110
+ // need to reload to remove translate plugin script
111
+ // Sleep so that the event loop can finish processing before the reload
112
+ sleep(0).then(() => {
113
+ window.location.reload();
114
+ });
115
+ }
116
+ }(),
117
+ new class extends ExperimentModel {
118
+ name = 'hypothesis';
119
+ title = 'Hypothes.is';
120
+ description = 'Create public, collaborative, or fully private annotations on books and the web.';
121
+ learnMore = 'https://web.hypothes.is/about/';
122
+ icon = 'images/hypothesis.ico';
123
+ enabled = false;
124
+
125
+ async enable({ manual = false }) {
126
+ // Hypothesis configs ; see https://h.readthedocs.io/projects/client/en/latest/publishers/config.html
127
+ const configScript = document.createElement('script');
128
+ configScript.type = 'application/json';
129
+ configScript.className = 'js-hypothesis-config';
130
+ configScript.textContent = JSON.stringify({
131
+ // Open the sidebar if this is the first time enabling
132
+ openSidebar: manual,
133
+ assetRoot: this.buildAssetPath('hypothesis/'),
134
+ });
135
+
136
+ document.head.appendChild(configScript);
137
+ return importAsScript(this.buildAssetPath('hypothesis/build/boot.js'));
138
+ // For testing
139
+ // return importAsScript('http://localhost:3001/hypothesis');
140
+ }
141
+
142
+ async disable() {
143
+ // need to reload to remove the Hypothesis script
144
+ // Sleep so that the event loop can finish processing before the reload
145
+ sleep(0).then(() => {
146
+ window.location.reload();
147
+ });
148
+ }
149
+ }(),
150
+ ]
151
+
152
+ /** @type {BrExperimentsPanel} */
153
+ _panel;
154
+
155
+ async init() {
156
+ if (!this.options.enabled) {
157
+ return;
158
+ }
159
+
160
+ for (const experiment of this.allExperiments) {
161
+ // TODO: imagesBaseURL should be replaced with assetRoot everywhere
162
+ experiment.assetRoot = this.br.options.imagesBaseURL.replace(/images\/$/, '');
163
+ if (experiment.icon) {
164
+ experiment.icon = experiment.buildAssetPath(experiment.icon);
165
+ }
166
+
167
+ experiment.br = this.br;
168
+
169
+ // Enable any experiments that should be automatically enabled
170
+ if (!experiment.enabled && this.options.autoEnabledExperiments.includes(experiment.name)) {
171
+ experiment.enabled = true;
172
+ await experiment.enable({ manual: false });
173
+ }
174
+ }
175
+
176
+ this._loadExperimentStates();
177
+ await Promise.resolve();
178
+ this._render();
179
+ }
180
+
181
+ /**
182
+ * @param {ExperimentName} experimentName
183
+ */
184
+ isEnabled(experimentName) {
185
+ const experiment = this.allExperiments.find(exp => exp.name === experimentName);
186
+ return experiment?.enabled;
187
+ }
188
+
189
+ _loadExperimentStates() {
190
+ const savedStates = JSON.parse(localStorage.getItem(this.options.localStorageKey) || '{}');
191
+ this.allExperiments.forEach(experiment => {
192
+ if (savedStates[experiment.name] !== undefined) {
193
+ experiment.enabled = savedStates[experiment.name];
194
+ if (experiment.enabled) {
195
+ experiment.enable({ manual: false });
196
+ }
197
+ }
198
+ });
199
+ }
200
+
201
+ _saveExperimentStates() {
202
+ const states = Object.fromEntries(
203
+ this.allExperiments.map(experiment => [experiment.name, experiment.enabled]),
204
+ );
205
+ localStorage.setItem(this.options.localStorageKey, JSON.stringify(states));
206
+ }
207
+
208
+ /**
209
+ * @param {ExperimentModel} experiment
210
+ * @param {boolean} enabled
211
+ */
212
+ async _toggleExperiment(experiment, enabled) {
213
+ experiment.enabledLoading = true;
214
+ this.br.plugins.archiveAnalytics?.sendEvent(`BRExperiment-${experiment.name}`, enabled ? 'Enable' : 'Disable');
215
+ this._panel.requestUpdate();
216
+
217
+ if (enabled) {
218
+ await experiment.enable({ manual: true });
219
+ } else {
220
+ await experiment.disable();
221
+ }
222
+ experiment.enabledLoading = false;
223
+ experiment.enabled = enabled;
224
+ this._panel.requestUpdate();
225
+ }
226
+
227
+ _render() {
228
+ this.br.shell.menuProviders['experiments'] = {
229
+ id: 'experiments',
230
+ icon: html`
231
+ <img src="${this.br.options.imagesBaseURL}/icon_experiment.svg" alt="" width="26"/>
232
+ `,
233
+ label: 'Experiments',
234
+ component: html`<br-experiments-panel
235
+ .experiments="${this.allExperiments.filter(experiment => this.options.availableExperiments.includes(experiment.name))}"
236
+ @connected="${e => this._panel = e.target}"
237
+ @toggle="${async e => {
238
+ await this._toggleExperiment(e.detail.experiment, e.detail.enabled);
239
+ this._saveExperimentStates();
240
+ }}"
241
+ />`,
242
+ };
243
+ this.br.shell.updateMenuContents();
244
+ }
245
+ }
246
+ BookReader?.registerPlugin('experiments', ExperimentsPlugin);
247
+
248
+ @customElement('br-experiments-panel')
249
+ export class BrExperimentsPanel extends LitElement {
250
+
251
+ /** @type {ExperimentModel[]} */
252
+ @property({ type: Array }) experiments = [];
253
+
254
+ render() {
255
+ return html`
256
+ <div style="padding: 10px">
257
+ ${this.experiments.map(
258
+ experiment => html`
259
+ <br-experiment-toggle
260
+ .icon="${experiment.icon}"
261
+ .title="${experiment.title}"
262
+ .description="${experiment.description}"
263
+ .enabled="${experiment.enabled}"
264
+ .loading="${experiment.enabledLoading}"
265
+ .learnMore="${experiment.learnMore}"
266
+ @toggle="${e => this._dispatchToggle(experiment, e.detail.enabled)}"
267
+ ></br-experiment-toggle>
268
+ `,
269
+ )}
270
+ </div>
271
+ `;
272
+ }
273
+
274
+ /**
275
+ * @param {ExperimentModel} experiment
276
+ * @param {boolean} enabled
277
+ */
278
+ async _dispatchToggle(experiment, enabled) {
279
+ this.dispatchEvent(new CustomEvent('toggle', {
280
+ detail: { experiment, enabled },
281
+ }));
282
+ }
283
+
284
+ connectedCallback() {
285
+ super.connectedCallback();
286
+ this.dispatchEvent(new CustomEvent('connected'));
287
+ }
288
+ }
289
+
290
+ @customElement('br-experiment-toggle')
291
+ export class BrExperimentToggle extends LitElement {
292
+ @property({ type: String }) icon = '';
293
+ @property({ type: String }) title = '';
294
+ @property({ type: String }) description = '';
295
+ @property({ type: Boolean }) enabled = false;
296
+ @property({ type: Boolean }) loading = false;
297
+ @property({ type: String }) learnMore = '';
298
+
299
+ /**
300
+ * We want to disable the button immediately if loading, but only display
301
+ * the loading indicator after 200ms.
302
+ */
303
+ @state() _longLoading = false;
304
+
305
+ /** @override */
306
+ update(changedProperties) {
307
+ super.update(changedProperties);
308
+ if (changedProperties.has('loading')) {
309
+ if (this.loading) {
310
+ sleep(500).then(() => {
311
+ if (this.loading) {
312
+ this._longLoading = true;
313
+ this.requestUpdate();
314
+ }
315
+ });
316
+ } else {
317
+ this._longLoading = false;
318
+ }
319
+ }
320
+ }
321
+
322
+ render() {
323
+ return html`
324
+ <div class="experiment-card" style="margin-bottom: 10px;">
325
+ <div style="display: flex; align-items: center; gap: 10px;">
326
+ ${this.icon ? html`<img src="${this.icon}" style="width: 20px; height: 20px;" alt="" />` : ''}
327
+ <div style="flex-grow: 1; font-weight: bold;">${this.title}</div>
328
+ </div>
329
+ <p style="opacity: 0.9">
330
+ ${this.description}
331
+ ${this.learnMore ? html`<a href="${this.learnMore}" target="_blank">Learn more</a>.` : ''}
332
+ </p>
333
+ <div style="display: flex">
334
+ <div style="flex-grow: 1;"></div>
335
+ <button @click="${this._dispatchToggle}" .disabled="${this.loading}">
336
+ ${this._longLoading ? 'Loading…' : this.enabled ? 'Disable' : 'Enable'}
337
+ </button>
338
+ </div>
339
+ </div>
340
+ `;
341
+ }
342
+
343
+ static get styles() {
344
+ return css`
345
+ .experiment-card {
346
+ border-radius: 8px;
347
+ background-color: #fff2;
348
+ padding: 10px;
349
+ display: flex;
350
+ flex-direction: column;
351
+ }
352
+
353
+ .experiment-card p {
354
+ margin: 6px 0;
355
+ }
356
+ `;
357
+ }
358
+
359
+ _dispatchToggle() {
360
+ this.dispatchEvent(new CustomEvent('toggle', { detail: { enabled: !this.enabled } }));
361
+ }
362
+ }
363
+
364
+ /**
365
+ * @param {string} url
366
+ */
367
+ async function importAsScript(url) {
368
+ return new Promise((resolve, reject) => {
369
+ const script = document.createElement('script');
370
+ script.src = url;
371
+ script.onload = () => resolve();
372
+ script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
373
+ document.head.appendChild(script);
374
+ });
375
+ }
@@ -1,48 +1,47 @@
1
- /* global BookReader */
2
- /**
3
- * Plugin for two-way communication between a BookReader in an IFrame and the
4
- * parent web page
5
- */
1
+ // @ts-check
2
+ import { EVENTS } from '../BookReader/events.js';
3
+ import { BookReaderPlugin } from '../BookReaderPlugin.js';
6
4
 
7
5
  const MESSAGE_TYPE_FRAGMENT_CHANGE = 'bookReaderFragmentChange';
8
6
 
9
- BookReader.prototype.init = (function (super_) {
10
- return function () {
11
- super_.call(this);
12
- _attachEventListeners(this);
13
- };
14
- })(BookReader.prototype.init);
15
-
16
7
  /**
17
- * @private
18
- * Using window.postMessage() and event listeners, the plugin notifies the
19
- * parent window when pages change, and the parent window can also
20
- * explicitly request a page change by sending its own message.
21
- *
22
- * @param {BookReader} br
23
- * @param {Window?} [parent]
8
+ * Plugin for two-way communication between a BookReader in an IFrame and the
9
+ * parent web page. Using window.postMessage() and event listeners, the
10
+ * plugin notifies the parent window when pages change, and the parent
11
+ * window can also explicitly request a page change by sending its own
12
+ * message.
24
13
  */
25
- export function _attachEventListeners(br, parent = window.parent) {
26
- // Not embedded, abort
27
- if (!parent) {
28
- return;
14
+ export class IframePlugin extends BookReaderPlugin {
15
+ options = {
16
+ enabled: true,
29
17
  }
30
18
 
31
- br.bind(BookReader.eventNames.fragmentChange, () => {
32
- const fragment = br.fragmentFromParams(br.paramsFromCurrent());
33
-
34
- parent.postMessage(
35
- { type: MESSAGE_TYPE_FRAGMENT_CHANGE, fragment },
36
- '*'
37
- );
38
- });
39
-
40
- window.addEventListener('message', event => {
41
- // Not a recognized message type, abort
42
- if (!event.data || event.data.type !== MESSAGE_TYPE_FRAGMENT_CHANGE) {
19
+ /** @override */
20
+ init() {
21
+ // Not enabled, or not embedded, abort
22
+ if (!this.options.enabled || !window.parent) {
43
23
  return;
44
24
  }
45
25
 
46
- br.updateFromParams(br.paramsFromFragment(event.data.fragment));
47
- });
26
+ this.br.bind(EVENTS.fragmentChange, () => {
27
+ const fragment = this.br.fragmentFromParams(this.br.paramsFromCurrent());
28
+
29
+ window.parent.postMessage(
30
+ { type: MESSAGE_TYPE_FRAGMENT_CHANGE, fragment },
31
+ '*',
32
+ );
33
+ });
34
+
35
+ window.addEventListener('message', event => {
36
+ // Not a recognized message type, abort
37
+ if (!event.data || event.data.type !== MESSAGE_TYPE_FRAGMENT_CHANGE) {
38
+ return;
39
+ }
40
+
41
+ this.br.updateFromParams(this.br.paramsFromFragment(event.data.fragment));
42
+ });
43
+ }
48
44
  }
45
+
46
+ const BookReader = /** @type {typeof import('../BookReader').default} */(window.BookReader);
47
+ BookReader?.registerPlugin('iframe', IframePlugin);
@@ -0,0 +1,147 @@
1
+ // @ts-check
2
+ import { BookReaderPlugin } from '../BookReaderPlugin.js';
3
+
4
+ const BookReader = /** @type {typeof import('../BookReader').default} */(window.BookReader);
5
+
6
+ /**
7
+ * @extends BookReaderPlugin<IiifPlugin['options']>
8
+ */
9
+ export class IiifPlugin extends BookReaderPlugin {
10
+ options = {
11
+ enabled: true,
12
+ /** @type {import('@iiif/presentation-3').Manifest | import('@iiif/presentation-2').Manifest | null} */
13
+ manifest: null,
14
+ }
15
+
16
+ /**
17
+ * @param {IiifPlugin['options']} options
18
+ */
19
+ setup(options) {
20
+ super.setup(options);
21
+ this.manifest = this.options.manifest;
22
+
23
+ if (this.options.enabled) {
24
+ Object.assign(this.br.options, this.load());
25
+ }
26
+ }
27
+
28
+ load() {
29
+ if (this.manifest["@context"] == "http://iiif.io/api/presentation/2/context.json") {
30
+ const manifest = /** @type {import('@iiif/presentation-2').Manifest} */(this.manifest);
31
+ return this.manifestToBookReaderV2(manifest);
32
+ } else if (this.manifest["@context"] == "http://iiif.io/api/presentation/3/context.json") {
33
+ const manifest = /** @type {import('@iiif/presentation-3').Manifest} */(this.manifest);
34
+ return this.manifestToBookReaderV3(manifest);
35
+ } else {
36
+ throw new Error("Unsupported IIIF context " + this.manifest["@context"]);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @param {import('@iiif/presentation-3').Manifest} manifest
42
+ */
43
+ manifestToBookReaderV3(manifest) {
44
+ /** @type {import('../BookReader/options.js').BookReaderOptions} */
45
+ const book = {
46
+ bookTitle: resolveInternationalString(manifest.label),
47
+ pageProgression: manifest.viewingDirection == "right-to-left" ? "rl" : "lr",
48
+ // numLeafs: manifest.items.length,
49
+ metadata: (manifest.metadata || []).map((metadata) => {
50
+ return {
51
+ label: resolveInternationalString(metadata.label),
52
+ value: resolveInternationalString(metadata.value),
53
+ };
54
+ }),
55
+ data: [],
56
+ /**
57
+ * @this {import('../BookReader.js').default}
58
+ */
59
+ getPageURI(pageIndex, reduce, rotate) {
60
+ const percent = Math.floor(100 * 1 / reduce);
61
+ const bodyArr = manifest.items[pageIndex].items[0].items[0].body;
62
+ const body = bodyArr instanceof Array ? bodyArr[0] : bodyArr;
63
+ const uri = body.service[0].id;
64
+ return `${uri}/full/pct:${percent}/0/default.jpg`;
65
+ },
66
+ };
67
+
68
+ if (manifest.viewingDirection == "top-to-bottom" || manifest.viewingDirection == "bottom-to-top") {
69
+ console.warn("Unsupported viewingDirection", manifest.viewingDirection);
70
+ }
71
+
72
+ let spread = [];
73
+ manifest.items.forEach((item, index) => {
74
+ const bodyArr = manifest.items[index].items[0].items[0].body;
75
+ const body = bodyArr instanceof Array ? bodyArr[0] : bodyArr;
76
+ const uri = body.service[0].id;
77
+ /** @type {import('../BookReader/options.js').PageData} */
78
+ const pageData = {
79
+ uri,
80
+ width: item.width,
81
+ height: item.height,
82
+ pageNum: resolveInternationalString(item.label),
83
+ };
84
+ spread.push(pageData);
85
+ if (index % 2 == 0) {
86
+ book.data.push(spread);
87
+ spread = [];
88
+ }
89
+ });
90
+ if (spread.length > 0) {
91
+ book.data.push(spread);
92
+ }
93
+ return book;
94
+ }
95
+
96
+ /**
97
+ * @param {import('@iiif/presentation-2').Manifest} manifest
98
+ */
99
+ manifestToBookReaderV2(manifest) {
100
+ /** @type {import('../BookReader/options.js').BookReaderOptions} */
101
+ const book = {
102
+ bookTitle: manifest.label,
103
+ metadata: manifest.metadata,
104
+ thumbnail: manifest.thumbnail?.['@id'],
105
+ // numLeafs: manifest.sequences[0].canvases.length,
106
+ data: [],
107
+ /**
108
+ * @this {import('../BookReader.js').default}
109
+ */
110
+ getPageURI(pageIndex, reduce, rotate) {
111
+ const percent = Math.floor(100 * 1 / reduce);
112
+ const uri = manifest.sequences[0].canvases[pageIndex].images[0].resource.service['@id'];
113
+ return `${uri}/full/pct:${percent}/0/default.jpg`;
114
+ },
115
+ };
116
+
117
+ let spread = [];
118
+ manifest.sequences[0].canvases.forEach((canvas, index) => {
119
+ /** @type {import('../BookReader/options.js').PageData} */
120
+ const pageData = {
121
+ uri: canvas.images[0].resource.service['@id'],
122
+ width: canvas.width,
123
+ height: canvas.height,
124
+ pageNum: canvas.label,
125
+ };
126
+ spread.push(pageData);
127
+ if (index % 2 == 0) {
128
+ book.data.push(spread);
129
+ spread = [];
130
+ }
131
+ });
132
+ if (spread.length > 0) {
133
+ book.data.push(spread);
134
+ }
135
+ return book;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * @param {import('@iiif/presentation-3').InternationalString} internationalString
141
+ */
142
+ function resolveInternationalString(internationalString) {
143
+ const anyLang = Object.keys(internationalString)[0];
144
+ return (internationalString[navigator.language] || internationalString[anyLang])[0];
145
+ }
146
+
147
+ BookReader?.registerPlugin('iiif', IiifPlugin);