@internetarchive/bookreader 5.0.0-9 → 5.0.0-90

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 (324) hide show
  1. package/.eslintrc.js +21 -19
  2. package/.github/workflows/node.js.yml +76 -11
  3. package/.github/workflows/npm-publish.yml +6 -20
  4. package/.testcaferc.js +10 -0
  5. package/BookReader/BookReader.css +404 -1125
  6. package/BookReader/BookReader.js +1 -1
  7. package/BookReader/BookReader.js.LICENSE.txt +20 -20
  8. package/BookReader/BookReader.js.map +1 -1
  9. package/BookReader/ia-bookreader-bundle.js +1782 -0
  10. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +7 -0
  11. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  12. package/BookReader/icons/1up.svg +1 -1
  13. package/BookReader/icons/2up.svg +1 -1
  14. package/BookReader/icons/advance.svg +1 -1
  15. package/BookReader/icons/chevron-right.svg +1 -1
  16. package/BookReader/icons/close-circle-dark.svg +1 -1
  17. package/BookReader/icons/close-circle.svg +1 -1
  18. package/BookReader/icons/fullscreen.svg +1 -1
  19. package/BookReader/icons/fullscreen_exit.svg +1 -1
  20. package/BookReader/icons/hamburger.svg +1 -1
  21. package/BookReader/icons/left-arrow.svg +1 -1
  22. package/BookReader/icons/magnify-minus.svg +1 -1
  23. package/BookReader/icons/magnify-plus.svg +1 -1
  24. package/BookReader/icons/magnify.svg +1 -1
  25. package/BookReader/icons/pause.svg +1 -1
  26. package/BookReader/icons/play.svg +1 -1
  27. package/BookReader/icons/playback-speed.svg +1 -1
  28. package/BookReader/icons/read-aloud.svg +1 -1
  29. package/BookReader/icons/review.svg +1 -1
  30. package/BookReader/icons/thumbnails.svg +1 -1
  31. package/BookReader/icons/voice.svg +1 -0
  32. package/BookReader/icons/volume-full.svg +1 -1
  33. package/BookReader/images/BRicons.svg +3 -3
  34. package/BookReader/images/books_graphic.svg +1 -1
  35. package/BookReader/images/icon_book.svg +1 -1
  36. package/BookReader/images/icon_bookmark.svg +1 -1
  37. package/BookReader/images/icon_gear.svg +1 -1
  38. package/BookReader/images/icon_hamburger.svg +1 -1
  39. package/BookReader/images/icon_home.svg +1 -1
  40. package/BookReader/images/icon_info.svg +1 -1
  41. package/BookReader/images/icon_one_page.svg +1 -1
  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 -1
  45. package/BookReader/images/icon_search_button.svg +1 -1
  46. package/BookReader/images/icon_share.svg +1 -1
  47. package/BookReader/images/icon_skip-ahead.svg +1 -1
  48. package/BookReader/images/icon_skip-back.svg +1 -1
  49. package/BookReader/images/icon_speaker.svg +1 -1
  50. package/BookReader/images/icon_speaker_open.svg +1 -1
  51. package/BookReader/images/icon_thumbnails.svg +1 -1
  52. package/BookReader/images/icon_toc.svg +1 -1
  53. package/BookReader/images/icon_two_pages.svg +1 -1
  54. package/BookReader/images/marker_chap-off.svg +1 -1
  55. package/BookReader/images/marker_chap-on.svg +1 -1
  56. package/BookReader/images/marker_srch-on.svg +1 -1
  57. package/BookReader/images/unviewable_page.png +0 -0
  58. package/BookReader/jquery-3.js +2 -0
  59. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  60. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  61. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  62. package/BookReader/plugins/plugin.autoplay.js +1 -1
  63. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  64. package/BookReader/plugins/plugin.chapters.js +25 -1
  65. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  66. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  67. package/BookReader/plugins/plugin.iframe.js +1 -1
  68. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  69. package/BookReader/plugins/plugin.iiif.js +2 -0
  70. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  71. package/BookReader/plugins/plugin.resume.js +1 -1
  72. package/BookReader/plugins/plugin.resume.js.map +1 -1
  73. package/BookReader/plugins/plugin.search.js +2 -1
  74. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  75. package/BookReader/plugins/plugin.search.js.map +1 -1
  76. package/BookReader/plugins/plugin.text_selection.js +2 -1
  77. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  78. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  79. package/BookReader/plugins/plugin.tts.js +1 -1
  80. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  81. package/BookReader/plugins/plugin.tts.js.map +1 -1
  82. package/BookReader/plugins/plugin.url.js +1 -1
  83. package/BookReader/plugins/plugin.url.js.map +1 -1
  84. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  85. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  86. package/BookReader/webcomponents-bundle.js +3 -0
  87. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  88. package/BookReader/webcomponents-bundle.js.map +1 -0
  89. package/BookReaderDemo/BookReaderDemo.css +18 -19
  90. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -3
  91. package/BookReaderDemo/BookReaderJSSimple.js +1 -0
  92. package/BookReaderDemo/IADemoBr.js +144 -0
  93. package/BookReaderDemo/demo-advanced.html +2 -2
  94. package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
  95. package/BookReaderDemo/demo-fullscreen-mobile.html +3 -5
  96. package/BookReaderDemo/demo-fullscreen.html +2 -4
  97. package/BookReaderDemo/demo-iiif.html +99 -12
  98. package/BookReaderDemo/demo-internetarchive.html +214 -18
  99. package/BookReaderDemo/demo-multiple.html +2 -1
  100. package/BookReaderDemo/demo-preview-pages.html +526 -525
  101. package/BookReaderDemo/demo-simple.html +2 -1
  102. package/BookReaderDemo/demo-vendor-fullscreen.html +2 -4
  103. package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
  104. package/BookReaderDemo/immersion-1up.html +2 -2
  105. package/BookReaderDemo/immersion-mode.html +2 -4
  106. package/BookReaderDemo/toggle_controls.html +3 -2
  107. package/BookReaderDemo/view_mode.html +2 -1
  108. package/BookReaderDemo/viewmode-cycle.html +2 -3
  109. package/CHANGELOG.md +584 -33
  110. package/README.md +14 -1
  111. package/babel.config.js +20 -0
  112. package/codecov.yml +6 -0
  113. package/index.html +5 -2
  114. package/jsconfig.json +19 -0
  115. package/netlify.toml +9 -0
  116. package/package.json +70 -62
  117. package/renovate.json +52 -0
  118. package/scripts/preversion.js +0 -1
  119. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  120. package/src/BookNavigator/assets/button-base.js +5 -2
  121. package/src/BookNavigator/assets/ia-logo.js +17 -0
  122. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  123. package/src/BookNavigator/assets/icon_close.js +1 -1
  124. package/src/BookNavigator/book-navigator.js +590 -0
  125. package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
  126. package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
  127. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  128. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
  129. package/src/BookNavigator/bookmarks/bookmarks-provider.js +27 -17
  130. package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
  131. package/src/BookNavigator/delete-modal-actions.js +1 -1
  132. package/src/BookNavigator/downloads/downloads-provider.js +36 -21
  133. package/src/BookNavigator/downloads/downloads.js +29 -25
  134. package/src/BookNavigator/search/search-provider.js +50 -28
  135. package/src/BookNavigator/search/search-results.js +24 -10
  136. package/src/BookNavigator/sharing.js +27 -0
  137. package/src/BookNavigator/viewable-files.js +95 -0
  138. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +13 -12
  139. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +7 -7
  140. package/src/BookReader/BookModel.js +76 -41
  141. package/src/BookReader/DragScrollable.js +233 -0
  142. package/src/BookReader/ImageCache.js +48 -15
  143. package/src/BookReader/Mode1Up.js +56 -351
  144. package/src/BookReader/Mode1UpLit.js +388 -0
  145. package/src/BookReader/Mode2Up.js +73 -1318
  146. package/src/BookReader/Mode2UpLit.js +777 -0
  147. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  148. package/src/BookReader/ModeSmoothZoom.js +312 -0
  149. package/src/BookReader/ModeThumb.js +19 -13
  150. package/src/BookReader/Navbar/Navbar.js +70 -54
  151. package/src/BookReader/PageContainer.js +116 -22
  152. package/src/BookReader/ReduceSet.js +3 -3
  153. package/src/BookReader/Toolbar/Toolbar.js +14 -41
  154. package/src/BookReader/events.js +2 -3
  155. package/src/BookReader/options.js +73 -15
  156. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  157. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  158. package/src/BookReader/utils/SelectionObserver.js +45 -0
  159. package/src/BookReader/utils/classes.js +1 -1
  160. package/src/BookReader/utils.js +128 -13
  161. package/src/BookReader.js +544 -1078
  162. package/src/BookReaderPlugin.js +44 -0
  163. package/src/assets/icons/magnify-minus.svg +3 -7
  164. package/src/assets/icons/magnify-plus.svg +3 -7
  165. package/src/assets/icons/voice.svg +1 -0
  166. package/src/assets/images/unviewable_page.png +0 -0
  167. package/src/css/BookReader.scss +1 -5
  168. package/src/css/_BRBookmarks.scss +1 -1
  169. package/src/css/_BRComponent.scss +1 -1
  170. package/src/css/_BRicon.scss +8 -2
  171. package/src/css/_BRmain.scss +16 -3
  172. package/src/css/_BRnav.scss +12 -42
  173. package/src/css/_BRpages.scss +170 -42
  174. package/src/css/_BRsearch.scss +68 -25
  175. package/src/css/_BRtoolbar.scss +5 -5
  176. package/src/css/_TextSelection.scss +87 -27
  177. package/src/css/_colorbox.scss +2 -2
  178. package/src/css/_controls.scss +24 -7
  179. package/src/css/_icons.scss +1 -1
  180. package/src/ia-bookreader/ia-bookreader.js +224 -0
  181. package/src/plugins/plugin.archive_analytics.js +84 -78
  182. package/src/plugins/plugin.autoplay.js +99 -104
  183. package/src/plugins/plugin.chapters.js +237 -191
  184. package/src/plugins/plugin.iframe.js +1 -1
  185. package/src/plugins/plugin.iiif.js +141 -0
  186. package/src/plugins/plugin.resume.js +53 -50
  187. package/src/plugins/plugin.text_selection.js +503 -175
  188. package/src/plugins/plugin.vendor-fullscreen.js +7 -7
  189. package/src/plugins/search/plugin.search.js +151 -127
  190. package/src/plugins/search/utils.js +43 -0
  191. package/src/plugins/search/view.js +37 -59
  192. package/src/plugins/tts/AbstractTTSEngine.js +75 -45
  193. package/src/plugins/tts/FestivalTTSEngine.js +21 -31
  194. package/src/plugins/tts/PageChunk.js +16 -23
  195. package/src/plugins/tts/PageChunkIterator.js +11 -17
  196. package/src/plugins/tts/WebTTSEngine.js +88 -72
  197. package/src/plugins/tts/plugin.tts.js +310 -350
  198. package/src/plugins/tts/utils.js +16 -26
  199. package/src/plugins/url/UrlPlugin.js +191 -0
  200. package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
  201. package/src/util/browserSniffing.js +22 -0
  202. package/src/util/docCookies.js +21 -2
  203. package/src/util/strings.js +1 -0
  204. package/tests/e2e/README.md +37 -0
  205. package/tests/e2e/autoplay.test.js +9 -6
  206. package/tests/e2e/base.test.js +8 -16
  207. package/tests/e2e/helpers/base.js +55 -50
  208. package/tests/e2e/helpers/debug.js +1 -1
  209. package/tests/e2e/helpers/mockSearch.js +19 -22
  210. package/tests/e2e/helpers/params.js +17 -0
  211. package/tests/e2e/helpers/rightToLeft.js +8 -14
  212. package/tests/e2e/helpers/search.js +73 -0
  213. package/tests/e2e/models/Navigation.js +20 -37
  214. package/tests/e2e/rightToLeft.test.js +4 -5
  215. package/tests/e2e/viewmode.test.js +40 -33
  216. package/tests/jest/BookNavigator/book-navigator.test.js +661 -0
  217. package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
  218. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
  219. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
  220. package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
  221. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
  222. package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
  223. package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
  224. package/tests/{karma → jest}/BookNavigator/search/search-results.test.js +109 -60
  225. package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
  226. package/tests/jest/BookNavigator/viewable-files/viewable-files-provider.test.js +80 -0
  227. package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
  228. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +74 -14
  229. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -0
  230. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  231. package/tests/jest/BookReader/Mode1UpLit.test.js +73 -0
  232. package/tests/jest/BookReader/Mode2Up.test.js +98 -0
  233. package/tests/jest/BookReader/Mode2UpLit.test.js +190 -0
  234. package/tests/jest/BookReader/ModeCoordinateSpace.test.js +16 -0
  235. package/tests/jest/BookReader/ModeSmoothZoom.test.js +218 -0
  236. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  237. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +42 -29
  238. package/tests/jest/BookReader/PageContainer.test.js +238 -0
  239. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  240. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +3 -3
  241. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  242. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  243. package/tests/jest/BookReader/utils/SelectionObserver.test.js +57 -0
  244. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  245. package/tests/jest/BookReader/utils.test.js +250 -0
  246. package/tests/jest/BookReader.keyboard.test.js +190 -0
  247. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +10 -2
  248. package/tests/{BookReader.test.js → jest/BookReader.test.js} +43 -53
  249. package/tests/jest/plugins/plugin.archive_analytics.test.js +20 -0
  250. package/tests/jest/plugins/plugin.autoplay.test.js +35 -0
  251. package/tests/jest/plugins/plugin.chapters.test.js +195 -0
  252. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +4 -4
  253. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +22 -35
  254. package/tests/jest/plugins/plugin.text_selection.test.js +316 -0
  255. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  256. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +19 -47
  257. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +42 -9
  258. package/tests/jest/plugins/search/utils.js +25 -0
  259. package/tests/jest/plugins/search/utils.test.js +29 -0
  260. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +30 -10
  261. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  262. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  263. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  264. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +47 -1
  265. package/tests/{plugins → jest/plugins}/tts/utils.test.js +1 -60
  266. package/tests/jest/plugins/url/UrlPlugin.test.js +198 -0
  267. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +57 -18
  268. package/tests/jest/setup.js +3 -0
  269. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  270. package/tests/jest/util/docCookies.test.js +24 -0
  271. package/tests/{util → jest/util}/strings.test.js +1 -1
  272. package/tests/{utils.js → jest/utils.js} +38 -0
  273. package/webpack.config.js +16 -10
  274. package/.babelrc +0 -12
  275. package/.dependabot/config.yml +0 -6
  276. package/.testcaferc.json +0 -5
  277. package/BookReader/bookreader-component-bundle.js +0 -1450
  278. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  279. package/BookReader/bookreader-component-bundle.js.map +0 -1
  280. package/BookReader/jquery-1.10.1.js +0 -2
  281. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  282. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  283. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  284. package/BookReader/plugins/plugin.mobile_nav.js +0 -2
  285. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  286. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  287. package/BookReaderDemo/IIIFBookReader.js +0 -207
  288. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  289. package/BookReaderDemo/demo-autoplay.html +0 -38
  290. package/BookReaderDemo/demo-iiif.js +0 -26
  291. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  292. package/karma.conf.js +0 -23
  293. package/src/BookNavigator/BookModel.js +0 -14
  294. package/src/BookNavigator/BookNavigator.js +0 -446
  295. package/src/BookNavigator/assets/book-loader.js +0 -27
  296. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  297. package/src/BookNavigator/search/a-search-result.js +0 -55
  298. package/src/BookReader/DebugConsole.js +0 -54
  299. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  300. package/src/ItemNavigator/ItemNavigator.js +0 -376
  301. package/src/ItemNavigator/providers/sharing.js +0 -29
  302. package/src/css/_MobileNav.scss +0 -194
  303. package/src/dragscrollable-br.js +0 -261
  304. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  305. package/src/plugins/plugin.mobile_nav.js +0 -287
  306. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  307. package/tests/BookReader/DebugConsole.test.js +0 -25
  308. package/tests/BookReader/Mode1Up.test.js +0 -164
  309. package/tests/BookReader/Mode2Up.test.js +0 -247
  310. package/tests/BookReader/PageContainer.test.js +0 -115
  311. package/tests/BookReader/utils.test.js +0 -109
  312. package/tests/e2e/helpers/desktopSearch.js +0 -72
  313. package/tests/e2e/helpers/mobileSearch.js +0 -85
  314. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  315. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  316. package/tests/karma/BookNavigator/search/search-provider.test.js +0 -23
  317. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  318. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  319. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  320. package/tests/plugins/plugin.autoplay.test.js +0 -52
  321. package/tests/plugins/plugin.chapters.test.js +0 -130
  322. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  323. package/tests/plugins/plugin.text_selection.test.js +0 -203
  324. package/tests/util/docCookies.test.js +0 -15
@@ -0,0 +1,233 @@
1
+ // @ts-check
2
+ /*
3
+ * jQuery dragscrollable Plugin
4
+ * Based off version: 1.0 (25-Jun-2009)
5
+ * Copyright (c) 2009 Miquel Herrera
6
+ *
7
+ * Portions Copyright (c) 2010 Reg Braithwaite
8
+ * Copyright (c) 2010 Internet Archive / Michael Ang
9
+ * Copyright (c) 2016 Internet Archive / Richard Caceres
10
+ *
11
+ * Dual licensed under the MIT and GPL licenses:
12
+ * http://www.opensource.org/licenses/mit-license.php
13
+ * http://www.gnu.org/licenses/gpl.html
14
+ */
15
+
16
+ /**
17
+ * @param {string} string_of_events
18
+ * @param {string} ns
19
+ * @returns
20
+ */
21
+ function append_namespace(string_of_events, ns) {
22
+ return string_of_events
23
+ .split(' ')
24
+ .map(event_name => event_name + ns)
25
+ .join(' ');
26
+ }
27
+
28
+ function left_top(event) {
29
+ /** @type {number} */
30
+ let x;
31
+ /** @type {number} */
32
+ let y;
33
+ if (typeof(event.clientX) != 'undefined') {
34
+ x = event.clientX;
35
+ y = event.clientY;
36
+ }
37
+ else if (typeof(event.screenX) != 'undefined') {
38
+ x = event.screenX;
39
+ y = event.screenY;
40
+ }
41
+ else if (typeof(event.targetTouches) != 'undefined') {
42
+ x = event.targetTouches[0].pageX;
43
+ y = event.targetTouches[0].pageY;
44
+ }
45
+ else if (typeof(event.originalEvent) == 'undefined') {
46
+ console.error("don't understand x and y for " + event.type, event);
47
+ }
48
+ else if (typeof(event.originalEvent.clientX) != 'undefined') {
49
+ x = event.originalEvent.clientX;
50
+ y = event.originalEvent.clientY;
51
+ }
52
+ else if (typeof(event.originalEvent.screenX) != 'undefined') {
53
+ x = event.originalEvent.screenX;
54
+ y = event.originalEvent.screenY;
55
+ }
56
+ else if (typeof(event.originalEvent.targetTouches) != 'undefined') {
57
+ x = event.originalEvent.targetTouches[0].pageX;
58
+ y = event.originalEvent.targetTouches[0].pageY;
59
+ }
60
+
61
+ return { left: x, top: y };
62
+ }
63
+
64
+ const DEFAULT_OPTIONS = {
65
+ /**
66
+ * @type {String|HTMLElement} jQuery selector to apply to each wrapped element to
67
+ * find which will be the dragging elements. Defaults to the first child of scrollable
68
+ * element
69
+ */
70
+ dragSelector: '>:first',
71
+
72
+ /** Will the dragging element accept propagated events? default is yes, a propagated
73
+ * mouse event on a inner element will be accepted and processed. If set to false,
74
+ * only events originated on the draggable elements will be processed. */
75
+ acceptPropagatedEvent: true,
76
+
77
+ /**
78
+ * Prevents the event to propagate further effectively disabling other default actions
79
+ */
80
+ preventDefault: true,
81
+
82
+ dragstart: 'mousedown touchstart',
83
+ dragcontinue: 'mousemove touchmove',
84
+ dragend: 'mouseup touchend', // mouseleave
85
+ dragMinDistance: 5,
86
+ namespace: '.ds',
87
+
88
+ /** Scroll the window rather than the element */
89
+ scrollWindow: false,
90
+ };
91
+
92
+ /**
93
+ * Adds the ability to manage elements scroll by dragging
94
+ * one or more of its descendant elements. Options parameter
95
+ * allow to specifically select which inner elements will
96
+ * respond to the drag events.
97
+ * usage examples:
98
+ *
99
+ * To add the scroll by drag to the element id=viewport when dragging its
100
+ * first child accepting any propagated events
101
+ * `new DragScrollable($('#viewport')[0]);`
102
+ *
103
+ * To add the scroll by drag ability to any element div of class viewport
104
+ * when dragging its first descendant of class dragMe responding only to
105
+ * evcents originated on the '.dragMe' elements.
106
+ * ```js
107
+ * new DragScrollable($('div.viewport')[0], {
108
+ * dragSelector: '.dragMe:first',
109
+ * acceptPropagatedEvent: false
110
+ * });
111
+ * ```
112
+ *
113
+ * Notice that some 'viewports' could be nested within others but events
114
+ * would not interfere as acceptPropagatedEvent is set to false.
115
+ */
116
+ export class DragScrollable {
117
+ /**
118
+ * @param {HTMLElement} element
119
+ * @param {Partial<DEFAULT_OPTIONS>} options
120
+ */
121
+ constructor(element, options = {}) {
122
+ this.handling_element = $(element);
123
+ /** @type {typeof DEFAULT_OPTIONS} */
124
+ this.settings = $.extend({}, DEFAULT_OPTIONS, options || {});
125
+ this.firstCoord = { left: 0, top: 0 };
126
+ this.lastCoord = { left: 0, top: 0 };
127
+
128
+ this.settings.dragstart = append_namespace(this.settings.dragstart, this.settings.namespace);
129
+ this.settings.dragcontinue = append_namespace(this.settings.dragcontinue, this.settings.namespace);
130
+ //settings.dragend = append_namespace(settings.dragend, settings.namespace);
131
+
132
+ // Set mouse initiating event on the desired descendant
133
+ this.handling_element.find(this.settings.dragSelector)
134
+ .on(this.settings.dragstart, this._dragStartHandler);
135
+ }
136
+
137
+ _shouldAbort() {
138
+ const isTouchDevice = !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);
139
+ return isTouchDevice;
140
+ }
141
+
142
+ /** @param {MouseEvent} event */
143
+ _dragStartHandler = (event) => {
144
+ if (this._shouldAbort()) { return true; }
145
+
146
+ // mousedown, left click, check propagation
147
+ if (event.which > 1 ||
148
+ (!this.settings.acceptPropagatedEvent && event.target != this.handling_element[0])) {
149
+ return false;
150
+ }
151
+
152
+ // Initial coordinates will be the last when dragging
153
+ this.lastCoord = this.firstCoord = left_top(event);
154
+
155
+ this.handling_element
156
+ .on(this.settings.dragcontinue, this._dragContinueHandler)
157
+ //.on(this.settings.dragend, this._dragEndHandler)
158
+ ;
159
+
160
+ // Note, we bind using addEventListener so we can use "capture" binding
161
+ // instead of "bubble" binding
162
+ this.settings.dragend.split(' ').forEach(event_name => {
163
+ this.handling_element[0].addEventListener(event_name, this._dragEndHandler, true);
164
+ });
165
+
166
+ if (this.settings.preventDefault) {
167
+ event.preventDefault();
168
+ return false;
169
+ }
170
+ }
171
+
172
+ /** @param {MouseEvent} event */
173
+ _dragContinueHandler = (event) => { // User is dragging
174
+ // console.log('drag continue');
175
+ if (this._shouldAbort()) { return true; }
176
+
177
+ const lt = left_top(event);
178
+
179
+ // How much did the mouse move?
180
+ const delta = {
181
+ left: (lt.left - this.lastCoord.left),
182
+ top: (lt.top - this.lastCoord.top),
183
+ };
184
+
185
+ const scrollTarget = this.settings.scrollWindow ? $(window) : this.handling_element;
186
+
187
+ // Set the scroll position relative to what ever the scroll is now
188
+ scrollTarget.scrollLeft( scrollTarget.scrollLeft() - delta.left );
189
+ scrollTarget.scrollTop( scrollTarget.scrollTop() - delta.top );
190
+
191
+ // Save where the cursor is
192
+ this.lastCoord = lt;
193
+
194
+ if (this.settings.preventDefault) {
195
+ event.preventDefault();
196
+ return false;
197
+ }
198
+ }
199
+
200
+ /** @param {MouseEvent} event */
201
+ _dragEndHandler = (event) => { // Stop scrolling
202
+ //console.log('dragEndHandler');
203
+
204
+ if (this._shouldAbort()) { return true; }
205
+
206
+ this.handling_element
207
+ .off(this.settings.dragcontinue)
208
+ // Note, for some reason, even though I removeEventListener below,
209
+ // this call to unbind is still necessary. I don't know why.
210
+ .off(this.settings.dragend);
211
+
212
+ // Note, we bind using addEventListener so we can use "capture" binding
213
+ // instead of "bubble" binding
214
+ this.settings.dragend.split(' ').forEach(event_name => {
215
+ this.handling_element[0].removeEventListener(event_name, this._dragEndHandler, true);
216
+ });
217
+
218
+ // How much did the mouse move total?
219
+ const delta = {
220
+ left: Math.abs(this.lastCoord.left - this.firstCoord.left),
221
+ top: Math.abs(this.lastCoord.top - this.firstCoord.top),
222
+ };
223
+ const distance = Math.max(delta.left, delta.top);
224
+
225
+ // Allow event to propagate if min distance was not achieved
226
+ if (this.settings.preventDefault && distance > this.settings.dragMinDistance) {
227
+ event.preventDefault();
228
+ event.stopImmediatePropagation();
229
+ event.stopPropagation();
230
+ return false;
231
+ }
232
+ }
233
+ }
@@ -7,8 +7,10 @@
7
7
  /** @typedef {import("./BookModel").BookModel} BookModel */
8
8
  /** @typedef {import("./BookModel").PageIndex} PageIndex */
9
9
  /** @typedef {import("./ReduceSet").ReduceSet} ReduceSet */
10
+ /** @typedef {import("./options").BookReaderOptions} BookReaderOptions */
10
11
 
11
12
  import { Pow2ReduceSet } from "./ReduceSet";
13
+ import { DEFAULT_OPTIONS } from "./options";
12
14
 
13
15
  export class ImageCache {
14
16
  /**
@@ -16,11 +18,25 @@ export class ImageCache {
16
18
  * @param {object} opts
17
19
  * @param {boolean} [opts.useSrcSet]
18
20
  * @param {ReduceSet} [opts.reduceSet]
21
+ * @param {BookReaderOptions['renderPageURI']} [opts.renderPageURI]
19
22
  */
20
- constructor(book, { useSrcSet = false, reduceSet = Pow2ReduceSet } = {}) {
23
+ constructor(
24
+ book,
25
+ {
26
+ useSrcSet = false,
27
+ reduceSet = Pow2ReduceSet,
28
+ renderPageURI = DEFAULT_OPTIONS.renderPageURI,
29
+ } = {},
30
+ ) {
31
+ /** @type {BookModel} */
21
32
  this.book = book;
33
+ /** @type {boolean} */
22
34
  this.useSrcSet = useSrcSet;
35
+ /** @type {ReduceSet} */
23
36
  this.reduceSet = reduceSet;
37
+ /** @type {BookReaderOptions['renderPageURI']} */
38
+ this.renderPageURI = renderPageURI;
39
+
24
40
  /** @type {{ [index: number]: { reduce: number, loaded: boolean }[] }} */
25
41
  this.cache = {};
26
42
  this.defaultScale = 8;
@@ -33,19 +49,35 @@ export class ImageCache {
33
49
  *
34
50
  * @param {PageIndex} index
35
51
  * @param {Number} reduce
52
+ * @param {HTMLImageElement?} [img]
36
53
  */
37
- image(index, reduce) {
54
+ image(index, reduce, img = null) {
55
+ const finalReduce = this.getFinalReduce(index, reduce);
56
+ return this._serveImageElement(index, finalReduce, img);
57
+ }
58
+
59
+ /**
60
+ * Get the final reduce factor to use for the given index
61
+ *
62
+ * @param {PageIndex} index
63
+ * @param {Number} reduce
64
+ */
65
+ getFinalReduce(index, reduce) {
38
66
  const cachedImages = this.cache[index] || [];
39
67
  const sufficientImages = cachedImages
40
68
  .filter(x => x.loaded && x.reduce <= reduce);
69
+
41
70
  if (sufficientImages.length) {
42
71
  // Choose the largest reduction factor that meets our needs
43
72
  const bestReduce = Math.max(...sufficientImages.map(e => e.reduce));
44
- return this._serveImageElement(index, bestReduce);
73
+ // Don't need to floor here, since we know the image is in the cache
74
+ // and hence was already floor'd by the below `else` clause before
75
+ // it was added
76
+ return bestReduce;
45
77
  } else {
46
78
  // Don't use a cache entry; i.e. a fresh fetch will be made
47
79
  // for this reduce
48
- return this._serveImageElement(index, reduce);
80
+ return this.reduceSet.floor(reduce);
49
81
  }
50
82
  }
51
83
 
@@ -87,26 +119,27 @@ export class ImageCache {
87
119
  *
88
120
  * @param {PageIndex} index
89
121
  * @param {number} reduce
122
+ * @param {HTMLImageElement?} [img]
90
123
  * @returns {JQuery<HTMLImageElement>} with base image classes
91
124
  */
92
- _serveImageElement(index, reduce) {
93
- const validReduce = this.reduceSet.floor(reduce);
94
- let cacheEntry = this.cache[index]?.find(e => e.reduce == validReduce);
125
+ _serveImageElement(index, reduce, img = null) {
126
+ let cacheEntry = this.cache[index]?.find(e => e.reduce == reduce);
95
127
  if (!cacheEntry) {
96
- cacheEntry = { reduce: validReduce, loaded: false };
128
+ cacheEntry = { reduce, loaded: false };
97
129
  const entries = this.cache[index] || (this.cache[index] = []);
98
130
  entries.push(cacheEntry);
99
131
  }
100
132
  const page = this.book.getPage(index);
101
133
 
102
- const $img = $('<img />', {
103
- 'class': 'BRpageimage',
104
- 'alt': 'Book page image',
105
- src: page.getURI(validReduce, 0),
106
- })
107
- .data('reduce', validReduce);
134
+ const uri = page.getURI(reduce, 0);
135
+ const $img = $(img || document.createElement('img'))
136
+ .addClass('BRpageimage')
137
+ .attr('alt', 'Book page image')
138
+ .data('reduce', reduce)
139
+ .data('src', uri);
140
+ this.renderPageURI($img[0], uri);
108
141
  if (this.useSrcSet) {
109
- $img.attr('srcset', page.getURISrcSet(validReduce));
142
+ $img.attr('srcset', page.getURISrcSet(reduce));
110
143
  }
111
144
  if (!cacheEntry.loaded) {
112
145
  $img.one('load', () => cacheEntry.loaded = true);