@internetarchive/bookreader 5.0.0-113 → 5.0.0-115
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.map +1 -1
- package/BookReader/BookReader.css +34 -10
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +20 -38
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +1 -1
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.experiments.js +1 -1
- package/BookReader/plugins/plugin.experiments.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +1 -1
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.iiif.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +1 -1
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +1 -1
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.translate.js +1 -1
- package/BookReader/plugins/plugin.translate.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +1 -1
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReader/plugins/translator-worker.js.map +1 -1
- package/BookReader/webcomponents-bundle.js.map +1 -1
- package/package.json +37 -31
- package/src/BookReader/utils/SelectionObserver.js +4 -2
- package/src/BookReader.js +2 -1
- package/src/css/_TextSelection.scss +32 -11
- package/src/ia-bookreader/ia-bookreader.js +13 -2
- package/src/plugins/plugin.experiments.js +13 -3
- package/src/plugins/plugin.iiif.js +7 -1
- package/src/plugins/plugin.text_selection.js +8 -1
- package/src/plugins/tts/WebTTSEngine.js +2 -2
- package/src/plugins/tts/plugin.tts.js +3 -3
- package/src/plugins/tts/utils.js +0 -19
- package/src/util/TextSelectionManager.js +276 -110
- package/src/util/browserSniffing.js +9 -0
- package/src/util/strings.js +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/bookreader",
|
|
3
|
-
"version": "5.0.0-
|
|
3
|
+
"version": "5.0.0-115",
|
|
4
4
|
"description": "The Internet Archive BookReader.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -32,21 +32,21 @@
|
|
|
32
32
|
"private": false,
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@internetarchive/bergamot-translator": "^0.4.9-ia.1",
|
|
35
|
-
"@internetarchive/ia-activity-indicator": "0.0
|
|
36
|
-
"@internetarchive/ia-item-navigator": "2.2.
|
|
37
|
-
"@internetarchive/icon-bookmark": "
|
|
38
|
-
"@internetarchive/icon-close": "1.4.
|
|
39
|
-
"@internetarchive/icon-dl": "
|
|
40
|
-
"@internetarchive/icon-edit-pencil": "
|
|
41
|
-
"@internetarchive/icon-ia-logo": "1.4.
|
|
42
|
-
"@internetarchive/icon-magnify-minus": "
|
|
43
|
-
"@internetarchive/icon-magnify-plus": "
|
|
44
|
-
"@internetarchive/icon-search": "
|
|
45
|
-
"@internetarchive/icon-share": "1.4.
|
|
46
|
-
"@internetarchive/icon-toc": "
|
|
47
|
-
"@internetarchive/icon-visual-adjustment": "
|
|
48
|
-
"@internetarchive/modal-manager": "2.0.
|
|
49
|
-
"@internetarchive/shared-resize-observer": "
|
|
35
|
+
"@internetarchive/ia-activity-indicator": "1.0.0",
|
|
36
|
+
"@internetarchive/ia-item-navigator": "2.2.3",
|
|
37
|
+
"@internetarchive/icon-bookmark": "1.4.1",
|
|
38
|
+
"@internetarchive/icon-close": "1.4.1",
|
|
39
|
+
"@internetarchive/icon-dl": "1.4.1",
|
|
40
|
+
"@internetarchive/icon-edit-pencil": "1.4.1",
|
|
41
|
+
"@internetarchive/icon-ia-logo": "1.4.1",
|
|
42
|
+
"@internetarchive/icon-magnify-minus": "1.4.1",
|
|
43
|
+
"@internetarchive/icon-magnify-plus": "1.4.1",
|
|
44
|
+
"@internetarchive/icon-search": "1.4.1",
|
|
45
|
+
"@internetarchive/icon-share": "1.4.1",
|
|
46
|
+
"@internetarchive/icon-toc": "1.4.1",
|
|
47
|
+
"@internetarchive/icon-visual-adjustment": "1.4.1",
|
|
48
|
+
"@internetarchive/modal-manager": "2.0.6",
|
|
49
|
+
"@internetarchive/shared-resize-observer": "0.2.0",
|
|
50
50
|
"interactjs": "^1.10.18",
|
|
51
51
|
"iso-language-codes": "2.0.0",
|
|
52
52
|
"jquery": "3.6.1",
|
|
@@ -58,36 +58,36 @@
|
|
|
58
58
|
"soundmanager2": "2.97.20170602"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@babel/core": "7.29.
|
|
62
|
-
"@babel/eslint-parser": "7.
|
|
61
|
+
"@babel/core": "7.29.7",
|
|
62
|
+
"@babel/eslint-parser": "7.29.7",
|
|
63
63
|
"@babel/plugin-proposal-class-properties": "7.18.6",
|
|
64
|
-
"@babel/plugin-proposal-decorators": "7.29.
|
|
65
|
-
"@babel/preset-env": "7.29.
|
|
66
|
-
"@iiif/presentation-2": "
|
|
67
|
-
"@iiif/presentation-3": "
|
|
64
|
+
"@babel/plugin-proposal-decorators": "7.29.7",
|
|
65
|
+
"@babel/preset-env": "7.29.7",
|
|
66
|
+
"@iiif/presentation-2": "1.0.4",
|
|
67
|
+
"@iiif/presentation-3": "2.2.3",
|
|
68
68
|
"@open-wc/testing-helpers": "3.0.1",
|
|
69
69
|
"@types/jest": "30.0.0",
|
|
70
70
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
|
71
71
|
"babel-loader": "10.1.1",
|
|
72
|
-
"concurrently": "
|
|
72
|
+
"concurrently": "10.0.3",
|
|
73
73
|
"core-js": "3.49.0",
|
|
74
|
-
"cpx2": "
|
|
74
|
+
"cpx2": "9.0.0",
|
|
75
75
|
"eslint": "7.32.0",
|
|
76
76
|
"eslint-plugin-no-jquery": "^2.7.0",
|
|
77
77
|
"eslint-plugin-testcafe": "0.2.1",
|
|
78
78
|
"http-server": "14.1.1",
|
|
79
79
|
"hypothesis": "^1.1627.0",
|
|
80
|
-
"jest": "30.
|
|
81
|
-
"jest-environment-jsdom": "30.
|
|
80
|
+
"jest": "30.4.2",
|
|
81
|
+
"jest-environment-jsdom": "30.4.1",
|
|
82
82
|
"live-server": "1.2.2",
|
|
83
83
|
"regenerator-runtime": "0.14.1",
|
|
84
|
-
"sass": "1.
|
|
85
|
-
"sinon": "
|
|
84
|
+
"sass": "1.100.0",
|
|
85
|
+
"sinon": "22.0.0",
|
|
86
86
|
"svgo": "4.0.1",
|
|
87
87
|
"testcafe": "3.7.4",
|
|
88
88
|
"testcafe-browser-provider-browserstack": "1.15.2",
|
|
89
|
-
"webpack": "5.
|
|
90
|
-
"webpack-cli": "7.0.
|
|
89
|
+
"webpack": "5.107.2",
|
|
90
|
+
"webpack-cli": "7.0.3"
|
|
91
91
|
},
|
|
92
92
|
"jest": {
|
|
93
93
|
"testEnvironment": "jsdom",
|
|
@@ -133,7 +133,13 @@
|
|
|
133
133
|
"test:e2e:dev": "npx testcafe --live --dev",
|
|
134
134
|
"DOCS:update:test-deps": "If CI succeeds, these should be good to update",
|
|
135
135
|
"update:test-deps": "npm i @babel/eslint-parser@latest @open-wc/testing-helpers@latest @types/jest@latest eslint@7 eslint-plugin-testcafe@latest jest@latest jest-environment-jsdom@latest sinon@latest testcafe@latest",
|
|
136
|
+
"update:test-deps:test": "npm run lint && npm run test && npm run test:e2e",
|
|
136
137
|
"DOCS:update:build-deps": "These can cause strange changes, so do an npm run build + check file size (git diff --stat), and check the site is as expected",
|
|
137
|
-
"update:build-deps": "npm i @babel/core@latest @babel/preset-env@latest @babel/plugin-proposal-class-properties@latest @babel/plugin-proposal-decorators@latest babel-loader@latest core-js@latest regenerator-runtime@latest sass@latest svgo@latest webpack@latest webpack-cli@latest"
|
|
138
|
+
"update:build-deps": "npm i @babel/core@latest @babel/preset-env@latest @babel/plugin-proposal-class-properties@latest @babel/plugin-proposal-decorators@latest babel-loader@latest core-js@latest regenerator-runtime@latest sass@latest svgo@latest webpack@latest webpack-cli@latest",
|
|
139
|
+
"update:build-deps:test": "npm run build",
|
|
140
|
+
"DOCS:update:dev-deps": "Packages used for development",
|
|
141
|
+
"update:dev-deps": "npm i @iiif/presentation-2@latest @iiif/presentation-3@latest concurrently@latest cpx2@latest http-server@latest live-server@latest",
|
|
142
|
+
"DOCS:update:ia-deps": "Packages by @internetarchive",
|
|
143
|
+
"update:ia-deps": "npm i @internetarchive/ia-activity-indicator@latest @internetarchive/ia-item-navigator@latest @internetarchive/icon-bookmark@latest @internetarchive/icon-close@latest @internetarchive/icon-dl@latest @internetarchive/icon-edit-pencil@latest @internetarchive/icon-ia-logo@latest @internetarchive/icon-magnify-minus@latest @internetarchive/icon-magnify-plus@latest @internetarchive/icon-search@latest @internetarchive/icon-share@latest @internetarchive/icon-toc@latest @internetarchive/icon-visual-adjustment@latest @internetarchive/modal-manager@latest @internetarchive/shared-resize-observer@latest"
|
|
138
144
|
}
|
|
139
145
|
}
|
|
@@ -4,7 +4,7 @@ export class SelectionObserver {
|
|
|
4
4
|
startedInSelector = false;
|
|
5
5
|
/** @type {HTMLElement} */
|
|
6
6
|
target = null;
|
|
7
|
-
/** @type {Node} */
|
|
7
|
+
/** @type {Node | null} */
|
|
8
8
|
lastKnownFocusNode = null;
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -30,6 +30,7 @@ export class SelectionObserver {
|
|
|
30
30
|
|
|
31
31
|
_onSelectionChange = () => {
|
|
32
32
|
const sel = window.getSelection();
|
|
33
|
+
if (!sel) return;
|
|
33
34
|
|
|
34
35
|
if (!this.selecting && sel.toString()) {
|
|
35
36
|
const target = $(sel.anchorNode).closest(this.selector)[0];
|
|
@@ -40,13 +41,14 @@ export class SelectionObserver {
|
|
|
40
41
|
this.handler('started', this.target);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
if (this.selecting &&
|
|
44
|
+
if (this.selecting && this.lastKnownFocusNode != sel.focusNode && sel.toString() && !sel.isCollapsed) {
|
|
44
45
|
this.lastKnownFocusNode = sel.focusNode;
|
|
45
46
|
this.handler('changed', this.target);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
if (this.selecting && (sel.isCollapsed || !sel.toString() || !$(sel.anchorNode).closest(this.selector)[0])) {
|
|
49
50
|
this.selecting = false;
|
|
51
|
+
this.lastKnownFocusNode = null;
|
|
50
52
|
this.handler('cleared', this.target);
|
|
51
53
|
}
|
|
52
54
|
};
|
package/src/BookReader.js
CHANGED
|
@@ -151,7 +151,7 @@ BookReader.defaultOptions = DEFAULT_OPTIONS;
|
|
|
151
151
|
* @type {BookReaderOptions}
|
|
152
152
|
* This is here, just in case you need to absolutely override an option.
|
|
153
153
|
*/
|
|
154
|
-
BookReader.optionOverrides = {};
|
|
154
|
+
BookReader.optionOverrides = BookReader.optionOverrides || {};
|
|
155
155
|
|
|
156
156
|
/**
|
|
157
157
|
* Setup
|
|
@@ -852,6 +852,7 @@ BookReader.prototype.setupKeyListeners = function () {
|
|
|
852
852
|
|
|
853
853
|
// Ignore if modifiers are active.
|
|
854
854
|
if (e.getModifierState('Control') ||
|
|
855
|
+
e.getModifierState('Shift') ||
|
|
855
856
|
e.getModifierState('Alt') ||
|
|
856
857
|
e.getModifierState('Meta') ||
|
|
857
858
|
e.getModifierState('Win') /* hack for IE */) {
|
|
@@ -149,10 +149,20 @@
|
|
|
149
149
|
display: none;
|
|
150
150
|
border-radius: 20px;
|
|
151
151
|
background-color: #333;
|
|
152
|
+
color: white;
|
|
152
153
|
color-scheme: dark;
|
|
153
154
|
padding: 2px;
|
|
154
155
|
overflow: hidden;
|
|
155
|
-
|
|
156
|
+
opacity: 1;
|
|
157
|
+
transition: border-radius 0.2s, opacity 0.2s;
|
|
158
|
+
|
|
159
|
+
@starting-style {
|
|
160
|
+
opacity: 0;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
.br-select-menu__root--scrolling {
|
|
164
|
+
opacity: 0;
|
|
165
|
+
pointer-events: none;
|
|
156
166
|
}
|
|
157
167
|
.br-select-menu__root:hover {
|
|
158
168
|
border-radius: 8px;
|
|
@@ -171,6 +181,7 @@
|
|
|
171
181
|
align-items: center;
|
|
172
182
|
border-radius: 20px;
|
|
173
183
|
font-family: inherit;
|
|
184
|
+
color: inherit;
|
|
174
185
|
border: 0;
|
|
175
186
|
transition: background-color 0.2s, border-radius 0.2s;
|
|
176
187
|
cursor: pointer;
|
|
@@ -190,18 +201,23 @@
|
|
|
190
201
|
}
|
|
191
202
|
|
|
192
203
|
.br-select-menu__label {
|
|
193
|
-
|
|
194
|
-
opacity: 0;
|
|
195
|
-
interpolate-size: allow-keywords;
|
|
196
|
-
transition: width 0.2s;
|
|
204
|
+
margin-left: 4px;
|
|
197
205
|
font-size: 12px;
|
|
198
206
|
}
|
|
199
207
|
|
|
200
|
-
|
|
201
|
-
.br-select-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
208
|
+
@media (hover: hover) {
|
|
209
|
+
.br-select-menu__label {
|
|
210
|
+
width: 0px;
|
|
211
|
+
margin-left: 0;
|
|
212
|
+
opacity: 0;
|
|
213
|
+
interpolate-size: allow-keywords;
|
|
214
|
+
transition: width 0.2s;
|
|
215
|
+
}
|
|
216
|
+
.br-select-menu__root:hover .br-select-menu__label {
|
|
217
|
+
width: auto;
|
|
218
|
+
margin-left: 4px;
|
|
219
|
+
opacity: 1;
|
|
220
|
+
}
|
|
205
221
|
}
|
|
206
222
|
|
|
207
223
|
.BRtextLayer .BRhighlight {
|
|
@@ -210,9 +226,14 @@
|
|
|
210
226
|
color: transparent;
|
|
211
227
|
}
|
|
212
228
|
|
|
213
|
-
|
|
229
|
+
@keyframes highlightTargetFlash {
|
|
230
|
+
to { background-color: hsla(45, 80%, 66%, 1); }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Style URI TextFragments, eg ?text=example
|
|
214
234
|
.BRtextLayer .BRhighlight--target-text, .BRtextLayer ::target-text {
|
|
215
235
|
// Similar colour to the default one used in Safari, Firefox. Note Chrome uses a purple colour
|
|
216
236
|
background-color: hsla(45, 80%, 66%, 0.6);
|
|
217
237
|
color: transparent;
|
|
238
|
+
animation: highlightTargetFlash 600ms 1 reverse;
|
|
218
239
|
}
|
|
@@ -302,8 +302,11 @@ export class IaBookReader extends LitElement {
|
|
|
302
302
|
providers.bookmarks = new BookmarksProvider({
|
|
303
303
|
...this.baseProviderConfig,
|
|
304
304
|
onProviderChange: (bookmarks) => {
|
|
305
|
-
|
|
306
|
-
|
|
305
|
+
if (Object.keys(bookmarks).length) {
|
|
306
|
+
this.addMenuShortcut('bookmarks');
|
|
307
|
+
} else {
|
|
308
|
+
this.removeMenuShortcut('bookmarks');
|
|
309
|
+
}
|
|
307
310
|
this.updateMenuContents();
|
|
308
311
|
},
|
|
309
312
|
});
|
|
@@ -463,6 +466,14 @@ export class IaBookReader extends LitElement {
|
|
|
463
466
|
this._sortMenuShortcuts();
|
|
464
467
|
}
|
|
465
468
|
|
|
469
|
+
/**
|
|
470
|
+
* @param {string} menuId
|
|
471
|
+
*/
|
|
472
|
+
removeMenuShortcut(menuId) {
|
|
473
|
+
this.menuShortcuts = this.menuShortcuts.filter((m) => m.id !== menuId);
|
|
474
|
+
this._sortMenuShortcuts();
|
|
475
|
+
}
|
|
476
|
+
|
|
466
477
|
/**
|
|
467
478
|
* Sorts the menuShortcuts property by comparing each provider's id to
|
|
468
479
|
* the id in each iteration over the shortcutOrder array.
|
|
@@ -52,8 +52,11 @@ export class ExperimentsPlugin extends BookReaderPlugin {
|
|
|
52
52
|
/** Where the state of this plugin is saved in localStorage */
|
|
53
53
|
localStorageKey: 'BrExperiments',
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
|
|
55
|
+
/** @type {ExperimentName[]} Experiments shown in the experiments panel */
|
|
56
|
+
availableExperiments: ['translate', 'copyLinkToHighlight'],
|
|
57
|
+
|
|
58
|
+
/** @type {ExperimentName[]} Experiments enabled by default */
|
|
59
|
+
autoEnabledExperiments: [],
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
/** @type {ExperimentModel[]} */
|
|
@@ -160,7 +163,14 @@ export class ExperimentsPlugin extends BookReaderPlugin {
|
|
|
160
163
|
if (experiment.icon) {
|
|
161
164
|
experiment.icon = experiment.buildAssetPath(experiment.icon);
|
|
162
165
|
}
|
|
166
|
+
|
|
163
167
|
experiment.br = this.br;
|
|
168
|
+
|
|
169
|
+
// Enable any experiments that should be automatically enabled
|
|
170
|
+
if (!experiment.enabled && this.options.autoEnabledExperiments.includes(experiment.name)) {
|
|
171
|
+
experiment.enabled = true;
|
|
172
|
+
await experiment.enable({ manual: false });
|
|
173
|
+
}
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
this._loadExperimentStates();
|
|
@@ -222,7 +232,7 @@ export class ExperimentsPlugin extends BookReaderPlugin {
|
|
|
222
232
|
`,
|
|
223
233
|
label: 'Experiments',
|
|
224
234
|
component: html`<br-experiments-panel
|
|
225
|
-
.experiments="${this.allExperiments.filter(experiment => this.options.
|
|
235
|
+
.experiments="${this.allExperiments.filter(experiment => this.options.availableExperiments.includes(experiment.name))}"
|
|
226
236
|
@connected="${e => this._panel = e.target}"
|
|
227
237
|
@toggle="${async e => {
|
|
228
238
|
await this._toggleExperiment(e.detail.experiment, e.detail.enabled);
|
|
@@ -3,13 +3,19 @@ import { BookReaderPlugin } from '../BookReaderPlugin.js';
|
|
|
3
3
|
|
|
4
4
|
const BookReader = /** @type {typeof import('../BookReader').default} */(window.BookReader);
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @extends BookReaderPlugin<IiifPlugin['options']>
|
|
8
|
+
*/
|
|
6
9
|
export class IiifPlugin extends BookReaderPlugin {
|
|
7
10
|
options = {
|
|
8
11
|
enabled: true,
|
|
9
|
-
/** @type {import('@iiif/presentation-3').Manifest | import('@iiif/presentation-2').Manifest} */
|
|
12
|
+
/** @type {import('@iiif/presentation-3').Manifest | import('@iiif/presentation-2').Manifest | null} */
|
|
10
13
|
manifest: null,
|
|
11
14
|
}
|
|
12
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @param {IiifPlugin['options']} options
|
|
18
|
+
*/
|
|
13
19
|
setup(options) {
|
|
14
20
|
super.setup(options);
|
|
15
21
|
this.manifest = this.options.manifest;
|
|
@@ -36,6 +36,8 @@ export class TextSelectionPlugin extends BookReaderPlugin {
|
|
|
36
36
|
*/
|
|
37
37
|
maxWordRendered = 2500;
|
|
38
38
|
|
|
39
|
+
_jumpedToHighlight = false;
|
|
40
|
+
|
|
39
41
|
/**
|
|
40
42
|
* @param {import('../BookReader.js').default} br
|
|
41
43
|
*/
|
|
@@ -71,7 +73,12 @@ export class TextSelectionPlugin extends BookReaderPlugin {
|
|
|
71
73
|
const pageIndex = targetTextFragment.pageIndex;
|
|
72
74
|
const hasTargetText = pageIndex === parseFloat(pageContainerEl.getAttribute('data-index'));
|
|
73
75
|
if (hasTargetText) {
|
|
74
|
-
renderHighlight(textLayer, targetTextFragment, 'BRhighlight--target-text');
|
|
76
|
+
const markEls = renderHighlight(textLayer, targetTextFragment, 'BRhighlight--target-text');
|
|
77
|
+
// Only jump once; presumably on first page load.
|
|
78
|
+
if (!this._jumpedToHighlight) {
|
|
79
|
+
markEls[0].scrollIntoView({behavior: 'smooth', block: 'center'});
|
|
80
|
+
this._jumpedToHighlight = true;
|
|
81
|
+
}
|
|
75
82
|
}
|
|
76
83
|
});
|
|
77
84
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* global br */
|
|
2
|
-
import { isChrome, isFirefox } from '../../util/browserSniffing.js';
|
|
3
|
-
import {
|
|
2
|
+
import { isChrome, isFirefox, isAndroid } from '../../util/browserSniffing.js';
|
|
3
|
+
import { DEBUG_READ_ALOUD } from './utils.js';
|
|
4
4
|
import { promisifyEvent, sleep } from '../../BookReader/utils.js';
|
|
5
5
|
import AbstractTTSEngine from './AbstractTTSEngine.js';
|
|
6
6
|
/** @typedef {import("./AbstractTTSEngine.js").PageChunk} PageChunk */
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import FestivalTTSEngine from './FestivalTTSEngine.js';
|
|
4
4
|
import WebTTSEngine from './WebTTSEngine.js';
|
|
5
|
-
import { toISO6391
|
|
5
|
+
import { toISO6391 } from './utils.js';
|
|
6
6
|
import { en as tooltips } from './tooltip_dict.js';
|
|
7
7
|
import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
|
|
8
8
|
import { BookReaderPlugin } from '../../BookReaderPlugin.js';
|
|
9
|
-
import { applyVariables } from '../../util/strings.js';
|
|
9
|
+
import { applyVariables, countWords } from '../../util/strings.js';
|
|
10
10
|
/** @typedef {import('./PageChunk.js').default} PageChunk */
|
|
11
11
|
/** @typedef {import("./AbstractTTSEngine.js").default} AbstractTTSEngine */
|
|
12
12
|
|
|
@@ -291,7 +291,7 @@ export class TtsPlugin extends BookReaderPlugin {
|
|
|
291
291
|
* @param {PageChunk} chunk
|
|
292
292
|
*/
|
|
293
293
|
sendChunkFinishedAnalyticsEvent(chunk) {
|
|
294
|
-
this.sendAnalyticsEvent('ChunkFinished-Words',
|
|
294
|
+
this.sendAnalyticsEvent('ChunkFinished-Words', countWords(chunk.text));
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
/**
|
package/src/plugins/tts/utils.js
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import langs from 'iso-language-codes';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Use regex to approximate word count in a string
|
|
6
|
-
* @param {string} text
|
|
7
|
-
* @return {number}
|
|
8
|
-
*/
|
|
9
|
-
export function approximateWordCount(text) {
|
|
10
|
-
const m = text.match(/\S+/g);
|
|
11
|
-
return m ? m.length : 0;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Checks whether the current browser is on android
|
|
16
|
-
* @param {string} [userAgent]
|
|
17
|
-
* @return {boolean}
|
|
18
|
-
*/
|
|
19
|
-
export function isAndroid(userAgent = navigator.userAgent) {
|
|
20
|
-
return /android/i.test(userAgent);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
4
|
/** @type {{[lang: string]: string}} */
|
|
24
5
|
// Handle odd one-off language pairs that might show up over time
|
|
25
6
|
const specialLangs = {
|