@internetarchive/bookreader 5.0.0-6-multiple-files → 5.0.0-60
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 +241 -377
- package/BookReader/BookReader.js +2 -21564
- 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/1up.svg +1 -12
- package/BookReader/icons/2up.svg +1 -15
- package/BookReader/icons/advance.svg +3 -26
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -0
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -17
- package/BookReader/icons/fullscreen_exit.svg +1 -17
- package/BookReader/icons/hamburger.svg +1 -15
- package/BookReader/icons/left-arrow.svg +1 -12
- package/BookReader/icons/magnify-minus.svg +1 -16
- package/BookReader/icons/magnify-plus.svg +1 -17
- package/BookReader/icons/magnify.svg +1 -15
- package/BookReader/icons/pause.svg +1 -23
- package/BookReader/icons/play.svg +1 -22
- package/BookReader/icons/playback-speed.svg +1 -34
- package/BookReader/icons/read-aloud.svg +1 -22
- package/BookReader/icons/review.svg +3 -22
- package/BookReader/icons/thumbnails.svg +1 -17
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -22
- package/BookReader/images/BRicons.svg +5 -94
- package/BookReader/images/books_graphic.svg +1 -177
- package/BookReader/images/icon_book.svg +1 -12
- package/BookReader/images/icon_bookmark.svg +1 -12
- package/BookReader/images/icon_gear.svg +1 -14
- package/BookReader/images/icon_hamburger.svg +1 -20
- package/BookReader/images/icon_home.svg +1 -21
- package/BookReader/images/icon_info.svg +1 -11
- package/BookReader/images/icon_one_page.svg +1 -8
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.svg +1 -1
- package/BookReader/images/icon_playback-rate.svg +1 -15
- package/BookReader/images/icon_search_button.svg +1 -8
- package/BookReader/images/icon_share.svg +1 -9
- package/BookReader/images/icon_skip-ahead.svg +1 -6
- package/BookReader/images/icon_skip-back.svg +2 -13
- package/BookReader/images/icon_speaker.svg +1 -18
- package/BookReader/images/icon_speaker_open.svg +1 -10
- package/BookReader/images/icon_thumbnails.svg +1 -12
- package/BookReader/images/icon_toc.svg +1 -5
- package/BookReader/images/icon_two_pages.svg +1 -9
- package/BookReader/images/marker_chap-off.svg +1 -11
- package/BookReader/images/marker_chap-on.svg +1 -11
- package/BookReader/images/marker_srch-on.svg +1 -11
- package/BookReader/jquery-3.js +2 -0
- package/BookReader/jquery-3.js.LICENSE.txt +24 -0
- package/BookReader/plugins/plugin.archive_analytics.js +1 -172
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -165
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +1 -304
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +1 -74
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.mobile_nav.js +1 -334
- package/BookReader/plugins/plugin.mobile_nav.js.map +1 -1
- package/BookReader/plugins/plugin.resume.js +1 -368
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +1 -1420
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +1 -1080
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +2 -9193
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +1 -269
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -379
- 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 +246 -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_ascending.js → icon_sort_desc.js} +2 -2
- 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 +88 -53
- package/src/BookNavigator/volumes/volumes.js +41 -14
- 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 +480 -825
- 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/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRmain.scss +33 -24
- package/src/css/_BRnav.scss +4 -26
- package/src/css/_BRpages.scss +147 -40
- package/src/css/_BRsearch.scss +25 -216
- 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 -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 +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 +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 +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 -14312
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/icons/sort-ascending.svg +0 -1
- package/BookReader/icons/sort-descending.svg +0 -1
- package/BookReader/jquery-1.10.1.js +0 -108
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -369
- 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 -452
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/BookNavigator/assets/icon_sort_descending.js +0 -5
- 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/assets/icons/sort-ascending.svg +0 -1
- package/src/assets/icons/sort-descending.svg +0 -1
- 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/karma/BookNavigator/volumes.test.js +0 -101
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
- package/tests/util/docCookies.test.js +0 -15
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { calcScreenDPI } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* There are a few different "coordinate spaces" at play in BR:
|
|
5
|
+
* (1) World units: i.e. inches. Unless otherwise stated, all computations
|
|
6
|
+
* are done in world units.
|
|
7
|
+
* (2) Rendered Pixels: i.e. img.width = '300'. Note this does _not_ take
|
|
8
|
+
* into account zoom scaling.
|
|
9
|
+
* (3) Visible Pixels: Just rendered pixels, but taking into account scaling.
|
|
10
|
+
*/
|
|
11
|
+
export class ModeCoordinateSpace {
|
|
12
|
+
screenDPI = calcScreenDPI();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {{ scale: number }} mode
|
|
16
|
+
*/
|
|
17
|
+
constructor(mode) {
|
|
18
|
+
this.mode = mode;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
worldUnitsToRenderedPixels = (/** @type {number} */inches) => inches * this.screenDPI;
|
|
22
|
+
renderedPixelsToWorldUnits = (/** @type {number} */px) => px / this.screenDPI;
|
|
23
|
+
|
|
24
|
+
renderedPixelsToVisiblePixels = (/** @type {number} */px) => px * this.mode.scale;
|
|
25
|
+
visiblePixelsToRenderedPixels = (/** @type {number} */px) => px / this.mode.scale;
|
|
26
|
+
|
|
27
|
+
worldUnitsToVisiblePixels = (/** @type {number} */px) => this.renderedPixelsToVisiblePixels(this.worldUnitsToRenderedPixels(px));
|
|
28
|
+
visiblePixelsToWorldUnits = (/** @type {number} */px) => this.renderedPixelsToWorldUnits(this.visiblePixelsToRenderedPixels(px));
|
|
29
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import Hammer from "hammerjs";
|
|
3
|
+
/** @typedef {import('./utils/HTMLDimensionsCacher.js').HTMLDimensionsCacher} HTMLDimensionsCacher */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} SmoothZoomable
|
|
7
|
+
* @property {HTMLElement} $container
|
|
8
|
+
* @property {HTMLElement} $visibleWorld
|
|
9
|
+
* @property {import("./options.js").AutoFitValues} autoFit
|
|
10
|
+
* @property {number} scale
|
|
11
|
+
* @property {{ x: number, y: number }} scaleCenter
|
|
12
|
+
* @property {HTMLDimensionsCacher} htmlDimensionsCacher
|
|
13
|
+
* @property {function(): void} [attachScrollListeners]
|
|
14
|
+
* @property {function(): void} [detachScrollListeners]
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Manages pinch-zoom, ctrl-wheel, and trackpad pinch smooth zooming. */
|
|
18
|
+
export class ModeSmoothZoom {
|
|
19
|
+
/** @param {SmoothZoomable} mode */
|
|
20
|
+
constructor(mode) {
|
|
21
|
+
/** @type {SmoothZoomable} */
|
|
22
|
+
this.mode = mode;
|
|
23
|
+
|
|
24
|
+
/** Non-null when a scale has been enqueued/is being processed by the buffer function */
|
|
25
|
+
this.pinchMoveFrame = null;
|
|
26
|
+
/** Promise for the current/enqueued pinch move frame. Resolves when it is complete. */
|
|
27
|
+
this.pinchMoveFramePromise = Promise.resolve();
|
|
28
|
+
this.oldScale = 1;
|
|
29
|
+
/** @type {{ scale: number, center: { x: number, y: number }}} */
|
|
30
|
+
this.lastEvent = null;
|
|
31
|
+
this.attached = false;
|
|
32
|
+
|
|
33
|
+
/** @type {function(function(): void): any} */
|
|
34
|
+
this.bufferFn = window.requestAnimationFrame.bind(window);
|
|
35
|
+
|
|
36
|
+
// Hammer.js by default set userSelect to None; we don't want that!
|
|
37
|
+
// TODO: Is there any way to do this not globally on Hammer?
|
|
38
|
+
delete Hammer.defaults.cssProps.userSelect;
|
|
39
|
+
this.hammer = new Hammer.Manager(this.mode.$container, {
|
|
40
|
+
touchAction: "pan-x pan-y",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
this.hammer.add(new Hammer.Pinch());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
attach() {
|
|
47
|
+
if (this.attached) return;
|
|
48
|
+
|
|
49
|
+
this.attachCtrlZoom();
|
|
50
|
+
|
|
51
|
+
// GestureEvents work only on Safari; they interfere with Hammer,
|
|
52
|
+
// so block them.
|
|
53
|
+
this.mode.$container.addEventListener('gesturestart', this._preventEvent);
|
|
54
|
+
this.mode.$container.addEventListener('gesturechange', this._preventEvent);
|
|
55
|
+
this.mode.$container.addEventListener('gestureend', this._preventEvent);
|
|
56
|
+
|
|
57
|
+
// The pinch listeners
|
|
58
|
+
this.hammer.on("pinchstart", this._pinchStart);
|
|
59
|
+
this.hammer.on("pinchmove", this._pinchMove);
|
|
60
|
+
this.hammer.on("pinchend", this._pinchEnd);
|
|
61
|
+
this.hammer.on("pinchcancel", this._pinchCancel);
|
|
62
|
+
|
|
63
|
+
this.attached = true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
detach() {
|
|
67
|
+
this.detachCtrlZoom();
|
|
68
|
+
|
|
69
|
+
// GestureEvents work only on Safari; they interfere with Hammer,
|
|
70
|
+
// so block them.
|
|
71
|
+
this.mode.$container.removeEventListener('gesturestart', this._preventEvent);
|
|
72
|
+
this.mode.$container.removeEventListener('gesturechange', this._preventEvent);
|
|
73
|
+
this.mode.$container.removeEventListener('gestureend', this._preventEvent);
|
|
74
|
+
|
|
75
|
+
// The pinch listeners
|
|
76
|
+
this.hammer.off("pinchstart", this._pinchStart);
|
|
77
|
+
this.hammer.off("pinchmove", this._pinchMove);
|
|
78
|
+
this.hammer.off("pinchend", this._pinchEnd);
|
|
79
|
+
this.hammer.off("pinchcancel", this._pinchCancel);
|
|
80
|
+
|
|
81
|
+
this.attached = false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @param {Event} ev */
|
|
85
|
+
_preventEvent = (ev) => {
|
|
86
|
+
ev.preventDefault();
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_pinchStart = () => {
|
|
91
|
+
// Do this in case the pinchend hasn't fired yet.
|
|
92
|
+
this.oldScale = 1;
|
|
93
|
+
this.mode.$visibleWorld.classList.add("BRsmooth-zooming");
|
|
94
|
+
this.mode.$visibleWorld.style.willChange = "transform";
|
|
95
|
+
this.mode.autoFit = "none";
|
|
96
|
+
this.detachCtrlZoom();
|
|
97
|
+
this.mode.detachScrollListeners?.();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** @param {{ scale: number, center: { x: number, y: number }}} e */
|
|
101
|
+
_pinchMove = async (e) => {
|
|
102
|
+
this.lastEvent = e;
|
|
103
|
+
if (!this.pinchMoveFrame) {
|
|
104
|
+
let pinchMoveFramePromiseRes = null;
|
|
105
|
+
this.pinchMoveFramePromise = new Promise(
|
|
106
|
+
(res) => (pinchMoveFramePromiseRes = res)
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Buffer these events; only update the scale when request animation fires
|
|
110
|
+
this.pinchMoveFrame = this.bufferFn(() => {
|
|
111
|
+
this.updateScaleCenter({
|
|
112
|
+
clientX: this.lastEvent.center.x,
|
|
113
|
+
clientY: this.lastEvent.center.y,
|
|
114
|
+
});
|
|
115
|
+
this.mode.scale *= this.lastEvent.scale / this.oldScale;
|
|
116
|
+
this.oldScale = this.lastEvent.scale;
|
|
117
|
+
this.pinchMoveFrame = null;
|
|
118
|
+
pinchMoveFramePromiseRes();
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_pinchEnd = async () => {
|
|
124
|
+
// Want this to happen after the pinchMoveFrame,
|
|
125
|
+
// if one is in progress; otherwise setting oldScale
|
|
126
|
+
// messes up the transform.
|
|
127
|
+
await this.pinchMoveFramePromise;
|
|
128
|
+
this.mode.scaleCenter = { x: 0.5, y: 0.5 };
|
|
129
|
+
this.oldScale = 1;
|
|
130
|
+
this.mode.$visibleWorld.classList.remove("BRsmooth-zooming");
|
|
131
|
+
this.mode.$visibleWorld.style.willChange = "auto";
|
|
132
|
+
this.attachCtrlZoom();
|
|
133
|
+
this.mode.attachScrollListeners?.();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
_pinchCancel = async () => {
|
|
137
|
+
// iOS fires pinchcancel ~randomly; it looks like it sometimes
|
|
138
|
+
// thinks the pinch becomes a pan, at which point it cancels?
|
|
139
|
+
await this._pinchEnd();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** @private */
|
|
143
|
+
attachCtrlZoom() {
|
|
144
|
+
window.addEventListener("wheel", this._handleCtrlWheel, { passive: false });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** @private */
|
|
148
|
+
detachCtrlZoom() {
|
|
149
|
+
window.removeEventListener("wheel", this._handleCtrlWheel);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** @param {WheelEvent} ev **/
|
|
153
|
+
_handleCtrlWheel = (ev) => {
|
|
154
|
+
if (!ev.ctrlKey) return;
|
|
155
|
+
ev.preventDefault();
|
|
156
|
+
const zoomMultiplier =
|
|
157
|
+
// Zooming on macs was painfully slow; likely due to their better
|
|
158
|
+
// trackpads. Give them a higher zoom rate.
|
|
159
|
+
/Mac/i.test(navigator.platform)
|
|
160
|
+
? 0.045
|
|
161
|
+
: // This worked well for me on Windows
|
|
162
|
+
0.03;
|
|
163
|
+
|
|
164
|
+
// Zoom around the cursor
|
|
165
|
+
this.updateScaleCenter(ev);
|
|
166
|
+
this.mode.autoFit = "none";
|
|
167
|
+
this.mode.scale *= 1 - Math.sign(ev.deltaY) * zoomMultiplier;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {object} param0
|
|
172
|
+
* @param {number} param0.clientX
|
|
173
|
+
* @param {number} param0.clientY
|
|
174
|
+
*/
|
|
175
|
+
updateScaleCenter({ clientX, clientY }) {
|
|
176
|
+
const bc = this.mode.htmlDimensionsCacher.boundingClientRect;
|
|
177
|
+
this.mode.scaleCenter = {
|
|
178
|
+
x: (clientX - bc.left) / this.mode.htmlDimensionsCacher.clientWidth,
|
|
179
|
+
y: (clientY - bc.top) / this.mode.htmlDimensionsCacher.clientHeight,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @param {number} newScale
|
|
185
|
+
* @param {number} oldScale
|
|
186
|
+
*/
|
|
187
|
+
updateViewportOnZoom(newScale, oldScale) {
|
|
188
|
+
const container = this.mode.$container;
|
|
189
|
+
const { scrollTop: T, scrollLeft: L } = container;
|
|
190
|
+
const W = this.mode.htmlDimensionsCacher.clientWidth;
|
|
191
|
+
const H = this.mode.htmlDimensionsCacher.clientHeight;
|
|
192
|
+
|
|
193
|
+
// Scale factor change
|
|
194
|
+
const F = newScale / oldScale;
|
|
195
|
+
|
|
196
|
+
// Where in the viewport the zoom is centered on
|
|
197
|
+
const XPOS = this.mode.scaleCenter.x;
|
|
198
|
+
const YPOS = this.mode.scaleCenter.y;
|
|
199
|
+
const oldCenter = {
|
|
200
|
+
x: L + XPOS * W,
|
|
201
|
+
y: T + YPOS * H,
|
|
202
|
+
};
|
|
203
|
+
const newCenter = {
|
|
204
|
+
x: F * oldCenter.x,
|
|
205
|
+
y: F * oldCenter.y,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
container.scrollTop = newCenter.y - YPOS * H;
|
|
209
|
+
container.scrollLeft = newCenter.x - XPOS * W;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { notInArray, clamp } from './utils.js';
|
|
3
3
|
import { EVENTS } from './events.js';
|
|
4
|
+
import { DragScrollable } from './DragScrollable.js';
|
|
4
5
|
/** @typedef {import('../BookREader.js').default} BookReader */
|
|
5
6
|
/** @typedef {import('./BookModel.js').PageIndex} PageIndex */
|
|
6
7
|
/** @typedef {import('./BookModel.js').BookModel} BookModel */
|
|
@@ -176,7 +177,7 @@ export class ModeThumb {
|
|
|
176
177
|
// shift viewModeOrder after clicking on thumbsnail leaf
|
|
177
178
|
const nextModeID = this.br.viewModeOrder.shift();
|
|
178
179
|
this.br.viewModeOrder.push(nextModeID);
|
|
179
|
-
this.br.updateViewModeButton($('.viewmode'), 'twopg', 'Two-page view');
|
|
180
|
+
this.br._components.navbar.updateViewModeButton($('.viewmode'), 'twopg', 'Two-page view');
|
|
180
181
|
|
|
181
182
|
this.br.trigger(EVENTS.fragmentChange);
|
|
182
183
|
event.stopPropagation();
|
|
@@ -214,8 +215,6 @@ export class ModeThumb {
|
|
|
214
215
|
|
|
215
216
|
// highlight current page
|
|
216
217
|
this.br.$('.pagediv' + this.br.currentIndex()).addClass('BRpagedivthumb_highlight');
|
|
217
|
-
|
|
218
|
-
this.br.updateToolbarZoom(this.br.reduce);
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
/**
|
|
@@ -234,20 +233,27 @@ export class ModeThumb {
|
|
|
234
233
|
}
|
|
235
234
|
|
|
236
235
|
/**
|
|
237
|
-
* @param {
|
|
236
|
+
* @param {'in' | 'out'} direction
|
|
238
237
|
*/
|
|
239
238
|
zoom(direction) {
|
|
240
239
|
const oldColumns = this.br.thumbColumns;
|
|
241
240
|
switch (direction) {
|
|
242
|
-
case
|
|
243
|
-
this.br.thumbColumns += 1;
|
|
244
|
-
break;
|
|
245
|
-
case 1:
|
|
241
|
+
case 'in':
|
|
246
242
|
this.br.thumbColumns -= 1;
|
|
247
243
|
break;
|
|
244
|
+
case 'out':
|
|
245
|
+
this.br.thumbColumns += 1;
|
|
246
|
+
break;
|
|
247
|
+
default:
|
|
248
|
+
console.error(`Unsupported direction: ${direction}`);
|
|
248
249
|
}
|
|
249
250
|
|
|
250
|
-
|
|
251
|
+
// Limit zoom in/out columns
|
|
252
|
+
this.br.thumbColumns = clamp(
|
|
253
|
+
this.br.thumbColumns,
|
|
254
|
+
this.br.options.thumbMinZoomColumns,
|
|
255
|
+
this.br.options.thumbMaxZoomColumns
|
|
256
|
+
);
|
|
251
257
|
|
|
252
258
|
if (this.br.thumbColumns != oldColumns) {
|
|
253
259
|
this.br.displayedRows = []; /* force a gallery redraw */
|
|
@@ -279,7 +285,7 @@ export class ModeThumb {
|
|
|
279
285
|
|
|
280
286
|
this.br.refs.$brPageViewEl = $("<div class='BRpageview'></div>");
|
|
281
287
|
this.br.refs.$brContainer.append(this.br.refs.$brPageViewEl);
|
|
282
|
-
this.br.refs.$brContainer
|
|
288
|
+
this.dragScrollable = this.dragScrollable || new DragScrollable(this.br.refs.$brContainer[0], {preventDefault: true});
|
|
283
289
|
|
|
284
290
|
this.br.bindGestures(this.br.refs.$brContainer);
|
|
285
291
|
|
|
@@ -330,7 +336,7 @@ export class ModeThumb {
|
|
|
330
336
|
} else {
|
|
331
337
|
this.br.animating = true;
|
|
332
338
|
this.br.refs.$brContainer.stop(true)
|
|
333
|
-
.animate({ scrollTop: leafTop }, 'fast', () => { this.br.animating = false });
|
|
339
|
+
.animate({ scrollTop: leafTop }, 'fast', () => { this.br.animating = false; });
|
|
334
340
|
}
|
|
335
341
|
}
|
|
336
342
|
}
|
|
@@ -4,6 +4,7 @@ import 'jquery-ui/ui/widget.js';
|
|
|
4
4
|
import 'jquery-ui/ui/widgets/mouse.js';
|
|
5
5
|
import 'jquery-ui/ui/widgets/slider.js';
|
|
6
6
|
import { EVENTS } from '../events.js';
|
|
7
|
+
import { throttle } from '../utils.js';
|
|
7
8
|
|
|
8
9
|
export class Navbar {
|
|
9
10
|
/**
|
|
@@ -27,6 +28,8 @@ export class Navbar {
|
|
|
27
28
|
this.maximumControls = [
|
|
28
29
|
'book_left', 'book_right', 'zoom_in', 'zoom_out', 'onepg', 'twopg', 'thumb'
|
|
29
30
|
];
|
|
31
|
+
|
|
32
|
+
this.updateNavIndexThrottled = throttle(this.updateNavIndex.bind(this), 250, false);
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
controlFor(controlName) {
|
|
@@ -213,7 +216,7 @@ export class Navbar {
|
|
|
213
216
|
const $slider = this.$root.find('.BRpager').slider({
|
|
214
217
|
animate: true,
|
|
215
218
|
min: 0,
|
|
216
|
-
max: br.getNumLeafs() - 1,
|
|
219
|
+
max: br.book.getNumLeafs() - 1,
|
|
217
220
|
value: br.currentIndex(),
|
|
218
221
|
range: "min"
|
|
219
222
|
});
|
|
@@ -240,35 +243,6 @@ export class Navbar {
|
|
|
240
243
|
return this.$nav;
|
|
241
244
|
}
|
|
242
245
|
|
|
243
|
-
/**
|
|
244
|
-
* Initialize the navigation bar when embedded
|
|
245
|
-
*/
|
|
246
|
-
initEmbed() {
|
|
247
|
-
const { br } = this;
|
|
248
|
-
// IA-specific
|
|
249
|
-
const thisLink = (window.location + '')
|
|
250
|
-
.replace('?ui=embed','')
|
|
251
|
-
.replace('/stream/', '/details/')
|
|
252
|
-
.replace('#', '/');
|
|
253
|
-
const logoHtml = br.showLogo ? `<a class="logo" href="${br.logoURL}" target="_blank"></a>` : '';
|
|
254
|
-
|
|
255
|
-
br.refs.$BRfooter = this.$root = $('<div class="BRfooter"></div>');
|
|
256
|
-
br.refs.$BRnav = this.$nav = $(
|
|
257
|
-
`<div class="BRnav BRnavEmbed">
|
|
258
|
-
${logoHtml}
|
|
259
|
-
<span class="BRembedreturn">
|
|
260
|
-
<a href="${thisLink}" target="_blank">${br.bookTitle}</a>
|
|
261
|
-
</span>
|
|
262
|
-
<span class="BRtoolbarbuttons">
|
|
263
|
-
<button class="BRicon book_left"></button>
|
|
264
|
-
<button class="BRicon book_right"></button>
|
|
265
|
-
<button class="BRicon full"></button>
|
|
266
|
-
</span>
|
|
267
|
-
</div>`);
|
|
268
|
-
this.$root.append(this.$nav);
|
|
269
|
-
br.refs.$br.append(this.$root);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
246
|
/**
|
|
273
247
|
* Returns the textual representation of the current page for the navbar
|
|
274
248
|
* @param {number} index
|
|
@@ -277,16 +251,16 @@ export class Navbar {
|
|
|
277
251
|
getNavPageNumString(index) {
|
|
278
252
|
const { br } = this;
|
|
279
253
|
// Accessible index starts at 0 (alas) so we add 1 to make human
|
|
280
|
-
const pageNum = br.getPageNum(index);
|
|
281
|
-
const pageType = br.getPageProp(index, 'pageType');
|
|
282
|
-
const numLeafs = br.getNumLeafs();
|
|
254
|
+
const pageNum = br.book.getPageNum(index);
|
|
255
|
+
const pageType = br.book.getPageProp(index, 'pageType');
|
|
256
|
+
const numLeafs = br.book.getNumLeafs();
|
|
283
257
|
|
|
284
258
|
if (!this.maxPageNum) {
|
|
285
259
|
// Calculate Max page num (used for pagination display)
|
|
286
260
|
let maxPageNum = 0;
|
|
287
261
|
let pageNumVal;
|
|
288
262
|
for (let i = 0; i < numLeafs; i++) {
|
|
289
|
-
pageNumVal = br.getPageNum(i);
|
|
263
|
+
pageNumVal = br.book.getPageNum(i);
|
|
290
264
|
if (!isNaN(pageNumVal) && pageNumVal > maxPageNum) {
|
|
291
265
|
maxPageNum = pageNumVal;
|
|
292
266
|
}
|
|
@@ -331,9 +305,9 @@ export function getNavPageNumHtml(index, numLeafs, pageNum, pageType, maxPageNum
|
|
|
331
305
|
|
|
332
306
|
if (!pageIsAsserted) {
|
|
333
307
|
const pageIndex = index + 1;
|
|
334
|
-
return `
|
|
308
|
+
return `(${pageIndex} of ${numLeafs})`; // Page (8 of 10)
|
|
335
309
|
}
|
|
336
310
|
|
|
337
311
|
const bookLengthLabel = maxPageNum ? ` of ${maxPageNum}` : '';
|
|
338
|
-
return
|
|
312
|
+
return `${pageNum}${bookLengthLabel}`;
|
|
339
313
|
}
|
|
@@ -46,11 +46,17 @@ export class PageContainer {
|
|
|
46
46
|
const alreadyLoaded = this.imageCache.imageLoaded(this.page.index, reduce);
|
|
47
47
|
const nextBestLoadedReduce = !alreadyLoaded && this.imageCache.getBestLoadedReduce(this.page.index, reduce);
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// Create high res image
|
|
50
|
+
const $newImg = this.imageCache.image(this.page.index, reduce);
|
|
51
|
+
|
|
52
|
+
// Avoid removing/re-adding the image if it's already there
|
|
53
|
+
// This can be called quite a bit, so we need to be fast
|
|
54
|
+
if (this.$img?.[0].src == $newImg[0].src) {
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
this.$img?.remove();
|
|
51
|
-
this.$img = this
|
|
52
|
-
.image(this.page.index, reduce)
|
|
53
|
-
.prependTo(this.$container);
|
|
59
|
+
this.$img = $newImg.prependTo(this.$container);
|
|
54
60
|
|
|
55
61
|
const backgroundLayers = [];
|
|
56
62
|
if (!alreadyLoaded) {
|
|
@@ -58,14 +64,14 @@ export class PageContainer {
|
|
|
58
64
|
backgroundLayers.push(`url("${this.loadingImage}") center/20px no-repeat`);
|
|
59
65
|
}
|
|
60
66
|
if (nextBestLoadedReduce) {
|
|
61
|
-
backgroundLayers.push(`url("${this.page.getURI(nextBestLoadedReduce, 0)}") center/100% no-repeat`);
|
|
67
|
+
backgroundLayers.push(`url("${this.page.getURI(nextBestLoadedReduce, 0)}") center/100% 100% no-repeat`);
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
if (!alreadyLoaded) {
|
|
65
71
|
this.$img
|
|
66
72
|
.css('background', backgroundLayers.join(','))
|
|
67
73
|
.one('loadend', async (ev) => {
|
|
68
|
-
$(ev.target).css({ 'background': '' })
|
|
74
|
+
$(ev.target).css({ 'background': '' });
|
|
69
75
|
$(ev.target).parent().removeClass('BRpageloading');
|
|
70
76
|
});
|
|
71
77
|
}
|
|
@@ -73,3 +79,60 @@ export class PageContainer {
|
|
|
73
79
|
return this;
|
|
74
80
|
}
|
|
75
81
|
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {PageModel} page
|
|
86
|
+
* @param {string} className
|
|
87
|
+
*/
|
|
88
|
+
export function createSVGPageLayer(page, className) {
|
|
89
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
90
|
+
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
91
|
+
svg.setAttribute("viewBox", `0 0 ${page.width} ${page.height}`);
|
|
92
|
+
svg.setAttribute('class', `BRPageLayer ${className}`);
|
|
93
|
+
svg.setAttribute('preserveAspectRatio', 'none');
|
|
94
|
+
return svg;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {{ l: number, r: number, b: number, t: number }} box
|
|
99
|
+
*/
|
|
100
|
+
export function boxToSVGRect({ l: left, r: right, b: bottom, t: top }) {
|
|
101
|
+
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
102
|
+
rect.setAttribute("x", left.toString());
|
|
103
|
+
rect.setAttribute("y", top.toString());
|
|
104
|
+
rect.setAttribute("width", (right - left).toString());
|
|
105
|
+
rect.setAttribute("height", (bottom - top).toString());
|
|
106
|
+
|
|
107
|
+
// Some style; corner radius 4px. Can't set this in CSS yet
|
|
108
|
+
rect.setAttribute("rx", "4");
|
|
109
|
+
rect.setAttribute("ry", "4");
|
|
110
|
+
return rect;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @param {string} layerClass
|
|
115
|
+
* @param {Array<{ l: number, r: number, b: number, t: number }>} boxes
|
|
116
|
+
* @param {PageModel} page
|
|
117
|
+
* @param {HTMLElement} containerEl
|
|
118
|
+
* @param {string[]} [rectClasses] CSS classes to add to the rects
|
|
119
|
+
*/
|
|
120
|
+
export function renderBoxesInPageContainerLayer(layerClass, boxes, page, containerEl, rectClasses = null) {
|
|
121
|
+
const mountedSvg = containerEl.querySelector(`.${layerClass}`);
|
|
122
|
+
// Create the layer if it's not there
|
|
123
|
+
const svg = mountedSvg || createSVGPageLayer(page, layerClass);
|
|
124
|
+
if (!mountedSvg) {
|
|
125
|
+
// Insert after the image if the image is already loaded.
|
|
126
|
+
const imgEl = containerEl.querySelector('.BRpageimage');
|
|
127
|
+
if (imgEl) $(svg).insertAfter(imgEl);
|
|
128
|
+
else $(svg).prependTo(containerEl);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (const [i, box] of boxes.entries()) {
|
|
132
|
+
const rect = boxToSVGRect(box);
|
|
133
|
+
if (rectClasses) {
|
|
134
|
+
rect.setAttribute('class', rectClasses[i]);
|
|
135
|
+
}
|
|
136
|
+
svg.appendChild(rect);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -54,7 +54,7 @@ export class Toolbar {
|
|
|
54
54
|
.attr({href: br.bookUrl, title: br.bookUrlTitle})
|
|
55
55
|
.addClass('BRreturn')
|
|
56
56
|
.html(br.bookUrlText || br.bookTitle)
|
|
57
|
-
)
|
|
57
|
+
);
|
|
58
58
|
} else if (br.bookTitle) {
|
|
59
59
|
$titleSectionEl.append(br.bookUrlText || br.bookTitle);
|
|
60
60
|
}
|
|
@@ -75,8 +75,6 @@ export class Toolbar {
|
|
|
75
75
|
br.$('.BRnavCntl').addClass('BRup');
|
|
76
76
|
br.$('.pause').hide();
|
|
77
77
|
|
|
78
|
-
this.updateToolbarZoom(br.reduce); // Pretty format
|
|
79
|
-
|
|
80
78
|
// We build in mode 2
|
|
81
79
|
br.refs.$BRtoolbar.append();
|
|
82
80
|
|
|
@@ -127,31 +125,6 @@ export class Toolbar {
|
|
|
127
125
|
});
|
|
128
126
|
}
|
|
129
127
|
|
|
130
|
-
/**
|
|
131
|
-
* @deprecated
|
|
132
|
-
* @todo .BRzoom doesn't exist anywhere, so this is likely dead code
|
|
133
|
-
* Update the displayed zoom factor based on reduction factor
|
|
134
|
-
* @param {number} reduce
|
|
135
|
-
*/
|
|
136
|
-
updateToolbarZoom(reduce) {
|
|
137
|
-
const { br } = this;
|
|
138
|
-
// $$$ TODO preserve zoom/fit for each mode
|
|
139
|
-
const autofit = br.mode == br.constMode2up ? br.twoPage.autofit : br.onePage.autofit;
|
|
140
|
-
/** @type {string} */
|
|
141
|
-
let value;
|
|
142
|
-
if (autofit) {
|
|
143
|
-
value = autofit.slice(0,1).toUpperCase() + autofit.slice(1);
|
|
144
|
-
} else {
|
|
145
|
-
value = (100 / reduce)
|
|
146
|
-
.toFixed(2)
|
|
147
|
-
// Strip trailing zeroes and decimal if all zeroes
|
|
148
|
-
.replace(/0+$/,'')
|
|
149
|
-
.replace(/\.$/,'')
|
|
150
|
-
+ '%';
|
|
151
|
-
}
|
|
152
|
-
br.$('.BRzoom').text(value);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
128
|
/**
|
|
156
129
|
* @param {JQuery} $shareDiv
|
|
157
130
|
*/
|
|
@@ -212,11 +185,11 @@ export class Toolbar {
|
|
|
212
185
|
$form.appendTo($shareDiv);
|
|
213
186
|
|
|
214
187
|
$form.find('.fieldset-embed input').on('change', event => {
|
|
215
|
-
const form = $(event.target).parents('form
|
|
188
|
+
const form = $(event.target).parents('form').first();
|
|
216
189
|
const params = {};
|
|
217
190
|
params.mode = $(form.find('.fieldset-embed input[name=pages]:checked')).val();
|
|
218
191
|
if (form.find('.fieldset-embed input[name=thispage]').prop('checked')) {
|
|
219
|
-
params.page = br.getPageNum(br.currentIndex());
|
|
192
|
+
params.page = br.book.getPageNum(br.currentIndex());
|
|
220
193
|
}
|
|
221
194
|
|
|
222
195
|
if (br.getEmbedCode) {
|
|
@@ -232,12 +205,12 @@ export class Toolbar {
|
|
|
232
205
|
// Bind share buttons
|
|
233
206
|
|
|
234
207
|
// Use url without hashes
|
|
235
|
-
$form.find('.facebook-share-button').click(
|
|
208
|
+
$form.find('.facebook-share-button').on("click", () => {
|
|
236
209
|
const params = $.param({ u: this._getSocialShareUrl() });
|
|
237
210
|
const url = 'https://www.facebook.com/sharer.php?' + params;
|
|
238
211
|
createPopup(url, 600, 400, 'Share');
|
|
239
212
|
});
|
|
240
|
-
$form.find('.twitter-share-button').click(
|
|
213
|
+
$form.find('.twitter-share-button').on("click", () => {
|
|
241
214
|
const params = $.param({
|
|
242
215
|
url: this._getSocialShareUrl(),
|
|
243
216
|
text: br.bookTitle
|
|
@@ -245,7 +218,7 @@ export class Toolbar {
|
|
|
245
218
|
const url = 'https://twitter.com/intent/tweet?' + params;
|
|
246
219
|
createPopup(url, 600, 400, 'Share');
|
|
247
220
|
});
|
|
248
|
-
$form.find('.email-share-button').click(
|
|
221
|
+
$form.find('.email-share-button').on("click", () => {
|
|
249
222
|
const body = `${br.bookTitle}\n\n${this._getSocialShareUrl()}`;
|
|
250
223
|
window.location.href = `mailto:?subject=${encodeURI(br.bookTitle)}&body=${encodeURI(body)}`;
|
|
251
224
|
});
|
|
@@ -331,11 +304,11 @@ export class Toolbar {
|
|
|
331
304
|
}
|
|
332
305
|
}
|
|
333
306
|
|
|
334
|
-
|
|
307
|
+
function blankInfoDiv() {
|
|
335
308
|
return $(`
|
|
336
309
|
<div class="BRfloat BRinfo">
|
|
337
310
|
<div class="BRfloatHead">About this book
|
|
338
|
-
<button class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></button>
|
|
311
|
+
<button class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="br-colorbox-shift">Close</span></button>
|
|
339
312
|
</div>
|
|
340
313
|
<div class="BRfloatBody">
|
|
341
314
|
<div class="BRfloatCover"></div>
|
|
@@ -351,12 +324,12 @@ export function blankInfoDiv() {
|
|
|
351
324
|
</div>`);
|
|
352
325
|
}
|
|
353
326
|
|
|
354
|
-
|
|
327
|
+
function blankShareDiv() {
|
|
355
328
|
return $(`
|
|
356
329
|
<div class="BRfloat BRshare">
|
|
357
330
|
<div class="BRfloatHead">
|
|
358
331
|
Share
|
|
359
|
-
<button class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></button>
|
|
332
|
+
<button class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="br-colorbox-shift">Close</span></button>
|
|
360
333
|
</div>
|
|
361
334
|
</div>`);
|
|
362
335
|
}
|
package/src/BookReader/events.js
CHANGED
|
@@ -3,9 +3,11 @@ export const EVENTS = {
|
|
|
3
3
|
/** Indicates that the fragment (a serialization of the reader
|
|
4
4
|
* state) has changed. */
|
|
5
5
|
fragmentChange: 'fragmentChange',
|
|
6
|
+
pageChanged: 'pageChanged',
|
|
6
7
|
PostInit: 'PostInit',
|
|
7
8
|
stop: 'stop',
|
|
8
9
|
resize: 'resize',
|
|
10
|
+
userAction: 'userAction', // event to know if user is actively reading
|
|
9
11
|
// nav events:
|
|
10
12
|
navToggled: 'navToggled',
|
|
11
13
|
// menu click events
|