@internetarchive/bookreader 5.0.0-5 → 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 (260) 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 +1 -1
  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/close-circle-dark.svg +1 -0
  13. package/BookReader/icons/magnify-minus.svg +1 -1
  14. package/BookReader/icons/magnify-plus.svg +1 -1
  15. package/BookReader/icons/pause.svg +1 -1
  16. package/BookReader/icons/playback-speed.svg +1 -1
  17. package/BookReader/icons/read-aloud.svg +1 -1
  18. package/BookReader/icons/voice.svg +1 -0
  19. package/BookReader/images/BRicons.svg +2 -2
  20. package/BookReader/images/books_graphic.svg +1 -1
  21. package/BookReader/images/icon_book.svg +1 -1
  22. package/BookReader/images/icon_gear.svg +1 -1
  23. package/BookReader/images/icon_info.svg +1 -1
  24. package/BookReader/images/icon_playback-rate.svg +1 -1
  25. package/BookReader/images/icon_search_button.svg +1 -1
  26. package/BookReader/images/icon_share.svg +1 -1
  27. package/BookReader/images/icon_speaker.svg +1 -1
  28. package/BookReader/images/icon_speaker_open.svg +1 -1
  29. package/BookReader/images/marker_chap-off.svg +1 -1
  30. package/BookReader/images/marker_chap-on.svg +1 -1
  31. package/BookReader/images/marker_srch-on.svg +1 -1
  32. package/BookReader/jquery-3.js +2 -0
  33. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  34. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  35. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  36. package/BookReader/plugins/plugin.autoplay.js +1 -1
  37. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  38. package/BookReader/plugins/plugin.chapters.js +1 -1
  39. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  40. package/BookReader/plugins/plugin.iframe.js +1 -1
  41. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  42. package/BookReader/plugins/plugin.mobile_nav.js +1 -1
  43. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  44. package/BookReader/plugins/plugin.resume.js +1 -1
  45. package/BookReader/plugins/plugin.resume.js.map +1 -1
  46. package/BookReader/plugins/plugin.search.js +1 -1
  47. package/BookReader/plugins/plugin.search.js.map +1 -1
  48. package/BookReader/plugins/plugin.text_selection.js +1 -1
  49. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  50. package/BookReader/plugins/plugin.tts.js +1 -1
  51. package/BookReader/plugins/plugin.tts.js.map +1 -1
  52. package/BookReader/plugins/plugin.url.js +1 -1
  53. package/BookReader/plugins/plugin.url.js.map +1 -1
  54. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  55. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  56. package/BookReader/webcomponents-bundle.js +3 -0
  57. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  58. package/BookReader/webcomponents-bundle.js.map +1 -0
  59. package/BookReaderDemo/BookReaderDemo.css +14 -1
  60. package/BookReaderDemo/IADemoBr.js +148 -0
  61. package/BookReaderDemo/demo-advanced.html +2 -2
  62. package/BookReaderDemo/demo-autoplay.html +2 -1
  63. package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
  64. package/BookReaderDemo/demo-fullscreen-mobile.html +2 -1
  65. package/BookReaderDemo/demo-fullscreen.html +2 -1
  66. package/BookReaderDemo/demo-iiif.html +2 -1
  67. package/BookReaderDemo/demo-internetarchive.html +84 -17
  68. package/BookReaderDemo/demo-multiple.html +2 -1
  69. package/BookReaderDemo/demo-preview-pages.html +2 -1
  70. package/BookReaderDemo/demo-simple.html +2 -1
  71. package/BookReaderDemo/demo-vendor-fullscreen.html +2 -1
  72. package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
  73. package/BookReaderDemo/immersion-1up.html +2 -1
  74. package/BookReaderDemo/immersion-mode.html +2 -1
  75. package/BookReaderDemo/toggle_controls.html +2 -1
  76. package/BookReaderDemo/view_mode.html +2 -1
  77. package/BookReaderDemo/viewmode-cycle.html +2 -3
  78. package/CHANGELOG.md +202 -0
  79. package/README.md +14 -1
  80. package/babel.config.js +18 -0
  81. package/codecov.yml +6 -0
  82. package/index.html +3 -0
  83. package/jsconfig.json +19 -0
  84. package/package.json +66 -56
  85. package/renovate.json +52 -0
  86. package/scripts/preversion.js +4 -1
  87. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  88. package/src/BookNavigator/assets/button-base.js +9 -2
  89. package/src/BookNavigator/assets/ia-logo.js +17 -0
  90. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  91. package/src/BookNavigator/assets/icon_close.js +1 -1
  92. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  93. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  94. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  95. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  96. package/src/BookNavigator/book-navigator.js +583 -0
  97. package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
  98. package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
  99. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  100. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +3 -8
  101. package/src/BookNavigator/bookmarks/bookmarks-provider.js +21 -8
  102. package/src/BookNavigator/bookmarks/ia-bookmarks.js +102 -66
  103. package/src/BookNavigator/delete-modal-actions.js +1 -1
  104. package/src/BookNavigator/downloads/downloads-provider.js +36 -21
  105. package/src/BookNavigator/downloads/downloads.js +41 -25
  106. package/src/BookNavigator/search/a-search-result.js +18 -13
  107. package/src/BookNavigator/search/search-provider.js +80 -28
  108. package/src/BookNavigator/search/search-results.js +10 -18
  109. package/src/BookNavigator/sharing.js +27 -0
  110. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +11 -10
  111. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
  112. package/src/BookNavigator/volumes/volumes-provider.js +114 -0
  113. package/src/BookNavigator/volumes/volumes.js +188 -0
  114. package/src/BookReader/BookModel.js +0 -29
  115. package/src/BookReader/DebugConsole.js +3 -3
  116. package/src/BookReader/DragScrollable.js +233 -0
  117. package/src/BookReader/Mode1Up.js +51 -351
  118. package/src/BookReader/Mode1UpLit.js +441 -0
  119. package/src/BookReader/Mode2Up.js +120 -105
  120. package/src/BookReader/ModeSmoothZoom.js +179 -0
  121. package/src/BookReader/ModeThumb.js +17 -11
  122. package/src/BookReader/Navbar/Navbar.js +10 -36
  123. package/src/BookReader/PageContainer.js +69 -6
  124. package/src/BookReader/ReduceSet.js +1 -1
  125. package/src/BookReader/Toolbar/Toolbar.js +10 -37
  126. package/src/BookReader/options.js +10 -0
  127. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  128. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  129. package/src/BookReader/utils.js +92 -13
  130. package/src/BookReader.js +431 -620
  131. package/src/assets/icons/close-circle-dark.svg +1 -0
  132. package/src/assets/icons/magnify-minus.svg +3 -7
  133. package/src/assets/icons/magnify-plus.svg +3 -7
  134. package/src/assets/icons/voice.svg +1 -0
  135. package/src/css/BookReader.scss +0 -12
  136. package/src/css/_BRComponent.scss +1 -1
  137. package/src/css/_BRmain.scss +19 -24
  138. package/src/css/_BRnav.scss +4 -26
  139. package/src/css/_BRpages.scss +35 -0
  140. package/src/css/_BRsearch.scss +25 -216
  141. package/src/css/_TextSelection.scss +14 -17
  142. package/src/css/_colorbox.scss +2 -2
  143. package/src/css/_controls.scss +17 -5
  144. package/src/css/_icons.scss +6 -0
  145. package/src/ia-bookreader/ia-bookreader.js +224 -0
  146. package/src/plugins/plugin.autoplay.js +4 -4
  147. package/src/plugins/plugin.chapters.js +28 -35
  148. package/src/plugins/plugin.mobile_nav.js +11 -10
  149. package/src/plugins/plugin.resume.js +3 -3
  150. package/src/plugins/plugin.text_selection.js +26 -39
  151. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  152. package/src/plugins/search/plugin.search.js +174 -116
  153. package/src/plugins/search/view.js +63 -179
  154. package/src/plugins/tts/AbstractTTSEngine.js +46 -37
  155. package/src/plugins/tts/FestivalTTSEngine.js +13 -14
  156. package/src/plugins/tts/PageChunk.js +15 -21
  157. package/src/plugins/tts/PageChunkIterator.js +8 -12
  158. package/src/plugins/tts/WebTTSEngine.js +66 -69
  159. package/src/plugins/tts/plugin.tts.js +92 -109
  160. package/src/plugins/tts/utils.js +0 -9
  161. package/src/plugins/url/UrlPlugin.js +184 -0
  162. package/src/plugins/{plugin.url.js → url/plugin.url.js} +28 -6
  163. package/src/util/manifestGenerator.js +0 -0
  164. package/tests/e2e/README.md +37 -0
  165. package/tests/e2e/autoplay.test.js +2 -2
  166. package/tests/e2e/base.test.js +7 -7
  167. package/tests/e2e/helpers/base.js +9 -3
  168. package/tests/e2e/helpers/debug.js +1 -1
  169. package/tests/e2e/helpers/desktopSearch.js +14 -13
  170. package/tests/e2e/helpers/mobileSearch.js +3 -3
  171. package/tests/e2e/helpers/params.js +17 -0
  172. package/tests/e2e/models/Navigation.js +13 -4
  173. package/tests/e2e/rightToLeft.test.js +4 -5
  174. package/tests/e2e/viewmode.test.js +38 -33
  175. package/tests/jest/BookNavigator/book-navigator.test.js +634 -0
  176. package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
  177. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
  178. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
  179. package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
  180. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
  181. package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
  182. package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
  183. package/tests/{karma/BookNavigator → jest/BookNavigator/search}/search-results.test.js +102 -58
  184. package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
  185. package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
  186. package/tests/jest/BookNavigator/volumes/volumes-provider.test.js +184 -0
  187. package/tests/jest/BookNavigator/volumes/volumes.test.js +97 -0
  188. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +34 -14
  189. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  190. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  191. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  192. package/tests/jest/BookReader/Mode1UpLit.test.js +92 -0
  193. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +36 -15
  194. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  195. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  196. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  197. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +88 -6
  198. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  199. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  200. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  201. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  202. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  203. package/tests/jest/BookReader/utils.test.js +186 -0
  204. package/tests/jest/BookReader.keyboard.test.js +190 -0
  205. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  206. package/tests/{BookReader.test.js → jest/BookReader.test.js} +18 -37
  207. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  208. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +4 -4
  209. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +10 -11
  210. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  211. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  212. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  213. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +39 -47
  214. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  215. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +63 -47
  216. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +35 -6
  217. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +9 -9
  218. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  219. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  220. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  221. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  222. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -28
  223. package/tests/jest/plugins/url/UrlPlugin.test.js +190 -0
  224. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  225. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  226. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  227. package/tests/{util → jest/util}/strings.test.js +1 -1
  228. package/tests/{utils.js → jest/utils.js} +38 -0
  229. package/webpack.config.js +11 -5
  230. package/.babelrc +0 -12
  231. package/.dependabot/config.yml +0 -6
  232. package/.testcaferc.json +0 -5
  233. package/BookReader/bookreader-component-bundle.js +0 -1450
  234. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  235. package/BookReader/bookreader-component-bundle.js.map +0 -1
  236. package/BookReader/jquery-1.10.1.js +0 -2
  237. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  238. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  239. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  240. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  241. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  242. package/karma.conf.js +0 -23
  243. package/src/BookNavigator/BookModel.js +0 -14
  244. package/src/BookNavigator/BookNavigator.js +0 -438
  245. package/src/BookNavigator/assets/book-loader.js +0 -27
  246. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  247. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  248. package/src/ItemNavigator/ItemNavigator.js +0 -372
  249. package/src/ItemNavigator/providers/sharing.js +0 -29
  250. package/src/Layers/sharing/sharing-provider.js +0 -22
  251. package/src/dragscrollable-br.js +0 -261
  252. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  253. package/src/plugins/plugin.bookmarks.js +0 -50
  254. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  255. package/tests/BookReader/Mode1Up.test.js +0 -164
  256. package/tests/BookReader/utils.test.js +0 -109
  257. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  258. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  259. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  260. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -1,12 +1,12 @@
1
1
  import sinon from 'sinon';
2
2
  import { afterEventLoop } from '../../utils.js';
3
- import AbstractTTSEngine from '../../../src/plugins/tts/AbstractTTSEngine.js';
4
- import PageChunkIterator from '../../../src/plugins/tts/PageChunkIterator.js';
5
- /** @typedef {import('../../../src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
3
+ import AbstractTTSEngine from '@/src/plugins/tts/AbstractTTSEngine.js';
4
+ import PageChunkIterator from '@/src/plugins/tts/PageChunkIterator.js';
5
+ /** @typedef {import('@/src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
6
6
 
7
7
  // Skipping because it's flaky. Fix in #672
8
8
  describe.skip('AbstractTTSEngine', () => {
9
- test('stops playing once done', () => {
9
+ test('stops playing once done', async () => {
10
10
  class DummyEngine extends AbstractTTSEngine {
11
11
  getVoices() { return []; }
12
12
  }
@@ -15,12 +15,12 @@ describe.skip('AbstractTTSEngine', () => {
15
15
  const stopStub = sinon.stub(d, 'stop');
16
16
  expect(stopStub.callCount).toBe(0);
17
17
  d.step();
18
- return afterEventLoop()
19
- .then(() => expect(stopStub.callCount).toBe(1));
18
+ await afterEventLoop();
19
+ expect(stopStub.callCount).toBe(1);
20
20
  });
21
21
  });
22
22
 
23
- for (const dummyVoice of [dummyVoice, dummyVoiceUnderscores]) {
23
+ for (const dummyVoice of [dummyVoiceHyphens, dummyVoiceUnderscores]) {
24
24
  describe(`getBestBookVoice with BCP47 ${dummyVoice == dummyVoiceUnderscores ? '+' : '-'} underscores`, () => {
25
25
  const { getBestBookVoice } = AbstractTTSEngine;
26
26
 
@@ -130,7 +130,7 @@ export const DUMMY_TTS_ENGINE_OPTS = {
130
130
  * @param {SpeechSynthesisVoice}
131
131
  * @return {SpeechSynthesisVoice}
132
132
  **/
133
- function dummyVoice(overrides) {
133
+ function dummyVoiceHyphens(overrides) {
134
134
  return Object.assign({
135
135
  default: false,
136
136
  lang: "en-US",
@@ -147,7 +147,7 @@ function dummyVoice(overrides) {
147
147
  * @return {SpeechSynthesisVoice}
148
148
  **/
149
149
  function dummyVoiceUnderscores(overrides) {
150
- const voice = dummyVoice(overrides);
150
+ const voice = dummyVoiceHyphens(overrides);
151
151
  voice.lang = voice.lang.replace('-', '_');
152
152
  return voice;
153
153
  }
@@ -1,10 +1,10 @@
1
- import FestivalTTSEngine from '../../../src/plugins/tts/FestivalTTSEngine.js';
1
+ import FestivalTTSEngine from '@/src/plugins/tts/FestivalTTSEngine.js';
2
2
  import sinon from 'sinon';
3
3
  import { afterEventLoop } from '../../utils.js';
4
4
  import { DUMMY_TTS_ENGINE_OPTS } from './AbstractTTSEngine.test.js';
5
- import PageChunk from '../../../src/plugins/tts/PageChunk.js';
6
- import PageChunkIterator from '../../../src/plugins/tts/PageChunkIterator.js';
7
- /** @typedef {import('../../../src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
5
+ import PageChunk from '@/src/plugins/tts/PageChunk.js';
6
+ import PageChunkIterator from '@/src/plugins/tts/PageChunkIterator.js';
7
+ /** @typedef {import('@/src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
8
8
 
9
9
  describe('iOSCaptureUserIntentHack', () => {
10
10
  test('synchronously calls createSound/play to capture user intent', () => {
@@ -1,4 +1,4 @@
1
- import PageChunk from '../../../src/plugins/tts/PageChunk.js';
1
+ import PageChunk from '@/src/plugins/tts/PageChunk.js';
2
2
 
3
3
  describe('_fixChunkRects', () => {
4
4
  const { _fixChunkRects } = PageChunk;
@@ -1,6 +1,6 @@
1
1
  import sinon from 'sinon';
2
- import PageChunkIterator from "../../../src/plugins/tts/PageChunkIterator";
3
- import PageChunk from '../../../src/plugins/tts/PageChunk';
2
+ import PageChunkIterator from "@/src/plugins/tts/PageChunkIterator";
3
+ import PageChunk from '@/src/plugins/tts/PageChunk';
4
4
 
5
5
  describe('Buffers pages', () => {
6
6
  test('Does not error if no room for reverse buffer', async () => {
@@ -109,7 +109,7 @@ describe('Iterates pages', () => {
109
109
  expect(iterator._cursor.chunk).toBe(0);
110
110
 
111
111
  for (let i = 2; i >= 0; i--) {
112
- await iterator.decrement()
112
+ await iterator.decrement();
113
113
  expect(iterator._cursor.page).toBe(49);
114
114
  expect(iterator._cursor.chunk).toBe(i);
115
115
  }
@@ -1,5 +1,5 @@
1
1
  import sinon from 'sinon';
2
- import { WebTTSSound } from '../../../src/plugins/tts/WebTTSEngine.js';
2
+ import { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
3
3
  import { afterEventLoop, eventTargetMixin } from '../../utils.js';
4
4
 
5
5
  beforeEach(() => {
@@ -1,6 +1,6 @@
1
1
  import sinon from 'sinon';
2
2
  import { afterEventLoop, eventTargetMixin } from '../../utils.js';
3
- import * as utils from '../../../src/plugins/tts/utils.js';
3
+ import * as utils from '@/src/plugins/tts/utils.js';
4
4
 
5
5
  describe('promisifyEvent', () => {
6
6
  const { promisifyEvent } = utils;
@@ -10,7 +10,7 @@ describe('promisifyEvent', () => {
10
10
  const resolveSpy = sinon.spy();
11
11
  promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
12
12
 
13
- await afterEventLoop()
13
+ await afterEventLoop();
14
14
  expect(resolveSpy.callCount).toBe(0);
15
15
  fakeTarget.dispatchEvent('pause', {});
16
16
  await afterEventLoop();
@@ -22,7 +22,7 @@ describe('promisifyEvent', () => {
22
22
  const resolveSpy = sinon.spy();
23
23
  promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
24
24
 
25
- await afterEventLoop()
25
+ await afterEventLoop();
26
26
  expect(resolveSpy.callCount).toBe(0);
27
27
  fakeTarget.dispatchEvent('pause', {});
28
28
  fakeTarget.dispatchEvent('pause', {});
@@ -66,31 +66,6 @@ describe('approximateWordCount', () => {
66
66
  });
67
67
  });
68
68
 
69
- describe('sleep', () => {
70
- const { sleep } = utils;
71
-
72
- test('Sleep 0 doest not called immediately', async () => {
73
- const spy = sinon.spy();
74
- sleep(0).then(spy);
75
- expect(spy.callCount).toBe(0);
76
- await afterEventLoop();
77
- expect(spy.callCount).toBe(1);
78
- });
79
-
80
- test('Waits the appropriate ms', async () => {
81
- const clock = sinon.useFakeTimers();
82
- const spy = sinon.spy();
83
- sleep(10).then(spy);
84
- expect(spy.callCount).toBe(0);
85
- clock.tick(10);
86
- expect(spy.callCount).toBe(0);
87
- clock.restore();
88
-
89
- await afterEventLoop();
90
- expect(spy.callCount).toBe(1);
91
- });
92
- });
93
-
94
69
  describe('toISO6391', () => {
95
70
  const { toISO6391 } = utils;
96
71
 
@@ -0,0 +1,190 @@
1
+ import { UrlPlugin } from '@/src/plugins/url/UrlPlugin';
2
+
3
+ afterEach(() => {
4
+ jest.clearAllMocks();
5
+ });
6
+
7
+ describe('UrlPlugin tests', () => {
8
+ const urlPlugin = new UrlPlugin();
9
+
10
+ describe('urlStateToUrlString tests', () => {
11
+ test('urlStateToUrlString with known states in schema', () => {
12
+ const urlState = { page: 'n7', mode: '1up', search: 'foo' };
13
+ const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', view: 'theater', sort: 'title_asc' };
14
+
15
+ const expectedUrlFromState = 'page/n7/mode/1up?q=foo';
16
+ const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&view=theater&sort=title_asc';
17
+
18
+ expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
19
+ expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
20
+ });
21
+
22
+ test('urlStateToUrlString with unknown states in schema', () => {
23
+ const urlState = { page: 'n7', mode: '1up' };
24
+ const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', viewer: 'theater', sortBy: 'title_asc' };
25
+
26
+ const expectedUrlFromState = 'page/n7/mode/1up';
27
+ const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&viewer=theater&sortBy=title_asc';
28
+
29
+ expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
30
+ expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
31
+ });
32
+
33
+ test('urlStateToUrlString with boolean value', () => {
34
+ const urlState = { page: 'n7', mode: '1up', search: 'foo', view: 'theater', wrapper: 'false' };
35
+ const expectedUrlFromState = 'page/n7/mode/1up?q=foo&view=theater&wrapper=false';
36
+
37
+ expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
38
+ });
39
+ });
40
+
41
+ describe('urlStringToUrlState tests', () => {
42
+ test('urlStringToUrlState without query string', () => {
43
+ const url = '/page/n7/mode/2up';
44
+ const url1 = '/page/n7/mode/1up';
45
+
46
+ expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up'});
47
+ expect(urlPlugin.urlStringToUrlState(url1)).toEqual({page: 'n7', mode: '1up'});
48
+ });
49
+
50
+ test('urlStringToUrlState with deprecated_for', () => {
51
+ const url = '/page/n7/mode/2up/search/hello';
52
+
53
+ expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up', q: 'hello'});
54
+ });
55
+
56
+ test('urlStringToUrlState with query string', () => {
57
+ const url = '/page/n7/mode/2up/search/hello?view=theather&foo=bar&sort=title_asc';
58
+ const url1 = '/mode/2up?ref=ol&ui=embed&wrapper=false&view=theater';
59
+
60
+ expect(urlPlugin.urlStringToUrlState(url)).toEqual(
61
+ {page: 'n7', mode: '2up', q: 'hello', view: 'theather', foo: 'bar', sort: 'title_asc'}
62
+ );
63
+ expect(urlPlugin.urlStringToUrlState(url1)).toEqual(
64
+ {mode: '2up', ref: 'ol', ui: 'embed', wrapper: 'false', view: 'theater'}
65
+ );
66
+ });
67
+
68
+ test('urlStringToUrlState compare search and ?q', () => {
69
+ const url = '/page/n7/mode/2up/search/hello';
70
+ urlPlugin.urlState = { q: 'hello' };
71
+
72
+ expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up', q: 'hello'});
73
+ });
74
+ });
75
+
76
+ describe('url plugin helper functions', () => {
77
+ test('setUrlParam', () => {
78
+ urlPlugin.urlState = {};
79
+ urlPlugin.setUrlParam('page', '20');
80
+ urlPlugin.setUrlParam('mode', '2up');
81
+
82
+ expect(urlPlugin.urlState).toEqual({page: '20', mode: '2up'});
83
+ });
84
+
85
+ test('removeUrlParam', () => {
86
+ urlPlugin.setUrlParam('page', '20');
87
+ urlPlugin.setUrlParam('mode', '2up');
88
+ urlPlugin.removeUrlParam('mode');
89
+
90
+ expect(urlPlugin.urlState).toEqual({page: '20'});
91
+ });
92
+
93
+ test('getUrlParam', () => {
94
+ urlPlugin.setUrlParam('page', '20');
95
+ urlPlugin.setUrlParam('mode', '2up');
96
+ expect(urlPlugin.getUrlParam('page')).toEqual('20');
97
+ expect(urlPlugin.getUrlParam('mode')).toEqual('2up');
98
+ });
99
+ });
100
+
101
+ describe('pullFromAddressBar and pushToAddressBar - hash mode', () => {
102
+ test('url first load - empty state', () => {
103
+ urlPlugin.urlState = {};
104
+ urlPlugin.urlMode = 'hash';
105
+
106
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#' });
107
+ expect(urlPlugin.urlState).toEqual({});
108
+
109
+ urlPlugin.pushToAddressBar();
110
+ expect(window.location.hash).toEqual('');
111
+ });
112
+
113
+ test('url without mode state value - use default', () => {
114
+ urlPlugin.urlState = {};
115
+ urlPlugin.urlMode = 'hash';
116
+
117
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12' });
118
+ expect(urlPlugin.urlState).toEqual({page: '12'});
119
+
120
+ urlPlugin.pushToAddressBar();
121
+ expect(window.location.hash).toEqual('#page/12');
122
+ });
123
+
124
+ test('url with query param', () => {
125
+ urlPlugin.urlState = {};
126
+ urlPlugin.urlMode = 'hash';
127
+
128
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12?q=hello&view=theater' });
129
+ expect(urlPlugin.urlState).toEqual({page: '12', q: 'hello', view: 'theater'});
130
+
131
+ urlPlugin.pushToAddressBar();
132
+ expect(window.location.hash).toEqual('#page/12?q=hello&view=theater');
133
+ });
134
+ });
135
+
136
+ describe('pullFromAddressBar and pushToAddressBar - history mode', () => {
137
+ test('url first load - empty state', () => {
138
+ urlPlugin.urlState = {};
139
+ urlPlugin.urlHistoryBasePath = '/details/foo';
140
+ urlPlugin.urlMode = 'history';
141
+
142
+ urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '' });
143
+ expect(urlPlugin.urlState).toEqual({});
144
+
145
+ urlPlugin.pushToAddressBar();
146
+ expect(window.location.pathname).toEqual('/details/foo');
147
+ });
148
+
149
+ test('url without mode state value', () => {
150
+ urlPlugin.urlState = {};
151
+ urlPlugin.urlHistoryBasePath = '/details/foo/';
152
+ urlPlugin.urlMode = 'history';
153
+
154
+ urlPlugin.pullFromAddressBar({ pathname: '/details/foo/page/12', search: '', hash: '' });
155
+ expect(urlPlugin.urlState).toEqual({page: '12'});
156
+
157
+ urlPlugin.pushToAddressBar();
158
+ expect(window.location.pathname).toEqual('/details/foo/page/12');
159
+ });
160
+
161
+ test('url with query param', () => {
162
+ urlPlugin.urlState = {};
163
+ urlPlugin.urlHistoryBasePath = '/details/foo/';
164
+ urlPlugin.urlMode = 'history';
165
+
166
+ urlPlugin.pullFromAddressBar({ pathname: '/details/foo/page/12', search: '?q=hello&view=theater', hash: '' });
167
+ expect(urlPlugin.urlState).toEqual({page: '12', q: 'hello', view: 'theater'});
168
+
169
+ urlPlugin.pushToAddressBar();
170
+ const locationUrl = `${window.location.pathname}${window.location.search}`;
171
+ expect(locationUrl).toEqual('/details/foo/page/12?q=hello&view=theater');
172
+ });
173
+
174
+ test('strips leading slash of incoming path name for no double slash', () => {
175
+ const urlPlugin = new UrlPlugin();
176
+ urlPlugin.urlMode = 'history';
177
+
178
+ urlPlugin.urlHistoryBasePath = '/details/SubBookTest/book1/GPORFP/';
179
+ urlPlugin.urlState = {
180
+ "mode": "1up",
181
+ };
182
+
183
+ urlPlugin.setUrlParam('sort', 'title_asc');
184
+ urlPlugin.setUrlParam('mode', 'thumb');
185
+
186
+ expect(window.location.href).toEqual('http://localhost/details/SubBookTest/book1/GPORFP/mode/thumb?sort=title_asc');
187
+ });
188
+ });
189
+
190
+ });
@@ -1,6 +1,6 @@
1
-
2
- import BookReader from '../../src/BookReader.js';
3
- import '../../src/plugins/plugin.url.js';
1
+ import BookReader from '@/src/BookReader.js';
2
+ import '@/src/plugins/url/plugin.url.js';
3
+ import sinon from 'sinon';
4
4
 
5
5
  let br;
6
6
  beforeAll(() => {
@@ -10,6 +10,7 @@ beforeAll(() => {
10
10
 
11
11
  afterEach(() => {
12
12
  jest.clearAllMocks();
13
+ sinon.restore();
13
14
  });
14
15
 
15
16
  describe('Plugin: URL controller', () => {
@@ -26,10 +27,10 @@ describe('Plugin: URL controller', () => {
26
27
  expect(defaultOptions).toHaveProperty('updateWindowTitle');
27
28
  expect(defaultOptions).toHaveProperty('defaults');
28
29
  expect(defaultOptions).toHaveProperty('bookId');
29
- })
30
+ });
30
31
 
31
32
  test('has a whitelist of params that it tracks', () => {
32
- ['page', 'search', 'mode', 'region', 'highlight']
33
+ ['page', 'search', 'mode', 'region', 'highlight'];
33
34
  const { defaultOptions: { urlTrackedParams } } = BookReader;
34
35
  expect(Array.isArray(urlTrackedParams)).toEqual(true);
35
36
  expect(urlTrackedParams.find(param => param === 'page')).toBeTruthy();
@@ -37,7 +38,8 @@ describe('Plugin: URL controller', () => {
37
38
  expect(urlTrackedParams.find(param => param === 'mode')).toBeTruthy();
38
39
  expect(urlTrackedParams.find(param => param === 'region')).toBeTruthy();
39
40
  expect(urlTrackedParams.find(param => param === 'highlight')).toBeTruthy();
40
- })
41
+ expect(urlTrackedParams.find(param => param === 'view')).toBeTruthy();
42
+ });
41
43
 
42
44
  test('initializes polling for url changes if using hash', () => {
43
45
  BookReader.prototype.urlStartLocationPolling = jest.fn();
@@ -60,7 +62,7 @@ describe('Plugin: URL controller', () => {
60
62
  br.urlUpdateFragment();
61
63
 
62
64
  expect(window.history.replaceState).toHaveBeenCalled();
63
- })
65
+ });
64
66
 
65
67
  test('updates URL when mode changes', () => {
66
68
  window.history.replaceState = jest.fn();
@@ -76,7 +78,7 @@ describe('Plugin: URL controller', () => {
76
78
  br.urlUpdateFragment();
77
79
 
78
80
  expect(window.history.replaceState).toHaveBeenCalled();
79
- })
81
+ });
80
82
 
81
83
  test('updates URL when search changes', () => {
82
84
  window.history.replaceState = jest.fn();
@@ -93,7 +95,24 @@ describe('Plugin: URL controller', () => {
93
95
  br.urlUpdateFragment();
94
96
 
95
97
  expect(window.history.replaceState).toHaveBeenCalled();
96
- })
98
+ });
99
+
100
+ test('updates URL when view changes', () => {
101
+ window.history.replaceState = jest.fn();
102
+ BookReader.prototype.currentIndex = jest.fn(() => 1);
103
+ BookReader.prototype.urlReadFragment = jest.fn(() => '');
104
+ BookReader.prototype.paramsFromCurrent = jest.fn(() => ({
105
+ index: 1,
106
+ mode: 2,
107
+ view: 'theater'
108
+ }));
109
+ BookReader.prototype.search = jest.fn();
110
+ br.options.urlMode = 'history';
111
+ br.init();
112
+ br.urlUpdateFragment();
113
+
114
+ expect(window.history.replaceState).toHaveBeenCalled();
115
+ });
97
116
 
98
117
  test('does not update URL when search in query string', () => {
99
118
  window.history.replaceState = jest.fn();
@@ -112,18 +131,18 @@ describe('Plugin: URL controller', () => {
112
131
  br.urlUpdateFragment();
113
132
 
114
133
  expect(window.history.replaceState).toHaveBeenCalledTimes(0);
115
- })
134
+ });
116
135
 
117
136
  test('only q= param is selected from url query params', () => {
118
- const INTIAL_URL = "http://127.0.0.1:8080/BookReaderDemo/demo-internetarchive.html?ocaid=adventuresofoli00dick&q=foo"
137
+ const INTIAL_URL = "http://127.0.0.1:8080/BookReaderDemo/demo-internetarchive.html?ocaid=adventuresofoli00dick&q=foo";
119
138
  const result = br.urlParamsFiltersOnlySearch(INTIAL_URL);
120
139
  expect(result).toBe("?q=foo");
121
- })
140
+ });
122
141
 
123
142
  test('only q= param is selected from url query params with special character', () => {
124
- const INTIAL_URL = "http://127.0.0.1:8080/BookReaderDemo/demo-internetarchive.html?ocaid=adventuresofoli00dick&q=foo%24%24"
143
+ const INTIAL_URL = "http://127.0.0.1:8080/BookReaderDemo/demo-internetarchive.html?ocaid=adventuresofoli00dick&q=foo%24%24";
125
144
  const result = br.urlParamsFiltersOnlySearch(INTIAL_URL);
126
145
  expect(result).toBe("?q=foo%24%24");
127
- })
146
+ });
128
147
  });
129
148
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isChrome, isFirefox, isSafari,
3
- } from '../../src/util/browserSniffing.js';
3
+ } from '@/src/util/browserSniffing.js';
4
4
 
5
5
  const TESTS = [
6
6
  {
@@ -1,4 +1,4 @@
1
- import * as docCookies from '../../src/util/docCookies.js';
1
+ import * as docCookies from '@/src/util/docCookies.js';
2
2
 
3
3
  afterEach(() => {
4
4
  jest.clearAllMocks();
@@ -1,4 +1,4 @@
1
- import { APPLY_FILTERS, applyVariables } from '../../src/util/strings.js';
1
+ import { APPLY_FILTERS, applyVariables } from '@/src/util/strings.js';
2
2
 
3
3
  describe('applyVariables', () => {
4
4
  test('null cases', () => {
@@ -31,6 +31,44 @@ export function eventTargetMixin() {
31
31
  };
32
32
  }
33
33
 
34
+ /** @implements {EventTarget} */
35
+ export class EventTargetSpy {
36
+ /** @type {Record<string, Function[]} */
37
+ _listeners = {}
38
+ get _totalListenerCount() {
39
+ return Object.values(this._listeners)
40
+ .map(a => a.length)
41
+ .reduce((a, b) => a + b, 0);
42
+ }
43
+
44
+ addEventListener(evName, listener) {
45
+ const listeners = this._listeners[evName] || [];
46
+ listeners.push(listener);
47
+ this._listeners[evName] = listeners;
48
+ }
49
+
50
+ dispatchEvent(evName, ev) {
51
+ const listeners = this._listeners[evName] || [];
52
+ listeners.forEach(fn => fn(ev));
53
+ }
54
+
55
+ removeEventListener(evName, listener) {
56
+ const listeners = this._listeners[evName] || [];
57
+ this._listeners[evName] = listeners.filter(fn => fn != listener);
58
+ }
59
+
60
+ /**
61
+ * @param {EventTarget} realEventTarget
62
+ */
63
+ static wrap(realEventTarget) {
64
+ const spy = new EventTargetSpy();
65
+ realEventTarget.addEventListener = spy.addEventListener.bind(spy);
66
+ realEventTarget.removeEventListener = spy.removeEventListener.bind(spy);
67
+ realEventTarget.dispatchEvent = spy.dispatchEvent.bind(spy);
68
+ return spy;
69
+ }
70
+ }
71
+
34
72
  /**
35
73
  * Lazy deep copy function; only supports objects (no classes)
36
74
  * @template T
package/webpack.config.js CHANGED
@@ -14,7 +14,11 @@ const shared = {
14
14
 
15
15
  module: {
16
16
  rules: [
17
- { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
17
+ {
18
+ test: /\.js$/,
19
+ exclude: /node_modules[/\\](?!(lit-element|lit-html|lit|@lit)[/\\]).*/,
20
+ loader: "babel-loader",
21
+ }
18
22
  ]
19
23
  },
20
24
 
@@ -31,6 +35,9 @@ module.exports = [
31
35
 
32
36
  // Output file -> srcfile
33
37
  entry: {
38
+ // Polyfill bundles
39
+ 'webcomponents-bundle.js': { import: '@webcomponents/webcomponentsjs/webcomponents-bundle.js' },
40
+
34
41
  // BookReader
35
42
  'BookReader.js': './src/BookReader.js',
36
43
 
@@ -39,15 +46,14 @@ module.exports = [
39
46
  'plugins/plugin.autoplay.js': { import: './src/plugins/plugin.autoplay.js', dependOn: 'BookReader.js' },
40
47
  'plugins/plugin.chapters.js': { import: './src/plugins/plugin.chapters.js', dependOn: 'BookReader.js' },
41
48
  'plugins/plugin.iframe.js': { import: './src/plugins/plugin.iframe.js', dependOn: 'BookReader.js' },
42
- 'plugins/plugin.menu_toggle.js': { import: './src/plugins/menu_toggle/plugin.menu_toggle.js', dependOn: 'BookReader.js' },
43
49
  'plugins/plugin.mobile_nav.js': { import: './src/plugins/plugin.mobile_nav.js', dependOn: 'BookReader.js' },
44
50
  'plugins/plugin.resume.js': { import: './src/plugins/plugin.resume.js', dependOn: 'BookReader.js' },
45
51
  'plugins/plugin.search.js': { import: './src/plugins/search/plugin.search.js', dependOn: 'BookReader.js' },
46
52
  'plugins/plugin.text_selection.js': { import: './src/plugins/plugin.text_selection.js', dependOn: 'BookReader.js' },
47
53
  'plugins/plugin.tts.js': { import: './src/plugins/tts/plugin.tts.js', dependOn: 'BookReader.js' },
48
- 'plugins/plugin.url.js': { import: './src/plugins/plugin.url.js', dependOn: 'BookReader.js' },
54
+ 'plugins/plugin.url.js': { import: './src/plugins/url/plugin.url.js', dependOn: 'BookReader.js' },
49
55
  'plugins/plugin.vendor-fullscreen.js': { import: './src/plugins/plugin.vendor-fullscreen.js', dependOn: 'BookReader.js' },
50
- 'bookreader-component-bundle.js': { import: './src/BookReaderComponent/BookReaderComponent.js', dependOn: 'BookReader.js' }
56
+ 'ia-bookreader-bundle.js': { import: './src/ia-bookreader/ia-bookreader.js', dependOn: 'BookReader.js' }
51
57
  },
52
58
 
53
59
  externals: {
@@ -80,7 +86,7 @@ module.exports = [
80
86
  ...shared,
81
87
 
82
88
  entry: {
83
- 'jquery-1.10.1.js': { import: './src/jquery-wrapper.js' },
89
+ 'jquery-3.js': { import: './src/jquery-wrapper.js' },
84
90
  },
85
91
  },
86
92
  ];
package/.babelrc DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "presets": [
3
- [
4
- "@babel/preset-env",
5
- {
6
- "targets": "> 2%, ie 11, edge 14, samsung > 9, OperaMini all, UCAndroid > 12",
7
- "useBuiltIns": "usage",
8
- "corejs": 3
9
- }
10
- ]
11
- ]
12
- }
@@ -1,6 +0,0 @@
1
- version: 1
2
-
3
- update_configs:
4
- - package_manager: "javascript"
5
- directory: "/"
6
- update_schedule: "monthly"
package/.testcaferc.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "appCommand": "npm run serve",
3
- "browsers": ["chrome:headless", "firefox:headless"],
4
- "src": ["tests/e2e/**/*test.js"]
5
- }