@internetarchive/bookreader 5.0.0-5 → 5.0.0-50-a1
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.
- package/.eslintrc.js +17 -15
- package/.github/workflows/node.js.yml +77 -6
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +131 -339
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.LICENSE.txt +24 -0
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1493 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +17 -0
- package/BookReader/ia-bookreader-bundle.js.map +1 -0
- package/BookReader/icons/close-circle-dark.svg +1 -0
- package/BookReader/icons/magnify-minus.svg +1 -1
- package/BookReader/icons/magnify-plus.svg +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/icons/voice.svg +1 -0
- 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_playback-rate.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/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/jquery-3.js +2 -0
- package/BookReader/jquery-3.js.LICENSE.txt +24 -0
- package/BookReader/plugins/plugin.archive_analytics.js +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +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 +1 -1
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +1 -1
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.mobile_nav.js +1 -1
- package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +1 -1
- package/BookReader/plugins/plugin.resume.js.map +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/BookReader/webcomponents-bundle.js +3 -0
- package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
- package/BookReader/webcomponents-bundle.js.map +1 -0
- package/BookReaderDemo/BookReaderDemo.css +14 -1
- package/BookReaderDemo/IADemoBr.js +148 -0
- package/BookReaderDemo/demo-advanced.html +2 -2
- package/BookReaderDemo/demo-autoplay.html +2 -1
- package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
- package/BookReaderDemo/demo-fullscreen-mobile.html +2 -1
- package/BookReaderDemo/demo-fullscreen.html +2 -1
- package/BookReaderDemo/demo-iiif.html +2 -1
- package/BookReaderDemo/demo-internetarchive.html +84 -17
- package/BookReaderDemo/demo-multiple.html +2 -1
- package/BookReaderDemo/demo-preview-pages.html +2 -1
- package/BookReaderDemo/demo-simple.html +2 -1
- package/BookReaderDemo/demo-vendor-fullscreen.html +2 -1
- package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
- package/BookReaderDemo/immersion-1up.html +2 -1
- package/BookReaderDemo/immersion-mode.html +2 -1
- package/BookReaderDemo/toggle_controls.html +2 -1
- package/BookReaderDemo/view_mode.html +2 -1
- package/BookReaderDemo/viewmode-cycle.html +2 -3
- package/CHANGELOG.md +202 -0
- package/README.md +14 -1
- package/babel.config.js +18 -0
- package/codecov.yml +6 -0
- package/index.html +3 -0
- package/jsconfig.json +19 -0
- package/package.json +66 -56
- package/renovate.json +52 -0
- package/scripts/preversion.js +4 -1
- package/src/BookNavigator/assets/bookmark-colors.js +1 -1
- package/src/BookNavigator/assets/button-base.js +9 -2
- package/src/BookNavigator/assets/ia-logo.js +17 -0
- package/src/BookNavigator/assets/icon_checkmark.js +1 -1
- package/src/BookNavigator/assets/icon_close.js +1 -1
- package/src/BookNavigator/assets/icon_sort_asc.js +5 -0
- package/src/BookNavigator/assets/icon_sort_desc.js +5 -0
- package/src/BookNavigator/assets/icon_sort_neutral.js +5 -0
- package/src/BookNavigator/assets/icon_volumes.js +11 -0
- package/src/BookNavigator/book-navigator.js +583 -0
- package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
- package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
- package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
- package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +3 -8
- package/src/BookNavigator/bookmarks/bookmarks-provider.js +21 -8
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +102 -66
- package/src/BookNavigator/delete-modal-actions.js +1 -1
- package/src/BookNavigator/downloads/downloads-provider.js +36 -21
- package/src/BookNavigator/downloads/downloads.js +41 -25
- package/src/BookNavigator/search/a-search-result.js +18 -13
- package/src/BookNavigator/search/search-provider.js +80 -28
- package/src/BookNavigator/search/search-results.js +10 -18
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +11 -10
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +3 -3
- package/src/BookNavigator/volumes/volumes-provider.js +114 -0
- package/src/BookNavigator/volumes/volumes.js +188 -0
- package/src/BookReader/BookModel.js +0 -29
- package/src/BookReader/DebugConsole.js +3 -3
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/Mode1Up.js +51 -351
- package/src/BookReader/Mode1UpLit.js +441 -0
- package/src/BookReader/Mode2Up.js +120 -105
- package/src/BookReader/ModeSmoothZoom.js +179 -0
- package/src/BookReader/ModeThumb.js +17 -11
- package/src/BookReader/Navbar/Navbar.js +10 -36
- package/src/BookReader/PageContainer.js +69 -6
- package/src/BookReader/ReduceSet.js +1 -1
- package/src/BookReader/Toolbar/Toolbar.js +10 -37
- package/src/BookReader/options.js +10 -0
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils.js +92 -13
- package/src/BookReader.js +431 -620
- package/src/assets/icons/close-circle-dark.svg +1 -0
- package/src/assets/icons/magnify-minus.svg +3 -7
- package/src/assets/icons/magnify-plus.svg +3 -7
- package/src/assets/icons/voice.svg +1 -0
- package/src/css/BookReader.scss +0 -12
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRmain.scss +19 -24
- package/src/css/_BRnav.scss +4 -26
- package/src/css/_BRpages.scss +35 -0
- package/src/css/_BRsearch.scss +25 -216
- package/src/css/_TextSelection.scss +14 -17
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +17 -5
- package/src/css/_icons.scss +6 -0
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.autoplay.js +4 -4
- package/src/plugins/plugin.chapters.js +28 -35
- package/src/plugins/plugin.mobile_nav.js +11 -10
- package/src/plugins/plugin.resume.js +3 -3
- package/src/plugins/plugin.text_selection.js +26 -39
- package/src/plugins/plugin.vendor-fullscreen.js +4 -4
- package/src/plugins/search/plugin.search.js +174 -116
- package/src/plugins/search/view.js +63 -179
- package/src/plugins/tts/AbstractTTSEngine.js +46 -37
- package/src/plugins/tts/FestivalTTSEngine.js +13 -14
- package/src/plugins/tts/PageChunk.js +15 -21
- package/src/plugins/tts/PageChunkIterator.js +8 -12
- package/src/plugins/tts/WebTTSEngine.js +66 -69
- package/src/plugins/tts/plugin.tts.js +92 -109
- package/src/plugins/tts/utils.js +0 -9
- package/src/plugins/url/UrlPlugin.js +184 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +28 -6
- package/src/util/manifestGenerator.js +0 -0
- package/tests/e2e/README.md +37 -0
- package/tests/e2e/autoplay.test.js +2 -2
- package/tests/e2e/base.test.js +7 -7
- package/tests/e2e/helpers/base.js +9 -3
- package/tests/e2e/helpers/debug.js +1 -1
- package/tests/e2e/helpers/desktopSearch.js +14 -13
- package/tests/e2e/helpers/mobileSearch.js +3 -3
- package/tests/e2e/helpers/params.js +17 -0
- package/tests/e2e/models/Navigation.js +13 -4
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +38 -33
- package/tests/jest/BookNavigator/book-navigator.test.js +634 -0
- package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
- package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
- package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
- package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
- package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
- package/tests/{karma/BookNavigator → jest/BookNavigator/search}/search-results.test.js +102 -58
- package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
- package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
- package/tests/jest/BookNavigator/volumes/volumes-provider.test.js +184 -0
- package/tests/jest/BookNavigator/volumes/volumes.test.js +97 -0
- package/tests/{BookReader → jest/BookReader}/BookModel.test.js +34 -14
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +176 -0
- package/tests/{BookReader → jest/BookReader}/DebugConsole.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
- package/tests/jest/BookReader/Mode1UpLit.test.js +92 -0
- package/tests/{BookReader → jest/BookReader}/Mode2Up.test.js +36 -15
- package/tests/jest/BookReader/ModeSmoothZoom.test.js +149 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +7 -7
- package/tests/{BookReader → jest/BookReader}/PageContainer.test.js +88 -6
- package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +2 -2
- package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
- package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
- package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
- package/tests/jest/BookReader/utils.test.js +186 -0
- package/tests/jest/BookReader.keyboard.test.js +190 -0
- package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +9 -1
- package/tests/{BookReader.test.js → jest/BookReader.test.js} +18 -37
- package/tests/{plugins → jest/plugins}/plugin.archive_analytics.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.autoplay.test.js +4 -4
- package/tests/{plugins → jest/plugins}/plugin.chapters.test.js +10 -11
- package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +2 -2
- package/tests/{plugins → jest/plugins}/plugin.mobile_nav.test.js +5 -5
- package/tests/{plugins → jest/plugins}/plugin.resume.test.js +3 -3
- package/tests/{plugins → jest/plugins}/plugin.text_selection.test.js +39 -47
- package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
- package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +63 -47
- package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +35 -6
- package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +9 -9
- package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
- package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
- package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/utils.test.js +3 -28
- package/tests/jest/plugins/url/UrlPlugin.test.js +190 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +33 -14
- package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
- package/tests/{util → jest/util}/docCookies.test.js +1 -1
- package/tests/{util → jest/util}/strings.test.js +1 -1
- package/tests/{utils.js → jest/utils.js} +38 -0
- package/webpack.config.js +11 -5
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -1450
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/jquery-1.10.1.js +0 -2
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -2
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
- package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
- package/karma.conf.js +0 -23
- package/src/BookNavigator/BookModel.js +0 -14
- package/src/BookNavigator/BookNavigator.js +0 -438
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -372
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/Layers/sharing/sharing-provider.js +0 -22
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/src/plugins/plugin.bookmarks.js +0 -50
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/e2e/ia-production/ia-prod-base.js +0 -17
- package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
@@ -1,4 +1,4 @@
|
|
1
|
-
import { html } from 'lit
|
1
|
+
import { html } from 'lit';
|
2
2
|
import '../delete-modal-actions.js';
|
3
3
|
import './bookmark-button.js';
|
4
4
|
import './ia-bookmarks.js';
|
@@ -10,17 +10,32 @@ import { IAIconBookmark } from '@internetarchive/icon-bookmark';
|
|
10
10
|
customElements.define('icon-bookmark', IAIconBookmark);
|
11
11
|
|
12
12
|
export default class BookmarksProvider {
|
13
|
-
constructor(options
|
14
|
-
const
|
13
|
+
constructor(options) {
|
14
|
+
const {
|
15
|
+
baseHost,
|
16
|
+
signedIn,
|
17
|
+
bookreader,
|
18
|
+
modal,
|
19
|
+
onProviderChange,
|
20
|
+
} = options;
|
21
|
+
|
22
|
+
const referrerStr = `referer=${encodeURIComponent(location.href)}`;
|
23
|
+
const loginUrl = `https://${baseHost}/account/login?${referrerStr}`;
|
24
|
+
|
15
25
|
this.component = document.createElement('ia-bookmarks');
|
16
26
|
this.component.bookreader = bookreader;
|
17
|
-
this.component.
|
18
|
-
|
27
|
+
this.component.displayMode = signedIn ? 'bookmarks' : 'login';
|
28
|
+
this.component.modal = modal;
|
29
|
+
this.component.loginOptions = {
|
30
|
+
loginClicked: this.bookmarksLoginClicked,
|
31
|
+
loginUrl
|
32
|
+
};
|
19
33
|
this.bindEvents();
|
20
34
|
|
21
35
|
this.icon = html`<icon-bookmark state="hollow" style="--iconWidth: 16px; --iconHeight: 24px;"></icon-bookmark>`;
|
22
36
|
this.label = 'Bookmarks';
|
23
37
|
this.id = 'bookmarks';
|
38
|
+
this.onProviderChange = onProviderChange;
|
24
39
|
this.component.setup();
|
25
40
|
this.updateMenu(this.component.bookmarks.length);
|
26
41
|
}
|
@@ -31,14 +46,12 @@ export default class BookmarksProvider {
|
|
31
46
|
|
32
47
|
bindEvents() {
|
33
48
|
this.component.addEventListener('bookmarksChanged', this.bookmarksChanged.bind(this));
|
34
|
-
this.component.addEventListener('showItemNavigatorModal', this.showItemNavigatorModal);
|
35
|
-
this.component.addEventListener('closeItemNavigatorModal', this.closeItemNavigatorModal);
|
36
49
|
}
|
37
50
|
|
38
51
|
bookmarksChanged({ detail }) {
|
39
52
|
const bookmarksLength = Object.keys(detail.bookmarks).length;
|
40
53
|
this.updateMenu(bookmarksLength);
|
41
|
-
this.
|
54
|
+
this.onProviderChange(detail.bookmarks, detail.showSidePanel);
|
42
55
|
}
|
43
56
|
|
44
57
|
bookmarksLoginClicked() {
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { LitElement, html, css, render } from 'lit';
|
2
|
+
// eslint-disable-next-line no-unused-vars
|
3
|
+
import { ModalConfig, ModalManager } from '@internetarchive/modal-manager';
|
3
4
|
import buttonStyles from '../assets/button-base.js';
|
4
5
|
import './bookmarks-loginCTA.js';
|
5
6
|
|
@@ -57,9 +58,11 @@ class IABookmarks extends LitElement {
|
|
57
58
|
activeBookmarkID: { type: String },
|
58
59
|
bookmarks: { type: Array },
|
59
60
|
bookreader: { type: Object },
|
60
|
-
options: { type: Object },
|
61
61
|
displayMode: { type: String },
|
62
62
|
editedBookmark: { type: Object },
|
63
|
+
deleteModalConfig: { type: Object},
|
64
|
+
modal: { attribute: false },
|
65
|
+
loginOptions: { type: Object, attribute: false }
|
63
66
|
};
|
64
67
|
}
|
65
68
|
|
@@ -92,7 +95,12 @@ class IABookmarks extends LitElement {
|
|
92
95
|
this.bookmarks = [];
|
93
96
|
this.bookreader = {};
|
94
97
|
this.editedBookmark = {};
|
95
|
-
|
98
|
+
/** @type {ModalManager} */
|
99
|
+
this.modal = undefined;
|
100
|
+
this.loginOptions = {
|
101
|
+
loginClicked: () => {},
|
102
|
+
loginUrl: '',
|
103
|
+
};
|
96
104
|
/**
|
97
105
|
* Toggles display to either bookmarks or login cta
|
98
106
|
* @param {('bookmarks'|'login')} displayMode
|
@@ -113,21 +121,45 @@ class IABookmarks extends LitElement {
|
|
113
121
|
// eslint-disable-next-line
|
114
122
|
this.defaultColor = this.bookmarkColors[0];
|
115
123
|
this.api = api;
|
124
|
+
this.deleteModalConfig = new ModalConfig({
|
125
|
+
title: 'Delete Bookmark',
|
126
|
+
headline: 'This bookmark contains a note. Deleting it will permanently delete the note. Are you sure?',
|
127
|
+
headerColor: '#194880',
|
128
|
+
});
|
116
129
|
}
|
117
130
|
|
118
|
-
updated() {
|
131
|
+
updated(changed) {
|
132
|
+
if (changed.has('displayMode')) {
|
133
|
+
this.updateDisplay();
|
134
|
+
}
|
135
|
+
|
119
136
|
this.emitBookmarksChanged();
|
120
137
|
}
|
121
138
|
|
122
139
|
setup() {
|
123
140
|
this.api.identifier = this.bookreader.bookId;
|
124
|
-
this.
|
125
|
-
|
126
|
-
|
141
|
+
if (this.displayMode === 'login') {
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
this.fetchUserBookmarks();
|
145
|
+
this.setBREventListeners();
|
127
146
|
}
|
128
147
|
|
129
|
-
|
130
|
-
this.displayMode
|
148
|
+
updateDisplay() {
|
149
|
+
if (this.displayMode === 'bookmarks') {
|
150
|
+
this.fetchUserBookmarks();
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
async fetchUserBookmarks() {
|
155
|
+
if (!this.api.identifier) {
|
156
|
+
return;
|
157
|
+
}
|
158
|
+
await this.fetchBookmarks();
|
159
|
+
this.initializeBookmarks();
|
160
|
+
}
|
161
|
+
|
162
|
+
setBREventListeners() {
|
131
163
|
['3PageViewSelected'].forEach((event) => {
|
132
164
|
window.addEventListener(`BookReader:${event}`, (e) => {
|
133
165
|
setTimeout(() => {
|
@@ -147,12 +179,12 @@ class IABookmarks extends LitElement {
|
|
147
179
|
});
|
148
180
|
['zoomOut', 'zoomIn', 'resize'].forEach((event) => {
|
149
181
|
window.addEventListener(`BookReader:${event}`, () => {
|
150
|
-
|
151
|
-
this.renderBookmarkButtons();
|
152
|
-
}
|
182
|
+
this.renderBookmarkButtons();
|
153
183
|
});
|
154
184
|
});
|
185
|
+
}
|
155
186
|
|
187
|
+
initializeBookmarks() {
|
156
188
|
this.renderBookmarkButtons();
|
157
189
|
this.markActiveBookmark(true);
|
158
190
|
this.emitBookmarksChanged();
|
@@ -181,8 +213,8 @@ class IABookmarks extends LitElement {
|
|
181
213
|
color: this.getBookmarkColor(color) ? color : this.defaultColor.id,
|
182
214
|
};
|
183
215
|
|
184
|
-
const page = IABookmarks.formatPage(this.bookreader.getPageNum(leafNum));
|
185
|
-
const thumbnail = this.bookreader.getPageURI(`${leafNum}`.replace(/\D/g, ''), 32); // Request thumbnail 1/32 the size of original image
|
216
|
+
const page = IABookmarks.formatPage(this.bookreader.book.getPageNum(leafNum));
|
217
|
+
const thumbnail = this.bookreader.book.getPageURI(`${leafNum}`.replace(/\D/g, ''), 32); // Request thumbnail 1/32 the size of original image
|
186
218
|
const bookmark = {
|
187
219
|
...nomalizedParams,
|
188
220
|
id: leafNum,
|
@@ -194,27 +226,35 @@ class IABookmarks extends LitElement {
|
|
194
226
|
return bookmark;
|
195
227
|
}
|
196
228
|
|
197
|
-
fetchBookmarks() {
|
198
|
-
|
229
|
+
async fetchBookmarks() {
|
230
|
+
const resText = await this.api.getAll().then(r=> r.text());
|
231
|
+
let parsedResponse;
|
232
|
+
try {
|
233
|
+
parsedResponse = JSON.parse(resText);
|
234
|
+
} catch (e) {
|
235
|
+
parsedResponse = {error : e.message};
|
236
|
+
}
|
237
|
+
|
238
|
+
const {
|
199
239
|
success,
|
200
240
|
error = 'Something happened while fetching bookmarks.',
|
201
241
|
value: bkmrks = [],
|
202
|
-
}
|
203
|
-
if (!success) {
|
204
|
-
throw new Error(`Failed to load bookmarks: ${error}`);
|
205
|
-
}
|
242
|
+
} = parsedResponse;
|
206
243
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
const formattedLeafNum = parseInt(leafNum, 10);
|
211
|
-
const formattedBookmark = this.formatBookmark({ ...bookmark, leafNum: formattedLeafNum });
|
212
|
-
bookmarks[leafNum] = formattedBookmark;
|
213
|
-
});
|
244
|
+
if (!success) {
|
245
|
+
console?.warn('Error fetching bookmarks', error);
|
246
|
+
}
|
214
247
|
|
215
|
-
|
216
|
-
|
248
|
+
const bookmarks = {};
|
249
|
+
Object.keys(bkmrks).forEach((leafNum) => {
|
250
|
+
const bookmark = bkmrks[leafNum];
|
251
|
+
const formattedLeafNum = parseInt(leafNum, 10);
|
252
|
+
const formattedBookmark = this.formatBookmark({ ...bookmark, leafNum: formattedLeafNum });
|
253
|
+
bookmarks[leafNum] = formattedBookmark;
|
217
254
|
});
|
255
|
+
|
256
|
+
this.bookmarks = bookmarks;
|
257
|
+
return bookmarks;
|
218
258
|
}
|
219
259
|
|
220
260
|
emitBookmarksChanged() {
|
@@ -250,12 +290,14 @@ class IABookmarks extends LitElement {
|
|
250
290
|
|
251
291
|
pages.forEach((pageEl) => {
|
252
292
|
const existingButton = pageEl.querySelector('.bookmark-button');
|
253
|
-
if (existingButton) {
|
293
|
+
if (existingButton) {
|
294
|
+
existingButton.remove();
|
295
|
+
}
|
254
296
|
const pageID = +pageEl.classList.value.match(/pagediv\d+/)[0].replace(/\D/g, '');
|
255
297
|
const pageBookmark = this.getBookmark(pageID);
|
256
298
|
const bookmarkState = pageBookmark ? 'filled' : 'hollow';
|
257
299
|
// eslint-disable-next-line
|
258
|
-
const pageData = this.bookreader.
|
300
|
+
const pageData = this.bookreader.book.getPage(pageID);
|
259
301
|
const { isViewable } = pageData;
|
260
302
|
|
261
303
|
if (!isViewable) { return; }
|
@@ -375,7 +417,7 @@ class IABookmarks extends LitElement {
|
|
375
417
|
|
376
418
|
bookmarkSelected({ detail }) {
|
377
419
|
const { leafNum } = detail.bookmark;
|
378
|
-
this.bookreader.jumpToPage(`${this.bookreader.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
420
|
+
this.bookreader.jumpToPage(`${this.bookreader.book.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
379
421
|
this.activeBookmarkID = leafNum;
|
380
422
|
}
|
381
423
|
|
@@ -390,33 +432,26 @@ class IABookmarks extends LitElement {
|
|
390
432
|
confirmDeletion(pageID) {
|
391
433
|
const existingBookmark = this.getBookmark(pageID);
|
392
434
|
if (existingBookmark.note) {
|
393
|
-
this.
|
435
|
+
this.displayDeletionModal(pageID);
|
394
436
|
return;
|
395
437
|
}
|
396
438
|
this.deleteBookmark({ detail: { id: `${pageID}` } });
|
397
439
|
}
|
398
440
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
.cancelAction=${() => this.emitCloseModal()}
|
408
|
-
.pageID=${pageID}
|
409
|
-
></delete-modal-actions>
|
410
|
-
`,
|
411
|
-
},
|
412
|
-
}));
|
413
|
-
}
|
441
|
+
displayDeletionModal(pageID) {
|
442
|
+
const customModalContent = html`
|
443
|
+
<delete-modal-actions
|
444
|
+
.deleteAction=${() => this.deleteBookmark({ detail: { id: `${pageID}` } })}
|
445
|
+
.cancelAction=${() => this.modal.closeModal()}
|
446
|
+
.pageID=${pageID}
|
447
|
+
></delete-modal-actions>
|
448
|
+
`;
|
414
449
|
|
415
|
-
|
416
|
-
this.
|
417
|
-
|
418
|
-
|
419
|
-
})
|
450
|
+
|
451
|
+
this.modal.showModal({
|
452
|
+
config: this.deleteModalConfig,
|
453
|
+
customModalContent,
|
454
|
+
});
|
420
455
|
}
|
421
456
|
|
422
457
|
deleteBookmark({ detail }) {
|
@@ -427,18 +462,10 @@ class IABookmarks extends LitElement {
|
|
427
462
|
|
428
463
|
this.api.delete(detail.id);
|
429
464
|
this.editedBookmark = {};
|
430
|
-
this.
|
465
|
+
this.modal.closeModal();
|
431
466
|
this.renderBookmarkButtons();
|
432
467
|
}
|
433
468
|
|
434
|
-
/**
|
435
|
-
* call `loginClicked` callback
|
436
|
-
*/
|
437
|
-
loginClick() {
|
438
|
-
const { loginClicked = () => {} } = this.options;
|
439
|
-
loginClicked();
|
440
|
-
}
|
441
|
-
|
442
469
|
/**
|
443
470
|
* Tells us if we should allow user to add bookmark via menu panel
|
444
471
|
* returns { Boolean }
|
@@ -460,6 +487,7 @@ class IABookmarks extends LitElement {
|
|
460
487
|
return html`
|
461
488
|
<button
|
462
489
|
class="ia-button primary"
|
490
|
+
tabindex="-1"
|
463
491
|
?disabled=${this.shouldEnableAddBookmarkButton}
|
464
492
|
@click=${this.addBookmark}>
|
465
493
|
Add bookmark
|
@@ -483,15 +511,23 @@ class IABookmarks extends LitElement {
|
|
483
511
|
`;
|
484
512
|
}
|
485
513
|
|
514
|
+
get bookmarkHelperMessage() {
|
515
|
+
return html`<p>Please use 1up or 2up view modes to add bookmark.</p>`;
|
516
|
+
}
|
517
|
+
|
486
518
|
render() {
|
487
|
-
const { loginUrl } = this.options;
|
488
519
|
const bookmarks = html`
|
489
520
|
${this.bookmarksList}
|
490
|
-
${this.allowAddingBookmark ? this.addBookmarkButton :
|
521
|
+
${this.allowAddingBookmark ? this.addBookmarkButton : this.bookmarkHelperMessage}
|
491
522
|
`;
|
492
523
|
return html`
|
493
524
|
<section class="bookmarks">
|
494
|
-
|
525
|
+
${ this.displayMode === 'login'
|
526
|
+
? html`<bookmarks-login
|
527
|
+
@click=${() => this.loginOptions.loginClicked()}
|
528
|
+
.url=${this.loginOptions.loginUrl}></bookmarks-login>`
|
529
|
+
: bookmarks
|
530
|
+
}
|
495
531
|
</section>
|
496
532
|
`;
|
497
533
|
}
|
@@ -1,42 +1,56 @@
|
|
1
|
-
import { html } from 'lit
|
1
|
+
import { html } from 'lit';
|
2
|
+
import '@internetarchive/icon-dl/icon-dl';
|
3
|
+
import './downloads';
|
2
4
|
|
3
|
-
/* register subpanel */
|
4
|
-
import { IABookDownloads } from './downloads';
|
5
|
-
customElements.define('ia-book-downloads', IABookDownloads);
|
6
|
-
|
7
|
-
let downloads = [];
|
8
5
|
const menuBase = {
|
9
6
|
pdf: {
|
10
7
|
type: 'Encrypted Adobe PDF',
|
11
8
|
url: '#',
|
12
9
|
note: 'PDF files contain high quality images of pages.',
|
13
10
|
},
|
11
|
+
lcppdf: {
|
12
|
+
type: 'Get LCP PDF',
|
13
|
+
url: '#',
|
14
|
+
note: 'PDF files contain high quality images of pages.',
|
15
|
+
},
|
16
|
+
lcpepub: {
|
17
|
+
type: 'Get LCP ePub',
|
18
|
+
url: '#',
|
19
|
+
note: 'ePub files are smaller in size, but may contain errors.',
|
20
|
+
},
|
14
21
|
epub: {
|
15
22
|
type: 'Encrypted Adobe ePub',
|
16
23
|
url: '#',
|
17
24
|
note: 'ePub files are smaller in size, but may contain errors.',
|
18
|
-
}
|
25
|
+
},
|
26
|
+
};
|
27
|
+
|
28
|
+
const publicMenuBase = {
|
29
|
+
pdf: "PDF",
|
30
|
+
epub: "ePub",
|
31
|
+
lcppdf: "LCP PDF",
|
32
|
+
lcpepub: "LCP ePub",
|
19
33
|
};
|
20
34
|
|
21
|
-
export default class {
|
22
|
-
|
23
|
-
|
35
|
+
export default class DownloadsProvider {
|
36
|
+
|
37
|
+
constructor({ bookreader }) {
|
38
|
+
this.icon = html`<ia-icon-dl style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-dl>`;
|
24
39
|
this.label = 'Downloadable files';
|
25
40
|
this.menuDetails = '';
|
41
|
+
this.downloads = [];
|
26
42
|
this.id = 'downloads';
|
27
43
|
this.component = '';
|
28
|
-
|
29
|
-
this.computeAvailableTypes = this.computeAvailableTypes.bind(this);
|
30
|
-
this.update = this.update.bind(this);
|
44
|
+
this.isBookProtected = bookreader?.options?.isProtected || false;
|
31
45
|
}
|
32
46
|
|
33
|
-
|
34
47
|
update(downloadTypes) {
|
35
48
|
this.computeAvailableTypes(downloadTypes);
|
36
49
|
this.component = this.menu;
|
50
|
+
this.component.isBookProtected = this.isBookProtected;
|
37
51
|
|
38
|
-
const ending = downloads.length === 1 ? '' : 's';
|
39
|
-
this.menuDetails = `(${downloads.length} format${ending})`;
|
52
|
+
const ending = this.downloads.length === 1 ? '' : 's';
|
53
|
+
this.menuDetails = `(${this.downloads.length} format${ending})`;
|
40
54
|
}
|
41
55
|
|
42
56
|
/**
|
@@ -45,22 +59,23 @@ export default class {
|
|
45
59
|
* @param availableTypes
|
46
60
|
*/
|
47
61
|
computeAvailableTypes(availableTypes = []) {
|
48
|
-
const menuData = availableTypes.reduce((found, incoming = []
|
62
|
+
const menuData = availableTypes.reduce((found, incoming = []) => {
|
49
63
|
const [ type = '', link = '' ] = incoming;
|
50
64
|
const formattedType = type.toLowerCase();
|
51
65
|
const downloadOption = menuBase[formattedType] || null;
|
66
|
+
|
52
67
|
if (downloadOption) {
|
53
|
-
const
|
68
|
+
const menuButtonText = this.isBookProtected ? menuBase[formattedType].type : publicMenuBase[formattedType];
|
69
|
+
const menuInfo = Object.assign({}, downloadOption, { url: link, type: menuButtonText});
|
54
70
|
found.push(menuInfo);
|
55
71
|
}
|
56
72
|
return found;
|
57
73
|
}, []);
|
58
74
|
|
59
|
-
downloads = menuData;
|
75
|
+
this.downloads = menuData;
|
60
76
|
}
|
61
77
|
|
62
|
-
|
63
78
|
get menu () {
|
64
|
-
return html`<ia-book-downloads .downloads=${downloads}></ia-book-downloads>`;
|
79
|
+
return html`<ia-book-downloads .downloads=${this.downloads}></ia-book-downloads>`;
|
65
80
|
}
|
66
81
|
}
|
@@ -1,11 +1,12 @@
|
|
1
|
-
import { css, html, LitElement } from 'lit
|
2
|
-
import
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
2
|
+
import buttonStyles from '../assets/button-base.js';
|
3
3
|
export class IABookDownloads extends LitElement {
|
4
4
|
static get properties() {
|
5
5
|
return {
|
6
6
|
downloads: { type: Array },
|
7
7
|
expiration: { type: Number },
|
8
8
|
renderHeader: { type: Boolean },
|
9
|
+
isBookProtected: { type: Boolean },
|
9
10
|
};
|
10
11
|
}
|
11
12
|
|
@@ -14,6 +15,7 @@ export class IABookDownloads extends LitElement {
|
|
14
15
|
this.downloads = [];
|
15
16
|
this.expiration = 0;
|
16
17
|
this.renderHeader = false;
|
18
|
+
this.isBookProtected = false;
|
17
19
|
}
|
18
20
|
|
19
21
|
get formatsCount() {
|
@@ -31,13 +33,23 @@ export class IABookDownloads extends LitElement {
|
|
31
33
|
return this.downloads.map(option => (
|
32
34
|
html`
|
33
35
|
<li>
|
34
|
-
<a class="button" href="${option.url}">Get ${option.type}</a>
|
36
|
+
<a class="ia-button link primary" href="${option.url}">Get ${option.type}</a>
|
35
37
|
${option.note ? html`<p>${option.note}</p>` : html``}
|
36
38
|
</li>
|
37
39
|
`
|
38
40
|
));
|
39
41
|
}
|
40
42
|
|
43
|
+
/**
|
44
|
+
* checks if downloads list contains an LCP option
|
45
|
+
* @return {boolean}
|
46
|
+
*/
|
47
|
+
get hasLCPOption() {
|
48
|
+
const regex = /^(LCP)/g;
|
49
|
+
const lcpAvailable = this.downloads.some(option => option.type?.match(regex));
|
50
|
+
return lcpAvailable;
|
51
|
+
}
|
52
|
+
|
41
53
|
get header() {
|
42
54
|
if (!this.renderHeader) {
|
43
55
|
return nothing;
|
@@ -50,18 +62,38 @@ export class IABookDownloads extends LitElement {
|
|
50
62
|
`;
|
51
63
|
}
|
52
64
|
|
65
|
+
get accessProtectedBook() {
|
66
|
+
return html`
|
67
|
+
<p>To access downloaded books, you need Adobe-compliant software on your device. The Internet Archive will administer this loan, but Adobe may also collect some information.</p>
|
68
|
+
<a class="ia-button external primary" href="https://www.adobe.com/solutions/ebook/digital-editions/download.html" rel="noopener noreferrer" target="_blank">Install Adobe Digital Editions</a>
|
69
|
+
`;
|
70
|
+
}
|
71
|
+
|
72
|
+
get installSimplyEAldikoThoriumMsg() {
|
73
|
+
return html`
|
74
|
+
<p>For LCP downloads, make sure you have SimplyE or Aldiko Next installed on mobile or Thorium on desktop.</p>
|
75
|
+
<ul>
|
76
|
+
<li><a href="https://librarysimplified.org/simplye/" rel="noopener noreferrer nofollow" target="_blank">Install SimplyE</a></li>
|
77
|
+
<li><a href="https://www.demarque.com/en-aldiko" rel="noopener noreferrer nofollow" target="_blank">Install Aldiko</a></li>
|
78
|
+
<li><a href="https://www.edrlab.org/software/thorium-reader/" rel="noopener noreferrer nofollow" target="_blank">Install Thorium</a></li>
|
79
|
+
</ul>
|
80
|
+
`;
|
81
|
+
}
|
82
|
+
|
53
83
|
render() {
|
54
84
|
return html`
|
55
85
|
${this.header}
|
56
86
|
${this.loanExpiryMessage}
|
57
87
|
<ul>${this.renderDownloadOptions()}</ul>
|
58
|
-
|
59
|
-
|
88
|
+
${this.hasLCPOption
|
89
|
+
? this.installSimplyEAldikoThoriumMsg
|
90
|
+
: (this.isBookProtected ? this.accessProtectedBook : nothing)
|
91
|
+
}
|
60
92
|
`;
|
61
93
|
}
|
62
94
|
|
63
95
|
static get styles() {
|
64
|
-
|
96
|
+
const mainCss = css`
|
65
97
|
:host {
|
66
98
|
display: block;
|
67
99
|
height: 100%;
|
@@ -79,24 +111,6 @@ export class IABookDownloads extends LitElement {
|
|
79
111
|
justify-self: end;
|
80
112
|
}
|
81
113
|
|
82
|
-
.button {
|
83
|
-
color: var(--primaryTextColor);
|
84
|
-
background: var(--primaryCTAFill);
|
85
|
-
border: 1px solid var(--primaryCTABorder);
|
86
|
-
display: inline-block;
|
87
|
-
padding: .6rem 1rem;
|
88
|
-
font-size: 1.4rem;
|
89
|
-
text-decoration: none;
|
90
|
-
text-shadow: 1px 1px #484848;
|
91
|
-
border-radius: 4px;
|
92
|
-
}
|
93
|
-
|
94
|
-
.button.external {
|
95
|
-
background: var(--secondaryCTAFill, transparent);
|
96
|
-
border: 1px solid var(--secondaryCTABorder, #999);
|
97
|
-
text-shadow: none;
|
98
|
-
}
|
99
|
-
|
100
114
|
header {
|
101
115
|
display: flex;
|
102
116
|
align-items: center;
|
@@ -109,7 +123,6 @@ export class IABookDownloads extends LitElement {
|
|
109
123
|
font-weight: bold;
|
110
124
|
font-style: italic;
|
111
125
|
}
|
112
|
-
|
113
126
|
header div {
|
114
127
|
display: flex;
|
115
128
|
align-items: baseline;
|
@@ -142,5 +155,8 @@ export class IABookDownloads extends LitElement {
|
|
142
155
|
line-height: 140%;
|
143
156
|
}
|
144
157
|
`;
|
158
|
+
|
159
|
+
return [buttonStyles, mainCss];
|
145
160
|
}
|
146
161
|
}
|
162
|
+
customElements.define('ia-book-downloads', IABookDownloads);
|
@@ -1,6 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
import { html, LitElement } from 'lit
|
3
|
-
import { unsafeHTML } from 'lit
|
1
|
+
import { escapeHTML } from '../../BookReader/utils.js';
|
2
|
+
import { html, LitElement, nothing } from 'lit';
|
3
|
+
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
4
|
+
/** @typedef {import('@/src/plugins/search/plugin.search.js').SearchInsideMatch} SearchInsideMatch */
|
4
5
|
|
5
6
|
export class BookSearchResult extends LitElement {
|
6
7
|
static get properties() {
|
@@ -12,17 +13,24 @@ export class BookSearchResult extends LitElement {
|
|
12
13
|
constructor() {
|
13
14
|
super();
|
14
15
|
|
15
|
-
this.matchRegex = new RegExp('{{{(.+?)}}}', '
|
16
|
+
this.matchRegex = new RegExp('{{{(.+?)}}}', 'gs');
|
16
17
|
}
|
17
18
|
|
18
19
|
createRenderRoot() {
|
19
20
|
return this;
|
20
21
|
}
|
21
22
|
|
23
|
+
/**
|
24
|
+
* Converts the search hit to a `<p>` template containing the full search result with all of
|
25
|
+
* its `{{{triple-brace-delimited}}}` matches replaced by `<mark>HTML mark tags</mark>`.
|
26
|
+
*
|
27
|
+
* This approach safely avoids the use of `unsafeHTML` and leaves any existing HTML tags
|
28
|
+
* in the snippets intact (as inert text), rather than stripping them away with DOMPurify.
|
29
|
+
*/
|
22
30
|
highlightedHit(hit) {
|
23
|
-
return html
|
24
|
-
|
25
|
-
|
31
|
+
return html`<p>
|
32
|
+
${unsafeHTML(escapeHTML(hit).replace(this.matchRegex, '<mark>$1</mark>'))}
|
33
|
+
</p>`;
|
26
34
|
}
|
27
35
|
|
28
36
|
resultSelected() {
|
@@ -36,17 +44,14 @@ export class BookSearchResult extends LitElement {
|
|
36
44
|
}
|
37
45
|
|
38
46
|
render() {
|
39
|
-
|
40
|
-
const
|
41
|
-
const [resultDetails = {}] = par;
|
42
|
-
const pageNumber = Number.isInteger(resultDetails.page)
|
43
|
-
? html`<p class="page-num">Page -${resultDetails.page}-</p>` : nothing;
|
47
|
+
/** @type {SearchInsideMatch} */
|
48
|
+
const match = this.match;
|
44
49
|
const coverImage = html`<img src="${match.cover}" />`;
|
45
50
|
return html`
|
46
51
|
<li @click=${this.resultSelected}>
|
47
52
|
${match.cover ? coverImage : nothing}
|
48
53
|
<h4>${match.title || nothing}</h4>
|
49
|
-
${
|
54
|
+
<p class="page-num">Page ${match.displayPageNumber}</p>
|
50
55
|
${this.highlightedHit(match.text)}
|
51
56
|
</li>
|
52
57
|
`;
|