@internetarchive/bookreader 5.0.0-9-multiple-files → 5.0.0-90
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 +21 -19
- package/.github/workflows/node.js.yml +81 -7
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +505 -1442
- package/BookReader/BookReader.js +2 -21564
- package/BookReader/BookReader.js.LICENSE.txt +20 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1782 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +7 -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/images/unviewable_page.png +0 -0
- 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 +22 -301
- package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
- 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.iiif.js +2 -0
- package/BookReader/plugins/plugin.iiif.js.map +1 -0
- package/BookReader/plugins/plugin.resume.js +1 -368
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +2 -1420
- package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +2 -1080
- package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +2 -9193
- package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
- 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 +18 -19
- package/BookReaderDemo/BookReaderJSAdvanced.js +0 -3
- package/BookReaderDemo/BookReaderJSSimple.js +1 -0
- package/BookReaderDemo/IADemoBr.js +144 -0
- package/BookReaderDemo/demo-advanced.html +2 -2
- package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
- package/BookReaderDemo/demo-fullscreen-mobile.html +3 -5
- package/BookReaderDemo/demo-fullscreen.html +2 -4
- package/BookReaderDemo/demo-iiif.html +99 -12
- package/BookReaderDemo/demo-internetarchive.html +214 -18
- package/BookReaderDemo/demo-multiple.html +2 -1
- package/BookReaderDemo/demo-preview-pages.html +526 -525
- package/BookReaderDemo/demo-simple.html +2 -1
- package/BookReaderDemo/demo-vendor-fullscreen.html +2 -4
- package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
- package/BookReaderDemo/immersion-1up.html +2 -2
- package/BookReaderDemo/immersion-mode.html +2 -4
- package/BookReaderDemo/toggle_controls.html +3 -2
- package/BookReaderDemo/view_mode.html +2 -1
- package/BookReaderDemo/viewmode-cycle.html +2 -3
- package/CHANGELOG.md +595 -33
- package/README.md +14 -1
- package/babel.config.js +20 -0
- package/codecov.yml +6 -0
- package/index.html +5 -2
- package/jsconfig.json +19 -0
- package/netlify.toml +9 -0
- package/package.json +70 -62
- package/renovate.json +52 -0
- package/scripts/preversion.js +0 -1
- package/src/BookNavigator/assets/bookmark-colors.js +1 -1
- package/src/BookNavigator/assets/button-base.js +10 -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/book-navigator.js +590 -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 +4 -9
- 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 +29 -25
- package/src/BookNavigator/search/search-provider.js +80 -28
- package/src/BookNavigator/search/search-results.js +29 -26
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/viewable-files.js +95 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +13 -12
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +7 -7
- package/src/BookReader/BookModel.js +76 -41
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/ImageCache.js +48 -15
- package/src/BookReader/Mode1Up.js +56 -351
- package/src/BookReader/Mode1UpLit.js +388 -0
- package/src/BookReader/Mode2Up.js +73 -1318
- package/src/BookReader/Mode2UpLit.js +777 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +312 -0
- package/src/BookReader/ModeThumb.js +19 -13
- package/src/BookReader/Navbar/Navbar.js +70 -54
- package/src/BookReader/PageContainer.js +116 -22
- package/src/BookReader/ReduceSet.js +3 -3
- package/src/BookReader/Toolbar/Toolbar.js +14 -41
- package/src/BookReader/events.js +2 -3
- package/src/BookReader/options.js +73 -15
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils/SelectionObserver.js +45 -0
- package/src/BookReader/utils/classes.js +1 -1
- package/src/BookReader/utils.js +128 -13
- package/src/BookReader.js +562 -1078
- package/src/BookReaderPlugin.js +44 -0
- 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/assets/images/unviewable_page.png +0 -0
- package/src/css/BookReader.scss +1 -17
- package/src/css/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRicon.scss +8 -2
- package/src/css/_BRmain.scss +33 -27
- package/src/css/_BRnav.scss +12 -42
- package/src/css/_BRpages.scss +170 -42
- package/src/css/_BRsearch.scss +68 -230
- package/src/css/_BRtoolbar.scss +5 -5
- package/src/css/_TextSelection.scss +87 -27
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +24 -7
- package/src/css/_icons.scss +7 -1
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.archive_analytics.js +84 -78
- package/src/plugins/plugin.autoplay.js +99 -104
- package/src/plugins/plugin.chapters.js +237 -191
- package/src/plugins/plugin.iframe.js +1 -1
- package/src/plugins/plugin.iiif.js +141 -0
- package/src/plugins/plugin.resume.js +53 -50
- package/src/plugins/plugin.text_selection.js +503 -175
- package/src/plugins/plugin.vendor-fullscreen.js +7 -7
- package/src/plugins/search/plugin.search.js +183 -121
- package/src/plugins/search/utils.js +43 -0
- package/src/plugins/search/view.js +67 -202
- package/src/plugins/tts/AbstractTTSEngine.js +75 -45
- package/src/plugins/tts/FestivalTTSEngine.js +21 -31
- package/src/plugins/tts/PageChunk.js +16 -23
- package/src/plugins/tts/PageChunkIterator.js +11 -17
- package/src/plugins/tts/WebTTSEngine.js +88 -72
- package/src/plugins/tts/plugin.tts.js +310 -350
- package/src/plugins/tts/utils.js +16 -26
- package/src/plugins/url/UrlPlugin.js +191 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
- package/src/util/browserSniffing.js +22 -0
- package/src/util/docCookies.js +21 -2
- package/src/util/strings.js +1 -0
- package/tests/e2e/README.md +37 -0
- package/tests/e2e/autoplay.test.js +9 -6
- package/tests/e2e/base.test.js +8 -16
- package/tests/e2e/helpers/base.js +55 -50
- package/tests/e2e/helpers/debug.js +1 -1
- package/tests/e2e/helpers/mockSearch.js +19 -22
- package/tests/e2e/helpers/params.js +17 -0
- package/tests/e2e/helpers/rightToLeft.js +8 -14
- package/tests/e2e/helpers/search.js +73 -0
- package/tests/e2e/models/Navigation.js +20 -37
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +40 -33
- package/tests/jest/BookNavigator/book-navigator.test.js +661 -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 +109 -60
- package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
- package/tests/jest/BookNavigator/viewable-files/viewable-files-provider.test.js +80 -0
- package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
- package/tests/{BookReader → jest/BookReader}/BookModel.test.js +74 -14
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -0
- 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 +218 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +42 -29
- package/tests/jest/BookReader/PageContainer.test.js +238 -0
- package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +3 -3
- package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
- package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
- package/tests/jest/BookReader/utils/SelectionObserver.test.js +57 -0
- package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
- package/tests/jest/BookReader/utils.test.js +250 -0
- package/tests/jest/BookReader.keyboard.test.js +190 -0
- package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +10 -2
- package/tests/{BookReader.test.js → jest/BookReader.test.js} +43 -53
- package/tests/jest/plugins/plugin.archive_analytics.test.js +20 -0
- package/tests/jest/plugins/plugin.autoplay.test.js +35 -0
- package/tests/jest/plugins/plugin.chapters.test.js +195 -0
- package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +4 -4
- package/tests/{plugins → jest/plugins}/plugin.resume.test.js +22 -35
- package/tests/jest/plugins/plugin.text_selection.test.js +316 -0
- package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
- package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +26 -47
- package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +42 -9
- package/tests/jest/plugins/search/utils.js +25 -0
- package/tests/jest/plugins/search/utils.test.js +29 -0
- package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +30 -10
- 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 +198 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +57 -18
- 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 +16 -10
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -14330
- 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/BookReader/plugins/plugin.mobile_nav.js +0 -335
- package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
- package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
- package/BookReaderDemo/IIIFBookReader.js +0 -207
- package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
- package/BookReaderDemo/demo-autoplay.html +0 -38
- package/BookReaderDemo/demo-iiif.js +0 -26
- 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_ascending.js +0 -5
- 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/BookNavigator/volumes/volumes-provider.js +0 -108
- package/src/BookNavigator/volumes/volumes.js +0 -162
- package/src/BookReader/DebugConsole.js +0 -54
- 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/css/_MobileNav.scss +0 -194
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/src/plugins/plugin.mobile_nav.js +0 -287
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/DebugConsole.test.js +0 -25
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/Mode2Up.test.js +0 -247
- package/tests/BookReader/PageContainer.test.js +0 -115
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/e2e/helpers/desktopSearch.js +0 -72
- package/tests/e2e/helpers/mobileSearch.js +0 -85
- 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 -133
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
- package/tests/plugins/plugin.archive_analytics.test.js +0 -23
- package/tests/plugins/plugin.autoplay.test.js +0 -52
- package/tests/plugins/plugin.chapters.test.js +0 -130
- package/tests/plugins/plugin.mobile_nav.test.js +0 -66
- package/tests/plugins/plugin.text_selection.test.js +0 -203
- 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,312 @@
|
|
1
|
+
// @ts-check
|
2
|
+
import interact from 'interactjs';
|
3
|
+
import { isIOS, isSamsungInternet } from '../util/browserSniffing.js';
|
4
|
+
import { sleep } from './utils.js';
|
5
|
+
/** @typedef {import('./utils/HTMLDimensionsCacher.js').HTMLDimensionsCacher} HTMLDimensionsCacher */
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @typedef {object} SmoothZoomable
|
9
|
+
* @property {HTMLElement} $container
|
10
|
+
* @property {HTMLElement} $visibleWorld
|
11
|
+
* @property {import("./options.js").AutoFitValues} autoFit
|
12
|
+
* @property {number} scale
|
13
|
+
* @property {HTMLDimensionsCacher} htmlDimensionsCacher
|
14
|
+
* @property {function(): void} [attachScrollListeners]
|
15
|
+
* @property {function(): void} [detachScrollListeners]
|
16
|
+
*/
|
17
|
+
|
18
|
+
/** Manages pinch-zoom, ctrl-wheel, and trackpad pinch smooth zooming. */
|
19
|
+
export class ModeSmoothZoom {
|
20
|
+
/** Position (in unit-less, [0, 1] coordinates) in client to scale around */
|
21
|
+
scaleCenter = { x: 0.5, y: 0.5 };
|
22
|
+
|
23
|
+
/** @param {SmoothZoomable} mode */
|
24
|
+
constructor(mode) {
|
25
|
+
/** @type {SmoothZoomable} */
|
26
|
+
this.mode = mode;
|
27
|
+
|
28
|
+
/** Whether a pinch is currently happening */
|
29
|
+
this.pinching = false;
|
30
|
+
/** Non-null when a scale has been enqueued/is being processed by the buffer function */
|
31
|
+
this.pinchMoveFrame = null;
|
32
|
+
/** Promise for the current/enqueued pinch move frame. Resolves when it is complete. */
|
33
|
+
this.pinchMoveFramePromise = Promise.resolve();
|
34
|
+
this.oldScale = 1;
|
35
|
+
/** @type {{ scale: number, clientX: number, clientY: number }}} */
|
36
|
+
this.lastEvent = null;
|
37
|
+
this.attached = false;
|
38
|
+
|
39
|
+
/** @type {function(function(): void): any} */
|
40
|
+
this.bufferFn = window.requestAnimationFrame.bind(window);
|
41
|
+
}
|
42
|
+
|
43
|
+
attach() {
|
44
|
+
if (this.attached) return;
|
45
|
+
|
46
|
+
this.attachCtrlZoom();
|
47
|
+
|
48
|
+
// GestureEvents work only on Safari; they're too glitchy to use
|
49
|
+
// fully, but they can sometimes help error correct when interact
|
50
|
+
// misses an end/start event on Safari due to Safari bugs.
|
51
|
+
this.mode.$container.addEventListener('gesturestart', this._pinchStart);
|
52
|
+
this.mode.$container.addEventListener('gesturechange', this._preventEvent);
|
53
|
+
this.mode.$container.addEventListener('gestureend', this._pinchEnd);
|
54
|
+
|
55
|
+
if (isIOS()) {
|
56
|
+
this.touchesMonitor = new TouchesMonitor(this.mode.$container);
|
57
|
+
this.touchesMonitor.attach();
|
58
|
+
}
|
59
|
+
|
60
|
+
this.mode.$container.style.touchAction = "pan-x pan-y";
|
61
|
+
|
62
|
+
// The pinch listeners
|
63
|
+
this.interact = interact(this.mode.$container);
|
64
|
+
this.interact.gesturable({
|
65
|
+
listeners: {
|
66
|
+
start: this._pinchStart,
|
67
|
+
end: this._pinchEnd,
|
68
|
+
},
|
69
|
+
});
|
70
|
+
if (isSamsungInternet()) {
|
71
|
+
// Samsung internet pinch-zoom will not work unless we disable
|
72
|
+
// all touch actions. So use interact.js' built-in drag support
|
73
|
+
// to handle moving on that browser.
|
74
|
+
this.mode.$container.style.touchAction = "none";
|
75
|
+
this.interact
|
76
|
+
.draggable({
|
77
|
+
inertia: {
|
78
|
+
resistance: 2,
|
79
|
+
minSpeed: 100,
|
80
|
+
allowResume: true,
|
81
|
+
},
|
82
|
+
listeners: { move: this._dragMove },
|
83
|
+
});
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
this.attached = true;
|
88
|
+
}
|
89
|
+
|
90
|
+
detach() {
|
91
|
+
this.detachCtrlZoom();
|
92
|
+
|
93
|
+
// GestureEvents work only on Safari; they interfere with Hammer,
|
94
|
+
// so block them.
|
95
|
+
this.mode.$container.removeEventListener('gesturestart', this._pinchStart);
|
96
|
+
this.mode.$container.removeEventListener('gesturechange', this._preventEvent);
|
97
|
+
this.mode.$container.removeEventListener('gestureend', this._pinchEnd);
|
98
|
+
|
99
|
+
this.touchesMonitor?.detach?.();
|
100
|
+
|
101
|
+
// The pinch listeners
|
102
|
+
this.interact.unset();
|
103
|
+
interact.removeDocument(document);
|
104
|
+
|
105
|
+
this.attached = false;
|
106
|
+
}
|
107
|
+
|
108
|
+
/** @param {Event} ev */
|
109
|
+
_preventEvent = (ev) => {
|
110
|
+
ev.preventDefault();
|
111
|
+
return false;
|
112
|
+
}
|
113
|
+
|
114
|
+
_pinchStart = async () => {
|
115
|
+
// Safari calls gesturestart twice!
|
116
|
+
if (this.pinching) return;
|
117
|
+
if (isIOS()) {
|
118
|
+
// Safari sometimes causes a pinch to trigger when there's only one touch!
|
119
|
+
await sleep(0); // touches monitor can receive the touch event late
|
120
|
+
if (this.touchesMonitor.touches < 2) return;
|
121
|
+
}
|
122
|
+
this.pinching = true;
|
123
|
+
|
124
|
+
// Do this in case the pinchend hasn't fired yet.
|
125
|
+
this.oldScale = 1;
|
126
|
+
this.mode.$visibleWorld.classList.add("BRsmooth-zooming");
|
127
|
+
this.mode.$visibleWorld.style.willChange = "transform";
|
128
|
+
this.mode.autoFit = "none";
|
129
|
+
this.detachCtrlZoom();
|
130
|
+
this.mode.detachScrollListeners?.();
|
131
|
+
|
132
|
+
this.interact.gesturable({
|
133
|
+
listeners: {
|
134
|
+
start: this._pinchStart,
|
135
|
+
move: this._pinchMove,
|
136
|
+
end: this._pinchEnd,
|
137
|
+
},
|
138
|
+
});
|
139
|
+
}
|
140
|
+
|
141
|
+
/** @param {{ scale: number, clientX: number, clientY: number }}} e */
|
142
|
+
_pinchMove = async (e) => {
|
143
|
+
if (!this.pinching) return;
|
144
|
+
this.lastEvent = {
|
145
|
+
scale: e.scale,
|
146
|
+
clientX: e.clientX,
|
147
|
+
clientY: e.clientY,
|
148
|
+
};
|
149
|
+
if (!this.pinchMoveFrame) {
|
150
|
+
// Buffer these events; only update the scale when request animation fires
|
151
|
+
this.pinchMoveFrame = this.bufferFn(this._drawPinchZoomFrame);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
_pinchEnd = async () => {
|
156
|
+
if (!this.pinching) return;
|
157
|
+
this.pinching = false;
|
158
|
+
this.interact.gesturable({
|
159
|
+
listeners: {
|
160
|
+
start: this._pinchStart,
|
161
|
+
end: this._pinchEnd,
|
162
|
+
},
|
163
|
+
});
|
164
|
+
// Want this to happen after the pinchMoveFrame,
|
165
|
+
// if one is in progress; otherwise setting oldScale
|
166
|
+
// messes up the transform.
|
167
|
+
await this.pinchMoveFramePromise;
|
168
|
+
this.scaleCenter = { x: 0.5, y: 0.5 };
|
169
|
+
this.oldScale = 1;
|
170
|
+
this.mode.$visibleWorld.classList.remove("BRsmooth-zooming");
|
171
|
+
this.mode.$visibleWorld.style.willChange = "auto";
|
172
|
+
this.attachCtrlZoom();
|
173
|
+
this.mode.attachScrollListeners?.();
|
174
|
+
}
|
175
|
+
|
176
|
+
_drawPinchZoomFrame = async () => {
|
177
|
+
// Because of the buffering/various timing locks,
|
178
|
+
// this can be called after the pinch has ended, which
|
179
|
+
// results in a janky zoom after the pinch.
|
180
|
+
if (!this.pinching) {
|
181
|
+
this.pinchMoveFrame = null;
|
182
|
+
return;
|
183
|
+
}
|
184
|
+
|
185
|
+
this.mode.$container.style.overflow = "hidden";
|
186
|
+
this.pinchMoveFramePromiseRes = null;
|
187
|
+
this.pinchMoveFramePromise = new Promise(
|
188
|
+
(res) => (this.pinchMoveFramePromiseRes = res),
|
189
|
+
);
|
190
|
+
this.updateScaleCenter({
|
191
|
+
clientX: this.lastEvent.clientX,
|
192
|
+
clientY: this.lastEvent.clientY,
|
193
|
+
});
|
194
|
+
const curScale = this.mode.scale;
|
195
|
+
const newScale = curScale * this.lastEvent.scale / this.oldScale;
|
196
|
+
|
197
|
+
if (curScale != newScale) {
|
198
|
+
this.mode.scale = newScale;
|
199
|
+
await this.pinchMoveFramePromise;
|
200
|
+
}
|
201
|
+
this.mode.$container.style.overflow = "auto";
|
202
|
+
this.oldScale = this.lastEvent.scale;
|
203
|
+
this.pinchMoveFrame = null;
|
204
|
+
}
|
205
|
+
|
206
|
+
_dragMove = async (e) => {
|
207
|
+
if (this.pinching) {
|
208
|
+
await this._pinchEnd();
|
209
|
+
}
|
210
|
+
this.mode.$container.scrollTop -= e.dy;
|
211
|
+
this.mode.$container.scrollLeft -= e.dx;
|
212
|
+
}
|
213
|
+
|
214
|
+
/** @private */
|
215
|
+
attachCtrlZoom() {
|
216
|
+
window.addEventListener("wheel", this._handleCtrlWheel, { passive: false });
|
217
|
+
}
|
218
|
+
|
219
|
+
/** @private */
|
220
|
+
detachCtrlZoom() {
|
221
|
+
window.removeEventListener("wheel", this._handleCtrlWheel);
|
222
|
+
}
|
223
|
+
|
224
|
+
/** @param {WheelEvent} ev **/
|
225
|
+
_handleCtrlWheel = (ev) => {
|
226
|
+
if (!ev.ctrlKey) return;
|
227
|
+
ev.preventDefault();
|
228
|
+
const zoomMultiplier =
|
229
|
+
// Zooming on macs was painfully slow; likely due to their better
|
230
|
+
// trackpads. Give them a higher zoom rate.
|
231
|
+
/Mac/i.test(navigator.platform)
|
232
|
+
? 0.045
|
233
|
+
: // This worked well for me on Windows
|
234
|
+
0.03;
|
235
|
+
|
236
|
+
// Zoom around the cursor
|
237
|
+
this.updateScaleCenter(ev);
|
238
|
+
this.mode.autoFit = "none";
|
239
|
+
this.mode.scale *= 1 - Math.sign(ev.deltaY) * zoomMultiplier;
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
* @param {object} param0
|
244
|
+
* @param {number} param0.clientX
|
245
|
+
* @param {number} param0.clientY
|
246
|
+
*/
|
247
|
+
updateScaleCenter({ clientX, clientY }) {
|
248
|
+
const bc = this.mode.htmlDimensionsCacher.boundingClientRect;
|
249
|
+
this.scaleCenter = {
|
250
|
+
x: (clientX - bc.left) / this.mode.htmlDimensionsCacher.clientWidth,
|
251
|
+
y: (clientY - bc.top) / this.mode.htmlDimensionsCacher.clientHeight,
|
252
|
+
};
|
253
|
+
}
|
254
|
+
|
255
|
+
/**
|
256
|
+
* @param {number} newScale
|
257
|
+
* @param {number} oldScale
|
258
|
+
*/
|
259
|
+
updateViewportOnZoom(newScale, oldScale) {
|
260
|
+
const container = this.mode.$container;
|
261
|
+
const { scrollTop: T, scrollLeft: L } = container;
|
262
|
+
const W = this.mode.htmlDimensionsCacher.clientWidth;
|
263
|
+
const H = this.mode.htmlDimensionsCacher.clientHeight;
|
264
|
+
|
265
|
+
// Scale factor change
|
266
|
+
const F = newScale / oldScale;
|
267
|
+
|
268
|
+
// Where in the viewport the zoom is centered on
|
269
|
+
const XPOS = this.scaleCenter.x;
|
270
|
+
const YPOS = this.scaleCenter.y;
|
271
|
+
const oldCenter = {
|
272
|
+
x: L + XPOS * W,
|
273
|
+
y: T + YPOS * H,
|
274
|
+
};
|
275
|
+
const newCenter = {
|
276
|
+
x: F * oldCenter.x,
|
277
|
+
y: F * oldCenter.y,
|
278
|
+
};
|
279
|
+
|
280
|
+
container.scrollTop = newCenter.y - YPOS * H;
|
281
|
+
container.scrollLeft = newCenter.x - XPOS * W;
|
282
|
+
this.pinchMoveFramePromiseRes?.();
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
export class TouchesMonitor {
|
287
|
+
/**
|
288
|
+
* @param {HTMLElement} container
|
289
|
+
*/
|
290
|
+
constructor(container) {
|
291
|
+
/** @type {HTMLElement} */
|
292
|
+
this.container = container;
|
293
|
+
this.touches = 0;
|
294
|
+
}
|
295
|
+
|
296
|
+
attach() {
|
297
|
+
this.container.addEventListener("touchstart", this._updateTouchCount);
|
298
|
+
this.container.addEventListener("touchend", this._updateTouchCount);
|
299
|
+
}
|
300
|
+
|
301
|
+
detach() {
|
302
|
+
this.container.removeEventListener("touchstart", this._updateTouchCount);
|
303
|
+
this.container.removeEventListener("touchend", this._updateTouchCount);
|
304
|
+
}
|
305
|
+
|
306
|
+
/**
|
307
|
+
* @param {TouchEvent} ev
|
308
|
+
*/
|
309
|
+
_updateTouchCount = (ev) => {
|
310
|
+
this.touches = ev.touches.length;
|
311
|
+
}
|
312
|
+
}
|
@@ -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 */
|
@@ -131,7 +132,7 @@ export class ModeThumb {
|
|
131
132
|
for (let i = 1; i < this.br.thumbRowBuffer; i++) {
|
132
133
|
if (firstRow - i >= 0) { rowsToDisplay.push(firstRow - i); }
|
133
134
|
}
|
134
|
-
rowsToDisplay.sort();
|
135
|
+
rowsToDisplay.sort((a, b) => a - b);
|
135
136
|
|
136
137
|
// Create the thumbnail divs and images (lazy loaded)
|
137
138
|
for (const row of rowsToDisplay) {
|
@@ -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 */
|
@@ -274,12 +280,12 @@ export class ModeThumb {
|
|
274
280
|
this.br.refs.$brContainer.empty();
|
275
281
|
this.br.refs.$brContainer.css({
|
276
282
|
overflowY: 'scroll',
|
277
|
-
overflowX: 'auto'
|
283
|
+
overflowX: 'auto',
|
278
284
|
});
|
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
|
/**
|
@@ -21,12 +22,14 @@ export class Navbar {
|
|
21
22
|
|
22
23
|
/** @type {Object} controls will be switch over "this.maximumControls" */
|
23
24
|
this.minimumControls = [
|
24
|
-
'viewmode'
|
25
|
+
'viewmode',
|
25
26
|
];
|
26
27
|
/** @type {Object} controls will be switch over "this.minimumControls" */
|
27
28
|
this.maximumControls = [
|
28
|
-
'book_left', 'book_right', 'zoom_in', 'zoom_out', 'onepg', 'twopg', 'thumb'
|
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) {
|
@@ -38,7 +41,7 @@ export class Navbar {
|
|
38
41
|
return `<li>
|
39
42
|
<button class="BRicon ${option.className}" title="${option.label}">
|
40
43
|
<div class="icon icon-${option.iconClassName}"></div>
|
41
|
-
<span class="
|
44
|
+
<span class="BRtooltip">${option.label}</span>
|
42
45
|
</button>
|
43
46
|
</li>`;
|
44
47
|
}
|
@@ -112,7 +115,7 @@ export class Navbar {
|
|
112
115
|
this.updateViewModeButton(
|
113
116
|
$button,
|
114
117
|
currentViewModeButton.className,
|
115
|
-
currentViewModeButton.title
|
118
|
+
currentViewModeButton.title,
|
116
119
|
);
|
117
120
|
});
|
118
121
|
}
|
@@ -127,7 +130,7 @@ export class Navbar {
|
|
127
130
|
.removeClass()
|
128
131
|
.addClass(`icon icon-${iconClass}`)
|
129
132
|
.end()
|
130
|
-
.find('.
|
133
|
+
.find('.BRtooltip')
|
131
134
|
.text(tooltipText);
|
132
135
|
}
|
133
136
|
|
@@ -135,16 +138,43 @@ export class Navbar {
|
|
135
138
|
* Switch navbar controls on mobile and desktop
|
136
139
|
*/
|
137
140
|
switchNavbarControls() {
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
+
if (this.br.refs.$brContainer.prop('clientWidth') < 640) {
|
142
|
+
this.showMinimumNavPageNum();
|
143
|
+
// we don't want navbar controls switching with liner-notes
|
144
|
+
if (this.br.options.bookType !== 'linerNotes') {
|
141
145
|
this.showMinimumNavbarControls();
|
142
|
-
}
|
146
|
+
}
|
147
|
+
} else {
|
148
|
+
this.showMaximumNavPageNum();
|
149
|
+
// we don't want navbar controls switching with liner-notes
|
150
|
+
if (this.br.options.bookType !== 'linerNotes') {
|
143
151
|
this.showMaximumNavbarControls();
|
144
152
|
}
|
145
153
|
}
|
146
154
|
}
|
147
155
|
|
156
|
+
/**
|
157
|
+
* Switch Book Nav page number display to minimum/mobile
|
158
|
+
*/
|
159
|
+
showMinimumNavPageNum() {
|
160
|
+
const minElement = document.querySelector('.BRcurrentpage.BRmin');
|
161
|
+
const maxElement = document.querySelector('.BRcurrentpage.BRmax');
|
162
|
+
|
163
|
+
if (minElement) minElement.classList.remove('hide');
|
164
|
+
if (maxElement) maxElement.classList.add('hide');
|
165
|
+
}
|
166
|
+
|
167
|
+
/**
|
168
|
+
* Switch Book Nav page number display to maximum/desktop
|
169
|
+
*/
|
170
|
+
showMaximumNavPageNum() {
|
171
|
+
const minElement = document.querySelector('.BRcurrentpage.BRmin');
|
172
|
+
const maxElement = document.querySelector('.BRcurrentpage.BRmax');
|
173
|
+
|
174
|
+
if (minElement) minElement.classList.add('hide');
|
175
|
+
if (maxElement) maxElement.classList.remove('hide');
|
176
|
+
}
|
177
|
+
|
148
178
|
/**
|
149
179
|
* Switch Book Navbar controls to minimised
|
150
180
|
* NOTE: only `this.minimumControls` and `this.maximumControls` switch on resize
|
@@ -200,7 +230,10 @@ export class Navbar {
|
|
200
230
|
<div class="BRpager"></div>
|
201
231
|
<div class="BRnavline"></div>
|
202
232
|
</div>
|
203
|
-
<p
|
233
|
+
<p>
|
234
|
+
<span class="BRcurrentpage BRmax"></span>
|
235
|
+
<span class="BRcurrentpage BRmin"></span>
|
236
|
+
</p>
|
204
237
|
</li>
|
205
238
|
${this._renderControls()}
|
206
239
|
</ul>
|
@@ -213,9 +246,9 @@ export class Navbar {
|
|
213
246
|
const $slider = this.$root.find('.BRpager').slider({
|
214
247
|
animate: true,
|
215
248
|
min: 0,
|
216
|
-
max: br.getNumLeafs() - 1,
|
249
|
+
max: br.book.getNumLeafs() - 1,
|
217
250
|
value: br.currentIndex(),
|
218
|
-
range: "min"
|
251
|
+
range: "min",
|
219
252
|
});
|
220
253
|
|
221
254
|
$slider.on('slide', (event, ui) => {
|
@@ -240,53 +273,25 @@ export class Navbar {
|
|
240
273
|
return this.$nav;
|
241
274
|
}
|
242
275
|
|
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
276
|
/**
|
273
277
|
* Returns the textual representation of the current page for the navbar
|
274
278
|
* @param {number} index
|
279
|
+
* @param {boolean} [useMaxFormat = false]
|
275
280
|
* @return {string}
|
276
281
|
*/
|
277
|
-
getNavPageNumString(index) {
|
282
|
+
getNavPageNumString(index, useMaxFormat = false) {
|
278
283
|
const { br } = this;
|
279
284
|
// 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();
|
285
|
+
const pageNum = br.book.getPageNum(index);
|
286
|
+
const pageType = br.book.getPageProp(index, 'pageType');
|
287
|
+
const numLeafs = br.book.getNumLeafs();
|
283
288
|
|
284
289
|
if (!this.maxPageNum) {
|
285
290
|
// Calculate Max page num (used for pagination display)
|
286
291
|
let maxPageNum = 0;
|
287
292
|
let pageNumVal;
|
288
293
|
for (let i = 0; i < numLeafs; i++) {
|
289
|
-
pageNumVal = br.getPageNum(i);
|
294
|
+
pageNumVal = parseFloat(br.book.getPageNum(i));
|
290
295
|
if (!isNaN(pageNumVal) && pageNumVal > maxPageNum) {
|
291
296
|
maxPageNum = pageNumVal;
|
292
297
|
}
|
@@ -294,7 +299,8 @@ export class Navbar {
|
|
294
299
|
this.maxPageNum = maxPageNum;
|
295
300
|
}
|
296
301
|
|
297
|
-
return getNavPageNumHtml(index, numLeafs, pageNum, pageType, this.maxPageNum);
|
302
|
+
return getNavPageNumHtml(index, numLeafs, pageNum, pageType, this.maxPageNum, useMaxFormat);
|
303
|
+
|
298
304
|
}
|
299
305
|
|
300
306
|
/**
|
@@ -302,7 +308,8 @@ export class Navbar {
|
|
302
308
|
* @param {number} index
|
303
309
|
*/
|
304
310
|
updateNavPageNum(index) {
|
305
|
-
this.$root.find('.BRcurrentpage').html(this.getNavPageNumString(index));
|
311
|
+
this.$root.find('.BRcurrentpage.BRmax').html(this.getNavPageNumString(index, true));
|
312
|
+
this.$root.find('.BRcurrentpage.BRmin').html(this.getNavPageNumString(index));
|
306
313
|
}
|
307
314
|
|
308
315
|
/**
|
@@ -322,18 +329,27 @@ export class Navbar {
|
|
322
329
|
* @param {number} index
|
323
330
|
* @param {number} numLeafs
|
324
331
|
* @param {number|string} pageNum
|
325
|
-
* @param {*} pageType
|
332
|
+
* @param {*} pageType - Deprecated
|
326
333
|
* @param {number} maxPageNum
|
334
|
+
* @param {boolean} [useMaxFormat = false]
|
327
335
|
* @return {string}
|
328
336
|
*/
|
329
|
-
export function getNavPageNumHtml(index, numLeafs, pageNum, pageType, maxPageNum) {
|
337
|
+
export function getNavPageNumHtml(index, numLeafs, pageNum, pageType, maxPageNum, useMaxFormat = false) {
|
330
338
|
const pageIsAsserted = pageNum[0] != 'n';
|
339
|
+
const pageIndex = index + 1;
|
340
|
+
|
341
|
+
if (!pageIsAsserted) {
|
342
|
+
pageNum = '—';
|
343
|
+
}
|
344
|
+
|
345
|
+
if (useMaxFormat === true) {
|
346
|
+
return `Page ${pageNum} (${pageIndex}/${numLeafs})`;
|
347
|
+
}
|
331
348
|
|
332
349
|
if (!pageIsAsserted) {
|
333
|
-
|
334
|
-
return `Page (${pageIndex} of ${numLeafs})`; // Page (8 of 10)
|
350
|
+
return `(${pageIndex} of ${numLeafs})`;
|
335
351
|
}
|
336
352
|
|
337
|
-
const bookLengthLabel = maxPageNum ? ` of ${maxPageNum}` : '';
|
338
|
-
return
|
353
|
+
const bookLengthLabel = (maxPageNum && parseFloat(pageNum)) ? ` of ${maxPageNum}` : '';
|
354
|
+
return `${pageNum}${bookLengthLabel}`;
|
339
355
|
}
|