@internetarchive/bookreader 5.0.0-50 → 5.0.0-52

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 5.0.0-52
2
+ # 5.0.0-51
3
+ - Fix: Bookmark with subfiles was broken @nsharma123
4
+ - Feature: Default 1up mode and options.defaults mode override exiting mode @nsharma123
5
+
1
6
  # 5.0.0-50
2
7
  Fix: Search results display @latonv
3
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/bookreader",
3
- "version": "5.0.0-50",
3
+ "version": "5.0.0-52",
4
4
  "description": "The Internet Archive BookReader.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -137,7 +137,7 @@ class IABookmarks extends LitElement {
137
137
  }
138
138
 
139
139
  setup() {
140
- this.api.identifier = this.bookreader.bookId;
140
+ this.api.identifier = this.getIdentifier();
141
141
  if (this.displayMode === 'login') {
142
142
  return;
143
143
  }
@@ -145,6 +145,19 @@ class IABookmarks extends LitElement {
145
145
  this.setBREventListeners();
146
146
  }
147
147
 
148
+ /**
149
+ * get identifier for current book including sub-files
150
+ *
151
+ * @returns Identifer
152
+ */
153
+ getIdentifier() {
154
+ if (this.bookreader.bookId !== this.bookreader.subPrefix) {
155
+ return `${this.bookreader.bookId}/${this.bookreader.subPrefix}`;
156
+ }
157
+
158
+ return this.bookreader.bookId;
159
+ }
160
+
148
161
  updateDisplay() {
149
162
  if (this.displayMode === 'bookmarks') {
150
163
  this.fetchUserBookmarks();
package/src/BookReader.js CHANGED
@@ -455,16 +455,18 @@ BookReader.prototype.readQueryString = function() {
455
455
  * @return {number} the mode
456
456
  */
457
457
  BookReader.prototype.getInitialMode = function(params) {
458
- // Use params or browser width to set view mode
459
- const windowWidth = $(window).width();
460
458
  let nextMode;
459
+
460
+ // if mobile breakpoint, we always show this.constMode1up mode
461
+ const ifMobileBreakpoint = () => {
462
+ // Use params or browser width to set view mode
463
+ const windowWidth = $(window).width();
464
+ return windowWidth && windowWidth <= this.onePageMinBreakpoint;
465
+ };
461
466
  if ('undefined' != typeof(params.mode)) {
462
467
  nextMode = params.mode;
463
- } else if (this.ui == 'full'
464
- && this.isFullscreenActive
465
- && windowWidth <= this.onePageMinBreakpoint
466
- ) {
467
- // In full mode, we set the default based on width
468
+ } else if ((this.ui == 'full' && this.isFullscreenActive) || ifMobileBreakpoint()) {
469
+ // In full mode OR device width, we set the default based on width
468
470
  nextMode = this.constMode1up;
469
471
  } else {
470
472
  nextMode = this.constMode2up;
@@ -473,6 +475,36 @@ BookReader.prototype.getInitialMode = function(params) {
473
475
  if (!this.canSwitchToMode(nextMode)) {
474
476
  nextMode = this.constMode1up;
475
477
  }
478
+
479
+ // override defaults mode via `options.defaults` metadata
480
+ if (this.options.defaults) {
481
+ nextMode = this.overridesBookMode();
482
+ }
483
+
484
+ return nextMode;
485
+ };
486
+
487
+ /**
488
+ * Overrides book mode using options.defaults param
489
+ * @return {number} the mode
490
+ */
491
+ BookReader.prototype.overridesBookMode = function() {
492
+ let nextMode = 2; // set default 2 (mode/2up)
493
+
494
+ switch (this.options.defaults) {
495
+ case 'mode/1up':
496
+ nextMode = this.constMode1up;
497
+ break;
498
+ case 'mode/2up':
499
+ nextMode = this.constMode2up;
500
+ break;
501
+ case 'mode/thumb':
502
+ nextMode = this.constModeThumb;
503
+ break;
504
+ default:
505
+ break;
506
+ }
507
+
476
508
  return nextMode;
477
509
  };
478
510
 
@@ -71,7 +71,22 @@ export default class WebTTSEngine extends AbstractTTSEngine {
71
71
  }
72
72
 
73
73
  /** @override */
74
- getVoices() { return speechSynthesis.getVoices(); }
74
+ getVoices() {
75
+ const voices = speechSynthesis.getVoices();
76
+ if (voices.filter(v => v.default).length != 1) {
77
+ // iOS bug where the default system voice is sometimes
78
+ // missing from the list
79
+ voices.unshift({
80
+ voiceURI: 'bookreader.SystemDefault',
81
+ name: 'System Default',
82
+ // Not necessarily true, but very likely
83
+ lang: navigator.language,
84
+ default: true,
85
+ localService: true,
86
+ });
87
+ }
88
+ return voices;
89
+ }
75
90
 
76
91
  /** @override */
77
92
  createSound(chunk) {
@@ -122,7 +137,11 @@ export class WebTTSSound {
122
137
  this.started = false;
123
138
 
124
139
  this.utterance = new SpeechSynthesisUtterance(this.text.slice(this._charIndex));
125
- this.utterance.voice = this.voice;
140
+ // iOS bug where the default system voice is sometimes
141
+ // missing from the list
142
+ if (this.voice?.voiceURI !== 'bookreader.SystemDefault') {
143
+ this.utterance.voice = this.voice;
144
+ }
126
145
  // Need to also set lang (for some reason); won't set voice on Chrome@Android otherwise
127
146
  if (this.voice) this.utterance.lang = this.voice.lang;
128
147
  this.utterance.rate = this.rate;
@@ -279,4 +279,35 @@ describe('nextReduce', () => {
279
279
  expect(nextReduce(2, 'auto', SAMPLE_FACTORS).reduce).toBe(0.5);
280
280
  });
281
281
  });
282
+
283
+ describe('Override book page mode using options.default param', () => {
284
+ test('replace current mode with options.default is set mode/1up', () => {
285
+ br.options.defaults = 'mode/1up';
286
+
287
+ const nextModeNumber = br.overridesBookMode();
288
+ expect(nextModeNumber).toBe(1);
289
+ });
290
+
291
+ test('replace current mode with options.default is set mode/2up', () => {
292
+ br.options.defaults = 'mode/2up';
293
+
294
+ const nextModeNumber = br.overridesBookMode();
295
+ expect(nextModeNumber).toBe(2);
296
+ });
297
+
298
+ test('replace current mode with options.default is set mode/thumb', () => {
299
+ br.options.defaults = 'mode/thumb';
300
+
301
+ const nextModeNumber = br.overridesBookMode();
302
+ expect(nextModeNumber).toBe(3);
303
+ });
304
+
305
+ test('test if options.default is NOT set', () => {
306
+ br.options.defaults = null;
307
+
308
+ // use mode/2up as default when no options.default metadata found
309
+ const nextModeNumber = br.overridesBookMode();
310
+ expect(nextModeNumber).toBe(2);
311
+ });
312
+ });
282
313
  });
@@ -1,5 +1,5 @@
1
1
  import sinon from 'sinon';
2
- import { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
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', () => {