@internetarchive/bookreader 5.0.0-11-multiple-files → 5.0.0-110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BookReader/474.js +2 -0
- package/BookReader/474.js.map +1 -0
- package/BookReader/BookReader.css +616 -1467
- package/BookReader/BookReader.js +2 -21564
- package/BookReader/BookReader.js.LICENSE.txt +20 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/bergamot-translator-worker.js +2966 -0
- package/BookReader/bergamot-translator-worker.wasm +0 -0
- package/BookReader/hypothesis/LICENSE +50 -0
- package/BookReader/hypothesis/README.md +55 -0
- package/BookReader/hypothesis/build/boot.js +1 -0
- package/BookReader/hypothesis/build/manifest.json +20 -0
- package/BookReader/hypothesis/build/scripts/annotator.bundle.js +184 -0
- package/BookReader/hypothesis/build/scripts/annotator.bundle.js.map +1 -0
- package/BookReader/hypothesis/build/scripts/sidebar.bundle.js +798 -0
- package/BookReader/hypothesis/build/scripts/sidebar.bundle.js.map +1 -0
- package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js +711 -0
- package/BookReader/hypothesis/build/scripts/ui-playground.bundle.js.map +1 -0
- package/BookReader/hypothesis/build/styles/annotator.css +2235 -0
- package/BookReader/hypothesis/build/styles/annotator.css.map +1 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/BookReader/hypothesis/build/styles/highlights.css +2 -0
- package/BookReader/hypothesis/build/styles/highlights.css.map +1 -0
- package/BookReader/hypothesis/build/styles/katex.min.css +2 -0
- package/BookReader/hypothesis/build/styles/katex.min.css.map +1 -0
- package/BookReader/hypothesis/build/styles/pdfjs-overrides.css +2 -0
- package/BookReader/hypothesis/build/styles/pdfjs-overrides.css.map +1 -0
- package/BookReader/hypothesis/build/styles/sidebar.css +2731 -0
- package/BookReader/hypothesis/build/styles/sidebar.css.map +1 -0
- package/BookReader/hypothesis/build/styles/ui-playground.css +2659 -0
- package/BookReader/hypothesis/build/styles/ui-playground.css.map +1 -0
- package/BookReader/hypothesis/package.json +126 -0
- package/BookReader/ia-bookreader-bundle.js +1907 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +19 -0
- package/BookReader/ia-bookreader-bundle.js.map +1 -0
- package/BookReader/icons/1up.svg +1 -12
- package/BookReader/icons/2up.svg +1 -15
- package/BookReader/icons/advance.svg +3 -26
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -0
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -17
- package/BookReader/icons/fullscreen_exit.svg +1 -17
- package/BookReader/icons/hamburger.svg +1 -15
- package/BookReader/icons/left-arrow.svg +1 -12
- package/BookReader/icons/magnify-minus.svg +1 -16
- package/BookReader/icons/magnify-plus.svg +1 -17
- package/BookReader/icons/magnify.svg +1 -15
- package/BookReader/icons/pause.svg +1 -23
- package/BookReader/icons/play.svg +1 -22
- package/BookReader/icons/playback-speed.svg +1 -34
- package/BookReader/icons/read-aloud.svg +1 -22
- package/BookReader/icons/review.svg +3 -22
- package/BookReader/icons/slider-toggle.svg +1 -0
- package/BookReader/icons/thumbnails.svg +1 -17
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -22
- package/BookReader/images/BRicons.svg +5 -94
- package/BookReader/images/books_graphic.svg +1 -177
- package/BookReader/images/hypothesis.ico +0 -0
- package/BookReader/images/icon_book.svg +1 -12
- package/BookReader/images/icon_bookmark.svg +1 -12
- package/BookReader/images/icon_experiment.svg +1 -0
- package/BookReader/images/icon_gear.svg +1 -14
- package/BookReader/images/icon_hamburger.svg +1 -20
- package/BookReader/images/icon_home.svg +1 -21
- package/BookReader/images/icon_info.svg +1 -11
- package/BookReader/images/icon_one_page.svg +1 -8
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.svg +1 -1
- package/BookReader/images/icon_playback-rate.svg +1 -15
- package/BookReader/images/icon_search_button.svg +1 -8
- package/BookReader/images/icon_share.svg +1 -9
- package/BookReader/images/icon_skip-ahead.svg +1 -6
- package/BookReader/images/icon_skip-back.svg +2 -13
- package/BookReader/images/icon_speaker.svg +1 -18
- package/BookReader/images/icon_speaker_open.svg +1 -10
- package/BookReader/images/icon_thumbnails.svg +1 -12
- package/BookReader/images/icon_toc.svg +1 -5
- package/BookReader/images/icon_two_pages.svg +1 -9
- package/BookReader/images/marker_chap-off.svg +1 -11
- package/BookReader/images/marker_chap-on.svg +1 -11
- package/BookReader/images/marker_srch-on.svg +1 -11
- package/BookReader/images/translate.svg +1 -0
- package/BookReader/images/unviewable_page.png +0 -0
- package/BookReader/jquery-3.js +2 -0
- package/BookReader/jquery-3.js.LICENSE.txt +24 -0
- package/BookReader/plugins/plugin.archive_analytics.js +1 -172
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -165
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +19 -301
- package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.experiments.js +3 -0
- package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.experiments.js.map +1 -0
- package/BookReader/plugins/plugin.iframe.js +1 -74
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.iiif.js +2 -0
- package/BookReader/plugins/plugin.iiif.js.map +1 -0
- package/BookReader/plugins/plugin.resume.js +1 -368
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +2 -1420
- package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +2 -1080
- package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.translate.js +137 -0
- package/BookReader/plugins/plugin.translate.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.translate.js.map +1 -0
- package/BookReader/plugins/plugin.tts.js +2 -9193
- package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +1 -269
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReader/plugins/translator-worker.js +2 -0
- package/BookReader/plugins/translator-worker.js.map +1 -0
- package/BookReader/silence.mp3 +0 -0
- package/BookReader/translator-worker.js +475 -0
- package/BookReader/webcomponents-bundle.js +3 -0
- package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
- package/BookReader/webcomponents-bundle.js.map +1 -0
- package/README.md +14 -3
- package/jsconfig.json +19 -0
- package/package.json +92 -70
- package/src/BookReader/BookModel.js +92 -46
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/ImageCache.js +49 -16
- package/src/BookReader/Mode1Up.js +66 -356
- package/src/BookReader/Mode1UpLit.js +392 -0
- package/src/BookReader/Mode2Up.js +87 -1315
- package/src/BookReader/Mode2UpLit.js +788 -0
- package/src/BookReader/ModeAbstract.js +43 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +312 -0
- package/src/BookReader/ModeThumb.js +30 -16
- package/src/BookReader/Navbar/Navbar.js +201 -76
- package/src/BookReader/PageContainer.js +120 -23
- package/src/BookReader/ReduceSet.js +3 -3
- package/src/BookReader/Toolbar/Toolbar.js +19 -41
- package/src/BookReader/events.js +3 -3
- package/src/BookReader/options.js +94 -17
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils/SelectionObserver.js +45 -0
- package/src/BookReader/utils/classes.js +1 -1
- package/src/BookReader/utils.js +141 -13
- package/src/BookReader.js +711 -1241
- package/src/BookReaderPlugin.js +52 -0
- package/src/assets/icons/close-circle-dark.svg +1 -0
- package/src/assets/icons/magnify-minus.svg +3 -7
- package/src/assets/icons/magnify-plus.svg +3 -7
- package/src/assets/icons/slider-toggle.svg +1 -0
- package/src/assets/icons/voice.svg +1 -0
- package/src/assets/images/hypothesis.ico +0 -0
- package/src/assets/images/icon_experiment.svg +1 -0
- package/src/assets/images/translate.svg +1 -0
- package/src/assets/images/unviewable_page.png +0 -0
- package/src/assets/silence.mp3 +0 -0
- package/src/css/BookReader.scss +1 -17
- package/src/css/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRicon.scss +8 -2
- package/src/css/_BRmain.scss +33 -27
- package/src/css/_BRnav.scss +74 -70
- package/src/css/_BRpages.scss +171 -42
- package/src/css/_BRsearch.scss +69 -235
- package/src/css/_BRtoolbar.scss +5 -5
- package/src/css/_TextSelection.scss +129 -24
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +24 -7
- package/src/css/_icons.scss +14 -1
- package/src/{BookNavigator/assets → css}/button-base.js +10 -3
- package/src/css/icon_checkmark.js +9 -0
- package/src/css/sharedStyles.js +15 -0
- package/src/ia-bookreader/downloads/downloads-provider.js +81 -0
- package/src/{BookNavigator → ia-bookreader}/downloads/downloads.js +29 -25
- package/src/ia-bookreader/ia-bookreader.js +666 -0
- package/src/ia-bookreader/sharing.js +27 -0
- package/src/ia-bookreader/viewable-files.js +98 -0
- package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments-provider.js +17 -17
- package/src/{BookNavigator → ia-bookreader}/visual-adjustments/visual-adjustments.js +75 -67
- package/src/{BookNavigator → plugins}/bookmarks/bookmark-button.js +4 -3
- package/src/{BookNavigator/assets → plugins/bookmarks}/bookmark-colors.js +1 -1
- package/src/{BookNavigator → plugins}/bookmarks/bookmark-edit.js +44 -32
- package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
- package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +5 -10
- package/src/plugins/bookmarks/bookmarks-provider.js +63 -0
- package/src/{BookNavigator → plugins/bookmarks}/delete-modal-actions.js +1 -1
- package/src/{BookNavigator → plugins}/bookmarks/ia-bookmarks.js +117 -68
- package/src/plugins/plugin.archive_analytics.js +84 -78
- package/src/plugins/plugin.autoplay.js +99 -104
- package/src/plugins/plugin.chapters.js +310 -201
- package/src/plugins/plugin.experiments.js +321 -0
- package/src/plugins/plugin.iframe.js +1 -1
- package/src/plugins/plugin.iiif.js +141 -0
- package/src/plugins/plugin.resume.js +53 -50
- package/src/plugins/plugin.text_selection.js +522 -219
- package/src/plugins/plugin.vendor-fullscreen.js +7 -7
- package/src/plugins/search/plugin.search.js +380 -360
- package/src/{BookNavigator → plugins}/search/search-provider.js +94 -32
- package/src/{BookNavigator → plugins}/search/search-results.js +108 -90
- package/src/plugins/search/utils.js +50 -0
- package/src/plugins/search/view.js +79 -210
- package/src/plugins/translate/TranslationManager.js +164 -0
- package/src/plugins/translate/plugin.translate.js +512 -0
- package/src/plugins/tts/AbstractTTSEngine.js +78 -49
- package/src/plugins/tts/FestivalTTSEngine.js +21 -31
- package/src/plugins/tts/PageChunk.js +33 -21
- package/src/plugins/tts/PageChunkIterator.js +11 -17
- package/src/plugins/tts/WebTTSEngine.js +131 -91
- package/src/plugins/tts/plugin.tts.js +345 -350
- package/src/plugins/tts/utils.js +77 -49
- package/src/plugins/url/UrlPlugin.js +191 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
- package/src/util/TextSelectionManager.js +282 -0
- package/src/util/browserSniffing.js +33 -1
- package/src/util/cache.js +20 -0
- package/src/util/docCookies.js +21 -2
- package/src/util/lit.js +15 -0
- package/src/util/strings.js +1 -0
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.eslintrc.js +0 -49
- package/.gitattributes +0 -2
- package/.github/ISSUE_TEMPLATE/bug.md +0 -32
- package/.github/ISSUE_TEMPLATE/feature-request.md +0 -30
- package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -15
- package/.github/workflows/node.js.yml +0 -28
- package/.github/workflows/npm-publish.yml +0 -47
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -14330
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/icons/sort-ascending.svg +0 -1
- package/BookReader/icons/sort-descending.svg +0 -1
- package/BookReader/jquery-1.10.1.js +0 -108
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -369
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReader/plugins/plugin.mobile_nav.js +0 -335
- package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
- package/BookReaderDemo/BookReaderDemo.css +0 -41
- package/BookReaderDemo/BookReaderJSAdvanced.js +0 -115
- package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
- package/BookReaderDemo/BookReaderJSSimple.js +0 -55
- package/BookReaderDemo/IIIFBookReader.js +0 -207
- package/BookReaderDemo/assets/v5/Bookreader-logo-cool-grad.svg +0 -1
- package/BookReaderDemo/assets/v5/Bookreader-logo-flat.svg +0 -1
- package/BookReaderDemo/assets/v5/Bookreader-logo-hex-cool-grad.png +0 -0
- package/BookReaderDemo/assets/v5/Bookreader-logo-hex-flat.png +0 -0
- package/BookReaderDemo/assets/v5/Bookreader-logo-lines.png +0 -0
- package/BookReaderDemo/assets/v5/Bookreader-logo-lines.svg +0 -1
- package/BookReaderDemo/assets/v5/Bookreader-logo-warm.svg +0 -1
- package/BookReaderDemo/assets/v5/bookreader-logo-renders@1x.png +0 -0
- package/BookReaderDemo/assets/v5/bookreader-logo-renders@2x.png +0 -0
- package/BookReaderDemo/assets/v5/bookreader-v5-screenshot.png +0 -0
- package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
- package/BookReaderDemo/demo-advanced.html +0 -33
- package/BookReaderDemo/demo-autoplay.html +0 -38
- package/BookReaderDemo/demo-embed-iframe-src.html +0 -84
- package/BookReaderDemo/demo-embed.html +0 -26
- package/BookReaderDemo/demo-fullscreen-mobile.html +0 -36
- package/BookReaderDemo/demo-fullscreen.html +0 -33
- package/BookReaderDemo/demo-iiif.html +0 -34
- package/BookReaderDemo/demo-iiif.js +0 -26
- package/BookReaderDemo/demo-internetarchive.html +0 -74
- package/BookReaderDemo/demo-multiple.html +0 -43
- package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
- package/BookReaderDemo/demo-preview-pages.html +0 -1092
- package/BookReaderDemo/demo-simple.html +0 -34
- package/BookReaderDemo/demo-vendor-fullscreen.html +0 -36
- package/BookReaderDemo/immersion-1up.html +0 -64
- package/BookReaderDemo/immersion-mode.html +0 -35
- package/BookReaderDemo/toggle_controls.html +0 -53
- package/BookReaderDemo/view_mode.html +0 -39
- package/BookReaderDemo/viewmode-cycle.html +0 -41
- package/CHANGELOG.md +0 -476
- package/CONTRIBUTING.md +0 -7
- package/codecov.yml +0 -17
- package/index.html +0 -31
- package/karma.conf.js +0 -23
- package/screenshot.png +0 -0
- package/scripts/postversion.js +0 -10
- package/scripts/preversion.js +0 -14
- package/scripts/version.js +0 -26
- package/src/BookNavigator/BookModel.js +0 -14
- package/src/BookNavigator/BookNavigator.js +0 -451
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/BookNavigator/assets/icon_checkmark.js +0 -6
- package/src/BookNavigator/assets/icon_close.js +0 -3
- package/src/BookNavigator/assets/icon_sort_ascending.js +0 -5
- package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
- package/src/BookNavigator/bookmarks/bookmarks-provider.js +0 -53
- package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
- package/src/BookNavigator/downloads/downloads-provider.js +0 -66
- package/src/BookNavigator/search/a-search-result.js +0 -55
- package/src/BookNavigator/volumes/volumes-provider.js +0 -75
- package/src/BookNavigator/volumes/volumes.js +0 -161
- package/src/BookReader/DebugConsole.js +0 -54
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -372
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/assets/icons/sort-ascending.svg +0 -1
- package/src/assets/icons/sort-descending.svg +0 -1
- package/src/css/_MobileNav.scss +0 -194
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/src/plugins/plugin.mobile_nav.js +0 -287
- package/tests/BookReader/BookModel.test.js +0 -312
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/DebugConsole.test.js +0 -25
- package/tests/BookReader/ImageCache.test.js +0 -150
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/Mode2Up.test.js +0 -247
- package/tests/BookReader/Navbar/Navbar.test.js +0 -169
- package/tests/BookReader/PageContainer.test.js +0 -115
- package/tests/BookReader/ReduceSet.test.js +0 -38
- package/tests/BookReader/Toolbar/Toolbar.test.js +0 -26
- package/tests/BookReader/utils/classes.test.js +0 -88
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/BookReader.options.test.js +0 -39
- package/tests/BookReader.test.js +0 -301
- package/tests/e2e/README.md +0 -75
- package/tests/e2e/autoplay.test.js +0 -13
- package/tests/e2e/base.test.js +0 -35
- package/tests/e2e/helpers/base.js +0 -258
- package/tests/e2e/helpers/debug.js +0 -13
- package/tests/e2e/helpers/desktopSearch.js +0 -72
- package/tests/e2e/helpers/mobileSearch.js +0 -85
- package/tests/e2e/helpers/mockSearch.js +0 -93
- package/tests/e2e/helpers/rightToLeft.js +0 -29
- package/tests/e2e/ia-production/ia-prod-base.js +0 -17
- package/tests/e2e/models/BookReader.js +0 -11
- package/tests/e2e/models/Navigation.js +0 -56
- package/tests/e2e/rightToLeft.test.js +0 -20
- package/tests/e2e/viewmode.test.js +0 -37
- package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
- package/tests/karma/BookNavigator/bookmarks/bookmark-edit.test.js +0 -133
- package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +0 -222
- package/tests/karma/BookNavigator/search-results.test.js +0 -240
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- package/tests/karma/BookNavigator/volumes.test.js +0 -133
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
- package/tests/plugins/plugin.archive_analytics.test.js +0 -23
- package/tests/plugins/plugin.autoplay.test.js +0 -52
- package/tests/plugins/plugin.chapters.test.js +0 -130
- package/tests/plugins/plugin.iframe.test.js +0 -42
- package/tests/plugins/plugin.mobile_nav.test.js +0 -66
- package/tests/plugins/plugin.resume.test.js +0 -98
- package/tests/plugins/plugin.text_selection.test.js +0 -203
- package/tests/plugins/plugin.url.test.js +0 -129
- package/tests/plugins/plugin.vendor-fullscreen.test.js +0 -65
- package/tests/plugins/search/plugin.search.test.js +0 -166
- package/tests/plugins/search/plugin.search.view.test.js +0 -106
- package/tests/plugins/tts/AbstractTTSEngine.test.js +0 -153
- package/tests/plugins/tts/FestivalTTSEngine.test.js +0 -59
- package/tests/plugins/tts/PageChunk.test.js +0 -57
- package/tests/plugins/tts/PageChunkIterator.test.js +0 -179
- package/tests/plugins/tts/WebTTSEngine.test.js +0 -126
- package/tests/plugins/tts/utils.test.js +0 -133
- package/tests/util/browserSniffing.test.js +0 -56
- package/tests/util/docCookies.test.js +0 -15
- package/tests/util/strings.test.js +0 -63
- package/tests/utils.js +0 -42
- package/webpack.config.js +0 -86
package/src/BookReader.js
CHANGED
|
@@ -19,54 +19,77 @@ This file is part of BookReader.
|
|
|
19
19
|
The BookReader source is hosted at http://github.com/internetarchive/bookreader/
|
|
20
20
|
|
|
21
21
|
*/
|
|
22
|
-
// effect.js gives acces to extra easing function (e.g. easeInOutExpo)
|
|
23
|
-
import 'jquery-ui/ui/effect.js';
|
|
24
|
-
|
|
25
22
|
// Needed by touch-punch
|
|
26
23
|
import 'jquery-ui/ui/widget.js';
|
|
27
24
|
import 'jquery-ui/ui/widgets/mouse.js';
|
|
28
25
|
import 'jquery-ui-touch-punch';
|
|
29
26
|
|
|
30
|
-
import './dragscrollable-br.js';
|
|
31
27
|
import PACKAGE_JSON from '../package.json';
|
|
32
28
|
import * as utils from './BookReader/utils.js';
|
|
33
29
|
import { exposeOverrideable } from './BookReader/utils/classes.js';
|
|
34
|
-
import { Navbar
|
|
35
|
-
import { DEFAULT_OPTIONS } from './BookReader/options.js';
|
|
30
|
+
import { Navbar } from './BookReader/Navbar/Navbar.js';
|
|
31
|
+
import { DEFAULT_OPTIONS, OptionsParseError } from './BookReader/options.js';
|
|
36
32
|
/** @typedef {import('./BookReader/options.js').BookReaderOptions} BookReaderOptions */
|
|
37
33
|
/** @typedef {import('./BookReader/options.js').ReductionFactor} ReductionFactor */
|
|
38
34
|
/** @typedef {import('./BookReader/BookModel.js').PageIndex} PageIndex */
|
|
39
35
|
import { EVENTS } from './BookReader/events.js';
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
Toolbar,
|
|
43
|
-
blankInfoDiv,
|
|
44
|
-
blankShareDiv,
|
|
45
|
-
createPopup,
|
|
46
|
-
} from './BookReader/Toolbar/Toolbar.js';
|
|
36
|
+
import { Toolbar } from './BookReader/Toolbar/Toolbar.js';
|
|
47
37
|
import { BookModel } from './BookReader/BookModel.js';
|
|
48
38
|
import { Mode1Up } from './BookReader/Mode1Up.js';
|
|
49
39
|
import { Mode2Up } from './BookReader/Mode2Up.js';
|
|
50
|
-
import { ModeThumb } from './BookReader/ModeThumb';
|
|
40
|
+
import { ModeThumb } from './BookReader/ModeThumb.js';
|
|
51
41
|
import { ImageCache } from './BookReader/ImageCache.js';
|
|
52
42
|
import { PageContainer } from './BookReader/PageContainer.js';
|
|
53
|
-
import { NAMED_REDUCE_SETS } from './BookReader/ReduceSet';
|
|
54
|
-
|
|
55
|
-
if (location.toString().indexOf('_debugShowConsole=true') != -1) {
|
|
56
|
-
$(() => new DebugConsole().init());
|
|
57
|
-
}
|
|
43
|
+
import { NAMED_REDUCE_SETS } from './BookReader/ReduceSet.js';
|
|
58
44
|
|
|
59
45
|
/**
|
|
60
46
|
* BookReader
|
|
61
|
-
* @param {BookReaderOptions}
|
|
47
|
+
* @param {Partial<BookReaderOptions>} overrides
|
|
62
48
|
* TODO document all options properties
|
|
63
49
|
* @constructor
|
|
64
50
|
*/
|
|
65
51
|
export default function BookReader(overrides = {}) {
|
|
66
|
-
const options =
|
|
52
|
+
const options = BookReader.extendOptions({}, BookReader.defaultOptions, overrides, BookReader.optionOverrides);
|
|
67
53
|
this.setup(options);
|
|
68
54
|
}
|
|
69
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Extend the default options for BookReader
|
|
58
|
+
* Accepts any number of option objects and merges them in order.
|
|
59
|
+
*
|
|
60
|
+
* Does a shallow merge of everything except plugin options. These are individually merged.
|
|
61
|
+
* @param {...Partial<BookReaderOptions>} newOptions
|
|
62
|
+
*/
|
|
63
|
+
BookReader.extendOptions = function(...newOptions) {
|
|
64
|
+
if (newOptions.length <= 1) {
|
|
65
|
+
return newOptions[0];
|
|
66
|
+
}
|
|
67
|
+
/** @type {Array<keyof BookReaderOptions>} */
|
|
68
|
+
const shallowOverrides = ['onePage', 'twoPage', 'vars'];
|
|
69
|
+
/** @type {Array<keyof BookReaderOptions>} */
|
|
70
|
+
const mapOverrides = ['plugins', 'controls'];
|
|
71
|
+
|
|
72
|
+
const result = newOptions.shift();
|
|
73
|
+
for (const opts of newOptions) {
|
|
74
|
+
for (const [key, value] of Object.entries(opts)) {
|
|
75
|
+
if (shallowOverrides.includes(key)) {
|
|
76
|
+
result[key] ||= {};
|
|
77
|
+
result[key] = Object.assign(result[key], value);
|
|
78
|
+
} else if (mapOverrides.includes(key)) {
|
|
79
|
+
result[key] ||= {};
|
|
80
|
+
for (const [name, mapValue] of Object.entries(value)) {
|
|
81
|
+
result[key][name] ||= {};
|
|
82
|
+
Object.assign(result[key][name], mapValue);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
result[key] = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return result;
|
|
91
|
+
};
|
|
92
|
+
|
|
70
93
|
BookReader.version = PACKAGE_JSON.version;
|
|
71
94
|
|
|
72
95
|
// Mode constants
|
|
@@ -76,6 +99,41 @@ BookReader.constMode1up = 1;
|
|
|
76
99
|
BookReader.constMode2up = 2;
|
|
77
100
|
/** thumbnails view */
|
|
78
101
|
BookReader.constModeThumb = 3;
|
|
102
|
+
|
|
103
|
+
// Although this can actualy have any BookReaderPlugin subclass as value, we
|
|
104
|
+
// hardcode the known plugins here for type checking
|
|
105
|
+
BookReader.PLUGINS = {
|
|
106
|
+
/** @type {typeof import('./plugins/plugin.archive_analytics.js').ArchiveAnalyticsPlugin | null}*/
|
|
107
|
+
archiveAnalytics: null,
|
|
108
|
+
/** @type {typeof import('./plugins/plugin.autoplay.js').AutoplayPlugin | null}*/
|
|
109
|
+
autoplay: null,
|
|
110
|
+
/** @type {typeof import('./plugins/plugin.chapters.js').ChaptersPlugin | null}*/
|
|
111
|
+
chapters: null,
|
|
112
|
+
/** @type {typeof import('./plugins/plugin.experiments.js').ExperimentsPlugin | null}*/
|
|
113
|
+
experiments: null,
|
|
114
|
+
/** @type {typeof import('./plugins/plugin.resume.js').ResumePlugin | null}*/
|
|
115
|
+
resume: null,
|
|
116
|
+
/** @type {typeof import('./plugins/search/plugin.search.js').SearchPlugin | null}*/
|
|
117
|
+
search: null,
|
|
118
|
+
/** @type {typeof import('./plugins/plugin.text_selection.js').TextSelectionPlugin | null}*/
|
|
119
|
+
textSelection: null,
|
|
120
|
+
/** @type {typeof import('./plugins/translate/plugin.translate.js').TranslatePlugin | null}*/
|
|
121
|
+
translate: null,
|
|
122
|
+
/** @type {typeof import('./plugins/tts/plugin.tts.js').TtsPlugin | null}*/
|
|
123
|
+
tts: null,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @param {string} pluginName
|
|
128
|
+
* @param {new (...args: any[]) => import('./BookReaderPlugin.js').BookReaderPlugin} plugin
|
|
129
|
+
*/
|
|
130
|
+
BookReader.registerPlugin = function(pluginName, plugin) {
|
|
131
|
+
if (BookReader.PLUGINS[pluginName]) {
|
|
132
|
+
console.warn(`Plugin ${pluginName} already registered. Overwriting.`);
|
|
133
|
+
}
|
|
134
|
+
BookReader.PLUGINS[pluginName] = plugin;
|
|
135
|
+
};
|
|
136
|
+
|
|
79
137
|
/** image cache */
|
|
80
138
|
BookReader.imageCache = null;
|
|
81
139
|
|
|
@@ -103,12 +161,63 @@ BookReader.prototype.setup = function(options) {
|
|
|
103
161
|
// Store the options used to setup bookreader
|
|
104
162
|
this.options = options;
|
|
105
163
|
|
|
164
|
+
/** @type {import('@/src/ia-bookreader/ia-bookreader.js').IaBookReader} */
|
|
165
|
+
this.shell;
|
|
166
|
+
|
|
167
|
+
// Base server used by some api calls
|
|
168
|
+
/** @deprecated */
|
|
169
|
+
this.bookId = options.bookId;
|
|
170
|
+
/** @deprecated */
|
|
171
|
+
this.server = options.server;
|
|
172
|
+
/** @deprecated */
|
|
173
|
+
this.subPrefix = options.subPrefix;
|
|
174
|
+
/** @deprecated */
|
|
175
|
+
this.bookPath = options.bookPath;
|
|
176
|
+
|
|
177
|
+
// Construct the usual plugins first to get type hints
|
|
178
|
+
this.plugins = {
|
|
179
|
+
archiveAnalytics: BookReader.PLUGINS.archiveAnalytics ? new BookReader.PLUGINS.archiveAnalytics(this) : null,
|
|
180
|
+
autoplay: BookReader.PLUGINS.autoplay ? new BookReader.PLUGINS.autoplay(this) : null,
|
|
181
|
+
chapters: BookReader.PLUGINS.chapters ? new BookReader.PLUGINS.chapters(this) : null,
|
|
182
|
+
experiments: BookReader.PLUGINS.experiments ? new BookReader.PLUGINS.experiments(this) : null,
|
|
183
|
+
search: BookReader.PLUGINS.search ? new BookReader.PLUGINS.search(this) : null,
|
|
184
|
+
resume: BookReader.PLUGINS.resume ? new BookReader.PLUGINS.resume(this) : null,
|
|
185
|
+
textSelection: BookReader.PLUGINS.textSelection ? new BookReader.PLUGINS.textSelection(this) : null,
|
|
186
|
+
translate: BookReader.PLUGINS.translate ? new BookReader.PLUGINS.translate(this) : null,
|
|
187
|
+
tts: BookReader.PLUGINS.tts ? new BookReader.PLUGINS.tts(this) : null,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Delete anything that's null
|
|
191
|
+
for (const [pluginName, plugin] of Object.entries(this.plugins)) {
|
|
192
|
+
if (!plugin) delete this.plugins[pluginName];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Now construct the rest of the plugins
|
|
196
|
+
for (const [pluginName, PluginClass] of Object.entries(BookReader.PLUGINS)) {
|
|
197
|
+
if (this.plugins[pluginName] || !PluginClass) continue;
|
|
198
|
+
this.plugins[pluginName] = new PluginClass(this);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// And call setup on them
|
|
202
|
+
for (const [pluginName, plugin] of Object.entries(this.plugins)) {
|
|
203
|
+
try {
|
|
204
|
+
plugin.setup(this.options.plugins?.[pluginName] ?? {});
|
|
205
|
+
// Write the options back; this way the plugin is the source of truth,
|
|
206
|
+
// and BR just contains a reference to it.
|
|
207
|
+
this.options.plugins[pluginName] = plugin.options;
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.error(`Error setting up plugin ${pluginName}`, e);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (this.plugins.search?.options.enabled) {
|
|
214
|
+
// Expose the search method for convenience / backward compat
|
|
215
|
+
this.search = this.plugins.search.search.bind(this.plugins.search);
|
|
216
|
+
}
|
|
217
|
+
|
|
106
218
|
/** @type {number} @deprecated some past iterations set this */
|
|
107
219
|
this.numLeafs = undefined;
|
|
108
220
|
|
|
109
|
-
/** Overridden by plugin.search.js */
|
|
110
|
-
this.enableSearch = false;
|
|
111
|
-
|
|
112
221
|
/**
|
|
113
222
|
* Store viewModeOrder states
|
|
114
223
|
* @var {boolean}
|
|
@@ -152,24 +261,16 @@ BookReader.prototype.setup = function(options) {
|
|
|
152
261
|
this.ui = options.ui;
|
|
153
262
|
this.uiAutoHide = options.uiAutoHide;
|
|
154
263
|
|
|
155
|
-
this.thumbWidth = 100; // will be overridden during
|
|
264
|
+
this.thumbWidth = 100; // will be overridden during this._modes.modeThumb.prepare();
|
|
156
265
|
this.thumbRowBuffer = options.thumbRowBuffer;
|
|
157
266
|
this.thumbColumns = options.thumbColumns;
|
|
158
267
|
this.thumbMaxLoading = options.thumbMaxLoading;
|
|
159
268
|
this.thumbPadding = options.thumbPadding;
|
|
160
269
|
this.displayedRows = [];
|
|
161
|
-
|
|
162
270
|
this.displayedIndices = [];
|
|
163
|
-
/** @deprecated Unused; will be remove in v5 */
|
|
164
|
-
this.imgs = {};
|
|
165
|
-
/** @deprecated No longer used; will be remove in v5 */
|
|
166
|
-
this.prefetchedImgs = {}; //an object with numeric keys corresponding to page index, reduce
|
|
167
271
|
|
|
168
272
|
this.animating = false;
|
|
169
|
-
this.flipSpeed = options.flipSpeed;
|
|
170
|
-
this.flipDelay = options.flipDelay;
|
|
171
|
-
this.twoPagePopUp = null;
|
|
172
|
-
this.leafEdgeTmp = null;
|
|
273
|
+
this.flipSpeed = utils.parseAnimationSpeed(options.flipSpeed) || 400;
|
|
173
274
|
|
|
174
275
|
/**
|
|
175
276
|
* Represents the first displayed index
|
|
@@ -178,8 +279,7 @@ BookReader.prototype.setup = function(options) {
|
|
|
178
279
|
* @property {number|null} firstIndex
|
|
179
280
|
*/
|
|
180
281
|
this.firstIndex = null;
|
|
181
|
-
this.
|
|
182
|
-
this.isFullscreenActive = false;
|
|
282
|
+
this.isFullscreenActive = options.startFullscreen || false;
|
|
183
283
|
this.lastScroll = null;
|
|
184
284
|
|
|
185
285
|
this.showLogo = options.showLogo;
|
|
@@ -212,26 +312,22 @@ BookReader.prototype.setup = function(options) {
|
|
|
212
312
|
|
|
213
313
|
// Assign the data methods
|
|
214
314
|
this.data = options.data;
|
|
215
|
-
if (options.getNumLeafs) BookReader.prototype.getNumLeafs = options.getNumLeafs;
|
|
216
|
-
if (options.getPageWidth) BookReader.prototype.getPageWidth = options.getPageWidth;
|
|
217
|
-
if (options.getPageHeight) BookReader.prototype.getPageHeight = options.getPageHeight;
|
|
218
|
-
if (options.getPageURI) BookReader.prototype.getPageURI = options.getPageURI;
|
|
219
|
-
if (options.getPageSide) BookReader.prototype.getPageSide = options.getPageSide;
|
|
220
|
-
if (options.getPageNum) BookReader.prototype.getPageNum = options.getPageNum;
|
|
221
|
-
if (options.getPageProp) BookReader.prototype.getPageProp = options.getPageProp;
|
|
222
|
-
if (options.getSpreadIndices) BookReader.prototype.getSpreadIndices = options.getSpreadIndices;
|
|
223
|
-
if (options.leafNumToIndex) BookReader.prototype.leafNumToIndex = options.leafNumToIndex;
|
|
224
315
|
|
|
225
316
|
/** @type {{[name: string]: JQuery}} */
|
|
226
317
|
this.refs = {};
|
|
227
318
|
|
|
228
|
-
/**
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.
|
|
233
|
-
|
|
234
|
-
|
|
319
|
+
/** The book being displayed in BookReader*/
|
|
320
|
+
this.book = new BookModel(this);
|
|
321
|
+
|
|
322
|
+
if (options.getNumLeafs) this.book.getNumLeafs = options.getNumLeafs.bind(this);
|
|
323
|
+
if (options.getPageWidth) this.book.getPageWidth = options.getPageWidth.bind(this);
|
|
324
|
+
if (options.getPageHeight) this.book.getPageHeight = options.getPageHeight.bind(this);
|
|
325
|
+
if (options.getPageURI) this.book.getPageURI = options.getPageURI.bind(this);
|
|
326
|
+
if (options.getPageSide) this.book.getPageSide = options.getPageSide.bind(this);
|
|
327
|
+
if (options.getPageNum) this.book.getPageNum = options.getPageNum.bind(this);
|
|
328
|
+
if (options.getPageProp) this.book.getPageProp = options.getPageProp.bind(this);
|
|
329
|
+
if (options.getSpreadIndices) this.book.getSpreadIndices = options.getSpreadIndices.bind(this);
|
|
330
|
+
if (options.leafNumToIndex) this.book.leafNumToIndex = options.leafNumToIndex.bind(this);
|
|
235
331
|
|
|
236
332
|
/**
|
|
237
333
|
* @private Components are 'subchunks' of bookreader functionality, usually UI related
|
|
@@ -245,14 +341,14 @@ BookReader.prototype.setup = function(options) {
|
|
|
245
341
|
};
|
|
246
342
|
|
|
247
343
|
this._modes = {
|
|
248
|
-
mode1Up: new Mode1Up(this, this.
|
|
249
|
-
mode2Up: new Mode2Up(this, this.
|
|
250
|
-
modeThumb: new ModeThumb(this, this.
|
|
344
|
+
mode1Up: new Mode1Up(this, this.book),
|
|
345
|
+
mode2Up: new Mode2Up(this, this.book),
|
|
346
|
+
modeThumb: new ModeThumb(this, this.book),
|
|
251
347
|
};
|
|
252
348
|
|
|
253
349
|
/** Stores classes which we want to expose (selectively) some methods as overridable */
|
|
254
350
|
this._overrideable = {
|
|
255
|
-
'
|
|
351
|
+
'book': this.book,
|
|
256
352
|
'_components.navbar': this._components.navbar,
|
|
257
353
|
'_components.toolbar': this._components.toolbar,
|
|
258
354
|
'_modes.mode1Up': this._modes.mode1Up,
|
|
@@ -261,21 +357,74 @@ BookReader.prototype.setup = function(options) {
|
|
|
261
357
|
};
|
|
262
358
|
|
|
263
359
|
/** Image cache for general image fetching */
|
|
264
|
-
this.imageCache = new ImageCache(this.
|
|
360
|
+
this.imageCache = new ImageCache(this.book, {
|
|
265
361
|
useSrcSet: this.options.useSrcSet,
|
|
266
362
|
reduceSet: this.reduceSet,
|
|
363
|
+
renderPageURI: options.renderPageURI.bind(this),
|
|
267
364
|
});
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Flag if BookReader has "focus" for keyboard shortcuts
|
|
368
|
+
* Initially true, set to false when:
|
|
369
|
+
* - BookReader scrolled out of view
|
|
370
|
+
* Set to true when:
|
|
371
|
+
* - BookReader scrolled into view
|
|
372
|
+
*/
|
|
373
|
+
this.hasKeyFocus = true;
|
|
268
374
|
};
|
|
269
375
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
376
|
+
BookReader.prototype.initializePlugin = function(pluginName) {
|
|
377
|
+
const plugin = new BookReader.PLUGINS[pluginName](this);
|
|
378
|
+
this.plugins[pluginName] = plugin;
|
|
379
|
+
try {
|
|
380
|
+
plugin.setup(this.options.plugins?.[pluginName] ?? {});
|
|
381
|
+
this.options.plugins[pluginName] = plugin.options;
|
|
382
|
+
} catch (e) {
|
|
383
|
+
console.error(`Error setting up plugin ${pluginName} outside of regular cycle`, e);
|
|
384
|
+
throw e;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
plugin.init();
|
|
389
|
+
} catch (e) {
|
|
390
|
+
console.error(`Error initializing plugin ${pluginName} outside of regular cycle`, e);
|
|
391
|
+
throw e;
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Get all the HTML Elements that are being/can be rendered.
|
|
396
|
+
* Includes cached elements which might be rendered again.
|
|
397
|
+
*/
|
|
398
|
+
BookReader.prototype.getActivePageContainerElements = function() {
|
|
399
|
+
let containerEls = Object.values(this._modes.mode2Up.mode2UpLit.pageContainerCache).map(pc => pc.$container[0])
|
|
400
|
+
.concat(Object.values(this._modes.mode1Up.mode1UpLit.pageContainerCache).map(pc => pc.$container[0]));
|
|
401
|
+
if (this.mode == this.constModeThumb) {
|
|
402
|
+
containerEls = containerEls.concat(this.$('.BRpagecontainer').toArray());
|
|
403
|
+
}
|
|
404
|
+
return containerEls;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Get the HTML Elements for the rendered page. Note there can be more than one, since
|
|
409
|
+
* (at least as of writing) different modes can maintain different caches.
|
|
410
|
+
* @param {PageIndex} pageIndex
|
|
411
|
+
* @returns {HTMLElement[]}
|
|
412
|
+
*/
|
|
413
|
+
BookReader.prototype.getActivePageContainerElementsForIndex = function(pageIndex) {
|
|
414
|
+
return [
|
|
415
|
+
this._modes.mode2Up.mode2UpLit.pageContainerCache[pageIndex]?.$container?.[0],
|
|
416
|
+
this._modes.mode1Up.mode1UpLit.pageContainerCache[pageIndex]?.$container?.[0],
|
|
417
|
+
...(this.mode == this.constModeThumb ? this.$(`.pagediv${pageIndex}`).toArray() : []),
|
|
418
|
+
].filter(x => x);
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
Object.defineProperty(BookReader.prototype, 'activeMode', {
|
|
422
|
+
/** @return {Mode1Up | Mode2Up | ModeThumb} */
|
|
423
|
+
get() { return {
|
|
424
|
+
1: this._modes.mode1Up,
|
|
425
|
+
2: this._modes.mode2Up,
|
|
426
|
+
3: this._modes.modeThumb,
|
|
427
|
+
}[this.mode]; },
|
|
279
428
|
});
|
|
280
429
|
|
|
281
430
|
/**
|
|
@@ -290,15 +439,15 @@ BookReader.util = utils;
|
|
|
290
439
|
* @private
|
|
291
440
|
*/
|
|
292
441
|
BookReader.prototype.extendParams = function(params, newParams) {
|
|
293
|
-
|
|
442
|
+
const modifiedNewParams = $.extend({}, newParams);
|
|
294
443
|
if ('undefined' != typeof(modifiedNewParams.page)) {
|
|
295
|
-
|
|
444
|
+
const pageIndex = this.book.parsePageString(modifiedNewParams.page);
|
|
296
445
|
if (!isNaN(pageIndex))
|
|
297
446
|
modifiedNewParams.index = pageIndex;
|
|
298
447
|
delete modifiedNewParams.page;
|
|
299
448
|
}
|
|
300
449
|
$.extend(params, modifiedNewParams);
|
|
301
|
-
}
|
|
450
|
+
};
|
|
302
451
|
|
|
303
452
|
/**
|
|
304
453
|
* Parses params from from various initialization contexts (url, cookie, options)
|
|
@@ -306,7 +455,7 @@ BookReader.prototype.extendParams = function(params, newParams) {
|
|
|
306
455
|
* @return {object} the parsed params
|
|
307
456
|
*/
|
|
308
457
|
BookReader.prototype.initParams = function() {
|
|
309
|
-
|
|
458
|
+
const params = {};
|
|
310
459
|
// Flag initializing for updateFromParams()
|
|
311
460
|
params.init = true;
|
|
312
461
|
|
|
@@ -323,8 +472,8 @@ BookReader.prototype.initParams = function() {
|
|
|
323
472
|
|
|
324
473
|
// If we have a title leaf, use that as the default instead of index 0,
|
|
325
474
|
// but only use as default if book has a few pages
|
|
326
|
-
if ('undefined' != typeof(this.titleLeaf) && this.
|
|
327
|
-
params.index = this.
|
|
475
|
+
if ('undefined' != typeof(this.titleLeaf) && this.book.getNumLeafs() > 2) {
|
|
476
|
+
params.index = this.book.leafNumToIndex(this.titleLeaf);
|
|
328
477
|
} else {
|
|
329
478
|
params.index = 0;
|
|
330
479
|
}
|
|
@@ -339,9 +488,9 @@ BookReader.prototype.initParams = function() {
|
|
|
339
488
|
}
|
|
340
489
|
|
|
341
490
|
// Check for Resume plugin
|
|
342
|
-
if (this.options.
|
|
491
|
+
if (this.plugins.resume?.options.enabled) {
|
|
343
492
|
// Check cookies
|
|
344
|
-
const val = this.getResumeValue();
|
|
493
|
+
const val = this.plugins.resume.getResumeValue();
|
|
345
494
|
if (val !== null) {
|
|
346
495
|
// If page index different from default
|
|
347
496
|
if (params.index !== val) {
|
|
@@ -355,7 +504,7 @@ BookReader.prototype.initParams = function() {
|
|
|
355
504
|
// Check for URL plugin
|
|
356
505
|
if (this.options.enableUrlPlugin) {
|
|
357
506
|
// Params explicitly set in URL take precedence over all other methods
|
|
358
|
-
|
|
507
|
+
let urlParams = this.paramsFromFragment(this.urlReadFragment());
|
|
359
508
|
|
|
360
509
|
// Get params if hash fragment available with 'history' urlMode
|
|
361
510
|
const hasHashURL = !Object.keys(urlParams).length && this.urlReadHashFragment();
|
|
@@ -375,23 +524,24 @@ BookReader.prototype.initParams = function() {
|
|
|
375
524
|
}
|
|
376
525
|
|
|
377
526
|
// Check for Search plugin
|
|
378
|
-
if (this.options.
|
|
527
|
+
if (this.plugins.search?.options.enabled) {
|
|
528
|
+
const sp = this.plugins.search;
|
|
379
529
|
// Go to first result only if no default or URL page
|
|
380
|
-
|
|
530
|
+
sp.options.goToFirstResult = !params.pageFound;
|
|
381
531
|
|
|
382
532
|
// If initialSearchTerm not set
|
|
383
|
-
if (!
|
|
533
|
+
if (!sp.initialSearchTerm) {
|
|
384
534
|
// Look for any term in URL
|
|
385
535
|
if (params.search) {
|
|
386
536
|
// Old style: /search/[term]
|
|
387
|
-
|
|
388
|
-
|
|
537
|
+
sp.options.initialSearchTerm = params.search;
|
|
538
|
+
sp.searchTerm = params.search;
|
|
389
539
|
} else {
|
|
390
540
|
// If we have a query string: q=[term]
|
|
391
541
|
const searchParams = new URLSearchParams(this.readQueryString());
|
|
392
|
-
const searchTerm = searchParams.get('q')
|
|
542
|
+
const searchTerm = searchParams.get('q');
|
|
393
543
|
if (searchTerm) {
|
|
394
|
-
|
|
544
|
+
sp.options.initialSearchTerm = utils.decodeURIComponentPlus(searchTerm);
|
|
395
545
|
}
|
|
396
546
|
}
|
|
397
547
|
}
|
|
@@ -401,21 +551,21 @@ BookReader.prototype.initParams = function() {
|
|
|
401
551
|
this.suppressFragmentChange = !params.fragmentChange;
|
|
402
552
|
|
|
403
553
|
return params;
|
|
404
|
-
}
|
|
554
|
+
};
|
|
405
555
|
|
|
406
556
|
/**
|
|
407
557
|
* Allow mocking of window.location.search
|
|
408
558
|
*/
|
|
409
559
|
BookReader.prototype.getLocationSearch = function () {
|
|
410
560
|
return window.location.search;
|
|
411
|
-
}
|
|
561
|
+
};
|
|
412
562
|
|
|
413
563
|
/**
|
|
414
564
|
* Allow mocking of window.location.hash
|
|
415
565
|
*/
|
|
416
566
|
BookReader.prototype.getLocationHash = function () {
|
|
417
567
|
return window.location.hash;
|
|
418
|
-
}
|
|
568
|
+
};
|
|
419
569
|
|
|
420
570
|
/**
|
|
421
571
|
* Return URL or fragment querystring
|
|
@@ -428,37 +578,63 @@ BookReader.prototype.readQueryString = function() {
|
|
|
428
578
|
const hash = this.getLocationHash();
|
|
429
579
|
const found = hash.search(/\?\w+=/);
|
|
430
580
|
return found > -1 ? hash.slice(found) : '';
|
|
431
|
-
}
|
|
581
|
+
};
|
|
432
582
|
|
|
433
583
|
/**
|
|
434
584
|
* Determines the initial mode for starting if a mode is not already
|
|
435
585
|
* present in the params argument
|
|
436
586
|
* @param {object} params
|
|
437
|
-
* @return {
|
|
587
|
+
* @return {1 | 2 | 3} the initial mode
|
|
438
588
|
*/
|
|
439
589
|
BookReader.prototype.getInitialMode = function(params) {
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
) {
|
|
450
|
-
// In full mode, we set the default based on width
|
|
451
|
-
nextMode = this.constMode1up;
|
|
590
|
+
// if mobile breakpoint, we always show this.constMode1up mode
|
|
591
|
+
const windowWidth = $(window).width();
|
|
592
|
+
const isMobile = windowWidth && windowWidth <= this.onePageMinBreakpoint;
|
|
593
|
+
|
|
594
|
+
let initialMode;
|
|
595
|
+
if (params.mode) {
|
|
596
|
+
initialMode = params.mode;
|
|
597
|
+
} else if (isMobile) {
|
|
598
|
+
initialMode = this.constMode1up;
|
|
452
599
|
} else {
|
|
453
|
-
|
|
600
|
+
initialMode = this.constMode2up;
|
|
454
601
|
}
|
|
455
602
|
|
|
456
|
-
if (!this.canSwitchToMode(
|
|
457
|
-
|
|
603
|
+
if (!this.canSwitchToMode(initialMode)) {
|
|
604
|
+
initialMode = this.constMode1up;
|
|
458
605
|
}
|
|
459
|
-
|
|
606
|
+
|
|
607
|
+
// override defaults mode via `options.defaults` metadata
|
|
608
|
+
if (this.options.defaults) {
|
|
609
|
+
try {
|
|
610
|
+
initialMode = _modeStringToNumber(this.options.defaults);
|
|
611
|
+
} catch (e) {
|
|
612
|
+
// Can ignore this error
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return initialMode;
|
|
460
617
|
};
|
|
461
618
|
|
|
619
|
+
/**
|
|
620
|
+
* Converts a mode string to a the mode numeric constant
|
|
621
|
+
* @param {'mode/1up'|'mode/2up'|'mode/thumb'} modeString
|
|
622
|
+
* @return {1 | 2 | 3}
|
|
623
|
+
*/
|
|
624
|
+
export function _modeStringToNumber(modeString) {
|
|
625
|
+
const MAPPING = {
|
|
626
|
+
'mode/1up': 1,
|
|
627
|
+
'mode/2up': 2,
|
|
628
|
+
'mode/thumb': 3,
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
if (!(modeString in MAPPING)) {
|
|
632
|
+
throw new OptionsParseError(`Invalid mode string: ${modeString}`);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
return MAPPING[modeString];
|
|
636
|
+
}
|
|
637
|
+
|
|
462
638
|
/**
|
|
463
639
|
* This is called by the client to initialize BookReader.
|
|
464
640
|
* It renders onto the DOM. It should only be called once.
|
|
@@ -467,7 +643,7 @@ BookReader.prototype.init = function() {
|
|
|
467
643
|
this.init.initComplete = false;
|
|
468
644
|
this.pageScale = this.reduce; // preserve current reduce
|
|
469
645
|
|
|
470
|
-
|
|
646
|
+
const params = this.initParams();
|
|
471
647
|
|
|
472
648
|
this.firstIndex = params.index ? params.index : 0;
|
|
473
649
|
|
|
@@ -497,41 +673,45 @@ BookReader.prototype.init = function() {
|
|
|
497
673
|
// Explicitly ensure this.mode exists for initNavbar() below
|
|
498
674
|
this.mode = params.mode;
|
|
499
675
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
676
|
+
// Display Navigation
|
|
677
|
+
if (this.options.showToolbar) {
|
|
678
|
+
this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
|
|
679
|
+
}
|
|
680
|
+
if (this.options.showNavbar) { // default navigation
|
|
681
|
+
const $navBar = this.initNavbar();
|
|
682
|
+
|
|
683
|
+
// extend navbar with plugins
|
|
684
|
+
for (const plugin of Object.values(this.plugins)) {
|
|
685
|
+
plugin.extendNavBar($navBar);
|
|
508
686
|
}
|
|
509
687
|
}
|
|
510
688
|
|
|
511
689
|
// Switch navbar controls on mobile/desktop
|
|
512
|
-
this.switchNavbarControls();
|
|
690
|
+
this._components.navbar.switchNavbarControls();
|
|
513
691
|
|
|
514
692
|
this.resizeBRcontainer();
|
|
515
693
|
this.updateFromParams(params);
|
|
516
694
|
this.initUIStrings();
|
|
517
695
|
|
|
518
696
|
// Bind to events
|
|
519
|
-
|
|
520
|
-
this.
|
|
697
|
+
this._components.navbar.bindControlClickHandlers();
|
|
698
|
+
for (const plugin of Object.values(this.plugins)) {
|
|
699
|
+
plugin._bindNavigationHandlers();
|
|
700
|
+
}
|
|
521
701
|
this.setupKeyListeners();
|
|
522
702
|
|
|
523
703
|
this.lastScroll = (new Date().getTime());
|
|
524
|
-
this.refs.$brContainer.
|
|
704
|
+
this.refs.$brContainer.on('scroll', this, function(e) {
|
|
525
705
|
// Note, this scroll event fires for both user, and js generated calls
|
|
526
706
|
// It is functioning in some cases as the primary triggerer for rendering
|
|
527
707
|
e.data.lastScroll = (new Date().getTime());
|
|
528
|
-
if (e.data.
|
|
708
|
+
if (e.data.constModeThumb == e.data.mode) {
|
|
529
709
|
e.data.drawLeafsThrottled();
|
|
530
710
|
}
|
|
531
711
|
});
|
|
532
712
|
|
|
533
713
|
if (this.options.autoResize) {
|
|
534
|
-
$(window).
|
|
714
|
+
$(window).on('resize', this, function(e) {
|
|
535
715
|
e.data.resize();
|
|
536
716
|
});
|
|
537
717
|
$(window).on("orientationchange", this, function(e) {
|
|
@@ -544,19 +724,31 @@ BookReader.prototype.init = function() {
|
|
|
544
724
|
}
|
|
545
725
|
|
|
546
726
|
// If not searching, set to allow on-going fragment changes
|
|
547
|
-
if (!this.options.initialSearchTerm) {
|
|
727
|
+
if (!this.plugins.search?.options.initialSearchTerm) {
|
|
548
728
|
this.suppressFragmentChange = false;
|
|
549
729
|
}
|
|
550
730
|
|
|
731
|
+
if (this.options.startFullscreen) {
|
|
732
|
+
this.enterFullscreen(true);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// Init plugins
|
|
736
|
+
for (const [pluginName, plugin] of Object.entries(this.plugins)) {
|
|
737
|
+
try {
|
|
738
|
+
plugin.init();
|
|
739
|
+
}
|
|
740
|
+
catch (e) {
|
|
741
|
+
console.error(`Error initializing plugin ${pluginName}`, e);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
551
745
|
this.init.initComplete = true;
|
|
552
746
|
this.trigger(BookReader.eventNames.PostInit);
|
|
553
747
|
|
|
554
748
|
// Must be called after this.init.initComplete set to true to allow
|
|
555
749
|
// BookReader.prototype.resize to run.
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
}
|
|
750
|
+
|
|
751
|
+
};
|
|
560
752
|
|
|
561
753
|
/**
|
|
562
754
|
* @param {EVENTS} name
|
|
@@ -564,7 +756,6 @@ BookReader.prototype.init = function() {
|
|
|
564
756
|
*/
|
|
565
757
|
BookReader.prototype.trigger = function(name, props = this) {
|
|
566
758
|
const eventName = 'BookReader:' + name;
|
|
567
|
-
$(document).trigger(eventName, props);
|
|
568
759
|
|
|
569
760
|
utils.polyfillCustomEvent(window);
|
|
570
761
|
window.dispatchEvent(new CustomEvent(eventName, {
|
|
@@ -572,14 +763,29 @@ BookReader.prototype.trigger = function(name, props = this) {
|
|
|
572
763
|
composed: true,
|
|
573
764
|
detail: { props },
|
|
574
765
|
}));
|
|
766
|
+
$(document).trigger(eventName, props);
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
BookReader.prototype.on = function(name, callback) {
|
|
770
|
+
$(document).on('BookReader:' + name, callback);
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
BookReader.prototype.off = function(name, callback) {
|
|
774
|
+
$(document).off('BookReader:' + name, callback);
|
|
575
775
|
};
|
|
576
776
|
|
|
777
|
+
/**
|
|
778
|
+
* @deprecated Use .on and .off instead
|
|
779
|
+
*/
|
|
577
780
|
BookReader.prototype.bind = function(name, callback) {
|
|
578
|
-
|
|
781
|
+
return this.on(name, callback);
|
|
579
782
|
};
|
|
580
783
|
|
|
784
|
+
/**
|
|
785
|
+
* @deprecated Use .on and .off instead
|
|
786
|
+
*/
|
|
581
787
|
BookReader.prototype.unbind = function(name, callback) {
|
|
582
|
-
|
|
788
|
+
return this.off(name, callback);
|
|
583
789
|
};
|
|
584
790
|
|
|
585
791
|
/**
|
|
@@ -591,135 +797,143 @@ BookReader.prototype.resize = function() {
|
|
|
591
797
|
this.resizeBRcontainer();
|
|
592
798
|
|
|
593
799
|
// Switch navbar controls on mobile/desktop
|
|
594
|
-
this.switchNavbarControls();
|
|
800
|
+
this._components.navbar.switchNavbarControls();
|
|
595
801
|
|
|
596
802
|
if (this.constMode1up == this.mode) {
|
|
597
803
|
if (this.onePage.autofit != 'none') {
|
|
598
|
-
this.
|
|
804
|
+
this._modes.mode1Up.resizePageView();
|
|
599
805
|
this.centerPageView();
|
|
600
|
-
if (this.enableSearch) this.updateSearchHilites(); //deletes highlights but does not call remove()
|
|
601
806
|
} else {
|
|
602
807
|
this.centerPageView();
|
|
603
808
|
this.displayedIndices = [];
|
|
604
|
-
if (this.enableSearch) this.updateSearchHilites(); //deletes highlights but does not call remove()
|
|
605
809
|
this.drawLeafsThrottled();
|
|
606
810
|
}
|
|
607
811
|
} else if (this.constModeThumb == this.mode) {
|
|
608
|
-
this.
|
|
812
|
+
this._modes.modeThumb.prepare();
|
|
609
813
|
} else {
|
|
610
|
-
|
|
611
|
-
if (this.twoPage.autofit) {
|
|
612
|
-
// most common path, esp. for archive.org books
|
|
613
|
-
this.prepareTwoPageView();
|
|
614
|
-
} else {
|
|
615
|
-
// used when zoomed in
|
|
616
|
-
// Re-center if the scrollbars have disappeared
|
|
617
|
-
var center = this.twoPageGetViewCenter();
|
|
618
|
-
var doRecenter = false;
|
|
619
|
-
if (this.twoPage.totalWidth < this.refs.$brContainer.prop('clientWidth')) {
|
|
620
|
-
center.percentageX = 0.5;
|
|
621
|
-
doRecenter = true;
|
|
622
|
-
}
|
|
623
|
-
if (this.twoPage.totalHeight < this.refs.$brContainer.prop('clientHeight')) {
|
|
624
|
-
center.percentageY = 0.5;
|
|
625
|
-
doRecenter = true;
|
|
626
|
-
}
|
|
627
|
-
if (doRecenter) {
|
|
628
|
-
this.twoPageCenterView(center.percentageX, center.percentageY);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
814
|
+
this._modes.mode2Up.resizePageView();
|
|
631
815
|
}
|
|
632
816
|
this.trigger(BookReader.eventNames.resize);
|
|
633
817
|
};
|
|
634
818
|
|
|
635
819
|
/**
|
|
636
|
-
* Binds keyboard event listeners
|
|
820
|
+
* Binds keyboard and keyboard focus event listeners
|
|
637
821
|
*/
|
|
638
|
-
BookReader.prototype.setupKeyListeners = function() {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
var KEY_MINUS = 189; // Chrome
|
|
652
|
-
var KEY_MINUS_F = 173; // Firefox
|
|
653
|
-
var KEY_NUMPAD_SUBTRACT = 109;
|
|
654
|
-
var KEY_EQUAL = 187; // Chrome
|
|
655
|
-
var KEY_EQUAL_F = 61; // Firefox
|
|
656
|
-
var KEY_NUMPAD_ADD = 107;
|
|
657
|
-
|
|
658
|
-
// We use document here instead of window to avoid a bug in jQuery on IE7
|
|
659
|
-
$(document).keydown(function(e) {
|
|
660
|
-
|
|
661
|
-
// Keyboard navigation
|
|
662
|
-
if (!self.keyboardNavigationIsDisabled(e)) {
|
|
663
|
-
switch (e.keyCode) {
|
|
664
|
-
case KEY_PGUP:
|
|
665
|
-
case KEY_UP:
|
|
666
|
-
// In 1up mode page scrolling is handled by browser
|
|
667
|
-
if (self.constMode2up == self.mode) {
|
|
668
|
-
e.preventDefault();
|
|
669
|
-
self.prev();
|
|
670
|
-
}
|
|
671
|
-
break;
|
|
672
|
-
case KEY_DOWN:
|
|
673
|
-
case KEY_PGDOWN:
|
|
674
|
-
if (self.constMode2up == self.mode) {
|
|
675
|
-
e.preventDefault();
|
|
676
|
-
self.next();
|
|
822
|
+
BookReader.prototype.setupKeyListeners = function () {
|
|
823
|
+
|
|
824
|
+
// Keyboard focus by BookReader in viewport
|
|
825
|
+
//
|
|
826
|
+
// Intersection observer and callback sets BookReader keyboard
|
|
827
|
+
// "focus" flag off when the BookReader is not in the viewport.
|
|
828
|
+
if (window.IntersectionObserver) {
|
|
829
|
+
const observer = new IntersectionObserver((entries) => {
|
|
830
|
+
entries.forEach((entry) => {
|
|
831
|
+
if (entry.intersectionRatio === 0) {
|
|
832
|
+
this.hasKeyFocus = false;
|
|
833
|
+
} else {
|
|
834
|
+
this.hasKeyFocus = true;
|
|
677
835
|
}
|
|
678
|
-
|
|
679
|
-
|
|
836
|
+
});
|
|
837
|
+
}, {
|
|
838
|
+
root: null,
|
|
839
|
+
rootMargin: '0px',
|
|
840
|
+
threshold: [0, 0.05, 1],
|
|
841
|
+
});
|
|
842
|
+
observer.observe(this.refs.$br[0]);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Keyboard listeners
|
|
846
|
+
document.addEventListener('keydown', (e) => {
|
|
847
|
+
|
|
848
|
+
// Ignore if BookReader "focus" flag not set
|
|
849
|
+
if (!this.hasKeyFocus) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// Ignore if modifiers are active.
|
|
854
|
+
if (e.getModifierState('Control') ||
|
|
855
|
+
e.getModifierState('Alt') ||
|
|
856
|
+
e.getModifierState('Meta') ||
|
|
857
|
+
e.getModifierState('Win') /* hack for IE */) {
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// Ignore in input elements
|
|
862
|
+
if (utils.isInputActive()) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// KeyboardEvent code values:
|
|
867
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values
|
|
868
|
+
switch (e.key) {
|
|
869
|
+
|
|
870
|
+
// Page navigation
|
|
871
|
+
case "Home":
|
|
872
|
+
e.preventDefault();
|
|
873
|
+
this.first();
|
|
874
|
+
break;
|
|
875
|
+
case "End":
|
|
876
|
+
e.preventDefault();
|
|
877
|
+
this.last();
|
|
878
|
+
break;
|
|
879
|
+
case "PageDown":
|
|
880
|
+
// In 1up and thumb mode page scrolling handled by browser
|
|
881
|
+
if (this.constMode2up === this.mode) {
|
|
680
882
|
e.preventDefault();
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
883
|
+
this.next();
|
|
884
|
+
}
|
|
885
|
+
break;
|
|
886
|
+
case "PageUp":
|
|
887
|
+
// In 1up and thumb mode page scrolling handled by browser
|
|
888
|
+
if (this.constMode2up === this.mode) {
|
|
684
889
|
e.preventDefault();
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
break;
|
|
693
|
-
case KEY_RIGHT:
|
|
694
|
-
if (self.constModeThumb != self.mode) {
|
|
695
|
-
e.preventDefault();
|
|
696
|
-
self.right();
|
|
697
|
-
}
|
|
698
|
-
break;
|
|
699
|
-
case KEY_MINUS:
|
|
700
|
-
case KEY_MINUS_F:
|
|
701
|
-
case KEY_NUMPAD_SUBTRACT:
|
|
890
|
+
this.prev();
|
|
891
|
+
}
|
|
892
|
+
break;
|
|
893
|
+
case "ArrowLeft":
|
|
894
|
+
case "Left": // hack for IE and old Gecko
|
|
895
|
+
// No y-scrolling in thumb mode
|
|
896
|
+
if (this.constModeThumb != this.mode) {
|
|
702
897
|
e.preventDefault();
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
898
|
+
this.left();
|
|
899
|
+
}
|
|
900
|
+
break;
|
|
901
|
+
case "ArrowRight":
|
|
902
|
+
case "Right": // hack for IE and old Gecko
|
|
903
|
+
// No y-scrolling in thumb mode
|
|
904
|
+
if (this.constModeThumb != this.mode) {
|
|
708
905
|
e.preventDefault();
|
|
709
|
-
|
|
710
|
-
break;
|
|
906
|
+
this.right();
|
|
711
907
|
}
|
|
908
|
+
break;
|
|
909
|
+
// Zoom
|
|
910
|
+
case '-':
|
|
911
|
+
case 'Subtract':
|
|
912
|
+
e.preventDefault();
|
|
913
|
+
this.zoom(-1);
|
|
914
|
+
break;
|
|
915
|
+
case '+':
|
|
916
|
+
case '=':
|
|
917
|
+
case 'Add':
|
|
918
|
+
e.preventDefault();
|
|
919
|
+
this.zoom(1);
|
|
920
|
+
break;
|
|
921
|
+
// Fullscreen
|
|
922
|
+
case 'F':
|
|
923
|
+
case 'f':
|
|
924
|
+
e.preventDefault();
|
|
925
|
+
this.toggleFullscreen();
|
|
926
|
+
break;
|
|
712
927
|
}
|
|
713
928
|
});
|
|
714
929
|
};
|
|
715
930
|
|
|
716
931
|
BookReader.prototype.drawLeafs = function() {
|
|
717
932
|
if (this.constMode1up == this.mode) {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
this.drawLeafsThumbnail();
|
|
933
|
+
// Not needed for Mode1Up anymore
|
|
934
|
+
return;
|
|
721
935
|
} else {
|
|
722
|
-
this.
|
|
936
|
+
this.activeMode.drawLeafs();
|
|
723
937
|
}
|
|
724
938
|
};
|
|
725
939
|
|
|
@@ -728,11 +942,17 @@ BookReader.prototype.drawLeafs = function() {
|
|
|
728
942
|
* @param {PageIndex} index
|
|
729
943
|
*/
|
|
730
944
|
BookReader.prototype._createPageContainer = function(index) {
|
|
731
|
-
|
|
945
|
+
const pageContainer = new PageContainer(this.book.getPage(index, false), {
|
|
732
946
|
isProtected: this.protected,
|
|
733
947
|
imageCache: this.imageCache,
|
|
734
|
-
loadingImage: this.imagesBaseURL + 'loading.gif',
|
|
735
948
|
});
|
|
949
|
+
|
|
950
|
+
// Call plugin handlers
|
|
951
|
+
for (const plugin of Object.values(this.plugins)) {
|
|
952
|
+
plugin._configurePageContainer(pageContainer);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
return pageContainer;
|
|
736
956
|
};
|
|
737
957
|
|
|
738
958
|
BookReader.prototype.bindGestures = function(jElement) {
|
|
@@ -742,8 +962,8 @@ BookReader.prototype.bindGestures = function(jElement) {
|
|
|
742
962
|
// when you move the book with one finger and then add another
|
|
743
963
|
// finger to pinch. Gestures are aware of scroll state.
|
|
744
964
|
|
|
745
|
-
|
|
746
|
-
|
|
965
|
+
const self = this;
|
|
966
|
+
let numTouches = 1;
|
|
747
967
|
|
|
748
968
|
jElement.unbind('touchmove').bind('touchmove', function(e) {
|
|
749
969
|
if (e.originalEvent.cancelable) numTouches = e.originalEvent.touches.length;
|
|
@@ -764,60 +984,25 @@ BookReader.prototype.bindGestures = function(jElement) {
|
|
|
764
984
|
});
|
|
765
985
|
};
|
|
766
986
|
|
|
767
|
-
/** @deprecated Not used outside ModeThumb */
|
|
768
|
-
BookReader.prototype.drawLeafsThumbnail = ModeThumb.prototype.drawLeafs;
|
|
769
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'drawLeafs', 'drawLeafsThumbnail');
|
|
770
|
-
/** @deprecated Not used outside ModeThumb */
|
|
771
|
-
BookReader.prototype.lazyLoadThumbnails = ModeThumb.prototype.lazyLoadThumbnails;
|
|
772
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'lazyLoadThumbnails', 'lazyLoadThumbnails');
|
|
773
|
-
BookReader.prototype.lazyLoadImage = ModeThumb.prototype.lazyLoadImage;
|
|
774
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'lazyLoadImage', 'lazyLoadImage');
|
|
775
|
-
/** @deprecated Internal use only */
|
|
776
|
-
BookReader.prototype.zoomThumb = ModeThumb.prototype.zoom;
|
|
777
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'zoom', 'zoomThumb');
|
|
778
|
-
/** @deprecated Not used outside ModeThumb */
|
|
779
|
-
BookReader.prototype.getThumbnailWidth = ModeThumb.prototype.getThumbnailWidth;
|
|
780
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'getThumbnailWidth', 'getThumbnailWidth');
|
|
781
|
-
/** @deprecated Not used outside ModeThumb */
|
|
782
|
-
BookReader.prototype.prepareThumbnailView = ModeThumb.prototype.prepare;
|
|
783
|
-
exposeOverrideableMethod(ModeThumb, '_modes.modeThumb', 'prepare', 'prepareThumbnailView');
|
|
784
|
-
|
|
785
987
|
/**
|
|
786
988
|
* A throttled version of drawLeafs
|
|
787
989
|
*/
|
|
788
990
|
BookReader.prototype.drawLeafsThrottled = utils.throttle(
|
|
789
991
|
BookReader.prototype.drawLeafs,
|
|
790
|
-
250 // 250 ms gives quick feedback, but doesn't eat cpu
|
|
992
|
+
250, // 250 ms gives quick feedback, but doesn't eat cpu
|
|
791
993
|
);
|
|
792
994
|
|
|
793
995
|
/**
|
|
794
996
|
* @param {number} direction Pass 1 to zoom in, anything else to zoom out
|
|
795
997
|
*/
|
|
796
998
|
BookReader.prototype.zoom = function(direction) {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
this.zoom1up('in');
|
|
802
|
-
} else {
|
|
803
|
-
this.zoom1up('out');
|
|
804
|
-
}
|
|
805
|
-
break
|
|
806
|
-
case this.constMode2up:
|
|
807
|
-
if (direction == 1) {
|
|
808
|
-
// XXX other cases
|
|
809
|
-
this.zoom2up('in');
|
|
810
|
-
} else {
|
|
811
|
-
this.zoom2up('out');
|
|
812
|
-
}
|
|
813
|
-
break
|
|
814
|
-
case this.constModeThumb:
|
|
815
|
-
// XXX update zoomThumb for named directions
|
|
816
|
-
this.zoomThumb(direction);
|
|
817
|
-
break
|
|
999
|
+
if (direction == 1) {
|
|
1000
|
+
this.activeMode.zoom('in');
|
|
1001
|
+
} else {
|
|
1002
|
+
this.activeMode.zoom('out');
|
|
818
1003
|
}
|
|
819
|
-
|
|
820
|
-
this.
|
|
1004
|
+
this.plugins.textSelection?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1005
|
+
this.plugins.translate?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
821
1006
|
return;
|
|
822
1007
|
};
|
|
823
1008
|
|
|
@@ -834,19 +1019,19 @@ BookReader.prototype.resizeBRcontainer = function(animate) {
|
|
|
834
1019
|
if (animate) {
|
|
835
1020
|
this.refs.$brContainer.animate({
|
|
836
1021
|
top: this.getToolBarHeight(),
|
|
837
|
-
bottom: this.getFooterHeight()
|
|
1022
|
+
bottom: this.getFooterHeight(),
|
|
838
1023
|
}, this.constResizeAnimationDuration, 'linear');
|
|
839
1024
|
} else {
|
|
840
1025
|
this.refs.$brContainer.css({
|
|
841
1026
|
top: this.getToolBarHeight(),
|
|
842
|
-
bottom: this.getFooterHeight()
|
|
1027
|
+
bottom: this.getFooterHeight(),
|
|
843
1028
|
});
|
|
844
1029
|
}
|
|
845
|
-
}
|
|
1030
|
+
};
|
|
846
1031
|
|
|
847
1032
|
BookReader.prototype.centerPageView = function() {
|
|
848
|
-
|
|
849
|
-
|
|
1033
|
+
const scrollWidth = this.refs.$brContainer.prop('scrollWidth');
|
|
1034
|
+
const clientWidth = this.refs.$brContainer.prop('clientWidth');
|
|
850
1035
|
if (scrollWidth > clientWidth) {
|
|
851
1036
|
this.refs.$brContainer.prop('scrollLeft', (scrollWidth - clientWidth) / 2);
|
|
852
1037
|
}
|
|
@@ -930,14 +1115,16 @@ BookReader.prototype._reduceSort = (a, b) => a.reduce - b.reduce;
|
|
|
930
1115
|
|
|
931
1116
|
/**
|
|
932
1117
|
* Attempts to jump to page
|
|
933
|
-
* @param {string}
|
|
1118
|
+
* @param {string} pageNum
|
|
1119
|
+
* @param {object} options
|
|
1120
|
+
* @param {boolean} [options.ariaLive = false]
|
|
934
1121
|
* @return {boolean} Returns true if page could be found, false otherwise.
|
|
935
1122
|
*/
|
|
936
|
-
BookReader.prototype.jumpToPage = function(pageNum) {
|
|
937
|
-
|
|
1123
|
+
BookReader.prototype.jumpToPage = function(pageNum, {ariaLive = false} = {}) {
|
|
1124
|
+
const pageIndex = this.book.parsePageString(pageNum);
|
|
938
1125
|
|
|
939
1126
|
if ('undefined' != typeof(pageIndex)) {
|
|
940
|
-
this.jumpToIndex(pageIndex);
|
|
1127
|
+
this.jumpToIndex(pageIndex, { ariaLive });
|
|
941
1128
|
return true;
|
|
942
1129
|
}
|
|
943
1130
|
|
|
@@ -950,44 +1137,47 @@ BookReader.prototype.jumpToPage = function(pageNum) {
|
|
|
950
1137
|
* @param {PageIndex} index
|
|
951
1138
|
*/
|
|
952
1139
|
BookReader.prototype._isIndexDisplayed = function(index) {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
this.currentIndex() == index;
|
|
957
|
-
}
|
|
1140
|
+
return this.displayedIndices ? this.displayedIndices.includes(index) :
|
|
1141
|
+
this.currentIndex() == index;
|
|
1142
|
+
};
|
|
958
1143
|
|
|
959
1144
|
/**
|
|
960
1145
|
* Changes the current page
|
|
961
|
-
* @param {PageIndex}
|
|
962
|
-
* @param {
|
|
963
|
-
* @param {number} [
|
|
964
|
-
* @param {
|
|
965
|
-
|
|
966
|
-
|
|
1146
|
+
* @param {PageIndex | 'left' | 'right' | 'next' | 'prev'} indexOrDirection
|
|
1147
|
+
* @param {object} options
|
|
1148
|
+
* @param {number} [options.pageX] Position on page ; not implemented
|
|
1149
|
+
* @param {number} [options.pageY] Position on page ; not implemented
|
|
1150
|
+
* @param {boolean} [options.noAnimate]
|
|
1151
|
+
* @param {number | 'fast' | 'slow'} [options.flipSpeed]
|
|
1152
|
+
* @param {boolean} [options.ariaLive]
|
|
1153
|
+
* @param {boolean} [options.triggerStop] - whether to trigger the stop event; default true; maybe deprecated?
|
|
1154
|
+
*/
|
|
1155
|
+
BookReader.prototype.jumpToIndex = function(indexOrDirection, {pageX = 0, pageY = 0, noAnimate = false, flipSpeed = null, ariaLive = false, triggerStop = true} = {}) {
|
|
1156
|
+
const page = this.activeMode.parsePageSpecifier(indexOrDirection);
|
|
1157
|
+
flipSpeed = utils.parseAnimationSpeed(flipSpeed) || this.flipSpeed;
|
|
1158
|
+
if (!page || page.index == this.currentIndex()) {
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
967
1162
|
// Don't jump into specific unviewable page
|
|
968
|
-
const page = this._models.book.getPage(index);
|
|
969
1163
|
if (!page.isViewable && page.unviewablesStart != page.index) {
|
|
970
1164
|
// If already in unviewable range, jump to end of that range
|
|
971
1165
|
const alreadyInPreview = this._isIndexDisplayed(page.unviewablesStart);
|
|
972
|
-
const newIndex = alreadyInPreview ? page.findNext({ combineConsecutiveUnviewables: true })
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
this.
|
|
980
|
-
|
|
981
|
-
this._modes.modeThumb.jumpToIndex(index);
|
|
982
|
-
} else { // 1up
|
|
983
|
-
this._modes.mode1Up.jumpToIndex(index, pageX, pageY, noAnimate);
|
|
1166
|
+
const newIndex = alreadyInPreview ? page.findNext({ combineConsecutiveUnviewables: true })?.index : page.unviewablesStart;
|
|
1167
|
+
// Rare, but a book can end on an unviewable page, so this could be undefined
|
|
1168
|
+
if (typeof newIndex !== 'undefined') {
|
|
1169
|
+
this.jumpToIndex(newIndex, { pageX, pageY, noAnimate, flipSpeed, ariaLive });
|
|
1170
|
+
}
|
|
1171
|
+
} else {
|
|
1172
|
+
if (triggerStop) this.trigger(BookReader.eventNames.stop);
|
|
1173
|
+
this.trigger(BookReader.eventNames.beforePageChanged, { index: page.index, ariaLive });
|
|
1174
|
+
this.activeMode.jumpToIndex(page.index, { pageX, pageY, noAnimate, flipSpeed, ariaLive });
|
|
984
1175
|
}
|
|
985
1176
|
};
|
|
986
1177
|
|
|
987
1178
|
/**
|
|
988
1179
|
* Return mode or 1up if initial thumb
|
|
989
1180
|
* @param {number}
|
|
990
|
-
* @see BookReader.prototype.drawLeafsThumbnail
|
|
991
1181
|
*/
|
|
992
1182
|
BookReader.prototype.getPrevReadMode = function(mode) {
|
|
993
1183
|
if (mode === BookReader.constMode1up || mode === BookReader.constMode2up) {
|
|
@@ -996,11 +1186,11 @@ BookReader.prototype.getPrevReadMode = function(mode) {
|
|
|
996
1186
|
// Initial thumb, return 1up
|
|
997
1187
|
return BookReader.constMode1up;
|
|
998
1188
|
}
|
|
999
|
-
}
|
|
1189
|
+
};
|
|
1000
1190
|
|
|
1001
1191
|
/**
|
|
1002
1192
|
* Switches the mode (eg 1up 2up thumb)
|
|
1003
|
-
* @param {number}
|
|
1193
|
+
* @param {number|'1up' | '2up' | 'thumb'}
|
|
1004
1194
|
* @param {object} [options]
|
|
1005
1195
|
* @param {boolean} [options.suppressFragmentChange = false]
|
|
1006
1196
|
* @param {boolean} [options.onInit = false] - this
|
|
@@ -1010,9 +1200,21 @@ BookReader.prototype.switchMode = function(
|
|
|
1010
1200
|
{
|
|
1011
1201
|
suppressFragmentChange = false,
|
|
1012
1202
|
init = false,
|
|
1013
|
-
pageFound = false
|
|
1014
|
-
} = {}
|
|
1203
|
+
pageFound = false,
|
|
1204
|
+
} = {},
|
|
1015
1205
|
) {
|
|
1206
|
+
if (typeof mode === 'string') {
|
|
1207
|
+
mode = {
|
|
1208
|
+
'1up': this.constMode1up,
|
|
1209
|
+
'2up': this.constMode2up,
|
|
1210
|
+
'thumb': this.constModeThumb,
|
|
1211
|
+
}[mode];
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
if (!mode) {
|
|
1215
|
+
throw new Error(`Invalid mode: ${mode}`);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1016
1218
|
// Skip checks before init() complete
|
|
1017
1219
|
if (this.init.initComplete) {
|
|
1018
1220
|
if (mode === this.mode) {
|
|
@@ -1024,10 +1226,13 @@ BookReader.prototype.switchMode = function(
|
|
|
1024
1226
|
}
|
|
1025
1227
|
|
|
1026
1228
|
this.trigger(BookReader.eventNames.stop);
|
|
1027
|
-
if (this.enableSearch) this.removeSearchHilites();
|
|
1028
1229
|
|
|
1029
1230
|
this.prevReadMode = this.getPrevReadMode(this.mode);
|
|
1030
1231
|
|
|
1232
|
+
if (this.mode != mode) {
|
|
1233
|
+
this.activeMode.unprepare?.();
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1031
1236
|
this.mode = mode;
|
|
1032
1237
|
|
|
1033
1238
|
// reinstate scale if moving from thumbnail view
|
|
@@ -1040,42 +1245,32 @@ BookReader.prototype.switchMode = function(
|
|
|
1040
1245
|
|
|
1041
1246
|
// XXX maybe better to preserve zoom in each mode
|
|
1042
1247
|
if (this.constMode1up == mode) {
|
|
1043
|
-
this.
|
|
1044
|
-
this.reduce = this.quantizeReduce(this.reduce, this.onePage.reductionFactors);
|
|
1045
|
-
this.prepareOnePageView();
|
|
1248
|
+
this._modes.mode1Up.prepare();
|
|
1046
1249
|
} else if (this.constModeThumb == mode) {
|
|
1047
1250
|
this.reduce = this.quantizeReduce(this.reduce, this.reductionFactors);
|
|
1048
|
-
this.
|
|
1251
|
+
this._modes.modeThumb.prepare();
|
|
1049
1252
|
} else {
|
|
1050
|
-
|
|
1051
|
-
// this.twoPage.autofit = null; // Take zoom level from other mode
|
|
1052
|
-
// spread indices not set, so let's set them
|
|
1053
|
-
if (init || !pageFound) {
|
|
1054
|
-
this.setSpreadIndices();
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
this.twoPageCalculateReductionFactors(); // this sets this.twoPage && this.reduce
|
|
1058
|
-
this.prepareTwoPageView();
|
|
1059
|
-
this.twoPageCenterView(0.5, 0.5); // $$$ TODO preserve center
|
|
1253
|
+
this._modes.mode2Up.prepare();
|
|
1060
1254
|
}
|
|
1061
1255
|
|
|
1062
1256
|
if (!(this.suppressFragmentChange || suppressFragmentChange)) {
|
|
1063
1257
|
this.trigger(BookReader.eventNames.fragmentChange);
|
|
1064
1258
|
}
|
|
1065
|
-
|
|
1259
|
+
const eventName = mode + 'PageViewSelected';
|
|
1066
1260
|
this.trigger(BookReader.eventNames[eventName]);
|
|
1067
1261
|
|
|
1068
|
-
this.
|
|
1262
|
+
this.plugins.textSelection?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1263
|
+
this.plugins.translate?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1069
1264
|
};
|
|
1070
1265
|
|
|
1071
1266
|
BookReader.prototype.updateBrClasses = function() {
|
|
1072
|
-
|
|
1267
|
+
const modeToClass = {};
|
|
1073
1268
|
modeToClass[this.constMode1up] = 'BRmode1up';
|
|
1074
|
-
modeToClass[this.constMode2up] = '
|
|
1269
|
+
modeToClass[this.constMode2up] = 'BRmode2up';
|
|
1075
1270
|
modeToClass[this.constModeThumb] = 'BRmodeThumb';
|
|
1076
1271
|
|
|
1077
1272
|
this.refs.$br
|
|
1078
|
-
.removeClass('BRmode1up
|
|
1273
|
+
.removeClass('BRmode1up BRmode2up BRmodeThumb')
|
|
1079
1274
|
.addClass(modeToClass[this.mode]);
|
|
1080
1275
|
|
|
1081
1276
|
if (this.isFullscreen()) {
|
|
@@ -1095,31 +1290,30 @@ BookReader.prototype.isFullscreen = function() {
|
|
|
1095
1290
|
* Toggles fullscreen
|
|
1096
1291
|
* @param { boolean } bindKeyboardControls
|
|
1097
1292
|
*/
|
|
1098
|
-
BookReader.prototype.toggleFullscreen = function(bindKeyboardControls = true) {
|
|
1293
|
+
BookReader.prototype.toggleFullscreen = async function(bindKeyboardControls = true) {
|
|
1099
1294
|
if (this.isFullscreen()) {
|
|
1100
|
-
this.exitFullScreen();
|
|
1295
|
+
await this.exitFullScreen();
|
|
1101
1296
|
} else {
|
|
1102
|
-
this.enterFullscreen(bindKeyboardControls);
|
|
1297
|
+
await this.enterFullscreen(bindKeyboardControls);
|
|
1103
1298
|
}
|
|
1104
1299
|
};
|
|
1105
1300
|
|
|
1106
1301
|
/**
|
|
1107
1302
|
* Enters fullscreen
|
|
1108
1303
|
* including:
|
|
1109
|
-
* - animation
|
|
1110
1304
|
* - binds keyboard controls
|
|
1111
1305
|
* - fires custom event
|
|
1112
1306
|
* @param { boolean } bindKeyboardControls
|
|
1113
1307
|
*/
|
|
1114
|
-
BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
|
|
1308
|
+
BookReader.prototype.enterFullscreen = async function(bindKeyboardControls = true) {
|
|
1309
|
+
this.refs.$br.addClass('BRfullscreenAnimation');
|
|
1115
1310
|
const currentIndex = this.currentIndex();
|
|
1116
|
-
this.refs.$brContainer.css('opacity', 0);
|
|
1117
1311
|
|
|
1118
1312
|
if (bindKeyboardControls) {
|
|
1119
1313
|
this._fullscreenCloseHandler = (e) => {
|
|
1120
1314
|
if (e.keyCode === 27) this.toggleFullscreen();
|
|
1121
1315
|
};
|
|
1122
|
-
$(document).keyup
|
|
1316
|
+
$(document).on("keyup", this._fullscreenCloseHandler);
|
|
1123
1317
|
}
|
|
1124
1318
|
|
|
1125
1319
|
const windowWidth = $(window).width();
|
|
@@ -1129,13 +1323,33 @@ BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
|
|
|
1129
1323
|
|
|
1130
1324
|
this.isFullscreenActive = true;
|
|
1131
1325
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
});
|
|
1326
|
+
// Change tooltip of fullscreen button
|
|
1327
|
+
this.$('.BRnav .BRicon.full').attr('title', 'Exit fullscreen');
|
|
1328
|
+
this.$('.BRnav .BRicon.full .BRtooltip').text('Exit fullscreen');
|
|
1136
1329
|
|
|
1137
|
-
|
|
1330
|
+
// prioritize class updates so CSS can propagate
|
|
1331
|
+
this.updateBrClasses();
|
|
1332
|
+
if (this.activeMode instanceof Mode1Up) {
|
|
1333
|
+
this.activeMode.mode1UpLit.scale = this.activeMode.mode1UpLit.computeDefaultScale(this.book.getPage(currentIndex));
|
|
1334
|
+
// Need the new scale to be applied before calling jumpToIndex
|
|
1335
|
+
this.activeMode.mode1UpLit.requestUpdate();
|
|
1336
|
+
await this.activeMode.mode1UpLit.updateComplete;
|
|
1337
|
+
}
|
|
1338
|
+
this.jumpToIndex(currentIndex);
|
|
1339
|
+
|
|
1340
|
+
this.plugins.textSelection?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1341
|
+
this.plugins.translate?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1342
|
+
// Add "?view=theater"
|
|
1343
|
+
this.trigger(BookReader.eventNames.fragmentChange);
|
|
1344
|
+
// trigger event here, so that animations,
|
|
1345
|
+
// class updates happen before book-nav relays to web components
|
|
1138
1346
|
this.trigger(BookReader.eventNames.fullscreenToggled);
|
|
1347
|
+
|
|
1348
|
+
// resize book after all events & css updates
|
|
1349
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
1350
|
+
|
|
1351
|
+
this.resize();
|
|
1352
|
+
this.refs.$br.removeClass('BRfullscreenAnimation');
|
|
1139
1353
|
};
|
|
1140
1354
|
|
|
1141
1355
|
/**
|
|
@@ -1145,26 +1359,51 @@ BookReader.prototype.enterFullscreen = function(bindKeyboardControls = true) {
|
|
|
1145
1359
|
* - fires custom event
|
|
1146
1360
|
* @param { boolean } bindKeyboardControls
|
|
1147
1361
|
*/
|
|
1148
|
-
BookReader.prototype.exitFullScreen = function() {
|
|
1149
|
-
this.refs.$
|
|
1150
|
-
|
|
1151
|
-
$(document).unbind('keyup', this._fullscreenCloseHandler);
|
|
1152
|
-
|
|
1153
|
-
var windowWidth = $(window).width();
|
|
1362
|
+
BookReader.prototype.exitFullScreen = async function () {
|
|
1363
|
+
this.refs.$br.addClass('BRfullscreenAnimation');
|
|
1364
|
+
$(document).off('keyup', this._fullscreenCloseHandler);
|
|
1154
1365
|
|
|
1366
|
+
const windowWidth = $(window).width();
|
|
1155
1367
|
const canShow2up = this.options.controls.twoPage.visible;
|
|
1156
1368
|
if (canShow2up && (windowWidth <= this.onePageMinBreakpoint)) {
|
|
1157
1369
|
this.switchMode(this.constMode2up);
|
|
1158
1370
|
}
|
|
1159
1371
|
|
|
1160
1372
|
this.isFullscreenActive = false;
|
|
1161
|
-
this.updateBrClasses();
|
|
1162
1373
|
|
|
1163
|
-
this
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1374
|
+
this.$('.BRnav .BRicon.full').attr('title', 'Go fullscreen');
|
|
1375
|
+
this.$('.BRnav .BRicon.full .BRtooltip').text('Go fullscreen');
|
|
1376
|
+
|
|
1377
|
+
// Trigger fullscreen event immediately
|
|
1378
|
+
// so that book-nav can relay to web components
|
|
1167
1379
|
this.trigger(BookReader.eventNames.fullscreenToggled);
|
|
1380
|
+
|
|
1381
|
+
this.updateBrClasses();
|
|
1382
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
1383
|
+
this.resize();
|
|
1384
|
+
|
|
1385
|
+
if (this.activeMode instanceof Mode1Up) {
|
|
1386
|
+
this.activeMode.mode1UpLit.scale = this.activeMode.mode1UpLit.computeDefaultScale(this.book.getPage(this.currentIndex()));
|
|
1387
|
+
this.activeMode.mode1UpLit.requestUpdate();
|
|
1388
|
+
await this.activeMode.mode1UpLit.updateComplete;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
this.plugins.textSelection?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1392
|
+
this.plugins.translate?.textSelectionManager.stopPageFlip(this.refs.$brContainer);
|
|
1393
|
+
// Remove "?view=theater"
|
|
1394
|
+
this.trigger(BookReader.eventNames.fragmentChange);
|
|
1395
|
+
this.refs.$br.removeClass('BRfullscreenAnimation');
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* Toggles the mobile slider and page controls
|
|
1400
|
+
*/
|
|
1401
|
+
BookReader.prototype.toggleSlider = function () {
|
|
1402
|
+
const toggleButton = this.refs.$BRnav.find('.toggle_slider');
|
|
1403
|
+
const mobileControls = this.refs.$br.find('.BRnavMobile');
|
|
1404
|
+
|
|
1405
|
+
toggleButton.toggleClass('active');
|
|
1406
|
+
mobileControls.toggleClass('docked');
|
|
1168
1407
|
};
|
|
1169
1408
|
|
|
1170
1409
|
/**
|
|
@@ -1178,7 +1417,7 @@ BookReader.prototype.currentIndex = function() {
|
|
|
1178
1417
|
return this.firstIndex; // $$$ TODO page in center of view would be better
|
|
1179
1418
|
} else if (this.mode == this.constMode2up) {
|
|
1180
1419
|
// Only allow indices that are actually present in book
|
|
1181
|
-
return utils.clamp(this.firstIndex, 0, this.
|
|
1420
|
+
return utils.clamp(this.firstIndex, 0, this.book.getNumLeafs() - 1);
|
|
1182
1421
|
} else {
|
|
1183
1422
|
throw 'currentIndex called for unimplemented mode ' + this.mode;
|
|
1184
1423
|
}
|
|
@@ -1193,13 +1432,11 @@ BookReader.prototype.currentIndex = function() {
|
|
|
1193
1432
|
*/
|
|
1194
1433
|
BookReader.prototype.updateFirstIndex = function(
|
|
1195
1434
|
index,
|
|
1196
|
-
{ suppressFragmentChange = false } = {}
|
|
1435
|
+
{ suppressFragmentChange = false } = {},
|
|
1197
1436
|
) {
|
|
1198
|
-
//
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
suppressFragmentChange = true;
|
|
1202
|
-
}
|
|
1437
|
+
// If there's no change, do nothing
|
|
1438
|
+
if (this.firstIndex === index) return;
|
|
1439
|
+
|
|
1203
1440
|
this.firstIndex = index;
|
|
1204
1441
|
if (!(this.suppressFragmentChange || suppressFragmentChange)) {
|
|
1205
1442
|
this.trigger(BookReader.eventNames.fragmentChange);
|
|
@@ -1207,22 +1444,21 @@ BookReader.prototype.updateFirstIndex = function(
|
|
|
1207
1444
|
// If there's an initial search we stop suppressing global URL changes
|
|
1208
1445
|
// when local suppression ends
|
|
1209
1446
|
// This seems to correctly handle multiple calls during mode/1up
|
|
1210
|
-
if (this.options.initialSearchTerm && !suppressFragmentChange) {
|
|
1447
|
+
if (this.plugins.search?.options.initialSearchTerm && !suppressFragmentChange) {
|
|
1211
1448
|
this.suppressFragmentChange = false;
|
|
1212
1449
|
}
|
|
1213
|
-
|
|
1214
|
-
this.
|
|
1450
|
+
|
|
1451
|
+
this.trigger(BookReader.eventNames.pageChanged);
|
|
1452
|
+
|
|
1453
|
+
// event to know if user is actively reading
|
|
1454
|
+
this.trigger(BookReader.eventNames.userAction);
|
|
1215
1455
|
};
|
|
1216
1456
|
|
|
1217
1457
|
/**
|
|
1218
1458
|
* Flip the right page over onto the left
|
|
1219
1459
|
*/
|
|
1220
|
-
BookReader.prototype.right = function() {
|
|
1221
|
-
|
|
1222
|
-
this.next();
|
|
1223
|
-
} else {
|
|
1224
|
-
this.prev();
|
|
1225
|
-
}
|
|
1460
|
+
BookReader.prototype.right = function({ ariaLive = true, triggerStop = true } = {}) {
|
|
1461
|
+
this.jumpToIndex('right', { ariaLive, triggerStop });
|
|
1226
1462
|
};
|
|
1227
1463
|
|
|
1228
1464
|
/**
|
|
@@ -1239,12 +1475,8 @@ BookReader.prototype.rightmost = function() {
|
|
|
1239
1475
|
/**
|
|
1240
1476
|
* Flip the left page over onto the right
|
|
1241
1477
|
*/
|
|
1242
|
-
BookReader.prototype.left = function() {
|
|
1243
|
-
|
|
1244
|
-
this.prev();
|
|
1245
|
-
} else {
|
|
1246
|
-
this.next();
|
|
1247
|
-
}
|
|
1478
|
+
BookReader.prototype.left = function({ ariaLive = true, triggerStop = true } = {}) {
|
|
1479
|
+
this.jumpToIndex('left', { ariaLive, triggerStop });
|
|
1248
1480
|
};
|
|
1249
1481
|
|
|
1250
1482
|
/**
|
|
@@ -1258,283 +1490,42 @@ BookReader.prototype.leftmost = function() {
|
|
|
1258
1490
|
}
|
|
1259
1491
|
};
|
|
1260
1492
|
|
|
1261
|
-
BookReader.prototype.next = function() {
|
|
1262
|
-
if (this.constMode2up == this.mode) {
|
|
1263
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1264
|
-
this.flipFwdToIndex(null);
|
|
1265
|
-
} else {
|
|
1266
|
-
if (this.firstIndex < this.lastDisplayableIndex()) {
|
|
1267
|
-
this.jumpToIndex(this.firstIndex + 1);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
};
|
|
1271
|
-
|
|
1272
|
-
BookReader.prototype.prev = function() {
|
|
1273
|
-
const isOnFrontPage = this.firstIndex < 1;
|
|
1274
|
-
if (isOnFrontPage) return;
|
|
1275
|
-
|
|
1276
|
-
if (this.constMode2up == this.mode) {
|
|
1277
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1278
|
-
this.flipBackToIndex(null);
|
|
1279
|
-
} else {
|
|
1280
|
-
if (this.firstIndex >= 1) {
|
|
1281
|
-
this.jumpToIndex(this.firstIndex - 1);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
1285
|
-
|
|
1286
|
-
BookReader.prototype.first = function() {
|
|
1287
|
-
this.jumpToIndex(this.firstDisplayableIndex());
|
|
1288
|
-
};
|
|
1289
|
-
|
|
1290
|
-
BookReader.prototype.last = function() {
|
|
1291
|
-
this.jumpToIndex(this.lastDisplayableIndex());
|
|
1292
|
-
};
|
|
1293
|
-
|
|
1294
|
-
/**
|
|
1295
|
-
* Scrolls down one screen view
|
|
1296
|
-
*/
|
|
1297
|
-
BookReader.prototype.scrollDown = function() {
|
|
1298
|
-
if ($.inArray(this.mode, [this.constMode1up, this.constModeThumb]) >= 0) {
|
|
1299
|
-
if ( this.mode == this.constMode1up && (this.reduce >= this.onePageGetAutofitHeight()) ) {
|
|
1300
|
-
// Whole pages are visible, scroll whole page only
|
|
1301
|
-
return this.next();
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
this.refs.$brContainer.stop(true).animate(
|
|
1305
|
-
{ scrollTop: '+=' + this._scrollAmount() + 'px'},
|
|
1306
|
-
400, 'easeInOutExpo'
|
|
1307
|
-
);
|
|
1308
|
-
return true;
|
|
1309
|
-
} else {
|
|
1310
|
-
return false;
|
|
1311
|
-
}
|
|
1312
|
-
};
|
|
1313
|
-
|
|
1314
|
-
/**
|
|
1315
|
-
* Scrolls up one screen view
|
|
1316
|
-
*/
|
|
1317
|
-
BookReader.prototype.scrollUp = function() {
|
|
1318
|
-
if ($.inArray(this.mode, [this.constMode1up, this.constModeThumb]) >= 0) {
|
|
1319
|
-
if ( this.mode == this.constMode1up && (this.reduce >= this.onePageGetAutofitHeight()) ) {
|
|
1320
|
-
// Whole pages are visible, scroll whole page only
|
|
1321
|
-
return this.prev();
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
this.refs.$brContainer.stop(true).animate(
|
|
1325
|
-
{ scrollTop: '-=' + this._scrollAmount() + 'px'},
|
|
1326
|
-
400, 'easeInOutExpo'
|
|
1327
|
-
);
|
|
1328
|
-
return true;
|
|
1329
|
-
} else {
|
|
1330
|
-
return false;
|
|
1331
|
-
}
|
|
1332
|
-
};
|
|
1333
|
-
|
|
1334
1493
|
/**
|
|
1335
|
-
*
|
|
1494
|
+
* @param {object} options
|
|
1495
|
+
* @param {boolean} [options.triggerStop = true]
|
|
1496
|
+
* @param {number | 'fast' | 'slow'} [options.flipSpeed]
|
|
1497
|
+
* @param {boolean} [options.ariaLive = true]
|
|
1336
1498
|
*/
|
|
1337
|
-
BookReader.prototype.
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
return parseInt(0.9 * this.refs.$brContainer.prop('clientHeight'));
|
|
1499
|
+
BookReader.prototype.next = function({
|
|
1500
|
+
triggerStop = true,
|
|
1501
|
+
flipSpeed = null,
|
|
1502
|
+
ariaLive = true,
|
|
1503
|
+
} = {}) {
|
|
1504
|
+
this.jumpToIndex('next', { ariaLive, flipSpeed, triggerStop });
|
|
1344
1505
|
};
|
|
1345
1506
|
|
|
1346
1507
|
/**
|
|
1347
|
-
* @
|
|
1508
|
+
* @param {object} options
|
|
1509
|
+
* @param {boolean} [options.triggerStop = true]
|
|
1510
|
+
* @param {number | 'fast' | 'slow'} [options.flipSpeed]
|
|
1511
|
+
* @param {boolean} [options.ariaLive = true]
|
|
1348
1512
|
*/
|
|
1349
|
-
BookReader.prototype.
|
|
1350
|
-
|
|
1513
|
+
BookReader.prototype.prev = function({
|
|
1514
|
+
triggerStop = true,
|
|
1515
|
+
flipSpeed = null,
|
|
1516
|
+
ariaLive = true,
|
|
1517
|
+
} = {}) {
|
|
1518
|
+
this.jumpToIndex('prev', { ariaLive, flipSpeed, triggerStop });
|
|
1351
1519
|
};
|
|
1352
1520
|
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
*/
|
|
1356
|
-
BookReader.prototype.pruneUnusedImgs = function() {
|
|
1357
|
-
console.warn('Call to deprecated function: BookReader.pruneUnused. No-op.');
|
|
1521
|
+
BookReader.prototype.first = function({ ariaLive = true, triggerStop = false } = {}) {
|
|
1522
|
+
this.jumpToIndex(0, { ariaLive, triggerStop });
|
|
1358
1523
|
};
|
|
1359
1524
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
/************************/
|
|
1363
|
-
/** @deprecated not used outside BookReader */
|
|
1364
|
-
BookReader.prototype.prepareOnePageView = Mode1Up.prototype.prepare;
|
|
1365
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'prepare', 'prepareOnePageView');
|
|
1366
|
-
/** @deprecated not used outside BookReader */
|
|
1367
|
-
BookReader.prototype.drawLeafsOnePage = Mode1Up.prototype.drawLeafs;
|
|
1368
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'drawLeafs', 'drawLeafsOnePage');
|
|
1369
|
-
/** @deprecated not used outside BookReader */
|
|
1370
|
-
BookReader.prototype.zoom1up = Mode1Up.prototype.zoom;
|
|
1371
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'zoom', 'zoom1up');
|
|
1372
|
-
/** @deprecated not used outside Mode1Up */
|
|
1373
|
-
BookReader.prototype.onePageGetAutofitWidth = Mode1Up.prototype.getAutofitWidth;
|
|
1374
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getAutofitWidth', 'onePageGetAutofitWidth');
|
|
1375
|
-
/** @deprecated not used outside Mode1Up, BookReader */
|
|
1376
|
-
BookReader.prototype.onePageGetAutofitHeight = Mode1Up.prototype.getAutofitHeight;
|
|
1377
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getAutofitHeight', 'onePageGetAutofitHeight');
|
|
1378
|
-
/** @deprecated not used outside Mode1Up, BookReader */
|
|
1379
|
-
BookReader.prototype.onePageGetPageTop = Mode1Up.prototype.getPageTop;
|
|
1380
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'getPageTop', 'onePageGetPageTop');
|
|
1381
|
-
/** @deprecated not used outside Mode1Up, BookReader */
|
|
1382
|
-
BookReader.prototype.onePageCalculateReductionFactors = Mode1Up.prototype.calculateReductionFactors;
|
|
1383
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'calculateReductionFactors', 'onePageCalculateReductionFactors');
|
|
1384
|
-
/** @deprecated not used outside Mode1Up, BookReader */
|
|
1385
|
-
BookReader.prototype.resizePageView1up = Mode1Up.prototype.resizePageView;
|
|
1386
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'resizePageView', 'resizePageView1up');
|
|
1387
|
-
/** @deprecated not used outside Mode1Up */
|
|
1388
|
-
BookReader.prototype.onePageCalculateViewDimensions = Mode1Up.prototype.calculateViewDimensions;
|
|
1389
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'calculateViewDimensions', 'onePageCalculateViewDimensions');
|
|
1390
|
-
/** @deprecated not used outside Mode1Up */
|
|
1391
|
-
BookReader.prototype.centerX1up = Mode1Up.prototype.centerX;
|
|
1392
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'centerX', 'centerX1up');
|
|
1393
|
-
/** @deprecated not used outside Mode1Up */
|
|
1394
|
-
BookReader.prototype.centerY1up = Mode1Up.prototype.centerY;
|
|
1395
|
-
exposeOverrideableMethod(Mode1Up, '_modes.mode1Up', 'centerY', 'centerY1up');
|
|
1396
|
-
|
|
1397
|
-
/************************/
|
|
1398
|
-
/** Mode2Up extensions **/
|
|
1399
|
-
/************************/
|
|
1400
|
-
/** @deprecated not used outside Mode2Up */
|
|
1401
|
-
BookReader.prototype.zoom2up = Mode2Up.prototype.zoom;
|
|
1402
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'zoom', 'zoom2up');
|
|
1403
|
-
BookReader.prototype.twoPageGetAutofitReduce = Mode2Up.prototype.getAutofitReduce;
|
|
1404
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'getAutofitReduce', 'twoPageGetAutofitReduce');
|
|
1405
|
-
BookReader.prototype.flipBackToIndex = Mode2Up.prototype.flipBackToIndex;
|
|
1406
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipBackToIndex', 'flipBackToIndex');
|
|
1407
|
-
BookReader.prototype.flipFwdToIndex = Mode2Up.prototype.flipFwdToIndex;
|
|
1408
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipFwdToIndex', 'flipFwdToIndex');
|
|
1409
|
-
BookReader.prototype.setHilightCss2UP = Mode2Up.prototype.setHilightCss;
|
|
1410
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setHilightCss', 'setHilightCss2UP');
|
|
1411
|
-
/** @deprecated not used outside Mode2Up */
|
|
1412
|
-
BookReader.prototype.setClickHandler2UP = Mode2Up.prototype.setClickHandler;
|
|
1413
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setClickHandler', 'setClickHandler2UP');
|
|
1414
|
-
/** @deprecated not used outside Mode2Up */
|
|
1415
|
-
BookReader.prototype.drawLeafsTwoPage = Mode2Up.prototype.drawLeafs;
|
|
1416
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'drawLeafs', 'drawLeafsTwoPage');
|
|
1417
|
-
/** @deprecated not used outside BookReader */
|
|
1418
|
-
BookReader.prototype.prepareTwoPageView = Mode2Up.prototype.prepareTwoPageView;
|
|
1419
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'prepareTwoPageView', 'prepareTwoPageView');
|
|
1420
|
-
/** @deprecated not used outside Mode2Up */
|
|
1421
|
-
BookReader.prototype.prepareTwoPagePopUp = Mode2Up.prototype.preparePopUp;
|
|
1422
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'preparePopUp', 'prepareTwoPagePopUp');
|
|
1423
|
-
/** @deprecated not used outside BookReader, Mode2Up */
|
|
1424
|
-
BookReader.prototype.calculateSpreadSize = Mode2Up.prototype.calculateSpreadSize;
|
|
1425
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'calculateSpreadSize', 'calculateSpreadSize');
|
|
1426
|
-
/** @deprecated not used outside BookReader, Mode2Up */
|
|
1427
|
-
BookReader.prototype.getIdealSpreadSize = Mode2Up.prototype.getIdealSpreadSize;
|
|
1428
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'getIdealSpreadSize', 'getIdealSpreadSize');
|
|
1429
|
-
/** @deprecated not used outside BookReader, Mode2Up */
|
|
1430
|
-
BookReader.prototype.getSpreadSizeFromReduce = Mode2Up.prototype.getSpreadSizeFromReduce;
|
|
1431
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'getSpreadSizeFromReduce', 'getSpreadSizeFromReduce');
|
|
1432
|
-
/** @deprecated unused */
|
|
1433
|
-
BookReader.prototype.twoPageIsZoomedIn = Mode2Up.prototype.isZoomedIn;
|
|
1434
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'isZoomedIn', 'twoPageIsZoomedIn');
|
|
1435
|
-
/** @deprecated not used outside BookReader */
|
|
1436
|
-
BookReader.prototype.twoPageCalculateReductionFactors = Mode2Up.prototype.calculateReductionFactors;
|
|
1437
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'calculateReductionFactors', 'twoPageCalculateReductionFactors');
|
|
1438
|
-
/** @deprecated unused */
|
|
1439
|
-
BookReader.prototype.twoPageSetCursor = Mode2Up.prototype.setCursor;
|
|
1440
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setCursor', 'twoPageSetCursor');
|
|
1441
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1442
|
-
BookReader.prototype.flipLeftToRight = Mode2Up.prototype.flipLeftToRight;
|
|
1443
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipLeftToRight', 'flipLeftToRight');
|
|
1444
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1445
|
-
BookReader.prototype.flipRightToLeft = Mode2Up.prototype.flipRightToLeft;
|
|
1446
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipRightToLeft', 'flipRightToLeft');
|
|
1447
|
-
/** @deprecated unused outside Mode2Up */
|
|
1448
|
-
BookReader.prototype.setMouseHandlers2UP = Mode2Up.prototype.setMouseHandlers;
|
|
1449
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setMouseHandlers', 'setMouseHandlers2UP');
|
|
1450
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1451
|
-
BookReader.prototype.prepareFlipLeftToRight = Mode2Up.prototype.prepareFlipLeftToRight;
|
|
1452
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'prepareFlipLeftToRight', 'prepareFlipLeftToRight');
|
|
1453
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1454
|
-
BookReader.prototype.prepareFlipRightToLeft = Mode2Up.prototype.prepareFlipRightToLeft;
|
|
1455
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'prepareFlipRightToLeft', 'prepareFlipRightToLeft');
|
|
1456
|
-
/** @deprecated unused outside Mode2Up */
|
|
1457
|
-
BookReader.prototype.getPageWidth2UP = Mode2Up.prototype.getPageWidth;
|
|
1458
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'getPageWidth', 'getPageWidth2UP');
|
|
1459
|
-
/** @deprecated unused outside Mode2Up */
|
|
1460
|
-
BookReader.prototype.twoPageGutter = Mode2Up.prototype.gutter;
|
|
1461
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'gutter', 'twoPageGutter');
|
|
1462
|
-
/** @deprecated unused outside Mode2Up */
|
|
1463
|
-
BookReader.prototype.twoPageTop = Mode2Up.prototype.top;
|
|
1464
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'top', 'twoPageTop');
|
|
1465
|
-
/** @deprecated unused outside Mode2Up */
|
|
1466
|
-
BookReader.prototype.twoPageCoverWidth = Mode2Up.prototype.coverWidth;
|
|
1467
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'coverWidth', 'twoPageCoverWidth');
|
|
1468
|
-
/** @deprecated unused outside Mode2Up */
|
|
1469
|
-
BookReader.prototype.twoPageGetViewCenter = Mode2Up.prototype.getViewCenter;
|
|
1470
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'getViewCenter', 'twoPageGetViewCenter');
|
|
1471
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1472
|
-
BookReader.prototype.twoPageCenterView = Mode2Up.prototype.centerView;
|
|
1473
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'centerView', 'twoPageCenterView');
|
|
1474
|
-
/** @deprecated unused outside Mode2Up */
|
|
1475
|
-
BookReader.prototype.twoPageFlipAreaHeight = Mode2Up.prototype.flipAreaHeight;
|
|
1476
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipAreaHeight', 'twoPageFlipAreaHeight');
|
|
1477
|
-
/** @deprecated unused outside Mode2Up */
|
|
1478
|
-
BookReader.prototype.twoPageFlipAreaWidth = Mode2Up.prototype.flipAreaWidth;
|
|
1479
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipAreaWidth', 'twoPageFlipAreaWidth');
|
|
1480
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1481
|
-
BookReader.prototype.twoPageFlipAreaTop = Mode2Up.prototype.flipAreaTop;
|
|
1482
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'flipAreaTop', 'twoPageFlipAreaTop');
|
|
1483
|
-
/** @deprecated unused outside Mode2Up */
|
|
1484
|
-
BookReader.prototype.twoPageLeftFlipAreaLeft = Mode2Up.prototype.leftFlipAreaLeft;
|
|
1485
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'leftFlipAreaLeft', 'twoPageLeftFlipAreaLeft');
|
|
1486
|
-
/** @deprecated unused outside Mode2Up */
|
|
1487
|
-
BookReader.prototype.twoPageRightFlipAreaLeft = Mode2Up.prototype.rightFlipAreaLeft;
|
|
1488
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'rightFlipAreaLeft', 'twoPageRightFlipAreaLeft');
|
|
1489
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1490
|
-
BookReader.prototype.gutterOffsetForIndex = Mode2Up.prototype.gutterOffsetForIndex;
|
|
1491
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'gutterOffsetForIndex', 'gutterOffsetForIndex');
|
|
1492
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1493
|
-
BookReader.prototype.leafEdgeWidth = Mode2Up.prototype.leafEdgeWidth;
|
|
1494
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'leafEdgeWidth', 'leafEdgeWidth');
|
|
1495
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1496
|
-
BookReader.prototype.jumpIndexForLeftEdgePageX = Mode2Up.prototype.jumpIndexForLeftEdgePageX;
|
|
1497
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'jumpIndexForLeftEdgePageX', 'jumpIndexForLeftEdgePageX');
|
|
1498
|
-
/** @deprecated unused outside BookReader, Mode2Up */
|
|
1499
|
-
BookReader.prototype.jumpIndexForRightEdgePageX = Mode2Up.prototype.jumpIndexForRightEdgePageX;
|
|
1500
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'jumpIndexForRightEdgePageX', 'jumpIndexForRightEdgePageX');
|
|
1501
|
-
/** @deprecated unused outside Mode2Up */
|
|
1502
|
-
BookReader.prototype.prefetch = Mode2Up.prototype.prefetch;
|
|
1503
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'prefetch', 'prefetch');
|
|
1504
|
-
/** @deprecated unused outside Mode2Up */
|
|
1505
|
-
BookReader.prototype.setSpreadIndices = Mode2Up.prototype.setSpreadIndices;
|
|
1506
|
-
exposeOverrideableMethod(Mode2Up, '_modes.mode2Up', 'setSpreadIndices', 'setSpreadIndices');
|
|
1507
|
-
/**
|
|
1508
|
-
* Immediately stop flip animations. Callbacks are triggered.
|
|
1509
|
-
*/
|
|
1510
|
-
BookReader.prototype.stopFlipAnimations = function() {
|
|
1511
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1512
|
-
|
|
1513
|
-
// Stop animation, clear queue, trigger callbacks
|
|
1514
|
-
if (this.leafEdgeTmp) {
|
|
1515
|
-
$(this.leafEdgeTmp).stop(false, true);
|
|
1516
|
-
}
|
|
1517
|
-
jQuery.each(this._modes.mode2Up.pageContainers, function() {
|
|
1518
|
-
$(this.$container).stop(false, true);
|
|
1519
|
-
});
|
|
1520
|
-
|
|
1521
|
-
// And again since animations also queued in callbacks
|
|
1522
|
-
if (this.leafEdgeTmp) {
|
|
1523
|
-
$(this.leafEdgeTmp).stop(false, true);
|
|
1524
|
-
}
|
|
1525
|
-
jQuery.each(this._modes.mode2Up.pageContainers, function() {
|
|
1526
|
-
$(this.$container).stop(false, true);
|
|
1527
|
-
});
|
|
1525
|
+
BookReader.prototype.last = function({ ariaLive = true, triggerStop = false } = {}) {
|
|
1526
|
+
this.jumpToIndex(this.book.getNumLeafs() - 1, { ariaLive, triggerStop });
|
|
1528
1527
|
};
|
|
1529
1528
|
|
|
1530
|
-
/**
|
|
1531
|
-
* Returns true if keyboard navigation should be disabled for the event
|
|
1532
|
-
* @param {Event}
|
|
1533
|
-
* @return {boolean}
|
|
1534
|
-
*/
|
|
1535
|
-
BookReader.prototype.keyboardNavigationIsDisabled = function(event) {
|
|
1536
|
-
return event.target.tagName == "INPUT";
|
|
1537
|
-
};
|
|
1538
1529
|
|
|
1539
1530
|
/**
|
|
1540
1531
|
* @template TClass extends { br: BookReader }
|
|
@@ -1558,30 +1549,9 @@ function exposeOverrideableMethod(Class, classKey, method, brMethod = method) {
|
|
|
1558
1549
|
/***********************/
|
|
1559
1550
|
/** Navbar extensions **/
|
|
1560
1551
|
/***********************/
|
|
1552
|
+
/** This cannot be removed yet because plugin.tts.js overrides it */
|
|
1561
1553
|
BookReader.prototype.initNavbar = Navbar.prototype.init;
|
|
1562
1554
|
exposeOverrideableMethod(Navbar, '_components.navbar', 'init', 'initNavbar');
|
|
1563
|
-
BookReader.prototype.switchNavbarControls = Navbar.prototype.switchNavbarControls;
|
|
1564
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'switchNavbarControls');
|
|
1565
|
-
BookReader.prototype.updateViewModeButton = Navbar.prototype.updateViewModeButton;
|
|
1566
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'updateViewModeButton');
|
|
1567
|
-
BookReader.prototype.getNavPageNumString = Navbar.prototype.getNavPageNumString;
|
|
1568
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'getNavPageNumString');
|
|
1569
|
-
/** @deprecated */
|
|
1570
|
-
BookReader.prototype.initEmbedNavbar = Navbar.prototype.initEmbed;
|
|
1571
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'initEmbed', 'initEmbedNavbar');
|
|
1572
|
-
/** @deprecated unused */
|
|
1573
|
-
BookReader.prototype.getNavPageNumHtml = getNavPageNumHtml;
|
|
1574
|
-
/** @deprecated unused outside this file */
|
|
1575
|
-
BookReader.prototype.updateNavPageNum = Navbar.prototype.updateNavPageNum;
|
|
1576
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'updateNavPageNum');
|
|
1577
|
-
/** @deprecated unused outside this file */
|
|
1578
|
-
BookReader.prototype.updateNavIndex = Navbar.prototype.updateNavIndex;
|
|
1579
|
-
exposeOverrideableMethod(Navbar, '_components.navbar', 'updateNavIndex');
|
|
1580
|
-
/** @deprecated unused outside this file */
|
|
1581
|
-
BookReader.prototype.updateNavIndexThrottled = utils.throttle(BookReader.prototype.updateNavIndex, 250, false);
|
|
1582
|
-
/** @deprecated unused */
|
|
1583
|
-
BookReader.prototype.updateNavIndexDebounced = utils.debounce(BookReader.prototype.updateNavIndex, 500, false);
|
|
1584
|
-
|
|
1585
1555
|
|
|
1586
1556
|
/************************/
|
|
1587
1557
|
/** Toolbar extensions **/
|
|
@@ -1596,515 +1566,15 @@ BookReader.prototype.buildInfoDiv = Toolbar.prototype.buildInfoDiv;
|
|
|
1596
1566
|
exposeOverrideableMethod(Toolbar, '_components.toolbar', 'buildInfoDiv');
|
|
1597
1567
|
BookReader.prototype.getToolBarHeight = Toolbar.prototype.getToolBarHeight;
|
|
1598
1568
|
exposeOverrideableMethod(Toolbar, '_components.toolbar', 'getToolBarHeight');
|
|
1599
|
-
/** @deprecated zoom no longer in toolbar */
|
|
1600
|
-
BookReader.prototype.updateToolbarZoom = Toolbar.prototype.updateToolbarZoom;
|
|
1601
|
-
exposeOverrideableMethod(Toolbar, '_components.toolbar', 'updateToolbarZoom');
|
|
1602
|
-
/** @deprecated unused */
|
|
1603
|
-
BookReader.prototype.blankInfoDiv = blankInfoDiv;
|
|
1604
|
-
/** @deprecated unused */
|
|
1605
|
-
BookReader.prototype.blankShareDiv = blankShareDiv;
|
|
1606
|
-
/** @deprecated unused */
|
|
1607
|
-
BookReader.prototype.createPopup = createPopup;
|
|
1608
|
-
|
|
1609
|
-
/**
|
|
1610
|
-
* Bind navigation handlers
|
|
1611
|
-
*/
|
|
1612
|
-
BookReader.prototype.bindNavigationHandlers = function() {
|
|
1613
|
-
const self = this;
|
|
1614
|
-
|
|
1615
|
-
// Note the mobile plugin attaches itself to body, so we need to select outside
|
|
1616
|
-
const jIcons = this.$('.BRicon').add('.BRmobileMenu .BRicon');
|
|
1617
|
-
// Map of jIcon class -> click handler
|
|
1618
|
-
const navigationControls = {
|
|
1619
|
-
book_left: () => {
|
|
1620
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1621
|
-
this.left();
|
|
1622
|
-
},
|
|
1623
|
-
book_right: () => {
|
|
1624
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1625
|
-
this.right();
|
|
1626
|
-
},
|
|
1627
|
-
book_up: () => {
|
|
1628
|
-
if ($.inArray(this.mode, [this.constMode1up, this.constModeThumb]) >= 0) {
|
|
1629
|
-
this.scrollUp();
|
|
1630
|
-
} else {
|
|
1631
|
-
this.prev();
|
|
1632
|
-
}
|
|
1633
|
-
},
|
|
1634
|
-
book_down: () => {
|
|
1635
|
-
if ($.inArray(this.mode, [this.constMode1up, this.constModeThumb]) >= 0) {
|
|
1636
|
-
this.scrollDown();
|
|
1637
|
-
} else {
|
|
1638
|
-
this.next();
|
|
1639
|
-
}
|
|
1640
|
-
},
|
|
1641
|
-
book_top: this.first.bind(this),
|
|
1642
|
-
book_bottom: this.last.bind(this),
|
|
1643
|
-
book_leftmost: this.leftmost.bind(this),
|
|
1644
|
-
book_rightmost: this.rightmost.bind(this),
|
|
1645
|
-
onepg: () => {
|
|
1646
|
-
this.switchMode(self.constMode1up);
|
|
1647
|
-
},
|
|
1648
|
-
thumb: () => {
|
|
1649
|
-
this.switchMode(self.constModeThumb);
|
|
1650
|
-
},
|
|
1651
|
-
twopg: () => {
|
|
1652
|
-
this.switchMode(self.constMode2up);
|
|
1653
|
-
},
|
|
1654
|
-
zoom_in: () => {
|
|
1655
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1656
|
-
this.zoom(1);
|
|
1657
|
-
this.trigger(BookReader.eventNames.zoomIn);
|
|
1658
|
-
},
|
|
1659
|
-
zoom_out: () => {
|
|
1660
|
-
this.trigger(BookReader.eventNames.stop);
|
|
1661
|
-
this.zoom(-1);
|
|
1662
|
-
this.trigger(BookReader.eventNames.zoomOut);
|
|
1663
|
-
},
|
|
1664
|
-
full: () => {
|
|
1665
|
-
if (this.ui == 'embed') {
|
|
1666
|
-
var url = this.$('.BRembedreturn a').attr('href');
|
|
1667
|
-
window.open(url);
|
|
1668
|
-
} else {
|
|
1669
|
-
this.toggleFullscreen();
|
|
1670
|
-
}
|
|
1671
|
-
},
|
|
1672
|
-
};
|
|
1673
|
-
|
|
1674
|
-
jIcons.filter('.fit').bind('fit', function() {
|
|
1675
|
-
// XXXmang implement autofit zoom
|
|
1676
|
-
});
|
|
1677
|
-
|
|
1678
|
-
for (const control in navigationControls) {
|
|
1679
|
-
jIcons.filter(`.${control}`).on('click.bindNavigationHandlers', () => {
|
|
1680
|
-
navigationControls[control]()
|
|
1681
|
-
return false;
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
var $brNavCntlBtmEl = this.$('.BRnavCntlBtm');
|
|
1686
|
-
var $brNavCntlTopEl = this.$('.BRnavCntlTop');
|
|
1687
|
-
|
|
1688
|
-
this.$('.BRnavCntl').click(
|
|
1689
|
-
function() {
|
|
1690
|
-
var promises = [];
|
|
1691
|
-
// TODO don't use magic constants
|
|
1692
|
-
// TODO move this to a function
|
|
1693
|
-
if ($brNavCntlBtmEl.hasClass('BRdn')) {
|
|
1694
|
-
if (self.refs.$BRtoolbar)
|
|
1695
|
-
promises.push(self.refs.$BRtoolbar.animate(
|
|
1696
|
-
{top: self.getToolBarHeight() * -1}
|
|
1697
|
-
).promise());
|
|
1698
|
-
promises.push(self.$('.BRfooter').animate({bottom: self.getFooterHeight() * -1}).promise());
|
|
1699
|
-
$brNavCntlBtmEl.addClass('BRup').removeClass('BRdn');
|
|
1700
|
-
$brNavCntlTopEl.addClass('BRdn').removeClass('BRup');
|
|
1701
|
-
self.$('.BRnavCntlBtm.BRnavCntl').animate({height:'45px'});
|
|
1702
|
-
self.$('.BRnavCntl').delay(1000).animate({opacity:.75}, 1000);
|
|
1703
|
-
} else {
|
|
1704
|
-
if (self.refs.$BRtoolbar)
|
|
1705
|
-
promises.push(self.refs.$BRtoolbar.animate({top:0}).promise());
|
|
1706
|
-
promises.push(self.$('.BRfooter').animate({bottom:0}).promise());
|
|
1707
|
-
$brNavCntlBtmEl.addClass('BRdn').removeClass('BRup');
|
|
1708
|
-
$brNavCntlTopEl.addClass('BRup').removeClass('BRdn');
|
|
1709
|
-
self.$('.BRnavCntlBtm.BRnavCntl').animate({height:'30px'});
|
|
1710
|
-
self.$('.BRvavCntl').animate({opacity:1})
|
|
1711
|
-
}
|
|
1712
|
-
$.when.apply($, promises).done(function() {
|
|
1713
|
-
// Only do full resize in auto mode and need to recalc. size
|
|
1714
|
-
if (self.mode == self.constMode2up && self.twoPage.autofit != null
|
|
1715
|
-
&& self.twoPage.autofit != 'none'
|
|
1716
|
-
) {
|
|
1717
|
-
self.resize();
|
|
1718
|
-
} else if (self.mode == self.constMode1up && self.onePage.autofit != null
|
|
1719
|
-
&& self.onePage.autofit != 'none') {
|
|
1720
|
-
self.resize();
|
|
1721
|
-
} else {
|
|
1722
|
-
// Don't do a full resize to avoid redrawing images
|
|
1723
|
-
self.resizeBRcontainer();
|
|
1724
|
-
}
|
|
1725
|
-
});
|
|
1726
|
-
}
|
|
1727
|
-
);
|
|
1728
|
-
$brNavCntlBtmEl.mouseover(function() {
|
|
1729
|
-
if ($(this).hasClass('BRup')) {
|
|
1730
|
-
self.$('.BRnavCntl').animate({opacity:1},250);
|
|
1731
|
-
}
|
|
1732
|
-
}).mouseleave(function() {
|
|
1733
|
-
if ($(this).hasClass('BRup')) {
|
|
1734
|
-
self.$('.BRnavCntl').animate({opacity:.75},250);
|
|
1735
|
-
}
|
|
1736
|
-
});
|
|
1737
|
-
$brNavCntlTopEl.mouseover(function() {
|
|
1738
|
-
if ($(this).hasClass('BRdn')) {
|
|
1739
|
-
self.$('.BRnavCntl').animate({opacity:1},250);
|
|
1740
|
-
}
|
|
1741
|
-
}).mouseleave(function() {
|
|
1742
|
-
if ($(this).hasClass('BRdn')) {
|
|
1743
|
-
self.$('.BRnavCntl').animate({opacity:.75},250);
|
|
1744
|
-
}
|
|
1745
|
-
});
|
|
1746
|
-
|
|
1747
|
-
this.initSwipeData();
|
|
1748
|
-
|
|
1749
|
-
$(document).off('mousemove.navigation', this.el);
|
|
1750
|
-
$(document).on(
|
|
1751
|
-
'mousemove.navigation',
|
|
1752
|
-
this.el,
|
|
1753
|
-
{ 'br': this },
|
|
1754
|
-
this.navigationMousemoveHandler
|
|
1755
|
-
);
|
|
1756
|
-
|
|
1757
|
-
$(document).off('mousedown.swipe', '.BRpageimage');
|
|
1758
|
-
$(document).on(
|
|
1759
|
-
'mousedown.swipe',
|
|
1760
|
-
'.BRpageimage',
|
|
1761
|
-
{ 'br': this },
|
|
1762
|
-
this.swipeMousedownHandler
|
|
1763
|
-
);
|
|
1764
|
-
|
|
1765
|
-
this.bindMozTouchHandlers();
|
|
1766
|
-
};
|
|
1767
|
-
|
|
1768
|
-
/**
|
|
1769
|
-
* Unbind navigation handlers
|
|
1770
|
-
*/
|
|
1771
|
-
BookReader.prototype.unbindNavigationHandlers = function() {
|
|
1772
|
-
$(document).off('mousemove.navigation', this.el);
|
|
1773
|
-
};
|
|
1774
|
-
|
|
1775
|
-
/**
|
|
1776
|
-
* Handle mousemove related to navigation. Bind at #BookReader level to allow autohide.
|
|
1777
|
-
*/
|
|
1778
|
-
BookReader.prototype.navigationMousemoveHandler = function(event) {
|
|
1779
|
-
// $$$ possibly not great to be calling this for every mousemove
|
|
1780
|
-
if (event.data['br'].uiAutoHide) {
|
|
1781
|
-
// 77px is an approximate height of the Internet Archive Top Nav
|
|
1782
|
-
// 75 & 76 (pixels) provide used in this context is checked against the IA top nav height
|
|
1783
|
-
var navkey = $(document).height() - 75;
|
|
1784
|
-
if ((event.pageY < 76) || (event.pageY > navkey)) {
|
|
1785
|
-
// inside or near navigation elements
|
|
1786
|
-
event.data['br'].hideNavigation();
|
|
1787
|
-
} else {
|
|
1788
|
-
event.data['br'].showNavigation();
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
};
|
|
1792
|
-
|
|
1793
|
-
BookReader.prototype.initSwipeData = function(clientX, clientY) {
|
|
1794
|
-
/*
|
|
1795
|
-
* Based on the really quite awesome "Today's Guardian" at http://guardian.gyford.com/
|
|
1796
|
-
*/
|
|
1797
|
-
this._swipe = {
|
|
1798
|
-
mightBeSwiping: false,
|
|
1799
|
-
didSwipe: false,
|
|
1800
|
-
mightBeDraggin: false,
|
|
1801
|
-
didDrag: false,
|
|
1802
|
-
startTime: (new Date).getTime(),
|
|
1803
|
-
startX: clientX,
|
|
1804
|
-
startY: clientY,
|
|
1805
|
-
lastX: clientX,
|
|
1806
|
-
lastY: clientY,
|
|
1807
|
-
deltaX: 0,
|
|
1808
|
-
deltaY: 0,
|
|
1809
|
-
deltaT: 0
|
|
1810
|
-
}
|
|
1811
|
-
};
|
|
1812
|
-
|
|
1813
|
-
BookReader.prototype.swipeMousedownHandler = function(event) {
|
|
1814
|
-
var self = event.data['br'];
|
|
1815
|
-
|
|
1816
|
-
// We should be the last bubble point for the page images
|
|
1817
|
-
// Disable image drag and select, but keep right-click
|
|
1818
|
-
if (event.which == 3) {
|
|
1819
|
-
return !self.protected;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
$(event.target).bind('mouseout.swipe',
|
|
1823
|
-
{ 'br': self},
|
|
1824
|
-
self.swipeMouseupHandler
|
|
1825
|
-
).bind('mouseup.swipe',
|
|
1826
|
-
{ 'br': self},
|
|
1827
|
-
self.swipeMouseupHandler
|
|
1828
|
-
).bind('mousemove.swipe',
|
|
1829
|
-
{ 'br': self },
|
|
1830
|
-
self.swipeMousemoveHandler
|
|
1831
|
-
);
|
|
1832
|
-
|
|
1833
|
-
self.initSwipeData(event.clientX, event.clientY);
|
|
1834
|
-
self._swipe.mightBeSwiping = true;
|
|
1835
|
-
self._swipe.mightBeDragging = true;
|
|
1836
|
-
|
|
1837
|
-
event.preventDefault();
|
|
1838
|
-
event.returnValue = false;
|
|
1839
|
-
event.cancelBubble = true;
|
|
1840
|
-
return false;
|
|
1841
|
-
};
|
|
1842
|
-
|
|
1843
|
-
BookReader.prototype.swipeMousemoveHandler = function(event) {
|
|
1844
|
-
var self = event.data['br'];
|
|
1845
|
-
var _swipe = self._swipe;
|
|
1846
|
-
if (! _swipe.mightBeSwiping) {
|
|
1847
|
-
return;
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
// Update swipe data
|
|
1851
|
-
_swipe.deltaX = event.clientX - _swipe.startX;
|
|
1852
|
-
_swipe.deltaY = event.clientY - _swipe.startY;
|
|
1853
|
-
_swipe.deltaT = (new Date).getTime() - _swipe.startTime;
|
|
1854
|
-
|
|
1855
|
-
var absX = Math.abs(_swipe.deltaX);
|
|
1856
|
-
var absY = Math.abs(_swipe.deltaY);
|
|
1857
|
-
|
|
1858
|
-
// Minimum distance in the amount of tim to trigger the swipe
|
|
1859
|
-
var minSwipeLength = Math.min(self.refs.$br.width() / 5, 80);
|
|
1860
|
-
var maxSwipeTime = 400;
|
|
1861
|
-
|
|
1862
|
-
// Check for horizontal swipe
|
|
1863
|
-
if (absX > absY && (absX > minSwipeLength) && _swipe.deltaT < maxSwipeTime) {
|
|
1864
|
-
_swipe.mightBeSwiping = false; // only trigger once
|
|
1865
|
-
_swipe.didSwipe = true;
|
|
1866
|
-
if (self.mode == self.constMode2up) {
|
|
1867
|
-
if (_swipe.deltaX < 0) {
|
|
1868
|
-
self.right();
|
|
1869
|
-
} else {
|
|
1870
|
-
self.left();
|
|
1871
|
-
}
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
if ( _swipe.deltaT > maxSwipeTime && !_swipe.didSwipe) {
|
|
1876
|
-
if (_swipe.mightBeDragging) {
|
|
1877
|
-
// Dragging
|
|
1878
|
-
_swipe.didDrag = true;
|
|
1879
|
-
self.refs.$brContainer
|
|
1880
|
-
.scrollTop(self.refs.$brContainer.scrollTop() - event.clientY + _swipe.lastY)
|
|
1881
|
-
.scrollLeft(self.refs.$brContainer.scrollLeft() - event.clientX + _swipe.lastX);
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
_swipe.lastX = event.clientX;
|
|
1885
|
-
_swipe.lastY = event.clientY;
|
|
1886
|
-
|
|
1887
|
-
event.preventDefault();
|
|
1888
|
-
event.returnValue = false;
|
|
1889
|
-
event.cancelBubble = true;
|
|
1890
|
-
return false;
|
|
1891
|
-
};
|
|
1892
|
-
|
|
1893
|
-
BookReader.prototype.swipeMouseupHandler = function(event) {
|
|
1894
|
-
var _swipe = event.data['br']._swipe;
|
|
1895
|
-
_swipe.mightBeSwiping = false;
|
|
1896
|
-
_swipe.mightBeDragging = false;
|
|
1897
|
-
|
|
1898
|
-
$(event.target).unbind('mouseout.swipe').unbind('mouseup.swipe').unbind('mousemove.swipe');
|
|
1899
|
-
|
|
1900
|
-
if (_swipe.didSwipe || _swipe.didDrag) {
|
|
1901
|
-
// Swallow event if completed swipe gesture
|
|
1902
|
-
event.preventDefault();
|
|
1903
|
-
event.returnValue = false;
|
|
1904
|
-
event.cancelBubble = true;
|
|
1905
|
-
return false;
|
|
1906
|
-
}
|
|
1907
|
-
return true;
|
|
1908
|
-
};
|
|
1909
|
-
|
|
1910
|
-
BookReader.prototype.bindMozTouchHandlers = function() {
|
|
1911
|
-
var self = this;
|
|
1912
|
-
|
|
1913
|
-
// Currently only want touch handlers in 2up
|
|
1914
|
-
this.refs.$br.bind('MozTouchDown', function(event) {
|
|
1915
|
-
if (this.mode == self.constMode2up) {
|
|
1916
|
-
event.preventDefault();
|
|
1917
|
-
}
|
|
1918
|
-
})
|
|
1919
|
-
.bind('MozTouchMove', function(event) {
|
|
1920
|
-
if (this.mode == self.constMode2up) {
|
|
1921
|
-
event.preventDefault();
|
|
1922
|
-
}
|
|
1923
|
-
})
|
|
1924
|
-
.bind('MozTouchUp', function(event) {
|
|
1925
|
-
if (this.mode == self.constMode2up) {
|
|
1926
|
-
event.preventDefault();
|
|
1927
|
-
}
|
|
1928
|
-
});
|
|
1929
|
-
};
|
|
1930
|
-
|
|
1931
|
-
/**
|
|
1932
|
-
* Returns true if the navigation elements are currently visible
|
|
1933
|
-
* @return {boolean}
|
|
1934
|
-
*/
|
|
1935
|
-
BookReader.prototype.navigationIsVisible = function() {
|
|
1936
|
-
// $$$ doesn't account for transitioning states, nav must be fully visible to return true
|
|
1937
|
-
var toolpos = this.refs.$BRtoolbar.position();
|
|
1938
|
-
var tooltop = toolpos.top;
|
|
1939
|
-
return tooltop == 0;
|
|
1940
|
-
};
|
|
1941
|
-
|
|
1942
|
-
/**
|
|
1943
|
-
* Main controller that sets navigation into view.
|
|
1944
|
-
* Defaults to SHOW the navigation chrome
|
|
1945
|
-
*/
|
|
1946
|
-
BookReader.prototype.setNavigationView = function brSetNavigationView(hide) {
|
|
1947
|
-
var animationLength = this.constNavAnimationDuration;
|
|
1948
|
-
var animationType = 'linear';
|
|
1949
|
-
var resizePageContainer = function resizePageContainer () {
|
|
1950
|
-
/* main page container fills whole container */
|
|
1951
|
-
if (this.constMode2up !== this.mode) {
|
|
1952
|
-
var animate = true;
|
|
1953
|
-
this.resizeBRcontainer(animate);
|
|
1954
|
-
}
|
|
1955
|
-
this.trigger(BookReader.eventNames.navToggled);
|
|
1956
|
-
}.bind(this);
|
|
1957
|
-
|
|
1958
|
-
var toolbarHeight = 0;
|
|
1959
|
-
var navbarHeight = 0;
|
|
1960
|
-
if (hide) {
|
|
1961
|
-
toolbarHeight = this.getToolBarHeight() * -1;
|
|
1962
|
-
navbarHeight = this.getFooterHeight() * -1;
|
|
1963
|
-
|
|
1964
|
-
this.refs.$BRtoolbar.addClass('js-menu-hide');
|
|
1965
|
-
this.refs.$BRfooter.addClass('js-menu-hide');
|
|
1966
|
-
} else {
|
|
1967
|
-
this.refs.$BRtoolbar.removeClass('js-menu-hide');
|
|
1968
|
-
this.refs.$BRfooter.removeClass('js-menu-hide');
|
|
1969
|
-
}
|
|
1970
|
-
|
|
1971
|
-
this.refs.$BRtoolbar.animate(
|
|
1972
|
-
{ top: toolbarHeight },
|
|
1973
|
-
animationLength,
|
|
1974
|
-
animationType,
|
|
1975
|
-
resizePageContainer
|
|
1976
|
-
);
|
|
1977
|
-
this.refs.$BRfooter.animate(
|
|
1978
|
-
{ bottom: navbarHeight },
|
|
1979
|
-
animationLength,
|
|
1980
|
-
animationType,
|
|
1981
|
-
resizePageContainer
|
|
1982
|
-
);
|
|
1983
|
-
};
|
|
1984
|
-
/**
|
|
1985
|
-
* Hide navigation elements, if visible
|
|
1986
|
-
*/
|
|
1987
|
-
BookReader.prototype.hideNavigation = function() {
|
|
1988
|
-
// Check if navigation is showing
|
|
1989
|
-
if (this.navigationIsVisible()) {
|
|
1990
|
-
var hide = true;
|
|
1991
|
-
this.setNavigationView(hide);
|
|
1992
|
-
}
|
|
1993
|
-
};
|
|
1994
|
-
|
|
1995
|
-
/**
|
|
1996
|
-
* Show navigation elements
|
|
1997
|
-
*/
|
|
1998
|
-
BookReader.prototype.showNavigation = function() {
|
|
1999
|
-
// Check if navigation is hidden
|
|
2000
|
-
if (!this.navigationIsVisible()) {
|
|
2001
|
-
this.setNavigationView();
|
|
2002
|
-
}
|
|
2003
|
-
};
|
|
2004
|
-
|
|
2005
|
-
/**
|
|
2006
|
-
* Returns the index of the first visible page, dependent on the mode.
|
|
2007
|
-
* $$$ Currently we cannot display the front/back cover in 2-up and will need to update
|
|
2008
|
-
* this function when we can as part of https://bugs.launchpad.net/gnubook/+bug/296788
|
|
2009
|
-
* @return {number}
|
|
2010
|
-
*/
|
|
2011
|
-
BookReader.prototype.firstDisplayableIndex = function() {
|
|
2012
|
-
if (this.mode != this.constMode2up) {
|
|
2013
|
-
return 0;
|
|
2014
|
-
}
|
|
2015
|
-
|
|
2016
|
-
if ('rl' != this.pageProgression) {
|
|
2017
|
-
// LTR
|
|
2018
|
-
if (this._models.book.getPageSide(0) == 'L') {
|
|
2019
|
-
return 0;
|
|
2020
|
-
} else {
|
|
2021
|
-
return -1;
|
|
2022
|
-
}
|
|
2023
|
-
} else {
|
|
2024
|
-
// RTL
|
|
2025
|
-
if (this._models.book.getPageSide(0) == 'R') {
|
|
2026
|
-
return 0;
|
|
2027
|
-
} else {
|
|
2028
|
-
return -1;
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
|
-
};
|
|
2032
|
-
|
|
2033
|
-
/**
|
|
2034
|
-
* Returns the index of the last visible page, dependent on the mode.
|
|
2035
|
-
* $$$ Currently we cannot display the front/back cover in 2-up and will need to update
|
|
2036
|
-
* this function when we can as part of https://bugs.launchpad.net/gnubook/+bug/296788
|
|
2037
|
-
* @return {number}
|
|
2038
|
-
*/
|
|
2039
|
-
BookReader.prototype.lastDisplayableIndex = function() {
|
|
2040
|
-
|
|
2041
|
-
var lastIndex = this._models.book.getNumLeafs() - 1;
|
|
2042
|
-
|
|
2043
|
-
if (this.mode != this.constMode2up) {
|
|
2044
|
-
return lastIndex;
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
if ('rl' != this.pageProgression) {
|
|
2048
|
-
// LTR
|
|
2049
|
-
if (this._models.book.getPageSide(lastIndex) == 'R') {
|
|
2050
|
-
return lastIndex;
|
|
2051
|
-
} else {
|
|
2052
|
-
return lastIndex + 1;
|
|
2053
|
-
}
|
|
2054
|
-
} else {
|
|
2055
|
-
// RTL
|
|
2056
|
-
if (this._models.book.getPageSide(lastIndex) == 'L') {
|
|
2057
|
-
return lastIndex;
|
|
2058
|
-
} else {
|
|
2059
|
-
return lastIndex + 1;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
};
|
|
2063
|
-
|
|
2064
1569
|
|
|
2065
1570
|
/**************************/
|
|
2066
1571
|
/** BookModel extensions **/
|
|
2067
1572
|
/**************************/
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getMedianPageSize');
|
|
2071
|
-
BookReader.prototype._getPageWidth = BookModel.prototype._getPageWidth;
|
|
2072
|
-
exposeOverrideableMethod(BookModel, '_models.book', '_getPageWidth');
|
|
2073
|
-
BookReader.prototype._getPageHeight = BookModel.prototype._getPageHeight;
|
|
2074
|
-
exposeOverrideableMethod(BookModel, '_models.book', '_getPageHeight');
|
|
2075
|
-
BookReader.prototype.getPageIndex = BookModel.prototype.getPageIndex;
|
|
2076
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageIndex');
|
|
2077
|
-
/** @deprecated not used outside */
|
|
2078
|
-
BookReader.prototype.getPageIndices = BookModel.prototype.getPageIndices;
|
|
2079
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageIndices');
|
|
2080
|
-
BookReader.prototype.getPageName = BookModel.prototype.getPageName;
|
|
2081
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageName');
|
|
2082
|
-
BookReader.prototype.getNumLeafs = BookModel.prototype.getNumLeafs;
|
|
2083
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getNumLeafs');
|
|
2084
|
-
BookReader.prototype.getPageWidth = BookModel.prototype.getPageWidth;
|
|
2085
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageWidth');
|
|
2086
|
-
BookReader.prototype.getPageHeight = BookModel.prototype.getPageHeight;
|
|
2087
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageHeight');
|
|
1573
|
+
// Must modify petabox extension, which expects this on the prototype
|
|
1574
|
+
// before removing.
|
|
2088
1575
|
BookReader.prototype.getPageURI = BookModel.prototype.getPageURI;
|
|
2089
|
-
exposeOverrideableMethod(BookModel, '
|
|
2090
|
-
|
|
2091
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageSide');
|
|
2092
|
-
BookReader.prototype.getPageNum = BookModel.prototype.getPageNum;
|
|
2093
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageNum');
|
|
2094
|
-
BookReader.prototype.getPageProp = BookModel.prototype.getPageProp;
|
|
2095
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getPageProp');
|
|
2096
|
-
BookReader.prototype.getSpreadIndices = BookModel.prototype.getSpreadIndices;
|
|
2097
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'getSpreadIndices');
|
|
2098
|
-
BookReader.prototype.leafNumToIndex = BookModel.prototype.leafNumToIndex;
|
|
2099
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'leafNumToIndex');
|
|
2100
|
-
BookReader.prototype.parsePageString = BookModel.prototype.parsePageString;
|
|
2101
|
-
exposeOverrideableMethod(BookModel, '_models.book', 'parsePageString');
|
|
2102
|
-
/** @deprecated unused */
|
|
2103
|
-
BookReader.prototype._getDataFlattened = BookModel.prototype._getDataFlattened;
|
|
2104
|
-
exposeOverrideableMethod(BookModel, '_models.book', '_getDataFlattened');
|
|
2105
|
-
/** @deprecated unused */
|
|
2106
|
-
BookReader.prototype._getDataProp = BookModel.prototype._getDataProp;
|
|
2107
|
-
exposeOverrideableMethod(BookModel, '_models.book', '_getDataProp');
|
|
1576
|
+
exposeOverrideableMethod(BookModel, 'book', 'getPageURI');
|
|
1577
|
+
|
|
2108
1578
|
|
|
2109
1579
|
// Parameter related functions
|
|
2110
1580
|
|
|
@@ -2123,7 +1593,7 @@ BookReader.prototype.updateFromParams = function(params) {
|
|
|
2123
1593
|
if (mode) {
|
|
2124
1594
|
this.switchMode(
|
|
2125
1595
|
mode,
|
|
2126
|
-
{ init: init, suppressFragmentChange: !fragmentChange }
|
|
1596
|
+
{ init: init, suppressFragmentChange: !fragmentChange },
|
|
2127
1597
|
);
|
|
2128
1598
|
}
|
|
2129
1599
|
|
|
@@ -2135,7 +1605,7 @@ BookReader.prototype.updateFromParams = function(params) {
|
|
|
2135
1605
|
}
|
|
2136
1606
|
} else if ('undefined' != typeof(params.page)) {
|
|
2137
1607
|
// $$$ this assumes page numbers are unique
|
|
2138
|
-
if (params.page != this.
|
|
1608
|
+
if (params.page != this.book.getPageNum(this.currentIndex())) {
|
|
2139
1609
|
this.jumpToPage(params.page);
|
|
2140
1610
|
}
|
|
2141
1611
|
}
|
|
@@ -2144,8 +1614,8 @@ BookReader.prototype.updateFromParams = function(params) {
|
|
|
2144
1614
|
// process /search
|
|
2145
1615
|
// @deprecated for urlMode 'history'
|
|
2146
1616
|
// Continues to work for urlMode 'hash'
|
|
2147
|
-
if (this.
|
|
2148
|
-
if (this.searchTerm !== params.search) {
|
|
1617
|
+
if (this.plugins.search?.enabled && 'undefined' != typeof(params.search)) {
|
|
1618
|
+
if (this.plugins.search.searchTerm !== params.search) {
|
|
2149
1619
|
this.$('.BRsearchInput').val(params.search);
|
|
2150
1620
|
}
|
|
2151
1621
|
}
|
|
@@ -2169,7 +1639,7 @@ BookReader.prototype.canSwitchToMode = function(mode) {
|
|
|
2169
1639
|
// check there are enough pages to display
|
|
2170
1640
|
// $$$ this is a workaround for the mis-feature that we can't display
|
|
2171
1641
|
// short books in 2up mode
|
|
2172
|
-
if (this.
|
|
1642
|
+
if (this.book.getNumLeafs() < 2) {
|
|
2173
1643
|
return false;
|
|
2174
1644
|
}
|
|
2175
1645
|
}
|
|
@@ -2177,31 +1647,6 @@ BookReader.prototype.canSwitchToMode = function(mode) {
|
|
|
2177
1647
|
return true;
|
|
2178
1648
|
};
|
|
2179
1649
|
|
|
2180
|
-
|
|
2181
|
-
/**
|
|
2182
|
-
* @deprecated. Use PageModel.getURISrcSet. Slated for removal in v5.
|
|
2183
|
-
* Returns the srcset with correct URIs or void string if out of range
|
|
2184
|
-
* Also makes the reduce argument optional
|
|
2185
|
-
* @param {number} index
|
|
2186
|
-
* @param {number} [reduce]
|
|
2187
|
-
* @param {number} [rotate]
|
|
2188
|
-
* @return {string}
|
|
2189
|
-
*/
|
|
2190
|
-
BookReader.prototype._getPageURISrcset = function(index, reduce, rotate) {
|
|
2191
|
-
const page = this._models.book.getPage(index, false);
|
|
2192
|
-
// Synthesize page
|
|
2193
|
-
if (!page) return "";
|
|
2194
|
-
|
|
2195
|
-
// reduce not passed in
|
|
2196
|
-
// $$$ this probably won't work for thumbnail mode
|
|
2197
|
-
if ('undefined' == typeof(reduce)) {
|
|
2198
|
-
reduce = page.height / this.twoPage.height;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
return page.getURISrcSet(reduce, rotate);
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
1650
|
/**
|
|
2206
1651
|
* Returns the page URI or transparent image if out of range
|
|
2207
1652
|
* Also makes the reduce argument optional
|
|
@@ -2211,7 +1656,7 @@ BookReader.prototype._getPageURISrcset = function(index, reduce, rotate) {
|
|
|
2211
1656
|
* @return {string}
|
|
2212
1657
|
*/
|
|
2213
1658
|
BookReader.prototype._getPageURI = function(index, reduce, rotate) {
|
|
2214
|
-
const page = this.
|
|
1659
|
+
const page = this.book.getPage(index, false);
|
|
2215
1660
|
// Synthesize page
|
|
2216
1661
|
if (!page) return this.imagesBaseURL + "transparent.png";
|
|
2217
1662
|
|
|
@@ -2225,21 +1670,37 @@ BookReader.prototype._getPageURI = function(index, reduce, rotate) {
|
|
|
2225
1670
|
};
|
|
2226
1671
|
|
|
2227
1672
|
/**
|
|
2228
|
-
* @param {string}
|
|
1673
|
+
* @param {string} msg
|
|
1674
|
+
* @param {function|undefined} onCloseCallback
|
|
2229
1675
|
*/
|
|
2230
|
-
BookReader.prototype.showProgressPopup = function(msg) {
|
|
1676
|
+
BookReader.prototype.showProgressPopup = function(msg, onCloseCallback) {
|
|
2231
1677
|
if (this.popup) return;
|
|
2232
1678
|
|
|
2233
1679
|
this.popup = document.createElement("div");
|
|
2234
1680
|
$(this.popup).prop('className', 'BRprogresspopup');
|
|
2235
|
-
|
|
1681
|
+
|
|
1682
|
+
if (typeof(onCloseCallback) === 'function') {
|
|
1683
|
+
const closeButton = document.createElement('button');
|
|
1684
|
+
closeButton.setAttribute('title', 'close');
|
|
1685
|
+
closeButton.setAttribute('class', 'close-popup');
|
|
1686
|
+
const icon = document.createElement('span');
|
|
1687
|
+
icon.setAttribute('class', 'icon icon-close-dark');
|
|
1688
|
+
$(closeButton).append(icon);
|
|
1689
|
+
closeButton.addEventListener('click', () => {
|
|
1690
|
+
onCloseCallback();
|
|
1691
|
+
this.removeProgressPopup();
|
|
1692
|
+
});
|
|
1693
|
+
$(this.popup).append(closeButton);
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
const bar = document.createElement("div");
|
|
2236
1697
|
$(bar).css({
|
|
2237
|
-
height: '20px'
|
|
1698
|
+
height: '20px',
|
|
2238
1699
|
}).prop('className', 'BRprogressbar');
|
|
2239
1700
|
$(this.popup).append(bar);
|
|
2240
1701
|
|
|
2241
1702
|
if (msg) {
|
|
2242
|
-
|
|
1703
|
+
const msgdiv = document.createElement("div");
|
|
2243
1704
|
msgdiv.innerHTML = msg;
|
|
2244
1705
|
$(this.popup).append(msgdiv);
|
|
2245
1706
|
}
|
|
@@ -2261,7 +1722,7 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2261
1722
|
// the toolbar and nav bar easier
|
|
2262
1723
|
|
|
2263
1724
|
// Setup tooltips -- later we could load these from a file for i18n
|
|
2264
|
-
|
|
1725
|
+
const titles = {
|
|
2265
1726
|
'.logo': 'Go to Archive.org', // $$$ update after getting OL record
|
|
2266
1727
|
'.zoom_in': 'Zoom in',
|
|
2267
1728
|
'.zoom_out': 'Zoom out',
|
|
@@ -2274,15 +1735,12 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2274
1735
|
'.bookmark': 'Bookmark this page',
|
|
2275
1736
|
'.share': 'Share this book',
|
|
2276
1737
|
'.info': 'About this book',
|
|
2277
|
-
'.full': '
|
|
1738
|
+
'.full': 'Go fullscreen',
|
|
1739
|
+
'.toggle_slider': 'Toggle page controls',
|
|
2278
1740
|
'.book_left': 'Flip left',
|
|
2279
1741
|
'.book_right': 'Flip right',
|
|
2280
|
-
'.book_up': 'Page up',
|
|
2281
|
-
'.book_down': 'Page down',
|
|
2282
1742
|
'.play': 'Play',
|
|
2283
1743
|
'.pause': 'Pause',
|
|
2284
|
-
'.BRdn': 'Show/hide nav bar', // Would have to keep updating on state change to have just "Hide nav bar"
|
|
2285
|
-
'.BRup': 'Show/hide nav bar',
|
|
2286
1744
|
'.book_top': 'First page',
|
|
2287
1745
|
'.book_bottom': 'Last page',
|
|
2288
1746
|
'.book_leftmost': 'First page',
|
|
@@ -2293,10 +1751,10 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2293
1751
|
titles['.book_rightmost'] = 'First page';
|
|
2294
1752
|
}
|
|
2295
1753
|
|
|
2296
|
-
for (
|
|
1754
|
+
for (const icon in titles) {
|
|
2297
1755
|
this.$(icon).prop('title', titles[icon]);
|
|
2298
1756
|
}
|
|
2299
|
-
}
|
|
1757
|
+
};
|
|
2300
1758
|
|
|
2301
1759
|
/**
|
|
2302
1760
|
* Reloads images. Useful when some images might have failed.
|
|
@@ -2304,7 +1762,7 @@ BookReader.prototype.initUIStrings = function() {
|
|
|
2304
1762
|
BookReader.prototype.reloadImages = function() {
|
|
2305
1763
|
this.refs.$brContainer.find('img').each(function(index, elem) {
|
|
2306
1764
|
if (!elem.complete || elem.naturalHeight === 0) {
|
|
2307
|
-
|
|
1765
|
+
const src = elem.src;
|
|
2308
1766
|
elem.src = '';
|
|
2309
1767
|
setTimeout(function() {
|
|
2310
1768
|
elem.src = src;
|
|
@@ -2318,16 +1776,16 @@ BookReader.prototype.reloadImages = function() {
|
|
|
2318
1776
|
* @return {number}
|
|
2319
1777
|
*/
|
|
2320
1778
|
BookReader.prototype.getFooterHeight = function() {
|
|
2321
|
-
|
|
1779
|
+
const $heightEl = this.mode == this.constMode2up ? this.refs.$BRfooter : this.refs.$BRnav;
|
|
2322
1780
|
if ($heightEl && this.refs.$BRfooter) {
|
|
2323
|
-
|
|
2324
|
-
|
|
1781
|
+
const outerHeight = $heightEl.outerHeight();
|
|
1782
|
+
const bottom = parseInt(this.refs.$BRfooter.css('bottom'));
|
|
2325
1783
|
if (!isNaN(outerHeight) && !isNaN(bottom)) {
|
|
2326
1784
|
return outerHeight + bottom;
|
|
2327
1785
|
}
|
|
2328
1786
|
}
|
|
2329
1787
|
return 0;
|
|
2330
|
-
}
|
|
1788
|
+
};
|
|
2331
1789
|
|
|
2332
1790
|
// Basic Usage built-in Methods (can be overridden through options)
|
|
2333
1791
|
// This implementation uses options.data value for populating BookReader
|
|
@@ -2337,10 +1795,11 @@ BookReader.prototype.getFooterHeight = function() {
|
|
|
2337
1795
|
* @return {Object}
|
|
2338
1796
|
*/
|
|
2339
1797
|
BookReader.prototype.paramsFromCurrent = function() {
|
|
2340
|
-
|
|
1798
|
+
const params = {};
|
|
2341
1799
|
|
|
2342
|
-
|
|
2343
|
-
|
|
1800
|
+
// Path params
|
|
1801
|
+
const index = this.currentIndex();
|
|
1802
|
+
const pageNum = this.book.getPageNum(index);
|
|
2344
1803
|
if ((pageNum === 0) || pageNum) {
|
|
2345
1804
|
params.page = pageNum;
|
|
2346
1805
|
}
|
|
@@ -2348,12 +1807,19 @@ BookReader.prototype.paramsFromCurrent = function() {
|
|
|
2348
1807
|
params.index = index;
|
|
2349
1808
|
params.mode = this.mode;
|
|
2350
1809
|
|
|
1810
|
+
// Unused params
|
|
2351
1811
|
// $$$ highlight
|
|
2352
1812
|
// $$$ region
|
|
2353
1813
|
|
|
2354
|
-
//
|
|
2355
|
-
|
|
2356
|
-
|
|
1814
|
+
// Querystring params
|
|
1815
|
+
// View
|
|
1816
|
+
const fullscreenView = 'theater';
|
|
1817
|
+
if (this.isFullscreenActive) {
|
|
1818
|
+
params.view = fullscreenView;
|
|
1819
|
+
}
|
|
1820
|
+
// Search
|
|
1821
|
+
if (this.plugins.search?.enabled) {
|
|
1822
|
+
params.search = this.plugins.search.searchTerm;
|
|
2357
1823
|
}
|
|
2358
1824
|
|
|
2359
1825
|
return params;
|
|
@@ -2372,7 +1838,7 @@ BookReader.prototype.paramsFromCurrent = function() {
|
|
|
2372
1838
|
* @return {Object}
|
|
2373
1839
|
*/
|
|
2374
1840
|
BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
2375
|
-
|
|
1841
|
+
const params = {};
|
|
2376
1842
|
|
|
2377
1843
|
// For backwards compatibility we allow an initial # character
|
|
2378
1844
|
// (as from window.location.hash) but don't require it
|
|
@@ -2381,7 +1847,7 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2381
1847
|
}
|
|
2382
1848
|
|
|
2383
1849
|
// Simple #nn syntax
|
|
2384
|
-
|
|
1850
|
+
const oldStyleLeafNum = parseInt( /^\d+$/.exec(fragment) );
|
|
2385
1851
|
if ( !isNaN(oldStyleLeafNum) ) {
|
|
2386
1852
|
params.index = oldStyleLeafNum;
|
|
2387
1853
|
|
|
@@ -2390,9 +1856,9 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2390
1856
|
}
|
|
2391
1857
|
|
|
2392
1858
|
// Split into key-value pairs
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
for (
|
|
1859
|
+
const urlArray = fragment.split('/');
|
|
1860
|
+
const urlHash = {};
|
|
1861
|
+
for (let i = 0; i < urlArray.length; i += 2) {
|
|
2396
1862
|
urlHash[urlArray[i]] = urlArray[i + 1];
|
|
2397
1863
|
}
|
|
2398
1864
|
|
|
@@ -2408,7 +1874,7 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2408
1874
|
// Index and page
|
|
2409
1875
|
if ('undefined' != typeof(urlHash['page'])) {
|
|
2410
1876
|
// page was set -- may not be int
|
|
2411
|
-
params.page = urlHash['page'];
|
|
1877
|
+
params.page = decodeURIComponent(urlHash['page']);
|
|
2412
1878
|
}
|
|
2413
1879
|
|
|
2414
1880
|
// $$$ process /region
|
|
@@ -2422,7 +1888,7 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2422
1888
|
|
|
2423
1889
|
// $$$ process /theme
|
|
2424
1890
|
if (urlHash['theme'] != undefined) {
|
|
2425
|
-
params.theme = urlHash['theme']
|
|
1891
|
+
params.theme = urlHash['theme'];
|
|
2426
1892
|
}
|
|
2427
1893
|
return params;
|
|
2428
1894
|
};
|
|
@@ -2440,11 +1906,10 @@ BookReader.prototype.paramsFromFragment = function(fragment) {
|
|
|
2440
1906
|
* @return {string}
|
|
2441
1907
|
*/
|
|
2442
1908
|
BookReader.prototype.fragmentFromParams = function(params, urlMode = 'hash') {
|
|
2443
|
-
const separator = '/';
|
|
2444
1909
|
const fragments = [];
|
|
2445
1910
|
|
|
2446
1911
|
if ('undefined' != typeof(params.page)) {
|
|
2447
|
-
fragments.push('page', params.page);
|
|
1912
|
+
fragments.push('page', encodeURIComponent(params.page));
|
|
2448
1913
|
} else {
|
|
2449
1914
|
if ('undefined' != typeof(params.index)) {
|
|
2450
1915
|
// Don't have page numbering but we do have the index
|
|
@@ -2470,15 +1935,18 @@ BookReader.prototype.fragmentFromParams = function(params, urlMode = 'hash') {
|
|
|
2470
1935
|
|
|
2471
1936
|
// search
|
|
2472
1937
|
if (params.search && urlMode === 'hash') {
|
|
2473
|
-
fragments.push('search', params.search);
|
|
1938
|
+
fragments.push('search', utils.encodeURIComponentPlus(params.search));
|
|
2474
1939
|
}
|
|
2475
1940
|
|
|
2476
|
-
return
|
|
1941
|
+
return fragments.join('/');
|
|
2477
1942
|
};
|
|
2478
1943
|
|
|
2479
1944
|
/**
|
|
2480
1945
|
* Create, update querystring from the params object
|
|
2481
1946
|
*
|
|
1947
|
+
* Handles:
|
|
1948
|
+
* view=
|
|
1949
|
+
* q=
|
|
2482
1950
|
* @param {Object} params
|
|
2483
1951
|
* @param {string} currQueryString
|
|
2484
1952
|
* @param {string} [urlMode]
|
|
@@ -2487,30 +1955,32 @@ BookReader.prototype.fragmentFromParams = function(params, urlMode = 'hash') {
|
|
|
2487
1955
|
BookReader.prototype.queryStringFromParams = function(
|
|
2488
1956
|
params,
|
|
2489
1957
|
currQueryString,
|
|
2490
|
-
urlMode = 'hash'
|
|
1958
|
+
urlMode = 'hash',
|
|
2491
1959
|
) {
|
|
2492
1960
|
const newParams = new URLSearchParams(currQueryString);
|
|
1961
|
+
|
|
1962
|
+
if (params.view) {
|
|
1963
|
+
// Set ?view=theater when fullscreen
|
|
1964
|
+
newParams.set('view', params.view);
|
|
1965
|
+
} else {
|
|
1966
|
+
// Remove
|
|
1967
|
+
newParams.delete('view');
|
|
1968
|
+
}
|
|
1969
|
+
|
|
2493
1970
|
if (params.search && urlMode === 'history') {
|
|
2494
|
-
newParams.set('q', params.search)
|
|
1971
|
+
newParams.set('q', params.search);
|
|
2495
1972
|
}
|
|
2496
1973
|
// https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/toString
|
|
2497
1974
|
// Note: This method returns the query string without the question mark.
|
|
2498
1975
|
const result = newParams.toString();
|
|
2499
1976
|
return result ? '?' + result : '';
|
|
2500
|
-
}
|
|
1977
|
+
};
|
|
2501
1978
|
|
|
2502
1979
|
/**
|
|
2503
1980
|
* Helper to select within instance's elements
|
|
2504
1981
|
*/
|
|
2505
1982
|
BookReader.prototype.$ = function(selector) {
|
|
2506
1983
|
return this.refs.$br.find(selector);
|
|
2507
|
-
}
|
|
2508
|
-
|
|
2509
|
-
/**
|
|
2510
|
-
* Polyfill for deprecated method
|
|
2511
|
-
*/
|
|
2512
|
-
jQuery.curCSS = function(element, prop, val) {
|
|
2513
|
-
return jQuery(element).css(prop, val);
|
|
2514
1984
|
};
|
|
2515
1985
|
|
|
2516
1986
|
window.BookReader = BookReader;
|