@internetarchive/bookreader 5.0.0-36 → 5.0.0-37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. package/.github/workflows/node.js.yml +3 -3
  2. package/.github/workflows/npm-publish.yml +2 -16
  3. package/BookReader/BookReader.js +1 -1
  4. package/BookReader/BookReader.js.LICENSE.txt +8 -29
  5. package/BookReader/BookReader.js.map +1 -1
  6. package/BookReader/ia-bookreader-bundle.js +101 -100
  7. package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +15 -12
  8. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  9. package/BookReader/plugins/plugin.chapters.js +1 -1
  10. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  11. package/BookReader/plugins/plugin.search.js +1 -1
  12. package/BookReader/plugins/plugin.search.js.map +1 -1
  13. package/BookReader/plugins/plugin.text_selection.js +1 -1
  14. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  15. package/BookReader/plugins/plugin.tts.js +1 -1
  16. package/BookReader/plugins/plugin.tts.js.map +1 -1
  17. package/CHANGELOG.md +9 -0
  18. package/README.md +1 -1
  19. package/package.json +7 -10
  20. package/src/BookNavigator/assets/bookmark-colors.js +1 -1
  21. package/src/BookNavigator/assets/button-base.js +1 -1
  22. package/src/BookNavigator/assets/ia-logo.js +1 -1
  23. package/src/BookNavigator/assets/icon_checkmark.js +1 -1
  24. package/src/BookNavigator/assets/icon_close.js +1 -1
  25. package/src/BookNavigator/assets/icon_sort_asc.js +1 -1
  26. package/src/BookNavigator/assets/icon_sort_desc.js +1 -1
  27. package/src/BookNavigator/assets/icon_sort_neutral.js +1 -1
  28. package/src/BookNavigator/assets/icon_volumes.js +1 -1
  29. package/src/BookNavigator/book-navigator.js +1 -2
  30. package/src/BookNavigator/bookmarks/bookmark-button.js +1 -1
  31. package/src/BookNavigator/bookmarks/bookmark-edit.js +2 -3
  32. package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
  33. package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +1 -1
  34. package/src/BookNavigator/bookmarks/bookmarks-provider.js +1 -1
  35. package/src/BookNavigator/bookmarks/ia-bookmarks.js +4 -7
  36. package/src/BookNavigator/delete-modal-actions.js +1 -1
  37. package/src/BookNavigator/downloads/downloads-provider.js +1 -1
  38. package/src/BookNavigator/downloads/downloads.js +1 -2
  39. package/src/BookNavigator/search/a-search-result.js +2 -3
  40. package/src/BookNavigator/search/search-provider.js +1 -2
  41. package/src/BookNavigator/search/search-results.js +1 -2
  42. package/src/BookNavigator/sharing.js +1 -1
  43. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +1 -1
  44. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
  45. package/src/BookNavigator/volumes/volumes-provider.js +1 -1
  46. package/src/BookNavigator/volumes/volumes.js +2 -3
  47. package/src/BookReader/Mode1Up.js +2 -1
  48. package/src/BookReader/Mode1UpLit.js +3 -2
  49. package/src/BookReader.js +4 -2
  50. package/src/ia-bookreader/ia-bookreader.js +1 -1
  51. package/src/plugins/plugin.chapters.js +11 -15
  52. package/src/plugins/plugin.text_selection.js +9 -10
  53. package/src/plugins/search/plugin.search.js +3 -3
  54. package/src/plugins/tts/FestivalTTSEngine.js +10 -11
  55. package/src/plugins/tts/PageChunk.js +11 -20
  56. package/src/plugins/tts/WebTTSEngine.js +22 -26
  57. package/tests/jest/BookReader/Mode1UpLit.test.js +2 -1
  58. package/tests/jest/plugins/plugin.text_selection.test.js +25 -23
  59. package/tests/jest/plugins/search/plugin.search.test.js +12 -20
  60. package/tests/jest/plugins/tts/AbstractTTSEngine.test.js +3 -3
  61. package/tests/karma/BookNavigator/bookmarks/bookmarks-list.test.js +2 -2
  62. package/tests/karma/BookNavigator/downloads/downloads.test.js +1 -1
  63. package/tests/karma/BookNavigator/volumes/volumes-provider.test.js +3 -3
  64. package/webpack.config.js +1 -1
  65. package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
@@ -167,7 +167,7 @@ export class WebTTSSound {
167
167
  * left off.
168
168
  * @return {Promise<void>}
169
169
  */
170
- reload() {
170
+ async reload() {
171
171
  // We'll restore the pause state, so copy it here
172
172
  const wasPaused = this.paused;
173
173
  // Use recent event to determine where we'll restart from
@@ -179,14 +179,12 @@ export class WebTTSSound {
179
179
  }
180
180
 
181
181
  // We can't modify the utterance object, so we have to make a new one
182
- return this.stop()
183
- .then(() => {
184
- this.load();
185
- // Instead of playing and immediately pausing, we don't start playing. Note
186
- // this is a requirement because pause doesn't work consistently across
187
- // browsers.
188
- if (!wasPaused) this.play();
189
- });
182
+ await this.stop();
183
+ this.load();
184
+ // Instead of playing and immediately pausing, we don't start playing. Note
185
+ // this is a requirement because pause doesn't work consistently across
186
+ // browsers.
187
+ if (!wasPaused) this.play();
190
188
  }
191
189
 
192
190
  play() {
@@ -222,15 +220,16 @@ export class WebTTSSound {
222
220
  return endPromise;
223
221
  }
224
222
 
225
- finish() {
226
- this.stop().then(() => this.utterance.dispatchEvent(new Event('finish')));
223
+ async finish() {
224
+ await this.stop();
225
+ this.utterance.dispatchEvent(new Event('finish'));
227
226
  }
228
227
 
229
228
  /**
230
229
  * @override
231
230
  * Will fire a pause event unless already paused
232
231
  **/
233
- pause() {
232
+ async pause() {
234
233
  if (this.paused) return;
235
234
 
236
235
  const pausePromise = promisifyEvent(this.utterance, 'pause');
@@ -246,15 +245,14 @@ export class WebTTSSound {
246
245
  if (pauseMightNotFire) {
247
246
  // wait for it just in case
248
247
  const timeoutPromise = sleep(100).then(() => 'timeout');
249
- Promise.race([pausePromise, timeoutPromise])
250
- .then(result => {
251
- // We got our pause event; nothing to do!
252
- if (result != 'timeout') return;
253
-
254
- this.utterance.dispatchEvent(new CustomEvent('pause', this._lastEvents.start));
255
- // if pause might not work, then we'll stop entirely and restart later
256
- if (pauseMightNotWork) this.stop();
257
- });
248
+ const result = await Promise.race([pausePromise, timeoutPromise]);
249
+ // We got our pause event; nothing to do!
250
+ if (result != 'timeout') return;
251
+
252
+ this.utterance.dispatchEvent(new CustomEvent('pause', this._lastEvents.start));
253
+
254
+ // if pause might not work, then we'll stop entirely and restart later
255
+ if (pauseMightNotWork) this.stop();
258
256
  }
259
257
  }
260
258
 
@@ -325,13 +323,11 @@ export class WebTTSSound {
325
323
  // We could do the same as before (but resume+pause instead of pause+resume),
326
324
  // but that means we'd _constantly_ be running in the background. So in that
327
325
  // case, let's just restart the chunk
328
- Promise.race([
326
+ await Promise.race([
329
327
  promisifyEvent(this.utterance, 'resume'),
330
328
  sleep(14000).then(() => 'timeout'),
331
- ])
332
- .then(result => {
333
- result == 'timeout' ? this.reload() : this._chromePausingBugFix();
334
- });
329
+ ]);
330
+ result == 'timeout' ? this.reload() : this._chromePausingBugFix();
335
331
  break;
336
332
  case 'timeout':
337
333
  // We hit Chrome's secret cut off time. Pause/resume
@@ -35,7 +35,8 @@ describe('pageTops', () => {
35
35
  const book = new BookModel(br);
36
36
  const mode = new Mode1UpLit(book, br);
37
37
  document.body.appendChild(mode);
38
- await mode.requestUpdate();
38
+ mode.requestUpdate();
39
+ await mode.updateComplete;
39
40
  expect(mode.pageTops).toEqual({});
40
41
  });
41
42
 
@@ -19,30 +19,32 @@ const FAKE_XML_5COORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwosho
19
19
  const FAKE_XML_EMPTY = '';
20
20
 
21
21
  describe("Generic tests", () => {
22
- let br;
23
- beforeEach(() => {
24
- document.body.innerHTML = '<div id="BookReader">';
25
- br = new BookreaderWithTextSelection({
26
- data: [
27
- [
28
- { width: 800, height: 1200,
29
- uri: '//archive.org/download/BookReader/img/page001.jpg' },
30
- ],
31
- [
32
- { width: 800, height: 1200,
33
- uri: '//archive.org/download/BookReader/img/page002.jpg' },
34
- { width: 800, height: 1200,
35
- uri: '//archive.org/download/BookReader/img/page003.jpg' },
36
- ],
37
- [
38
- { width: 800, height: 1200,
39
- uri: '//archive.org/download/BookReader/img/page004.jpg' },
40
- { width: 800, height: 1200,
41
- uri: '//archive.org/download/BookReader/img/page005.jpg' },
42
- ]
22
+ document.body.innerHTML = '<div id="BookReader">';
23
+ const br = new BookreaderWithTextSelection({
24
+ data: [
25
+ [
26
+ { width: 800, height: 1200,
27
+ uri: '//archive.org/download/BookReader/img/page001.jpg' },
43
28
  ],
44
- });
45
- br.init();
29
+ [
30
+ { width: 800, height: 1200,
31
+ uri: '//archive.org/download/BookReader/img/page002.jpg' },
32
+ { width: 800, height: 1200,
33
+ uri: '//archive.org/download/BookReader/img/page003.jpg' },
34
+ ],
35
+ [
36
+ { width: 800, height: 1200,
37
+ uri: '//archive.org/download/BookReader/img/page004.jpg' },
38
+ { width: 800, height: 1200,
39
+ uri: '//archive.org/download/BookReader/img/page005.jpg' },
40
+ ]
41
+ ],
42
+ });
43
+ br.init();
44
+
45
+ afterEach(() => {
46
+ sinon.restore();
47
+ $('.textSelectionSVG').remove();
46
48
  });
47
49
 
48
50
  test("_createPageContainer overridden function still creates a BRpagecontainer element", () => {
@@ -123,28 +123,24 @@ describe('Plugin: Search', () => {
123
123
  expect(br.options.goToFirstResult).toBeTruthy();
124
124
  });
125
125
 
126
- test('SearchCallback event fires when AJAX search returns results', () => {
126
+ test('SearchCallback event fires when AJAX search returns results', async () => {
127
127
  br.init();
128
- const dfd = br.search('foo');
129
- return dfd.then(() => {
130
- expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
131
- });
128
+ await br.search('foo');
129
+ expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
132
130
  });
133
131
 
134
- test('SearchCallbackError event fires when AJAX search returns error', () => {
132
+ test('SearchCallbackError event fires when AJAX search returns error', async () => {
135
133
  $.ajax = jest.fn().mockImplementation(() => {
136
134
  return Promise.resolve({
137
135
  error: true,
138
136
  });
139
137
  });
140
138
  br.init();
141
- const dfd = br.search('foo');
142
- return dfd.then(() => {
143
- expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
144
- });
139
+ await br.search('foo');
140
+ expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
145
141
  });
146
142
 
147
- test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', () => {
143
+ test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', async () => {
148
144
  $.ajax = jest.fn().mockImplementation(() => {
149
145
  return Promise.resolve({
150
146
  matches: [],
@@ -152,22 +148,18 @@ describe('Plugin: Search', () => {
152
148
  });
153
149
  });
154
150
  br.init();
155
- const dfd = br.search('foo');
156
- return dfd.then(() => {
157
- expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
158
- });
151
+ await br.search('foo');
152
+ expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
159
153
  });
160
154
 
161
- test('SearchCallbackEmpty event fires when AJAX search returns no matches', () => {
155
+ test('SearchCallbackEmpty event fires when AJAX search returns no matches', async () => {
162
156
  $.ajax = jest.fn().mockImplementation(() => {
163
157
  return Promise.resolve({
164
158
  matches: [],
165
159
  });
166
160
  });
167
161
  br.init();
168
- const dfd = br.search('foo');
169
- return dfd.then(() => {
170
- expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
171
- });
162
+ await br.search('foo');
163
+ expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
172
164
  });
173
165
  });
@@ -6,7 +6,7 @@ import PageChunkIterator from '@/src/plugins/tts/PageChunkIterator.js';
6
6
 
7
7
  // Skipping because it's flaky. Fix in #672
8
8
  describe.skip('AbstractTTSEngine', () => {
9
- test('stops playing once done', () => {
9
+ test('stops playing once done', async () => {
10
10
  class DummyEngine extends AbstractTTSEngine {
11
11
  getVoices() { return []; }
12
12
  }
@@ -15,8 +15,8 @@ describe.skip('AbstractTTSEngine', () => {
15
15
  const stopStub = sinon.stub(d, 'stop');
16
16
  expect(stopStub.callCount).toBe(0);
17
17
  d.step();
18
- return afterEventLoop()
19
- .then(() => expect(stopStub.callCount).toBe(1));
18
+ await afterEventLoop();
19
+ expect(stopStub.callCount).toBe(1);
20
20
  });
21
21
  });
22
22
 
@@ -49,7 +49,7 @@ describe('<ia-bookmarks-list>', () => {
49
49
  it('renders bookmarks that contain page numbers', async () => {
50
50
  const el = await fixture(container(bookmarks));
51
51
 
52
- expect(el.shadowRoot.innerHTML).to.include(`Page ${bookmarks[0].page}`);
52
+ expect(el.shadowRoot.textContent).to.include(`Page ${bookmarks[0].page}`);
53
53
  });
54
54
 
55
55
  it('renders bookmarks that contain an optional note', async () => {
@@ -161,7 +161,7 @@ describe('<ia-bookmarks-list>', () => {
161
161
  const el = await fixture(container([bookmarks[0]]));
162
162
  const bookmarksCount = await fixture(el.bookmarksCount);
163
163
 
164
- expect(bookmarksCount.innerHTML).to.include('(1)');
164
+ expect(bookmarksCount.textContent).to.include('(1)');
165
165
  });
166
166
 
167
167
  it('does not render the bookmarks count when no bookmarks present', async () => {
@@ -49,6 +49,6 @@ describe('<ia-book-downloads>', () => {
49
49
  expect(el.shadowRoot.querySelector("ul").childElementCount).to.equal(2);
50
50
  expect(el.isBookProtected).to.equal(false);
51
51
 
52
- expect(el.shadowRoot.querySelector("ul li a").innerHTML).to.include("Get PDF");
52
+ expect(el.shadowRoot.querySelector("ul li a").textContent).to.include("Get PDF");
53
53
  });
54
54
  });
@@ -77,15 +77,15 @@ describe('Volumes Provider', () => {
77
77
 
78
78
  provider.sortVolumes("title_asc");
79
79
  expect(provider.sortOrderBy).to.equal("title_asc");
80
- expect(provider.sortButton.getHTML()).includes("sort-by asc-icon");
80
+ expect(fixtureSync(provider.sortButton).outerHTML).includes("sort-by asc-icon");
81
81
 
82
82
  provider.sortVolumes("title_desc");
83
83
  expect(provider.sortOrderBy).to.equal("title_desc");
84
- expect(provider.sortButton.getHTML()).includes("sort-by desc-icon");
84
+ expect(fixtureSync(provider.sortButton).outerHTML).includes("sort-by desc-icon");
85
85
 
86
86
  provider.sortVolumes("default");
87
87
  expect(provider.sortOrderBy).to.equal("default");
88
- expect(provider.sortButton.getHTML()).includes("sort-by neutral-icon");
88
+ expect(fixtureSync(provider.sortButton).outerHTML).includes("sort-by neutral-icon");
89
89
  });
90
90
 
91
91
  it('sort volumes in initial order', async () => {
package/webpack.config.js CHANGED
@@ -16,7 +16,7 @@ const shared = {
16
16
  rules: [
17
17
  {
18
18
  test: /\.js$/,
19
- exclude: /node_modules[/\\](?!(lit-element|lit-html)[/\\]).*/,
19
+ exclude: /node_modules[/\\](?!(lit-element|lit-html|lit|@lit)[/\\]).*/,
20
20
  loader: "babel-loader",
21
21
  }
22
22
  ]