@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
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import Hammer from "hammerjs";
|
|
3
|
+
/** @typedef {import('./utils/HTMLDimensionsCacher.js').HTMLDimensionsCacher} HTMLDimensionsCacher */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} SmoothZoomable
|
|
7
|
+
* @property {HTMLElement} $container
|
|
8
|
+
* @property {HTMLElement} $visibleWorld
|
|
9
|
+
* @property {number} scale
|
|
10
|
+
* @property {{ x: number, y: number }} scaleCenter
|
|
11
|
+
* @property {HTMLDimensionsCacher} htmlDimensionsCacher
|
|
12
|
+
* @property {function(): void} [attachScrollListeners]
|
|
13
|
+
* @property {function(): void} [detachScrollListeners]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Manages pinch-zoom, ctrl-wheel, and trackpad pinch smooth zooming. */
|
|
17
|
+
export class ModeSmoothZoom {
|
|
18
|
+
/** @param {SmoothZoomable} mode */
|
|
19
|
+
constructor(mode) {
|
|
20
|
+
/** @type {SmoothZoomable} */
|
|
21
|
+
this.mode = mode;
|
|
22
|
+
|
|
23
|
+
/** Non-null when a scale has been enqueued/is being processed by the buffer function */
|
|
24
|
+
this.pinchMoveFrame = null;
|
|
25
|
+
/** Promise for the current/enqueued pinch move frame. Resolves when it is complete. */
|
|
26
|
+
this.pinchMoveFramePromise = Promise.resolve();
|
|
27
|
+
this.oldScale = 1;
|
|
28
|
+
/** @type {{ scale: number, center: { x: number, y: number }}} */
|
|
29
|
+
this.lastEvent = null;
|
|
30
|
+
this.attached = false;
|
|
31
|
+
|
|
32
|
+
/** @type {function(function(): void): any} */
|
|
33
|
+
this.bufferFn = window.requestAnimationFrame.bind(window);
|
|
34
|
+
|
|
35
|
+
// Hammer.js by default set userSelect to None; we don't want that!
|
|
36
|
+
// TODO: Is there any way to do this not globally on Hammer?
|
|
37
|
+
delete Hammer.defaults.cssProps.userSelect;
|
|
38
|
+
this.hammer = new Hammer.Manager(this.mode.$container, {
|
|
39
|
+
touchAction: "pan-x pan-y",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.hammer.add(new Hammer.Pinch());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
attach() {
|
|
46
|
+
if (this.attached) return;
|
|
47
|
+
|
|
48
|
+
this.attachCtrlZoom();
|
|
49
|
+
|
|
50
|
+
// GestureEvents work only on Safari; they interfere with Hammer,
|
|
51
|
+
// so block them.
|
|
52
|
+
this.mode.$container.addEventListener('gesturestart', this._preventEvent);
|
|
53
|
+
this.mode.$container.addEventListener('gesturechange', this._preventEvent);
|
|
54
|
+
this.mode.$container.addEventListener('gestureend', this._preventEvent);
|
|
55
|
+
|
|
56
|
+
// The pinch listeners
|
|
57
|
+
this.hammer.on("pinchstart", this._pinchStart);
|
|
58
|
+
this.hammer.on("pinchmove", this._pinchMove);
|
|
59
|
+
this.hammer.on("pinchend", this._pinchEnd);
|
|
60
|
+
this.hammer.on("pinchcancel", this._pinchCancel);
|
|
61
|
+
|
|
62
|
+
this.attached = true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
detach() {
|
|
66
|
+
this.detachCtrlZoom();
|
|
67
|
+
|
|
68
|
+
// GestureEvents work only on Safari; they interfere with Hammer,
|
|
69
|
+
// so block them.
|
|
70
|
+
this.mode.$container.removeEventListener('gesturestart', this._preventEvent);
|
|
71
|
+
this.mode.$container.removeEventListener('gesturechange', this._preventEvent);
|
|
72
|
+
this.mode.$container.removeEventListener('gestureend', this._preventEvent);
|
|
73
|
+
|
|
74
|
+
// The pinch listeners
|
|
75
|
+
this.hammer.off("pinchstart", this._pinchStart);
|
|
76
|
+
this.hammer.off("pinchmove", this._pinchMove);
|
|
77
|
+
this.hammer.off("pinchend", this._pinchEnd);
|
|
78
|
+
this.hammer.off("pinchcancel", this._pinchCancel);
|
|
79
|
+
|
|
80
|
+
this.attached = false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @param {Event} ev */
|
|
84
|
+
_preventEvent = (ev) => {
|
|
85
|
+
ev.preventDefault();
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
_pinchStart = () => {
|
|
90
|
+
// Do this in case the pinchend hasn't fired yet.
|
|
91
|
+
this.oldScale = 1;
|
|
92
|
+
this.mode.$visibleWorld.style.willChange = "transform";
|
|
93
|
+
this.detachCtrlZoom();
|
|
94
|
+
this.mode.detachScrollListeners?.();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** @param {{ scale: number, center: { x: number, y: number }}} e */
|
|
98
|
+
_pinchMove = async (e) => {
|
|
99
|
+
this.lastEvent = e;
|
|
100
|
+
if (!this.pinchMoveFrame) {
|
|
101
|
+
let pinchMoveFramePromiseRes = null;
|
|
102
|
+
this.pinchMoveFramePromise = new Promise(
|
|
103
|
+
(res) => (pinchMoveFramePromiseRes = res)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Buffer these events; only update the scale when request animation fires
|
|
107
|
+
this.pinchMoveFrame = this.bufferFn(() => {
|
|
108
|
+
this.updateScaleCenter({
|
|
109
|
+
clientX: this.lastEvent.center.x,
|
|
110
|
+
clientY: this.lastEvent.center.y,
|
|
111
|
+
});
|
|
112
|
+
this.mode.scale *= this.lastEvent.scale / this.oldScale;
|
|
113
|
+
this.oldScale = this.lastEvent.scale;
|
|
114
|
+
this.pinchMoveFrame = null;
|
|
115
|
+
pinchMoveFramePromiseRes();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_pinchEnd = async () => {
|
|
121
|
+
// Want this to happen after the pinchMoveFrame,
|
|
122
|
+
// if one is in progress; otherwise setting oldScale
|
|
123
|
+
// messes up the transform.
|
|
124
|
+
await this.pinchMoveFramePromise;
|
|
125
|
+
this.mode.scaleCenter = { x: 0.5, y: 0.5 };
|
|
126
|
+
this.oldScale = 1;
|
|
127
|
+
this.mode.$visibleWorld.style.willChange = "auto";
|
|
128
|
+
this.attachCtrlZoom();
|
|
129
|
+
this.mode.attachScrollListeners?.();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
_pinchCancel = async () => {
|
|
133
|
+
// iOS fires pinchcancel ~randomly; it looks like it sometimes
|
|
134
|
+
// thinks the pinch becomes a pan, at which point it cancels?
|
|
135
|
+
await this._pinchEnd();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** @private */
|
|
139
|
+
attachCtrlZoom() {
|
|
140
|
+
window.addEventListener("wheel", this._handleCtrlWheel, { passive: false });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** @private */
|
|
144
|
+
detachCtrlZoom() {
|
|
145
|
+
window.removeEventListener("wheel", this._handleCtrlWheel);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** @param {WheelEvent} ev **/
|
|
149
|
+
_handleCtrlWheel = (ev) => {
|
|
150
|
+
if (!ev.ctrlKey) return;
|
|
151
|
+
ev.preventDefault();
|
|
152
|
+
const zoomMultiplier =
|
|
153
|
+
// Zooming on macs was painfully slow; likely due to their better
|
|
154
|
+
// trackpads. Give them a higher zoom rate.
|
|
155
|
+
/Mac/i.test(navigator.platform)
|
|
156
|
+
? 0.045
|
|
157
|
+
: // This worked well for me on Windows
|
|
158
|
+
0.03;
|
|
159
|
+
|
|
160
|
+
// Zoom around the cursor
|
|
161
|
+
this.updateScaleCenter(ev);
|
|
162
|
+
this.mode.scale *= 1 - Math.sign(ev.deltaY) * zoomMultiplier;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {object} param0
|
|
167
|
+
* @param {number} param0.clientX
|
|
168
|
+
* @param {number} param0.clientY
|
|
169
|
+
*/
|
|
170
|
+
updateScaleCenter({ clientX, clientY }) {
|
|
171
|
+
const bc = this.mode.htmlDimensionsCacher.boundingClientRect;
|
|
172
|
+
this.mode.scaleCenter = {
|
|
173
|
+
x: (clientX - bc.left) / this.mode.htmlDimensionsCacher.clientWidth,
|
|
174
|
+
y: (clientY - bc.top) / this.mode.htmlDimensionsCacher.clientHeight,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { notInArray, clamp } from './utils.js';
|
|
3
3
|
import { EVENTS } from './events.js';
|
|
4
|
+
import { DragScrollable } from './DragScrollable.js';
|
|
4
5
|
/** @typedef {import('../BookREader.js').default} BookReader */
|
|
5
6
|
/** @typedef {import('./BookModel.js').PageIndex} PageIndex */
|
|
6
7
|
/** @typedef {import('./BookModel.js').BookModel} BookModel */
|
|
@@ -234,20 +235,27 @@ export class ModeThumb {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
/**
|
|
237
|
-
* @param {
|
|
238
|
+
* @param {'in' | 'out'} direction
|
|
238
239
|
*/
|
|
239
240
|
zoom(direction) {
|
|
240
241
|
const oldColumns = this.br.thumbColumns;
|
|
241
242
|
switch (direction) {
|
|
242
|
-
case
|
|
243
|
-
this.br.thumbColumns += 1;
|
|
244
|
-
break;
|
|
245
|
-
case 1:
|
|
243
|
+
case 'in':
|
|
246
244
|
this.br.thumbColumns -= 1;
|
|
247
245
|
break;
|
|
246
|
+
case 'out':
|
|
247
|
+
this.br.thumbColumns += 1;
|
|
248
|
+
break;
|
|
249
|
+
default:
|
|
250
|
+
console.error(`Unsupported direction: ${direction}`);
|
|
248
251
|
}
|
|
249
252
|
|
|
250
|
-
|
|
253
|
+
// Limit zoom in/out columns
|
|
254
|
+
this.br.thumbColumns = clamp(
|
|
255
|
+
this.br.thumbColumns,
|
|
256
|
+
this.br.options.thumbMinZoomColumns,
|
|
257
|
+
this.br.options.thumbMaxZoomColumns
|
|
258
|
+
);
|
|
251
259
|
|
|
252
260
|
if (this.br.thumbColumns != oldColumns) {
|
|
253
261
|
this.br.displayedRows = []; /* force a gallery redraw */
|
|
@@ -279,7 +287,7 @@ export class ModeThumb {
|
|
|
279
287
|
|
|
280
288
|
this.br.refs.$brPageViewEl = $("<div class='BRpageview'></div>");
|
|
281
289
|
this.br.refs.$brContainer.append(this.br.refs.$brPageViewEl);
|
|
282
|
-
this.br.refs.$brContainer
|
|
290
|
+
this.dragScrollable = this.dragScrollable || new DragScrollable(this.br.refs.$brContainer[0], {preventDefault: true});
|
|
283
291
|
|
|
284
292
|
this.br.bindGestures(this.br.refs.$brContainer);
|
|
285
293
|
|
|
@@ -330,7 +338,7 @@ export class ModeThumb {
|
|
|
330
338
|
} else {
|
|
331
339
|
this.br.animating = true;
|
|
332
340
|
this.br.refs.$brContainer.stop(true)
|
|
333
|
-
.animate({ scrollTop: leafTop }, 'fast', () => { this.br.animating = false });
|
|
341
|
+
.animate({ scrollTop: leafTop }, 'fast', () => { this.br.animating = false; });
|
|
334
342
|
}
|
|
335
343
|
}
|
|
336
344
|
}
|
|
@@ -240,35 +240,6 @@ export class Navbar {
|
|
|
240
240
|
return this.$nav;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
/**
|
|
244
|
-
* Initialize the navigation bar when embedded
|
|
245
|
-
*/
|
|
246
|
-
initEmbed() {
|
|
247
|
-
const { br } = this;
|
|
248
|
-
// IA-specific
|
|
249
|
-
const thisLink = (window.location + '')
|
|
250
|
-
.replace('?ui=embed','')
|
|
251
|
-
.replace('/stream/', '/details/')
|
|
252
|
-
.replace('#', '/');
|
|
253
|
-
const logoHtml = br.showLogo ? `<a class="logo" href="${br.logoURL}" target="_blank"></a>` : '';
|
|
254
|
-
|
|
255
|
-
br.refs.$BRfooter = this.$root = $('<div class="BRfooter"></div>');
|
|
256
|
-
br.refs.$BRnav = this.$nav = $(
|
|
257
|
-
`<div class="BRnav BRnavEmbed">
|
|
258
|
-
${logoHtml}
|
|
259
|
-
<span class="BRembedreturn">
|
|
260
|
-
<a href="${thisLink}" target="_blank">${br.bookTitle}</a>
|
|
261
|
-
</span>
|
|
262
|
-
<span class="BRtoolbarbuttons">
|
|
263
|
-
<button class="BRicon book_left"></button>
|
|
264
|
-
<button class="BRicon book_right"></button>
|
|
265
|
-
<button class="BRicon full"></button>
|
|
266
|
-
</span>
|
|
267
|
-
</div>`);
|
|
268
|
-
this.$root.append(this.$nav);
|
|
269
|
-
br.refs.$br.append(this.$root);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
243
|
/**
|
|
273
244
|
* Returns the textual representation of the current page for the navbar
|
|
274
245
|
* @param {number} index
|
|
@@ -331,9 +302,9 @@ export function getNavPageNumHtml(index, numLeafs, pageNum, pageType, maxPageNum
|
|
|
331
302
|
|
|
332
303
|
if (!pageIsAsserted) {
|
|
333
304
|
const pageIndex = index + 1;
|
|
334
|
-
return `
|
|
305
|
+
return `(${pageIndex} of ${numLeafs})`; // Page (8 of 10)
|
|
335
306
|
}
|
|
336
307
|
|
|
337
308
|
const bookLengthLabel = maxPageNum ? ` of ${maxPageNum}` : '';
|
|
338
|
-
return
|
|
309
|
+
return `${pageNum}${bookLengthLabel}`;
|
|
339
310
|
}
|
|
@@ -58,14 +58,14 @@ export class PageContainer {
|
|
|
58
58
|
backgroundLayers.push(`url("${this.loadingImage}") center/20px no-repeat`);
|
|
59
59
|
}
|
|
60
60
|
if (nextBestLoadedReduce) {
|
|
61
|
-
backgroundLayers.push(`url("${this.page.getURI(nextBestLoadedReduce, 0)}") center/100% no-repeat`);
|
|
61
|
+
backgroundLayers.push(`url("${this.page.getURI(nextBestLoadedReduce, 0)}") center/100% 100% no-repeat`);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (!alreadyLoaded) {
|
|
65
65
|
this.$img
|
|
66
66
|
.css('background', backgroundLayers.join(','))
|
|
67
67
|
.one('loadend', async (ev) => {
|
|
68
|
-
$(ev.target).css({ 'background': '' })
|
|
68
|
+
$(ev.target).css({ 'background': '' });
|
|
69
69
|
$(ev.target).parent().removeClass('BRpageloading');
|
|
70
70
|
});
|
|
71
71
|
}
|
|
@@ -73,3 +73,48 @@ export class PageContainer {
|
|
|
73
73
|
return this;
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {PageModel} page
|
|
80
|
+
* @param {string} className
|
|
81
|
+
*/
|
|
82
|
+
export function createSVGPageLayer(page, className) {
|
|
83
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
84
|
+
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
85
|
+
svg.setAttribute("viewBox", `0 0 ${page.width} ${page.height}`);
|
|
86
|
+
svg.setAttribute('class', `BRPageLayer ${className}`);
|
|
87
|
+
svg.setAttribute('preserveAspectRatio', 'none');
|
|
88
|
+
return svg;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {{ l: number, r: number, b: number, t: number }} box
|
|
93
|
+
*/
|
|
94
|
+
export function boxToSVGRect({ l: left, r: right, b: bottom, t: top }) {
|
|
95
|
+
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
96
|
+
rect.setAttribute("x", left.toString());
|
|
97
|
+
rect.setAttribute("y", top.toString());
|
|
98
|
+
rect.setAttribute("width", (right - left).toString());
|
|
99
|
+
rect.setAttribute("height", (bottom - top).toString());
|
|
100
|
+
return rect;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {string} layerClass
|
|
105
|
+
* @param {Array<{ l: number, r: number, b: number, t: number }>} boxes
|
|
106
|
+
* @param {PageModel} page
|
|
107
|
+
* @param {HTMLElement} containerEl
|
|
108
|
+
*/
|
|
109
|
+
export function renderBoxesInPageContainerLayer(layerClass, boxes, page, containerEl) {
|
|
110
|
+
const mountedSvg = containerEl.querySelector(`.${layerClass}`);
|
|
111
|
+
// Create the layer if it's not there
|
|
112
|
+
const svg = mountedSvg || createSVGPageLayer(page, layerClass);
|
|
113
|
+
if (!mountedSvg) {
|
|
114
|
+
// Insert after the image if the image is already loaded.
|
|
115
|
+
const imgEl = containerEl.querySelector('.BRpageimage');
|
|
116
|
+
if (imgEl) $(svg).insertAfter(imgEl);
|
|
117
|
+
else $(svg).prependTo(containerEl);
|
|
118
|
+
}
|
|
119
|
+
boxes.forEach(box => svg.appendChild(boxToSVGRect(box)));
|
|
120
|
+
}
|
|
@@ -54,7 +54,7 @@ export class Toolbar {
|
|
|
54
54
|
.attr({href: br.bookUrl, title: br.bookUrlTitle})
|
|
55
55
|
.addClass('BRreturn')
|
|
56
56
|
.html(br.bookUrlText || br.bookTitle)
|
|
57
|
-
)
|
|
57
|
+
);
|
|
58
58
|
} else if (br.bookTitle) {
|
|
59
59
|
$titleSectionEl.append(br.bookUrlText || br.bookTitle);
|
|
60
60
|
}
|
|
@@ -212,7 +212,7 @@ export class Toolbar {
|
|
|
212
212
|
$form.appendTo($shareDiv);
|
|
213
213
|
|
|
214
214
|
$form.find('.fieldset-embed input').on('change', event => {
|
|
215
|
-
const form = $(event.target).parents('form
|
|
215
|
+
const form = $(event.target).parents('form').first();
|
|
216
216
|
const params = {};
|
|
217
217
|
params.mode = $(form.find('.fieldset-embed input[name=pages]:checked')).val();
|
|
218
218
|
if (form.find('.fieldset-embed input[name=thispage]').prop('checked')) {
|
|
@@ -232,12 +232,12 @@ export class Toolbar {
|
|
|
232
232
|
// Bind share buttons
|
|
233
233
|
|
|
234
234
|
// Use url without hashes
|
|
235
|
-
$form.find('.facebook-share-button').click(
|
|
235
|
+
$form.find('.facebook-share-button').on("click", () => {
|
|
236
236
|
const params = $.param({ u: this._getSocialShareUrl() });
|
|
237
237
|
const url = 'https://www.facebook.com/sharer.php?' + params;
|
|
238
238
|
createPopup(url, 600, 400, 'Share');
|
|
239
239
|
});
|
|
240
|
-
$form.find('.twitter-share-button').click(
|
|
240
|
+
$form.find('.twitter-share-button').on("click", () => {
|
|
241
241
|
const params = $.param({
|
|
242
242
|
url: this._getSocialShareUrl(),
|
|
243
243
|
text: br.bookTitle
|
|
@@ -245,7 +245,7 @@ export class Toolbar {
|
|
|
245
245
|
const url = 'https://twitter.com/intent/tweet?' + params;
|
|
246
246
|
createPopup(url, 600, 400, 'Share');
|
|
247
247
|
});
|
|
248
|
-
$form.find('.email-share-button').click(
|
|
248
|
+
$form.find('.email-share-button').on("click", () => {
|
|
249
249
|
const body = `${br.bookTitle}\n\n${this._getSocialShareUrl()}`;
|
|
250
250
|
window.location.href = `mailto:?subject=${encodeURI(br.bookTitle)}&body=${encodeURI(body)}`;
|
|
251
251
|
});
|
|
@@ -25,6 +25,10 @@ export const DEFAULT_OPTIONS = {
|
|
|
25
25
|
thumbMaxLoading: 4,
|
|
26
26
|
/** spacing between thumbnails */
|
|
27
27
|
thumbPadding: 10,
|
|
28
|
+
/** min zoom in columns */
|
|
29
|
+
thumbMinZoomColumns: 2,
|
|
30
|
+
/** max zoom out columns */
|
|
31
|
+
thumbMaxZoomColumns: 8,
|
|
28
32
|
|
|
29
33
|
/** @type {number | 'fast' | 'slow'} speed for flip animation */
|
|
30
34
|
flipSpeed: 'fast',
|
|
@@ -275,6 +279,12 @@ export const DEFAULT_OPTIONS = {
|
|
|
275
279
|
*/
|
|
276
280
|
startFullscreen: false,
|
|
277
281
|
|
|
282
|
+
/**
|
|
283
|
+
* @type {Boolean}
|
|
284
|
+
* will show logo at fullscreen mode
|
|
285
|
+
*/
|
|
286
|
+
enableFSLogoShortcut: false,
|
|
287
|
+
|
|
278
288
|
/**
|
|
279
289
|
* @type {Boolean}
|
|
280
290
|
* On init, by default, we want to handle resizing bookreader
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { debounce } from '../utils';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Computing these things repeatedly is expensive (the browser needs to
|
|
6
|
+
* do a lot of computations/redrawing to make sure these are correct),
|
|
7
|
+
* so we store them here, and only recompute them when necessary:
|
|
8
|
+
* - window resize could have cause the container to change size
|
|
9
|
+
* - zoom could have cause scrollbars to appear/disappear, changing
|
|
10
|
+
* the client size.
|
|
11
|
+
*/
|
|
12
|
+
export class HTMLDimensionsCacher {
|
|
13
|
+
clientWidth = 100;
|
|
14
|
+
clientHeight = 100;
|
|
15
|
+
|
|
16
|
+
boundingClientRect = { top: 0, left: 0 };
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {HTMLElement} element
|
|
20
|
+
*/
|
|
21
|
+
constructor(element) {
|
|
22
|
+
/** @type {HTMLElement} */
|
|
23
|
+
this.element = element;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
updateClientSizes = () => {
|
|
27
|
+
const bc = this.element.getBoundingClientRect();
|
|
28
|
+
this.clientWidth = this.element.clientWidth;
|
|
29
|
+
this.clientHeight = this.element.clientHeight;
|
|
30
|
+
this.boundingClientRect.top = bc.top;
|
|
31
|
+
this.boundingClientRect.left = bc.left;
|
|
32
|
+
}
|
|
33
|
+
debouncedUpdateClientSizes = debounce(this.updateClientSizes, 150, false);
|
|
34
|
+
|
|
35
|
+
/** @param {EventTarget} win */
|
|
36
|
+
attachResizeListener(win = window) {
|
|
37
|
+
win.addEventListener('resize', this.debouncedUpdateClientSizes);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** @param {EventTarget} win */
|
|
41
|
+
detachResizeListener(win = window) {
|
|
42
|
+
win.removeEventListener('resize', this.debouncedUpdateClientSizes);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/BookReader/utils.js
CHANGED
|
@@ -40,6 +40,24 @@ export function notInArray(value, array) {
|
|
|
40
40
|
return !array.includes(value);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Determines the active element, going into shadow doms.
|
|
45
|
+
* @return {Element}
|
|
46
|
+
*/
|
|
47
|
+
export function getActiveElement(doc = document, recurseShadowDom = true) {
|
|
48
|
+
const activeElement = doc.activeElement;
|
|
49
|
+
if (recurseShadowDom && activeElement?.shadowRoot) {
|
|
50
|
+
return getActiveElement(activeElement.shadowRoot, true);
|
|
51
|
+
}
|
|
52
|
+
return activeElement;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Check if an input field/textarea is active. Also checks shadow DOMs. */
|
|
56
|
+
export function isInputActive(doc = document) {
|
|
57
|
+
const activeEl = getActiveElement(doc);
|
|
58
|
+
return activeEl?.tagName == "INPUT" || activeEl?.tagName == "TEXTAREA";
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
/**
|
|
44
62
|
* @param {HTMLIFrameElement} iframe
|
|
45
63
|
* @return {Document}
|
|
@@ -80,16 +98,17 @@ export function encodeURIComponentPlus(value) {
|
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
/**
|
|
101
|
+
* @template {Function} T
|
|
83
102
|
* Returns a function, that, as long as it continues to be invoked, will not
|
|
84
103
|
* be triggered. The function will be called after it stops being called for
|
|
85
104
|
* N milliseconds. If `immediate` is passed, trigger the function on the
|
|
86
105
|
* leading edge, instead of the trailing.
|
|
87
106
|
* @see https://davidwalsh.name/javascript-debounce-function
|
|
88
107
|
*
|
|
89
|
-
* @param {
|
|
108
|
+
* @param {T} func
|
|
90
109
|
* @param {number} wait
|
|
91
110
|
* @param {boolean} immediate
|
|
92
|
-
* @return {
|
|
111
|
+
* @return {T}
|
|
93
112
|
*/
|
|
94
113
|
export function debounce(func, wait, immediate) {
|
|
95
114
|
let timeout;
|
|
@@ -108,12 +127,13 @@ export function debounce(func, wait, immediate) {
|
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
/**
|
|
130
|
+
* @template T
|
|
111
131
|
* Throttle function
|
|
112
132
|
* @see https://remysharp.com/2010/07/21/throttling-function-calls
|
|
113
|
-
* @param {
|
|
133
|
+
* @param {T} fn
|
|
114
134
|
* @param {number} threshold
|
|
115
135
|
* @param {boolean} delay
|
|
116
|
-
* @return {
|
|
136
|
+
* @return {T}
|
|
117
137
|
*/
|
|
118
138
|
export function throttle(fn, threshold, delay) {
|
|
119
139
|
threshold || (threshold = 250);
|
|
@@ -160,14 +180,6 @@ export function PolyfilledCustomEvent(eventName, {bubbles = false, cancelable =
|
|
|
160
180
|
return event;
|
|
161
181
|
}
|
|
162
182
|
|
|
163
|
-
/**
|
|
164
|
-
* Promise based sleep - resolves at default 500ms
|
|
165
|
-
* @param {Number} wait time in milliseconds
|
|
166
|
-
*/
|
|
167
|
-
export function sleep(ms = 500) {
|
|
168
|
-
return new Promise(res => setTimeout(res(true), ms));
|
|
169
|
-
}
|
|
170
|
-
|
|
171
183
|
/*
|
|
172
184
|
* Returns the number pixels something should be rendered at to be ~1n on the users
|
|
173
185
|
* screen when measured with a ruler.
|
|
@@ -179,7 +191,50 @@ export function calcScreenDPI() {
|
|
|
179
191
|
const dpi = el.offsetWidth;
|
|
180
192
|
document.body.removeChild(el);
|
|
181
193
|
|
|
182
|
-
|
|
194
|
+
// Do you believe in magic... numbers? We tested on some devices, and the displayed
|
|
195
|
+
// size of `width: 1in` was less than desired. On @pezvi's mac, it was ~75% ; on
|
|
196
|
+
// @cdrini's laptop it was ~85%. Since we want to avoid things appearing too small,
|
|
197
|
+
// let's just use a multiplier of 1.25
|
|
198
|
+
const screenDPI = dpi * 1.25;
|
|
183
199
|
// This will return 0 in testing; never want it to be 0!
|
|
184
200
|
return screenDPI == 0 ? 100 : screenDPI;
|
|
185
201
|
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @param {number[]} nums
|
|
205
|
+
* @returns {number}
|
|
206
|
+
*/
|
|
207
|
+
export function sum(nums) {
|
|
208
|
+
return nums.reduce((cur, acc) => cur + acc, 0);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @template T
|
|
213
|
+
* @param {Generator<T>} gen
|
|
214
|
+
* @returns {T[]}
|
|
215
|
+
*/
|
|
216
|
+
export function genToArray(gen) {
|
|
217
|
+
const result = [];
|
|
218
|
+
for (const item of gen) {
|
|
219
|
+
result.push(item);
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Check if arrays contain the same elements. Does reference comparison.
|
|
226
|
+
* @param {Array} arr1
|
|
227
|
+
* @param {Array} arr2
|
|
228
|
+
*/
|
|
229
|
+
export function arrEquals(arr1, arr2) {
|
|
230
|
+
return arr1.length == arr2.length && arr1.every((x, i) => x == arr2[i]);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Check if array has changed; namely to be used with lit's property.hasChanged
|
|
235
|
+
* @param {Array} [arr1]
|
|
236
|
+
* @param {Array} [arr2]
|
|
237
|
+
*/
|
|
238
|
+
export function arrChanged(arr1, arr2) {
|
|
239
|
+
return arr1 && arr2 && !arrEquals(arr1, arr2);
|
|
240
|
+
}
|