@internetarchive/bookreader 5.0.0-3 → 5.0.0-30-d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +17 -5
- package/.github/dependabot.yml +8 -0
- package/.github/workflows/node.js.yml +10 -1
- package/.husky/_/husky.sh +30 -0
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +75 -323
- package/BookReader/BookReader.js +32261 -2
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +15235 -0
- package/BookReader/ia-bookreader-bundle.js.map +1 -0
- package/BookReader/icons/close-circle-dark.svg +1 -0
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/jquery-1.10.1.js +108 -2
- package/BookReader/plugins/plugin.archive_analytics.js +170 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +163 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +333 -1
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +72 -1
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.mobile_nav.js +332 -1
- package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +241 -1
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +1261 -1
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +839 -1
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +9115 -2
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +811 -1
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +326 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReader/webcomponents-bundle.js +412 -0
- package/BookReader/webcomponents-bundle.js.map +1 -0
- package/BookReaderDemo/BookReaderDemo.css +14 -1
- package/BookReaderDemo/IADemoBr.js +107 -0
- package/BookReaderDemo/demo-advanced.html +1 -1
- package/BookReaderDemo/demo-autoplay.html +1 -0
- package/BookReaderDemo/demo-embed-iframe-src.html +1 -0
- package/BookReaderDemo/demo-fullscreen-mobile.html +1 -0
- package/BookReaderDemo/demo-fullscreen.html +1 -0
- package/BookReaderDemo/demo-iiif.html +1 -0
- package/BookReaderDemo/demo-internetarchive.html +66 -18
- package/BookReaderDemo/demo-multiple.html +1 -0
- package/BookReaderDemo/demo-preview-pages.html +1 -0
- package/BookReaderDemo/demo-simple.html +1 -0
- package/BookReaderDemo/demo-vendor-fullscreen.html +1 -0
- package/BookReaderDemo/immersion-1up.html +1 -0
- package/BookReaderDemo/immersion-mode.html +1 -0
- package/BookReaderDemo/toggle_controls.html +1 -0
- package/BookReaderDemo/view_mode.html +1 -0
- package/BookReaderDemo/viewmode-cycle.html +1 -2
- package/CHANGELOG.md +114 -0
- package/babel.config.js +18 -0
- package/index.html +3 -0
- package/jsconfig.json +19 -0
- package/package.json +45 -27
- package/src/BookNavigator/assets/button-base.js +8 -1
- package/src/BookNavigator/assets/ia-logo.js +17 -0
- package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
- package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
- package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
- package/src/BookNavigator/assets/icon_volumes.js +11 -0
- package/src/BookNavigator/book-navigator.js +528 -0
- package/src/BookNavigator/bookmarks/bookmark-button.js +2 -1
- package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -1
- package/src/BookNavigator/bookmarks/bookmarks-list.js +1 -0
- package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
- package/src/BookNavigator/bookmarks/bookmarks-provider.js +32 -11
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +88 -43
- package/src/BookNavigator/downloads/downloads-provider.js +22 -16
- package/src/BookNavigator/downloads/downloads.js +16 -23
- package/src/BookNavigator/search/a-search-result.js +1 -0
- package/src/BookNavigator/search/search-provider.js +54 -20
- package/src/BookNavigator/search/search-results.js +7 -18
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +10 -12
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +1 -0
- package/src/BookNavigator/volumes/volumes-provider.js +114 -0
- package/src/BookNavigator/volumes/volumes.js +189 -0
- package/src/BookReader/DebugConsole.js +3 -3
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/Mode1Up.js +50 -351
- package/src/BookReader/Mode1UpLit.js +434 -0
- package/src/BookReader/Mode2Up.js +94 -72
- package/src/BookReader/ModeSmoothZoom.js +177 -0
- package/src/BookReader/ModeThumb.js +16 -8
- package/src/BookReader/Navbar/Navbar.js +2 -31
- package/src/BookReader/PageContainer.js +47 -2
- package/src/BookReader/ReduceSet.js +1 -1
- package/src/BookReader/Toolbar/Toolbar.js +5 -5
- package/src/BookReader/options.js +10 -0
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils.js +68 -13
- package/src/BookReader.js +316 -232
- package/src/assets/icons/close-circle-dark.svg +1 -0
- package/src/assets/icons/voice.svg +1 -0
- package/src/css/BookReader.scss +0 -12
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRmain.scss +19 -24
- package/src/css/_BRnav.scss +4 -26
- package/src/css/_BRpages.scss +35 -0
- package/src/css/_BRsearch.scss +11 -215
- package/src/css/_TextSelection.scss +1 -17
- package/src/css/_controls.scss +16 -3
- package/src/css/_icons.scss +6 -0
- package/src/ia-bookreader/ia-bookreader.js +206 -0
- package/src/plugins/plugin.chapters.js +15 -18
- package/src/plugins/plugin.mobile_nav.js +11 -10
- package/src/plugins/plugin.resume.js +3 -3
- package/src/plugins/plugin.text_selection.js +17 -29
- package/src/plugins/plugin.vendor-fullscreen.js +4 -4
- package/src/plugins/search/plugin.search.js +113 -104
- package/src/plugins/search/view.js +48 -163
- package/src/plugins/tts/AbstractTTSEngine.js +7 -0
- package/src/plugins/tts/FestivalTTSEngine.js +2 -2
- package/src/plugins/tts/WebTTSEngine.js +5 -0
- package/src/plugins/tts/plugin.tts.js +67 -102
- package/src/plugins/url/UrlPlugin.js +184 -0
- package/src/plugins/url/plugin.url.js +220 -0
- package/{src → stat}/BookNavigator/BookModel.js +0 -0
- package/{src → stat}/BookNavigator/BookNavigator.js +151 -104
- package/stat/BookNavigator/assets/bookmark-colors.js +15 -0
- package/stat/BookNavigator/assets/button-base.js +61 -0
- package/stat/BookNavigator/assets/ia-logo.js +17 -0
- package/stat/BookNavigator/assets/icon_checkmark.js +6 -0
- package/stat/BookNavigator/assets/icon_close.js +3 -0
- package/stat/BookNavigator/assets/icon_sort_asc.js +5 -0
- package/stat/BookNavigator/assets/icon_sort_desc.js +5 -0
- package/stat/BookNavigator/assets/icon_sort_neutral.js +5 -0
- package/stat/BookNavigator/assets/icon_volumes.js +11 -0
- package/stat/BookNavigator/bookmarks/bookmark-button.js +64 -0
- package/stat/BookNavigator/bookmarks/bookmark-edit.js +215 -0
- package/stat/BookNavigator/bookmarks/bookmarks-list.js +285 -0
- package/stat/BookNavigator/bookmarks/bookmarks-loginCTA.js +28 -0
- package/stat/BookNavigator/bookmarks/bookmarks-provider.js +56 -0
- package/stat/BookNavigator/bookmarks/ia-bookmarks.js +523 -0
- package/{src → stat}/BookNavigator/br-fullscreen-mgr.js +1 -2
- package/stat/BookNavigator/delete-modal-actions.js +49 -0
- package/stat/BookNavigator/downloads/downloads-provider.js +72 -0
- package/stat/BookNavigator/downloads/downloads.js +139 -0
- package/stat/BookNavigator/provider-config.js +0 -0
- package/stat/BookNavigator/search/a-search-result.js +55 -0
- package/stat/BookNavigator/search/search-provider.js +180 -0
- package/stat/BookNavigator/search/search-results.js +360 -0
- package/stat/BookNavigator/sharing.js +31 -0
- package/stat/BookNavigator/visual-adjustments/visual-adjustments-provider.js +94 -0
- package/stat/BookNavigator/visual-adjustments/visual-adjustments.js +280 -0
- package/stat/BookNavigator/volumes/volumes-provider.js +83 -0
- package/stat/BookNavigator/volumes/volumes.js +178 -0
- package/stat/BookReader/BookModel.js +518 -0
- package/stat/BookReader/DebugConsole.js +54 -0
- package/stat/BookReader/DragScrollable.js +233 -0
- package/stat/BookReader/ImageCache.js +116 -0
- package/stat/BookReader/Mode1Up.js +102 -0
- package/stat/BookReader/Mode1UpLit.js +434 -0
- package/stat/BookReader/Mode2Up.js +1372 -0
- package/stat/BookReader/ModeSmoothZoom.js +177 -0
- package/stat/BookReader/ModeThumb.js +344 -0
- package/stat/BookReader/Navbar/Navbar.js +310 -0
- package/stat/BookReader/PageContainer.js +120 -0
- package/stat/BookReader/ReduceSet.js +26 -0
- package/stat/BookReader/Toolbar/Toolbar.js +384 -0
- package/stat/BookReader/events.js +20 -0
- package/stat/BookReader/options.js +324 -0
- package/stat/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/stat/BookReader/utils/classes.js +36 -0
- package/stat/BookReader/utils.js +240 -0
- package/stat/BookReader.js +2550 -0
- package/{src → stat}/BookReaderComponent/BookReaderComponent.js +16 -11
- package/stat/assets/icons/1up.svg +12 -0
- package/stat/assets/icons/2up.svg +15 -0
- package/stat/assets/icons/advance.svg +26 -0
- package/stat/assets/icons/chevron-right.svg +1 -0
- package/stat/assets/icons/close-circle-dark.svg +1 -0
- package/stat/assets/icons/close-circle.svg +1 -0
- package/stat/assets/icons/fullscreen.svg +17 -0
- package/stat/assets/icons/fullscreen_exit.svg +17 -0
- package/stat/assets/icons/hamburger.svg +15 -0
- package/stat/assets/icons/left-arrow.svg +12 -0
- package/stat/assets/icons/magnify-minus.svg +16 -0
- package/stat/assets/icons/magnify-plus.svg +17 -0
- package/stat/assets/icons/magnify.svg +15 -0
- package/stat/assets/icons/pause.svg +23 -0
- package/stat/assets/icons/play.svg +22 -0
- package/stat/assets/icons/playback-speed.svg +34 -0
- package/stat/assets/icons/read-aloud.svg +22 -0
- package/stat/assets/icons/review.svg +22 -0
- package/stat/assets/icons/thumbnails.svg +17 -0
- package/stat/assets/icons/voice.svg +1 -0
- package/stat/assets/icons/volume-full.svg +22 -0
- package/stat/assets/images/BRicons.png +0 -0
- package/stat/assets/images/BRicons.svg +94 -0
- package/stat/assets/images/BRicons_ia.png +0 -0
- package/stat/assets/images/back_pages.png +0 -0
- package/stat/assets/images/book_bottom_icon.png +0 -0
- package/stat/assets/images/book_down_icon.png +0 -0
- package/stat/assets/images/book_left_icon.png +0 -0
- package/stat/assets/images/book_leftmost_icon.png +0 -0
- package/stat/assets/images/book_right_icon.png +0 -0
- package/stat/assets/images/book_rightmost_icon.png +0 -0
- package/stat/assets/images/book_top_icon.png +0 -0
- package/stat/assets/images/book_up_icon.png +0 -0
- package/stat/assets/images/books_graphic.svg +177 -0
- package/stat/assets/images/booksplit.png +0 -0
- package/stat/assets/images/control_pause_icon.png +0 -0
- package/stat/assets/images/control_play_icon.png +0 -0
- package/stat/assets/images/embed_icon.png +0 -0
- package/stat/assets/images/icon-home-ia.png +0 -0
- package/stat/assets/images/icon_OL-logo-xs.png +0 -0
- package/stat/assets/images/icon_alert-xs.png +0 -0
- package/stat/assets/images/icon_book.svg +12 -0
- package/stat/assets/images/icon_bookmark.svg +12 -0
- package/stat/assets/images/icon_close-pop.png +0 -0
- package/stat/assets/images/icon_download.png +0 -0
- package/stat/assets/images/icon_gear.svg +14 -0
- package/stat/assets/images/icon_hamburger.svg +20 -0
- package/stat/assets/images/icon_home.png +0 -0
- package/stat/assets/images/icon_home.svg +21 -0
- package/stat/assets/images/icon_home_ia.png +0 -0
- package/stat/assets/images/icon_indicator.png +0 -0
- package/stat/assets/images/icon_info.svg +11 -0
- package/stat/assets/images/icon_one_page.svg +8 -0
- package/stat/assets/images/icon_pause.svg +1 -0
- package/stat/assets/images/icon_play.svg +1 -0
- package/stat/assets/images/icon_playback-rate.svg +15 -0
- package/stat/assets/images/icon_return.png +0 -0
- package/stat/assets/images/icon_search_button.svg +8 -0
- package/stat/assets/images/icon_share.svg +9 -0
- package/stat/assets/images/icon_skip-ahead.svg +6 -0
- package/stat/assets/images/icon_skip-back.svg +13 -0
- package/stat/assets/images/icon_speaker.svg +18 -0
- package/stat/assets/images/icon_speaker_open.svg +10 -0
- package/stat/assets/images/icon_thumbnails.svg +12 -0
- package/stat/assets/images/icon_toc.svg +5 -0
- package/stat/assets/images/icon_two_pages.svg +9 -0
- package/stat/assets/images/icon_zoomer.png +0 -0
- package/stat/assets/images/loading.gif +0 -0
- package/stat/assets/images/logo_icon.png +0 -0
- package/stat/assets/images/marker_chap-off.png +0 -0
- package/stat/assets/images/marker_chap-off.svg +11 -0
- package/stat/assets/images/marker_chap-off_ia.png +0 -0
- package/stat/assets/images/marker_chap-on.png +0 -0
- package/stat/assets/images/marker_chap-on.svg +11 -0
- package/stat/assets/images/marker_srch-on.svg +11 -0
- package/stat/assets/images/marker_srchchap-off.png +0 -0
- package/stat/assets/images/marker_srchchap-on.png +0 -0
- package/stat/assets/images/nav_control-dn.png +0 -0
- package/stat/assets/images/nav_control-dn_ia.png +0 -0
- package/stat/assets/images/nav_control-up.png +0 -0
- package/stat/assets/images/nav_control-up_ia.png +0 -0
- package/stat/assets/images/nav_control.png +0 -0
- package/stat/assets/images/one_page_mode_icon.png +0 -0
- package/stat/assets/images/paper-badge.png +0 -0
- package/stat/assets/images/print_icon.png +0 -0
- package/stat/assets/images/progressbar.gif +0 -0
- package/stat/assets/images/right_edges.png +0 -0
- package/stat/assets/images/slider.png +0 -0
- package/stat/assets/images/slider_ia.png +0 -0
- package/stat/assets/images/thumbnail_mode_icon.png +0 -0
- package/stat/assets/images/transparent.png +0 -0
- package/stat/assets/images/two_page_mode_icon.png +0 -0
- package/stat/assets/images/zoom_in_icon.png +0 -0
- package/stat/assets/images/zoom_out_icon.png +0 -0
- package/stat/css/BookReader.scss +89 -0
- package/stat/css/_BRBookmarks.scss +29 -0
- package/stat/css/_BRComponent.scss +13 -0
- package/stat/css/_BRfloat.scss +197 -0
- package/stat/css/_BRicon.scss +48 -0
- package/stat/css/_BRmain.scss +251 -0
- package/stat/css/_BRnav.scss +359 -0
- package/stat/css/_BRpages.scss +139 -0
- package/stat/css/_BRsearch.scss +226 -0
- package/stat/css/_BRtoolbar.scss +84 -0
- package/stat/css/_BRvendor.scss +5 -0
- package/stat/css/_MobileNav.scss +194 -0
- package/stat/css/_TextSelection.scss +32 -0
- package/stat/css/_colorbox.scss +52 -0
- package/stat/css/_controls.scss +253 -0
- package/stat/css/_icons.scss +121 -0
- package/stat/jquery-wrapper.js +4 -0
- package/stat/plugins/plugin.archive_analytics.js +86 -0
- package/stat/plugins/plugin.autoplay.js +129 -0
- package/stat/plugins/plugin.chapters.js +248 -0
- package/stat/plugins/plugin.iframe.js +48 -0
- package/stat/plugins/plugin.mobile_nav.js +288 -0
- package/stat/plugins/plugin.resume.js +68 -0
- package/stat/plugins/plugin.text_selection.js +291 -0
- package/{src → stat}/plugins/plugin.url.js +4 -4
- package/stat/plugins/plugin.vendor-fullscreen.js +247 -0
- package/stat/plugins/search/plugin.search.js +439 -0
- package/stat/plugins/search/view.js +439 -0
- package/stat/plugins/tts/AbstractTTSEngine.js +249 -0
- package/stat/plugins/tts/FestivalTTSEngine.js +169 -0
- package/stat/plugins/tts/PageChunk.js +107 -0
- package/stat/plugins/tts/PageChunkIterator.js +163 -0
- package/stat/plugins/tts/WebTTSEngine.js +357 -0
- package/stat/plugins/tts/plugin.tts.js +357 -0
- package/stat/plugins/tts/tooltip_dict.js +15 -0
- package/stat/plugins/tts/utils.js +91 -0
- package/stat/util/browserSniffing.js +30 -0
- package/stat/util/debouncer.js +26 -0
- package/stat/util/docCookies.js +67 -0
- package/stat/util/strings.js +34 -0
- package/tests/e2e/README.md +37 -0
- package/tests/e2e/autoplay.test.js +2 -2
- package/tests/e2e/base.test.js +5 -7
- package/tests/e2e/helpers/base.js +8 -3
- package/tests/e2e/helpers/debug.js +1 -1
- package/tests/e2e/helpers/desktopSearch.js +1 -1
- package/tests/e2e/helpers/mobileSearch.js +3 -3
- package/tests/e2e/helpers/params.js +17 -0
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +30 -31
- package/tests/{BookReader → jest/BookReader}/BookModel.test.js +3 -3
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
- package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
- package/tests/jest/BookReader/Mode1UpLit.test.js +87 -0
- package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +5 -7
- package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
- package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +74 -2
- package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
- package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
- package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
- package/tests/jest/BookReader/utils.test.js +136 -0
- package/tests/jest/BookReader.keyboard.test.js +190 -0
- package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
- package/tests/{BookReader.test.js → jest/BookReader.test.js} +20 -4
- package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +8 -8
- package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
- package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
- package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +14 -24
- package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
- package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +12 -5
- package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +6 -6
- package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +3 -3
- package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
- package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
- package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -3
- package/tests/jest/plugins/url/UrlPlugin.test.js +175 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
- package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
- package/tests/{util → jest/util}/docCookies.test.js +1 -1
- package/tests/{util → jest/util}/strings.test.js +1 -1
- package/tests/{utils.js → jest/utils.js} +38 -0
- package/tests/karma/BookNavigator/book-navigator.test.js +485 -0
- package/tests/karma/BookNavigator/bookmarks/bookmark-button.test.js +44 -0
- package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +1 -3
- package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +1 -2
- package/tests/karma/BookNavigator/downloads/downloads-provider.test.js +67 -0
- package/tests/karma/BookNavigator/downloads/downloads.test.js +54 -0
- package/tests/karma/BookNavigator/search/search-provider.test.js +123 -0
- package/tests/karma/BookNavigator/{search-results.test.js → search/search-results.test.js} +1 -4
- package/tests/karma/BookNavigator/sharing/sharing-provider.test.js +49 -0
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -2
- package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +184 -0
- package/tests/karma/BookNavigator/volumes/volumes.test.js +98 -0
- package/webpack.config.js +11 -5
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.testcaferc.json +0 -5
- package/BookReader/BookReader.js.LICENSE.txt +0 -72
- package/BookReader/bookreader-component-bundle.js +0 -1450
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -2
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReader/plugins/plugin.tts.js.LICENSE.txt +0 -27
- package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/ItemNavigator/ItemNavigator.js +0 -372
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
|
@@ -20,8 +20,13 @@
|
|
|
20
20
|
* the book has not had OCR text indexed yet. Receives `instance`
|
|
21
21
|
* @event BookReader:SearchCallbackEmpty - When no results found. Receives
|
|
22
22
|
* `instance`
|
|
23
|
+
* @event BookReader:SearchCanceled - When no results found. Receives
|
|
24
|
+
* `instance`
|
|
23
25
|
*/
|
|
26
|
+
import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
|
|
24
27
|
import SearchView from './view.js';
|
|
28
|
+
/** @typedef {import('../../BookReader/PageContainer').PageContainer} PageContainer */
|
|
29
|
+
/** @typedef {import('../../BookReader/BookModel').PageIndex} PageIndex */
|
|
25
30
|
|
|
26
31
|
jQuery.extend(BookReader.defaultOptions, {
|
|
27
32
|
server: 'ia600609.us.archive.org',
|
|
@@ -42,7 +47,6 @@ BookReader.prototype.setup = (function (super_) {
|
|
|
42
47
|
this.searchResults = null;
|
|
43
48
|
this.searchInsideUrl = options.searchInsideUrl;
|
|
44
49
|
this.enableSearch = options.enableSearch;
|
|
45
|
-
this.goToFirstResult = false;
|
|
46
50
|
|
|
47
51
|
// Base server used by some api calls
|
|
48
52
|
this.bookId = options.bookId;
|
|
@@ -50,11 +54,14 @@ BookReader.prototype.setup = (function (super_) {
|
|
|
50
54
|
this.subPrefix = options.subPrefix;
|
|
51
55
|
this.bookPath = options.bookPath;
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
57
|
+
this.searchXHR = null;
|
|
58
|
+
this._cancelSearch.bind(this);
|
|
59
|
+
this.cancelSearchRequest.bind(this);
|
|
60
|
+
|
|
61
|
+
/** @type { {[pageIndex: number]: SearchInsideMatchBox[]} } */
|
|
62
|
+
this._searchBoxesByIndex = {};
|
|
63
|
+
|
|
64
|
+
this.searchView = undefined;
|
|
58
65
|
};
|
|
59
66
|
})(BookReader.prototype.setup);
|
|
60
67
|
|
|
@@ -62,28 +69,31 @@ BookReader.prototype.setup = (function (super_) {
|
|
|
62
69
|
BookReader.prototype.init = (function (super_) {
|
|
63
70
|
return function () {
|
|
64
71
|
super_.call(this);
|
|
65
|
-
|
|
72
|
+
// give SearchView the most complete bookreader state
|
|
73
|
+
this.searchView = new SearchView({
|
|
74
|
+
br: this,
|
|
75
|
+
searchCancelledCallback: () => {
|
|
76
|
+
this._cancelSearch();
|
|
77
|
+
this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
66
80
|
if (this.options.enableSearch && this.options.initialSearchTerm) {
|
|
81
|
+
/**
|
|
82
|
+
* this.search() take two parameter
|
|
83
|
+
* 1. this.options.initialSearchTerm - search term
|
|
84
|
+
* 2. {
|
|
85
|
+
* goToFirstResult: this.options.goToFirstResult,
|
|
86
|
+
* suppressFragmentChange: false // always want to change fragment in URL
|
|
87
|
+
* }
|
|
88
|
+
*/
|
|
67
89
|
this.search(
|
|
68
90
|
this.options.initialSearchTerm,
|
|
69
|
-
{ goToFirstResult: this.goToFirstResult, suppressFragmentChange:
|
|
91
|
+
{ goToFirstResult: this.options.goToFirstResult, suppressFragmentChange: false }
|
|
70
92
|
);
|
|
71
93
|
}
|
|
72
94
|
};
|
|
73
95
|
})(BookReader.prototype.init);
|
|
74
96
|
|
|
75
|
-
/** @override */
|
|
76
|
-
BookReader.prototype.buildMobileDrawerElement = (function (super_) {
|
|
77
|
-
return function () {
|
|
78
|
-
const $el = super_.call(this);
|
|
79
|
-
if (!this.enableSearch) { return; }
|
|
80
|
-
if (this.searchView.dom.mobileSearch) {
|
|
81
|
-
$el.find('.BRmobileMenu__moreInfoRow').after(this.searchView.dom.mobileSearch);
|
|
82
|
-
}
|
|
83
|
-
return $el;
|
|
84
|
-
};
|
|
85
|
-
})(BookReader.prototype.buildMobileDrawerElement);
|
|
86
|
-
|
|
87
97
|
/** @override */
|
|
88
98
|
BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
89
99
|
return function () {
|
|
@@ -96,6 +106,18 @@ BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
|
96
106
|
};
|
|
97
107
|
})(BookReader.prototype.buildToolbarElement);
|
|
98
108
|
|
|
109
|
+
/** @override */
|
|
110
|
+
BookReader.prototype._createPageContainer = (function (super_) {
|
|
111
|
+
return function (index) {
|
|
112
|
+
const pageContainer = super_.call(this, index);
|
|
113
|
+
if (this.enableSearch && pageContainer.page && index in this._searchBoxesByIndex) {
|
|
114
|
+
const pageIndex = pageContainer.page.index;
|
|
115
|
+
renderBoxesInPageContainerLayer('searchHiliteLayer', this._searchBoxesByIndex[pageIndex], pageContainer.page, pageContainer.$container[0]);
|
|
116
|
+
}
|
|
117
|
+
return pageContainer;
|
|
118
|
+
};
|
|
119
|
+
})(BookReader.prototype._createPageContainer);
|
|
120
|
+
|
|
99
121
|
/**
|
|
100
122
|
* @typedef {object} SearchOptions
|
|
101
123
|
* @property {boolean} goToFirstResult
|
|
@@ -157,7 +179,15 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
|
157
179
|
|
|
158
180
|
const url = `${baseUrl}${paramStr}`;
|
|
159
181
|
|
|
182
|
+
const cleanup = () => {
|
|
183
|
+
this.searchXHR = null;
|
|
184
|
+
window.BRSearchInProgress = () => {};
|
|
185
|
+
};
|
|
186
|
+
|
|
160
187
|
const processSearchResults = (searchInsideResults) => {
|
|
188
|
+
if (!this.searchXHR) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
161
191
|
const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;
|
|
162
192
|
const hasCustomError = typeof options.error === 'function';
|
|
163
193
|
const hasCustomSuccess = typeof options.success === 'function';
|
|
@@ -171,15 +201,49 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
|
171
201
|
? options.success.call(this, searchInsideResults, options)
|
|
172
202
|
: this.BRSearchCallback(searchInsideResults, options);
|
|
173
203
|
}
|
|
204
|
+
cleanup();
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const beforeSend = (xhr) => {
|
|
208
|
+
this.searchXHR = xhr;
|
|
209
|
+
window.BRSearchInProgress = processSearchResults;
|
|
174
210
|
};
|
|
175
211
|
|
|
176
|
-
this.trigger('SearchStarted', { term: this.searchTerm });
|
|
212
|
+
this.trigger('SearchStarted', { term: this.searchTerm, instance: this });
|
|
177
213
|
return $.ajax({
|
|
178
214
|
url: url,
|
|
179
|
-
dataType: 'jsonp'
|
|
215
|
+
dataType: 'jsonp',
|
|
216
|
+
cache: true,
|
|
217
|
+
beforeSend,
|
|
218
|
+
jsonpCallback: 'BRSearchInProgress'
|
|
180
219
|
}).then(processSearchResults);
|
|
181
220
|
};
|
|
182
221
|
|
|
222
|
+
/**
|
|
223
|
+
* cancels AJAX Call
|
|
224
|
+
* emits custom event
|
|
225
|
+
*/
|
|
226
|
+
BookReader.prototype._cancelSearch = function () {
|
|
227
|
+
this.searchXHR?.abort();
|
|
228
|
+
this.searchView.clearSearchFieldAndResults(false);
|
|
229
|
+
this.searchTerm = '';
|
|
230
|
+
this.searchXHR = null;
|
|
231
|
+
this.searchResults = [];
|
|
232
|
+
window.BRSearchInProgress = () => {};
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* External function to cancel search
|
|
237
|
+
* checks for term & xhr in flight before running
|
|
238
|
+
*/
|
|
239
|
+
BookReader.prototype.cancelSearchRequest = function () {
|
|
240
|
+
if (this.searchXHR !== null) {
|
|
241
|
+
this._cancelSearch();
|
|
242
|
+
this.searchView.toggleSearchPending();
|
|
243
|
+
this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
183
247
|
/**
|
|
184
248
|
* @typedef {object} SearchInsideMatchBox
|
|
185
249
|
* @property {number} page
|
|
@@ -211,15 +275,16 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
|
211
275
|
* @param {boolean} options.goToFirstResult
|
|
212
276
|
*/
|
|
213
277
|
BookReader.prototype.BRSearchCallback = function(results, options) {
|
|
214
|
-
this.searchResults = results;
|
|
278
|
+
this.searchResults = results || [];
|
|
215
279
|
|
|
216
280
|
this.updateSearchHilites();
|
|
217
281
|
this.removeProgressPopup();
|
|
218
282
|
if (options.goToFirstResult) {
|
|
219
|
-
this.
|
|
283
|
+
const pageIndex = this._models.book.leafNumToIndex(results.matches[0].par[0].page);
|
|
284
|
+
this._searchPluginGoToResult(pageIndex);
|
|
220
285
|
}
|
|
221
286
|
this.trigger('SearchCallback', { results, options, instance: this });
|
|
222
|
-
}
|
|
287
|
+
};
|
|
223
288
|
|
|
224
289
|
/**
|
|
225
290
|
* Main search results error handler
|
|
@@ -259,95 +324,39 @@ BookReader.prototype._BRSearchCallbackError = function(results) {
|
|
|
259
324
|
* updates search on-page highlights controller
|
|
260
325
|
*/
|
|
261
326
|
BookReader.prototype.updateSearchHilites = function() {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
this.updateSearchHilites1UP();
|
|
267
|
-
};
|
|
327
|
+
/** @type {SearchInsideMatch[]} */
|
|
328
|
+
const matches = this.searchResults?.matches || [];
|
|
329
|
+
/** @type { {[pageIndex: number]: SearchInsideMatch[]} } */
|
|
330
|
+
const boxesByIndex = {};
|
|
268
331
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
results.matches.forEach(match => {
|
|
276
|
-
match.par[0].boxes.forEach(box => {
|
|
332
|
+
// Clear any existing svg layers
|
|
333
|
+
this.removeSearchHilites();
|
|
334
|
+
|
|
335
|
+
// Group by pageIndex
|
|
336
|
+
for (const match of matches) {
|
|
337
|
+
for (const box of match.par[0].boxes) {
|
|
277
338
|
const pageIndex = this.leafNumToIndex(box.page);
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
box.div = document.createElement('div');
|
|
283
|
-
$(box.div).prop('className', 'BookReaderSearchHilite').appendTo(this.$(`.pagediv${pageIndex}`));
|
|
284
|
-
}
|
|
285
|
-
const page = this._models.book.getPage(pageIndex);
|
|
286
|
-
const highlight = {
|
|
287
|
-
width: this._modes.mode1Up.physicalInchesToDisplayPixels((box.r - box.l) / page.ppi),
|
|
288
|
-
height: this._modes.mode1Up.physicalInchesToDisplayPixels((box.b - box.t) / page.ppi),
|
|
289
|
-
left: this._modes.mode1Up.physicalInchesToDisplayPixels(box.l / page.ppi),
|
|
290
|
-
top: this._modes.mode1Up.physicalInchesToDisplayPixels(box.t / page.ppi),
|
|
291
|
-
};
|
|
292
|
-
$(box.div).css(highlight);
|
|
293
|
-
} else {
|
|
294
|
-
if (box.div) {
|
|
295
|
-
$(box.div).remove();
|
|
296
|
-
box.div = null;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
};
|
|
339
|
+
const pageMatches = boxesByIndex[pageIndex] || (boxesByIndex[pageIndex] = []);
|
|
340
|
+
pageMatches.push(box);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
302
343
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
344
|
+
// update any already created pages
|
|
345
|
+
for (const [pageIndexString, boxes] of Object.entries(boxesByIndex)) {
|
|
346
|
+
const pageIndex = parseFloat(pageIndexString);
|
|
347
|
+
const page = this._models.book.getPage(pageIndex);
|
|
348
|
+
const pageContainers = this.getActivePageContainerElementsForIndex(pageIndex);
|
|
349
|
+
pageContainers.forEach(container => renderBoxesInPageContainerLayer('searchHiliteLayer', boxes, page, container));
|
|
350
|
+
}
|
|
308
351
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const { matches } = results;
|
|
312
|
-
matches.forEach((match) => {
|
|
313
|
-
match.par[0].boxes.forEach(box => {
|
|
314
|
-
const pageIndex = this.leafNumToIndex(match.par[0].page);
|
|
315
|
-
const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;
|
|
316
|
-
const { isViewable } = this._models.book.getPage(pageIndex);
|
|
317
|
-
|
|
318
|
-
if (pageIsInView && isViewable) {
|
|
319
|
-
if (!box.div) {
|
|
320
|
-
//create a div for the search highlight, and stash it in the box object
|
|
321
|
-
box.div = document.createElement('div');
|
|
322
|
-
$(box.div).addClass('BookReaderSearchHilite')
|
|
323
|
-
.appendTo(this.refs.$brTwoPageView);
|
|
324
|
-
}
|
|
325
|
-
this.setHilightCss2UP(box.div, pageIndex, box.l, box.r, box.t, box.b);
|
|
326
|
-
} else {
|
|
327
|
-
// clear stale reference
|
|
328
|
-
if (box.div) {
|
|
329
|
-
$(box.div).remove();
|
|
330
|
-
box.div = null;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
});
|
|
352
|
+
this._searchBoxesByIndex = boxesByIndex;
|
|
335
353
|
};
|
|
336
354
|
|
|
337
355
|
/**
|
|
338
356
|
* remove search highlights
|
|
339
357
|
*/
|
|
340
358
|
BookReader.prototype.removeSearchHilites = function() {
|
|
341
|
-
|
|
342
|
-
if (null == results || !results.matches) { return; }
|
|
343
|
-
results.matches.forEach(match => {
|
|
344
|
-
match.par[0].boxes.forEach(box => {
|
|
345
|
-
if (null != box.div) {
|
|
346
|
-
$(box.div).remove();
|
|
347
|
-
box.div = null;
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
});
|
|
359
|
+
$(this.getActivePageContainerElements()).find('.searchHiliteLayer').remove();
|
|
351
360
|
};
|
|
352
361
|
|
|
353
362
|
/**
|
|
@@ -1,75 +1,31 @@
|
|
|
1
1
|
class SearchView {
|
|
2
2
|
/**
|
|
3
3
|
* @param {object} params
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @param {object} params.br The BookReader instance
|
|
4
|
+
* @param {object} params.br The BookReader instance
|
|
5
|
+
* @param {function} params.cancelSearch callback when a user wants to cancel search
|
|
7
6
|
*
|
|
8
7
|
* @event BookReader:SearchResultsCleared - when the search results nav gets cleared
|
|
9
8
|
* @event BookReader:ToggleSearchMenu - when search results menu should toggle
|
|
10
9
|
*/
|
|
11
|
-
constructor(
|
|
12
|
-
|
|
13
|
-
console.warn('BookReader::Search - SearchView must be passed a valid CSS selector');
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
this.br = params.br;
|
|
10
|
+
constructor({ br, searchCancelledCallback = () => {} }) {
|
|
11
|
+
this.br = br;
|
|
18
12
|
|
|
19
13
|
// Search results are returned as a text blob with the hits wrapped in
|
|
20
14
|
// triple mustaches. Hits occasionally include text beyond the search
|
|
21
15
|
// term, so everything within the staches is captured and wrapped.
|
|
22
16
|
this.matcher = new RegExp('{{{(.+?)}}}', 'g');
|
|
23
17
|
this.matches = [];
|
|
24
|
-
this.cacheDOMElements(
|
|
18
|
+
this.cacheDOMElements();
|
|
25
19
|
this.bindEvents();
|
|
20
|
+
this.cancelSearch = searchCancelledCallback;
|
|
26
21
|
}
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
* @param {string} selector A selector for the element that the search tray will be rendered in
|
|
30
|
-
*/
|
|
31
|
-
cacheDOMElements(selector) {
|
|
23
|
+
cacheDOMElements() {
|
|
32
24
|
this.dom = {};
|
|
33
|
-
|
|
34
|
-
// The parent search tray in mobile menu
|
|
35
|
-
this.dom.searchTray = this.renderSearchTray(selector);
|
|
36
|
-
// Container for rendered search results
|
|
37
|
-
this.dom.results = this.dom.searchTray.querySelector('[data-id="results"]');
|
|
38
|
-
// Element used to display number of results
|
|
39
|
-
this.dom.resultsCount = this.dom.searchTray.querySelector('[data-id="results_count"]');
|
|
40
|
-
// Search input within the mobile search tray
|
|
41
|
-
this.dom.searchField = this.dom.searchTray.querySelector('[name="query"]');
|
|
42
|
-
// Waiting indicator displayed while waiting for a search request
|
|
43
|
-
this.dom.searchPending = this.dom.searchTray.querySelector('[data-id="searchPending"]');
|
|
44
|
-
// The element added to the mobile menu that is animated into view when
|
|
45
|
-
// the "search" nav item is clicked
|
|
46
|
-
this.dom.mobileSearch = this.buildMobileDrawer();
|
|
47
25
|
// Search input within the top toolbar. Will be removed once the mobile menu is replaced.
|
|
48
26
|
this.dom.toolbarSearch = this.buildToolbarSearch();
|
|
49
27
|
}
|
|
50
28
|
|
|
51
|
-
/**
|
|
52
|
-
* @param {boolean} bool
|
|
53
|
-
*/
|
|
54
|
-
toggleSearchTray(bool = this.dom.searchTray.classList.contains('hidden')) {
|
|
55
|
-
this.dom.searchTray.classList.toggle('hidden', !bool);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @param {boolean} bool
|
|
60
|
-
*/
|
|
61
|
-
toggleResultsCount(bool) {
|
|
62
|
-
this.dom.resultsCount.classList.toggle('visible', bool);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @param {SearchInsideResults} results
|
|
67
|
-
*/
|
|
68
|
-
updateResultsCount(results) {
|
|
69
|
-
this.dom.resultsCount.innerText = `(${results} result${results != 1 ? 's' : ''})`;
|
|
70
|
-
this.toggleResultsCount(true);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
29
|
/**
|
|
74
30
|
* @param {string} query
|
|
75
31
|
*/
|
|
@@ -78,7 +34,6 @@ class SearchView {
|
|
|
78
34
|
}
|
|
79
35
|
|
|
80
36
|
emptyMatches() {
|
|
81
|
-
this.dom.results.innerHTML = '';
|
|
82
37
|
this.matches = [];
|
|
83
38
|
}
|
|
84
39
|
|
|
@@ -86,48 +41,20 @@ class SearchView {
|
|
|
86
41
|
this.br.$('.BRnavpos .BRsearch').remove();
|
|
87
42
|
}
|
|
88
43
|
|
|
89
|
-
clearSearchFieldAndResults() {
|
|
44
|
+
clearSearchFieldAndResults(dispatchEventWhenComplete = true) {
|
|
90
45
|
this.br.removeSearchResults();
|
|
91
|
-
this.toggleResultsCount(false);
|
|
92
46
|
this.removeResultPins();
|
|
93
47
|
this.emptyMatches();
|
|
94
48
|
this.setQuery('');
|
|
95
49
|
this.teardownSearchNavigation();
|
|
96
|
-
|
|
50
|
+
if (dispatchEventWhenComplete) {
|
|
51
|
+
this.br.trigger('SearchResultsCleared');
|
|
52
|
+
}
|
|
97
53
|
}
|
|
98
54
|
|
|
99
55
|
toggleSidebar() {
|
|
100
56
|
this.br.trigger('ToggleSearchMenu');
|
|
101
57
|
}
|
|
102
|
-
/**
|
|
103
|
-
* @param {string} selector The ID attribute to be used for the search tray
|
|
104
|
-
*/
|
|
105
|
-
renderSearchTray(selector) {
|
|
106
|
-
const searchTray = document.createElement('div');
|
|
107
|
-
searchTray.setAttribute('id', selector.replace(/^#/, ''));
|
|
108
|
-
searchTray.innerHTML = `
|
|
109
|
-
<header>
|
|
110
|
-
<div>
|
|
111
|
-
<h3>Search inside</h3>
|
|
112
|
-
<p data-id="results_count"></p>
|
|
113
|
-
</div>
|
|
114
|
-
<a href="#" class="close"></a>
|
|
115
|
-
</header>
|
|
116
|
-
<form action="" method="get">
|
|
117
|
-
<fieldset>
|
|
118
|
-
<input name="all_files" id="all_files" type="checkbox" />
|
|
119
|
-
<label class="checkbox" for="all_files">Search all files</label>
|
|
120
|
-
<input type="search" name="query" placeholder="Enter a search term" />
|
|
121
|
-
</fieldset>
|
|
122
|
-
</form>
|
|
123
|
-
<div data-id="searchPending" id="search_pending">
|
|
124
|
-
<p>Your search results will appear below</p>
|
|
125
|
-
<div class="loader tc mt20"></div>
|
|
126
|
-
</div>
|
|
127
|
-
<ul data-id="results"></ul>
|
|
128
|
-
`;
|
|
129
|
-
return searchTray;
|
|
130
|
-
}
|
|
131
58
|
|
|
132
59
|
renderSearchNavigation() {
|
|
133
60
|
const selector = 'BRsearch-navigation';
|
|
@@ -215,7 +142,7 @@ class SearchView {
|
|
|
215
142
|
const start = pool.slice(0, pool.length / 2);
|
|
216
143
|
const end = pool.slice(pool.length / 2);
|
|
217
144
|
return closestTo((comparisonFn(start, end, comparator) ? start : end), comparator);
|
|
218
|
-
}
|
|
145
|
+
};
|
|
219
146
|
|
|
220
147
|
const closestPage = closestTo(matchPages, currentPage);
|
|
221
148
|
return this.matches.indexOf(this.matches.find((m) => m.par[0].page === closestPage));
|
|
@@ -272,19 +199,6 @@ class SearchView {
|
|
|
272
199
|
this.updateSearchNavigationButtons();
|
|
273
200
|
}
|
|
274
201
|
|
|
275
|
-
/**
|
|
276
|
-
* @param {array} matches
|
|
277
|
-
*/
|
|
278
|
-
renderMatches(matches) {
|
|
279
|
-
const items = matches.map((match) => `
|
|
280
|
-
<li data-page="${match.par[0].page}" data-page-index="${this.br.leafNumToIndex(match.par[0].page)}">
|
|
281
|
-
<h4>Page ${match.par[0].page}</h4>
|
|
282
|
-
<p>${match.text.replace(this.matcher, '<mark>$1</mark>')}</p>
|
|
283
|
-
</li>
|
|
284
|
-
`);
|
|
285
|
-
this.dom.results.innerHTML = items.join('');
|
|
286
|
-
}
|
|
287
|
-
|
|
288
202
|
/**
|
|
289
203
|
* @param {boolean} bool
|
|
290
204
|
*/
|
|
@@ -293,23 +207,6 @@ class SearchView {
|
|
|
293
207
|
this.br.refs.$BRfooter.find('.BRsearch').css({ visibility: pinsVisibleState });
|
|
294
208
|
}
|
|
295
209
|
|
|
296
|
-
buildMobileDrawer() {
|
|
297
|
-
const mobileSearch = document.createElement('li');
|
|
298
|
-
mobileSearch.innerHTML = `
|
|
299
|
-
<span>
|
|
300
|
-
<span class="DrawerIconWrapper">
|
|
301
|
-
<img class="DrawerIcon" src="${this.br.imagesBaseURL}icon_search_button.svg" />
|
|
302
|
-
</span>
|
|
303
|
-
Search
|
|
304
|
-
</span>
|
|
305
|
-
<div data-id="search_slot">
|
|
306
|
-
</div>
|
|
307
|
-
`;
|
|
308
|
-
mobileSearch.querySelector('[data-id="search_slot"]').appendChild(this.dom.searchTray);
|
|
309
|
-
mobileSearch.classList.add('BRmobileMenu__search');
|
|
310
|
-
return mobileSearch;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
210
|
buildToolbarSearch() {
|
|
314
211
|
const toolbarSearch = document.createElement('span');
|
|
315
212
|
toolbarSearch.classList.add('BRtoolbarSection', 'BRtoolbarSectionSearch');
|
|
@@ -363,28 +260,26 @@ class SearchView {
|
|
|
363
260
|
`)
|
|
364
261
|
.data({ pageIndex })
|
|
365
262
|
.appendTo(this.br.$('.BRnavline'))
|
|
366
|
-
.
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
.click(function (event) {
|
|
263
|
+
.on("mouseenter", (event) => {
|
|
264
|
+
// remove from other markers then turn on just for this
|
|
265
|
+
// XXX should be done when nav slider moves
|
|
266
|
+
const marker = event.currentTarget;
|
|
267
|
+
const tooltip = marker.querySelector('.BRquery');
|
|
268
|
+
const tooltipOffset = tooltip.getBoundingClientRect();
|
|
269
|
+
const targetOffset = marker.getBoundingClientRect();
|
|
270
|
+
const boxSizeAdjust = parseInt(getComputedStyle(tooltip).paddingLeft) * 2;
|
|
271
|
+
if (tooltipOffset.x - boxSizeAdjust < 0) {
|
|
272
|
+
tooltip.style.setProperty('transform', `translateX(-${targetOffset.left - boxSizeAdjust}px)`);
|
|
273
|
+
}
|
|
274
|
+
$('.BRsearch,.BRchapter').removeClass('front');
|
|
275
|
+
$(event.target).addClass('front');
|
|
276
|
+
})
|
|
277
|
+
.on("mouseleave", (event) => $(event.target).removeClass('front'))
|
|
278
|
+
.on("click", function (event) {
|
|
383
279
|
// closures are nested and deep, using an arrow function breaks references.
|
|
384
280
|
// Todo: update to arrow function & clean up closures
|
|
385
281
|
// to remove `bind` dependency
|
|
386
282
|
this.br._searchPluginGoToResult(+$(event.target).data('pageIndex'));
|
|
387
|
-
this.br.updateSearchHilites();
|
|
388
283
|
}.bind(this));
|
|
389
284
|
});
|
|
390
285
|
}
|
|
@@ -393,20 +288,28 @@ class SearchView {
|
|
|
393
288
|
* @param {boolean} bool
|
|
394
289
|
*/
|
|
395
290
|
toggleSearchPending(bool) {
|
|
396
|
-
this.dom.searchPending.classList.toggle('visible', bool);
|
|
397
291
|
if (bool) {
|
|
398
|
-
this.br.showProgressPopup("Search results will appear below...");
|
|
292
|
+
this.br.showProgressPopup("Search results will appear below...", () => this.progressPopupClosed());
|
|
399
293
|
}
|
|
400
294
|
else {
|
|
401
295
|
this.br.removeProgressPopup();
|
|
402
296
|
}
|
|
403
297
|
}
|
|
404
298
|
|
|
405
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Primary callback when user cancels search popup
|
|
301
|
+
*/
|
|
302
|
+
progressPopupClosed() {
|
|
303
|
+
this.toggleSearchPending();
|
|
304
|
+
this.cancelSearch();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
renderErrorModal(textIsProcessing = false) {
|
|
308
|
+
const errorDetails = `${!textIsProcessing ? 'The text may still be processing. ' : ''}Please try again.`;
|
|
406
309
|
this.renderModalMessage(`
|
|
407
310
|
Sorry, there was an error with your search.
|
|
408
311
|
<br />
|
|
409
|
-
|
|
312
|
+
${errorDetails}
|
|
410
313
|
`);
|
|
411
314
|
this.delayModalRemovalFor(4000);
|
|
412
315
|
}
|
|
@@ -445,14 +348,6 @@ class SearchView {
|
|
|
445
348
|
setTimeout(this.br.removeProgressPopup.bind(this.br), timeoutMS);
|
|
446
349
|
}
|
|
447
350
|
|
|
448
|
-
openMobileMenu() {
|
|
449
|
-
this.br.refs.$mmenu.data('mmenu').open();
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
closeMobileMenu() {
|
|
453
|
-
this.br.refs.$mmenu.data('mmenu').close();
|
|
454
|
-
}
|
|
455
|
-
|
|
456
351
|
/**
|
|
457
352
|
* @param {Event} e
|
|
458
353
|
*/
|
|
@@ -461,7 +356,6 @@ class SearchView {
|
|
|
461
356
|
const query = e.target.querySelector('[name="query"]').value;
|
|
462
357
|
if (!query.length) { return false; }
|
|
463
358
|
this.br.search(query);
|
|
464
|
-
this.dom.searchField.blur();
|
|
465
359
|
this.emptyMatches();
|
|
466
360
|
this.toggleSearchPending(true);
|
|
467
361
|
return false;
|
|
@@ -479,9 +373,7 @@ class SearchView {
|
|
|
479
373
|
this.teardownSearchNavigation();
|
|
480
374
|
this.renderSearchNavigation();
|
|
481
375
|
this.bindSearchNavigationEvents();
|
|
482
|
-
this.renderMatches(results.matches);
|
|
483
376
|
this.renderPins(results.matches);
|
|
484
|
-
this.updateResultsCount(results.matches.length);
|
|
485
377
|
this.toggleSearchPending(false);
|
|
486
378
|
if (options.goToFirstResult) {
|
|
487
379
|
$(document).one('BookReader:pageChanged', () => {
|
|
@@ -498,7 +390,6 @@ class SearchView {
|
|
|
498
390
|
handleNavToggledCallback(e) {
|
|
499
391
|
const is_visible = this.br.navigationIsVisible();
|
|
500
392
|
this.togglePinsFor(is_visible);
|
|
501
|
-
this.toggleSearchTray(is_visible ? !!this.dom.results.querySelector('li') : false);
|
|
502
393
|
}
|
|
503
394
|
|
|
504
395
|
handleSearchStarted() {
|
|
@@ -510,9 +401,14 @@ class SearchView {
|
|
|
510
401
|
this.setQuery(this.br.searchTerm);
|
|
511
402
|
}
|
|
512
403
|
|
|
513
|
-
|
|
404
|
+
/**
|
|
405
|
+
* Event listener for: `BookReader:SearchCallbackError`
|
|
406
|
+
* @param {CustomEvent} event
|
|
407
|
+
*/
|
|
408
|
+
handleSearchCallbackError(event = {}) {
|
|
514
409
|
this.toggleSearchPending(false);
|
|
515
|
-
|
|
410
|
+
const isIndexed = event?.detail?.props?.results?.indexed;
|
|
411
|
+
this.renderErrorModal(isIndexed);
|
|
516
412
|
}
|
|
517
413
|
|
|
518
414
|
handleSearchCallbackBookNotIndexed() {
|
|
@@ -528,26 +424,15 @@ class SearchView {
|
|
|
528
424
|
bindEvents() {
|
|
529
425
|
const namespace = 'BookReader:';
|
|
530
426
|
|
|
427
|
+
window.addEventListener(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this));
|
|
531
428
|
$(document).on(`${namespace}SearchCallback`, this.handleSearchCallback.bind(this))
|
|
532
429
|
.on(`${namespace}navToggled`, this.handleNavToggledCallback.bind(this))
|
|
533
430
|
.on(`${namespace}SearchStarted`, this.handleSearchStarted.bind(this))
|
|
534
|
-
.on(`${namespace}SearchCallbackError`, this.handleSearchCallbackError.bind(this))
|
|
535
431
|
.on(`${namespace}SearchCallbackBookNotIndexed`, this.handleSearchCallbackBookNotIndexed.bind(this))
|
|
536
432
|
.on(`${namespace}SearchCallbackEmpty`, this.handleSearchCallbackEmpty.bind(this))
|
|
537
433
|
.on(`${namespace}pageChanged`, this.updateSearchNavigation.bind(this));
|
|
538
434
|
|
|
539
|
-
this.dom.searchTray.addEventListener('submit', this.submitHandler.bind(this));
|
|
540
435
|
this.dom.toolbarSearch.querySelector('form').addEventListener('submit', this.submitHandler.bind(this));
|
|
541
|
-
this.dom.searchField.addEventListener('search', () => {
|
|
542
|
-
if (this.dom.searchField.value) { return; }
|
|
543
|
-
this.clearSearchFieldAndResults();
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
$(this.dom.results).on('click', 'li', (e) => {
|
|
547
|
-
this.br._searchPluginGoToResult(+e.currentTarget.dataset.pageIndex);
|
|
548
|
-
this.br.updateSearchHilites();
|
|
549
|
-
this.closeMobileMenu();
|
|
550
|
-
});
|
|
551
436
|
}
|
|
552
437
|
}
|
|
553
438
|
|
|
@@ -28,6 +28,7 @@ import PageChunkIterator from './PageChunkIterator.js';
|
|
|
28
28
|
* @property {() => void} resume
|
|
29
29
|
* @property {() => void} finish force the sound to 'finish'
|
|
30
30
|
* @property {number => void} setPlaybackRate
|
|
31
|
+
* @property {SpeechSynthesisVoice => void} setVoice
|
|
31
32
|
**/
|
|
32
33
|
|
|
33
34
|
/** Handling bookreader's text-to-speech */
|
|
@@ -133,6 +134,12 @@ export default class AbstractTTSEngine {
|
|
|
133
134
|
.then(() => this.step());
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
/** @param {number} newRate */
|
|
138
|
+
setVoice(voiceURI) {
|
|
139
|
+
this.voice = this.getVoices().find(voice => voice.voiceURI === voiceURI);
|
|
140
|
+
if (this.activeSound) this.activeSound.setVoice(this.voice);
|
|
141
|
+
}
|
|
142
|
+
|
|
136
143
|
/** @param {number} newRate */
|
|
137
144
|
setPlaybackRate(newRate) {
|
|
138
145
|
this.playbackRate = newRate;
|