@internetarchive/bookreader 5.0.0-5-multiple-files → 5.0.0-50-a1

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 (289) hide show
  1. package/.eslintrc.js +17 -15
  2. package/.github/workflows/node.js.yml +77 -6
  3. package/.github/workflows/npm-publish.yml +6 -20
  4. package/.testcaferc.js +10 -0
  5. package/BookReader/BookReader.css +131 -339
  6. package/BookReader/BookReader.js +2 -21564
  7. package/BookReader/BookReader.js.LICENSE.txt +24 -0
  8. package/BookReader/BookReader.js.map +1 -1
  9. package/BookReader/ia-bookreader-bundle.js +1493 -0
  10. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +17 -0
  11. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  12. package/BookReader/icons/1up.svg +1 -12
  13. package/BookReader/icons/2up.svg +1 -15
  14. package/BookReader/icons/advance.svg +3 -26
  15. package/BookReader/icons/chevron-right.svg +1 -1
  16. package/BookReader/icons/close-circle-dark.svg +1 -0
  17. package/BookReader/icons/close-circle.svg +1 -1
  18. package/BookReader/icons/fullscreen.svg +1 -17
  19. package/BookReader/icons/fullscreen_exit.svg +1 -17
  20. package/BookReader/icons/hamburger.svg +1 -15
  21. package/BookReader/icons/left-arrow.svg +1 -12
  22. package/BookReader/icons/magnify-minus.svg +1 -16
  23. package/BookReader/icons/magnify-plus.svg +1 -17
  24. package/BookReader/icons/magnify.svg +1 -15
  25. package/BookReader/icons/pause.svg +1 -23
  26. package/BookReader/icons/play.svg +1 -22
  27. package/BookReader/icons/playback-speed.svg +1 -34
  28. package/BookReader/icons/read-aloud.svg +1 -22
  29. package/BookReader/icons/review.svg +3 -22
  30. package/BookReader/icons/thumbnails.svg +1 -17
  31. package/BookReader/icons/voice.svg +1 -0
  32. package/BookReader/icons/volume-full.svg +1 -22
  33. package/BookReader/images/BRicons.svg +5 -94
  34. package/BookReader/images/books_graphic.svg +1 -177
  35. package/BookReader/images/icon_book.svg +1 -12
  36. package/BookReader/images/icon_bookmark.svg +1 -12
  37. package/BookReader/images/icon_gear.svg +1 -14
  38. package/BookReader/images/icon_hamburger.svg +1 -20
  39. package/BookReader/images/icon_home.svg +1 -21
  40. package/BookReader/images/icon_info.svg +1 -11
  41. package/BookReader/images/icon_one_page.svg +1 -8
  42. package/BookReader/images/icon_pause.svg +1 -1
  43. package/BookReader/images/icon_play.svg +1 -1
  44. package/BookReader/images/icon_playback-rate.svg +1 -15
  45. package/BookReader/images/icon_search_button.svg +1 -8
  46. package/BookReader/images/icon_share.svg +1 -9
  47. package/BookReader/images/icon_skip-ahead.svg +1 -6
  48. package/BookReader/images/icon_skip-back.svg +2 -13
  49. package/BookReader/images/icon_speaker.svg +1 -18
  50. package/BookReader/images/icon_speaker_open.svg +1 -10
  51. package/BookReader/images/icon_thumbnails.svg +1 -12
  52. package/BookReader/images/icon_toc.svg +1 -5
  53. package/BookReader/images/icon_two_pages.svg +1 -9
  54. package/BookReader/images/marker_chap-off.svg +1 -11
  55. package/BookReader/images/marker_chap-on.svg +1 -11
  56. package/BookReader/images/marker_srch-on.svg +1 -11
  57. package/BookReader/jquery-3.js +2 -0
  58. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  59. package/BookReader/plugins/plugin.archive_analytics.js +1 -172
  60. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  61. package/BookReader/plugins/plugin.autoplay.js +1 -165
  62. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  63. package/BookReader/plugins/plugin.chapters.js +1 -304
  64. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  65. package/BookReader/plugins/plugin.iframe.js +1 -74
  66. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  67. package/BookReader/plugins/plugin.mobile_nav.js +1 -334
  68. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  69. package/BookReader/plugins/plugin.resume.js +1 -368
  70. package/BookReader/plugins/plugin.resume.js.map +1 -1
  71. package/BookReader/plugins/plugin.search.js +1 -1420
  72. package/BookReader/plugins/plugin.search.js.map +1 -1
  73. package/BookReader/plugins/plugin.text_selection.js +1 -1080
  74. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  75. package/BookReader/plugins/plugin.tts.js +2 -9193
  76. package/BookReader/plugins/plugin.tts.js.map +1 -1
  77. package/BookReader/plugins/plugin.url.js +1 -269
  78. package/BookReader/plugins/plugin.url.js.map +1 -1
  79. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
  80. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  81. package/BookReader/webcomponents-bundle.js +3 -0
  82. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  83. package/BookReader/webcomponents-bundle.js.map +1 -0
  84. package/BookReaderDemo/BookReaderDemo.css +14 -1
  85. package/BookReaderDemo/IADemoBr.js +148 -0
  86. package/BookReaderDemo/demo-advanced.html +2 -2
  87. package/BookReaderDemo/demo-autoplay.html +2 -1
  88. package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
  89. package/BookReaderDemo/demo-fullscreen-mobile.html +2 -1
  90. package/BookReaderDemo/demo-fullscreen.html +2 -1
  91. package/BookReaderDemo/demo-iiif.html +2 -1
  92. package/BookReaderDemo/demo-internetarchive.html +84 -17
  93. package/BookReaderDemo/demo-multiple.html +2 -1
  94. package/BookReaderDemo/demo-preview-pages.html +2 -1
  95. package/BookReaderDemo/demo-simple.html +2 -1
  96. package/BookReaderDemo/demo-vendor-fullscreen.html +2 -1
  97. package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
  98. package/BookReaderDemo/immersion-1up.html +2 -1
  99. package/BookReaderDemo/immersion-mode.html +2 -1
  100. package/BookReaderDemo/toggle_controls.html +2 -1
  101. package/BookReaderDemo/view_mode.html +2 -1
  102. package/BookReaderDemo/viewmode-cycle.html +2 -3
  103. package/CHANGELOG.md +202 -0
  104. package/README.md +14 -1
  105. package/babel.config.js +18 -0
  106. package/codecov.yml +6 -0
  107. package/index.html +3 -0
  108. package/jsconfig.json +19 -0
  109. package/package.json +66 -56
  110. package/renovate.json +52 -0
  111. package/scripts/preversion.js +4 -1
  112. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  113. package/src/BookNavigator/assets/button-base.js +9 -2
  114. package/src/BookNavigator/assets/ia-logo.js +17 -0
  115. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  116. package/src/BookNavigator/assets/icon_close.js +1 -1
  117. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  118. package/src/BookNavigator/assets/{icon_sort_ascending.js → icon_sort_desc.js} +2 -2
  119. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  120. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  121. package/src/BookNavigator/book-navigator.js +583 -0
  122. package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
  123. package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
  124. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  125. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +3 -8
  126. package/src/BookNavigator/bookmarks/bookmarks-provider.js +21 -8
  127. package/src/BookNavigator/bookmarks/ia-bookmarks.js +102 -66
  128. package/src/BookNavigator/delete-modal-actions.js +1 -1
  129. package/src/BookNavigator/downloads/downloads-provider.js +36 -21
  130. package/src/BookNavigator/downloads/downloads.js +41 -25
  131. package/src/BookNavigator/search/a-search-result.js +18 -13
  132. package/src/BookNavigator/search/search-provider.js +80 -28
  133. package/src/BookNavigator/search/search-results.js +10 -18
  134. package/src/BookNavigator/sharing.js +27 -0
  135. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +11 -10
  136. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
  137. package/src/BookNavigator/volumes/volumes-provider.js +93 -63
  138. package/src/BookNavigator/volumes/volumes.js +40 -46
  139. package/src/BookReader/BookModel.js +0 -29
  140. package/src/BookReader/DebugConsole.js +3 -3
  141. package/src/BookReader/DragScrollable.js +233 -0
  142. package/src/BookReader/Mode1Up.js +51 -351
  143. package/src/BookReader/Mode1UpLit.js +441 -0
  144. package/src/BookReader/Mode2Up.js +120 -105
  145. package/src/BookReader/ModeSmoothZoom.js +179 -0
  146. package/src/BookReader/ModeThumb.js +17 -11
  147. package/src/BookReader/Navbar/Navbar.js +10 -36
  148. package/src/BookReader/PageContainer.js +69 -6
  149. package/src/BookReader/ReduceSet.js +1 -1
  150. package/src/BookReader/Toolbar/Toolbar.js +10 -37
  151. package/src/BookReader/options.js +10 -0
  152. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  153. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  154. package/src/BookReader/utils.js +92 -13
  155. package/src/BookReader.js +431 -620
  156. package/src/assets/icons/close-circle-dark.svg +1 -0
  157. package/src/assets/icons/magnify-minus.svg +3 -7
  158. package/src/assets/icons/magnify-plus.svg +3 -7
  159. package/src/assets/icons/voice.svg +1 -0
  160. package/src/css/BookReader.scss +0 -12
  161. package/src/css/_BRComponent.scss +1 -1
  162. package/src/css/_BRmain.scss +19 -24
  163. package/src/css/_BRnav.scss +4 -26
  164. package/src/css/_BRpages.scss +35 -0
  165. package/src/css/_BRsearch.scss +25 -216
  166. package/src/css/_TextSelection.scss +14 -17
  167. package/src/css/_colorbox.scss +2 -2
  168. package/src/css/_controls.scss +17 -5
  169. package/src/css/_icons.scss +6 -0
  170. package/src/ia-bookreader/ia-bookreader.js +224 -0
  171. package/src/plugins/plugin.autoplay.js +4 -4
  172. package/src/plugins/plugin.chapters.js +28 -35
  173. package/src/plugins/plugin.mobile_nav.js +11 -10
  174. package/src/plugins/plugin.resume.js +3 -3
  175. package/src/plugins/plugin.text_selection.js +26 -39
  176. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  177. package/src/plugins/search/plugin.search.js +174 -116
  178. package/src/plugins/search/view.js +63 -179
  179. package/src/plugins/tts/AbstractTTSEngine.js +46 -37
  180. package/src/plugins/tts/FestivalTTSEngine.js +13 -14
  181. package/src/plugins/tts/PageChunk.js +15 -21
  182. package/src/plugins/tts/PageChunkIterator.js +8 -12
  183. package/src/plugins/tts/WebTTSEngine.js +66 -69
  184. package/src/plugins/tts/plugin.tts.js +92 -109
  185. package/src/plugins/tts/utils.js +0 -9
  186. package/src/plugins/url/UrlPlugin.js +184 -0
  187. package/src/plugins/{plugin.url.js → url/plugin.url.js} +28 -6
  188. package/src/util/manifestGenerator.js +0 -0
  189. package/tests/e2e/README.md +37 -0
  190. package/tests/e2e/autoplay.test.js +2 -2
  191. package/tests/e2e/base.test.js +7 -7
  192. package/tests/e2e/helpers/base.js +9 -3
  193. package/tests/e2e/helpers/debug.js +1 -1
  194. package/tests/e2e/helpers/desktopSearch.js +14 -13
  195. package/tests/e2e/helpers/mobileSearch.js +3 -3
  196. package/tests/e2e/helpers/params.js +17 -0
  197. package/tests/e2e/models/Navigation.js +13 -4
  198. package/tests/e2e/rightToLeft.test.js +4 -5
  199. package/tests/e2e/viewmode.test.js +38 -33
  200. package/tests/jest/BookNavigator/book-navigator.test.js +634 -0
  201. package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
  202. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
  203. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
  204. package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
  205. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
  206. package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
  207. package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
  208. package/tests/{karma/BookNavigator → jest/BookNavigator/search}/search-results.test.js +102 -58
  209. package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
  210. package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
  211. package/tests/jest/BookNavigator/volumes/volumes-provider.test.js +184 -0
  212. package/tests/jest/BookNavigator/volumes/volumes.test.js +97 -0
  213. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +34 -14
  214. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  215. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  216. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  217. package/tests/jest/BookReader/Mode1UpLit.test.js +92 -0
  218. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +36 -15
  219. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  220. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  221. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  222. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +88 -6
  223. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  224. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  225. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  226. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  227. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  228. package/tests/jest/BookReader/utils.test.js +186 -0
  229. package/tests/jest/BookReader.keyboard.test.js +190 -0
  230. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  231. package/tests/{BookReader.test.js → jest/BookReader.test.js} +18 -37
  232. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  233. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +4 -4
  234. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +10 -11
  235. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  236. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  237. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  238. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +39 -47
  239. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  240. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +63 -47
  241. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +35 -6
  242. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +9 -9
  243. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  244. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  245. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  246. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  247. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -28
  248. package/tests/jest/plugins/url/UrlPlugin.test.js +190 -0
  249. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  250. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  251. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  252. package/tests/{util → jest/util}/strings.test.js +1 -1
  253. package/tests/{utils.js → jest/utils.js} +38 -0
  254. package/webpack.config.js +11 -5
  255. package/.babelrc +0 -12
  256. package/.dependabot/config.yml +0 -6
  257. package/.testcaferc.json +0 -5
  258. package/BookReader/bookreader-component-bundle.js +0 -14275
  259. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  260. package/BookReader/bookreader-component-bundle.js.map +0 -1
  261. package/BookReader/icons/sort-ascending.svg +0 -1
  262. package/BookReader/icons/sort-descending.svg +0 -1
  263. package/BookReader/jquery-1.10.1.js +0 -108
  264. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  265. package/BookReader/plugins/plugin.menu_toggle.js +0 -369
  266. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  267. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  268. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  269. package/karma.conf.js +0 -23
  270. package/src/BookNavigator/BookModel.js +0 -14
  271. package/src/BookNavigator/BookNavigator.js +0 -448
  272. package/src/BookNavigator/assets/book-loader.js +0 -27
  273. package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
  274. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  275. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  276. package/src/ItemNavigator/ItemNavigator.js +0 -373
  277. package/src/ItemNavigator/providers/sharing.js +0 -29
  278. package/src/assets/icons/sort-ascending.svg +0 -1
  279. package/src/assets/icons/sort-descending.svg +0 -1
  280. package/src/dragscrollable-br.js +0 -261
  281. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  282. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  283. package/tests/BookReader/Mode1Up.test.js +0 -164
  284. package/tests/BookReader/utils.test.js +0 -109
  285. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  286. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  287. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  288. package/tests/karma/BookNavigator/volumes.test.js +0 -101
  289. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -0,0 +1,176 @@
1
+ import BookReader from '@/src/BookReader';
2
+ import { sleep } from '@/src/BookReader/utils.js';
3
+ import sinon from 'sinon';
4
+
5
+ beforeAll(() => {
6
+ global.alert = sinon.fake();
7
+ });
8
+ afterEach(() => {
9
+ sinon.restore();
10
+ });
11
+
12
+ describe('BookReader.prototype.toggleFullscreen', () => {
13
+ test('uses `isFullscreen` to check fullscreen state', () => {
14
+ const isFSmock = sinon.fake();
15
+ // isFSmock.mockReturnValueOnce(false);
16
+ const br = new BookReader();
17
+ br.mode = br.constMode1up;
18
+ br.enterFullscreen = sinon.fake();
19
+ br.isFullscreen = isFSmock;
20
+
21
+ br.toggleFullscreen();
22
+ expect(br.isFullscreen.callCount).toEqual(1);
23
+ });
24
+
25
+ test('will always emit an event', async () => {
26
+ const br = new BookReader();
27
+ br.mode = br.constMode2up;
28
+ br.trigger = sinon.fake();
29
+ br.switchMode = sinon.fake();
30
+ br.updateBrClasses = sinon.fake();
31
+ br.refs.$brContainer = {
32
+ css: sinon.fake(),
33
+ animate: (options, speed, style, callback) => callback()
34
+ };
35
+ br.refs.$br = {
36
+ updateBrClasses: sinon.fake(),
37
+ removeClass: sinon.fake(),
38
+ addClass: sinon.fake(),
39
+ css: sinon.fake(),
40
+ animate: (options, speed, style, callback) => callback()
41
+ };
42
+
43
+ await br.toggleFullscreen();
44
+ expect(br.trigger.callCount).toBeGreaterThan(0);
45
+ });
46
+
47
+ test('will start with opening fullscreen', () => {
48
+ const br = new BookReader();
49
+ br.mode = br.constMode2up;
50
+ br.enterFullscreen = sinon.fake();
51
+
52
+ br.toggleFullscreen();
53
+ expect(br.enterFullscreen.callCount).toEqual(1);
54
+ });
55
+
56
+ test('will close fullscreen if BookReader is in fullscreen', () => {
57
+ const br = new BookReader();
58
+ br.mode = br.constMode1up;
59
+ br.exitFullScreen = sinon.fake();
60
+ br.isFullscreenActive = true;
61
+
62
+ br.toggleFullscreen();
63
+ expect(br.exitFullScreen.callCount).toEqual(1);
64
+ });
65
+ });
66
+
67
+ describe('BookReader.prototype.enterFullscreen', () => {
68
+ test('will bind `_fullscreenCloseHandler` by default', () => {
69
+ const br = new BookReader();
70
+ br.mode = br.constMode1up;
71
+ br.switchMode = sinon.fake();
72
+ br.updateBrClasses = sinon.fake();
73
+ br.refs.$brContainer = {
74
+ css: sinon.fake(),
75
+ animate: sinon.fake(),
76
+ };
77
+ expect(br._fullscreenCloseHandler).toBeUndefined();
78
+
79
+ br.enterFullscreen();
80
+ expect(br._fullscreenCloseHandler).toBeDefined();
81
+ });
82
+
83
+ test('fires certain events when called', async () => {
84
+ const br = new BookReader();
85
+ br.mode = br.constMode2up;
86
+ br.switchMode = sinon.fake();
87
+ br.updateBrClasses = sinon.fake();
88
+ br.trigger = sinon.fake();
89
+ br.resize = sinon.fake();
90
+ br.jumpToIndex = sinon.fake();
91
+ br.refs.$brContainer = {
92
+ css: sinon.fake(),
93
+ animate: (options, speed, style, callback) => callback()
94
+ };
95
+
96
+ await br.enterFullscreen();
97
+ expect(br.switchMode.callCount).toEqual(1);
98
+ expect(br.updateBrClasses.callCount).toEqual(1);
99
+ expect(br.trigger.callCount).toEqual(2); // fragmentChange, fullscreenToggled
100
+ expect(br.jumpToIndex.callCount).toEqual(1);
101
+
102
+ await sleep(0);
103
+ expect(br.resize.callCount).toEqual(1);
104
+ });
105
+ });
106
+
107
+ describe('BookReader.prototype.exitFullScreen', () => {
108
+ test('fires certain events when called', async () => {
109
+ const br = new BookReader();
110
+ br.mode = br.constMode2up;
111
+ br.switchMode = sinon.fake();
112
+ br.updateBrClasses = sinon.fake();
113
+ br.trigger = sinon.fake();
114
+ br.resize = sinon.fake();
115
+ br.refs.$brContainer = {
116
+ css: sinon.fake(),
117
+ animate: (options, speed, style, callback) => callback()
118
+ };
119
+ await br.exitFullScreen();
120
+ expect(br.switchMode.callCount).toEqual(1);
121
+ expect(br.updateBrClasses.callCount).toEqual(1);
122
+ expect(br.trigger.callCount).toEqual(2); // fragmentChange, fullscreenToggled
123
+ expect(br.resize.callCount).toEqual(1);
124
+ });
125
+ });
126
+
127
+ describe('BookReader.prototype.trigger', () => {
128
+ test('fires custom event', () => {
129
+ const br = new BookReader();
130
+ global.br = br;
131
+ global.dispatchEvent = sinon.fake();
132
+
133
+ const props = {bar: 1};
134
+ br.trigger('foo', props);
135
+ expect(global.dispatchEvent.callCount).toBe(1);
136
+ });
137
+ });
138
+
139
+ describe('`BookReader.prototype.prev`', () => {
140
+ const br = new BookReader();
141
+ global.br = br;
142
+ br.trigger = sinon.fake();
143
+ br._modes.mode2Up.flipBackToIndex = sinon.fake();
144
+ br.jumpToIndex = sinon.fake();
145
+
146
+ test('does not take action if user is on front page', () => {
147
+ br.firstIndex = 0;
148
+ br.prev();
149
+ expect(br.trigger.callCount).toBe(0);
150
+ expect(br._modes.mode2Up.flipBackToIndex.callCount).toBe(0);
151
+ expect(br.jumpToIndex.callCount).toBe(0);
152
+ });
153
+
154
+ describe('2up mode', () => {
155
+ test('fires event and turns the page', () => {
156
+ br.firstIndex = 10;
157
+ br.mode = br.constMode2up;
158
+ br.prev();
159
+ expect(br.jumpToIndex.callCount).toBe(0); // <-- does not get called
160
+ expect(br.trigger.callCount).toBe(1);
161
+ expect(br._modes.mode2Up.flipBackToIndex.callCount).toBe(1);
162
+ });
163
+ });
164
+
165
+ describe('non 2up mode', () => {
166
+ test('jumps to provided index', () => {
167
+ br.firstIndex = 100;
168
+ br.mode = br.constMode1up;
169
+ br.prev();
170
+ expect(br.jumpToIndex.callCount).toBe(1); // <-- gets called
171
+ expect(br.trigger.callCount).toBe(1); // <-- gets called by `jumpToIndex` internally
172
+ expect(br._modes.mode2Up.flipBackToIndex.callCount).toBe(1); // <-- gets called by `jumpToIndex` internally
173
+ });
174
+ });
175
+ });
176
+
@@ -1,5 +1,5 @@
1
1
  import sinon from 'sinon';
2
- import { DebugConsole } from '../../src/BookReader/DebugConsole.js';
2
+ import { DebugConsole } from '@/src/BookReader/DebugConsole.js';
3
3
 
4
4
  beforeEach(() => {
5
5
  sinon.stub(console, 'log');
@@ -1,8 +1,8 @@
1
1
  import sinon from 'sinon';
2
- import { BookModel } from '../../src/BookReader/BookModel.js';
3
- import { ImageCache } from '../../src/BookReader/ImageCache.js';
4
- import { Pow2ReduceSet } from '../../src/BookReader/ReduceSet.js';
5
- /** @typedef {import('../../src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
2
+ import { BookModel } from '@/src/BookReader/BookModel.js';
3
+ import { ImageCache } from '@/src/BookReader/ImageCache.js';
4
+ import { Pow2ReduceSet } from '@/src/BookReader/ReduceSet.js';
5
+ /** @typedef {import('@/src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
6
6
 
7
7
  afterEach(() => {
8
8
  jest.restoreAllMocks();
@@ -0,0 +1,92 @@
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
+ _components: {
26
+ navbar: {
27
+ updateNavIndexThrottled() {},
28
+ }
29
+ },
30
+ data: []
31
+ }, overrides);
32
+ }
33
+
34
+ describe('pageTops', () => {
35
+ afterEach(() => document.body.innerHTML = '');
36
+
37
+ test('Works with empty book', async () => {
38
+ const br = make_dummy_br({ data: [] });
39
+ const book = new BookModel(br);
40
+ const mode = new Mode1UpLit(book, br);
41
+ document.body.appendChild(mode);
42
+ mode.requestUpdate();
43
+ await mode.updateComplete;
44
+ expect(mode.pageTops).toEqual({});
45
+ });
46
+
47
+ test('Iterates all pages', async () => {
48
+ const br = make_dummy_br({ data: SAMPLE_DATA });
49
+ const book = new BookModel(br);
50
+ const mode = new Mode1UpLit(book, br);
51
+ document.body.appendChild(mode);
52
+ await mode.requestUpdate();
53
+ expect(Object.values(mode.pageTops)).toHaveLength(6);
54
+ });
55
+
56
+ test('Computes tops', async () => {
57
+ const br = make_dummy_br({ data: SAMPLE_DATA });
58
+ const book = new BookModel(br);
59
+ const mode = new Mode1UpLit(book, br);
60
+ document.body.appendChild(mode);
61
+ await mode.requestUpdate();
62
+ const tops = Object.entries(mode.pageTops);
63
+ expect(tops.map(([index, top]) => [index, top.toFixed(1)])).toEqual([
64
+ // Recall these are in inches
65
+ ['0', '0.2'],
66
+ ['1', '0.6'],
67
+ ['2', '1.1'],
68
+ ['3', '1.5'],
69
+ ['4', '2.0'],
70
+ ['5', '2.4'],
71
+ ]);
72
+ });
73
+ });
74
+
75
+ describe('worldUnitsToRenderedPixels', () => {
76
+ test('0 case', () => {
77
+ const mode = new Mode1UpLit(null, null);
78
+ expect(mode.worldUnitsToRenderedPixels(0)).toBe(0);
79
+ });
80
+ test('Misc cases', () => {
81
+ const mode = new Mode1UpLit(null, null);
82
+ mode.screenDPI = 100;
83
+ mode.realWorldReduce = 1;
84
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(100);
85
+ mode.screenDPI = 100;
86
+ mode.realWorldReduce = 2;
87
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(50);
88
+ mode.screenDPI = 78;
89
+ mode.realWorldReduce = 1;
90
+ expect(mode.worldUnitsToRenderedPixels(1)).toBe(78);
91
+ });
92
+ });
@@ -1,12 +1,12 @@
1
1
 
2
2
  import sinon from 'sinon';
3
3
  import { deepCopy } from '../utils.js';
4
- import BookReader from '../../src/BookReader.js';
5
- /** @typedef {import('../../src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
4
+ import BookReader from '@/src/BookReader.js';
5
+ /** @typedef {import('@/src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
6
6
 
7
7
  beforeAll(() => {
8
8
  global.alert = jest.fn();
9
- })
9
+ });
10
10
  afterEach(() => {
11
11
  jest.restoreAllMocks();
12
12
  sinon.restore();
@@ -47,6 +47,29 @@ describe('zoom', () => {
47
47
  });
48
48
  });
49
49
 
50
+ describe('page flip directions', () => {
51
+ test('animates the left page in the correct direction', () => {
52
+ const br = new BookReader({ data: SAMPLE_DATA });
53
+ br.init();
54
+
55
+ const fake = sinon.fake();
56
+ const fakeAnimWithCB = sinon.fake.yields();
57
+ const fakeAnim = sinon.fake((...args) =>
58
+ typeof args[args.length - 1] === 'function' ? fakeAnimWithCB(...args) : fake
59
+ );
60
+ sinon.replace(jQuery.prototype, 'animate', fakeAnim);
61
+
62
+ const fakeCSS = sinon.spy(jQuery.prototype, 'css');
63
+
64
+ br.next();
65
+
66
+ expect(fakeAnimWithCB.callCount).toBe(2);
67
+ // Find the call to .css() immediately preceding the second animation with a callback (i.e., the left page animation)
68
+ const preSecondAnimCssCallIndex = fakeCSS.getCalls().findIndex(call => call.calledAfter(fakeAnimWithCB.getCall(1))) - 1;
69
+ expect(fakeCSS.getCall(preSecondAnimCssCallIndex).args[0].left).toBe('');
70
+ });
71
+ });
72
+
50
73
  describe('prefetch', () => {
51
74
  test('loads nearby pages', () => {
52
75
  const br = new BookReader({ data: SAMPLE_DATA });
@@ -83,7 +106,7 @@ describe('draw 2up leaves', () => {
83
106
 
84
107
  br.init();
85
108
  expect(drawLeafs.callCount).toBe(1);
86
- })
109
+ });
87
110
 
88
111
  test('sets `this.displayedIndices`', () => {
89
112
  const extremelyWrongValueForDisplayedIndices = null;
@@ -98,7 +121,7 @@ describe('draw 2up leaves', () => {
98
121
  expect(br.displayedIndices).not.toBe(extremelyWrongValueForDisplayedIndices);
99
122
  expect(br.displayedIndices.length).toBe(2); // is array
100
123
  expect(br.displayedIndices).toEqual([-1, 0]); // default to starting index on right, placeholder for left
101
- })
124
+ });
102
125
  });
103
126
 
104
127
  describe('resizeSpread', () => {
@@ -122,13 +145,13 @@ describe('2up Container sizing', () => {
122
145
  test('baseLeafCss', () => {
123
146
  const br = new BookReader({ data: SAMPLE_DATA });
124
147
  br.init();
125
- br.calculateSpreadSize();
148
+ br._modes.mode2Up.calculateSpreadSize();
126
149
  expect(Object.keys(br._modes.mode2Up.baseLeafCss)).toEqual(['position', 'right', 'top', 'zIndex']);
127
150
  });
128
151
  test('heightCss', () => {
129
152
  const br = new BookReader({ data: SAMPLE_DATA });
130
153
  br.init();
131
- br.calculateSpreadSize();
154
+ br._modes.mode2Up.calculateSpreadSize();
132
155
  const heightStub = 1000;
133
156
  br.twoPage.height = heightStub;
134
157
  expect(Object.keys(br._modes.mode2Up.heightCss)).toEqual(['height']);
@@ -137,7 +160,7 @@ describe('2up Container sizing', () => {
137
160
  describe('left side', () => {
138
161
  const br = new BookReader({ data: SAMPLE_DATA });
139
162
  br.init();
140
- br.calculateSpreadSize();
163
+ br._modes.mode2Up.calculateSpreadSize();
141
164
 
142
165
  test('leftLeafCss', () => {
143
166
  expect(Object.keys(br._modes.mode2Up.leftLeafCss)).toEqual([
@@ -163,7 +186,7 @@ describe('2up Container sizing', () => {
163
186
  describe('right side', () => {
164
187
  const br = new BookReader({ data: SAMPLE_DATA });
165
188
  br.init();
166
- br.calculateSpreadSize();
189
+ br._modes.mode2Up.calculateSpreadSize();
167
190
 
168
191
  test('rightLeafCss', () => {
169
192
  expect(Object.keys(br._modes.mode2Up.rightLeafCss)).toEqual([
@@ -190,20 +213,20 @@ describe('2up Container sizing', () => {
190
213
  test('mainContainerCss', () => {
191
214
  const br = new BookReader({ data: SAMPLE_DATA });
192
215
  br.init();
193
- br.calculateSpreadSize();
216
+ br._modes.mode2Up.calculateSpreadSize();
194
217
 
195
218
  expect(Object.keys(br._modes.mode2Up.mainContainerCss)).toEqual(['height', 'width', 'position']);
196
219
  });
197
220
  test('spreadCoverCss', () => {
198
221
  const br = new BookReader({ data: SAMPLE_DATA });
199
222
  br.init();
200
- br.calculateSpreadSize();
223
+ br._modes.mode2Up.calculateSpreadSize();
201
224
  expect(Object.keys(br._modes.mode2Up.spreadCoverCss)).toEqual(['width', 'height', 'visibility']);
202
225
  });
203
226
  test('spineCss', () => {
204
227
  const br = new BookReader({ data: SAMPLE_DATA });
205
228
  br.init();
206
- br.calculateSpreadSize();
229
+ br._modes.mode2Up.calculateSpreadSize();
207
230
  expect(Object.keys(br._modes.mode2Up.spineCss)).toEqual(['width', 'height', 'left', 'top']);
208
231
  });
209
232
  });
@@ -220,19 +243,17 @@ describe('prepareTwoPageView', () => {
220
243
  const calculateSpreadSize = sinon.spy(mode2Up, 'calculateSpreadSize');
221
244
  const prunePageContainers = sinon.spy(mode2Up, 'prunePageContainers');
222
245
  const prefetch = sinon.spy(mode2Up, 'prefetch');
223
- const bindGestures = sinon.spy(br, 'bindGestures');
224
246
  const centerView = sinon.spy(mode2Up, 'centerView');
225
247
  const preparePopUp = sinon.spy(mode2Up, 'preparePopUp');
226
248
  const updateBrClasses = sinon.spy(br, 'updateBrClasses');
227
249
 
228
- br.prepareTwoPageView(undefined, undefined, true);
250
+ mode2Up.prepare(undefined, undefined, true);
229
251
  expect(prefetch.callCount).toBe(1);
230
252
 
231
253
  expect(resizeSpread.callCount).toBe(0);
232
254
  expect(drawLeafs.callCount).toBe(1);
233
255
  expect(calculateSpreadSize.callCount).toBe(1);
234
256
  expect(prunePageContainers.callCount).toBe(1);
235
- expect(bindGestures.callCount).toBe(1);
236
257
  expect(centerView.callCount).toBe(1);
237
258
  expect(preparePopUp.callCount).toBe(1);
238
259
  expect(updateBrClasses.callCount).toBe(1);
@@ -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,71 @@
1
+
2
+ import sinon from 'sinon';
3
+ import BookReader from '@/src/BookReader.js';
4
+ /** @typedef {import('@/src/BookReader/options.js').BookReaderOptions} BookReaderOptions */
5
+
6
+ beforeAll(() => {
7
+ global.alert = jest.fn();
8
+ });
9
+ afterEach(() => {
10
+ jest.restoreAllMocks();
11
+ sinon.restore();
12
+ });
13
+
14
+ /** @type {BookReaderOptions['data']} */
15
+ const SAMPLE_DATA = [
16
+ [
17
+ { width: 123, height: 123, uri: 'https://archive.org/image0.jpg', pageNum: '1' },
18
+ ],
19
+ [
20
+ { width: 123, height: 123, uri: 'https://archive.org/image1.jpg', pageNum: '2' },
21
+ { width: 123, height: 123, uri: 'https://archive.org/image2.jpg', pageNum: '3' },
22
+ ],
23
+ [
24
+ { width: 123, height: 123, uri: 'https://archive.org/image3.jpg', pageNum: '4' },
25
+ { width: 123, height: 123, uri: 'https://archive.org/image4.jpg', pageNum: '5' },
26
+ ],
27
+ [
28
+ { width: 123, height: 123, uri: 'https://archive.org/image5.jpg', pageNum: '6' },
29
+ ],
30
+ ];
31
+
32
+ describe('zoom', () => {
33
+ const br = new BookReader({ data: SAMPLE_DATA });
34
+ br.init();
35
+
36
+ test('initializes with default columns', () => {
37
+ expect(br.thumbColumns).toBe(br.options.thumbColumns);
38
+ });
39
+
40
+ test('removes column and redraws zooming in', () => {
41
+ const prepare = sinon.spy(br._modes.modeThumb, 'prepare');
42
+ const startColumns = br.thumbColumns;
43
+ br._modes.modeThumb.zoom('in');
44
+ expect(br.thumbColumns).toBe(startColumns - 1);
45
+ expect(prepare.callCount).toBe(1);
46
+ });
47
+
48
+ test('adds column and redraws zooming out', () => {
49
+ const prepare = sinon.spy(br._modes.modeThumb, 'prepare');
50
+ const startColumns = br.thumbColumns;
51
+ br._modes.modeThumb.zoom('out');
52
+ expect(br.thumbColumns).toBe(startColumns + 1);
53
+ expect(prepare.callCount).toBe(1);
54
+ });
55
+
56
+ test('keeps columns and no redraw at zooming in limit', () => {
57
+ const prepare = sinon.spy(br._modes.modeThumb, 'prepare');
58
+ br.thumbColumns = br.options.thumbMinZoomColumns;
59
+ br._modes.modeThumb.zoom('in');
60
+ expect(br.thumbColumns).toBe(br.options.thumbMinZoomColumns);
61
+ expect(prepare.callCount).toBe(0);
62
+ });
63
+
64
+ test('keeps columns and no redraw at zooming out limit', () => {
65
+ const prepare = sinon.spy(br._modes.modeThumb, 'prepare');
66
+ br.thumbColumns = br.options.thumbMaxZoomColumns;
67
+ br._modes.modeThumb.zoom('out');
68
+ expect(br.thumbColumns).toBe(br.options.thumbMaxZoomColumns);
69
+ expect(prepare.callCount).toBe(0);
70
+ });
71
+ });
@@ -1,19 +1,19 @@
1
1
  import sinon from 'sinon';
2
- import { getNavPageNumHtml } from '../../../src/BookReader/Navbar/Navbar.js';
3
- import BookReader from '../../../src/BookReader.js';
2
+ import { getNavPageNumHtml } from '@/src/BookReader/Navbar/Navbar.js';
3
+ import BookReader from '@/src/BookReader.js';
4
4
 
5
5
  describe('getNavPageNumHtml', () => {
6
6
  const f = getNavPageNumHtml;
7
7
  test('handle n-prefixed page numbers', () => {
8
- expect(f(3, 40, 'n3', '', 40)).toBe('Page (4 of 40)');
8
+ expect(f(3, 40, 'n3', '', 40)).toBe('(4 of 40)');
9
9
  });
10
10
 
11
11
  test('handle regular page numbers', () => {
12
- expect(f(3, 40, '14', '', 40)).toBe('Page 14 of 40');
12
+ expect(f(3, 40, '14', '', 40)).toBe('14 of 40');
13
13
  });
14
14
 
15
15
  test('handle no max page', () => {
16
- expect(f(3, 40, '14', '', null)).toBe('Page 14');
16
+ expect(f(3, 40, '14', '', null)).toBe('14');
17
17
  });
18
18
  });
19
19
 
@@ -97,9 +97,9 @@ describe('Navbar controls overrides', () => {
97
97
  const $viewMode = navbar.$root.find('.viewmode');
98
98
 
99
99
  expect($viewMode.find('.icon-thumb').length).toBe(1);
100
- $viewMode.click();
100
+ $viewMode.trigger("click");
101
101
  expect($viewMode.find('.icon-twopg').length).toBe(1);
102
- $viewMode.click();
102
+ $viewMode.trigger("click");
103
103
  expect($viewMode.find('.icon-thumb').length).toBe(1);
104
104
  });
105
105