@internetarchive/bookreader 5.0.0-6-multiple-files → 5.0.0-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +17 -15
- package/.github/workflows/node.js.yml +77 -6
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +241 -377
- package/BookReader/BookReader.js +2 -21564
- package/BookReader/BookReader.js.LICENSE.txt +24 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1519 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +17 -0
- package/BookReader/ia-bookreader-bundle.js.map +1 -0
- package/BookReader/icons/1up.svg +1 -12
- package/BookReader/icons/2up.svg +1 -15
- package/BookReader/icons/advance.svg +3 -26
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -0
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -17
- package/BookReader/icons/fullscreen_exit.svg +1 -17
- package/BookReader/icons/hamburger.svg +1 -15
- package/BookReader/icons/left-arrow.svg +1 -12
- package/BookReader/icons/magnify-minus.svg +1 -16
- package/BookReader/icons/magnify-plus.svg +1 -17
- package/BookReader/icons/magnify.svg +1 -15
- package/BookReader/icons/pause.svg +1 -23
- package/BookReader/icons/play.svg +1 -22
- package/BookReader/icons/playback-speed.svg +1 -34
- package/BookReader/icons/read-aloud.svg +1 -22
- package/BookReader/icons/review.svg +3 -22
- package/BookReader/icons/thumbnails.svg +1 -17
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -22
- package/BookReader/images/BRicons.svg +5 -94
- package/BookReader/images/books_graphic.svg +1 -177
- package/BookReader/images/icon_book.svg +1 -12
- package/BookReader/images/icon_bookmark.svg +1 -12
- package/BookReader/images/icon_gear.svg +1 -14
- package/BookReader/images/icon_hamburger.svg +1 -20
- package/BookReader/images/icon_home.svg +1 -21
- package/BookReader/images/icon_info.svg +1 -11
- package/BookReader/images/icon_one_page.svg +1 -8
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.svg +1 -1
- package/BookReader/images/icon_playback-rate.svg +1 -15
- package/BookReader/images/icon_search_button.svg +1 -8
- package/BookReader/images/icon_share.svg +1 -9
- package/BookReader/images/icon_skip-ahead.svg +1 -6
- package/BookReader/images/icon_skip-back.svg +2 -13
- package/BookReader/images/icon_speaker.svg +1 -18
- package/BookReader/images/icon_speaker_open.svg +1 -10
- package/BookReader/images/icon_thumbnails.svg +1 -12
- package/BookReader/images/icon_toc.svg +1 -5
- package/BookReader/images/icon_two_pages.svg +1 -9
- package/BookReader/images/marker_chap-off.svg +1 -11
- package/BookReader/images/marker_chap-on.svg +1 -11
- package/BookReader/images/marker_srch-on.svg +1 -11
- package/BookReader/jquery-3.js +2 -0
- package/BookReader/jquery-3.js.LICENSE.txt +24 -0
- package/BookReader/plugins/plugin.archive_analytics.js +1 -172
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -165
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +1 -304
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +1 -74
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.mobile_nav.js +1 -334
- package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +1 -368
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +1 -1420
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +1 -1080
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +2 -9193
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +1 -269
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReader/webcomponents-bundle.js +3 -0
- package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
- package/BookReader/webcomponents-bundle.js.map +1 -0
- package/BookReaderDemo/BookReaderDemo.css +14 -1
- package/BookReaderDemo/BookReaderJSAutoplay.js +4 -1
- package/BookReaderDemo/BookReaderJSSimple.js +1 -0
- package/BookReaderDemo/IADemoBr.js +147 -0
- package/BookReaderDemo/demo-advanced.html +2 -2
- package/BookReaderDemo/demo-autoplay.html +2 -1
- package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
- package/BookReaderDemo/demo-fullscreen-mobile.html +2 -1
- package/BookReaderDemo/demo-fullscreen.html +2 -1
- package/BookReaderDemo/demo-iiif.html +2 -1
- package/BookReaderDemo/demo-internetarchive.html +84 -17
- package/BookReaderDemo/demo-multiple.html +2 -1
- package/BookReaderDemo/demo-preview-pages.html +2 -1
- package/BookReaderDemo/demo-simple.html +2 -1
- package/BookReaderDemo/demo-vendor-fullscreen.html +2 -1
- package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
- package/BookReaderDemo/immersion-1up.html +2 -1
- package/BookReaderDemo/immersion-mode.html +2 -1
- package/BookReaderDemo/toggle_controls.html +2 -1
- package/BookReaderDemo/view_mode.html +2 -1
- package/BookReaderDemo/viewmode-cycle.html +2 -3
- package/CHANGELOG.md +246 -0
- package/README.md +14 -1
- package/babel.config.js +19 -0
- package/codecov.yml +6 -0
- package/index.html +3 -0
- package/jsconfig.json +19 -0
- package/netlify.toml +5 -0
- package/package.json +70 -59
- package/renovate.json +52 -0
- package/scripts/preversion.js +4 -1
- package/src/BookNavigator/assets/bookmark-colors.js +1 -1
- package/src/BookNavigator/assets/button-base.js +9 -2
- 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/assets/icon_sort_asc.js +5 -0
- package/src/BookNavigator/assets/{icon_sort_ascending.js → icon_sort_desc.js} +2 -2
- package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
- package/src/BookNavigator/assets/icon_volumes.js +11 -0
- package/src/BookNavigator/book-navigator.js +585 -0
- package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
- package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
- package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
- package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +3 -8
- 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 +41 -25
- package/src/BookNavigator/search/search-provider.js +80 -28
- package/src/BookNavigator/search/search-results.js +34 -25
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +11 -10
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
- package/src/BookNavigator/volumes/volumes-provider.js +88 -53
- package/src/BookNavigator/volumes/volumes.js +41 -14
- package/src/BookReader/BookModel.js +59 -30
- package/src/BookReader/DebugConsole.js +3 -3
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/Mode1Up.js +56 -351
- package/src/BookReader/Mode1UpLit.js +391 -0
- package/src/BookReader/Mode2Up.js +73 -1318
- package/src/BookReader/Mode2UpLit.js +781 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +211 -0
- package/src/BookReader/ModeThumb.js +17 -11
- package/src/BookReader/Navbar/Navbar.js +10 -36
- package/src/BookReader/PageContainer.js +69 -6
- package/src/BookReader/ReduceSet.js +1 -1
- package/src/BookReader/Toolbar/Toolbar.js +10 -37
- package/src/BookReader/events.js +2 -0
- package/src/BookReader/options.js +24 -2
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils.js +108 -13
- package/src/BookReader.js +480 -825
- package/src/assets/icons/close-circle-dark.svg +1 -0
- package/src/assets/icons/magnify-minus.svg +3 -7
- package/src/assets/icons/magnify-plus.svg +3 -7
- package/src/assets/icons/voice.svg +1 -0
- package/src/css/BookReader.scss +0 -12
- package/src/css/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRmain.scss +33 -24
- package/src/css/_BRnav.scss +4 -26
- package/src/css/_BRpages.scss +147 -40
- package/src/css/_BRsearch.scss +25 -216
- package/src/css/_TextSelection.scss +16 -17
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +17 -5
- package/src/css/_icons.scss +7 -1
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.archive_analytics.js +3 -3
- package/src/plugins/plugin.autoplay.js +4 -9
- package/src/plugins/plugin.chapters.js +28 -35
- package/src/plugins/plugin.mobile_nav.js +11 -10
- package/src/plugins/plugin.resume.js +3 -3
- package/src/plugins/plugin.text_selection.js +32 -41
- package/src/plugins/plugin.vendor-fullscreen.js +4 -4
- package/src/plugins/search/plugin.search.js +179 -116
- package/src/plugins/search/view.js +63 -179
- package/src/plugins/tts/AbstractTTSEngine.js +46 -37
- package/src/plugins/tts/FestivalTTSEngine.js +13 -14
- package/src/plugins/tts/PageChunk.js +15 -21
- package/src/plugins/tts/PageChunkIterator.js +8 -12
- package/src/plugins/tts/WebTTSEngine.js +87 -71
- package/src/plugins/tts/plugin.tts.js +94 -125
- package/src/plugins/tts/utils.js +0 -25
- package/src/plugins/url/UrlPlugin.js +193 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +45 -16
- package/src/util/docCookies.js +21 -2
- package/tests/e2e/README.md +37 -0
- package/tests/e2e/autoplay.test.js +2 -2
- package/tests/e2e/base.test.js +7 -7
- package/tests/e2e/helpers/base.js +28 -23
- package/tests/e2e/helpers/debug.js +1 -1
- package/tests/e2e/helpers/desktopSearch.js +14 -13
- package/tests/e2e/helpers/mobileSearch.js +3 -3
- package/tests/e2e/helpers/params.js +17 -0
- package/tests/e2e/helpers/rightToLeft.js +4 -10
- package/tests/e2e/models/Navigation.js +13 -4
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +40 -33
- package/tests/jest/BookNavigator/book-navigator.test.js +658 -0
- package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
- package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
- package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
- package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
- package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
- package/tests/{karma/BookNavigator → jest/BookNavigator/search}/search-results.test.js +104 -60
- package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
- package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
- package/tests/jest/BookNavigator/volumes/volumes-provider.test.js +184 -0
- package/tests/jest/BookNavigator/volumes/volumes.test.js +97 -0
- package/tests/{BookReader → jest/BookReader}/BookModel.test.js +59 -14
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -0
- package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
- package/tests/jest/BookReader/Mode1UpLit.test.js +73 -0
- package/tests/jest/BookReader/Mode2Up.test.js +98 -0
- package/tests/jest/BookReader/Mode2UpLit.test.js +190 -0
- package/tests/jest/BookReader/ModeCoordinateSpace.test.js +16 -0
- package/tests/jest/BookReader/ModeSmoothZoom.test.js +175 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +10 -10
- package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +88 -6
- package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
- package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
- package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
- package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
- package/tests/jest/BookReader/utils.test.js +217 -0
- package/tests/jest/BookReader.keyboard.test.js +190 -0
- package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
- package/tests/{BookReader.test.js → jest/BookReader.test.js} +26 -37
- package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +4 -4
- package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +10 -11
- package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
- package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
- package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +39 -47
- package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
- package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +63 -47
- package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +35 -6
- package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +9 -9
- package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
- package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
- package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +47 -1
- package/tests/{plugins → jest/plugins}/tts/utils.test.js +1 -60
- package/tests/jest/plugins/url/UrlPlugin.test.js +190 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +53 -14
- package/tests/jest/setup.js +3 -0
- package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
- package/tests/jest/util/docCookies.test.js +24 -0
- package/tests/{util → jest/util}/strings.test.js +1 -1
- package/tests/{utils.js → jest/utils.js} +38 -0
- package/webpack.config.js +11 -5
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -14312
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/icons/sort-ascending.svg +0 -1
- package/BookReader/icons/sort-descending.svg +0 -1
- package/BookReader/jquery-1.10.1.js +0 -108
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -369
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
- package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
- package/karma.conf.js +0 -23
- package/src/BookNavigator/BookModel.js +0 -14
- package/src/BookNavigator/BookNavigator.js +0 -452
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
- package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
- package/src/BookNavigator/search/a-search-result.js +0 -55
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -372
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/assets/icons/sort-ascending.svg +0 -1
- package/src/assets/icons/sort-descending.svg +0 -1
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/Mode2Up.test.js +0 -247
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/e2e/ia-production/ia-prod-base.js +0 -17
- package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- package/tests/karma/BookNavigator/volumes.test.js +0 -101
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
- package/tests/util/docCookies.test.js +0 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
2
|
|
|
3
|
-
import '
|
|
4
|
-
import { BookreaderWithTextSelection, TextSelectionPlugin, Cache } from '
|
|
3
|
+
import '@/src/BookReader.js';
|
|
4
|
+
import { BookreaderWithTextSelection, TextSelectionPlugin, Cache } from '@/src/plugins/plugin.text_selection.js';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
/** @type {BookReader} */
|
|
@@ -19,30 +19,32 @@ const FAKE_XML_5COORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwosho
|
|
|
19
19
|
const FAKE_XML_EMPTY = '';
|
|
20
20
|
|
|
21
21
|
describe("Generic tests", () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{ width: 800, height: 1200,
|
|
29
|
-
uri: '//archive.org/download/BookReader/img/page001.jpg' },
|
|
30
|
-
],
|
|
31
|
-
[
|
|
32
|
-
{ width: 800, height: 1200,
|
|
33
|
-
uri: '//archive.org/download/BookReader/img/page002.jpg' },
|
|
34
|
-
{ width: 800, height: 1200,
|
|
35
|
-
uri: '//archive.org/download/BookReader/img/page003.jpg' },
|
|
36
|
-
],
|
|
37
|
-
[
|
|
38
|
-
{ width: 800, height: 1200,
|
|
39
|
-
uri: '//archive.org/download/BookReader/img/page004.jpg' },
|
|
40
|
-
{ width: 800, height: 1200,
|
|
41
|
-
uri: '//archive.org/download/BookReader/img/page005.jpg' },
|
|
42
|
-
]
|
|
22
|
+
document.body.innerHTML = '<div id="BookReader">';
|
|
23
|
+
const br = new BookreaderWithTextSelection({
|
|
24
|
+
data: [
|
|
25
|
+
[
|
|
26
|
+
{ width: 800, height: 1200,
|
|
27
|
+
uri: '//archive.org/download/BookReader/img/page001.jpg' },
|
|
43
28
|
],
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
[
|
|
30
|
+
{ width: 800, height: 1200,
|
|
31
|
+
uri: '//archive.org/download/BookReader/img/page002.jpg' },
|
|
32
|
+
{ width: 800, height: 1200,
|
|
33
|
+
uri: '//archive.org/download/BookReader/img/page003.jpg' },
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
{ width: 800, height: 1200,
|
|
37
|
+
uri: '//archive.org/download/BookReader/img/page004.jpg' },
|
|
38
|
+
{ width: 800, height: 1200,
|
|
39
|
+
uri: '//archive.org/download/BookReader/img/page005.jpg' },
|
|
40
|
+
]
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
br.init();
|
|
44
|
+
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
sinon.restore();
|
|
47
|
+
$('.textSelectionSVG').remove();
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
test("_createPageContainer overridden function still creates a BRpagecontainer element", () => {
|
|
@@ -72,8 +74,8 @@ describe("Generic tests", () => {
|
|
|
72
74
|
const $container = br.refs.$brContainer;
|
|
73
75
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
74
76
|
.returns($(new DOMParser().parseFromString(FAKE_XML_1WORD, "text/xml")));
|
|
75
|
-
const pageIndex = br.data.length - 1
|
|
76
|
-
await br.textSelectionPlugin.createTextLayer(pageIndex,
|
|
77
|
+
const pageIndex = br.data.length - 1;
|
|
78
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: pageIndex, width: 100, height: 100 }});
|
|
77
79
|
expect($container.find(".textSelectionSVG").length).toBe(1);
|
|
78
80
|
expect($container.find(".BRparagElement").length).toBe(1);
|
|
79
81
|
});
|
|
@@ -83,17 +85,7 @@ describe("Generic tests", () => {
|
|
|
83
85
|
const xml = FAKE_XML_1WORD.replace(/<WORD.*<\/WORD>/, FAKE_XML_1WORD.match(/<WORD.*<\/WORD>/)[0].repeat(3000));
|
|
84
86
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
85
87
|
.returns($(new DOMParser().parseFromString(xml, "text/xml")));
|
|
86
|
-
await br.textSelectionPlugin.createTextLayer(0,
|
|
87
|
-
expect($container.find(".textSelectionSVG").length).toBe(0);
|
|
88
|
-
expect($container.find(".BRparagElement").length).toBe(0);
|
|
89
|
-
expect($container.find(".BRwordElement").length).toBe(0);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// GRRRR!!! This is a useful test :( But can't get it working for some reason,
|
|
93
|
-
// and the error output is super cryptic.
|
|
94
|
-
test.skip("createTextLayer will not create text layer if index is more than total number of book pages", async () => {
|
|
95
|
-
const $container = br.refs.$brContainer;
|
|
96
|
-
await br.textSelectionPlugin.createTextLayer(150, $container);
|
|
88
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: 0, width: 100, height: 100 }});
|
|
97
89
|
expect($container.find(".textSelectionSVG").length).toBe(0);
|
|
98
90
|
expect($container.find(".BRparagElement").length).toBe(0);
|
|
99
91
|
expect($container.find(".BRwordElement").length).toBe(0);
|
|
@@ -103,7 +95,7 @@ describe("Generic tests", () => {
|
|
|
103
95
|
const $container = br.refs.$brContainer;
|
|
104
96
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
105
97
|
.returns($(new DOMParser().parseFromString(FAKE_XML_1WORD, "text/xml")));
|
|
106
|
-
await br.textSelectionPlugin.createTextLayer(1,
|
|
98
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: 1, width: 100, height: 100 }});
|
|
107
99
|
expect($container.find(".textSelectionSVG").length).toBe(1);
|
|
108
100
|
expect($container.find(".BRparagElement").length).toBe(1);
|
|
109
101
|
expect($container.find(".BRwordElement").length).toBe(1);
|
|
@@ -114,7 +106,7 @@ describe("Generic tests", () => {
|
|
|
114
106
|
const $container = br.refs.$brContainer;
|
|
115
107
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
116
108
|
.returns($(new DOMParser().parseFromString(FAKE_XML_MULT_WORDS, "text/xml")));
|
|
117
|
-
await br.textSelectionPlugin.createTextLayer(2,
|
|
109
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: 2, width: 100, height: 100 }});
|
|
118
110
|
expect($container.find(".textSelectionSVG").length).toBe(1);
|
|
119
111
|
expect($container.find(".BRparagElement").length).toBe(1);
|
|
120
112
|
expect($container.find(".BRwordElement").length).toBe(5);
|
|
@@ -125,7 +117,7 @@ describe("Generic tests", () => {
|
|
|
125
117
|
const $container = br.refs.$brContainer;
|
|
126
118
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
127
119
|
.returns($(new DOMParser().parseFromString(FAKE_XML_5COORDS, "text/xml")));
|
|
128
|
-
await br.textSelectionPlugin.createTextLayer(3,
|
|
120
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
|
|
129
121
|
expect($container.find(".textSelectionSVG").length).toBe(1);
|
|
130
122
|
expect($container.find(".BRparagElement").length).toBe(1);
|
|
131
123
|
expect($container.find(".BRwordElement").length).toBe(1);
|
|
@@ -135,7 +127,7 @@ describe("Generic tests", () => {
|
|
|
135
127
|
const $container = br.refs.$brContainer;
|
|
136
128
|
sinon.stub(br.textSelectionPlugin, "getPageText")
|
|
137
129
|
.returns($(new DOMParser().parseFromString(FAKE_XML_EMPTY, "text/xml")));
|
|
138
|
-
await br.textSelectionPlugin.createTextLayer(4,
|
|
130
|
+
await br.textSelectionPlugin.createTextLayer({ $container, page: { index: 4, width: 100, height: 100 }});
|
|
139
131
|
expect($container.find(".textSelectionSVG").length).toBe(1);
|
|
140
132
|
expect($container.find(".BRparagElement").length).toBe(0);
|
|
141
133
|
expect($container.find(".BRwordElement").length).toBe(0);
|
|
@@ -146,28 +138,28 @@ describe("Generic tests", () => {
|
|
|
146
138
|
const $container = br.refs.$brContainer;
|
|
147
139
|
br.textSelectionPlugin.stopPageFlip($container);
|
|
148
140
|
const currIndex = br.currentIndex();
|
|
149
|
-
$container.find("BRwordElement").mousedown
|
|
141
|
+
$container.find("BRwordElement").trigger("mousedown");
|
|
150
142
|
// Waits for long press
|
|
151
143
|
setTimeout(() => {
|
|
152
|
-
$container.find("BRwordElement").mousedown
|
|
144
|
+
$container.find("BRwordElement").trigger("mousedown");
|
|
153
145
|
// Waits for flipping animation
|
|
154
146
|
setTimeout(() => {
|
|
155
147
|
expect(br.currentIndex()).toBe(currIndex);
|
|
156
148
|
}, 2000);
|
|
157
149
|
}, LONG_PRESS_DURATION);
|
|
158
150
|
});
|
|
159
|
-
})
|
|
151
|
+
});
|
|
160
152
|
|
|
161
153
|
describe("textSelectionPlugin constructor", () => {
|
|
162
154
|
test("textSelectionPlugin constructor with firefox browser", () => {
|
|
163
|
-
const tsp = new TextSelectionPlugin({}, {}, true)
|
|
155
|
+
const tsp = new TextSelectionPlugin({}, {}, true);
|
|
164
156
|
expect(tsp.djvuPagesPromise).toBe(null);
|
|
165
157
|
expect(tsp.svgParagraphElement).toBe("g");
|
|
166
158
|
expect(tsp.svgWordElement).toBe("text");
|
|
167
159
|
});
|
|
168
160
|
|
|
169
161
|
test("textSelectionPlugin constructor not on firefox browser", () => {
|
|
170
|
-
const tsp = new TextSelectionPlugin({}, {}, false)
|
|
162
|
+
const tsp = new TextSelectionPlugin({}, {}, false);
|
|
171
163
|
expect(tsp.djvuPagesPromise).toBe(null);
|
|
172
164
|
expect(tsp.svgParagraphElement).toBe("text");
|
|
173
165
|
expect(tsp.svgWordElement).toBe("tspan");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import BookReader from '
|
|
3
|
-
import * as util from '
|
|
2
|
+
import BookReader from '@/src/BookReader.js';
|
|
3
|
+
import * as util from '@/src/plugins/plugin.vendor-fullscreen.js';
|
|
4
4
|
|
|
5
5
|
let br;
|
|
6
6
|
beforeEach(() => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import BookReader from '@/src/BookReader.js';
|
|
2
|
+
import '@/src/plugins/plugin.mobile_nav.js';
|
|
3
|
+
import { marshallSearchResults } from '@/src/plugins/search/plugin.search.js';
|
|
4
|
+
import { deepCopy } from '../../utils.js';
|
|
1
5
|
|
|
2
|
-
|
|
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');
|
|
6
|
+
jest.mock('@/src/plugins/search/view.js');
|
|
7
7
|
|
|
8
8
|
let br;
|
|
9
9
|
const namespace = 'BookReader:';
|
|
@@ -14,31 +14,33 @@ const triggeredEvents = () => {
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
const DUMMY_RESULTS = {
|
|
18
|
+
ia: "adventuresofoli00dick",
|
|
19
|
+
q: "child",
|
|
20
|
+
indexed: true,
|
|
21
|
+
page_count: 644,
|
|
22
|
+
body_length: 666,
|
|
23
|
+
leaf0_missing: false,
|
|
24
|
+
matches: [{
|
|
25
|
+
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.',
|
|
26
|
+
par: [{
|
|
27
|
+
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
|
28
|
+
b: 2535,
|
|
29
|
+
t: 1942,
|
|
30
|
+
page_width: 1790,
|
|
31
|
+
r: 1598,
|
|
32
|
+
l: 50,
|
|
33
|
+
page_height: 2940,
|
|
34
|
+
page: 37
|
|
35
|
+
}]
|
|
36
|
+
}]
|
|
37
|
+
};
|
|
38
|
+
|
|
17
39
|
beforeEach(() => {
|
|
18
40
|
$.ajax = jest.fn().mockImplementation(() => {
|
|
19
41
|
// return from:
|
|
20
42
|
// `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
|
-
});
|
|
43
|
+
return Promise.resolve(deepCopy(DUMMY_RESULTS));
|
|
42
44
|
});
|
|
43
45
|
|
|
44
46
|
$.fn.trigger = jest.fn();
|
|
@@ -46,6 +48,7 @@ beforeEach(() => {
|
|
|
46
48
|
br = new BookReader();
|
|
47
49
|
br.initToolbar = jest.fn();
|
|
48
50
|
br.showProgressPopup = jest.fn();
|
|
51
|
+
br.searchXHR = jest.fn();
|
|
49
52
|
});
|
|
50
53
|
|
|
51
54
|
afterEach(() => {
|
|
@@ -101,7 +104,7 @@ describe('Plugin: Search', () => {
|
|
|
101
104
|
expect(br.search.mock.calls[0][1])
|
|
102
105
|
.toHaveProperty('goToFirstResult', true);
|
|
103
106
|
expect(br.search.mock.calls[0][1])
|
|
104
|
-
.toHaveProperty('suppressFragmentChange',
|
|
107
|
+
.toHaveProperty('suppressFragmentChange', false);
|
|
105
108
|
});
|
|
106
109
|
|
|
107
110
|
test('calling `search` fires ajax call`', () => {
|
|
@@ -116,28 +119,30 @@ describe('Plugin: Search', () => {
|
|
|
116
119
|
expect(triggeredEvents()).toContain(`${namespace}SearchStarted`);
|
|
117
120
|
});
|
|
118
121
|
|
|
119
|
-
test('
|
|
122
|
+
test('SearchStarted event fires and should go to first result', () => {
|
|
120
123
|
br.init();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
br.search('foo', { goToFirstResult: true});
|
|
125
|
+
expect(br.options.goToFirstResult).toBeTruthy();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('SearchCallback event fires when AJAX search returns results', async () => {
|
|
129
|
+
br.init();
|
|
130
|
+
await br.search('foo');
|
|
131
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
|
|
125
132
|
});
|
|
126
133
|
|
|
127
|
-
test('SearchCallbackError event fires when AJAX search returns error', () => {
|
|
134
|
+
test('SearchCallbackError event fires when AJAX search returns error', async () => {
|
|
128
135
|
$.ajax = jest.fn().mockImplementation(() => {
|
|
129
136
|
return Promise.resolve({
|
|
130
137
|
error: true,
|
|
131
138
|
});
|
|
132
139
|
});
|
|
133
140
|
br.init();
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
|
|
137
|
-
});
|
|
141
|
+
await br.search('foo');
|
|
142
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
|
|
138
143
|
});
|
|
139
144
|
|
|
140
|
-
test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', () => {
|
|
145
|
+
test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', async () => {
|
|
141
146
|
$.ajax = jest.fn().mockImplementation(() => {
|
|
142
147
|
return Promise.resolve({
|
|
143
148
|
matches: [],
|
|
@@ -145,22 +150,33 @@ describe('Plugin: Search', () => {
|
|
|
145
150
|
});
|
|
146
151
|
});
|
|
147
152
|
br.init();
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
|
|
151
|
-
});
|
|
153
|
+
await br.search('foo');
|
|
154
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
|
|
152
155
|
});
|
|
153
156
|
|
|
154
|
-
test('SearchCallbackEmpty event fires when AJAX search returns no matches', () => {
|
|
157
|
+
test('SearchCallbackEmpty event fires when AJAX search returns no matches', async () => {
|
|
155
158
|
$.ajax = jest.fn().mockImplementation(() => {
|
|
156
159
|
return Promise.resolve({
|
|
157
160
|
matches: [],
|
|
158
161
|
});
|
|
159
162
|
});
|
|
160
163
|
br.init();
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
await br.search('foo');
|
|
165
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('marshallSearchResults', () => {
|
|
170
|
+
test('Adds match index', () => {
|
|
171
|
+
const results = deepCopy(DUMMY_RESULTS);
|
|
172
|
+
marshallSearchResults(results, x => x.toString());
|
|
173
|
+
expect(results.matches[0]).toHaveProperty('matchIndex', 0);
|
|
174
|
+
expect(results.matches[0].par[0].boxes[0]).toHaveProperty('matchIndex', 0);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('Adds display page number', () => {
|
|
178
|
+
const results = deepCopy(DUMMY_RESULTS);
|
|
179
|
+
marshallSearchResults(results, x => `n${x}`);
|
|
180
|
+
expect(results.matches[0]).toHaveProperty('displayPageNumber', 'n37');
|
|
165
181
|
});
|
|
166
182
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import BookReader from '
|
|
3
|
-
import '
|
|
4
|
-
import '
|
|
5
|
-
import '
|
|
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
6
|
|
|
7
7
|
let br;
|
|
8
8
|
const namespace = 'BookReader:';
|
|
@@ -27,6 +27,27 @@ const results = {
|
|
|
27
27
|
}]
|
|
28
28
|
}]
|
|
29
29
|
};
|
|
30
|
+
const resultWithScript = {
|
|
31
|
+
ia: "adventuresofoli00dick",
|
|
32
|
+
q: "child",
|
|
33
|
+
indexed: true,
|
|
34
|
+
page_count: 644,
|
|
35
|
+
body_length: 666,
|
|
36
|
+
leaf0_missing: false,
|
|
37
|
+
matches: [{
|
|
38
|
+
text: 'foo bar <script>alert(1);</script> {{{keyword}}} baz',
|
|
39
|
+
par: [{
|
|
40
|
+
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
|
41
|
+
b: 2535,
|
|
42
|
+
t: 1942,
|
|
43
|
+
page_width: 1790,
|
|
44
|
+
r: 1598,
|
|
45
|
+
l: 50,
|
|
46
|
+
page_height: 2940,
|
|
47
|
+
page: 37
|
|
48
|
+
}]
|
|
49
|
+
}]
|
|
50
|
+
};
|
|
30
51
|
beforeEach(() => {
|
|
31
52
|
$.ajax = jest.fn().mockImplementation(() => {
|
|
32
53
|
// return from:
|
|
@@ -63,14 +84,14 @@ describe('View: Plugin: Search', () => {
|
|
|
63
84
|
|
|
64
85
|
expect(br.searchView.dom.searchNavigation).toBeUndefined();
|
|
65
86
|
|
|
66
|
-
br.searchView.handleSearchCallback(event, { results, options})
|
|
87
|
+
br.searchView.handleSearchCallback(event, { results, options});
|
|
67
88
|
expect(br.searchView.dom.searchNavigation).toBeDefined();
|
|
68
89
|
});
|
|
69
90
|
test('has controls', () => {
|
|
70
91
|
br.init();
|
|
71
92
|
const event = new CustomEvent(`${namespace}SearchCallback`);
|
|
72
93
|
const options = { goToFirstResult: false };
|
|
73
|
-
br.searchView.handleSearchCallback(event, { results, options})
|
|
94
|
+
br.searchView.handleSearchCallback(event, { results, options});
|
|
74
95
|
|
|
75
96
|
const searchResultsNav = document.querySelector('.BRsearch-navigation');
|
|
76
97
|
expect(searchResultsNav).toBeDefined();
|
|
@@ -81,6 +102,14 @@ describe('View: Plugin: Search', () => {
|
|
|
81
102
|
expect(searchResultsNav.querySelector('.prev')).toBeDefined();
|
|
82
103
|
expect(searchResultsNav.querySelector('.next')).toBeDefined();
|
|
83
104
|
});
|
|
105
|
+
test('disallows xss from search results', () => {
|
|
106
|
+
br.init();
|
|
107
|
+
const event = new CustomEvent(`${namespace}SearchCallback`);
|
|
108
|
+
const options = { goToFirstResult: false };
|
|
109
|
+
br.searchView.handleSearchCallback(event, { results: resultWithScript, options });
|
|
110
|
+
|
|
111
|
+
expect(br.searchView.dom.searchNavigation.parent().html()).not.toContain('<script>alert(1);</script>');
|
|
112
|
+
});
|
|
84
113
|
|
|
85
114
|
describe('Click events handlers', () => {
|
|
86
115
|
it('triggers custom event when toggling side menu', () => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
2
|
import { afterEventLoop } from '../../utils.js';
|
|
3
|
-
import AbstractTTSEngine from '
|
|
4
|
-
import PageChunkIterator from '
|
|
5
|
-
/** @typedef {import('
|
|
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
6
|
|
|
7
7
|
// Skipping because it's flaky. Fix in #672
|
|
8
8
|
describe.skip('AbstractTTSEngine', () => {
|
|
9
|
-
test('stops playing once done', () => {
|
|
9
|
+
test('stops playing once done', async () => {
|
|
10
10
|
class DummyEngine extends AbstractTTSEngine {
|
|
11
11
|
getVoices() { return []; }
|
|
12
12
|
}
|
|
@@ -15,12 +15,12 @@ describe.skip('AbstractTTSEngine', () => {
|
|
|
15
15
|
const stopStub = sinon.stub(d, 'stop');
|
|
16
16
|
expect(stopStub.callCount).toBe(0);
|
|
17
17
|
d.step();
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
await afterEventLoop();
|
|
19
|
+
expect(stopStub.callCount).toBe(1);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
for (const dummyVoice of [
|
|
23
|
+
for (const dummyVoice of [dummyVoiceHyphens, dummyVoiceUnderscores]) {
|
|
24
24
|
describe(`getBestBookVoice with BCP47 ${dummyVoice == dummyVoiceUnderscores ? '+' : '-'} underscores`, () => {
|
|
25
25
|
const { getBestBookVoice } = AbstractTTSEngine;
|
|
26
26
|
|
|
@@ -130,7 +130,7 @@ export const DUMMY_TTS_ENGINE_OPTS = {
|
|
|
130
130
|
* @param {SpeechSynthesisVoice}
|
|
131
131
|
* @return {SpeechSynthesisVoice}
|
|
132
132
|
**/
|
|
133
|
-
function
|
|
133
|
+
function dummyVoiceHyphens(overrides) {
|
|
134
134
|
return Object.assign({
|
|
135
135
|
default: false,
|
|
136
136
|
lang: "en-US",
|
|
@@ -147,7 +147,7 @@ function dummyVoice(overrides) {
|
|
|
147
147
|
* @return {SpeechSynthesisVoice}
|
|
148
148
|
**/
|
|
149
149
|
function dummyVoiceUnderscores(overrides) {
|
|
150
|
-
const voice =
|
|
150
|
+
const voice = dummyVoiceHyphens(overrides);
|
|
151
151
|
voice.lang = voice.lang.replace('-', '_');
|
|
152
152
|
return voice;
|
|
153
153
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import FestivalTTSEngine from '
|
|
1
|
+
import FestivalTTSEngine from '@/src/plugins/tts/FestivalTTSEngine.js';
|
|
2
2
|
import sinon from 'sinon';
|
|
3
3
|
import { afterEventLoop } from '../../utils.js';
|
|
4
4
|
import { DUMMY_TTS_ENGINE_OPTS } from './AbstractTTSEngine.test.js';
|
|
5
|
-
import PageChunk from '
|
|
6
|
-
import PageChunkIterator from '
|
|
7
|
-
/** @typedef {import('
|
|
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
8
|
|
|
9
9
|
describe('iOSCaptureUserIntentHack', () => {
|
|
10
10
|
test('synchronously calls createSound/play to capture user intent', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
|
-
import PageChunkIterator from "
|
|
3
|
-
import PageChunk from '
|
|
2
|
+
import PageChunkIterator from "@/src/plugins/tts/PageChunkIterator";
|
|
3
|
+
import PageChunk from '@/src/plugins/tts/PageChunk';
|
|
4
4
|
|
|
5
5
|
describe('Buffers pages', () => {
|
|
6
6
|
test('Does not error if no room for reverse buffer', async () => {
|
|
@@ -109,7 +109,7 @@ describe('Iterates pages', () => {
|
|
|
109
109
|
expect(iterator._cursor.chunk).toBe(0);
|
|
110
110
|
|
|
111
111
|
for (let i = 2; i >= 0; i--) {
|
|
112
|
-
await iterator.decrement()
|
|
112
|
+
await iterator.decrement();
|
|
113
113
|
expect(iterator._cursor.page).toBe(49);
|
|
114
114
|
expect(iterator._cursor.chunk).toBe(i);
|
|
115
115
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
|
-
import { WebTTSSound } from '
|
|
2
|
+
import WebTTSEngine, { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
|
|
3
3
|
import { afterEventLoop, eventTargetMixin } from '../../utils.js';
|
|
4
4
|
|
|
5
5
|
beforeEach(() => {
|
|
@@ -8,6 +8,7 @@ beforeEach(() => {
|
|
|
8
8
|
speak: sinon.stub(),
|
|
9
9
|
pause: sinon.stub(),
|
|
10
10
|
resume: sinon.stub(),
|
|
11
|
+
|
|
11
12
|
...eventTargetMixin(),
|
|
12
13
|
};
|
|
13
14
|
window.SpeechSynthesisUtterance = function (text) {
|
|
@@ -21,6 +22,51 @@ afterEach(() => {
|
|
|
21
22
|
delete window.SpeechSynthesisUtterance;
|
|
22
23
|
});
|
|
23
24
|
|
|
25
|
+
describe('WebTTSEngine', () => {
|
|
26
|
+
test('getVoices should include default voice when no actual default', () => {
|
|
27
|
+
// iOS devices set all the voices to default -_-
|
|
28
|
+
speechSynthesis.getVoices = () => [
|
|
29
|
+
{
|
|
30
|
+
default: true,
|
|
31
|
+
lang: "ar-001",
|
|
32
|
+
localService: true,
|
|
33
|
+
name: "Majed",
|
|
34
|
+
voiceURI: "com.apple.voice.compact.ar-001.Maged",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
default: true,
|
|
38
|
+
lang: "bg-BG",
|
|
39
|
+
localService: true,
|
|
40
|
+
name: "Daria",
|
|
41
|
+
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
const voices = WebTTSEngine.prototype.getVoices();
|
|
45
|
+
expect(voices.length).toBe(3);
|
|
46
|
+
expect(voices[0].voiceURI).toBe('bookreader.SystemDefault');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('getVoices should not include default voice when there is a default', () => {
|
|
50
|
+
speechSynthesis.getVoices = () => [
|
|
51
|
+
{
|
|
52
|
+
default: true,
|
|
53
|
+
lang: "ar-001",
|
|
54
|
+
localService: true,
|
|
55
|
+
name: "Majed",
|
|
56
|
+
voiceURI: "com.apple.voice.compact.ar-001.Maged",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
default: false,
|
|
60
|
+
lang: "bg-BG",
|
|
61
|
+
localService: true,
|
|
62
|
+
name: "Daria",
|
|
63
|
+
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
|
|
64
|
+
}
|
|
65
|
+
];
|
|
66
|
+
const voices = WebTTSEngine.prototype.getVoices();
|
|
67
|
+
expect(voices.length).toBe(2);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
24
70
|
|
|
25
71
|
describe('WebTTSSound', () => {
|
|
26
72
|
describe('setPlaybackRate', () => {
|
|
@@ -1,38 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { afterEventLoop, eventTargetMixin } from '../../utils.js';
|
|
3
|
-
import * as utils from '../../../src/plugins/tts/utils.js';
|
|
4
|
-
|
|
5
|
-
describe('promisifyEvent', () => {
|
|
6
|
-
const { promisifyEvent } = utils;
|
|
7
|
-
|
|
8
|
-
test('Resolves once event fires', async () => {
|
|
9
|
-
const fakeTarget = eventTargetMixin();
|
|
10
|
-
const resolveSpy = sinon.spy();
|
|
11
|
-
promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
|
|
12
|
-
|
|
13
|
-
await afterEventLoop()
|
|
14
|
-
expect(resolveSpy.callCount).toBe(0);
|
|
15
|
-
fakeTarget.dispatchEvent('pause', {});
|
|
16
|
-
await afterEventLoop();
|
|
17
|
-
expect(resolveSpy.callCount).toBe(1);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('Only resolves once', async () => {
|
|
21
|
-
const fakeTarget = eventTargetMixin();
|
|
22
|
-
const resolveSpy = sinon.spy();
|
|
23
|
-
promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
|
|
24
|
-
|
|
25
|
-
await afterEventLoop()
|
|
26
|
-
expect(resolveSpy.callCount).toBe(0);
|
|
27
|
-
fakeTarget.dispatchEvent('pause', {});
|
|
28
|
-
fakeTarget.dispatchEvent('pause', {});
|
|
29
|
-
fakeTarget.dispatchEvent('pause', {});
|
|
30
|
-
fakeTarget.dispatchEvent('pause', {});
|
|
31
|
-
|
|
32
|
-
await afterEventLoop();
|
|
33
|
-
expect(resolveSpy.callCount).toBe(1);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
1
|
+
import * as utils from '@/src/plugins/tts/utils.js';
|
|
36
2
|
|
|
37
3
|
describe('approximateWordCount', () => {
|
|
38
4
|
const { approximateWordCount } = utils;
|
|
@@ -66,31 +32,6 @@ describe('approximateWordCount', () => {
|
|
|
66
32
|
});
|
|
67
33
|
});
|
|
68
34
|
|
|
69
|
-
describe('sleep', () => {
|
|
70
|
-
const { sleep } = utils;
|
|
71
|
-
|
|
72
|
-
test('Sleep 0 doest not called immediately', async () => {
|
|
73
|
-
const spy = sinon.spy();
|
|
74
|
-
sleep(0).then(spy);
|
|
75
|
-
expect(spy.callCount).toBe(0);
|
|
76
|
-
await afterEventLoop();
|
|
77
|
-
expect(spy.callCount).toBe(1);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test('Waits the appropriate ms', async () => {
|
|
81
|
-
const clock = sinon.useFakeTimers();
|
|
82
|
-
const spy = sinon.spy();
|
|
83
|
-
sleep(10).then(spy);
|
|
84
|
-
expect(spy.callCount).toBe(0);
|
|
85
|
-
clock.tick(10);
|
|
86
|
-
expect(spy.callCount).toBe(0);
|
|
87
|
-
clock.restore();
|
|
88
|
-
|
|
89
|
-
await afterEventLoop();
|
|
90
|
-
expect(spy.callCount).toBe(1);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
35
|
describe('toISO6391', () => {
|
|
95
36
|
const { toISO6391 } = utils;
|
|
96
37
|
|