@internetarchive/bookreader 5.0.0-8-multiple-files → 5.0.0-80

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 (321) hide show
  1. package/.eslintrc.js +17 -15
  2. package/.github/workflows/node.js.yml +78 -6
  3. package/.github/workflows/npm-publish.yml +6 -20
  4. package/.testcaferc.js +10 -0
  5. package/BookReader/BookReader.css +442 -1393
  6. package/BookReader/BookReader.js +2 -21564
  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 -12
  13. package/BookReader/icons/2up.svg +1 -15
  14. package/BookReader/icons/advance.svg +3 -26
  15. package/BookReader/icons/chevron-right.svg +1 -1
  16. package/BookReader/icons/close-circle-dark.svg +1 -0
  17. package/BookReader/icons/close-circle.svg +1 -1
  18. package/BookReader/icons/fullscreen.svg +1 -17
  19. package/BookReader/icons/fullscreen_exit.svg +1 -17
  20. package/BookReader/icons/hamburger.svg +1 -15
  21. package/BookReader/icons/left-arrow.svg +1 -12
  22. package/BookReader/icons/magnify-minus.svg +1 -16
  23. package/BookReader/icons/magnify-plus.svg +1 -17
  24. package/BookReader/icons/magnify.svg +1 -15
  25. package/BookReader/icons/pause.svg +1 -23
  26. package/BookReader/icons/play.svg +1 -22
  27. package/BookReader/icons/playback-speed.svg +1 -34
  28. package/BookReader/icons/read-aloud.svg +1 -22
  29. package/BookReader/icons/review.svg +3 -22
  30. package/BookReader/icons/thumbnails.svg +1 -17
  31. package/BookReader/icons/voice.svg +1 -0
  32. package/BookReader/icons/volume-full.svg +1 -22
  33. package/BookReader/images/BRicons.svg +5 -94
  34. package/BookReader/images/books_graphic.svg +1 -177
  35. package/BookReader/images/icon_book.svg +1 -12
  36. package/BookReader/images/icon_bookmark.svg +1 -12
  37. package/BookReader/images/icon_gear.svg +1 -14
  38. package/BookReader/images/icon_hamburger.svg +1 -20
  39. package/BookReader/images/icon_home.svg +1 -21
  40. package/BookReader/images/icon_info.svg +1 -11
  41. package/BookReader/images/icon_one_page.svg +1 -8
  42. package/BookReader/images/icon_pause.svg +1 -1
  43. package/BookReader/images/icon_play.svg +1 -1
  44. package/BookReader/images/icon_playback-rate.svg +1 -15
  45. package/BookReader/images/icon_search_button.svg +1 -8
  46. package/BookReader/images/icon_share.svg +1 -9
  47. package/BookReader/images/icon_skip-ahead.svg +1 -6
  48. package/BookReader/images/icon_skip-back.svg +2 -13
  49. package/BookReader/images/icon_speaker.svg +1 -18
  50. package/BookReader/images/icon_speaker_open.svg +1 -10
  51. package/BookReader/images/icon_thumbnails.svg +1 -12
  52. package/BookReader/images/icon_toc.svg +1 -5
  53. package/BookReader/images/icon_two_pages.svg +1 -9
  54. package/BookReader/images/marker_chap-off.svg +1 -11
  55. package/BookReader/images/marker_chap-on.svg +1 -11
  56. package/BookReader/images/marker_srch-on.svg +1 -11
  57. package/BookReader/jquery-3.js +2 -0
  58. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  59. package/BookReader/plugins/plugin.archive_analytics.js +1 -172
  60. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  61. package/BookReader/plugins/plugin.autoplay.js +1 -165
  62. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  63. package/BookReader/plugins/plugin.chapters.js +22 -301
  64. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  65. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  66. package/BookReader/plugins/plugin.iframe.js +1 -74
  67. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  68. package/BookReader/plugins/plugin.iiif.js +2 -0
  69. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  70. package/BookReader/plugins/plugin.resume.js +1 -368
  71. package/BookReader/plugins/plugin.resume.js.map +1 -1
  72. package/BookReader/plugins/plugin.search.js +2 -1420
  73. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  74. package/BookReader/plugins/plugin.search.js.map +1 -1
  75. package/BookReader/plugins/plugin.text_selection.js +2 -1080
  76. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  77. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  78. package/BookReader/plugins/plugin.tts.js +2 -9193
  79. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  80. package/BookReader/plugins/plugin.tts.js.map +1 -1
  81. package/BookReader/plugins/plugin.url.js +1 -269
  82. package/BookReader/plugins/plugin.url.js.map +1 -1
  83. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
  84. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  85. package/BookReader/webcomponents-bundle.js +3 -0
  86. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  87. package/BookReader/webcomponents-bundle.js.map +1 -0
  88. package/BookReaderDemo/BookReaderDemo.css +18 -19
  89. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -3
  90. package/BookReaderDemo/BookReaderJSAutoplay.js +4 -1
  91. package/BookReaderDemo/BookReaderJSSimple.js +1 -0
  92. package/BookReaderDemo/IADemoBr.js +147 -0
  93. package/BookReaderDemo/demo-advanced.html +2 -2
  94. package/BookReaderDemo/demo-autoplay.html +2 -3
  95. package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
  96. package/BookReaderDemo/demo-fullscreen-mobile.html +3 -5
  97. package/BookReaderDemo/demo-fullscreen.html +2 -4
  98. package/BookReaderDemo/demo-iiif.html +99 -12
  99. package/BookReaderDemo/demo-internetarchive.html +214 -18
  100. package/BookReaderDemo/demo-multiple.html +2 -1
  101. package/BookReaderDemo/demo-preview-pages.html +2 -1
  102. package/BookReaderDemo/demo-simple.html +2 -1
  103. package/BookReaderDemo/demo-vendor-fullscreen.html +2 -4
  104. package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
  105. package/BookReaderDemo/immersion-1up.html +2 -2
  106. package/BookReaderDemo/immersion-mode.html +2 -4
  107. package/BookReaderDemo/toggle_controls.html +3 -2
  108. package/BookReaderDemo/view_mode.html +2 -1
  109. package/BookReaderDemo/viewmode-cycle.html +2 -3
  110. package/CHANGELOG.md +545 -33
  111. package/README.md +14 -1
  112. package/babel.config.js +20 -0
  113. package/codecov.yml +6 -0
  114. package/index.html +4 -1
  115. package/jsconfig.json +19 -0
  116. package/netlify.toml +9 -0
  117. package/package.json +70 -60
  118. package/renovate.json +52 -0
  119. package/scripts/preversion.js +0 -1
  120. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  121. package/src/BookNavigator/assets/button-base.js +9 -2
  122. package/src/BookNavigator/assets/ia-logo.js +17 -0
  123. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  124. package/src/BookNavigator/assets/icon_close.js +1 -1
  125. package/src/BookNavigator/book-navigator.js +590 -0
  126. package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
  127. package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
  128. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  129. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +3 -8
  130. package/src/BookNavigator/bookmarks/bookmarks-provider.js +27 -17
  131. package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
  132. package/src/BookNavigator/delete-modal-actions.js +1 -1
  133. package/src/BookNavigator/downloads/downloads-provider.js +36 -21
  134. package/src/BookNavigator/downloads/downloads.js +41 -25
  135. package/src/BookNavigator/search/search-provider.js +80 -28
  136. package/src/BookNavigator/search/search-results.js +28 -25
  137. package/src/BookNavigator/sharing.js +27 -0
  138. package/src/BookNavigator/viewable-files.js +95 -0
  139. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +11 -10
  140. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
  141. package/src/BookReader/BookModel.js +64 -34
  142. package/src/BookReader/DragScrollable.js +233 -0
  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 +776 -0
  147. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  148. package/src/BookReader/ModeSmoothZoom.js +312 -0
  149. package/src/BookReader/ModeThumb.js +18 -12
  150. package/src/BookReader/Navbar/Navbar.js +14 -40
  151. package/src/BookReader/PageContainer.js +81 -6
  152. package/src/BookReader/ReduceSet.js +1 -1
  153. package/src/BookReader/Toolbar/Toolbar.js +10 -37
  154. package/src/BookReader/events.js +2 -3
  155. package/src/BookReader/options.js +27 -2
  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.js +118 -13
  160. package/src/BookReader.js +446 -1062
  161. package/src/assets/icons/close-circle-dark.svg +1 -0
  162. package/src/assets/icons/magnify-minus.svg +3 -7
  163. package/src/assets/icons/magnify-plus.svg +3 -7
  164. package/src/assets/icons/voice.svg +1 -0
  165. package/src/css/BookReader.scss +1 -17
  166. package/src/css/_BRBookmarks.scss +1 -1
  167. package/src/css/_BRComponent.scss +1 -1
  168. package/src/css/_BRmain.scss +33 -27
  169. package/src/css/_BRnav.scss +12 -39
  170. package/src/css/_BRpages.scss +149 -40
  171. package/src/css/_BRsearch.scss +68 -230
  172. package/src/css/_BRtoolbar.scss +5 -5
  173. package/src/css/_TextSelection.scss +87 -27
  174. package/src/css/_colorbox.scss +2 -2
  175. package/src/css/_controls.scss +20 -7
  176. package/src/css/_icons.scss +7 -1
  177. package/src/ia-bookreader/ia-bookreader.js +224 -0
  178. package/src/plugins/plugin.archive_analytics.js +3 -3
  179. package/src/plugins/plugin.autoplay.js +5 -11
  180. package/src/plugins/plugin.chapters.js +237 -191
  181. package/src/plugins/plugin.iiif.js +151 -0
  182. package/src/plugins/plugin.resume.js +3 -3
  183. package/src/plugins/plugin.text_selection.js +464 -134
  184. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  185. package/src/plugins/search/plugin.search.js +175 -120
  186. package/src/plugins/search/utils.js +43 -0
  187. package/src/plugins/search/view.js +64 -202
  188. package/src/plugins/tts/AbstractTTSEngine.js +71 -40
  189. package/src/plugins/tts/FestivalTTSEngine.js +13 -14
  190. package/src/plugins/tts/PageChunk.js +15 -21
  191. package/src/plugins/tts/PageChunkIterator.js +8 -12
  192. package/src/plugins/tts/WebTTSEngine.js +87 -71
  193. package/src/plugins/tts/plugin.tts.js +96 -127
  194. package/src/plugins/tts/utils.js +15 -25
  195. package/src/plugins/url/UrlPlugin.js +191 -0
  196. package/src/plugins/{plugin.url.js → url/plugin.url.js} +45 -16
  197. package/src/util/browserSniffing.js +22 -0
  198. package/src/util/docCookies.js +21 -2
  199. package/tests/e2e/README.md +37 -0
  200. package/tests/e2e/autoplay.test.js +2 -2
  201. package/tests/e2e/base.test.js +8 -16
  202. package/tests/e2e/helpers/base.js +53 -48
  203. package/tests/e2e/helpers/debug.js +1 -1
  204. package/tests/e2e/helpers/params.js +17 -0
  205. package/tests/e2e/helpers/rightToLeft.js +8 -14
  206. package/tests/e2e/helpers/search.js +73 -0
  207. package/tests/e2e/models/Navigation.js +20 -37
  208. package/tests/e2e/rightToLeft.test.js +4 -5
  209. package/tests/e2e/viewmode.test.js +40 -33
  210. package/tests/jest/BookNavigator/book-navigator.test.js +661 -0
  211. package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
  212. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
  213. package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
  214. package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
  215. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
  216. package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
  217. package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
  218. package/tests/{karma/BookNavigator → jest/BookNavigator/search}/search-results.test.js +109 -60
  219. package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
  220. package/tests/jest/BookNavigator/viewable-files/viewable-files-provider.test.js +80 -0
  221. package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
  222. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +74 -14
  223. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -0
  224. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  225. package/tests/jest/BookReader/Mode1UpLit.test.js +73 -0
  226. package/tests/jest/BookReader/Mode2Up.test.js +98 -0
  227. package/tests/jest/BookReader/Mode2UpLit.test.js +190 -0
  228. package/tests/jest/BookReader/ModeCoordinateSpace.test.js +16 -0
  229. package/tests/jest/BookReader/ModeSmoothZoom.test.js +218 -0
  230. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  231. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +10 -10
  232. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +88 -6
  233. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  234. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  235. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  236. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
  237. package/tests/jest/BookReader/utils/SelectionObserver.test.js +57 -0
  238. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  239. package/tests/jest/BookReader/utils.test.js +229 -0
  240. package/tests/jest/BookReader.keyboard.test.js +190 -0
  241. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  242. package/tests/{BookReader.test.js → jest/BookReader.test.js} +26 -37
  243. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  244. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +4 -4
  245. package/tests/jest/plugins/plugin.chapters.test.js +195 -0
  246. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  247. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  248. package/tests/jest/plugins/plugin.text_selection.test.js +317 -0
  249. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  250. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +26 -47
  251. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +39 -6
  252. package/tests/jest/plugins/search/utils.js +25 -0
  253. package/tests/jest/plugins/search/utils.test.js +29 -0
  254. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +29 -9
  255. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  256. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  257. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  258. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +47 -1
  259. package/tests/{plugins → jest/plugins}/tts/utils.test.js +1 -60
  260. package/tests/jest/plugins/url/UrlPlugin.test.js +198 -0
  261. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +53 -14
  262. package/tests/jest/setup.js +3 -0
  263. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  264. package/tests/jest/util/docCookies.test.js +24 -0
  265. package/tests/{util → jest/util}/strings.test.js +1 -1
  266. package/tests/{utils.js → jest/utils.js} +38 -0
  267. package/webpack.config.js +12 -6
  268. package/.babelrc +0 -12
  269. package/.dependabot/config.yml +0 -6
  270. package/.testcaferc.json +0 -5
  271. package/BookReader/bookreader-component-bundle.js +0 -14312
  272. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  273. package/BookReader/bookreader-component-bundle.js.map +0 -1
  274. package/BookReader/icons/sort-ascending.svg +0 -1
  275. package/BookReader/icons/sort-descending.svg +0 -1
  276. package/BookReader/jquery-1.10.1.js +0 -108
  277. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  278. package/BookReader/plugins/plugin.menu_toggle.js +0 -369
  279. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  280. package/BookReader/plugins/plugin.mobile_nav.js +0 -335
  281. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  282. package/BookReaderDemo/IIIFBookReader.js +0 -207
  283. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  284. package/BookReaderDemo/demo-iiif.js +0 -26
  285. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  286. package/karma.conf.js +0 -23
  287. package/src/BookNavigator/BookModel.js +0 -14
  288. package/src/BookNavigator/BookNavigator.js +0 -452
  289. package/src/BookNavigator/assets/book-loader.js +0 -27
  290. package/src/BookNavigator/assets/icon_sort_ascending.js +0 -5
  291. package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
  292. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  293. package/src/BookNavigator/search/a-search-result.js +0 -55
  294. package/src/BookNavigator/volumes/volumes-provider.js +0 -76
  295. package/src/BookNavigator/volumes/volumes.js +0 -161
  296. package/src/BookReader/DebugConsole.js +0 -54
  297. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  298. package/src/ItemNavigator/ItemNavigator.js +0 -372
  299. package/src/ItemNavigator/providers/sharing.js +0 -29
  300. package/src/assets/icons/sort-ascending.svg +0 -1
  301. package/src/assets/icons/sort-descending.svg +0 -1
  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/utils.test.js +0 -109
  311. package/tests/e2e/helpers/desktopSearch.js +0 -72
  312. package/tests/e2e/helpers/mobileSearch.js +0 -85
  313. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  314. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  315. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  316. package/tests/karma/BookNavigator/volumes.test.js +0 -101
  317. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  318. package/tests/plugins/plugin.chapters.test.js +0 -130
  319. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  320. package/tests/plugins/plugin.text_selection.test.js +0 -203
  321. package/tests/util/docCookies.test.js +0 -15
@@ -0,0 +1,661 @@
1
+ import {
2
+ html,
3
+ elementUpdated,
4
+ fixtureCleanup,
5
+ fixtureSync,
6
+ } from '@open-wc/testing-helpers';
7
+ import sinon from 'sinon';
8
+ import DownloadsProvider from '@/src/BookNavigator/downloads/downloads-provider.js';
9
+ import SearchProvider from '@/src/BookNavigator/search/search-provider.js';
10
+ import SharingProvider from '@/src/BookNavigator/sharing.js';
11
+ import VisualAdjustmentsProvider from '@/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js';
12
+ import ViewableFilesProvider from '@/src/BookNavigator/viewable-files.js';
13
+ import { ModalManager } from '@internetarchive/modal-manager';
14
+ import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
15
+ import '@/src/BookNavigator/book-navigator.js';
16
+
17
+ const promise0 = () => new Promise(res => setTimeout(res, 0));
18
+
19
+ const container = (sharedObserver = null) => {
20
+ const itemStub = {
21
+ metadata: {
22
+ identifier: 'foo',
23
+ creator: 'bar',
24
+ title: 'baz',
25
+ }
26
+ };
27
+ const modalMgr = new ModalManager();
28
+ return html`
29
+ <book-navigator
30
+ .itemMD=${itemStub}
31
+ .baseHost=${`https://foo.archive.org`}
32
+ .sharedObserver=${sharedObserver || new SharedResizeObserver()}
33
+ .modal=${modalMgr}
34
+ >
35
+ <div slot="main">
36
+ <div id="BookReader"></div>
37
+ <p class="visible-in-reader">now showing</p>
38
+ <\div>
39
+ </book-navigator>
40
+ `;
41
+ };
42
+
43
+ window.ResizeObserver = class ResizeObserver {
44
+ observe = sinon.fake()
45
+ unobserve = sinon.fake()
46
+ disconnect = sinon.fake()
47
+ };
48
+
49
+ beforeEach(() => {
50
+ window.archive_analytics = {
51
+ send_event_no_sampling: sinon.fake(),
52
+ send_event: sinon.fake()
53
+ };
54
+ });
55
+
56
+ afterEach(() => {
57
+ window.br = null;
58
+ fixtureCleanup();
59
+ const body = document.querySelector('body');
60
+ body.innerHTML = '';
61
+ sinon.restore();
62
+ });
63
+
64
+
65
+ describe('<book-navigator>', () => {
66
+ describe("How it loads", () => {
67
+ describe('Attaches BookReader listeners before `br.init` is called', () => {
68
+ test('binds global event listeners', async () => {
69
+ const el = fixtureSync(container());
70
+ const spy = sinon.spy(el, 'bindEventListeners');
71
+ await elementUpdated(el);
72
+ expect(spy.callCount).toEqual(1);
73
+ });
74
+ test('Listens for Global Event @BookReader:PostInit', async () => {
75
+ const brStub = {
76
+ resize: sinon.fake(),
77
+ currentIndex: sinon.fake(),
78
+ jumpToIndex: sinon.fake(),
79
+ options: { enableMultipleBooks: false }, // for multipleBooks
80
+ el: '#BookReader',
81
+ refs: {}
82
+ };
83
+
84
+ const sharedObserver = new SharedResizeObserver();
85
+ sinon.spy(sharedObserver, 'addObserver');
86
+ const el = fixtureSync(container(sharedObserver));
87
+
88
+ el.initializeBookSubmenus = sinon.fake();
89
+ el.emitLoadingStatusUpdate = sinon.fake();
90
+ el.handleResize = sinon.fake();
91
+ await elementUpdated(el);
92
+
93
+ expect(brStub.resize.callCount).toEqual(0);
94
+
95
+ window.dispatchEvent(new CustomEvent('BookReader:PostInit', {
96
+ detail: { props: brStub }
97
+ }));
98
+ await elementUpdated(el);
99
+
100
+ expect(el.emitLoadingStatusUpdate.callCount).toEqual(1);
101
+ expect(el.bookreader).toEqual(brStub); // sets bookreader
102
+ expect(el.bookReaderLoaded).toBeTruthy(); // notes bookreader is loaded
103
+ expect(el.bookReaderCannotLoad).toBeFalsy();
104
+ expect(sharedObserver.addObserver.callCount).toEqual(1);
105
+
106
+ await promise0();
107
+
108
+ expect(brStub.resize.callCount > 0).toBeTruthy();
109
+ });
110
+ });
111
+ test('Emits a BrBookNav:PostInit event at completion', async () => {
112
+ let initEventFired = false;
113
+ window.addEventListener('BrBookNav:PostInit', (e) => {
114
+ initEventFired = true;
115
+ });
116
+ const el = fixtureSync(container());
117
+ const spy = sinon.spy(el, 'emitPostInit');
118
+
119
+ await elementUpdated(el);
120
+
121
+ expect(initEventFired).toBeTruthy();
122
+ expect(spy.callCount).toEqual(1);
123
+ });
124
+
125
+ test('creates an item image from metadata', async () => {
126
+ const el = fixtureSync(container());
127
+ const itemImage = fixtureSync(el.itemImage);
128
+ expect(itemImage).toBeInstanceOf(HTMLImageElement);
129
+ expect(itemImage.getAttribute('class')).toEqual('cover-img');
130
+ expect(itemImage.getAttribute('src')).toEqual('https://https://foo.archive.org/services/img/foo');
131
+ });
132
+ });
133
+ describe('Menu/Layer Provider', () => {
134
+ describe('Connecting with a provider:', () => {
135
+ // loads Providers with base shared resources
136
+ test('We load 3 Sub Menus by default', async() => {
137
+ const el = fixtureSync(container());
138
+ const $brContainer = document.createElement('div');
139
+ const brStub = {
140
+ resize: sinon.fake(),
141
+ currentIndex: sinon.fake(),
142
+ jumpToIndex: sinon.fake(),
143
+ options: {},
144
+ refs: {
145
+ $brContainer
146
+ }
147
+ };
148
+ el.bookreader = brStub;
149
+ await el.elementUpdated;
150
+
151
+ el.downloadableTypes = ['foo/bar'];
152
+ await el.elementUpdated;
153
+
154
+ el.initializeBookSubmenus();
155
+ await el.elementUpdated;
156
+ const defaultMenus = Object.keys(el.menuProviders);
157
+ expect(defaultMenus).toContain('downloads');
158
+ expect(el.menuProviders.downloads).toBeInstanceOf(DownloadsProvider);
159
+
160
+ expect(defaultMenus).toContain('share');
161
+ expect(el.menuProviders.share).toBeInstanceOf(SharingProvider);
162
+
163
+ expect(defaultMenus).toContain('visualAdjustments');
164
+ expect(el.menuProviders.visualAdjustments).toBeInstanceOf(VisualAdjustmentsProvider);
165
+ });
166
+ describe('Loading Sub Menus By Plugin Flags', () => {
167
+ test('Search: uses `enableSearch` flag', async() => {
168
+ const el = fixtureSync(container());
169
+ const $brContainer = document.createElement('div');
170
+ const brStub = {
171
+ resize: sinon.fake(),
172
+ currentIndex: sinon.fake(),
173
+ jumpToIndex: sinon.fake(),
174
+ options: { enableSearch: true },
175
+ refs: {
176
+ $brContainer
177
+ }
178
+ };
179
+ el.bookreader = brStub;
180
+ await el.elementUpdated;
181
+
182
+ el.initializeBookSubmenus();
183
+ await el.elementUpdated;
184
+
185
+ expect(el.menuProviders.search).toBeDefined();
186
+ expect(el.menuProviders.search).toBeInstanceOf(SearchProvider);
187
+
188
+ // also adds a menu shortcut
189
+ expect(el.menuShortcuts.find(m => m.id === 'search')).toBeDefined();
190
+ });
191
+ test('Volumes/Multiple Books: uses `enableMultipleBooks` flag', async() => {
192
+ const el = fixtureSync(container());
193
+ const $brContainer = document.createElement('div');
194
+ const brStub = {
195
+ resize: sinon.fake(),
196
+ currentIndex: sinon.fake(),
197
+ jumpToIndex: sinon.fake(),
198
+ options: {
199
+ enableMultipleBooks: true,
200
+ multipleBooksList: {
201
+ by_subprefix: {
202
+ fooSubprefix: 'beep'
203
+ }
204
+ }
205
+ },
206
+ refs: {
207
+ $brContainer
208
+ }
209
+ };
210
+ el.bookreader = brStub;
211
+ await el.elementUpdated;
212
+
213
+ el.initializeBookSubmenus();
214
+ await el.elementUpdated;
215
+
216
+ expect(el.menuProviders.volumes).toBeDefined();
217
+ expect(el.menuProviders.volumes).toBeInstanceOf(ViewableFilesProvider);
218
+
219
+ // also adds a menu shortcut
220
+ expect(el.menuShortcuts.find(m => m.id === 'volumes')).toBeDefined();
221
+ });
222
+ });
223
+ test('keeps track of base shared resources for providers in: `baseProviderConfig`', () => {
224
+ const el = fixtureSync(container());
225
+ const baseConfigKeys = Object.keys(el.baseProviderConfig);
226
+ expect(baseConfigKeys).toContain('baseHost');
227
+ expect(baseConfigKeys).toContain('modal');
228
+ expect(baseConfigKeys).toContain('sharedObserver');
229
+ expect(baseConfigKeys).toContain('bookreader');
230
+ expect(baseConfigKeys).toContain('item');
231
+ expect(baseConfigKeys).toContain('signedIn');
232
+ expect(baseConfigKeys).toContain('isAdmin');
233
+ expect(baseConfigKeys).toContain('onProviderChange');
234
+ });
235
+
236
+ test('Downloads panel - does not show if no available `downloadableTypes`', async () => {
237
+ const el = fixtureSync(container());
238
+ const $brContainer = document.createElement('div');
239
+ const brStub = {
240
+ resize: sinon.fake(),
241
+ currentIndex: sinon.fake(),
242
+ jumpToIndex: sinon.fake(),
243
+ options: {},
244
+ refs: {
245
+ $brContainer
246
+ }
247
+ };
248
+ el.bookreader = brStub;
249
+ await el.elementUpdated;
250
+
251
+ el.initializeBookSubmenus();
252
+ await el.elementUpdated;
253
+ const defaultMenus = Object.keys(el.menuProviders);
254
+ expect(defaultMenus.find(menu => menu === 'downloads')).toBeUndefined;
255
+ });
256
+ });
257
+
258
+ describe('Controlling Menu Side Panel & Shortcuts', () => {
259
+ describe('Side Menu Panels', () => {
260
+ test('`isWideEnoughToOpenMenu` checks if menu should be open', async () => {
261
+ const el = fixtureSync(container());
262
+ el.brWidth = 300;
263
+ await el.elementUpdated;
264
+
265
+ expect(el.isWideEnoughToOpenMenu).toEqual(false);
266
+
267
+ el.brWidth = 641;
268
+ await el.elementUpdated;
269
+
270
+ expect(el.isWideEnoughToOpenMenu).toEqual(true);
271
+ });
272
+ describe('Control which side menu to toggle open by using: `this.updateSideMenu`', () => {
273
+ test('Emits `@updateSideMenu` to signal which menu gets the update', async () => {
274
+ const el = fixtureSync(container());
275
+ const brStub = {
276
+ resize: sinon.fake(),
277
+ currentIndex: sinon.fake(),
278
+ jumpToIndex: sinon.fake(),
279
+ options: { enableMultipleBooks: true },
280
+ refs: {},
281
+ };
282
+ el.bookreader = brStub;
283
+ await elementUpdated(el);
284
+
285
+ let initEventFired = false;
286
+ let eventDetails = {};
287
+ el.addEventListener('updateSideMenu', (e) => {
288
+ eventDetails = e.detail;
289
+ initEventFired = true;
290
+ });
291
+
292
+ el.updateSideMenu('foo', 'open');
293
+ expect(initEventFired).toEqual(true);
294
+ expect(eventDetails.menuId).toEqual('foo');
295
+ expect(eventDetails.action).toEqual('open');
296
+ });
297
+ test('Will Not Emit `@updateSideMenu` if menu ID is missing', async() => {
298
+ const el = fixtureSync(container());
299
+ const brStub = {
300
+ resize: sinon.fake(),
301
+ currentIndex: sinon.fake(),
302
+ jumpToIndex: sinon.fake(),
303
+ options: { enableMultipleBooks: true },
304
+ refs: {},
305
+ };
306
+ el.bookreader = brStub;
307
+ await elementUpdated(el);
308
+
309
+ let initEventFired = false;
310
+ el.addEventListener('updateSideMenu', (e) => {
311
+ initEventFired = true;
312
+ });
313
+
314
+ el.updateSideMenu('', 'open');
315
+ expect(initEventFired).toEqual(false);
316
+ });
317
+ });
318
+ });
319
+
320
+ describe('Shortcuts', () => {
321
+ test('has specific order of menu shortcuts to show', () => {
322
+ const el = fixtureSync(container());
323
+ expect(el.shortcutOrder).toEqual([
324
+ 'fullscreen',
325
+ 'volumes',
326
+ 'chapters',
327
+ 'search',
328
+ 'bookmarks'
329
+ ]);
330
+ });
331
+ });
332
+
333
+ describe('Behaviors for specific menus', () => {
334
+ describe('Search menu - ref: plugin.search.js', () => {
335
+ test('Event: listens for `BookReader:ToggleSearchMenu to open search side panel', async () => {
336
+ const el = fixtureSync(container());
337
+ const brStub = {
338
+ resize: sinon.fake(),
339
+ currentIndex: sinon.fake(),
340
+ jumpToIndex: sinon.fake(),
341
+ options: { enableMultipleBooks: true },
342
+ refs: {},
343
+ };
344
+ el.bookreader = brStub;
345
+ await elementUpdated(el);
346
+
347
+ let sidePanelConfig = {};
348
+ el.addEventListener('updateSideMenu', (e) => {
349
+ console.log();
350
+ sidePanelConfig = e.detail;
351
+ });
352
+ const toggleSearchMenuEvent = new Event('BookReader:ToggleSearchMenu');
353
+ window.dispatchEvent(toggleSearchMenuEvent);
354
+
355
+ await elementUpdated(el);
356
+ expect(sidePanelConfig.menuId).toEqual('search');
357
+ expect(sidePanelConfig.action).toEqual('toggle');
358
+ });
359
+ });
360
+ });
361
+ });
362
+ });
363
+
364
+ describe('Resizing',() => {
365
+ test('keeps track of `brWidth` and `brHeight`', async () => {
366
+ const el = fixtureSync(container());
367
+ const brStub = {
368
+ resize: sinon.fake(),
369
+ options: {},
370
+ refs: {
371
+ $brContainer: document.createElement('div')
372
+ }
373
+ };
374
+ el.bookreader = brStub;
375
+ await elementUpdated(el);
376
+ expect(el.brWidth).toEqual(0);
377
+ expect(el.brHeight).toEqual(0);
378
+
379
+ const mockResizeEvent = {
380
+ contentRect: {
381
+ height: 500,
382
+ width: 900
383
+ },
384
+ target: el.mainBRContainer
385
+ };
386
+ el.handleResize(mockResizeEvent);
387
+
388
+ await elementUpdated(el);
389
+ await promise0();
390
+
391
+ expect(el.brHeight).toEqual(500);
392
+ expect(el.brWidth).toEqual(900);
393
+ });
394
+ test('resizes if height/width changes && is not animating', async () => {
395
+ const el = fixtureSync(container());
396
+ const brStub = {
397
+ animating: false,
398
+ resize: sinon.fake(),
399
+ options: {},
400
+ refs: {
401
+ $brContainer: document.createElement('div')
402
+ }
403
+ };
404
+
405
+ el.bookreader = brStub;
406
+ await elementUpdated(el);
407
+ expect(el.brWidth).toEqual(0);
408
+ expect(el.brHeight).toEqual(0);
409
+
410
+ const mockResizeEvent = {
411
+ contentRect: {
412
+ height: 500,
413
+ width: 900
414
+ },
415
+ target: el.mainBRContainer
416
+ };
417
+ el.handleResize(mockResizeEvent);
418
+
419
+ await elementUpdated(el);
420
+ await promise0();
421
+
422
+ expect(brStub.resize.callCount).toEqual(1);
423
+ });
424
+ test('does not resize bookreader if animating', async () => {
425
+ const el = fixtureSync(container());
426
+ const brStub = {
427
+ animating: true, // <-- testing for this
428
+ resize: sinon.fake(),
429
+ currentIndex: sinon.fake(),
430
+ jumpToIndex: sinon.fake(),
431
+ options: { enableMultipleBooks: true },
432
+ refs: {},
433
+ };
434
+
435
+ el.bookreader = brStub;
436
+ await elementUpdated(el);
437
+
438
+ expect(el.bookreader.resize.callCount).toEqual(0);
439
+ expect(el.bookreader.currentIndex.callCount).toEqual(0);
440
+ expect(el.bookreader.jumpToIndex.callCount).toEqual(0);
441
+ });
442
+ });
443
+
444
+ describe('Fullscreen Management', () => {
445
+ test('needs option: `enableFSLogoShortcut` to use FS logo', async () => {
446
+ const el = fixtureSync(container());
447
+ const brStub = {
448
+ isFullscreen: () => true,
449
+ options: {
450
+ enableFSLogoShortcut: false,
451
+ },
452
+ refs: {},
453
+ };
454
+
455
+ el.bookreader = brStub;
456
+ el.emitMenuShortcutsUpdated = sinon.fake();
457
+ await elementUpdated(el);
458
+
459
+ el.manageFullScreenBehavior();
460
+ await elementUpdated(el);
461
+ expect(el.menuShortcuts.length).toEqual(0);
462
+ });
463
+ test('sets fullscreen shortcut when entering Fullscreen', async () => {
464
+ const el = fixtureSync(container());
465
+ const brStub = {
466
+ isFullscreen: () => true,
467
+ options: {
468
+ enableFSLogoShortcut: true,
469
+ },
470
+ refs: {},
471
+ };
472
+
473
+ el.bookreader = brStub;
474
+ el.emitMenuShortcutsUpdated = sinon.fake();
475
+ await elementUpdated(el);
476
+
477
+ el.manageFullScreenBehavior();
478
+ await elementUpdated(el);
479
+ expect(el.menuShortcuts.length).toEqual(1);
480
+ expect(el.menuShortcuts[0].id).toEqual('fullscreen');
481
+ expect(el.menuShortcuts[0].icon).toBeDefined();
482
+ expect(el.emitMenuShortcutsUpdated.callCount).toEqual(1);
483
+ });
484
+ test('clicking Fullscreen shortcut closes fullscreen', async () => {
485
+ const el = fixtureSync(container());
486
+ const brStub = {
487
+ isFullscreen: () => true,
488
+ options: {
489
+ enableFSLogoShortcut: true,
490
+ },
491
+ refs: {},
492
+ };
493
+
494
+ el.bookreader = brStub;
495
+ el.emitMenuShortcutsUpdated = sinon.fake();
496
+ el.closeFullscreen = sinon.fake();
497
+ await elementUpdated(el);
498
+
499
+ el.manageFullScreenBehavior();
500
+ await elementUpdated(el);
501
+
502
+ fixtureSync(el.menuShortcuts[0].icon).click();
503
+ await elementUpdated(el);
504
+
505
+ expect(el.closeFullscreen.callCount).toEqual(1);
506
+ });
507
+ test('removes Fullscreen shortcut when leaving fullscreen', async() => {
508
+ const el = fixtureSync(container());
509
+ const brStub = {
510
+ isFullscreen: () => false,
511
+ options: {
512
+ enableFSLogoShortcut: true,
513
+ },
514
+ refs: {},
515
+ };
516
+
517
+ el.bookreader = brStub;
518
+ el.emitMenuShortcutsUpdated = sinon.fake();
519
+ await elementUpdated(el);
520
+
521
+ el.manageFullScreenBehavior();
522
+ await elementUpdated(el);
523
+ expect(el.menuShortcuts.length).toEqual(0);
524
+ expect(el.emitMenuShortcutsUpdated.callCount).toEqual(1);
525
+ });
526
+ test('Event: Listens for `BookReader:FullscreenToggled', async() => {
527
+ const el = fixtureSync(container());
528
+ const brStub = {
529
+ isFullscreen: () => true,
530
+ resize: sinon.fake(),
531
+ currentIndex: sinon.fake(),
532
+ jumpToIndex: sinon.fake(),
533
+ options: {
534
+ enableFSLogoShortcut: true,
535
+ },
536
+ refs: {},
537
+ };
538
+ el.bookreader = brStub;
539
+ el.manageFullScreenBehavior = sinon.fake();
540
+ await elementUpdated(el);
541
+
542
+ window.dispatchEvent(new CustomEvent('BookReader:fullscreenToggled', {
543
+ detail: { props: brStub }
544
+ }));
545
+ await elementUpdated(el);
546
+
547
+ expect(el.manageFullScreenBehavior.callCount).toEqual(1);
548
+ });
549
+ });
550
+ describe('Handles Restricted Books', () => {
551
+ describe('contextMenu is prevented when book is restricted', () => {
552
+ it('watches on `div.BRscreen`', async () => {
553
+ const el = fixtureSync(container());
554
+ const brStub = {
555
+ options: { restricted: true },
556
+ };
557
+
558
+ el.bookreader = brStub;
559
+ el.bookIsRestricted = true;
560
+
561
+ const elSpy = sinon.spy(el.manageContextMenuVisibility);
562
+ await el.elementUpdated;
563
+
564
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(false);
565
+ expect(window.archive_analytics.send_event.called).toEqual(false);
566
+ expect(elSpy.called).toEqual(false);
567
+
568
+ const body = document.querySelector('body');
569
+
570
+ const divBRscreen = document.createElement('div');
571
+ divBRscreen.classList.add('BRscreen');
572
+ body.appendChild(divBRscreen);
573
+
574
+ const contextMenuEvent = new Event('contextmenu', { bubbles: true });
575
+
576
+ // Set spy on contextMenuEvent to check if `preventDefault` is called
577
+ const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
578
+ expect(preventDefaultSpy.called).toEqual(false);
579
+
580
+ divBRscreen.dispatchEvent(contextMenuEvent);
581
+
582
+ // analytics fires
583
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
584
+ false
585
+ );
586
+ expect(window.archive_analytics.send_event.called).toEqual(true);
587
+ // we prevent default
588
+ expect(preventDefaultSpy.called).toEqual(true);
589
+ });
590
+ it('watches on `img.BRpageimage`', async () => {
591
+ const el = fixtureSync(container());
592
+ const brStub = {
593
+ options: { restricted: true },
594
+ };
595
+
596
+ el.bookreader = brStub;
597
+ el.bookIsRestricted = true;
598
+
599
+ await el.elementUpdated;
600
+
601
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(false);
602
+ expect(window.archive_analytics.send_event.called).toEqual(false);
603
+
604
+ const body = document.querySelector('body');
605
+ // const element stub for img.BRpageimage
606
+ const imgBRpageimage = document.createElement('img');
607
+ imgBRpageimage.classList.add('BRpageimage');
608
+ body.appendChild(imgBRpageimage);
609
+ const contextMenuEvent = new Event('contextmenu', { bubbles: true });
610
+
611
+ // Set spy on contextMenuEvent to check if `preventDefault` is called
612
+ const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
613
+ expect(preventDefaultSpy.called).toEqual(false);
614
+
615
+ imgBRpageimage.dispatchEvent(contextMenuEvent);
616
+
617
+ // analytics fires
618
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(false);
619
+ expect(window.archive_analytics.send_event.called).toEqual(true);
620
+ // we prevent default
621
+ expect(preventDefaultSpy.called).toEqual(true);
622
+ });
623
+ });
624
+ it('Allows unrestricted books access to context menu', async () => {
625
+ const el = fixtureSync(container());
626
+ const brStub = {
627
+ options: { restricted: false },
628
+ };
629
+
630
+ el.bookreader = brStub;
631
+ el.bookIsRestricted = false;
632
+
633
+ await el.elementUpdated;
634
+
635
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(
636
+ false
637
+ );
638
+ expect(window.archive_analytics.send_event.called).toEqual(false);
639
+
640
+
641
+ const body = document.querySelector('body');
642
+ // const element stub for img.BRpageimage
643
+ const imgBRpageimage = document.createElement('img');
644
+ imgBRpageimage.classList.add('not-targeted-element');
645
+ body.appendChild(imgBRpageimage);
646
+ const contextMenuEvent = new Event('contextmenu', { bubbles: true });
647
+
648
+ // Set spy on contextMenuEvent to check if `preventDefault` is called
649
+ const preventDefaultSpy = sinon.spy(contextMenuEvent, 'preventDefault');
650
+ expect(preventDefaultSpy.called).toEqual(false);
651
+
652
+ imgBRpageimage.dispatchEvent(contextMenuEvent);
653
+
654
+ // analytics fires
655
+ expect(window.archive_analytics.send_event_no_sampling.called).toEqual(false);
656
+ expect(window.archive_analytics.send_event.called).toEqual(true);
657
+ // we do not prevent default
658
+ expect(preventDefaultSpy.called).toEqual(false);
659
+ });
660
+ });
661
+ });
@@ -0,0 +1,43 @@
1
+ import {
2
+ html,
3
+ fixtureSync,
4
+ fixtureCleanup,
5
+ } from '@open-wc/testing-helpers';
6
+ import '@/src/BookNavigator/bookmarks/bookmark-button.js';
7
+ import sinon from 'sinon';
8
+
9
+ afterEach(() => {
10
+ sinon.restore();
11
+ fixtureCleanup();
12
+ });
13
+
14
+ describe('<bookmark-button>', () => {
15
+ test('sets default properties', async () => {
16
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
17
+
18
+ expect(el.side).toBeUndefined();
19
+ expect(el.state).toEqual('hollow');
20
+ });
21
+ test('Event: fires `@bookmarkButtonClicked on click', async () => {
22
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
23
+ let buttonClicked = false;
24
+ el.addEventListener('bookmarkButtonClicked', () => { buttonClicked = true; });
25
+ const eventStub = { preventDefault: sinon.fake()};
26
+ el.handleClick(eventStub);
27
+ await el.updateComplete;
28
+
29
+ expect(buttonClicked).toBeTruthy();
30
+ expect(eventStub.preventDefault.callCount).toEqual(1);
31
+ });
32
+ test('Title: Toggles title between `Add/Remove bookmark`', async () => {
33
+ const el = fixtureSync(html`<bookmark-button></bookmark-button>`);
34
+ expect(el.title).toEqual('Add bookmark');
35
+ expect(el.state).toEqual('hollow');
36
+
37
+ el.state = 'filled';
38
+ await el.updateComplete;
39
+
40
+ expect(el.title).toEqual('Remove bookmark');
41
+ expect(el.state).not.toEqual('hollow');
42
+ });
43
+ });