@internetarchive/bookreader 5.0.0-48-alpha2 → 5.0.0-49-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/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +89 -89
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReaderDemo/IADemoBr.js +2 -0
- package/CHANGELOG.md +4 -0
- package/package.json +2 -2
- package/src/BookNavigator/book-navigator.js +2 -2
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +4 -4
- package/src/BookNavigator/downloads/downloads-provider.js +42 -10
- package/src/BookNavigator/downloads/downloads.js +47 -83
- package/src/BookNavigator/volumes/volumes-provider.js +1 -1
- package/src/BookReader/BookModel.js +0 -29
- package/src/BookReader/Mode1UpLit.js +1 -1
- package/src/BookReader/Mode2Up.js +9 -34
- package/src/BookReader/ModeThumb.js +1 -3
- package/src/BookReader/Navbar/Navbar.js +8 -5
- package/src/BookReader/Toolbar/Toolbar.js +3 -30
- package/src/BookReader.js +65 -338
- package/src/plugins/plugin.autoplay.js +4 -4
- package/src/plugins/plugin.chapters.js +2 -2
- package/src/plugins/search/plugin.search.js +6 -6
- package/src/plugins/search/view.js +2 -2
- package/src/plugins/tts/plugin.tts.js +2 -2
- package/src/util/manifestGenerator.js +0 -0
- package/tests/e2e/models/Navigation.js +1 -1
- package/tests/jest/BookNavigator/book-navigator.test.js +19 -15
- package/tests/jest/BookReader/BookModel.test.js +31 -11
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +4 -4
- package/tests/jest/BookReader/Mode1UpLit.test.js +5 -1
- package/tests/jest/BookReader/Mode2Up.test.js +8 -8
- package/tests/jest/BookReader.test.js +0 -35
- package/tests/jest/plugins/plugin.autoplay.test.js +2 -2
- package/tests/jest/plugins/plugin.chapters.test.js +2 -3
- package/tests/e2e/ia-production/ia-prod-base.js +0 -17
@@ -82,6 +82,8 @@ const initializeBookReader = (brManifest) => {
|
|
82
82
|
// we expect this at the global level
|
83
83
|
BookReaderJSIAinit(brManifest.data, options);
|
84
84
|
|
85
|
+
const isRestricted = brManifest.data.isRestricted;
|
86
|
+
window.dispatchEvent(new CustomEvent('contextmenu', { detail: { isRestricted } }));
|
85
87
|
if (customAutoflipParams.autoflip) {
|
86
88
|
br.autoToggle(customAutoflipParams);
|
87
89
|
}
|
package/CHANGELOG.md
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-49-a1",
|
4
4
|
"description": "The Internet Archive BookReader.",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -46,7 +46,7 @@
|
|
46
46
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
47
47
|
"@babel/plugin-proposal-decorators": "7.17.9",
|
48
48
|
"@babel/preset-env": "7.16.11",
|
49
|
-
"@open-wc/testing-helpers": "^2.1.
|
49
|
+
"@open-wc/testing-helpers": "^2.1.4",
|
50
50
|
"@types/jest": "^29.1.1",
|
51
51
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
52
52
|
"babel-loader": "8.2.5",
|
@@ -449,10 +449,10 @@ export class BookNavigator extends LitElement {
|
|
449
449
|
/** Display an element's context menu */
|
450
450
|
manageContextMenuVisibility(e) {
|
451
451
|
if (window.archive_analytics) {
|
452
|
-
window.archive_analytics?.
|
452
|
+
window.archive_analytics?.send_event(
|
453
453
|
'BookReader',
|
454
454
|
`contextmenu-${this.bookIsRestricted ? 'restricted' : 'unrestricted'}`,
|
455
|
-
e.target
|
455
|
+
e.target?.classList?.value
|
456
456
|
);
|
457
457
|
}
|
458
458
|
if (!this.bookIsRestricted) {
|
@@ -213,8 +213,8 @@ class IABookmarks extends LitElement {
|
|
213
213
|
color: this.getBookmarkColor(color) ? color : this.defaultColor.id,
|
214
214
|
};
|
215
215
|
|
216
|
-
const page = IABookmarks.formatPage(this.bookreader.getPageNum(leafNum));
|
217
|
-
const thumbnail = this.bookreader.getPageURI(`${leafNum}`.replace(/\D/g, ''), 32); // Request thumbnail 1/32 the size of original image
|
216
|
+
const page = IABookmarks.formatPage(this.bookreader.book.getPageNum(leafNum));
|
217
|
+
const thumbnail = this.bookreader.book.getPageURI(`${leafNum}`.replace(/\D/g, ''), 32); // Request thumbnail 1/32 the size of original image
|
218
218
|
const bookmark = {
|
219
219
|
...nomalizedParams,
|
220
220
|
id: leafNum,
|
@@ -297,7 +297,7 @@ class IABookmarks extends LitElement {
|
|
297
297
|
const pageBookmark = this.getBookmark(pageID);
|
298
298
|
const bookmarkState = pageBookmark ? 'filled' : 'hollow';
|
299
299
|
// eslint-disable-next-line
|
300
|
-
const pageData = this.bookreader.
|
300
|
+
const pageData = this.bookreader.book.getPage(pageID);
|
301
301
|
const { isViewable } = pageData;
|
302
302
|
|
303
303
|
if (!isViewable) { return; }
|
@@ -417,7 +417,7 @@ class IABookmarks extends LitElement {
|
|
417
417
|
|
418
418
|
bookmarkSelected({ detail }) {
|
419
419
|
const { leafNum } = detail.bookmark;
|
420
|
-
this.bookreader.jumpToPage(`${this.bookreader.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
420
|
+
this.bookreader.jumpToPage(`${this.bookreader.book.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
421
421
|
this.activeBookmarkID = leafNum;
|
422
422
|
}
|
423
423
|
|
@@ -2,16 +2,46 @@ import { html } from 'lit';
|
|
2
2
|
import '@internetarchive/icon-dl/icon-dl';
|
3
3
|
import './downloads';
|
4
4
|
|
5
|
+
const menuBase = {
|
6
|
+
pdf: {
|
7
|
+
type: 'Encrypted Adobe PDF',
|
8
|
+
url: '#',
|
9
|
+
note: 'PDF files contain high quality images of pages.',
|
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
|
+
},
|
21
|
+
epub: {
|
22
|
+
type: 'Encrypted Adobe ePub',
|
23
|
+
url: '#',
|
24
|
+
note: 'ePub files are smaller in size, but may contain errors.',
|
25
|
+
},
|
26
|
+
};
|
27
|
+
|
28
|
+
const publicMenuBase = {
|
29
|
+
pdf: "PDF",
|
30
|
+
epub: "ePub",
|
31
|
+
lcppdf: "LCP PDF",
|
32
|
+
lcpepub: "LCP ePub",
|
33
|
+
};
|
34
|
+
|
5
35
|
export default class DownloadsProvider {
|
6
36
|
|
7
37
|
constructor({ bookreader }) {
|
8
38
|
this.icon = html`<ia-icon-dl style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-dl>`;
|
9
|
-
this.label = '
|
39
|
+
this.label = 'Downloadable files';
|
10
40
|
this.menuDetails = '';
|
11
41
|
this.downloads = [];
|
12
42
|
this.id = 'downloads';
|
13
43
|
this.component = '';
|
14
|
-
this.isBookProtected = bookreader?.options?.
|
44
|
+
this.isBookProtected = bookreader?.options?.isProtected || false;
|
15
45
|
}
|
16
46
|
|
17
47
|
update(downloadTypes) {
|
@@ -24,21 +54,23 @@ export default class DownloadsProvider {
|
|
24
54
|
}
|
25
55
|
|
26
56
|
/**
|
27
|
-
*
|
28
|
-
*
|
57
|
+
* Generates Download Menu Info for available types
|
58
|
+
* sets global `downloads`
|
29
59
|
* @param availableTypes
|
30
60
|
*/
|
31
61
|
computeAvailableTypes(availableTypes = []) {
|
32
62
|
const menuData = availableTypes.reduce((found, incoming = []) => {
|
33
63
|
const [ type = '', link = '' ] = incoming;
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
64
|
+
const formattedType = type.toLowerCase();
|
65
|
+
const downloadOption = menuBase[formattedType] || null;
|
66
|
+
|
67
|
+
if (downloadOption) {
|
68
|
+
const menuButtonText = this.isBookProtected ? menuBase[formattedType].type : publicMenuBase[formattedType];
|
69
|
+
const menuInfo = Object.assign({}, downloadOption, { url: link, type: menuButtonText});
|
70
|
+
found.push(menuInfo);
|
38
71
|
}
|
39
|
-
found[formattedType] = link;
|
40
72
|
return found;
|
41
|
-
},
|
73
|
+
}, []);
|
42
74
|
|
43
75
|
this.downloads = menuData;
|
44
76
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import { css, html, LitElement, nothing } from 'lit';
|
2
2
|
import buttonStyles from '../assets/button-base.js';
|
3
|
-
|
4
3
|
export class IABookDownloads extends LitElement {
|
5
4
|
static get properties() {
|
6
5
|
return {
|
@@ -19,26 +18,6 @@ export class IABookDownloads extends LitElement {
|
|
19
18
|
this.isBookProtected = false;
|
20
19
|
}
|
21
20
|
|
22
|
-
render() {
|
23
|
-
return html`
|
24
|
-
${this.header}
|
25
|
-
${this.loanExpiryMessage}
|
26
|
-
${this.renderDownloadOptions()}
|
27
|
-
`;
|
28
|
-
}
|
29
|
-
|
30
|
-
get header() {
|
31
|
-
if (!this.renderHeader) {
|
32
|
-
return nothing;
|
33
|
-
}
|
34
|
-
return html`
|
35
|
-
<header>
|
36
|
-
<h3>Read offline</h3>
|
37
|
-
${this.formatsCount}
|
38
|
-
</header>
|
39
|
-
`;
|
40
|
-
}
|
41
|
-
|
42
21
|
get formatsCount() {
|
43
22
|
const count = this.downloads.length;
|
44
23
|
return count ? html`<p>${count} format${count > 1 ? 's' : ''}</p>` : html``;
|
@@ -51,80 +30,65 @@ export class IABookDownloads extends LitElement {
|
|
51
30
|
}
|
52
31
|
|
53
32
|
renderDownloadOptions() {
|
54
|
-
|
55
|
-
|
56
|
-
if (this.downloads[format]) {
|
57
|
-
downloadOptions.push(this.downloadOption(format, this.downloads[format]));
|
58
|
-
}
|
59
|
-
});
|
60
|
-
return html`
|
61
|
-
<ul>
|
62
|
-
${downloadOptions}
|
63
|
-
</ul>
|
64
|
-
`;
|
65
|
-
}
|
66
|
-
|
67
|
-
downloadOption(format, link) {
|
68
|
-
if (/^adobe/.test(format)) {
|
69
|
-
return html`
|
33
|
+
return this.downloads.map(option => (
|
34
|
+
html`
|
70
35
|
<li>
|
71
|
-
<a
|
72
|
-
|
73
|
-
data-event-click-tracking="BookReader|Download-${format}"
|
74
|
-
>${this.menuText[format].linkText}</a>
|
75
|
-
${this.menuText[format].message ?? nothing}
|
36
|
+
<a class="ia-button link primary" href="${option.url}">Get ${option.type}</a>
|
37
|
+
${option.note ? html`<p>${option.note}</p>` : html``}
|
76
38
|
</li>
|
77
|
-
|
39
|
+
`
|
40
|
+
));
|
41
|
+
}
|
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
|
+
|
53
|
+
get header() {
|
54
|
+
if (!this.renderHeader) {
|
55
|
+
return nothing;
|
78
56
|
}
|
79
57
|
return html`
|
80
|
-
<
|
81
|
-
<
|
82
|
-
|
83
|
-
|
84
|
-
>${this.menuText[format].linkText}</a>
|
85
|
-
${this.menuText[format].message ? html`<p>${this.menuText[format].message}</p>` : nothing}
|
86
|
-
</li>
|
58
|
+
<header>
|
59
|
+
<h3>Downloadable files</h3>
|
60
|
+
${this.formatsCount}
|
61
|
+
</header>
|
87
62
|
`;
|
88
63
|
}
|
89
64
|
|
90
|
-
get
|
91
|
-
return {
|
92
|
-
pdf: {
|
93
|
-
linkText: 'Get high-resolution PDF',
|
94
|
-
message: html``,
|
95
|
-
},
|
96
|
-
epub: {
|
97
|
-
linkText: 'Get text-based ebook',
|
98
|
-
message: html`Smaller size. May contain some errors.`,
|
99
|
-
},
|
100
|
-
lcppdf: {
|
101
|
-
linkText: 'Get high-resolution PDF',
|
102
|
-
message: this.lcpNote,
|
103
|
-
},
|
104
|
-
lcpepub: {
|
105
|
-
linkText: 'Get text-based ebook',
|
106
|
-
message: html`Smaller size. May contain some errors. ${this.lcpNote}`,
|
107
|
-
},
|
108
|
-
adobepdf: {
|
109
|
-
linkText:'Get legacy Adobe DRM PDF version here.',
|
110
|
-
message: this.adobeNote,
|
111
|
-
},
|
112
|
-
adobeepub: {
|
113
|
-
linkText: 'Get legacy Adobe DRM EPUB version here.',
|
114
|
-
message: this.adobeNote,
|
115
|
-
},
|
116
|
-
};
|
117
|
-
};
|
118
|
-
|
119
|
-
get lcpNote() {
|
65
|
+
get accessProtectedBook() {
|
120
66
|
return html`
|
121
|
-
|
67
|
+
<p>To access downloaded books, you need Adobe-compliant software on your device. The Internet Archive will administer this loan, but Adobe may also collect some information.</p>
|
68
|
+
<a class="ia-button external primary" href="https://www.adobe.com/solutions/ebook/digital-editions/download.html" rel="noopener noreferrer" target="_blank">Install Adobe Digital Editions</a>
|
122
69
|
`;
|
123
70
|
}
|
124
71
|
|
125
|
-
get
|
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 nofollow" target="_blank">Install SimplyE</a></li>
|
77
|
+
<li><a href="https://www.demarque.com/en-aldiko" rel="noopener noreferrer nofollow" target="_blank">Install Aldiko</a></li>
|
78
|
+
<li><a href="https://www.edrlab.org/software/thorium-reader/" rel="noopener noreferrer nofollow" target="_blank">Install Thorium</a></li>
|
79
|
+
</ul>
|
80
|
+
`;
|
81
|
+
}
|
82
|
+
|
83
|
+
render() {
|
126
84
|
return html`
|
127
|
-
|
85
|
+
${this.header}
|
86
|
+
${this.loanExpiryMessage}
|
87
|
+
<ul>${this.renderDownloadOptions()}</ul>
|
88
|
+
${this.hasLCPOption
|
89
|
+
? this.installSimplyEAldikoThoriumMsg
|
90
|
+
: (this.isBookProtected ? this.accessProtectedBook : nothing)
|
91
|
+
}
|
128
92
|
`;
|
129
93
|
}
|
130
94
|
|
@@ -104,7 +104,7 @@ export default class VolumesProvider {
|
|
104
104
|
if (!window.archive_analytics) {
|
105
105
|
return;
|
106
106
|
}
|
107
|
-
window.archive_analytics?.
|
107
|
+
window.archive_analytics?.send_event(
|
108
108
|
'BookReader',
|
109
109
|
`VolumesSort|${orderBy}`,
|
110
110
|
window.location.path,
|
@@ -26,39 +26,10 @@ export class BookModel {
|
|
26
26
|
|
27
27
|
/** @type {{width: number, height: number}} memoize storage */
|
28
28
|
this._medianPageSize = null;
|
29
|
-
/** @deprecated @type {{width: number, height: number}} memoize storage */
|
30
|
-
this._medianPageSizePixels = null;
|
31
29
|
/** @type {[PageData[], number]} */
|
32
30
|
this._getDataFlattenedCached = null;
|
33
31
|
}
|
34
32
|
|
35
|
-
/**
|
36
|
-
* @deprecated Use getMedianPageSizeInches
|
37
|
-
* Memoized
|
38
|
-
* @return {{width: number, height: number}}
|
39
|
-
*/
|
40
|
-
getMedianPageSize() {
|
41
|
-
if (this._medianPageSizePixels) {
|
42
|
-
return this._medianPageSizePixels;
|
43
|
-
}
|
44
|
-
|
45
|
-
// A little expensive but we just do it once
|
46
|
-
const widths = [];
|
47
|
-
const heights = [];
|
48
|
-
for (let i = 0; i < this.getNumLeafs(); i++) {
|
49
|
-
widths.push(this.getPageWidth(i));
|
50
|
-
heights.push(this.getPageHeight(i));
|
51
|
-
}
|
52
|
-
|
53
|
-
widths.sort();
|
54
|
-
heights.sort();
|
55
|
-
this._medianPageSizePixels = {
|
56
|
-
width: widths[Math.floor(widths.length / 2)],
|
57
|
-
height: heights[Math.floor(heights.length / 2)]
|
58
|
-
};
|
59
|
-
return this._medianPageSizePixels;
|
60
|
-
}
|
61
|
-
|
62
33
|
/** Get median width/height of page in inches. Memoized for performance. */
|
63
34
|
getMedianPageSizeInches() {
|
64
35
|
if (this._medianPageSize) {
|
@@ -205,7 +205,7 @@ export class Mode1UpLit extends LitElement {
|
|
205
205
|
this.throttledUpdateRenderedPages();
|
206
206
|
this.br.displayedIndices = this.visiblePages.map(p => p.index);
|
207
207
|
this.br.updateFirstIndex(this.br.displayedIndices[0]);
|
208
|
-
this.br.updateNavIndexThrottled();
|
208
|
+
this.br._components.navbar.updateNavIndexThrottled();
|
209
209
|
}
|
210
210
|
if (changedProps.has('scale')) {
|
211
211
|
const oldVal = changedProps.get('scale');
|
@@ -90,7 +90,6 @@ export class Mode2Up {
|
|
90
90
|
|
91
91
|
this.displayedIndices = [this.br.twoPage.currentIndexL, this.br.twoPage.currentIndexR];
|
92
92
|
this.br.displayedIndices = this.displayedIndices;
|
93
|
-
this.br.updateToolbarZoom(this.br.reduce);
|
94
93
|
this.br.trigger('pageChanged');
|
95
94
|
}
|
96
95
|
|
@@ -118,7 +117,7 @@ export class Mode2Up {
|
|
118
117
|
|
119
118
|
// Prepare view with new center to minimize visual glitches
|
120
119
|
const drawNewSpread = true;
|
121
|
-
this.
|
120
|
+
this.prepare(oldCenter.percentageX, oldCenter.percentageY, drawNewSpread);
|
122
121
|
}
|
123
122
|
|
124
123
|
/**
|
@@ -150,7 +149,7 @@ export class Mode2Up {
|
|
150
149
|
* @param {number} centerPercentageY
|
151
150
|
* @param {Boolean} drawNewSpread
|
152
151
|
*/
|
153
|
-
|
152
|
+
prepare(centerPercentageX, centerPercentageY, drawNewSpread = false) {
|
154
153
|
// Some decisions about two page view:
|
155
154
|
//
|
156
155
|
// Both pages will be displayed at the same height, even if they were different physical/scanned
|
@@ -241,7 +240,6 @@ export class Mode2Up {
|
|
241
240
|
this.br.displayedIndices = [];
|
242
241
|
|
243
242
|
this.drawLeafs();
|
244
|
-
this.br.updateToolbarZoom(this.br.reduce);
|
245
243
|
this.br.updateBrClasses();
|
246
244
|
|
247
245
|
this.smoothZoomer = this.smoothZoomer || new ModeSmoothZoom(this);
|
@@ -391,7 +389,7 @@ export class Mode2Up {
|
|
391
389
|
|
392
390
|
// Leaf edges
|
393
391
|
this.br.twoPage.edgeWidth = spreadSize.totalLeafEdgeWidth; // The combined width of both edges
|
394
|
-
this.br.twoPage.leafEdgeWidthL = this.
|
392
|
+
this.br.twoPage.leafEdgeWidthL = this.leafEdgeWidth(this.br.twoPage.currentIndexL);
|
395
393
|
this.br.twoPage.leafEdgeWidthR = this.br.twoPage.edgeWidth - this.br.twoPage.leafEdgeWidthL;
|
396
394
|
|
397
395
|
|
@@ -528,21 +526,6 @@ export class Mode2Up {
|
|
528
526
|
return spreadSize.reduce;
|
529
527
|
}
|
530
528
|
|
531
|
-
/**
|
532
|
-
* Returns true if the pages extend past the edge of the view
|
533
|
-
* @deprecated slated for deprecation by v5.0.0
|
534
|
-
* @return {boolean}
|
535
|
-
*/
|
536
|
-
isZoomedIn() {
|
537
|
-
let isZoomedIn = false;
|
538
|
-
if (this.br.twoPage.autofit != 'auto') {
|
539
|
-
if (this.br.reduce < this.getAutofitReduce()) {
|
540
|
-
isZoomedIn = true;
|
541
|
-
}
|
542
|
-
}
|
543
|
-
return isZoomedIn;
|
544
|
-
}
|
545
|
-
|
546
529
|
calculateReductionFactors() {
|
547
530
|
this.br.twoPage.reductionFactors = this.br.reductionFactors.concat([
|
548
531
|
{
|
@@ -553,14 +536,6 @@ export class Mode2Up {
|
|
553
536
|
this.br.twoPage.reductionFactors.sort(this.br._reduceSort);
|
554
537
|
}
|
555
538
|
|
556
|
-
/**
|
557
|
-
* Set the cursor for two page view
|
558
|
-
* @deprecated Since version 4.3.3. Will be deleted in version 5.0
|
559
|
-
*/
|
560
|
-
setCursor() {
|
561
|
-
console.warn('Call to deprecated method, Mode2Up.setCursor. No-op.');
|
562
|
-
}
|
563
|
-
|
564
539
|
/**
|
565
540
|
* @param {Number|null} index to flip back one spread, pass index=null
|
566
541
|
*/
|
@@ -584,7 +559,7 @@ export class Mode2Up {
|
|
584
559
|
if (prev.pageSide == 'R') index--;
|
585
560
|
}
|
586
561
|
|
587
|
-
this.br.updateNavIndexThrottled(index);
|
562
|
+
this.br._components.navbar.updateNavIndexThrottled(index);
|
588
563
|
|
589
564
|
const previousIndices = this.book.getSpreadIndices(index);
|
590
565
|
|
@@ -614,8 +589,8 @@ export class Mode2Up {
|
|
614
589
|
this.br.refs.$brContainer.addClass("BRpageFlipping");
|
615
590
|
const leftLeaf = this.br.twoPage.currentIndexL;
|
616
591
|
|
617
|
-
const oldLeafEdgeWidthL = this.
|
618
|
-
const newLeafEdgeWidthL = this.
|
592
|
+
const oldLeafEdgeWidthL = this.leafEdgeWidth(this.br.twoPage.currentIndexL);
|
593
|
+
const newLeafEdgeWidthL = this.leafEdgeWidth(newIndexL);
|
619
594
|
const leafEdgeTmpW = oldLeafEdgeWidthL - newLeafEdgeWidthL;
|
620
595
|
|
621
596
|
const currWidthL = this.getPageWidth(leftLeaf);
|
@@ -782,7 +757,7 @@ export class Mode2Up {
|
|
782
757
|
}
|
783
758
|
if (index > this.br.lastDisplayableIndex()) return;
|
784
759
|
|
785
|
-
this.br.updateNavIndexThrottled(index);
|
760
|
+
this.br._components.navbar.updateNavIndexThrottled(index);
|
786
761
|
|
787
762
|
this.br.animating = true;
|
788
763
|
|
@@ -808,9 +783,9 @@ export class Mode2Up {
|
|
808
783
|
flipRightToLeft(newIndexL, newIndexR) {
|
809
784
|
this.br.refs.$brContainer.addClass("BRpageFlipping");
|
810
785
|
|
811
|
-
const oldLeafEdgeWidthL = this.
|
786
|
+
const oldLeafEdgeWidthL = this.leafEdgeWidth(this.br.twoPage.currentIndexL);
|
812
787
|
const oldLeafEdgeWidthR = this.br.twoPage.edgeWidth - oldLeafEdgeWidthL;
|
813
|
-
const newLeafEdgeWidthL = this.
|
788
|
+
const newLeafEdgeWidthL = this.leafEdgeWidth(newIndexL);
|
814
789
|
const newLeafEdgeWidthR = this.br.twoPage.edgeWidth - newLeafEdgeWidthL;
|
815
790
|
|
816
791
|
const leafEdgeTmpW = oldLeafEdgeWidthR - newLeafEdgeWidthR;
|
@@ -177,7 +177,7 @@ export class ModeThumb {
|
|
177
177
|
// shift viewModeOrder after clicking on thumbsnail leaf
|
178
178
|
const nextModeID = this.br.viewModeOrder.shift();
|
179
179
|
this.br.viewModeOrder.push(nextModeID);
|
180
|
-
this.br.updateViewModeButton($('.viewmode'), 'twopg', 'Two-page view');
|
180
|
+
this.br._components.navbar.updateViewModeButton($('.viewmode'), 'twopg', 'Two-page view');
|
181
181
|
|
182
182
|
this.br.trigger(EVENTS.fragmentChange);
|
183
183
|
event.stopPropagation();
|
@@ -215,8 +215,6 @@ export class ModeThumb {
|
|
215
215
|
|
216
216
|
// highlight current page
|
217
217
|
this.br.$('.pagediv' + this.br.currentIndex()).addClass('BRpagedivthumb_highlight');
|
218
|
-
|
219
|
-
this.br.updateToolbarZoom(this.br.reduce);
|
220
218
|
}
|
221
219
|
|
222
220
|
/**
|
@@ -4,6 +4,7 @@ import 'jquery-ui/ui/widget.js';
|
|
4
4
|
import 'jquery-ui/ui/widgets/mouse.js';
|
5
5
|
import 'jquery-ui/ui/widgets/slider.js';
|
6
6
|
import { EVENTS } from '../events.js';
|
7
|
+
import { throttle } from '../utils.js';
|
7
8
|
|
8
9
|
export class Navbar {
|
9
10
|
/**
|
@@ -27,6 +28,8 @@ export class Navbar {
|
|
27
28
|
this.maximumControls = [
|
28
29
|
'book_left', 'book_right', 'zoom_in', 'zoom_out', 'onepg', 'twopg', 'thumb'
|
29
30
|
];
|
31
|
+
|
32
|
+
this.updateNavIndexThrottled = throttle(this.updateNavIndex.bind(this), 250, false);
|
30
33
|
}
|
31
34
|
|
32
35
|
controlFor(controlName) {
|
@@ -213,7 +216,7 @@ export class Navbar {
|
|
213
216
|
const $slider = this.$root.find('.BRpager').slider({
|
214
217
|
animate: true,
|
215
218
|
min: 0,
|
216
|
-
max: br.getNumLeafs() - 1,
|
219
|
+
max: br.book.getNumLeafs() - 1,
|
217
220
|
value: br.currentIndex(),
|
218
221
|
range: "min"
|
219
222
|
});
|
@@ -248,16 +251,16 @@ export class Navbar {
|
|
248
251
|
getNavPageNumString(index) {
|
249
252
|
const { br } = this;
|
250
253
|
// Accessible index starts at 0 (alas) so we add 1 to make human
|
251
|
-
const pageNum = br.getPageNum(index);
|
252
|
-
const pageType = br.getPageProp(index, 'pageType');
|
253
|
-
const numLeafs = br.getNumLeafs();
|
254
|
+
const pageNum = br.book.getPageNum(index);
|
255
|
+
const pageType = br.book.getPageProp(index, 'pageType');
|
256
|
+
const numLeafs = br.book.getNumLeafs();
|
254
257
|
|
255
258
|
if (!this.maxPageNum) {
|
256
259
|
// Calculate Max page num (used for pagination display)
|
257
260
|
let maxPageNum = 0;
|
258
261
|
let pageNumVal;
|
259
262
|
for (let i = 0; i < numLeafs; i++) {
|
260
|
-
pageNumVal = br.getPageNum(i);
|
263
|
+
pageNumVal = br.book.getPageNum(i);
|
261
264
|
if (!isNaN(pageNumVal) && pageNumVal > maxPageNum) {
|
262
265
|
maxPageNum = pageNumVal;
|
263
266
|
}
|
@@ -75,8 +75,6 @@ export class Toolbar {
|
|
75
75
|
br.$('.BRnavCntl').addClass('BRup');
|
76
76
|
br.$('.pause').hide();
|
77
77
|
|
78
|
-
this.updateToolbarZoom(br.reduce); // Pretty format
|
79
|
-
|
80
78
|
// We build in mode 2
|
81
79
|
br.refs.$BRtoolbar.append();
|
82
80
|
|
@@ -127,31 +125,6 @@ export class Toolbar {
|
|
127
125
|
});
|
128
126
|
}
|
129
127
|
|
130
|
-
/**
|
131
|
-
* @deprecated
|
132
|
-
* @todo .BRzoom doesn't exist anywhere, so this is likely dead code
|
133
|
-
* Update the displayed zoom factor based on reduction factor
|
134
|
-
* @param {number} reduce
|
135
|
-
*/
|
136
|
-
updateToolbarZoom(reduce) {
|
137
|
-
const { br } = this;
|
138
|
-
// $$$ TODO preserve zoom/fit for each mode
|
139
|
-
const autofit = br.mode == br.constMode2up ? br.twoPage.autofit : br.onePage.autofit;
|
140
|
-
/** @type {string} */
|
141
|
-
let value;
|
142
|
-
if (autofit) {
|
143
|
-
value = autofit.slice(0,1).toUpperCase() + autofit.slice(1);
|
144
|
-
} else {
|
145
|
-
value = (100 / reduce)
|
146
|
-
.toFixed(2)
|
147
|
-
// Strip trailing zeroes and decimal if all zeroes
|
148
|
-
.replace(/0+$/,'')
|
149
|
-
.replace(/\.$/,'')
|
150
|
-
+ '%';
|
151
|
-
}
|
152
|
-
br.$('.BRzoom').text(value);
|
153
|
-
}
|
154
|
-
|
155
128
|
/**
|
156
129
|
* @param {JQuery} $shareDiv
|
157
130
|
*/
|
@@ -216,7 +189,7 @@ export class Toolbar {
|
|
216
189
|
const params = {};
|
217
190
|
params.mode = $(form.find('.fieldset-embed input[name=pages]:checked')).val();
|
218
191
|
if (form.find('.fieldset-embed input[name=thispage]').prop('checked')) {
|
219
|
-
params.page = br.getPageNum(br.currentIndex());
|
192
|
+
params.page = br.book.getPageNum(br.currentIndex());
|
220
193
|
}
|
221
194
|
|
222
195
|
if (br.getEmbedCode) {
|
@@ -331,7 +304,7 @@ export class Toolbar {
|
|
331
304
|
}
|
332
305
|
}
|
333
306
|
|
334
|
-
|
307
|
+
function blankInfoDiv() {
|
335
308
|
return $(`
|
336
309
|
<div class="BRfloat BRinfo">
|
337
310
|
<div class="BRfloatHead">About this book
|
@@ -351,7 +324,7 @@ export function blankInfoDiv() {
|
|
351
324
|
</div>`);
|
352
325
|
}
|
353
326
|
|
354
|
-
|
327
|
+
function blankShareDiv() {
|
355
328
|
return $(`
|
356
329
|
<div class="BRfloat BRshare">
|
357
330
|
<div class="BRfloatHead">
|