@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,87 @@
1
+ import { BookModel } from '../../src/BookReader/BookModel.js';
2
+ import { Mode1UpLit } from '../../src/BookReader/Mode1UpLit.js';
3
+
4
+ /** @type {import('../../src/BookReader/options.js').BookReaderOptions['data']} */
5
+ const SAMPLE_DATA = [
6
+ [
7
+ { width: 123, height: 123, uri: 'https://archive.org/image0.jpg', pageNum: '1' },
8
+ ],
9
+ [
10
+ { width: 123, height: 123, uri: 'https://archive.org/image1.jpg', pageNum: '2' },
11
+ { width: 123, height: 123, uri: 'https://archive.org/image2.jpg', pageNum: '3' },
12
+ ],
13
+ [
14
+ { width: 123, height: 123, uri: 'https://archive.org/image3.jpg', pageNum: '4' },
15
+ { width: 123, height: 123, uri: 'https://archive.org/image4.jpg', pageNum: '5' },
16
+ ],
17
+ [
18
+ { width: 123, height: 123, uri: 'https://archive.org/image5.jpg', pageNum: '6' },
19
+ ],
20
+ ];
21
+
22
+ function make_dummy_br(overrides = {}) {
23
+ return Object.assign({
24
+ updateFirstIndex() {},
25
+ updateNavIndexThrottled() {},
26
+ data: []
27
+ }, overrides);
28
+ }
29
+
30
+ describe('pageTops', () => {
31
+ afterEach(() => document.body.innerHTML = '');
32
+
33
+ test('Works with empty book', async () => {
34
+ const br = make_dummy_br({ data: [] });
35
+ const book = new BookModel(br);
36
+ const mode = new Mode1UpLit(book, br);
37
+ document.body.appendChild(mode);
38
+ await mode.requestUpdate();
39
+ expect(mode.pageTops).toEqual({});
40
+ });
41
+
42
+ test('Iterates all pages', async () => {
43
+ const br = make_dummy_br({ data: SAMPLE_DATA });
44
+ const book = new BookModel(br);
45
+ const mode = new Mode1UpLit(book, br);
46
+ document.body.appendChild(mode);
47
+ await mode.requestUpdate();
48
+ expect(Object.values(mode.pageTops)).toHaveLength(6);
49
+ });
50
+
51
+ test('Computes tops', async () => {
52
+ const br = make_dummy_br({ data: SAMPLE_DATA });
53
+ const book = new BookModel(br);
54
+ const mode = new Mode1UpLit(book, br);
55
+ document.body.appendChild(mode);
56
+ await mode.requestUpdate();
57
+ const tops = Object.entries(mode.pageTops);
58
+ expect(tops.map(([index, top]) => [index, top.toFixed(1)])).toEqual([
59
+ // Recall these are in inches
60
+ ['0', '0.2'],
61
+ ['1', '0.6'],
62
+ ['2', '1.1'],
63
+ ['3', '1.5'],
64
+ ['4', '2.0'],
65
+ ['5', '2.4'],
66
+ ]);
67
+ });
68
+ });
69
+
70
+ describe('worldUnitsToRenderedPixels', () => {
71
+ test('0 case', () => {
72
+ const mode = new Mode1UpLit(null, null);
73
+ expect(mode.worldUnitsToRenderedPixels(0)).toBe(0);
74
+ });
75
+ test('Misc cases', () => {
76
+ const mode = new Mode1UpLit(null, null);
77
+ mode.screenDPI = 100;
78
+ mode.realWorldReduce = 1;
79
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(100);
80
+ mode.screenDPI = 100;
81
+ mode.realWorldReduce = 2;
82
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(50);
83
+ mode.screenDPI = 78;
84
+ mode.realWorldReduce = 1;
85
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(78);
86
+ });
87
+ });
@@ -0,0 +1,245 @@
1
+
2
+ import sinon from 'sinon';
3
+ import { deepCopy } from '../utils.js';
4
+ import BookReader from '../../src/BookReader.js';
5
+ /** @typedef {import('../../src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
6
+
7
+ beforeAll(() => {
8
+ global.alert = jest.fn();
9
+ });
10
+ afterEach(() => {
11
+ jest.restoreAllMocks();
12
+ sinon.restore();
13
+ });
14
+
15
+ /** @type {BookReaderOptions['data']} */
16
+ const SAMPLE_DATA = [
17
+ [
18
+ { width: 123, height: 123, uri: 'https://archive.org/image0.jpg', pageNum: '1' },
19
+ ],
20
+ [
21
+ { width: 123, height: 123, uri: 'https://archive.org/image1.jpg', pageNum: '2' },
22
+ { width: 123, height: 123, uri: 'https://archive.org/image2.jpg', pageNum: '3' },
23
+ ],
24
+ [
25
+ { width: 123, height: 123, uri: 'https://archive.org/image3.jpg', pageNum: '4' },
26
+ { width: 123, height: 123, uri: 'https://archive.org/image4.jpg', pageNum: '5' },
27
+ ],
28
+ [
29
+ { width: 123, height: 123, uri: 'https://archive.org/image5.jpg', pageNum: '6' },
30
+ ],
31
+ ];
32
+
33
+
34
+ describe('zoom', () => {
35
+ const br = new BookReader({ data: SAMPLE_DATA });
36
+ br.init();
37
+
38
+ const stopAnim = sinon.spy(br, 'stopFlipAnimations');
39
+ const resizeSpread = sinon.spy(br._modes.mode2Up, 'resizeSpread');
40
+ br._modes.mode2Up.zoom('in');
41
+
42
+ test('stops animations when zooming', () => {
43
+ expect(stopAnim.callCount).toBe(1);
44
+ });
45
+ test('always redraws when zooming', () => {
46
+ expect(resizeSpread.callCount).toBe(0);
47
+ });
48
+ });
49
+
50
+ describe('prefetch', () => {
51
+ test('loads nearby pages', () => {
52
+ const br = new BookReader({ data: SAMPLE_DATA });
53
+ const mode2Up = br._modes.mode2Up;
54
+ br.init();
55
+ mode2Up.prefetch();
56
+ expect(Object.keys(mode2Up.pageContainers).length).toBeGreaterThan(2);
57
+ });
58
+
59
+ test('works when at end of book', () => {
60
+ const br = new BookReader({ data: SAMPLE_DATA });
61
+ const mode2Up = br._modes.mode2Up;
62
+ br.init();
63
+ br.jumpToIndex(-1);
64
+ mode2Up.prefetch();
65
+ expect(Object.keys(mode2Up.pageContainers).length).toBeGreaterThan(2);
66
+ });
67
+
68
+ test('skips consecutive unviewables', () => {
69
+ const data = deepCopy(SAMPLE_DATA);
70
+ data[1].forEach(page => page.viewable = false);
71
+ const br = new BookReader({ data });
72
+ const mode2Up = br._modes.mode2Up;
73
+ br.init();
74
+ mode2Up.prefetch();
75
+ expect(mode2Up.pageContainers).not.toContain(2);
76
+ });
77
+ });
78
+
79
+ describe('draw 2up leaves', () => {
80
+ test('calls `drawLeafs` on init as default', () => {
81
+ const br = new BookReader({ data: SAMPLE_DATA });
82
+ const drawLeafs = sinon.spy(br._modes.mode2Up, 'drawLeafs');
83
+
84
+ br.init();
85
+ expect(drawLeafs.callCount).toBe(1);
86
+ });
87
+
88
+ test('sets `this.displayedIndices`', () => {
89
+ const extremelyWrongValueForDisplayedIndices = null;
90
+ const br = new BookReader({ data: SAMPLE_DATA });
91
+
92
+ br.init();
93
+ br.displayedIndices = extremelyWrongValueForDisplayedIndices;
94
+ expect(br.displayedIndices).toBe(extremelyWrongValueForDisplayedIndices);
95
+
96
+ br._modes.mode2Up.drawLeafs();
97
+
98
+ expect(br.displayedIndices).not.toBe(extremelyWrongValueForDisplayedIndices);
99
+ expect(br.displayedIndices.length).toBe(2); // is array
100
+ expect(br.displayedIndices).toEqual([-1, 0]); // default to starting index on right, placeholder for left
101
+ });
102
+ });
103
+
104
+ describe('resizeSpread', () => {
105
+ test('only resizes spread', () => {
106
+ const br = new BookReader({ data: SAMPLE_DATA });
107
+ br.init();
108
+ const resizeBRcontainer = sinon.spy(br, 'resizeBRcontainer');
109
+ const calculateSpreadSize = sinon.spy(br._modes.mode2Up, 'calculateSpreadSize');
110
+ const drawLeafs = sinon.spy(br._modes.mode2Up, 'drawLeafs');
111
+ const centerView = sinon.spy(br._modes.mode2Up, 'centerView');
112
+
113
+ br._modes.mode2Up.resizeSpread();
114
+ expect(drawLeafs.callCount).toBe(0); // no draw
115
+ expect(resizeBRcontainer.callCount).toBe(1);
116
+ expect(calculateSpreadSize.callCount).toBe(1);
117
+ expect(centerView.callCount).toBe(1);
118
+ });
119
+ });
120
+
121
+ describe('2up Container sizing', () => {
122
+ test('baseLeafCss', () => {
123
+ const br = new BookReader({ data: SAMPLE_DATA });
124
+ br.init();
125
+ br.calculateSpreadSize();
126
+ expect(Object.keys(br._modes.mode2Up.baseLeafCss)).toEqual(['position', 'right', 'top', 'zIndex']);
127
+ });
128
+ test('heightCss', () => {
129
+ const br = new BookReader({ data: SAMPLE_DATA });
130
+ br.init();
131
+ br.calculateSpreadSize();
132
+ const heightStub = 1000;
133
+ br.twoPage.height = heightStub;
134
+ expect(Object.keys(br._modes.mode2Up.heightCss)).toEqual(['height']);
135
+ expect(br._modes.mode2Up.heightCss).toEqual({height: `${heightStub}px`});
136
+ });
137
+ describe('left side', () => {
138
+ const br = new BookReader({ data: SAMPLE_DATA });
139
+ br.init();
140
+ br.calculateSpreadSize();
141
+
142
+ test('leftLeafCss', () => {
143
+ expect(Object.keys(br._modes.mode2Up.leftLeafCss)).toEqual([
144
+ 'position',
145
+ 'right',
146
+ 'top',
147
+ 'zIndex',
148
+ 'height',
149
+ 'left',
150
+ 'width',
151
+ ]);
152
+ });
153
+ test('leafEdgeLCss', () => {
154
+ expect(Object.keys(br._modes.mode2Up.leafEdgeLCss)).toEqual([
155
+ 'height',
156
+ 'width',
157
+ 'left',
158
+ 'top',
159
+ 'border'
160
+ ]);
161
+ });
162
+ });
163
+ describe('right side', () => {
164
+ const br = new BookReader({ data: SAMPLE_DATA });
165
+ br.init();
166
+ br.calculateSpreadSize();
167
+
168
+ test('rightLeafCss', () => {
169
+ expect(Object.keys(br._modes.mode2Up.rightLeafCss)).toEqual([
170
+ 'position',
171
+ 'right',
172
+ 'top',
173
+ 'zIndex',
174
+ 'height',
175
+ 'left',
176
+ 'width',
177
+ ]);
178
+ });
179
+ test('leafEdgeRCss', () => {
180
+ expect(Object.keys(br._modes.mode2Up.leafEdgeRCss)).toEqual([
181
+ 'height',
182
+ 'width',
183
+ 'left',
184
+ 'top',
185
+ 'border'
186
+ ]);
187
+ });
188
+ });
189
+ describe('full width container, overlay + spine', () => {
190
+ test('mainContainerCss', () => {
191
+ const br = new BookReader({ data: SAMPLE_DATA });
192
+ br.init();
193
+ br.calculateSpreadSize();
194
+
195
+ expect(Object.keys(br._modes.mode2Up.mainContainerCss)).toEqual(['height', 'width', 'position']);
196
+ });
197
+ test('spreadCoverCss', () => {
198
+ const br = new BookReader({ data: SAMPLE_DATA });
199
+ br.init();
200
+ br.calculateSpreadSize();
201
+ expect(Object.keys(br._modes.mode2Up.spreadCoverCss)).toEqual(['width', 'height', 'visibility']);
202
+ });
203
+ test('spineCss', () => {
204
+ const br = new BookReader({ data: SAMPLE_DATA });
205
+ br.init();
206
+ br.calculateSpreadSize();
207
+ expect(Object.keys(br._modes.mode2Up.spineCss)).toEqual(['width', 'height', 'left', 'top']);
208
+ });
209
+ });
210
+ });
211
+
212
+ describe('prepareTwoPageView', () => {
213
+ describe('drawing spread', () => {
214
+ test('always draws new spread if `drawNewSpread` is true ', () => {
215
+ const br = new BookReader({ data: SAMPLE_DATA });
216
+ const mode2Up = br._modes.mode2Up;
217
+ br.init();
218
+ const drawLeafs = sinon.spy(mode2Up, 'drawLeafs');
219
+ const resizeSpread = sinon.spy(mode2Up, 'resizeSpread');
220
+ const calculateSpreadSize = sinon.spy(mode2Up, 'calculateSpreadSize');
221
+ const prunePageContainers = sinon.spy(mode2Up, 'prunePageContainers');
222
+ const prefetch = sinon.spy(mode2Up, 'prefetch');
223
+ const centerView = sinon.spy(mode2Up, 'centerView');
224
+ const preparePopUp = sinon.spy(mode2Up, 'preparePopUp');
225
+ const updateBrClasses = sinon.spy(br, 'updateBrClasses');
226
+
227
+ br.prepareTwoPageView(undefined, undefined, true);
228
+ expect(prefetch.callCount).toBe(1);
229
+
230
+ expect(resizeSpread.callCount).toBe(0);
231
+ expect(drawLeafs.callCount).toBe(1);
232
+ expect(calculateSpreadSize.callCount).toBe(1);
233
+ expect(prunePageContainers.callCount).toBe(1);
234
+ expect(centerView.callCount).toBe(1);
235
+ expect(preparePopUp.callCount).toBe(1);
236
+ expect(updateBrClasses.callCount).toBe(1);
237
+ });
238
+ });
239
+ });
240
+
241
+ test('uses ImageCache', () => {
242
+ const br = new BookReader({ data: SAMPLE_DATA });
243
+ br.init();
244
+ expect(Object.keys(br.imageCache.cache).length).toBeGreaterThan(2);
245
+ });
@@ -0,0 +1,149 @@
1
+ import sinon from 'sinon';
2
+ import { EventTargetSpy } from '../utils.js';
3
+ import { ModeSmoothZoom } from '../../src/BookReader/ModeSmoothZoom.js';
4
+ /** @typedef {import('../../src/BookReader/ModeSmoothZoom.js').SmoothZoomable} SmoothZoomable */
5
+
6
+ /**
7
+ * @param {Partial<SmoothZoomable>} overrides
8
+ * @returns {SmoothZoomable}
9
+ */
10
+ function dummy_mode(overrides = {}) {
11
+ return {
12
+ $container: document.createElement('div'),
13
+ $visibleWorld: document.createElement('div'),
14
+ scale: 1,
15
+ htmlDimensionsCacher: {
16
+ clientWidth: 100,
17
+ clientHeight: 100,
18
+ boundingClientRect: { left: 0, top: 0 },
19
+ },
20
+ scaleCenter: {x: 0.5, y: 0.5},
21
+ ...overrides
22
+ };
23
+ }
24
+
25
+ afterEach(() => sinon.restore());
26
+
27
+ describe('ModeSmoothZoom', () => {
28
+ test('preventsDefault on iOS-only gesture events', () => {
29
+ const mode = dummy_mode();
30
+ const msz = new ModeSmoothZoom(mode);
31
+ msz.attach();
32
+ for (const event_name of ['gesturestart', 'gesturechange', 'gestureend']) {
33
+ const ev = new Event(event_name, {});
34
+ const prevDefaultSpy = sinon.spy(ev, 'preventDefault');
35
+ mode.$container.dispatchEvent(ev);
36
+ expect(prevDefaultSpy.callCount).toBe(1);
37
+ }
38
+ });
39
+
40
+ test('pinchCancel alias for pinchEnd', () => {
41
+ const mode = dummy_mode();
42
+ const msz = new ModeSmoothZoom(mode);
43
+ const pinchEndSpy = sinon.spy(msz, '_pinchEnd');
44
+ msz._pinchStart();
45
+ msz._pinchCancel();
46
+ expect(pinchEndSpy.callCount).toBe(1);
47
+ });
48
+
49
+ test('sets will-change', async () => {
50
+ const mode = dummy_mode();
51
+ const msz = new ModeSmoothZoom(mode);
52
+ expect(mode.$visibleWorld.style.willChange).toBeFalsy();
53
+ msz._pinchStart();
54
+ expect(mode.$visibleWorld.style.willChange).toBe('transform');
55
+ await msz._pinchEnd();
56
+ expect(mode.$visibleWorld.style.willChange).toBe('auto');
57
+ });
58
+
59
+ test('pinch move updates scale', () => {
60
+ const mode = dummy_mode();
61
+ const msz = new ModeSmoothZoom(mode);
62
+ // disable buffering
63
+ msz.bufferFn = (callback) => callback();
64
+ msz._pinchStart();
65
+ expect(mode.scale).toBe(1);
66
+ msz._pinchMove({ scale: 2, center: { x: 0, y: 0 }});
67
+ expect(mode.scale).toBe(2);
68
+ });
69
+
70
+ test('updateScaleCenter sets scaleCenter in unitless coordinates', () => {
71
+ const mode = dummy_mode({
72
+ htmlDimensionsCacher: {
73
+ clientWidth: 200,
74
+ clientHeight: 100,
75
+ boundingClientRect: {
76
+ left: 5,
77
+ top: 50
78
+ }
79
+ }
80
+ });
81
+ const msz = new ModeSmoothZoom(mode);
82
+ expect(mode.scaleCenter).toEqual({ x: 0.5, y: 0.5 });
83
+ msz.updateScaleCenter({ clientX: 85, clientY: 110 });
84
+ expect(mode.scaleCenter).toEqual({ x: 0.4, y: 0.6 });
85
+ });
86
+
87
+ test('detaches all listeners', () => {
88
+ const mode = dummy_mode();
89
+ const msz = new ModeSmoothZoom(mode);
90
+ const containerEventSpy = EventTargetSpy.wrap(mode.$container);
91
+ const visibleWorldSpy = EventTargetSpy.wrap(mode.$visibleWorld);
92
+ const hammerEventSpy = new EventTargetSpy();
93
+ msz.hammer.on = hammerEventSpy.addEventListener.bind(hammerEventSpy);
94
+ msz.hammer.off = hammerEventSpy.removeEventListener.bind(hammerEventSpy);
95
+
96
+ msz.attach();
97
+ expect(containerEventSpy._totalListenerCount).toBeGreaterThan(0);
98
+ expect(hammerEventSpy._totalListenerCount).toBeGreaterThan(0);
99
+
100
+ msz.detach();
101
+ expect(containerEventSpy._totalListenerCount).toBe(0);
102
+ expect(visibleWorldSpy._totalListenerCount).toBe(0);
103
+ expect(hammerEventSpy._totalListenerCount).toBe(0);
104
+ });
105
+
106
+ test('attach can be called twice without double attachments', () => {
107
+ const mode = dummy_mode();
108
+ const msz = new ModeSmoothZoom(mode);
109
+ const containerEventSpy = EventTargetSpy.wrap(mode.$container);
110
+ const visibleWorldSpy = EventTargetSpy.wrap(mode.$visibleWorld);
111
+ const hammerEventSpy = new EventTargetSpy();
112
+ msz.hammer.on = hammerEventSpy.addEventListener.bind(hammerEventSpy);
113
+ msz.hammer.off = hammerEventSpy.removeEventListener.bind(hammerEventSpy);
114
+ msz.attach();
115
+
116
+ const containerListenersCount = containerEventSpy._totalListenerCount;
117
+ const visibleWorldListenersCount = visibleWorldSpy._totalListenerCount;
118
+ const hammerListenersCount = hammerEventSpy._totalListenerCount;
119
+
120
+ msz.attach();
121
+ expect(containerEventSpy._totalListenerCount).toBe(containerListenersCount);
122
+ expect(visibleWorldSpy._totalListenerCount).toBe(visibleWorldListenersCount);
123
+ expect(hammerEventSpy._totalListenerCount).toBe(hammerListenersCount);
124
+ });
125
+
126
+ describe('_handleCtrlWheel', () => {
127
+ test('non-ctrl wheel events ignored', () => {
128
+ const mode = dummy_mode();
129
+ const msz = new ModeSmoothZoom(mode);
130
+ expect(mode.scale).toBe(1);
131
+ const ev = new WheelEvent('wheel', { ctrlKey: false, deltaY: 20 });
132
+ const preventDefaultSpy = sinon.spy(ev, 'preventDefault');
133
+ msz._handleCtrlWheel(ev);
134
+ expect(preventDefaultSpy.callCount).toBe(0);
135
+ expect(mode.scale).toBe(1);
136
+ });
137
+
138
+ test('ctrl-wheel events update scale', () => {
139
+ const mode = dummy_mode();
140
+ const msz = new ModeSmoothZoom(mode);
141
+ expect(mode.scale).toBe(1);
142
+ const ev = new WheelEvent('wheel', { ctrlKey: true, deltaY: 20 });
143
+ const preventDefaultSpy = sinon.spy(ev, 'preventDefault');
144
+ msz._handleCtrlWheel(ev);
145
+ expect(preventDefaultSpy.callCount).toBe(1);
146
+ expect(mode.scale).not.toBe(1);
147
+ });
148
+ });
149
+ });
@@ -0,0 +1,169 @@
1
+ import sinon from 'sinon';
2
+ import { getNavPageNumHtml } from '../../../src/BookReader/Navbar/Navbar.js';
3
+ import BookReader from '../../../src/BookReader.js';
4
+
5
+ describe('getNavPageNumHtml', () => {
6
+ const f = getNavPageNumHtml;
7
+ test('handle n-prefixed page numbers', () => {
8
+ expect(f(3, 40, 'n3', '', 40)).toBe('(4 of 40)');
9
+ });
10
+
11
+ test('handle regular page numbers', () => {
12
+ expect(f(3, 40, '14', '', 40)).toBe('14 of 40');
13
+ });
14
+
15
+ test('handle no max page', () => {
16
+ expect(f(3, 40, '14', '', null)).toBe('14');
17
+ });
18
+ });
19
+
20
+ /** @type {BookReader} */
21
+ let br;
22
+ /** @type {Navbar} */
23
+ let navbar;
24
+ beforeEach(() => {
25
+ document.body.innerHTML = '<div id="BookReader">';
26
+ br = new BookReader({
27
+ data: [
28
+ [
29
+ { width: 800, height: 1200,
30
+ uri: '//archive.org/download/BookReader/img/page001.jpg' },
31
+ ],
32
+ [
33
+ { width: 800, height: 1200,
34
+ uri: '//archive.org/download/BookReader/img/page002.jpg' },
35
+ { width: 800, height: 1200,
36
+ uri: '//archive.org/download/BookReader/img/page003.jpg' },
37
+ ],
38
+ [
39
+ { width: 800, height: 1200,
40
+ uri: '//archive.org/download/BookReader/img/page004.jpg' },
41
+ { width: 800, height: 1200,
42
+ uri: '//archive.org/download/BookReader/img/page005.jpg' },
43
+ ]
44
+ ],
45
+ });
46
+ br.init();
47
+ navbar = br._components.navbar;
48
+ });
49
+
50
+ afterEach(() => sinon.restore());
51
+
52
+ describe('Navbar slider', () => {
53
+ test('while sliding, visible page number updates, but does not flip', () => {
54
+ const $slider = navbar.$root.find('.BRpager');
55
+ const jumpToIndexSpy = sinon.spy(br, 'jumpToIndex');
56
+ expect(br.currentIndex()).toBe(0);
57
+
58
+ $slider.trigger('slide', { value: 3 });
59
+
60
+ expect(navbar.$root.find('.BRcurrentpage').text().includes('3'));
61
+ expect(jumpToIndexSpy.callCount).toBe(0);
62
+ });
63
+
64
+ test('on slide change, actual page changes', () => {
65
+ const $slider = navbar.$root.find('.BRpager');
66
+ const jumpToIndexSpy = sinon.spy(br, 'jumpToIndex');
67
+ expect(br.currentIndex()).toBe(0);
68
+
69
+ $slider.trigger('slidechange', { value: 3 });
70
+
71
+ expect(navbar.$root.find('.BRcurrentpage').text().includes('3'));
72
+ expect(jumpToIndexSpy.callCount).toBe(1);
73
+ expect(jumpToIndexSpy.args[0][0]).toBe(3);
74
+ });
75
+ });
76
+
77
+ describe('Navbar controls overrides', () => {
78
+ const createBRWithOverrides = (overrides) => {
79
+ br = new BookReader($.extend(true, br.options, overrides));
80
+ br.init();
81
+ navbar = br._components.navbar;
82
+ };
83
+
84
+ test(`when a view mode is excluded,
85
+ the mode should not be used in viewport toggling`, () => {
86
+ const overrides = {
87
+ controls: {
88
+ viewmode: {
89
+ visible: true,
90
+ className: 'viewmode',
91
+ excludedModes: [1],
92
+ }
93
+ }
94
+ };
95
+ createBRWithOverrides(overrides);
96
+
97
+ const $viewMode = navbar.$root.find('.viewmode');
98
+
99
+ expect($viewMode.find('.icon-thumb').length).toBe(1);
100
+ $viewMode.click();
101
+ expect($viewMode.find('.icon-twopg').length).toBe(1);
102
+ $viewMode.click();
103
+ expect($viewMode.find('.icon-thumb').length).toBe(1);
104
+ });
105
+
106
+ test('when a control is set to visible: false, do not return a button template', () => {
107
+ const overrides = {
108
+ controls: {
109
+ onePage: {
110
+ visible: false
111
+ }
112
+ }
113
+ };
114
+ createBRWithOverrides(overrides);
115
+
116
+ expect(navbar.$root.find('.onepg').length).toBe(0);
117
+ expect(navbar.$root.find('.twopg').length).toBe(1);
118
+ });
119
+
120
+ test(`when a control's className is overridden,
121
+ the class should be used in place of the default`, () => {
122
+ const overrides = {
123
+ controls: {
124
+ onePage: {
125
+ className: 'foo'
126
+ }
127
+ }
128
+ };
129
+ createBRWithOverrides(overrides);
130
+
131
+ expect(navbar.$root.find(`.${overrides.controls.onePage.className}`).length).toBe(1);
132
+ expect(navbar.$root.find('.onepg').length).toBe(0);
133
+ });
134
+
135
+ test(`when a control's template is overridden,
136
+ the HTML output should match the template provided`, () => {
137
+ const overrides = {
138
+ controls: {
139
+ onePage: {
140
+ template: () => (
141
+ '<button id="foo"></button>'
142
+ )
143
+ }
144
+ }
145
+ };
146
+ createBRWithOverrides(overrides);
147
+
148
+ expect(navbar.$root.find('#foo').length).toBe(1);
149
+ expect(navbar.$root.find('.onepg').length).toBe(0);
150
+ });
151
+
152
+ test(`when viewmode control set to visible,
153
+ the individual view mode controls are not rendered`, () => {
154
+ const overrides = {
155
+ controls: {
156
+ viewmode: {
157
+ visible: true
158
+ },
159
+ onePage: {
160
+ visible: false
161
+ }
162
+ }
163
+ };
164
+ createBRWithOverrides(overrides);
165
+
166
+ expect(navbar.$root.find('.viewmode').length).toBe(1);
167
+ expect(navbar.$root.find('.onepg').length).toBe(0);
168
+ });
169
+ });