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

Sign up to get free protection for your applications and to get access to all the features.
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