@internetarchive/bookreader 5.0.0-50 → 5.0.0-52

Sign up to get free protection for your applications and to get access to all the features.
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', () => {