@internetarchive/bookreader 5.0.0-11-multiple-files → 5.0.0-110

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 (389) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +616 -1467
  4. package/BookReader/BookReader.js +2 -21564
  5. package/BookReader/BookReader.js.LICENSE.txt +20 -20
  6. package/BookReader/BookReader.js.map +1 -1
  7. package/BookReader/bergamot-translator-worker.js +2966 -0
  8. package/BookReader/bergamot-translator-worker.wasm +0 -0
  9. package/BookReader/hypothesis/LICENSE +50 -0
  10. package/BookReader/hypothesis/README.md +55 -0
  11. package/BookReader/hypothesis/build/boot.js +1 -0
  12. package/BookReader/hypothesis/build/manifest.json +20 -0
  13. package/BookReader/hypothesis/build/scripts/annotator.bundle.js +184 -0
  14. package/BookReader/hypothesis/build/scripts/annotator.bundle.js.map +1 -0
  15. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js +798 -0
  16. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js.map +1 -0
  17. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js +711 -0
  18. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js.map +1 -0
  19. package/BookReader/hypothesis/build/styles/annotator.css +2235 -0
  20. package/BookReader/hypothesis/build/styles/annotator.css.map +1 -0
  21. package/BookReader/hypothesis/build/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  22. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  23. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  24. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  25. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  26. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
  27. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  28. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
  29. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
  30. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  31. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
  32. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  33. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  34. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  35. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
  36. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  37. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  38. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  39. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  40. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  41. package/BookReader/hypothesis/build/styles/highlights.css +2 -0
  42. package/BookReader/hypothesis/build/styles/highlights.css.map +1 -0
  43. package/BookReader/hypothesis/build/styles/katex.min.css +2 -0
  44. package/BookReader/hypothesis/build/styles/katex.min.css.map +1 -0
  45. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css +2 -0
  46. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css.map +1 -0
  47. package/BookReader/hypothesis/build/styles/sidebar.css +2731 -0
  48. package/BookReader/hypothesis/build/styles/sidebar.css.map +1 -0
  49. package/BookReader/hypothesis/build/styles/ui-playground.css +2659 -0
  50. package/BookReader/hypothesis/build/styles/ui-playground.css.map +1 -0
  51. package/BookReader/hypothesis/package.json +126 -0
  52. package/BookReader/ia-bookreader-bundle.js +1907 -0
  53. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +19 -0
  54. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  55. package/BookReader/icons/1up.svg +1 -12
  56. package/BookReader/icons/2up.svg +1 -15
  57. package/BookReader/icons/advance.svg +3 -26
  58. package/BookReader/icons/chevron-right.svg +1 -1
  59. package/BookReader/icons/close-circle-dark.svg +1 -0
  60. package/BookReader/icons/close-circle.svg +1 -1
  61. package/BookReader/icons/fullscreen.svg +1 -17
  62. package/BookReader/icons/fullscreen_exit.svg +1 -17
  63. package/BookReader/icons/hamburger.svg +1 -15
  64. package/BookReader/icons/left-arrow.svg +1 -12
  65. package/BookReader/icons/magnify-minus.svg +1 -16
  66. package/BookReader/icons/magnify-plus.svg +1 -17
  67. package/BookReader/icons/magnify.svg +1 -15
  68. package/BookReader/icons/pause.svg +1 -23
  69. package/BookReader/icons/play.svg +1 -22
  70. package/BookReader/icons/playback-speed.svg +1 -34
  71. package/BookReader/icons/read-aloud.svg +1 -22
  72. package/BookReader/icons/review.svg +3 -22
  73. package/BookReader/icons/slider-toggle.svg +1 -0
  74. package/BookReader/icons/thumbnails.svg +1 -17
  75. package/BookReader/icons/voice.svg +1 -0
  76. package/BookReader/icons/volume-full.svg +1 -22
  77. package/BookReader/images/BRicons.svg +5 -94
  78. package/BookReader/images/books_graphic.svg +1 -177
  79. package/BookReader/images/hypothesis.ico +0 -0
  80. package/BookReader/images/icon_book.svg +1 -12
  81. package/BookReader/images/icon_bookmark.svg +1 -12
  82. package/BookReader/images/icon_experiment.svg +1 -0
  83. package/BookReader/images/icon_gear.svg +1 -14
  84. package/BookReader/images/icon_hamburger.svg +1 -20
  85. package/BookReader/images/icon_home.svg +1 -21
  86. package/BookReader/images/icon_info.svg +1 -11
  87. package/BookReader/images/icon_one_page.svg +1 -8
  88. package/BookReader/images/icon_pause.svg +1 -1
  89. package/BookReader/images/icon_play.svg +1 -1
  90. package/BookReader/images/icon_playback-rate.svg +1 -15
  91. package/BookReader/images/icon_search_button.svg +1 -8
  92. package/BookReader/images/icon_share.svg +1 -9
  93. package/BookReader/images/icon_skip-ahead.svg +1 -6
  94. package/BookReader/images/icon_skip-back.svg +2 -13
  95. package/BookReader/images/icon_speaker.svg +1 -18
  96. package/BookReader/images/icon_speaker_open.svg +1 -10
  97. package/BookReader/images/icon_thumbnails.svg +1 -12
  98. package/BookReader/images/icon_toc.svg +1 -5
  99. package/BookReader/images/icon_two_pages.svg +1 -9
  100. package/BookReader/images/marker_chap-off.svg +1 -11
  101. package/BookReader/images/marker_chap-on.svg +1 -11
  102. package/BookReader/images/marker_srch-on.svg +1 -11
  103. package/BookReader/images/translate.svg +1 -0
  104. package/BookReader/images/unviewable_page.png +0 -0
  105. package/BookReader/jquery-3.js +2 -0
  106. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  107. package/BookReader/plugins/plugin.archive_analytics.js +1 -172
  108. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  109. package/BookReader/plugins/plugin.autoplay.js +1 -165
  110. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  111. package/BookReader/plugins/plugin.chapters.js +19 -301
  112. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  113. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  114. package/BookReader/plugins/plugin.experiments.js +3 -0
  115. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  116. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  117. package/BookReader/plugins/plugin.iframe.js +1 -74
  118. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  119. package/BookReader/plugins/plugin.iiif.js +2 -0
  120. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  121. package/BookReader/plugins/plugin.resume.js +1 -368
  122. package/BookReader/plugins/plugin.resume.js.map +1 -1
  123. package/BookReader/plugins/plugin.search.js +2 -1420
  124. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  125. package/BookReader/plugins/plugin.search.js.map +1 -1
  126. package/BookReader/plugins/plugin.text_selection.js +2 -1080
  127. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  128. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  129. package/BookReader/plugins/plugin.translate.js +137 -0
  130. package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
  131. package/BookReader/plugins/plugin.translate.js.map +1 -0
  132. package/BookReader/plugins/plugin.tts.js +2 -9193
  133. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  134. package/BookReader/plugins/plugin.tts.js.map +1 -1
  135. package/BookReader/plugins/plugin.url.js +1 -269
  136. package/BookReader/plugins/plugin.url.js.map +1 -1
  137. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
  138. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  139. package/BookReader/plugins/translator-worker.js +2 -0
  140. package/BookReader/plugins/translator-worker.js.map +1 -0
  141. package/BookReader/silence.mp3 +0 -0
  142. package/BookReader/translator-worker.js +475 -0
  143. package/BookReader/webcomponents-bundle.js +3 -0
  144. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  145. package/BookReader/webcomponents-bundle.js.map +1 -0
  146. package/README.md +14 -3
  147. package/jsconfig.json +19 -0
  148. package/package.json +92 -70
  149. package/src/BookReader/BookModel.js +92 -46
  150. package/src/BookReader/DragScrollable.js +233 -0
  151. package/src/BookReader/ImageCache.js +49 -16
  152. package/src/BookReader/Mode1Up.js +66 -356
  153. package/src/BookReader/Mode1UpLit.js +392 -0
  154. package/src/BookReader/Mode2Up.js +87 -1315
  155. package/src/BookReader/Mode2UpLit.js +788 -0
  156. package/src/BookReader/ModeAbstract.js +43 -0
  157. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  158. package/src/BookReader/ModeSmoothZoom.js +312 -0
  159. package/src/BookReader/ModeThumb.js +30 -16
  160. package/src/BookReader/Navbar/Navbar.js +201 -76
  161. package/src/BookReader/PageContainer.js +120 -23
  162. package/src/BookReader/ReduceSet.js +3 -3
  163. package/src/BookReader/Toolbar/Toolbar.js +19 -41
  164. package/src/BookReader/events.js +3 -3
  165. package/src/BookReader/options.js +94 -17
  166. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  167. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  168. package/src/BookReader/utils/SelectionObserver.js +45 -0
  169. package/src/BookReader/utils/classes.js +1 -1
  170. package/src/BookReader/utils.js +141 -13
  171. package/src/BookReader.js +711 -1241
  172. package/src/BookReaderPlugin.js +52 -0
  173. package/src/assets/icons/close-circle-dark.svg +1 -0
  174. package/src/assets/icons/magnify-minus.svg +3 -7
  175. package/src/assets/icons/magnify-plus.svg +3 -7
  176. package/src/assets/icons/slider-toggle.svg +1 -0
  177. package/src/assets/icons/voice.svg +1 -0
  178. package/src/assets/images/hypothesis.ico +0 -0
  179. package/src/assets/images/icon_experiment.svg +1 -0
  180. package/src/assets/images/translate.svg +1 -0
  181. package/src/assets/images/unviewable_page.png +0 -0
  182. package/src/assets/silence.mp3 +0 -0
  183. package/src/css/BookReader.scss +1 -17
  184. package/src/css/_BRBookmarks.scss +1 -1
  185. package/src/css/_BRComponent.scss +1 -1
  186. package/src/css/_BRicon.scss +8 -2
  187. package/src/css/_BRmain.scss +33 -27
  188. package/src/css/_BRnav.scss +74 -70
  189. package/src/css/_BRpages.scss +171 -42
  190. package/src/css/_BRsearch.scss +69 -235
  191. package/src/css/_BRtoolbar.scss +5 -5
  192. package/src/css/_TextSelection.scss +129 -24
  193. package/src/css/_colorbox.scss +2 -2
  194. package/src/css/_controls.scss +24 -7
  195. package/src/css/_icons.scss +14 -1
  196. package/src/{BookNavigator/assets → css}/button-base.js +10 -3
  197. package/src/css/icon_checkmark.js +9 -0
  198. package/src/css/sharedStyles.js +15 -0
  199. package/src/ia-bookreader/downloads/downloads-provider.js +81 -0
  200. package/src/{BookNavigator → ia-bookreader}/downloads/downloads.js +29 -25
  201. package/src/ia-bookreader/ia-bookreader.js +666 -0
  202. package/src/ia-bookreader/sharing.js +27 -0
  203. package/src/ia-bookreader/viewable-files.js +98 -0
  204. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments-provider.js +17 -17
  205. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments.js +75 -67
  206. package/src/{BookNavigator → plugins}/bookmarks/bookmark-button.js +4 -3
  207. package/src/{BookNavigator/assets → plugins/bookmarks}/bookmark-colors.js +1 -1
  208. package/src/{BookNavigator → plugins}/bookmarks/bookmark-edit.js +44 -32
  209. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
  210. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +5 -10
  211. package/src/plugins/bookmarks/bookmarks-provider.js +63 -0
  212. package/src/{BookNavigator → plugins/bookmarks}/delete-modal-actions.js +1 -1
  213. package/src/{BookNavigator → plugins}/bookmarks/ia-bookmarks.js +117 -68
  214. package/src/plugins/plugin.archive_analytics.js +84 -78
  215. package/src/plugins/plugin.autoplay.js +99 -104
  216. package/src/plugins/plugin.chapters.js +310 -201
  217. package/src/plugins/plugin.experiments.js +321 -0
  218. package/src/plugins/plugin.iframe.js +1 -1
  219. package/src/plugins/plugin.iiif.js +141 -0
  220. package/src/plugins/plugin.resume.js +53 -50
  221. package/src/plugins/plugin.text_selection.js +522 -219
  222. package/src/plugins/plugin.vendor-fullscreen.js +7 -7
  223. package/src/plugins/search/plugin.search.js +380 -360
  224. package/src/{BookNavigator → plugins}/search/search-provider.js +94 -32
  225. package/src/{BookNavigator → plugins}/search/search-results.js +108 -90
  226. package/src/plugins/search/utils.js +50 -0
  227. package/src/plugins/search/view.js +79 -210
  228. package/src/plugins/translate/TranslationManager.js +164 -0
  229. package/src/plugins/translate/plugin.translate.js +512 -0
  230. package/src/plugins/tts/AbstractTTSEngine.js +78 -49
  231. package/src/plugins/tts/FestivalTTSEngine.js +21 -31
  232. package/src/plugins/tts/PageChunk.js +33 -21
  233. package/src/plugins/tts/PageChunkIterator.js +11 -17
  234. package/src/plugins/tts/WebTTSEngine.js +131 -91
  235. package/src/plugins/tts/plugin.tts.js +345 -350
  236. package/src/plugins/tts/utils.js +77 -49
  237. package/src/plugins/url/UrlPlugin.js +191 -0
  238. package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
  239. package/src/util/TextSelectionManager.js +282 -0
  240. package/src/util/browserSniffing.js +33 -1
  241. package/src/util/cache.js +20 -0
  242. package/src/util/docCookies.js +21 -2
  243. package/src/util/lit.js +15 -0
  244. package/src/util/strings.js +1 -0
  245. package/.babelrc +0 -12
  246. package/.dependabot/config.yml +0 -6
  247. package/.eslintrc.js +0 -49
  248. package/.gitattributes +0 -2
  249. package/.github/ISSUE_TEMPLATE/bug.md +0 -32
  250. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
  251. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
  252. package/.github/workflows/node.js.yml +0 -28
  253. package/.github/workflows/npm-publish.yml +0 -47
  254. package/.testcaferc.json +0 -5
  255. package/BookReader/bookreader-component-bundle.js +0 -14330
  256. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  257. package/BookReader/bookreader-component-bundle.js.map +0 -1
  258. package/BookReader/icons/sort-ascending.svg +0 -1
  259. package/BookReader/icons/sort-descending.svg +0 -1
  260. package/BookReader/jquery-1.10.1.js +0 -108
  261. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  262. package/BookReader/plugins/plugin.menu_toggle.js +0 -369
  263. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  264. package/BookReader/plugins/plugin.mobile_nav.js +0 -335
  265. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  266. package/BookReaderDemo/BookReaderDemo.css +0 -41
  267. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
  268. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  269. package/BookReaderDemo/BookReaderJSSimple.js +0 -55
  270. package/BookReaderDemo/IIIFBookReader.js +0 -207
  271. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
  272. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
  273. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  274. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  275. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  276. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
  277. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
  278. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  279. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  280. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  281. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  282. package/BookReaderDemo/demo-advanced.html +0 -33
  283. package/BookReaderDemo/demo-autoplay.html +0 -38
  284. package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
  285. package/BookReaderDemo/demo-embed.html +0 -26
  286. package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
  287. package/BookReaderDemo/demo-fullscreen.html +0 -33
  288. package/BookReaderDemo/demo-iiif.html +0 -34
  289. package/BookReaderDemo/demo-iiif.js +0 -26
  290. package/BookReaderDemo/demo-internetarchive.html +0 -74
  291. package/BookReaderDemo/demo-multiple.html +0 -43
  292. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  293. package/BookReaderDemo/demo-preview-pages.html +0 -1092
  294. package/BookReaderDemo/demo-simple.html +0 -34
  295. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
  296. package/BookReaderDemo/immersion-1up.html +0 -64
  297. package/BookReaderDemo/immersion-mode.html +0 -35
  298. package/BookReaderDemo/toggle_controls.html +0 -53
  299. package/BookReaderDemo/view_mode.html +0 -39
  300. package/BookReaderDemo/viewmode-cycle.html +0 -41
  301. package/CHANGELOG.md +0 -476
  302. package/CONTRIBUTING.md +0 -7
  303. package/codecov.yml +0 -17
  304. package/index.html +0 -31
  305. package/karma.conf.js +0 -23
  306. package/screenshot.png +0 -0
  307. package/scripts/postversion.js +0 -10
  308. package/scripts/preversion.js +0 -14
  309. package/scripts/version.js +0 -26
  310. package/src/BookNavigator/BookModel.js +0 -14
  311. package/src/BookNavigator/BookNavigator.js +0 -451
  312. package/src/BookNavigator/assets/book-loader.js +0 -27
  313. package/src/BookNavigator/assets/icon_checkmark.js +0 -6
  314. package/src/BookNavigator/assets/icon_close.js +0 -3
  315. package/src/BookNavigator/assets/icon_sort_ascending.js +0 -5
  316. package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
  317. package/src/BookNavigator/bookmarks/bookmarks-provider.js +0 -53
  318. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  319. package/src/BookNavigator/downloads/downloads-provider.js +0 -66
  320. package/src/BookNavigator/search/a-search-result.js +0 -55
  321. package/src/BookNavigator/volumes/volumes-provider.js +0 -75
  322. package/src/BookNavigator/volumes/volumes.js +0 -161
  323. package/src/BookReader/DebugConsole.js +0 -54
  324. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  325. package/src/ItemNavigator/ItemNavigator.js +0 -372
  326. package/src/ItemNavigator/providers/sharing.js +0 -29
  327. package/src/assets/icons/sort-ascending.svg +0 -1
  328. package/src/assets/icons/sort-descending.svg +0 -1
  329. package/src/css/_MobileNav.scss +0 -194
  330. package/src/dragscrollable-br.js +0 -261
  331. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  332. package/src/plugins/plugin.mobile_nav.js +0 -287
  333. package/tests/BookReader/BookModel.test.js +0 -312
  334. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  335. package/tests/BookReader/DebugConsole.test.js +0 -25
  336. package/tests/BookReader/ImageCache.test.js +0 -150
  337. package/tests/BookReader/Mode1Up.test.js +0 -164
  338. package/tests/BookReader/Mode2Up.test.js +0 -247
  339. package/tests/BookReader/Navbar/Navbar.test.js +0 -169
  340. package/tests/BookReader/PageContainer.test.js +0 -115
  341. package/tests/BookReader/ReduceSet.test.js +0 -38
  342. package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
  343. package/tests/BookReader/utils/classes.test.js +0 -88
  344. package/tests/BookReader/utils.test.js +0 -109
  345. package/tests/BookReader.options.test.js +0 -39
  346. package/tests/BookReader.test.js +0 -301
  347. package/tests/e2e/README.md +0 -75
  348. package/tests/e2e/autoplay.test.js +0 -13
  349. package/tests/e2e/base.test.js +0 -35
  350. package/tests/e2e/helpers/base.js +0 -258
  351. package/tests/e2e/helpers/debug.js +0 -13
  352. package/tests/e2e/helpers/desktopSearch.js +0 -72
  353. package/tests/e2e/helpers/mobileSearch.js +0 -85
  354. package/tests/e2e/helpers/mockSearch.js +0 -93
  355. package/tests/e2e/helpers/rightToLeft.js +0 -29
  356. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  357. package/tests/e2e/models/BookReader.js +0 -11
  358. package/tests/e2e/models/Navigation.js +0 -56
  359. package/tests/e2e/rightToLeft.test.js +0 -20
  360. package/tests/e2e/viewmode.test.js +0 -37
  361. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  362. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
  363. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
  364. package/tests/karma/BookNavigator/search-results.test.js +0 -240
  365. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  366. package/tests/karma/BookNavigator/volumes.test.js +0 -133
  367. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  368. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  369. package/tests/plugins/plugin.autoplay.test.js +0 -52
  370. package/tests/plugins/plugin.chapters.test.js +0 -130
  371. package/tests/plugins/plugin.iframe.test.js +0 -42
  372. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  373. package/tests/plugins/plugin.resume.test.js +0 -98
  374. package/tests/plugins/plugin.text_selection.test.js +0 -203
  375. package/tests/plugins/plugin.url.test.js +0 -129
  376. package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
  377. package/tests/plugins/search/plugin.search.test.js +0 -166
  378. package/tests/plugins/search/plugin.search.view.test.js +0 -106
  379. package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
  380. package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
  381. package/tests/plugins/tts/PageChunk.test.js +0 -57
  382. package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
  383. package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
  384. package/tests/plugins/tts/utils.test.js +0 -133
  385. package/tests/util/browserSniffing.test.js +0 -56
  386. package/tests/util/docCookies.test.js +0 -15
  387. package/tests/util/strings.test.js +0 -63
  388. package/tests/utils.js +0 -42
  389. package/webpack.config.js +0 -86
@@ -1,75 +1,33 @@
1
+ // @ts-check
2
+ /** @typedef {import('@/src/BookReader.js').default} BookReader */
3
+
1
4
  class SearchView {
2
5
  /**
3
6
  * @param {object} params
4
- * @param {string} params.selector A selector for the element that the search tray will be rendered in
5
- * @param {string} params.query An existing query string
6
- * @param {object} params.br The BookReader instance
7
+ * @param {BookReader} params.br The BookReader instance
8
+ * @param {function} params.searchCancelledCallback callback when a user wants to cancel search
7
9
  *
8
10
  * @event BookReader:SearchResultsCleared - when the search results nav gets cleared
9
11
  * @event BookReader:ToggleSearchMenu - when search results menu should toggle
10
12
  */
11
- constructor(params) {
12
- if (!params.selector) {
13
- console.warn('BookReader::Search - SearchView must be passed a valid CSS selector');
14
- return;
15
- }
16
-
17
- this.br = params.br;
18
-
19
- // Search results are returned as a text blob with the hits wrapped in
20
- // triple mustaches. Hits occasionally include text beyond the search
21
- // term, so everything within the staches is captured and wrapped.
22
- this.matcher = new RegExp('{{{(.+?)}}}', 'g');
13
+ constructor({ br, searchCancelledCallback = () => {} }) {
14
+ /** @type {BookReader} */
15
+ this.br = br;
23
16
  this.matches = [];
24
- this.cacheDOMElements(params.selector);
17
+ this.cacheDOMElements();
18
+ this.cancelSearch = searchCancelledCallback;
19
+ }
20
+
21
+ init() {
25
22
  this.bindEvents();
26
23
  }
27
24
 
28
- /**
29
- * @param {string} selector A selector for the element that the search tray will be rendered in
30
- */
31
- cacheDOMElements(selector) {
25
+ cacheDOMElements() {
32
26
  this.dom = {};
33
-
34
- // The parent search tray in mobile menu
35
- this.dom.searchTray = this.renderSearchTray(selector);
36
- // Container for rendered search results
37
- this.dom.results = this.dom.searchTray.querySelector('[data-id="results"]');
38
- // Element used to display number of results
39
- this.dom.resultsCount = this.dom.searchTray.querySelector('[data-id="results_count"]');
40
- // Search input within the mobile search tray
41
- this.dom.searchField = this.dom.searchTray.querySelector('[name="query"]');
42
- // Waiting indicator displayed while waiting for a search request
43
- this.dom.searchPending = this.dom.searchTray.querySelector('[data-id="searchPending"]');
44
- // The element added to the mobile menu that is animated into view when
45
- // the "search" nav item is clicked
46
- this.dom.mobileSearch = this.buildMobileDrawer();
47
27
  // Search input within the top toolbar. Will be removed once the mobile menu is replaced.
48
28
  this.dom.toolbarSearch = this.buildToolbarSearch();
49
29
  }
50
30
 
51
- /**
52
- * @param {boolean} bool
53
- */
54
- toggleSearchTray(bool = this.dom.searchTray.classList.contains('hidden')) {
55
- this.dom.searchTray.classList.toggle('hidden', !bool);
56
- }
57
-
58
- /**
59
- * @param {boolean} bool
60
- */
61
- toggleResultsCount(bool) {
62
- this.dom.resultsCount.classList.toggle('visible', bool);
63
- }
64
-
65
- /**
66
- * @param {SearchInsideResults} results
67
- */
68
- updateResultsCount(results) {
69
- this.dom.resultsCount.innerText = `(${results} result${results != 1 ? 's' : ''})`;
70
- this.toggleResultsCount(true);
71
- }
72
-
73
31
  /**
74
32
  * @param {string} query
75
33
  */
@@ -78,7 +36,6 @@ class SearchView {
78
36
  }
79
37
 
80
38
  emptyMatches() {
81
- this.dom.results.innerHTML = '';
82
39
  this.matches = [];
83
40
  }
84
41
 
@@ -86,52 +43,24 @@ class SearchView {
86
43
  this.br.$('.BRnavpos .BRsearch').remove();
87
44
  }
88
45
 
89
- clearSearchFieldAndResults() {
90
- this.br.removeSearchResults();
91
- this.toggleResultsCount(false);
46
+ clearSearchFieldAndResults(dispatchEventWhenComplete = true) {
47
+ this.br.plugins.search.removeSearchResults();
92
48
  this.removeResultPins();
93
49
  this.emptyMatches();
94
50
  this.setQuery('');
95
51
  this.teardownSearchNavigation();
96
- this.br.trigger('SearchResultsCleared');
52
+ if (dispatchEventWhenComplete) {
53
+ this.br.trigger('SearchResultsCleared');
54
+ }
97
55
  }
98
56
 
99
57
  toggleSidebar() {
100
58
  this.br.trigger('ToggleSearchMenu');
101
59
  }
102
- /**
103
- * @param {string} selector The ID attribute to be used for the search tray
104
- */
105
- renderSearchTray(selector) {
106
- const searchTray = document.createElement('div');
107
- searchTray.setAttribute('id', selector.replace(/^#/, ''));
108
- searchTray.innerHTML = `
109
- <header>
110
- <div>
111
- <h3>Search inside</h3>
112
- <p data-id="results_count"></p>
113
- </div>
114
- <a href="#" class="close"></a>
115
- </header>
116
- <form action="" method="get">
117
- <fieldset>
118
- <input name="all_files" id="all_files" type="checkbox" />
119
- <label class="checkbox" for="all_files">Search all files</label>
120
- <input type="search" name="query" placeholder="Enter a search term" />
121
- </fieldset>
122
- </form>
123
- <div data-id="searchPending" id="search_pending">
124
- <p>Your search results will appear below</p>
125
- <div class="loader tc mt20"></div>
126
- </div>
127
- <ul data-id="results"></ul>
128
- `;
129
- return searchTray;
130
- }
131
60
 
132
61
  renderSearchNavigation() {
133
62
  const selector = 'BRsearch-navigation';
134
- $('.BRnav').before(`
63
+ $('.BRnav.BRnavMain').before(`
135
64
  <div class="${selector}">
136
65
  <button class="toggle-sidebar">
137
66
  <h4>
@@ -215,17 +144,19 @@ class SearchView {
215
144
  const start = pool.slice(0, pool.length / 2);
216
145
  const end = pool.slice(pool.length / 2);
217
146
  return closestTo((comparisonFn(start, end, comparator) ? start : end), comparator);
218
- }
147
+ };
219
148
 
220
149
  const closestPage = closestTo(matchPages, currentPage);
221
150
  return this.matches.indexOf(this.matches.find((m) => m.par[0].page === closestPage));
222
151
  }
223
152
 
224
153
  updateResultsPosition() {
154
+ if (!this.dom.searchNavigation) return;
225
155
  this.dom.searchNavigation.find('[data-id=resultsCount]').text(this.resultsPosition());
226
156
  }
227
157
 
228
158
  updateSearchNavigationButtons() {
159
+ if (!this.dom.searchNavigation) return;
229
160
  this.dom.searchNavigation.find('.prev').attr('disabled', !this.currentMatchIndex);
230
161
  this.dom.searchNavigation.find('.next').attr('disabled', this.currentMatchIndex + 1 === this.matches.length);
231
162
  }
@@ -272,19 +203,6 @@ class SearchView {
272
203
  this.updateSearchNavigationButtons();
273
204
  }
274
205
 
275
- /**
276
- * @param {array} matches
277
- */
278
- renderMatches(matches) {
279
- const items = matches.map((match) => `
280
- <li data-page="${match.par[0].page}" data-page-index="${this.br.leafNumToIndex(match.par[0].page)}">
281
- <h4>Page ${match.par[0].page}</h4>
282
- <p>${match.text.replace(this.matcher, '<mark>$1</mark>')}</p>
283
- </li>
284
- `);
285
- this.dom.results.innerHTML = items.join('');
286
- }
287
-
288
206
  /**
289
207
  * @param {boolean} bool
290
208
  */
@@ -293,23 +211,6 @@ class SearchView {
293
211
  this.br.refs.$BRfooter.find('.BRsearch').css({ visibility: pinsVisibleState });
294
212
  }
295
213
 
296
- buildMobileDrawer() {
297
- const mobileSearch = document.createElement('li');
298
- mobileSearch.innerHTML = `
299
- <span>
300
- <span class="DrawerIconWrapper">
301
- <img class="DrawerIcon" src="${this.br.imagesBaseURL}icon_search_button.svg" />
302
- </span>
303
- Search
304
- </span>
305
- <div data-id="search_slot">
306
- </div>
307
- `;
308
- mobileSearch.querySelector('[data-id="search_slot"]').appendChild(this.dom.searchTray);
309
- mobileSearch.classList.add('BRmobileMenu__search');
310
- return mobileSearch;
311
- }
312
-
313
214
  buildToolbarSearch() {
314
215
  const toolbarSearch = document.createElement('span');
315
216
  toolbarSearch.classList.add('BRtoolbarSection', 'BRtoolbarSectionSearch');
@@ -317,7 +218,7 @@ class SearchView {
317
218
  <form class="BRbooksearch desktop">
318
219
  <input type="search" name="query" class="BRsearchInput" value="" placeholder="Search inside"/>
319
220
  <button type="submit" class="BRsearchSubmit">
320
- <img src="${this.br.imagesBaseURL}icon_search_button.svg" />
221
+ <img src="${this.br.options.imagesBaseURL}icon_search_button.svg" />
321
222
  </button>
322
223
  </form>
323
224
  `;
@@ -329,25 +230,20 @@ class SearchView {
329
230
  */
330
231
  renderPins(matches) {
331
232
  matches.forEach((match) => {
332
- const queryString = match.text;
333
- const pageIndex = this.br.leafNumToIndex(match.par[0].page);
334
- const pageNumber = this.br.getPageNum(pageIndex);
233
+ const pageIndex = this.br.book.leafNumToIndex(match.par[0].page);
335
234
  const uiStringSearch = "Search result"; // i18n
336
- const uiStringPage = "Page"; // i18n
337
-
338
- const percentThrough = this.br.constructor.util.cssPercentage(pageIndex, this.br.getNumLeafs() - 1);
339
-
340
- const queryStringWithB = queryString.replace(this.matcher, '<b>$1</b>');
341
-
342
- let queryStringWithBTruncated = '';
343
-
344
- if (queryString.length > 100) {
345
- queryStringWithBTruncated = queryString
346
- .replace(/^(.{100}[^\s]*).*/, "$1")
347
- .replace(this.matcher, '<b>$1</b>')
348
- + '...';
235
+ const percentThrough = this.br.constructor.util.cssPercentage(pageIndex, this.br.book.getNumLeafs() - 1);
236
+
237
+ let html = match.html;
238
+ if (html.length > 200) {
239
+ const start = Math.max(0, html.indexOf('<mark>') - 100);
240
+ if (start != 0) {
241
+ html = '' + match.html
242
+ .substring(start)
243
+ // Make sure at word boundary though
244
+ .replace(/^\S+/, '');
245
+ }
349
246
  }
350
-
351
247
  // draw marker
352
248
  $('<div>')
353
249
  .addClass('BRsearch')
@@ -357,56 +253,56 @@ class SearchView {
357
253
  .attr('title', uiStringSearch)
358
254
  .append(`
359
255
  <div class="BRquery">
360
- <div>${queryStringWithBTruncated || queryStringWithB}</div>
361
- <div>${uiStringPage} ${pageNumber}</div>
256
+ <main>${html}</main>
257
+ <footer>Page ${match.displayPageNumber}</footer>
362
258
  </div>
363
259
  `)
364
- .data({ pageIndex })
365
260
  .appendTo(this.br.$('.BRnavline'))
366
- .hover(
367
- (event) => {
368
- // remove from other markers then turn on just for this
369
- // XXX should be done when nav slider moves
370
- const marker = event.currentTarget;
371
- const tooltip = marker.querySelector('.BRquery');
372
- const tooltipOffset = tooltip.getBoundingClientRect();
373
- const targetOffset = marker.getBoundingClientRect();
374
- const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;
375
- if (tooltipOffset.x - boxSizeAdjust < 0) {
376
- tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);
377
- }
378
- $('.BRsearch,.BRchapter').removeClass('front');
379
- $(event.target).addClass('front');
380
- },
381
- (event) => $(event.target).removeClass('front'))
382
- .click(function (event) {
383
- // closures are nested and deep, using an arrow function breaks references.
384
- // Todo: update to arrow function & clean up closures
385
- // to remove `bind` dependency
386
- this.br._searchPluginGoToResult(+$(event.target).data('pageIndex'));
387
- this.br.updateSearchHilites();
388
- }.bind(this));
261
+ .on("mouseenter", (event) => {
262
+ // remove from other markers then turn on just for this
263
+ // XXX should be done when nav slider moves
264
+ const marker = event.currentTarget;
265
+ const tooltip = marker.querySelector('.BRquery');
266
+ const tooltipOffset = tooltip.getBoundingClientRect();
267
+ const targetOffset = marker.getBoundingClientRect();
268
+ const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;
269
+ if (tooltipOffset.x - boxSizeAdjust < 0) {
270
+ tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);
271
+ }
272
+ $('.BRsearch,.BRchapter').removeClass('front');
273
+ $(event.target).addClass('front');
274
+ })
275
+ .on("mouseleave", (event) => $(event.target).removeClass('front'))
276
+ .on("click", () => { this.br.plugins.search.jumpToMatch(match.matchIndex); });
389
277
  });
390
278
  }
391
279
 
392
280
  /**
393
- * @param {boolean} bool
281
+ * @param {boolean} show
394
282
  */
395
- toggleSearchPending(bool) {
396
- this.dom.searchPending.classList.toggle('visible', bool);
397
- if (bool) {
398
- this.br.showProgressPopup("Search results will appear below...");
283
+ toggleSearchPending(show = false) {
284
+ if (show) {
285
+ this.br.showProgressPopup("Search results will appear below...", () => this.progressPopupClosed());
399
286
  }
400
287
  else {
401
288
  this.br.removeProgressPopup();
402
289
  }
403
290
  }
404
291
 
405
- renderErrorModal() {
292
+ /**
293
+ * Primary callback when user cancels search popup
294
+ */
295
+ progressPopupClosed() {
296
+ this.toggleSearchPending();
297
+ this.cancelSearch();
298
+ }
299
+
300
+ renderErrorModal(textIsProcessing = false) {
301
+ const errorDetails = `${!textIsProcessing ? 'The text may still be processing. ' : ''}Please try again.`;
406
302
  this.renderModalMessage(`
407
303
  Sorry, there was an error with your search.
408
304
  <br />
409
- The text may still be processing.
305
+ ${errorDetails}
410
306
  `);
411
307
  this.delayModalRemovalFor(4000);
412
308
  }
@@ -445,14 +341,6 @@ class SearchView {
445
341
  setTimeout(this.br.removeProgressPopup.bind(this.br), timeoutMS);
446
342
  }
447
343
 
448
- openMobileMenu() {
449
- this.br.refs.$mmenu.data('mmenu').open();
450
- }
451
-
452
- closeMobileMenu() {
453
- this.br.refs.$mmenu.data('mmenu').close();
454
- }
455
-
456
344
  /**
457
345
  * @param {Event} e
458
346
  */
@@ -461,7 +349,6 @@ class SearchView {
461
349
  const query = e.target.querySelector('[name="query"]').value;
462
350
  if (!query.length) { return false; }
463
351
  this.br.search(query);
464
- this.dom.searchField.blur();
465
352
  this.emptyMatches();
466
353
  this.toggleSearchPending(true);
467
354
  return false;
@@ -479,9 +366,7 @@ class SearchView {
479
366
  this.teardownSearchNavigation();
480
367
  this.renderSearchNavigation();
481
368
  this.bindSearchNavigationEvents();
482
- this.renderMatches(results.matches);
483
369
  this.renderPins(results.matches);
484
- this.updateResultsCount(results.matches.length);
485
370
  this.toggleSearchPending(false);
486
371
  if (options.goToFirstResult) {
487
372
  $(document).one('BookReader:pageChanged', () => {
@@ -492,27 +377,23 @@ class SearchView {
492
377
  }
493
378
  }
494
379
 
495
- /**
496
- * @param {Event} e
497
- */
498
- handleNavToggledCallback(e) {
499
- const is_visible = this.br.navigationIsVisible();
500
- this.togglePinsFor(is_visible);
501
- this.toggleSearchTray(is_visible ? !!this.dom.results.querySelector('li') : false);
502
- }
503
-
504
380
  handleSearchStarted() {
505
381
  this.emptyMatches();
506
- this.br.removeSearchHilites();
382
+ this.br.plugins.search.removeSearchHilites();
507
383
  this.removeResultPins();
508
384
  this.toggleSearchPending(true);
509
385
  this.teardownSearchNavigation();
510
- this.setQuery(this.br.searchTerm);
386
+ this.setQuery(this.br.plugins.search.searchTerm);
511
387
  }
512
388
 
513
- handleSearchCallbackError() {
389
+ /**
390
+ * Event listener for: `BookReader:SearchCallbackError`
391
+ * @param {CustomEvent} event
392
+ */
393
+ handleSearchCallbackError(event = {}) {
514
394
  this.toggleSearchPending(false);
515
- this.renderErrorModal();
395
+ const isIndexed = event?.detail?.props?.results?.indexed;
396
+ this.renderErrorModal(isIndexed);
516
397
  }
517
398
 
518
399
  handleSearchCallbackBookNotIndexed() {
@@ -528,26 +409,14 @@ class SearchView {
528
409
  bindEvents() {
529
410
  const namespace = 'BookReader:';
530
411
 
412
+ window.addEventListener(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this));
531
413
  $(document).on(`${namespace}SearchCallback`, this.handleSearchCallback.bind(this))
532
- .on(`${namespace}navToggled`, this.handleNavToggledCallback.bind(this))
533
414
  .on(`${namespace}SearchStarted`, this.handleSearchStarted.bind(this))
534
- .on(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this))
535
415
  .on(`${namespace}SearchCallbackBookNotIndexed`, this.handleSearchCallbackBookNotIndexed.bind(this))
536
416
  .on(`${namespace}SearchCallbackEmpty`, this.handleSearchCallbackEmpty.bind(this))
537
417
  .on(`${namespace}pageChanged`, this.updateSearchNavigation.bind(this));
538
418
 
539
- this.dom.searchTray.addEventListener('submit', this.submitHandler.bind(this));
540
419
  this.dom.toolbarSearch.querySelector('form').addEventListener('submit', this.submitHandler.bind(this));
541
- this.dom.searchField.addEventListener('search', () => {
542
- if (this.dom.searchField.value) { return; }
543
- this.clearSearchFieldAndResults();
544
- });
545
-
546
- $(this.dom.results).on('click', 'li', (e) => {
547
- this.br._searchPluginGoToResult(+e.currentTarget.dataset.pageIndex);
548
- this.br.updateSearchHilites();
549
- this.closeMobileMenu();
550
- });
551
420
  }
552
421
  }
553
422
 
@@ -0,0 +1,164 @@
1
+ // @ts-check
2
+ import { Cache } from '../../util/cache.js';
3
+ import { BatchTranslator } from '@internetarchive/bergamot-translator/translator.js';
4
+ import { toISO6391, toNativeName } from '../tts/utils.js';
5
+
6
+ export class TranslationManager {
7
+ /** @type {Cache<{index: string, response: string}>} */
8
+ alreadyTranslated = new Cache(100);
9
+
10
+ /**
11
+ * @typedef {Object} genericModelInfo
12
+ * @property {string} name
13
+ * @property {number} size
14
+ * @property {number} estimatedCompressedSize
15
+ * @property {any} [qualityModel]
16
+ * @property {string} [expectedSha256Hash]
17
+ * @property {string} [modelType]
18
+ */
19
+ /**
20
+ * @type { {[langPair: string] : {model: genericModelInfo, lex: genericModelInfo, vocab: genericModelInfo, quality?: genericModelInfo}} }
21
+ */
22
+ modelRegistry = {};
23
+
24
+ /** @type {Record<key, {promise: Promise<string>, resolve: function, reject: function}>} */
25
+ currentlyTranslating = {}
26
+
27
+ /** @type {Record<string, string>[]} */
28
+ fromLanguages = [];
29
+ /** @type {Record<string, string>[]} */
30
+ toLanguages = [];
31
+
32
+ /** @type {boolean} */
33
+ active = false;
34
+
35
+ publicPath = '';
36
+
37
+ constructor() {
38
+ //TODO Should default to the book language as the first element
39
+ const enModel = {code: "en", name: "English (en)", type: "prod"};
40
+ this.fromLanguages.push(enModel);
41
+ this.toLanguages.push(enModel);
42
+ }
43
+
44
+
45
+ async initWorker() {
46
+ if (this.initPromise) return this.initPromise;
47
+ this.initPromise = new Promise((resolve, reject) => {
48
+ this._initResolve = resolve;
49
+ this._initReject = reject;
50
+ });
51
+ const registryUrl = "https://cors.archive.org/cors/mozilla-translate-models/firefox_models/";
52
+ const registryJson = await fetch(registryUrl + "registry.json").then(r => r.json());
53
+ for (const language of Object.values(registryJson)) {
54
+ for (const file of Object.values(language)) {
55
+ file.name = registryUrl + file.name;
56
+ }
57
+ }
58
+
59
+ /** @type {BatchTranslator} */
60
+ // Arbitrary setting for number of workers, 1 is already quite fast
61
+ // batchSize from 8 -> 4 for improved performance
62
+ this.translator = new BatchTranslator({
63
+ registryUrl: `data:application/json,${encodeURIComponent(JSON.stringify(registryJson))}`,
64
+ workers: 2,
65
+ batchSize: 4,
66
+ workerUrl: this.publicPath + '/translator-worker.js',
67
+ });
68
+
69
+ const modelType = await this.translator.backing.registry;
70
+ const arr = {}; // unsure if we need to keep track of the files
71
+ for (const obj of Object.values(modelType)) {
72
+ const firstLang = obj['from'];
73
+ const secondLang = obj['to'];
74
+ const fromModelType = obj['files'];
75
+ arr[`${firstLang}${secondLang}`] = fromModelType;
76
+ // Assuming that all of the languages loaded from the registryUrl inside @internetarchive/bergamot-translator/translator.js are prod
77
+ // List of dev models found here https://github.com/mozilla/firefox-translations-models/tree/main/models/base
78
+ // There are also differences between the model types in the repo above here: https://github.com/mozilla/firefox-translations-models?tab=readme-ov-file#firefox-translations-models
79
+ if (firstLang !== "en") {
80
+ const name = `${toNativeName(firstLang)} (${toISO6391(firstLang)})`;
81
+ this.fromLanguages.push({code: firstLang, name: name, type: "prod"});
82
+ }
83
+ if (secondLang !== "en") {
84
+ const name = `${toNativeName(secondLang)} (${toISO6391(secondLang)})`;
85
+ this.toLanguages.push({code: secondLang, name: name, type: "prod"});
86
+ }
87
+ }
88
+ this._initResolve([this.modelRegistry]);
89
+ return this.initPromise;
90
+ }
91
+
92
+ /**
93
+ * Targets the page and paragraph of a text layer to create a translation from the "fromLang" to the "toLang". Tries to force order in translation by using the pageIndex (+1000 if the current page is not visible) and paragraphIndex
94
+ * @param {string} fromLang
95
+ * @param {string} toLang
96
+ * @param {string} pageIndex
97
+ * @param {number} paragraphIndex
98
+ * @param {string} text
99
+ * @param {number} priority
100
+ * @return {Promise<string>} translated text
101
+ */
102
+
103
+ getTranslation = async (fromLang, toLang, pageIndex, paragraphIndex, text, priority) => {
104
+ this.active = true;
105
+ if (fromLang == toLang || !fromLang || !toLang) {
106
+ return;
107
+ }
108
+ const key = `${fromLang}${toLang}-${pageIndex}:${paragraphIndex}`;
109
+ const cachedEntry = this.alreadyTranslated.entries.find(x => x.index == key);
110
+
111
+ if (cachedEntry) {
112
+ return cachedEntry.response;
113
+ }
114
+
115
+ if (key in this.currentlyTranslating) {
116
+ return this.currentlyTranslating[key].promise;
117
+ }
118
+
119
+ let _resolve = null;
120
+ let _reject = null;
121
+ const promise = new Promise((res, rej) => {
122
+ _resolve = res;
123
+ _reject = rej;
124
+ });
125
+
126
+ this.currentlyTranslating[key] = {
127
+ promise,
128
+ resolve: _resolve,
129
+ reject: _reject,
130
+ };
131
+
132
+ if (!text) {
133
+ this.currentlyTranslating[key].reject("No text was provided");
134
+ return promise;
135
+ }
136
+ this.translator.translate({
137
+ to: toLang,
138
+ from: fromLang,
139
+ text: text,
140
+ html: false,
141
+ priority: priority,
142
+ }).then((resp) => {
143
+ const response = resp;
144
+ this.currentlyTranslating[key].resolve(response.target.text);
145
+ this.alreadyTranslated.add({index: key, response: response.target.text});
146
+ delete this.currentlyTranslating[key];
147
+ });
148
+
149
+ return promise;
150
+ }
151
+
152
+ /**
153
+ * Checks and updates the status of a model that is currently being retreived from IA
154
+ * @param {string} fromLanguage
155
+ * @param {string} toLanguage
156
+ * @returns {Promise<boolean>}
157
+ */
158
+ getTranslationModel = async(fromLanguage, toLanguage) => {
159
+ return this.translator.backing.getTranslationModel({from: fromLanguage, to: toLanguage})
160
+ .catch((err) => {
161
+ console.error(`An error occurred while trying to retreive the ${fromLanguage}-${toLanguage} model`);
162
+ });
163
+ }
164
+ }