@internetarchive/bookreader 5.0.0-65 → 5.0.0-67

Sign up to get free protection for your applications and to get access to all the features.
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
  });