@internetarchive/bookreader 5.0.0-3 → 5.0.0-30-d

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 (391) hide show
  1. package/.eslintrc.js +17 -5
  2. package/.github/dependabot.yml +8 -0
  3. package/.github/workflows/node.js.yml +10 -1
  4. package/.husky/_/husky.sh +30 -0
  5. package/.testcaferc.js +10 -0
  6. package/BookReader/BookReader.css +75 -323
  7. package/BookReader/BookReader.js +32261 -2
  8. package/BookReader/BookReader.js.map +1 -1
  9. package/BookReader/ia-bookreader-bundle.js +15235 -0
  10. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  11. package/BookReader/icons/close-circle-dark.svg +1 -0
  12. package/BookReader/icons/voice.svg +1 -0
  13. package/BookReader/jquery-1.10.1.js +108 -2
  14. package/BookReader/plugins/plugin.archive_analytics.js +170 -1
  15. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  16. package/BookReader/plugins/plugin.autoplay.js +163 -1
  17. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  18. package/BookReader/plugins/plugin.chapters.js +333 -1
  19. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  20. package/BookReader/plugins/plugin.iframe.js +72 -1
  21. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  22. package/BookReader/plugins/plugin.mobile_nav.js +332 -1
  23. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  24. package/BookReader/plugins/plugin.resume.js +241 -1
  25. package/BookReader/plugins/plugin.resume.js.map +1 -1
  26. package/BookReader/plugins/plugin.search.js +1261 -1
  27. package/BookReader/plugins/plugin.search.js.map +1 -1
  28. package/BookReader/plugins/plugin.text_selection.js +839 -1
  29. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  30. package/BookReader/plugins/plugin.tts.js +9115 -2
  31. package/BookReader/plugins/plugin.tts.js.map +1 -1
  32. package/BookReader/plugins/plugin.url.js +811 -1
  33. package/BookReader/plugins/plugin.url.js.map +1 -1
  34. package/BookReader/plugins/plugin.vendor-fullscreen.js +326 -1
  35. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  36. package/BookReader/webcomponents-bundle.js +412 -0
  37. package/BookReader/webcomponents-bundle.js.map +1 -0
  38. package/BookReaderDemo/BookReaderDemo.css +14 -1
  39. package/BookReaderDemo/IADemoBr.js +107 -0
  40. package/BookReaderDemo/demo-advanced.html +1 -1
  41. package/BookReaderDemo/demo-autoplay.html +1 -0
  42. package/BookReaderDemo/demo-embed-iframe-src.html +1 -0
  43. package/BookReaderDemo/demo-fullscreen-mobile.html +1 -0
  44. package/BookReaderDemo/demo-fullscreen.html +1 -0
  45. package/BookReaderDemo/demo-iiif.html +1 -0
  46. package/BookReaderDemo/demo-internetarchive.html +66 -18
  47. package/BookReaderDemo/demo-multiple.html +1 -0
  48. package/BookReaderDemo/demo-preview-pages.html +1 -0
  49. package/BookReaderDemo/demo-simple.html +1 -0
  50. package/BookReaderDemo/demo-vendor-fullscreen.html +1 -0
  51. package/BookReaderDemo/immersion-1up.html +1 -0
  52. package/BookReaderDemo/immersion-mode.html +1 -0
  53. package/BookReaderDemo/toggle_controls.html +1 -0
  54. package/BookReaderDemo/view_mode.html +1 -0
  55. package/BookReaderDemo/viewmode-cycle.html +1 -2
  56. package/CHANGELOG.md +114 -0
  57. package/babel.config.js +18 -0
  58. package/index.html +3 -0
  59. package/jsconfig.json +19 -0
  60. package/package.json +45 -27
  61. package/src/BookNavigator/assets/button-base.js +8 -1
  62. package/src/BookNavigator/assets/ia-logo.js +17 -0
  63. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  64. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  65. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  66. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  67. package/src/BookNavigator/book-navigator.js +528 -0
  68. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  69. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -1
  70. package/src/BookNavigator/bookmarks/bookmarks-list.js +1 -0
  71. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
  72. package/src/BookNavigator/bookmarks/bookmarks-provider.js +32 -11
  73. package/src/BookNavigator/bookmarks/ia-bookmarks.js +88 -43
  74. package/src/BookNavigator/downloads/downloads-provider.js +22 -16
  75. package/src/BookNavigator/downloads/downloads.js +16 -23
  76. package/src/BookNavigator/search/a-search-result.js +1 -0
  77. package/src/BookNavigator/search/search-provider.js +54 -20
  78. package/src/BookNavigator/search/search-results.js +7 -18
  79. package/src/BookNavigator/sharing.js +27 -0
  80. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +10 -12
  81. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +1 -0
  82. package/src/BookNavigator/volumes/volumes-provider.js +114 -0
  83. package/src/BookNavigator/volumes/volumes.js +189 -0
  84. package/src/BookReader/DebugConsole.js +3 -3
  85. package/src/BookReader/DragScrollable.js +233 -0
  86. package/src/BookReader/Mode1Up.js +50 -351
  87. package/src/BookReader/Mode1UpLit.js +434 -0
  88. package/src/BookReader/Mode2Up.js +94 -72
  89. package/src/BookReader/ModeSmoothZoom.js +177 -0
  90. package/src/BookReader/ModeThumb.js +16 -8
  91. package/src/BookReader/Navbar/Navbar.js +2 -31
  92. package/src/BookReader/PageContainer.js +47 -2
  93. package/src/BookReader/ReduceSet.js +1 -1
  94. package/src/BookReader/Toolbar/Toolbar.js +5 -5
  95. package/src/BookReader/options.js +10 -0
  96. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  97. package/src/BookReader/utils.js +68 -13
  98. package/src/BookReader.js +316 -232
  99. package/src/assets/icons/close-circle-dark.svg +1 -0
  100. package/src/assets/icons/voice.svg +1 -0
  101. package/src/css/BookReader.scss +0 -12
  102. package/src/css/_BRComponent.scss +1 -1
  103. package/src/css/_BRmain.scss +19 -24
  104. package/src/css/_BRnav.scss +4 -26
  105. package/src/css/_BRpages.scss +35 -0
  106. package/src/css/_BRsearch.scss +11 -215
  107. package/src/css/_TextSelection.scss +1 -17
  108. package/src/css/_controls.scss +16 -3
  109. package/src/css/_icons.scss +6 -0
  110. package/src/ia-bookreader/ia-bookreader.js +206 -0
  111. package/src/plugins/plugin.chapters.js +15 -18
  112. package/src/plugins/plugin.mobile_nav.js +11 -10
  113. package/src/plugins/plugin.resume.js +3 -3
  114. package/src/plugins/plugin.text_selection.js +17 -29
  115. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  116. package/src/plugins/search/plugin.search.js +113 -104
  117. package/src/plugins/search/view.js +48 -163
  118. package/src/plugins/tts/AbstractTTSEngine.js +7 -0
  119. package/src/plugins/tts/FestivalTTSEngine.js +2 -2
  120. package/src/plugins/tts/WebTTSEngine.js +5 -0
  121. package/src/plugins/tts/plugin.tts.js +67 -102
  122. package/src/plugins/url/UrlPlugin.js +184 -0
  123. package/src/plugins/url/plugin.url.js +220 -0
  124. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  125. package/{src → stat}/BookNavigator/BookNavigator.js +151 -104
  126. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  127. package/stat/BookNavigator/assets/button-base.js +61 -0
  128. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  129. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  130. package/stat/BookNavigator/assets/icon_close.js +3 -0
  131. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  132. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  133. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  134. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  135. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  136. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  137. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  138. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  139. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  140. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  141. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  142. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  143. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  144. package/stat/BookNavigator/downloads/downloads.js +139 -0
  145. package/stat/BookNavigator/provider-config.js +0 -0
  146. package/stat/BookNavigator/search/a-search-result.js +55 -0
  147. package/stat/BookNavigator/search/search-provider.js +180 -0
  148. package/stat/BookNavigator/search/search-results.js +360 -0
  149. package/stat/BookNavigator/sharing.js +31 -0
  150. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  151. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  152. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  153. package/stat/BookNavigator/volumes/volumes.js +178 -0
  154. package/stat/BookReader/BookModel.js +518 -0
  155. package/stat/BookReader/DebugConsole.js +54 -0
  156. package/stat/BookReader/DragScrollable.js +233 -0
  157. package/stat/BookReader/ImageCache.js +116 -0
  158. package/stat/BookReader/Mode1Up.js +102 -0
  159. package/stat/BookReader/Mode1UpLit.js +434 -0
  160. package/stat/BookReader/Mode2Up.js +1372 -0
  161. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  162. package/stat/BookReader/ModeThumb.js +344 -0
  163. package/stat/BookReader/Navbar/Navbar.js +310 -0
  164. package/stat/BookReader/PageContainer.js +120 -0
  165. package/stat/BookReader/ReduceSet.js +26 -0
  166. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  167. package/stat/BookReader/events.js +20 -0
  168. package/stat/BookReader/options.js +324 -0
  169. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  170. package/stat/BookReader/utils/classes.js +36 -0
  171. package/stat/BookReader/utils.js +240 -0
  172. package/stat/BookReader.js +2550 -0
  173. package/{src → stat}/BookReaderComponent/BookReaderComponent.js +16 -11
  174. package/stat/assets/icons/1up.svg +12 -0
  175. package/stat/assets/icons/2up.svg +15 -0
  176. package/stat/assets/icons/advance.svg +26 -0
  177. package/stat/assets/icons/chevron-right.svg +1 -0
  178. package/stat/assets/icons/close-circle-dark.svg +1 -0
  179. package/stat/assets/icons/close-circle.svg +1 -0
  180. package/stat/assets/icons/fullscreen.svg +17 -0
  181. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  182. package/stat/assets/icons/hamburger.svg +15 -0
  183. package/stat/assets/icons/left-arrow.svg +12 -0
  184. package/stat/assets/icons/magnify-minus.svg +16 -0
  185. package/stat/assets/icons/magnify-plus.svg +17 -0
  186. package/stat/assets/icons/magnify.svg +15 -0
  187. package/stat/assets/icons/pause.svg +23 -0
  188. package/stat/assets/icons/play.svg +22 -0
  189. package/stat/assets/icons/playback-speed.svg +34 -0
  190. package/stat/assets/icons/read-aloud.svg +22 -0
  191. package/stat/assets/icons/review.svg +22 -0
  192. package/stat/assets/icons/thumbnails.svg +17 -0
  193. package/stat/assets/icons/voice.svg +1 -0
  194. package/stat/assets/icons/volume-full.svg +22 -0
  195. package/stat/assets/images/BRicons.png +0 -0
  196. package/stat/assets/images/BRicons.svg +94 -0
  197. package/stat/assets/images/BRicons_ia.png +0 -0
  198. package/stat/assets/images/back_pages.png +0 -0
  199. package/stat/assets/images/book_bottom_icon.png +0 -0
  200. package/stat/assets/images/book_down_icon.png +0 -0
  201. package/stat/assets/images/book_left_icon.png +0 -0
  202. package/stat/assets/images/book_leftmost_icon.png +0 -0
  203. package/stat/assets/images/book_right_icon.png +0 -0
  204. package/stat/assets/images/book_rightmost_icon.png +0 -0
  205. package/stat/assets/images/book_top_icon.png +0 -0
  206. package/stat/assets/images/book_up_icon.png +0 -0
  207. package/stat/assets/images/books_graphic.svg +177 -0
  208. package/stat/assets/images/booksplit.png +0 -0
  209. package/stat/assets/images/control_pause_icon.png +0 -0
  210. package/stat/assets/images/control_play_icon.png +0 -0
  211. package/stat/assets/images/embed_icon.png +0 -0
  212. package/stat/assets/images/icon-home-ia.png +0 -0
  213. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  214. package/stat/assets/images/icon_alert-xs.png +0 -0
  215. package/stat/assets/images/icon_book.svg +12 -0
  216. package/stat/assets/images/icon_bookmark.svg +12 -0
  217. package/stat/assets/images/icon_close-pop.png +0 -0
  218. package/stat/assets/images/icon_download.png +0 -0
  219. package/stat/assets/images/icon_gear.svg +14 -0
  220. package/stat/assets/images/icon_hamburger.svg +20 -0
  221. package/stat/assets/images/icon_home.png +0 -0
  222. package/stat/assets/images/icon_home.svg +21 -0
  223. package/stat/assets/images/icon_home_ia.png +0 -0
  224. package/stat/assets/images/icon_indicator.png +0 -0
  225. package/stat/assets/images/icon_info.svg +11 -0
  226. package/stat/assets/images/icon_one_page.svg +8 -0
  227. package/stat/assets/images/icon_pause.svg +1 -0
  228. package/stat/assets/images/icon_play.svg +1 -0
  229. package/stat/assets/images/icon_playback-rate.svg +15 -0
  230. package/stat/assets/images/icon_return.png +0 -0
  231. package/stat/assets/images/icon_search_button.svg +8 -0
  232. package/stat/assets/images/icon_share.svg +9 -0
  233. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  234. package/stat/assets/images/icon_skip-back.svg +13 -0
  235. package/stat/assets/images/icon_speaker.svg +18 -0
  236. package/stat/assets/images/icon_speaker_open.svg +10 -0
  237. package/stat/assets/images/icon_thumbnails.svg +12 -0
  238. package/stat/assets/images/icon_toc.svg +5 -0
  239. package/stat/assets/images/icon_two_pages.svg +9 -0
  240. package/stat/assets/images/icon_zoomer.png +0 -0
  241. package/stat/assets/images/loading.gif +0 -0
  242. package/stat/assets/images/logo_icon.png +0 -0
  243. package/stat/assets/images/marker_chap-off.png +0 -0
  244. package/stat/assets/images/marker_chap-off.svg +11 -0
  245. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  246. package/stat/assets/images/marker_chap-on.png +0 -0
  247. package/stat/assets/images/marker_chap-on.svg +11 -0
  248. package/stat/assets/images/marker_srch-on.svg +11 -0
  249. package/stat/assets/images/marker_srchchap-off.png +0 -0
  250. package/stat/assets/images/marker_srchchap-on.png +0 -0
  251. package/stat/assets/images/nav_control-dn.png +0 -0
  252. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  253. package/stat/assets/images/nav_control-up.png +0 -0
  254. package/stat/assets/images/nav_control-up_ia.png +0 -0
  255. package/stat/assets/images/nav_control.png +0 -0
  256. package/stat/assets/images/one_page_mode_icon.png +0 -0
  257. package/stat/assets/images/paper-badge.png +0 -0
  258. package/stat/assets/images/print_icon.png +0 -0
  259. package/stat/assets/images/progressbar.gif +0 -0
  260. package/stat/assets/images/right_edges.png +0 -0
  261. package/stat/assets/images/slider.png +0 -0
  262. package/stat/assets/images/slider_ia.png +0 -0
  263. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  264. package/stat/assets/images/transparent.png +0 -0
  265. package/stat/assets/images/two_page_mode_icon.png +0 -0
  266. package/stat/assets/images/zoom_in_icon.png +0 -0
  267. package/stat/assets/images/zoom_out_icon.png +0 -0
  268. package/stat/css/BookReader.scss +89 -0
  269. package/stat/css/_BRBookmarks.scss +29 -0
  270. package/stat/css/_BRComponent.scss +13 -0
  271. package/stat/css/_BRfloat.scss +197 -0
  272. package/stat/css/_BRicon.scss +48 -0
  273. package/stat/css/_BRmain.scss +251 -0
  274. package/stat/css/_BRnav.scss +359 -0
  275. package/stat/css/_BRpages.scss +139 -0
  276. package/stat/css/_BRsearch.scss +226 -0
  277. package/stat/css/_BRtoolbar.scss +84 -0
  278. package/stat/css/_BRvendor.scss +5 -0
  279. package/stat/css/_MobileNav.scss +194 -0
  280. package/stat/css/_TextSelection.scss +32 -0
  281. package/stat/css/_colorbox.scss +52 -0
  282. package/stat/css/_controls.scss +253 -0
  283. package/stat/css/_icons.scss +121 -0
  284. package/stat/jquery-wrapper.js +4 -0
  285. package/stat/plugins/plugin.archive_analytics.js +86 -0
  286. package/stat/plugins/plugin.autoplay.js +129 -0
  287. package/stat/plugins/plugin.chapters.js +248 -0
  288. package/stat/plugins/plugin.iframe.js +48 -0
  289. package/stat/plugins/plugin.mobile_nav.js +288 -0
  290. package/stat/plugins/plugin.resume.js +68 -0
  291. package/stat/plugins/plugin.text_selection.js +291 -0
  292. package/{src → stat}/plugins/plugin.url.js +4 -4
  293. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  294. package/stat/plugins/search/plugin.search.js +439 -0
  295. package/stat/plugins/search/view.js +439 -0
  296. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  297. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  298. package/stat/plugins/tts/PageChunk.js +107 -0
  299. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  300. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  301. package/stat/plugins/tts/plugin.tts.js +357 -0
  302. package/stat/plugins/tts/tooltip_dict.js +15 -0
  303. package/stat/plugins/tts/utils.js +91 -0
  304. package/stat/util/browserSniffing.js +30 -0
  305. package/stat/util/debouncer.js +26 -0
  306. package/stat/util/docCookies.js +67 -0
  307. package/stat/util/strings.js +34 -0
  308. package/tests/e2e/README.md +37 -0
  309. package/tests/e2e/autoplay.test.js +2 -2
  310. package/tests/e2e/base.test.js +5 -7
  311. package/tests/e2e/helpers/base.js +8 -3
  312. package/tests/e2e/helpers/debug.js +1 -1
  313. package/tests/e2e/helpers/desktopSearch.js +1 -1
  314. package/tests/e2e/helpers/mobileSearch.js +3 -3
  315. package/tests/e2e/helpers/params.js +17 -0
  316. package/tests/e2e/rightToLeft.test.js +4 -5
  317. package/tests/e2e/viewmode.test.js +30 -31
  318. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +3 -3
  319. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  320. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  321. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  322. package/tests/jest/BookReader/Mode1UpLit.test.js +87 -0
  323. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +5 -7
  324. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  325. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  326. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  327. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +74 -2
  328. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  329. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  330. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  331. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  332. package/tests/jest/BookReader/utils.test.js +136 -0
  333. package/tests/jest/BookReader.keyboard.test.js +190 -0
  334. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  335. package/tests/{BookReader.test.js → jest/BookReader.test.js} +20 -4
  336. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  337. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +2 -2
  338. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +8 -8
  339. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  340. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  341. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  342. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +14 -24
  343. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  344. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +12 -5
  345. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +6 -6
  346. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +3 -3
  347. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  348. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  349. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  350. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  351. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -3
  352. package/tests/jest/plugins/url/UrlPlugin.test.js +175 -0
  353. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  354. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  355. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  356. package/tests/{util → jest/util}/strings.test.js +1 -1
  357. package/tests/{utils.js → jest/utils.js} +38 -0
  358. package/tests/karma/BookNavigator/book-navigator.test.js +485 -0
  359. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  360. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +1 -3
  361. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +1 -2
  362. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +67 -0
  363. package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
  364. package/tests/karma/BookNavigator/search/search-provider.test.js +123 -0
  365. package/tests/karma/BookNavigator/{search-results.test.js → search/search-results.test.js} +1 -4
  366. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +49 -0
  367. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -2
  368. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +184 -0
  369. package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
  370. package/webpack.config.js +11 -5
  371. package/.babelrc +0 -12
  372. package/.dependabot/config.yml +0 -6
  373. package/.testcaferc.json +0 -5
  374. package/BookReader/BookReader.js.LICENSE.txt +0 -72
  375. package/BookReader/bookreader-component-bundle.js +0 -1450
  376. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  377. package/BookReader/bookreader-component-bundle.js.map +0 -1
  378. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  379. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  380. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  381. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +0 -27
  382. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  383. package/src/BookNavigator/assets/book-loader.js +0 -27
  384. package/src/ItemNavigator/ItemNavigator.js +0 -372
  385. package/src/ItemNavigator/providers/sharing.js +0 -29
  386. package/src/dragscrollable-br.js +0 -261
  387. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  388. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  389. package/tests/BookReader/Mode1Up.test.js +0 -164
  390. package/tests/BookReader/utils.test.js +0 -109
  391. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -1,5 +1,7 @@
1
- import { render, nothing } from 'lit-html';
1
+ import { render } from 'lit-html';
2
2
  import { LitElement, html, css } from 'lit-element';
3
+ // eslint-disable-next-line no-unused-vars
4
+ import { ModalConfig, ModalManager } from '@internetarchive/modal-manager';
3
5
  import buttonStyles from '../assets/button-base.js';
4
6
  import './bookmarks-loginCTA.js';
5
7
 
@@ -57,9 +59,11 @@ class IABookmarks extends LitElement {
57
59
  activeBookmarkID: { type: String },
58
60
  bookmarks: { type: Array },
59
61
  bookreader: { type: Object },
60
- options: { type: Object },
61
62
  displayMode: { type: String },
62
63
  editedBookmark: { type: Object },
64
+ deleteModalConfig: { type: Object},
65
+ modal: { attribute: false },
66
+ loginOptions: { type: Object, attribute: false }
63
67
  };
64
68
  }
65
69
 
@@ -92,7 +96,12 @@ class IABookmarks extends LitElement {
92
96
  this.bookmarks = [];
93
97
  this.bookreader = {};
94
98
  this.editedBookmark = {};
95
- this.options = {};
99
+ /** @type {ModalManager} */
100
+ this.modal = undefined;
101
+ this.loginOptions = {
102
+ loginClicked: () => {},
103
+ loginUrl: '',
104
+ };
96
105
  /**
97
106
  * Toggles display to either bookmarks or login cta
98
107
  * @param {('bookmarks'|'login')} displayMode
@@ -113,21 +122,44 @@ class IABookmarks extends LitElement {
113
122
  // eslint-disable-next-line
114
123
  this.defaultColor = this.bookmarkColors[0];
115
124
  this.api = api;
125
+ this.deleteModalConfig = new ModalConfig({
126
+ title: 'Delete Bookmark',
127
+ headline: 'This bookmark contains a note. Deleting it will permanently delete the note. Are you sure?',
128
+ headerColor: '#194880',
129
+ });
116
130
  }
117
131
 
118
- updated() {
132
+ updated(changed) {
133
+ if (changed.has('displayMode')) {
134
+ this.updateDisplay();
135
+ }
136
+
119
137
  this.emitBookmarksChanged();
120
138
  }
121
139
 
122
140
  setup() {
123
141
  this.api.identifier = this.bookreader.bookId;
142
+ if (this.displayMode === 'login') {
143
+ return;
144
+ }
145
+ this.setBREventListeners();
146
+ this.initializeBookmarks();
147
+ }
148
+
149
+ updateDisplay() {
150
+ if (this.displayMode === 'bookmarks') {
151
+ this.fetchUserBookmarks();
152
+ }
153
+ }
154
+
155
+ fetchUserBookmarks() {
124
156
  this.fetchBookmarks()
125
- .then(() => this.initializeBookmarks())
126
- .catch((err) => this.displayMode = 'login');
157
+ .then(() => {
158
+ this.initializeBookmarks();
159
+ });
127
160
  }
128
161
 
129
- initializeBookmarks() {
130
- this.displayMode = 'bookmarks';
162
+ setBREventListeners() {
131
163
  ['3PageViewSelected'].forEach((event) => {
132
164
  window.addEventListener(`BookReader:${event}`, (e) => {
133
165
  setTimeout(() => {
@@ -147,12 +179,12 @@ class IABookmarks extends LitElement {
147
179
  });
148
180
  ['zoomOut', 'zoomIn', 'resize'].forEach((event) => {
149
181
  window.addEventListener(`BookReader:${event}`, () => {
150
- if (this.bookreader.mode === this.bookreader.constModeThumb) {
151
- this.renderBookmarkButtons();
152
- }
182
+ this.renderBookmarkButtons();
153
183
  });
154
184
  });
185
+ }
155
186
 
187
+ initializeBookmarks() {
156
188
  this.renderBookmarkButtons();
157
189
  this.markActiveBookmark(true);
158
190
  this.emitBookmarksChanged();
@@ -195,13 +227,22 @@ class IABookmarks extends LitElement {
195
227
  }
196
228
 
197
229
  fetchBookmarks() {
198
- return this.api.getAll().then((res) => res.json()).then(({
199
- success,
200
- error = 'Something happened while fetching bookmarks.',
201
- value: bkmrks = [],
202
- }) => {
230
+ return this.api.getAll().then((res) => {
231
+ let response;
232
+ try {
233
+ response = JSON.parse(res);
234
+ } catch (e) {
235
+ response = { error: e.message };
236
+ }
237
+ return response;
238
+ }).then((response) => {
239
+ const {
240
+ success,
241
+ error = 'Something happened while fetching bookmarks.',
242
+ value: bkmrks = [],
243
+ } = response;
203
244
  if (!success) {
204
- throw new Error(`Failed to load bookmarks: ${error}`);
245
+ console?.warn('Error fetching bookmarks', error);
205
246
  }
206
247
 
207
248
  const bookmarks = {};
@@ -250,7 +291,9 @@ class IABookmarks extends LitElement {
250
291
 
251
292
  pages.forEach((pageEl) => {
252
293
  const existingButton = pageEl.querySelector('.bookmark-button');
253
- if (existingButton) { existingButton.remove(); }
294
+ if (existingButton) {
295
+ existingButton.remove();
296
+ }
254
297
  const pageID = +pageEl.classList.value.match(/pagediv\d+/)[0].replace(/\D/g, '');
255
298
  const pageBookmark = this.getBookmark(pageID);
256
299
  const bookmarkState = pageBookmark ? 'filled' : 'hollow';
@@ -390,33 +433,26 @@ class IABookmarks extends LitElement {
390
433
  confirmDeletion(pageID) {
391
434
  const existingBookmark = this.getBookmark(pageID);
392
435
  if (existingBookmark.note) {
393
- this.emitShowModal(pageID);
436
+ this.displayDeletionModal(pageID);
394
437
  return;
395
438
  }
396
439
  this.deleteBookmark({ detail: { id: `${pageID}` } });
397
440
  }
398
441
 
399
- emitShowModal(pageID) {
400
- this.dispatchEvent(new CustomEvent('showItemNavigatorModal', {
401
- bubbles: true,
402
- composed: true,
403
- detail: {
404
- customModalContent: html`
405
- <delete-modal-actions
406
- .deleteAction=${() => this.deleteBookmark({ detail: { id: `${pageID}` } })}
407
- .cancelAction=${() => this.emitCloseModal()}
408
- .pageID=${pageID}
409
- ></delete-modal-actions>
410
- `,
411
- },
412
- }));
413
- }
442
+ displayDeletionModal(pageID) {
443
+ const customModalContent = html`
444
+ <delete-modal-actions
445
+ .deleteAction=${() => this.deleteBookmark({ detail: { id: `${pageID}` } })}
446
+ .cancelAction=${() => this.modal.closeModal()}
447
+ .pageID=${pageID}
448
+ ></delete-modal-actions>
449
+ `;
414
450
 
415
- emitCloseModal() {
416
- this.dispatchEvent(new CustomEvent('closeItemNavigatorModal', {
417
- bubbles: true,
418
- composed: true,
419
- }));
451
+
452
+ this.modal.showModal({
453
+ config: this.deleteModalConfig,
454
+ customModalContent,
455
+ });
420
456
  }
421
457
 
422
458
  deleteBookmark({ detail }) {
@@ -427,7 +463,7 @@ class IABookmarks extends LitElement {
427
463
 
428
464
  this.api.delete(detail.id);
429
465
  this.editedBookmark = {};
430
- this.emitCloseModal();
466
+ this.modal.closeModal();
431
467
  this.renderBookmarkButtons();
432
468
  }
433
469
 
@@ -452,6 +488,7 @@ class IABookmarks extends LitElement {
452
488
  return html`
453
489
  <button
454
490
  class="ia-button primary"
491
+ tabindex="-1"
455
492
  ?disabled=${this.shouldEnableAddBookmarkButton}
456
493
  @click=${this.addBookmark}>
457
494
  Add bookmark
@@ -475,15 +512,23 @@ class IABookmarks extends LitElement {
475
512
  `;
476
513
  }
477
514
 
515
+ get bookmarkHelperMessage() {
516
+ return html`<p>Please use 1up or 2up view modes to add bookmark.</p>`;
517
+ }
518
+
478
519
  render() {
479
- const { loginUrl } = this.options;
480
520
  const bookmarks = html`
481
521
  ${this.bookmarksList}
482
- ${this.allowAddingBookmark ? this.addBookmarkButton : nothing}
522
+ ${this.allowAddingBookmark ? this.addBookmarkButton : this.bookmarkHelperMessage}
483
523
  `;
484
524
  return html`
485
525
  <section class="bookmarks">
486
- ${this.displayMode === 'login' ? html`<bookmarks-login .url=${loginUrl}></bookmarks-login>` : bookmarks}
526
+ ${ this.displayMode === 'login'
527
+ ? html`<bookmarks-login
528
+ @click=${() => this.loginOptions.loginClicked()}
529
+ .url=${this.loginOptions.loginUrl}></bookmarks-login>`
530
+ : bookmarks
531
+ }
487
532
  </section>
488
533
  `;
489
534
  }
@@ -1,10 +1,7 @@
1
1
  import { html } from 'lit-element';
2
+ import '@internetarchive/icon-dl/icon-dl';
3
+ import './downloads';
2
4
 
3
- /* register subpanel */
4
- import { IABookDownloads } from './downloads';
5
- customElements.define('ia-book-downloads', IABookDownloads);
6
-
7
- let downloads = [];
8
5
  const menuBase = {
9
6
  pdf: {
10
7
  type: 'Encrypted Adobe PDF',
@@ -18,25 +15,33 @@ const menuBase = {
18
15
  }
19
16
  };
20
17
 
21
- export default class {
22
- constructor() {
23
- this.icon = html`<ia-icon icon="download" style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon>`;
18
+ const publicMenuBase = {
19
+ pdf: "PDF",
20
+ epub: "ePub"
21
+ };
22
+
23
+ export default class DownloadsProvider {
24
+
25
+ constructor({ bookreader }) {
26
+ this.icon = html`<ia-icon-dl style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-dl>`;
24
27
  this.label = 'Downloadable files';
25
28
  this.menuDetails = '';
29
+ this.downloads = [];
26
30
  this.id = 'downloads';
27
31
  this.component = '';
32
+ this.isBookProtected = bookreader?.options?.isProtected || false;
28
33
 
29
34
  this.computeAvailableTypes = this.computeAvailableTypes.bind(this);
30
35
  this.update = this.update.bind(this);
31
36
  }
32
37
 
33
-
34
38
  update(downloadTypes) {
35
39
  this.computeAvailableTypes(downloadTypes);
36
40
  this.component = this.menu;
41
+ this.component.isBookProtected = this.isBookProtected;
37
42
 
38
- const ending = downloads.length === 1 ? '' : 's';
39
- this.menuDetails = `(${downloads.length} format${ending})`;
43
+ const ending = this.downloads.length === 1 ? '' : 's';
44
+ this.menuDetails = `(${this.downloads.length} format${ending})`;
40
45
  }
41
46
 
42
47
  /**
@@ -45,22 +50,23 @@ export default class {
45
50
  * @param availableTypes
46
51
  */
47
52
  computeAvailableTypes(availableTypes = []) {
48
- const menuData = availableTypes.reduce((found, incoming = [], index) => {
53
+ const menuData = availableTypes.reduce((found, incoming = []) => {
49
54
  const [ type = '', link = '' ] = incoming;
50
55
  const formattedType = type.toLowerCase();
51
56
  const downloadOption = menuBase[formattedType] || null;
57
+
52
58
  if (downloadOption) {
53
- const menuInfo = Object.assign({}, downloadOption, { url: link });
59
+ const menuButtonText = this.isBookProtected ? menuBase[formattedType].type : publicMenuBase[formattedType];
60
+ const menuInfo = Object.assign({}, downloadOption, { url: link, type: menuButtonText});
54
61
  found.push(menuInfo);
55
62
  }
56
63
  return found;
57
64
  }, []);
58
65
 
59
- downloads = menuData;
66
+ this.downloads = menuData;
60
67
  }
61
68
 
62
-
63
69
  get menu () {
64
- return html`<ia-book-downloads .downloads=${downloads}></ia-book-downloads>`;
70
+ return html`<ia-book-downloads .downloads=${this.downloads}></ia-book-downloads>`;
65
71
  }
66
72
  }
@@ -1,11 +1,13 @@
1
1
  import { css, html, LitElement } from 'lit-element';
2
2
  import { nothing } from 'lit-html';
3
+ import buttonStyles from '../assets/button-base.js';
3
4
  export class IABookDownloads extends LitElement {
4
5
  static get properties() {
5
6
  return {
6
7
  downloads: { type: Array },
7
8
  expiration: { type: Number },
8
9
  renderHeader: { type: Boolean },
10
+ isBookProtected: { type: Boolean },
9
11
  };
10
12
  }
11
13
 
@@ -14,6 +16,7 @@ export class IABookDownloads extends LitElement {
14
16
  this.downloads = [];
15
17
  this.expiration = 0;
16
18
  this.renderHeader = false;
19
+ this.isBookProtected = false;
17
20
  }
18
21
 
19
22
  get formatsCount() {
@@ -31,7 +34,7 @@ export class IABookDownloads extends LitElement {
31
34
  return this.downloads.map(option => (
32
35
  html`
33
36
  <li>
34
- <a class="button" href="${option.url}">Get ${option.type}</a>
37
+ <a class="ia-button link primary" href="${option.url}">Get ${option.type}</a>
35
38
  ${option.note ? html`<p>${option.note}</p>` : html``}
36
39
  </li>
37
40
  `
@@ -50,18 +53,24 @@ export class IABookDownloads extends LitElement {
50
53
  `;
51
54
  }
52
55
 
56
+ get accessProtectedBook() {
57
+ return html`
58
+ <p>To access downloaded books, you need Adobe-compliant software on your device. The Internet Archive will administer this loan, but Adobe may also collect some information.</p>
59
+ <a class="ia-button external primary" href="https://www.adobe.com/solutions/ebook/digital-editions/download.html" rel="noopener noreferrer" target="_blank">Install Adobe Digital Editions</a>
60
+ `;
61
+ }
62
+
53
63
  render() {
54
64
  return html`
55
65
  ${this.header}
56
66
  ${this.loanExpiryMessage}
57
67
  <ul>${this.renderDownloadOptions()}</ul>
58
- <p>To access downloaded books, you need Adobe-compliant software on your device. The Internet Archive will administer this loan, but Adobe may also collect some information.</p>
59
- <a class="button external" href="https://www.adobe.com/solutions/ebook/digital-editions/download.html" rel="noopener noreferrer" target="_blank">Install Adobe Digital Editions</a>
68
+ ${this.isBookProtected ? this.accessProtectedBook : nothing}
60
69
  `;
61
70
  }
62
71
 
63
72
  static get styles() {
64
- return css`
73
+ const mainCss = css`
65
74
  :host {
66
75
  display: block;
67
76
  height: 100%;
@@ -79,24 +88,6 @@ export class IABookDownloads extends LitElement {
79
88
  justify-self: end;
80
89
  }
81
90
 
82
- .button {
83
- color: var(--primaryTextColor);
84
- background: var(--primaryCTAFill);
85
- border: 1px solid var(--primaryCTABorder);
86
- display: inline-block;
87
- padding: .6rem 1rem;
88
- font-size: 1.4rem;
89
- text-decoration: none;
90
- text-shadow: 1px 1px #484848;
91
- border-radius: 4px;
92
- }
93
-
94
- .button.external {
95
- background: var(--secondaryCTAFill, transparent);
96
- border: 1px solid var(--secondaryCTABorder, #999);
97
- text-shadow: none;
98
- }
99
-
100
91
  header {
101
92
  display: flex;
102
93
  align-items: center;
@@ -109,7 +100,6 @@ export class IABookDownloads extends LitElement {
109
100
  font-weight: bold;
110
101
  font-style: italic;
111
102
  }
112
-
113
103
  header div {
114
104
  display: flex;
115
105
  align-items: baseline;
@@ -142,5 +132,8 @@ export class IABookDownloads extends LitElement {
142
132
  line-height: 140%;
143
133
  }
144
134
  `;
135
+
136
+ return [buttonStyles, mainCss];
145
137
  }
146
138
  }
139
+ customElements.define('ia-book-downloads', IABookDownloads);
@@ -52,3 +52,4 @@ export class BookSearchResult extends LitElement {
52
52
  `;
53
53
  }
54
54
  }
55
+ customElements.define('book-search-result', BookSearchResult);
@@ -1,9 +1,7 @@
1
1
  import { html } from 'lit-element';
2
2
  import { nothing } from 'lit-html';
3
-
4
- /* instantiate web component */
5
- import { IABookSearchResults } from './search-results';
6
- customElements.define('ia-book-search-results', IABookSearchResults);
3
+ import '@internetarchive/icon-search/icon-search';
4
+ import './search-results';
7
5
 
8
6
  let searchState = {
9
7
  query: '',
@@ -12,8 +10,11 @@ let searchState = {
12
10
  queryInProgress: false,
13
11
  errorMessage: '',
14
12
  };
15
- export default class {
16
- constructor(onSearchChange = () => {}, brInstance) {
13
+ export default class SearchProvider {
14
+ constructor({
15
+ onProviderChange,
16
+ bookreader
17
+ }) {
17
18
  /* search menu events */
18
19
  this.onBookSearchInitiated = this.onBookSearchInitiated.bind(this);
19
20
  /* bookreader search events */
@@ -22,6 +23,8 @@ export default class {
22
23
  this.onSearchResultsClicked = this.onSearchResultsClicked.bind(this);
23
24
  this.onSearchResultsChange = this.onSearchResultsChange.bind(this);
24
25
  this.onSearchResultsCleared = this.onSearchResultsCleared.bind(this);
26
+ this.searchCanceledInMenu = this.searchCanceledInMenu.bind(this);
27
+
25
28
  /* class methods */
26
29
  this.bindEventListeners = this.bindEventListeners.bind(this);
27
30
  this.getMenuDetails = this.getMenuDetails.bind(this);
@@ -29,9 +32,9 @@ export default class {
29
32
  this.advanceToPage = this.advanceToPage.bind(this);
30
33
  this.updateMenu = this.updateMenu.bind(this);
31
34
 
32
- this.onSearchChange = onSearchChange;
33
- this.bookreader = brInstance;
34
- this.icon = html`<ia-icon icon="search" style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon>`;
35
+ this.onProviderChange = onProviderChange;
36
+ this.bookreader = bookreader;
37
+ this.icon = html`<ia-icon-search style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-search>`;
35
38
  this.label = 'Search inside';
36
39
  this.menuDetails = this.getMenuDetails();
37
40
  this.id = 'search';
@@ -41,7 +44,7 @@ export default class {
41
44
 
42
45
  getMenuDetails() {
43
46
  const { resultsCount, query, queryInProgress } = searchState;
44
- if (queryInProgress || !query) { return nothing }
47
+ if (queryInProgress || !query) { return nothing; }
45
48
  const unit = resultsCount === 1 ? 'result' : 'results';
46
49
  return html`(${resultsCount} ${unit})`;
47
50
  }
@@ -49,14 +52,36 @@ export default class {
49
52
  bindEventListeners() {
50
53
  window.addEventListener('BookReader:SearchStarted', this.onSearchStarted);
51
54
  window.addEventListener('BookReader:SearchCallback', this.onSearchResultsChange);
52
- window.addEventListener('BookReader:SearchCallbackEmpty', (event) => { this.onSearchRequestError(event, 'noResults') });
53
- window.addEventListener('BookReader:SearchCallbackNotIndexed', (event) => { this.onSearchRequestError(event, 'notIndexed') });
54
- window.addEventListener('BookReader:SearchCallbackError', (event) => { this.onSearchRequestError(event) });
55
- window.addEventListener('BookReader:SearchResultsCleared', () => { this.onSearchResultsCleared() });
55
+ window.addEventListener('BookReader:SearchCallbackEmpty', (event) => { this.onSearchRequestError(event, 'noResults'); });
56
+ window.addEventListener('BookReader:SearchCallbackNotIndexed', (event) => { this.onSearchRequestError(event, 'notIndexed'); });
57
+ window.addEventListener('BookReader:SearchCallbackError', (event) => { this.onSearchRequestError(event); });
58
+ window.addEventListener('BookReader:SearchResultsCleared', () => { this.onSearchResultsCleared(); });
59
+ window.addEventListener('BookReader:SearchCanceled', (e) => { this.onSearchCanceled(e); });
60
+ }
61
+
62
+ /**
63
+ * Cancel search handler
64
+ * resets `searchState`
65
+ */
66
+ onSearchCanceled() {
67
+ searchState = {
68
+ query: '',
69
+ results: [],
70
+ resultsCount: 0,
71
+ queryInProgress: false,
72
+ errorMessage: '',
73
+ };
74
+ const updateMenuFor = {
75
+ searchCanceled: true
76
+ };
77
+ this.updateMenu(updateMenuFor);
56
78
  }
57
79
 
58
80
  onSearchStarted(e) {
59
- const { term = '' } = e.detail.props;
81
+ const { term = '', instance } = e.detail.props;
82
+ if (instance) {
83
+ this.bookreader = instance;
84
+ }
60
85
  searchState.query = term;
61
86
  searchState.results = [];
62
87
  searchState.resultsCount = 0;
@@ -81,10 +106,11 @@ export default class {
81
106
  noResults: '0 results',
82
107
  notIndexed: `This book hasn't been indexed for searching yet. We've just started indexing it,
83
108
  so search should be available soon. Please try again later. Thanks!`,
84
- default: 'Sorry, there was an error with your search. The text may still be processing.',
109
+ default: 'Sorry, there was an error with your search. Please try again.',
85
110
  };
86
111
 
87
112
  const messageToShow = errorMessages[errorType] ?? errorMessages.default;
113
+ searchState.query = instance?.searchResults?.q || '';
88
114
  searchState.results = [];
89
115
  searchState.resultsCount = 0;
90
116
  searchState.queryInProgress = false;
@@ -106,6 +132,10 @@ export default class {
106
132
  this.updateMenu();
107
133
  }
108
134
 
135
+ searchCanceledInMenu() {
136
+ this.bookreader?.cancelSearchRequest();
137
+ }
138
+
109
139
  onSearchResultsCleared() {
110
140
  searchState = {
111
141
  query: '',
@@ -113,15 +143,19 @@ export default class {
113
143
  resultsCount: 0,
114
144
  queryInProgress: false,
115
145
  errorMessage: '',
116
- }
146
+ };
117
147
  this.updateMenu();
118
148
  this.bookreader?.searchView?.clearSearchFieldAndResults();
119
149
  }
120
150
 
121
- updateMenu() {
151
+ /**
152
+ * Relays how to update side menu given the context of a search update
153
+ @param {{searchCanceled: boolean}} searchUpdates
154
+ */
155
+ updateMenu(searchUpdates = {}) {
122
156
  this.menuDetails = this.getMenuDetails();
123
157
  this.component = this.getComponent();
124
- this.onSearchChange(this.bookreader);
158
+ this.onProviderChange(this.bookreader, searchUpdates);
125
159
  }
126
160
 
127
161
  getComponent() {
@@ -136,6 +170,7 @@ export default class {
136
170
  @resultSelected=${this.onSearchResultsClicked}
137
171
  @bookSearchInitiated=${this.onBookSearchInitiated}
138
172
  @bookSearchResultsCleared=${this.onSearchResultsCleared}
173
+ @bookSearchCanceled=${this.searchCanceledInMenu}
139
174
  ></ia-book-search-results>
140
175
  `;
141
176
  }
@@ -148,6 +183,5 @@ export default class {
148
183
  advanceToPage(leaf) {
149
184
  const page = this.bookreader.leafNumToIndex(leaf);
150
185
  this.bookreader._searchPluginGoToResult(page);
151
- this.bookreader.updateSearchHilites();
152
186
  }
153
187
  }
@@ -2,11 +2,11 @@
2
2
  import { nothing } from 'lit-html';
3
3
  import { css, html, LitElement } from 'lit-element';
4
4
  import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
5
- import { BookSearchResult } from './a-search-result.js';
5
+ import './a-search-result.js';
6
6
  import checkmarkIcon from '../assets/icon_checkmark.js';
7
7
  import closeIcon from '../assets/icon_close.js';
8
+ import buttonCSS from '../assets/button-base.js';
8
9
 
9
- customElements.define('book-search-result', BookSearchResult);
10
10
 
11
11
  export class IABookSearchResults extends LitElement {
12
12
  static get properties() {
@@ -91,10 +91,7 @@ export class IABookSearchResults extends LitElement {
91
91
  }
92
92
 
93
93
  dispatchSearchCanceled() {
94
- this.dispatchEvent(new CustomEvent('bookSearchCanceled', {
95
- bubbles: true,
96
- composed: true,
97
- }));
94
+ this.dispatchEvent(new Event('bookSearchCanceled'));
98
95
  }
99
96
 
100
97
  get resultsCount() {
@@ -123,6 +120,7 @@ export class IABookSearchResults extends LitElement {
123
120
  <div class="loading">
124
121
  <ia-activity-indicator mode="processing"></ia-activity-indicator>
125
122
  <p>Searching</p>
123
+ <button class="ia-button external cancel-search" @click=${this.cancelSearch}>Cancel</button>
126
124
  </div>
127
125
  `;
128
126
  }
@@ -189,7 +187,7 @@ export class IABookSearchResults extends LitElement {
189
187
  const searchResultBorder = css`var(--searchResultBorder, #adaedc)`;
190
188
  const activeButtonBg = css`(--tertiaryBGColor, #333)`;
191
189
 
192
- return css`
190
+ const mainCSS = css`
193
191
  :host {
194
192
  display: block;
195
193
  height: 100%;
@@ -349,17 +347,6 @@ export class IABookSearchResults extends LitElement {
349
347
  font-size: 1.2rem;
350
348
  }
351
349
 
352
- .loading button {
353
- -webkit-appearance: none;
354
- appearance: none;
355
- padding: .5rem .7rem;
356
- font: normal 1.4rem "Helvetica Neue", Helvetica, Arial, sans-serif;
357
- border: 1px solid #656565;
358
- border-radius: 3px;
359
- cursor: pointer;
360
- background: transparent;
361
- }
362
-
363
350
  ia-activity-indicator {
364
351
  display: block;
365
352
  width: 40px;
@@ -367,5 +354,7 @@ export class IABookSearchResults extends LitElement {
367
354
  margin: 0 auto;
368
355
  }
369
356
  `;
357
+ return [buttonCSS, mainCSS];
370
358
  }
371
359
  }
360
+ customElements.define('ia-book-search-results', IABookSearchResults);
@@ -0,0 +1,27 @@
1
+ import { html } from 'lit-element';
2
+ import '@internetarchive/icon-share/icon-share';
3
+ import '@internetarchive/ia-sharing-options';
4
+
5
+ export default class SharingProvider {
6
+ constructor({
7
+ item,
8
+ baseHost,
9
+ bookreader
10
+ }) {
11
+ const { identifier, creator, title } = item?.metadata;
12
+ const creatorToUse = Array.isArray(creator) ? creator[0] : creator;
13
+ const subPrefix = bookreader.options.subPrefix || '';
14
+ const label = `Share this book`;
15
+ this.icon = html`<ia-icon-share style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-share>`;
16
+ this.label = label;
17
+ this.id = 'share';
18
+ this.component = html`<ia-sharing-options
19
+ .identifier=${identifier}
20
+ .type=${`book`}
21
+ .creator=${creatorToUse}
22
+ .description=${title}
23
+ .baseHost=${baseHost}
24
+ .fileSubPrefix=${subPrefix}
25
+ ></ia-sharing-options>`;
26
+ }
27
+ }