@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
@@ -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
|
@@ -20,8 +18,17 @@
|
|
20
18
|
* the book has not had OCR text indexed yet. Receives `instance`
|
21
19
|
* @event BookReader:SearchCallbackEmpty - When no results found. Receives
|
22
20
|
* `instance`
|
21
|
+
* @event BookReader:SearchCanceled - When no results found. Receives
|
22
|
+
* `instance`
|
23
23
|
*/
|
24
|
+
import { poll } from '../../BookReader/utils.js';
|
25
|
+
import { renderBoxesInPageContainerLayer } from '../../BookReader/PageContainer.js';
|
24
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 */
|
25
32
|
|
26
33
|
jQuery.extend(BookReader.defaultOptions, {
|
27
34
|
server: 'ia600609.us.archive.org',
|
@@ -29,7 +36,10 @@ jQuery.extend(BookReader.defaultOptions, {
|
|
29
36
|
subPrefix: '',
|
30
37
|
bookPath: '',
|
31
38
|
enableSearch: true,
|
39
|
+
searchInsideProtocol: 'https',
|
32
40
|
searchInsideUrl: '/fulltext/inside.php',
|
41
|
+
searchInsidePreTag: '{{{',
|
42
|
+
searchInsidePostTag: '}}}',
|
33
43
|
initialSearchTerm: null,
|
34
44
|
});
|
35
45
|
|
@@ -42,7 +52,6 @@ BookReader.prototype.setup = (function (super_) {
|
|
42
52
|
this.searchResults = null;
|
43
53
|
this.searchInsideUrl = options.searchInsideUrl;
|
44
54
|
this.enableSearch = options.enableSearch;
|
45
|
-
this.goToFirstResult = false;
|
46
55
|
|
47
56
|
// Base server used by some api calls
|
48
57
|
this.bookId = options.bookId;
|
@@ -50,11 +59,24 @@ BookReader.prototype.setup = (function (super_) {
|
|
50
59
|
this.subPrefix = options.subPrefix;
|
51
60
|
this.bookPath = options.bookPath;
|
52
61
|
|
53
|
-
|
54
|
-
this.
|
55
|
-
|
56
|
-
|
57
|
-
}
|
62
|
+
this.searchXHR = null;
|
63
|
+
this._cancelSearch.bind(this);
|
64
|
+
this.cancelSearchRequest.bind(this);
|
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
|
+
}
|
58
80
|
};
|
59
81
|
})(BookReader.prototype.setup);
|
60
82
|
|
@@ -62,28 +84,26 @@ BookReader.prototype.setup = (function (super_) {
|
|
62
84
|
BookReader.prototype.init = (function (super_) {
|
63
85
|
return function () {
|
64
86
|
super_.call(this);
|
65
|
-
|
66
|
-
|
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
|
+
*/
|
67
99
|
this.search(
|
68
100
|
this.options.initialSearchTerm,
|
69
|
-
{ goToFirstResult: this.goToFirstResult, suppressFragmentChange:
|
101
|
+
{ goToFirstResult: this.options.goToFirstResult, suppressFragmentChange: false },
|
70
102
|
);
|
71
103
|
}
|
72
104
|
};
|
73
105
|
})(BookReader.prototype.init);
|
74
106
|
|
75
|
-
/** @override */
|
76
|
-
BookReader.prototype.buildMobileDrawerElement = (function (super_) {
|
77
|
-
return function () {
|
78
|
-
const $el = super_.call(this);
|
79
|
-
if (!this.enableSearch) { return; }
|
80
|
-
if (this.searchView.dom.mobileSearch) {
|
81
|
-
$el.find('.BRmobileMenu__moreInfoRow').after(this.searchView.dom.mobileSearch);
|
82
|
-
}
|
83
|
-
return $el;
|
84
|
-
};
|
85
|
-
})(BookReader.prototype.buildMobileDrawerElement);
|
86
|
-
|
87
107
|
/** @override */
|
88
108
|
BookReader.prototype.buildToolbarElement = (function (super_) {
|
89
109
|
return function () {
|
@@ -96,6 +116,25 @@ BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
96
116
|
};
|
97
117
|
})(BookReader.prototype.buildToolbarElement);
|
98
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
|
+
|
99
138
|
/**
|
100
139
|
* @typedef {object} SearchOptions
|
101
140
|
* @property {boolean} goToFirstResult
|
@@ -110,7 +149,7 @@ BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
110
149
|
* @param {string} term
|
111
150
|
* @param {SearchOptions} overrides
|
112
151
|
*/
|
113
|
-
BookReader.prototype.search = function(term = '', overrides = {}) {
|
152
|
+
BookReader.prototype.search = async function(term = '', overrides = {}) {
|
114
153
|
/** @type {SearchOptions} */
|
115
154
|
const defaultOptions = {
|
116
155
|
goToFirstResult: false, /* jump to the first result (default=false) */
|
@@ -122,6 +161,7 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
122
161
|
};
|
123
162
|
const options = jQuery.extend({}, defaultOptions, overrides);
|
124
163
|
this.suppressFragmentChange = options.suppressFragmentChange;
|
164
|
+
this.searchCancelled = false;
|
125
165
|
|
126
166
|
// strip slashes, since this goes in the url
|
127
167
|
this.searchTerm = term.replace(/\//g, ' ');
|
@@ -136,7 +176,7 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
136
176
|
|
137
177
|
// Remove the port and userdir
|
138
178
|
const serverPath = this.server.replace(/:.+/, '');
|
139
|
-
const baseUrl =
|
179
|
+
const baseUrl = `${this.options.searchInsideProtocol}://${serverPath}${this.searchInsideUrl}?`;
|
140
180
|
|
141
181
|
// Remove subPrefix from end of path
|
142
182
|
let path = this.bookPath;
|
@@ -150,6 +190,8 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
150
190
|
doc: this.subPrefix,
|
151
191
|
path,
|
152
192
|
q: term,
|
193
|
+
pre_tag: this.options.searchInsidePreTag,
|
194
|
+
post_tag: this.options.searchInsidePostTag,
|
153
195
|
};
|
154
196
|
|
155
197
|
// NOTE that the API does not expect / (slashes) to be encoded. (%2F) won't work
|
@@ -157,12 +199,16 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
157
199
|
|
158
200
|
const url = `${baseUrl}${paramStr}`;
|
159
201
|
|
160
|
-
const
|
202
|
+
const callSearchResultsCallback = (searchInsideResults) => {
|
203
|
+
if (this.searchCancelled) {
|
204
|
+
return;
|
205
|
+
}
|
161
206
|
const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;
|
162
207
|
const hasCustomError = typeof options.error === 'function';
|
163
208
|
const hasCustomSuccess = typeof options.success === 'function';
|
164
209
|
|
165
210
|
if (responseHasError) {
|
211
|
+
console.error('Search Inside Response Error', searchInsideResults.error || 'matches.length == 0');
|
166
212
|
hasCustomError
|
167
213
|
? options.error.call(this, searchInsideResults, options)
|
168
214
|
: this.BRSearchCallbackError(searchInsideResults, options);
|
@@ -173,11 +219,41 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
173
219
|
}
|
174
220
|
};
|
175
221
|
|
176
|
-
this.trigger('SearchStarted', { term: this.searchTerm });
|
177
|
-
|
222
|
+
this.trigger('SearchStarted', { term: this.searchTerm, instance: this });
|
223
|
+
callSearchResultsCallback(await $.ajax({
|
178
224
|
url: url,
|
179
|
-
|
180
|
-
|
225
|
+
cache: true,
|
226
|
+
xhrFields: {
|
227
|
+
withCredentials: this.protected,
|
228
|
+
},
|
229
|
+
beforeSend: xhr => { this.searchXHR = xhr; },
|
230
|
+
}));
|
231
|
+
};
|
232
|
+
|
233
|
+
/**
|
234
|
+
* cancels AJAX Call
|
235
|
+
* emits custom event
|
236
|
+
*/
|
237
|
+
BookReader.prototype._cancelSearch = function () {
|
238
|
+
this.searchXHR?.abort();
|
239
|
+
this.searchView.clearSearchFieldAndResults(false);
|
240
|
+
this.searchTerm = '';
|
241
|
+
this.searchXHR = null;
|
242
|
+
this.searchCancelled = true;
|
243
|
+
this.searchResults = [];
|
244
|
+
};
|
245
|
+
|
246
|
+
/**
|
247
|
+
* External function to cancel search
|
248
|
+
* checks for term & xhr in flight before running
|
249
|
+
*/
|
250
|
+
BookReader.prototype.cancelSearchRequest = function () {
|
251
|
+
this.searchCancelled = true;
|
252
|
+
if (this.searchXHR !== null) {
|
253
|
+
this._cancelSearch();
|
254
|
+
this.searchView.toggleSearchPending();
|
255
|
+
this.trigger('SearchCanceled', { term: this.searchTerm, instance: this });
|
256
|
+
}
|
181
257
|
};
|
182
258
|
|
183
259
|
/**
|
@@ -188,10 +264,14 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
188
264
|
* @property {number} b
|
189
265
|
* @property {number} t
|
190
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.
|
191
268
|
*/
|
192
269
|
|
193
270
|
/**
|
194
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.
|
195
275
|
* @property {string} text
|
196
276
|
* @property {Array<{ page: number, boxes: SearchInsideMatchBox[] }>} par
|
197
277
|
*/
|
@@ -205,21 +285,26 @@ BookReader.prototype.search = function(term = '', overrides = {}) {
|
|
205
285
|
|
206
286
|
/**
|
207
287
|
* Search Results return handler
|
208
|
-
* @callback
|
209
288
|
* @param {SearchInsideResults} results
|
210
289
|
* @param {object} options
|
211
290
|
* @param {boolean} options.goToFirstResult
|
212
291
|
*/
|
213
292
|
BookReader.prototype.BRSearchCallback = function(results, options) {
|
214
|
-
|
293
|
+
marshallSearchResults(
|
294
|
+
results,
|
295
|
+
pageNum => this.book.getPageNum(this.book.leafNumToIndex(pageNum)),
|
296
|
+
this.options.searchInsidePreTag,
|
297
|
+
this.options.searchInsidePostTag,
|
298
|
+
);
|
299
|
+
this.searchResults = results || [];
|
215
300
|
|
216
301
|
this.updateSearchHilites();
|
217
302
|
this.removeProgressPopup();
|
218
303
|
if (options.goToFirstResult) {
|
219
|
-
this._searchPluginGoToResult(
|
304
|
+
this._searchPluginGoToResult(0);
|
220
305
|
}
|
221
306
|
this.trigger('SearchCallback', { results, options, instance: this });
|
222
|
-
}
|
307
|
+
};
|
223
308
|
|
224
309
|
/**
|
225
310
|
* Main search results error handler
|
@@ -259,95 +344,41 @@ BookReader.prototype._BRSearchCallbackError = function(results) {
|
|
259
344
|
* updates search on-page highlights controller
|
260
345
|
*/
|
261
346
|
BookReader.prototype.updateSearchHilites = function() {
|
262
|
-
|
263
|
-
|
264
|
-
|
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
|
+
}
|
265
362
|
}
|
266
|
-
this.updateSearchHilites1UP();
|
267
|
-
};
|
268
|
-
|
269
|
-
/**
|
270
|
-
* update search on-page highlights in 1up mode
|
271
|
-
*/
|
272
|
-
BookReader.prototype.updateSearchHilites1UP = function() {
|
273
|
-
const results = this.searchResults;
|
274
|
-
if (null == results) return;
|
275
|
-
results.matches.forEach(match => {
|
276
|
-
match.par[0].boxes.forEach(box => {
|
277
|
-
const pageIndex = this.leafNumToIndex(box.page);
|
278
|
-
const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;
|
279
|
-
if (pageIsInView) {
|
280
|
-
if (!box.div) {
|
281
|
-
//create a div for the search highlight, and stash it in the box object
|
282
|
-
box.div = document.createElement('div');
|
283
|
-
$(box.div).prop('className', 'BookReaderSearchHilite').appendTo(this.$(`.pagediv${pageIndex}`));
|
284
|
-
}
|
285
|
-
const page = this._models.book.getPage(pageIndex);
|
286
|
-
const highlight = {
|
287
|
-
width: this._modes.mode1Up.physicalInchesToDisplayPixels((box.r - box.l) / page.ppi),
|
288
|
-
height: this._modes.mode1Up.physicalInchesToDisplayPixels((box.b - box.t) / page.ppi),
|
289
|
-
left: this._modes.mode1Up.physicalInchesToDisplayPixels(box.l / page.ppi),
|
290
|
-
top: this._modes.mode1Up.physicalInchesToDisplayPixels(box.t / page.ppi),
|
291
|
-
};
|
292
|
-
$(box.div).css(highlight);
|
293
|
-
} else {
|
294
|
-
if (box.div) {
|
295
|
-
$(box.div).remove();
|
296
|
-
box.div = null;
|
297
|
-
}
|
298
|
-
}
|
299
|
-
});
|
300
|
-
});
|
301
|
-
};
|
302
363
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
+
}
|
308
373
|
|
309
|
-
|
310
|
-
|
311
|
-
const { matches } = results;
|
312
|
-
matches.forEach((match) => {
|
313
|
-
match.par[0].boxes.forEach(box => {
|
314
|
-
const pageIndex = this.leafNumToIndex(match.par[0].page);
|
315
|
-
const pageIsInView = jQuery.inArray(pageIndex, this.displayedIndices) >= 0;
|
316
|
-
const { isViewable } = this._models.book.getPage(pageIndex);
|
317
|
-
|
318
|
-
if (pageIsInView && isViewable) {
|
319
|
-
if (!box.div) {
|
320
|
-
//create a div for the search highlight, and stash it in the box object
|
321
|
-
box.div = document.createElement('div');
|
322
|
-
$(box.div).addClass('BookReaderSearchHilite')
|
323
|
-
.appendTo(this.refs.$brTwoPageView);
|
324
|
-
}
|
325
|
-
this.setHilightCss2UP(box.div, pageIndex, box.l, box.r, box.t, box.b);
|
326
|
-
} else {
|
327
|
-
// clear stale reference
|
328
|
-
if (box.div) {
|
329
|
-
$(box.div).remove();
|
330
|
-
box.div = null;
|
331
|
-
}
|
332
|
-
}
|
333
|
-
});
|
334
|
-
});
|
374
|
+
this._searchBoxesByIndex = boxesByIndex;
|
335
375
|
};
|
336
376
|
|
337
377
|
/**
|
338
378
|
* remove search highlights
|
339
379
|
*/
|
340
380
|
BookReader.prototype.removeSearchHilites = function() {
|
341
|
-
|
342
|
-
if (null == results || !results.matches) { return; }
|
343
|
-
results.matches.forEach(match => {
|
344
|
-
match.par[0].boxes.forEach(box => {
|
345
|
-
if (null != box.div) {
|
346
|
-
$(box.div).remove();
|
347
|
-
box.div = null;
|
348
|
-
}
|
349
|
-
});
|
350
|
-
});
|
381
|
+
$(this.getActivePageContainerElements()).find('.searchHiliteLayer').remove();
|
351
382
|
};
|
352
383
|
|
353
384
|
/**
|
@@ -355,11 +386,14 @@ BookReader.prototype.removeSearchHilites = function() {
|
|
355
386
|
* Goes to the page specified. If the page is not viewable, tries to load the page
|
356
387
|
* FIXME Most of this logic is IA specific, and should be less integrated into here
|
357
388
|
* or at least more configurable.
|
358
|
-
* @param {
|
389
|
+
* @param {number} matchIndex
|
359
390
|
*/
|
360
|
-
BookReader.prototype._searchPluginGoToResult = async function (
|
361
|
-
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);
|
362
395
|
const page = book.getPage(pageIndex);
|
396
|
+
const onNearbyPage = Math.abs(this.currentIndex() - pageIndex) < 3;
|
363
397
|
let makeUnviewableAtEnd = false;
|
364
398
|
if (!page.isViewable) {
|
365
399
|
const resp = await fetch('/services/bookreader/request_page?' + new URLSearchParams({
|
@@ -378,15 +412,43 @@ BookReader.prototype._searchPluginGoToResult = async function (pageIndex) {
|
|
378
412
|
book.getPage(pageIndex).makeViewable();
|
379
413
|
makeUnviewableAtEnd = true;
|
380
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
|
+
}
|
381
421
|
}
|
382
422
|
/* this updates the URL */
|
383
|
-
this.
|
384
|
-
|
423
|
+
if (!this._isIndexDisplayed(pageIndex)) {
|
424
|
+
this.suppressFragmentChange = false;
|
425
|
+
this.jumpToIndex(pageIndex);
|
426
|
+
}
|
385
427
|
|
386
428
|
// Reset it to unviewable if it wasn't resolved
|
387
429
|
if (makeUnviewableAtEnd) {
|
388
430
|
book.getPage(pageIndex).makeViewable(false);
|
389
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
|
+
}
|
390
452
|
};
|
391
453
|
|
392
454
|
/**
|
@@ -420,7 +482,7 @@ BookReader.prototype.searchHighlightVisible = function() {
|
|
420
482
|
|
421
483
|
results.matches.some(match => {
|
422
484
|
return match.par[0].boxes.some(box => {
|
423
|
-
const pageIndex = this.leafNumToIndex(box.page);
|
485
|
+
const pageIndex = this.book.leafNumToIndex(box.page);
|
424
486
|
if (jQuery.inArray(pageIndex, visiblePages) >= 0) {
|
425
487
|
return true;
|
426
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
|
+
}
|