@internetarchive/bookreader 5.0.0-9 → 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 +76 -11
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +404 -1125
- package/BookReader/BookReader.js +1 -1
- 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 -1
- package/BookReader/icons/2up.svg +1 -1
- package/BookReader/icons/advance.svg +1 -1
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -1
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -1
- package/BookReader/icons/fullscreen_exit.svg +1 -1
- package/BookReader/icons/hamburger.svg +1 -1
- package/BookReader/icons/left-arrow.svg +1 -1
- package/BookReader/icons/magnify-minus.svg +1 -1
- package/BookReader/icons/magnify-plus.svg +1 -1
- package/BookReader/icons/magnify.svg +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/play.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/icons/review.svg +1 -1
- package/BookReader/icons/thumbnails.svg +1 -1
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -1
- package/BookReader/images/BRicons.svg +3 -3
- package/BookReader/images/books_graphic.svg +1 -1
- package/BookReader/images/icon_book.svg +1 -1
- package/BookReader/images/icon_bookmark.svg +1 -1
- package/BookReader/images/icon_gear.svg +1 -1
- package/BookReader/images/icon_hamburger.svg +1 -1
- package/BookReader/images/icon_home.svg +1 -1
- package/BookReader/images/icon_info.svg +1 -1
- package/BookReader/images/icon_one_page.svg +1 -1
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.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_skip-ahead.svg +1 -1
- package/BookReader/images/icon_skip-back.svg +1 -1
- package/BookReader/images/icon_speaker.svg +1 -1
- package/BookReader/images/icon_speaker_open.svg +1 -1
- package/BookReader/images/icon_thumbnails.svg +1 -1
- package/BookReader/images/icon_toc.svg +1 -1
- package/BookReader/images/icon_two_pages.svg +1 -1
- package/BookReader/images/marker_chap-off.svg +1 -1
- package/BookReader/images/marker_chap-on.svg +1 -1
- package/BookReader/images/marker_srch-on.svg +1 -1
- package/BookReader/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 -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 +25 -1
- 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 -1
- 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 -1
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +2 -1
- 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 -1
- 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 +1 -1
- 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 -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 +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 +584 -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 +5 -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 +50 -28
- package/src/BookNavigator/search/search-results.js +24 -10
- 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 +544 -1078
- package/src/BookReaderPlugin.js +44 -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 -5
- 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 +16 -3
- package/src/css/_BRnav.scss +12 -42
- package/src/css/_BRpages.scss +170 -42
- package/src/css/_BRsearch.scss +68 -25
- 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 +1 -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 +151 -127
- package/src/plugins/search/utils.js +43 -0
- package/src/plugins/search/view.js +37 -59
- 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 → 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 +19 -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 -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/BookReader/plugins/plugin.mobile_nav.js +0 -2
- 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 -446
- 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/BookReader/DebugConsole.js +0 -54
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -376
- package/src/ItemNavigator/providers/sharing.js +0 -29
- 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/search/search-provider.test.js +0 -23
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- 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
@@ -8,7 +8,7 @@ if (!isMobile()) {
|
|
8
8
|
|
9
9
|
jQuery.extend(BookReader.defaultOptions, {
|
10
10
|
/** @type {boolean} */
|
11
|
-
enableVendorFullscreenPlugin: true
|
11
|
+
enableVendorFullscreenPlugin: true,
|
12
12
|
});
|
13
13
|
|
14
14
|
/** @override */
|
@@ -56,7 +56,7 @@ if (!isMobile()) {
|
|
56
56
|
$(document.body).append(cboxOverlay).append(cbox);
|
57
57
|
}
|
58
58
|
});
|
59
|
-
}
|
59
|
+
};
|
60
60
|
})(BookReader.prototype.init);
|
61
61
|
|
62
62
|
/**
|
@@ -92,7 +92,7 @@ if (!isMobile()) {
|
|
92
92
|
$(document).off('keyup' + EVENT_NAMESPACE);
|
93
93
|
|
94
94
|
this.isFullscreenActive = false;
|
95
|
-
this.updateBrClasses()
|
95
|
+
this.updateBrClasses();
|
96
96
|
|
97
97
|
this.resize();
|
98
98
|
this.refs.$brContainer.animate({ opacity: 1 }, 400, 'linear');
|
@@ -225,16 +225,16 @@ export function fullscreenAllowed() {
|
|
225
225
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenchange_event
|
226
226
|
*/
|
227
227
|
export function bindFullscreenChangeListener(
|
228
|
-
data, fullscreenchangeListener
|
228
|
+
data, fullscreenchangeListener,
|
229
229
|
) {
|
230
230
|
const event = 'fullscreenchange ';
|
231
231
|
const vendor_prefixes = [
|
232
232
|
'webkit',
|
233
233
|
'moz',
|
234
|
-
'ms'
|
234
|
+
'ms',
|
235
235
|
];
|
236
|
-
const all_events =
|
237
|
-
$(document).
|
236
|
+
const all_events = (event + vendor_prefixes.join(event) + event).trim();
|
237
|
+
$(document).on(all_events, data, fullscreenchangeListener);
|
238
238
|
}
|
239
239
|
|
240
240
|
/**
|
@@ -1,9 +1,7 @@
|
|
1
|
+
// @ts-check
|
1
2
|
/* global BookReader */
|
2
3
|
/**
|
3
4
|
* Plugin for Archive.org book search
|
4
|
-
* NOTE: This script must be loaded AFTER `plugin.mobile_nav.js`
|
5
|
-
* as it mutates mobile nav drawer
|
6
|
-
*
|
7
5
|
* Events fired at various points throughout search processing are published
|
8
6
|
* on the document DOM element. These can be subscribed to using jQuery's event
|
9
7
|
* binding method `$.fn.on`. All of the events are prefixed with a BookReader
|
@@ -23,7 +21,14 @@
|
|
23
21
|
* @event BookReader:SearchCanceled - When no results found. Receives
|
24
22
|
* `instance`
|
25
23
|
*/
|
24
|
+
import { poll } from '../../BookReader/utils.js';
|
25
|
+
import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
|
26
26
|
import SearchView from './view.js';
|
27
|
+
import { marshallSearchResults } from './utils.js';
|
28
|
+
/** @typedef {import('../../BookReader/PageContainer').PageContainer} PageContainer */
|
29
|
+
/** @typedef {import('../../BookReader/BookModel').PageIndex} PageIndex */
|
30
|
+
/** @typedef {import('../../BookReader/BookModel').LeafNum} LeafNum */
|
31
|
+
/** @typedef {import('../../BookReader/BookModel').PageNumString} PageNumString */
|
27
32
|
|
28
33
|
jQuery.extend(BookReader.defaultOptions, {
|
29
34
|
server: 'ia600609.us.archive.org',
|
@@ -31,7 +36,10 @@ jQuery.extend(BookReader.defaultOptions, {
|
|
31
36
|
subPrefix: '',
|
32
37
|
bookPath: '',
|
33
38
|
enableSearch: true,
|
39
|
+
searchInsideProtocol: 'https',
|
34
40
|
searchInsideUrl: '/fulltext/inside.php',
|
41
|
+
searchInsidePreTag: '{{{',
|
42
|
+
searchInsidePostTag: '}}}',
|
35
43
|
initialSearchTerm: null,
|
36
44
|
});
|
37
45
|
|
@@ -55,14 +63,20 @@ BookReader.prototype.setup = (function (super_) {
|
|
55
63
|
this._cancelSearch.bind(this);
|
56
64
|
this.cancelSearchRequest.bind(this);
|
57
65
|
|
58
|
-
|
59
|
-
this.
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
+
/** @type { {[pageIndex: number]: SearchInsideMatchBox[]} } */
|
67
|
+
this._searchBoxesByIndex = {};
|
68
|
+
|
69
|
+
if (this.enableSearch) {
|
70
|
+
this.searchView = new SearchView({
|
71
|
+
br: this,
|
72
|
+
searchCancelledCallback: () => {
|
73
|
+
this._cancelSearch();
|
74
|
+
this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });
|
75
|
+
},
|
76
|
+
});
|
77
|
+
} else {
|
78
|
+
this.searchView = null;
|
79
|
+
}
|
66
80
|
};
|
67
81
|
})(BookReader.prototype.setup);
|
68
82
|
|
@@ -70,11 +84,21 @@ BookReader.prototype.setup = (function (super_) {
|
|
70
84
|
BookReader.prototype.init = (function (super_) {
|
71
85
|
return function () {
|
72
86
|
super_.call(this);
|
73
|
-
|
74
|
-
|
87
|
+
if (!this.enableSearch) return;
|
88
|
+
|
89
|
+
this.searchView.init();
|
90
|
+
if (this.options.initialSearchTerm) {
|
91
|
+
/**
|
92
|
+
* this.search() take two parameter
|
93
|
+
* 1. this.options.initialSearchTerm - search term
|
94
|
+
* 2. {
|
95
|
+
* goToFirstResult: this.options.goToFirstResult,
|
96
|
+
* suppressFragmentChange: false // always want to change fragment in URL
|
97
|
+
* }
|
98
|
+
*/
|
75
99
|
this.search(
|
76
100
|
this.options.initialSearchTerm,
|
77
|
-
{ goToFirstResult: this.options.goToFirstResult, suppressFragmentChange:
|
101
|
+
{ goToFirstResult: this.options.goToFirstResult, suppressFragmentChange: false },
|
78
102
|
);
|
79
103
|
}
|
80
104
|
};
|
@@ -92,6 +116,25 @@ BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
92
116
|
};
|
93
117
|
})(BookReader.prototype.buildToolbarElement);
|
94
118
|
|
119
|
+
/** @override */
|
120
|
+
BookReader.prototype._createPageContainer = (function (super_) {
|
121
|
+
return function (index) {
|
122
|
+
const pageContainer = super_.call(this, index);
|
123
|
+
if (this.enableSearch && pageContainer.page && index in this._searchBoxesByIndex) {
|
124
|
+
const pageIndex = pageContainer.page.index;
|
125
|
+
const boxes = this._searchBoxesByIndex[pageIndex];
|
126
|
+
renderBoxesInPageContainerLayer(
|
127
|
+
'searchHiliteLayer',
|
128
|
+
boxes,
|
129
|
+
pageContainer.page,
|
130
|
+
pageContainer.$container[0],
|
131
|
+
boxes.map(b => `match-index-${b.matchIndex}`),
|
132
|
+
);
|
133
|
+
}
|
134
|
+
return pageContainer;
|
135
|
+
};
|
136
|
+
})(BookReader.prototype._createPageContainer);
|
137
|
+
|
95
138
|
/**
|
96
139
|
* @typedef {object} SearchOptions
|
97
140
|
* @property {boolean} goToFirstResult
|
@@ -106,7 +149,7 @@ BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
106
149
|
* @param {string} term
|
107
150
|
* @param {SearchOptions} overrides
|
108
151
|
*/
|
109
|
-
BookReader.prototype.search = function(term = '', overrides = {}) {
|
152
|
+
BookReader.prototype.search = async function(term = '', overrides = {}) {
|
110
153
|
/** @type {SearchOptions} */
|
111
154
|
const defaultOptions = {
|
112
155
|
goToFirstResult: false, /* jump to the first result (default=false) */
|
@@ -118,6 +161,7 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
118
161
|
};
|
119
162
|
const options = jQuery.extend({}, defaultOptions, overrides);
|
120
163
|
this.suppressFragmentChange = options.suppressFragmentChange;
|
164
|
+
this.searchCancelled = false;
|
121
165
|
|
122
166
|
// strip slashes, since this goes in the url
|
123
167
|
this.searchTerm = term.replace(/\//g, ' ');
|
@@ -132,7 +176,7 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
132
176
|
|
133
177
|
// Remove the port and userdir
|
134
178
|
const serverPath = this.server.replace(/:.+/, '');
|
135
|
-
const baseUrl =
|
179
|
+
const baseUrl = `${this.options.searchInsideProtocol}://${serverPath}${this.searchInsideUrl}?`;
|
136
180
|
|
137
181
|
// Remove subPrefix from end of path
|
138
182
|
let path = this.bookPath;
|
@@ -146,6 +190,8 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
146
190
|
doc: this.subPrefix,
|
147
191
|
path,
|
148
192
|
q: term,
|
193
|
+
pre_tag: this.options.searchInsidePreTag,
|
194
|
+
post_tag: this.options.searchInsidePostTag,
|
149
195
|
};
|
150
196
|
|
151
197
|
// NOTE that the API does not expect / (slashes) to be encoded. (%2F) won't work
|
@@ -153,13 +199,8 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
153
199
|
|
154
200
|
const url = `${baseUrl}${paramStr}`;
|
155
201
|
|
156
|
-
const
|
157
|
-
this.
|
158
|
-
window.BRSearchInProgress = () => {};
|
159
|
-
};
|
160
|
-
|
161
|
-
const processSearchResults = (searchInsideResults) => {
|
162
|
-
if (!this.searchXHR) {
|
202
|
+
const callSearchResultsCallback = (searchInsideResults) => {
|
203
|
+
if (this.searchCancelled) {
|
163
204
|
return;
|
164
205
|
}
|
165
206
|
const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;
|
@@ -167,6 +208,7 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
167
208
|
const hasCustomSuccess = typeof options.success === 'function';
|
168
209
|
|
169
210
|
if (responseHasError) {
|
211
|
+
console.error('Search Inside Response Error', searchInsideResults.error || 'matches.length == 0');
|
170
212
|
hasCustomError
|
171
213
|
? options.error.call(this, searchInsideResults, options)
|
172
214
|
: this.BRSearchCallbackError(searchInsideResults, options);
|
@@ -175,21 +217,17 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
175
217
|
? options.success.call(this, searchInsideResults, options)
|
176
218
|
: this.BRSearchCallback(searchInsideResults, options);
|
177
219
|
}
|
178
|
-
cleanup();
|
179
|
-
};
|
180
|
-
|
181
|
-
const beforeSend = (xhr) => {
|
182
|
-
this.searchXHR = xhr;
|
183
|
-
window.BRSearchInProgress = processSearchResults;
|
184
220
|
};
|
185
221
|
|
186
222
|
this.trigger('SearchStarted', { term: this.searchTerm, instance: this });
|
187
|
-
|
223
|
+
callSearchResultsCallback(await $.ajax({
|
188
224
|
url: url,
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
225
|
+
cache: true,
|
226
|
+
xhrFields: {
|
227
|
+
withCredentials: this.protected,
|
228
|
+
},
|
229
|
+
beforeSend: xhr => { this.searchXHR = xhr; },
|
230
|
+
}));
|
193
231
|
};
|
194
232
|
|
195
233
|
/**
|
@@ -201,21 +239,22 @@ BookReader.prototype._cancelSearch = function () {
|
|
201
239
|
this.searchView.clearSearchFieldAndResults(false);
|
202
240
|
this.searchTerm = '';
|
203
241
|
this.searchXHR = null;
|
242
|
+
this.searchCancelled = true;
|
204
243
|
this.searchResults = [];
|
205
|
-
|
206
|
-
}
|
244
|
+
};
|
207
245
|
|
208
246
|
/**
|
209
247
|
* External function to cancel search
|
210
248
|
* checks for term & xhr in flight before running
|
211
249
|
*/
|
212
250
|
BookReader.prototype.cancelSearchRequest = function () {
|
251
|
+
this.searchCancelled = true;
|
213
252
|
if (this.searchXHR !== null) {
|
214
253
|
this._cancelSearch();
|
215
254
|
this.searchView.toggleSearchPending();
|
216
255
|
this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });
|
217
256
|
}
|
218
|
-
}
|
257
|
+
};
|
219
258
|
|
220
259
|
/**
|
221
260
|
* @typedef {object} SearchInsideMatchBox
|
@@ -225,10 +264,14 @@ BookReader.prototype.cancelSearchRequest = function () {
|
|
225
264
|
* @property {number} b
|
226
265
|
* @property {number} t
|
227
266
|
* @property {HTMLDivElement} [div]
|
267
|
+
* @property {number} matchIndex This is a fake field! not part of the API response. The index of the match that contains this box in total search results matches.
|
228
268
|
*/
|
229
269
|
|
230
270
|
/**
|
231
271
|
* @typedef {object} SearchInsideMatch
|
272
|
+
* @property {number} matchIndex This is a fake field! Not part of the API response. It is added by the JS.
|
273
|
+
* @property {string} displayPageNumber (fake field) The page number as it should be displayed in the UI.
|
274
|
+
* @property {string} html (computed field) The html-escaped raw html to display in the UI.
|
232
275
|
* @property {string} text
|
233
276
|
* @property {Array<{ page: number, boxes: SearchInsideMatchBox[] }>} par
|
234
277
|
*/
|
@@ -242,22 +285,26 @@ BookReader.prototype.cancelSearchRequest = function () {
|
|
242
285
|
|
243
286
|
/**
|
244
287
|
* Search Results return handler
|
245
|
-
* @callback
|
246
288
|
* @param {SearchInsideResults} results
|
247
289
|
* @param {object} options
|
248
290
|
* @param {boolean} options.goToFirstResult
|
249
291
|
*/
|
250
292
|
BookReader.prototype.BRSearchCallback = function(results, options) {
|
293
|
+
marshallSearchResults(
|
294
|
+
results,
|
295
|
+
pageNum => this.book.getPageNum(this.book.leafNumToIndex(pageNum)),
|
296
|
+
this.options.searchInsidePreTag,
|
297
|
+
this.options.searchInsidePostTag,
|
298
|
+
);
|
251
299
|
this.searchResults = results || [];
|
252
300
|
|
253
301
|
this.updateSearchHilites();
|
254
302
|
this.removeProgressPopup();
|
255
303
|
if (options.goToFirstResult) {
|
256
|
-
|
257
|
-
this._searchPluginGoToResult(pageIndex);
|
304
|
+
this._searchPluginGoToResult(0);
|
258
305
|
}
|
259
306
|
this.trigger('SearchCallback', { results, options, instance: this });
|
260
|
-
}
|
307
|
+
};
|
261
308
|
|
262
309
|
/**
|
263
310
|
* Main search results error handler
|
@@ -297,95 +344,41 @@ BookReader.prototype._BRSearchCallbackError = function(results) {
|
|
297
344
|
* updates search on-page highlights controller
|
298
345
|
*/
|
299
346
|
BookReader.prototype.updateSearchHilites = function() {
|
300
|
-
|
301
|
-
|
302
|
-
|
347
|
+
/** @type {SearchInsideMatch[]} */
|
348
|
+
const matches = this.searchResults?.matches || [];
|
349
|
+
/** @type { {[pageIndex: number]: SearchInsideMatchBox[]} } */
|
350
|
+
const boxesByIndex = {};
|
351
|
+
|
352
|
+
// Clear any existing svg layers
|
353
|
+
this.removeSearchHilites();
|
354
|
+
|
355
|
+
// Group by pageIndex
|
356
|
+
for (const match of matches) {
|
357
|
+
for (const box of match.par[0].boxes) {
|
358
|
+
const pageIndex = this.book.leafNumToIndex(box.page);
|
359
|
+
const pageBoxes = boxesByIndex[pageIndex] || (boxesByIndex[pageIndex] = []);
|
360
|
+
pageBoxes.push(box);
|
361
|
+
}
|
303
362
|
}
|
304
|
-
this.updateSearchHilites1UP();
|
305
|
-
};
|
306
|
-
|
307
|
-
/**
|
308
|
-
* update search on-page highlights in 1up mode
|
309
|
-
*/
|
310
|
-
BookReader.prototype.updateSearchHilites1UP = function() {
|
311
|
-
const results = this.searchResults;
|
312
|
-
if (null == results) return;
|
313
|
-
results.matches?.forEach(match => {
|
314
|
-
match.par[0].boxes.forEach(box => {
|
315
|
-
const pageIndex = this.leafNumToIndex(box.page);
|
316
|
-
const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;
|
317
|
-
if (pageIsInView) {
|
318
|
-
if (!box.div) {
|
319
|
-
//create a div for the search highlight, and stash it in the box object
|
320
|
-
box.div = document.createElement('div');
|
321
|
-
$(box.div).prop('className', 'BookReaderSearchHilite').appendTo(this.$(`.pagediv${pageIndex}`));
|
322
|
-
}
|
323
|
-
const page = this._models.book.getPage(pageIndex);
|
324
|
-
const highlight = {
|
325
|
-
width: this._modes.mode1Up.physicalInchesToDisplayPixels((box.r - box.l) / page.ppi),
|
326
|
-
height: this._modes.mode1Up.physicalInchesToDisplayPixels((box.b - box.t) / page.ppi),
|
327
|
-
left: this._modes.mode1Up.physicalInchesToDisplayPixels(box.l / page.ppi),
|
328
|
-
top: this._modes.mode1Up.physicalInchesToDisplayPixels(box.t / page.ppi),
|
329
|
-
};
|
330
|
-
$(box.div).css(highlight);
|
331
|
-
} else {
|
332
|
-
if (box.div) {
|
333
|
-
$(box.div).remove();
|
334
|
-
box.div = null;
|
335
|
-
}
|
336
|
-
}
|
337
|
-
});
|
338
|
-
});
|
339
|
-
};
|
340
363
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
364
|
+
// update any already created pages
|
365
|
+
for (const [pageIndexString, boxes] of Object.entries(boxesByIndex)) {
|
366
|
+
const pageIndex = parseFloat(pageIndexString);
|
367
|
+
const page = this.book.getPage(pageIndex);
|
368
|
+
const pageContainers = this.getActivePageContainerElementsForIndex(pageIndex);
|
369
|
+
for (const container of pageContainers) {
|
370
|
+
renderBoxesInPageContainerLayer('searchHiliteLayer', boxes, page, container, boxes.map(b => `match-index-${b.matchIndex}`));
|
371
|
+
}
|
372
|
+
}
|
346
373
|
|
347
|
-
|
348
|
-
|
349
|
-
const { matches = [] } = results;
|
350
|
-
matches.forEach((match) => {
|
351
|
-
match.par[0].boxes.forEach(box => {
|
352
|
-
const pageIndex = this.leafNumToIndex(match.par[0].page);
|
353
|
-
const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;
|
354
|
-
const { isViewable } = this._models.book.getPage(pageIndex);
|
355
|
-
|
356
|
-
if (pageIsInView && isViewable) {
|
357
|
-
if (!box.div) {
|
358
|
-
//create a div for the search highlight, and stash it in the box object
|
359
|
-
box.div = document.createElement('div');
|
360
|
-
$(box.div).addClass('BookReaderSearchHilite')
|
361
|
-
.appendTo(this.refs.$brTwoPageView);
|
362
|
-
}
|
363
|
-
this.setHilightCss2UP(box.div, pageIndex, box.l, box.r, box.t, box.b);
|
364
|
-
} else {
|
365
|
-
// clear stale reference
|
366
|
-
if (box.div) {
|
367
|
-
$(box.div).remove();
|
368
|
-
box.div = null;
|
369
|
-
}
|
370
|
-
}
|
371
|
-
});
|
372
|
-
});
|
374
|
+
this._searchBoxesByIndex = boxesByIndex;
|
373
375
|
};
|
374
376
|
|
375
377
|
/**
|
376
378
|
* remove search highlights
|
377
379
|
*/
|
378
380
|
BookReader.prototype.removeSearchHilites = function() {
|
379
|
-
|
380
|
-
if (null == results || !results.matches) { return; }
|
381
|
-
results.matches.forEach(match => {
|
382
|
-
match.par[0].boxes.forEach(box => {
|
383
|
-
if (null != box.div) {
|
384
|
-
$(box.div).remove();
|
385
|
-
box.div = null;
|
386
|
-
}
|
387
|
-
});
|
388
|
-
});
|
381
|
+
$(this.getActivePageContainerElements()).find('.searchHiliteLayer').remove();
|
389
382
|
};
|
390
383
|
|
391
384
|
/**
|
@@ -393,11 +386,14 @@ BookReader.prototype.removeSearchHilites = function() {
|
|
393
386
|
* Goes to the page specified. If the page is not viewable, tries to load the page
|
394
387
|
* FIXME Most of this logic is IA specific, and should be less integrated into here
|
395
388
|
* or at least more configurable.
|
396
|
-
* @param {
|
389
|
+
* @param {number} matchIndex
|
397
390
|
*/
|
398
|
-
BookReader.prototype._searchPluginGoToResult = async function (
|
399
|
-
const
|
391
|
+
BookReader.prototype._searchPluginGoToResult = async function (matchIndex) {
|
392
|
+
const match = this.searchResults?.matches[matchIndex];
|
393
|
+
const book = this.book;
|
394
|
+
const pageIndex = book.leafNumToIndex(match.par[0].page);
|
400
395
|
const page = book.getPage(pageIndex);
|
396
|
+
const onNearbyPage = Math.abs(this.currentIndex() - pageIndex) < 3;
|
401
397
|
let makeUnviewableAtEnd = false;
|
402
398
|
if (!page.isViewable) {
|
403
399
|
const resp = await fetch('/services/bookreader/request_page?' + new URLSearchParams({
|
@@ -416,15 +412,43 @@ BookReader.prototype._searchPluginGoToResult = async function (pageIndex) {
|
|
416
412
|
book.getPage(pageIndex).makeViewable();
|
417
413
|
makeUnviewableAtEnd = true;
|
418
414
|
}
|
415
|
+
|
416
|
+
// Trigger an update of book
|
417
|
+
this._modes.mode1Up.mode1UpLit.updatePages();
|
418
|
+
if (this.activeMode == this._modes.mode1Up) {
|
419
|
+
await this._modes.mode1Up.mode1UpLit.updateComplete;
|
420
|
+
}
|
419
421
|
}
|
420
422
|
/* this updates the URL */
|
421
|
-
this.
|
422
|
-
|
423
|
+
if (!this._isIndexDisplayed(pageIndex)) {
|
424
|
+
this.suppressFragmentChange = false;
|
425
|
+
this.jumpToIndex(pageIndex);
|
426
|
+
}
|
423
427
|
|
424
428
|
// Reset it to unviewable if it wasn't resolved
|
425
429
|
if (makeUnviewableAtEnd) {
|
426
430
|
book.getPage(pageIndex).makeViewable(false);
|
427
431
|
}
|
432
|
+
|
433
|
+
// Scroll/flash in the ui
|
434
|
+
const $boxes = await poll(() => $(`rect.match-index-${match.matchIndex}`), { until: result => result.length > 0 });
|
435
|
+
if ($boxes.length) {
|
436
|
+
$boxes.css('animation', 'none');
|
437
|
+
$boxes[0].scrollIntoView({
|
438
|
+
// Only vertically center the highlight if we're in 1up or in full screen. In
|
439
|
+
// 2up, if we're not fullscreen, the whole body gets scrolled around to try to
|
440
|
+
// center the highlight 🙄 See:
|
441
|
+
// https://stackoverflow.com/questions/11039885/scrollintoview-causing-the-whole-page-to-move/11041376
|
442
|
+
// Note: nearest doesn't quite work great, because the ReadAloud toolbar is now
|
443
|
+
// full-width, and covers up the last line of the highlight.
|
444
|
+
block: this.constMode1up == this.mode || this.isFullscreenActive ? 'center' : 'nearest',
|
445
|
+
inline: 'center',
|
446
|
+
behavior: onNearbyPage ? 'smooth' : 'auto',
|
447
|
+
});
|
448
|
+
// wait for animation to start
|
449
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
450
|
+
$boxes.removeAttr("style");
|
451
|
+
}
|
428
452
|
};
|
429
453
|
|
430
454
|
/**
|
@@ -458,7 +482,7 @@ BookReader.prototype.searchHighlightVisible = function() {
|
|
458
482
|
|
459
483
|
results.matches.some(match => {
|
460
484
|
return match.par[0].boxes.some(box => {
|
461
|
-
const pageIndex = this.leafNumToIndex(box.page);
|
485
|
+
const pageIndex = this.book.leafNumToIndex(box.page);
|
462
486
|
if (jQuery.inArray(pageIndex, visiblePages) >= 0) {
|
463
487
|
return true;
|
464
488
|
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { escapeHTML, escapeRegExp } from '../../BookReader/utils.js';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @param {string} match
|
5
|
+
* @param {string} preTag
|
6
|
+
* @param {string} postTag
|
7
|
+
* @returns {string}
|
8
|
+
*/
|
9
|
+
export function renderMatch(match, preTag, postTag) {
|
10
|
+
// Search results are returned as a text blob with the hits wrapped in
|
11
|
+
// triple mustaches. Hits occasionally include text beyond the search
|
12
|
+
// term, so everything within the staches is captured and wrapped.
|
13
|
+
const preTagRe = escapeRegExp(escapeHTML(preTag));
|
14
|
+
const postTagRe = escapeRegExp(escapeHTML(postTag));
|
15
|
+
// [^] matches any character, including line breaks
|
16
|
+
const regex = new RegExp(`${preTagRe}([^]+?)${postTagRe}`, 'g');
|
17
|
+
return escapeHTML(match)
|
18
|
+
.replace(regex, '<mark>$1</mark>')
|
19
|
+
// Fix trailing hyphens. This over-corrects but is net useful.
|
20
|
+
.replace(/(\b)- /g, '$1');
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Attach some fields to search inside results
|
25
|
+
* @param {SearchInsideResults} results
|
26
|
+
* @param {(pageNum: LeafNum) => PageNumString} displayPageNumberFn
|
27
|
+
* @param {string} preTag
|
28
|
+
* @param {string} postTag
|
29
|
+
*/
|
30
|
+
export function marshallSearchResults(results, displayPageNumberFn, preTag, postTag) {
|
31
|
+
// Attach matchIndex to a few things to make it easier to identify
|
32
|
+
// an active/selected match
|
33
|
+
for (const [index, match] of results.matches.entries()) {
|
34
|
+
match.matchIndex = index;
|
35
|
+
match.displayPageNumber = displayPageNumberFn(match.par[0].page);
|
36
|
+
match.html = renderMatch(match.text, preTag, postTag);
|
37
|
+
for (const par of match.par) {
|
38
|
+
for (const box of par.boxes) {
|
39
|
+
box.matchIndex = index;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|