@internetarchive/bookreader 5.0.0-92 → 5.0.0-94

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.
Files changed (102) hide show
  1. package/BookReader/BookReader.css +2 -1
  2. package/BookReader/BookReader.js +1 -1
  3. package/BookReader/BookReader.js.map +1 -1
  4. package/BookReader/ia-bookreader-bundle.js +14 -14
  5. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  6. package/BookReader/images/hypothesis.ico +0 -0
  7. package/BookReader/jquery-3.js +1 -1
  8. package/BookReader/plugins/plugin.archive_analytics.js +1 -1
  9. package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
  10. package/BookReader/plugins/plugin.autoplay.js +1 -1
  11. package/BookReader/plugins/plugin.autoplay.js.map +1 -1
  12. package/BookReader/plugins/plugin.chapters.js +2 -2
  13. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  14. package/BookReader/plugins/plugin.experiments.js +3 -0
  15. package/BookReader/plugins/plugin.experiments.js.LICENSE.txt +1 -0
  16. package/BookReader/plugins/plugin.experiments.js.map +1 -0
  17. package/BookReader/plugins/plugin.iframe.js +1 -1
  18. package/BookReader/plugins/plugin.iiif.js +1 -1
  19. package/BookReader/plugins/plugin.iiif.js.map +1 -1
  20. package/BookReader/plugins/plugin.resume.js +1 -1
  21. package/BookReader/plugins/plugin.resume.js.map +1 -1
  22. package/BookReader/plugins/plugin.search.js +1 -1
  23. package/BookReader/plugins/plugin.search.js.map +1 -1
  24. package/BookReader/plugins/plugin.text_selection.js +1 -1
  25. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  26. package/BookReader/plugins/plugin.tts.js +1 -1
  27. package/BookReader/plugins/plugin.tts.js.map +1 -1
  28. package/BookReader/plugins/plugin.url.js +1 -1
  29. package/BookReader/plugins/plugin.url.js.map +1 -1
  30. package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
  31. package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
  32. package/BookReaderDemo/IADemoBr.js +1 -24
  33. package/BookReaderDemo/demo-internetarchive.html +1 -0
  34. package/CHANGELOG.md +14 -0
  35. package/package.json +8 -4
  36. package/scripts/postversion.js +3 -2
  37. package/scripts/preversion.js +3 -1
  38. package/scripts/version.js +4 -3
  39. package/src/BookNavigator/book-navigator.js +38 -12
  40. package/src/BookNavigator/downloads/downloads-provider.js +2 -2
  41. package/src/BookNavigator/search/search-provider.js +5 -5
  42. package/src/BookNavigator/search/search-results.js +1 -1
  43. package/src/BookNavigator/sharing.js +2 -2
  44. package/src/BookNavigator/viewable-files.js +2 -2
  45. package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +3 -3
  46. package/src/BookNavigator/visual-adjustments/visual-adjustments.js +2 -2
  47. package/src/BookReader/BookModel.js +13 -3
  48. package/src/BookReader/ImageCache.js +2 -2
  49. package/src/BookReader/Mode1Up.js +2 -0
  50. package/src/BookReader/Mode1UpLit.js +5 -5
  51. package/src/BookReader/Mode2Up.js +2 -0
  52. package/src/BookReader/Mode2UpLit.js +5 -5
  53. package/src/BookReader/ModeCoordinateSpace.js +1 -1
  54. package/src/BookReader/ModeThumb.js +2 -0
  55. package/src/BookReader/PageContainer.js +4 -1
  56. package/src/BookReader/Toolbar/Toolbar.js +1 -1
  57. package/src/BookReader/options.js +5 -0
  58. package/src/BookReader/utils/HTMLDimensionsCacher.js +1 -1
  59. package/src/BookReader/utils.js +13 -0
  60. package/src/BookReader.js +57 -31
  61. package/src/assets/images/hypothesis.ico +0 -0
  62. package/src/css/_TextSelection.scss +3 -1
  63. package/src/plugins/plugin.autoplay.js +3 -3
  64. package/src/plugins/plugin.chapters.js +2 -2
  65. package/src/plugins/plugin.experiments.js +294 -0
  66. package/src/plugins/plugin.iiif.js +1 -1
  67. package/src/plugins/plugin.text_selection.js +112 -1
  68. package/src/plugins/search/plugin.search.js +2 -2
  69. package/src/plugins/search/view.js +5 -5
  70. package/src/plugins/tts/plugin.tts.js +3 -3
  71. package/src/plugins/url/plugin.url.js +2 -2
  72. package/tests/e2e/autoplay.test.js +1 -1
  73. package/tests/e2e/base.test.js +4 -4
  74. package/tests/e2e/helpers/base.js +2 -2
  75. package/tests/e2e/models/BookReader.js +1 -1
  76. package/tests/e2e/rightToLeft.test.js +4 -4
  77. package/tests/e2e/viewmode.test.js +2 -2
  78. package/tests/jest/BookNavigator/book-navigator.test.js +0 -13
  79. package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +1 -1
  80. package/tests/jest/BookNavigator/downloads/downloads.test.js +1 -1
  81. package/tests/jest/BookNavigator/search/search-provider.test.js +5 -5
  82. package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +1 -1
  83. package/tests/jest/BookReader/Mode2Up.test.js +1 -1
  84. package/tests/jest/BookReader/ModeCoordinateSpace.test.js +1 -1
  85. package/tests/jest/BookReader/PageContainer.test.js +14 -3
  86. package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +1 -1
  87. package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +1 -1
  88. package/tests/jest/BookReader/utils/SelectionObserver.test.js +1 -1
  89. package/tests/jest/BookReader.test.js +10 -10
  90. package/tests/jest/plugins/plugin.autoplay.test.js +6 -6
  91. package/tests/jest/plugins/plugin.chapters.test.js +2 -2
  92. package/tests/jest/plugins/plugin.resume.test.js +13 -13
  93. package/tests/jest/plugins/plugin.text_selection.test.js +155 -24
  94. package/tests/jest/plugins/search/plugin.search.test.js +7 -7
  95. package/tests/jest/plugins/search/plugin.search.view.test.js +8 -8
  96. package/tests/jest/plugins/search/utils.js +1 -1
  97. package/tests/jest/plugins/tts/PageChunkIterator.test.js +2 -2
  98. package/tests/jest/plugins/url/UrlPlugin.test.js +1 -1
  99. package/webpack.config.js +8 -3
  100. /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
  101. /package/{.testcaferc.js → .testcaferc.cjs} +0 -0
  102. /package/{babel.config.js → babel.config.cjs} +0 -0
@@ -3,14 +3,14 @@ import sinon from 'sinon';
3
3
  import BookReader from '@/src/BookReader.js';
4
4
  import {
5
5
  Cache,
6
+ genAt,
7
+ genFilter,
6
8
  genMap,
7
9
  lookAroundWindow,
10
+ walkBetweenNodes,
8
11
  zip,
9
12
  } from '@/src/plugins/plugin.text_selection.js';
10
13
 
11
-
12
- /** @type {BookReader} */
13
-
14
14
  // djvu.xml book infos copied from https://ia803103.us.archive.org/14/items/goodytwoshoes00newyiala/goodytwoshoes00newyiala_djvu.xml
15
15
  const FAKE_XML_1WORD = `
16
16
  <OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
@@ -113,9 +113,56 @@ describe("Generic tests", () => {
113
113
  $('.BRtextLayer').remove();
114
114
  });
115
115
 
116
+ test("_limitSelection handles short selection", async () => {
117
+ const $container = br.refs.$brContainer;
118
+ br.options.plugins.textSelection.maxProtectedWords = 5;
119
+ sinon.stub(br.plugins.textSelection, "getPageText")
120
+ .returns($(new DOMParser().parseFromString(FAKE_XML_MULT_LINES, "text/xml")));
121
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
122
+
123
+ const rangeBefore = document.createRange();
124
+ rangeBefore.setStart($container.find(".BRwordElement")[0].firstChild, 0);
125
+ rangeBefore.setEnd($container.find(".BRwordElement")[4].firstChild, 1);
126
+ const selection = window.getSelection();
127
+ selection.removeAllRanges();
128
+ selection.addRange(rangeBefore);
129
+
130
+ br.plugins.textSelection._limitSelection();
131
+
132
+ const rangeAfter = window.getSelection().getRangeAt(0);
133
+ expect(rangeAfter.startContainer).toBe(rangeBefore.startContainer);
134
+ expect(rangeAfter.startOffset).toBe(0);
135
+ expect(rangeAfter.endContainer).toBe(rangeBefore.endContainer);
136
+ expect(rangeAfter.endOffset).toBe(1);
137
+
138
+ window.getSelection().removeAllRanges();
139
+ });
140
+
141
+ test("_limitSelection shrinks selection", async () => {
142
+ const $container = br.refs.$brContainer;
143
+ br.options.plugins.textSelection.maxProtectedWords = 5;
144
+ sinon.stub(br.plugins.textSelection, "getPageText")
145
+ .returns($(new DOMParser().parseFromString(FAKE_XML_MULT_LINES, "text/xml")));
146
+
147
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
148
+
149
+ const rangeBefore = document.createRange();
150
+ rangeBefore.setStart($container.find(".BRwordElement")[0].firstChild, 0);
151
+ rangeBefore.setEnd($container.find(".BRwordElement")[12].firstChild, 1);
152
+ const selection = window.getSelection();
153
+ selection.removeAllRanges();
154
+ selection.addRange(rangeBefore);
155
+
156
+ br.plugins.textSelection._limitSelection();
157
+
158
+ const rangeAfter = window.getSelection().getRangeAt(0);
159
+ expect(rangeAfter.startContainer).toBe(rangeBefore.startContainer);
160
+ expect(rangeAfter.endContainer).toBe($container.find(".BRwordElement")[4].firstChild);
161
+ });
162
+
116
163
  test("_createPageContainer overridden function still creates a BRpagecontainer element", () => {
117
- const spy = sinon.spy(br._plugins.textSelection, 'createTextLayer');
118
- sinon.stub(br._plugins.textSelection, "getPageText")
164
+ const spy = sinon.spy(br.plugins.textSelection, 'createTextLayer');
165
+ sinon.stub(br.plugins.textSelection, "getPageText")
119
166
  .returns($(new DOMParser().parseFromString(FAKE_XML_1WORD, "text/xml")));
120
167
  const container = br._createPageContainer(1, {});
121
168
  expect(container).toBeTruthy();
@@ -124,24 +171,24 @@ describe("Generic tests", () => {
124
171
 
125
172
  // test loading first object from sample data
126
173
  test("_createPageContainer handles index 0", () => {
127
- const spy = sinon.spy(br._plugins.textSelection, 'createTextLayer');
174
+ const spy = sinon.spy(br.plugins.textSelection, 'createTextLayer');
128
175
  br._createPageContainer(0, {});
129
176
  expect(spy.callCount).toBe(1);
130
177
  });
131
178
 
132
179
  // test loading last object from sample data
133
180
  test("_createPageContainer handles index -1", () => {
134
- const spy = sinon.spy(br._plugins.textSelection, 'createTextLayer');
181
+ const spy = sinon.spy(br.plugins.textSelection, 'createTextLayer');
135
182
  br._createPageContainer(-1, {});
136
183
  expect(spy.callCount).toBe(0);
137
184
  });
138
185
 
139
186
  test("createTextLayer will render the last page and create text layer properly", async () => {
140
187
  const $container = br.refs.$brContainer;
141
- sinon.stub(br._plugins.textSelection, "getPageText")
188
+ sinon.stub(br.plugins.textSelection, "getPageText")
142
189
  .returns($(new DOMParser().parseFromString(FAKE_XML_1WORD, "text/xml")));
143
190
  const pageIndex = br.data.length - 1;
144
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: pageIndex, width: 100, height: 100 }});
191
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: pageIndex, width: 100, height: 100 }});
145
192
  expect($container.find(".BRtextLayer").length).toBe(1);
146
193
  expect($container.find("p").length).toBe(1);
147
194
  });
@@ -149,9 +196,9 @@ describe("Generic tests", () => {
149
196
  test("createTextLayer will not create text layer if there are too many words", async () => {
150
197
  const $container = br.refs.$brContainer;
151
198
  const xml = FAKE_XML_1WORD.replace(/<WORD.*<\/WORD>/, FAKE_XML_1WORD.match(/<WORD.*<\/WORD>/)[0].repeat(3000));
152
- sinon.stub(br._plugins.textSelection, "getPageText")
199
+ sinon.stub(br.plugins.textSelection, "getPageText")
153
200
  .returns($(new DOMParser().parseFromString(xml, "text/xml")));
154
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 0, width: 100, height: 100 }});
201
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 0, width: 100, height: 100 }});
155
202
  expect($container.find(".BRtextLayer").length).toBe(0);
156
203
  expect($container.find("p").length).toBe(0);
157
204
  expect($container.find(".BRwordElement").length).toBe(0);
@@ -159,9 +206,9 @@ describe("Generic tests", () => {
159
206
 
160
207
  test("createTextLayer creates text layer with paragraph with 1 word element", async () => {
161
208
  const $container = br.refs.$brContainer;
162
- sinon.stub(br._plugins.textSelection, "getPageText")
209
+ sinon.stub(br.plugins.textSelection, "getPageText")
163
210
  .returns($(new DOMParser().parseFromString(FAKE_XML_1WORD, "text/xml")));
164
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 1, width: 100, height: 100 }});
211
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 1, width: 100, height: 100 }});
165
212
  expect($container.find(".BRtextLayer").length).toBe(1);
166
213
  expect($container.find("p").length).toBe(1);
167
214
  expect($container.find(".BRwordElement").length).toBe(1);
@@ -170,9 +217,9 @@ describe("Generic tests", () => {
170
217
 
171
218
  test("createTextLayer creates text layer with paragraph with multiple word elements", async () => {
172
219
  const $container = br.refs.$brContainer;
173
- sinon.stub(br._plugins.textSelection, "getPageText")
220
+ sinon.stub(br.plugins.textSelection, "getPageText")
174
221
  .returns($(new DOMParser().parseFromString(FAKE_XML_MULT_WORDS, "text/xml")));
175
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 2, width: 100, height: 100 }});
222
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 2, width: 100, height: 100 }});
176
223
  expect($container.find(".BRtextLayer").length).toBe(1);
177
224
  expect($container.find("p").length).toBe(1);
178
225
  expect($container.find(".BRwordElement").length).toBe(3);
@@ -181,9 +228,9 @@ describe("Generic tests", () => {
181
228
 
182
229
  test("createTextLayer creates text layer with paragraph with word with 5 params coordinates", async () => {
183
230
  const $container = br.refs.$brContainer;
184
- sinon.stub(br._plugins.textSelection, "getPageText")
231
+ sinon.stub(br.plugins.textSelection, "getPageText")
185
232
  .returns($(new DOMParser().parseFromString(FAKE_XML_5COORDS, "text/xml")));
186
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
233
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
187
234
  expect($container.find(".BRtextLayer").length).toBe(1);
188
235
  expect($container.find("p").length).toBe(1);
189
236
  expect($container.find(".BRwordElement").length).toBe(1);
@@ -191,9 +238,9 @@ describe("Generic tests", () => {
191
238
 
192
239
  test("createTextLayer handles multiple lines", async () => {
193
240
  const $container = br.refs.$brContainer;
194
- sinon.stub(br._plugins.textSelection, "getPageText")
241
+ sinon.stub(br.plugins.textSelection, "getPageText")
195
242
  .returns($(new DOMParser().parseFromString(FAKE_XML_MULT_LINES, "text/xml")));
196
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
243
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
197
244
  expect($container.find(".BRtextLayer").length).toBe(1);
198
245
  expect($container.find("p").length).toBe(1);
199
246
  expect($container.find(".BRlineElement").length).toBe(3);
@@ -206,9 +253,9 @@ describe("Generic tests", () => {
206
253
 
207
254
  test("createTextLayer repairs trailing hyphens", async () => {
208
255
  const $container = br.refs.$brContainer;
209
- sinon.stub(br._plugins.textSelection, "getPageText")
256
+ sinon.stub(br.plugins.textSelection, "getPageText")
210
257
  .returns($(new DOMParser().parseFromString(FAKE_XML_MULT_LINES, "text/xml")));
211
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
258
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 3, width: 100, height: 100 }});
212
259
 
213
260
  expect($container.find(".BRwordElement--hyphen").length).toBe(1);
214
261
  expect($container.find(".BRwordElement--hyphen").closest(".BRlineElement").text().endsWith(' ')).toBe(false);
@@ -217,9 +264,9 @@ describe("Generic tests", () => {
217
264
 
218
265
  test("createTextLayer can handle empty xml", async () => {
219
266
  const $container = br.refs.$brContainer;
220
- sinon.stub(br._plugins.textSelection, "getPageText")
267
+ sinon.stub(br.plugins.textSelection, "getPageText")
221
268
  .returns($(new DOMParser().parseFromString(FAKE_XML_EMPTY, "text/xml")));
222
- await br._plugins.textSelection.createTextLayer({ $container, page: { index: 4, width: 100, height: 100 }});
269
+ await br.plugins.textSelection.createTextLayer({ $container, page: { index: 4, width: 100, height: 100 }});
223
270
  expect($container.find(".BRtextLayer").length).toBe(1);
224
271
  expect($container.find("p").length).toBe(0);
225
272
  expect($container.find(".BRwordElement").length).toBe(0);
@@ -228,7 +275,7 @@ describe("Generic tests", () => {
228
275
  const LONG_PRESS_DURATION = 500;
229
276
  test("calling stopPageFlip does not allow long click to flip the page", () => {
230
277
  const $container = br.refs.$brContainer;
231
- br._plugins.textSelection.stopPageFlip($container);
278
+ br.plugins.textSelection.stopPageFlip($container);
232
279
  const currIndex = br.currentIndex();
233
280
  $container.find("BRwordElement").trigger("mousedown");
234
281
  // Waits for long press
@@ -270,6 +317,38 @@ describe("Cache", () => {
270
317
  });
271
318
  });
272
319
 
320
+ describe('genAt', () => {
321
+ test('handles empty', () => {
322
+ expect(genAt(genRange(-1), 0)).toBeUndefined();
323
+ });
324
+
325
+ test('handles non-empty', () => {
326
+ expect(genAt(genRange(3), 0)).toBe(0);
327
+ expect(genAt(genRange(3), 1)).toBe(1);
328
+ expect(genAt(genRange(3), 2)).toBe(2);
329
+ });
330
+
331
+ test('handles out of bounds', () => {
332
+ expect(genAt(genRange(3), 4)).toBeUndefined();
333
+ expect(genAt(genRange(3), -1)).toBeUndefined();
334
+ });
335
+ });
336
+
337
+ describe('genFilter', () => {
338
+ test('handles empty', () => {
339
+ expect(Array.from(genFilter(genRange(0), x => x > 0))).toEqual([]);
340
+ });
341
+
342
+ test('handles non-empty', () => {
343
+ expect(Array.from(genFilter(genRange(3), x => x > 1))).toEqual([2, 3]);
344
+ expect(Array.from(genFilter(genRange(3), x => x < 1))).toEqual([0]);
345
+ });
346
+
347
+ test('handles all false', () => {
348
+ expect(Array.from(genFilter(genRange(3), x => x > 3))).toEqual([]);
349
+ });
350
+ });
351
+
273
352
  describe('genMap', () => {
274
353
  test('handles empty', () => {
275
354
  expect(Array.from(genMap([], x => x ** 2))).toEqual([]);
@@ -314,3 +393,55 @@ describe('zip', () => {
314
393
  expect(Array.from(zip([1, 2], [3, 4]))).toEqual([[1, 3], [2, 4]]);
315
394
  });
316
395
  });
396
+
397
+ describe('walkBetweenNodes', () => {
398
+ const tree = $(FAKE_XML_MULT_LINES);
399
+
400
+ test('handles empty', () => {
401
+ const result = Array.from(walkBetweenNodes(tree[0], tree[0]));
402
+ expect(result).toHaveLength(1);
403
+ expect(result[0]).toBe(tree[0]);
404
+ });
405
+
406
+ test('Words on same line', () => {
407
+ const start = tree.find('WORD')[2];
408
+ const end = start.nextElementSibling;
409
+ // Use first child so we hit the text nodes
410
+ const result = Array.from(walkBetweenNodes(start.firstChild, end.firstChild));
411
+ expect(result).toHaveLength(5);
412
+ expect(result[0].nodeType).toBe(Node.TEXT_NODE);
413
+ expect(result[0].textContent).toBe('false ');
414
+ expect(result[1]).toBe(start);
415
+ // Whitespace
416
+ expect(result[2].nodeType).toBe(Node.TEXT_NODE);
417
+ expect(result[2].textContent).toMatch(/^\s*$/);
418
+ expect(result[3]).toBe(end);
419
+ expect(result[4].nodeType).toBe(Node.TEXT_NODE);
420
+ expect(result[4].textContent).toBe('judgment ');
421
+ });
422
+
423
+ test('Words on different lines', () => {
424
+ const start = tree.find('WORD')[2];
425
+ const end = tree.find('WORD')[19];
426
+ const result = Array.from(walkBetweenNodes(start.firstChild, end.firstChild));
427
+ // Expect two LINES in result
428
+ expect(result.filter(x => x.nodeName == 'LINE')).toHaveLength(2);
429
+ // Expect 18 WORDs in result
430
+ expect(result.filter(x => x.nodeName == 'WORD')).toHaveLength(18);
431
+ // First word should be the start word
432
+ expect(result[0].parentElement).toBe(start);
433
+ expect(result[0].textContent).toBe('false ');
434
+ // Last word should be the end word
435
+ expect(result[result.length - 1].parentElement).toBe(end);
436
+ expect(result[result.length - 1].textContent).toBe('Suppose');
437
+ });
438
+ });
439
+
440
+ /**
441
+ * @param {number} n
442
+ */
443
+ function* genRange(n) {
444
+ for (let i = 0; i <= n; i++) {
445
+ yield i;
446
+ }
447
+ }
@@ -31,7 +31,7 @@ beforeEach(() => {
31
31
  });
32
32
  br.initToolbar = jest.fn();
33
33
  br.showProgressPopup = jest.fn();
34
- br._plugins.search.searchXHR = jest.fn();
34
+ br.plugins.search.searchXHR = jest.fn();
35
35
  });
36
36
 
37
37
  afterEach(() => {
@@ -45,18 +45,18 @@ describe('Plugin: Search', () => {
45
45
  });
46
46
 
47
47
  test('Constructs SearchView', () => {
48
- expect(br._plugins.search.searchView).toBeDefined();
48
+ expect(br.plugins.search.searchView).toBeDefined();
49
49
  });
50
50
 
51
51
  test('On init, it will run a search if given `options.initialSearchTerm`', () => {
52
- br._plugins.search.search = jest.fn();
52
+ br.plugins.search.search = jest.fn();
53
53
  br.options.plugins.search.initialSearchTerm = 'foo';
54
54
  br.init();
55
55
 
56
- expect(br._plugins.search.search).toHaveBeenCalled();
57
- expect(br._plugins.search.search.mock.calls[0][1])
56
+ expect(br.plugins.search.search).toHaveBeenCalled();
57
+ expect(br.plugins.search.search.mock.calls[0][1])
58
58
  .toHaveProperty('goToFirstResult', true);
59
- expect(br._plugins.search.search.mock.calls[0][1])
59
+ expect(br.plugins.search.search.mock.calls[0][1])
60
60
  .toHaveProperty('suppressFragmentChange', false);
61
61
  });
62
62
 
@@ -75,7 +75,7 @@ describe('Plugin: Search', () => {
75
75
  test('SearchStarted event fires and should go to first result', () => {
76
76
  br.init();
77
77
  br.search('foo', { goToFirstResult: true});
78
- expect(br._plugins.search.options.goToFirstResult).toBeTruthy();
78
+ expect(br.plugins.search.options.goToFirstResult).toBeTruthy();
79
79
  });
80
80
 
81
81
  test('SearchCallback event fires when AJAX search returns results', async () => {
@@ -78,16 +78,16 @@ describe('View: Plugin: Search', () => {
78
78
  const event = new CustomEvent(`${namespace}SearchCallback`);
79
79
  const options = { goToFirstResult: false };
80
80
 
81
- expect(br._plugins.search.searchView.dom.searchNavigation).toBeUndefined();
81
+ expect(br.plugins.search.searchView.dom.searchNavigation).toBeUndefined();
82
82
 
83
- br._plugins.search.searchView.handleSearchCallback(event, { results, options});
84
- expect(br._plugins.search.searchView.dom.searchNavigation).toBeDefined();
83
+ br.plugins.search.searchView.handleSearchCallback(event, { results, options});
84
+ expect(br.plugins.search.searchView.dom.searchNavigation).toBeDefined();
85
85
  });
86
86
  test('has controls', () => {
87
87
  br.init();
88
88
  const event = new CustomEvent(`${namespace}SearchCallback`);
89
89
  const options = { goToFirstResult: false };
90
- br._plugins.search.searchView.handleSearchCallback(event, { results, options});
90
+ br.plugins.search.searchView.handleSearchCallback(event, { results, options});
91
91
 
92
92
  const searchResultsNav = document.querySelector('.BRsearch-navigation');
93
93
  expect(searchResultsNav).toBeDefined();
@@ -102,9 +102,9 @@ describe('View: Plugin: Search', () => {
102
102
  br.init();
103
103
  const event = new CustomEvent(`${namespace}SearchCallback`);
104
104
  const options = { goToFirstResult: false };
105
- br._plugins.search.searchView.handleSearchCallback(event, { results: resultWithScript, options });
105
+ br.plugins.search.searchView.handleSearchCallback(event, { results: resultWithScript, options });
106
106
 
107
- expect(br._plugins.search.searchView.dom.searchNavigation.parent().html()).not.toContain('<script>alert(1);</script>');
107
+ expect(br.plugins.search.searchView.dom.searchNavigation.parent().html()).not.toContain('<script>alert(1);</script>');
108
108
  });
109
109
 
110
110
  describe('Click events handlers', () => {
@@ -114,7 +114,7 @@ describe('View: Plugin: Search', () => {
114
114
  br.trigger = (eventName) => eventNameTriggered = eventName;
115
115
 
116
116
  expect(eventNameTriggered).toBeFalsy();
117
- br._plugins.search.searchView.toggleSidebar();
117
+ br.plugins.search.searchView.toggleSidebar();
118
118
  expect(eventNameTriggered).toEqual('ToggleSearchMenu');
119
119
  });
120
120
  it('triggers custom event when closing navbar', () => {
@@ -123,7 +123,7 @@ describe('View: Plugin: Search', () => {
123
123
  br.trigger = (eventName) => eventNameTriggered = eventName;
124
124
 
125
125
  expect(eventNameTriggered).toBeFalsy();
126
- br._plugins.search.searchView.clearSearchFieldAndResults();
126
+ br.plugins.search.searchView.clearSearchFieldAndResults();
127
127
  expect(eventNameTriggered).toEqual('SearchResultsCleared');
128
128
  });
129
129
  });
@@ -1,4 +1,4 @@
1
- import { marshallSearchResults } from "@/src/plugins/search/utils";
1
+ import { marshallSearchResults } from "@/src/plugins/search/utils.js";
2
2
 
3
3
  export const DUMMY_RESULTS = {
4
4
  ia: "adventuresofoli00dick",
@@ -1,6 +1,6 @@
1
1
  import sinon from 'sinon';
2
- import PageChunkIterator from "@/src/plugins/tts/PageChunkIterator";
3
- import PageChunk from '@/src/plugins/tts/PageChunk';
2
+ import PageChunkIterator from "@/src/plugins/tts/PageChunkIterator.js";
3
+ import PageChunk from '@/src/plugins/tts/PageChunk.js';
4
4
 
5
5
  describe('Buffers pages', () => {
6
6
  test('Does not error if no room for reverse buffer', async () => {
@@ -1,4 +1,4 @@
1
- import { UrlPlugin } from '@/src/plugins/url/UrlPlugin';
1
+ import { UrlPlugin } from '@/src/plugins/url/UrlPlugin.js';
2
2
 
3
3
  afterEach(() => {
4
4
  jest.clearAllMocks();
package/webpack.config.js CHANGED
@@ -1,6 +1,10 @@
1
1
  // @ts-check
2
- const path = require('path');
3
- const webpack = require('webpack');
2
+ import path from 'path';
3
+ import webpack from 'webpack';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
4
8
 
5
9
  /** @type {webpack.Configuration} */
6
10
  const shared = {
@@ -29,7 +33,7 @@ const shared = {
29
33
  };
30
34
 
31
35
  /** @type {webpack.Configuration[]} */
32
- module.exports = [
36
+ export default [
33
37
  {
34
38
  ...shared,
35
39
 
@@ -45,6 +49,7 @@ module.exports = [
45
49
  'plugins/plugin.archive_analytics.js': { import: './src/plugins/plugin.archive_analytics.js', dependOn: 'BookReader.js' },
46
50
  'plugins/plugin.autoplay.js': { import: './src/plugins/plugin.autoplay.js', dependOn: 'BookReader.js' },
47
51
  'plugins/plugin.chapters.js': { import: './src/plugins/plugin.chapters.js', dependOn: 'BookReader.js' },
52
+ 'plugins/plugin.experiments.js': { import: './src/plugins/plugin.experiments.js', dependOn: 'BookReader.js' },
48
53
  'plugins/plugin.iframe.js': { import: './src/plugins/plugin.iframe.js', dependOn: 'BookReader.js' },
49
54
  'plugins/plugin.iiif.js': { import: './src/plugins/plugin.iiif.js', dependOn: 'BookReader.js' },
50
55
  'plugins/plugin.resume.js': { import: './src/plugins/plugin.resume.js', dependOn: 'BookReader.js' },
File without changes
File without changes
File without changes