@internetarchive/bookreader 5.0.0-11-multiple-files → 5.0.0-110

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 (389) hide show
  1. package/BookReader/474.js +2 -0
  2. package/BookReader/474.js.map +1 -0
  3. package/BookReader/BookReader.css +616 -1467
  4. package/BookReader/BookReader.js +2 -21564
  5. package/BookReader/BookReader.js.LICENSE.txt +20 -20
  6. package/BookReader/BookReader.js.map +1 -1
  7. package/BookReader/bergamot-translator-worker.js +2966 -0
  8. package/BookReader/bergamot-translator-worker.wasm +0 -0
  9. package/BookReader/hypothesis/LICENSE +50 -0
  10. package/BookReader/hypothesis/README.md +55 -0
  11. package/BookReader/hypothesis/build/boot.js +1 -0
  12. package/BookReader/hypothesis/build/manifest.json +20 -0
  13. package/BookReader/hypothesis/build/scripts/annotator.bundle.js +184 -0
  14. package/BookReader/hypothesis/build/scripts/annotator.bundle.js.map +1 -0
  15. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js +798 -0
  16. package/BookReader/hypothesis/build/scripts/sidebar.bundle.js.map +1 -0
  17. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js +711 -0
  18. package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js.map +1 -0
  19. package/BookReader/hypothesis/build/styles/annotator.css +2235 -0
  20. package/BookReader/hypothesis/build/styles/annotator.css.map +1 -0
  21. package/BookReader/hypothesis/build/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  22. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  23. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  24. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  25. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  26. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
  27. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  28. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
  29. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
  30. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  31. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
  32. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  33. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  34. package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  35. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
  36. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  37. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  38. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  39. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  40. package/BookReader/hypothesis/build/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  41. package/BookReader/hypothesis/build/styles/highlights.css +2 -0
  42. package/BookReader/hypothesis/build/styles/highlights.css.map +1 -0
  43. package/BookReader/hypothesis/build/styles/katex.min.css +2 -0
  44. package/BookReader/hypothesis/build/styles/katex.min.css.map +1 -0
  45. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css +2 -0
  46. package/BookReader/hypothesis/build/styles/pdfjs-overrides.css.map +1 -0
  47. package/BookReader/hypothesis/build/styles/sidebar.css +2731 -0
  48. package/BookReader/hypothesis/build/styles/sidebar.css.map +1 -0
  49. package/BookReader/hypothesis/build/styles/ui-playground.css +2659 -0
  50. package/BookReader/hypothesis/build/styles/ui-playground.css.map +1 -0
  51. package/BookReader/hypothesis/package.json +126 -0
  52. package/BookReader/ia-bookreader-bundle.js +1907 -0
  53. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +19 -0
  54. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  55. package/BookReader/icons/1up.svg +1 -12
  56. package/BookReader/icons/2up.svg +1 -15
  57. package/BookReader/icons/advance.svg +3 -26
  58. package/BookReader/icons/chevron-right.svg +1 -1
  59. package/BookReader/icons/close-circle-dark.svg +1 -0
  60. package/BookReader/icons/close-circle.svg +1 -1
  61. package/BookReader/icons/fullscreen.svg +1 -17
  62. package/BookReader/icons/fullscreen_exit.svg +1 -17
  63. package/BookReader/icons/hamburger.svg +1 -15
  64. package/BookReader/icons/left-arrow.svg +1 -12
  65. package/BookReader/icons/magnify-minus.svg +1 -16
  66. package/BookReader/icons/magnify-plus.svg +1 -17
  67. package/BookReader/icons/magnify.svg +1 -15
  68. package/BookReader/icons/pause.svg +1 -23
  69. package/BookReader/icons/play.svg +1 -22
  70. package/BookReader/icons/playback-speed.svg +1 -34
  71. package/BookReader/icons/read-aloud.svg +1 -22
  72. package/BookReader/icons/review.svg +3 -22
  73. package/BookReader/icons/slider-toggle.svg +1 -0
  74. package/BookReader/icons/thumbnails.svg +1 -17
  75. package/BookReader/icons/voice.svg +1 -0
  76. package/BookReader/icons/volume-full.svg +1 -22
  77. package/BookReader/images/BRicons.svg +5 -94
  78. package/BookReader/images/books_graphic.svg +1 -177
  79. package/BookReader/images/hypothesis.ico +0 -0
  80. package/BookReader/images/icon_book.svg +1 -12
  81. package/BookReader/images/icon_bookmark.svg +1 -12
  82. package/BookReader/images/icon_experiment.svg +1 -0
  83. package/BookReader/images/icon_gear.svg +1 -14
  84. package/BookReader/images/icon_hamburger.svg +1 -20
  85. package/BookReader/images/icon_home.svg +1 -21
  86. package/BookReader/images/icon_info.svg +1 -11
  87. package/BookReader/images/icon_one_page.svg +1 -8
  88. package/BookReader/images/icon_pause.svg +1 -1
  89. package/BookReader/images/icon_play.svg +1 -1
  90. package/BookReader/images/icon_playback-rate.svg +1 -15
  91. package/BookReader/images/icon_search_button.svg +1 -8
  92. package/BookReader/images/icon_share.svg +1 -9
  93. package/BookReader/images/icon_skip-ahead.svg +1 -6
  94. package/BookReader/images/icon_skip-back.svg +2 -13
  95. package/BookReader/images/icon_speaker.svg +1 -18
  96. package/BookReader/images/icon_speaker_open.svg +1 -10
  97. package/BookReader/images/icon_thumbnails.svg +1 -12
  98. package/BookReader/images/icon_toc.svg +1 -5
  99. package/BookReader/images/icon_two_pages.svg +1 -9
  100. package/BookReader/images/marker_chap-off.svg +1 -11
  101. package/BookReader/images/marker_chap-on.svg +1 -11
  102. package/BookReader/images/marker_srch-on.svg +1 -11
  103. package/BookReader/images/translate.svg +1 -0
  104. package/BookReader/images/unviewable_page.png +0 -0
  105. package/BookReader/jquery-3.js +2 -0
  106. package/BookReader/jquery-3.js.LICENSE.txt +24 -0
  107. package/BookReader/plugins/plugin.archive_analytics.js +1 -172
  108. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  109. package/BookReader/plugins/plugin.autoplay.js +1 -165
  110. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  111. package/BookReader/plugins/plugin.chapters.js +19 -301
  112. package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
  113. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  114. package/BookReader/plugins/plugin.experiments.js +3 -0
  115. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  116. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  117. package/BookReader/plugins/plugin.iframe.js +1 -74
  118. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  119. package/BookReader/plugins/plugin.iiif.js +2 -0
  120. package/BookReader/plugins/plugin.iiif.js.map +1 -0
  121. package/BookReader/plugins/plugin.resume.js +1 -368
  122. package/BookReader/plugins/plugin.resume.js.map +1 -1
  123. package/BookReader/plugins/plugin.search.js +2 -1420
  124. package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
  125. package/BookReader/plugins/plugin.search.js.map +1 -1
  126. package/BookReader/plugins/plugin.text_selection.js +2 -1080
  127. package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
  128. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  129. package/BookReader/plugins/plugin.translate.js +137 -0
  130. package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
  131. package/BookReader/plugins/plugin.translate.js.map +1 -0
  132. package/BookReader/plugins/plugin.tts.js +2 -9193
  133. package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
  134. package/BookReader/plugins/plugin.tts.js.map +1 -1
  135. package/BookReader/plugins/plugin.url.js +1 -269
  136. package/BookReader/plugins/plugin.url.js.map +1 -1
  137. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
  138. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  139. package/BookReader/plugins/translator-worker.js +2 -0
  140. package/BookReader/plugins/translator-worker.js.map +1 -0
  141. package/BookReader/silence.mp3 +0 -0
  142. package/BookReader/translator-worker.js +475 -0
  143. package/BookReader/webcomponents-bundle.js +3 -0
  144. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  145. package/BookReader/webcomponents-bundle.js.map +1 -0
  146. package/README.md +14 -3
  147. package/jsconfig.json +19 -0
  148. package/package.json +92 -70
  149. package/src/BookReader/BookModel.js +92 -46
  150. package/src/BookReader/DragScrollable.js +233 -0
  151. package/src/BookReader/ImageCache.js +49 -16
  152. package/src/BookReader/Mode1Up.js +66 -356
  153. package/src/BookReader/Mode1UpLit.js +392 -0
  154. package/src/BookReader/Mode2Up.js +87 -1315
  155. package/src/BookReader/Mode2UpLit.js +788 -0
  156. package/src/BookReader/ModeAbstract.js +43 -0
  157. package/src/BookReader/ModeCoordinateSpace.js +29 -0
  158. package/src/BookReader/ModeSmoothZoom.js +312 -0
  159. package/src/BookReader/ModeThumb.js +30 -16
  160. package/src/BookReader/Navbar/Navbar.js +201 -76
  161. package/src/BookReader/PageContainer.js +120 -23
  162. package/src/BookReader/ReduceSet.js +3 -3
  163. package/src/BookReader/Toolbar/Toolbar.js +19 -41
  164. package/src/BookReader/events.js +3 -3
  165. package/src/BookReader/options.js +94 -17
  166. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  167. package/src/BookReader/utils/ScrollClassAdder.js +31 -0
  168. package/src/BookReader/utils/SelectionObserver.js +45 -0
  169. package/src/BookReader/utils/classes.js +1 -1
  170. package/src/BookReader/utils.js +141 -13
  171. package/src/BookReader.js +711 -1241
  172. package/src/BookReaderPlugin.js +52 -0
  173. package/src/assets/icons/close-circle-dark.svg +1 -0
  174. package/src/assets/icons/magnify-minus.svg +3 -7
  175. package/src/assets/icons/magnify-plus.svg +3 -7
  176. package/src/assets/icons/slider-toggle.svg +1 -0
  177. package/src/assets/icons/voice.svg +1 -0
  178. package/src/assets/images/hypothesis.ico +0 -0
  179. package/src/assets/images/icon_experiment.svg +1 -0
  180. package/src/assets/images/translate.svg +1 -0
  181. package/src/assets/images/unviewable_page.png +0 -0
  182. package/src/assets/silence.mp3 +0 -0
  183. package/src/css/BookReader.scss +1 -17
  184. package/src/css/_BRBookmarks.scss +1 -1
  185. package/src/css/_BRComponent.scss +1 -1
  186. package/src/css/_BRicon.scss +8 -2
  187. package/src/css/_BRmain.scss +33 -27
  188. package/src/css/_BRnav.scss +74 -70
  189. package/src/css/_BRpages.scss +171 -42
  190. package/src/css/_BRsearch.scss +69 -235
  191. package/src/css/_BRtoolbar.scss +5 -5
  192. package/src/css/_TextSelection.scss +129 -24
  193. package/src/css/_colorbox.scss +2 -2
  194. package/src/css/_controls.scss +24 -7
  195. package/src/css/_icons.scss +14 -1
  196. package/src/{BookNavigator/assets → css}/button-base.js +10 -3
  197. package/src/css/icon_checkmark.js +9 -0
  198. package/src/css/sharedStyles.js +15 -0
  199. package/src/ia-bookreader/downloads/downloads-provider.js +81 -0
  200. package/src/{BookNavigator → ia-bookreader}/downloads/downloads.js +29 -25
  201. package/src/ia-bookreader/ia-bookreader.js +666 -0
  202. package/src/ia-bookreader/sharing.js +27 -0
  203. package/src/ia-bookreader/viewable-files.js +98 -0
  204. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments-provider.js +17 -17
  205. package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments.js +75 -67
  206. package/src/{BookNavigator → plugins}/bookmarks/bookmark-button.js +4 -3
  207. package/src/{BookNavigator/assets → plugins/bookmarks}/bookmark-colors.js +1 -1
  208. package/src/{BookNavigator → plugins}/bookmarks/bookmark-edit.js +44 -32
  209. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
  210. package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +5 -10
  211. package/src/plugins/bookmarks/bookmarks-provider.js +63 -0
  212. package/src/{BookNavigator → plugins/bookmarks}/delete-modal-actions.js +1 -1
  213. package/src/{BookNavigator → plugins}/bookmarks/ia-bookmarks.js +117 -68
  214. package/src/plugins/plugin.archive_analytics.js +84 -78
  215. package/src/plugins/plugin.autoplay.js +99 -104
  216. package/src/plugins/plugin.chapters.js +310 -201
  217. package/src/plugins/plugin.experiments.js +321 -0
  218. package/src/plugins/plugin.iframe.js +1 -1
  219. package/src/plugins/plugin.iiif.js +141 -0
  220. package/src/plugins/plugin.resume.js +53 -50
  221. package/src/plugins/plugin.text_selection.js +522 -219
  222. package/src/plugins/plugin.vendor-fullscreen.js +7 -7
  223. package/src/plugins/search/plugin.search.js +380 -360
  224. package/src/{BookNavigator → plugins}/search/search-provider.js +94 -32
  225. package/src/{BookNavigator → plugins}/search/search-results.js +108 -90
  226. package/src/plugins/search/utils.js +50 -0
  227. package/src/plugins/search/view.js +79 -210
  228. package/src/plugins/translate/TranslationManager.js +164 -0
  229. package/src/plugins/translate/plugin.translate.js +512 -0
  230. package/src/plugins/tts/AbstractTTSEngine.js +78 -49
  231. package/src/plugins/tts/FestivalTTSEngine.js +21 -31
  232. package/src/plugins/tts/PageChunk.js +33 -21
  233. package/src/plugins/tts/PageChunkIterator.js +11 -17
  234. package/src/plugins/tts/WebTTSEngine.js +131 -91
  235. package/src/plugins/tts/plugin.tts.js +345 -350
  236. package/src/plugins/tts/utils.js +77 -49
  237. package/src/plugins/url/UrlPlugin.js +191 -0
  238. package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
  239. package/src/util/TextSelectionManager.js +282 -0
  240. package/src/util/browserSniffing.js +33 -1
  241. package/src/util/cache.js +20 -0
  242. package/src/util/docCookies.js +21 -2
  243. package/src/util/lit.js +15 -0
  244. package/src/util/strings.js +1 -0
  245. package/.babelrc +0 -12
  246. package/.dependabot/config.yml +0 -6
  247. package/.eslintrc.js +0 -49
  248. package/.gitattributes +0 -2
  249. package/.github/ISSUE_TEMPLATE/bug.md +0 -32
  250. package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
  251. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
  252. package/.github/workflows/node.js.yml +0 -28
  253. package/.github/workflows/npm-publish.yml +0 -47
  254. package/.testcaferc.json +0 -5
  255. package/BookReader/bookreader-component-bundle.js +0 -14330
  256. package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
  257. package/BookReader/bookreader-component-bundle.js.map +0 -1
  258. package/BookReader/icons/sort-ascending.svg +0 -1
  259. package/BookReader/icons/sort-descending.svg +0 -1
  260. package/BookReader/jquery-1.10.1.js +0 -108
  261. package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
  262. package/BookReader/plugins/plugin.menu_toggle.js +0 -369
  263. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  264. package/BookReader/plugins/plugin.mobile_nav.js +0 -335
  265. package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
  266. package/BookReaderDemo/BookReaderDemo.css +0 -41
  267. package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
  268. package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
  269. package/BookReaderDemo/BookReaderJSSimple.js +0 -55
  270. package/BookReaderDemo/IIIFBookReader.js +0 -207
  271. package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
  272. package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
  273. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
  274. package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
  275. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
  276. package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
  277. package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
  278. package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
  279. package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
  280. package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
  281. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
  282. package/BookReaderDemo/demo-advanced.html +0 -33
  283. package/BookReaderDemo/demo-autoplay.html +0 -38
  284. package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
  285. package/BookReaderDemo/demo-embed.html +0 -26
  286. package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
  287. package/BookReaderDemo/demo-fullscreen.html +0 -33
  288. package/BookReaderDemo/demo-iiif.html +0 -34
  289. package/BookReaderDemo/demo-iiif.js +0 -26
  290. package/BookReaderDemo/demo-internetarchive.html +0 -74
  291. package/BookReaderDemo/demo-multiple.html +0 -43
  292. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  293. package/BookReaderDemo/demo-preview-pages.html +0 -1092
  294. package/BookReaderDemo/demo-simple.html +0 -34
  295. package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
  296. package/BookReaderDemo/immersion-1up.html +0 -64
  297. package/BookReaderDemo/immersion-mode.html +0 -35
  298. package/BookReaderDemo/toggle_controls.html +0 -53
  299. package/BookReaderDemo/view_mode.html +0 -39
  300. package/BookReaderDemo/viewmode-cycle.html +0 -41
  301. package/CHANGELOG.md +0 -476
  302. package/CONTRIBUTING.md +0 -7
  303. package/codecov.yml +0 -17
  304. package/index.html +0 -31
  305. package/karma.conf.js +0 -23
  306. package/screenshot.png +0 -0
  307. package/scripts/postversion.js +0 -10
  308. package/scripts/preversion.js +0 -14
  309. package/scripts/version.js +0 -26
  310. package/src/BookNavigator/BookModel.js +0 -14
  311. package/src/BookNavigator/BookNavigator.js +0 -451
  312. package/src/BookNavigator/assets/book-loader.js +0 -27
  313. package/src/BookNavigator/assets/icon_checkmark.js +0 -6
  314. package/src/BookNavigator/assets/icon_close.js +0 -3
  315. package/src/BookNavigator/assets/icon_sort_ascending.js +0 -5
  316. package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
  317. package/src/BookNavigator/bookmarks/bookmarks-provider.js +0 -53
  318. package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
  319. package/src/BookNavigator/downloads/downloads-provider.js +0 -66
  320. package/src/BookNavigator/search/a-search-result.js +0 -55
  321. package/src/BookNavigator/volumes/volumes-provider.js +0 -75
  322. package/src/BookNavigator/volumes/volumes.js +0 -161
  323. package/src/BookReader/DebugConsole.js +0 -54
  324. package/src/BookReaderComponent/BookReaderComponent.js +0 -112
  325. package/src/ItemNavigator/ItemNavigator.js +0 -372
  326. package/src/ItemNavigator/providers/sharing.js +0 -29
  327. package/src/assets/icons/sort-ascending.svg +0 -1
  328. package/src/assets/icons/sort-descending.svg +0 -1
  329. package/src/css/_MobileNav.scss +0 -194
  330. package/src/dragscrollable-br.js +0 -261
  331. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  332. package/src/plugins/plugin.mobile_nav.js +0 -287
  333. package/tests/BookReader/BookModel.test.js +0 -312
  334. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  335. package/tests/BookReader/DebugConsole.test.js +0 -25
  336. package/tests/BookReader/ImageCache.test.js +0 -150
  337. package/tests/BookReader/Mode1Up.test.js +0 -164
  338. package/tests/BookReader/Mode2Up.test.js +0 -247
  339. package/tests/BookReader/Navbar/Navbar.test.js +0 -169
  340. package/tests/BookReader/PageContainer.test.js +0 -115
  341. package/tests/BookReader/ReduceSet.test.js +0 -38
  342. package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
  343. package/tests/BookReader/utils/classes.test.js +0 -88
  344. package/tests/BookReader/utils.test.js +0 -109
  345. package/tests/BookReader.options.test.js +0 -39
  346. package/tests/BookReader.test.js +0 -301
  347. package/tests/e2e/README.md +0 -75
  348. package/tests/e2e/autoplay.test.js +0 -13
  349. package/tests/e2e/base.test.js +0 -35
  350. package/tests/e2e/helpers/base.js +0 -258
  351. package/tests/e2e/helpers/debug.js +0 -13
  352. package/tests/e2e/helpers/desktopSearch.js +0 -72
  353. package/tests/e2e/helpers/mobileSearch.js +0 -85
  354. package/tests/e2e/helpers/mockSearch.js +0 -93
  355. package/tests/e2e/helpers/rightToLeft.js +0 -29
  356. package/tests/e2e/ia-production/ia-prod-base.js +0 -17
  357. package/tests/e2e/models/BookReader.js +0 -11
  358. package/tests/e2e/models/Navigation.js +0 -56
  359. package/tests/e2e/rightToLeft.test.js +0 -20
  360. package/tests/e2e/viewmode.test.js +0 -37
  361. package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
  362. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
  363. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
  364. package/tests/karma/BookNavigator/search-results.test.js +0 -240
  365. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
  366. package/tests/karma/BookNavigator/volumes.test.js +0 -133
  367. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
  368. package/tests/plugins/plugin.archive_analytics.test.js +0 -23
  369. package/tests/plugins/plugin.autoplay.test.js +0 -52
  370. package/tests/plugins/plugin.chapters.test.js +0 -130
  371. package/tests/plugins/plugin.iframe.test.js +0 -42
  372. package/tests/plugins/plugin.mobile_nav.test.js +0 -66
  373. package/tests/plugins/plugin.resume.test.js +0 -98
  374. package/tests/plugins/plugin.text_selection.test.js +0 -203
  375. package/tests/plugins/plugin.url.test.js +0 -129
  376. package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
  377. package/tests/plugins/search/plugin.search.test.js +0 -166
  378. package/tests/plugins/search/plugin.search.view.test.js +0 -106
  379. package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
  380. package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
  381. package/tests/plugins/tts/PageChunk.test.js +0 -57
  382. package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
  383. package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
  384. package/tests/plugins/tts/utils.test.js +0 -133
  385. package/tests/util/browserSniffing.test.js +0 -56
  386. package/tests/util/docCookies.test.js +0 -15
  387. package/tests/util/strings.test.js +0 -63
  388. package/tests/utils.js +0 -42
  389. package/webpack.config.js +0 -86
@@ -1,7 +1,10 @@
1
- import { html } from 'lit-element';
2
- import { nothing } from 'lit-html';
3
-
4
- import './search-results';
1
+ // @ts-check
2
+ import { html, nothing } from 'lit';
3
+ import '@internetarchive/icon-search/icon-search.js';
4
+ import './search-results.js';
5
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideMatch} SearchInsideMatch */
6
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideResults} SearchInsideResults */
7
+ /** @typedef {import('@/src/BookReader.js').default} BookReader */
5
8
 
6
9
  let searchState = {
7
10
  query: '',
@@ -10,8 +13,11 @@ let searchState = {
10
13
  queryInProgress: false,
11
14
  errorMessage: '',
12
15
  };
13
- export default class {
14
- constructor(onSearchChange = () => {}, brInstance) {
16
+ export default class SearchProvider {
17
+ constructor({
18
+ onProviderChange,
19
+ bookreader,
20
+ }) {
15
21
  /* search menu events */
16
22
  this.onBookSearchInitiated = this.onBookSearchInitiated.bind(this);
17
23
  /* bookreader search events */
@@ -20,16 +26,22 @@ export default class {
20
26
  this.onSearchResultsClicked = this.onSearchResultsClicked.bind(this);
21
27
  this.onSearchResultsChange = this.onSearchResultsChange.bind(this);
22
28
  this.onSearchResultsCleared = this.onSearchResultsCleared.bind(this);
29
+ this.searchCanceledInMenu = this.searchCanceledInMenu.bind(this);
30
+
23
31
  /* class methods */
24
32
  this.bindEventListeners = this.bindEventListeners.bind(this);
25
33
  this.getMenuDetails = this.getMenuDetails.bind(this);
26
34
  this.getComponent = this.getComponent.bind(this);
27
- this.advanceToPage = this.advanceToPage.bind(this);
28
35
  this.updateMenu = this.updateMenu.bind(this);
29
36
 
30
- this.onSearchChange = onSearchChange;
31
- this.bookreader = brInstance;
32
- this.icon = html`<ia-icon icon="search" style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon>`;
37
+ this.onProviderChange = onProviderChange;
38
+ /** @type {import('@/src/BookReader.js').default} */
39
+ this.bookreader = bookreader;
40
+ this.icon = html`
41
+ <ia-icon-search
42
+ aria-hidden="true" role="presentation"
43
+ style="width: var(--iconWidth); height: var(--iconHeight);"
44
+ ></ia-icon-search>`;
33
45
  this.label = 'Search inside';
34
46
  this.menuDetails = this.getMenuDetails();
35
47
  this.id = 'search';
@@ -39,7 +51,7 @@ export default class {
39
51
 
40
52
  getMenuDetails() {
41
53
  const { resultsCount, query, queryInProgress } = searchState;
42
- if (queryInProgress || !query) { return nothing }
54
+ if (queryInProgress || !query) { return nothing; }
43
55
  const unit = resultsCount === 1 ? 'result' : 'results';
44
56
  return html`(${resultsCount} ${unit})`;
45
57
  }
@@ -47,14 +59,40 @@ export default class {
47
59
  bindEventListeners() {
48
60
  window.addEventListener('BookReader:SearchStarted', this.onSearchStarted);
49
61
  window.addEventListener('BookReader:SearchCallback', this.onSearchResultsChange);
50
- window.addEventListener('BookReader:SearchCallbackEmpty', (event) => { this.onSearchRequestError(event, 'noResults') });
51
- window.addEventListener('BookReader:SearchCallbackNotIndexed', (event) => { this.onSearchRequestError(event, 'notIndexed') });
52
- window.addEventListener('BookReader:SearchCallbackError', (event) => { this.onSearchRequestError(event) });
53
- window.addEventListener('BookReader:SearchResultsCleared', () => { this.onSearchResultsCleared() });
62
+ window.addEventListener('BookReader:SearchCallbackEmpty', (event) => { this.onSearchRequestError(event, 'noResults'); });
63
+ window.addEventListener('BookReader:SearchCallbackNotIndexed', (event) => { this.onSearchRequestError(event, 'notIndexed'); });
64
+ window.addEventListener('BookReader:SearchCallbackError', (event) => { this.onSearchRequestError(event); });
65
+ window.addEventListener('BookReader:SearchResultsCleared', () => { this.onSearchResultsCleared(); });
66
+ window.addEventListener('BookReader:SearchCanceled', (e) => { this.onSearchCanceled(e); });
67
+ }
68
+
69
+ /**
70
+ * Cancel search handler
71
+ * resets `searchState`
72
+ */
73
+ onSearchCanceled() {
74
+ searchState = {
75
+ query: '',
76
+ results: [],
77
+ resultsCount: 0,
78
+ queryInProgress: false,
79
+ errorMessage: '',
80
+ };
81
+ const updateMenuFor = {
82
+ searchCanceled: true,
83
+ };
84
+ this.updateMenu(updateMenuFor);
85
+
86
+ if (this.bookreader.urlPlugin) {
87
+ this.updateSearchInUrl();
88
+ }
54
89
  }
55
90
 
56
91
  onSearchStarted(e) {
57
- const { term = '' } = e.detail.props;
92
+ const { term = '', instance } = e.detail.props;
93
+ if (instance) {
94
+ this.bookreader = instance;
95
+ }
58
96
  searchState.query = term;
59
97
  searchState.results = [];
60
98
  searchState.resultsCount = 0;
@@ -68,21 +106,25 @@ export default class {
68
106
  this.bookreader.search(searchState.query);
69
107
  }
70
108
 
109
+ /**
110
+ * @param {CustomEvent<{props: {instance: BookReader, results: SearchInsideResults}}>} event
111
+ */
71
112
  onSearchRequestError(event, errorType = 'default') {
72
- const { detail: { props = {} } } = event;
73
- const { instance = null } = props;
113
+ const { detail: { props } } = event;
114
+ const { instance, results } = props;
74
115
  if (instance) {
75
- /* keep bookreader instance reference up-to-date */
116
+ /** @type {BookReader} keep bookreader instance reference up-to-date */
76
117
  this.bookreader = instance;
77
118
  }
78
119
  const errorMessages = {
79
120
  noResults: '0 results',
80
121
  notIndexed: `This book hasn't been indexed for searching yet. We've just started indexing it,
81
122
  so search should be available soon. Please try again later. Thanks!`,
82
- default: 'Sorry, there was an error with your search. The text may still be processing.',
123
+ default: 'Sorry, there was an error with your search. Please try again.',
83
124
  };
84
125
 
85
126
  const messageToShow = errorMessages[errorType] ?? errorMessages.default;
127
+ searchState.query = results?.q || '';
86
128
  searchState.results = [];
87
129
  searchState.resultsCount = 0;
88
130
  searchState.queryInProgress = false;
@@ -104,6 +146,10 @@ export default class {
104
146
  this.updateMenu();
105
147
  }
106
148
 
149
+ searchCanceledInMenu() {
150
+ this.bookreader.plugins.search.cancelSearchRequest();
151
+ }
152
+
107
153
  onSearchResultsCleared() {
108
154
  searchState = {
109
155
  query: '',
@@ -111,15 +157,34 @@ export default class {
111
157
  resultsCount: 0,
112
158
  queryInProgress: false,
113
159
  errorMessage: '',
160
+ };
161
+ this.updateMenu({ openMenu: false });
162
+ this.bookreader.plugins.search.searchView.clearSearchFieldAndResults(false);
163
+ if (this.bookreader.urlPlugin) {
164
+ this.updateSearchInUrl();
165
+ }
166
+ }
167
+
168
+ /** update URL `q=<term>` query param in URL */
169
+ updateSearchInUrl() {
170
+ if (this.bookreader.urlPlugin) {
171
+ this.bookreader.urlPlugin.pullFromAddressBar();
172
+ if (searchState.query) {
173
+ this.bookreader.urlPlugin.setUrlParam('q', searchState.query);
174
+ } else {
175
+ this.bookreader.urlPlugin.removeUrlParam('q');
176
+ }
114
177
  }
115
- this.updateMenu();
116
- this.bookreader?.searchView?.clearSearchFieldAndResults();
117
178
  }
118
179
 
119
- updateMenu() {
180
+ /**
181
+ * Relays how to update side menu given the context of a search update
182
+ @param {{searchCanceled: boolean}} searchUpdates
183
+ */
184
+ updateMenu(searchUpdates = {}) {
120
185
  this.menuDetails = this.getMenuDetails();
121
186
  this.component = this.getComponent();
122
- this.onSearchChange(this.bookreader);
187
+ this.onProviderChange(this.bookreader, searchUpdates);
123
188
  }
124
189
 
125
190
  getComponent() {
@@ -134,18 +199,15 @@ export default class {
134
199
  @resultSelected=${this.onSearchResultsClicked}
135
200
  @bookSearchInitiated=${this.onBookSearchInitiated}
136
201
  @bookSearchResultsCleared=${this.onSearchResultsCleared}
202
+ @bookSearchCanceled=${this.searchCanceledInMenu}
137
203
  ></ia-book-search-results>
138
204
  `;
139
205
  }
140
206
 
207
+ /**
208
+ * @param {{ detail: {match: SearchInsideMatch} }} param0
209
+ */
141
210
  onSearchResultsClicked({ detail }) {
142
- const page = detail.match.par[0].page;
143
- this.advanceToPage(page);
144
- }
145
-
146
- advanceToPage(leaf) {
147
- const page = this.bookreader.leafNumToIndex(leaf);
148
- this.bookreader._searchPluginGoToResult(page);
149
- this.bookreader.updateSearchHilites();
211
+ this.bookreader.plugins.search.jumpToMatch(detail.match.matchIndex);
150
212
  }
151
213
  }
@@ -1,11 +1,17 @@
1
1
  /* eslint-disable class-methods-use-this */
2
- import { nothing } from 'lit-html';
3
- import { css, html, LitElement } from 'lit-element';
4
- import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
5
- import './a-search-result.js';
6
- import checkmarkIcon from '../assets/icon_checkmark.js';
7
- import closeIcon from '../assets/icon_close.js';
8
-
2
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
3
+ import { css, html, LitElement, nothing } from 'lit';
4
+ import '@internetarchive/ia-activity-indicator';
5
+ import checkmarkIconTemplate from '../../css/icon_checkmark.js';
6
+ import closeIconTemplate from '@internetarchive/icon-close/index.js';
7
+ import buttonCSS from '../../css/button-base.js';
8
+ import { ifDefined } from 'lit/directives/if-defined.js';
9
+ import { sharedStyles } from '../../css/sharedStyles.js';
10
+ import { svgToDataUrl } from '../../util/lit.js';
11
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideMatch} SearchInsideMatch */
12
+
13
+ const checkmarkIconData = svgToDataUrl(checkmarkIconTemplate);
14
+ const closeIconData = svgToDataUrl(closeIconTemplate);
9
15
 
10
16
  export class IABookSearchResults extends LitElement {
11
17
  static get properties() {
@@ -15,7 +21,6 @@ export class IABookSearchResults extends LitElement {
15
21
  queryInProgress: { type: Boolean },
16
22
  renderHeader: { type: Boolean },
17
23
  renderSearchAllFiles: { type: Boolean },
18
- displayResultImages: { type: Boolean },
19
24
  errorMessage: { type: String },
20
25
  };
21
26
  }
@@ -23,12 +28,12 @@ export class IABookSearchResults extends LitElement {
23
28
  constructor() {
24
29
  super();
25
30
 
31
+ /** @type {SearchInsideMatch[]} */
26
32
  this.results = [];
27
33
  this.query = '';
28
34
  this.queryInProgress = false;
29
35
  this.renderHeader = false;
30
- this.renderSearchAllFields = false;
31
- this.displayResultImages = false;
36
+ this.renderSearchAllFiles = false;
32
37
  this.errorMessage = '';
33
38
 
34
39
  this.bindBookReaderListeners();
@@ -60,6 +65,9 @@ export class IABookSearchResults extends LitElement {
60
65
 
61
66
  setQuery(e) {
62
67
  this.query = e.currentTarget.value;
68
+ if (!this.query) {
69
+ this.cancelSearch();
70
+ }
63
71
  }
64
72
 
65
73
  performSearch(e) {
@@ -77,7 +85,15 @@ export class IABookSearchResults extends LitElement {
77
85
  }));
78
86
  }
79
87
 
80
- selectResult() {
88
+ /**
89
+ * @param {SearchInsideMatch} match
90
+ */
91
+ selectResult(match) {
92
+ this.dispatchEvent(new CustomEvent('resultSelected', {
93
+ bubbles: true,
94
+ composed: true,
95
+ detail: { match },
96
+ }));
81
97
  this.dispatchEvent(new CustomEvent('closeMenu', {
82
98
  bubbles: true,
83
99
  composed: true,
@@ -90,21 +106,18 @@ export class IABookSearchResults extends LitElement {
90
106
  }
91
107
 
92
108
  dispatchSearchCanceled() {
93
- this.dispatchEvent(new CustomEvent('bookSearchCanceled', {
94
- bubbles: true,
95
- composed: true,
96
- }));
109
+ this.dispatchEvent(new Event('bookSearchCanceled'));
97
110
  }
98
111
 
99
112
  get resultsCount() {
100
113
  const count = this.results.length;
101
- return count ? html`<p>(${count} result${count > 1 ? 's' : ''})</p>` : nothing;
114
+ return count ? `${count} result${count > 1 ? 's' : ''}` : nothing;
102
115
  }
103
116
 
104
117
  get headerSection() {
105
118
  const header = html`<header>
106
119
  <h3>Search inside</h3>
107
- ${this.resultsCount}
120
+ ${this.resultsCount ? html`(${this.resultsCount})` : nothing}
108
121
  </header>`;
109
122
  return this.renderHeader ? header : nothing;
110
123
  }
@@ -120,40 +133,45 @@ export class IABookSearchResults extends LitElement {
120
133
  get loadingIndicator() {
121
134
  return html`
122
135
  <div class="loading">
123
- <ia-activity-indicator mode="processing"></ia-activity-indicator>
136
+ <ia-activity-indicator mode="processing" aria-hidden="true" role="presentation"></ia-activity-indicator>
124
137
  <p>Searching</p>
138
+ <button class="ia-button external cancel-search" @click=${this.cancelSearch}>Cancel</button>
125
139
  </div>
126
140
  `;
127
141
  }
128
142
 
129
143
  get resultsSet() {
130
- const resultsClass = this.displayResultImages ? 'show-image' : '';
131
144
  return html`
132
- <ul class="results ${resultsClass}">
145
+ <nav aria-label="Search results">
146
+ <div>
147
+ ${this.resultsCount}
148
+ <a
149
+ href="#"
150
+ class="skip-link"
151
+ @click=${(e) => {
152
+ e.preventDefault();
153
+ this.shadowRoot.querySelector('.results li:last-child .result-item').focus();
154
+ }}
155
+ >Skip to last result</a>
156
+ </div>
157
+ <ul class="results">
133
158
  ${this.results.map(match => html`
134
- <book-search-result
135
- .match=${match}
136
- @resultSelected=${this.selectResult}
137
- ></book-search-result>
159
+ <li>
160
+ <button class="result-item" @click=${this.selectResult.bind(this, match)}>
161
+ <span class="page-num">Page ${match.displayPageNumber}</span> — <span lang=${ifDefined(match.lang)}>${unsafeHTML(match.html)}</span>
162
+ </button>
163
+ </li>
138
164
  `)}
139
165
  </ul>
140
- `;
141
- }
142
-
143
- get searchForm() {
144
- return html`
145
- <form action="" method="get" @submit=${this.performSearch}>
146
- <fieldset>
147
- ${this.searchMultipleControls}
148
- <input
149
- type="search"
150
- name="query"
151
- alt="Search inside this book."
152
- @keyup=${this.setQuery}
153
- .value=${this.query}
154
- />
155
- </fieldset>
156
- </form>
166
+ <a
167
+ href="#"
168
+ class="skip-link"
169
+ @click=${(e) => {
170
+ e.preventDefault();
171
+ this.shadowRoot.querySelector('.results li:first-child .result-item').focus();
172
+ }}
173
+ >Skip to first result</a>
174
+ </nav>
157
175
  `;
158
176
  }
159
177
 
@@ -163,21 +181,29 @@ export class IABookSearchResults extends LitElement {
163
181
  `;
164
182
  }
165
183
 
166
- get searchCTA() {
167
- return html`<p class="search-cta"><em>Please enter text to search for</em></p>`;
168
- }
169
-
170
184
  render() {
171
185
  const showSearchCTA = (!this.queryInProgress && !this.errorMessage)
172
186
  && (!this.queryInProgress && !this.results.length);
173
187
  return html`
174
188
  ${this.headerSection}
175
- ${this.searchForm}
176
- <div class="results-container">
189
+ <form action="" method="get" @submit=${this.performSearch}>
190
+ ${this.searchMultipleControls}
191
+ <input
192
+ type="search"
193
+ name="query"
194
+ id="br-search-input"
195
+ @keyup=${this.setQuery}
196
+ @search=${this.setQuery}
197
+ .value=${this.query}
198
+ />
199
+ <label class="search-cta ${showSearchCTA ? '' : 'sr-only'}" for="br-search-input">
200
+ Please enter text to search for
201
+ </label>
202
+ </form>
203
+ <div class="results-container" aria-live="polite">
177
204
  ${this.queryInProgress ? this.loadingIndicator : nothing}
178
205
  ${this.errorMessage ? this.setErrorMessage : nothing}
179
206
  ${this.results.length ? this.resultsSet : nothing}
180
- ${showSearchCTA ? this.searchCTA : nothing}
181
207
  </div>
182
208
  `;
183
209
  }
@@ -188,7 +214,7 @@ export class IABookSearchResults extends LitElement {
188
214
  const searchResultBorder = css`var(--searchResultBorder, #adaedc)`;
189
215
  const activeButtonBg = css`(--tertiaryBGColor, #333)`;
190
216
 
191
- return css`
217
+ const mainCSS = css`
192
218
  :host {
193
219
  display: block;
194
220
  height: 100%;
@@ -198,6 +224,15 @@ export class IABookSearchResults extends LitElement {
198
224
  box-sizing: border-box;
199
225
  }
200
226
 
227
+ .skip-link {
228
+ position: absolute;
229
+ left: -9999px;
230
+ }
231
+ .skip-link:focus {
232
+ position: static;
233
+ left: auto;
234
+ }
235
+
201
236
  mark {
202
237
  padding: 0 .2rem;
203
238
  color: ${searchResultText};
@@ -225,9 +260,8 @@ export class IABookSearchResults extends LitElement {
225
260
  font-style: italic;
226
261
  }
227
262
 
228
- fieldset {
263
+ form {
229
264
  padding: 0 0 1rem 0;
230
- border: none;
231
265
  }
232
266
 
233
267
  [type="checkbox"] {
@@ -255,7 +289,7 @@ export class IABookSearchResults extends LitElement {
255
289
  border-radius: 2px;
256
290
  }
257
291
  :checked + label.checkbox:after {
258
- background-image: url('${checkmarkIcon}');
292
+ background-image: url('${checkmarkIconData}');
259
293
  }
260
294
 
261
295
  label.checkbox[for="all_files"]:after {
@@ -269,7 +303,7 @@ export class IABookSearchResults extends LitElement {
269
303
  -webkit-appearance: textfield;
270
304
  width: 100%;
271
305
  height: 3rem;
272
- padding: 0 1.5rem;
306
+ padding: 0 10px;
273
307
  box-sizing: border-box;
274
308
  font: normal 1.6rem "Helvetica qNeue", Helvetica, Arial, sans-serif;
275
309
  border-radius: 1.5rem;
@@ -281,22 +315,25 @@ export class IABookSearchResults extends LitElement {
281
315
  [type="search"]::-webkit-search-cancel-button {
282
316
  width: 18px;
283
317
  height: 18px;
318
+ margin-right: -5px;
284
319
  -webkit-appearance: none;
285
320
  appearance: none;
286
- -webkit-mask: url('${closeIcon}') 0 0 no-repeat;
287
- mask: url('${closeIcon}') 0 0 no-repeat;
321
+ -webkit-mask: url('${closeIconData}') 0 0 no-repeat;
322
+ mask: url('${closeIconData}') 0 0 no-repeat;
288
323
  -webkit-mask-size: 100%;
289
324
  mask-size: 100%;
290
325
  background: #fff;
291
326
  }
292
327
 
293
- p.page-num {
328
+ .page-num {
294
329
  font-weight: bold;
295
330
  padding-bottom: 0;
296
331
  }
297
332
 
298
- p.search-cta {
333
+ .search-cta {
334
+ padding: 10px 0;
299
335
  text-align: center;
336
+ font-style: italic;
300
337
  }
301
338
 
302
339
  .results-container {
@@ -309,33 +346,24 @@ export class IABookSearchResults extends LitElement {
309
346
  list-style: none;
310
347
  }
311
348
 
312
- ul.show-image li {
313
- display: grid;
314
- }
315
-
316
- li {
349
+ .result-item {
317
350
  cursor: pointer;
318
- grid-template-columns: 30px 1fr;
319
- grid-gap: 0 .5rem;
320
- }
321
-
322
- li img {
351
+ margin-top: 8px;
352
+ font-size: 12px;
353
+ padding: 5px;
354
+ border-radius: 4px;
323
355
  display: block;
324
356
  width: 100%;
357
+ /* Reset button styles */
358
+ background: none;
359
+ border: none;
360
+ text-align: left;
361
+ font-family: inherit;
362
+ transition: background-color 0.2s;
325
363
  }
326
364
 
327
- li h4 {
328
- grid-column: 2 / 3;
329
- padding: 0 0 2rem 0;
330
- margin: 0;
331
- font-weight: normal;
332
- }
333
-
334
- li p {
335
- grid-column: 2 / 3;
336
- padding: 0 0 1.5rem 0;
337
- margin: 0;
338
- font-size: 1.2rem;
365
+ .result-item:hover {
366
+ background-color: rgba(255, 255, 255, 0.1);
339
367
  }
340
368
 
341
369
  .loading {
@@ -348,17 +376,6 @@ export class IABookSearchResults extends LitElement {
348
376
  font-size: 1.2rem;
349
377
  }
350
378
 
351
- .loading button {
352
- -webkit-appearance: none;
353
- appearance: none;
354
- padding: .5rem .7rem;
355
- font: normal 1.4rem "Helvetica Neue", Helvetica, Arial, sans-serif;
356
- border: 1px solid #656565;
357
- border-radius: 3px;
358
- cursor: pointer;
359
- background: transparent;
360
- }
361
-
362
379
  ia-activity-indicator {
363
380
  display: block;
364
381
  width: 40px;
@@ -366,6 +383,7 @@ export class IABookSearchResults extends LitElement {
366
383
  margin: 0 auto;
367
384
  }
368
385
  `;
386
+ return [sharedStyles, buttonCSS, mainCSS];
369
387
  }
370
388
  }
371
389
  customElements.define('ia-book-search-results', IABookSearchResults);
@@ -0,0 +1,50 @@
1
+ // @ts-check
2
+ import { escapeHTML, escapeRegExp } from '../../BookReader/utils.js';
3
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideResults} SearchInsideResults */
4
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').LeafNum} LeafNum */
5
+ /** @typedef {import('@/src/plugins/search/plugin.search.js').PageNumString} PageNumString */
6
+
7
+ /**
8
+ * @param {string} match
9
+ * @param {string} preTag
10
+ * @param {string} postTag
11
+ * @returns {string}
12
+ */
13
+ export function renderMatch(match, preTag, postTag) {
14
+ // Search results are returned as a text blob with the hits wrapped in
15
+ // triple mustaches. Hits occasionally include text beyond the search
16
+ // term, so everything within the staches is captured and wrapped.
17
+ const preTagRe = escapeRegExp(escapeHTML(preTag));
18
+ const postTagRe = escapeRegExp(escapeHTML(postTag));
19
+ // [^] matches any character, including line breaks
20
+ const regex = new RegExp(`${preTagRe}([^]+?)${postTagRe}`, 'g');
21
+ return escapeHTML(match)
22
+ .replace(regex, '<mark>$1</mark>')
23
+ // Fix trailing hyphens. This over-corrects but is net useful.
24
+ .replace(/(\b)- /g, '$1');
25
+ }
26
+
27
+ /**
28
+ * Attach some fields to search inside results
29
+ * @param {SearchInsideResults} results
30
+ * @param {(pageNum: LeafNum) => PageNumString} displayPageNumberFn
31
+ * @param {string} preTag
32
+ * @param {string} postTag
33
+ * @param {string | null} bookLanguage The ISO 639-1 language code of the book
34
+ */
35
+ export function marshallSearchResults(results, displayPageNumberFn, preTag, postTag, bookLanguage) {
36
+ // Attach matchIndex to a few things to make it easier to identify
37
+ // an active/selected match
38
+
39
+ for (const [index, match] of results.matches.entries()) {
40
+ match.matchIndex = index;
41
+ match.displayPageNumber = displayPageNumberFn(match.par[0].page);
42
+ match.html = renderMatch(match.text, preTag, postTag);
43
+ match.lang = bookLanguage;
44
+ for (const par of match.par) {
45
+ for (const box of par.boxes) {
46
+ box.matchIndex = index;
47
+ }
48
+ }
49
+ }
50
+ }