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

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 (391) hide show
  1. package/.eslintrc.js +17 -5
  2. package/.github/dependabot.yml +8 -0
  3. package/.github/workflows/node.js.yml +10 -1
  4. package/.husky/_/husky.sh +30 -0
  5. package/.testcaferc.js +10 -0
  6. package/BookReader/BookReader.css +75 -323
  7. package/BookReader/BookReader.js +32261 -2
  8. package/BookReader/BookReader.js.map +1 -1
  9. package/BookReader/ia-bookreader-bundle.js +15235 -0
  10. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  11. package/BookReader/icons/close-circle-dark.svg +1 -0
  12. package/BookReader/icons/voice.svg +1 -0
  13. package/BookReader/jquery-1.10.1.js +108 -2
  14. package/BookReader/plugins/plugin.archive_analytics.js +170 -1
  15. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  16. package/BookReader/plugins/plugin.autoplay.js +163 -1
  17. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  18. package/BookReader/plugins/plugin.chapters.js +333 -1
  19. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  20. package/BookReader/plugins/plugin.iframe.js +72 -1
  21. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  22. package/BookReader/plugins/plugin.mobile_nav.js +332 -1
  23. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  24. package/BookReader/plugins/plugin.resume.js +241 -1
  25. package/BookReader/plugins/plugin.resume.js.map +1 -1
  26. package/BookReader/plugins/plugin.search.js +1261 -1
  27. package/BookReader/plugins/plugin.search.js.map +1 -1
  28. package/BookReader/plugins/plugin.text_selection.js +839 -1
  29. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  30. package/BookReader/plugins/plugin.tts.js +9115 -2
  31. package/BookReader/plugins/plugin.tts.js.map +1 -1
  32. package/BookReader/plugins/plugin.url.js +811 -1
  33. package/BookReader/plugins/plugin.url.js.map +1 -1
  34. package/BookReader/plugins/plugin.vendor-fullscreen.js +326 -1
  35. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  36. package/BookReader/webcomponents-bundle.js +412 -0
  37. package/BookReader/webcomponents-bundle.js.map +1 -0
  38. package/BookReaderDemo/BookReaderDemo.css +14 -1
  39. package/BookReaderDemo/IADemoBr.js +107 -0
  40. package/BookReaderDemo/demo-advanced.html +1 -1
  41. package/BookReaderDemo/demo-autoplay.html +1 -0
  42. package/BookReaderDemo/demo-embed-iframe-src.html +1 -0
  43. package/BookReaderDemo/demo-fullscreen-mobile.html +1 -0
  44. package/BookReaderDemo/demo-fullscreen.html +1 -0
  45. package/BookReaderDemo/demo-iiif.html +1 -0
  46. package/BookReaderDemo/demo-internetarchive.html +66 -18
  47. package/BookReaderDemo/demo-multiple.html +1 -0
  48. package/BookReaderDemo/demo-preview-pages.html +1 -0
  49. package/BookReaderDemo/demo-simple.html +1 -0
  50. package/BookReaderDemo/demo-vendor-fullscreen.html +1 -0
  51. package/BookReaderDemo/immersion-1up.html +1 -0
  52. package/BookReaderDemo/immersion-mode.html +1 -0
  53. package/BookReaderDemo/toggle_controls.html +1 -0
  54. package/BookReaderDemo/view_mode.html +1 -0
  55. package/BookReaderDemo/viewmode-cycle.html +1 -2
  56. package/CHANGELOG.md +114 -0
  57. package/babel.config.js +18 -0
  58. package/index.html +3 -0
  59. package/jsconfig.json +19 -0
  60. package/package.json +45 -27
  61. package/src/BookNavigator/assets/button-base.js +8 -1
  62. package/src/BookNavigator/assets/ia-logo.js +17 -0
  63. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  64. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  65. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  66. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  67. package/src/BookNavigator/book-navigator.js +528 -0
  68. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  69. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -1
  70. package/src/BookNavigator/bookmarks/bookmarks-list.js +1 -0
  71. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
  72. package/src/BookNavigator/bookmarks/bookmarks-provider.js +32 -11
  73. package/src/BookNavigator/bookmarks/ia-bookmarks.js +88 -43
  74. package/src/BookNavigator/downloads/downloads-provider.js +22 -16
  75. package/src/BookNavigator/downloads/downloads.js +16 -23
  76. package/src/BookNavigator/search/a-search-result.js +1 -0
  77. package/src/BookNavigator/search/search-provider.js +54 -20
  78. package/src/BookNavigator/search/search-results.js +7 -18
  79. package/src/BookNavigator/sharing.js +27 -0
  80. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +10 -12
  81. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +1 -0
  82. package/src/BookNavigator/volumes/volumes-provider.js +114 -0
  83. package/src/BookNavigator/volumes/volumes.js +189 -0
  84. package/src/BookReader/DebugConsole.js +3 -3
  85. package/src/BookReader/DragScrollable.js +233 -0
  86. package/src/BookReader/Mode1Up.js +50 -351
  87. package/src/BookReader/Mode1UpLit.js +434 -0
  88. package/src/BookReader/Mode2Up.js +94 -72
  89. package/src/BookReader/ModeSmoothZoom.js +177 -0
  90. package/src/BookReader/ModeThumb.js +16 -8
  91. package/src/BookReader/Navbar/Navbar.js +2 -31
  92. package/src/BookReader/PageContainer.js +47 -2
  93. package/src/BookReader/ReduceSet.js +1 -1
  94. package/src/BookReader/Toolbar/Toolbar.js +5 -5
  95. package/src/BookReader/options.js +10 -0
  96. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  97. package/src/BookReader/utils.js +68 -13
  98. package/src/BookReader.js +316 -232
  99. package/src/assets/icons/close-circle-dark.svg +1 -0
  100. package/src/assets/icons/voice.svg +1 -0
  101. package/src/css/BookReader.scss +0 -12
  102. package/src/css/_BRComponent.scss +1 -1
  103. package/src/css/_BRmain.scss +19 -24
  104. package/src/css/_BRnav.scss +4 -26
  105. package/src/css/_BRpages.scss +35 -0
  106. package/src/css/_BRsearch.scss +11 -215
  107. package/src/css/_TextSelection.scss +1 -17
  108. package/src/css/_controls.scss +16 -3
  109. package/src/css/_icons.scss +6 -0
  110. package/src/ia-bookreader/ia-bookreader.js +206 -0
  111. package/src/plugins/plugin.chapters.js +15 -18
  112. package/src/plugins/plugin.mobile_nav.js +11 -10
  113. package/src/plugins/plugin.resume.js +3 -3
  114. package/src/plugins/plugin.text_selection.js +17 -29
  115. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  116. package/src/plugins/search/plugin.search.js +113 -104
  117. package/src/plugins/search/view.js +48 -163
  118. package/src/plugins/tts/AbstractTTSEngine.js +7 -0
  119. package/src/plugins/tts/FestivalTTSEngine.js +2 -2
  120. package/src/plugins/tts/WebTTSEngine.js +5 -0
  121. package/src/plugins/tts/plugin.tts.js +67 -102
  122. package/src/plugins/url/UrlPlugin.js +184 -0
  123. package/src/plugins/url/plugin.url.js +220 -0
  124. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  125. package/{src → stat}/BookNavigator/BookNavigator.js +151 -104
  126. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  127. package/stat/BookNavigator/assets/button-base.js +61 -0
  128. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  129. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  130. package/stat/BookNavigator/assets/icon_close.js +3 -0
  131. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  132. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  133. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  134. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  135. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  136. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  137. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  138. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  139. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  140. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  141. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  142. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  143. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  144. package/stat/BookNavigator/downloads/downloads.js +139 -0
  145. package/stat/BookNavigator/provider-config.js +0 -0
  146. package/stat/BookNavigator/search/a-search-result.js +55 -0
  147. package/stat/BookNavigator/search/search-provider.js +180 -0
  148. package/stat/BookNavigator/search/search-results.js +360 -0
  149. package/stat/BookNavigator/sharing.js +31 -0
  150. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  151. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  152. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  153. package/stat/BookNavigator/volumes/volumes.js +178 -0
  154. package/stat/BookReader/BookModel.js +518 -0
  155. package/stat/BookReader/DebugConsole.js +54 -0
  156. package/stat/BookReader/DragScrollable.js +233 -0
  157. package/stat/BookReader/ImageCache.js +116 -0
  158. package/stat/BookReader/Mode1Up.js +102 -0
  159. package/stat/BookReader/Mode1UpLit.js +434 -0
  160. package/stat/BookReader/Mode2Up.js +1372 -0
  161. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  162. package/stat/BookReader/ModeThumb.js +344 -0
  163. package/stat/BookReader/Navbar/Navbar.js +310 -0
  164. package/stat/BookReader/PageContainer.js +120 -0
  165. package/stat/BookReader/ReduceSet.js +26 -0
  166. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  167. package/stat/BookReader/events.js +20 -0
  168. package/stat/BookReader/options.js +324 -0
  169. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  170. package/stat/BookReader/utils/classes.js +36 -0
  171. package/stat/BookReader/utils.js +240 -0
  172. package/stat/BookReader.js +2550 -0
  173. package/{src → stat}/BookReaderComponent/BookReaderComponent.js +16 -11
  174. package/stat/assets/icons/1up.svg +12 -0
  175. package/stat/assets/icons/2up.svg +15 -0
  176. package/stat/assets/icons/advance.svg +26 -0
  177. package/stat/assets/icons/chevron-right.svg +1 -0
  178. package/stat/assets/icons/close-circle-dark.svg +1 -0
  179. package/stat/assets/icons/close-circle.svg +1 -0
  180. package/stat/assets/icons/fullscreen.svg +17 -0
  181. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  182. package/stat/assets/icons/hamburger.svg +15 -0
  183. package/stat/assets/icons/left-arrow.svg +12 -0
  184. package/stat/assets/icons/magnify-minus.svg +16 -0
  185. package/stat/assets/icons/magnify-plus.svg +17 -0
  186. package/stat/assets/icons/magnify.svg +15 -0
  187. package/stat/assets/icons/pause.svg +23 -0
  188. package/stat/assets/icons/play.svg +22 -0
  189. package/stat/assets/icons/playback-speed.svg +34 -0
  190. package/stat/assets/icons/read-aloud.svg +22 -0
  191. package/stat/assets/icons/review.svg +22 -0
  192. package/stat/assets/icons/thumbnails.svg +17 -0
  193. package/stat/assets/icons/voice.svg +1 -0
  194. package/stat/assets/icons/volume-full.svg +22 -0
  195. package/stat/assets/images/BRicons.png +0 -0
  196. package/stat/assets/images/BRicons.svg +94 -0
  197. package/stat/assets/images/BRicons_ia.png +0 -0
  198. package/stat/assets/images/back_pages.png +0 -0
  199. package/stat/assets/images/book_bottom_icon.png +0 -0
  200. package/stat/assets/images/book_down_icon.png +0 -0
  201. package/stat/assets/images/book_left_icon.png +0 -0
  202. package/stat/assets/images/book_leftmost_icon.png +0 -0
  203. package/stat/assets/images/book_right_icon.png +0 -0
  204. package/stat/assets/images/book_rightmost_icon.png +0 -0
  205. package/stat/assets/images/book_top_icon.png +0 -0
  206. package/stat/assets/images/book_up_icon.png +0 -0
  207. package/stat/assets/images/books_graphic.svg +177 -0
  208. package/stat/assets/images/booksplit.png +0 -0
  209. package/stat/assets/images/control_pause_icon.png +0 -0
  210. package/stat/assets/images/control_play_icon.png +0 -0
  211. package/stat/assets/images/embed_icon.png +0 -0
  212. package/stat/assets/images/icon-home-ia.png +0 -0
  213. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  214. package/stat/assets/images/icon_alert-xs.png +0 -0
  215. package/stat/assets/images/icon_book.svg +12 -0
  216. package/stat/assets/images/icon_bookmark.svg +12 -0
  217. package/stat/assets/images/icon_close-pop.png +0 -0
  218. package/stat/assets/images/icon_download.png +0 -0
  219. package/stat/assets/images/icon_gear.svg +14 -0
  220. package/stat/assets/images/icon_hamburger.svg +20 -0
  221. package/stat/assets/images/icon_home.png +0 -0
  222. package/stat/assets/images/icon_home.svg +21 -0
  223. package/stat/assets/images/icon_home_ia.png +0 -0
  224. package/stat/assets/images/icon_indicator.png +0 -0
  225. package/stat/assets/images/icon_info.svg +11 -0
  226. package/stat/assets/images/icon_one_page.svg +8 -0
  227. package/stat/assets/images/icon_pause.svg +1 -0
  228. package/stat/assets/images/icon_play.svg +1 -0
  229. package/stat/assets/images/icon_playback-rate.svg +15 -0
  230. package/stat/assets/images/icon_return.png +0 -0
  231. package/stat/assets/images/icon_search_button.svg +8 -0
  232. package/stat/assets/images/icon_share.svg +9 -0
  233. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  234. package/stat/assets/images/icon_skip-back.svg +13 -0
  235. package/stat/assets/images/icon_speaker.svg +18 -0
  236. package/stat/assets/images/icon_speaker_open.svg +10 -0
  237. package/stat/assets/images/icon_thumbnails.svg +12 -0
  238. package/stat/assets/images/icon_toc.svg +5 -0
  239. package/stat/assets/images/icon_two_pages.svg +9 -0
  240. package/stat/assets/images/icon_zoomer.png +0 -0
  241. package/stat/assets/images/loading.gif +0 -0
  242. package/stat/assets/images/logo_icon.png +0 -0
  243. package/stat/assets/images/marker_chap-off.png +0 -0
  244. package/stat/assets/images/marker_chap-off.svg +11 -0
  245. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  246. package/stat/assets/images/marker_chap-on.png +0 -0
  247. package/stat/assets/images/marker_chap-on.svg +11 -0
  248. package/stat/assets/images/marker_srch-on.svg +11 -0
  249. package/stat/assets/images/marker_srchchap-off.png +0 -0
  250. package/stat/assets/images/marker_srchchap-on.png +0 -0
  251. package/stat/assets/images/nav_control-dn.png +0 -0
  252. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  253. package/stat/assets/images/nav_control-up.png +0 -0
  254. package/stat/assets/images/nav_control-up_ia.png +0 -0
  255. package/stat/assets/images/nav_control.png +0 -0
  256. package/stat/assets/images/one_page_mode_icon.png +0 -0
  257. package/stat/assets/images/paper-badge.png +0 -0
  258. package/stat/assets/images/print_icon.png +0 -0
  259. package/stat/assets/images/progressbar.gif +0 -0
  260. package/stat/assets/images/right_edges.png +0 -0
  261. package/stat/assets/images/slider.png +0 -0
  262. package/stat/assets/images/slider_ia.png +0 -0
  263. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  264. package/stat/assets/images/transparent.png +0 -0
  265. package/stat/assets/images/two_page_mode_icon.png +0 -0
  266. package/stat/assets/images/zoom_in_icon.png +0 -0
  267. package/stat/assets/images/zoom_out_icon.png +0 -0
  268. package/stat/css/BookReader.scss +89 -0
  269. package/stat/css/_BRBookmarks.scss +29 -0
  270. package/stat/css/_BRComponent.scss +13 -0
  271. package/stat/css/_BRfloat.scss +197 -0
  272. package/stat/css/_BRicon.scss +48 -0
  273. package/stat/css/_BRmain.scss +251 -0
  274. package/stat/css/_BRnav.scss +359 -0
  275. package/stat/css/_BRpages.scss +139 -0
  276. package/stat/css/_BRsearch.scss +226 -0
  277. package/stat/css/_BRtoolbar.scss +84 -0
  278. package/stat/css/_BRvendor.scss +5 -0
  279. package/stat/css/_MobileNav.scss +194 -0
  280. package/stat/css/_TextSelection.scss +32 -0
  281. package/stat/css/_colorbox.scss +52 -0
  282. package/stat/css/_controls.scss +253 -0
  283. package/stat/css/_icons.scss +121 -0
  284. package/stat/jquery-wrapper.js +4 -0
  285. package/stat/plugins/plugin.archive_analytics.js +86 -0
  286. package/stat/plugins/plugin.autoplay.js +129 -0
  287. package/stat/plugins/plugin.chapters.js +248 -0
  288. package/stat/plugins/plugin.iframe.js +48 -0
  289. package/stat/plugins/plugin.mobile_nav.js +288 -0
  290. package/stat/plugins/plugin.resume.js +68 -0
  291. package/stat/plugins/plugin.text_selection.js +291 -0
  292. package/{src → stat}/plugins/plugin.url.js +4 -4
  293. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  294. package/stat/plugins/search/plugin.search.js +439 -0
  295. package/stat/plugins/search/view.js +439 -0
  296. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  297. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  298. package/stat/plugins/tts/PageChunk.js +107 -0
  299. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  300. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  301. package/stat/plugins/tts/plugin.tts.js +357 -0
  302. package/stat/plugins/tts/tooltip_dict.js +15 -0
  303. package/stat/plugins/tts/utils.js +91 -0
  304. package/stat/util/browserSniffing.js +30 -0
  305. package/stat/util/debouncer.js +26 -0
  306. package/stat/util/docCookies.js +67 -0
  307. package/stat/util/strings.js +34 -0
  308. package/tests/e2e/README.md +37 -0
  309. package/tests/e2e/autoplay.test.js +2 -2
  310. package/tests/e2e/base.test.js +5 -7
  311. package/tests/e2e/helpers/base.js +8 -3
  312. package/tests/e2e/helpers/debug.js +1 -1
  313. package/tests/e2e/helpers/desktopSearch.js +1 -1
  314. package/tests/e2e/helpers/mobileSearch.js +3 -3
  315. package/tests/e2e/helpers/params.js +17 -0
  316. package/tests/e2e/rightToLeft.test.js +4 -5
  317. package/tests/e2e/viewmode.test.js +30 -31
  318. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +3 -3
  319. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  320. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  321. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  322. package/tests/jest/BookReader/Mode1UpLit.test.js +87 -0
  323. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +5 -7
  324. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  325. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  326. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  327. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +74 -2
  328. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  329. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  330. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  331. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  332. package/tests/jest/BookReader/utils.test.js +136 -0
  333. package/tests/jest/BookReader.keyboard.test.js +190 -0
  334. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  335. package/tests/{BookReader.test.js → jest/BookReader.test.js} +20 -4
  336. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  337. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +2 -2
  338. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +8 -8
  339. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  340. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  341. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  342. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +14 -24
  343. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  344. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +12 -5
  345. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +6 -6
  346. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +3 -3
  347. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  348. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  349. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  350. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  351. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -3
  352. package/tests/jest/plugins/url/UrlPlugin.test.js +175 -0
  353. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  354. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  355. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  356. package/tests/{util → jest/util}/strings.test.js +1 -1
  357. package/tests/{utils.js → jest/utils.js} +38 -0
  358. package/tests/karma/BookNavigator/book-navigator.test.js +485 -0
  359. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  360. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +1 -3
  361. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +1 -2
  362. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +67 -0
  363. package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
  364. package/tests/karma/BookNavigator/search/search-provider.test.js +123 -0
  365. package/tests/karma/BookNavigator/{search-results.test.js → search/search-results.test.js} +1 -4
  366. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +49 -0
  367. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -2
  368. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +184 -0
  369. package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
  370. package/webpack.config.js +11 -5
  371. package/.babelrc +0 -12
  372. package/.dependabot/config.yml +0 -6
  373. package/.testcaferc.json +0 -5
  374. package/BookReader/BookReader.js.LICENSE.txt +0 -72
  375. package/BookReader/bookreader-component-bundle.js +0 -1450
  376. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  377. package/BookReader/bookreader-component-bundle.js.map +0 -1
  378. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  379. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  380. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  381. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +0 -27
  382. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  383. package/src/BookNavigator/assets/book-loader.js +0 -27
  384. package/src/ItemNavigator/ItemNavigator.js +0 -372
  385. package/src/ItemNavigator/providers/sharing.js +0 -29
  386. package/src/dragscrollable-br.js +0 -261
  387. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  388. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  389. package/tests/BookReader/Mode1Up.test.js +0 -164
  390. package/tests/BookReader/utils.test.js +0 -109
  391. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
package/src/BookReader.js CHANGED
@@ -27,7 +27,6 @@ import 'jquery-ui/ui/widget.js';
27
27
  import 'jquery-ui/ui/widgets/mouse.js';
28
28
  import 'jquery-ui-touch-punch';
29
29
 
30
- import './dragscrollable-br.js';
31
30
  import PACKAGE_JSON from '../package.json';
32
31
  import * as utils from './BookReader/utils.js';
33
32
  import { exposeOverrideable } from './BookReader/utils/classes.js';
@@ -179,7 +178,7 @@ BookReader.prototype.setup = function(options) {
179
178
  */
180
179
  this.firstIndex = null;
181
180
  this.lastDisplayableIndex2up = null;
182
- this.isFullscreenActive = false;
181
+ this.isFullscreenActive = options.startFullscreen || false;
183
182
  this.lastScroll = null;
184
183
 
185
184
  this.showLogo = options.showLogo;
@@ -265,8 +264,52 @@ BookReader.prototype.setup = function(options) {
265
264
  useSrcSet: this.options.useSrcSet,
266
265
  reduceSet: this.reduceSet,
267
266
  });
267
+
268
+ /**
269
+ * Flag if BookReader has "focus" for keyboard shortcuts
270
+ * Initially true, set to false when:
271
+ * - BookReader scrolled out of view
272
+ * Set to true when:
273
+ * - BookReader scrolled into view
274
+ */
275
+ this.hasKeyFocus = true;
276
+ };
277
+
278
+ /**
279
+ * Get all the HTML Elements that are being/can be rendered.
280
+ * Includes cached elements which might be rendered again.
281
+ */
282
+ BookReader.prototype.getActivePageContainerElements = function() {
283
+ let containerEls = Object.values(this._modes.mode2Up.pageContainers).map(pc => pc.$container[0])
284
+ .concat(Object.values(this._modes.mode1Up.mode1UpLit.pageContainerCache).map(pc => pc.$container[0]));
285
+ if (this.mode == this.constModeThumb) {
286
+ containerEls = containerEls.concat(this.$('.BRpagecontainer').toArray());
287
+ }
288
+ return containerEls;
289
+ };
290
+
291
+ /**
292
+ * Get the HTML Elements for the rendered page. Note there can be more than one, since
293
+ * (at least as of writing) different modes can maintain different caches.
294
+ * @param {PageIndex} pageIndex
295
+ */
296
+ BookReader.prototype.getActivePageContainerElementsForIndex = function(pageIndex) {
297
+ return [
298
+ this._modes.mode2Up.pageContainers[pageIndex]?.$container?.[0],
299
+ this._modes.mode1Up.mode1UpLit.pageContainerCache[pageIndex]?.$container?.[0],
300
+ ...(this.mode == this.constModeThumb ? this.$(`.pagediv${pageIndex}`).toArray() : [])
301
+ ].filter(x => x);
268
302
  };
269
303
 
304
+ Object.defineProperty(BookReader.prototype, 'activeMode', {
305
+ /** @return {Mode1Up | Mode2Up | ModeThumb} */
306
+ get() { return {
307
+ 1: this._modes.mode1Up,
308
+ 2: this._modes.mode2Up,
309
+ 3: this._modes.modeThumb,
310
+ }[this.mode]; },
311
+ });
312
+
270
313
  /** @deprecated unused outside Mode2Up */
271
314
  Object.defineProperty(BookReader.prototype, 'leafEdgeL', {
272
315
  get() { return this._modes.mode2Up.leafEdgeL; },
@@ -298,7 +341,7 @@ BookReader.prototype.extendParams = function(params, newParams) {
298
341
  delete modifiedNewParams.page;
299
342
  }
300
343
  $.extend(params, modifiedNewParams);
301
- }
344
+ };
302
345
 
303
346
  /**
304
347
  * Parses params from from various initialization contexts (url, cookie, options)
@@ -377,7 +420,7 @@ BookReader.prototype.initParams = function() {
377
420
  // Check for Search plugin
378
421
  if (this.options.enableSearch) {
379
422
  // Go to first result only if no default or URL page
380
- this.goToFirstResult = !params.pageFound
423
+ this.options.goToFirstResult = !params.pageFound;
381
424
 
382
425
  // If initialSearchTerm not set
383
426
  if (!this.options.initialSearchTerm) {
@@ -389,7 +432,7 @@ BookReader.prototype.initParams = function() {
389
432
  } else {
390
433
  // If we have a query string: q=[term]
391
434
  const searchParams = new URLSearchParams(this.readQueryString());
392
- const searchTerm = searchParams.get('q')
435
+ const searchTerm = searchParams.get('q');
393
436
  if (searchTerm) {
394
437
  this.options.initialSearchTerm = utils.decodeURIComponentPlus(searchTerm);
395
438
  }
@@ -401,21 +444,21 @@ BookReader.prototype.initParams = function() {
401
444
  this.suppressFragmentChange = !params.fragmentChange;
402
445
 
403
446
  return params;
404
- }
447
+ };
405
448
 
406
449
  /**
407
450
  * Allow mocking of window.location.search
408
451
  */
409
452
  BookReader.prototype.getLocationSearch = function () {
410
453
  return window.location.search;
411
- }
454
+ };
412
455
 
413
456
  /**
414
457
  * Allow mocking of window.location.hash
415
458
  */
416
459
  BookReader.prototype.getLocationHash = function () {
417
460
  return window.location.hash;
418
- }
461
+ };
419
462
 
420
463
  /**
421
464
  * Return URL or fragment querystring
@@ -428,7 +471,7 @@ BookReader.prototype.readQueryString = function() {
428
471
  const hash = this.getLocationHash();
429
472
  const found = hash.search(/\?\w+=/);
430
473
  return found > -1 ? hash.slice(found) : '';
431
- }
474
+ };
432
475
 
433
476
  /**
434
477
  * Determines the initial mode for starting if a mode is not already
@@ -443,7 +486,6 @@ BookReader.prototype.getInitialMode = function(params) {
443
486
  if ('undefined' != typeof(params.mode)) {
444
487
  nextMode = params.mode;
445
488
  } else if (this.ui == 'full'
446
- && this.enableMobileNav
447
489
  && this.isFullscreenActive
448
490
  && windowWidth <= this.onePageMinBreakpoint
449
491
  ) {
@@ -497,15 +539,12 @@ BookReader.prototype.init = function() {
497
539
  // Explicitly ensure this.mode exists for initNavbar() below
498
540
  this.mode = params.mode;
499
541
 
500
- if (this.ui == "embed" && this.options.showNavbar) {
501
- this.initEmbedNavbar();
502
- } else {
503
- if (this.options.showToolbar) {
504
- this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
505
- }
506
- if (this.options.showNavbar) {
507
- this.initNavbar();
508
- }
542
+ // Display Navigation
543
+ if (this.options.showToolbar) {
544
+ this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
545
+ }
546
+ if (this.options.showNavbar) { // default navigation
547
+ this.initNavbar();
509
548
  }
510
549
 
511
550
  // Switch navbar controls on mobile/desktop
@@ -521,17 +560,17 @@ BookReader.prototype.init = function() {
521
560
  this.setupKeyListeners();
522
561
 
523
562
  this.lastScroll = (new Date().getTime());
524
- this.refs.$brContainer.bind('scroll', this, function(e) {
563
+ this.refs.$brContainer.on('scroll', this, function(e) {
525
564
  // Note, this scroll event fires for both user, and js generated calls
526
565
  // It is functioning in some cases as the primary triggerer for rendering
527
566
  e.data.lastScroll = (new Date().getTime());
528
- if (e.data.constMode2up != e.data.mode) {
567
+ if (e.data.constModeThumb == e.data.mode) {
529
568
  e.data.drawLeafsThrottled();
530
569
  }
531
570
  });
532
571
 
533
572
  if (this.options.autoResize) {
534
- $(window).bind('resize', this, function(e) {
573
+ $(window).on('resize', this, function(e) {
535
574
  e.data.resize();
536
575
  });
537
576
  $(window).on("orientationchange", this, function(e) {
@@ -548,15 +587,17 @@ BookReader.prototype.init = function() {
548
587
  this.suppressFragmentChange = false;
549
588
  }
550
589
 
590
+ if (this.options.startFullscreen) {
591
+ this.enterFullscreen(true);
592
+ }
593
+
551
594
  this.init.initComplete = true;
552
595
  this.trigger(BookReader.eventNames.PostInit);
553
596
 
554
597
  // Must be called after this.init.initComplete set to true to allow
555
598
  // BookReader.prototype.resize to run.
556
- if (this.options.startFullscreen) {
557
- this.toggleFullscreen();
558
- }
559
- }
599
+
600
+ };
560
601
 
561
602
  /**
562
603
  * @param {EVENTS} name
@@ -564,7 +605,6 @@ BookReader.prototype.init = function() {
564
605
  */
565
606
  BookReader.prototype.trigger = function(name, props = this) {
566
607
  const eventName = 'BookReader:' + name;
567
- $(document).trigger(eventName, props);
568
608
 
569
609
  utils.polyfillCustomEvent(window);
570
610
  window.dispatchEvent(new CustomEvent(eventName, {
@@ -572,14 +612,15 @@ BookReader.prototype.trigger = function(name, props = this) {
572
612
  composed: true,
573
613
  detail: { props },
574
614
  }));
615
+ $(document).trigger(eventName, props);
575
616
  };
576
617
 
577
618
  BookReader.prototype.bind = function(name, callback) {
578
- $(document).bind('BookReader:' + name, callback);
619
+ $(document).on('BookReader:' + name, callback);
579
620
  };
580
621
 
581
622
  BookReader.prototype.unbind = function(name, callback) {
582
- $(document).unbind('BookReader:' + name, callback);
623
+ $(document).off('BookReader:' + name, callback);
583
624
  };
584
625
 
585
626
  /**
@@ -597,11 +638,9 @@ BookReader.prototype.resize = function() {
597
638
  if (this.onePage.autofit != 'none') {
598
639
  this.resizePageView1up();
599
640
  this.centerPageView();
600
- if (this.enableSearch) this.updateSearchHilites(); //deletes highlights but does not call remove()
601
641
  } else {
602
642
  this.centerPageView();
603
643
  this.displayedIndices = [];
604
- if (this.enableSearch) this.updateSearchHilites(); //deletes highlights but does not call remove()
605
644
  this.drawLeafsThrottled();
606
645
  }
607
646
  } else if (this.constModeThumb == this.mode) {
@@ -633,89 +672,124 @@ BookReader.prototype.resize = function() {
633
672
  };
634
673
 
635
674
  /**
636
- * Binds keyboard event listeners
675
+ * Binds keyboard and keyboard focus event listeners
637
676
  */
638
- BookReader.prototype.setupKeyListeners = function() {
639
- var self = this;
677
+ BookReader.prototype.setupKeyListeners = function () {
640
678
 
641
- var KEY_PGUP = 33;
642
- var KEY_PGDOWN = 34;
643
- var KEY_END = 35;
644
- var KEY_HOME = 36;
645
-
646
- var KEY_LEFT = 37;
647
- var KEY_UP = 38;
648
- var KEY_RIGHT = 39;
649
- var KEY_DOWN = 40;
650
- // The minus(-) and equal(=) keys have different mappings for different browsers
651
- var KEY_MINUS = 189; // Chrome
652
- var KEY_MINUS_F = 173; // Firefox
653
- var KEY_NUMPAD_SUBTRACT = 109;
654
- var KEY_EQUAL = 187; // Chrome
655
- var KEY_EQUAL_F = 61; // Firefox
656
- var KEY_NUMPAD_ADD = 107;
657
-
658
- // We use document here instead of window to avoid a bug in jQuery on IE7
659
- $(document).keydown(function(e) {
660
-
661
- // Keyboard navigation
662
- if (!self.keyboardNavigationIsDisabled(e)) {
663
- switch (e.keyCode) {
664
- case KEY_PGUP:
665
- case KEY_UP:
666
- // In 1up mode page scrolling is handled by browser
667
- if (self.constMode2up == self.mode) {
668
- e.preventDefault();
669
- self.prev();
670
- }
671
- break;
672
- case KEY_DOWN:
673
- case KEY_PGDOWN:
674
- if (self.constMode2up == self.mode) {
675
- e.preventDefault();
676
- self.next();
679
+ // Keyboard focus by BookReader in viewport
680
+ //
681
+ // Intersection observer and callback sets BookReader keyboard
682
+ // "focus" flag off when the BookReader is not in the viewport.
683
+ if (window.IntersectionObserver) {
684
+ const observer = new IntersectionObserver((entries) => {
685
+ entries.forEach((entry) => {
686
+ if (entry.intersectionRatio === 0) {
687
+ this.hasKeyFocus = false;
688
+ } else {
689
+ this.hasKeyFocus = true;
677
690
  }
678
- break;
679
- case KEY_END:
691
+ });
692
+ }, {
693
+ root: null,
694
+ rootMargin: '0px',
695
+ threshold: [0, 0.05, 1],
696
+ });
697
+ observer.observe(this.refs.$br[0]);
698
+ }
699
+
700
+ // Keyboard listeners
701
+ document.addEventListener('keydown', (e) => {
702
+
703
+ // Ignore if BookReader "focus" flag not set
704
+ if (!this.hasKeyFocus) {
705
+ return;
706
+ }
707
+
708
+ // Ignore if modifiers are active.
709
+ if (e.getModifierState('Control') ||
710
+ e.getModifierState('Alt') ||
711
+ e.getModifierState('Meta') ||
712
+ e.getModifierState('Win') /* hack for IE */) {
713
+ return;
714
+ }
715
+
716
+ // Ignore in input elements
717
+ if (utils.isInputActive()) {
718
+ return;
719
+ }
720
+
721
+ // KeyboardEvent code values:
722
+ // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values
723
+ switch (e.key) {
724
+
725
+ // Page navigation
726
+ case "Home":
727
+ e.preventDefault();
728
+ this.first();
729
+ break;
730
+ case "End":
731
+ e.preventDefault();
732
+ this.last();
733
+ break;
734
+ case "ArrowDown":
735
+ case "PageDown":
736
+ case "Down": // hack for IE and old Gecko
737
+ // In 1up and thumb mode page scrolling handled by browser
738
+ if (this.constMode2up === this.mode) {
680
739
  e.preventDefault();
681
- self.last();
682
- break;
683
- case KEY_HOME:
740
+ this.next();
741
+ }
742
+ break;
743
+ case "ArrowUp":
744
+ case "PageUp":
745
+ case "Up": // hack for IE and old Gecko
746
+ // In 1up and thumb mode page scrolling handled by browser
747
+ if (this.constMode2up === this.mode) {
684
748
  e.preventDefault();
685
- self.first();
686
- break;
687
- case KEY_LEFT:
688
- if (self.constModeThumb != self.mode) {
689
- e.preventDefault();
690
- self.left();
691
- }
692
- break;
693
- case KEY_RIGHT:
694
- if (self.constModeThumb != self.mode) {
695
- e.preventDefault();
696
- self.right();
697
- }
698
- break;
699
- case KEY_MINUS:
700
- case KEY_MINUS_F:
701
- case KEY_NUMPAD_SUBTRACT:
749
+ this.prev();
750
+ }
751
+ break;
752
+ case "ArrowLeft":
753
+ case "Left": // hack for IE and old Gecko
754
+ // No y-scrolling in thumb mode
755
+ if (this.constModeThumb != this.mode) {
702
756
  e.preventDefault();
703
- self.zoom(-1);
704
- break;
705
- case KEY_EQUAL:
706
- case KEY_EQUAL_F:
707
- case KEY_NUMPAD_ADD:
757
+ this.left();
758
+ }
759
+ break;
760
+ case "ArrowRight":
761
+ case "Right": // hack for IE and old Gecko
762
+ // No y-scrolling in thumb mode
763
+ if (this.constModeThumb != this.mode) {
708
764
  e.preventDefault();
709
- self.zoom(+1);
710
- break;
765
+ this.right();
711
766
  }
767
+ break;
768
+ // Zoom
769
+ case '-':
770
+ case 'Subtract':
771
+ e.preventDefault();
772
+ this.zoom(-1);
773
+ break;
774
+ case '+':
775
+ case '=':
776
+ case 'Add':
777
+ e.preventDefault();
778
+ this.zoom(1);
779
+ break;
780
+ // Fullscreen
781
+ case 'F':
782
+ case 'f':
783
+ e.preventDefault();
784
+ this.toggleFullscreen();
785
+ break;
712
786
  }
713
787
  });
714
788
  };
715
789
 
716
790
  BookReader.prototype.drawLeafs = function() {
717
791
  if (this.constMode1up == this.mode) {
718
- this.drawLeafsOnePage();
792
+ // Not needed for Mode1Up anymore
719
793
  } else if (this.constModeThumb == this.mode) {
720
794
  this.drawLeafsThumbnail();
721
795
  } else {
@@ -794,29 +868,11 @@ BookReader.prototype.drawLeafsThrottled = utils.throttle(
794
868
  * @param {number} direction Pass 1 to zoom in, anything else to zoom out
795
869
  */
796
870
  BookReader.prototype.zoom = function(direction) {
797
- switch (this.mode) {
798
- case this.constMode1up:
799
- if (direction == 1) {
800
- // XXX other cases
801
- this.zoom1up('in');
802
- } else {
803
- this.zoom1up('out');
804
- }
805
- break
806
- case this.constMode2up:
807
- if (direction == 1) {
808
- // XXX other cases
809
- this.zoom2up('in');
810
- } else {
811
- this.zoom2up('out');
812
- }
813
- break
814
- case this.constModeThumb:
815
- // XXX update zoomThumb for named directions
816
- this.zoomThumb(direction);
817
- break
871
+ if (direction == 1) {
872
+ this.activeMode.zoom('in');
873
+ } else {
874
+ this.activeMode.zoom('out');
818
875
  }
819
-
820
876
  this.textSelectionPlugin?.stopPageFlip(this.refs.$brContainer);
821
877
  return;
822
878
  };
@@ -842,7 +898,7 @@ BookReader.prototype.resizeBRcontainer = function(animate) {
842
898
  bottom: this.getFooterHeight()
843
899
  });
844
900
  }
845
- }
901
+ };
846
902
 
847
903
  BookReader.prototype.centerPageView = function() {
848
904
  var scrollWidth = this.refs.$brContainer.prop('scrollWidth');
@@ -954,7 +1010,7 @@ BookReader.prototype._isIndexDisplayed = function(index) {
954
1010
  return this.constMode1up == this.mode ? this.displayedIndices.slice(1, -1).includes(index) :
955
1011
  this.displayedIndices ? this.displayedIndices.includes(index) :
956
1012
  this.currentIndex() == index;
957
- }
1013
+ };
958
1014
 
959
1015
  /**
960
1016
  * Changes the current page
@@ -996,7 +1052,7 @@ BookReader.prototype.getPrevReadMode = function(mode) {
996
1052
  // Initial thumb, return 1up
997
1053
  return BookReader.constMode1up;
998
1054
  }
999
- }
1055
+ };
1000
1056
 
1001
1057
  /**
1002
1058
  * Switches the mode (eg 1up 2up thumb)
@@ -1024,10 +1080,13 @@ BookReader.prototype.switchMode = function(
1024
1080
  }
1025
1081
 
1026
1082
  this.trigger(BookReader.eventNames.stop);
1027
- if (this.enableSearch) this.removeSearchHilites();
1028
1083
 
1029
1084
  this.prevReadMode = this.getPrevReadMode(this.mode);
1030
1085
 
1086
+ if (this.mode != mode) {
1087
+ this.activeMode.unprepare?.();
1088
+ }
1089
+
1031
1090
  this.mode = mode;
1032
1091
 
1033
1092
  // reinstate scale if moving from thumbnail view
@@ -1040,8 +1099,6 @@ BookReader.prototype.switchMode = function(
1040
1099
 
1041
1100
  // XXX maybe better to preserve zoom in each mode
1042
1101
  if (this.constMode1up == mode) {
1043
- this.onePageCalculateReductionFactors();
1044
- this.reduce = this.quantizeReduce(this.reduce, this.onePage.reductionFactors);
1045
1102
  this.prepareOnePageView();
1046
1103
  } else if (this.constModeThumb == mode) {
1047
1104
  this.reduce = this.quantizeReduce(this.reduce, this.reductionFactors);
@@ -1095,11 +1152,11 @@ BookReader.prototype.isFullscreen = function() {
1095
1152
  * Toggles fullscreen
1096
1153
  * @param { boolean } bindKeyboardControls
1097
1154
  */
1098
- BookReader.prototype.toggleFullscreen = function(bindKeyboardControls = true) {
1155
+ BookReader.prototype.toggleFullscreen = async function(bindKeyboardControls = true) {
1099
1156
  if (this.isFullscreen()) {
1100
- this.exitFullScreen();
1157
+ await this.exitFullScreen();
1101
1158
  } else {
1102
- this.enterFullscreen(bindKeyboardControls);
1159
+ await this.enterFullscreen(bindKeyboardControls);
1103
1160
  }
1104
1161
  };
1105
1162
 
@@ -1111,7 +1168,7 @@ BookReader.prototype.toggleFullscreen = function(bindKeyboardControls = true) {
1111
1168
  * - fires custom event
1112
1169
  * @param { boolean } bindKeyboardControls
1113
1170
  */
1114
- BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
1171
+ BookReader.prototype.enterFullscreen = async function(bindKeyboardControls = true) {
1115
1172
  const currentIndex = this.currentIndex();
1116
1173
  this.refs.$brContainer.css('opacity', 0);
1117
1174
 
@@ -1119,7 +1176,7 @@ BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
1119
1176
  this._fullscreenCloseHandler = (e) => {
1120
1177
  if (e.keyCode === 27) this.toggleFullscreen();
1121
1178
  };
1122
- $(document).keyup(this._fullscreenCloseHandler);
1179
+ $(document).on("keyup", this._fullscreenCloseHandler);
1123
1180
  }
1124
1181
 
1125
1182
  const windowWidth = $(window).width();
@@ -1128,14 +1185,29 @@ BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
1128
1185
  }
1129
1186
 
1130
1187
  this.isFullscreenActive = true;
1131
-
1132
- this.refs.$brContainer.animate({opacity: 1}, 'fast', 'linear',() => {
1133
- this.resize();
1134
- this.jumpToIndex(currentIndex);
1135
- });
1188
+ // prioritize class updates so CSS can propagate
1189
+ this.updateBrClasses();
1190
+ this.animating = true;
1191
+ await new Promise(res => this.refs.$brContainer.animate({opacity: 1}, 'fast', 'linear', res));
1192
+ if (this.activeMode instanceof Mode1Up) {
1193
+ this.activeMode.mode1UpLit.scale = this.activeMode.mode1UpLit.computeDefaultScale(this._models.book.getPage(currentIndex));
1194
+ // Need the new scale to be applied before calling jumpToIndex
1195
+ await this.activeMode.mode1UpLit.requestUpdate();
1196
+ }
1197
+ this.jumpToIndex(currentIndex);
1198
+ this.animating = false;
1136
1199
 
1137
1200
  this.textSelectionPlugin?.stopPageFlip(this.refs.$brContainer);
1201
+ // Add "?view=theater"
1202
+ this.trigger(BookReader.eventNames.fragmentChange);
1203
+ // trigger event here, so that animations,
1204
+ // class updates happen before book-nav relays to web components
1138
1205
  this.trigger(BookReader.eventNames.fullscreenToggled);
1206
+
1207
+ setTimeout(() => {
1208
+ // resize book after all events & css updates
1209
+ this.resize();
1210
+ }, 0);
1139
1211
  };
1140
1212
 
1141
1213
  /**
@@ -1145,10 +1217,10 @@ BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
1145
1217
  * - fires custom event
1146
1218
  * @param { boolean } bindKeyboardControls
1147
1219
  */
1148
- BookReader.prototype.exitFullScreen = function() {
1220
+ BookReader.prototype.exitFullScreen = async function () {
1149
1221
  this.refs.$brContainer.css('opacity', 0);
1150
1222
 
1151
- $(document).unbind('keyup', this._fullscreenCloseHandler);
1223
+ $(document).off('keyup', this._fullscreenCloseHandler);
1152
1224
 
1153
1225
  var windowWidth = $(window).width();
1154
1226
 
@@ -1158,13 +1230,25 @@ BookReader.prototype.exitFullScreen = function() {
1158
1230
  }
1159
1231
 
1160
1232
  this.isFullscreenActive = false;
1233
+ // Trigger fullscreen event immediately
1234
+ // so that book-nav can relay to web components
1235
+ this.trigger(BookReader.eventNames.fullscreenToggled);
1236
+
1161
1237
  this.updateBrClasses();
1238
+ this.animating = true;
1239
+ await new Promise((res => this.refs.$brContainer.animate({opacity: 1}, 'fast', 'linear', res)));
1240
+ this.resize();
1241
+
1242
+ if (this.activeMode instanceof Mode1Up) {
1243
+ this.activeMode.mode1UpLit.scale = this.activeMode.mode1UpLit.computeDefaultScale(this._models.book.getPage(this.currentIndex()));
1244
+ await this.activeMode.mode1UpLit.requestUpdate();
1245
+ }
1246
+
1247
+ this.animating = false;
1162
1248
 
1163
- this.refs.$brContainer.animate({opacity: 1}, 'fast', 'linear', () => {
1164
- this.resize();
1165
- });
1166
1249
  this.textSelectionPlugin?.stopPageFlip(this.refs.$brContainer);
1167
- this.trigger(BookReader.eventNames.fullscreenToggled);
1250
+ // Remove "?view=theater"
1251
+ this.trigger(BookReader.eventNames.fragmentChange);
1168
1252
  };
1169
1253
 
1170
1254
  /**
@@ -1195,11 +1279,9 @@ BookReader.prototype.updateFirstIndex = function(
1195
1279
  index,
1196
1280
  { suppressFragmentChange = false } = {}
1197
1281
  ) {
1198
- // Called multiple times when defaults contains "mode/1up",
1199
- // including after init(). Skip fragment change if no index change
1200
- if (this.firstIndex === index) {
1201
- suppressFragmentChange = true;
1202
- }
1282
+ // If there's no change, do nothing
1283
+ if (this.firstIndex === index) return;
1284
+
1203
1285
  this.firstIndex = index;
1204
1286
  if (!(this.suppressFragmentChange || suppressFragmentChange)) {
1205
1287
  this.trigger(BookReader.eventNames.fragmentChange);
@@ -1364,35 +1446,14 @@ BookReader.prototype.pruneUnusedImgs = function() {
1364
1446
  BookReader.prototype.prepareOnePageView = Mode1Up.prototype.prepare;
1365
1447
  exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'prepare', 'prepareOnePageView');
1366
1448
  /** @deprecated not used outside BookReader */
1367
- BookReader.prototype.drawLeafsOnePage = Mode1Up.prototype.drawLeafs;
1368
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'drawLeafs', 'drawLeafsOnePage');
1369
- /** @deprecated not used outside BookReader */
1370
1449
  BookReader.prototype.zoom1up = Mode1Up.prototype.zoom;
1371
1450
  exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'zoom', 'zoom1up');
1372
- /** @deprecated not used outside Mode1Up */
1373
- BookReader.prototype.onePageGetAutofitWidth = Mode1Up.prototype.getAutofitWidth;
1374
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getAutofitWidth', 'onePageGetAutofitWidth');
1375
- /** @deprecated not used outside Mode1Up, BookReader */
1376
- BookReader.prototype.onePageGetAutofitHeight = Mode1Up.prototype.getAutofitHeight;
1377
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getAutofitHeight', 'onePageGetAutofitHeight');
1378
- /** @deprecated not used outside Mode1Up, BookReader */
1379
- BookReader.prototype.onePageGetPageTop = Mode1Up.prototype.getPageTop;
1380
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getPageTop', 'onePageGetPageTop');
1381
- /** @deprecated not used outside Mode1Up, BookReader */
1382
- BookReader.prototype.onePageCalculateReductionFactors = Mode1Up.prototype.calculateReductionFactors;
1383
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'calculateReductionFactors', 'onePageCalculateReductionFactors');
1384
1451
  /** @deprecated not used outside Mode1Up, BookReader */
1385
1452
  BookReader.prototype.resizePageView1up = Mode1Up.prototype.resizePageView;
1386
1453
  exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'resizePageView', 'resizePageView1up');
1387
1454
  /** @deprecated not used outside Mode1Up */
1388
1455
  BookReader.prototype.onePageCalculateViewDimensions = Mode1Up.prototype.calculateViewDimensions;
1389
1456
  exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'calculateViewDimensions', 'onePageCalculateViewDimensions');
1390
- /** @deprecated not used outside Mode1Up */
1391
- BookReader.prototype.centerX1up = Mode1Up.prototype.centerX;
1392
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'centerX', 'centerX1up');
1393
- /** @deprecated not used outside Mode1Up */
1394
- BookReader.prototype.centerY1up = Mode1Up.prototype.centerY;
1395
- exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'centerY', 'centerY1up');
1396
1457
 
1397
1458
  /************************/
1398
1459
  /** Mode2Up extensions **/
@@ -1409,9 +1470,6 @@ exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipFwdToIndex', 'flipFwdTo
1409
1470
  BookReader.prototype.setHilightCss2UP = Mode2Up.prototype.setHilightCss;
1410
1471
  exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setHilightCss', 'setHilightCss2UP');
1411
1472
  /** @deprecated not used outside Mode2Up */
1412
- BookReader.prototype.setClickHandler2UP = Mode2Up.prototype.setClickHandler;
1413
- exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setClickHandler', 'setClickHandler2UP');
1414
- /** @deprecated not used outside Mode2Up */
1415
1473
  BookReader.prototype.drawLeafsTwoPage = Mode2Up.prototype.drawLeafs;
1416
1474
  exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'drawLeafs', 'drawLeafsTwoPage');
1417
1475
  /** @deprecated not used outside BookReader */
@@ -1444,9 +1502,6 @@ exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipLeftToRight', 'flipLeft
1444
1502
  /** @deprecated unused outside BookReader, Mode2Up */
1445
1503
  BookReader.prototype.flipRightToLeft = Mode2Up.prototype.flipRightToLeft;
1446
1504
  exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipRightToLeft', 'flipRightToLeft');
1447
- /** @deprecated unused outside Mode2Up */
1448
- BookReader.prototype.setMouseHandlers2UP = Mode2Up.prototype.setMouseHandlers;
1449
- exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setMouseHandlers', 'setMouseHandlers2UP');
1450
1505
  /** @deprecated unused outside BookReader, Mode2Up */
1451
1506
  BookReader.prototype.prepareFlipLeftToRight = Mode2Up.prototype.prepareFlipLeftToRight;
1452
1507
  exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'prepareFlipLeftToRight', 'prepareFlipLeftToRight');
@@ -1527,15 +1582,6 @@ BookReader.prototype.stopFlipAnimations = function() {
1527
1582
  });
1528
1583
  };
1529
1584
 
1530
- /**
1531
- * Returns true if keyboard navigation should be disabled for the event
1532
- * @param {Event}
1533
- * @return {boolean}
1534
- */
1535
- BookReader.prototype.keyboardNavigationIsDisabled = function(event) {
1536
- return event.target.tagName == "INPUT";
1537
- };
1538
-
1539
1585
  /**
1540
1586
  * @template TClass extends { br: BookReader }
1541
1587
  * Helper method to expose a method onto BookReader from a composed class.
@@ -1566,9 +1612,6 @@ BookReader.prototype.updateViewModeButton = Navbar.prototype.updateViewModeButto
1566
1612
  exposeOverrideableMethod(Navbar, '_components.navbar', 'updateViewModeButton');
1567
1613
  BookReader.prototype.getNavPageNumString = Navbar.prototype.getNavPageNumString;
1568
1614
  exposeOverrideableMethod(Navbar, '_components.navbar', 'getNavPageNumString');
1569
- /** @deprecated */
1570
- BookReader.prototype.initEmbedNavbar = Navbar.prototype.initEmbed;
1571
- exposeOverrideableMethod(Navbar, '_components.navbar', 'initEmbed', 'initEmbedNavbar');
1572
1615
  /** @deprecated unused */
1573
1616
  BookReader.prototype.getNavPageNumHtml = getNavPageNumHtml;
1574
1617
  /** @deprecated unused outside this file */
@@ -1677,7 +1720,7 @@ BookReader.prototype.bindNavigationHandlers = function() {
1677
1720
 
1678
1721
  for (const control in navigationControls) {
1679
1722
  jIcons.filter(`.${control}`).on('click.bindNavigationHandlers', () => {
1680
- navigationControls[control]()
1723
+ navigationControls[control]();
1681
1724
  return false;
1682
1725
  });
1683
1726
  }
@@ -1707,7 +1750,7 @@ BookReader.prototype.bindNavigationHandlers = function() {
1707
1750
  $brNavCntlBtmEl.addClass('BRdn').removeClass('BRup');
1708
1751
  $brNavCntlTopEl.addClass('BRup').removeClass('BRdn');
1709
1752
  self.$('.BRnavCntlBtm.BRnavCntl').animate({height:'30px'});
1710
- self.$('.BRvavCntl').animate({opacity:1})
1753
+ self.$('.BRvavCntl').animate({opacity:1});
1711
1754
  }
1712
1755
  $.when.apply($, promises).done(function() {
1713
1756
  // Only do full resize in auto mode and need to recalc. size
@@ -1725,24 +1768,28 @@ BookReader.prototype.bindNavigationHandlers = function() {
1725
1768
  });
1726
1769
  }
1727
1770
  );
1728
- $brNavCntlBtmEl.mouseover(function() {
1729
- if ($(this).hasClass('BRup')) {
1730
- self.$('.BRnavCntl').animate({opacity:1},250);
1731
- }
1732
- }).mouseleave(function() {
1733
- if ($(this).hasClass('BRup')) {
1734
- self.$('.BRnavCntl').animate({opacity:.75},250);
1735
- }
1736
- });
1737
- $brNavCntlTopEl.mouseover(function() {
1738
- if ($(this).hasClass('BRdn')) {
1739
- self.$('.BRnavCntl').animate({opacity:1},250);
1740
- }
1741
- }).mouseleave(function() {
1742
- if ($(this).hasClass('BRdn')) {
1743
- self.$('.BRnavCntl').animate({opacity:.75},250);
1744
- }
1745
- });
1771
+ $brNavCntlBtmEl
1772
+ .on("mouseover", function() {
1773
+ if ($(this).hasClass('BRup')) {
1774
+ self.$('.BRnavCntl').animate({opacity:1},250);
1775
+ }
1776
+ })
1777
+ .on("mouseleave", function() {
1778
+ if ($(this).hasClass('BRup')) {
1779
+ self.$('.BRnavCntl').animate({opacity:.75},250);
1780
+ }
1781
+ });
1782
+ $brNavCntlTopEl
1783
+ .on("mouseover", function() {
1784
+ if ($(this).hasClass('BRdn')) {
1785
+ self.$('.BRnavCntl').animate({opacity:1},250);
1786
+ }
1787
+ })
1788
+ .on("mouseleave", function() {
1789
+ if ($(this).hasClass('BRdn')) {
1790
+ self.$('.BRnavCntl').animate({opacity:.75},250);
1791
+ }
1792
+ });
1746
1793
 
1747
1794
  this.initSwipeData();
1748
1795
 
@@ -1807,7 +1854,7 @@ BookReader.prototype.initSwipeData = function(clientX, clientY) {
1807
1854
  deltaX: 0,
1808
1855
  deltaY: 0,
1809
1856
  deltaT: 0
1810
- }
1857
+ };
1811
1858
  };
1812
1859
 
1813
1860
  BookReader.prototype.swipeMousedownHandler = function(event) {
@@ -1819,13 +1866,13 @@ BookReader.prototype.swipeMousedownHandler = function(event) {
1819
1866
  return !self.protected;
1820
1867
  }
1821
1868
 
1822
- $(event.target).bind('mouseout.swipe',
1869
+ $(event.target).on('mouseout.swipe',
1823
1870
  { 'br': self},
1824
1871
  self.swipeMouseupHandler
1825
- ).bind('mouseup.swipe',
1872
+ ).on('mouseup.swipe',
1826
1873
  { 'br': self},
1827
1874
  self.swipeMouseupHandler
1828
- ).bind('mousemove.swipe',
1875
+ ).on('mousemove.swipe',
1829
1876
  { 'br': self },
1830
1877
  self.swipeMousemoveHandler
1831
1878
  );
@@ -1895,7 +1942,7 @@ BookReader.prototype.swipeMouseupHandler = function(event) {
1895
1942
  _swipe.mightBeSwiping = false;
1896
1943
  _swipe.mightBeDragging = false;
1897
1944
 
1898
- $(event.target).unbind('mouseout.swipe').unbind('mouseup.swipe').unbind('mousemove.swipe');
1945
+ $(event.target).off('mouseout.swipe').off('mouseup.swipe').off('mousemove.swipe');
1899
1946
 
1900
1947
  if (_swipe.didSwipe || _swipe.didDrag) {
1901
1948
  // Swallow event if completed swipe gesture
@@ -1911,17 +1958,18 @@ BookReader.prototype.bindMozTouchHandlers = function() {
1911
1958
  var self = this;
1912
1959
 
1913
1960
  // Currently only want touch handlers in 2up
1914
- this.refs.$br.bind('MozTouchDown', function(event) {
1915
- if (this.mode == self.constMode2up) {
1916
- event.preventDefault();
1917
- }
1918
- })
1919
- .bind('MozTouchMove', function(event) {
1961
+ this.refs.$br
1962
+ .on('MozTouchDown', function(event) {
1920
1963
  if (this.mode == self.constMode2up) {
1921
1964
  event.preventDefault();
1922
1965
  }
1923
1966
  })
1924
- .bind('MozTouchUp', function(event) {
1967
+ .on('MozTouchMove', function(event) {
1968
+ if (this.mode == self.constMode2up) {
1969
+ event.preventDefault();
1970
+ }
1971
+ })
1972
+ .on('MozTouchUp', function(event) {
1925
1973
  if (this.mode == self.constMode2up) {
1926
1974
  event.preventDefault();
1927
1975
  }
@@ -2199,7 +2247,7 @@ BookReader.prototype._getPageURISrcset = function(index, reduce, rotate) {
2199
2247
  }
2200
2248
 
2201
2249
  return page.getURISrcSet(reduce, rotate);
2202
- }
2250
+ };
2203
2251
 
2204
2252
 
2205
2253
  /**
@@ -2225,21 +2273,37 @@ BookReader.prototype._getPageURI = function(index, reduce, rotate) {
2225
2273
  };
2226
2274
 
2227
2275
  /**
2228
- * @param {string}
2276
+ * @param {string} msg
2277
+ * @param {function|undefined} onCloseCallback
2229
2278
  */
2230
- BookReader.prototype.showProgressPopup = function(msg) {
2279
+ BookReader.prototype.showProgressPopup = function(msg, onCloseCallback) {
2231
2280
  if (this.popup) return;
2232
2281
 
2233
2282
  this.popup = document.createElement("div");
2234
2283
  $(this.popup).prop('className', 'BRprogresspopup');
2235
- var bar = document.createElement("div");
2284
+
2285
+ if (typeof(onCloseCallback) === 'function') {
2286
+ const closeButton = document.createElement('button');
2287
+ closeButton.setAttribute('title', 'close');
2288
+ closeButton.setAttribute('class', 'close-popup');
2289
+ const icon = document.createElement('span');
2290
+ icon.setAttribute('class', 'icon icon-close-dark');
2291
+ $(closeButton).append(icon);
2292
+ closeButton.addEventListener('click', () => {
2293
+ onCloseCallback();
2294
+ this.removeProgressPopup();
2295
+ });
2296
+ $(this.popup).append(closeButton);
2297
+ }
2298
+
2299
+ const bar = document.createElement("div");
2236
2300
  $(bar).css({
2237
2301
  height: '20px'
2238
2302
  }).prop('className', 'BRprogressbar');
2239
2303
  $(this.popup).append(bar);
2240
2304
 
2241
2305
  if (msg) {
2242
- var msgdiv = document.createElement("div");
2306
+ const msgdiv = document.createElement("div");
2243
2307
  msgdiv.innerHTML = msg;
2244
2308
  $(this.popup).append(msgdiv);
2245
2309
  }
@@ -2296,7 +2360,7 @@ BookReader.prototype.initUIStrings = function() {
2296
2360
  for (var icon in titles) {
2297
2361
  this.$(icon).prop('title', titles[icon]);
2298
2362
  }
2299
- }
2363
+ };
2300
2364
 
2301
2365
  /**
2302
2366
  * Reloads images. Useful when some images might have failed.
@@ -2327,7 +2391,7 @@ BookReader.prototype.getFooterHeight = function() {
2327
2391
  }
2328
2392
  }
2329
2393
  return 0;
2330
- }
2394
+ };
2331
2395
 
2332
2396
  // Basic Usage built-in Methods (can be overridden through options)
2333
2397
  // This implementation uses options.data value for populating BookReader
@@ -2339,6 +2403,7 @@ BookReader.prototype.getFooterHeight = function() {
2339
2403
  BookReader.prototype.paramsFromCurrent = function() {
2340
2404
  var params = {};
2341
2405
 
2406
+ // Path params
2342
2407
  var index = this.currentIndex();
2343
2408
  var pageNum = this._models.book.getPageNum(index);
2344
2409
  if ((pageNum === 0) || pageNum) {
@@ -2348,10 +2413,17 @@ BookReader.prototype.paramsFromCurrent = function() {
2348
2413
  params.index = index;
2349
2414
  params.mode = this.mode;
2350
2415
 
2416
+ // Unused params
2351
2417
  // $$$ highlight
2352
2418
  // $$$ region
2353
2419
 
2354
- // search
2420
+ // Querystring params
2421
+ // View
2422
+ const fullscreenView = 'theater';
2423
+ if (this.isFullscreenActive) {
2424
+ params.view = fullscreenView;
2425
+ }
2426
+ // Search
2355
2427
  if (this.enableSearch) {
2356
2428
  params.search = this.searchTerm;
2357
2429
  }
@@ -2422,7 +2494,7 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
2422
2494
 
2423
2495
  // $$$ process /theme
2424
2496
  if (urlHash['theme'] != undefined) {
2425
- params.theme = urlHash['theme']
2497
+ params.theme = urlHash['theme'];
2426
2498
  }
2427
2499
  return params;
2428
2500
  };
@@ -2479,6 +2551,9 @@ BookReader.prototype.fragmentFromParams = function(params, urlMode = 'hash') {
2479
2551
  /**
2480
2552
  * Create, update querystring from the params object
2481
2553
  *
2554
+ * Handles:
2555
+ * view=
2556
+ * q=
2482
2557
  * @param {Object} params
2483
2558
  * @param {string} currQueryString
2484
2559
  * @param {string} [urlMode]
@@ -2490,21 +2565,30 @@ BookReader.prototype.queryStringFromParams = function(
2490
2565
  urlMode = 'hash'
2491
2566
  ) {
2492
2567
  const newParams = new URLSearchParams(currQueryString);
2568
+
2569
+ if (params.view) {
2570
+ // Set ?view=theater when fullscreen
2571
+ newParams.set('view', params.view);
2572
+ } else {
2573
+ // Remove
2574
+ newParams.delete('view');
2575
+ }
2576
+
2493
2577
  if (params.search && urlMode === 'history') {
2494
- newParams.set('q', params.search)
2578
+ newParams.set('q', params.search);
2495
2579
  }
2496
2580
  // https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/toString
2497
2581
  // Note: This method returns the query string without the question mark.
2498
2582
  const result = newParams.toString();
2499
2583
  return result ? '?' + result : '';
2500
- }
2584
+ };
2501
2585
 
2502
2586
  /**
2503
2587
  * Helper to select within instance's elements
2504
2588
  */
2505
2589
  BookReader.prototype.$ = function(selector) {
2506
2590
  return this.refs.$br.find(selector);
2507
- }
2591
+ };
2508
2592
 
2509
2593
  /**
2510
2594
  * Polyfill for deprecated method