@internetarchive/bookreader 5.0.0-18

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 (428) hide show
  1. package/.eslintrc.js +58 -0
  2. package/.gitattributes +2 -0
  3. package/.github/ISSUE_TEMPLATE/bug.md +32 -0
  4. package/.github/ISSUE_TEMPLATE/feature-request.md +30 -0
  5. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +15 -0
  6. package/.github/dependabot.yml +8 -0
  7. package/.github/workflows/node.js.yml +37 -0
  8. package/.github/workflows/npm-publish.yml +47 -0
  9. package/.testcaferc.json +5 -0
  10. package/BookReader/BookReader.css +2983 -0
  11. package/BookReader/BookReader.js +3 -0
  12. package/BookReader/BookReader.js.LICENSE.txt +117 -0
  13. package/BookReader/BookReader.js.map +1 -0
  14. package/BookReader/bookreader-component-bundle.js +1436 -0
  15. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +27 -0
  16. package/BookReader/bookreader-component-bundle.js.map +1 -0
  17. package/BookReader/icons/1up.svg +1 -0
  18. package/BookReader/icons/2up.svg +1 -0
  19. package/BookReader/icons/advance.svg +3 -0
  20. package/BookReader/icons/chevron-right.svg +1 -0
  21. package/BookReader/icons/close-circle-dark.svg +1 -0
  22. package/BookReader/icons/close-circle.svg +1 -0
  23. package/BookReader/icons/fullscreen.svg +1 -0
  24. package/BookReader/icons/fullscreen_exit.svg +1 -0
  25. package/BookReader/icons/hamburger.svg +1 -0
  26. package/BookReader/icons/left-arrow.svg +1 -0
  27. package/BookReader/icons/magnify-minus.svg +1 -0
  28. package/BookReader/icons/magnify-plus.svg +1 -0
  29. package/BookReader/icons/magnify.svg +1 -0
  30. package/BookReader/icons/pause.svg +1 -0
  31. package/BookReader/icons/play.svg +1 -0
  32. package/BookReader/icons/playback-speed.svg +1 -0
  33. package/BookReader/icons/read-aloud.svg +1 -0
  34. package/BookReader/icons/review.svg +3 -0
  35. package/BookReader/icons/thumbnails.svg +1 -0
  36. package/BookReader/icons/volume-full.svg +1 -0
  37. package/BookReader/images/BRicons.png +0 -0
  38. package/BookReader/images/BRicons.svg +5 -0
  39. package/BookReader/images/BRicons_ia.png +0 -0
  40. package/BookReader/images/back_pages.png +0 -0
  41. package/BookReader/images/book_bottom_icon.png +0 -0
  42. package/BookReader/images/book_down_icon.png +0 -0
  43. package/BookReader/images/book_left_icon.png +0 -0
  44. package/BookReader/images/book_leftmost_icon.png +0 -0
  45. package/BookReader/images/book_right_icon.png +0 -0
  46. package/BookReader/images/book_rightmost_icon.png +0 -0
  47. package/BookReader/images/book_top_icon.png +0 -0
  48. package/BookReader/images/book_up_icon.png +0 -0
  49. package/BookReader/images/books_graphic.svg +1 -0
  50. package/BookReader/images/booksplit.png +0 -0
  51. package/BookReader/images/control_pause_icon.png +0 -0
  52. package/BookReader/images/control_play_icon.png +0 -0
  53. package/BookReader/images/embed_icon.png +0 -0
  54. package/BookReader/images/icon-home-ia.png +0 -0
  55. package/BookReader/images/icon_OL-logo-xs.png +0 -0
  56. package/BookReader/images/icon_alert-xs.png +0 -0
  57. package/BookReader/images/icon_book.svg +1 -0
  58. package/BookReader/images/icon_bookmark.svg +1 -0
  59. package/BookReader/images/icon_close-pop.png +0 -0
  60. package/BookReader/images/icon_download.png +0 -0
  61. package/BookReader/images/icon_gear.svg +1 -0
  62. package/BookReader/images/icon_hamburger.svg +1 -0
  63. package/BookReader/images/icon_home.png +0 -0
  64. package/BookReader/images/icon_home.svg +1 -0
  65. package/BookReader/images/icon_home_ia.png +0 -0
  66. package/BookReader/images/icon_indicator.png +0 -0
  67. package/BookReader/images/icon_info.svg +1 -0
  68. package/BookReader/images/icon_one_page.svg +1 -0
  69. package/BookReader/images/icon_pause.svg +1 -0
  70. package/BookReader/images/icon_play.svg +1 -0
  71. package/BookReader/images/icon_playback-rate.svg +1 -0
  72. package/BookReader/images/icon_return.png +0 -0
  73. package/BookReader/images/icon_search_button.svg +1 -0
  74. package/BookReader/images/icon_share.svg +1 -0
  75. package/BookReader/images/icon_skip-ahead.svg +1 -0
  76. package/BookReader/images/icon_skip-back.svg +2 -0
  77. package/BookReader/images/icon_speaker.svg +1 -0
  78. package/BookReader/images/icon_speaker_open.svg +1 -0
  79. package/BookReader/images/icon_thumbnails.svg +1 -0
  80. package/BookReader/images/icon_toc.svg +1 -0
  81. package/BookReader/images/icon_two_pages.svg +1 -0
  82. package/BookReader/images/icon_zoomer.png +0 -0
  83. package/BookReader/images/loading.gif +0 -0
  84. package/BookReader/images/logo_icon.png +0 -0
  85. package/BookReader/images/marker_chap-off.png +0 -0
  86. package/BookReader/images/marker_chap-off.svg +1 -0
  87. package/BookReader/images/marker_chap-off_ia.png +0 -0
  88. package/BookReader/images/marker_chap-on.png +0 -0
  89. package/BookReader/images/marker_chap-on.svg +1 -0
  90. package/BookReader/images/marker_srch-on.svg +1 -0
  91. package/BookReader/images/marker_srchchap-off.png +0 -0
  92. package/BookReader/images/marker_srchchap-on.png +0 -0
  93. package/BookReader/images/nav_control-dn.png +0 -0
  94. package/BookReader/images/nav_control-dn_ia.png +0 -0
  95. package/BookReader/images/nav_control-up.png +0 -0
  96. package/BookReader/images/nav_control-up_ia.png +0 -0
  97. package/BookReader/images/nav_control.png +0 -0
  98. package/BookReader/images/one_page_mode_icon.png +0 -0
  99. package/BookReader/images/paper-badge.png +0 -0
  100. package/BookReader/images/print_icon.png +0 -0
  101. package/BookReader/images/progressbar.gif +0 -0
  102. package/BookReader/images/right_edges.png +0 -0
  103. package/BookReader/images/slider.png +0 -0
  104. package/BookReader/images/slider_ia.png +0 -0
  105. package/BookReader/images/thumbnail_mode_icon.png +0 -0
  106. package/BookReader/images/transparent.png +0 -0
  107. package/BookReader/images/two_page_mode_icon.png +0 -0
  108. package/BookReader/images/zoom_in_icon.png +0 -0
  109. package/BookReader/images/zoom_out_icon.png +0 -0
  110. package/BookReader/jquery-1.10.1.js +2 -0
  111. package/BookReader/jquery-1.10.1.js.LICENSE.txt +24 -0
  112. package/BookReader/plugins/plugin.archive_analytics.js +2 -0
  113. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -0
  114. package/BookReader/plugins/plugin.autoplay.js +2 -0
  115. package/BookReader/plugins/plugin.autoplay.js.map +1 -0
  116. package/BookReader/plugins/plugin.chapters.js +2 -0
  117. package/BookReader/plugins/plugin.chapters.js.map +1 -0
  118. package/BookReader/plugins/plugin.iframe.js +2 -0
  119. package/BookReader/plugins/plugin.iframe.js.map +1 -0
  120. package/BookReader/plugins/plugin.mobile_nav.js +2 -0
  121. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -0
  122. package/BookReader/plugins/plugin.resume.js +2 -0
  123. package/BookReader/plugins/plugin.resume.js.map +1 -0
  124. package/BookReader/plugins/plugin.search.js +2 -0
  125. package/BookReader/plugins/plugin.search.js.map +1 -0
  126. package/BookReader/plugins/plugin.text_selection.js +2 -0
  127. package/BookReader/plugins/plugin.text_selection.js.map +1 -0
  128. package/BookReader/plugins/plugin.tts.js +3 -0
  129. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +27 -0
  130. package/BookReader/plugins/plugin.tts.js.map +1 -0
  131. package/BookReader/plugins/plugin.url.js +2 -0
  132. package/BookReader/plugins/plugin.url.js.map +1 -0
  133. package/BookReader/plugins/plugin.vendor-fullscreen.js +2 -0
  134. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -0
  135. package/BookReaderDemo/BookReaderDemo.css +41 -0
  136. package/BookReaderDemo/BookReaderJSAdvanced.js +115 -0
  137. package/BookReaderDemo/BookReaderJSAutoplay.js +56 -0
  138. package/BookReaderDemo/BookReaderJSSimple.js +55 -0
  139. package/BookReaderDemo/IIIFBookReader.js +207 -0
  140. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +1 -0
  141. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +1 -0
  142. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  143. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  144. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  145. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +1 -0
  146. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +1 -0
  147. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  148. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  149. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  150. package/BookReaderDemo/bookreader-template-bundle.js +7178 -0
  151. package/BookReaderDemo/demo-advanced.html +32 -0
  152. package/BookReaderDemo/demo-autoplay.html +38 -0
  153. package/BookReaderDemo/demo-embed-iframe-src.html +84 -0
  154. package/BookReaderDemo/demo-embed.html +26 -0
  155. package/BookReaderDemo/demo-fullscreen-mobile.html +36 -0
  156. package/BookReaderDemo/demo-fullscreen.html +33 -0
  157. package/BookReaderDemo/demo-iiif.html +34 -0
  158. package/BookReaderDemo/demo-iiif.js +26 -0
  159. package/BookReaderDemo/demo-internetarchive.html +74 -0
  160. package/BookReaderDemo/demo-multiple.html +43 -0
  161. package/BookReaderDemo/demo-preview-pages.html +1092 -0
  162. package/BookReaderDemo/demo-simple.html +34 -0
  163. package/BookReaderDemo/demo-vendor-fullscreen.html +36 -0
  164. package/BookReaderDemo/immersion-1up.html +64 -0
  165. package/BookReaderDemo/immersion-mode.html +35 -0
  166. package/BookReaderDemo/toggle_controls.html +53 -0
  167. package/BookReaderDemo/view_mode.html +39 -0
  168. package/BookReaderDemo/viewmode-cycle.html +41 -0
  169. package/CHANGELOG.md +540 -0
  170. package/CONTRIBUTING.md +7 -0
  171. package/LICENSE +661 -0
  172. package/README.md +205 -0
  173. package/babel.config.js +18 -0
  174. package/codecov.yml +17 -0
  175. package/index.html +31 -0
  176. package/jsconfig.json +14 -0
  177. package/karma.conf.js +23 -0
  178. package/package.json +129 -0
  179. package/screenshot.png +0 -0
  180. package/scripts/postversion.js +10 -0
  181. package/scripts/preversion.js +14 -0
  182. package/scripts/version.js +26 -0
  183. package/src/BookNavigator/BookModel.js +14 -0
  184. package/src/BookNavigator/BookNavigator.js +468 -0
  185. package/src/BookNavigator/assets/book-loader.js +27 -0
  186. package/src/BookNavigator/assets/bookmark-colors.js +15 -0
  187. package/src/BookNavigator/assets/button-base.js +61 -0
  188. package/src/BookNavigator/assets/icon_checkmark.js +6 -0
  189. package/src/BookNavigator/assets/icon_close.js +3 -0
  190. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  191. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  192. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  193. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  194. package/src/BookNavigator/bookmarks/bookmark-button.js +64 -0
  195. package/src/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  196. package/src/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  197. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  198. package/src/BookNavigator/bookmarks/bookmarks-provider.js +53 -0
  199. package/src/BookNavigator/bookmarks/ia-bookmarks.js +500 -0
  200. package/src/BookNavigator/br-fullscreen-mgr.js +83 -0
  201. package/src/BookNavigator/delete-modal-actions.js +49 -0
  202. package/src/BookNavigator/downloads/downloads-provider.js +76 -0
  203. package/src/BookNavigator/downloads/downloads.js +138 -0
  204. package/src/BookNavigator/search/a-search-result.js +55 -0
  205. package/src/BookNavigator/search/search-provider.js +180 -0
  206. package/src/BookNavigator/search/search-results.js +360 -0
  207. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +93 -0
  208. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  209. package/src/BookNavigator/volumes/volumes-provider.js +83 -0
  210. package/src/BookNavigator/volumes/volumes.js +178 -0
  211. package/src/BookReader/BookModel.js +518 -0
  212. package/src/BookReader/DebugConsole.js +54 -0
  213. package/src/BookReader/ImageCache.js +116 -0
  214. package/src/BookReader/Mode1Up.js +90 -0
  215. package/src/BookReader/Mode1UpLit.js +434 -0
  216. package/src/BookReader/Mode2Up.js +1372 -0
  217. package/src/BookReader/ModeSmoothZoom.js +177 -0
  218. package/src/BookReader/ModeThumb.js +336 -0
  219. package/src/BookReader/Navbar/Navbar.js +339 -0
  220. package/src/BookReader/PageContainer.js +120 -0
  221. package/src/BookReader/ReduceSet.js +26 -0
  222. package/src/BookReader/Toolbar/Toolbar.js +384 -0
  223. package/src/BookReader/events.js +20 -0
  224. package/src/BookReader/options.js +320 -0
  225. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  226. package/src/BookReader/utils/classes.js +36 -0
  227. package/src/BookReader/utils.js +240 -0
  228. package/src/BookReader.js +2546 -0
  229. package/src/BookReaderComponent/BookReaderComponent.js +112 -0
  230. package/src/ItemNavigator/ItemNavigator.js +376 -0
  231. package/src/ItemNavigator/providers/sharing.js +33 -0
  232. package/src/assets/icons/1up.svg +12 -0
  233. package/src/assets/icons/2up.svg +15 -0
  234. package/src/assets/icons/advance.svg +26 -0
  235. package/src/assets/icons/chevron-right.svg +1 -0
  236. package/src/assets/icons/close-circle-dark.svg +1 -0
  237. package/src/assets/icons/close-circle.svg +1 -0
  238. package/src/assets/icons/fullscreen.svg +17 -0
  239. package/src/assets/icons/fullscreen_exit.svg +17 -0
  240. package/src/assets/icons/hamburger.svg +15 -0
  241. package/src/assets/icons/left-arrow.svg +12 -0
  242. package/src/assets/icons/magnify-minus.svg +16 -0
  243. package/src/assets/icons/magnify-plus.svg +17 -0
  244. package/src/assets/icons/magnify.svg +15 -0
  245. package/src/assets/icons/pause.svg +23 -0
  246. package/src/assets/icons/play.svg +22 -0
  247. package/src/assets/icons/playback-speed.svg +34 -0
  248. package/src/assets/icons/read-aloud.svg +22 -0
  249. package/src/assets/icons/review.svg +22 -0
  250. package/src/assets/icons/thumbnails.svg +17 -0
  251. package/src/assets/icons/volume-full.svg +22 -0
  252. package/src/assets/images/BRicons.png +0 -0
  253. package/src/assets/images/BRicons.svg +94 -0
  254. package/src/assets/images/BRicons_ia.png +0 -0
  255. package/src/assets/images/back_pages.png +0 -0
  256. package/src/assets/images/book_bottom_icon.png +0 -0
  257. package/src/assets/images/book_down_icon.png +0 -0
  258. package/src/assets/images/book_left_icon.png +0 -0
  259. package/src/assets/images/book_leftmost_icon.png +0 -0
  260. package/src/assets/images/book_right_icon.png +0 -0
  261. package/src/assets/images/book_rightmost_icon.png +0 -0
  262. package/src/assets/images/book_top_icon.png +0 -0
  263. package/src/assets/images/book_up_icon.png +0 -0
  264. package/src/assets/images/books_graphic.svg +177 -0
  265. package/src/assets/images/booksplit.png +0 -0
  266. package/src/assets/images/control_pause_icon.png +0 -0
  267. package/src/assets/images/control_play_icon.png +0 -0
  268. package/src/assets/images/embed_icon.png +0 -0
  269. package/src/assets/images/icon-home-ia.png +0 -0
  270. package/src/assets/images/icon_OL-logo-xs.png +0 -0
  271. package/src/assets/images/icon_alert-xs.png +0 -0
  272. package/src/assets/images/icon_book.svg +12 -0
  273. package/src/assets/images/icon_bookmark.svg +12 -0
  274. package/src/assets/images/icon_close-pop.png +0 -0
  275. package/src/assets/images/icon_download.png +0 -0
  276. package/src/assets/images/icon_gear.svg +14 -0
  277. package/src/assets/images/icon_hamburger.svg +20 -0
  278. package/src/assets/images/icon_home.png +0 -0
  279. package/src/assets/images/icon_home.svg +21 -0
  280. package/src/assets/images/icon_home_ia.png +0 -0
  281. package/src/assets/images/icon_indicator.png +0 -0
  282. package/src/assets/images/icon_info.svg +11 -0
  283. package/src/assets/images/icon_one_page.svg +8 -0
  284. package/src/assets/images/icon_pause.svg +1 -0
  285. package/src/assets/images/icon_play.svg +1 -0
  286. package/src/assets/images/icon_playback-rate.svg +15 -0
  287. package/src/assets/images/icon_return.png +0 -0
  288. package/src/assets/images/icon_search_button.svg +8 -0
  289. package/src/assets/images/icon_share.svg +9 -0
  290. package/src/assets/images/icon_skip-ahead.svg +6 -0
  291. package/src/assets/images/icon_skip-back.svg +13 -0
  292. package/src/assets/images/icon_speaker.svg +18 -0
  293. package/src/assets/images/icon_speaker_open.svg +10 -0
  294. package/src/assets/images/icon_thumbnails.svg +12 -0
  295. package/src/assets/images/icon_toc.svg +5 -0
  296. package/src/assets/images/icon_two_pages.svg +9 -0
  297. package/src/assets/images/icon_zoomer.png +0 -0
  298. package/src/assets/images/loading.gif +0 -0
  299. package/src/assets/images/logo_icon.png +0 -0
  300. package/src/assets/images/marker_chap-off.png +0 -0
  301. package/src/assets/images/marker_chap-off.svg +11 -0
  302. package/src/assets/images/marker_chap-off_ia.png +0 -0
  303. package/src/assets/images/marker_chap-on.png +0 -0
  304. package/src/assets/images/marker_chap-on.svg +11 -0
  305. package/src/assets/images/marker_srch-on.svg +11 -0
  306. package/src/assets/images/marker_srchchap-off.png +0 -0
  307. package/src/assets/images/marker_srchchap-on.png +0 -0
  308. package/src/assets/images/nav_control-dn.png +0 -0
  309. package/src/assets/images/nav_control-dn_ia.png +0 -0
  310. package/src/assets/images/nav_control-up.png +0 -0
  311. package/src/assets/images/nav_control-up_ia.png +0 -0
  312. package/src/assets/images/nav_control.png +0 -0
  313. package/src/assets/images/one_page_mode_icon.png +0 -0
  314. package/src/assets/images/paper-badge.png +0 -0
  315. package/src/assets/images/print_icon.png +0 -0
  316. package/src/assets/images/progressbar.gif +0 -0
  317. package/src/assets/images/right_edges.png +0 -0
  318. package/src/assets/images/slider.png +0 -0
  319. package/src/assets/images/slider_ia.png +0 -0
  320. package/src/assets/images/thumbnail_mode_icon.png +0 -0
  321. package/src/assets/images/transparent.png +0 -0
  322. package/src/assets/images/two_page_mode_icon.png +0 -0
  323. package/src/assets/images/zoom_in_icon.png +0 -0
  324. package/src/assets/images/zoom_out_icon.png +0 -0
  325. package/src/css/BookReader.scss +89 -0
  326. package/src/css/_BRBookmarks.scss +29 -0
  327. package/src/css/_BRComponent.scss +13 -0
  328. package/src/css/_BRfloat.scss +197 -0
  329. package/src/css/_BRicon.scss +48 -0
  330. package/src/css/_BRmain.scss +251 -0
  331. package/src/css/_BRnav.scss +382 -0
  332. package/src/css/_BRpages.scss +139 -0
  333. package/src/css/_BRsearch.scss +226 -0
  334. package/src/css/_BRtoolbar.scss +84 -0
  335. package/src/css/_BRvendor.scss +5 -0
  336. package/src/css/_MobileNav.scss +194 -0
  337. package/src/css/_TextSelection.scss +32 -0
  338. package/src/css/_colorbox.scss +52 -0
  339. package/src/css/_controls.scss +244 -0
  340. package/src/css/_icons.scss +121 -0
  341. package/src/dragscrollable-br.js +261 -0
  342. package/src/jquery-wrapper.js +4 -0
  343. package/src/plugins/plugin.archive_analytics.js +86 -0
  344. package/src/plugins/plugin.autoplay.js +129 -0
  345. package/src/plugins/plugin.chapters.js +251 -0
  346. package/src/plugins/plugin.iframe.js +48 -0
  347. package/src/plugins/plugin.mobile_nav.js +287 -0
  348. package/src/plugins/plugin.resume.js +68 -0
  349. package/src/plugins/plugin.text_selection.js +291 -0
  350. package/src/plugins/plugin.url.js +198 -0
  351. package/src/plugins/plugin.vendor-fullscreen.js +247 -0
  352. package/src/plugins/search/plugin.search.js +439 -0
  353. package/src/plugins/search/view.js +440 -0
  354. package/src/plugins/tts/AbstractTTSEngine.js +242 -0
  355. package/src/plugins/tts/FestivalTTSEngine.js +169 -0
  356. package/src/plugins/tts/PageChunk.js +107 -0
  357. package/src/plugins/tts/PageChunkIterator.js +163 -0
  358. package/src/plugins/tts/WebTTSEngine.js +352 -0
  359. package/src/plugins/tts/plugin.tts.js +335 -0
  360. package/src/plugins/tts/tooltip_dict.js +15 -0
  361. package/src/plugins/tts/utils.js +91 -0
  362. package/src/util/browserSniffing.js +30 -0
  363. package/src/util/debouncer.js +26 -0
  364. package/src/util/docCookies.js +67 -0
  365. package/src/util/strings.js +34 -0
  366. package/tests/BookReader/BookModel.test.js +312 -0
  367. package/tests/BookReader/BookReaderPublicFunctions.test.js +164 -0
  368. package/tests/BookReader/DebugConsole.test.js +25 -0
  369. package/tests/BookReader/ImageCache.test.js +150 -0
  370. package/tests/BookReader/Mode1UpLit.test.js +87 -0
  371. package/tests/BookReader/Mode2Up.test.js +245 -0
  372. package/tests/BookReader/ModeSmoothZoom.test.js +149 -0
  373. package/tests/BookReader/Navbar/Navbar.test.js +169 -0
  374. package/tests/BookReader/PageContainer.test.js +187 -0
  375. package/tests/BookReader/ReduceSet.test.js +38 -0
  376. package/tests/BookReader/Toolbar/Toolbar.test.js +26 -0
  377. package/tests/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  378. package/tests/BookReader/utils/classes.test.js +88 -0
  379. package/tests/BookReader/utils.test.js +136 -0
  380. package/tests/BookReader.options.test.js +39 -0
  381. package/tests/BookReader.test.js +301 -0
  382. package/tests/e2e/README.md +75 -0
  383. package/tests/e2e/autoplay.test.js +13 -0
  384. package/tests/e2e/base.test.js +35 -0
  385. package/tests/e2e/helpers/base.js +263 -0
  386. package/tests/e2e/helpers/debug.js +13 -0
  387. package/tests/e2e/helpers/desktopSearch.js +72 -0
  388. package/tests/e2e/helpers/mobileSearch.js +85 -0
  389. package/tests/e2e/helpers/mockSearch.js +93 -0
  390. package/tests/e2e/helpers/rightToLeft.js +29 -0
  391. package/tests/e2e/ia-production/ia-prod-base.js +17 -0
  392. package/tests/e2e/models/BookReader.js +11 -0
  393. package/tests/e2e/models/Navigation.js +56 -0
  394. package/tests/e2e/rightToLeft.test.js +20 -0
  395. package/tests/e2e/viewmode.test.js +37 -0
  396. package/tests/karma/BookNavigator/book-navigator.test.js +180 -0
  397. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +133 -0
  398. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +222 -0
  399. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +64 -0
  400. package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
  401. package/tests/karma/BookNavigator/search/search-provider.test.js +23 -0
  402. package/tests/karma/BookNavigator/search/search-results.test.js +240 -0
  403. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +40 -0
  404. package/tests/karma/BookNavigator/visual-adjustments.test.js +201 -0
  405. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +160 -0
  406. package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
  407. package/tests/plugins/plugin.archive_analytics.test.js +23 -0
  408. package/tests/plugins/plugin.autoplay.test.js +52 -0
  409. package/tests/plugins/plugin.chapters.test.js +130 -0
  410. package/tests/plugins/plugin.iframe.test.js +42 -0
  411. package/tests/plugins/plugin.mobile_nav.test.js +66 -0
  412. package/tests/plugins/plugin.resume.test.js +98 -0
  413. package/tests/plugins/plugin.text_selection.test.js +193 -0
  414. package/tests/plugins/plugin.url.test.js +129 -0
  415. package/tests/plugins/plugin.vendor-fullscreen.test.js +65 -0
  416. package/tests/plugins/search/plugin.search.test.js +173 -0
  417. package/tests/plugins/search/plugin.search.view.test.js +106 -0
  418. package/tests/plugins/tts/AbstractTTSEngine.test.js +153 -0
  419. package/tests/plugins/tts/FestivalTTSEngine.test.js +59 -0
  420. package/tests/plugins/tts/PageChunk.test.js +57 -0
  421. package/tests/plugins/tts/PageChunkIterator.test.js +179 -0
  422. package/tests/plugins/tts/WebTTSEngine.test.js +126 -0
  423. package/tests/plugins/tts/utils.test.js +133 -0
  424. package/tests/util/browserSniffing.test.js +56 -0
  425. package/tests/util/docCookies.test.js +15 -0
  426. package/tests/util/strings.test.js +63 -0
  427. package/tests/utils.js +80 -0
  428. package/webpack.config.js +85 -0
@@ -0,0 +1,177 @@
1
+ // @ts-check
2
+ import Hammer from "hammerjs";
3
+ /** @typedef {import('./utils/HTMLDimensionsCacher.js').HTMLDimensionsCacher} HTMLDimensionsCacher */
4
+
5
+ /**
6
+ * @typedef {object} SmoothZoomable
7
+ * @property {HTMLElement} $container
8
+ * @property {HTMLElement} $visibleWorld
9
+ * @property {number} scale
10
+ * @property {{ x: number, y: number }} scaleCenter
11
+ * @property {HTMLDimensionsCacher} htmlDimensionsCacher
12
+ * @property {function(): void} [attachScrollListeners]
13
+ * @property {function(): void} [detachScrollListeners]
14
+ */
15
+
16
+ /** Manages pinch-zoom, ctrl-wheel, and trackpad pinch smooth zooming. */
17
+ export class ModeSmoothZoom {
18
+ /** @param {SmoothZoomable} mode */
19
+ constructor(mode) {
20
+ /** @type {SmoothZoomable} */
21
+ this.mode = mode;
22
+
23
+ /** Non-null when a scale has been enqueued/is being processed by the buffer function */
24
+ this.pinchMoveFrame = null;
25
+ /** Promise for the current/enqueued pinch move frame. Resolves when it is complete. */
26
+ this.pinchMoveFramePromise = Promise.resolve();
27
+ this.oldScale = 1;
28
+ /** @type {{ scale: number, center: { x: number, y: number }}} */
29
+ this.lastEvent = null;
30
+ this.attached = false;
31
+
32
+ /** @type {function(function(): void): any} */
33
+ this.bufferFn = window.requestAnimationFrame.bind(window);
34
+
35
+ // Hammer.js by default set userSelect to None; we don't want that!
36
+ // TODO: Is there any way to do this not globally on Hammer?
37
+ delete Hammer.defaults.cssProps.userSelect;
38
+ this.hammer = new Hammer.Manager(this.mode.$container, {
39
+ touchAction: "pan-x pan-y",
40
+ });
41
+
42
+ this.hammer.add(new Hammer.Pinch());
43
+ }
44
+
45
+ attach() {
46
+ if (this.attached) return;
47
+
48
+ this.attachCtrlZoom();
49
+
50
+ // GestureEvents work only on Safari; they interfere with Hammer,
51
+ // so block them.
52
+ this.mode.$container.addEventListener('gesturestart', this._preventEvent);
53
+ this.mode.$container.addEventListener('gesturechange', this._preventEvent);
54
+ this.mode.$container.addEventListener('gestureend', this._preventEvent);
55
+
56
+ // The pinch listeners
57
+ this.hammer.on("pinchstart", this._pinchStart);
58
+ this.hammer.on("pinchmove", this._pinchMove);
59
+ this.hammer.on("pinchend", this._pinchEnd);
60
+ this.hammer.on("pinchcancel", this._pinchCancel);
61
+
62
+ this.attached = true;
63
+ }
64
+
65
+ detach() {
66
+ this.detachCtrlZoom();
67
+
68
+ // GestureEvents work only on Safari; they interfere with Hammer,
69
+ // so block them.
70
+ this.mode.$container.removeEventListener('gesturestart', this._preventEvent);
71
+ this.mode.$container.removeEventListener('gesturechange', this._preventEvent);
72
+ this.mode.$container.removeEventListener('gestureend', this._preventEvent);
73
+
74
+ // The pinch listeners
75
+ this.hammer.off("pinchstart", this._pinchStart);
76
+ this.hammer.off("pinchmove", this._pinchMove);
77
+ this.hammer.off("pinchend", this._pinchEnd);
78
+ this.hammer.off("pinchcancel", this._pinchCancel);
79
+
80
+ this.attached = false;
81
+ }
82
+
83
+ /** @param {Event} ev */
84
+ _preventEvent = (ev) => {
85
+ ev.preventDefault();
86
+ return false;
87
+ }
88
+
89
+ _pinchStart = () => {
90
+ // Do this in case the pinchend hasn't fired yet.
91
+ this.oldScale = 1;
92
+ this.mode.$visibleWorld.style.willChange = "transform";
93
+ this.detachCtrlZoom();
94
+ this.mode.detachScrollListeners?.();
95
+ }
96
+
97
+ /** @param {{ scale: number, center: { x: number, y: number }}} e */
98
+ _pinchMove = async (e) => {
99
+ this.lastEvent = e;
100
+ if (!this.pinchMoveFrame) {
101
+ let pinchMoveFramePromiseRes = null;
102
+ this.pinchMoveFramePromise = new Promise(
103
+ (res) => (pinchMoveFramePromiseRes = res)
104
+ );
105
+
106
+ // Buffer these events; only update the scale when request animation fires
107
+ this.pinchMoveFrame = this.bufferFn(() => {
108
+ this.updateScaleCenter({
109
+ clientX: this.lastEvent.center.x,
110
+ clientY: this.lastEvent.center.y,
111
+ });
112
+ this.mode.scale *= this.lastEvent.scale / this.oldScale;
113
+ this.oldScale = this.lastEvent.scale;
114
+ this.pinchMoveFrame = null;
115
+ pinchMoveFramePromiseRes();
116
+ });
117
+ }
118
+ }
119
+
120
+ _pinchEnd = async () => {
121
+ // Want this to happen after the pinchMoveFrame,
122
+ // if one is in progress; otherwise setting oldScale
123
+ // messes up the transform.
124
+ await this.pinchMoveFramePromise;
125
+ this.mode.scaleCenter = { x: 0.5, y: 0.5 };
126
+ this.oldScale = 1;
127
+ this.mode.$visibleWorld.style.willChange = "auto";
128
+ this.attachCtrlZoom();
129
+ this.mode.attachScrollListeners?.();
130
+ }
131
+
132
+ _pinchCancel = async () => {
133
+ // iOS fires pinchcancel ~randomly; it looks like it sometimes
134
+ // thinks the pinch becomes a pan, at which point it cancels?
135
+ await this._pinchEnd();
136
+ }
137
+
138
+ /** @private */
139
+ attachCtrlZoom() {
140
+ window.addEventListener("wheel", this._handleCtrlWheel, { passive: false });
141
+ }
142
+
143
+ /** @private */
144
+ detachCtrlZoom() {
145
+ window.removeEventListener("wheel", this._handleCtrlWheel);
146
+ }
147
+
148
+ /** @param {WheelEvent} ev **/
149
+ _handleCtrlWheel = (ev) => {
150
+ if (!ev.ctrlKey) return;
151
+ ev.preventDefault();
152
+ const zoomMultiplier =
153
+ // Zooming on macs was painfully slow; likely due to their better
154
+ // trackpads. Give them a higher zoom rate.
155
+ /Mac/i.test(navigator.platform)
156
+ ? 0.045
157
+ : // This worked well for me on Windows
158
+ 0.03;
159
+
160
+ // Zoom around the cursor
161
+ this.updateScaleCenter(ev);
162
+ this.mode.scale *= 1 - Math.sign(ev.deltaY) * zoomMultiplier;
163
+ }
164
+
165
+ /**
166
+ * @param {object} param0
167
+ * @param {number} param0.clientX
168
+ * @param {number} param0.clientY
169
+ */
170
+ updateScaleCenter({ clientX, clientY }) {
171
+ const bc = this.mode.htmlDimensionsCacher.boundingClientRect;
172
+ this.mode.scaleCenter = {
173
+ x: (clientX - bc.left) / this.mode.htmlDimensionsCacher.clientWidth,
174
+ y: (clientY - bc.top) / this.mode.htmlDimensionsCacher.clientHeight,
175
+ };
176
+ }
177
+ }
@@ -0,0 +1,336 @@
1
+ // @ts-check
2
+ import { notInArray, clamp } from './utils.js';
3
+ import { EVENTS } from './events.js';
4
+ /** @typedef {import('../BookREader.js').default} BookReader */
5
+ /** @typedef {import('./BookModel.js').PageIndex} PageIndex */
6
+ /** @typedef {import('./BookModel.js').BookModel} BookModel */
7
+
8
+ /** @typedef {JQuery} $lazyLoadImgPlaceholder * jQuery element with data attributes: leaf, reduce */
9
+
10
+ export class ModeThumb {
11
+ /**
12
+ * @param {BookReader} br
13
+ * @param {BookModel} bookModel
14
+ */
15
+ constructor(br, bookModel) {
16
+ this.br = br;
17
+ this.book = bookModel;
18
+ }
19
+
20
+ /**
21
+ * Draws the thumbnail view
22
+ * @param {number} [seekIndex] If seekIndex is defined, the view will be drawn
23
+ * with that page visible (without any animated scrolling).
24
+ *
25
+ * Creates place holder for image to load after gallery has been drawn
26
+ */
27
+ drawLeafs(seekIndex) {
28
+ const { floor } = Math;
29
+ const { book } = this;
30
+ const viewWidth = this.br.refs.$brContainer.prop('scrollWidth') - 20; // width minus buffer
31
+
32
+ let leafHeight;
33
+ let rightPos = 0;
34
+ let bottomPos = 0;
35
+ let maxRight = 0;
36
+ let currentRow = 0;
37
+ let leafIndex = 0;
38
+ /** @type {Array<{ leafs?: Array<{num: PageIndex, left: number}>, height?: number, top?: number }>} */
39
+ const leafMap = [];
40
+
41
+ // Will be set to top of requested seek index, if set
42
+ let seekTop;
43
+
44
+ // Calculate the position of every thumbnail. $$$ cache instead of calculating on every draw
45
+ // make `leafMap`
46
+ for (const page of book.pagesIterator({ combineConsecutiveUnviewables: true })) {
47
+ const leafWidth = this.br.thumbWidth;
48
+ if (rightPos + (leafWidth + this.br.thumbPadding) > viewWidth) {
49
+ currentRow++;
50
+ rightPos = 0;
51
+ leafIndex = 0;
52
+ }
53
+
54
+ // Init current row in leafMap
55
+ if (!leafMap[currentRow]) {
56
+ leafMap[currentRow] = {};
57
+ }
58
+ if (!leafMap[currentRow].leafs) {
59
+ leafMap[currentRow].leafs = [];
60
+ leafMap[currentRow].height = 0;
61
+ leafMap[currentRow].top = 0;
62
+ }
63
+ leafMap[currentRow].leafs[leafIndex] = {
64
+ num: page.index,
65
+ left: rightPos,
66
+ };
67
+
68
+ leafHeight = floor((page.height * this.br.thumbWidth) / page.width);
69
+ if (leafHeight > leafMap[currentRow].height) {
70
+ leafMap[currentRow].height = leafHeight;
71
+ }
72
+ if (leafIndex === 0) { bottomPos += this.br.thumbPadding + leafMap[currentRow].height; }
73
+ rightPos += leafWidth + this.br.thumbPadding;
74
+ if (rightPos > maxRight) { maxRight = rightPos; }
75
+ leafIndex++;
76
+
77
+ if (page.index == seekIndex) {
78
+ seekTop = bottomPos - this.br.thumbPadding - leafMap[currentRow].height;
79
+ }
80
+ }
81
+
82
+ // reset the bottom position based on thumbnails
83
+ this.br.refs.$brPageViewEl.height(bottomPos);
84
+
85
+ const pageViewBuffer = floor((this.br.refs.$brContainer.prop('scrollWidth') - maxRight) / 2) - 14;
86
+
87
+ // If seekTop is defined, seeking was requested and target found
88
+ if (typeof(seekTop) != 'undefined') {
89
+ this.br.refs.$brContainer.scrollTop(seekTop);
90
+ }
91
+
92
+ const scrollTop = this.br.refs.$brContainer.prop('scrollTop');
93
+ const scrollBottom = scrollTop + this.br.refs.$brContainer.height();
94
+
95
+ let leafTop = 0;
96
+ let leafBottom = 0;
97
+ const rowsToDisplay = [];
98
+ const imagesToDisplay = [];
99
+
100
+ // Visible leafs with least/greatest index
101
+ let leastVisible = book.getNumLeafs() - 1;
102
+ let mostVisible = 0;
103
+
104
+ // Determine the thumbnails in view
105
+ for (let i = 0; i < leafMap.length; i++) {
106
+ if (!leafMap[i]) { continue; }
107
+ leafBottom += this.br.thumbPadding + leafMap[i].height;
108
+ const topInView = (leafTop >= scrollTop) && (leafTop <= scrollBottom);
109
+ const bottomInView = (leafBottom >= scrollTop) && (leafBottom <= scrollBottom);
110
+ const middleInView = (leafTop <= scrollTop) && (leafBottom >= scrollBottom);
111
+ if (topInView || bottomInView || middleInView) {
112
+ rowsToDisplay.push(i);
113
+ if (leafMap[i].leafs[0].num < leastVisible) {
114
+ leastVisible = leafMap[i].leafs[0].num;
115
+ }
116
+ if (leafMap[i].leafs[leafMap[i].leafs.length - 1].num > mostVisible) {
117
+ mostVisible = leafMap[i].leafs[leafMap[i].leafs.length - 1].num;
118
+ }
119
+ }
120
+ if (leafTop > leafMap[i].top) { leafMap[i].top = leafTop; }
121
+ leafTop = leafBottom;
122
+ }
123
+ // at this point, `rowsToDisplay` now has all the rows in view
124
+
125
+ // create a buffer of preloaded rows before and after the visible rows
126
+ const firstRow = rowsToDisplay[0];
127
+ const lastRow = rowsToDisplay[rowsToDisplay.length - 1];
128
+ for (let i = 1; i < this.br.thumbRowBuffer + 1; i++) {
129
+ if (lastRow + i < leafMap.length) { rowsToDisplay.push(lastRow + i); }
130
+ }
131
+ for (let i = 1; i < this.br.thumbRowBuffer; i++) {
132
+ if (firstRow - i >= 0) { rowsToDisplay.push(firstRow - i); }
133
+ }
134
+ rowsToDisplay.sort();
135
+
136
+ // Create the thumbnail divs and images (lazy loaded)
137
+ for (const row of rowsToDisplay) {
138
+ if (notInArray(row, this.br.displayedRows)) {
139
+ if (!leafMap[row]) { continue; }
140
+ for (const { num: leaf, left: leafLeft } of leafMap[row].leafs) {
141
+ const leafWidth = this.br.thumbWidth;
142
+ const leafHeight = floor((book.getPageHeight(leaf) * this.br.thumbWidth) / book.getPageWidth(leaf));
143
+ const leafTop = leafMap[row].top;
144
+ let left = leafLeft + pageViewBuffer;
145
+ if ('rl' == this.br.pageProgression) {
146
+ left = viewWidth - leafWidth - left;
147
+ }
148
+
149
+ left += this.br.thumbPadding;
150
+ imagesToDisplay.push(leaf);
151
+
152
+ /* get thumbnail's reducer */
153
+ const idealReduce = floor(book.getPageWidth(leaf) / this.br.thumbWidth);
154
+ const nearestFactor2 = 2 * Math.round(idealReduce / 2);
155
+ const thumbReduce = nearestFactor2;
156
+
157
+ const pageContainer = this.br._createPageContainer(leaf)
158
+ .update({
159
+ dimensions: {
160
+ width: leafWidth,
161
+ height: leafHeight,
162
+ top: leafTop,
163
+ left,
164
+ },
165
+ reduce: thumbReduce,
166
+ });
167
+
168
+ pageContainer.$container.data('leaf', leaf).on('mouseup', event => {
169
+ // We want to suppress the fragmentChange triggers in `updateFirstIndex` and `switchMode`
170
+ // because otherwise it repeatedly triggers listeners and we get in an infinite loop.
171
+ // We manually trigger the `fragmentChange` once at the end.
172
+ this.br.updateFirstIndex(leaf, { suppressFragmentChange: true });
173
+ // as per request in webdev-4042, we want to switch 1-up mode while clicking on thumbnail leafs
174
+ this.br.switchMode(this.br.constMode1up, { suppressFragmentChange: true });
175
+
176
+ // shift viewModeOrder after clicking on thumbsnail leaf
177
+ const nextModeID = this.br.viewModeOrder.shift();
178
+ this.br.viewModeOrder.push(nextModeID);
179
+ this.br.updateViewModeButton($('.viewmode'), 'twopg', 'Two-page view');
180
+
181
+ this.br.trigger(EVENTS.fragmentChange);
182
+ event.stopPropagation();
183
+ });
184
+
185
+ this.br.refs.$brPageViewEl.append(pageContainer.$container);
186
+ }
187
+ }
188
+ }
189
+
190
+ // Remove thumbnails that are not to be displayed
191
+ for (const row of this.br.displayedRows) {
192
+ if (notInArray(row, rowsToDisplay)) {
193
+ for (const { num: index } of leafMap[row]?.leafs) {
194
+ if (!imagesToDisplay?.includes(index)) {
195
+ this.br.$(`.pagediv${index}`)?.remove();
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ // Update which page is considered current to make sure a visible page is the current one
202
+ const currentIndex = this.br.currentIndex();
203
+ if (currentIndex < leastVisible) {
204
+ this.br.updateFirstIndex(leastVisible);
205
+ } else if (currentIndex > mostVisible) {
206
+ this.br.updateFirstIndex(mostVisible);
207
+ }
208
+
209
+ // remember what rows are displayed
210
+ this.br.displayedRows = rowsToDisplay.slice();
211
+
212
+ // remove previous highlights
213
+ this.br.$('.BRpagedivthumb_highlight').removeClass('BRpagedivthumb_highlight');
214
+
215
+ // highlight current page
216
+ this.br.$('.pagediv' + this.br.currentIndex()).addClass('BRpagedivthumb_highlight');
217
+
218
+ this.br.updateToolbarZoom(this.br.reduce);
219
+ }
220
+
221
+ /**
222
+ * Replaces placeholder image with real one
223
+ *
224
+ * @param {$lazyLoadImgPlaceholder} imgPlaceholder
225
+ */
226
+ lazyLoadImage(imgPlaceholder) {
227
+ const leaf = $(imgPlaceholder).data('leaf');
228
+ const reduce = $(imgPlaceholder).data('reduce');
229
+ const $img = this.br.imageCache.image(leaf, reduce);
230
+ const $parent = $(imgPlaceholder).parent();
231
+ /* March 16, 2021 (isa) - manually append & remove, `replaceWith` currently loses closure scope */
232
+ $($parent).append($img);
233
+ $(imgPlaceholder).remove();
234
+ }
235
+
236
+ /**
237
+ * @param {1 | -1} direction
238
+ */
239
+ zoom(direction) {
240
+ const oldColumns = this.br.thumbColumns;
241
+ switch (direction) {
242
+ case -1:
243
+ this.br.thumbColumns += 1;
244
+ break;
245
+ case 1:
246
+ this.br.thumbColumns -= 1;
247
+ break;
248
+ }
249
+
250
+ this.br.thumbColumns = clamp(this.br.thumbColumns, 2, 8);
251
+
252
+ if (this.br.thumbColumns != oldColumns) {
253
+ this.br.displayedRows = []; /* force a gallery redraw */
254
+ this.prepare();
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Returns the width per thumbnail to display the requested number of columns
260
+ * Note: #BRpageview must already exist since its width is used to calculate the
261
+ * thumbnail width
262
+ * @param {number} thumbnailColumns
263
+ */
264
+ getThumbnailWidth(thumbnailColumns) {
265
+ const DEFAULT_THUMBNAIL_WIDTH = 100;
266
+
267
+ const padding = (thumbnailColumns + 1) * this.br.thumbPadding;
268
+ const width = (this.br.refs.$brPageViewEl.width() - padding) / (thumbnailColumns + 0.5); // extra 0.5 is for some space at sides
269
+ const idealThumbnailWidth = Math.floor(width);
270
+ return idealThumbnailWidth > 0 ? idealThumbnailWidth : DEFAULT_THUMBNAIL_WIDTH;
271
+ }
272
+
273
+ prepare() {
274
+ this.br.refs.$brContainer.empty();
275
+ this.br.refs.$brContainer.css({
276
+ overflowY: 'scroll',
277
+ overflowX: 'auto'
278
+ });
279
+
280
+ this.br.refs.$brPageViewEl = $("<div class='BRpageview'></div>");
281
+ this.br.refs.$brContainer.append(this.br.refs.$brPageViewEl);
282
+ this.br.refs.$brContainer.dragscrollable({preventDefault:true});
283
+
284
+ this.br.bindGestures(this.br.refs.$brContainer);
285
+
286
+ // $$$ keep select enabled for now since disabling it breaks keyboard
287
+ // nav in FF 3.6 (https://bugs.edge.launchpad.net/bookreader/+bug/544666)
288
+ // disableSelect(this.br.$('#BRpageview'));
289
+ this.br.thumbWidth = this.getThumbnailWidth(this.br.thumbColumns);
290
+ this.br.reduce = this.book.getPageWidth(0) / this.br.thumbWidth;
291
+ this.br.displayedRows = [];
292
+ // Draw leafs with current index directly in view (no animating to the index)
293
+ this.drawLeafs(this.br.currentIndex());
294
+ this.br.updateBrClasses();
295
+ }
296
+
297
+ /**
298
+ * @param {PageIndex} index
299
+ */
300
+ jumpToIndex(index) {
301
+ const { floor } = Math;
302
+ const { book } = this;
303
+ const viewWidth = this.br.refs.$brContainer.prop('scrollWidth') - 20; // width minus buffer
304
+ const leafWidth = this.br.thumbWidth;
305
+ let leafTop = 0;
306
+ let rightPos = 0;
307
+ let bottomPos = 0;
308
+ let rowHeight = 0;
309
+ let leafIndex = 0;
310
+
311
+ for (let i = 0; i <= index; i++) {
312
+ if (rightPos + (leafWidth + this.br.thumbPadding) > viewWidth) {
313
+ rightPos = 0;
314
+ rowHeight = 0;
315
+ leafIndex = 0;
316
+ }
317
+
318
+ const leafHeight = floor((book.getPageHeight(leafIndex) * this.br.thumbWidth) / book.getPageWidth(leafIndex));
319
+ if (leafHeight > rowHeight) { rowHeight = leafHeight; }
320
+ if (leafIndex == 0) {
321
+ leafTop = bottomPos;
322
+ bottomPos += this.br.thumbPadding + rowHeight;
323
+ }
324
+ rightPos += leafWidth + this.br.thumbPadding;
325
+ leafIndex++;
326
+ }
327
+ this.br.updateFirstIndex(index);
328
+ if (this.br.refs.$brContainer.prop('scrollTop') == leafTop) {
329
+ this.br.drawLeafs();
330
+ } else {
331
+ this.br.animating = true;
332
+ this.br.refs.$brContainer.stop(true)
333
+ .animate({ scrollTop: leafTop }, 'fast', () => { this.br.animating = false; });
334
+ }
335
+ }
336
+ }