@internetarchive/bookreader 5.0.0-28-remove-url-defaults → 5.0.0-30-b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. package/.husky/_/husky.sh +30 -0
  2. package/BookReader/BookReader.css +1 -1
  3. package/BookReader/BookReader.js +1 -1
  4. package/BookReader/BookReader.js.map +1 -1
  5. package/BookReader/ia-bookreader-bundle.js +1458 -0
  6. package/BookReader/{bookreader-component-bundle.js.LICENSE.txt → ia-bookreader-bundle.js.LICENSE.txt} +12 -0
  7. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  8. package/BookReader/plugins/plugin.search.js +1 -1
  9. package/BookReader/plugins/plugin.search.js.map +1 -1
  10. package/BookReaderDemo/BookReaderDemo.css +14 -1
  11. package/BookReaderDemo/IADemoBr.js +107 -0
  12. package/BookReaderDemo/demo-internetarchive.html +64 -99
  13. package/CHANGELOG.md +4 -0
  14. package/package.json +9 -6
  15. package/src/BookNavigator/assets/ia-logo.js +17 -0
  16. package/src/BookNavigator/book-navigator.js +528 -0
  17. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  18. package/src/BookNavigator/bookmarks/bookmarks-provider.js +20 -8
  19. package/src/BookNavigator/bookmarks/ia-bookmarks.js +84 -51
  20. package/src/BookNavigator/downloads/downloads-provider.js +5 -9
  21. package/src/BookNavigator/downloads/downloads.js +1 -0
  22. package/src/BookNavigator/search/search-provider.js +15 -8
  23. package/src/BookNavigator/sharing.js +27 -0
  24. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +9 -8
  25. package/src/BookNavigator/volumes/volumes-provider.js +3 -4
  26. package/src/BookReader/options.js +6 -0
  27. package/src/BookReader.js +20 -8
  28. package/src/css/_BRComponent.scss +1 -1
  29. package/src/ia-bookreader/ia-bookreader.js +209 -0
  30. package/src/plugins/search/plugin.search.js +9 -9
  31. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  32. package/{src → stat}/BookNavigator/BookNavigator.js +109 -102
  33. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  34. package/stat/BookNavigator/assets/button-base.js +61 -0
  35. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  36. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  37. package/stat/BookNavigator/assets/icon_close.js +3 -0
  38. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  39. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  40. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  41. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  42. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  43. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  44. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  45. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  46. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  47. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  48. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  49. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  50. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  51. package/stat/BookNavigator/downloads/downloads.js +139 -0
  52. package/stat/BookNavigator/provider-config.js +0 -0
  53. package/stat/BookNavigator/search/a-search-result.js +55 -0
  54. package/stat/BookNavigator/search/search-provider.js +180 -0
  55. package/stat/BookNavigator/search/search-results.js +360 -0
  56. package/{src/ItemNavigator/providers → stat/BookNavigator}/sharing.js +3 -5
  57. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  58. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  59. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  60. package/stat/BookNavigator/volumes/volumes.js +178 -0
  61. package/stat/BookReader/BookModel.js +518 -0
  62. package/stat/BookReader/DebugConsole.js +54 -0
  63. package/stat/BookReader/DragScrollable.js +233 -0
  64. package/stat/BookReader/ImageCache.js +116 -0
  65. package/stat/BookReader/Mode1Up.js +102 -0
  66. package/stat/BookReader/Mode1UpLit.js +434 -0
  67. package/stat/BookReader/Mode2Up.js +1372 -0
  68. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  69. package/stat/BookReader/ModeThumb.js +344 -0
  70. package/stat/BookReader/Navbar/Navbar.js +310 -0
  71. package/stat/BookReader/PageContainer.js +120 -0
  72. package/stat/BookReader/ReduceSet.js +26 -0
  73. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  74. package/stat/BookReader/events.js +20 -0
  75. package/stat/BookReader/options.js +324 -0
  76. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  77. package/stat/BookReader/utils/classes.js +36 -0
  78. package/stat/BookReader/utils.js +240 -0
  79. package/stat/BookReader.js +2550 -0
  80. package/{src → stat}/BookReaderComponent/BookReaderComponent.js +15 -10
  81. package/stat/assets/icons/1up.svg +12 -0
  82. package/stat/assets/icons/2up.svg +15 -0
  83. package/stat/assets/icons/advance.svg +26 -0
  84. package/stat/assets/icons/chevron-right.svg +1 -0
  85. package/stat/assets/icons/close-circle-dark.svg +1 -0
  86. package/stat/assets/icons/close-circle.svg +1 -0
  87. package/stat/assets/icons/fullscreen.svg +17 -0
  88. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  89. package/stat/assets/icons/hamburger.svg +15 -0
  90. package/stat/assets/icons/left-arrow.svg +12 -0
  91. package/stat/assets/icons/magnify-minus.svg +16 -0
  92. package/stat/assets/icons/magnify-plus.svg +17 -0
  93. package/stat/assets/icons/magnify.svg +15 -0
  94. package/stat/assets/icons/pause.svg +23 -0
  95. package/stat/assets/icons/play.svg +22 -0
  96. package/stat/assets/icons/playback-speed.svg +34 -0
  97. package/stat/assets/icons/read-aloud.svg +22 -0
  98. package/stat/assets/icons/review.svg +22 -0
  99. package/stat/assets/icons/thumbnails.svg +17 -0
  100. package/stat/assets/icons/voice.svg +1 -0
  101. package/stat/assets/icons/volume-full.svg +22 -0
  102. package/stat/assets/images/BRicons.png +0 -0
  103. package/stat/assets/images/BRicons.svg +94 -0
  104. package/stat/assets/images/BRicons_ia.png +0 -0
  105. package/stat/assets/images/back_pages.png +0 -0
  106. package/stat/assets/images/book_bottom_icon.png +0 -0
  107. package/stat/assets/images/book_down_icon.png +0 -0
  108. package/stat/assets/images/book_left_icon.png +0 -0
  109. package/stat/assets/images/book_leftmost_icon.png +0 -0
  110. package/stat/assets/images/book_right_icon.png +0 -0
  111. package/stat/assets/images/book_rightmost_icon.png +0 -0
  112. package/stat/assets/images/book_top_icon.png +0 -0
  113. package/stat/assets/images/book_up_icon.png +0 -0
  114. package/stat/assets/images/books_graphic.svg +177 -0
  115. package/stat/assets/images/booksplit.png +0 -0
  116. package/stat/assets/images/control_pause_icon.png +0 -0
  117. package/stat/assets/images/control_play_icon.png +0 -0
  118. package/stat/assets/images/embed_icon.png +0 -0
  119. package/stat/assets/images/icon-home-ia.png +0 -0
  120. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  121. package/stat/assets/images/icon_alert-xs.png +0 -0
  122. package/stat/assets/images/icon_book.svg +12 -0
  123. package/stat/assets/images/icon_bookmark.svg +12 -0
  124. package/stat/assets/images/icon_close-pop.png +0 -0
  125. package/stat/assets/images/icon_download.png +0 -0
  126. package/stat/assets/images/icon_gear.svg +14 -0
  127. package/stat/assets/images/icon_hamburger.svg +20 -0
  128. package/stat/assets/images/icon_home.png +0 -0
  129. package/stat/assets/images/icon_home.svg +21 -0
  130. package/stat/assets/images/icon_home_ia.png +0 -0
  131. package/stat/assets/images/icon_indicator.png +0 -0
  132. package/stat/assets/images/icon_info.svg +11 -0
  133. package/stat/assets/images/icon_one_page.svg +8 -0
  134. package/stat/assets/images/icon_pause.svg +1 -0
  135. package/stat/assets/images/icon_play.svg +1 -0
  136. package/stat/assets/images/icon_playback-rate.svg +15 -0
  137. package/stat/assets/images/icon_return.png +0 -0
  138. package/stat/assets/images/icon_search_button.svg +8 -0
  139. package/stat/assets/images/icon_share.svg +9 -0
  140. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  141. package/stat/assets/images/icon_skip-back.svg +13 -0
  142. package/stat/assets/images/icon_speaker.svg +18 -0
  143. package/stat/assets/images/icon_speaker_open.svg +10 -0
  144. package/stat/assets/images/icon_thumbnails.svg +12 -0
  145. package/stat/assets/images/icon_toc.svg +5 -0
  146. package/stat/assets/images/icon_two_pages.svg +9 -0
  147. package/stat/assets/images/icon_zoomer.png +0 -0
  148. package/stat/assets/images/loading.gif +0 -0
  149. package/stat/assets/images/logo_icon.png +0 -0
  150. package/stat/assets/images/marker_chap-off.png +0 -0
  151. package/stat/assets/images/marker_chap-off.svg +11 -0
  152. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  153. package/stat/assets/images/marker_chap-on.png +0 -0
  154. package/stat/assets/images/marker_chap-on.svg +11 -0
  155. package/stat/assets/images/marker_srch-on.svg +11 -0
  156. package/stat/assets/images/marker_srchchap-off.png +0 -0
  157. package/stat/assets/images/marker_srchchap-on.png +0 -0
  158. package/stat/assets/images/nav_control-dn.png +0 -0
  159. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  160. package/stat/assets/images/nav_control-up.png +0 -0
  161. package/stat/assets/images/nav_control-up_ia.png +0 -0
  162. package/stat/assets/images/nav_control.png +0 -0
  163. package/stat/assets/images/one_page_mode_icon.png +0 -0
  164. package/stat/assets/images/paper-badge.png +0 -0
  165. package/stat/assets/images/print_icon.png +0 -0
  166. package/stat/assets/images/progressbar.gif +0 -0
  167. package/stat/assets/images/right_edges.png +0 -0
  168. package/stat/assets/images/slider.png +0 -0
  169. package/stat/assets/images/slider_ia.png +0 -0
  170. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  171. package/stat/assets/images/transparent.png +0 -0
  172. package/stat/assets/images/two_page_mode_icon.png +0 -0
  173. package/stat/assets/images/zoom_in_icon.png +0 -0
  174. package/stat/assets/images/zoom_out_icon.png +0 -0
  175. package/stat/css/BookReader.scss +89 -0
  176. package/stat/css/_BRBookmarks.scss +29 -0
  177. package/stat/css/_BRComponent.scss +13 -0
  178. package/stat/css/_BRfloat.scss +197 -0
  179. package/stat/css/_BRicon.scss +48 -0
  180. package/stat/css/_BRmain.scss +251 -0
  181. package/stat/css/_BRnav.scss +359 -0
  182. package/stat/css/_BRpages.scss +139 -0
  183. package/stat/css/_BRsearch.scss +226 -0
  184. package/stat/css/_BRtoolbar.scss +84 -0
  185. package/stat/css/_BRvendor.scss +5 -0
  186. package/stat/css/_MobileNav.scss +194 -0
  187. package/stat/css/_TextSelection.scss +32 -0
  188. package/stat/css/_colorbox.scss +52 -0
  189. package/stat/css/_controls.scss +253 -0
  190. package/stat/css/_icons.scss +121 -0
  191. package/stat/jquery-wrapper.js +4 -0
  192. package/stat/plugins/plugin.archive_analytics.js +86 -0
  193. package/stat/plugins/plugin.autoplay.js +129 -0
  194. package/stat/plugins/plugin.chapters.js +248 -0
  195. package/stat/plugins/plugin.iframe.js +48 -0
  196. package/stat/plugins/plugin.mobile_nav.js +288 -0
  197. package/stat/plugins/plugin.resume.js +68 -0
  198. package/stat/plugins/plugin.text_selection.js +291 -0
  199. package/stat/plugins/plugin.url.js +198 -0
  200. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  201. package/stat/plugins/search/plugin.search.js +439 -0
  202. package/stat/plugins/search/view.js +439 -0
  203. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  204. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  205. package/stat/plugins/tts/PageChunk.js +107 -0
  206. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  207. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  208. package/stat/plugins/tts/plugin.tts.js +357 -0
  209. package/stat/plugins/tts/tooltip_dict.js +15 -0
  210. package/stat/plugins/tts/utils.js +91 -0
  211. package/stat/util/browserSniffing.js +30 -0
  212. package/stat/util/debouncer.js +26 -0
  213. package/stat/util/docCookies.js +67 -0
  214. package/stat/util/strings.js +34 -0
  215. package/tests/e2e/viewmode.test.js +30 -30
  216. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +64 -52
  217. package/tests/karma/BookNavigator/book-navigator.test.js +413 -108
  218. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  219. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +6 -3
  220. package/tests/karma/BookNavigator/search/search-provider.test.js +106 -6
  221. package/tests/karma/BookNavigator/search/search-results.test.js +0 -2
  222. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +29 -20
  223. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +41 -17
  224. package/webpack.config.js +1 -1
  225. package/.nvmrc +0 -1
  226. package/BookReader/bookreader-component-bundle.js +0 -1436
  227. package/BookReader/bookreader-component-bundle.js.map +0 -1
  228. package/src/BookNavigator/assets/book-loader.js +0 -27
  229. package/src/ItemNavigator/ItemNavigator.js +0 -377
@@ -6,175 +6,480 @@ import {
6
6
  expect,
7
7
  } from '@open-wc/testing';
8
8
  import sinon from 'sinon';
9
+ import DownloadsProvider from '../../../src/BookNavigator/downloads/downloads-provider.js';
10
+ import SearchProvider from '../../../src/BookNavigator/search/search-provider.js';
11
+ import SharingProvider from '../../../src/BookNavigator/sharing.js';
12
+ import VisualAdjustmentsProvider from '../../../src/BookNavigator/visual-adjustments/visual-adjustments-provider.js';
13
+ import VolumesProvider from '../../../src/BookNavigator/volumes/volumes-provider.js';
14
+ import { ModalManager } from '@internetarchive/modal-manager';
15
+ import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
16
+ import '../../../src/BookNavigator/book-navigator.js';
9
17
 
10
- import '../../../src/BookNavigator/BookNavigator.js';
11
- import BRFullscreenMgr from '../../../src/BookNavigator/br-fullscreen-mgr.js';
18
+ const promise0 = () => new Promise(res => setTimeout(res, 0));
12
19
 
13
- const container = () => {
14
- const item = {};
20
+ const container = (sharedObserver = null) => {
21
+ const itemStub = {
22
+ metadata: {
23
+ identifier: 'foo',
24
+ creator: 'bar',
25
+ title: 'baz',
26
+ }
27
+ };
28
+ const modalMgr = new ModalManager();
15
29
  return html`
16
30
  <book-navigator
17
- .item=${item}
18
- .baseHost
31
+ .itemMD=${itemStub}
32
+ .baseHost=${`https://foo.archive.org`}
33
+ .sharedObserver=${sharedObserver || new SharedResizeObserver()}
34
+ .modal=${modalMgr}
19
35
  >
20
- <div slot="bookreader">
36
+ <div slot="theater-main">
37
+ <div id="BookReader"></div>
21
38
  <p class="visible-in-reader">now showing</p>
22
- <div>
23
- <p class="bunny">foo</p>
24
- </
39
+ <\div>
40
+ </book-navigator>
25
41
  `;
26
42
  };
27
43
 
28
- beforeEach(() => {
29
- const body = document.querySelector('body');
30
- const brHook = document.createElement('div');
31
- brHook.setAttribute('id', 'BookReader');
32
- body.appendChild(brHook);
33
- });
34
-
35
44
  afterEach(() => {
36
45
  window.br = null;
37
46
  fixtureCleanup();
47
+ const body = document.querySelector('body');
48
+ body.innerHTML = '';
49
+ sinon.restore();
38
50
  });
39
51
 
40
52
 
41
53
  describe('<book-navigator>', () => {
42
- describe('first update', () => {
43
- it('binds global event listeners', async () => {
44
- const el = fixtureSync(container());
45
- const spy = sinon.spy(el, 'bindEventListeners');
46
- await elementUpdated(el);
47
- expect(spy.callCount).to.equal(1);
48
- });
54
+ describe("How it loads", () => {
55
+ describe('Attaches BookReader listeners before `br.init` is called', () => {
56
+ it('binds global event listeners', async () => {
57
+ const el = fixtureSync(container());
58
+ const spy = sinon.spy(el, 'bindEventListeners');
59
+ await elementUpdated(el);
60
+ expect(spy.callCount).to.equal(1);
61
+ });
62
+ it('Listens for Global Event @BookReader:PostInit', async () => {
63
+ const brStub = {
64
+ resize: sinon.fake(),
65
+ currentIndex: sinon.fake(),
66
+ jumpToIndex: sinon.fake(),
67
+ options: { enableMultipleBooks: false }, // for multipleBooks
68
+ el: '#BookReader'
69
+ };
70
+
71
+ const sharedObserver = new SharedResizeObserver();
72
+ sinon.spy(sharedObserver, 'addObserver');
73
+ const el = fixtureSync(container(sharedObserver));
74
+
75
+ el.initializeBookSubmenus = sinon.fake();
76
+ el.emitLoadingStatusUpdate = sinon.fake();
77
+ el.handleResize = sinon.fake();
78
+ await elementUpdated(el);
79
+
80
+ expect(brStub.resize.callCount).to.equal(0);
81
+
82
+ window.dispatchEvent(new CustomEvent('BookReader:PostInit', {
83
+ detail: { props: brStub }
84
+ }));
85
+ await elementUpdated(el);
86
+
87
+ expect(el.emitLoadingStatusUpdate.callCount).to.equal(1);
88
+ expect(el.bookreader).to.equal(brStub); // sets bookreader
89
+ expect(el.bookReaderLoaded).to.be.true; // notes bookreader is loaded
90
+ expect(el.bookReaderCannotLoad).to.be.false;
91
+ expect(sharedObserver.addObserver.callCount).to.equal(1);
92
+
93
+ await promise0();
49
94
 
50
- it('emits a BrBookNav:PostInit event', async () => {
95
+ expect(brStub.resize.callCount > 0).to.be.true;
96
+ });
97
+ });
98
+ it('Emits a BrBookNav:PostInit event at completion', async () => {
51
99
  let initEventFired = false;
52
100
  window.addEventListener('BrBookNav:PostInit', (e) => {
53
101
  initEventFired = true;
54
102
  });
55
103
  const el = fixtureSync(container());
56
104
  const spy = sinon.spy(el, 'emitPostInit');
105
+
57
106
  await elementUpdated(el);
58
107
 
59
108
  expect(initEventFired).to.be.true;
60
109
  expect(spy.callCount).to.equal(1);
61
110
  });
62
- });
63
111
 
64
- it('handles global event: BookReader:PostInit', async () => {
65
- const setTimeoutSpy = sinon.spy(window, 'setTimeout');
66
- const brStub = {
67
- resize: sinon.fake(),
68
- currentIndex: sinon.fake(),
69
- jumpToIndex: sinon.fake(),
70
- options: { enableMultipleBooks: false }, // for multipleBooks
71
- el: '#BookReader'
72
- };
73
-
74
- const el = fixtureSync(container());
75
- const initializeBookSubmenus = sinon.spy(el, 'initializeBookSubmenus');
76
-
77
- await elementUpdated(el);
78
- window.dispatchEvent(new CustomEvent('BookReader:PostInit', {
79
- detail: { props: brStub }
80
- }));
81
- await elementUpdated(el);
82
-
83
- expect(initializeBookSubmenus.callCount).to.equal(1);
84
- expect(el.bookreader).to.equal(brStub); // sets bookreader
85
- expect(el.bookReaderLoaded).to.be.true; // notes bookreader is loaded
86
- expect(el.bookReaderCannotLoad).to.be.false;
87
- expect(el.fullscreenMgr).to.an.instanceof(BRFullscreenMgr);
88
- expect(el.brResizeObserver).to.an.instanceof(window.ResizeObserver);
89
- expect(setTimeoutSpy.callCount).to.equal(1); // resizes at end
112
+ it('creates an item image from metadata', async () => {
113
+ const el = fixtureSync(container());
114
+ el.item = {
115
+ metadata: { identifier: 'foo' },
116
+ };
117
+ await elementUpdated(el);
118
+
119
+ const itemImage = fixtureSync(el.itemImage);
120
+ expect(itemImage).to.be.instanceOf(HTMLImageElement);
121
+ expect(itemImage.getAttribute('class')).to.equal('cover-img');
122
+ expect(itemImage.getAttribute('src')).to.equal('https://https://foo.archive.org/services/img/foo');
123
+ });
90
124
  });
125
+ describe('Menu/Layer Provider', () => {
126
+ describe('Connecting with a provider:', () => {
127
+ // loads Providers with base shared resources
128
+ it('We load 3 Sub Menus by default', async() => {
129
+ const el = fixtureSync(container());
130
+ const $brContainer = document.createElement('div');
131
+ const brStub = {
132
+ resize: sinon.fake(),
133
+ currentIndex: sinon.fake(),
134
+ jumpToIndex: sinon.fake(),
135
+ options: {},
136
+ refs: {
137
+ $brContainer
138
+ }
139
+ };
140
+ el.bookreader = brStub;
141
+ await el.elementUpdated;
142
+
143
+ el.initializeBookSubmenus();
144
+ await el.elementUpdated;
145
+ const defaultMenus = Object.keys(el.menuProviders);
146
+ expect(defaultMenus).to.contain('downloads');
147
+ expect(el.menuProviders.downloads).to.be.instanceOf(DownloadsProvider);
91
148
 
92
- it('resizes bookreader when side menu toggles', async () => {
93
- const el = fixtureSync(container());
94
- const brStub = {
95
- resize: sinon.fake(),
96
- currentIndex: sinon.fake(),
97
- jumpToIndex: sinon.fake(),
98
- options: { enableMultipleBooks: true },
99
- };
149
+ expect(defaultMenus).to.contain('share');
150
+ expect(el.menuProviders.share).to.be.instanceOf(SharingProvider);
100
151
 
101
- el.bookreader = brStub;
102
- await elementUpdated(el);
152
+ expect(defaultMenus).to.contain('visualAdjustments');
153
+ expect(el.menuProviders.visualAdjustments).to.be.instanceOf(VisualAdjustmentsProvider);
154
+ });
155
+ describe('Loading Sub Menus By Plugin Flags', async() => {
156
+ it('Search: uses `enableSearch` flag', async() => {
157
+ const el = fixtureSync(container());
158
+ const $brContainer = document.createElement('div');
159
+ const brStub = {
160
+ resize: sinon.fake(),
161
+ currentIndex: sinon.fake(),
162
+ jumpToIndex: sinon.fake(),
163
+ options: { enableSearch: true },
164
+ refs: {
165
+ $brContainer
166
+ }
167
+ };
168
+ el.bookreader = brStub;
169
+ await el.elementUpdated;
103
170
 
104
- el.sideMenuOpen = true;
105
- await elementUpdated(el);
171
+ el.initializeBookSubmenus();
172
+ await el.elementUpdated;
106
173
 
107
- expect(el.bookreader.resize.callCount).to.equal(1);
174
+ expect(el.menuProviders.search).to.exist;
175
+ expect(el.menuProviders.search).to.be.instanceOf(SearchProvider);
108
176
 
109
- el.sideMenuOpen = false;
110
- await elementUpdated(el);
177
+ // also adds a menu shortcut
178
+ expect(el.menuShortcuts.find(m => m.id === 'search')).to.exist;
179
+ });
180
+ it('Volumes/Multiple Books: uses `enableMultipleBooks` flag', async() => {
181
+ const el = fixtureSync(container());
182
+ const $brContainer = document.createElement('div');
183
+ const brStub = {
184
+ resize: sinon.fake(),
185
+ currentIndex: sinon.fake(),
186
+ jumpToIndex: sinon.fake(),
187
+ options: {
188
+ enableMultipleBooks: true,
189
+ multipleBooksList: {
190
+ by_subprefix: {
191
+ fooSubprefix: 'beep'
192
+ }
193
+ }
194
+ },
195
+ refs: {
196
+ $brContainer
197
+ }
198
+ };
199
+ el.bookreader = brStub;
200
+ await el.elementUpdated;
111
201
 
112
- expect(el.bookreader.resize.callCount).to.equal(2);
113
- });
202
+ el.initializeBookSubmenus();
203
+ await el.elementUpdated;
114
204
 
115
- it('does not resize bookreader if animating', async () => {
116
- const el = fixtureSync(container());
117
- const brStub = {
118
- animating: true, // <-- testing for this
119
- resize: sinon.fake(),
120
- currentIndex: sinon.fake(),
121
- jumpToIndex: sinon.fake(),
122
- options: { enableMultipleBooks: true }
123
- };
124
-
125
- el.bookreader = brStub;
126
- await elementUpdated(el);
127
-
128
- el.sideMenuOpen = true;
129
- await elementUpdated(el);
130
-
131
- expect(el.bookreader.resize.callCount).to.equal(0);
132
- expect(el.bookreader.currentIndex.callCount).to.equal(0);
133
- expect(el.bookreader.jumpToIndex.callCount).to.equal(0);
205
+ expect(el.menuProviders.volumes).to.exist;
206
+ expect(el.menuProviders.volumes).to.be.instanceOf(VolumesProvider);
207
+
208
+ // also adds a menu shortcut
209
+ expect(el.menuShortcuts.find(m => m.id === 'volumes')).to.be.exist;
210
+ });
211
+ });
212
+ it('keeps track of base shared resources for providers in: `baseProviderConfig`', () => {
213
+ const el = fixtureSync(container());
214
+ const baseConfigKeys = Object.keys(el.baseProviderConfig);
215
+ expect(baseConfigKeys).to.contain('baseHost');
216
+ expect(baseConfigKeys).to.contain('modal');
217
+ expect(baseConfigKeys).to.contain('sharedObserver');
218
+ expect(baseConfigKeys).to.contain('bookreader');
219
+ expect(baseConfigKeys).to.contain('item');
220
+ expect(baseConfigKeys).to.contain('signedIn');
221
+ expect(baseConfigKeys).to.contain('isAdmin');
222
+ expect(baseConfigKeys).to.contain('onProviderChange');
223
+ });
224
+ });
225
+
226
+ describe('Controlling Menu Side Panel & Shortcuts', () => {
227
+ describe('Side Menu Panels', () => {
228
+ describe('Control which side menu to toggle open by using: `this.updateSideMenu`', () => {
229
+ it('Emits `@updateSideMenu` to signal which menu gets the update', async () => {
230
+ const el = fixtureSync(container());
231
+ const brStub = {
232
+ resize: sinon.fake(),
233
+ currentIndex: sinon.fake(),
234
+ jumpToIndex: sinon.fake(),
235
+ options: { enableMultipleBooks: true }
236
+ };
237
+ el.bookreader = brStub;
238
+ await elementUpdated(el);
239
+
240
+ let initEventFired = false;
241
+ let eventDetails = {};
242
+ el.addEventListener('updateSideMenu', (e) => {
243
+ eventDetails = e.detail;
244
+ initEventFired = true;
245
+ });
246
+
247
+ el.updateSideMenu('foo', 'open');
248
+ expect(initEventFired).to.equal(true);
249
+ expect(eventDetails.menuId).to.equal('foo');
250
+ expect(eventDetails.action).to.equal('open');
251
+ });
252
+ it('Will Not Emit `@updateSideMenu` if menu ID is missing', async() => {
253
+ const el = fixtureSync(container());
254
+ const brStub = {
255
+ resize: sinon.fake(),
256
+ currentIndex: sinon.fake(),
257
+ jumpToIndex: sinon.fake(),
258
+ options: { enableMultipleBooks: true }
259
+ };
260
+ el.bookreader = brStub;
261
+ await elementUpdated(el);
262
+
263
+ let initEventFired = false;
264
+ el.addEventListener('updateSideMenu', (e) => {
265
+ initEventFired = true;
266
+ });
267
+
268
+ el.updateSideMenu('', 'open');
269
+ expect(initEventFired).to.equal(false);
270
+ });
271
+ });
272
+ });
273
+
274
+ describe('Shortcuts', () => {
275
+ it('has specific order of menu shortcuts to show', () => {
276
+ const el = fixtureSync(container());
277
+ expect(el.shortcutOrder[0]).to.equal('fullscreen');
278
+ expect(el.shortcutOrder[1]).to.equal('volumes');
279
+ expect(el.shortcutOrder[2]).to.equal('search');
280
+ expect(el.shortcutOrder[3]).to.equal('bookmarks');
281
+ });
282
+ });
283
+
284
+ describe('Behaviors for specific menus', () => {
285
+ describe('Search menu - ref: plugin.search.js', () => {
286
+ it('Event: listens for `BookReader:ToggleSearchMenu to open search side panel', async () => {
287
+ const el = fixtureSync(container());
288
+ const brStub = {
289
+ resize: sinon.fake(),
290
+ currentIndex: sinon.fake(),
291
+ jumpToIndex: sinon.fake(),
292
+ options: { enableMultipleBooks: true }
293
+ };
294
+ el.bookreader = brStub;
295
+ await elementUpdated(el);
296
+
297
+ let sidePanelConfig = {};
298
+ el.addEventListener('updateSideMenu', (e) => {
299
+ console.log();
300
+ sidePanelConfig = e.detail;
301
+ });
302
+ const toggleSearchMenuEvent = new Event('BookReader:ToggleSearchMenu');
303
+ window.dispatchEvent(toggleSearchMenuEvent);
304
+
305
+ await elementUpdated(el);
306
+ expect(sidePanelConfig.menuId).to.equal('search');
307
+ expect(sidePanelConfig.action).to.equal('toggle');
308
+ });
309
+ });
310
+ });
311
+ });
134
312
  });
135
313
 
136
- describe(`this.updateSideMenu`, () => {
137
- it('emits custom event', async () => {
314
+ describe('Resizing',() => {
315
+ it('keeps track of `brWidth` and `brHeight`', async () => {
138
316
  const el = fixtureSync(container());
139
317
  const brStub = {
140
318
  resize: sinon.fake(),
319
+ };
320
+ el.bookreader = brStub;
321
+ await elementUpdated(el);
322
+ expect(el.brWidth).to.equal(0);
323
+ expect(el.brHeight).to.equal(0);
324
+
325
+ const mockResizeEvent = {
326
+ contentRect: {
327
+ height: 500,
328
+ width: 900
329
+ },
330
+ target: el.mainBRContainer
331
+ };
332
+ el.handleResize(mockResizeEvent);
333
+
334
+ await elementUpdated(el);
335
+ await promise0();
336
+
337
+ expect(el.brHeight).to.equal(500);
338
+ expect(el.brWidth).to.equal(900);
339
+ });
340
+ it('resizes if height/width changes && is not animating', async () => {
341
+ const el = fixtureSync(container());
342
+ const brStub = {
343
+ animating: false,
344
+ resize: sinon.fake(),
345
+ };
346
+ el.bookreader = brStub;
347
+ await elementUpdated(el);
348
+ expect(el.brWidth).to.equal(0);
349
+ expect(el.brHeight).to.equal(0);
350
+
351
+ const mockResizeEvent = {
352
+ contentRect: {
353
+ height: 500,
354
+ width: 900
355
+ },
356
+ target: el.mainBRContainer
357
+ };
358
+ el.handleResize(mockResizeEvent);
359
+
360
+ await elementUpdated(el);
361
+ await promise0();
362
+
363
+ expect(brStub.resize.callCount).to.equal(1);
364
+ });
365
+ it('does not resize bookreader if animating', async () => {
366
+ const el = fixtureSync(container());
367
+ const brStub = {
368
+ animating: true, // <-- testing for this
369
+ resize: sinon.fake(),
141
370
  currentIndex: sinon.fake(),
142
371
  jumpToIndex: sinon.fake(),
143
372
  options: { enableMultipleBooks: true }
144
373
  };
374
+
145
375
  el.bookreader = brStub;
146
376
  await elementUpdated(el);
147
377
 
148
- let initEventFired = false;
149
- let eventDetails = {};
150
- el.addEventListener('updateSideMenu', (e) => {
151
- eventDetails = e.detail;
152
- initEventFired = true;
153
- });
378
+ expect(el.bookreader.resize.callCount).to.equal(0);
379
+ expect(el.bookreader.currentIndex.callCount).to.equal(0);
380
+ expect(el.bookreader.jumpToIndex.callCount).to.equal(0);
381
+ });
382
+ });
383
+
384
+ describe('Fullscreen Management', () => {
385
+ it('needs option: `enableFSLogoShortcut` to use FS logo', async () => {
386
+ const el = fixtureSync(container());
387
+ const brStub = {
388
+ isFullscreen: () => true,
389
+ options: {
390
+ enableFSLogoShortcut: false,
391
+ }
392
+ };
393
+
394
+ el.bookreader = brStub;
395
+ el.emitMenuShortcutsUpdated = sinon.fake();
396
+ await elementUpdated(el);
397
+
398
+ el.manageFullScreenBehavior();
399
+ await elementUpdated(el);
400
+ expect(el.menuShortcuts.length).to.equal(0);
401
+ });
402
+ it('sets fullscreen shortcut when entering Fullscreen', async () => {
403
+ const el = fixtureSync(container());
404
+ const brStub = {
405
+ isFullscreen: () => true,
406
+ options: {
407
+ enableFSLogoShortcut: true,
408
+ }
409
+ };
410
+
411
+ el.bookreader = brStub;
412
+ el.emitMenuShortcutsUpdated = sinon.fake();
413
+ await elementUpdated(el);
414
+
415
+ el.manageFullScreenBehavior();
416
+ await elementUpdated(el);
417
+ expect(el.menuShortcuts.length).to.equal(1);
418
+ expect(el.menuShortcuts[0].id).to.equal('fullscreen');
419
+ expect(el.menuShortcuts[0].icon).to.exist;
420
+ expect(el.emitMenuShortcutsUpdated.callCount).to.equal(1);
421
+ });
422
+ it('clicking Fullscreen shortcut closes fullscreen', async () => {
423
+ const el = fixtureSync(container());
424
+ const brStub = {
425
+ isFullscreen: () => true,
426
+ options: {
427
+ enableFSLogoShortcut: true,
428
+ }
429
+ };
430
+
431
+ el.bookreader = brStub;
432
+ el.emitMenuShortcutsUpdated = sinon.fake();
433
+ el.closeFullscreen = sinon.fake();
434
+ await elementUpdated(el);
435
+
436
+ el.manageFullScreenBehavior();
437
+ await elementUpdated(el);
438
+
439
+ fixtureSync(el.menuShortcuts[0].icon).click();
440
+ await elementUpdated(el);
154
441
 
155
- el.updateSideMenu('foo', 'open');
156
- expect(initEventFired).to.equal(true);
157
- expect(eventDetails.menuId).to.equal('foo');
158
- expect(eventDetails.action).to.equal('open');
442
+ expect(el.closeFullscreen.callCount).to.equal(1);
159
443
  });
160
- it('does not emit event if missing an arg', async() => {
444
+ it('removes Fullscreen shortcut when leaving fullscreen', async() => {
161
445
  const el = fixtureSync(container());
162
446
  const brStub = {
447
+ isFullscreen: () => false,
448
+ options: {
449
+ enableFSLogoShortcut: true,
450
+ }
451
+ };
452
+
453
+ el.bookreader = brStub;
454
+ el.emitMenuShortcutsUpdated = sinon.fake();
455
+ await elementUpdated(el);
456
+
457
+ el.manageFullScreenBehavior();
458
+ await elementUpdated(el);
459
+ expect(el.menuShortcuts.length).to.equal(0);
460
+ expect(el.emitMenuShortcutsUpdated.callCount).to.equal(1);
461
+ });
462
+ it('Event: Listens for `BookReader:FullscreenToggled', async() => {
463
+ const el = fixtureSync(container());
464
+ const brStub = {
465
+ isFullscreen: () => true,
163
466
  resize: sinon.fake(),
164
467
  currentIndex: sinon.fake(),
165
468
  jumpToIndex: sinon.fake(),
166
- options: { enableMultipleBooks: true }
469
+ options: {
470
+ enableFSLogoShortcut: true,
471
+ }
167
472
  };
168
473
  el.bookreader = brStub;
474
+ el.manageFullScreenBehavior = sinon.fake();
169
475
  await elementUpdated(el);
170
476
 
171
- let initEventFired = false;
172
- el.addEventListener('updateSideMenu', (e) => {
173
- initEventFired = true;
174
- });
477
+ window.dispatchEvent(new CustomEvent('BookReader:fullscreenToggled', {
478
+ detail: { props: brStub }
479
+ }));
480
+ await elementUpdated(el);
175
481
 
176
- el.updateSideMenu('', 'open');
177
- expect(initEventFired).to.equal(false);
482
+ expect(el.manageFullScreenBehavior.callCount).to.equal(1);
178
483
  });
179
484
  });
180
485
  });
@@ -0,0 +1,44 @@
1
+ import {
2
+ html,
3
+ fixtureSync,
4
+ expect,
5
+ fixtureCleanup,
6
+ } from '@open-wc/testing';
7
+ import '../../../../src/BookNavigator/bookmarks/bookmark-button.js';
8
+ import sinon from 'sinon';
9
+
10
+ afterEach(() => {
11
+ sinon.restore();
12
+ fixtureCleanup();
13
+ });
14
+
15
+ describe('<bookmark-button>', () => {
16
+ it('sets default properties', async () => {
17
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
18
+
19
+ expect(el.side).to.be.undefined;
20
+ expect(el.state).to.equal('hollow');
21
+ });
22
+ it('Event: fires `@bookmarkButtonClicked on click', async () => {
23
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
24
+ let buttonClicked = false;
25
+ el.addEventListener('bookmarkButtonClicked', () => { buttonClicked = true; });
26
+ const eventStub = { preventDefault: sinon.fake()};
27
+ el.handleClick(eventStub);
28
+ await el.updateComplete;
29
+
30
+ expect(buttonClicked).to.be.true;
31
+ expect(eventStub.preventDefault.callCount).to.equal(1);
32
+ });
33
+ it('Title: Toggles title between `Add/Remove bookmark`', async () => {
34
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
35
+ expect(el.title).to.equal('Add bookmark');
36
+ expect(el.state).to.equal('hollow');
37
+
38
+ el.state = 'filled';
39
+ await el.updateComplete;
40
+
41
+ expect(el.title).to.equal('Remove bookmark');
42
+ expect(el.state).to.not.equal('hollow');
43
+ });
44
+ });
@@ -1,4 +1,4 @@
1
- import { expect } from '@open-wc/testing';
1
+ import { expect, fixtureCleanup, fixtureSync } from '@open-wc/testing';
2
2
  import sinon from 'sinon';
3
3
  import DownloadsProvider from '../../../../src/BookNavigator/downloads/downloads-provider';
4
4
 
@@ -25,6 +25,7 @@ const downloads = [
25
25
 
26
26
  afterEach(() => {
27
27
  sinon.restore();
28
+ fixtureCleanup();
28
29
  });
29
30
 
30
31
  describe('Downloads Provider', () => {
@@ -34,6 +35,7 @@ describe('Downloads Provider', () => {
34
35
 
35
36
  expect(provider.id).to.equal('downloads');
36
37
  expect(provider.icon).to.exist;
38
+ expect(fixtureSync(provider.icon).tagName).to.equal('IA-ICON-DL');
37
39
  expect(provider.label).to.equal('Downloadable files');
38
40
  expect(provider.menuDetails).to.exist;
39
41
  expect(provider.component).to.exist;
@@ -49,8 +51,9 @@ describe('Downloads Provider', () => {
49
51
  });
50
52
 
51
53
  it('render view if book is protected', () => {
52
- const isBookProtected = true;
53
- const provider = new DownloadsProvider(isBookProtected);
54
+ const provider = new DownloadsProvider({
55
+ bookreader: { options: { isProtected: true } }
56
+ });
54
57
 
55
58
  expect(provider.isBookProtected).to.equal(true);
56
59