@internetarchive/bookreader 5.0.0-10-alpha-3 → 5.0.0-100

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 (374) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +428 -1139
  4. package/BookReader/BookReader.js +1 -1
  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 +1782 -0
  53. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +7 -0
  54. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  55. package/BookReader/icons/1up.svg +1 -1
  56. package/BookReader/icons/2up.svg +1 -1
  57. package/BookReader/icons/advance.svg +1 -1
  58. package/BookReader/icons/chevron-right.svg +1 -1
  59. package/BookReader/icons/close-circle-dark.svg +1 -1
  60. package/BookReader/icons/close-circle.svg +1 -1
  61. package/BookReader/icons/fullscreen.svg +1 -1
  62. package/BookReader/icons/fullscreen_exit.svg +1 -1
  63. package/BookReader/icons/hamburger.svg +1 -1
  64. package/BookReader/icons/left-arrow.svg +1 -1
  65. package/BookReader/icons/magnify-minus.svg +1 -1
  66. package/BookReader/icons/magnify-plus.svg +1 -1
  67. package/BookReader/icons/magnify.svg +1 -1
  68. package/BookReader/icons/pause.svg +1 -1
  69. package/BookReader/icons/play.svg +1 -1
  70. package/BookReader/icons/playback-speed.svg +1 -1
  71. package/BookReader/icons/read-aloud.svg +1 -1
  72. package/BookReader/icons/review.svg +1 -1
  73. package/BookReader/icons/thumbnails.svg +1 -1
  74. package/BookReader/icons/voice.svg +1 -0
  75. package/BookReader/icons/volume-full.svg +1 -1
  76. package/BookReader/images/BRicons.svg +3 -3
  77. package/BookReader/images/books_graphic.svg +1 -1
  78. package/BookReader/images/hypothesis.ico +0 -0
  79. package/BookReader/images/icon_book.svg +1 -1
  80. package/BookReader/images/icon_bookmark.svg +1 -1
  81. package/BookReader/images/icon_experiment.svg +1 -0
  82. package/BookReader/images/icon_gear.svg +1 -1
  83. package/BookReader/images/icon_hamburger.svg +1 -1
  84. package/BookReader/images/icon_home.svg +1 -1
  85. package/BookReader/images/icon_info.svg +1 -1
  86. package/BookReader/images/icon_one_page.svg +1 -1
  87. package/BookReader/images/icon_pause.svg +1 -1
  88. package/BookReader/images/icon_play.svg +1 -1
  89. package/BookReader/images/icon_playback-rate.svg +1 -1
  90. package/BookReader/images/icon_search_button.svg +1 -1
  91. package/BookReader/images/icon_share.svg +1 -1
  92. package/BookReader/images/icon_skip-ahead.svg +1 -1
  93. package/BookReader/images/icon_skip-back.svg +1 -1
  94. package/BookReader/images/icon_speaker.svg +1 -1
  95. package/BookReader/images/icon_speaker_open.svg +1 -1
  96. package/BookReader/images/icon_thumbnails.svg +1 -1
  97. package/BookReader/images/icon_toc.svg +1 -1
  98. package/BookReader/images/icon_two_pages.svg +1 -1
  99. package/BookReader/images/marker_chap-off.svg +1 -1
  100. package/BookReader/images/marker_chap-on.svg +1 -1
  101. package/BookReader/images/marker_srch-on.svg +1 -1
  102. package/BookReader/images/translate.svg +1 -0
  103. package/BookReader/images/unviewable_page.png +0 -0
  104. package/BookReader/jquery-3.js +2 -0
  105. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  106. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  107. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  108. package/BookReader/plugins/plugin.autoplay.js +1 -1
  109. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  110. package/BookReader/plugins/plugin.chapters.js +25 -1
  111. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  112. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  113. package/BookReader/plugins/plugin.experiments.js +3 -0
  114. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  115. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  116. package/BookReader/plugins/plugin.iframe.js +1 -1
  117. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  118. package/BookReader/plugins/plugin.iiif.js +2 -0
  119. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  120. package/BookReader/plugins/plugin.resume.js +1 -1
  121. package/BookReader/plugins/plugin.resume.js.map +1 -1
  122. package/BookReader/plugins/plugin.search.js +2 -1
  123. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  124. package/BookReader/plugins/plugin.search.js.map +1 -1
  125. package/BookReader/plugins/plugin.text_selection.js +2 -1
  126. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  127. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  128. package/BookReader/plugins/plugin.translate.js +137 -0
  129. package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
  130. package/BookReader/plugins/plugin.translate.js.map +1 -0
  131. package/BookReader/plugins/plugin.tts.js +1 -1
  132. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  133. package/BookReader/plugins/plugin.tts.js.map +1 -1
  134. package/BookReader/plugins/plugin.url.js +1 -1
  135. package/BookReader/plugins/plugin.url.js.map +1 -1
  136. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  137. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  138. package/BookReader/plugins/translator-worker.js +2 -0
  139. package/BookReader/plugins/translator-worker.js.map +1 -0
  140. package/BookReader/silence.mp3 +0 -0
  141. package/BookReader/translator-worker.js +475 -0
  142. package/BookReader/webcomponents-bundle.js +3 -0
  143. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  144. package/BookReader/webcomponents-bundle.js.map +1 -0
  145. package/README.md +14 -3
  146. package/jsconfig.json +19 -0
  147. package/package.json +84 -64
  148. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  149. package/src/BookNavigator/assets/button-base.js +2 -1
  150. package/src/BookNavigator/assets/ia-logo.js +17 -0
  151. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  152. package/src/BookNavigator/assets/icon_close.js +1 -1
  153. package/src/BookNavigator/book-navigator.js +620 -0
  154. package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
  155. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -3
  156. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  157. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +2 -2
  158. package/src/BookNavigator/bookmarks/bookmarks-provider.js +27 -17
  159. package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
  160. package/src/BookNavigator/delete-modal-actions.js +1 -1
  161. package/src/BookNavigator/downloads/downloads-provider.js +36 -21
  162. package/src/BookNavigator/downloads/downloads.js +24 -4
  163. package/src/BookNavigator/search/search-provider.js +55 -27
  164. package/src/BookNavigator/search/search-results.js +25 -11
  165. package/src/BookNavigator/sharing.js +27 -0
  166. package/src/BookNavigator/viewable-files.js +95 -0
  167. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +13 -12
  168. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +9 -9
  169. package/src/BookReader/BookModel.js +92 -46
  170. package/src/BookReader/DragScrollable.js +233 -0
  171. package/src/BookReader/ImageCache.js +49 -16
  172. package/src/BookReader/Mode1Up.js +58 -360
  173. package/src/BookReader/Mode1UpLit.js +393 -0
  174. package/src/BookReader/Mode2Up.js +75 -1318
  175. package/src/BookReader/Mode2UpLit.js +787 -0
  176. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  177. package/src/BookReader/ModeSmoothZoom.js +312 -0
  178. package/src/BookReader/ModeThumb.js +20 -12
  179. package/src/BookReader/Navbar/Navbar.js +130 -53
  180. package/src/BookReader/PageContainer.js +120 -23
  181. package/src/BookReader/ReduceSet.js +2 -2
  182. package/src/BookReader/Toolbar/Toolbar.js +18 -40
  183. package/src/BookReader/events.js +2 -3
  184. package/src/BookReader/options.js +87 -16
  185. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  186. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  187. package/src/BookReader/utils/SelectionObserver.js +45 -0
  188. package/src/BookReader/utils/classes.js +1 -1
  189. package/src/BookReader/utils.js +136 -12
  190. package/src/BookReader.js +641 -1192
  191. package/src/BookReaderPlugin.js +52 -0
  192. package/src/assets/icons/magnify-minus.svg +3 -7
  193. package/src/assets/icons/magnify-plus.svg +3 -7
  194. package/src/assets/icons/voice.svg +1 -0
  195. package/src/assets/images/hypothesis.ico +0 -0
  196. package/src/assets/images/icon_experiment.svg +1 -0
  197. package/src/assets/images/translate.svg +1 -0
  198. package/src/assets/images/unviewable_page.png +0 -0
  199. package/src/assets/silence.mp3 +0 -0
  200. package/src/css/BookReader.scss +1 -5
  201. package/src/css/_BRBookmarks.scss +1 -1
  202. package/src/css/_BRComponent.scss +1 -1
  203. package/src/css/_BRicon.scss +8 -2
  204. package/src/css/_BRmain.scss +16 -3
  205. package/src/css/_BRnav.scss +12 -66
  206. package/src/css/_BRpages.scss +163 -43
  207. package/src/css/_BRsearch.scss +69 -30
  208. package/src/css/_BRtoolbar.scss +5 -5
  209. package/src/css/_TextSelection.scss +129 -24
  210. package/src/css/_colorbox.scss +2 -2
  211. package/src/css/_controls.scss +24 -7
  212. package/src/css/_icons.scss +1 -1
  213. package/src/ia-bookreader/ia-bookreader.js +224 -0
  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 +314 -205
  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 +54 -51
  221. package/src/plugins/plugin.text_selection.js +510 -219
  222. package/src/plugins/plugin.vendor-fullscreen.js +5 -5
  223. package/src/plugins/search/plugin.search.js +370 -392
  224. package/src/plugins/search/utils.js +43 -0
  225. package/src/plugins/search/view.js +49 -67
  226. package/src/plugins/translate/TranslationManager.js +162 -0
  227. package/src/plugins/translate/plugin.translate.js +523 -0
  228. package/src/plugins/tts/AbstractTTSEngine.js +78 -49
  229. package/src/plugins/tts/FestivalTTSEngine.js +20 -30
  230. package/src/plugins/tts/PageChunk.js +33 -21
  231. package/src/plugins/tts/PageChunkIterator.js +11 -17
  232. package/src/plugins/tts/WebTTSEngine.js +131 -91
  233. package/src/plugins/tts/plugin.tts.js +344 -350
  234. package/src/plugins/tts/utils.js +49 -47
  235. package/src/plugins/url/UrlPlugin.js +191 -0
  236. package/src/plugins/{plugin.url.js → url/plugin.url.js} +44 -15
  237. package/src/util/TextSelectionManager.js +282 -0
  238. package/src/util/browserSniffing.js +33 -1
  239. package/src/util/cache.js +20 -0
  240. package/src/util/docCookies.js +21 -2
  241. package/src/util/strings.js +1 -0
  242. package/.babelrc +0 -12
  243. package/.dependabot/config.yml +0 -6
  244. package/.eslintrc.js +0 -50
  245. package/.gitattributes +0 -2
  246. package/.github/ISSUE_TEMPLATE/bug.md +0 -32
  247. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
  248. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
  249. package/.github/workflows/node.js.yml +0 -37
  250. package/.github/workflows/npm-publish.yml +0 -47
  251. package/.testcaferc.json +0 -5
  252. package/BookReader/bookreader-component-bundle.js +0 -1450
  253. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  254. package/BookReader/bookreader-component-bundle.js.map +0 -1
  255. package/BookReader/jquery-1.10.1.js +0 -2
  256. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  257. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  258. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  259. package/BookReader/plugins/plugin.mobile_nav.js +0 -2
  260. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  261. package/BookReaderDemo/BookReaderDemo.css +0 -41
  262. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
  263. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  264. package/BookReaderDemo/BookReaderJSSimple.js +0 -55
  265. package/BookReaderDemo/IIIFBookReader.js +0 -207
  266. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
  267. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
  268. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  269. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  270. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  271. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
  272. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
  273. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  274. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  275. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  276. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  277. package/BookReaderDemo/demo-advanced.html +0 -33
  278. package/BookReaderDemo/demo-autoplay.html +0 -38
  279. package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
  280. package/BookReaderDemo/demo-embed.html +0 -26
  281. package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
  282. package/BookReaderDemo/demo-fullscreen.html +0 -33
  283. package/BookReaderDemo/demo-iiif.html +0 -34
  284. package/BookReaderDemo/demo-iiif.js +0 -26
  285. package/BookReaderDemo/demo-internetarchive.html +0 -74
  286. package/BookReaderDemo/demo-multiple.html +0 -43
  287. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  288. package/BookReaderDemo/demo-preview-pages.html +0 -1092
  289. package/BookReaderDemo/demo-simple.html +0 -34
  290. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
  291. package/BookReaderDemo/immersion-1up.html +0 -64
  292. package/BookReaderDemo/immersion-mode.html +0 -35
  293. package/BookReaderDemo/toggle_controls.html +0 -53
  294. package/BookReaderDemo/view_mode.html +0 -39
  295. package/BookReaderDemo/viewmode-cycle.html +0 -41
  296. package/CHANGELOG.md +0 -493
  297. package/CONTRIBUTING.md +0 -7
  298. package/codecov.yml +0 -17
  299. package/index.html +0 -31
  300. package/karma.conf.js +0 -23
  301. package/screenshot.png +0 -0
  302. package/scripts/postversion.js +0 -10
  303. package/scripts/preversion.js +0 -14
  304. package/scripts/version.js +0 -26
  305. package/src/BookNavigator/BookModel.js +0 -14
  306. package/src/BookNavigator/BookNavigator.js +0 -446
  307. package/src/BookNavigator/assets/book-loader.js +0 -27
  308. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  309. package/src/BookNavigator/search/a-search-result.js +0 -55
  310. package/src/BookReader/DebugConsole.js +0 -54
  311. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  312. package/src/ItemNavigator/ItemNavigator.js +0 -376
  313. package/src/ItemNavigator/providers/sharing.js +0 -29
  314. package/src/css/_MobileNav.scss +0 -194
  315. package/src/dragscrollable-br.js +0 -261
  316. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  317. package/src/plugins/plugin.mobile_nav.js +0 -287
  318. package/tests/BookReader/BookModel.test.js +0 -312
  319. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  320. package/tests/BookReader/DebugConsole.test.js +0 -25
  321. package/tests/BookReader/ImageCache.test.js +0 -150
  322. package/tests/BookReader/Mode1Up.test.js +0 -164
  323. package/tests/BookReader/Mode2Up.test.js +0 -247
  324. package/tests/BookReader/Navbar/Navbar.test.js +0 -169
  325. package/tests/BookReader/PageContainer.test.js +0 -115
  326. package/tests/BookReader/ReduceSet.test.js +0 -38
  327. package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
  328. package/tests/BookReader/utils/classes.test.js +0 -88
  329. package/tests/BookReader/utils.test.js +0 -109
  330. package/tests/BookReader.options.test.js +0 -39
  331. package/tests/BookReader.test.js +0 -301
  332. package/tests/e2e/README.md +0 -75
  333. package/tests/e2e/autoplay.test.js +0 -13
  334. package/tests/e2e/base.test.js +0 -35
  335. package/tests/e2e/helpers/base.js +0 -263
  336. package/tests/e2e/helpers/debug.js +0 -13
  337. package/tests/e2e/helpers/desktopSearch.js +0 -72
  338. package/tests/e2e/helpers/mobileSearch.js +0 -85
  339. package/tests/e2e/helpers/mockSearch.js +0 -93
  340. package/tests/e2e/helpers/rightToLeft.js +0 -29
  341. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  342. package/tests/e2e/models/BookReader.js +0 -11
  343. package/tests/e2e/models/Navigation.js +0 -56
  344. package/tests/e2e/rightToLeft.test.js +0 -20
  345. package/tests/e2e/viewmode.test.js +0 -37
  346. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  347. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
  348. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
  349. package/tests/karma/BookNavigator/search/search-provider.test.js +0 -23
  350. package/tests/karma/BookNavigator/search/search-results.test.js +0 -240
  351. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  352. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  353. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  354. package/tests/plugins/plugin.autoplay.test.js +0 -52
  355. package/tests/plugins/plugin.chapters.test.js +0 -130
  356. package/tests/plugins/plugin.iframe.test.js +0 -42
  357. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  358. package/tests/plugins/plugin.resume.test.js +0 -98
  359. package/tests/plugins/plugin.text_selection.test.js +0 -203
  360. package/tests/plugins/plugin.url.test.js +0 -129
  361. package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
  362. package/tests/plugins/search/plugin.search.test.js +0 -173
  363. package/tests/plugins/search/plugin.search.view.test.js +0 -106
  364. package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
  365. package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
  366. package/tests/plugins/tts/PageChunk.test.js +0 -57
  367. package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
  368. package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
  369. package/tests/plugins/tts/utils.test.js +0 -133
  370. package/tests/util/browserSniffing.test.js +0 -56
  371. package/tests/util/docCookies.test.js +0 -15
  372. package/tests/util/strings.test.js +0 -63
  373. package/tests/utils.js +0 -42
  374. package/webpack.config.js +0 -86
@@ -1,12 +1,12 @@
1
1
  import PageChunkIterator from './PageChunkIterator.js';
2
+ import { hasLocalStorage } from './utils.js';
2
3
  /** @typedef {import('./utils.js').ISO6391} ISO6391 */
3
4
  /** @typedef {import('./PageChunk.js')} PageChunk */
4
5
 
5
6
  /**
6
7
  * @export
7
8
  * @typedef {Object} TTSEngineOptions
8
- * @property {String} server
9
- * @property {String} bookPath
9
+ * @property {import('@/src/util/strings.js').StringWithVars} pageChunkUrl
10
10
  * @property {ISO6391} bookLanguage
11
11
  * @property {Function} onLoadingStart
12
12
  * @property {Function} onLoadingComplete
@@ -28,6 +28,7 @@ import PageChunkIterator from './PageChunkIterator.js';
28
28
  * @property {() => void} resume
29
29
  * @property {() => void} finish force the sound to 'finish'
30
30
  * @property {number => void} setPlaybackRate
31
+ * @property {SpeechSynthesisVoice => void} setVoice
31
32
  **/
32
33
 
33
34
  /** Handling bookreader's text-to-speech */
@@ -39,6 +40,7 @@ export default class AbstractTTSEngine {
39
40
  constructor(options) {
40
41
  this.playing = false;
41
42
  this.paused = false;
43
+ /** @type {TTSEngineOptions} */
42
44
  this.opts = options;
43
45
  /** @type {PageChunkIterator} */
44
46
  this._chunkIterator = null;
@@ -50,9 +52,7 @@ export default class AbstractTTSEngine {
50
52
  /** @type {SpeechSynthesisVoice} */
51
53
  this.voice = null;
52
54
  // Listen for voice changes (fired by subclasses)
53
- this.events.on('voiceschanged', () => {
54
- this.voice = AbstractTTSEngine.getBestBookVoice(this.getVoices(), this.opts.bookLanguage);
55
- });
55
+ this.events.on('voiceschanged', this.updateBestVoice);
56
56
  this.events.trigger('voiceschanged');
57
57
  }
58
58
 
@@ -71,20 +71,23 @@ export default class AbstractTTSEngine {
71
71
  /** @abstract */
72
72
  init() { return null; }
73
73
 
74
+ updateBestVoice = () => {
75
+ this.voice = AbstractTTSEngine.getBestBookVoice(this.getVoices(), this.opts.bookLanguage);
76
+ }
77
+
74
78
  /**
75
79
  * @param {number} leafIndex
76
80
  * @param {number} numLeafs total number of leafs in the current book
77
81
  */
78
82
  start(leafIndex, numLeafs) {
79
83
  this.playing = true;
84
+ this.paused = false;
80
85
  this.opts.onLoadingStart();
81
86
 
82
87
  this._chunkIterator = new PageChunkIterator(numLeafs, leafIndex, {
83
- server: this.opts.server,
84
- bookPath: this.opts.bookPath,
85
- pageBufferSize: 5,
88
+ pageChunkUrl: this.opts.pageChunkUrl,
89
+ pageBufferSize: 3,
86
90
  });
87
-
88
91
  this.step();
89
92
  this.events.trigger('start');
90
93
  }
@@ -92,6 +95,7 @@ export default class AbstractTTSEngine {
92
95
  stop() {
93
96
  if (this.activeSound) this.activeSound.stop();
94
97
  this.playing = false;
98
+ this.paused = true;
95
99
  this._chunkIterator = null;
96
100
  this.activeSound = null;
97
101
  this.events.trigger('stop');
@@ -124,13 +128,26 @@ export default class AbstractTTSEngine {
124
128
  }
125
129
 
126
130
  /** @public */
127
- jumpBackward() {
128
- Promise.all([
131
+ async jumpBackward() {
132
+ await Promise.all([
129
133
  this.activeSound.stop(),
130
134
  this._chunkIterator.decrement()
131
- .then(() => this._chunkIterator.decrement())
132
- ])
133
- .then(() => this.step());
135
+ .then(() => this._chunkIterator.decrement()),
136
+ ]);
137
+ this.step();
138
+ }
139
+
140
+ /** @param {string} voiceURI */
141
+ setVoice(voiceURI) {
142
+ // if the user actively selects a voice, don't re-choose best voice anymore
143
+ // MS Edge fires voices changed randomly very often
144
+ this.events.off('voiceschanged', this.updateBestVoice);
145
+ this.voice = this.getVoices().find(voice => voice.voiceURI === voiceURI);
146
+ // if the current book has a language set, store the selected voice with the book language as a suffix
147
+ if (this.opts.bookLanguage && hasLocalStorage()) {
148
+ localStorage.setItem(`BRtts-voice-${this.opts.bookLanguage}`, this.voice.voiceURI);
149
+ }
150
+ if (this.activeSound) this.activeSound.setVoice(this.voice);
134
151
  }
135
152
 
136
153
  /** @param {number} newRate */
@@ -140,36 +157,33 @@ export default class AbstractTTSEngine {
140
157
  }
141
158
 
142
159
  /** @private */
143
- step() {
144
- this._chunkIterator.next()
145
- .then(chunk => {
146
- if (chunk == PageChunkIterator.AT_END) {
147
- this.stop();
148
- this.opts.onDone();
149
- return;
150
- }
151
-
152
- this.opts.onLoadingStart();
153
- const sound = this.createSound(chunk);
154
- sound.chunk = chunk;
155
- sound.rate = this.playbackRate;
156
- sound.voice = this.voice;
157
- sound.load(() => this.opts.onLoadingComplete());
158
-
159
- this.opts.onLoadingComplete();
160
- return this.opts.beforeChunkPlay(chunk).then(() => sound);
161
- })
162
- .then(sound => {
163
- if (!this.playing) return;
164
-
165
- const playPromise = this.playSound(sound)
166
- .then(() => this.opts.afterChunkPlay(sound.chunk));
167
- if (this.paused) this.pause();
168
- return playPromise;
169
- })
170
- .then(() => {
171
- if (this.playing) return this.step();
172
- });
160
+ async step() {
161
+ const chunk = await this._chunkIterator.next();
162
+ if (chunk == PageChunkIterator.AT_END) {
163
+ this.stop();
164
+ this.opts.onDone();
165
+ return;
166
+ }
167
+ this.opts.onLoadingStart();
168
+ const sound = this.createSound(chunk);
169
+ sound.chunk = chunk;
170
+ sound.rate = this.playbackRate;
171
+ sound.voice = this.voice;
172
+ sound.load(() => this.opts.onLoadingComplete());
173
+
174
+ this.opts.onLoadingComplete();
175
+
176
+ await this.opts.beforeChunkPlay(chunk);
177
+
178
+ if (!this.playing) return;
179
+
180
+ const playPromise = await this.playSound(sound)
181
+ .then(()=> this.opts.afterChunkPlay(sound.chunk));
182
+
183
+ if (this.paused) this.pause();
184
+ await playPromise;
185
+
186
+ if (this.playing) return this.step();
173
187
  }
174
188
 
175
189
  /**
@@ -190,8 +204,8 @@ export default class AbstractTTSEngine {
190
204
  }
191
205
 
192
206
  /** Convenience wrapper for {@see AbstractTTSEngine.getBestVoice} */
193
- getBestVoice() {
194
- return AbstractTTSEngine.getBestBookVoice(this.getVoices(), this.opts.bookLanguage);
207
+ getBestVoice(languageOverride) {
208
+ return AbstractTTSEngine.getBestBookVoice(this.getVoices(), languageOverride || this.opts.bookLanguage);
195
209
  }
196
210
 
197
211
  /**
@@ -212,10 +226,12 @@ export default class AbstractTTSEngine {
212
226
  // user languages that match the book language
213
227
  const matchingUserLangs = userLanguages.filter(lang => lang.startsWith(bookLanguage));
214
228
 
215
- // Try to find voices that intersect these two sets
216
- return AbstractTTSEngine.getMatchingVoice(matchingUserLangs, bookLangVoices) ||
229
+ // First try to find the last chosen voice from localStorage for the current book language
230
+ return AbstractTTSEngine.getMatchingStoredVoice(bookLangVoices, bookLanguage)
231
+ // Try to find voices that intersect these two sets
232
+ || AbstractTTSEngine.getMatchingVoice(matchingUserLangs, bookLangVoices)
217
233
  // no user languages match the books; let's return the best voice for the book language
218
- (bookLangVoices.find(v => v.default) || bookLangVoices[0])
234
+ || (bookLangVoices.find(v => v.default) || bookLangVoices[0])
219
235
  // No voices match the book language? let's find a voice in the user's language
220
236
  // and ignore book lang
221
237
  || AbstractTTSEngine.getMatchingVoice(userLanguages, voices)
@@ -223,6 +239,19 @@ export default class AbstractTTSEngine {
223
239
  || (voices.find(v => v.default) || voices[0]);
224
240
  }
225
241
 
242
+ /**
243
+ * @private
244
+ * Get the voice last selected by the user for the book language from localStorage.
245
+ * Returns undefined if no voice is stored or found.
246
+ * @param {SpeechSynthesisVoice[]} voices browser voices to choose from
247
+ * @param {ISO6391} bookLanguage book language to look for
248
+ * @return {SpeechSynthesisVoice | undefined}
249
+ */
250
+ static getMatchingStoredVoice(voices, bookLanguage) {
251
+ const storedVoice = hasLocalStorage() && localStorage.getItem(`BRtts-voice-${bookLanguage}`);
252
+ return (storedVoice ? voices.find(v => v.voiceURI === storedVoice) : undefined);
253
+ }
254
+
226
255
  /**
227
256
  * @private
228
257
  * Get the best voice that matches one of the BCP47 languages (order by preference)
@@ -1,5 +1,6 @@
1
1
  import AbstractTTSEngine from './AbstractTTSEngine.js';
2
- import { sleep } from './utils.js';
2
+ import { sleep } from '../../BookReader/utils.js';
3
+ import { applyVariables } from '../../util/strings.js';
3
4
  /* global soundManager */
4
5
  import 'soundmanager2';
5
6
  import 'jquery.browser';
@@ -17,19 +18,21 @@ export default class FestivalTTSEngine extends AbstractTTSEngine {
17
18
  return typeof(soundManager) !== 'undefined' && soundManager.supported();
18
19
  }
19
20
 
20
- /** @param {TTSEngineOptions} options */
21
+ /** @param {TTSEngineOptions | { festivalUrl: import('@/src/util/strings.js').StringWithVars }} options */
21
22
  constructor(options) {
22
23
  super(options);
23
24
  // $.browsers is sometimes undefined on some Android browsers :/
24
25
  // Likely related to when $.browser was moved to npm
25
26
  /** @type {'mp3' | 'ogg'} format of audio to get */
26
- this.audioFormat = $.browser?.mozilla ? 'ogg' : 'mp3';
27
+ this.audioFormat = $.browser?.mozilla ? 'ogg' : 'mp3'; //eslint-disable-line no-jquery/no-browser
28
+ /** @type {import('@/src/util/strings.js').StringWithVars} */
29
+ this.festivalUrl = options.festivalUrl;
27
30
  }
28
31
 
29
32
  /** @override */
30
33
  getVoices() {
31
34
  return [
32
- { default: true, lang: "en-US", localService: false, name: "Festival - English (US)", voiceURI: null }
35
+ { default: true, lang: "en-US", localService: false, name: "Festival - English (US)", voiceURI: null },
33
36
  ];
34
37
  }
35
38
 
@@ -45,7 +48,7 @@ export default class FestivalTTSEngine extends AbstractTTSEngine {
45
48
  url: '/bookreader/BookReader/soundmanager/swf',
46
49
  useHTML5Audio: true,
47
50
  //flash 8 version of swf is buggy when calling play() on a sound that is still loading
48
- flashVersion: 9
51
+ flashVersion: 9,
49
52
  });
50
53
  }
51
54
 
@@ -68,19 +71,7 @@ export default class FestivalTTSEngine extends AbstractTTSEngine {
68
71
 
69
72
  /** @override */
70
73
  createSound(chunk) {
71
- return new FestivalTTSSound(this.getSoundUrl(chunk.text));
72
- }
73
-
74
- /**
75
- * @private
76
- * Get URL for audio that says this text
77
- * @param {String} dataString the thing to say
78
- * @return {String} url
79
- */
80
- getSoundUrl(dataString) {
81
- return 'https://' + this.opts.server + '/BookReader/BookReaderGetTTS.php?string='
82
- + encodeURIComponent(dataString)
83
- + '&format=.' + this.audioFormat;
74
+ return new FestivalTTSSound(applyVariables(this.festivalUrl, { text: chunk.text, format: this.audioFormat }));
84
75
  }
85
76
 
86
77
  /**
@@ -91,10 +82,10 @@ export default class FestivalTTSEngine extends AbstractTTSEngine {
91
82
  * See https://stackoverflow.com/questions/12206631/html5-audio-cant-play-through-javascript-unless-triggered-manually-once
92
83
  * @return {PromiseLike}
93
84
  */
94
- iOSCaptureUserIntentHack() {
85
+ async iOSCaptureUserIntentHack() {
95
86
  const sound = soundManager.createSound({ url: SILENCE_1MS[this.audioFormat] });
96
- return new Promise(res => sound.play({onfinish: res}))
97
- .then(() => sound.destruct());
87
+ await new Promise(res => sound.play({onfinish: res}));
88
+ sound.destruct();
98
89
  }
99
90
  }
100
91
 
@@ -122,21 +113,20 @@ class FestivalTTSSound {
122
113
  if (this.rate != 1) this.sound.setPlaybackRate(this.rate);
123
114
  onload();
124
115
  },
125
- onresume: () => {
126
- sleep(25).then(() => {
127
- if (this.rate != 1) this.sound.setPlaybackRate(this.rate);
128
- });
129
- }
116
+ onresume: async () => {
117
+ await sleep(25);
118
+ if (this.rate != 1) this.sound.setPlaybackRate(this.rate);
119
+ },
130
120
  });
131
121
  return this.sound.load();
132
122
  }
133
123
 
134
- play() {
135
- return new Promise(res => {
124
+ async play() {
125
+ await new Promise(res => {
136
126
  this._finishResolver = res;
137
127
  this.sound.play({ onfinish: res });
138
- })
139
- .then(() => this.sound.destruct());
128
+ });
129
+ this.sound.destruct();
140
130
  }
141
131
 
142
132
  /** @override */
@@ -1,3 +1,5 @@
1
+ import { applyVariables } from "../../util/strings.js";
2
+
1
3
  /**
2
4
  * Class to manage a 'chunk' (approximately a paragraph) of text on a page.
3
5
  */
@@ -16,32 +18,39 @@ export default class PageChunk {
16
18
  }
17
19
 
18
20
  /**
19
- * @param {string} server
20
- * @param {string} bookPath
21
+ * @param {import('@/src/util/strings.js').StringWithVars} pageChunkUrl
21
22
  * @param {number} leafIndex
22
23
  * @return {Promise<PageChunk[]>}
23
24
  */
24
- static fetch(server, bookPath, leafIndex) {
25
- // jquery's ajax "PromiseLike" implementation is inconsistent with
26
- // modern Promises, so convert it to a full promise (it doesn't forward
27
- // a returned promise to the next handler in the chain, which kind of
28
- // defeats the entire point of using promises to avoid "callback hell")
29
- return new Promise((res, rej) => {
30
- $.ajax({
25
+ static async fetch(pageChunkUrl, leafIndex) {
26
+ if (window.br.plugins.translate?.translationManager.active) {
27
+ const translateLayers = await window.br.plugins.translate.getTranslateLayers(leafIndex);
28
+ const paragraphs = Array.from(translateLayers[0].childNodes);
29
+
30
+ const pageChunks = [];
31
+ for (const [idx, item] of paragraphs.entries()) {
32
+ // Should not read paragraphs w/ header or footer roles
33
+ if (!item.classList.contains('ocr-role-header-footer')) {
34
+ const translatedChunk = new PageChunk(leafIndex, idx, item.textContent, []);
35
+ pageChunks.push(translatedChunk);
36
+ }
37
+ }
38
+ if (pageChunks.length === 0) {
39
+ const placeholder = new PageChunk(leafIndex, 0, "", []);
40
+ pageChunks.push(placeholder);
41
+ }
42
+ return pageChunks;
43
+ } else {
44
+ const chunks = await $.ajax({
31
45
  type: 'GET',
32
- url: `https://${server}/BookReader/BookReaderGetTextWrapper.php`,
33
- dataType:'jsonp',
46
+ url: applyVariables(pageChunkUrl, { pageIndex: leafIndex }),
34
47
  cache: true,
35
- data: {
36
- path: `${bookPath}_djvu.xml`,
37
- page: leafIndex
48
+ xhrFields: {
49
+ withCredentials: window.br.protected,
38
50
  },
39
- error: rej,
40
- })
41
- .then(chunks => {
42
- res(PageChunk._fromTextWrapperResponse(leafIndex, chunks));
43
- });
44
- });
51
+ });
52
+ return PageChunk._fromTextWrapperResponse(leafIndex, chunks);
53
+ }
45
54
  }
46
55
 
47
56
  /**
@@ -97,7 +106,10 @@ export default class PageChunk {
97
106
  * @return {string}
98
107
  */
99
108
  static _removeDanglingHyphens(text) {
100
- return text.replace(/-\s+/g, '');
109
+ // Some books mis-OCR a dangling hyphen as a ¬ (mathematical not sign) . Since in math
110
+ // the not sign should not appear followed by a space, we think we can safely assume
111
+ // this should be replaced.
112
+ return text.replace(/[-¬]\s+/g, '');
101
113
  }
102
114
  }
103
115
 
@@ -53,22 +53,18 @@ export default class PageChunkIterator {
53
53
  * in the correct order.
54
54
  * @return {PromiseLike<"__PageChunkIterator.AT_END__" | PageChunk>}
55
55
  */
56
- _nextUncontrolled() {
56
+ async _nextUncontrolled() {
57
57
  if (this._cursor.page == this.pageCount) {
58
58
  return Promise.resolve(PageChunkIterator.AT_END);
59
59
  }
60
-
61
60
  this._recenterBuffer(this._cursor.page);
62
-
63
- return this._fetchPageChunks(this._cursor.page)
64
- .then(chunks => {
65
- if (this._cursor.chunk == chunks.length) {
66
- this._cursor.page++;
67
- this._cursor.chunk = 0;
68
- return this._nextUncontrolled();
69
- }
70
- return chunks[this._cursor.chunk++];
71
- });
61
+ const chunks = await this._fetchPageChunks(this._cursor.page);
62
+ if (this._cursor.chunk == chunks.length) {
63
+ this._cursor.page++;
64
+ this._cursor.chunk = 0;
65
+ return this._nextUncontrolled();
66
+ }
67
+ return chunks[this._cursor.chunk++];
72
68
  }
73
69
 
74
70
  /**
@@ -142,7 +138,7 @@ export default class PageChunkIterator {
142
138
  * @param {number} index
143
139
  */
144
140
  _fetchPageChunksDirect(index) {
145
- return PageChunk.fetch(this.opts.server, this.opts.bookPath, index);
141
+ return PageChunk.fetch(this.opts.pageChunkUrl, index);
146
142
  }
147
143
  }
148
144
 
@@ -150,14 +146,12 @@ PageChunkIterator.AT_END = "__PageChunkIterator.AT_END__";
150
146
 
151
147
  /** @type {PageChunkIteratorOptions} */
152
148
  const DEFAULT_OPTS = {
153
- server: null,
154
- bookPath: null,
149
+ pageChunkUrl: null,
155
150
  pageBufferSize: 2,
156
151
  };
157
152
 
158
153
  /**
159
154
  * @typedef {Object} PageChunkIteratorOptions
160
- * @property {string} server
161
- * @property {string} bookPath
155
+ * @property {import('@/src/util/strings.js').StringWithVars} pageChunkUrl
162
156
  * @property {number} [pageBufferSize] number of pages to buffer before/after the current page
163
157
  */