@internetarchive/bookreader 5.0.0-11 → 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 (380) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +604 -1239
  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 +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 -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/slider-toggle.svg +1 -0
  74. package/BookReader/icons/thumbnails.svg +1 -1
  75. package/BookReader/icons/voice.svg +1 -0
  76. package/BookReader/icons/volume-full.svg +1 -1
  77. package/BookReader/images/BRicons.svg +3 -3
  78. package/BookReader/images/books_graphic.svg +1 -1
  79. package/BookReader/images/hypothesis.ico +0 -0
  80. package/BookReader/images/icon_book.svg +1 -1
  81. package/BookReader/images/icon_bookmark.svg +1 -1
  82. package/BookReader/images/icon_experiment.svg +1 -0
  83. package/BookReader/images/icon_gear.svg +1 -1
  84. package/BookReader/images/icon_hamburger.svg +1 -1
  85. package/BookReader/images/icon_home.svg +1 -1
  86. package/BookReader/images/icon_info.svg +1 -1
  87. package/BookReader/images/icon_one_page.svg +1 -1
  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 -1
  91. package/BookReader/images/icon_search_button.svg +1 -1
  92. package/BookReader/images/icon_share.svg +1 -1
  93. package/BookReader/images/icon_skip-ahead.svg +1 -1
  94. package/BookReader/images/icon_skip-back.svg +1 -1
  95. package/BookReader/images/icon_speaker.svg +1 -1
  96. package/BookReader/images/icon_speaker_open.svg +1 -1
  97. package/BookReader/images/icon_thumbnails.svg +1 -1
  98. package/BookReader/images/icon_toc.svg +1 -1
  99. package/BookReader/images/icon_two_pages.svg +1 -1
  100. package/BookReader/images/marker_chap-off.svg +1 -1
  101. package/BookReader/images/marker_chap-on.svg +1 -1
  102. package/BookReader/images/marker_srch-on.svg +1 -1
  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 -1
  108. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  109. package/BookReader/plugins/plugin.autoplay.js +1 -1
  110. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  111. package/BookReader/plugins/plugin.chapters.js +22 -1
  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 -1
  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 -1
  122. package/BookReader/plugins/plugin.resume.js.map +1 -1
  123. package/BookReader/plugins/plugin.search.js +2 -1
  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 -1
  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 +1 -1
  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 -1
  136. package/BookReader/plugins/plugin.url.js.map +1 -1
  137. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  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 -365
  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 +29 -15
  160. package/src/BookReader/Navbar/Navbar.js +201 -76
  161. package/src/BookReader/PageContainer.js +120 -23
  162. package/src/BookReader/ReduceSet.js +2 -2
  163. package/src/BookReader/Toolbar/Toolbar.js +18 -40
  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 +136 -12
  171. package/src/BookReader.js +678 -1226
  172. package/src/BookReaderPlugin.js +52 -0
  173. package/src/assets/icons/magnify-minus.svg +3 -7
  174. package/src/assets/icons/magnify-plus.svg +3 -7
  175. package/src/assets/icons/slider-toggle.svg +1 -0
  176. package/src/assets/icons/voice.svg +1 -0
  177. package/src/assets/images/hypothesis.ico +0 -0
  178. package/src/assets/images/icon_experiment.svg +1 -0
  179. package/src/assets/images/translate.svg +1 -0
  180. package/src/assets/images/unviewable_page.png +0 -0
  181. package/src/assets/silence.mp3 +0 -0
  182. package/src/css/BookReader.scss +1 -5
  183. package/src/css/_BRBookmarks.scss +1 -1
  184. package/src/css/_BRComponent.scss +1 -1
  185. package/src/css/_BRicon.scss +8 -2
  186. package/src/css/_BRmain.scss +16 -3
  187. package/src/css/_BRnav.scss +74 -70
  188. package/src/css/_BRpages.scss +171 -42
  189. package/src/css/_BRsearch.scss +69 -30
  190. package/src/css/_BRtoolbar.scss +5 -5
  191. package/src/css/_TextSelection.scss +129 -24
  192. package/src/css/_colorbox.scss +2 -2
  193. package/src/css/_controls.scss +24 -7
  194. package/src/css/_icons.scss +8 -1
  195. package/src/{BookNavigator/assets → css}/button-base.js +2 -2
  196. package/src/css/icon_checkmark.js +9 -0
  197. package/src/css/sharedStyles.js +15 -0
  198. package/src/ia-bookreader/downloads/downloads-provider.js +81 -0
  199. package/src/{BookNavigator → ia-bookreader}/downloads/downloads.js +25 -5
  200. package/src/ia-bookreader/ia-bookreader.js +666 -0
  201. package/src/ia-bookreader/sharing.js +27 -0
  202. package/src/ia-bookreader/viewable-files.js +98 -0
  203. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments-provider.js +17 -17
  204. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments.js +75 -67
  205. package/src/{BookNavigator → plugins}/bookmarks/bookmark-button.js +4 -3
  206. package/src/{BookNavigator/assets → plugins/bookmarks}/bookmark-colors.js +1 -1
  207. package/src/{BookNavigator → plugins}/bookmarks/bookmark-edit.js +43 -31
  208. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
  209. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +3 -3
  210. package/src/plugins/bookmarks/bookmarks-provider.js +63 -0
  211. package/src/{BookNavigator → plugins/bookmarks}/delete-modal-actions.js +1 -1
  212. package/src/{BookNavigator → plugins}/bookmarks/ia-bookmarks.js +117 -68
  213. package/src/plugins/plugin.archive_analytics.js +84 -78
  214. package/src/plugins/plugin.autoplay.js +99 -104
  215. package/src/plugins/plugin.chapters.js +314 -205
  216. package/src/plugins/plugin.experiments.js +321 -0
  217. package/src/plugins/plugin.iframe.js +1 -1
  218. package/src/plugins/plugin.iiif.js +141 -0
  219. package/src/plugins/plugin.resume.js +54 -51
  220. package/src/plugins/plugin.text_selection.js +522 -219
  221. package/src/plugins/plugin.vendor-fullscreen.js +5 -5
  222. package/src/plugins/search/plugin.search.js +374 -392
  223. package/src/{BookNavigator → plugins}/search/search-provider.js +59 -27
  224. package/src/{BookNavigator → plugins}/search/search-results.js +105 -76
  225. package/src/plugins/search/utils.js +50 -0
  226. package/src/plugins/search/view.js +50 -68
  227. package/src/plugins/translate/TranslationManager.js +164 -0
  228. package/src/plugins/translate/plugin.translate.js +512 -0
  229. package/src/plugins/tts/AbstractTTSEngine.js +78 -49
  230. package/src/plugins/tts/FestivalTTSEngine.js +20 -30
  231. package/src/plugins/tts/PageChunk.js +33 -21
  232. package/src/plugins/tts/PageChunkIterator.js +11 -17
  233. package/src/plugins/tts/WebTTSEngine.js +131 -91
  234. package/src/plugins/tts/plugin.tts.js +345 -350
  235. package/src/plugins/tts/utils.js +77 -49
  236. package/src/plugins/url/UrlPlugin.js +191 -0
  237. package/src/plugins/{plugin.url.js → url/plugin.url.js} +44 -15
  238. package/src/util/TextSelectionManager.js +282 -0
  239. package/src/util/browserSniffing.js +33 -1
  240. package/src/util/cache.js +20 -0
  241. package/src/util/docCookies.js +21 -2
  242. package/src/util/lit.js +15 -0
  243. package/src/util/strings.js +1 -0
  244. package/.babelrc +0 -12
  245. package/.dependabot/config.yml +0 -6
  246. package/.eslintrc.js +0 -50
  247. package/.gitattributes +0 -2
  248. package/.github/ISSUE_TEMPLATE/bug.md +0 -32
  249. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
  250. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
  251. package/.github/workflows/node.js.yml +0 -37
  252. package/.github/workflows/npm-publish.yml +0 -47
  253. package/.testcaferc.json +0 -5
  254. package/BookReader/bookreader-component-bundle.js +0 -1450
  255. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  256. package/BookReader/bookreader-component-bundle.js.map +0 -1
  257. package/BookReader/jquery-1.10.1.js +0 -2
  258. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  259. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  260. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  261. package/BookReader/plugins/plugin.mobile_nav.js +0 -2
  262. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  263. package/BookReaderDemo/BookReaderDemo.css +0 -41
  264. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
  265. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  266. package/BookReaderDemo/BookReaderJSSimple.js +0 -55
  267. package/BookReaderDemo/IIIFBookReader.js +0 -207
  268. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
  269. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
  270. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  271. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  272. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  273. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
  274. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
  275. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  276. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  277. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  278. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  279. package/BookReaderDemo/demo-advanced.html +0 -33
  280. package/BookReaderDemo/demo-autoplay.html +0 -38
  281. package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
  282. package/BookReaderDemo/demo-embed.html +0 -26
  283. package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
  284. package/BookReaderDemo/demo-fullscreen.html +0 -33
  285. package/BookReaderDemo/demo-iiif.html +0 -34
  286. package/BookReaderDemo/demo-iiif.js +0 -26
  287. package/BookReaderDemo/demo-internetarchive.html +0 -74
  288. package/BookReaderDemo/demo-multiple.html +0 -43
  289. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  290. package/BookReaderDemo/demo-preview-pages.html +0 -1092
  291. package/BookReaderDemo/demo-simple.html +0 -34
  292. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
  293. package/BookReaderDemo/immersion-1up.html +0 -64
  294. package/BookReaderDemo/immersion-mode.html +0 -35
  295. package/BookReaderDemo/toggle_controls.html +0 -53
  296. package/BookReaderDemo/view_mode.html +0 -39
  297. package/BookReaderDemo/viewmode-cycle.html +0 -41
  298. package/CHANGELOG.md +0 -495
  299. package/CONTRIBUTING.md +0 -7
  300. package/codecov.yml +0 -17
  301. package/index.html +0 -31
  302. package/karma.conf.js +0 -23
  303. package/screenshot.png +0 -0
  304. package/scripts/postversion.js +0 -10
  305. package/scripts/preversion.js +0 -14
  306. package/scripts/version.js +0 -26
  307. package/src/BookNavigator/BookModel.js +0 -14
  308. package/src/BookNavigator/BookNavigator.js +0 -446
  309. package/src/BookNavigator/assets/book-loader.js +0 -27
  310. package/src/BookNavigator/assets/icon_checkmark.js +0 -6
  311. package/src/BookNavigator/assets/icon_close.js +0 -3
  312. package/src/BookNavigator/bookmarks/bookmarks-provider.js +0 -53
  313. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  314. package/src/BookNavigator/downloads/downloads-provider.js +0 -66
  315. package/src/BookNavigator/search/a-search-result.js +0 -55
  316. package/src/BookReader/DebugConsole.js +0 -54
  317. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  318. package/src/ItemNavigator/ItemNavigator.js +0 -376
  319. package/src/ItemNavigator/providers/sharing.js +0 -29
  320. package/src/css/_MobileNav.scss +0 -194
  321. package/src/dragscrollable-br.js +0 -261
  322. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  323. package/src/plugins/plugin.mobile_nav.js +0 -287
  324. package/tests/BookReader/BookModel.test.js +0 -312
  325. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  326. package/tests/BookReader/DebugConsole.test.js +0 -25
  327. package/tests/BookReader/ImageCache.test.js +0 -150
  328. package/tests/BookReader/Mode1Up.test.js +0 -164
  329. package/tests/BookReader/Mode2Up.test.js +0 -247
  330. package/tests/BookReader/Navbar/Navbar.test.js +0 -169
  331. package/tests/BookReader/PageContainer.test.js +0 -115
  332. package/tests/BookReader/ReduceSet.test.js +0 -38
  333. package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
  334. package/tests/BookReader/utils/classes.test.js +0 -88
  335. package/tests/BookReader/utils.test.js +0 -109
  336. package/tests/BookReader.options.test.js +0 -39
  337. package/tests/BookReader.test.js +0 -301
  338. package/tests/e2e/README.md +0 -75
  339. package/tests/e2e/autoplay.test.js +0 -13
  340. package/tests/e2e/base.test.js +0 -35
  341. package/tests/e2e/helpers/base.js +0 -263
  342. package/tests/e2e/helpers/debug.js +0 -13
  343. package/tests/e2e/helpers/desktopSearch.js +0 -72
  344. package/tests/e2e/helpers/mobileSearch.js +0 -85
  345. package/tests/e2e/helpers/mockSearch.js +0 -93
  346. package/tests/e2e/helpers/rightToLeft.js +0 -29
  347. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  348. package/tests/e2e/models/BookReader.js +0 -11
  349. package/tests/e2e/models/Navigation.js +0 -56
  350. package/tests/e2e/rightToLeft.test.js +0 -20
  351. package/tests/e2e/viewmode.test.js +0 -37
  352. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  353. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
  354. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
  355. package/tests/karma/BookNavigator/search/search-provider.test.js +0 -23
  356. package/tests/karma/BookNavigator/search/search-results.test.js +0 -240
  357. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  358. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  359. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  360. package/tests/plugins/plugin.autoplay.test.js +0 -52
  361. package/tests/plugins/plugin.chapters.test.js +0 -130
  362. package/tests/plugins/plugin.iframe.test.js +0 -42
  363. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  364. package/tests/plugins/plugin.resume.test.js +0 -98
  365. package/tests/plugins/plugin.text_selection.test.js +0 -203
  366. package/tests/plugins/plugin.url.test.js +0 -129
  367. package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
  368. package/tests/plugins/search/plugin.search.test.js +0 -173
  369. package/tests/plugins/search/plugin.search.view.test.js +0 -106
  370. package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
  371. package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
  372. package/tests/plugins/tts/PageChunk.test.js +0 -57
  373. package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
  374. package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
  375. package/tests/plugins/tts/utils.test.js +0 -133
  376. package/tests/util/browserSniffing.test.js +0 -56
  377. package/tests/util/docCookies.test.js +0 -15
  378. package/tests/util/strings.test.js +0 -63
  379. package/tests/utils.js +0 -42
  380. 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
  */