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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (389) 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 +1 -1
  8. package/BookReader/BookReader.js.LICENSE.txt +45 -0
  9. package/BookReader/BookReader.js.map +1 -1
  10. package/BookReader/ia-bookreader-bundle.js +1458 -0
  11. package/BookReader/{bookreader-component-bundle.js.LICENSE.txt → ia-bookreader-bundle.js.LICENSE.txt} +10 -9
  12. package/BookReader/ia-bookreader-bundle.js.map +1 -0
  13. package/BookReader/icons/close-circle-dark.svg +1 -0
  14. package/BookReader/icons/voice.svg +1 -0
  15. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  16. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  17. package/BookReader/plugins/plugin.autoplay.js +1 -1
  18. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  19. package/BookReader/plugins/plugin.chapters.js +1 -1
  20. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  21. package/BookReader/plugins/plugin.iframe.js +1 -1
  22. package/BookReader/plugins/plugin.iframe.js.map +1 -1
  23. package/BookReader/plugins/plugin.mobile_nav.js +1 -1
  24. package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
  25. package/BookReader/plugins/plugin.resume.js +1 -1
  26. package/BookReader/plugins/plugin.resume.js.map +1 -1
  27. package/BookReader/plugins/plugin.search.js +1 -1
  28. package/BookReader/plugins/plugin.search.js.map +1 -1
  29. package/BookReader/plugins/plugin.text_selection.js +1 -1
  30. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  31. package/BookReader/plugins/plugin.tts.js +1 -1
  32. package/BookReader/plugins/plugin.tts.js.map +1 -1
  33. package/BookReader/plugins/plugin.url.js +1 -1
  34. package/BookReader/plugins/plugin.url.js.map +1 -1
  35. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  36. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  37. package/BookReader/webcomponents-bundle.js +3 -0
  38. package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
  39. package/BookReader/webcomponents-bundle.js.map +1 -0
  40. package/BookReaderDemo/BookReaderDemo.css +14 -1
  41. package/BookReaderDemo/IADemoBr.js +107 -0
  42. package/BookReaderDemo/demo-advanced.html +1 -1
  43. package/BookReaderDemo/demo-autoplay.html +1 -0
  44. package/BookReaderDemo/demo-embed-iframe-src.html +1 -0
  45. package/BookReaderDemo/demo-fullscreen-mobile.html +1 -0
  46. package/BookReaderDemo/demo-fullscreen.html +1 -0
  47. package/BookReaderDemo/demo-iiif.html +1 -0
  48. package/BookReaderDemo/demo-internetarchive.html +66 -18
  49. package/BookReaderDemo/demo-multiple.html +1 -0
  50. package/BookReaderDemo/demo-preview-pages.html +1 -0
  51. package/BookReaderDemo/demo-simple.html +1 -0
  52. package/BookReaderDemo/demo-vendor-fullscreen.html +1 -0
  53. package/BookReaderDemo/immersion-1up.html +1 -0
  54. package/BookReaderDemo/immersion-mode.html +1 -0
  55. package/BookReaderDemo/toggle_controls.html +1 -0
  56. package/BookReaderDemo/view_mode.html +1 -0
  57. package/BookReaderDemo/viewmode-cycle.html +1 -2
  58. package/CHANGELOG.md +114 -0
  59. package/babel.config.js +18 -0
  60. package/index.html +3 -0
  61. package/jsconfig.json +19 -0
  62. package/package.json +45 -27
  63. package/src/BookNavigator/assets/button-base.js +8 -1
  64. package/src/BookNavigator/assets/ia-logo.js +17 -0
  65. package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
  66. package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
  67. package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
  68. package/src/BookNavigator/assets/icon_volumes.js +11 -0
  69. package/src/BookNavigator/book-navigator.js +528 -0
  70. package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
  71. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -1
  72. package/src/BookNavigator/bookmarks/bookmarks-list.js +1 -0
  73. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
  74. package/src/BookNavigator/bookmarks/bookmarks-provider.js +32 -11
  75. package/src/BookNavigator/bookmarks/ia-bookmarks.js +88 -43
  76. package/src/BookNavigator/downloads/downloads-provider.js +22 -16
  77. package/src/BookNavigator/downloads/downloads.js +16 -23
  78. package/src/BookNavigator/search/a-search-result.js +1 -0
  79. package/src/BookNavigator/search/search-provider.js +54 -20
  80. package/src/BookNavigator/search/search-results.js +7 -18
  81. package/src/BookNavigator/sharing.js +27 -0
  82. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +10 -12
  83. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +1 -0
  84. package/src/BookNavigator/volumes/volumes-provider.js +114 -0
  85. package/src/BookNavigator/volumes/volumes.js +189 -0
  86. package/src/BookReader/DebugConsole.js +3 -3
  87. package/src/BookReader/DragScrollable.js +233 -0
  88. package/src/BookReader/Mode1Up.js +50 -351
  89. package/src/BookReader/Mode1UpLit.js +434 -0
  90. package/src/BookReader/Mode2Up.js +94 -72
  91. package/src/BookReader/ModeSmoothZoom.js +177 -0
  92. package/src/BookReader/ModeThumb.js +16 -8
  93. package/src/BookReader/Navbar/Navbar.js +2 -31
  94. package/src/BookReader/PageContainer.js +47 -2
  95. package/src/BookReader/ReduceSet.js +1 -1
  96. package/src/BookReader/Toolbar/Toolbar.js +5 -5
  97. package/src/BookReader/options.js +10 -0
  98. package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  99. package/src/BookReader/utils.js +68 -13
  100. package/src/BookReader.js +316 -232
  101. package/src/assets/icons/close-circle-dark.svg +1 -0
  102. package/src/assets/icons/voice.svg +1 -0
  103. package/src/css/BookReader.scss +0 -12
  104. package/src/css/_BRComponent.scss +1 -1
  105. package/src/css/_BRmain.scss +19 -24
  106. package/src/css/_BRnav.scss +4 -26
  107. package/src/css/_BRpages.scss +35 -0
  108. package/src/css/_BRsearch.scss +11 -215
  109. package/src/css/_TextSelection.scss +1 -17
  110. package/src/css/_controls.scss +16 -3
  111. package/src/css/_icons.scss +6 -0
  112. package/src/ia-bookreader/ia-bookreader.js +205 -0
  113. package/src/plugins/plugin.chapters.js +15 -18
  114. package/src/plugins/plugin.mobile_nav.js +11 -10
  115. package/src/plugins/plugin.resume.js +3 -3
  116. package/src/plugins/plugin.text_selection.js +17 -29
  117. package/src/plugins/plugin.vendor-fullscreen.js +4 -4
  118. package/src/plugins/search/plugin.search.js +113 -104
  119. package/src/plugins/search/view.js +48 -163
  120. package/src/plugins/tts/AbstractTTSEngine.js +7 -0
  121. package/src/plugins/tts/FestivalTTSEngine.js +2 -2
  122. package/src/plugins/tts/WebTTSEngine.js +5 -0
  123. package/src/plugins/tts/plugin.tts.js +67 -102
  124. package/src/plugins/url/UrlPlugin.js +184 -0
  125. package/src/plugins/url/plugin.url.js +220 -0
  126. package/{src → stat}/BookNavigator/BookModel.js +0 -0
  127. package/{src → stat}/BookNavigator/BookNavigator.js +151 -104
  128. package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
  129. package/stat/BookNavigator/assets/button-base.js +61 -0
  130. package/stat/BookNavigator/assets/ia-logo.js +17 -0
  131. package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
  132. package/stat/BookNavigator/assets/icon_close.js +3 -0
  133. package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
  134. package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
  135. package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
  136. package/stat/BookNavigator/assets/icon_volumes.js +11 -0
  137. package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
  138. package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
  139. package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
  140. package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
  141. package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
  142. package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
  143. package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
  144. package/stat/BookNavigator/delete-modal-actions.js +49 -0
  145. package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
  146. package/stat/BookNavigator/downloads/downloads.js +139 -0
  147. package/stat/BookNavigator/provider-config.js +0 -0
  148. package/stat/BookNavigator/search/a-search-result.js +55 -0
  149. package/stat/BookNavigator/search/search-provider.js +180 -0
  150. package/stat/BookNavigator/search/search-results.js +360 -0
  151. package/stat/BookNavigator/sharing.js +31 -0
  152. package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
  153. package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
  154. package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
  155. package/stat/BookNavigator/volumes/volumes.js +178 -0
  156. package/stat/BookReader/BookModel.js +518 -0
  157. package/stat/BookReader/DebugConsole.js +54 -0
  158. package/stat/BookReader/DragScrollable.js +233 -0
  159. package/stat/BookReader/ImageCache.js +116 -0
  160. package/stat/BookReader/Mode1Up.js +102 -0
  161. package/stat/BookReader/Mode1UpLit.js +434 -0
  162. package/stat/BookReader/Mode2Up.js +1372 -0
  163. package/stat/BookReader/ModeSmoothZoom.js +177 -0
  164. package/stat/BookReader/ModeThumb.js +344 -0
  165. package/stat/BookReader/Navbar/Navbar.js +310 -0
  166. package/stat/BookReader/PageContainer.js +120 -0
  167. package/stat/BookReader/ReduceSet.js +26 -0
  168. package/stat/BookReader/Toolbar/Toolbar.js +384 -0
  169. package/stat/BookReader/events.js +20 -0
  170. package/stat/BookReader/options.js +324 -0
  171. package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
  172. package/stat/BookReader/utils/classes.js +36 -0
  173. package/stat/BookReader/utils.js +240 -0
  174. package/stat/BookReader.js +2550 -0
  175. package/{src → stat}/BookReaderComponent/BookReaderComponent.js +16 -11
  176. package/stat/assets/icons/1up.svg +12 -0
  177. package/stat/assets/icons/2up.svg +15 -0
  178. package/stat/assets/icons/advance.svg +26 -0
  179. package/stat/assets/icons/chevron-right.svg +1 -0
  180. package/stat/assets/icons/close-circle-dark.svg +1 -0
  181. package/stat/assets/icons/close-circle.svg +1 -0
  182. package/stat/assets/icons/fullscreen.svg +17 -0
  183. package/stat/assets/icons/fullscreen_exit.svg +17 -0
  184. package/stat/assets/icons/hamburger.svg +15 -0
  185. package/stat/assets/icons/left-arrow.svg +12 -0
  186. package/stat/assets/icons/magnify-minus.svg +16 -0
  187. package/stat/assets/icons/magnify-plus.svg +17 -0
  188. package/stat/assets/icons/magnify.svg +15 -0
  189. package/stat/assets/icons/pause.svg +23 -0
  190. package/stat/assets/icons/play.svg +22 -0
  191. package/stat/assets/icons/playback-speed.svg +34 -0
  192. package/stat/assets/icons/read-aloud.svg +22 -0
  193. package/stat/assets/icons/review.svg +22 -0
  194. package/stat/assets/icons/thumbnails.svg +17 -0
  195. package/stat/assets/icons/voice.svg +1 -0
  196. package/stat/assets/icons/volume-full.svg +22 -0
  197. package/stat/assets/images/BRicons.png +0 -0
  198. package/stat/assets/images/BRicons.svg +94 -0
  199. package/stat/assets/images/BRicons_ia.png +0 -0
  200. package/stat/assets/images/back_pages.png +0 -0
  201. package/stat/assets/images/book_bottom_icon.png +0 -0
  202. package/stat/assets/images/book_down_icon.png +0 -0
  203. package/stat/assets/images/book_left_icon.png +0 -0
  204. package/stat/assets/images/book_leftmost_icon.png +0 -0
  205. package/stat/assets/images/book_right_icon.png +0 -0
  206. package/stat/assets/images/book_rightmost_icon.png +0 -0
  207. package/stat/assets/images/book_top_icon.png +0 -0
  208. package/stat/assets/images/book_up_icon.png +0 -0
  209. package/stat/assets/images/books_graphic.svg +177 -0
  210. package/stat/assets/images/booksplit.png +0 -0
  211. package/stat/assets/images/control_pause_icon.png +0 -0
  212. package/stat/assets/images/control_play_icon.png +0 -0
  213. package/stat/assets/images/embed_icon.png +0 -0
  214. package/stat/assets/images/icon-home-ia.png +0 -0
  215. package/stat/assets/images/icon_OL-logo-xs.png +0 -0
  216. package/stat/assets/images/icon_alert-xs.png +0 -0
  217. package/stat/assets/images/icon_book.svg +12 -0
  218. package/stat/assets/images/icon_bookmark.svg +12 -0
  219. package/stat/assets/images/icon_close-pop.png +0 -0
  220. package/stat/assets/images/icon_download.png +0 -0
  221. package/stat/assets/images/icon_gear.svg +14 -0
  222. package/stat/assets/images/icon_hamburger.svg +20 -0
  223. package/stat/assets/images/icon_home.png +0 -0
  224. package/stat/assets/images/icon_home.svg +21 -0
  225. package/stat/assets/images/icon_home_ia.png +0 -0
  226. package/stat/assets/images/icon_indicator.png +0 -0
  227. package/stat/assets/images/icon_info.svg +11 -0
  228. package/stat/assets/images/icon_one_page.svg +8 -0
  229. package/stat/assets/images/icon_pause.svg +1 -0
  230. package/stat/assets/images/icon_play.svg +1 -0
  231. package/stat/assets/images/icon_playback-rate.svg +15 -0
  232. package/stat/assets/images/icon_return.png +0 -0
  233. package/stat/assets/images/icon_search_button.svg +8 -0
  234. package/stat/assets/images/icon_share.svg +9 -0
  235. package/stat/assets/images/icon_skip-ahead.svg +6 -0
  236. package/stat/assets/images/icon_skip-back.svg +13 -0
  237. package/stat/assets/images/icon_speaker.svg +18 -0
  238. package/stat/assets/images/icon_speaker_open.svg +10 -0
  239. package/stat/assets/images/icon_thumbnails.svg +12 -0
  240. package/stat/assets/images/icon_toc.svg +5 -0
  241. package/stat/assets/images/icon_two_pages.svg +9 -0
  242. package/stat/assets/images/icon_zoomer.png +0 -0
  243. package/stat/assets/images/loading.gif +0 -0
  244. package/stat/assets/images/logo_icon.png +0 -0
  245. package/stat/assets/images/marker_chap-off.png +0 -0
  246. package/stat/assets/images/marker_chap-off.svg +11 -0
  247. package/stat/assets/images/marker_chap-off_ia.png +0 -0
  248. package/stat/assets/images/marker_chap-on.png +0 -0
  249. package/stat/assets/images/marker_chap-on.svg +11 -0
  250. package/stat/assets/images/marker_srch-on.svg +11 -0
  251. package/stat/assets/images/marker_srchchap-off.png +0 -0
  252. package/stat/assets/images/marker_srchchap-on.png +0 -0
  253. package/stat/assets/images/nav_control-dn.png +0 -0
  254. package/stat/assets/images/nav_control-dn_ia.png +0 -0
  255. package/stat/assets/images/nav_control-up.png +0 -0
  256. package/stat/assets/images/nav_control-up_ia.png +0 -0
  257. package/stat/assets/images/nav_control.png +0 -0
  258. package/stat/assets/images/one_page_mode_icon.png +0 -0
  259. package/stat/assets/images/paper-badge.png +0 -0
  260. package/stat/assets/images/print_icon.png +0 -0
  261. package/stat/assets/images/progressbar.gif +0 -0
  262. package/stat/assets/images/right_edges.png +0 -0
  263. package/stat/assets/images/slider.png +0 -0
  264. package/stat/assets/images/slider_ia.png +0 -0
  265. package/stat/assets/images/thumbnail_mode_icon.png +0 -0
  266. package/stat/assets/images/transparent.png +0 -0
  267. package/stat/assets/images/two_page_mode_icon.png +0 -0
  268. package/stat/assets/images/zoom_in_icon.png +0 -0
  269. package/stat/assets/images/zoom_out_icon.png +0 -0
  270. package/stat/css/BookReader.scss +89 -0
  271. package/stat/css/_BRBookmarks.scss +29 -0
  272. package/stat/css/_BRComponent.scss +13 -0
  273. package/stat/css/_BRfloat.scss +197 -0
  274. package/stat/css/_BRicon.scss +48 -0
  275. package/stat/css/_BRmain.scss +251 -0
  276. package/stat/css/_BRnav.scss +359 -0
  277. package/stat/css/_BRpages.scss +139 -0
  278. package/stat/css/_BRsearch.scss +226 -0
  279. package/stat/css/_BRtoolbar.scss +84 -0
  280. package/stat/css/_BRvendor.scss +5 -0
  281. package/stat/css/_MobileNav.scss +194 -0
  282. package/stat/css/_TextSelection.scss +32 -0
  283. package/stat/css/_colorbox.scss +52 -0
  284. package/stat/css/_controls.scss +253 -0
  285. package/stat/css/_icons.scss +121 -0
  286. package/stat/jquery-wrapper.js +4 -0
  287. package/stat/plugins/plugin.archive_analytics.js +86 -0
  288. package/stat/plugins/plugin.autoplay.js +129 -0
  289. package/stat/plugins/plugin.chapters.js +248 -0
  290. package/stat/plugins/plugin.iframe.js +48 -0
  291. package/stat/plugins/plugin.mobile_nav.js +288 -0
  292. package/stat/plugins/plugin.resume.js +68 -0
  293. package/stat/plugins/plugin.text_selection.js +291 -0
  294. package/{src → stat}/plugins/plugin.url.js +4 -4
  295. package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
  296. package/stat/plugins/search/plugin.search.js +439 -0
  297. package/stat/plugins/search/view.js +439 -0
  298. package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
  299. package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
  300. package/stat/plugins/tts/PageChunk.js +107 -0
  301. package/stat/plugins/tts/PageChunkIterator.js +163 -0
  302. package/stat/plugins/tts/WebTTSEngine.js +357 -0
  303. package/stat/plugins/tts/plugin.tts.js +357 -0
  304. package/stat/plugins/tts/tooltip_dict.js +15 -0
  305. package/stat/plugins/tts/utils.js +91 -0
  306. package/stat/util/browserSniffing.js +30 -0
  307. package/stat/util/debouncer.js +26 -0
  308. package/stat/util/docCookies.js +67 -0
  309. package/stat/util/strings.js +34 -0
  310. package/tests/e2e/README.md +37 -0
  311. package/tests/e2e/autoplay.test.js +2 -2
  312. package/tests/e2e/base.test.js +5 -7
  313. package/tests/e2e/helpers/base.js +8 -3
  314. package/tests/e2e/helpers/debug.js +1 -1
  315. package/tests/e2e/helpers/desktopSearch.js +1 -1
  316. package/tests/e2e/helpers/mobileSearch.js +3 -3
  317. package/tests/e2e/helpers/params.js +17 -0
  318. package/tests/e2e/rightToLeft.test.js +4 -5
  319. package/tests/e2e/viewmode.test.js +30 -31
  320. package/tests/{BookReader → jest/BookReader}/BookModel.test.js +3 -3
  321. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
  322. package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
  323. package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
  324. package/tests/jest/BookReader/Mode1UpLit.test.js +87 -0
  325. package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +5 -7
  326. package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
  327. package/tests/jest/BookReader/ModeThumb.test.js +71 -0
  328. package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
  329. package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +74 -2
  330. package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
  331. package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
  332. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
  333. package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
  334. package/tests/jest/BookReader/utils.test.js +136 -0
  335. package/tests/jest/BookReader.keyboard.test.js +190 -0
  336. package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
  337. package/tests/{BookReader.test.js → jest/BookReader.test.js} +20 -4
  338. package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
  339. package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +2 -2
  340. package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +8 -8
  341. package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
  342. package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
  343. package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
  344. package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +14 -24
  345. package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
  346. package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +12 -5
  347. package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +6 -6
  348. package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +3 -3
  349. package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
  350. package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
  351. package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
  352. package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
  353. package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -3
  354. package/tests/jest/plugins/url/UrlPlugin.test.js +175 -0
  355. package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
  356. package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
  357. package/tests/{util → jest/util}/docCookies.test.js +1 -1
  358. package/tests/{util → jest/util}/strings.test.js +1 -1
  359. package/tests/{utils.js → jest/utils.js} +38 -0
  360. package/tests/karma/BookNavigator/book-navigator.test.js +485 -0
  361. package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
  362. package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +1 -3
  363. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +1 -2
  364. package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +67 -0
  365. package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
  366. package/tests/karma/BookNavigator/search/search-provider.test.js +123 -0
  367. package/tests/karma/BookNavigator/{search-results.test.js → search/search-results.test.js} +1 -4
  368. package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +49 -0
  369. package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -2
  370. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +184 -0
  371. package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
  372. package/webpack.config.js +10 -4
  373. package/.babelrc +0 -12
  374. package/.dependabot/config.yml +0 -6
  375. package/.testcaferc.json +0 -5
  376. package/BookReader/bookreader-component-bundle.js +0 -1450
  377. package/BookReader/bookreader-component-bundle.js.map +0 -1
  378. package/BookReader/plugins/plugin.menu_toggle.js +0 -2
  379. package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
  380. package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
  381. package/src/BookNavigator/assets/book-loader.js +0 -27
  382. package/src/ItemNavigator/ItemNavigator.js +0 -372
  383. package/src/ItemNavigator/providers/sharing.js +0 -29
  384. package/src/dragscrollable-br.js +0 -261
  385. package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
  386. package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
  387. package/tests/BookReader/Mode1Up.test.js +0 -164
  388. package/tests/BookReader/utils.test.js +0 -109
  389. package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://@internetarchive/bookreader/./src/plugins/search/plugin.search.js","webpack://@internetarchive/bookreader/./src/plugins/search/view.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/inherit-if-required.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.object.assign.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.regexp.constructor.js"],"names":["super_","params","selector","this","br","matcher","RegExp","matches","cacheDOMElements","bindEvents","console","warn","dom","searchTray","renderSearchTray","results","querySelector","resultsCount","searchField","searchPending","mobileSearch","buildMobileDrawer","toolbarSearch","buildToolbarSearch","bool","classList","contains","toggle","innerText","toggleResultsCount","query","$","val","innerHTML","remove","removeSearchResults","removeResultPins","emptyMatches","setQuery","teardownSearchNavigation","trigger","document","createElement","setAttribute","replace","before","resultsPosition","searchNavigation","positionMessage","length","currentMatchIndex","namespace","on","clearSearchFieldAndResults","bind","showPrevResult","showNextResult","toggleSidebar","mode","constModeThumb","switchMode","constMode1up","getClosestMatchIndex","start","end","comparator","eq","click","updateResultsPosition","updateSearchNavigationButtons","comparisonFn","closestPage","closestTo","pool","slice","map","m","par","page","currentIndex","indexOf","find","text","attr","off","resize","matchingSearchResult","constMode2up","find2upMatchingSearchResult","find1upMatchingSearchResult","_isIndexDisplayed","setCurrentMatchIndex","items","match","leafNumToIndex","join","pinsVisibleState","refs","$BRfooter","css","visibility","imagesBaseURL","appendChild","add","forEach","queryString","pageIndex","pageNumber","getPageNum","percentThrough","constructor","util","cssPercentage","getNumLeafs","queryStringWithB","queryStringWithBTruncated","addClass","left","append","data","appendTo","hover","event","marker","currentTarget","tooltip","tooltipOffset","getBoundingClientRect","targetOffset","boxSizeAdjust","parseInt","getComputedStyle","paddingLeft","x","style","setProperty","removeClass","target","_searchPluginGoToResult","updateSearchHilites","showProgressPopup","removeProgressPopup","renderModalMessage","delayModalRemovalFor","messageHTML","modal","el","timeoutMS","setTimeout","$mmenu","open","close","e","preventDefault","value","search","blur","toggleSearchPending","options","renderSearchNavigation","bindSearchNavigationEvents","renderMatches","renderPins","updateResultsCount","goToFirstResult","one","is_visible","navigationIsVisible","togglePinsFor","toggleSearchTray","removeSearchHilites","searchTerm","renderErrorModal","renderBookNotIndexedModal","renderResultsEmptyModal","handleSearchCallback","handleNavToggledCallback","handleSearchStarted","handleSearchCallbackError","handleSearchCallbackBookNotIndexed","handleSearchCallbackEmpty","updateSearchNavigation","addEventListener","submitHandler","dataset","closeMobileMenu","jQuery","extend","BookReader","defaultOptions","server","bookId","subPrefix","bookPath","enableSearch","searchInsideUrl","initialSearchTerm","prototype","setup","call","searchResults","searchView","SearchView","init","suppressFragmentChange","buildMobileDrawerElement","$el","after","buildToolbarElement","term","overrides","disablePopup","error","success","eventNames","fragmentChange","serverPath","baseUrl","path","subPrefixWithSlash","lastIndexOf","substr","urlParams","item_id","doc","q","paramStr","param","url","processSearchResults","searchInsideResults","responseHasError","hasCustomError","hasCustomSuccess","BRSearchCallbackError","BRSearchCallback","ajax","dataType","then","instance","_BRSearchCallbackError","basePayload","payload","Object","assign","indexed","updateSearchHilites1UP","updateSearchHilites2UP","boxes","box","inArray","displayedIndices","div","prop","_models","book","getPage","highlight","width","_modes","mode1Up","physicalInchesToDisplayPixels","r","l","ppi","height","b","t","top","pageIsInView","isViewable","$brTwoPageView","setHilightCss2UP","makeUnviewableAtEnd","fetch","URLSearchParams","id","subprefix","leafNum","json","resp","makeViewable","jumpToIndex","searchHighlightVisible","visiblePages","twoPage","currentIndexL","currentIndexR","some","isObject","setPrototypeOf","module","exports","$this","dummy","Wrapper","NewTarget","NewTargetPrototype","stat","forced","DESCRIPTORS","global","isForced","inheritIfRequired","defineProperty","getOwnPropertyNames","isRegExp","getFlags","stickyHelpers","redefine","fails","enforceInternalState","setSpecies","MATCH","wellKnownSymbol","NativeRegExp","RegExpPrototype","re1","re2","CORRECT_NEW","UNSUPPORTED_Y","RegExpWrapper","pattern","flags","sticky","thisIsRegExp","patternIsRegExp","flagsAreUndefined","undefined","source","result","proxy","key","configurable","get","set","it","keys","index"],"mappings":"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","file":"plugins/plugin.search.js","sourcesContent":["/* global BookReader */\n/**\n * Plugin for Archive.org book search\n * NOTE: This script must be loaded AFTER `plugin.mobile_nav.js`\n * as it mutates mobile nav drawer\n *\n * Events fired at various points throughout search processing are published\n * on the document DOM element. These can be subscribed to using jQuery's event\n * binding method `$.fn.on`. All of the events are prefixed with a BookReader\n * namespace. The events are:\n *\n * @event BookReader:SearchStarted - When a search form is submitted, immediately\n * before an AJAX call is made to request search results\n * @event BookReader:SearchCallback - When the search AJAX call is returned and at\n * least one result is returned. The event callback receives an object\n * with the `results`, plugin `options`, and the BookReader `instance`\n * @event BookReader:SearchCallbackError - When the AJAX request returns an error.\n * Receives the `results` and `instance`\n * @event BookReader:SearchCallbackNotIndexed - When a message is received that\n * the book has not had OCR text indexed yet. Receives `instance`\n * @event BookReader:SearchCallbackEmpty - When no results found. Receives\n * `instance`\n */\nimport SearchView from './view.js';\n\njQuery.extend(BookReader.defaultOptions, {\n server: 'ia600609.us.archive.org',\n bookId: '',\n subPrefix: '',\n bookPath: '',\n enableSearch: true,\n searchInsideUrl: '/fulltext/inside.php',\n initialSearchTerm: null,\n});\n\n/** @override */\nBookReader.prototype.setup = (function (super_) {\n return function (options) {\n super_.call(this, options);\n\n this.searchTerm = '';\n this.searchResults = null;\n this.searchInsideUrl = options.searchInsideUrl;\n this.enableSearch = options.enableSearch;\n this.goToFirstResult = false;\n\n // Base server used by some api calls\n this.bookId = options.bookId;\n this.server = options.server;\n this.subPrefix = options.subPrefix;\n this.bookPath = options.bookPath;\n\n if (this.searchView) { return; }\n this.searchView = new SearchView({\n br: this,\n selector: '#BRsearch_tray',\n });\n };\n})(BookReader.prototype.setup);\n\n/** @override */\nBookReader.prototype.init = (function (super_) {\n return function () {\n super_.call(this);\n\n if (this.options.enableSearch && this.options.initialSearchTerm) {\n this.search(\n this.options.initialSearchTerm,\n { goToFirstResult: this.goToFirstResult, suppressFragmentChange: true }\n );\n }\n };\n})(BookReader.prototype.init);\n\n/** @override */\nBookReader.prototype.buildMobileDrawerElement = (function (super_) {\n return function () {\n const $el = super_.call(this);\n if (!this.enableSearch) { return; }\n if (this.searchView.dom.mobileSearch) {\n $el.find('.BRmobileMenu__moreInfoRow').after(this.searchView.dom.mobileSearch);\n }\n return $el;\n };\n})(BookReader.prototype.buildMobileDrawerElement);\n\n/** @override */\nBookReader.prototype.buildToolbarElement = (function (super_) {\n return function () {\n const $el = super_.call(this);\n if (!this.enableSearch) { return; }\n if (this.searchView.dom.toolbarSearch) {\n $el.find('.BRtoolbarSectionInfo').after(this.searchView.dom.toolbarSearch);\n }\n return $el;\n };\n})(BookReader.prototype.buildToolbarElement);\n\n/**\n * @typedef {object} SearchOptions\n * @property {boolean} goToFirstResult\n * @property {boolean} disablePopup\n * @property {(null|function)} error - @deprecated at v.5.0\n * @property {(null|function)} success - @deprecated at v.5.0\n */\n\n/**\n * Submits search request\n *\n * @param {string} term\n * @param {SearchOptions} overrides\n */\nBookReader.prototype.search = function(term = '', overrides = {}) {\n /** @type {SearchOptions} */\n const defaultOptions = {\n goToFirstResult: false, /* jump to the first result (default=false) */\n disablePopup: false, /* don't show the modal progress (default=false) */\n suppressFragmentChange: false, /* don't change the URL on initial load */\n error: null, /* optional error handler (default=null) */\n success: null, /* optional success handler (default=null) */\n\n };\n const options = jQuery.extend({}, defaultOptions, overrides);\n this.suppressFragmentChange = options.suppressFragmentChange;\n\n // strip slashes, since this goes in the url\n this.searchTerm = term.replace(/\\//g, ' ');\n\n if (!options.suppressFragmentChange) {\n this.trigger(BookReader.eventNames.fragmentChange);\n }\n\n // Add quotes to the term. This is to compenstate for the backends default OR query\n // term = term.replace(/['\"]+/g, '');\n // term = '\"' + term + '\"';\n\n // Remove the port and userdir\n const serverPath = this.server.replace(/:.+/, '');\n const baseUrl = `https://${serverPath}${this.searchInsideUrl}?`;\n\n // Remove subPrefix from end of path\n let path = this.bookPath;\n const subPrefixWithSlash = `/${this.subPrefix}`;\n if (this.bookPath.length - this.bookPath.lastIndexOf(subPrefixWithSlash) == subPrefixWithSlash.length) {\n path = this.bookPath.substr(0, this.bookPath.length - subPrefixWithSlash.length);\n }\n\n const urlParams = {\n item_id: this.bookId,\n doc: this.subPrefix,\n path,\n q: term,\n };\n\n // NOTE that the API does not expect / (slashes) to be encoded. (%2F) won't work\n const paramStr = $.param(urlParams).replace(/%2F/g, '/');\n\n const url = `${baseUrl}${paramStr}`;\n\n const processSearchResults = (searchInsideResults) => {\n const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;\n const hasCustomError = typeof options.error === 'function';\n const hasCustomSuccess = typeof options.success === 'function';\n\n if (responseHasError) {\n hasCustomError\n ? options.error.call(this, searchInsideResults, options)\n : this.BRSearchCallbackError(searchInsideResults, options);\n } else {\n hasCustomSuccess\n ? options.success.call(this, searchInsideResults, options)\n : this.BRSearchCallback(searchInsideResults, options);\n }\n };\n\n this.trigger('SearchStarted', { term: this.searchTerm });\n return $.ajax({\n url: url,\n dataType: 'jsonp'\n }).then(processSearchResults);\n};\n\n/**\n * @typedef {object} SearchInsideMatchBox\n * @property {number} page\n * @property {number} r\n * @property {number} l\n * @property {number} b\n * @property {number} t\n * @property {HTMLDivElement} [div]\n */\n\n/**\n * @typedef {object} SearchInsideMatch\n * @property {string} text\n * @property {Array<{ page: number, boxes: SearchInsideMatchBox[] }>} par\n */\n\n/**\n * @typedef {object} SearchInsideResults\n * @property {string} error\n * @property {SearchInsideMatch[]} matches\n * @property {boolean} indexed\n */\n\n/**\n * Search Results return handler\n * @callback\n * @param {SearchInsideResults} results\n * @param {object} options\n * @param {boolean} options.goToFirstResult\n */\nBookReader.prototype.BRSearchCallback = function(results, options) {\n this.searchResults = results;\n\n this.updateSearchHilites();\n this.removeProgressPopup();\n if (options.goToFirstResult) {\n this._searchPluginGoToResult(results.matches[0].par[0].page);\n }\n this.trigger('SearchCallback', { results, options, instance: this });\n}\n\n/**\n * Main search results error handler\n * @callback\n * @param {SearchInsideResults} results\n */\nBookReader.prototype.BRSearchCallbackError = function(results) {\n this._BRSearchCallbackError(results);\n};\n\n/**\n * @private draws search results error\n * @callback\n * @param {SearchInsideResults} results\n * @param {jQuery} $el\n * @param {boolean} fade\n */\nBookReader.prototype._BRSearchCallbackError = function(results) {\n this.searchResults = results;\n const basePayload = {\n term: this.searchTerm,\n instance: this,\n };\n if (results.error) {\n const payload = Object.assign({}, basePayload, { results });\n this.trigger('SearchCallbackError', payload);\n } else if (0 == results.matches.length) {\n if (false === results.indexed) {\n this.trigger('SearchCallbackBookNotIndexed', basePayload);\n return;\n }\n this.trigger('SearchCallbackEmpty', basePayload);\n }\n};\n\n/**\n * updates search on-page highlights controller\n */\nBookReader.prototype.updateSearchHilites = function() {\n if (this.constMode2up == this.mode) {\n this.updateSearchHilites2UP();\n return;\n }\n this.updateSearchHilites1UP();\n};\n\n/**\n * update search on-page highlights in 1up mode\n */\nBookReader.prototype.updateSearchHilites1UP = function() {\n const results = this.searchResults;\n if (null == results) return;\n results.matches.forEach(match => {\n match.par[0].boxes.forEach(box => {\n const pageIndex = this.leafNumToIndex(box.page);\n const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;\n if (pageIsInView) {\n if (!box.div) {\n //create a div for the search highlight, and stash it in the box object\n box.div = document.createElement('div');\n $(box.div).prop('className', 'BookReaderSearchHilite').appendTo(this.$(`.pagediv${pageIndex}`));\n }\n const page = this._models.book.getPage(pageIndex);\n const highlight = {\n width: this._modes.mode1Up.physicalInchesToDisplayPixels((box.r - box.l) / page.ppi),\n height: this._modes.mode1Up.physicalInchesToDisplayPixels((box.b - box.t) / page.ppi),\n left: this._modes.mode1Up.physicalInchesToDisplayPixels(box.l / page.ppi),\n top: this._modes.mode1Up.physicalInchesToDisplayPixels(box.t / page.ppi),\n };\n $(box.div).css(highlight);\n } else {\n if (box.div) {\n $(box.div).remove();\n box.div = null;\n }\n }\n });\n });\n};\n\n/**\n * update search on-page highlights in 2up mode\n */\nBookReader.prototype.updateSearchHilites2UP = function() {\n const results = this.searchResults;\n\n if (results === null) return;\n\n const { matches } = results;\n matches.forEach((match) => {\n match.par[0].boxes.forEach(box => {\n const pageIndex = this.leafNumToIndex(match.par[0].page);\n const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;\n const { isViewable } = this._models.book.getPage(pageIndex);\n\n if (pageIsInView && isViewable) {\n if (!box.div) {\n //create a div for the search highlight, and stash it in the box object\n box.div = document.createElement('div');\n $(box.div).addClass('BookReaderSearchHilite')\n .appendTo(this.refs.$brTwoPageView);\n }\n this.setHilightCss2UP(box.div, pageIndex, box.l, box.r, box.t, box.b);\n } else {\n // clear stale reference\n if (box.div) {\n $(box.div).remove();\n box.div = null;\n }\n }\n });\n });\n};\n\n/**\n * remove search highlights\n */\nBookReader.prototype.removeSearchHilites = function() {\n const results = this.searchResults;\n if (null == results || !results.matches) { return; }\n results.matches.forEach(match => {\n match.par[0].boxes.forEach(box => {\n if (null != box.div) {\n $(box.div).remove();\n box.div = null;\n }\n });\n });\n};\n\n/**\n * @private\n * Goes to the page specified. If the page is not viewable, tries to load the page\n * FIXME Most of this logic is IA specific, and should be less integrated into here\n * or at least more configurable.\n * @param {PageIndex} pageIndex\n */\nBookReader.prototype._searchPluginGoToResult = async function (pageIndex) {\n const { book } = this._models;\n const page = book.getPage(pageIndex);\n let makeUnviewableAtEnd = false;\n if (!page.isViewable) {\n const resp = await fetch('/services/bookreader/request_page?' + new URLSearchParams({\n id: this.options.bookId,\n subprefix: this.options.subPrefix,\n leafNum: page.leafNum,\n })).then(r => r.json());\n\n for (const leafNum of resp.value) {\n book.getPage(book.leafNumToIndex(leafNum)).makeViewable();\n }\n\n // not able to show page; make the page viewable anyways so that it can\n // actually open. On IA, it has a fallback to a special error page.\n if (!resp.value.length) {\n book.getPage(pageIndex).makeViewable();\n makeUnviewableAtEnd = true;\n }\n }\n /* this updates the URL */\n this.suppressFragmentChange = false;\n this.jumpToIndex(pageIndex);\n\n // Reset it to unviewable if it wasn't resolved\n if (makeUnviewableAtEnd) {\n book.getPage(pageIndex).makeViewable(false);\n }\n};\n\n/**\n * Removes all search pins\n */\nBookReader.prototype.removeSearchResults = function(suppressFragmentChange = false) {\n this.removeSearchHilites(); //be sure to set all box.divs to null\n this.searchTerm = null;\n this.searchResults = null;\n if (!suppressFragmentChange) {\n this.trigger(BookReader.eventNames.fragmentChange);\n }\n};\n\n/**\n * Returns true if a search highlight is currently being displayed\n * @returns {boolean}\n */\nBookReader.prototype.searchHighlightVisible = function() {\n const results = this.searchResults;\n let visiblePages = [];\n if (null == results) return false;\n\n if (this.constMode2up == this.mode) {\n visiblePages = [this.twoPage.currentIndexL, this.twoPage.currentIndexR];\n } else if (this.constMode1up == this.mode) {\n visiblePages = [this.currentIndex()];\n } else {\n return false;\n }\n\n results.matches.some(match => {\n return match.par[0].boxes.some(box => {\n const pageIndex = this.leafNumToIndex(box.page);\n if (jQuery.inArray(pageIndex, visiblePages) >= 0) {\n return true;\n }\n });\n });\n\n return false;\n};\n","class SearchView {\n /**\n * @param {object} params\n * @param {string} params.selector A selector for the element that the search tray will be rendered in\n * @param {string} params.query An existing query string\n * @param {object} params.br The BookReader instance\n *\n * @event BookReader:SearchResultsCleared - when the search results nav gets cleared\n * @event BookReader:ToggleSearchMenu - when search results menu should toggle\n */\n constructor(params) {\n if (!params.selector) {\n console.warn('BookReader::Search - SearchView must be passed a valid CSS selector');\n return;\n }\n\n this.br = params.br;\n\n // Search results are returned as a text blob with the hits wrapped in\n // triple mustaches. Hits occasionally include text beyond the search\n // term, so everything within the staches is captured and wrapped.\n this.matcher = new RegExp('{{{(.+?)}}}', 'g');\n this.matches = [];\n this.cacheDOMElements(params.selector);\n this.bindEvents();\n }\n\n /**\n * @param {string} selector A selector for the element that the search tray will be rendered in\n */\n cacheDOMElements(selector) {\n this.dom = {};\n\n // The parent search tray in mobile menu\n this.dom.searchTray = this.renderSearchTray(selector);\n // Container for rendered search results\n this.dom.results = this.dom.searchTray.querySelector('[data-id=\"results\"]');\n // Element used to display number of results\n this.dom.resultsCount = this.dom.searchTray.querySelector('[data-id=\"results_count\"]');\n // Search input within the mobile search tray\n this.dom.searchField = this.dom.searchTray.querySelector('[name=\"query\"]');\n // Waiting indicator displayed while waiting for a search request\n this.dom.searchPending = this.dom.searchTray.querySelector('[data-id=\"searchPending\"]');\n // The element added to the mobile menu that is animated into view when\n // the \"search\" nav item is clicked\n this.dom.mobileSearch = this.buildMobileDrawer();\n // Search input within the top toolbar. Will be removed once the mobile menu is replaced.\n this.dom.toolbarSearch = this.buildToolbarSearch();\n }\n\n /**\n * @param {boolean} bool\n */\n toggleSearchTray(bool = this.dom.searchTray.classList.contains('hidden')) {\n this.dom.searchTray.classList.toggle('hidden', !bool);\n }\n\n /**\n * @param {boolean} bool\n */\n toggleResultsCount(bool) {\n this.dom.resultsCount.classList.toggle('visible', bool);\n }\n\n /**\n * @param {SearchInsideResults} results\n */\n updateResultsCount(results) {\n this.dom.resultsCount.innerText = `(${results} result${results != 1 ? 's' : ''})`;\n this.toggleResultsCount(true);\n }\n\n /**\n * @param {string} query\n */\n setQuery(query) {\n this.br.$('[name=\"query\"]').val(query);\n }\n\n emptyMatches() {\n this.dom.results.innerHTML = '';\n this.matches = [];\n }\n\n removeResultPins() {\n this.br.$('.BRnavpos .BRsearch').remove();\n }\n\n clearSearchFieldAndResults() {\n this.br.removeSearchResults();\n this.toggleResultsCount(false);\n this.removeResultPins();\n this.emptyMatches();\n this.setQuery('');\n this.teardownSearchNavigation();\n this.br.trigger('SearchResultsCleared');\n }\n\n toggleSidebar() {\n this.br.trigger('ToggleSearchMenu');\n }\n /**\n * @param {string} selector The ID attribute to be used for the search tray\n */\n renderSearchTray(selector) {\n const searchTray = document.createElement('div');\n searchTray.setAttribute('id', selector.replace(/^#/, ''));\n searchTray.innerHTML = `\n <header>\n <div>\n <h3>Search inside</h3>\n <p data-id=\"results_count\"></p>\n </div>\n <a href=\"#\" class=\"close\"></a>\n </header>\n <form action=\"\" method=\"get\">\n <fieldset>\n <input name=\"all_files\" id=\"all_files\" type=\"checkbox\" />\n <label class=\"checkbox\" for=\"all_files\">Search all files</label>\n <input type=\"search\" name=\"query\" placeholder=\"Enter a search term\" />\n </fieldset>\n </form>\n <div data-id=\"searchPending\" id=\"search_pending\">\n <p>Your search results will appear below</p>\n <div class=\"loader tc mt20\"></div>\n </div>\n <ul data-id=\"results\"></ul>\n `;\n return searchTray;\n }\n\n renderSearchNavigation() {\n const selector = 'BRsearch-navigation';\n $('.BRnav').before(`\n <div class=\"${selector}\">\n <button class=\"toggle-sidebar\">\n <h4>\n <span class=\"icon icon-search\"></span> Results\n </h4>\n </button>\n <div class=\"pagination\">\n <button class=\"prev\" title=\"Previous result\"><span class=\"icon icon-chevron hflip\"></span></button>\n <span data-id=\"resultsCount\">${this.resultsPosition()}</span>\n <button class=\"next\" title=\"Next result\"><span class=\"icon icon-chevron\"></button>\n </div>\n <button class=\"clear\" title=\"Clear search results\">\n <span class=\"icon icon-close\"></span>\n </button>\n </div>\n `);\n this.dom.searchNavigation = $(`.${selector}`);\n }\n\n resultsPosition() {\n let positionMessage = `${this.matches.length} result${this.matches.length === 1 ? '' : 's'}`;\n if (~this.currentMatchIndex) {\n positionMessage = `${this.currentMatchIndex + 1} / ${this.matches.length}`;\n }\n return positionMessage;\n }\n\n bindSearchNavigationEvents() {\n if (!this.dom.searchNavigation) { return; }\n const namespace = 'searchNavigation';\n\n this.dom.searchNavigation\n .on(`click.${namespace}`, '.clear', this.clearSearchFieldAndResults.bind(this))\n .on(`click.${namespace}`, '.prev', this.showPrevResult.bind(this))\n .on(`click.${namespace}`, '.next', this.showNextResult.bind(this))\n .on(`click.${namespace}`, '.toggle-sidebar', this.toggleSidebar.bind(this))\n .on(`click.${namespace}`, false);\n }\n\n showPrevResult() {\n if (this.currentMatchIndex === 0) { return; }\n if (this.br.mode === this.br.constModeThumb) { this.br.switchMode(this.br.constMode1up); }\n if (!~this.currentMatchIndex) {\n this.currentMatchIndex = this.getClosestMatchIndex((start, end, comparator) => end[0] > comparator) + 1;\n }\n this.br.$('.BRnavline .BRsearch').eq(--this.currentMatchIndex).click();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n showNextResult() {\n if (this.currentMatchIndex + 1 === this.matches.length) { return; }\n if (this.br.mode === this.br.constModeThumb) { this.br.switchMode(this.br.constMode1up); }\n if (!~this.currentMatchIndex) {\n this.currentMatchIndex = this.getClosestMatchIndex((start, end, comparator) => start[start.length - 1] > comparator) - 1;\n }\n this.br.$('.BRnavline .BRsearch').eq(++this.currentMatchIndex).click();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n /**\n * Obtains closest match based on the logical comparison function passed in.\n * When the comparison function returns true, the starting (left) half of the\n * matches array is used in the binary split, else the ending (right) half is\n * used. A recursive call is made to perform the same split and comparison\n * on the winning half of the matches. This is traditionally known as binary\n * search (https://en.wikipedia.org/wiki/Binary_search_algorithm), and in\n * most cases (medium to large search result arrays) should outperform\n * traversing the array from start to finish. In the case of small arrays,\n * the speed difference is negligible.\n *\n * @param {function} comparisonFn\n * @return {number} matchIndex\n */\n getClosestMatchIndex(comparisonFn) {\n const matchPages = this.matches.map((m) => m.par[0].page);\n const currentPage = this.br.currentIndex() + 1;\n const closestTo = (pool, comparator) => {\n if (pool.length === 1) { return pool[0]; }\n const start = pool.slice(0, pool.length / 2);\n const end = pool.slice(pool.length / 2);\n return closestTo((comparisonFn(start, end, comparator) ? start : end), comparator);\n }\n\n const closestPage = closestTo(matchPages, currentPage);\n return this.matches.indexOf(this.matches.find((m) => m.par[0].page === closestPage));\n }\n\n updateResultsPosition() {\n this.dom.searchNavigation.find('[data-id=resultsCount]').text(this.resultsPosition());\n }\n\n updateSearchNavigationButtons() {\n this.dom.searchNavigation.find('.prev').attr('disabled', !this.currentMatchIndex);\n this.dom.searchNavigation.find('.next').attr('disabled', this.currentMatchIndex + 1 === this.matches.length);\n }\n\n teardownSearchNavigation() {\n if (!this.dom.searchNavigation) {\n this.dom.searchNavigation = $('.BRsearch-navigation');\n }\n if (!this.dom.searchNavigation.length) { return; }\n\n this.dom.searchNavigation.off('.searchNavigation').remove();\n this.dom.searchNavigation = null;\n this.br.resize();\n }\n\n setCurrentMatchIndex() {\n let matchingSearchResult;\n if (this.br.mode === this.br.constModeThumb) {\n this.currentMatchIndex = -1;\n return;\n }\n if (this.br.mode === this.br.constMode2up) {\n matchingSearchResult = this.find2upMatchingSearchResult();\n }\n else {\n matchingSearchResult = this.find1upMatchingSearchResult();\n }\n this.currentMatchIndex = this.matches.indexOf(matchingSearchResult);\n }\n\n find1upMatchingSearchResult() {\n return this.matches.find((m) => this.br.currentIndex() === m.par[0].page - 1);\n }\n\n find2upMatchingSearchResult() {\n return this.matches.find((m) => this.br._isIndexDisplayed(m.par[0].page - 1));\n }\n\n updateSearchNavigation() {\n if (!this.matches.length) { return; }\n\n this.setCurrentMatchIndex();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n /**\n * @param {array} matches\n */\n renderMatches(matches) {\n const items = matches.map((match) => `\n <li data-page=\"${match.par[0].page}\" data-page-index=\"${this.br.leafNumToIndex(match.par[0].page)}\">\n <h4>Page ${match.par[0].page}</h4>\n <p>${match.text.replace(this.matcher, '<mark>$1</mark>')}</p>\n </li>\n `);\n this.dom.results.innerHTML = items.join('');\n }\n\n /**\n * @param {boolean} bool\n */\n togglePinsFor(bool) {\n const pinsVisibleState = bool ? 'visible' : 'hidden';\n this.br.refs.$BRfooter.find('.BRsearch').css({ visibility: pinsVisibleState });\n }\n\n buildMobileDrawer() {\n const mobileSearch = document.createElement('li');\n mobileSearch.innerHTML = `\n <span>\n <span class=\"DrawerIconWrapper\">\n <img class=\"DrawerIcon\" src=\"${this.br.imagesBaseURL}icon_search_button.svg\" />\n </span>\n Search\n </span>\n <div data-id=\"search_slot\">\n </div>\n `;\n mobileSearch.querySelector('[data-id=\"search_slot\"]').appendChild(this.dom.searchTray);\n mobileSearch.classList.add('BRmobileMenu__search');\n return mobileSearch;\n }\n\n buildToolbarSearch() {\n const toolbarSearch = document.createElement('span');\n toolbarSearch.classList.add('BRtoolbarSection', 'BRtoolbarSectionSearch');\n toolbarSearch.innerHTML = `\n <form class=\"BRbooksearch desktop\">\n <input type=\"search\" name=\"query\" class=\"BRsearchInput\" value=\"\" placeholder=\"Search inside\"/>\n <button type=\"submit\" class=\"BRsearchSubmit\">\n <img src=\"${this.br.imagesBaseURL}icon_search_button.svg\" />\n </button>\n </form>\n `;\n return toolbarSearch;\n }\n\n /**\n * @param {array} matches\n */\n renderPins(matches) {\n matches.forEach((match) => {\n const queryString = match.text;\n const pageIndex = this.br.leafNumToIndex(match.par[0].page);\n const pageNumber = this.br.getPageNum(pageIndex);\n const uiStringSearch = \"Search result\"; // i18n\n const uiStringPage = \"Page\"; // i18n\n\n const percentThrough = this.br.constructor.util.cssPercentage(pageIndex, this.br.getNumLeafs() - 1);\n\n const queryStringWithB = queryString.replace(this.matcher, '<b>$1</b>');\n\n let queryStringWithBTruncated = '';\n\n if (queryString.length > 100) {\n queryStringWithBTruncated = queryString\n .replace(/^(.{100}[^\\s]*).*/, \"$1\")\n .replace(this.matcher, '<b>$1</b>')\n + '...';\n }\n\n // draw marker\n $('<div>')\n .addClass('BRsearch')\n .css({\n left: percentThrough,\n })\n .attr('title', uiStringSearch)\n .append(`\n <div class=\"BRquery\">\n <div>${queryStringWithBTruncated || queryStringWithB}</div>\n <div>${uiStringPage} ${pageNumber}</div>\n </div>\n `)\n .data({ pageIndex })\n .appendTo(this.br.$('.BRnavline'))\n .hover(\n (event) => {\n // remove from other markers then turn on just for this\n // XXX should be done when nav slider moves\n const marker = event.currentTarget;\n const tooltip = marker.querySelector('.BRquery');\n const tooltipOffset = tooltip.getBoundingClientRect();\n const targetOffset = marker.getBoundingClientRect();\n const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;\n if (tooltipOffset.x - boxSizeAdjust < 0) {\n tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);\n }\n $('.BRsearch,.BRchapter').removeClass('front');\n $(event.target).addClass('front');\n },\n (event) => $(event.target).removeClass('front'))\n .click(function (event) {\n // closures are nested and deep, using an arrow function breaks references.\n // Todo: update to arrow function & clean up closures\n // to remove `bind` dependency\n this.br._searchPluginGoToResult(+$(event.target).data('pageIndex'));\n this.br.updateSearchHilites();\n }.bind(this));\n });\n }\n\n /**\n * @param {boolean} bool\n */\n toggleSearchPending(bool) {\n this.dom.searchPending.classList.toggle('visible', bool);\n if (bool) {\n this.br.showProgressPopup(\"Search results will appear below...\");\n }\n else {\n this.br.removeProgressPopup();\n }\n }\n\n renderErrorModal() {\n this.renderModalMessage(`\n Sorry, there was an error with your search.\n <br />\n The text may still be processing.\n `);\n this.delayModalRemovalFor(4000);\n }\n\n renderBookNotIndexedModal() {\n this.renderModalMessage(`\n <p>\n This book hasn't been indexed for searching yet.\n We've just started indexing it, so search should be available soon.\n <br />\n Please try again later. Thanks!\n </p>\n `);\n this.delayModalRemovalFor(5000);\n }\n\n renderResultsEmptyModal() {\n this.renderModalMessage('No matches were found.');\n this.delayModalRemovalFor(2000);\n }\n\n /**\n * @param {string} messageHTML The innerHTML string used to popupate the modal contents\n */\n renderModalMessage(messageHTML) {\n const modal = document.createElement('div');\n modal.classList.add('BRprogresspopup', 'search_modal');\n modal.innerHTML = messageHTML;\n document.querySelector(this.br.el).append(modal);\n }\n\n /**\n * @param {number} timeoutMS\n */\n delayModalRemovalFor(timeoutMS) {\n setTimeout(this.br.removeProgressPopup.bind(this.br), timeoutMS);\n }\n\n openMobileMenu() {\n this.br.refs.$mmenu.data('mmenu').open();\n }\n\n closeMobileMenu() {\n this.br.refs.$mmenu.data('mmenu').close();\n }\n\n /**\n * @param {Event} e\n */\n submitHandler(e) {\n e.preventDefault();\n const query = e.target.querySelector('[name=\"query\"]').value;\n if (!query.length) { return false; }\n this.br.search(query);\n this.dom.searchField.blur();\n this.emptyMatches();\n this.toggleSearchPending(true);\n return false;\n }\n\n /**\n * @param {Event} e\n * @param {object} properties\n * @param {object} properties.results\n * @param {object} properties.options\n */\n handleSearchCallback(e, { results, options }) {\n this.matches = results.matches;\n this.setCurrentMatchIndex();\n this.teardownSearchNavigation();\n this.renderSearchNavigation();\n this.bindSearchNavigationEvents();\n this.renderMatches(results.matches);\n this.renderPins(results.matches);\n this.updateResultsCount(results.matches.length);\n this.toggleSearchPending(false);\n if (options.goToFirstResult) {\n $(document).one('BookReader:pageChanged', () => {\n this.br.resize();\n });\n } else {\n this.br.resize();\n }\n }\n\n /**\n * @param {Event} e\n */\n handleNavToggledCallback(e) {\n const is_visible = this.br.navigationIsVisible();\n this.togglePinsFor(is_visible);\n this.toggleSearchTray(is_visible ? !!this.dom.results.querySelector('li') : false);\n }\n\n handleSearchStarted() {\n this.emptyMatches();\n this.br.removeSearchHilites();\n this.removeResultPins();\n this.toggleSearchPending(true);\n this.teardownSearchNavigation();\n this.setQuery(this.br.searchTerm);\n }\n\n handleSearchCallbackError() {\n this.toggleSearchPending(false);\n this.renderErrorModal();\n }\n\n handleSearchCallbackBookNotIndexed() {\n this.toggleSearchPending(false);\n this.renderBookNotIndexedModal();\n }\n\n handleSearchCallbackEmpty() {\n this.toggleSearchPending(false);\n this.renderResultsEmptyModal();\n }\n\n bindEvents() {\n const namespace = 'BookReader:';\n\n $(document).on(`${namespace}SearchCallback`, this.handleSearchCallback.bind(this))\n .on(`${namespace}navToggled`, this.handleNavToggledCallback.bind(this))\n .on(`${namespace}SearchStarted`, this.handleSearchStarted.bind(this))\n .on(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this))\n .on(`${namespace}SearchCallbackBookNotIndexed`, this.handleSearchCallbackBookNotIndexed.bind(this))\n .on(`${namespace}SearchCallbackEmpty`, this.handleSearchCallbackEmpty.bind(this))\n .on(`${namespace}pageChanged`, this.updateSearchNavigation.bind(this));\n\n this.dom.searchTray.addEventListener('submit', this.submitHandler.bind(this));\n this.dom.toolbarSearch.querySelector('form').addEventListener('submit', this.submitHandler.bind(this));\n this.dom.searchField.addEventListener('search', () => {\n if (this.dom.searchField.value) { return; }\n this.clearSearchFieldAndResults();\n });\n\n $(this.dom.results).on('click', 'li', (e) => {\n this.br._searchPluginGoToResult(+e.currentTarget.dataset.pageIndex);\n this.br.updateSearchHilites();\n this.closeMobileMenu();\n });\n }\n}\n\nexport default SearchView;\n","var isObject = require('../internals/is-object');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\n\n// makes subclassing work correct for wrapped built-ins\nmodule.exports = function ($this, dummy, Wrapper) {\n var NewTarget, NewTargetPrototype;\n if (\n // it can work only with native `setPrototypeOf`\n setPrototypeOf &&\n // we haven't completely correct pre-ES6 way for getting `new.target`, so use this\n typeof (NewTarget = dummy.constructor) == 'function' &&\n NewTarget !== Wrapper &&\n isObject(NewTargetPrototype = NewTarget.prototype) &&\n NewTargetPrototype !== Wrapper.prototype\n ) setPrototypeOf($this, NewTargetPrototype);\n return $this;\n};\n","var $ = require('../internals/export');\nvar assign = require('../internals/object-assign');\n\n// `Object.assign` method\n// https://tc39.es/ecma262/#sec-object.assign\n// eslint-disable-next-line es/no-object-assign -- required for testing\n$({ target: 'Object', stat: true, forced: Object.assign !== assign }, {\n assign: assign\n});\n","var DESCRIPTORS = require('../internals/descriptors');\nvar global = require('../internals/global');\nvar isForced = require('../internals/is-forced');\nvar inheritIfRequired = require('../internals/inherit-if-required');\nvar defineProperty = require('../internals/object-define-property').f;\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar isRegExp = require('../internals/is-regexp');\nvar getFlags = require('../internals/regexp-flags');\nvar stickyHelpers = require('../internals/regexp-sticky-helpers');\nvar redefine = require('../internals/redefine');\nvar fails = require('../internals/fails');\nvar enforceInternalState = require('../internals/internal-state').enforce;\nvar setSpecies = require('../internals/set-species');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar MATCH = wellKnownSymbol('match');\nvar NativeRegExp = global.RegExp;\nvar RegExpPrototype = NativeRegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n\n// \"new\" should create a new object, old webkit bug\nvar CORRECT_NEW = new NativeRegExp(re1) !== re1;\n\nvar UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;\n\nvar FORCED = DESCRIPTORS && isForced('RegExp', (!CORRECT_NEW || UNSUPPORTED_Y || fails(function () {\n re2[MATCH] = false;\n // RegExp constructor can alter flags and IsRegExp works correct with @@match\n return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';\n})));\n\n// `RegExp` constructor\n// https://tc39.es/ecma262/#sec-regexp-constructor\nif (FORCED) {\n var RegExpWrapper = function RegExp(pattern, flags) {\n var thisIsRegExp = this instanceof RegExpWrapper;\n var patternIsRegExp = isRegExp(pattern);\n var flagsAreUndefined = flags === undefined;\n var sticky;\n\n if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) {\n return pattern;\n }\n\n if (CORRECT_NEW) {\n if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source;\n } else if (pattern instanceof RegExpWrapper) {\n if (flagsAreUndefined) flags = getFlags.call(pattern);\n pattern = pattern.source;\n }\n\n if (UNSUPPORTED_Y) {\n sticky = !!flags && flags.indexOf('y') > -1;\n if (sticky) flags = flags.replace(/y/g, '');\n }\n\n var result = inheritIfRequired(\n CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags),\n thisIsRegExp ? this : RegExpPrototype,\n RegExpWrapper\n );\n\n if (UNSUPPORTED_Y && sticky) {\n var state = enforceInternalState(result);\n state.sticky = true;\n }\n\n return result;\n };\n var proxy = function (key) {\n key in RegExpWrapper || defineProperty(RegExpWrapper, key, {\n configurable: true,\n get: function () { return NativeRegExp[key]; },\n set: function (it) { NativeRegExp[key] = it; }\n });\n };\n var keys = getOwnPropertyNames(NativeRegExp);\n var index = 0;\n while (keys.length > index) proxy(keys[index++]);\n RegExpPrototype.constructor = RegExpWrapper;\n RegExpWrapper.prototype = RegExpPrototype;\n redefine(global, 'RegExp', RegExpWrapper);\n}\n\n// https://tc39.es/ecma262/#sec-get-regexp-@@species\nsetSpecies('RegExp');\n"],"sourceRoot":""}
1
+ {"version":3,"file":"plugins/plugin.search.js","mappings":"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","sources":["webpack://@internetarchive/bookreader/./src/plugins/search/plugin.search.js","webpack://@internetarchive/bookreader/./src/plugins/search/view.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.object.entries.js"],"sourcesContent":["/* global BookReader */\n/**\n * Plugin for Archive.org book search\n * NOTE: This script must be loaded AFTER `plugin.mobile_nav.js`\n * as it mutates mobile nav drawer\n *\n * Events fired at various points throughout search processing are published\n * on the document DOM element. These can be subscribed to using jQuery's event\n * binding method `$.fn.on`. All of the events are prefixed with a BookReader\n * namespace. The events are:\n *\n * @event BookReader:SearchStarted - When a search form is submitted, immediately\n * before an AJAX call is made to request search results\n * @event BookReader:SearchCallback - When the search AJAX call is returned and at\n * least one result is returned. The event callback receives an object\n * with the `results`, plugin `options`, and the BookReader `instance`\n * @event BookReader:SearchCallbackError - When the AJAX request returns an error.\n * Receives the `results` and `instance`\n * @event BookReader:SearchCallbackNotIndexed - When a message is received that\n * the book has not had OCR text indexed yet. Receives `instance`\n * @event BookReader:SearchCallbackEmpty - When no results found. Receives\n * `instance`\n * @event BookReader:SearchCanceled - When no results found. Receives\n * `instance`\n */\nimport { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';\nimport SearchView from './view.js';\n/** @typedef {import('../../BookReader/PageContainer').PageContainer} PageContainer */\n/** @typedef {import('../../BookReader/BookModel').PageIndex} PageIndex */\n\njQuery.extend(BookReader.defaultOptions, {\n server: 'ia600609.us.archive.org',\n bookId: '',\n subPrefix: '',\n bookPath: '',\n enableSearch: true,\n searchInsideUrl: '/fulltext/inside.php',\n initialSearchTerm: null,\n});\n\n/** @override */\nBookReader.prototype.setup = (function (super_) {\n return function (options) {\n super_.call(this, options);\n\n this.searchTerm = '';\n this.searchResults = null;\n this.searchInsideUrl = options.searchInsideUrl;\n this.enableSearch = options.enableSearch;\n\n // Base server used by some api calls\n this.bookId = options.bookId;\n this.server = options.server;\n this.subPrefix = options.subPrefix;\n this.bookPath = options.bookPath;\n\n this.searchXHR = null;\n this._cancelSearch.bind(this);\n this.cancelSearchRequest.bind(this);\n\n /** @type { {[pageIndex: number]: SearchInsideMatchBox[]} } */\n this._searchBoxesByIndex = {};\n\n this.searchView = undefined;\n };\n})(BookReader.prototype.setup);\n\n/** @override */\nBookReader.prototype.init = (function (super_) {\n return function () {\n super_.call(this);\n // give SearchView the most complete bookreader state\n this.searchView = new SearchView({\n br: this,\n searchCancelledCallback: () => {\n this._cancelSearch();\n this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });\n }\n });\n if (this.options.enableSearch && this.options.initialSearchTerm) {\n /**\n * this.search() take two parameter\n * 1. this.options.initialSearchTerm - search term\n * 2. {\n * goToFirstResult: this.options.goToFirstResult,\n * suppressFragmentChange: false // always want to change fragment in URL\n * }\n */\n this.search(\n this.options.initialSearchTerm,\n { goToFirstResult: this.options.goToFirstResult, suppressFragmentChange: false }\n );\n }\n };\n})(BookReader.prototype.init);\n\n/** @override */\nBookReader.prototype.buildToolbarElement = (function (super_) {\n return function () {\n const $el = super_.call(this);\n if (!this.enableSearch) { return; }\n if (this.searchView.dom.toolbarSearch) {\n $el.find('.BRtoolbarSectionInfo').after(this.searchView.dom.toolbarSearch);\n }\n return $el;\n };\n})(BookReader.prototype.buildToolbarElement);\n\n/** @override */\nBookReader.prototype._createPageContainer = (function (super_) {\n return function (index) {\n const pageContainer = super_.call(this, index);\n if (this.enableSearch && pageContainer.page && index in this._searchBoxesByIndex) {\n const pageIndex = pageContainer.page.index;\n renderBoxesInPageContainerLayer('searchHiliteLayer', this._searchBoxesByIndex[pageIndex], pageContainer.page, pageContainer.$container[0]);\n }\n return pageContainer;\n };\n})(BookReader.prototype._createPageContainer);\n\n/**\n * @typedef {object} SearchOptions\n * @property {boolean} goToFirstResult\n * @property {boolean} disablePopup\n * @property {(null|function)} error - @deprecated at v.5.0\n * @property {(null|function)} success - @deprecated at v.5.0\n */\n\n/**\n * Submits search request\n *\n * @param {string} term\n * @param {SearchOptions} overrides\n */\nBookReader.prototype.search = function(term = '', overrides = {}) {\n /** @type {SearchOptions} */\n const defaultOptions = {\n goToFirstResult: false, /* jump to the first result (default=false) */\n disablePopup: false, /* don't show the modal progress (default=false) */\n suppressFragmentChange: false, /* don't change the URL on initial load */\n error: null, /* optional error handler (default=null) */\n success: null, /* optional success handler (default=null) */\n\n };\n const options = jQuery.extend({}, defaultOptions, overrides);\n this.suppressFragmentChange = options.suppressFragmentChange;\n\n // strip slashes, since this goes in the url\n this.searchTerm = term.replace(/\\//g, ' ');\n\n if (!options.suppressFragmentChange) {\n this.trigger(BookReader.eventNames.fragmentChange);\n }\n\n // Add quotes to the term. This is to compenstate for the backends default OR query\n // term = term.replace(/['\"]+/g, '');\n // term = '\"' + term + '\"';\n\n // Remove the port and userdir\n const serverPath = this.server.replace(/:.+/, '');\n const baseUrl = `https://${serverPath}${this.searchInsideUrl}?`;\n\n // Remove subPrefix from end of path\n let path = this.bookPath;\n const subPrefixWithSlash = `/${this.subPrefix}`;\n if (this.bookPath.length - this.bookPath.lastIndexOf(subPrefixWithSlash) == subPrefixWithSlash.length) {\n path = this.bookPath.substr(0, this.bookPath.length - subPrefixWithSlash.length);\n }\n\n const urlParams = {\n item_id: this.bookId,\n doc: this.subPrefix,\n path,\n q: term,\n };\n\n // NOTE that the API does not expect / (slashes) to be encoded. (%2F) won't work\n const paramStr = $.param(urlParams).replace(/%2F/g, '/');\n\n const url = `${baseUrl}${paramStr}`;\n\n const cleanup = () => {\n this.searchXHR = null;\n window.BRSearchInProgress = () => {};\n };\n\n const processSearchResults = (searchInsideResults) => {\n if (!this.searchXHR) {\n return;\n }\n const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;\n const hasCustomError = typeof options.error === 'function';\n const hasCustomSuccess = typeof options.success === 'function';\n\n if (responseHasError) {\n hasCustomError\n ? options.error.call(this, searchInsideResults, options)\n : this.BRSearchCallbackError(searchInsideResults, options);\n } else {\n hasCustomSuccess\n ? options.success.call(this, searchInsideResults, options)\n : this.BRSearchCallback(searchInsideResults, options);\n }\n cleanup();\n };\n\n const beforeSend = (xhr) => {\n this.searchXHR = xhr;\n window.BRSearchInProgress = processSearchResults;\n };\n\n this.trigger('SearchStarted', { term: this.searchTerm, instance: this });\n return $.ajax({\n url: url,\n dataType: 'jsonp',\n cache: true,\n beforeSend,\n jsonpCallback: 'BRSearchInProgress'\n }).then(processSearchResults);\n};\n\n/**\n * cancels AJAX Call\n * emits custom event\n */\nBookReader.prototype._cancelSearch = function () {\n this.searchXHR?.abort();\n this.searchView.clearSearchFieldAndResults(false);\n this.searchTerm = '';\n this.searchXHR = null;\n this.searchResults = [];\n window.BRSearchInProgress = () => {};\n};\n\n/**\n * External function to cancel search\n * checks for term & xhr in flight before running\n */\nBookReader.prototype.cancelSearchRequest = function () {\n if (this.searchXHR !== null) {\n this._cancelSearch();\n this.searchView.toggleSearchPending();\n this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });\n }\n};\n\n/**\n * @typedef {object} SearchInsideMatchBox\n * @property {number} page\n * @property {number} r\n * @property {number} l\n * @property {number} b\n * @property {number} t\n * @property {HTMLDivElement} [div]\n */\n\n/**\n * @typedef {object} SearchInsideMatch\n * @property {string} text\n * @property {Array<{ page: number, boxes: SearchInsideMatchBox[] }>} par\n */\n\n/**\n * @typedef {object} SearchInsideResults\n * @property {string} error\n * @property {SearchInsideMatch[]} matches\n * @property {boolean} indexed\n */\n\n/**\n * Search Results return handler\n * @callback\n * @param {SearchInsideResults} results\n * @param {object} options\n * @param {boolean} options.goToFirstResult\n */\nBookReader.prototype.BRSearchCallback = function(results, options) {\n this.searchResults = results || [];\n\n this.updateSearchHilites();\n this.removeProgressPopup();\n if (options.goToFirstResult) {\n const pageIndex = this._models.book.leafNumToIndex(results.matches[0].par[0].page);\n this._searchPluginGoToResult(pageIndex);\n }\n this.trigger('SearchCallback', { results, options, instance: this });\n};\n\n/**\n * Main search results error handler\n * @callback\n * @param {SearchInsideResults} results\n */\nBookReader.prototype.BRSearchCallbackError = function(results) {\n this._BRSearchCallbackError(results);\n};\n\n/**\n * @private draws search results error\n * @callback\n * @param {SearchInsideResults} results\n * @param {jQuery} $el\n * @param {boolean} fade\n */\nBookReader.prototype._BRSearchCallbackError = function(results) {\n this.searchResults = results;\n const basePayload = {\n term: this.searchTerm,\n instance: this,\n };\n if (results.error) {\n const payload = Object.assign({}, basePayload, { results });\n this.trigger('SearchCallbackError', payload);\n } else if (0 == results.matches.length) {\n if (false === results.indexed) {\n this.trigger('SearchCallbackBookNotIndexed', basePayload);\n return;\n }\n this.trigger('SearchCallbackEmpty', basePayload);\n }\n};\n\n/**\n * updates search on-page highlights controller\n */\nBookReader.prototype.updateSearchHilites = function() {\n /** @type {SearchInsideMatch[]} */\n const matches = this.searchResults?.matches || [];\n /** @type { {[pageIndex: number]: SearchInsideMatch[]} } */\n const boxesByIndex = {};\n\n // Clear any existing svg layers\n this.removeSearchHilites();\n\n // Group by pageIndex\n for (const match of matches) {\n for (const box of match.par[0].boxes) {\n const pageIndex = this.leafNumToIndex(box.page);\n const pageMatches = boxesByIndex[pageIndex] || (boxesByIndex[pageIndex] = []);\n pageMatches.push(box);\n }\n }\n\n // update any already created pages\n for (const [pageIndexString, boxes] of Object.entries(boxesByIndex)) {\n const pageIndex = parseFloat(pageIndexString);\n const page = this._models.book.getPage(pageIndex);\n const pageContainers = this.getActivePageContainerElementsForIndex(pageIndex);\n pageContainers.forEach(container => renderBoxesInPageContainerLayer('searchHiliteLayer', boxes, page, container));\n }\n\n this._searchBoxesByIndex = boxesByIndex;\n};\n\n/**\n * remove search highlights\n */\nBookReader.prototype.removeSearchHilites = function() {\n $(this.getActivePageContainerElements()).find('.searchHiliteLayer').remove();\n};\n\n/**\n * @private\n * Goes to the page specified. If the page is not viewable, tries to load the page\n * FIXME Most of this logic is IA specific, and should be less integrated into here\n * or at least more configurable.\n * @param {PageIndex} pageIndex\n */\nBookReader.prototype._searchPluginGoToResult = async function (pageIndex) {\n const { book } = this._models;\n const page = book.getPage(pageIndex);\n let makeUnviewableAtEnd = false;\n if (!page.isViewable) {\n const resp = await fetch('/services/bookreader/request_page?' + new URLSearchParams({\n id: this.options.bookId,\n subprefix: this.options.subPrefix,\n leafNum: page.leafNum,\n })).then(r => r.json());\n\n for (const leafNum of resp.value) {\n book.getPage(book.leafNumToIndex(leafNum)).makeViewable();\n }\n\n // not able to show page; make the page viewable anyways so that it can\n // actually open. On IA, it has a fallback to a special error page.\n if (!resp.value.length) {\n book.getPage(pageIndex).makeViewable();\n makeUnviewableAtEnd = true;\n }\n }\n /* this updates the URL */\n this.suppressFragmentChange = false;\n this.jumpToIndex(pageIndex);\n\n // Reset it to unviewable if it wasn't resolved\n if (makeUnviewableAtEnd) {\n book.getPage(pageIndex).makeViewable(false);\n }\n};\n\n/**\n * Removes all search pins\n */\nBookReader.prototype.removeSearchResults = function(suppressFragmentChange = false) {\n this.removeSearchHilites(); //be sure to set all box.divs to null\n this.searchTerm = null;\n this.searchResults = null;\n if (!suppressFragmentChange) {\n this.trigger(BookReader.eventNames.fragmentChange);\n }\n};\n\n/**\n * Returns true if a search highlight is currently being displayed\n * @returns {boolean}\n */\nBookReader.prototype.searchHighlightVisible = function() {\n const results = this.searchResults;\n let visiblePages = [];\n if (null == results) return false;\n\n if (this.constMode2up == this.mode) {\n visiblePages = [this.twoPage.currentIndexL, this.twoPage.currentIndexR];\n } else if (this.constMode1up == this.mode) {\n visiblePages = [this.currentIndex()];\n } else {\n return false;\n }\n\n results.matches.some(match => {\n return match.par[0].boxes.some(box => {\n const pageIndex = this.leafNumToIndex(box.page);\n if (jQuery.inArray(pageIndex, visiblePages) >= 0) {\n return true;\n }\n });\n });\n\n return false;\n};\n","class SearchView {\n /**\n * @param {object} params\n * @param {object} params.br The BookReader instance\n * @param {function} params.cancelSearch callback when a user wants to cancel search\n *\n * @event BookReader:SearchResultsCleared - when the search results nav gets cleared\n * @event BookReader:ToggleSearchMenu - when search results menu should toggle\n */\n constructor({ br, searchCancelledCallback = () => {} }) {\n this.br = br;\n\n // Search results are returned as a text blob with the hits wrapped in\n // triple mustaches. Hits occasionally include text beyond the search\n // term, so everything within the staches is captured and wrapped.\n this.matcher = new RegExp('{{{(.+?)}}}', 'g');\n this.matches = [];\n this.cacheDOMElements();\n this.bindEvents();\n this.cancelSearch = searchCancelledCallback;\n }\n\n cacheDOMElements() {\n this.dom = {};\n // Search input within the top toolbar. Will be removed once the mobile menu is replaced.\n this.dom.toolbarSearch = this.buildToolbarSearch();\n }\n\n /**\n * @param {string} query\n */\n setQuery(query) {\n this.br.$('[name=\"query\"]').val(query);\n }\n\n emptyMatches() {\n this.matches = [];\n }\n\n removeResultPins() {\n this.br.$('.BRnavpos .BRsearch').remove();\n }\n\n clearSearchFieldAndResults(dispatchEventWhenComplete = true) {\n this.br.removeSearchResults();\n this.removeResultPins();\n this.emptyMatches();\n this.setQuery('');\n this.teardownSearchNavigation();\n if (dispatchEventWhenComplete) {\n this.br.trigger('SearchResultsCleared');\n }\n }\n\n toggleSidebar() {\n this.br.trigger('ToggleSearchMenu');\n }\n\n renderSearchNavigation() {\n const selector = 'BRsearch-navigation';\n $('.BRnav').before(`\n <div class=\"${selector}\">\n <button class=\"toggle-sidebar\">\n <h4>\n <span class=\"icon icon-search\"></span> Results\n </h4>\n </button>\n <div class=\"pagination\">\n <button class=\"prev\" title=\"Previous result\"><span class=\"icon icon-chevron hflip\"></span></button>\n <span data-id=\"resultsCount\">${this.resultsPosition()}</span>\n <button class=\"next\" title=\"Next result\"><span class=\"icon icon-chevron\"></button>\n </div>\n <button class=\"clear\" title=\"Clear search results\">\n <span class=\"icon icon-close\"></span>\n </button>\n </div>\n `);\n this.dom.searchNavigation = $(`.${selector}`);\n }\n\n resultsPosition() {\n let positionMessage = `${this.matches.length} result${this.matches.length === 1 ? '' : 's'}`;\n if (~this.currentMatchIndex) {\n positionMessage = `${this.currentMatchIndex + 1} / ${this.matches.length}`;\n }\n return positionMessage;\n }\n\n bindSearchNavigationEvents() {\n if (!this.dom.searchNavigation) { return; }\n const namespace = 'searchNavigation';\n\n this.dom.searchNavigation\n .on(`click.${namespace}`, '.clear', this.clearSearchFieldAndResults.bind(this))\n .on(`click.${namespace}`, '.prev', this.showPrevResult.bind(this))\n .on(`click.${namespace}`, '.next', this.showNextResult.bind(this))\n .on(`click.${namespace}`, '.toggle-sidebar', this.toggleSidebar.bind(this))\n .on(`click.${namespace}`, false);\n }\n\n showPrevResult() {\n if (this.currentMatchIndex === 0) { return; }\n if (this.br.mode === this.br.constModeThumb) { this.br.switchMode(this.br.constMode1up); }\n if (!~this.currentMatchIndex) {\n this.currentMatchIndex = this.getClosestMatchIndex((start, end, comparator) => end[0] > comparator) + 1;\n }\n this.br.$('.BRnavline .BRsearch').eq(--this.currentMatchIndex).click();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n showNextResult() {\n if (this.currentMatchIndex + 1 === this.matches.length) { return; }\n if (this.br.mode === this.br.constModeThumb) { this.br.switchMode(this.br.constMode1up); }\n if (!~this.currentMatchIndex) {\n this.currentMatchIndex = this.getClosestMatchIndex((start, end, comparator) => start[start.length - 1] > comparator) - 1;\n }\n this.br.$('.BRnavline .BRsearch').eq(++this.currentMatchIndex).click();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n /**\n * Obtains closest match based on the logical comparison function passed in.\n * When the comparison function returns true, the starting (left) half of the\n * matches array is used in the binary split, else the ending (right) half is\n * used. A recursive call is made to perform the same split and comparison\n * on the winning half of the matches. This is traditionally known as binary\n * search (https://en.wikipedia.org/wiki/Binary_search_algorithm), and in\n * most cases (medium to large search result arrays) should outperform\n * traversing the array from start to finish. In the case of small arrays,\n * the speed difference is negligible.\n *\n * @param {function} comparisonFn\n * @return {number} matchIndex\n */\n getClosestMatchIndex(comparisonFn) {\n const matchPages = this.matches.map((m) => m.par[0].page);\n const currentPage = this.br.currentIndex() + 1;\n const closestTo = (pool, comparator) => {\n if (pool.length === 1) { return pool[0]; }\n const start = pool.slice(0, pool.length / 2);\n const end = pool.slice(pool.length / 2);\n return closestTo((comparisonFn(start, end, comparator) ? start : end), comparator);\n };\n\n const closestPage = closestTo(matchPages, currentPage);\n return this.matches.indexOf(this.matches.find((m) => m.par[0].page === closestPage));\n }\n\n updateResultsPosition() {\n this.dom.searchNavigation.find('[data-id=resultsCount]').text(this.resultsPosition());\n }\n\n updateSearchNavigationButtons() {\n this.dom.searchNavigation.find('.prev').attr('disabled', !this.currentMatchIndex);\n this.dom.searchNavigation.find('.next').attr('disabled', this.currentMatchIndex + 1 === this.matches.length);\n }\n\n teardownSearchNavigation() {\n if (!this.dom.searchNavigation) {\n this.dom.searchNavigation = $('.BRsearch-navigation');\n }\n if (!this.dom.searchNavigation.length) { return; }\n\n this.dom.searchNavigation.off('.searchNavigation').remove();\n this.dom.searchNavigation = null;\n this.br.resize();\n }\n\n setCurrentMatchIndex() {\n let matchingSearchResult;\n if (this.br.mode === this.br.constModeThumb) {\n this.currentMatchIndex = -1;\n return;\n }\n if (this.br.mode === this.br.constMode2up) {\n matchingSearchResult = this.find2upMatchingSearchResult();\n }\n else {\n matchingSearchResult = this.find1upMatchingSearchResult();\n }\n this.currentMatchIndex = this.matches.indexOf(matchingSearchResult);\n }\n\n find1upMatchingSearchResult() {\n return this.matches.find((m) => this.br.currentIndex() === m.par[0].page - 1);\n }\n\n find2upMatchingSearchResult() {\n return this.matches.find((m) => this.br._isIndexDisplayed(m.par[0].page - 1));\n }\n\n updateSearchNavigation() {\n if (!this.matches.length) { return; }\n\n this.setCurrentMatchIndex();\n this.updateResultsPosition();\n this.updateSearchNavigationButtons();\n }\n\n /**\n * @param {boolean} bool\n */\n togglePinsFor(bool) {\n const pinsVisibleState = bool ? 'visible' : 'hidden';\n this.br.refs.$BRfooter.find('.BRsearch').css({ visibility: pinsVisibleState });\n }\n\n buildToolbarSearch() {\n const toolbarSearch = document.createElement('span');\n toolbarSearch.classList.add('BRtoolbarSection', 'BRtoolbarSectionSearch');\n toolbarSearch.innerHTML = `\n <form class=\"BRbooksearch desktop\">\n <input type=\"search\" name=\"query\" class=\"BRsearchInput\" value=\"\" placeholder=\"Search inside\"/>\n <button type=\"submit\" class=\"BRsearchSubmit\">\n <img src=\"${this.br.imagesBaseURL}icon_search_button.svg\" />\n </button>\n </form>\n `;\n return toolbarSearch;\n }\n\n /**\n * @param {array} matches\n */\n renderPins(matches) {\n matches.forEach((match) => {\n const queryString = match.text;\n const pageIndex = this.br.leafNumToIndex(match.par[0].page);\n const pageNumber = this.br.getPageNum(pageIndex);\n const uiStringSearch = \"Search result\"; // i18n\n const uiStringPage = \"Page\"; // i18n\n\n const percentThrough = this.br.constructor.util.cssPercentage(pageIndex, this.br.getNumLeafs() - 1);\n\n const queryStringWithB = queryString.replace(this.matcher, '<b>$1</b>');\n\n let queryStringWithBTruncated = '';\n\n if (queryString.length > 100) {\n queryStringWithBTruncated = queryString\n .replace(/^(.{100}[^\\s]*).*/, \"$1\")\n .replace(this.matcher, '<b>$1</b>')\n + '...';\n }\n\n // draw marker\n $('<div>')\n .addClass('BRsearch')\n .css({\n left: percentThrough,\n })\n .attr('title', uiStringSearch)\n .append(`\n <div class=\"BRquery\">\n <div>${queryStringWithBTruncated || queryStringWithB}</div>\n <div>${uiStringPage} ${pageNumber}</div>\n </div>\n `)\n .data({ pageIndex })\n .appendTo(this.br.$('.BRnavline'))\n .on(\"mouseenter\", (event) => {\n // remove from other markers then turn on just for this\n // XXX should be done when nav slider moves\n const marker = event.currentTarget;\n const tooltip = marker.querySelector('.BRquery');\n const tooltipOffset = tooltip.getBoundingClientRect();\n const targetOffset = marker.getBoundingClientRect();\n const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;\n if (tooltipOffset.x - boxSizeAdjust < 0) {\n tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);\n }\n $('.BRsearch,.BRchapter').removeClass('front');\n $(event.target).addClass('front');\n })\n .on(\"mouseleave\", (event) => $(event.target).removeClass('front'))\n .on(\"click\", function (event) {\n // closures are nested and deep, using an arrow function breaks references.\n // Todo: update to arrow function & clean up closures\n // to remove `bind` dependency\n this.br._searchPluginGoToResult(+$(event.target).data('pageIndex'));\n }.bind(this));\n });\n }\n\n /**\n * @param {boolean} bool\n */\n toggleSearchPending(bool) {\n if (bool) {\n this.br.showProgressPopup(\"Search results will appear below...\", () => this.progressPopupClosed());\n }\n else {\n this.br.removeProgressPopup();\n }\n }\n\n /**\n * Primary callback when user cancels search popup\n */\n progressPopupClosed() {\n this.toggleSearchPending();\n this.cancelSearch();\n }\n\n renderErrorModal(textIsProcessing = false) {\n const errorDetails = `${!textIsProcessing ? 'The text may still be processing. ' : ''}Please try again.`;\n this.renderModalMessage(`\n Sorry, there was an error with your search.\n <br />\n ${errorDetails}\n `);\n this.delayModalRemovalFor(4000);\n }\n\n renderBookNotIndexedModal() {\n this.renderModalMessage(`\n <p>\n This book hasn't been indexed for searching yet.\n We've just started indexing it, so search should be available soon.\n <br />\n Please try again later. Thanks!\n </p>\n `);\n this.delayModalRemovalFor(5000);\n }\n\n renderResultsEmptyModal() {\n this.renderModalMessage('No matches were found.');\n this.delayModalRemovalFor(2000);\n }\n\n /**\n * @param {string} messageHTML The innerHTML string used to popupate the modal contents\n */\n renderModalMessage(messageHTML) {\n const modal = document.createElement('div');\n modal.classList.add('BRprogresspopup', 'search_modal');\n modal.innerHTML = messageHTML;\n document.querySelector(this.br.el).append(modal);\n }\n\n /**\n * @param {number} timeoutMS\n */\n delayModalRemovalFor(timeoutMS) {\n setTimeout(this.br.removeProgressPopup.bind(this.br), timeoutMS);\n }\n\n /**\n * @param {Event} e\n */\n submitHandler(e) {\n e.preventDefault();\n const query = e.target.querySelector('[name=\"query\"]').value;\n if (!query.length) { return false; }\n this.br.search(query);\n this.emptyMatches();\n this.toggleSearchPending(true);\n return false;\n }\n\n /**\n * @param {Event} e\n * @param {object} properties\n * @param {object} properties.results\n * @param {object} properties.options\n */\n handleSearchCallback(e, { results, options }) {\n this.matches = results.matches;\n this.setCurrentMatchIndex();\n this.teardownSearchNavigation();\n this.renderSearchNavigation();\n this.bindSearchNavigationEvents();\n this.renderPins(results.matches);\n this.toggleSearchPending(false);\n if (options.goToFirstResult) {\n $(document).one('BookReader:pageChanged', () => {\n this.br.resize();\n });\n } else {\n this.br.resize();\n }\n }\n\n /**\n * @param {Event} e\n */\n handleNavToggledCallback(e) {\n const is_visible = this.br.navigationIsVisible();\n this.togglePinsFor(is_visible);\n }\n\n handleSearchStarted() {\n this.emptyMatches();\n this.br.removeSearchHilites();\n this.removeResultPins();\n this.toggleSearchPending(true);\n this.teardownSearchNavigation();\n this.setQuery(this.br.searchTerm);\n }\n\n /**\n * Event listener for: `BookReader:SearchCallbackError`\n * @param {CustomEvent} event\n */\n handleSearchCallbackError(event = {}) {\n this.toggleSearchPending(false);\n const isIndexed = event?.detail?.props?.results?.indexed;\n this.renderErrorModal(isIndexed);\n }\n\n handleSearchCallbackBookNotIndexed() {\n this.toggleSearchPending(false);\n this.renderBookNotIndexedModal();\n }\n\n handleSearchCallbackEmpty() {\n this.toggleSearchPending(false);\n this.renderResultsEmptyModal();\n }\n\n bindEvents() {\n const namespace = 'BookReader:';\n\n window.addEventListener(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this));\n $(document).on(`${namespace}SearchCallback`, this.handleSearchCallback.bind(this))\n .on(`${namespace}navToggled`, this.handleNavToggledCallback.bind(this))\n .on(`${namespace}SearchStarted`, this.handleSearchStarted.bind(this))\n .on(`${namespace}SearchCallbackBookNotIndexed`, this.handleSearchCallbackBookNotIndexed.bind(this))\n .on(`${namespace}SearchCallbackEmpty`, this.handleSearchCallbackEmpty.bind(this))\n .on(`${namespace}pageChanged`, this.updateSearchNavigation.bind(this));\n\n this.dom.toolbarSearch.querySelector('form').addEventListener('submit', this.submitHandler.bind(this));\n }\n}\n\nexport default SearchView;\n","var $ = require('../internals/export');\nvar $entries = require('../internals/object-to-array').entries;\n\n// `Object.entries` method\n// https://tc39.es/ecma262/#sec-object.entries\n$({ target: 'Object', stat: true }, {\n entries: function entries(O) {\n return $entries(O);\n }\n});\n"],"names":["super_","SearchView","br","searchCancelledCallback","this","matcher","RegExp","matches","cacheDOMElements","bindEvents","cancelSearch","dom","toolbarSearch","buildToolbarSearch","query","$","val","remove","dispatchEventWhenComplete","removeSearchResults","removeResultPins","emptyMatches","setQuery","teardownSearchNavigation","trigger","selector","before","resultsPosition","searchNavigation","positionMessage","length","currentMatchIndex","namespace","on","clearSearchFieldAndResults","bind","showPrevResult","showNextResult","toggleSidebar","mode","constModeThumb","switchMode","constMode1up","getClosestMatchIndex","start","end","comparator","eq","click","updateResultsPosition","updateSearchNavigationButtons","comparisonFn","closestPage","closestTo","pool","slice","map","m","par","page","currentIndex","indexOf","find","text","attr","off","resize","matchingSearchResult","constMode2up","find2upMatchingSearchResult","find1upMatchingSearchResult","_isIndexDisplayed","setCurrentMatchIndex","bool","pinsVisibleState","refs","$BRfooter","css","visibility","document","createElement","classList","add","innerHTML","imagesBaseURL","forEach","match","queryString","pageIndex","leafNumToIndex","pageNumber","getPageNum","percentThrough","constructor","util","cssPercentage","getNumLeafs","queryStringWithB","replace","queryStringWithBTruncated","addClass","left","append","data","appendTo","event","marker","currentTarget","tooltip","querySelector","tooltipOffset","getBoundingClientRect","targetOffset","boxSizeAdjust","parseInt","getComputedStyle","paddingLeft","x","style","setProperty","removeClass","target","_searchPluginGoToResult","showProgressPopup","progressPopupClosed","removeProgressPopup","toggleSearchPending","textIsProcessing","errorDetails","renderModalMessage","delayModalRemovalFor","messageHTML","modal","el","timeoutMS","setTimeout","e","preventDefault","value","search","results","options","renderSearchNavigation","bindSearchNavigationEvents","renderPins","goToFirstResult","one","is_visible","navigationIsVisible","togglePinsFor","removeSearchHilites","searchTerm","isIndexed","detail","props","indexed","renderErrorModal","renderBookNotIndexedModal","renderResultsEmptyModal","window","addEventListener","handleSearchCallbackError","handleSearchCallback","handleNavToggledCallback","handleSearchStarted","handleSearchCallbackBookNotIndexed","handleSearchCallbackEmpty","updateSearchNavigation","submitHandler","jQuery","extend","BookReader","defaultOptions","server","bookId","subPrefix","bookPath","enableSearch","searchInsideUrl","initialSearchTerm","prototype","setup","call","searchResults","searchXHR","_cancelSearch","cancelSearchRequest","_searchBoxesByIndex","searchView","undefined","init","term","instance","suppressFragmentChange","buildToolbarElement","$el","after","_createPageContainer","index","pageContainer","renderBoxesInPageContainerLayer","$container","overrides","disablePopup","error","success","eventNames","fragmentChange","serverPath","baseUrl","path","subPrefixWithSlash","lastIndexOf","substr","urlParams","item_id","doc","q","paramStr","param","url","cleanup","BRSearchInProgress","processSearchResults","searchInsideResults","responseHasError","hasCustomError","hasCustomSuccess","BRSearchCallbackError","BRSearchCallback","beforeSend","xhr","ajax","dataType","cache","jsonpCallback","then","abort","updateSearchHilites","_models","book","_BRSearchCallbackError","basePayload","payload","Object","assign","boxesByIndex","boxes","box","push","pageIndexString","parseFloat","getPage","getActivePageContainerElementsForIndex","container","entries","getActivePageContainerElements","makeUnviewableAtEnd","isViewable","fetch","URLSearchParams","id","subprefix","leafNum","r","json","resp","makeViewable","jumpToIndex","searchHighlightVisible","visiblePages","twoPage","currentIndexL","currentIndexR","some","inArray","$entries","stat","O"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (self.webpackChunk_internetarchive_bookreader=self.webpackChunk_internetarchive_bookreader||[]).push([[423],{7967:function(t,e,n){"use strict";n(5666),n(6992),n(1539),n(3948),n(9826),n(9714),n(2222),n(1249),n(4916),n(3123),n(9601),n(8674),n(2526),n(1817),n(2165),n(8783),n(7042),n(8309),n(1038),n(489),n(2419),n(4819),n(5003);var r=n(7775);function o(t){return function(t){if(Array.isArray(t))return t}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return i(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function a(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:u;return null==t?void 0:t.replace(/\{\{([^}]*?)\}\}/g,(function(t,i){if(!i)return t;var a=o(i.split("|").map((function(t){return t.trim()}))),u=a[0],c=a.slice(1);if(!(u in n)&&!(u in e))return t;var s=u in n?n[u]:u in e?e[u]:null;return c.map((function(t){return r[t]})).reduce((function(t,e){return e(t)}),s&&s.toString())}))}n(5306),n(3210),n(5827);var u={urlencode:encodeURIComponent},c=n(3609);function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function l(t,e,n){return(l="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var r=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=g(t)););return t}(t,e);if(r){var o=Object.getOwnPropertyDescriptor(r,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}function f(t,e){return(f=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function p(t,e){return!e||"object"!==s(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function g(t){return(g=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function h(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=t&&("undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"]);if(null!=n){var r,o,i=[],a=!0,u=!1;try{for(n=n.call(t);!(a=(r=n.next()).done)&&(i.push(r.value),!e||i.length!==e);a=!0);}catch(t){u=!0,o=t}finally{try{a||null==n.return||n.return()}finally{if(u)throw o}}return i}}(t,e)||function(t,e){if(t){if("string"==typeof t)return d(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(t,e):void 0}}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function v(t,e,n,r,o,i,a){try{var u=t[i](a),c=u.value}catch(t){return void n(t)}u.done?e(c):Promise.resolve(c).then(r,o)}function y(t){return function(){var e=this,n=arguments;return new Promise((function(r,o){var i=t.apply(e,n);function a(t){v(i,r,o,a,u,"next",t)}function u(t){v(i,r,o,a,u,"throw",t)}a(void 0)}))}}function m(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function b(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function w(t,e,n){return e&&b(t.prototype,e),n&&b(t,n),t}var x=window.BookReader,S={enabled:!0,fullDjvuXmlUrl:null,singlePageDjvuXmlUrl:null},P=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10;m(this,t),this.maxSize=e,this.entries=[]}return w(t,[{key:"add",value:function(t){this.entries.length>=this.maxSize&&this.entries.shift(),this.entries.push(t)}}]),t}(),A=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:S,n=arguments.length>1?arguments[1]:void 0,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:(0,r.vU)(),i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:(0,r.G6)();m(this,t),this.options=e,this.optionVariables=n,this.djvuPagesPromise=null,this.svgParagraphElement="text",this.svgWordElement="tspan",this.insertNewlines=o,this.pointerEventsOnParagraph=i,o&&(this.svgParagraphElement="g",this.svgWordElement="text"),this.pageTextCache=new P,this.maxWordRendered=2500}var e,n;return w(t,[{key:"init",value:function(){this.options.singlePageDjvuXmlUrl||(this.djvuPagesPromise=c.ajax({type:"GET",url:a(this.options.fullDjvuXmlUrl,this.optionVariables),dataType:"html",error:function(t){}}).then((function(t){try{var e=c.parseXML(t);return e&&c(e).find("OBJECT")}catch(t){return}})))}},{key:"getPageText",value:(n=y(regeneratorRuntime.mark((function t(e){var n,r,o=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!this.options.singlePageDjvuXmlUrl){t.next=7;break}if(!(n=this.pageTextCache.entries.find((function(t){return t.index==e})))){t.next=4;break}return t.abrupt("return",n.response);case 4:return t.abrupt("return",c.ajax({type:"GET",url:a(this.options.singlePageDjvuXmlUrl,this.optionVariables,{pageIndex:e}),dataType:"html",error:function(t){}}).then((function(t){try{var n=c.parseXML(t),r=n&&c(n).find("OBJECT")[0];return o.pageTextCache.add({index:e,response:r}),r}catch(t){return}})));case 7:return t.next=9,this.djvuPagesPromise;case 9:if(!(r=t.sent)){t.next=12;break}return t.abrupt("return",r[e]);case 12:case"end":return t.stop()}}),t,this)}))),function(t){return n.apply(this,arguments)})},{key:"interceptCopy",value:function(t){t[0].addEventListener("copy",(function(t){var e=document.getSelection();t.clipboardData.setData("text/plain",e.toString()),t.preventDefault()}))}},{key:"defaultMode",value:function(t){var e=this;t.classList.remove("selectingSVG"),c(t).on("mousedown.textSelectPluginHandler",(function(n){c(n.target).is(".BRwordElement")&&(n.stopPropagation(),t.classList.add("selectingSVG"),c(t).one("mouseup.textSelectPluginHandler",(function(n){""!=window.getSelection().toString()?(n.stopPropagation(),c(t).off(".textSelectPluginHandler"),e.textSelectingMode(t)):t.classList.remove("selectingSVG")})))}))}},{key:"textSelectingMode",value:function(t){var e=this;c(t).on("mousedown.textSelectPluginHandler",(function(t){c(t.target).is(".BRwordElement")||""!=window.getSelection().toString()&&window.getSelection().removeAllRanges(),t.stopPropagation()})),c(t).on("mouseup.textSelectPluginHandler",(function(n){n.stopPropagation(),""==window.getSelection().toString()&&(c(t).off(".textSelectPluginHandler"),e.defaultMode(t))}))}},{key:"stopPageFlip",value:function(t){var e=this,n=t.find("svg.textSelectionSVG");n.length&&(n.each((function(t,n){return e.defaultMode(n)})),this.interceptCopy(t))}},{key:"createTextLayer",value:(e=y(regeneratorRuntime.mark((function t(e,n){var r,o,i,a,u,s=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!n.find(".textSelectionSVG").length){t.next=3;break}return t.abrupt("return");case 3:return t.next=5,this.getPageText(e);case 5:if(r=t.sent){t.next=8;break}return t.abrupt("return");case 8:if(o=c(r).attr("width"),i=c(r).attr("height"),!((a=c(r).find("WORD").length)>this.maxWordRendered)){t.next=14;break}return console.log("Page ".concat(e," has too many words (").concat(a," > ").concat(this.maxWordRendered,"). Not rendering text layer.")),t.abrupt("return");case 14:(u=document.createElementNS("http://www.w3.org/2000/svg","svg")).setAttribute("xmlns","http://www.w3.org/2000/svg"),u.setAttribute("viewBox","0 0 ".concat(o," ").concat(i)),n.append(u),u.setAttribute("class","textSelectionSVG"),u.setAttribute("preserveAspectRatio","none"),c(u).css({width:"100%",position:"absolute",height:"100%",top:"0",left:"0"}),c(r).find("PARAGRAPH").each((function(t,e){var n=c(e).find("WORD");if(n.length){var r=document.createElementNS("http://www.w3.org/2000/svg",s.svgParagraphElement);r.setAttribute("class","BRparagElement"),s.pointerEventsOnParagraph&&(r.style.pointerEvents="all");for(var o=[],i=0;i<n.length;i++){var a=n[i],l=h(c(a).attr("coords").split(",").map(parseFloat),4),f=l[0],p=l[1],g=l[2],d=p-l[3];o.push(d);var v=document.createElementNS("http://www.w3.org/2000/svg",s.svgWordElement);if(v.setAttribute("class","BRwordElement"),v.setAttribute("x",f.toString()),v.setAttribute("y",p.toString()),v.setAttribute("textLength",(g-f).toString()),v.setAttribute("lengthAdjust","spacingAndGlyphs"),v.textContent=a.textContent,r.appendChild(v),i<n.length-1){var y=n[i+1],m=h(c(y).attr("coords").split(",").map(parseFloat),4),b=m[0],w=(m[1],m[2],m[3],document.createElementNS("http://www.w3.org/2000/svg",s.svgWordElement));w.setAttribute("class","BRwordElement"),w.setAttribute("x",g.toString()),w.setAttribute("y",p.toString()),b-g>0&&w.setAttribute("textLength",(b-g).toString()),w.setAttribute("lengthAdjust","spacingAndGlyphs"),w.textContent=" ",r.appendChild(w)}i==n.length-1&&s.insertNewlines&&r.appendChild(document.createTextNode("\n"))}o.sort();var x=o[Math.floor(.85*o.length)];r.setAttribute("font-size",x.toString()),u.appendChild(r)}})),this.stopPageFlip(n);case 23:case"end":return t.stop()}}),t,this)}))),function(t,n){return e.apply(this,arguments)})}]),t}(),R=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&f(t,e)}(o,t);var e,n,r=(e=o,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}(),function(){var t,r=g(e);if(n){var o=g(this).constructor;t=Reflect.construct(r,arguments,o)}else t=r.apply(this,arguments);return p(this,t)});function o(){return m(this,o),r.apply(this,arguments)}return w(o,[{key:"init",value:function(){var t=Object.assign({},S,this.options.plugins.textSelection);t.enabled&&(this.textSelectionPlugin=new A(t,this.options.vars),this.options.plugins.textSelection=t,this.textSelectionPlugin.init()),l(g(o.prototype),"init",this).call(this)}},{key:"_createPageContainer",value:function(t){var e,n=l(g(o.prototype),"_createPageContainer",this).call(this,t),r=this.getNumLeafs()-1;return this.mode!==this.constModeThumb&&t>=0&&t<=r&&(null===(e=this.textSelectionPlugin)||void 0===e||e.createTextLayer(t,n.$container)),n}}]),o}(x);window.BookReader=R},7775:function(t,e,n){"use strict";function r(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:navigator.vendor;return/chrome/i.test(t)&&/google inc/i.test(e)}function o(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent;return/firefox/i.test(t)}function i(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent;return/safari/i.test(t)&&!/chrome|chromium/i.test(t)}n.d(e,{i7:function(){return r},vU:function(){return o},G6:function(){return i}})},7065:function(t,e,n){"use strict";var r=n(3099),o=n(111),i=[].slice,a={},u=function(t,e,n){if(!(e in a)){for(var r=[],o=0;o<e;o++)r[o]="a["+o+"]";a[e]=Function("C,a","return new C("+r.join(",")+")")}return a[e](t,n)};t.exports=Function.bind||function(t){var e=r(this),n=i.call(arguments,1),a=function(){var r=n.concat(i.call(arguments));return this instanceof a?u(e,r.length,r):e.apply(t,r)};return o(e.prototype)&&(a.prototype=e.prototype),a}},6091:function(t,e,n){var r=n(7293),o=n(1361);t.exports=function(t){return r((function(){return!!o[t]()||"​…᠎"!="​…᠎"[t]()||o[t].name!==t}))}},3111:function(t,e,n){var r=n(4488),o="["+n(1361)+"]",i=RegExp("^"+o+o+"*"),a=RegExp(o+o+"*$"),u=function(t){return function(e){var n=String(r(e));return 1&t&&(n=n.replace(i,"")),2&t&&(n=n.replace(a,"")),n}};t.exports={start:u(1),end:u(2),trim:u(3)}},1361:function(t){t.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},9601:function(t,e,n){var r=n(2109),o=n(1574);r({target:"Object",stat:!0,forced:Object.assign!==o},{assign:o})},489:function(t,e,n){var r=n(2109),o=n(7293),i=n(7908),a=n(9518),u=n(8544);r({target:"Object",stat:!0,forced:o((function(){a(1)})),sham:!u},{getPrototypeOf:function(t){return a(i(t))}})},2419:function(t,e,n){var r=n(2109),o=n(5005),i=n(3099),a=n(9670),u=n(111),c=n(30),s=n(7065),l=n(7293),f=o("Reflect","construct"),p=l((function(){function t(){}return!(f((function(){}),[],t)instanceof t)})),g=!l((function(){f((function(){}))})),h=p||g;r({target:"Reflect",stat:!0,forced:h,sham:h},{construct:function(t,e){i(t),a(e);var n=arguments.length<3?t:i(arguments[2]);if(g&&!p)return f(t,e,n);if(t==n){switch(e.length){case 0:return new t;case 1:return new t(e[0]);case 2:return new t(e[0],e[1]);case 3:return new t(e[0],e[1],e[2]);case 4:return new t(e[0],e[1],e[2],e[3])}var r=[null];return r.push.apply(r,e),new(s.apply(t,r))}var o=n.prototype,l=c(u(o)?o:Object.prototype),h=Function.apply.call(t,l,e);return u(h)?h:l}})},4819:function(t,e,n){var r=n(2109),o=n(111),i=n(9670),a=n(6656),u=n(1236),c=n(9518);r({target:"Reflect",stat:!0},{get:function t(e,n){var r,s,l=arguments.length<3?e:arguments[2];return i(e)===l?e[n]:(r=u.f(e,n))?a(r,"value")?r.value:void 0===r.get?void 0:r.get.call(l):o(s=c(e))?t(s,n,l):void 0}})},3210:function(t,e,n){"use strict";var r=n(2109),o=n(3111).trim;r({target:"String",proto:!0,forced:n(6091)("trim")},{trim:function(){return o(this)}})}},function(t){"use strict";t(t.s=7967)}]);
1
+ (self.webpackChunk_internetarchive_bookreader=self.webpackChunk_internetarchive_bookreader||[]).push([[423],{7967:function(t,e,n){"use strict";n(5666),n(6992),n(1539),n(3948),n(9826),n(9714),n(2222),n(1249),n(4916),n(3123),n(2707),n(9601),n(8674),n(2526),n(1817),n(2165),n(8783),n(7042),n(8309),n(1038),n(489),n(2419),n(4819),n(5003);var r=n(9860),o=n(7775);function i(t){return function(t){if(Array.isArray(t))return t}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return a(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?a(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function u(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;return null==t?void 0:t.replace(/\{\{([^}]*?)\}\}/g,(function(t,o){if(!o)return t;var a=i(o.split("|").map((function(t){return t.trim()}))),u=a[0],s=a.slice(1);if(!(u in n)&&!(u in e))return t;var l=u in n?n[u]:u in e?e[u]:null;return s.map((function(t){return r[t]})).reduce((function(t,e){return e(t)}),l&&l.toString())}))}n(5306),n(3210),n(5827);var s={urlencode:encodeURIComponent},l=n(3609);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(t,e,n){return(f="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var r=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=g(t)););return t}(t,e);if(r){var o=Object.getOwnPropertyDescriptor(r,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}function p(t,e){return(p=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(t,e){if(e&&("object"===c(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function g(t){return(g=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function d(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var r,o,i=[],a=!0,u=!1;try{for(n=n.call(t);!(a=(r=n.next()).done)&&(i.push(r.value),!e||i.length!==e);a=!0);}catch(t){u=!0,o=t}finally{try{a||null==n.return||n.return()}finally{if(u)throw o}}return i}}(t,e)||function(t,e){if(t){if("string"==typeof t)return v(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?v(t,e):void 0}}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function v(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function y(t,e,n,r,o,i,a){try{var u=t[i](a),s=u.value}catch(t){return void n(t)}u.done?e(s):Promise.resolve(s).then(r,o)}function m(t){return function(){var e=this,n=arguments;return new Promise((function(r,o){var i=t.apply(e,n);function a(t){y(i,r,o,a,u,"next",t)}function u(t){y(i,r,o,a,u,"throw",t)}a(void 0)}))}}function b(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function w(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function x(t,e,n){return e&&w(t.prototype,e),n&&w(t,n),t}var S=window.BookReader,P={enabled:!0,fullDjvuXmlUrl:null,singlePageDjvuXmlUrl:null},A=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10;b(this,t),this.maxSize=e,this.entries=[]}return x(t,[{key:"add",value:function(t){this.entries.length>=this.maxSize&&this.entries.shift(),this.entries.push(t)}}]),t}(),j=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:P,n=arguments.length>1?arguments[1]:void 0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:(0,o.vU)(),i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:(0,o.G6)();b(this,t),this.options=e,this.optionVariables=n,this.djvuPagesPromise=null,this.svgParagraphElement="text",this.svgWordElement="tspan",this.insertNewlines=r,this.pointerEventsOnParagraph=i,r&&(this.svgParagraphElement="g",this.svgWordElement="text"),this.pageTextCache=new A,this.maxWordRendered=2500}var e,n;return x(t,[{key:"init",value:function(){this.options.singlePageDjvuXmlUrl||(this.djvuPagesPromise=l.ajax({type:"GET",url:u(this.options.fullDjvuXmlUrl,this.optionVariables),dataType:"html",error:function(t){}}).then((function(t){try{var e=l.parseXML(t);return e&&l(e).find("OBJECT")}catch(t){return}})))}},{key:"getPageText",value:(n=m(regeneratorRuntime.mark((function t(e){var n,r,o=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!this.options.singlePageDjvuXmlUrl){t.next=7;break}if(!(n=this.pageTextCache.entries.find((function(t){return t.index==e})))){t.next=4;break}return t.abrupt("return",n.response);case 4:return t.abrupt("return",l.ajax({type:"GET",url:u(this.options.singlePageDjvuXmlUrl,this.optionVariables,{pageIndex:e}),dataType:"html",error:function(t){}}).then((function(t){try{var n=l.parseXML(t),r=n&&l(n).find("OBJECT")[0];return o.pageTextCache.add({index:e,response:r}),r}catch(t){return}})));case 7:return t.next=9,this.djvuPagesPromise;case 9:if(!(r=t.sent)){t.next=12;break}return t.abrupt("return",r[e]);case 12:case"end":return t.stop()}}),t,this)}))),function(t){return n.apply(this,arguments)})},{key:"interceptCopy",value:function(t){t[0].addEventListener("copy",(function(t){var e=document.getSelection();t.clipboardData.setData("text/plain",e.toString()),t.preventDefault()}))}},{key:"defaultMode",value:function(t){var e=this;t.classList.remove("selectingSVG"),l(t).on("mousedown.textSelectPluginHandler",(function(n){l(n.target).is(".BRwordElement")&&(n.stopPropagation(),t.classList.add("selectingSVG"),l(t).one("mouseup.textSelectPluginHandler",(function(n){""!=window.getSelection().toString()?(n.stopPropagation(),l(t).off(".textSelectPluginHandler"),e.textSelectingMode(t)):t.classList.remove("selectingSVG")})))}))}},{key:"textSelectingMode",value:function(t){var e=this;l(t).on("mousedown.textSelectPluginHandler",(function(t){l(t.target).is(".BRwordElement")||""!=window.getSelection().toString()&&window.getSelection().removeAllRanges(),t.stopPropagation()})),l(t).on("mouseup.textSelectPluginHandler",(function(n){n.stopPropagation(),""==window.getSelection().toString()&&(l(t).off(".textSelectPluginHandler"),e.defaultMode(t))}))}},{key:"stopPageFlip",value:function(t){var e=this,n=t.find("svg.textSelectionSVG");n.length&&(n.each((function(t,n){return e.defaultMode(n)})),this.interceptCopy(t))}},{key:"createTextLayer",value:(e=m(regeneratorRuntime.mark((function t(e){var n,o,i,a,u,s=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n=e.page.index,!(o=e.$container).find(".textSelectionSVG").length){t.next=5;break}return t.abrupt("return");case 5:return t.next=7,this.getPageText(n);case 7:if(i=t.sent){t.next=10;break}return t.abrupt("return");case 10:if(!((a=l(i).find("WORD").length)>this.maxWordRendered)){t.next=14;break}return console.log("Page ".concat(n," has too many words (").concat(a," > ").concat(this.maxWordRendered,"). Not rendering text layer.")),t.abrupt("return");case 14:u=(0,r.hy)(e.page,"textSelectionSVG"),o.append(u),l(i).find("PARAGRAPH").each((function(t,e){var n=l(e).find("WORD");if(n.length){var r=document.createElementNS("http://www.w3.org/2000/svg",s.svgParagraphElement);r.setAttribute("class","BRparagElement"),s.pointerEventsOnParagraph&&(r.style.pointerEvents="all");for(var o=[],i=0;i<n.length;i++){var a=n[i],c=d(l(a).attr("coords").split(",").map(parseFloat),4),f=c[0],p=c[1],h=c[2],g=p-c[3];o.push(g);var v=document.createElementNS("http://www.w3.org/2000/svg",s.svgWordElement);if(v.setAttribute("class","BRwordElement"),v.setAttribute("x",f.toString()),v.setAttribute("y",p.toString()),v.setAttribute("textLength",(h-f).toString()),v.setAttribute("lengthAdjust","spacingAndGlyphs"),v.textContent=a.textContent,r.appendChild(v),i<n.length-1){var y=n[i+1],m=d(l(y).attr("coords").split(",").map(parseFloat),4),b=m[0],w=(m[1],m[2],m[3],document.createElementNS("http://www.w3.org/2000/svg",s.svgWordElement));w.setAttribute("class","BRwordElement"),w.setAttribute("x",h.toString()),w.setAttribute("y",p.toString()),b-h>0&&w.setAttribute("textLength",(b-h).toString()),w.setAttribute("lengthAdjust","spacingAndGlyphs"),w.textContent=" ",r.appendChild(w)}i==n.length-1&&s.insertNewlines&&r.appendChild(document.createTextNode("\n"))}o.sort();var x=o[Math.floor(.85*o.length)];r.setAttribute("font-size",x.toString()),u.appendChild(r)}})),this.stopPageFlip(o);case 18:case"end":return t.stop()}}),t,this)}))),function(t){return e.apply(this,arguments)})}]),t}(),E=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&p(t,e)}(o,t);var e,n,r=(e=o,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}(),function(){var t,r=g(e);if(n){var o=g(this).constructor;t=Reflect.construct(r,arguments,o)}else t=r.apply(this,arguments);return h(this,t)});function o(){return b(this,o),r.apply(this,arguments)}return x(o,[{key:"init",value:function(){var t=Object.assign({},P,this.options.plugins.textSelection);t.enabled&&(this.textSelectionPlugin=new j(t,this.options.vars),this.options.plugins.textSelection=t,this.textSelectionPlugin.init()),f(g(o.prototype),"init",this).call(this)}},{key:"_createPageContainer",value:function(t){var e,n=f(g(o.prototype),"_createPageContainer",this).call(this,t);return this.mode!==this.constModeThumb&&n.page&&(null===(e=this.textSelectionPlugin)||void 0===e||e.createTextLayer(n)),n}}]),o}(S);window.BookReader=E},7775:function(t,e,n){"use strict";function r(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:navigator.vendor;return/chrome/i.test(t)&&/google inc/i.test(e)}function o(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent;return/firefox/i.test(t)}function i(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:navigator.userAgent;return/safari/i.test(t)&&!/chrome|chromium/i.test(t)}n.d(e,{i7:function(){return r},vU:function(){return o},G6:function(){return i}})},6091:function(t,e,n){var r=n(7293),o=n(1361);t.exports=function(t){return r((function(){return!!o[t]()||"​…᠎"!="​…᠎"[t]()||o[t].name!==t}))}},3210:function(t,e,n){"use strict";var r=n(2109),o=n(3111).trim;r({target:"String",proto:!0,forced:n(6091)("trim")},{trim:function(){return o(this)}})}},function(t){t(t.s=7967)}]);
2
2
  //# sourceMappingURL=plugin.text_selection.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://@internetarchive/bookreader/./src/util/strings.js","webpack://@internetarchive/bookreader/./src/plugins/plugin.text_selection.js","webpack://@internetarchive/bookreader/./src/util/browserSniffing.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/function-bind.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/string-trim-forced.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/string-trim.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/whitespaces.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.object.assign.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.object.get-prototype-of.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.reflect.construct.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.reflect.get.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.string.trim.js"],"names":["applyVariables","template","vars","overrides","possibleFilters","APPLY_FILTERS","replace","$0","$1","split","map","x","trim","varName","filterNames","value","n","reduce","acc","cur","toString","urlencode","encodeURIComponent","BookReader","window","DEFAULT_OPTIONS","enabled","fullDjvuXmlUrl","singlePageDjvuXmlUrl","Cache","maxSize","this","entries","entry","length","shift","push","TextSelectionPlugin","options","optionVariables","avoidTspans","isFirefox","pointerEventsOnParagraph","isSafari","djvuPagesPromise","svgParagraphElement","svgWordElement","insertNewlines","pageTextCache","maxWordRendered","$","ajax","type","url","dataType","error","e","then","res","xmlMap","parseXML","find","index","cachedEntry","response","pageIndex","xmlDoc","result","add","XMLpagesArr","$container","addEventListener","event","selection","document","getSelection","clipboardData","setData","preventDefault","svg","classList","remove","on","target","is","stopPropagation","one","off","textSelectingMode","removeAllRanges","defaultMode","$svg","each","i","s","interceptCopy","getPageText","XMLpage","XMLwidth","attr","XMLheight","totalWords","console","log","createElementNS","setAttribute","append","css","paragraph","words","paragSvg","style","pointerEvents","wordHeightArr","currWord","parseFloat","left","bottom","right","wordHeight","wordTspan","textContent","appendChild","nextWord","leftNext","spaceTspan","createTextNode","sort","paragWordHeight","Math","floor","stopPageFlip","BookreaderWithTextSelection","Object","assign","plugins","textSelection","textSelectionPlugin","init","pageContainer","lastPageIndex","getNumLeafs","mode","constModeThumb","createTextLayer","isChrome","userAgent","navigator","vendor","test","aFunction","isObject","slice","factories","construct","C","argsLength","args","list","Function","join","module","exports","bind","that","fn","partArgs","call","arguments","boundFunction","concat","apply","prototype","fails","whitespaces","METHOD_NAME","name","requireObjectCoercible","whitespace","ltrim","RegExp","rtrim","createMethod","TYPE","$this","string","String","start","end","stat","forced","toObject","nativeGetPrototypeOf","CORRECT_PROTOTYPE_GETTER","sham","getPrototypeOf","it","getBuiltIn","anObject","create","nativeConstruct","NEW_TARGET_BUG","F","ARGS_BUG","FORCED","Target","newTarget","$args","proto","instance","has","getOwnPropertyDescriptorModule","get","propertyKey","descriptor","receiver","f","undefined","$trim","forcedStringTrimMethod"],"mappings":"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","file":"plugins/plugin.text_selection.js","sourcesContent":["/**\n * @typedef {String} StringWithVars\n * A template string with {{foo}} style variables\n * Also supports filters, like {{bookPath|urlencode}} (See APPLY_FILTERS for the\n * supported list of filters)\n **/\n\n/**\n * @param {StringWithVars|String} template\n * @param { {[varName: string]: { toString: () => string} } } vars\n * @param { {[varName: string]: { toString: () => string} } } [overrides]\n */\nexport function applyVariables(template, vars, overrides = {}, possibleFilters = APPLY_FILTERS) {\n return template?.replace(/\\{\\{([^}]*?)\\}\\}/g, ($0, $1) => {\n if (!$1) return $0;\n /** @type {string} */\n const expression = $1;\n const [varName, ...filterNames] = expression.split('|').map(x => x.trim());\n const defined = varName in overrides || varName in vars;\n\n // If it's not defined, don't expand it at all\n if (!defined) return $0;\n\n const value = varName in overrides ? overrides[varName]\n : varName in vars ? vars[varName] : null;\n const filters = filterNames.map(n => possibleFilters[n]);\n return filters.reduce((acc, cur) => cur(acc), value && value.toString());\n });\n}\n\n/** @type { {[filterName: String]:( string => string)} } */\nexport const APPLY_FILTERS = {\n urlencode: encodeURIComponent,\n};\n","//@ts-check\nimport { isFirefox, isSafari } from '../util/browserSniffing.js';\nimport { applyVariables } from '../util/strings.js';\n/** @typedef {import('../util/strings.js').StringWithVars} StringWithVars */\n\nconst BookReader = /** @type {typeof import('../BookReader').default} */(window.BookReader);\n\nexport const DEFAULT_OPTIONS = {\n enabled: true,\n /** @type {StringWithVars} The URL to fetch the entire DJVU xml. Supports options.vars */\n fullDjvuXmlUrl: null,\n /** @type {StringWithVars} The URL to fetch a single page of the DJVU xml. Supports options.vars. Also has {{pageIndex}} */\n singlePageDjvuXmlUrl: null,\n};\n/** @typedef {typeof DEFAULT_OPTIONS} TextSelectionPluginOptions */\n\n/**\n * @template T\n */\nexport class Cache {\n constructor(maxSize = 10) {\n this.maxSize = maxSize;\n /** @type {T[]} */\n this.entries = [];\n }\n\n /**\n * @param {T} entry\n */\n add(entry) {\n if (this.entries.length >= this.maxSize) {\n this.entries.shift();\n }\n this.entries.push(entry);\n }\n}\n\nexport class TextSelectionPlugin {\n\n constructor(options = DEFAULT_OPTIONS, optionVariables, avoidTspans = isFirefox(), pointerEventsOnParagraph = isSafari()) {\n this.options = options;\n this.optionVariables = optionVariables;\n /**@type {PromiseLike<JQuery<HTMLElement>|undefined>} */\n this.djvuPagesPromise = null;\n // Using text elements instead of tspans for words because Firefox does not allow svg tspan stretch.\n // Tspans are necessary on Chrome because they prevent newline character after every word when copying\n this.svgParagraphElement = \"text\";\n this.svgWordElement = \"tspan\";\n this.insertNewlines = avoidTspans\n // Safari has a bug where `pointer-events` doesn't work on `<tspans>`. So\n // there we will set `pointer-events: all` on the paragraph element. We don't\n // do this everywhere, because it's a worse experience. Thanks Safari :/\n this.pointerEventsOnParagraph = pointerEventsOnParagraph;\n if (avoidTspans) {\n this.svgParagraphElement = \"g\";\n this.svgWordElement = \"text\";\n }\n\n /** @type {Cache<{index: number, response: any}>} */\n this.pageTextCache = new Cache();\n\n /**\n * Sometimes there are too many words on a page, and the browser becomes near\n * unusable. For now don't render text layer for pages with too many words.\n */\n this.maxWordRendered = 2500;\n }\n\n init() {\n // Only fetch the full djvu xml if the single page url isn't there\n if (this.options.singlePageDjvuXmlUrl) return;\n this.djvuPagesPromise = $.ajax({\n type: \"GET\",\n url: applyVariables(this.options.fullDjvuXmlUrl, this.optionVariables),\n dataType: \"html\",\n error: (e) => undefined\n }).then((res) => {\n try {\n const xmlMap = $.parseXML(res);\n return xmlMap && $(xmlMap).find(\"OBJECT\");\n } catch (e) {\n return undefined;\n }\n });\n }\n\n /**\n * @param {number} index\n * @returns {Promise<HTMLElement|undefined>}\n */\n async getPageText(index) {\n if (this.options.singlePageDjvuXmlUrl) {\n const cachedEntry = this.pageTextCache.entries.find(x => x.index == index);\n if (cachedEntry) {\n return cachedEntry.response;\n }\n return $.ajax({\n type: \"GET\",\n url: applyVariables(this.options.singlePageDjvuXmlUrl, this.optionVariables, { pageIndex: index }),\n dataType: \"html\",\n error: (e) => undefined,\n }).then((res) => {\n try {\n const xmlDoc = $.parseXML(res);\n const result = xmlDoc && $(xmlDoc).find(\"OBJECT\")[0];\n this.pageTextCache.add({ index, response: result });\n return result;\n } catch (e) {\n return undefined;\n }\n });\n } else {\n const XMLpagesArr = await this.djvuPagesPromise;\n if (XMLpagesArr) return XMLpagesArr[index];\n }\n }\n\n /**\n * Intercept copied text to remove any styling applied to it\n * @param {JQuery} $container\n */\n interceptCopy($container) {\n $container[0].addEventListener('copy', (event) => {\n const selection = document.getSelection();\n event.clipboardData.setData('text/plain', selection.toString());\n event.preventDefault();\n });\n }\n\n /**\n * Applies mouse events when in default mode\n * @param {SVGElement} svg\n */\n defaultMode(svg) {\n svg.classList.remove(\"selectingSVG\");\n $(svg).on(\"mousedown.textSelectPluginHandler\", (event) => {\n if (!$(event.target).is(\".BRwordElement\")) return;\n event.stopPropagation();\n svg.classList.add(\"selectingSVG\");\n $(svg).one(\"mouseup.textSelectPluginHandler\", (event) => {\n if (window.getSelection().toString() != \"\") {\n event.stopPropagation();\n $(svg).off(\".textSelectPluginHandler\");\n this.textSelectingMode(svg);\n }\n else svg.classList.remove(\"selectingSVG\");\n })\n })\n }\n\n /**\n * Applies mouse events when in textSelecting mode\n * @param {SVGElement} svg\n */\n textSelectingMode(svg) {\n $(svg).on('mousedown.textSelectPluginHandler', (event) => {\n if (!$(event.target).is(\".BRwordElement\")) {\n if (window.getSelection().toString() != \"\") window.getSelection().removeAllRanges();\n }\n event.stopPropagation();\n })\n $(svg).on('mouseup.textSelectPluginHandler', (event) => {\n event.stopPropagation();\n if (window.getSelection().toString() == \"\") {\n $(svg).off(\".textSelectPluginHandler\");\n this.defaultMode(svg); }\n })\n }\n\n /**\n * Initializes text selection modes if there is an svg on the page\n * @param {JQuery} $container\n */\n stopPageFlip($container) {\n /** @type {JQuery<SVGElement>} */\n const $svg = $container.find('svg.textSelectionSVG');\n if (!$svg.length) return;\n $svg.each((i, s) => this.defaultMode(s))\n this.interceptCopy($container);\n }\n\n /**\n * @param {number} pageIndex\n * @param {JQuery} $container\n */\n async createTextLayer(pageIndex, $container) {\n const $svgLayers = $container.find('.textSelectionSVG');\n if ($svgLayers.length) return;\n const XMLpage = await this.getPageText(pageIndex);\n if (!XMLpage) return;\n const XMLwidth = $(XMLpage).attr(\"width\");\n const XMLheight = $(XMLpage).attr(\"height\");\n\n const totalWords = $(XMLpage).find(\"WORD\").length;\n if (totalWords > this.maxWordRendered) {\n console.log(`Page ${pageIndex} has too many words (${totalWords} > ${this.maxWordRendered}). Not rendering text layer.`);\n return;\n }\n\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n svg.setAttribute(\"viewBox\", `0 0 ${XMLwidth} ${XMLheight}`);\n $container.append(svg);\n svg.setAttribute('class', 'textSelectionSVG');\n svg.setAttribute('preserveAspectRatio', 'none');\n $(svg).css({\n \"width\": \"100%\",\n \"position\": \"absolute\",\n \"height\": \"100%\",\n \"top\": \"0\",\n \"left\": \"0\",\n });\n\n $(XMLpage).find(\"PARAGRAPH\").each((i, paragraph) => {\n // Adding text element for each paragraph in the page\n const words = $(paragraph).find(\"WORD\");\n if (!words.length) return;\n const paragSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgParagraphElement);\n paragSvg.setAttribute(\"class\", \"BRparagElement\");\n if (this.pointerEventsOnParagraph) {\n paragSvg.style.pointerEvents = \"all\";\n }\n\n const wordHeightArr = [];\n\n for (let i = 0; i < words.length; i++) {\n // Adding tspan for each word in paragraph\n const currWord = words[i];\n // eslint-disable-next-line no-unused-vars\n const [left, bottom, right, top] = $(currWord).attr(\"coords\").split(',').map(parseFloat);\n const wordHeight = bottom - top;\n wordHeightArr.push(wordHeight);\n\n const wordTspan = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgWordElement);\n wordTspan.setAttribute(\"class\", \"BRwordElement\");\n wordTspan.setAttribute(\"x\", left.toString());\n wordTspan.setAttribute(\"y\", bottom.toString());\n wordTspan.setAttribute(\"textLength\", (right - left).toString());\n wordTspan.setAttribute(\"lengthAdjust\", \"spacingAndGlyphs\");\n wordTspan.textContent = currWord.textContent;\n paragSvg.appendChild(wordTspan);\n\n // Adding spaces after words except at the end of the paragraph\n // TODO: assumes left-to-right text\n if (i < words.length - 1) {\n const nextWord = words[i + 1];\n // eslint-disable-next-line no-unused-vars\n const [leftNext, bottomNext, rightNext, topNext] = $(nextWord).attr(\"coords\").split(',').map(parseFloat);\n const spaceTspan = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgWordElement);\n spaceTspan.setAttribute(\"class\", \"BRwordElement\");\n spaceTspan.setAttribute(\"x\", right.toString());\n spaceTspan.setAttribute(\"y\", bottom.toString());\n if ((leftNext - right) > 0) spaceTspan.setAttribute(\"textLength\", (leftNext - right).toString());\n spaceTspan.setAttribute(\"lengthAdjust\", \"spacingAndGlyphs\");\n spaceTspan.textContent = \" \";\n paragSvg.appendChild(spaceTspan);\n }\n\n // Adds newline at the end of paragraph on Firefox\n if ((i == words.length - 1 && (this.insertNewlines))) {\n paragSvg.appendChild(document.createTextNode(\"\\n\"));\n }\n }\n\n wordHeightArr.sort();\n const paragWordHeight = wordHeightArr[Math.floor(wordHeightArr.length * 0.85)];\n paragSvg.setAttribute(\"font-size\", paragWordHeight.toString());\n svg.appendChild(paragSvg);\n })\n this.stopPageFlip($container);\n }\n}\n\nexport class BookreaderWithTextSelection extends BookReader {\n init() {\n const options = Object.assign({}, DEFAULT_OPTIONS, this.options.plugins.textSelection);\n if (options.enabled) {\n this.textSelectionPlugin = new TextSelectionPlugin(options, this.options.vars);\n // Write this back; this way the plugin is the source of truth, and BR just\n // contains a reference to it.\n this.options.plugins.textSelection = options;\n this.textSelectionPlugin.init();\n }\n super.init();\n }\n\n /**\n * @param {number} index\n */\n _createPageContainer(index) {\n const pageContainer = super._createPageContainer(index);\n // Disable if thumb mode; it's too janky\n // index can be -1 for \"pre-cover\" region\n // Added checking of lastPageIndex to avoid loop around index value\n const lastPageIndex = this.getNumLeafs() - 1;\n if (this.mode !== this.constModeThumb && (index >= 0 && index <= lastPageIndex)) {\n this.textSelectionPlugin?.createTextLayer(index, pageContainer.$container);\n }\n return pageContainer;\n }\n}\nwindow.BookReader = BookreaderWithTextSelection;\nexport default BookreaderWithTextSelection;\n","\n/**\n * Checks whether the current browser is a Chrome/Chromium browser\n * Code from https://stackoverflow.com/a/4565120/2317712\n * @param {string} [userAgent]\n * @param {string} [vendor]\n * @return {boolean}\n */\nexport function isChrome(userAgent = navigator.userAgent, vendor = navigator.vendor) {\n return /chrome/i.test(userAgent) && /google inc/i.test(vendor);\n}\n\n/**\n * Checks whether the current browser is firefox\n * @param {string} [userAgent]\n * @return {boolean}\n */\nexport function isFirefox(userAgent = navigator.userAgent) {\n return /firefox/i.test(userAgent);\n}\n\n/**\n * Checks whether the current browser is safari\n * https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#Browser_Name\n * @param {string} [userAgent]\n * @return {boolean}\n */\nexport function isSafari(userAgent = navigator.userAgent) {\n return /safari/i.test(userAgent) && !/chrome|chromium/i.test(userAgent);\n}\n","'use strict';\nvar aFunction = require('../internals/a-function');\nvar isObject = require('../internals/is-object');\n\nvar slice = [].slice;\nvar factories = {};\n\nvar construct = function (C, argsLength, args) {\n if (!(argsLength in factories)) {\n for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']';\n // eslint-disable-next-line no-new-func -- we have no proper alternatives, IE8- only\n factories[argsLength] = Function('C,a', 'return new C(' + list.join(',') + ')');\n } return factories[argsLength](C, args);\n};\n\n// `Function.prototype.bind` method implementation\n// https://tc39.es/ecma262/#sec-function.prototype.bind\nmodule.exports = Function.bind || function bind(that /* , ...args */) {\n var fn = aFunction(this);\n var partArgs = slice.call(arguments, 1);\n var boundFunction = function bound(/* args... */) {\n var args = partArgs.concat(slice.call(arguments));\n return this instanceof boundFunction ? construct(fn, args.length, args) : fn.apply(that, args);\n };\n if (isObject(fn.prototype)) boundFunction.prototype = fn.prototype;\n return boundFunction;\n};\n","var fails = require('../internals/fails');\nvar whitespaces = require('../internals/whitespaces');\n\nvar non = '\\u200B\\u0085\\u180E';\n\n// check that a method works with the correct list\n// of whitespaces and has a correct name\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;\n });\n};\n","var requireObjectCoercible = require('../internals/require-object-coercible');\nvar whitespaces = require('../internals/whitespaces');\n\nvar whitespace = '[' + whitespaces + ']';\nvar ltrim = RegExp('^' + whitespace + whitespace + '*');\nvar rtrim = RegExp(whitespace + whitespace + '*$');\n\n// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation\nvar createMethod = function (TYPE) {\n return function ($this) {\n var string = String(requireObjectCoercible($this));\n if (TYPE & 1) string = string.replace(ltrim, '');\n if (TYPE & 2) string = string.replace(rtrim, '');\n return string;\n };\n};\n\nmodule.exports = {\n // `String.prototype.{ trimLeft, trimStart }` methods\n // https://tc39.es/ecma262/#sec-string.prototype.trimstart\n start: createMethod(1),\n // `String.prototype.{ trimRight, trimEnd }` methods\n // https://tc39.es/ecma262/#sec-string.prototype.trimend\n end: createMethod(2),\n // `String.prototype.trim` method\n // https://tc39.es/ecma262/#sec-string.prototype.trim\n trim: createMethod(3)\n};\n","// a string of all valid unicode whitespaces\nmodule.exports = '\\u0009\\u000A\\u000B\\u000C\\u000D\\u0020\\u00A0\\u1680\\u2000\\u2001\\u2002' +\n '\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n","var $ = require('../internals/export');\nvar assign = require('../internals/object-assign');\n\n// `Object.assign` method\n// https://tc39.es/ecma262/#sec-object.assign\n// eslint-disable-next-line es/no-object-assign -- required for testing\n$({ target: 'Object', stat: true, forced: Object.assign !== assign }, {\n assign: assign\n});\n","var $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar toObject = require('../internals/to-object');\nvar nativeGetPrototypeOf = require('../internals/object-get-prototype-of');\nvar CORRECT_PROTOTYPE_GETTER = require('../internals/correct-prototype-getter');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeGetPrototypeOf(1); });\n\n// `Object.getPrototypeOf` method\n// https://tc39.es/ecma262/#sec-object.getprototypeof\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !CORRECT_PROTOTYPE_GETTER }, {\n getPrototypeOf: function getPrototypeOf(it) {\n return nativeGetPrototypeOf(toObject(it));\n }\n});\n\n","var $ = require('../internals/export');\nvar getBuiltIn = require('../internals/get-built-in');\nvar aFunction = require('../internals/a-function');\nvar anObject = require('../internals/an-object');\nvar isObject = require('../internals/is-object');\nvar create = require('../internals/object-create');\nvar bind = require('../internals/function-bind');\nvar fails = require('../internals/fails');\n\nvar nativeConstruct = getBuiltIn('Reflect', 'construct');\n\n// `Reflect.construct` method\n// https://tc39.es/ecma262/#sec-reflect.construct\n// MS Edge supports only 2 arguments and argumentsList argument is optional\n// FF Nightly sets third argument as `new.target`, but does not create `this` from it\nvar NEW_TARGET_BUG = fails(function () {\n function F() { /* empty */ }\n return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F);\n});\nvar ARGS_BUG = !fails(function () {\n nativeConstruct(function () { /* empty */ });\n});\nvar FORCED = NEW_TARGET_BUG || ARGS_BUG;\n\n$({ target: 'Reflect', stat: true, forced: FORCED, sham: FORCED }, {\n construct: function construct(Target, args /* , newTarget */) {\n aFunction(Target);\n anObject(args);\n var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);\n if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget);\n if (Target == newTarget) {\n // w/o altered newTarget, optimization for 0-4 arguments\n switch (args.length) {\n case 0: return new Target();\n case 1: return new Target(args[0]);\n case 2: return new Target(args[0], args[1]);\n case 3: return new Target(args[0], args[1], args[2]);\n case 4: return new Target(args[0], args[1], args[2], args[3]);\n }\n // w/o altered newTarget, lot of arguments case\n var $args = [null];\n $args.push.apply($args, args);\n return new (bind.apply(Target, $args))();\n }\n // with altered newTarget, not support built-in constructors\n var proto = newTarget.prototype;\n var instance = create(isObject(proto) ? proto : Object.prototype);\n var result = Function.apply.call(Target, instance, args);\n return isObject(result) ? result : instance;\n }\n});\n","var $ = require('../internals/export');\nvar isObject = require('../internals/is-object');\nvar anObject = require('../internals/an-object');\nvar has = require('../internals/has');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\n\n// `Reflect.get` method\n// https://tc39.es/ecma262/#sec-reflect.get\nfunction get(target, propertyKey /* , receiver */) {\n var receiver = arguments.length < 3 ? target : arguments[2];\n var descriptor, prototype;\n if (anObject(target) === receiver) return target[propertyKey];\n if (descriptor = getOwnPropertyDescriptorModule.f(target, propertyKey)) return has(descriptor, 'value')\n ? descriptor.value\n : descriptor.get === undefined\n ? undefined\n : descriptor.get.call(receiver);\n if (isObject(prototype = getPrototypeOf(target))) return get(prototype, propertyKey, receiver);\n}\n\n$({ target: 'Reflect', stat: true }, {\n get: get\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar $trim = require('../internals/string-trim').trim;\nvar forcedStringTrimMethod = require('../internals/string-trim-forced');\n\n// `String.prototype.trim` method\n// https://tc39.es/ecma262/#sec-string.prototype.trim\n$({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {\n trim: function trim() {\n return $trim(this);\n }\n});\n"],"sourceRoot":""}
1
+ {"version":3,"file":"plugins/plugin.text_selection.js","mappings":"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","sources":["webpack://@internetarchive/bookreader/./src/util/strings.js","webpack://@internetarchive/bookreader/./src/plugins/plugin.text_selection.js","webpack://@internetarchive/bookreader/./src/util/browserSniffing.js","webpack://@internetarchive/bookreader/./node_modules/core-js/internals/string-trim-forced.js","webpack://@internetarchive/bookreader/./node_modules/core-js/modules/es.string.trim.js"],"sourcesContent":["/**\n * @typedef {String} StringWithVars\n * A template string with {{foo}} style variables\n * Also supports filters, like {{bookPath|urlencode}} (See APPLY_FILTERS for the\n * supported list of filters)\n **/\n\n/**\n * @param {StringWithVars|String} template\n * @param { {[varName: string]: { toString: () => string} } } vars\n * @param { {[varName: string]: { toString: () => string} } } [overrides]\n */\nexport function applyVariables(template, vars, overrides = {}, possibleFilters = APPLY_FILTERS) {\n return template?.replace(/\\{\\{([^}]*?)\\}\\}/g, ($0, $1) => {\n if (!$1) return $0;\n /** @type {string} */\n const expression = $1;\n const [varName, ...filterNames] = expression.split('|').map(x => x.trim());\n const defined = varName in overrides || varName in vars;\n\n // If it's not defined, don't expand it at all\n if (!defined) return $0;\n\n const value = varName in overrides ? overrides[varName]\n : varName in vars ? vars[varName] : null;\n const filters = filterNames.map(n => possibleFilters[n]);\n return filters.reduce((acc, cur) => cur(acc), value && value.toString());\n });\n}\n\n/** @type { {[filterName: String]:( string => string)} } */\nexport const APPLY_FILTERS = {\n urlencode: encodeURIComponent,\n};\n","//@ts-check\nimport { createSVGPageLayer } from '../BookReader/PageContainer.js';\nimport { isFirefox, isSafari } from '../util/browserSniffing.js';\nimport { applyVariables } from '../util/strings.js';\n/** @typedef {import('../util/strings.js').StringWithVars} StringWithVars */\n/** @typedef {import('../BookReader/PageContainer.js').PageContainer} PageContainer */\n\nconst BookReader = /** @type {typeof import('../BookReader').default} */(window.BookReader);\n\nexport const DEFAULT_OPTIONS = {\n enabled: true,\n /** @type {StringWithVars} The URL to fetch the entire DJVU xml. Supports options.vars */\n fullDjvuXmlUrl: null,\n /** @type {StringWithVars} The URL to fetch a single page of the DJVU xml. Supports options.vars. Also has {{pageIndex}} */\n singlePageDjvuXmlUrl: null,\n};\n/** @typedef {typeof DEFAULT_OPTIONS} TextSelectionPluginOptions */\n\n/**\n * @template T\n */\nexport class Cache {\n constructor(maxSize = 10) {\n this.maxSize = maxSize;\n /** @type {T[]} */\n this.entries = [];\n }\n\n /**\n * @param {T} entry\n */\n add(entry) {\n if (this.entries.length >= this.maxSize) {\n this.entries.shift();\n }\n this.entries.push(entry);\n }\n}\n\nexport class TextSelectionPlugin {\n\n constructor(options = DEFAULT_OPTIONS, optionVariables, avoidTspans = isFirefox(), pointerEventsOnParagraph = isSafari()) {\n this.options = options;\n this.optionVariables = optionVariables;\n /**@type {PromiseLike<JQuery<HTMLElement>|undefined>} */\n this.djvuPagesPromise = null;\n // Using text elements instead of tspans for words because Firefox does not allow svg tspan stretch.\n // Tspans are necessary on Chrome because they prevent newline character after every word when copying\n this.svgParagraphElement = \"text\";\n this.svgWordElement = \"tspan\";\n this.insertNewlines = avoidTspans;\n // Safari has a bug where `pointer-events` doesn't work on `<tspans>`. So\n // there we will set `pointer-events: all` on the paragraph element. We don't\n // do this everywhere, because it's a worse experience. Thanks Safari :/\n this.pointerEventsOnParagraph = pointerEventsOnParagraph;\n if (avoidTspans) {\n this.svgParagraphElement = \"g\";\n this.svgWordElement = \"text\";\n }\n\n /** @type {Cache<{index: number, response: any}>} */\n this.pageTextCache = new Cache();\n\n /**\n * Sometimes there are too many words on a page, and the browser becomes near\n * unusable. For now don't render text layer for pages with too many words.\n */\n this.maxWordRendered = 2500;\n }\n\n init() {\n // Only fetch the full djvu xml if the single page url isn't there\n if (this.options.singlePageDjvuXmlUrl) return;\n this.djvuPagesPromise = $.ajax({\n type: \"GET\",\n url: applyVariables(this.options.fullDjvuXmlUrl, this.optionVariables),\n dataType: \"html\",\n error: (e) => undefined\n }).then((res) => {\n try {\n const xmlMap = $.parseXML(res);\n return xmlMap && $(xmlMap).find(\"OBJECT\");\n } catch (e) {\n return undefined;\n }\n });\n }\n\n /**\n * @param {number} index\n * @returns {Promise<HTMLElement|undefined>}\n */\n async getPageText(index) {\n if (this.options.singlePageDjvuXmlUrl) {\n const cachedEntry = this.pageTextCache.entries.find(x => x.index == index);\n if (cachedEntry) {\n return cachedEntry.response;\n }\n return $.ajax({\n type: \"GET\",\n url: applyVariables(this.options.singlePageDjvuXmlUrl, this.optionVariables, { pageIndex: index }),\n dataType: \"html\",\n error: (e) => undefined,\n }).then((res) => {\n try {\n const xmlDoc = $.parseXML(res);\n const result = xmlDoc && $(xmlDoc).find(\"OBJECT\")[0];\n this.pageTextCache.add({ index, response: result });\n return result;\n } catch (e) {\n return undefined;\n }\n });\n } else {\n const XMLpagesArr = await this.djvuPagesPromise;\n if (XMLpagesArr) return XMLpagesArr[index];\n }\n }\n\n /**\n * Intercept copied text to remove any styling applied to it\n * @param {JQuery} $container\n */\n interceptCopy($container) {\n $container[0].addEventListener('copy', (event) => {\n const selection = document.getSelection();\n event.clipboardData.setData('text/plain', selection.toString());\n event.preventDefault();\n });\n }\n\n /**\n * Applies mouse events when in default mode\n * @param {SVGElement} svg\n */\n defaultMode(svg) {\n svg.classList.remove(\"selectingSVG\");\n $(svg).on(\"mousedown.textSelectPluginHandler\", (event) => {\n if (!$(event.target).is(\".BRwordElement\")) return;\n event.stopPropagation();\n svg.classList.add(\"selectingSVG\");\n $(svg).one(\"mouseup.textSelectPluginHandler\", (event) => {\n if (window.getSelection().toString() != \"\") {\n event.stopPropagation();\n $(svg).off(\".textSelectPluginHandler\");\n this.textSelectingMode(svg);\n }\n else svg.classList.remove(\"selectingSVG\");\n });\n });\n }\n\n /**\n * Applies mouse events when in textSelecting mode\n * @param {SVGElement} svg\n */\n textSelectingMode(svg) {\n $(svg).on('mousedown.textSelectPluginHandler', (event) => {\n if (!$(event.target).is(\".BRwordElement\")) {\n if (window.getSelection().toString() != \"\") window.getSelection().removeAllRanges();\n }\n event.stopPropagation();\n });\n $(svg).on('mouseup.textSelectPluginHandler', (event) => {\n event.stopPropagation();\n if (window.getSelection().toString() == \"\") {\n $(svg).off(\".textSelectPluginHandler\");\n this.defaultMode(svg); }\n });\n }\n\n /**\n * Initializes text selection modes if there is an svg on the page\n * @param {JQuery} $container\n */\n stopPageFlip($container) {\n /** @type {JQuery<SVGElement>} */\n const $svg = $container.find('svg.textSelectionSVG');\n if (!$svg.length) return;\n $svg.each((i, s) => this.defaultMode(s));\n this.interceptCopy($container);\n }\n\n /**\n * @param {PageContainer} pageContainer\n */\n async createTextLayer(pageContainer) {\n const pageIndex = pageContainer.page.index;\n const $container = pageContainer.$container;\n const $svgLayers = $container.find('.textSelectionSVG');\n if ($svgLayers.length) return;\n const XMLpage = await this.getPageText(pageIndex);\n if (!XMLpage) return;\n\n const totalWords = $(XMLpage).find(\"WORD\").length;\n if (totalWords > this.maxWordRendered) {\n console.log(`Page ${pageIndex} has too many words (${totalWords} > ${this.maxWordRendered}). Not rendering text layer.`);\n return;\n }\n\n const svg = createSVGPageLayer(pageContainer.page, 'textSelectionSVG');\n $container.append(svg);\n\n $(XMLpage).find(\"PARAGRAPH\").each((i, paragraph) => {\n // Adding text element for each paragraph in the page\n const words = $(paragraph).find(\"WORD\");\n if (!words.length) return;\n const paragSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgParagraphElement);\n paragSvg.setAttribute(\"class\", \"BRparagElement\");\n if (this.pointerEventsOnParagraph) {\n paragSvg.style.pointerEvents = \"all\";\n }\n\n const wordHeightArr = [];\n\n for (let i = 0; i < words.length; i++) {\n // Adding tspan for each word in paragraph\n const currWord = words[i];\n // eslint-disable-next-line no-unused-vars\n const [left, bottom, right, top] = $(currWord).attr(\"coords\").split(',').map(parseFloat);\n const wordHeight = bottom - top;\n wordHeightArr.push(wordHeight);\n\n const wordTspan = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgWordElement);\n wordTspan.setAttribute(\"class\", \"BRwordElement\");\n wordTspan.setAttribute(\"x\", left.toString());\n wordTspan.setAttribute(\"y\", bottom.toString());\n wordTspan.setAttribute(\"textLength\", (right - left).toString());\n wordTspan.setAttribute(\"lengthAdjust\", \"spacingAndGlyphs\");\n wordTspan.textContent = currWord.textContent;\n paragSvg.appendChild(wordTspan);\n\n // Adding spaces after words except at the end of the paragraph\n // TODO: assumes left-to-right text\n if (i < words.length - 1) {\n const nextWord = words[i + 1];\n // eslint-disable-next-line no-unused-vars\n const [leftNext, bottomNext, rightNext, topNext] = $(nextWord).attr(\"coords\").split(',').map(parseFloat);\n const spaceTspan = document.createElementNS(\"http://www.w3.org/2000/svg\", this.svgWordElement);\n spaceTspan.setAttribute(\"class\", \"BRwordElement\");\n spaceTspan.setAttribute(\"x\", right.toString());\n spaceTspan.setAttribute(\"y\", bottom.toString());\n if ((leftNext - right) > 0) spaceTspan.setAttribute(\"textLength\", (leftNext - right).toString());\n spaceTspan.setAttribute(\"lengthAdjust\", \"spacingAndGlyphs\");\n spaceTspan.textContent = \" \";\n paragSvg.appendChild(spaceTspan);\n }\n\n // Adds newline at the end of paragraph on Firefox\n if ((i == words.length - 1 && (this.insertNewlines))) {\n paragSvg.appendChild(document.createTextNode(\"\\n\"));\n }\n }\n\n wordHeightArr.sort();\n const paragWordHeight = wordHeightArr[Math.floor(wordHeightArr.length * 0.85)];\n paragSvg.setAttribute(\"font-size\", paragWordHeight.toString());\n svg.appendChild(paragSvg);\n });\n this.stopPageFlip($container);\n }\n}\n\nexport class BookreaderWithTextSelection extends BookReader {\n init() {\n const options = Object.assign({}, DEFAULT_OPTIONS, this.options.plugins.textSelection);\n if (options.enabled) {\n this.textSelectionPlugin = new TextSelectionPlugin(options, this.options.vars);\n // Write this back; this way the plugin is the source of truth, and BR just\n // contains a reference to it.\n this.options.plugins.textSelection = options;\n this.textSelectionPlugin.init();\n }\n super.init();\n }\n\n /**\n * @param {number} index\n */\n _createPageContainer(index) {\n const pageContainer = super._createPageContainer(index);\n // Disable if thumb mode; it's too janky\n // .page can be null for \"pre-cover\" region\n if (this.mode !== this.constModeThumb && pageContainer.page) {\n this.textSelectionPlugin?.createTextLayer(pageContainer);\n }\n return pageContainer;\n }\n}\nwindow.BookReader = BookreaderWithTextSelection;\nexport default BookreaderWithTextSelection;\n","\n/**\n * Checks whether the current browser is a Chrome/Chromium browser\n * Code from https://stackoverflow.com/a/4565120/2317712\n * @param {string} [userAgent]\n * @param {string} [vendor]\n * @return {boolean}\n */\nexport function isChrome(userAgent = navigator.userAgent, vendor = navigator.vendor) {\n return /chrome/i.test(userAgent) && /google inc/i.test(vendor);\n}\n\n/**\n * Checks whether the current browser is firefox\n * @param {string} [userAgent]\n * @return {boolean}\n */\nexport function isFirefox(userAgent = navigator.userAgent) {\n return /firefox/i.test(userAgent);\n}\n\n/**\n * Checks whether the current browser is safari\n * https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#Browser_Name\n * @param {string} [userAgent]\n * @return {boolean}\n */\nexport function isSafari(userAgent = navigator.userAgent) {\n return /safari/i.test(userAgent) && !/chrome|chromium/i.test(userAgent);\n}\n","var fails = require('../internals/fails');\nvar whitespaces = require('../internals/whitespaces');\n\nvar non = '\\u200B\\u0085\\u180E';\n\n// check that a method works with the correct list\n// of whitespaces and has a correct name\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;\n });\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar $trim = require('../internals/string-trim').trim;\nvar forcedStringTrimMethod = require('../internals/string-trim-forced');\n\n// `String.prototype.trim` method\n// https://tc39.es/ecma262/#sec-string.prototype.trim\n$({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {\n trim: function trim() {\n return $trim(this);\n }\n});\n"],"names":["applyVariables","template","vars","overrides","possibleFilters","APPLY_FILTERS","replace","$0","$1","split","map","x","trim","varName","filterNames","value","n","reduce","acc","cur","toString","urlencode","encodeURIComponent","BookReader","window","DEFAULT_OPTIONS","enabled","fullDjvuXmlUrl","singlePageDjvuXmlUrl","Cache","maxSize","this","entries","entry","length","shift","push","TextSelectionPlugin","options","optionVariables","avoidTspans","isFirefox","pointerEventsOnParagraph","isSafari","djvuPagesPromise","svgParagraphElement","svgWordElement","insertNewlines","pageTextCache","maxWordRendered","$","ajax","type","url","dataType","error","e","then","res","xmlMap","parseXML","find","index","cachedEntry","response","pageIndex","xmlDoc","result","add","XMLpagesArr","$container","addEventListener","event","selection","document","getSelection","clipboardData","setData","preventDefault","svg","classList","remove","on","target","is","stopPropagation","one","off","textSelectingMode","removeAllRanges","defaultMode","$svg","each","i","s","interceptCopy","pageContainer","page","getPageText","XMLpage","totalWords","console","log","createSVGPageLayer","append","paragraph","words","paragSvg","createElementNS","setAttribute","style","pointerEvents","wordHeightArr","currWord","attr","parseFloat","left","bottom","right","wordHeight","wordTspan","textContent","appendChild","nextWord","leftNext","spaceTspan","createTextNode","sort","paragWordHeight","Math","floor","stopPageFlip","BookreaderWithTextSelection","Object","assign","plugins","textSelection","textSelectionPlugin","init","mode","constModeThumb","createTextLayer","isChrome","userAgent","navigator","vendor","test","fails","whitespaces","module","exports","METHOD_NAME","name","$trim","proto","forced","forcedStringTrimMethod"],"sourceRoot":""}