@internetarchive/bookreader 5.0.0-6-14 → 5.0.0-60
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc.js +17 -15
- package/.github/workflows/node.js.yml +72 -10
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +241 -140
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.LICENSE.txt +24 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1519 -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/BookReaderJSAutoplay.js +4 -1
- package/BookReaderDemo/BookReaderJSSimple.js +1 -0
- package/BookReaderDemo/IADemoBr.js +147 -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 +244 -0
- package/README.md +14 -1
- package/babel.config.js +19 -0
- package/codecov.yml +6 -0
- package/index.html +3 -0
- package/jsconfig.json +19 -0
- package/netlify.toml +5 -0
- package/package.json +70 -59
- 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 +585 -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 +27 -17
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
- 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/search-provider.js +80 -28
- package/src/BookNavigator/search/search-results.js +34 -25
- 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 +111 -0
- package/src/BookNavigator/volumes/volumes.js +188 -0
- package/src/BookReader/BookModel.js +59 -30
- package/src/BookReader/DebugConsole.js +3 -3
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/Mode1Up.js +56 -351
- package/src/BookReader/Mode1UpLit.js +391 -0
- package/src/BookReader/Mode2Up.js +73 -1318
- package/src/BookReader/Mode2UpLit.js +781 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +211 -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/events.js +2 -0
- package/src/BookReader/options.js +24 -2
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils.js +108 -13
- package/src/BookReader.js +481 -828
- 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/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRmain.scss +33 -0
- package/src/css/_BRnav.scss +4 -26
- package/src/css/_BRpages.scss +147 -40
- package/src/css/_BRsearch.scss +25 -11
- package/src/css/_TextSelection.scss +16 -17
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +17 -5
- package/src/css/_icons.scss +7 -1
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.archive_analytics.js +3 -3
- package/src/plugins/plugin.autoplay.js +4 -9
- 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 +32 -41
- package/src/plugins/plugin.vendor-fullscreen.js +4 -4
- package/src/plugins/search/plugin.search.js +179 -103
- package/src/plugins/search/view.js +59 -44
- 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 +87 -71
- package/src/plugins/tts/plugin.tts.js +94 -125
- package/src/plugins/tts/utils.js +0 -25
- package/src/plugins/url/UrlPlugin.js +193 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +45 -16
- package/src/util/docCookies.js +21 -2
- 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 +28 -23
- 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/helpers/rightToLeft.js +4 -10
- package/tests/e2e/models/Navigation.js +13 -4
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +40 -33
- package/tests/jest/BookNavigator/book-navigator.test.js +658 -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 +104 -60
- 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 +59 -14
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -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 +73 -0
- package/tests/jest/BookReader/Mode2Up.test.js +98 -0
- package/tests/jest/BookReader/Mode2UpLit.test.js +190 -0
- package/tests/jest/BookReader/ModeCoordinateSpace.test.js +16 -0
- package/tests/jest/BookReader/ModeSmoothZoom.test.js +175 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +10 -10
- 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 +217 -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} +26 -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 +57 -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 +47 -1
- package/tests/{plugins → jest/plugins}/tts/utils.test.js +1 -60
- package/tests/jest/plugins/url/UrlPlugin.test.js +190 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +53 -14
- package/tests/jest/setup.js +3 -0
- package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
- package/tests/jest/util/docCookies.test.js +24 -0
- 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/BookNavigator/search/a-search-result.js +0 -55
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -372
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/Mode2Up.test.js +0 -247
- 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
- package/tests/util/docCookies.test.js +0 -15
@@ -1,6 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { css, html, LitElement } from 'lit-element';
|
1
|
+
import { repeat } from 'lit/directives/repeat.js';
|
2
|
+
import { css, html, LitElement, nothing } from 'lit';
|
4
3
|
import bookmarkColorsCSS from '../assets/bookmark-colors.js';
|
5
4
|
import buttonCSS from '../assets/button-base.js';
|
6
5
|
|
@@ -208,7 +207,7 @@ export class IABookmarkEdit extends LitElement {
|
|
208
207
|
grid-gap: 0 1rem;
|
209
208
|
justify-items: stretch;
|
210
209
|
}
|
211
|
-
|
210
|
+
`;
|
212
211
|
return [buttonCSS, bookmarkColorsCSS, bookmarkEditCSS];
|
213
212
|
}
|
214
213
|
}
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { css, html, LitElement } from 'lit-element';
|
1
|
+
import { repeat } from 'lit/directives/repeat.js';
|
2
|
+
import { css, html, LitElement, nothing } from 'lit';
|
4
3
|
import './bookmark-edit.js';
|
5
4
|
import '@internetarchive/icon-edit-pencil/icon-edit-pencil.js';
|
6
5
|
import bookmarkColorsCSS from '../assets/bookmark-colors.js';
|
@@ -1,20 +1,15 @@
|
|
1
|
-
import { LitElement, html
|
1
|
+
import { LitElement, html } from 'lit';
|
2
2
|
import buttonStyles from '../assets/button-base.js';
|
3
3
|
|
4
4
|
class BookmarksLogin extends LitElement {
|
5
5
|
static get properties() {
|
6
6
|
return {
|
7
7
|
url: { type: String }
|
8
|
-
}
|
8
|
+
};
|
9
9
|
}
|
10
10
|
|
11
11
|
static get styles() {
|
12
|
-
|
13
|
-
a {
|
14
|
-
text-decoration: none;
|
15
|
-
}
|
16
|
-
`;
|
17
|
-
return [buttonStyles, mainCss];
|
12
|
+
return buttonStyles;
|
18
13
|
}
|
19
14
|
|
20
15
|
constructor() {
|
@@ -1,26 +1,40 @@
|
|
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';
|
5
5
|
|
6
6
|
import './bookmark-edit.js';
|
7
7
|
import './bookmarks-list.js';
|
8
|
-
import
|
8
|
+
import '@internetarchive/icon-bookmark';
|
9
9
|
|
10
|
-
customElements.define('icon-bookmark', IAIconBookmark);
|
11
10
|
|
12
11
|
export default class BookmarksProvider {
|
13
|
-
constructor(options
|
14
|
-
const
|
12
|
+
constructor(options) {
|
13
|
+
const {
|
14
|
+
baseHost,
|
15
|
+
signedIn,
|
16
|
+
bookreader,
|
17
|
+
modal,
|
18
|
+
onProviderChange,
|
19
|
+
} = options;
|
20
|
+
|
21
|
+
const referrerStr = `referer=${encodeURIComponent(location.href)}`;
|
22
|
+
const loginUrl = `https://${baseHost}/account/login?${referrerStr}`;
|
23
|
+
|
15
24
|
this.component = document.createElement('ia-bookmarks');
|
16
25
|
this.component.bookreader = bookreader;
|
17
|
-
this.component.
|
18
|
-
|
26
|
+
this.component.displayMode = signedIn ? 'bookmarks' : 'login';
|
27
|
+
this.component.modal = modal;
|
28
|
+
this.component.loginOptions = {
|
29
|
+
loginClicked: this.bookmarksLoginClicked,
|
30
|
+
loginUrl
|
31
|
+
};
|
19
32
|
this.bindEvents();
|
20
33
|
|
21
34
|
this.icon = html`<icon-bookmark state="hollow" style="--iconWidth: 16px; --iconHeight: 24px;"></icon-bookmark>`;
|
22
35
|
this.label = 'Bookmarks';
|
23
36
|
this.id = 'bookmarks';
|
37
|
+
this.onProviderChange = onProviderChange;
|
24
38
|
this.component.setup();
|
25
39
|
this.updateMenu(this.component.bookmarks.length);
|
26
40
|
}
|
@@ -31,23 +45,19 @@ export default class BookmarksProvider {
|
|
31
45
|
|
32
46
|
bindEvents() {
|
33
47
|
this.component.addEventListener('bookmarksChanged', this.bookmarksChanged.bind(this));
|
34
|
-
this.component.addEventListener('showItemNavigatorModal', this.showItemNavigatorModal);
|
35
|
-
this.component.addEventListener('closeItemNavigatorModal', this.closeItemNavigatorModal);
|
36
48
|
}
|
37
49
|
|
38
50
|
bookmarksChanged({ detail }) {
|
39
51
|
const bookmarksLength = Object.keys(detail.bookmarks).length;
|
40
52
|
this.updateMenu(bookmarksLength);
|
41
|
-
this.
|
53
|
+
this.onProviderChange(detail.bookmarks, detail.showSidePanel);
|
42
54
|
}
|
43
55
|
|
44
56
|
bookmarksLoginClicked() {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
);
|
51
|
-
}
|
57
|
+
window.archive_analytics?.send_event_no_sampling(
|
58
|
+
'BookReader',
|
59
|
+
`BookmarksLogin`,
|
60
|
+
window.location.path,
|
61
|
+
);
|
52
62
|
}
|
53
63
|
}
|
@@ -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,58 @@ 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
|
-
this.api.identifier = this.
|
124
|
-
this.
|
125
|
-
|
126
|
-
|
140
|
+
this.api.identifier = this.getIdentifier();
|
141
|
+
if (this.displayMode === 'login') {
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
this.fetchUserBookmarks();
|
145
|
+
this.setBREventListeners();
|
127
146
|
}
|
128
147
|
|
129
|
-
|
130
|
-
|
148
|
+
/**
|
149
|
+
* get identifier for current book including sub-files
|
150
|
+
*
|
151
|
+
* @returns Identifer
|
152
|
+
*/
|
153
|
+
getIdentifier() {
|
154
|
+
if (this.bookreader.bookId !== this.bookreader.subPrefix) {
|
155
|
+
return `${this.bookreader.bookId}/${this.bookreader.subPrefix}`;
|
156
|
+
}
|
157
|
+
|
158
|
+
return this.bookreader.bookId;
|
159
|
+
}
|
160
|
+
|
161
|
+
updateDisplay() {
|
162
|
+
if (this.displayMode === 'bookmarks') {
|
163
|
+
this.fetchUserBookmarks();
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
async fetchUserBookmarks() {
|
168
|
+
if (!this.api.identifier) {
|
169
|
+
return;
|
170
|
+
}
|
171
|
+
await this.fetchBookmarks();
|
172
|
+
this.initializeBookmarks();
|
173
|
+
}
|
174
|
+
|
175
|
+
setBREventListeners() {
|
131
176
|
['3PageViewSelected'].forEach((event) => {
|
132
177
|
window.addEventListener(`BookReader:${event}`, (e) => {
|
133
178
|
setTimeout(() => {
|
@@ -147,12 +192,12 @@ class IABookmarks extends LitElement {
|
|
147
192
|
});
|
148
193
|
['zoomOut', 'zoomIn', 'resize'].forEach((event) => {
|
149
194
|
window.addEventListener(`BookReader:${event}`, () => {
|
150
|
-
|
151
|
-
this.renderBookmarkButtons();
|
152
|
-
}
|
195
|
+
this.renderBookmarkButtons();
|
153
196
|
});
|
154
197
|
});
|
198
|
+
}
|
155
199
|
|
200
|
+
initializeBookmarks() {
|
156
201
|
this.renderBookmarkButtons();
|
157
202
|
this.markActiveBookmark(true);
|
158
203
|
this.emitBookmarksChanged();
|
@@ -181,8 +226,8 @@ class IABookmarks extends LitElement {
|
|
181
226
|
color: this.getBookmarkColor(color) ? color : this.defaultColor.id,
|
182
227
|
};
|
183
228
|
|
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
|
229
|
+
const page = IABookmarks.formatPage(this.bookreader.book.getPageNum(leafNum));
|
230
|
+
const thumbnail = this.bookreader.book.getPageURI(`${leafNum}`.replace(/\D/g, ''), 32); // Request thumbnail 1/32 the size of original image
|
186
231
|
const bookmark = {
|
187
232
|
...nomalizedParams,
|
188
233
|
id: leafNum,
|
@@ -194,27 +239,35 @@ class IABookmarks extends LitElement {
|
|
194
239
|
return bookmark;
|
195
240
|
}
|
196
241
|
|
197
|
-
fetchBookmarks() {
|
198
|
-
|
242
|
+
async fetchBookmarks() {
|
243
|
+
const resText = await this.api.getAll().then(r=> r.text());
|
244
|
+
let parsedResponse;
|
245
|
+
try {
|
246
|
+
parsedResponse = JSON.parse(resText);
|
247
|
+
} catch (e) {
|
248
|
+
parsedResponse = {error : e.message};
|
249
|
+
}
|
250
|
+
|
251
|
+
const {
|
199
252
|
success,
|
200
253
|
error = 'Something happened while fetching bookmarks.',
|
201
254
|
value: bkmrks = [],
|
202
|
-
}
|
203
|
-
if (!success) {
|
204
|
-
throw new Error(`Failed to load bookmarks: ${error}`);
|
205
|
-
}
|
255
|
+
} = parsedResponse;
|
206
256
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
const formattedLeafNum = parseInt(leafNum, 10);
|
211
|
-
const formattedBookmark = this.formatBookmark({ ...bookmark, leafNum: formattedLeafNum });
|
212
|
-
bookmarks[leafNum] = formattedBookmark;
|
213
|
-
});
|
257
|
+
if (!success) {
|
258
|
+
console?.warn('Error fetching bookmarks', error);
|
259
|
+
}
|
214
260
|
|
215
|
-
|
216
|
-
|
261
|
+
const bookmarks = {};
|
262
|
+
Object.keys(bkmrks).forEach((leafNum) => {
|
263
|
+
const bookmark = bkmrks[leafNum];
|
264
|
+
const formattedLeafNum = parseInt(leafNum, 10);
|
265
|
+
const formattedBookmark = this.formatBookmark({ ...bookmark, leafNum: formattedLeafNum });
|
266
|
+
bookmarks[leafNum] = formattedBookmark;
|
217
267
|
});
|
268
|
+
|
269
|
+
this.bookmarks = bookmarks;
|
270
|
+
return bookmarks;
|
218
271
|
}
|
219
272
|
|
220
273
|
emitBookmarksChanged() {
|
@@ -250,12 +303,14 @@ class IABookmarks extends LitElement {
|
|
250
303
|
|
251
304
|
pages.forEach((pageEl) => {
|
252
305
|
const existingButton = pageEl.querySelector('.bookmark-button');
|
253
|
-
if (existingButton) {
|
306
|
+
if (existingButton) {
|
307
|
+
existingButton.remove();
|
308
|
+
}
|
254
309
|
const pageID = +pageEl.classList.value.match(/pagediv\d+/)[0].replace(/\D/g, '');
|
255
310
|
const pageBookmark = this.getBookmark(pageID);
|
256
311
|
const bookmarkState = pageBookmark ? 'filled' : 'hollow';
|
257
312
|
// eslint-disable-next-line
|
258
|
-
const pageData = this.bookreader.
|
313
|
+
const pageData = this.bookreader.book.getPage(pageID);
|
259
314
|
const { isViewable } = pageData;
|
260
315
|
|
261
316
|
if (!isViewable) { return; }
|
@@ -375,7 +430,7 @@ class IABookmarks extends LitElement {
|
|
375
430
|
|
376
431
|
bookmarkSelected({ detail }) {
|
377
432
|
const { leafNum } = detail.bookmark;
|
378
|
-
this.bookreader.jumpToPage(`${this.bookreader.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
433
|
+
this.bookreader.jumpToPage(`${this.bookreader.book.getPageNum(`${leafNum}`.replace(/\D/g, ''))}`);
|
379
434
|
this.activeBookmarkID = leafNum;
|
380
435
|
}
|
381
436
|
|
@@ -390,33 +445,26 @@ class IABookmarks extends LitElement {
|
|
390
445
|
confirmDeletion(pageID) {
|
391
446
|
const existingBookmark = this.getBookmark(pageID);
|
392
447
|
if (existingBookmark.note) {
|
393
|
-
this.
|
448
|
+
this.displayDeletionModal(pageID);
|
394
449
|
return;
|
395
450
|
}
|
396
451
|
this.deleteBookmark({ detail: { id: `${pageID}` } });
|
397
452
|
}
|
398
453
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
.cancelAction=${() => this.emitCloseModal()}
|
408
|
-
.pageID=${pageID}
|
409
|
-
></delete-modal-actions>
|
410
|
-
`,
|
411
|
-
},
|
412
|
-
}));
|
413
|
-
}
|
454
|
+
displayDeletionModal(pageID) {
|
455
|
+
const customModalContent = html`
|
456
|
+
<delete-modal-actions
|
457
|
+
.deleteAction=${() => this.deleteBookmark({ detail: { id: `${pageID}` } })}
|
458
|
+
.cancelAction=${() => this.modal.closeModal()}
|
459
|
+
.pageID=${pageID}
|
460
|
+
></delete-modal-actions>
|
461
|
+
`;
|
414
462
|
|
415
|
-
|
416
|
-
this.
|
417
|
-
|
418
|
-
|
419
|
-
})
|
463
|
+
|
464
|
+
this.modal.showModal({
|
465
|
+
config: this.deleteModalConfig,
|
466
|
+
customModalContent,
|
467
|
+
});
|
420
468
|
}
|
421
469
|
|
422
470
|
deleteBookmark({ detail }) {
|
@@ -427,18 +475,10 @@ class IABookmarks extends LitElement {
|
|
427
475
|
|
428
476
|
this.api.delete(detail.id);
|
429
477
|
this.editedBookmark = {};
|
430
|
-
this.
|
478
|
+
this.modal.closeModal();
|
431
479
|
this.renderBookmarkButtons();
|
432
480
|
}
|
433
481
|
|
434
|
-
/**
|
435
|
-
* call `loginClicked` callback
|
436
|
-
*/
|
437
|
-
loginClick() {
|
438
|
-
const { loginClicked = () => {} } = this.options;
|
439
|
-
loginClicked();
|
440
|
-
}
|
441
|
-
|
442
482
|
/**
|
443
483
|
* Tells us if we should allow user to add bookmark via menu panel
|
444
484
|
* returns { Boolean }
|
@@ -460,6 +500,7 @@ class IABookmarks extends LitElement {
|
|
460
500
|
return html`
|
461
501
|
<button
|
462
502
|
class="ia-button primary"
|
503
|
+
tabindex="-1"
|
463
504
|
?disabled=${this.shouldEnableAddBookmarkButton}
|
464
505
|
@click=${this.addBookmark}>
|
465
506
|
Add bookmark
|
@@ -483,15 +524,23 @@ class IABookmarks extends LitElement {
|
|
483
524
|
`;
|
484
525
|
}
|
485
526
|
|
527
|
+
get bookmarkHelperMessage() {
|
528
|
+
return html`<p>Please use 1up or 2up view modes to add bookmark.</p>`;
|
529
|
+
}
|
530
|
+
|
486
531
|
render() {
|
487
|
-
const { loginUrl } = this.options;
|
488
532
|
const bookmarks = html`
|
489
533
|
${this.bookmarksList}
|
490
|
-
${this.allowAddingBookmark ? this.addBookmarkButton :
|
534
|
+
${this.allowAddingBookmark ? this.addBookmarkButton : this.bookmarkHelperMessage}
|
491
535
|
`;
|
492
536
|
return html`
|
493
537
|
<section class="bookmarks">
|
494
|
-
|
538
|
+
${ this.displayMode === 'login'
|
539
|
+
? html`<bookmarks-login
|
540
|
+
@click=${() => this.loginOptions.loginClicked()}
|
541
|
+
.url=${this.loginOptions.loginUrl}></bookmarks-login>`
|
542
|
+
: bookmarks
|
543
|
+
}
|
495
544
|
</section>
|
496
545
|
`;
|
497
546
|
}
|
@@ -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);
|