@internetarchive/bookreader 5.0.0-42-a2 → 5.0.0-44-a1
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/.github/workflows/node.js.yml +14 -14
- package/.github/workflows/npm-publish.yml +4 -4
- package/BookReader/BookReader.css +14 -15
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +87 -87
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/images/BRicons.svg +2 -2
- package/BookReader/images/books_graphic.svg +1 -1
- package/BookReader/images/icon_book.svg +1 -1
- package/BookReader/images/icon_gear.svg +1 -1
- package/BookReader/images/icon_info.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_speaker.svg +1 -1
- package/BookReader/images/icon_speaker_open.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/jquery-1.10.1.js +1 -1
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +6 -6
- package/BookReader/plugins/plugin.archive_analytics.js +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +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.tts.js +1 -1
- 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/BookReaderDemo/IADemoBr.js +30 -0
- package/BookReaderDemo/demo-internetarchive.html +3 -0
- package/CHANGELOG.md +9 -0
- package/babel.config.js +1 -1
- package/package.json +22 -27
- package/renovate.json +13 -4
- package/scripts/preversion.js +4 -1
- package/src/BookNavigator/book-navigator.js +4 -0
- package/src/BookNavigator/downloads/downloads-provider.js +14 -5
- package/src/BookNavigator/downloads/downloads.js +23 -1
- package/src/BookNavigator/search/a-search-result.js +4 -6
- package/src/css/_controls.scss +1 -2
- package/src/plugins/search/plugin.search.js +17 -4
- package/src/plugins/search/view.js +1 -3
- package/src/plugins/tts/plugin.tts.js +15 -3
- package/tests/{karma → jest}/BookNavigator/book-navigator.test.js +119 -104
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-button.test.js +13 -14
- 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/{karma → jest}/BookNavigator/downloads/downloads-provider.test.js +18 -18
- package/tests/{karma → jest}/BookNavigator/downloads/downloads.test.js +7 -8
- package/tests/{karma → jest}/BookNavigator/search/search-provider.test.js +29 -29
- package/tests/{karma → jest}/BookNavigator/search/search-results.test.js +57 -56
- package/tests/{karma → jest}/BookNavigator/sharing/sharing-provider.test.js +8 -8
- package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
- package/tests/{karma → jest}/BookNavigator/volumes/volumes-provider.test.js +38 -38
- package/tests/{karma → jest}/BookNavigator/volumes/volumes.test.js +15 -16
- package/tests/jest/plugins/search/plugin.search.test.js +40 -23
- package/tests/jest/plugins/tts/AbstractTTSEngine.test.js +3 -3
- package/karma.conf.js +0 -23
- package/tests/karma/BookNavigator/bookmarks/ia-bookmarks.test.js +0 -57
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
@@ -14,6 +14,25 @@ const searchTerm = urlParams.get('q');
|
|
14
14
|
|
15
15
|
const iaBookReader = document.querySelector('ia-bookreader');
|
16
16
|
|
17
|
+
const downloadListWithLCP = [
|
18
|
+
[
|
19
|
+
"PDF",
|
20
|
+
"regular pdf link"
|
21
|
+
],
|
22
|
+
[
|
23
|
+
"lcpPDF",
|
24
|
+
"link to lcp pdf"
|
25
|
+
],
|
26
|
+
[
|
27
|
+
"ePub",
|
28
|
+
"link to epub"
|
29
|
+
],
|
30
|
+
[
|
31
|
+
"lcpEPUB",
|
32
|
+
"link to lcp epub"
|
33
|
+
]
|
34
|
+
];
|
35
|
+
|
17
36
|
if (openFullImmersionTheater) {
|
18
37
|
$(document.body).addClass('BRfullscreenActive');
|
19
38
|
iaBookReader.fullscreen = openFullImmersionTheater;
|
@@ -78,6 +97,17 @@ const initializeBookReader = (brManifest) => {
|
|
78
97
|
|
79
98
|
window.initializeBookReader = initializeBookReader;
|
80
99
|
|
100
|
+
const showLCP = document.querySelector('#show-lcp');
|
101
|
+
showLCP.addEventListener('click', async () => {
|
102
|
+
const iaBr = document.querySelector('ia-bookreader');
|
103
|
+
const bookNav = iaBr.shadowRoot.querySelector('book-navigator');
|
104
|
+
|
105
|
+
bookNav.downloadableTypes = downloadListWithLCP;
|
106
|
+
|
107
|
+
bookNav.updateMenuContents();
|
108
|
+
await bookNav.updateComplete;
|
109
|
+
});
|
110
|
+
|
81
111
|
const multiVolume = document.querySelector('#multi-volume');
|
82
112
|
multiVolume.addEventListener('click', () => {
|
83
113
|
// remove everything
|
@@ -77,6 +77,9 @@
|
|
77
77
|
<p>Features behind signed in gate: Bookmarks</p>
|
78
78
|
<p>Logged In Status: <span id="logged-in-status">Logged Out</span></p>
|
79
79
|
</div>
|
80
|
+
<div class="demo">
|
81
|
+
<button id="show-lcp">LCP Download option</button>
|
82
|
+
</div>
|
80
83
|
<div class="demo">
|
81
84
|
<button id="multi-volume">Multiple books</button>
|
82
85
|
</div>
|
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 5.0.0-43
|
2
|
+
Fix: search results panel display asserted page numbers @cdrini
|
3
|
+
Dev: dependency updates @renovate
|
4
|
+
Dev: node-fetch update @cdrini
|
5
|
+
|
6
|
+
# 5.0.0-42
|
7
|
+
Dev: update testing dependencies @renovate
|
8
|
+
Dev: update `<ia-item-navigator>` @iisa
|
9
|
+
|
1
10
|
# 5.0.0-40
|
2
11
|
Fix: Better search highlights @cdrini
|
3
12
|
Dev: update lit 2 components @iisa
|
package/babel.config.js
CHANGED
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-44-a1",
|
4
4
|
"description": "The Internet Archive BookReader.",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -41,19 +41,18 @@
|
|
41
41
|
"lit": "^2.2.2"
|
42
42
|
},
|
43
43
|
"devDependencies": {
|
44
|
-
"@babel/core": "7.17.
|
44
|
+
"@babel/core": "7.17.9",
|
45
45
|
"@babel/eslint-parser": "7.17.0",
|
46
46
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
47
|
-
"@babel/plugin-proposal-decorators": "7.17.
|
47
|
+
"@babel/plugin-proposal-decorators": "7.17.9",
|
48
48
|
"@babel/preset-env": "7.16.11",
|
49
|
-
"@open-wc/testing": "^
|
50
|
-
"@
|
51
|
-
"@types/jest": "^27.4.1",
|
49
|
+
"@open-wc/testing-helpers": "^2.1.2",
|
50
|
+
"@types/jest": "^27.5.1",
|
52
51
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
53
|
-
"babel-loader": "8.2.
|
52
|
+
"babel-loader": "8.2.5",
|
54
53
|
"codecov": "^3.8.3",
|
55
|
-
"concurrently": "7.
|
56
|
-
"core-js": "3.
|
54
|
+
"concurrently": "7.1.0",
|
55
|
+
"core-js": "3.22.3",
|
57
56
|
"cpx2": "4.2.0",
|
58
57
|
"eslint": "^7.32.0",
|
59
58
|
"eslint-plugin-no-jquery": "^2.7.0",
|
@@ -61,30 +60,30 @@
|
|
61
60
|
"hammerjs": "^2.0.8",
|
62
61
|
"http-server": "14.1.0",
|
63
62
|
"iso-language-codes": "1.1.0",
|
64
|
-
"jest": "^
|
65
|
-
"
|
63
|
+
"jest": "^28.1.0",
|
64
|
+
"jest-environment-jsdom": "^28.1.0",
|
65
|
+
"jquery": "1.12.4",
|
66
66
|
"jquery-colorbox": "1.6.4",
|
67
67
|
"jquery-ui": "1.12.1",
|
68
68
|
"jquery-ui-touch-punch": "0.2.3",
|
69
69
|
"jquery.browser": "0.1.0",
|
70
70
|
"jquery.mmenu": "5.6.5",
|
71
|
-
"
|
72
|
-
"
|
73
|
-
"node-fetch": "2.6.7",
|
71
|
+
"live-server": "1.2.2",
|
72
|
+
"node-fetch": "3.2.4",
|
74
73
|
"regenerator-runtime": "0.13.9",
|
75
|
-
"sass": "1.
|
76
|
-
"sinon": "^
|
74
|
+
"sass": "1.51.0",
|
75
|
+
"sinon": "^14.0.0",
|
77
76
|
"soundmanager2": "2.97.20170602",
|
78
|
-
"svgo": "2.
|
77
|
+
"svgo": "2.8.0",
|
79
78
|
"testcafe": "^1.18.6",
|
80
79
|
"testcafe-browser-provider-browserstack": "^1.13.2-alpha.1",
|
81
80
|
"webpack": "5.51.1",
|
82
|
-
"webpack-cli": "4.
|
81
|
+
"webpack-cli": "4.9.2"
|
83
82
|
},
|
84
83
|
"jest": {
|
85
84
|
"testEnvironment": "jsdom",
|
86
85
|
"transformIgnorePatterns": [
|
87
|
-
"node_modules/(?!(lit-html|lit-element|lit|@lit|@internetarchive)/)"
|
86
|
+
"node_modules/(?!(lit-html|lit-element|lit|@lit|@internetarchive|@open-wc)/)"
|
88
87
|
],
|
89
88
|
"moduleNameMapper": {
|
90
89
|
"^@/(.*)$": "<rootDir>/$1"
|
@@ -95,8 +94,7 @@
|
|
95
94
|
"roots": [
|
96
95
|
"<rootDir>/src/",
|
97
96
|
"<rootDir>/tests/jest/"
|
98
|
-
]
|
99
|
-
"coverageDirectory": "<rootDir>/coverage-jest"
|
97
|
+
]
|
100
98
|
},
|
101
99
|
"scripts": {
|
102
100
|
"preversion": "npm run test && node scripts/preversion.js",
|
@@ -115,15 +113,12 @@
|
|
115
113
|
"serve": "npx http-server . --port 8000",
|
116
114
|
"serve-live": "npx live-server . --port 8000 --watch=index.html,BookReader,BookReaderDemo",
|
117
115
|
"serve-dev": "npm run build-css && npx concurrently --kill-others npm:serve-live npm:build-*:watch",
|
118
|
-
"test": "npx
|
116
|
+
"test": "npx jest --coverage --colors",
|
117
|
+
"test:watch": "npx jest --watch",
|
119
118
|
"test:e2e": "npm run build && npx testcafe",
|
120
119
|
"test:e2e:dev": "npx testcafe --live --dev",
|
121
|
-
"test-jest:watch": "npx jest --watch",
|
122
|
-
"test-jest": "npx jest --coverage --colors",
|
123
|
-
"test-karma": "npx karma start --coverage",
|
124
|
-
"test-karma:watch": "npx karma start --auto-watch=true --single-run=false",
|
125
120
|
"DOCS:update:test-deps": "If CI succeeds, these should be good to update",
|
126
|
-
"update:test-deps": "npm i @babel/eslint-parser@latest @open-wc/testing
|
121
|
+
"update:test-deps": "npm i @babel/eslint-parser@latest @open-wc/testing-helpers@latest @types/jest@latest codecov@latest eslint@latest eslint-plugin-testcafe@latest jest@latest sinon@latest testcafe@latest",
|
127
122
|
"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",
|
128
123
|
"update:build-deps": "npm i @babel/core@latest @babel/preset-env@latest babel-loader@latest core-js@latest regenerator-runtime@latest sass@latest svgo@latest webpack@latest webpack-cli@latest",
|
129
124
|
"codecov": "npx codecov"
|
package/renovate.json
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
{
|
2
2
|
"extends": [
|
3
|
-
"config:base"
|
3
|
+
"config:base",
|
4
|
+
"schedule:monthly"
|
4
5
|
],
|
5
6
|
"packageRules": [
|
6
7
|
{
|
7
8
|
"matchPackageNames": [
|
8
9
|
"@babel/eslint-parser",
|
9
|
-
"@open-wc/testing",
|
10
|
-
"@open-wc/testing-karma",
|
10
|
+
"@open-wc/testing-helpers",
|
11
11
|
"@types/jest",
|
12
12
|
"codecov",
|
13
13
|
"eslint",
|
14
14
|
"eslint-plugin-no-jquery",
|
15
15
|
"eslint-plugin-testcafe",
|
16
16
|
"jest",
|
17
|
-
"
|
17
|
+
"jest-environment-jsdom",
|
18
18
|
"sinon",
|
19
19
|
"testcafe"
|
20
20
|
],
|
@@ -38,6 +38,15 @@
|
|
38
38
|
{
|
39
39
|
"matchPackagePatterns": ["*"],
|
40
40
|
"rangeStrategy": "bump"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"matchPackagePatterns": ["^actions/"],
|
44
|
+
"groupName": "GitHub Actions",
|
45
|
+
"automerge": true
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"matchPackagePatterns": ["^@internetarchive"],
|
49
|
+
"schedule": ["at any time"]
|
41
50
|
}
|
42
51
|
]
|
43
52
|
}
|
package/scripts/preversion.js
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
const { version: OLD_VERSION } = require('../package.json');
|
2
|
-
const fetch = require('node-fetch');
|
3
2
|
const OLD_RELEASE_URL = `https://api.github.com/repos/internetarchive/bookreader/releases/tags/v${OLD_VERSION}`;
|
4
3
|
|
5
4
|
async function main() {
|
5
|
+
// Need this because fetch is ESM-only, and we're on Node 16. Someday we should
|
6
|
+
// be able to move this up to the top without renaming this file to a .mjs or whatever
|
7
|
+
const {default: fetch} = await import('node-fetch');
|
8
|
+
|
6
9
|
const {created_at} = await fetch(OLD_RELEASE_URL).then(r => r.json());
|
7
10
|
const today = new Date().toISOString().slice(0, -5);
|
8
11
|
const searchUrl = 'https://github.com/internetarchive/bookreader/pulls?' + new URLSearchParams({
|
@@ -8,16 +8,28 @@ const menuBase = {
|
|
8
8
|
url: '#',
|
9
9
|
note: 'PDF files contain high quality images of pages.',
|
10
10
|
},
|
11
|
+
lcppdf: {
|
12
|
+
type: 'Get LCP PDF',
|
13
|
+
url: '#',
|
14
|
+
note: 'PDF files contain high quality images of pages.',
|
15
|
+
},
|
16
|
+
lcpepub: {
|
17
|
+
type: 'Get LCP ePub',
|
18
|
+
url: '#',
|
19
|
+
note: 'ePub files are smaller in size, but may contain errors.',
|
20
|
+
},
|
11
21
|
epub: {
|
12
22
|
type: 'Encrypted Adobe ePub',
|
13
23
|
url: '#',
|
14
24
|
note: 'ePub files are smaller in size, but may contain errors.',
|
15
|
-
}
|
25
|
+
},
|
16
26
|
};
|
17
27
|
|
18
28
|
const publicMenuBase = {
|
19
29
|
pdf: "PDF",
|
20
|
-
epub: "ePub"
|
30
|
+
epub: "ePub",
|
31
|
+
lcppdf: "LCP PDF",
|
32
|
+
lcpepub: "LCP ePub",
|
21
33
|
};
|
22
34
|
|
23
35
|
export default class DownloadsProvider {
|
@@ -30,9 +42,6 @@ export default class DownloadsProvider {
|
|
30
42
|
this.id = 'downloads';
|
31
43
|
this.component = '';
|
32
44
|
this.isBookProtected = bookreader?.options?.isProtected || false;
|
33
|
-
|
34
|
-
this.computeAvailableTypes = this.computeAvailableTypes.bind(this);
|
35
|
-
this.update = this.update.bind(this);
|
36
45
|
}
|
37
46
|
|
38
47
|
update(downloadTypes) {
|
@@ -40,6 +40,16 @@ export class IABookDownloads extends LitElement {
|
|
40
40
|
));
|
41
41
|
}
|
42
42
|
|
43
|
+
/**
|
44
|
+
* checks if downloads list contains an LCP option
|
45
|
+
* @return {boolean}
|
46
|
+
*/
|
47
|
+
get hasLCPOption() {
|
48
|
+
const regex = /^(LCP)/g;
|
49
|
+
const lcpAvailable = this.downloads.some(option => option.type?.match(regex));
|
50
|
+
return lcpAvailable;
|
51
|
+
}
|
52
|
+
|
43
53
|
get header() {
|
44
54
|
if (!this.renderHeader) {
|
45
55
|
return nothing;
|
@@ -59,12 +69,24 @@ export class IABookDownloads extends LitElement {
|
|
59
69
|
`;
|
60
70
|
}
|
61
71
|
|
72
|
+
get installSimplyEAldikoThoriumMsg() {
|
73
|
+
return html`
|
74
|
+
<p>For LCP downloads, make sure you have SimplyE or Aldiko Next installed on mobile or Thorium on desktop.</p>
|
75
|
+
<ul>
|
76
|
+
<li><a href="https://librarysimplified.org/simplye/" rel="noopener noreferrer" target="_blank">Install SimplyE</a></li>
|
77
|
+
<li><a href="https://www.demarque.com/en-aldiko" rel="noopener noreferrer" target="_blank">Install Aldiko</a></li>
|
78
|
+
<li><a href="https://www.edrlab.org/software/thorium-reader/" rel="noopener noreferrer" target="_blank">Install Thorium</a></li>
|
79
|
+
</ul>
|
80
|
+
`;
|
81
|
+
}
|
82
|
+
|
62
83
|
render() {
|
63
84
|
return html`
|
64
85
|
${this.header}
|
65
86
|
${this.loanExpiryMessage}
|
66
87
|
<ul>${this.renderDownloadOptions()}</ul>
|
67
|
-
${this.
|
88
|
+
${this.hasLCPOption ? this.installSimplyEAldikoThoriumMsg : nothing}
|
89
|
+
${this.isBookProtected && !this.hasLCPOption ? this.accessProtectedBook : nothing}
|
68
90
|
`;
|
69
91
|
}
|
70
92
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { html, LitElement, nothing } from 'lit';
|
2
2
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
3
|
+
/** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideMatch} SearchInsideMatch */
|
3
4
|
|
4
5
|
export class BookSearchResult extends LitElement {
|
5
6
|
static get properties() {
|
@@ -35,17 +36,14 @@ export class BookSearchResult extends LitElement {
|
|
35
36
|
}
|
36
37
|
|
37
38
|
render() {
|
38
|
-
|
39
|
-
const
|
40
|
-
const [resultDetails = {}] = par;
|
41
|
-
const pageNumber = Number.isInteger(resultDetails.page)
|
42
|
-
? html`<p class="page-num">Page -${resultDetails.page}-</p>` : nothing;
|
39
|
+
/** @type {SearchInsideMatch} */
|
40
|
+
const match = this.match;
|
43
41
|
const coverImage = html`<img src="${match.cover}" />`;
|
44
42
|
return html`
|
45
43
|
<li @click=${this.resultSelected}>
|
46
44
|
${match.cover ? coverImage : nothing}
|
47
45
|
<h4>${match.title || nothing}</h4>
|
48
|
-
${
|
46
|
+
<p class="page-num">Page ${match.displayPageNumber}</p>
|
49
47
|
${this.highlightedHit(match.text)}
|
50
48
|
</li>
|
51
49
|
`;
|
package/src/css/_controls.scss
CHANGED
@@ -34,12 +34,11 @@
|
|
34
34
|
-webkit-appearance: none;
|
35
35
|
appearance: none;
|
36
36
|
font-size: 10px;
|
37
|
-
text-align: center;
|
38
37
|
text-align-last: center;
|
39
38
|
color: $controlsText;
|
40
39
|
border: none;
|
41
40
|
cursor: pointer;
|
42
|
-
option {
|
41
|
+
option, optgroup {
|
43
42
|
background: $controlsBG;
|
44
43
|
}
|
45
44
|
}
|
@@ -29,6 +29,8 @@ import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.
|
|
29
29
|
import SearchView from './view.js';
|
30
30
|
/** @typedef {import('../../BookReader/PageContainer').PageContainer} PageContainer */
|
31
31
|
/** @typedef {import('../../BookReader/BookModel').PageIndex} PageIndex */
|
32
|
+
/** @typedef {import('../../BookReader/BookModel').LeafNum} LeafNum */
|
33
|
+
/** @typedef {import('../../BookReader/BookModel').PageNumString} PageNumString */
|
32
34
|
|
33
35
|
jQuery.extend(BookReader.defaultOptions, {
|
34
36
|
server: 'ia600609.us.archive.org',
|
@@ -257,6 +259,7 @@ BookReader.prototype.cancelSearchRequest = function () {
|
|
257
259
|
/**
|
258
260
|
* @typedef {object} SearchInsideMatch
|
259
261
|
* @property {number} matchIndex This is a fake field! Not part of the API response. It is added by the JS.
|
262
|
+
* @property {string} displayPageNumber (fake field) The page number as it should be displayed in the UI.
|
260
263
|
* @property {string} text
|
261
264
|
* @property {Array<{ page: number, boxes: SearchInsideMatchBox[] }>} par
|
262
265
|
*/
|
@@ -269,22 +272,32 @@ BookReader.prototype.cancelSearchRequest = function () {
|
|
269
272
|
*/
|
270
273
|
|
271
274
|
/**
|
272
|
-
*
|
275
|
+
* Attach some fields to search inside results
|
273
276
|
* @param {SearchInsideResults} results
|
274
|
-
* @param {
|
275
|
-
* @param {boolean} options.goToFirstResult
|
277
|
+
* @param {(pageNum: LeafNum) => PageNumString} displayPageNumberFn
|
276
278
|
*/
|
277
|
-
|
279
|
+
export function marshallSearchResults(results, displayPageNumberFn) {
|
278
280
|
// Attach matchIndex to a few things to make it easier to identify
|
279
281
|
// an active/selected match
|
280
282
|
for (const [index, match] of results.matches.entries()) {
|
281
283
|
match.matchIndex = index;
|
284
|
+
match.displayPageNumber = displayPageNumberFn(match.par[0].page);
|
282
285
|
for (const par of match.par) {
|
283
286
|
for (const box of par.boxes) {
|
284
287
|
box.matchIndex = index;
|
285
288
|
}
|
286
289
|
}
|
287
290
|
}
|
291
|
+
}
|
292
|
+
|
293
|
+
/**
|
294
|
+
* Search Results return handler
|
295
|
+
* @param {SearchInsideResults} results
|
296
|
+
* @param {object} options
|
297
|
+
* @param {boolean} options.goToFirstResult
|
298
|
+
*/
|
299
|
+
BookReader.prototype.BRSearchCallback = function(results, options) {
|
300
|
+
marshallSearchResults(results, pageNum => this.getPageNum(this.leafNumToIndex(pageNum)));
|
288
301
|
this.searchResults = results || [];
|
289
302
|
|
290
303
|
this.updateSearchHilites();
|
@@ -230,9 +230,7 @@ class SearchView {
|
|
230
230
|
matches.forEach((match) => {
|
231
231
|
const queryString = match.text;
|
232
232
|
const pageIndex = this.br.leafNumToIndex(match.par[0].page);
|
233
|
-
const pageNumber = this.br.getPageNum(pageIndex);
|
234
233
|
const uiStringSearch = "Search result"; // i18n
|
235
|
-
const uiStringPage = "Page"; // i18n
|
236
234
|
|
237
235
|
const percentThrough = this.br.constructor.util.cssPercentage(pageIndex, this.br.getNumLeafs() - 1);
|
238
236
|
|
@@ -257,7 +255,7 @@ class SearchView {
|
|
257
255
|
.append(`
|
258
256
|
<div class="BRquery">
|
259
257
|
<div>${queryStringWithBTruncated || queryStringWithB}</div>
|
260
|
-
<div
|
258
|
+
<div>Page ${match.displayPageNumber}</div>
|
261
259
|
</div>
|
262
260
|
`)
|
263
261
|
.appendTo(this.br.$('.BRnavline'))
|
@@ -158,18 +158,30 @@ BookReader.prototype.initNavbar = (function (super_) {
|
|
158
158
|
|
159
159
|
$el.find('.BRcontrols').prepend(this.refs.$BRReadAloudToolbar);
|
160
160
|
|
161
|
+
const renderVoiceOption = (voices) => {
|
162
|
+
return voices.map(voice =>
|
163
|
+
`<option value="${voice.voiceURI}">${voice.lang} - ${voice.name}</option>`).join('');
|
164
|
+
};
|
165
|
+
|
166
|
+
const voiceSortOrder = (a,b) => `${a.lang} - ${a.name}`.localeCompare(`${b.lang} - ${b.name}`);
|
167
|
+
|
161
168
|
const renderVoicesMenu = (voicesMenu) => {
|
162
169
|
voicesMenu.empty();
|
170
|
+
const bookLanguage = this.ttsEngine.opts.bookLanguage;
|
171
|
+
const bookLanguages = this.ttsEngine.getVoices().filter(v => v.lang.startsWith(bookLanguage)).sort(voiceSortOrder);
|
172
|
+
const otherLanguages = this.ttsEngine.getVoices().filter(v => !v.lang.startsWith(bookLanguage)).sort(voiceSortOrder);
|
173
|
+
|
163
174
|
if (this.ttsEngine.getVoices().length > 1) {
|
164
|
-
voicesMenu.append(
|
165
|
-
|
166
|
-
|
175
|
+
voicesMenu.append($(`<optgroup label="Book Language (${bookLanguage})"> ${renderVoiceOption(bookLanguages)} </optgroup>`));
|
176
|
+
voicesMenu.append($(`<optgroup label="Other Languages"> ${renderVoiceOption(otherLanguages)} </optgroup>`));
|
177
|
+
|
167
178
|
voicesMenu.val(this.ttsEngine.voice.voiceURI);
|
168
179
|
voicesMenu.show();
|
169
180
|
} else {
|
170
181
|
voicesMenu.hide();
|
171
182
|
}
|
172
183
|
};
|
184
|
+
|
173
185
|
const voicesMenu = this.refs.$BRReadAloudToolbar.find('[name=playback-voice]');
|
174
186
|
renderVoicesMenu(voicesMenu);
|
175
187
|
voicesMenu.on("change", ev => this.ttsEngine.setVoice(voicesMenu.val()));
|