@internetarchive/bookreader 5.0.0-58 → 5.0.0-59
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.css +110 -39
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.LICENSE.txt +0 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1 -1
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +1 -1
- package/BookReader/plugins/plugin.resume.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/BookReaderDemo/BookReaderJSAutoplay.js +4 -1
- package/BookReaderDemo/BookReaderJSSimple.js +1 -0
- package/BookReaderDemo/IADemoBr.js +1 -2
- package/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/src/BookReader/BookModel.js +59 -1
- package/src/BookReader/Mode1UpLit.js +13 -70
- package/src/BookReader/Mode2Up.js +72 -1332
- package/src/BookReader/Mode2UpLit.js +774 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +32 -0
- package/src/BookReader/options.js +8 -2
- package/src/BookReader/utils.js +16 -0
- package/src/BookReader.js +24 -217
- package/src/css/_BRBookmarks.scss +1 -1
- package/src/css/_BRmain.scss +14 -0
- package/src/css/_BRpages.scss +113 -41
- package/src/plugins/plugin.autoplay.js +1 -6
- package/src/plugins/tts/WebTTSEngine.js +2 -2
- package/src/plugins/tts/plugin.tts.js +3 -17
- package/src/plugins/tts/utils.js +0 -16
- package/tests/e2e/helpers/base.js +20 -20
- package/tests/e2e/helpers/rightToLeft.js +4 -10
- package/tests/e2e/viewmode.test.js +10 -8
- package/tests/jest/BookReader/BookModel.test.js +25 -0
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +28 -11
- package/tests/jest/BookReader/Mode1UpLit.test.js +0 -19
- package/tests/jest/BookReader/Mode2Up.test.js +55 -225
- 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 +26 -0
- package/tests/jest/BookReader/Navbar/Navbar.test.js +3 -3
- package/tests/jest/BookReader/utils.test.js +32 -1
- package/tests/jest/plugins/tts/utils.test.js +0 -34
@@ -23,6 +23,8 @@ export class BookModel {
|
|
23
23
|
this.br = br;
|
24
24
|
this.reduceSet = br.reduceSet;
|
25
25
|
this.ppi = br.options?.ppi ?? DEFAULT_OPTIONS.ppi;
|
26
|
+
/** @type {'lr' | 'rl'} Page progression */
|
27
|
+
this.pageProgression = br.options?.pageProgression ?? DEFAULT_OPTIONS.pageProgression;
|
26
28
|
|
27
29
|
/** @type {{width: number, height: number}} memoize storage */
|
28
30
|
this._medianPageSize = null;
|
@@ -197,7 +199,7 @@ export class BookModel {
|
|
197
199
|
* @return {[PageIndex, PageIndex]} eg [0, 1]
|
198
200
|
*/
|
199
201
|
getSpreadIndices(pindex) {
|
200
|
-
if (this.
|
202
|
+
if (this.pageProgression == 'rl') {
|
201
203
|
return this.getPageSide(pindex) == 'R' ? [pindex + 1, pindex] : [pindex, pindex - 1];
|
202
204
|
} else {
|
203
205
|
return this.getPageSide(pindex) == 'L' ? [pindex, pindex + 1] : [pindex - 1, pindex];
|
@@ -408,6 +410,42 @@ export class PageModel {
|
|
408
410
|
return this.findNext();
|
409
411
|
}
|
410
412
|
|
413
|
+
/** @type {PageModel | null} */
|
414
|
+
get left() {
|
415
|
+
return this.book.pageProgression === 'lr' ? this.prev : this.next;
|
416
|
+
}
|
417
|
+
|
418
|
+
/** @type {PageModel | null} */
|
419
|
+
get right() {
|
420
|
+
return this.book.pageProgression === 'lr' ? this.next : this.prev;
|
421
|
+
}
|
422
|
+
|
423
|
+
/**
|
424
|
+
* @type {{left: PageModel | null, right: PageModel | null}}
|
425
|
+
*/
|
426
|
+
get spread() {
|
427
|
+
return {
|
428
|
+
left: this.pageSide === 'L' ? this : this.left,
|
429
|
+
right: this.pageSide === 'R' ? this : this.right,
|
430
|
+
};
|
431
|
+
}
|
432
|
+
|
433
|
+
/**
|
434
|
+
* @param {number} pages
|
435
|
+
*/
|
436
|
+
goLeft(pages) {
|
437
|
+
const newIndex = this.book.pageProgression === 'lr' ? this.index - pages : this.index + pages;
|
438
|
+
return this.book.getPage(newIndex);
|
439
|
+
}
|
440
|
+
|
441
|
+
/**
|
442
|
+
* @param {number} pages
|
443
|
+
*/
|
444
|
+
goRight(pages) {
|
445
|
+
const newIndex = this.book.pageProgression === 'lr' ? this.index + pages : this.index - pages;
|
446
|
+
return this.book.getPage(newIndex);
|
447
|
+
}
|
448
|
+
|
411
449
|
/**
|
412
450
|
* @param {number} reduce
|
413
451
|
* @param {number} rotate
|
@@ -469,6 +507,26 @@ export class PageModel {
|
|
469
507
|
return new PageModel(this.book, this.index - 1);
|
470
508
|
}
|
471
509
|
}
|
510
|
+
|
511
|
+
/**
|
512
|
+
* @param {object} [arg0]
|
513
|
+
* @param {boolean} [arg0.combineConsecutiveUnviewables] Whether to only yield the first page
|
514
|
+
* of a series of unviewable pages instead of each page
|
515
|
+
* @return {PageModel|void}
|
516
|
+
*/
|
517
|
+
findLeft({ combineConsecutiveUnviewables = false } = {}) {
|
518
|
+
return this.book.pageProgression === 'lr' ? this.findPrev({ combineConsecutiveUnviewables }) : this.findNext({ combineConsecutiveUnviewables });
|
519
|
+
}
|
520
|
+
|
521
|
+
/**
|
522
|
+
* @param {object} [arg0]
|
523
|
+
* @param {boolean} [arg0.combineConsecutiveUnviewables] Whether to only yield the first page
|
524
|
+
* of a series of unviewable pages instead of each page
|
525
|
+
* @return {PageModel|void}
|
526
|
+
*/
|
527
|
+
findRight({ combineConsecutiveUnviewables = false } = {}) {
|
528
|
+
return this.book.pageProgression === 'lr' ? this.findNext({ combineConsecutiveUnviewables }) : this.findPrev({ combineConsecutiveUnviewables });
|
529
|
+
}
|
472
530
|
}
|
473
531
|
|
474
532
|
// There are a few main ways we can reference a specific page in a book:
|
@@ -3,9 +3,10 @@ import { customElement, property, query } from 'lit/decorators.js';
|
|
3
3
|
import {LitElement, html} from 'lit';
|
4
4
|
import { styleMap } from 'lit/directives/style-map.js';
|
5
5
|
import { ModeSmoothZoom } from './ModeSmoothZoom';
|
6
|
-
import { arrChanged,
|
6
|
+
import { arrChanged, genToArray, sum, throttle } from './utils';
|
7
7
|
import { HTMLDimensionsCacher } from "./utils/HTMLDimensionsCacher";
|
8
8
|
import { ScrollClassAdder } from './utils/ScrollClassAdder';
|
9
|
+
import { ModeCoordinateSpace } from './ModeCoordinateSpace';
|
9
10
|
/** @typedef {import('./BookModel').BookModel} BookModel */
|
10
11
|
/** @typedef {import('./BookModel').PageIndex} PageIndex */
|
11
12
|
/** @typedef {import('./BookModel').PageModel} PageModel */
|
@@ -41,17 +42,8 @@ export class Mode1UpLit extends LitElement {
|
|
41
42
|
|
42
43
|
/************** SCALE-RELATED PROPERTIES **************/
|
43
44
|
|
44
|
-
/** @
|
45
|
-
|
46
|
-
|
47
|
-
/**
|
48
|
-
* How much smaller the rendered pages are than the real-world item
|
49
|
-
*
|
50
|
-
* Mode1Up doesn't use the br.reduce because it is DPI aware. The reduction factor
|
51
|
-
* of a given leaf can change (since leaves can have different DPIs), but the real-world
|
52
|
-
* reduction is constant throughout.
|
53
|
-
*/
|
54
|
-
realWorldReduce = 1;
|
45
|
+
/** @type {ModeCoordinateSpace} Manage conversion between coordinates */
|
46
|
+
coordSpace = new ModeCoordinateSpace(this);
|
55
47
|
|
56
48
|
@property({ type: Number })
|
57
49
|
scale = 1;
|
@@ -95,7 +87,7 @@ export class Mode1UpLit extends LitElement {
|
|
95
87
|
worldDimensions = { width: 100, height: 100 };
|
96
88
|
|
97
89
|
get worldStyle() {
|
98
|
-
const wToR = this.worldUnitsToRenderedPixels;
|
90
|
+
const wToR = this.coordSpace.worldUnitsToRenderedPixels;
|
99
91
|
return {
|
100
92
|
width: wToR(this.worldDimensions.width) + "px",
|
101
93
|
height: wToR(this.worldDimensions.height) + "px",
|
@@ -139,7 +131,7 @@ export class Mode1UpLit extends LitElement {
|
|
139
131
|
if (smooth) {
|
140
132
|
this.style.scrollBehavior = 'smooth';
|
141
133
|
}
|
142
|
-
this.scrollTop = this.worldUnitsToVisiblePixels(this.pageTops[index] - this.SPACING_IN / 2);
|
134
|
+
this.scrollTop = this.coordSpace.worldUnitsToVisiblePixels(this.pageTops[index] - this.SPACING_IN / 2);
|
143
135
|
// TODO: Also h center?
|
144
136
|
if (smooth) {
|
145
137
|
setTimeout(() => this.style.scrollBehavior = '', 100);
|
@@ -214,7 +206,8 @@ export class Mode1UpLit extends LitElement {
|
|
214
206
|
const oldVal = changedProps.get('scale');
|
215
207
|
// Need to set this scale to actually scale the pages
|
216
208
|
this.$visibleWorld.style.transform = `scale(${this.scale})`;
|
217
|
-
this.updateViewportOnZoom(this.scale, oldVal);
|
209
|
+
this.smoothZoomer.updateViewportOnZoom(this.scale, oldVal);
|
210
|
+
this.updateVisibleRegion();
|
218
211
|
// Need to set this scale to update the world size, so the scrollbar gets the correct size
|
219
212
|
this.$world.style.transform = `scale(${this.scale})`;
|
220
213
|
}
|
@@ -244,25 +237,6 @@ export class Mode1UpLit extends LitElement {
|
|
244
237
|
return this;
|
245
238
|
}
|
246
239
|
|
247
|
-
/************** COORDINATE SPACE CONVERTERS **************/
|
248
|
-
/**
|
249
|
-
* There are a few different "coordinate spaces" at play in BR:
|
250
|
-
* (1) World units: i.e. inches. Unless otherwise stated, all computations
|
251
|
-
* are done in world units.
|
252
|
-
* (2) Rendered Pixels: i.e. img.width = '300'. Note this does _not_ take
|
253
|
-
* into account zoom scaling.
|
254
|
-
* (3) Visible Pixels: Just rendered pixels, but taking into account scaling.
|
255
|
-
*/
|
256
|
-
|
257
|
-
worldUnitsToRenderedPixels = (/** @type {number} */inches) => inches * this.screenDPI / this.realWorldReduce;
|
258
|
-
renderedPixelsToWorldUnits = (/** @type {number} */px) => px * this.realWorldReduce / this.screenDPI;
|
259
|
-
|
260
|
-
renderedPixelsToVisiblePixels = (/** @type {number} */px) => px * this.scale;
|
261
|
-
visiblePixelsToRenderedPixels = (/** @type {number} */px) => px / this.scale;
|
262
|
-
|
263
|
-
worldUnitsToVisiblePixels = (/** @type {number} */px) => this.renderedPixelsToVisiblePixels(this.worldUnitsToRenderedPixels(px));
|
264
|
-
visiblePixelsToWorldUnits = (/** @type {number} */px) => this.renderedPixelsToWorldUnits(this.visiblePixelsToRenderedPixels(px));
|
265
|
-
|
266
240
|
/************** RENDERING **************/
|
267
241
|
|
268
242
|
/** @override */
|
@@ -286,9 +260,9 @@ export class Mode1UpLit extends LitElement {
|
|
286
260
|
|
287
261
|
/** @param {PageModel} page */
|
288
262
|
renderPage = (page) => {
|
289
|
-
const wToR = this.worldUnitsToRenderedPixels;
|
290
|
-
const wToV = this.worldUnitsToVisiblePixels;
|
291
|
-
const containerWidth = this.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientWidth);
|
263
|
+
const wToR = this.coordSpace.worldUnitsToRenderedPixels;
|
264
|
+
const wToV = this.coordSpace.worldUnitsToVisiblePixels;
|
265
|
+
const containerWidth = this.coordSpace.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientWidth);
|
292
266
|
|
293
267
|
const width = wToR(page.widthInches);
|
294
268
|
const height = wToR(page.heightInches);
|
@@ -323,7 +297,7 @@ export class Mode1UpLit extends LitElement {
|
|
323
297
|
// Note: scrollTop, and clientWidth all are in visible space;
|
324
298
|
// i.e. they are affects by the CSS transforms.
|
325
299
|
|
326
|
-
const vToW = this.visiblePixelsToWorldUnits;
|
300
|
+
const vToW = this.coordSpace.visiblePixelsToWorldUnits;
|
327
301
|
this.visibleRegion = {
|
328
302
|
top: vToW(scrollTop),
|
329
303
|
height: vToW(clientHeight),
|
@@ -375,7 +349,7 @@ export class Mode1UpLit extends LitElement {
|
|
375
349
|
*/
|
376
350
|
computeDefaultScale(page) {
|
377
351
|
// Default to real size if it fits, otherwise default to full width
|
378
|
-
const containerWidthIn = this.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientWidth);
|
352
|
+
const containerWidthIn = this.coordSpace.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientWidth);
|
379
353
|
return Math.min(1, containerWidthIn / (page.widthInches + 2 * this.SPACING_IN)) || 1;
|
380
354
|
}
|
381
355
|
|
@@ -399,37 +373,6 @@ export class Mode1UpLit extends LitElement {
|
|
399
373
|
});
|
400
374
|
}
|
401
375
|
|
402
|
-
/************** ZOOMING LOGIC **************/
|
403
|
-
|
404
|
-
/**
|
405
|
-
* @param {number} newScale
|
406
|
-
* @param {number} oldScale
|
407
|
-
*/
|
408
|
-
updateViewportOnZoom(newScale, oldScale) {
|
409
|
-
const container = this;
|
410
|
-
const { scrollTop: T, scrollLeft: L } = container;
|
411
|
-
const W = this.htmlDimensionsCacher.clientWidth;
|
412
|
-
const H = this.htmlDimensionsCacher.clientHeight;
|
413
|
-
|
414
|
-
// Scale factor change
|
415
|
-
const F = newScale / oldScale;
|
416
|
-
|
417
|
-
// Where in the viewport the zoom is centered on
|
418
|
-
const XPOS = this.scaleCenter.x;
|
419
|
-
const YPOS = this.scaleCenter.y;
|
420
|
-
const oldCenter = {
|
421
|
-
x: L + XPOS * W,
|
422
|
-
y: T + YPOS * H,
|
423
|
-
};
|
424
|
-
const newCenter = {
|
425
|
-
x: F * oldCenter.x,
|
426
|
-
y: F * oldCenter.y,
|
427
|
-
};
|
428
|
-
container.scrollTop = newCenter.y - YPOS * H;
|
429
|
-
container.scrollLeft = newCenter.x - XPOS * W;
|
430
|
-
this.updateVisibleRegion();
|
431
|
-
}
|
432
|
-
|
433
376
|
/************** INPUT HANDLERS **************/
|
434
377
|
|
435
378
|
attachScrollListeners = () => {
|