@internetarchive/bookreader 5.0.0-65 → 5.0.0-67

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 (35) hide show
  1. package/BookReader/BookReader.css +16 -28
  2. package/BookReader/BookReader.js +1 -1
  3. package/BookReader/BookReader.js.LICENSE.txt +0 -6
  4. package/BookReader/BookReader.js.map +1 -1
  5. package/BookReader/ia-bookreader-bundle.js +102 -114
  6. package/BookReader/ia-bookreader-bundle.js.map +1 -1
  7. package/BookReader/plugins/plugin.chapters.js +24 -1
  8. package/BookReader/plugins/plugin.chapters.js.map +1 -1
  9. package/BookReader/plugins/plugin.search.js +1 -1
  10. package/BookReader/plugins/plugin.search.js.map +1 -1
  11. package/BookReader/plugins/plugin.text_selection.js +1 -1
  12. package/BookReader/plugins/plugin.text_selection.js.map +1 -1
  13. package/BookReader/plugins/plugin.tts.js +1 -1
  14. package/BookReader/plugins/plugin.tts.js.map +1 -1
  15. package/BookReaderDemo/demo-internetarchive.html +41 -3
  16. package/BookReaderDemo/toggle_controls.html +1 -1
  17. package/CHANGELOG.md +8 -0
  18. package/index.html +1 -1
  19. package/package.json +5 -4
  20. package/src/BookNavigator/book-navigator.js +4 -3
  21. package/src/BookReader/BookModel.js +12 -0
  22. package/src/BookReader/Mode1Up.js +1 -1
  23. package/src/BookReader/Mode1UpLit.js +0 -3
  24. package/src/BookReader/Mode2UpLit.js +0 -4
  25. package/src/BookReader/ModeSmoothZoom.js +153 -52
  26. package/src/BookReader/Navbar/Navbar.js +2 -2
  27. package/src/css/_BRnav.scss +5 -2
  28. package/src/css/_BRsearch.scss +6 -2
  29. package/src/css/_MobileNav.scss +0 -26
  30. package/src/css/_controls.scss +3 -2
  31. package/src/plugins/plugin.chapters.js +201 -169
  32. package/src/plugins/tts/plugin.tts.js +1 -1
  33. package/src/util/browserSniffing.js +22 -0
  34. package/tests/jest/BookReader/ModeSmoothZoom.test.js +75 -32
  35. package/tests/jest/plugins/plugin.chapters.test.js +93 -76
@@ -1,37 +1,36 @@
1
- import sinon from 'sinon';
1
+ import sinon from "sinon";
2
2
 
3
- import BookReader from '@/src/BookReader.js';
4
- import '@/src/plugins/plugin.mobile_nav.js';
5
- import '@/src/plugins/plugin.chapters.js';
3
+ import BookReader from "@/src/BookReader.js";
4
+ import "@/src/plugins/plugin.mobile_nav.js";
5
+ import "@/src/plugins/plugin.chapters.js";
6
+ import { BookModel } from "@/src/BookReader/BookModel";
7
+ import { deepCopy } from "../utils";
6
8
 
7
9
  const SAMPLE_TOC = [{
8
10
  "pagenum": "3",
9
11
  "level": 1,
10
12
  "label": "CHAPTER I",
11
- "type": {"key": "/type/toc_item"},
13
+ "type": { "key": "/type/toc_item" },
12
14
  "title": "THE COUNTRY AND THE MISSION 1",
13
15
  "pageIndex": 3,
14
- },{
16
+ }, {
15
17
  "pagenum": "17",
16
18
  "level": 1,
17
19
  "label": "CHAPTER II",
18
- "type": {"key": "/type/toc_item"},
20
+ "type": { "key": "/type/toc_item" },
19
21
  "title": "THE COUNTRY AND THE MISSION 2",
20
22
  "pageIndex": 17,
21
- },
22
- {
23
+ }, {
23
24
  "pagenum": "undefined",
24
25
  "level": 1,
25
26
  "label": "CHAPTER III",
26
- "type": {"key": "/type/toc_item"},
27
+ "type": { "key": "/type/toc_item" },
27
28
  "title": "THE COUNTRY AND THE MISSION 3",
28
- "pageIndex": undefined,
29
- },
30
- {
29
+ }, {
31
30
  "pagenum": "40",
32
31
  "level": 1,
33
32
  "label": "CHAPTER IV",
34
- "type": {"key": "/type/toc_item"},
33
+ "type": { "key": "/type/toc_item" },
35
34
  "title": "THE COUNTRY AND THE MISSION 4",
36
35
  "pageIndex": 40,
37
36
  }];
@@ -41,89 +40,107 @@ const SAMPLE_TOC_UNDEF = [
41
40
  "pagenum": "undefined",
42
41
  "level": 1,
43
42
  "label": "CHAPTER I",
44
- "type": {"key": "/type/toc_item"},
43
+ "type": { "key": "/type/toc_item" },
45
44
  "title": "THE COUNTRY AND THE MISSION 1",
46
- "pageIndex": undefined,
47
45
  },
48
46
  {
49
47
  "pagenum": "undefined",
50
48
  "level": 1,
51
49
  "label": "CHAPTER II",
52
- "type": {"key": "/type/toc_item"},
50
+ "type": { "key": "/type/toc_item" },
53
51
  "title": "THE COUNTRY AND THE MISSION 2",
54
- "pageIndex": undefined,
55
- }
52
+ },
56
53
  ];
57
54
 
58
- /** @type {BookReader} */
59
- let br;
60
- beforeEach(() => {
61
- $.ajax = jest.fn().mockImplementation((args) => {
62
- return Promise.resolve([{
63
- table_of_contents: SAMPLE_TOC,
64
- }]);
65
- });
66
- document.body.innerHTML = '<div id="BookReader">';
67
- br = new BookReader();
68
- });
69
-
70
55
  afterEach(() => {
71
- jest.clearAllMocks();
56
+ sinon.restore();
72
57
  });
73
58
 
74
- describe('Plugin: Menu Toggle', () => {
75
- test('has option flag', () => {
76
- expect(BookReader.defaultOptions.enableChaptersPlugin).toEqual(true);
77
- });
78
- test('has added BR property: olHost', () => {
79
- expect(br).toHaveProperty('olHost');
80
- expect(br.olHost).toBeTruthy();
81
- });
82
- test('has added BR property: bookId', () => {
83
- expect(br).toHaveProperty('bookId');
84
- expect(br.bookId).toBeFalsy();
85
- });
86
- test('fetches OL Book Record on init', () => {
87
- br.getOpenLibraryRecord = jest.fn();
88
- br.init();
89
- expect(br.getOpenLibraryRecord).toHaveBeenCalled();
90
- });
91
- test('Updates Table of Contents when available', () => {
92
- br.init();
93
- expect($.ajax).toHaveBeenCalled();
59
+ describe("BRChaptersPlugin", () => {
60
+ beforeEach(() => {
61
+ sinon.stub(BookModel.prototype, "getPageIndex").callsFake((str) =>
62
+ parseFloat(str)
63
+ );
94
64
  });
95
- });
96
65
 
97
- describe('updateTOCState', () => {
66
+ describe("_chaptersInit", () => {
67
+ test("does not render when no open library record", async () => {
68
+ const fakeBR = {
69
+ options: {},
70
+ getOpenLibraryRecord: async () => null,
71
+ _chaptersRender: sinon.stub(),
72
+ };
73
+ await BookReader.prototype._chapterInit.call(fakeBR);
74
+ expect(fakeBR._chaptersRender.callCount).toBe(0);
75
+ });
98
76
 
99
- beforeEach(() => {
100
- window.HTMLElement.prototype.scrollIntoView = sinon.stub();
101
- br.book.getPageIndex = (str) => parseFloat(str);
102
- br.init();
103
- });
77
+ test("does not render when open library record with no TOC", async () => {
78
+ const fakeBR = {
79
+ options: {},
80
+ getOpenLibraryRecord: async () => ({ key: "/books/OL1M" }),
81
+ _chaptersRender: sinon.stub(),
82
+ };
83
+ await BookReader.prototype._chapterInit.call(fakeBR);
84
+ expect(fakeBR._chaptersRender.callCount).toBe(0);
85
+ });
104
86
 
105
- test('Test page is one of TOC', () => {
106
- br.updateTOCState(20, SAMPLE_TOC);
107
- expect($('li.BRtable-contents-el')[1].classList.contains('current-chapter'));
87
+ test("renders if valid TOC on open library", async () => {
88
+ const fakeBR = {
89
+ options: {},
90
+ bind: sinon.stub(),
91
+ book: {
92
+ getPageIndex: (str) => parseFloat(str),
93
+ },
94
+ getOpenLibraryRecord: async () => ({
95
+ "title": "The Adventures of Sherlock Holmes",
96
+ "table_of_contents": deepCopy(SAMPLE_TOC_UNDEF),
97
+ "ocaid": "adventureofsherl0000unse",
98
+ }),
99
+ _chaptersRender: sinon.stub(),
100
+ };
101
+ await BookReader.prototype._chapterInit.call(fakeBR);
102
+ expect(fakeBR._chaptersRender.callCount).toBe(1);
103
+ });
108
104
  });
109
105
 
110
- test('Only one element has .current-chapter', () => {
111
- br.updateTOCState(9, SAMPLE_TOC);
112
- expect($('li.BRtable-contents-el.current-chapter').length).toBe(1);
106
+ describe('_chaptersRender', () => {
107
+ test('renders markers and panel', () => {
108
+ const fakeBR = {
109
+ _tocEntries: SAMPLE_TOC,
110
+ _chaptersRenderMarker: sinon.stub(),
111
+ shell: {
112
+ menuProviders: {},
113
+ updateMenuContents: sinon.stub(),
114
+ }
115
+ };
116
+ BookReader.prototype._chaptersRender.call(fakeBR);
117
+ expect(fakeBR.shell.menuProviders['chapters']).toBeTruthy();
118
+ expect(fakeBR.shell.updateMenuContents.callCount).toBe(1);
119
+ expect(fakeBR._chaptersRenderMarker.callCount).toBeGreaterThan(1);
120
+ });
113
121
  });
114
122
 
115
- test('No chapter has .current-chapter if current index is < than any chapter index', () => {
116
- br.updateTOCState(1, SAMPLE_TOC);
117
- expect($('li.BRtable-contents-el.current-chapter').length).toBe(0);
118
- });
123
+ describe('_chaptersUpdateCurrent', () => {
124
+ test('highlights the current chapter', () => {
125
+ const fakeBR = {
126
+ mode: 2,
127
+ firstIndex: 16,
128
+ displayedIndices: [16, 17],
129
+ _tocEntries: SAMPLE_TOC,
130
+ _chaptersPanel: {
131
+ currentChapter: null,
132
+ }
133
+ };
134
+ BookReader.prototype._chaptersUpdateCurrent.call(fakeBR);
135
+ expect(fakeBR._chaptersPanel.currentChapter).toEqual(SAMPLE_TOC[1]);
119
136
 
120
- test('if current index == chapter index ', () => {
121
- br.updateTOCState(17, SAMPLE_TOC);
122
- expect($('li.BRtable-contents-el')[1].classList.contains('current-chapter'));
123
- });
137
+ fakeBR.mode = 1;
138
+ BookReader.prototype._chaptersUpdateCurrent.call(fakeBR);
139
+ expect(fakeBR._chaptersPanel.currentChapter).toEqual(SAMPLE_TOC[0]);
124
140
 
125
- test('No chapter has .current-chapter if all chapter have undefined pageIndex ', () => {
126
- br.updateTOCState(10, SAMPLE_TOC_UNDEF);
127
- expect($('li.BRtable-contents-el.current-chapter').length).toBe(0);
141
+ fakeBR.firstIndex = 0;
142
+ BookReader.prototype._chaptersUpdateCurrent.call(fakeBR);
143
+ expect(fakeBR._chaptersPanel.currentChapter).toBeUndefined();
144
+ });
128
145
  });
129
146
  });