@internetarchive/bookreader 5.0.0-10-alpha-1 → 5.0.0-100
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 +428 -1139
- 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 +1782 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +7 -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/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 +25 -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 +2 -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 +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 +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 +1 -1
- 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 +84 -64
- package/src/BookNavigator/assets/bookmark-colors.js +1 -1
- package/src/BookNavigator/assets/button-base.js +2 -1
- package/src/BookNavigator/assets/ia-logo.js +17 -0
- package/src/BookNavigator/assets/icon_checkmark.js +1 -1
- package/src/BookNavigator/assets/icon_close.js +1 -1
- package/src/BookNavigator/book-navigator.js +620 -0
- package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
- package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -3
- package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
- package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +2 -2
- package/src/BookNavigator/bookmarks/bookmarks-provider.js +27 -17
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
- package/src/BookNavigator/delete-modal-actions.js +1 -1
- package/src/BookNavigator/downloads/downloads-provider.js +36 -21
- package/src/BookNavigator/downloads/downloads.js +24 -4
- package/src/BookNavigator/search/search-provider.js +55 -27
- package/src/BookNavigator/search/search-results.js +25 -11
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/viewable-files.js +95 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +13 -12
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +9 -9
- 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 +58 -360
- package/src/BookReader/Mode1UpLit.js +393 -0
- package/src/BookReader/Mode2Up.js +75 -1318
- package/src/BookReader/Mode2UpLit.js +787 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +312 -0
- package/src/BookReader/ModeThumb.js +20 -12
- package/src/BookReader/Navbar/Navbar.js +130 -53
- 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 +2 -3
- package/src/BookReader/options.js +87 -16
- 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 +136 -12
- package/src/BookReader.js +641 -1192
- 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/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 +12 -66
- package/src/css/_BRpages.scss +163 -43
- package/src/css/_BRsearch.scss +69 -30
- 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 +1 -1
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.archive_analytics.js +84 -78
- package/src/plugins/plugin.autoplay.js +99 -104
- package/src/plugins/plugin.chapters.js +314 -205
- 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 +54 -51
- package/src/plugins/plugin.text_selection.js +510 -219
- package/src/plugins/plugin.vendor-fullscreen.js +5 -5
- package/src/plugins/search/plugin.search.js +370 -392
- package/src/plugins/search/utils.js +43 -0
- package/src/plugins/search/view.js +49 -67
- package/src/plugins/translate/TranslationManager.js +162 -0
- package/src/plugins/translate/plugin.translate.js +523 -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 +344 -350
- package/src/plugins/tts/utils.js +49 -47
- package/src/plugins/url/UrlPlugin.js +191 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +44 -15
- 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/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 -493
- 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/br-fullscreen-mgr.js +0 -83
- 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
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import BookReader from '../../src/BookReader.js';
|
|
3
|
-
import * as util from '../../src/plugins/plugin.vendor-fullscreen.js';
|
|
4
|
-
|
|
5
|
-
let br;
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
document.body.innerHTML = '<div id="BookReader">';
|
|
8
|
-
br = new BookReader();
|
|
9
|
-
br.init();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
jest.clearAllMocks();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('Plugin: Vendor-fullscreen', () => {
|
|
17
|
-
test('has option flag', () => {
|
|
18
|
-
expect(BookReader.defaultOptions.enableVendorFullscreenPlugin).toEqual(true);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test('enterFullWindow will run when enter in Fullscreen mode', () => {
|
|
22
|
-
const enterFullWindow = br.enterFullWindow;
|
|
23
|
-
br.updateBrClasses = jest.fn();
|
|
24
|
-
br.resize = jest.fn();
|
|
25
|
-
br.init();
|
|
26
|
-
br.enterFullWindow();
|
|
27
|
-
|
|
28
|
-
expect(enterFullWindow).toBeTruthy();
|
|
29
|
-
|
|
30
|
-
// br.isVendorFullscreenActive set to `true` when enterFullWindow Called
|
|
31
|
-
expect(br.isVendorFullscreenActive).toEqual(true);
|
|
32
|
-
|
|
33
|
-
// br.updateBrClasses trigger when enterFullWindow called
|
|
34
|
-
expect(br.updateBrClasses).toHaveBeenCalledTimes(2);
|
|
35
|
-
|
|
36
|
-
// br.resize trigger when enterFullWindow called
|
|
37
|
-
expect(br.resize).toHaveBeenCalledTimes(1);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('exitFullWindow will run when exit Fullscreen mode', () => {
|
|
41
|
-
const exitFullWindow = br.exitFullWindow;
|
|
42
|
-
br.updateBrClasses = jest.fn();
|
|
43
|
-
br.init();
|
|
44
|
-
br.exitFullWindow();
|
|
45
|
-
|
|
46
|
-
expect(exitFullWindow).toBeTruthy();
|
|
47
|
-
|
|
48
|
-
// br.isFullscreenActive set to `false` when exitFullWindow Called
|
|
49
|
-
expect(br.isFullscreenActive).toEqual(false);
|
|
50
|
-
|
|
51
|
-
// br.updateBrClasses trigger when exitFullWindow called
|
|
52
|
-
expect(br.updateBrClasses).toHaveBeenCalledTimes(2);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('isFullscreen returns true when fullscreen activated', () => {
|
|
56
|
-
br.init();
|
|
57
|
-
br.isVendorFullscreenActive = true;
|
|
58
|
-
expect(br.isFullscreen).toBeTruthy();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('util: isFullscreenActive', () => {
|
|
62
|
-
document.fullscreenElement = true;
|
|
63
|
-
expect(util.isFullscreenActive).toBeTruthy();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import BookReader from '../../../src/BookReader.js';
|
|
3
|
-
import '../../../src/plugins/plugin.mobile_nav.js';
|
|
4
|
-
import '../../../src/plugins/search/plugin.search.js';
|
|
5
|
-
|
|
6
|
-
jest.mock('../../../src/plugins/search/view.js');
|
|
7
|
-
|
|
8
|
-
let br;
|
|
9
|
-
const namespace = 'BookReader:';
|
|
10
|
-
const triggeredEvents = () => {
|
|
11
|
-
return $.fn.trigger.mock.calls.map((params) => {
|
|
12
|
-
if (typeof params[0] === 'string') { return params[0]; }
|
|
13
|
-
return params[0].type;
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
$.ajax = jest.fn().mockImplementation(() => {
|
|
19
|
-
// return from:
|
|
20
|
-
// `https://ia800304.us.archive.org/fulltext/inside.php?item_id=adventuresofoli00dick&doc=adventuresofoli00dick&path=/30/items/adventuresofoli00dick&q=child&callback=<serialized jQ CB>`
|
|
21
|
-
return Promise.resolve({
|
|
22
|
-
ia: "adventuresofoli00dick",
|
|
23
|
-
q: "child",
|
|
24
|
-
indexed: true,
|
|
25
|
-
page_count: 644,
|
|
26
|
-
body_length: 666,
|
|
27
|
-
leaf0_missing: false,
|
|
28
|
-
matches: [{
|
|
29
|
-
text: 'For a long; time after it was ushered into this world of sorrow and trouble, by the parish surgeon, it remained a matter of considerable doubt wliether the {{{child}}} Avould survi^ e to bear any name at all; in which case it is somewhat more than probable that these memoirs would never have appeared; or, if they had, that being comprised within a couple of pages, they would have possessed the inestimable meiit of being the most concise and faithful specimen of biography, extant in the literature of any age or country.',
|
|
30
|
-
par: [{
|
|
31
|
-
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
|
32
|
-
b: 2535,
|
|
33
|
-
t: 1942,
|
|
34
|
-
page_width: 1790,
|
|
35
|
-
r: 1598,
|
|
36
|
-
l: 50,
|
|
37
|
-
page_height: 2940,
|
|
38
|
-
page: 37
|
|
39
|
-
}]
|
|
40
|
-
}]
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
$.fn.trigger = jest.fn();
|
|
45
|
-
document.body.innerHTML = '<div id="BookReader">';
|
|
46
|
-
br = new BookReader();
|
|
47
|
-
br.initToolbar = jest.fn();
|
|
48
|
-
br.showProgressPopup = jest.fn();
|
|
49
|
-
br.searchXHR = jest.fn();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
afterEach(() => {
|
|
53
|
-
jest.clearAllMocks();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe('Plugin: Search', () => {
|
|
57
|
-
test('has option flag', () => {
|
|
58
|
-
expect(BookReader.defaultOptions.enableSearch).toEqual(true);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('has added BR property: server', () => {
|
|
62
|
-
expect(br).toHaveProperty('server');
|
|
63
|
-
expect(br.server).toBeTruthy();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('has added BR property: bookId', () => {
|
|
67
|
-
expect(br).toHaveProperty('bookId');
|
|
68
|
-
expect(br.bookId).toBeFalsy();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('has added BR property: subPrefix', () => {
|
|
72
|
-
expect(br).toHaveProperty('subPrefix');
|
|
73
|
-
expect(br.subPrefix).toBeFalsy();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('has added BR property: bookPath', () => {
|
|
77
|
-
expect(br).toHaveProperty('bookPath');
|
|
78
|
-
expect(br.bookPath).toBeFalsy();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('has added BR property: searchInsideUrl', () => {
|
|
82
|
-
expect(br).toHaveProperty('searchInsideUrl');
|
|
83
|
-
expect(br.searchInsideUrl).toBeTruthy();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('has added BR property: initialSearchTerm', () => {
|
|
87
|
-
expect(br.options).toHaveProperty('initialSearchTerm');
|
|
88
|
-
expect(br.options.initialSearchTerm).toBeFalsy();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('On init, it loads the toolbar', () => {
|
|
92
|
-
br.init();
|
|
93
|
-
expect(br.initToolbar).toHaveBeenCalled();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test('On init, it will run a search if given `options.initialSearchTerm`', () => {
|
|
97
|
-
br.search = jest.fn();
|
|
98
|
-
br.options.initialSearchTerm = 'foo';
|
|
99
|
-
br.init();
|
|
100
|
-
|
|
101
|
-
expect(br.search).toHaveBeenCalled();
|
|
102
|
-
expect(br.search.mock.calls[0][1])
|
|
103
|
-
.toHaveProperty('goToFirstResult', true);
|
|
104
|
-
expect(br.search.mock.calls[0][1])
|
|
105
|
-
.toHaveProperty('suppressFragmentChange', true);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test('calling `search` fires ajax call`', () => {
|
|
109
|
-
br.init();
|
|
110
|
-
br.search('foo');
|
|
111
|
-
expect($.ajax).toHaveBeenCalled();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
test('SearchStarted event fires when search method called', () => {
|
|
115
|
-
br.init();
|
|
116
|
-
br.search('foo');
|
|
117
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchStarted`);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('SearchStarted event fires and should go to first result', () => {
|
|
121
|
-
br.init();
|
|
122
|
-
br.search('foo', { goToFirstResult: true});
|
|
123
|
-
expect(br.options.goToFirstResult).toBeTruthy();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test('SearchCallback event fires when AJAX search returns results', () => {
|
|
127
|
-
br.init();
|
|
128
|
-
const dfd = br.search('foo');
|
|
129
|
-
return dfd.then(() => {
|
|
130
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test('SearchCallbackError event fires when AJAX search returns error', () => {
|
|
135
|
-
$.ajax = jest.fn().mockImplementation(() => {
|
|
136
|
-
return Promise.resolve({
|
|
137
|
-
error: true,
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
br.init();
|
|
141
|
-
const dfd = br.search('foo');
|
|
142
|
-
return dfd.then(() => {
|
|
143
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', () => {
|
|
148
|
-
$.ajax = jest.fn().mockImplementation(() => {
|
|
149
|
-
return Promise.resolve({
|
|
150
|
-
matches: [],
|
|
151
|
-
indexed: false,
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
br.init();
|
|
155
|
-
const dfd = br.search('foo');
|
|
156
|
-
return dfd.then(() => {
|
|
157
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test('SearchCallbackEmpty event fires when AJAX search returns no matches', () => {
|
|
162
|
-
$.ajax = jest.fn().mockImplementation(() => {
|
|
163
|
-
return Promise.resolve({
|
|
164
|
-
matches: [],
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
br.init();
|
|
168
|
-
const dfd = br.search('foo');
|
|
169
|
-
return dfd.then(() => {
|
|
170
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
});
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import BookReader from '../../../src/BookReader.js';
|
|
3
|
-
import '../../../src/plugins/plugin.mobile_nav.js';
|
|
4
|
-
import '../../../src/plugins/search/plugin.search.js';
|
|
5
|
-
import '../../../src/plugins/search/view.js';
|
|
6
|
-
|
|
7
|
-
let br;
|
|
8
|
-
const namespace = 'BookReader:';
|
|
9
|
-
const results = {
|
|
10
|
-
ia: "adventuresofoli00dick",
|
|
11
|
-
q: "child",
|
|
12
|
-
indexed: true,
|
|
13
|
-
page_count: 644,
|
|
14
|
-
body_length: 666,
|
|
15
|
-
leaf0_missing: false,
|
|
16
|
-
matches: [{
|
|
17
|
-
text: 'For a long; time after it was ushered into this world of sorrow and trouble, by the parish surgeon, it remained a matter of considerable doubt wliether the {{{child}}} Avould survi^ e to bear any name at all; in which case it is somewhat more than probable that these memoirs would never have appeared; or, if they had, that being comprised within a couple of pages, they would have possessed the inestimable meiit of being the most concise and faithful specimen of biography, extant in the literature of any age or country.',
|
|
18
|
-
par: [{
|
|
19
|
-
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
|
20
|
-
b: 2535,
|
|
21
|
-
t: 1942,
|
|
22
|
-
page_width: 1790,
|
|
23
|
-
r: 1598,
|
|
24
|
-
l: 50,
|
|
25
|
-
page_height: 2940,
|
|
26
|
-
page: 37
|
|
27
|
-
}]
|
|
28
|
-
}]
|
|
29
|
-
};
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
$.ajax = jest.fn().mockImplementation(() => {
|
|
32
|
-
// return from:
|
|
33
|
-
// `https://ia800304.us.archive.org/fulltext/inside.php?item_id=adventuresofoli00dick&doc=adventuresofoli00dick&path=/30/items/adventuresofoli00dick&q=child&callback=<serialized jQ CB>`
|
|
34
|
-
return Promise.resolve(results);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
$.fn.trigger = jest.fn();
|
|
38
|
-
document.body.innerHTML = '<div id="BookReader">';
|
|
39
|
-
br = new BookReader();
|
|
40
|
-
br.initToolbar = jest.fn();
|
|
41
|
-
br.showProgressPopup = jest.fn();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
afterEach(() => {
|
|
45
|
-
jest.clearAllMocks();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe('View: Plugin: Search', () => {
|
|
49
|
-
test('When search runs, the view gets created.', () => {
|
|
50
|
-
br.search = jest.fn();
|
|
51
|
-
br.options.initialSearchTerm = 'foo';
|
|
52
|
-
br.init();
|
|
53
|
-
|
|
54
|
-
expect(br.searchView).toBeDefined();
|
|
55
|
-
expect(br.searchView.handleSearchCallback).toBeDefined();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe("Search results navigation bar", () => {
|
|
59
|
-
test('Search Results callback creates the results nav', () => {
|
|
60
|
-
br.init();
|
|
61
|
-
const event = new CustomEvent(`${namespace}SearchCallback`);
|
|
62
|
-
const options = { goToFirstResult: false };
|
|
63
|
-
|
|
64
|
-
expect(br.searchView.dom.searchNavigation).toBeUndefined();
|
|
65
|
-
|
|
66
|
-
br.searchView.handleSearchCallback(event, { results, options});
|
|
67
|
-
expect(br.searchView.dom.searchNavigation).toBeDefined();
|
|
68
|
-
});
|
|
69
|
-
test('has controls', () => {
|
|
70
|
-
br.init();
|
|
71
|
-
const event = new CustomEvent(`${namespace}SearchCallback`);
|
|
72
|
-
const options = { goToFirstResult: false };
|
|
73
|
-
br.searchView.handleSearchCallback(event, { results, options});
|
|
74
|
-
|
|
75
|
-
const searchResultsNav = document.querySelector('.BRsearch-navigation');
|
|
76
|
-
expect(searchResultsNav).toBeDefined();
|
|
77
|
-
|
|
78
|
-
expect(searchResultsNav.querySelectorAll('button').length).toEqual(4);
|
|
79
|
-
expect(searchResultsNav.querySelector('.clear')).toBeDefined();
|
|
80
|
-
expect(searchResultsNav.querySelector('.toggle-sidebar')).toBeDefined();
|
|
81
|
-
expect(searchResultsNav.querySelector('.prev')).toBeDefined();
|
|
82
|
-
expect(searchResultsNav.querySelector('.next')).toBeDefined();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('Click events handlers', () => {
|
|
86
|
-
it('triggers custom event when toggling side menu', () => {
|
|
87
|
-
br.init();
|
|
88
|
-
let eventNameTriggered = '';
|
|
89
|
-
br.trigger = (eventName) => eventNameTriggered = eventName;
|
|
90
|
-
|
|
91
|
-
expect(eventNameTriggered).toBeFalsy();
|
|
92
|
-
br.searchView.toggleSidebar();
|
|
93
|
-
expect(eventNameTriggered).toEqual('ToggleSearchMenu');
|
|
94
|
-
});
|
|
95
|
-
it('triggers custom event when closing navbar', () => {
|
|
96
|
-
br.init();
|
|
97
|
-
let eventNameTriggered = '';
|
|
98
|
-
br.trigger = (eventName) => eventNameTriggered = eventName;
|
|
99
|
-
|
|
100
|
-
expect(eventNameTriggered).toBeFalsy();
|
|
101
|
-
br.searchView.clearSearchFieldAndResults();
|
|
102
|
-
expect(eventNameTriggered).toEqual('SearchResultsCleared');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
});
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import sinon from 'sinon';
|
|
2
|
-
import { afterEventLoop } from '../../utils.js';
|
|
3
|
-
import AbstractTTSEngine from '../../../src/plugins/tts/AbstractTTSEngine.js';
|
|
4
|
-
import PageChunkIterator from '../../../src/plugins/tts/PageChunkIterator.js';
|
|
5
|
-
/** @typedef {import('../../../src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
|
|
6
|
-
|
|
7
|
-
// Skipping because it's flaky. Fix in #672
|
|
8
|
-
describe.skip('AbstractTTSEngine', () => {
|
|
9
|
-
test('stops playing once done', () => {
|
|
10
|
-
class DummyEngine extends AbstractTTSEngine {
|
|
11
|
-
getVoices() { return []; }
|
|
12
|
-
}
|
|
13
|
-
const d = new DummyEngine(DUMMY_TTS_ENGINE_OPTS);
|
|
14
|
-
d._chunkIterator = { next: sinon.stub().resolves(PageChunkIterator.AT_END) };
|
|
15
|
-
const stopStub = sinon.stub(d, 'stop');
|
|
16
|
-
expect(stopStub.callCount).toBe(0);
|
|
17
|
-
d.step();
|
|
18
|
-
return afterEventLoop()
|
|
19
|
-
.then(() => expect(stopStub.callCount).toBe(1));
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
for (const dummyVoice of [dummyVoice, dummyVoiceUnderscores]) {
|
|
24
|
-
describe(`getBestBookVoice with BCP47 ${dummyVoice == dummyVoiceUnderscores ? '+' : '-'} underscores`, () => {
|
|
25
|
-
const { getBestBookVoice } = AbstractTTSEngine;
|
|
26
|
-
|
|
27
|
-
test('undefined if no voices', () => {
|
|
28
|
-
expect(getBestBookVoice([], 'en', [])).toBe(undefined);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('returns first voice if no matching', () => {
|
|
32
|
-
const enVoice = dummyVoice({lang: "en-US"});
|
|
33
|
-
expect(getBestBookVoice([enVoice], 'fr', [])).toBe(enVoice);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('choose first matching voice', () => {
|
|
37
|
-
const voices = [
|
|
38
|
-
dummyVoice({lang: "en-GB"}),
|
|
39
|
-
dummyVoice({lang: "en-US"}),
|
|
40
|
-
];
|
|
41
|
-
expect(getBestBookVoice(voices, 'en', [])).toBe(voices[0]);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('choose first matching default voice', () => {
|
|
45
|
-
const voices = [
|
|
46
|
-
dummyVoice({lang: "en-GB"}),
|
|
47
|
-
dummyVoice({lang: "en-US", default: true}),
|
|
48
|
-
];
|
|
49
|
-
expect(getBestBookVoice(voices, 'en', [])).toBe(voices[1]);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test('does not choose default if better language match exists', () => {
|
|
53
|
-
const voices = [
|
|
54
|
-
dummyVoice({lang: "en-US", default: true}),
|
|
55
|
-
dummyVoice({lang: "fr-FR"}),
|
|
56
|
-
];
|
|
57
|
-
expect(getBestBookVoice(voices, 'fr', [])).toBe(voices[1]);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('choose users dialect if present', () => {
|
|
61
|
-
const voices = [
|
|
62
|
-
dummyVoice({lang: "en-GB"}),
|
|
63
|
-
dummyVoice({lang: "en-CA"}),
|
|
64
|
-
dummyVoice({lang: "en-US"}),
|
|
65
|
-
];
|
|
66
|
-
expect(getBestBookVoice(voices, 'en', ['en-CA', 'en'])).toBe(voices[1]);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test('choose users dialect even if not default', () => {
|
|
70
|
-
const voices = [
|
|
71
|
-
dummyVoice({lang: "en-US", default: true}),
|
|
72
|
-
dummyVoice({lang: "en-GB"}),
|
|
73
|
-
dummyVoice({lang: "en-CA"}),
|
|
74
|
-
];
|
|
75
|
-
expect(getBestBookVoice(voices, 'en', ['en-CA', 'en'])).toBe(voices[2]);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test('choose language even if dialect does not match', () => {
|
|
79
|
-
const voices = [
|
|
80
|
-
dummyVoice({lang: "en-GB"}),
|
|
81
|
-
];
|
|
82
|
-
expect(getBestBookVoice(voices, 'en', ['en-CA'])).toBe(voices[0]);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test('real world example', () => {
|
|
86
|
-
// Chrome 77 @ Windows 10
|
|
87
|
-
const voices = [
|
|
88
|
-
{ default: true, lang: "en-US", name: "Microsoft David Desktop - English (United States)", localService: true, voiceURI: "Microsoft David Desktop - English (United States)" },
|
|
89
|
-
{ default: false, lang: "de-DE", name: "Microsoft Hedda Desktop - German", localService: true, voiceURI: "Microsoft Hedda Desktop - German" },
|
|
90
|
-
{ default: false, lang: "en-US", name: "Microsoft Zira Desktop - English (United States)", localService: true, voiceURI: "Microsoft Zira Desktop - English (United States)" },
|
|
91
|
-
{ default: false, lang: "de-DE", name: "Google Deutsch", localService: false, voiceURI: "Google Deutsch" },
|
|
92
|
-
{ default: false, lang: "en-US", name: "Google US English", localService: false, voiceURI: "Google US English" },
|
|
93
|
-
{ default: false, lang: "en-GB", name: "Google UK English Female", localService: false, voiceURI: "Google UK English Female" },
|
|
94
|
-
{ default: false, lang: "en-GB", name: "Google UK English Male", localService: false, voiceURI: "Google UK English Male" },
|
|
95
|
-
{ default: false, lang: "es-ES", name: "Google español", localService: false, voiceURI: "Google español" },
|
|
96
|
-
{ default: false, lang: "es-US", name: "Google español de Estados Unidos", localService: false, voiceURI: "Google español de Estados Unidos" },
|
|
97
|
-
{ default: false, lang: "fr-FR", name: "Google français", localService: false, voiceURI: "Google français" },
|
|
98
|
-
{ default: false, lang: "hi-IN", name: "Google हिन्दी", localService: false, voiceURI: "Google हिन्दी" },
|
|
99
|
-
{ default: false, lang: "id-ID", name: "Google Bahasa Indonesia", localService: false, voiceURI: "Google Bahasa Indonesia" },
|
|
100
|
-
{ default: false, lang: "it-IT", name: "Google italiano", localService: false, voiceURI: "Google italiano" },
|
|
101
|
-
{ default: false, lang: "ja-JP", name: "Google 日本語", localService: false, voiceURI: "Google 日本語" },
|
|
102
|
-
{ default: false, lang: "ko-KR", name: "Google 한국의", localService: false, voiceURI: "Google 한국의" },
|
|
103
|
-
{ default: false, lang: "nl-NL", name: "Google Nederlands", localService: false, voiceURI: "Google Nederlands" },
|
|
104
|
-
{ default: false, lang: "pl-PL", name: "Google polski", localService: false, voiceURI: "Google polski" },
|
|
105
|
-
{ default: false, lang: "pt-BR", name: "Google português do Brasil", localService: false, voiceURI: "Google português do Brasil" },
|
|
106
|
-
{ default: false, lang: "ru-RU", name: "Google русский", localService: false, voiceURI: "Google русский" },
|
|
107
|
-
{ default: false, lang: "zh-CN", name: "Google 普通话(中国大陆)", localService: false, voiceURI: "Google 普通话(中国大陆)" },
|
|
108
|
-
{ default: false, lang: "zh-HK", name: "Google 粤語(香港)", localService: false, voiceURI: "Google 粤語(香港)" },
|
|
109
|
-
{ default: false, lang: "zh-TW", name: "Google 國語(臺灣)", localService: false, voiceURI: "Google 國語(臺灣)" }
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
expect(getBestBookVoice(voices, 'en', ['en-CA', 'en'])).toBe(voices[0]);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** @type {TTSEngineOptions} */
|
|
118
|
-
export const DUMMY_TTS_ENGINE_OPTS = {
|
|
119
|
-
server: 'blah',
|
|
120
|
-
bookPath: 'blah',
|
|
121
|
-
bookLanguage: 'blah',
|
|
122
|
-
onLoadingStart() {},
|
|
123
|
-
onLoadingComplete() {},
|
|
124
|
-
onDone() {},
|
|
125
|
-
beforeChunkPlay() { return Promise.resolve(); },
|
|
126
|
-
afterChunkPlay() {},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @param {SpeechSynthesisVoice}
|
|
131
|
-
* @return {SpeechSynthesisVoice}
|
|
132
|
-
**/
|
|
133
|
-
function dummyVoice(overrides) {
|
|
134
|
-
return Object.assign({
|
|
135
|
-
default: false,
|
|
136
|
-
lang: "en-US",
|
|
137
|
-
name: "Microsoft David",
|
|
138
|
-
localService: false,
|
|
139
|
-
voiceURI: "",
|
|
140
|
-
}, overrides);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Construct a voice-like object using underscores instead of hyphenes
|
|
145
|
-
* (Like Chrome/Android)
|
|
146
|
-
* @param {SpeechSynthesisVoice}
|
|
147
|
-
* @return {SpeechSynthesisVoice}
|
|
148
|
-
**/
|
|
149
|
-
function dummyVoiceUnderscores(overrides) {
|
|
150
|
-
const voice = dummyVoice(overrides);
|
|
151
|
-
voice.lang = voice.lang.replace('-', '_');
|
|
152
|
-
return voice;
|
|
153
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import FestivalTTSEngine from '../../../src/plugins/tts/FestivalTTSEngine.js';
|
|
2
|
-
import sinon from 'sinon';
|
|
3
|
-
import { afterEventLoop } from '../../utils.js';
|
|
4
|
-
import { DUMMY_TTS_ENGINE_OPTS } from './AbstractTTSEngine.test.js';
|
|
5
|
-
import PageChunk from '../../../src/plugins/tts/PageChunk.js';
|
|
6
|
-
import PageChunkIterator from '../../../src/plugins/tts/PageChunkIterator.js';
|
|
7
|
-
/** @typedef {import('../../../src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
|
|
8
|
-
|
|
9
|
-
describe('iOSCaptureUserIntentHack', () => {
|
|
10
|
-
test('synchronously calls createSound/play to capture user intent', () => {
|
|
11
|
-
const mockSound = createMockSound();
|
|
12
|
-
const sm = {
|
|
13
|
-
supported: sinon.stub().returns(true),
|
|
14
|
-
createSound: sinon.stub().returns(mockSound),
|
|
15
|
-
};
|
|
16
|
-
window.soundManager = sm;
|
|
17
|
-
const engine = new FestivalTTSEngine(DUMMY_TTS_ENGINE_OPTS);
|
|
18
|
-
engine.iOSCaptureUserIntentHack();
|
|
19
|
-
|
|
20
|
-
expect(sm.createSound.callCount).toBe(1);
|
|
21
|
-
expect(mockSound.play.callCount).toBe(1);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
describe('misc', () => {
|
|
26
|
-
test('starts playing even if onload not called until play starts', async () => {
|
|
27
|
-
const sm = {
|
|
28
|
-
supported: sinon.stub().returns(true),
|
|
29
|
-
createSound: sinon.stub().returns(createMockSound()),
|
|
30
|
-
stopAll: sinon.stub(),
|
|
31
|
-
};
|
|
32
|
-
window.soundManager = sm;
|
|
33
|
-
const engine = new FestivalTTSEngine(DUMMY_TTS_ENGINE_OPTS);
|
|
34
|
-
sinon.stub(engine, 'playSound').returns(new Promise(() => {}));
|
|
35
|
-
sinon.stub(engine, 'stop');
|
|
36
|
-
sinon.stub(PageChunkIterator.prototype, '_fetchPageChunks').resolves([dummyPageChunk()]);
|
|
37
|
-
engine.start(0, 5);
|
|
38
|
-
|
|
39
|
-
// because things happen in callbacks, need to run code at end of the JS event loop
|
|
40
|
-
await afterEventLoop();
|
|
41
|
-
expect(sm.createSound.callCount).toBe(1);
|
|
42
|
-
expect(PageChunkIterator.prototype._fetchPageChunks.callCount).toBeGreaterThanOrEqual(1);
|
|
43
|
-
expect(engine.playSound.callCount).toBe(1);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
/** @returns {SMSound} */
|
|
48
|
-
function createMockSound() {
|
|
49
|
-
return {
|
|
50
|
-
load: sinon.stub(),
|
|
51
|
-
play: sinon.stub(),
|
|
52
|
-
destruct: sinon.stub(),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** @return {PageChunk} */
|
|
57
|
-
function dummyPageChunk() {
|
|
58
|
-
return new PageChunk(0, 0, 'Once upon a time', []);
|
|
59
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import PageChunk from '../../../src/plugins/tts/PageChunk.js';
|
|
2
|
-
|
|
3
|
-
describe('_fixChunkRects', () => {
|
|
4
|
-
const { _fixChunkRects } = PageChunk;
|
|
5
|
-
|
|
6
|
-
test('Handles empty array', () => {
|
|
7
|
-
const rects = [];
|
|
8
|
-
expect(_fixChunkRects(rects)).toBe(rects);
|
|
9
|
-
expect(rects).toEqual([]);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test('Does not modify normal values values normal', () => {
|
|
13
|
-
const rects = [[100,100,500,80], [200,200,500,180], [300,300,500,280]];
|
|
14
|
-
expect(_fixChunkRects(rects)).toBe(rects);
|
|
15
|
-
expect(rects).toEqual([[100,100,500,80], [200,200,500,180], [300,300,500,280]]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('Fixes outlier values in first rect', () => {
|
|
19
|
-
const rects = [[100,2300,2300,0], [200,200,200,180], [300,300,200,280]];
|
|
20
|
-
expect(_fixChunkRects(rects)).toBe(rects);
|
|
21
|
-
expect(rects).toEqual([[100,2300,200,2280], [200,200,200,180], [300,300,200,280]]);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
describe('_fromTextWrapperResponse', () => {
|
|
26
|
-
const { _fromTextWrapperResponse } = PageChunk;
|
|
27
|
-
|
|
28
|
-
test('Handles empty array', () => {
|
|
29
|
-
expect(_fromTextWrapperResponse(0, [])).toEqual([]);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('Basic test', () => {
|
|
33
|
-
const chunks = _fromTextWrapperResponse(0, [['Line', [0,100,100,0]]]);
|
|
34
|
-
expect(chunks).toEqual([new PageChunk(0, 0, 'Line', [[0,100,100,0]])]);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('_removeDanglingHyphens', () => {
|
|
39
|
-
const { _removeDanglingHyphens } = PageChunk;
|
|
40
|
-
|
|
41
|
-
test('No change to empty string', () => {
|
|
42
|
-
expect(_removeDanglingHyphens('')).toEqual('');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('No change when no hyphens string', () => {
|
|
46
|
-
expect(_removeDanglingHyphens('Hello world!')).toEqual('Hello world!');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('No change to hyphens mid-word', () => {
|
|
50
|
-
expect(_removeDanglingHyphens('It is mid-word!')).toEqual('It is mid-word!');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('Removes hyphens followed by spaces', () => {
|
|
54
|
-
expect(_removeDanglingHyphens('It is not mid- word!')).toEqual('It is not midword!');
|
|
55
|
-
expect(_removeDanglingHyphens('mid- word fid- word')).toEqual('midword fidword');
|
|
56
|
-
});
|
|
57
|
-
});
|