r2-navigator-js
Version:
Readium 2 'navigator' for NodeJS (TypeScript)
1,149 lines (1,148 loc) • 137 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeCFI = exports.computeProgressionData = void 0;
var tslib_1 = require("tslib");
var debounce_1 = require("debounce");
var debug_ = require("debug");
var electron_1 = require("electron");
var tabbable_1 = require("tabbable");
var UrlUtils_1 = require("r2-utils-js/dist/es5/src/_utils/http/UrlUtils");
var sessions_1 = require("../../common/sessions");
var events_1 = require("../../common/events");
var readium_css_inject_1 = require("../../common/readium-css-inject");
var selection_1 = require("../../common/selection");
var styles_1 = require("../../common/styles");
var animateProperty_1 = require("../common/animateProperty");
var cssselector2_3_1 = require("../common/cssselector2-3");
var dom_text_utils_1 = require("../common/dom-text-utils");
var easings_1 = require("../common/easings");
var popup_dialog_1 = require("../common/popup-dialog");
var querystring_1 = require("../common/querystring");
var rect_utils_1 = require("../common/rect-utils");
var url_params_1 = require("../common/url-params");
var audiobook_1 = require("./audiobook");
var epubReadingSystem_1 = require("./epubReadingSystem");
var highlight_1 = require("./highlight");
var popoutImages_1 = require("./popoutImages");
var popupFootNotes_1 = require("./popupFootNotes");
var readaloud_1 = require("./readaloud");
var readium_css_1 = require("./readium-css");
var selection_2 = require("./selection");
var IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");
if (IS_DEV) {
var cr = require("../common/console-redirect");
cr.consoleRedirect("r2:navigator#electron/renderer/webview/preload", process.stdout, process.stderr, true);
}
var debug = debug_("r2:navigator#electron/renderer/webview/preload");
var INJECTED_LINK_TXT = "__";
var win = global.window;
win.READIUM2 = {
DEBUG_VISUALS: false,
fxlViewportHeight: 0,
fxlViewportScale: 1,
fxlViewportWidth: 0,
fxlZoomPercent: 0,
hashElement: null,
isAudio: false,
ignorekeyDownUpEvents: false,
isClipboardIntercept: false,
isFixedLayout: false,
locationHashOverride: undefined,
locationHashOverrideInfo: {
audioPlaybackInfo: undefined,
docInfo: undefined,
epubPage: undefined,
epubPageID: undefined,
headings: undefined,
href: "",
locations: {
cfi: undefined,
cssSelector: undefined,
position: undefined,
progression: undefined,
},
paginationInfo: undefined,
secondWebViewHref: undefined,
selectionInfo: undefined,
selectionIsNew: undefined,
title: undefined,
userInteract: false,
},
ttsClickEnabled: false,
ttsOverlayEnabled: false,
ttsPlaybackRate: 1,
ttsSkippabilityEnabled: false,
ttsSentenceDetectionEnabled: true,
ttsVoice: null,
urlQueryParams: win.location.search ? (0, querystring_1.getURLQueryParams)(win.location.search) : undefined,
webViewSlot: styles_1.WebViewSlotEnum.center,
};
win.alert = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log.apply(win, args);
};
win.confirm = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log.apply(win, args);
return false;
};
win.prompt = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log.apply(win, args);
return "";
};
var CSS_PIXEL_TOLERANCE = 5;
var TOUCH_SWIPE_DELTA_MIN = 80;
var TOUCH_SWIPE_LONG_PRESS_MAX_TIME = 500;
var TOUCH_SWIPE_MAX_TIME = 500;
var touchstartEvent;
var touchEventEnd;
win.document.addEventListener("touchstart", function (event) {
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
touchstartEvent = undefined;
touchEventEnd = undefined;
return;
}
if (event.changedTouches.length !== 1) {
return;
}
touchstartEvent = event;
}, true);
win.document.addEventListener("touchend", function (event) {
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
touchstartEvent = undefined;
touchEventEnd = undefined;
return;
}
if (event.changedTouches.length !== 1) {
return;
}
if (!touchstartEvent) {
return;
}
var startTouch = touchstartEvent.changedTouches[0];
var endTouch = event.changedTouches[0];
if (!startTouch || !endTouch) {
return;
}
var deltaX = (startTouch.clientX - endTouch.clientX) / win.devicePixelRatio;
var deltaY = (startTouch.clientY - endTouch.clientY) / win.devicePixelRatio;
if (Math.abs(deltaX) < TOUCH_SWIPE_DELTA_MIN &&
Math.abs(deltaY) < TOUCH_SWIPE_DELTA_MIN) {
if (touchEventEnd) {
touchstartEvent = undefined;
touchEventEnd = undefined;
return;
}
if (event.timeStamp - touchstartEvent.timeStamp >
TOUCH_SWIPE_LONG_PRESS_MAX_TIME) {
touchstartEvent = undefined;
touchEventEnd = undefined;
return;
}
touchstartEvent = undefined;
touchEventEnd = event;
return;
}
touchEventEnd = undefined;
if (event.timeStamp - touchstartEvent.timeStamp >
TOUCH_SWIPE_MAX_TIME) {
touchstartEvent = undefined;
return;
}
var slope = (startTouch.clientY - endTouch.clientY) /
(startTouch.clientX - endTouch.clientX);
if (Math.abs(slope) > 0.5) {
touchstartEvent = undefined;
return;
}
if (deltaX < 0) {
var payload = {
direction: "LTR",
go: "NEXT",
nav: true,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
}
else {
var payload = {
direction: "LTR",
go: "PREVIOUS",
nav: true,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
}
touchstartEvent = undefined;
}, true);
function keyDownUpEventHandler(ev, keyDown) {
if (win.READIUM2.ignorekeyDownUpEvents) {
return;
}
var elementName = (ev.target && ev.target.nodeName) ?
ev.target.nodeName : "";
var elementAttributes = {};
if (ev.target && ev.target.attributes) {
for (var i = 0; i < ev.target.attributes.length; i++) {
var attr = ev.target.attributes[i];
elementAttributes[attr.name] = attr.value;
}
}
var payload = {
altKey: ev.altKey,
code: ev.code,
ctrlKey: ev.ctrlKey,
elementAttributes: elementAttributes,
elementName: elementName,
key: ev.key,
metaKey: ev.metaKey,
shiftKey: ev.shiftKey,
};
electron_1.ipcRenderer.sendToHost(keyDown ? events_1.R2_EVENT_WEBVIEW_KEYDOWN : events_1.R2_EVENT_WEBVIEW_KEYUP, payload);
}
win.document.addEventListener("keydown", function (ev) {
keyDownUpEventHandler(ev, true);
}, {
capture: true,
once: false,
passive: false,
});
win.document.addEventListener("keyup", function (ev) {
keyDownUpEventHandler(ev, false);
}, {
capture: true,
once: false,
passive: false,
});
win.READIUM2.isAudio = win.location.protocol === "data:";
if (win.READIUM2.urlQueryParams) {
var readiumEpubReadingSystemJson = void 0;
var base64EpubReadingSystem = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_EPUBREADINGSYSTEM];
if (base64EpubReadingSystem) {
try {
var str = Buffer.from(base64EpubReadingSystem, "base64").toString("utf8");
readiumEpubReadingSystemJson = JSON.parse(str);
}
catch (err) {
debug(err);
}
}
if (readiumEpubReadingSystemJson) {
(0, epubReadingSystem_1.setWindowNavigatorEpubReadingSystem)(win, readiumEpubReadingSystemJson);
}
win.READIUM2.DEBUG_VISUALS = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_DEBUG_VISUALS] === "true";
win.READIUM2.isClipboardIntercept = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_CLIPBOARD_INTERCEPT] === "true";
win.READIUM2.webViewSlot =
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_WEBVIEW_SLOT] === "left" ? styles_1.WebViewSlotEnum.left :
(win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_WEBVIEW_SLOT] === "right" ? styles_1.WebViewSlotEnum.right :
styles_1.WebViewSlotEnum.center);
}
if (IS_DEV) {
electron_1.ipcRenderer.on(events_1.R2_EVENT_DEBUG_VISUALS, function (_event, payload) {
win.READIUM2.DEBUG_VISUALS = payload.debugVisuals;
if (!payload.debugVisuals) {
var existings = win.document.querySelectorAll("*[".concat(styles_1.readPosCssStylesAttr1, "], *[").concat(styles_1.readPosCssStylesAttr2, "], *[").concat(styles_1.readPosCssStylesAttr3, "], *[").concat(styles_1.readPosCssStylesAttr4, "]"));
existings.forEach(function (existing) {
existing.removeAttribute("".concat(styles_1.readPosCssStylesAttr1));
existing.removeAttribute("".concat(styles_1.readPosCssStylesAttr2));
existing.removeAttribute("".concat(styles_1.readPosCssStylesAttr3));
existing.removeAttribute("".concat(styles_1.readPosCssStylesAttr4));
});
}
if (payload.cssClass) {
if (_blacklistIdClassForCssSelectors.indexOf(payload.cssClass) < 0) {
_blacklistIdClassForCssSelectors.push(payload.cssClass.toLowerCase());
}
if (payload.debugVisuals && payload.cssStyles && payload.cssStyles.length) {
var idSuffix = "debug_for_class_".concat(payload.cssClass);
(0, readium_css_inject_1.appendCSSInline)(win.document, idSuffix, payload.cssStyles);
if (payload.cssSelector) {
var toHighlights = win.document.querySelectorAll(payload.cssSelector);
toHighlights.forEach(function (toHighlight) {
var clazz = "".concat(payload.cssClass);
if (!toHighlight.classList.contains(clazz)) {
toHighlight.classList.add(clazz);
}
});
}
}
else {
var existings = win.document.querySelectorAll(".".concat(payload.cssClass));
existings.forEach(function (existing) {
existing.classList.remove("".concat(payload.cssClass));
});
}
}
});
}
function computeVisibility_(element, domRect) {
if (win.READIUM2.isFixedLayout) {
return true;
}
else if (!win.document || !win.document.documentElement || !win.document.body) {
return false;
}
if (element === win.document.body || element === win.document.documentElement) {
return true;
}
var blacklisted = checkBlacklisted(element);
if (blacklisted) {
return false;
}
var elStyle = win.getComputedStyle(element);
if (elStyle) {
var display = elStyle.getPropertyValue("display");
if (display === "none") {
if (IS_DEV) {
debug("element DISPLAY NONE");
}
return false;
}
var opacity = elStyle.getPropertyValue("opacity");
if (opacity === "0") {
if (IS_DEV) {
debug("element OPACITY ZERO");
}
return false;
}
}
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
if (!(0, readium_css_inject_1.isPaginated)(win.document)) {
var rect = domRect || element.getBoundingClientRect();
if (rect.top >= 0 &&
rect.top <= win.document.documentElement.clientHeight) {
return true;
}
return false;
}
if ((0, readium_css_1.isVerticalWritingMode)()) {
return false;
}
var scrollLeftPotentiallyExcessive = getScrollOffsetIntoView(element, domRect);
var extraShift = scrollElement.scrollLeftExtra;
var currentOffset = scrollElement.scrollLeft;
if (extraShift) {
currentOffset += (((currentOffset < 0) ? -1 : 1) * extraShift);
}
if (scrollLeftPotentiallyExcessive >= (currentOffset - 10) &&
scrollLeftPotentiallyExcessive <= (currentOffset + 10)) {
return true;
}
return false;
}
function computeVisibility(location) {
var visible = false;
if (win.READIUM2.isAudio) {
visible = true;
}
else if (win.READIUM2.isFixedLayout) {
visible = true;
}
else if (!win.document || !win.document.documentElement || !win.document.body) {
visible = false;
}
else if (!location || !location.cssSelector) {
visible = false;
}
else {
var selected = null;
try {
selected = win.document.querySelector(location.cssSelector);
}
catch (err) {
debug(err);
}
if (selected) {
visible = computeVisibility_(selected, undefined);
}
}
return visible;
}
electron_1.ipcRenderer.on(events_1.R2_EVENT_LOCATOR_VISIBLE, function (_event, payload) {
payload.visible = computeVisibility(payload.location);
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_LOCATOR_VISIBLE, payload);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_SCROLLTO, function (_event, payload) {
if (win.READIUM2.isAudio) {
return;
}
showHideContentMask(false, win.READIUM2.isFixedLayout);
(0, selection_2.clearCurrentSelection)(win);
(0, popup_dialog_1.closePopupDialogs)(win.document);
if (!win.READIUM2.urlQueryParams) {
win.READIUM2.urlQueryParams = {};
}
if (payload.isSecondWebView) {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW] = "1";
}
else {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW] = "0";
}
if (payload.previous) {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_PREVIOUS] = "true";
}
else {
if (typeof win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_PREVIOUS] !== "undefined") {
delete win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_PREVIOUS];
}
}
if (payload.goto) {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO] = payload.goto;
}
else {
if (typeof win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO] !== "undefined") {
delete win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO];
}
}
if (payload.gotoDomRange) {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO_DOM_RANGE] = payload.gotoDomRange;
}
else {
if (typeof win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO_DOM_RANGE] !== "undefined") {
delete win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO_DOM_RANGE];
}
}
if (win.READIUM2.isFixedLayout) {
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
debug("processXYRaw BODY");
processXYRaw(0, 0, false);
notifyReadingLocationDebounced();
return;
}
var delayScrollIntoView = false;
if (payload.hash) {
debug(".hashElement = 1");
win.READIUM2.hashElement = win.document.getElementById(payload.hash);
if (win.READIUM2.DEBUG_VISUALS) {
if (win.READIUM2.hashElement) {
win.READIUM2.hashElement.setAttribute(styles_1.readPosCssStylesAttr1, "R2_EVENT_SCROLLTO hashElement");
}
}
win.location.href = "#" + payload.hash;
delayScrollIntoView = true;
}
else {
win.location.href = "#";
win.READIUM2.hashElement = null;
}
win.READIUM2.locationHashOverride = undefined;
resetLocationHashOverrideInfo();
if (delayScrollIntoView) {
setTimeout(function () {
debug("++++ scrollToHashRaw FROM DELAYED SCROLL_TO");
scrollToHashRaw(false);
}, 100);
}
else {
debug("++++ scrollToHashRaw FROM SCROLL_TO");
scrollToHashRaw(false);
}
});
function resetLocationHashOverrideInfo() {
win.READIUM2.locationHashOverrideInfo = {
audioPlaybackInfo: undefined,
docInfo: undefined,
epubPage: undefined,
epubPageID: undefined,
headings: undefined,
href: "",
locations: {
cfi: undefined,
cssSelector: undefined,
position: undefined,
progression: undefined,
},
paginationInfo: undefined,
secondWebViewHref: undefined,
selectionInfo: undefined,
selectionIsNew: undefined,
title: undefined,
userInteract: false,
};
}
var _lastAnimState;
function elementCapturesKeyboardArrowKeys(target) {
var curElement = target;
while (curElement && curElement.nodeType === Node.ELEMENT_NODE) {
var editable = curElement.getAttribute("contenteditable");
if (editable) {
return true;
}
var arrayOfKeyboardCaptureElements = ["input", "textarea", "video", "audio", "select"];
if (arrayOfKeyboardCaptureElements.indexOf(curElement.tagName.toLowerCase()) >= 0) {
return true;
}
curElement = curElement.parentNode;
}
return false;
}
function ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable() {
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var val = scrollElement.scrollLeftExtra;
if (val === 0) {
return 0;
}
scrollElement.scrollLeftExtra = 0;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHIFT_VIEW_X, { offset: 0, backgroundColor: undefined });
return val;
}
function ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable(scrollLeftExtra) {
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
scrollElement.scrollLeftExtra = scrollLeftExtra;
var scrollLeftExtraBackgroundColor = scrollElement.scrollLeftExtraBackgroundColor;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHIFT_VIEW_X, {
backgroundColor: scrollLeftExtraBackgroundColor ? scrollLeftExtraBackgroundColor : undefined,
offset: ((0, readium_css_1.isRTL)() ? 1 : -1) * scrollLeftExtra,
});
}
function ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffset, maxScrollShift) {
if (!win || !win.document || !win.document.body || !win.document.documentElement) {
return;
}
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var dialogPopup = (0, popup_dialog_1.isPopupDialogOpen)(win.document);
if (dialogPopup) {
var diagEl = win.document.getElementById(styles_1.POPUP_DIALOG_CLASS);
if (diagEl) {
var isCollapsed = diagEl.classList.contains(styles_1.POPUP_DIALOG_CLASS_COLLAPSE);
if (isCollapsed) {
dialogPopup = false;
}
}
}
var noChange = dialogPopup ||
!(0, readium_css_inject_1.isPaginated)(win.document) ||
!(0, readium_css_1.isTwoPageSpread)() ||
(0, readium_css_1.isVerticalWritingMode)() ||
maxScrollShift <= 0 ||
Math.abs(scrollOffset) <= maxScrollShift;
if (noChange) {
scrollElement.scrollLeftExtra = 0;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHIFT_VIEW_X, { offset: 0, backgroundColor: undefined });
return;
}
var extraOffset = Math.abs(scrollOffset) - maxScrollShift;
var backgroundColor;
var docStyle = win.getComputedStyle(win.document.documentElement);
if (docStyle) {
backgroundColor = docStyle.getPropertyValue("background-color");
}
if (!backgroundColor || backgroundColor === "transparent") {
var bodyStyle = win.getComputedStyle(win.document.body);
backgroundColor = bodyStyle.getPropertyValue("background-color");
if (backgroundColor === "transparent") {
backgroundColor = undefined;
}
}
scrollElement.scrollLeftExtra = extraOffset;
scrollElement.scrollLeftExtraBackgroundColor = backgroundColor;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHIFT_VIEW_X, {
backgroundColor: backgroundColor ? backgroundColor : undefined,
offset: ((0, readium_css_1.isRTL)() ? 1 : -1) * extraOffset,
});
}
function onEventPageTurn(payload) {
var leftRightKeyWasUsedInsideKeyboardCapture = false;
if (win.document.activeElement &&
elementCapturesKeyboardArrowKeys(win.document.activeElement)) {
if (win.document.hasFocus()) {
leftRightKeyWasUsedInsideKeyboardCapture = true;
}
else {
var oldDate = win.document.activeElement.r2_leftrightKeyboardTimeStamp;
if (oldDate) {
var newDate = new Date();
var msDiff = newDate.getTime() - oldDate.getTime();
if (msDiff <= 300) {
leftRightKeyWasUsedInsideKeyboardCapture = true;
}
}
}
}
if (leftRightKeyWasUsedInsideKeyboardCapture) {
return;
}
(0, selection_2.clearCurrentSelection)(win);
(0, popup_dialog_1.closePopupDialogs)(win.document);
if (win.READIUM2.isAudio || win.READIUM2.isFixedLayout || !win.document.body) {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
if (!win.document || !win.document.documentElement) {
return;
}
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var reduceMotion = win.document.documentElement.classList.contains(styles_1.ROOT_CLASS_REDUCE_MOTION);
var isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
var goPREVIOUS = payload.go === "PREVIOUS";
var animationTime = 300;
if (_lastAnimState && _lastAnimState.animating) {
win.cancelAnimationFrame(_lastAnimState.id);
_lastAnimState.object[_lastAnimState.property] = _lastAnimState.destVal;
}
if (!goPREVIOUS) {
var maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
var maxScrollShiftTolerated = maxScrollShift - CSS_PIXEL_TOLERANCE;
if (isPaged) {
var unit = (0, readium_css_1.isVerticalWritingMode)() ?
win.document.documentElement.offsetHeight :
win.document.documentElement.offsetWidth;
var scrollElementOffset = Math.round((0, readium_css_1.isVerticalWritingMode)() ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
var isNegative = scrollElementOffset < 0;
var scrollElementOffsetAbs = Math.abs(scrollElementOffset);
var fractional = scrollElementOffsetAbs / unit;
var integral = Math.floor(fractional);
var decimal = fractional - integral;
var partial = decimal * unit;
if (partial <= CSS_PIXEL_TOLERANCE) {
scrollElementOffset = (isNegative ? -1 : 1) * integral * unit;
}
else if (partial >= (unit - CSS_PIXEL_TOLERANCE)) {
scrollElementOffset = (isNegative ? -1 : 1) * (integral + 1) * unit;
}
if ((0, readium_css_1.isVerticalWritingMode)() && (scrollElementOffsetAbs < maxScrollShiftTolerated) ||
!(0, readium_css_1.isVerticalWritingMode)() && (scrollElementOffsetAbs < maxScrollShiftTolerated)) {
var scrollOffsetPotentiallyExcessive_ = (0, readium_css_1.isVerticalWritingMode)() ?
(scrollElementOffset + unit) :
(scrollElementOffset + ((0, readium_css_1.isRTL)() ? -1 : 1) * unit);
var nWholes = Math.floor(scrollOffsetPotentiallyExcessive_ / unit);
var scrollOffsetPotentiallyExcessive = nWholes * unit;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffsetPotentiallyExcessive, maxScrollShift);
var scrollOffset = (scrollOffsetPotentiallyExcessive < 0 ? -1 : 1) *
Math.min(Math.abs(scrollOffsetPotentiallyExcessive), maxScrollShift);
var targetObj = scrollElement;
var targetProp = (0, readium_css_1.isVerticalWritingMode)() ? "scrollTop" : "scrollLeft";
if (reduceMotion) {
_lastAnimState = undefined;
targetObj[targetProp] = scrollOffset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, function (_cancelled) {
_ignoreScrollEvent = false;
onScrollDebounced();
}, targetProp, animationTime, targetObj, scrollOffset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
payload.direction = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if ((0, readium_css_1.isVerticalWritingMode)() && (Math.abs(scrollElement.scrollLeft) < maxScrollShiftTolerated) ||
!(0, readium_css_1.isVerticalWritingMode)() && (Math.abs(scrollElement.scrollTop) < maxScrollShiftTolerated)) {
var newVal = (0, readium_css_1.isVerticalWritingMode)() ?
(scrollElement.scrollLeft + ((0, readium_css_1.isRTL)() ? -1 : 1) * win.document.documentElement.clientWidth) :
(scrollElement.scrollTop + win.document.documentElement.clientHeight);
var targetObj = scrollElement;
var targetProp = (0, readium_css_1.isVerticalWritingMode)() ? "scrollLeft" : "scrollTop";
if (reduceMotion) {
_lastAnimState = undefined;
targetObj[targetProp] = newVal;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, function (_cancelled) {
_ignoreScrollEvent = false;
onScrollDebounced();
}, targetProp, animationTime, targetObj, newVal, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
payload.direction = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
}
else if (goPREVIOUS) {
if (isPaged) {
var unit = (0, readium_css_1.isVerticalWritingMode)() ?
win.document.documentElement.offsetHeight :
win.document.documentElement.offsetWidth;
var scrollElementOffset = Math.round((0, readium_css_1.isVerticalWritingMode)() ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
var isNegative = scrollElementOffset < 0;
var scrollElementOffsetAbs = Math.abs(scrollElementOffset);
var fractional = scrollElementOffsetAbs / unit;
var integral = Math.floor(fractional);
var decimal = fractional - integral;
var partial = decimal * unit;
if (partial <= CSS_PIXEL_TOLERANCE) {
scrollElementOffset = (isNegative ? -1 : 1) * integral * unit;
}
else if (partial >= (unit - CSS_PIXEL_TOLERANCE)) {
scrollElementOffset = (isNegative ? -1 : 1) * (integral + 1) * unit;
}
if ((0, readium_css_1.isVerticalWritingMode)() && (scrollElementOffsetAbs > 0) ||
!(0, readium_css_1.isVerticalWritingMode)() && (scrollElementOffsetAbs > 0)) {
var scrollOffset_ = (0, readium_css_1.isVerticalWritingMode)() ?
(scrollElementOffset - unit) :
(scrollElementOffset - ((0, readium_css_1.isRTL)() ? -1 : 1) * unit);
var nWholes = (0, readium_css_1.isRTL)() ? Math.floor(scrollOffset_ / unit) : Math.ceil(scrollOffset_ / unit);
var scrollOffset = nWholes * unit;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffset, 0);
var targetObj = scrollElement;
var targetProp = (0, readium_css_1.isVerticalWritingMode)() ? "scrollTop" : "scrollLeft";
if (reduceMotion) {
_lastAnimState = undefined;
targetObj[targetProp] = scrollOffset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, function (_cancelled) {
_ignoreScrollEvent = false;
onScrollDebounced();
}, targetProp, animationTime, targetObj, scrollOffset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
payload.direction = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if ((0, readium_css_1.isVerticalWritingMode)() && (Math.abs(scrollElement.scrollLeft) > 0) ||
!(0, readium_css_1.isVerticalWritingMode)() && (Math.abs(scrollElement.scrollTop) > 0)) {
var newVal = (0, readium_css_1.isVerticalWritingMode)() ?
(scrollElement.scrollLeft - ((0, readium_css_1.isRTL)() ? -1 : 1) * win.document.documentElement.clientWidth) :
(scrollElement.scrollTop - win.document.documentElement.clientHeight);
var targetObj = scrollElement;
var targetProp = (0, readium_css_1.isVerticalWritingMode)() ? "scrollLeft" : "scrollTop";
if (reduceMotion) {
_lastAnimState = undefined;
targetObj[targetProp] = newVal;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, function (_cancelled) {
_ignoreScrollEvent = false;
onScrollDebounced();
}, targetProp, animationTime, targetObj, newVal, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
payload.direction = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
}
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
}
electron_1.ipcRenderer.on(events_1.R2_EVENT_PAGE_TURN, function (_event, payload) {
setTimeout(function () {
onEventPageTurn(payload);
}, 100);
});
function focusElement(element) {
if (element === win.document.body) {
var attr = element.getAttribute("tabindex");
if (!attr) {
element.setAttribute("tabindex", "-1");
element.classList.add(styles_1.CSS_CLASS_NO_FOCUS_OUTLINE);
if (IS_DEV) {
debug("tabindex -1 set BODY (focusable):");
debug(getCssSelector(element));
}
}
element.focus({ preventScroll: true });
}
else {
element.focus();
}
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_KEYBOARD_FOCUS_REQUEST, null);
if (IS_DEV) {
debug("KEYBOARD FOCUS REQUEST (1) ", getCssSelector(element));
}
}
var _lastAnimState2;
var animationTime2 = 400;
function scrollElementIntoView(element, doFocus, animate, domRect) {
if (win.READIUM2.DEBUG_VISUALS) {
var existings = win.document.querySelectorAll("*[".concat(styles_1.readPosCssStylesAttr3, "]"));
existings.forEach(function (existing) {
existing.removeAttribute("".concat(styles_1.readPosCssStylesAttr3));
});
element.setAttribute(styles_1.readPosCssStylesAttr3, "scrollElementIntoView");
}
if (win.READIUM2.isFixedLayout) {
debug("scrollElementIntoView_ SKIP FXL");
return;
}
if (doFocus) {
if (!domRect && !(0, tabbable_1.isFocusable)(element)) {
var attr = element.getAttribute("tabindex");
if (!attr) {
element.setAttribute("tabindex", "-1");
element.classList.add(styles_1.CSS_CLASS_NO_FOCUS_OUTLINE);
if (IS_DEV) {
debug("tabindex -1 set (focusable):");
debug(getCssSelector(element));
}
}
}
var targets = win.document.querySelectorAll(".".concat(styles_1.LINK_TARGET_CLASS));
targets.forEach(function (t) {
t.classList.remove(styles_1.LINK_TARGET_CLASS);
});
element.style.animation = "none";
void element.offsetWidth;
element.style.animation = "";
element.classList.add(styles_1.LINK_TARGET_CLASS);
if (element._timeoutTargetClass) {
clearTimeout(element._timeoutTargetClass);
element._timeoutTargetClass = undefined;
}
element._timeoutTargetClass = setTimeout(function () {
debug("ANIMATION TIMEOUT REMOVE");
element.classList.remove(styles_1.LINK_TARGET_CLASS);
}, 2000);
if (!domRect) {
focusElement(element);
}
}
setTimeout(function () {
var isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
if (isPaged) {
scrollIntoView(element, domRect);
}
else {
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var rect = domRect || element.getBoundingClientRect();
var scrollTopMax = scrollElement.scrollHeight - win.document.documentElement.clientHeight;
var offset = scrollElement.scrollTop + (rect.top - (win.document.documentElement.clientHeight / 2));
if (offset > scrollTopMax) {
offset = scrollTopMax;
}
else if (offset < 0) {
offset = 0;
}
var diff = Math.abs(scrollElement.scrollTop - offset);
if (diff < 10) {
return;
}
if (animate) {
var reduceMotion = win.document.documentElement.classList.contains(styles_1.ROOT_CLASS_REDUCE_MOTION);
if (_lastAnimState2 && _lastAnimState2.animating) {
win.cancelAnimationFrame(_lastAnimState2.id);
_lastAnimState2.object[_lastAnimState2.property] = _lastAnimState2.destVal;
}
var targetObj = scrollElement;
var targetProp = "scrollTop";
if (reduceMotion) {
_lastAnimState2 = undefined;
targetObj[targetProp] = offset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState2 = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, function (_cancelled) {
_ignoreScrollEvent = false;
onScrollDebounced();
}, targetProp, animationTime2, targetObj, offset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
}
else {
scrollElement.scrollTop = offset;
}
}
}, doFocus ? 100 : 0);
}
function getScrollOffsetIntoView(element, domRect) {
if (!win.document || !win.document.documentElement || !win.document.body ||
!(0, readium_css_inject_1.isPaginated)(win.document) || (0, readium_css_1.isVerticalWritingMode)()) {
return 0;
}
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var rect = domRect || element.getBoundingClientRect();
var columnDimension = (0, readium_css_1.calculateColumnDimension)();
var isTwoPage = (0, readium_css_1.isTwoPageSpread)();
var fullOffset = ((0, readium_css_1.isRTL)() ?
((columnDimension * (isTwoPage ? 2 : 1)) - (rect.left + rect.width)) :
rect.left) +
(((0, readium_css_1.isRTL)() ? -1 : 1) * scrollElement.scrollLeft);
var columnIndex = Math.floor(fullOffset / columnDimension);
var spreadIndex = isTwoPage ? Math.floor(columnIndex / 2) : columnIndex;
return ((0, readium_css_1.isRTL)() ? -1 : 1) *
(spreadIndex * (columnDimension * (isTwoPage ? 2 : 1)));
}
function scrollIntoView(element, domRect) {
if (!win.document || !win.document.documentElement || !win.document.body || !(0, readium_css_inject_1.isPaginated)(win.document)) {
return;
}
var maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
var scrollLeftPotentiallyExcessive = getScrollOffsetIntoView(element, domRect);
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollLeftPotentiallyExcessive, maxScrollShift);
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
var scrollOffset = (scrollLeftPotentiallyExcessive < 0 ? -1 : 1) *
Math.min(Math.abs(scrollLeftPotentiallyExcessive), maxScrollShift);
scrollElement.scrollLeft = scrollOffset;
}
var scrollToHashRaw = function (animate) {
if (!win.document || !win.document.body || !win.document.documentElement) {
return;
}
(0, highlight_1.recreateAllHighlights)(win);
debug("++++ scrollToHashRaw");
var isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
if (win.READIUM2.locationHashOverride) {
scrollElementIntoView(win.READIUM2.locationHashOverride, true, animate, undefined);
notifyReadingLocationDebounced();
return;
}
else if (win.READIUM2.hashElement) {
win.READIUM2.locationHashOverride = win.READIUM2.hashElement;
scrollElementIntoView(win.READIUM2.hashElement, true, animate, undefined);
notifyReadingLocationDebounced();
return;
}
else {
var scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
if (win.READIUM2.urlQueryParams) {
var previous = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_PREVIOUS];
var isPreviousNavDirection = previous === "true";
if (isPreviousNavDirection) {
var _a = (0, readium_css_1.calculateMaxScrollShift)(), maxScrollShift = _a.maxScrollShift, maxScrollShiftAdjusted = _a.maxScrollShiftAdjusted;
_ignoreScrollEvent = true;
if (isPaged) {
if ((0, readium_css_1.isVerticalWritingMode)()) {
scrollElement.scrollLeft = 0;
scrollElement.scrollTop = maxScrollShift;
}
else {
var scrollLeftPotentiallyExcessive = ((0, readium_css_1.isRTL)() ? -1 : 1) * maxScrollShiftAdjusted;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollLeftPotentiallyExcessive, maxScrollShift);
var scrollLeft = ((0, readium_css_1.isRTL)() ? -1 : 1) * maxScrollShift;
scrollElement.scrollLeft = scrollLeft;
scrollElement.scrollTop = 0;
}
}
else {
if ((0, readium_css_1.isVerticalWritingMode)()) {
scrollElement.scrollLeft = ((0, readium_css_1.isRTL)() ? -1 : 1) * maxScrollShift;
scrollElement.scrollTop = 0;
}
else {
scrollElement.scrollLeft = 0;
scrollElement.scrollTop = maxScrollShift;
}
}
win.READIUM2.locationHashOverride = undefined;
resetLocationHashOverrideInfo();
setTimeout(function () {
processXYRaw(0, 0, false);
showHideContentMask(false, win.READIUM2.isFixedLayout);
if (!win.READIUM2.locationHashOverride) {
notifyReadingLocationDebounced();
}
setTimeout(function () {
_ignoreScrollEvent = false;
}, 10);
}, 60);
return;
}
var gto = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO];
var gotoCssSelector = void 0;
var gotoProgression = void 0;
if (gto) {
var locStr = Buffer.from(gto, "base64").toString("utf8");
var locObj = JSON.parse(locStr);
gotoCssSelector = locObj.cssSelector;
gotoProgression = locObj.progression;
}
if (gotoCssSelector) {
gotoCssSelector = gotoCssSelector.replace(/\+/g, " ");
var selected = null;
try {
selected = win.document.querySelector(gotoCssSelector);
}
catch (err) {
debug(err);
}
if (selected) {
win.READIUM2.locationHashOverride = selected;
debug(".hashElement = 2");
win.READIUM2.hashElement = selected;
resetLocationHashOverrideInfo();
if (win.READIUM2.locationHashOverrideInfo) {
win.READIUM2.locationHashOverrideInfo.locations.cssSelector = gotoCssSelector;
}
var domRect = void 0;
var gtoDomRange = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO_DOM_RANGE];
if (gtoDomRange) {
try {
var rangeInfoStr = Buffer.from(gtoDomRange, "base64").toString("utf8");
var rangeInfo = JSON.parse(rangeInfoStr);
debug("rangeInfo", rangeInfo);
var domRange = (0, selection_2.convertRangeInfo)(win.document, rangeInfo);
if (domRange) {
domRect = domRange.getBoundingClientRect();
}
}
catch (err) {
debug("gtoDomRange", err);
}
}
scrollElementIntoView(selected, true, animate, domRect);
notifyReadingLocationDebounced();
return;
}
}
else if (gotoProgression) {
var maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
if (isPaged) {
var isTwoPage = (0, readium_css_1.isTwoPageSpread)();
var nColumns = (0, readium_css_1.calculateTotalColumns)();
var nUnits = isTwoPage ? Math.ceil(nColumns / 2) : nColumns;
var unitIndex = Math.floor(gotoProgression * nUnits);
var unit = (0, readium_css_1.isVerticalWritingMode)() ?
win.document.documentElement.offsetHeight :
win.document.documentElement.offsetWidth;
var scrollOffsetPotentiallyExcessive = (0, readium_css_1.isVerticalWritingMode)() ?
(unitIndex * unit) :
(((0, readium_css_1.isRTL)() ? -1 : 1) * unitIndex * unit);
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffsetPotentiallyExcessive, maxScrollShift);
var scrollOffsetPaged = (scrollOffsetPotentiallyExcessive < 0 ? -1 : 1) *
Math.min(Math.abs(scrollOffsetPotentiallyExcessive), maxScrollShift);
_ignoreScrollEvent = true;
if ((0, readium_css_1.isVerticalWritingMode)()) {
scrollElement.scrollTop = scrollOffsetPaged;
}
else {
scrollElement.scrollLeft = scrollOffsetPaged;
}
setTimeout(function () {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
focusElement(win.READIUM2.locationHashOverride);
processXYRaw(0, 0, false);
if (!win.READIUM2.locationHashOverride) {
notifyReadingLocationDebounced();
}
return;
}
var scrollOffset = gotoProgression * maxScrollShift;
_ignoreScrollEvent = true;
if ((0, readium_css_1.isVerticalWritingMode)()) {
scrollElement.scrollLeft = scrollOffset;
}
else {
scrollElement.scrollTop = scrollOffset;
}
setTimeout(function () {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
focusElement(win.READIUM2.locationHashOverride);
processXYRaw(0, 0, false);
if (!win.READIUM2.locationHashOverride) {
notifyReadingLocationDebounced();
}
return;
}
}
_ignoreScrollEvent = true;
scrollElement.scrollLeft = 0;
scrollElement.scrollTop = 0;
setTimeout(function () {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
focusElement(win.READIUM2.locationHashOverride);
debug("processXYRaw BODY");
processXYRaw(0, 0, false);
}
notifyReadingLocationDebounced();
};
var scrollToHashDebounced = (0, debounce_1.debounce)(function (animate) {
debug("++++ scrollToHashRaw FROM DEBOUNCED");
scrollToHashRaw(animate);
}, 100);
var _ignoreScrollEvent = false;
function showHideContentMask(doHide, isFixedLayout) {
if (doHide) {
win.document.documentElement.classList.add(styles_1.ROOT_CLASS_INVISIBLE_MASK);
win.document.documentElement.classList.remove(styles_1.ROOT_CLASS_INVISIBLE_MASK_REMOVED);
}
else {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHOW, null);
if (isFixedLayout) {
win.document.documentElement.classList.add(styles_1.ROOT_CLASS_INVISIBLE_MASK_REMOVED);
}
win.document.documentElement.classList.remove(styles_1.ROOT_CLASS_INVISIBLE_MASK);
}
}
function focusScrollRaw(el, doFocus, animate, domRect) {
scrollElementIntoView(el, doFocus, animate, domRect);
if (win.READIUM2.locationHashOverride === el) {
return;
}
var blacklisted = checkBlacklisted(el);
if (blacklisted) {
return;
}
debug(".hashElement = 3");
win.READIUM2.hashElement = doFocus ? el : win.READIUM2.hashElement;
win.READIUM2.locationHashOverride = el;
notifyReadingLocationDebounced();
}
var focusScrollDebounced = (0, debounce_1.debounce)(function (el, doFocus, animate, domRect) {
focusScrollRaw(el, doFocus, animate, domRect);
}, 100);
var handleFocusInDebounced = (0, debounce_1.debounce)(function (target, tabKeyDownEvent) {
handleFocusInRaw(target, tabKeyDownEvent);
}, 100);
function handleFocusInRaw(target, _tabKeyDownEvent) {
if (!target || !win.document.body) {
return;
}
focusScrollRaw(target, false, false, undefined);
}
electron_1.ipcRenderer.on(events_1.R2_EVENT_READIUMCSS, function (_event, payload) {
showHideContentMask(true, payload.isFixedLayout || win.READIUM2.isFixedLayout);
(0, readium_css_1.readiumCSS)(win.document, payload);
(0, highlight_1.recreateAllHighlights)(win);
showHideContentMask(false, payload.isFixedLayout || win.READIUM2.isFixedLayout);
});
var _docTitle;
win.addEventListener("DOMContentLoaded", function () {
debug("############# DOMContentLoaded");
var titleElement = win.document.documentElement.querySelector("head > title");
if (titleElement && titleElement.textContent) {
_docTitle = titleElement.textContent;
}
if (!win.READIUM2.isAudio &&
win.location.hash && win.location.hash.length > 1) {
debug(".hashElement = 4");
win.READIUM2.hashElement = win.document.getElementById(win.location.hash.substr(1));
if (win.READIUM2.DEBUG_VISUALS) {
if (win.READIUM2.hashElement) {
win.READIUM2.hashElement.setAttribute(styles_1.readPosCssStylesAttr1, "DOMContentLoaded hashElement");
}
}
}
win.READIUM2.locationHashOverride = undefined;
win.READIUM2.ttsClickEnabled = false;
win.READIUM2.ttsSkippabilityEnabled = false;
win.READIUM2.ttsSentenceDetectionEnabled = true;
win.READIUM2.ttsOverlayEnabled = false;
var readiumcssJson;
if (win.READIUM2.urlQueryParams) {
var base64ReadiumCSS = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_CSS];
if (base64ReadiumCSS) {
var str = void 0;