@internetarchive/bookreader 5.0.0-11 → 5.0.0-111
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 +649 -1225
- package/BookReader/BookReader.js +1 -1
- 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 +1904 -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 -1
- package/BookReader/icons/2up.svg +1 -1
- package/BookReader/icons/advance.svg +1 -1
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -1
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -1
- package/BookReader/icons/fullscreen_exit.svg +1 -1
- package/BookReader/icons/hamburger.svg +1 -1
- package/BookReader/icons/left-arrow.svg +1 -1
- package/BookReader/icons/magnify-minus.svg +1 -1
- package/BookReader/icons/magnify-plus.svg +1 -1
- package/BookReader/icons/magnify.svg +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/play.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/icons/review.svg +1 -1
- package/BookReader/icons/slider-toggle.svg +1 -0
- package/BookReader/icons/thumbnails.svg +1 -1
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -1
- package/BookReader/images/BRicons.svg +3 -3
- package/BookReader/images/books_graphic.svg +1 -1
- package/BookReader/images/hypothesis.ico +0 -0
- package/BookReader/images/icon_book.svg +1 -1
- package/BookReader/images/icon_bookmark.svg +1 -1
- package/BookReader/images/icon_experiment.svg +1 -0
- package/BookReader/images/icon_gear.svg +1 -1
- package/BookReader/images/icon_hamburger.svg +1 -1
- package/BookReader/images/icon_home.svg +1 -1
- package/BookReader/images/icon_info.svg +1 -1
- package/BookReader/images/icon_one_page.svg +1 -1
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.svg +1 -1
- package/BookReader/images/icon_playback-rate.svg +1 -1
- package/BookReader/images/icon_search_button.svg +1 -1
- package/BookReader/images/icon_share.svg +1 -1
- package/BookReader/images/icon_skip-ahead.svg +1 -1
- package/BookReader/images/icon_skip-back.svg +1 -1
- package/BookReader/images/icon_speaker.svg +1 -1
- package/BookReader/images/icon_speaker_open.svg +1 -1
- package/BookReader/images/icon_thumbnails.svg +1 -1
- package/BookReader/images/icon_toc.svg +1 -1
- package/BookReader/images/icon_two_pages.svg +1 -1
- package/BookReader/images/marker_chap-off.svg +1 -1
- package/BookReader/images/marker_chap-on.svg +1 -1
- package/BookReader/images/marker_srch-on.svg +1 -1
- 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 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +22 -1
- 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 -1
- 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 -1
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +2 -1
- 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 +24 -1
- 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 +159 -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 +1 -1
- 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 +2 -1
- package/BookReader/plugins/plugin.url.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
- 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 +93 -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 -365
- package/src/BookReader/Mode1UpLit.js +392 -0
- package/src/BookReader/Mode2Up.js +87 -1315
- package/src/BookReader/Mode2UpLit.js +786 -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 +29 -15
- package/src/BookReader/Navbar/Navbar.js +201 -76
- package/src/BookReader/PageContainer.js +120 -23
- package/src/BookReader/ReduceSet.js +2 -2
- package/src/BookReader/Toolbar/Toolbar.js +18 -40
- 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 +53 -0
- package/src/BookReader/utils/classes.js +1 -1
- package/src/BookReader/utils.js +136 -12
- package/src/BookReader.js +695 -1228
- package/src/BookReaderPlugin.js +52 -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 -5
- 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 +16 -3
- package/src/css/_BRnav.scss +74 -70
- package/src/css/_BRpages.scss +171 -42
- package/src/css/_BRsearch.scss +69 -30
- package/src/css/_BRtoolbar.scss +5 -5
- package/src/css/_TextSelection.scss +188 -24
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +24 -7
- package/src/css/_icons.scss +8 -1
- package/src/{BookNavigator/assets → css}/button-base.js +2 -2
- 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 +25 -5
- 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 +43 -31
- package/src/{BookNavigator → plugins}/bookmarks/bookmarks-list.js +48 -49
- package/src/{BookNavigator → plugins}/bookmarks/bookmarks-loginCTA.js +3 -3
- 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 +319 -205
- package/src/plugins/plugin.experiments.js +339 -0
- package/src/plugins/plugin.iframe.js +1 -1
- package/src/plugins/plugin.iiif.js +141 -0
- package/src/plugins/plugin.resume.js +54 -51
- package/src/plugins/plugin.text_selection.js +539 -219
- package/src/plugins/plugin.vendor-fullscreen.js +5 -5
- package/src/plugins/search/plugin.search.js +374 -392
- package/src/{BookNavigator → plugins}/search/search-provider.js +59 -27
- package/src/{BookNavigator → plugins}/search/search-results.js +105 -76
- package/src/plugins/search/utils.js +50 -0
- package/src/plugins/search/view.js +50 -68
- 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 +20 -30
- 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 +211 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +105 -20
- package/src/util/TextSelectionManager.js +532 -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 -50
- 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 -37
- package/.github/workflows/npm-publish.yml +0 -47
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -1450
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/jquery-1.10.1.js +0 -2
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -2
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReader/plugins/plugin.mobile_nav.js +0 -2
- 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 -495
- 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 -446
- 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/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/BookReader/DebugConsole.js +0 -54
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -376
- package/src/ItemNavigator/providers/sharing.js +0 -29
- 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 -263
- 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/search-provider.test.js +0 -23
- package/tests/karma/BookNavigator/search/search-results.test.js +0 -240
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- 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 -173
- 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/plugins/tts/utils.js
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Convert a EventTarget style event into a promise
|
|
5
|
-
* @param {EventTarget} target
|
|
6
|
-
* @param {string} eventType
|
|
7
|
-
* @return {Promise<Event>}
|
|
8
|
-
*/
|
|
9
|
-
export function promisifyEvent(target, eventType) {
|
|
10
|
-
return new Promise(res => {
|
|
11
|
-
const resolver = ev => {
|
|
12
|
-
target.removeEventListener(eventType, resolver);
|
|
13
|
-
res(ev);
|
|
14
|
-
};
|
|
15
|
-
target.addEventListener(eventType, resolver);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
1
|
+
// @ts-check
|
|
2
|
+
import langs from 'iso-language-codes';
|
|
18
3
|
|
|
19
4
|
/**
|
|
20
5
|
* Use regex to approximate word count in a string
|
|
@@ -26,15 +11,6 @@ export function approximateWordCount(text) {
|
|
|
26
11
|
return m ? m.length : 0;
|
|
27
12
|
}
|
|
28
13
|
|
|
29
|
-
/**
|
|
30
|
-
* Waits the provided number of ms and then resolves with a promise
|
|
31
|
-
* @param {number} ms
|
|
32
|
-
* @return {Promise}
|
|
33
|
-
*/
|
|
34
|
-
export function sleep(ms) {
|
|
35
|
-
return new Promise(res => setTimeout(res, ms));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
14
|
/**
|
|
39
15
|
* Checks whether the current browser is on android
|
|
40
16
|
* @param {string} [userAgent]
|
|
@@ -44,48 +20,100 @@ export function isAndroid(userAgent = navigator.userAgent) {
|
|
|
44
20
|
return /android/i.test(userAgent);
|
|
45
21
|
}
|
|
46
22
|
|
|
23
|
+
/** @type {{[lang: string]: string}} */
|
|
24
|
+
// Handle odd one-off language pairs that might show up over time
|
|
25
|
+
const specialLangs = {
|
|
26
|
+
"zh-hans": "中文 (Zhōngwén)",
|
|
27
|
+
};
|
|
28
|
+
|
|
47
29
|
/**
|
|
48
30
|
* @typedef {string} ISO6391
|
|
49
31
|
* Language code in ISO 639-1 format. e.g. en, fr, zh
|
|
50
32
|
**/
|
|
51
33
|
|
|
52
|
-
/** Each lang is an array, with each index mapping to a different property */
|
|
53
|
-
const COLUMN_TO_LANG_INDEX = {
|
|
54
|
-
'Name': 0,
|
|
55
|
-
'Endonym': 1,
|
|
56
|
-
'ISO 639-1': 2,
|
|
57
|
-
'ISO 639-2/T': 3,
|
|
58
|
-
'ISO 639-2/B': 4
|
|
59
|
-
};
|
|
60
|
-
|
|
61
34
|
/**
|
|
62
35
|
* @param {string} language in some format
|
|
63
36
|
* @return {ISO6391?}
|
|
64
37
|
*/
|
|
65
38
|
export function toISO6391(language) {
|
|
66
39
|
if (!language) return null;
|
|
67
|
-
language = language.
|
|
40
|
+
language = language.toLocaleLowerCase();
|
|
41
|
+
if (specialLangs[language]) {
|
|
42
|
+
return language;
|
|
43
|
+
}
|
|
44
|
+
const codeObj = (
|
|
45
|
+
findLanguage(language, ['iso639_1']) ||
|
|
46
|
+
findLanguage(language, ['iso639_2T']) ||
|
|
47
|
+
findLanguage(language, ['iso639_2B', 'name', 'nativeName'])
|
|
48
|
+
);
|
|
49
|
+
if (codeObj) return codeObj.iso639_1;
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
68
52
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @param {string} language
|
|
56
|
+
* @returns {string}
|
|
57
|
+
*/
|
|
58
|
+
export function toNativeName(language) {
|
|
59
|
+
if (!language) return null;
|
|
60
|
+
language = language.toLocaleLowerCase();
|
|
61
|
+
if (specialLangs[language]) {
|
|
62
|
+
return specialLangs[language];
|
|
63
|
+
}
|
|
64
|
+
const codeObj = (
|
|
65
|
+
findLanguage(language, ['iso639_1']) ||
|
|
66
|
+
findLanguage(language, ['iso639_2T']) ||
|
|
67
|
+
findLanguage(language, ['iso639_2B', 'name', 'nativeName'])
|
|
68
|
+
);
|
|
69
|
+
if (codeObj?.nativeName) return codeObj.nativeName.split(", ")[0];
|
|
70
|
+
return null;
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
/** @typedef {import('iso-language-codes').Code} Code */
|
|
74
|
+
|
|
74
75
|
/**
|
|
75
|
-
* Searches for the given long in the given columns.
|
|
76
76
|
* @param {string} language
|
|
77
|
-
* @param {Array<
|
|
78
|
-
* @
|
|
77
|
+
* @param {Array<'iso639_1' | 'iso639_2T' | 'iso639_2B' | 'nativeName' | 'name'>} fields
|
|
78
|
+
* @returns {Code | null}
|
|
79
79
|
*/
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
return
|
|
80
|
+
function findLanguage(language, fields) {
|
|
81
|
+
if (!language) return null;
|
|
82
|
+
language = language.toLowerCase();
|
|
83
|
+
for (const lang of langs) {
|
|
84
|
+
for (const codeType of fields) {
|
|
85
|
+
if (lang[codeType]?.toLowerCase().split(", ").includes(language)) {
|
|
86
|
+
return lang;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
return null;
|
|
91
91
|
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Checks whether the current browser supports localStorage or
|
|
95
|
+
* if the current context has access to it.
|
|
96
|
+
* @return {boolean}
|
|
97
|
+
*/
|
|
98
|
+
export function hasLocalStorage() {
|
|
99
|
+
try {
|
|
100
|
+
return !!window.localStorage;
|
|
101
|
+
} catch (e) {
|
|
102
|
+
// Will throw in sandboxed iframe
|
|
103
|
+
// DOMException: Window.localStorage getter: Forbidden in a sandboxed document without the 'allow-same-origin' flag.
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const DEBUG_READ_ALOUD = location.toString().indexOf('_debugReadAloud=true') != -1;
|
|
109
|
+
|
|
110
|
+
export async function checkIfFiresPause() {
|
|
111
|
+
// Pick some random text so that if it accidentally speaks, it's not too annoying
|
|
112
|
+
const u = new SpeechSynthesisUtterance("Loading");
|
|
113
|
+
let calledPause = false;
|
|
114
|
+
u.addEventListener('pause', () => calledPause = true);
|
|
115
|
+
speechSynthesis.speak(u);
|
|
116
|
+
await new Promise(res => setTimeout(res, 10));
|
|
117
|
+
speechSynthesis.pause();
|
|
118
|
+
return calledPause;
|
|
119
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
export class UrlPlugin {
|
|
2
|
+
constructor(options = {}) {
|
|
3
|
+
this.bookReaderOptions = options;
|
|
4
|
+
|
|
5
|
+
// the canonical order of elements is important in the path and query string
|
|
6
|
+
this.urlSchema = [
|
|
7
|
+
{ name: 'page', position: 'path', default: 'n0' },
|
|
8
|
+
{ name: 'mode', position: 'path', default: '2up' },
|
|
9
|
+
{ name: 'search', position: 'path', deprecated_for: 'q' },
|
|
10
|
+
{ name: 'q', position: 'query_param' },
|
|
11
|
+
{ name: 'sort', position: 'query_param' },
|
|
12
|
+
{ name: 'view', position: 'query_param' },
|
|
13
|
+
{ name: 'admin', position: 'query_param' },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
this.urlState = {};
|
|
17
|
+
this.urlMode = this.bookReaderOptions.urlMode || 'hash';
|
|
18
|
+
this.urlHistoryBasePath = this.bookReaderOptions.urlHistoryBasePath || '/';
|
|
19
|
+
this.urlLocationPollId = null;
|
|
20
|
+
this.oldLocationHash = null;
|
|
21
|
+
this.oldUserHash = null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parse JSON object URL state to string format
|
|
26
|
+
* Arrange path names in an order that it is positioned on the urlSchema
|
|
27
|
+
* @param {Object} urlState
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
30
|
+
urlStateToUrlString(urlState) {
|
|
31
|
+
const searchParams = new URLSearchParams();
|
|
32
|
+
const pathParams = {};
|
|
33
|
+
|
|
34
|
+
Object.keys(urlState).forEach(key => {
|
|
35
|
+
let schema = this.urlSchema.find(schema => schema.name === key);
|
|
36
|
+
if (schema?.deprecated_for) {
|
|
37
|
+
schema = this.urlSchema.find(schemaKey => schemaKey.name === schema.deprecated_for);
|
|
38
|
+
}
|
|
39
|
+
if (schema?.position == 'path') {
|
|
40
|
+
pathParams[schema?.name] = urlState[key];
|
|
41
|
+
} else {
|
|
42
|
+
searchParams.append(schema?.name || key, urlState[key]);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const strPathParams = this.urlSchema
|
|
47
|
+
.filter(s => s.position == 'path')
|
|
48
|
+
.map(schema => pathParams[schema.name] ? `${schema.name}/${encodeURIComponent(pathParams[schema.name])}` : '')
|
|
49
|
+
.join('/');
|
|
50
|
+
|
|
51
|
+
// replace consecutive slashes with a single slash + remove trailing slashes
|
|
52
|
+
const strStrippedTrailingSlash = `${strPathParams.replace(/\/+/g, '/').replace(/\/+$/, '')}`;
|
|
53
|
+
const concatenatedPath = `${strStrippedTrailingSlash}?${searchParams.toString()}`;
|
|
54
|
+
return searchParams.toString() ? concatenatedPath : `${strStrippedTrailingSlash}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parse string URL and add it in the current urlState
|
|
59
|
+
* Example:
|
|
60
|
+
* /page/n7/mode/2up => {page: 'n7', mode: '2up'}
|
|
61
|
+
* /page/n7/mode/2up/search/hello => {page: 'n7', mode: '2up', q: 'hello'}
|
|
62
|
+
* @param {string} urlString
|
|
63
|
+
* @returns {object}
|
|
64
|
+
*/
|
|
65
|
+
urlStringToUrlState(urlString) {
|
|
66
|
+
const urlState = {};
|
|
67
|
+
|
|
68
|
+
// Fetch searchParams from given {str}
|
|
69
|
+
// Note: whole URL path is needed for URL parsing
|
|
70
|
+
const urlPath = new URL(urlString, 'http://example.com');
|
|
71
|
+
const urlSearchParamsObj = Object.fromEntries(urlPath.searchParams.entries());
|
|
72
|
+
const splitUrlMatches = urlPath.pathname.match(/[^\\/]+\/[^\\/]+/g);
|
|
73
|
+
const urlStrSplitSlashObj = splitUrlMatches ? Object.fromEntries(splitUrlMatches.map(x => x.split('/'))) : {};
|
|
74
|
+
|
|
75
|
+
const doesKeyExists = (_object, _key) => {
|
|
76
|
+
return Object.keys(_object).some(value => value == _key);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Add path objects to urlState
|
|
80
|
+
this.urlSchema
|
|
81
|
+
.filter(schema => schema.position == 'path')
|
|
82
|
+
.forEach(schema => {
|
|
83
|
+
const hasPropertyKey = doesKeyExists(urlStrSplitSlashObj, schema.name);
|
|
84
|
+
const hasDeprecatedKey = doesKeyExists(schema, 'deprecated_for') && hasPropertyKey;
|
|
85
|
+
|
|
86
|
+
// Not in the URL
|
|
87
|
+
if (!hasPropertyKey && !hasDeprecatedKey) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const urlStateParam = hasDeprecatedKey ? schema.deprecated_for : schema.name;
|
|
92
|
+
urlState[urlStateParam] = decodeURIComponent(urlStrSplitSlashObj[schema.name]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Add searchParams to urlState
|
|
96
|
+
Object.entries(urlSearchParamsObj).forEach(([key, value]) => {
|
|
97
|
+
urlState[key] = value;
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return urlState;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Add or update key-value to the urlState
|
|
105
|
+
* @param {string} key
|
|
106
|
+
* @param {string} val
|
|
107
|
+
*/
|
|
108
|
+
setUrlParam(key, value) {
|
|
109
|
+
this.urlState[key] = value;
|
|
110
|
+
|
|
111
|
+
this.pushToAddressBar();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Delete key-value to the urlState
|
|
116
|
+
* @param {string} key
|
|
117
|
+
*/
|
|
118
|
+
removeUrlParam(key) {
|
|
119
|
+
delete this.urlState[key];
|
|
120
|
+
|
|
121
|
+
this.pushToAddressBar();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get key-value from the urlState
|
|
126
|
+
* @param {string} key
|
|
127
|
+
* @return {string}
|
|
128
|
+
*/
|
|
129
|
+
getUrlParam(key) {
|
|
130
|
+
return this.urlState[key];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Push URL params to addressbar
|
|
135
|
+
*/
|
|
136
|
+
pushToAddressBar() {
|
|
137
|
+
const urlStrPath = this.urlStateToUrlString(this.urlState);
|
|
138
|
+
const concatenatedPath = urlStrPath !== '/' ? urlStrPath : '';
|
|
139
|
+
if (this.urlMode == 'history') {
|
|
140
|
+
if (!window.history || !window.history.replaceState) {
|
|
141
|
+
this.options.urlMode = 'hash';
|
|
142
|
+
} else {
|
|
143
|
+
const newUrlPath = `${this.urlHistoryBasePath}${concatenatedPath}`.trim().replace(/(\/+)/g, '/');
|
|
144
|
+
try {
|
|
145
|
+
window.history.replaceState({}, null, newUrlPath);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
// DOMException on Chrome when in sandboxed iframe
|
|
148
|
+
this.urlMode = 'hash';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (this.urlMode == 'hash') {
|
|
154
|
+
window.location.replace('#' + concatenatedPath);
|
|
155
|
+
}
|
|
156
|
+
this.oldLocationHash = urlStrPath;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get the url and check if it has changed
|
|
161
|
+
* If it was changeed, update the urlState
|
|
162
|
+
*/
|
|
163
|
+
listenForHashChanges() {
|
|
164
|
+
this.oldLocationHash = this.getHash();
|
|
165
|
+
if (this.urlLocationPollId) {
|
|
166
|
+
clearInterval(this.urlLocationPollId);
|
|
167
|
+
this.urlLocationPollId = null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// check if the URL changes
|
|
171
|
+
const updateHash = () => {
|
|
172
|
+
const newFragment = this.getHash();
|
|
173
|
+
const hasFragmentChange = newFragment != this.oldLocationHash;
|
|
174
|
+
|
|
175
|
+
if (!hasFragmentChange) { return; }
|
|
176
|
+
|
|
177
|
+
this.urlState = this.urlStringToUrlState(newFragment);
|
|
178
|
+
};
|
|
179
|
+
this.urlLocationPollId = setInterval(updateHash, 500);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Will read either the hash or URL and return the bookreader fragment
|
|
184
|
+
*/
|
|
185
|
+
pullFromAddressBar(location = window.location) {
|
|
186
|
+
const path = this.urlMode === 'history'
|
|
187
|
+
? (location.pathname.substr(this.urlHistoryBasePath.length) + location.search)
|
|
188
|
+
: location.hash.substr(1);
|
|
189
|
+
this.urlState = this.urlStringToUrlState(path);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get the hash out of the current URL. Also augments it with the text
|
|
194
|
+
* from the main part of the URL, since that is not readable by JS
|
|
195
|
+
* from the actual hash
|
|
196
|
+
* @returns
|
|
197
|
+
*/
|
|
198
|
+
getHash() {
|
|
199
|
+
const text = this.retrieveTextFragment(window.location.search);
|
|
200
|
+
const textFragment = text ? `:~:text=${text[0]}` : '';
|
|
201
|
+
return `${window.location.hash.slice(1)}${textFragment}`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @param {string} urlString
|
|
206
|
+
* @returns {string}
|
|
207
|
+
*/
|
|
208
|
+
retrieveTextFragment(urlString) {
|
|
209
|
+
return urlString.match(/(?<=[&?]?text=)[^&]*/);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/* global BookReader */
|
|
2
|
+
|
|
3
|
+
import { UrlPlugin } from "./UrlPlugin.js";
|
|
4
|
+
import { sleep } from "../../BookReader/utils.js";
|
|
5
|
+
|
|
2
6
|
/**
|
|
3
7
|
* Plugin for URL management in BookReader
|
|
4
8
|
* Note read more about the url "fragment" here:
|
|
@@ -22,7 +26,7 @@ jQuery.extend(BookReader.defaultOptions, {
|
|
|
22
26
|
urlHistoryBasePath: '/',
|
|
23
27
|
|
|
24
28
|
/** Only these params will be reflected onto the URL */
|
|
25
|
-
urlTrackedParams: ['page', 'search', 'mode', 'region', 'highlight'],
|
|
29
|
+
urlTrackedParams: ['page', 'search', 'mode', 'region', 'highlight', 'view', 'text'],
|
|
26
30
|
|
|
27
31
|
/** If true, don't update the URL when `page == n0 (eg "/page/n0")` */
|
|
28
32
|
urlTrackIndex0: false,
|
|
@@ -39,6 +43,10 @@ BookReader.prototype.setup = (function(super_) {
|
|
|
39
43
|
this.locationPollId = null;
|
|
40
44
|
this.oldLocationHash = null;
|
|
41
45
|
this.oldUserHash = null;
|
|
46
|
+
// Should include the :~:text= prefix
|
|
47
|
+
this.textFragment = null;
|
|
48
|
+
// Tracks the original textFragment page num when first loaded
|
|
49
|
+
this.textFragmentPage = null;
|
|
42
50
|
};
|
|
43
51
|
})(BookReader.prototype.setup);
|
|
44
52
|
|
|
@@ -50,7 +58,7 @@ BookReader.prototype.init = (function(super_) {
|
|
|
50
58
|
this.bind(BookReader.eventNames.PostInit, () => {
|
|
51
59
|
const { updateWindowTitle, urlMode } = this.options;
|
|
52
60
|
if (updateWindowTitle) {
|
|
53
|
-
document.title = this.shortTitle(50);
|
|
61
|
+
document.title = this.shortTitle(this.bookTitle, 50);
|
|
54
62
|
}
|
|
55
63
|
if (urlMode === 'hash') {
|
|
56
64
|
this.urlStartLocationPolling();
|
|
@@ -58,7 +66,7 @@ BookReader.prototype.init = (function(super_) {
|
|
|
58
66
|
});
|
|
59
67
|
|
|
60
68
|
this.bind(BookReader.eventNames.fragmentChange,
|
|
61
|
-
this.urlUpdateFragment.bind(this)
|
|
69
|
+
this.urlUpdateFragment.bind(this),
|
|
62
70
|
);
|
|
63
71
|
}
|
|
64
72
|
super_.call(this);
|
|
@@ -86,7 +94,7 @@ BookReader.prototype.urlStartLocationPolling = function() {
|
|
|
86
94
|
this.oldLocationHash = this.urlReadFragment();
|
|
87
95
|
|
|
88
96
|
if (this.locationPollId) {
|
|
89
|
-
clearInterval(this.
|
|
97
|
+
clearInterval(this.locationPollId);
|
|
90
98
|
this.locationPollId = null;
|
|
91
99
|
}
|
|
92
100
|
|
|
@@ -103,7 +111,7 @@ BookReader.prototype.urlStartLocationPolling = function() {
|
|
|
103
111
|
this.trigger(BookReader.eventNames.stop);
|
|
104
112
|
if (this.animating) {
|
|
105
113
|
// Queue change if animating
|
|
106
|
-
|
|
114
|
+
this.plugins.autoplay?.stop();
|
|
107
115
|
this.animationFinishedCallback = updateParams;
|
|
108
116
|
} else {
|
|
109
117
|
// update immediately
|
|
@@ -121,7 +129,7 @@ BookReader.prototype.urlStartLocationPolling = function() {
|
|
|
121
129
|
*/
|
|
122
130
|
BookReader.prototype.urlUpdateFragment = function() {
|
|
123
131
|
const allParams = this.paramsFromCurrent();
|
|
124
|
-
const {
|
|
132
|
+
const { urlTrackIndex0, urlTrackedParams } = this.options;
|
|
125
133
|
|
|
126
134
|
if (!urlTrackIndex0
|
|
127
135
|
&& (typeof(allParams.index) !== 'undefined')
|
|
@@ -137,29 +145,69 @@ BookReader.prototype.urlUpdateFragment = function() {
|
|
|
137
145
|
return validParams;
|
|
138
146
|
}, {});
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
// eg 'page/3/mode/2up'; no query params (in hash mode, it might have /search/term)
|
|
149
|
+
// Does NOT have the :~:text fragment
|
|
150
|
+
const newFragment = this.fragmentFromParams(params, this.options.urlMode);
|
|
151
|
+
const newFragmentWithSlash = newFragment === '' ? '' : `/${newFragment}`;
|
|
152
|
+
// eg 'page/3/mode/2up'; no query params
|
|
153
|
+
// WILL CONTAIN the :~:text fragment in hash mode (!)
|
|
141
154
|
const currFragment = this.urlReadFragment();
|
|
155
|
+
// This should have both ?q=foo&text=bar (and any other params) as an encoded string
|
|
142
156
|
const currQueryString = this.getLocationSearch();
|
|
143
|
-
|
|
144
|
-
|
|
157
|
+
// Eg ?q=foo&text=bar; only query params, no fragment
|
|
158
|
+
const newQueryString = this.queryStringFromParams(params, currQueryString, this.options.urlMode);
|
|
159
|
+
|
|
160
|
+
// NOTE: If ?text is in the URL, we will fire fragment change events on every render; which is
|
|
161
|
+
// not desireable, but currently don't have a way to handle re-writing ?text to the hash text
|
|
162
|
+
// fragment form, :~:text=foo.
|
|
163
|
+
const hasTextParam = this.urlPlugin.retrieveTextFragment(currQueryString);
|
|
164
|
+
if (currFragment === newFragment && currQueryString === newQueryString && !hasTextParam) {
|
|
145
165
|
return;
|
|
146
166
|
}
|
|
147
167
|
|
|
148
|
-
if (urlMode === 'history') {
|
|
149
|
-
if (window.history
|
|
168
|
+
if (this.options.urlMode === 'history') {
|
|
169
|
+
if (!window.history || !window.history.replaceState) {
|
|
170
|
+
this.options.urlMode = 'hash';
|
|
171
|
+
} else {
|
|
150
172
|
const baseWithoutSlash = this.options.urlHistoryBasePath.replace(/\/+$/, '');
|
|
151
|
-
const
|
|
152
|
-
|
|
173
|
+
const textFragment = this.urlPlugin.retrieveTextFragment(newQueryString);
|
|
153
174
|
const newUrlPath = `${baseWithoutSlash}${newFragmentWithSlash}${newQueryString}`;
|
|
154
|
-
|
|
155
|
-
this.
|
|
156
|
-
|
|
175
|
+
const extractedPage = this.urlPlugin.urlStringToUrlState(newFragmentWithSlash)?.page;
|
|
176
|
+
if (!this.textFragmentPage && textFragment) {
|
|
177
|
+
this.textFragmentPage = extractedPage ? extractedPage : null;
|
|
178
|
+
this.textFragment = `:~:text=${textFragment}`;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
window.history.replaceState({}, null, newUrlPath);
|
|
182
|
+
this.oldLocationHash = newFragment + newQueryString;
|
|
183
|
+
if (textFragment) {
|
|
184
|
+
this.oldLocationHash += `:~:text=${textFragment[0]}`;
|
|
185
|
+
}
|
|
186
|
+
} catch (e) {
|
|
187
|
+
// DOMException on Chrome when in sandboxed iframe
|
|
188
|
+
this.options.urlMode = 'hash';
|
|
189
|
+
}
|
|
157
190
|
}
|
|
158
|
-
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (this.options.urlMode === 'hash') {
|
|
159
194
|
const newQueryStringSearch = this.urlParamsFiltersOnlySearch(this.readQueryString());
|
|
160
|
-
|
|
161
|
-
|
|
195
|
+
let textFragment = this.urlPlugin.retrieveTextFragment(this.readQueryString());
|
|
196
|
+
const extractedPage = this.urlPlugin.urlStringToUrlState(newFragmentWithSlash)?.page;
|
|
162
197
|
|
|
198
|
+
if (textFragment) {
|
|
199
|
+
textFragment = `:~:text=${textFragment[0]}`;
|
|
200
|
+
} else {
|
|
201
|
+
textFragment = '';
|
|
202
|
+
}
|
|
203
|
+
if (!this.textFragmentPage && textFragment) {
|
|
204
|
+
this.textFragmentPage = extractedPage ? extractedPage : null;
|
|
205
|
+
this.textFragment = textFragment;
|
|
206
|
+
} else if (this.textFragmentPage && extractedPage != this.textFragmentPage) {
|
|
207
|
+
textFragment = '';
|
|
208
|
+
}
|
|
209
|
+
window.location.replace('#' + newFragment + newQueryStringSearch + textFragment);
|
|
210
|
+
this.oldLocationHash = newFragment + newQueryStringSearch + textFragment;
|
|
163
211
|
}
|
|
164
212
|
};
|
|
165
213
|
|
|
@@ -185,7 +233,7 @@ BookReader.prototype.urlReadFragment = function() {
|
|
|
185
233
|
if (urlMode === 'history') {
|
|
186
234
|
return window.location.pathname.substr(urlHistoryBasePath.length);
|
|
187
235
|
} else {
|
|
188
|
-
return
|
|
236
|
+
return this.urlPlugin.getHash();
|
|
189
237
|
}
|
|
190
238
|
};
|
|
191
239
|
|
|
@@ -196,3 +244,40 @@ BookReader.prototype.urlReadFragment = function() {
|
|
|
196
244
|
BookReader.prototype.urlReadHashFragment = function() {
|
|
197
245
|
return window.location.hash.substr(1);
|
|
198
246
|
};
|
|
247
|
+
export class BookreaderUrlPlugin extends BookReader {
|
|
248
|
+
init() {
|
|
249
|
+
if (this.options.enableUrlPlugin) {
|
|
250
|
+
this.urlPlugin = new UrlPlugin(this.options);
|
|
251
|
+
const location = this.getLocationSearch();
|
|
252
|
+
if (location.includes("text=")) {
|
|
253
|
+
this.on('textLayerVisible', async (_, {pageContainerEl}) => {
|
|
254
|
+
const visiblePageNum = pageContainerEl.getAttribute('data-page-num');
|
|
255
|
+
|
|
256
|
+
// Hack: More time mode 1up page "settle down" from user scrolling
|
|
257
|
+
await sleep(this.mode === 1 ? 900 : 100);
|
|
258
|
+
|
|
259
|
+
// No textFragment found or the textFragment stored doesn't match current visible page loaded
|
|
260
|
+
if (!this.textFragment || this.textFragmentPage !== visiblePageNum) return;
|
|
261
|
+
if (this.options.urlMode === 'history') {
|
|
262
|
+
window.location.replace(`#${this.textFragment}`);
|
|
263
|
+
} else {
|
|
264
|
+
// for urlMode hash, textFragment is stored in oldLocationHash already
|
|
265
|
+
window.location.replace(`#${this.oldLocationHash}`);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
this.bind(BookReader.eventNames.PostInit, () => {
|
|
270
|
+
const { urlMode } = this.options;
|
|
271
|
+
|
|
272
|
+
if (urlMode === 'hash') {
|
|
273
|
+
this.urlPlugin.listenForHashChanges();
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
super.init();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
window.BookReader = BookreaderUrlPlugin;
|
|
283
|
+
export default BookreaderUrlPlugin;
|