@internetarchive/bookreader 5.0.0-72 → 5.0.0-73-alpha1
Sign up to get free protection for your applications and to get access to all the features.
- package/BookReader/BookReader.css +9 -6
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +9 -9
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/icons/1up.svg +1 -1
- package/BookReader/icons/2up.svg +1 -1
- package/BookReader/icons/advance.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -1
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -1
- package/BookReader/icons/fullscreen_exit.svg +1 -1
- package/BookReader/icons/hamburger.svg +1 -1
- package/BookReader/icons/left-arrow.svg +1 -1
- package/BookReader/icons/magnify-minus.svg +1 -1
- package/BookReader/icons/magnify-plus.svg +1 -1
- package/BookReader/icons/magnify.svg +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/play.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/icons/review.svg +1 -1
- package/BookReader/icons/thumbnails.svg +1 -1
- package/BookReader/images/BRicons.svg +2 -2
- package/BookReader/images/books_graphic.svg +1 -1
- package/BookReader/images/icon_book.svg +1 -1
- package/BookReader/images/icon_gear.svg +1 -1
- package/BookReader/images/icon_info.svg +1 -1
- package/BookReader/images/icon_one_page.svg +1 -1
- package/BookReader/images/icon_search_button.svg +1 -1
- package/BookReader/images/icon_share.svg +1 -1
- package/BookReader/images/icon_speaker.svg +1 -1
- package/BookReader/images/icon_speaker_open.svg +1 -1
- package/BookReader/images/icon_thumbnails.svg +1 -1
- package/BookReader/images/icon_toc.svg +1 -1
- package/BookReader/images/icon_two_pages.svg +1 -1
- package/BookReader/images/marker_chap-off.svg +1 -1
- package/BookReader/images/marker_chap-on.svg +1 -1
- package/BookReader/images/marker_srch-on.svg +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +2 -2
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +1 -1
- package/BookReader/plugins/plugin.search.js +1 -1
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +1 -1
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +1 -1
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +1 -1
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReaderDemo/BookReaderDemo.css +3 -0
- package/CHANGELOG.md +6 -1
- package/package.json +16 -16
- package/src/BookReader/options.js +3 -0
- package/src/css/_BRsearch.scss +4 -6
- package/src/plugins/plugin.chapters.js +36 -16
- package/tests/jest/plugins/plugin.chapters.test.js +51 -3
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 5.0.0-73
|
2
|
+
- Feature: Add `table_of_contents` option to work with chapters plugin @cdrini
|
3
|
+
- Fix: Simple demos not working @xonx4l
|
4
|
+
- Dev: Update test/build dependencies @cdrini
|
5
|
+
|
1
6
|
# 5.0.0-72
|
2
7
|
- Fix: Play/pause button out of sync with ReadAloud @sbwhitt
|
3
8
|
- Fix: BookReader not loading in sandboxed iframe @cdrini
|
@@ -647,7 +652,7 @@ be no observable changes, but note this was a big change.
|
|
647
652
|
|
648
653
|
# 4.2.5
|
649
654
|
- Large refactor of plugin.tts.js
|
650
|
-
- ES6
|
655
|
+
- ES6 compilation step
|
651
656
|
- Known bug: Clicking on page while TTS is playing won't stop the playback
|
652
657
|
|
653
658
|
# 4.2.4
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@internetarchive/bookreader",
|
3
|
-
"version": "5.0.0-
|
3
|
+
"version": "5.0.0-73-alpha1",
|
4
4
|
"description": "The Internet Archive BookReader.",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -26,7 +26,7 @@
|
|
26
26
|
"private": false,
|
27
27
|
"dependencies": {
|
28
28
|
"@internetarchive/ia-activity-indicator": "^0.0.4",
|
29
|
-
"@internetarchive/ia-item-navigator": "^2.0.3",
|
29
|
+
"@internetarchive/ia-item-navigator": "^2.0.3-alpha2",
|
30
30
|
"@internetarchive/icon-bookmark": "^1.3.4",
|
31
31
|
"@internetarchive/icon-dl": "^1.3.4",
|
32
32
|
"@internetarchive/icon-edit-pencil": "^1.3.4",
|
@@ -40,18 +40,18 @@
|
|
40
40
|
"lit": "^2.5.0"
|
41
41
|
},
|
42
42
|
"devDependencies": {
|
43
|
-
"@babel/core": "7.
|
44
|
-
"@babel/eslint-parser": "7.
|
43
|
+
"@babel/core": "7.23.3",
|
44
|
+
"@babel/eslint-parser": "7.23.3",
|
45
45
|
"@babel/plugin-proposal-class-properties": "7.18.6",
|
46
|
-
"@babel/plugin-proposal-decorators": "7.
|
47
|
-
"@babel/preset-env": "7.
|
48
|
-
"@open-wc/testing-helpers": "
|
49
|
-
"@types/jest": "29.5.
|
46
|
+
"@babel/plugin-proposal-decorators": "7.23.3",
|
47
|
+
"@babel/preset-env": "7.23.3",
|
48
|
+
"@open-wc/testing-helpers": "3.0.0",
|
49
|
+
"@types/jest": "29.5.10",
|
50
50
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
51
51
|
"babel-loader": "9.1.3",
|
52
52
|
"codecov": "^3.8.3",
|
53
|
-
"concurrently": "
|
54
|
-
"core-js": "3.
|
53
|
+
"concurrently": "8.2.2",
|
54
|
+
"core-js": "3.33.3",
|
55
55
|
"cpx2": "4.2.3",
|
56
56
|
"eslint": "^7.32.0",
|
57
57
|
"eslint-plugin-no-jquery": "^2.7.0",
|
@@ -67,14 +67,14 @@
|
|
67
67
|
"jquery-ui-touch-punch": "0.2.3",
|
68
68
|
"jquery.browser": "0.1.0",
|
69
69
|
"live-server": "1.2.2",
|
70
|
-
"regenerator-runtime": "0.
|
71
|
-
"sass": "1.
|
72
|
-
"sinon": "
|
70
|
+
"regenerator-runtime": "0.14.0",
|
71
|
+
"sass": "1.69.5",
|
72
|
+
"sinon": "17.0.1",
|
73
73
|
"soundmanager2": "2.97.20170602",
|
74
|
-
"svgo": "3.0.
|
75
|
-
"testcafe": "
|
74
|
+
"svgo": "3.0.4",
|
75
|
+
"testcafe": "3.4.0",
|
76
76
|
"testcafe-browser-provider-browserstack": "^1.13.2-alpha.1",
|
77
|
-
"webpack": "5.
|
77
|
+
"webpack": "5.89.0",
|
78
78
|
"webpack-cli": "5.1.4"
|
79
79
|
},
|
80
80
|
"jest": {
|
@@ -180,6 +180,9 @@ export const DEFAULT_OPTIONS = {
|
|
180
180
|
*/
|
181
181
|
data: [],
|
182
182
|
|
183
|
+
/** @type {import('../plugins/plugin.chapters.js').TocEntry[]} */
|
184
|
+
table_of_contents: null,
|
185
|
+
|
183
186
|
/** Advanced methods for page rendering */
|
184
187
|
/** @type {() => number} */
|
185
188
|
getNumLeafs: null,
|
package/src/css/_BRsearch.scss
CHANGED
@@ -9,8 +9,7 @@
|
|
9
9
|
display: none;
|
10
10
|
position: absolute;
|
11
11
|
bottom: calc(100% + 5px);
|
12
|
-
left:
|
13
|
-
transform: translateX(-50%);
|
12
|
+
left: -14px;
|
14
13
|
width: 350px;
|
15
14
|
max-width: 100vw;
|
16
15
|
padding: 12px 14px;
|
@@ -34,9 +33,7 @@
|
|
34
33
|
position: absolute;
|
35
34
|
content: "";
|
36
35
|
bottom: -9px;
|
37
|
-
left:
|
38
|
-
margin-left: -1px;
|
39
|
-
transform: translateX(-50%);
|
36
|
+
left: 0;
|
40
37
|
width: 30px;
|
41
38
|
height: 10px;
|
42
39
|
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
@@ -131,9 +128,10 @@
|
|
131
128
|
main {
|
132
129
|
@include ellipsis-lines(4);
|
133
130
|
margin-bottom: 6px;
|
131
|
+
&:before { content: "“"; }
|
132
|
+
&:after { content: "”"; }
|
134
133
|
}
|
135
134
|
footer {
|
136
|
-
text-align: center;
|
137
135
|
font-size: 0.85em;
|
138
136
|
opacity: .8;
|
139
137
|
}
|
@@ -28,11 +28,28 @@ BookReader.prototype.init = (function(super_) {
|
|
28
28
|
})(BookReader.prototype.init);
|
29
29
|
|
30
30
|
BookReader.prototype._chapterInit = async function() {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
let rawTableOfContents = null;
|
32
|
+
// Prefer IA TOC for now, until we update the second half to check for
|
33
|
+
// `openlibrary_edition` on the IA metadata instead of making a bunch of
|
34
|
+
// requests to OL.
|
35
|
+
if (this.options.table_of_contents?.length) {
|
36
|
+
rawTableOfContents = this.options.table_of_contents;
|
37
|
+
} else {
|
38
|
+
const olEdition = await this.getOpenLibraryRecord(this.options.olHost, this.options.bookId);
|
39
|
+
if (olEdition?.table_of_contents?.length) {
|
40
|
+
rawTableOfContents = olEdition.table_of_contents;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
if (rawTableOfContents) {
|
45
|
+
this._tocEntries = rawTableOfContents
|
46
|
+
.map(rawTOCEntry => (Object.assign({}, rawTOCEntry, {
|
47
|
+
pageIndex: (
|
48
|
+
typeof(rawTOCEntry.leaf) == 'number' ? this.book.leafNumToIndex(rawTOCEntry.leaf) :
|
49
|
+
rawTOCEntry.pagenum ? this.book.getPageIndex(rawTOCEntry.pagenum) :
|
50
|
+
undefined
|
51
|
+
),
|
52
|
+
})));
|
36
53
|
this._chaptersRender(this._tocEntries);
|
37
54
|
this.bind(BookReader.eventNames.pageChanged, () => this._chaptersUpdateCurrent());
|
38
55
|
}
|
@@ -60,19 +77,18 @@ BookReader.prototype._chaptersRender = function() {
|
|
60
77
|
/>`,
|
61
78
|
};
|
62
79
|
shell.updateMenuContents();
|
63
|
-
|
64
|
-
this._chaptersRenderMarker(tocEntry);
|
65
|
-
}
|
80
|
+
this._tocEntries.forEach((tocEntry, i) => this._chaptersRenderMarker(tocEntry, i));
|
66
81
|
};
|
67
82
|
|
68
83
|
/**
|
69
84
|
* @typedef {Object} TocEntry
|
70
85
|
* Table of contents entry as defined by Open Library, with some extra values for internal use
|
71
|
-
* @property {
|
72
|
-
* @property {
|
73
|
-
* @property {string}
|
74
|
-
* @property {
|
75
|
-
* @property {
|
86
|
+
* @property {number} [level]
|
87
|
+
* @property {string} [label]
|
88
|
+
* @property {string} [title]
|
89
|
+
* @property {PageString} [pagenum]
|
90
|
+
* @property {LeafNum} [leaf]
|
91
|
+
* @property {number} [pageIndex] - Added
|
76
92
|
*
|
77
93
|
* @example {
|
78
94
|
* "pagenum": "17",
|
@@ -84,21 +100,25 @@ BookReader.prototype._chaptersRender = function() {
|
|
84
100
|
|
85
101
|
/**
|
86
102
|
* @param {TocEntry} tocEntry
|
103
|
+
* @param {number} entryIndex
|
87
104
|
*/
|
88
|
-
BookReader.prototype._chaptersRenderMarker = function(tocEntry) {
|
105
|
+
BookReader.prototype._chaptersRenderMarker = function(tocEntry, entryIndex) {
|
89
106
|
if (tocEntry.pageIndex == undefined) return;
|
90
107
|
|
91
108
|
//creates a string with non-void tocEntry.label and tocEntry.title
|
92
109
|
const chapterStr = [tocEntry.label, tocEntry.title]
|
93
110
|
.filter(x => x)
|
94
|
-
.join(' ')
|
111
|
+
.join(' ') || `Chapter ${entryIndex + 1}`;
|
95
112
|
|
96
113
|
const percentThrough = BookReader.util.cssPercentage(tocEntry.pageIndex, this.book.getNumLeafs() - 1);
|
97
114
|
$(`<div></div>`)
|
98
115
|
.append(
|
99
116
|
$('<div />')
|
100
117
|
.text(chapterStr)
|
101
|
-
.append(
|
118
|
+
.append(
|
119
|
+
$('<div class="BRchapterPage" />')
|
120
|
+
.text(this.book.getPageName(tocEntry.pageIndex))
|
121
|
+
)
|
102
122
|
)
|
103
123
|
.addClass('BRchapter')
|
104
124
|
.css({ left: percentThrough })
|
@@ -4,7 +4,9 @@ import BookReader from "@/src/BookReader.js";
|
|
4
4
|
import "@/src/plugins/plugin.chapters.js";
|
5
5
|
import { BookModel } from "@/src/BookReader/BookModel";
|
6
6
|
import { deepCopy } from "../utils";
|
7
|
+
/** @typedef {import('@/src/plugins/plugin.chapters').TocEntry} TocEntry */
|
7
8
|
|
9
|
+
/** @type {TocEntry[]} */
|
8
10
|
const SAMPLE_TOC = [{
|
9
11
|
"pagenum": "3",
|
10
12
|
"level": 1,
|
@@ -34,16 +36,15 @@ const SAMPLE_TOC = [{
|
|
34
36
|
"pageIndex": 40,
|
35
37
|
}];
|
36
38
|
|
39
|
+
/** @type {TocEntry[]} */
|
37
40
|
const SAMPLE_TOC_UNDEF = [
|
38
41
|
{
|
39
|
-
"pagenum": "undefined",
|
40
42
|
"level": 1,
|
41
43
|
"label": "CHAPTER I",
|
42
44
|
"type": { "key": "/type/toc_item" },
|
43
45
|
"title": "THE COUNTRY AND THE MISSION 1",
|
44
46
|
},
|
45
47
|
{
|
46
|
-
"pagenum": "undefined",
|
47
48
|
"level": 1,
|
48
49
|
"label": "CHAPTER II",
|
49
50
|
"type": { "key": "/type/toc_item" },
|
@@ -51,6 +52,18 @@ const SAMPLE_TOC_UNDEF = [
|
|
51
52
|
},
|
52
53
|
];
|
53
54
|
|
55
|
+
/** @type {TocEntry[]} */
|
56
|
+
const SAMPLE_TOC_OPTION = [
|
57
|
+
{
|
58
|
+
"level": 1,
|
59
|
+
"title": "THE COUNTRY AND THE MISSION 1",
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"level": 1,
|
63
|
+
"title": "THE COUNTRY AND THE MISSION 2",
|
64
|
+
},
|
65
|
+
];
|
66
|
+
|
54
67
|
afterEach(() => {
|
55
68
|
sinon.restore();
|
56
69
|
});
|
@@ -92,7 +105,7 @@ describe("BRChaptersPlugin", () => {
|
|
92
105
|
},
|
93
106
|
getOpenLibraryRecord: async () => ({
|
94
107
|
"title": "The Adventures of Sherlock Holmes",
|
95
|
-
"table_of_contents": deepCopy(
|
108
|
+
"table_of_contents": deepCopy(SAMPLE_TOC_OPTION),
|
96
109
|
"ocaid": "adventureofsherl0000unse",
|
97
110
|
}),
|
98
111
|
_chaptersRender: sinon.stub(),
|
@@ -100,6 +113,41 @@ describe("BRChaptersPlugin", () => {
|
|
100
113
|
await BookReader.prototype._chapterInit.call(fakeBR);
|
101
114
|
expect(fakeBR._chaptersRender.callCount).toBe(1);
|
102
115
|
});
|
116
|
+
|
117
|
+
test("does not fetch open library record if table of contents in options", async () => {
|
118
|
+
const fakeBR = {
|
119
|
+
options: {
|
120
|
+
table_of_contents: deepCopy(SAMPLE_TOC_UNDEF),
|
121
|
+
},
|
122
|
+
bind: sinon.stub(),
|
123
|
+
getOpenLibraryRecord: sinon.stub(),
|
124
|
+
_chaptersRender: sinon.stub(),
|
125
|
+
};
|
126
|
+
await BookReader.prototype._chapterInit.call(fakeBR);
|
127
|
+
expect(fakeBR.getOpenLibraryRecord.callCount).toBe(0);
|
128
|
+
expect(fakeBR._chaptersRender.callCount).toBe(1);
|
129
|
+
});
|
130
|
+
|
131
|
+
test("converts leafs and pagenums to page index", async () => {
|
132
|
+
const table_of_contents = deepCopy(SAMPLE_TOC_UNDEF);
|
133
|
+
table_of_contents[0].leaf = 0;
|
134
|
+
table_of_contents[1].pagenum = '17';
|
135
|
+
const fakeBR = {
|
136
|
+
options: {
|
137
|
+
table_of_contents,
|
138
|
+
},
|
139
|
+
bind: sinon.stub(),
|
140
|
+
book: {
|
141
|
+
leafNumToIndex: (leaf) => leaf + 1,
|
142
|
+
getPageIndex: (str) => parseFloat(str),
|
143
|
+
},
|
144
|
+
_chaptersRender: sinon.stub(),
|
145
|
+
};
|
146
|
+
await BookReader.prototype._chapterInit.call(fakeBR);
|
147
|
+
expect(fakeBR._chaptersRender.callCount).toBe(1);
|
148
|
+
expect(fakeBR._tocEntries[0].pageIndex).toBe(1);
|
149
|
+
expect(fakeBR._tocEntries[1].pageIndex).toBe(17);
|
150
|
+
});
|
103
151
|
});
|
104
152
|
|
105
153
|
describe('_chaptersRender', () => {
|