r2-navigator-js
Version:
Readium 2 'navigator' for NodeJS (TypeScript)
3,750 lines • 174 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const debounce = require("debounce");
const debug_ = require("debug");
const electron_1 = require("electron");
const tabbable_1 = require("tabbable");
const styles_1 = require("../../common/styles");
const UrlUtils_1 = require("r2-utils-js/dist/es8-es2017/src/_utils/http/UrlUtils");
const sessions_1 = require("../../common/sessions");
const events_1 = require("../../common/events");
const highlight_1 = require("../../common/highlight");
const readium_css_inject_1 = require("../../common/readium-css-inject");
const selection_1 = require("../../common/selection");
const styles_2 = require("../../common/styles");
const animateProperty_1 = require("../common/animateProperty");
const cssselector3_1 = require("../common/cssselector3");
const dom_text_utils_1 = require("../common/dom-text-utils");
const easings_1 = require("../common/easings");
const popup_dialog_1 = require("../common/popup-dialog");
const querystring_1 = require("../common/querystring");
const rect_utils_1 = require("../common/rect-utils");
const url_params_1 = require("../common/url-params");
const audiobook_1 = require("./audiobook");
const epubReadingSystem_1 = require("./epubReadingSystem");
const highlight_2 = require("./highlight");
const popoutImages_1 = require("./popoutImages");
const popupFootNotes_1 = require("./popupFootNotes");
const readaloud_1 = require("./readaloud");
const readium_css_1 = require("./readium-css");
const selection_2 = require("./selection");
const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");
const DEBUG_TRACE = true && IS_DEV;
if (IS_DEV) {
const cr = require("../common/console-redirect");
cr.consoleRedirect("r2:navigator#electron/renderer/webview/preload", process.stdout, process.stderr, true);
}
const debug = debug_("r2:navigator#electron/renderer/webview/preload");
let __locEventID = 0;
const INJECTED_LINK_TXT = "__";
const win = global.window;
win.READIUM2 = {
lastClickedTextChar: undefined,
DEBUG_VISUALS: false,
fxlViewportHeight: 0,
fxlViewportScale: 1,
fxlViewportWidth: 0,
fxlZoomPercent: 0,
hashElement: null,
isAudio: false,
ignorekeyDownUpEvents: false,
accessibilitySupportEnabled: false,
isClipboardIntercept: false,
isFixedLayout: false,
locationHashOverride: undefined,
locationHashOverrideInfo: {
locEventID: undefined,
audioPlaybackInfo: undefined,
docInfo: undefined,
epubPage: undefined,
epubPageID: undefined,
headings: undefined,
href: "",
locations: {
cfi: undefined,
cssSelector: undefined,
position: undefined,
progression: undefined,
xpath: undefined,
},
paginationInfo: undefined,
secondWebViewHref: undefined,
selectionInfo: undefined,
selectionIsNew: undefined,
title: undefined,
userInteract: false,
},
ttsHighlightStyle: highlight_1.HighlightDrawTypeBackground,
ttsHighlightColor: undefined,
ttsHighlightColor_WORD: undefined,
ttsHighlightStyle_WORD: undefined,
ttsClickEnabled: false,
ttsOverlayEnabled: false,
ttsPlaybackRate: 1,
ttsAndMediaOverlaysManualPlayNext: false,
ttsSkippabilityEnabled: false,
ttsSentenceDetectionEnabled: true,
ttsVoices: null,
urlQueryParams: win.location.search ? (0, querystring_1.getURLQueryParams)(win.location.search) : undefined,
webViewSlot: styles_2.WebViewSlotEnum.center,
};
win.alert = (...args) => {
console.log.apply(win, args);
};
win.confirm = (...args) => {
console.log.apply(win, args);
return false;
};
win.prompt = (...args) => {
console.log.apply(win, args);
return "";
};
const CSS_PIXEL_TOLERANCE = 5;
(0, selection_2.setSelectionChangeAction)(win, () => {
if (DEBUG_TRACE)
debug("setSelectionChangeAction: notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced(true, false, true);
});
const TOUCH_SWIPE_DELTA_MIN = 80;
const TOUCH_SWIPE_LONG_PRESS_MAX_TIME = 500;
const TOUCH_SWIPE_MAX_TIME = 500;
let touchstartEvent;
let touchEventEnd;
win.document.addEventListener("touchstart", (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", (event) => {
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
touchstartEvent = undefined;
touchEventEnd = undefined;
return;
}
if (event.changedTouches.length !== 1) {
return;
}
if (!touchstartEvent) {
return;
}
const startTouch = touchstartEvent.changedTouches[0];
const endTouch = event.changedTouches[0];
if (!startTouch || !endTouch) {
return;
}
const deltaX = (startTouch.clientX - endTouch.clientX) / win.devicePixelRatio;
const 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;
}
const slope = (startTouch.clientY - endTouch.clientY) /
(startTouch.clientX - endTouch.clientX);
if (Math.abs(slope) > 0.5) {
touchstartEvent = undefined;
return;
}
const rtl = (0, readium_css_1.isRTL)();
if (deltaX > 0) {
const payload = {
go: rtl ? "PREVIOUS" : "NEXT",
nav: true,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
}
else {
const payload = {
go: rtl ? "NEXT" : "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;
}
const elementName = (ev.target && ev.target.nodeName) ?
ev.target.nodeName : "";
const elementAttributes = {};
if (ev.target && ev.target.attributes) {
for (let i = 0; i < ev.target.attributes.length; i++) {
const attr = ev.target.attributes[i];
elementAttributes[attr.name] = attr.value;
}
}
const payload = {
altKey: ev.altKey,
code: ev.code,
ctrlKey: ev.ctrlKey,
elementAttributes,
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", (ev) => {
keyDownUpEventHandler(ev, true);
}, {
capture: true,
once: false,
passive: false,
});
win.document.addEventListener("keyup", (ev) => {
keyDownUpEventHandler(ev, false);
}, {
capture: true,
once: false,
passive: false,
});
win.READIUM2.isAudio = win.location.protocol === "data:";
if (win.READIUM2.urlQueryParams) {
let readiumEpubReadingSystemJson;
const base64EpubReadingSystem = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_EPUBREADINGSYSTEM];
if (base64EpubReadingSystem) {
try {
const 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.accessibilitySupportEnabled = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_A11Y_SUPPORT_ENABLED] === "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_2.WebViewSlotEnum.left :
(win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_WEBVIEW_SLOT] === "right" ? styles_2.WebViewSlotEnum.right :
styles_2.WebViewSlotEnum.center);
}
if (IS_DEV) {
electron_1.ipcRenderer.on(events_1.R2_EVENT_DEBUG_VISUALS, (_event, payload) => {
win.READIUM2.DEBUG_VISUALS = payload.debugVisuals;
if (!payload.debugVisuals) {
const existings = win.document.querySelectorAll(`*[${styles_2.readPosCssStylesAttr1}], *[${styles_2.readPosCssStylesAttr2}], *[${styles_2.readPosCssStylesAttr3}], *[${styles_2.readPosCssStylesAttr4}]`);
existings.forEach((existing) => {
existing.removeAttribute(`${styles_2.readPosCssStylesAttr1}`);
existing.removeAttribute(`${styles_2.readPosCssStylesAttr2}`);
existing.removeAttribute(`${styles_2.readPosCssStylesAttr3}`);
existing.removeAttribute(`${styles_2.readPosCssStylesAttr4}`);
});
}
if (payload.cssClass) {
if (_blacklistIdClassForCssSelectors.indexOf(payload.cssClass) < 0) {
_blacklistIdClassForCssSelectors.push(payload.cssClass.toLowerCase());
}
if (payload.debugVisuals && payload.cssStyles && payload.cssStyles.length) {
const idSuffix = `debug_for_class_${payload.cssClass}`;
(0, readium_css_inject_1.appendCSSInline)(win.document, idSuffix, payload.cssStyles);
if (payload.cssSelector) {
const toHighlights = win.document.querySelectorAll(payload.cssSelector);
toHighlights.forEach((toHighlight) => {
const clazz = `${payload.cssClass}`;
if (!toHighlight.classList.contains(clazz)) {
toHighlight.classList.add(clazz);
}
});
}
}
else {
const existings = win.document.querySelectorAll(`.${payload.cssClass}`);
existings.forEach((existing) => {
existing.classList.remove(`${payload.cssClass}`);
});
}
}
});
}
function isVisible(allowPartial, element, domRect) {
if (DEBUG_TRACE)
debug("isVisible:", getCssSelector(element), allowPartial);
if (DEBUG_TRACE && domRect)
debug("isVisible domRect:", domRect.x, domRect.y, domRect.width, domRect.height);
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) {
if (DEBUG_TRACE)
debug("isVisible: HTML BODY always true");
return true;
}
const blacklisted = checkBlacklisted(element);
if (blacklisted) {
return false;
}
const elStyle = win.getComputedStyle(element);
if (elStyle) {
const display = elStyle.getPropertyValue("display");
if (display === "none") {
if (IS_DEV) {
debug("isVisible element DISPLAY NONE");
}
return false;
}
const opacity = elStyle.getPropertyValue("opacity");
if (opacity === "0") {
if (IS_DEV) {
debug("isVisible element OPACITY ZERO");
}
return false;
}
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
if (!(0, readium_css_inject_1.isPaginated)(win.document)) {
const rect = domRect || element.getBoundingClientRect();
if (isVWM) {
if (rect.left >= 0 &&
(rect.left + rect.width) <= win.document.documentElement.clientWidth) {
return true;
}
if (allowPartial && (rect.left >= 0 || (rect.left + rect.width) <= win.document.documentElement.clientWidth)) {
return true;
}
}
else {
if (rect.top >= 0 &&
(rect.top + rect.height) <= win.document.documentElement.clientHeight) {
return true;
}
if (allowPartial && (rect.top >= 0 || (rect.top + rect.height) <= win.document.documentElement.clientWidth)) {
return true;
}
}
return false;
}
if (isVWM) {
debug("isVisible FALSE VWM paginated");
return false;
}
const scrollLeftPotentiallyExcessive = getScrollOffsetIntoView(element, domRect);
const extraShift = styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD ? scrollElement.scrollLeftExtra : 0;
let currentOffset = scrollElement.scrollLeft;
if (extraShift) {
currentOffset += (((currentOffset < 0) ? -1 : 1) * extraShift);
}
if (scrollLeftPotentiallyExcessive[0] >= (currentOffset - 10) &&
scrollLeftPotentiallyExcessive[0] <= (currentOffset + 10)) {
if (DEBUG_TRACE)
debug("isVisible TRUE (!!!allowPartial)", scrollLeftPotentiallyExcessive[0], scrollLeftPotentiallyExcessive[1], currentOffset);
return true;
}
if (allowPartial) {
if (scrollLeftPotentiallyExcessive[1] >= (currentOffset - 10) &&
scrollLeftPotentiallyExcessive[1] <= (currentOffset + 10)) {
if (DEBUG_TRACE)
debug("isVisible TRUE (allowPartial)", scrollLeftPotentiallyExcessive[0], scrollLeftPotentiallyExcessive[1], currentOffset);
return true;
}
}
if (DEBUG_TRACE)
debug("isVisible FALSE", scrollLeftPotentiallyExcessive[0], scrollLeftPotentiallyExcessive[1], currentOffset);
return false;
}
function isVisible_(location) {
let 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 {
let selected = null;
try {
selected = win.document.querySelector(location.cssSelector);
}
catch (err) {
debug(err);
}
if (selected) {
visible = isVisible(false, selected, undefined);
}
}
return visible;
}
electron_1.ipcRenderer.on(events_1.R2_EVENT_LOCATOR_VISIBLE, (_event, payload, eventID) => {
payload.visible = isVisible_(payload.location);
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_LOCATOR_VISIBLE, payload, eventID);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_SCROLLTO, (_event, payload) => {
if (DEBUG_TRACE)
debug("R2_EVENT_SCROLLTO");
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();
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("R2_EVENT_SCROLLTO: processXYRaw()...");
processXYRaw(x, y, false, false);
if (DEBUG_TRACE)
debug("R2_EVENT_SCROLLTO: notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
return;
}
let 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_2.readPosCssStylesAttr1, "R2_EVENT_SCROLLTO hashElement");
}
}
win.location.href = "#" + payload.hash;
delayScrollIntoView = true;
}
else {
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const scrollTop = scrollElement.scrollTop;
const scrollLeft = scrollElement.scrollLeft;
win.location.href = "#";
delayScrollIntoView = true;
setTimeout(() => {
debug("location HREF # hash, reset scroll left/top: ", scrollTop, scrollLeft);
scrollElement.scrollTop = scrollTop;
scrollElement.scrollLeft = scrollLeft;
}, 0);
win.READIUM2.hashElement = null;
}
win.READIUM2.locationHashOverride = undefined;
resetLocationHashOverrideInfo();
if (delayScrollIntoView) {
setTimeout(() => {
if (DEBUG_TRACE)
debug("R2_EVENT_SCROLLTO: delayScrollIntoView + scrollToHashRaw()...");
scrollToHashRaw(false, true);
}, 100);
}
else {
if (DEBUG_TRACE)
debug("R2_EVENT_SCROLLTO: !delayScrollIntoView + scrollToHashRaw()...");
scrollToHashRaw(false, true);
}
});
function resetLocationHashOverrideInfo() {
win.READIUM2.locationHashOverrideInfo = {
locEventID: undefined,
audioPlaybackInfo: undefined,
docInfo: undefined,
epubPage: undefined,
epubPageID: undefined,
headings: undefined,
href: "",
locations: {
cfi: undefined,
cssSelector: undefined,
position: undefined,
progression: undefined,
xpath: undefined,
},
paginationInfo: undefined,
secondWebViewHref: undefined,
selectionInfo: undefined,
selectionIsNew: undefined,
title: undefined,
userInteract: false,
};
}
let _lastAnimState;
function elementCapturesKeyboardArrowKeys(target) {
let curElement = target;
while (curElement && curElement.nodeType === Node.ELEMENT_NODE) {
const editable = curElement.getAttribute("contenteditable");
if (editable) {
return true;
}
const arrayOfKeyboardCaptureElements = ["input", "textarea", "video", "audio", "select"];
if (arrayOfKeyboardCaptureElements.indexOf(curElement.tagName.toLowerCase()) >= 0) {
return true;
}
curElement = curElement.parentNode;
}
return false;
}
function ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable() {
if (!styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD) {
return 0;
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const 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) {
if (!styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD) {
return;
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
scrollElement.scrollLeftExtra = scrollLeftExtra;
const 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 (!styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD) {
return;
}
if (!win || !win.document || !win.document.body || !win.document.documentElement) {
return;
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
let dialogPopup = (0, popup_dialog_1.isPopupDialogOpen)(win.document);
if (dialogPopup) {
const diagEl = win.document.getElementById(styles_2.POPUP_DIALOG_CLASS);
if (diagEl) {
const isCollapsed = diagEl.classList.contains(styles_2.POPUP_DIALOG_CLASS_COLLAPSE);
if (isCollapsed) {
dialogPopup = false;
}
}
}
const 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;
}
const extraOffset = Math.abs(scrollOffset) - maxScrollShift;
let backgroundColor;
const docStyle = win.getComputedStyle(win.document.documentElement);
if (docStyle) {
backgroundColor = docStyle.getPropertyValue("background-color");
}
if (!backgroundColor || backgroundColor === "transparent") {
const 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) {
if (DEBUG_TRACE)
debug("onEventPageTurn");
let leftRightKeyWasUsedInsideKeyboardCapture = false;
if (win.document.activeElement &&
elementCapturesKeyboardArrowKeys(win.document.activeElement)) {
if (win.document.hasFocus()) {
leftRightKeyWasUsedInsideKeyboardCapture = true;
}
else {
const oldDate = win.document.activeElement.r2_leftrightKeyboardTimeStamp;
if (oldDate) {
const newDate = new Date();
const 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;
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const reduceMotion = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_REDUCE_MOTION);
const isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
const goPREVIOUS = payload.go === "PREVIOUS";
const animationTime = 300;
if (_lastAnimState && _lastAnimState.animating) {
win.cancelAnimationFrame(_lastAnimState.id);
_lastAnimState.object[_lastAnimState.property] = _lastAnimState.destVal;
}
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
if (!goPREVIOUS) {
const maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
const maxScrollShiftTolerated = maxScrollShift - CSS_PIXEL_TOLERANCE;
if (isPaged) {
const unit = isVWM ?
scrollElement.offsetHeight :
scrollElement.offsetWidth;
let scrollElementOffset = Math.round(isVWM ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
const isNegative = scrollElementOffset < 0;
const scrollElementOffsetAbs = Math.abs(scrollElementOffset);
const fractional = scrollElementOffsetAbs / unit;
const integral = Math.floor(fractional);
const decimal = fractional - integral;
const 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 (isVWM && (scrollElementOffsetAbs < maxScrollShiftTolerated) ||
!isVWM && (scrollElementOffsetAbs < maxScrollShiftTolerated)) {
const scrollOffsetPotentiallyExcessive_ = isVWM ?
(scrollElementOffset + unit) :
(scrollElementOffset + ((0, readium_css_1.isRTL)() ? -1 : 1) * unit);
const nWholes = Math.floor(scrollOffsetPotentiallyExcessive_ / unit);
const scrollOffsetPotentiallyExcessive = nWholes * unit;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffsetPotentiallyExcessive, maxScrollShift);
const scrollOffset = (scrollOffsetPotentiallyExcessive < 0 ? -1 : 1) *
Math.min(Math.abs(scrollOffsetPotentiallyExcessive), maxScrollShift);
const targetObj = scrollElement;
const targetProp = isVWM ? "scrollTop" : "scrollLeft";
if (reduceMotion) {
_lastAnimState = undefined;
if (DEBUG_TRACE)
debug("onEventPageTurn: !goPREVIOUS + isPaged + reduceMotion + scroll?...");
targetObj[targetProp] = scrollOffset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, (_cancelled) => {
_ignoreScrollEvent = false;
if (DEBUG_TRACE)
debug("onEventPageTurn: !goPREVIOUS + isPaged + !reduceMotion + onScrollDebounced()...");
onScrollDebounced();
}, targetProp, animationTime, targetObj, scrollOffset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if (isVWM && (Math.abs(scrollElement.scrollLeft) < (maxScrollShiftTolerated - CSS_PIXEL_TOLERANCE)) ||
!isVWM && (Math.abs(scrollElement.scrollTop) < (maxScrollShiftTolerated - CSS_PIXEL_TOLERANCE))) {
const newVal = isVWM ?
(scrollElement.scrollLeft + ((0, readium_css_1.isRTL)() ? -1 : 1) * win.document.documentElement.clientWidth) :
(scrollElement.scrollTop + win.document.documentElement.clientHeight);
const targetObj = scrollElement;
const targetProp = isVWM ? "scrollLeft" : "scrollTop";
if (reduceMotion) {
_lastAnimState = undefined;
if (DEBUG_TRACE)
debug("onEventPageTurn: !goPREVIOUS + !isPaged + reduceMotion + scroll?...");
targetObj[targetProp] = newVal;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, (_cancelled) => {
_ignoreScrollEvent = false;
if (DEBUG_TRACE)
debug("onEventPageTurn: !goPREVIOUS + !isPaged + !reduceMotion + onScrollDebounced()...");
onScrollDebounced();
}, targetProp, animationTime, targetObj, newVal, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
}
else if (goPREVIOUS) {
if (isPaged) {
const unit = isVWM ?
scrollElement.offsetHeight :
scrollElement.offsetWidth;
let scrollElementOffset = Math.round(isVWM ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
const isNegative = scrollElementOffset < 0;
const scrollElementOffsetAbs = Math.abs(scrollElementOffset);
const fractional = scrollElementOffsetAbs / unit;
const integral = Math.floor(fractional);
const decimal = fractional - integral;
const 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 (isVWM && (scrollElementOffsetAbs > 0) ||
!isVWM && (scrollElementOffsetAbs > 0)) {
const scrollOffset_ = isVWM ?
(scrollElementOffset - unit) :
(scrollElementOffset - ((0, readium_css_1.isRTL)() ? -1 : 1) * unit);
const nWholes = (0, readium_css_1.isRTL)() ? Math.floor(scrollOffset_ / unit) : Math.ceil(scrollOffset_ / unit);
const scrollOffset = nWholes * unit;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffset, 0);
const targetObj = scrollElement;
const targetProp = isVWM ? "scrollTop" : "scrollLeft";
if (reduceMotion) {
_lastAnimState = undefined;
if (DEBUG_TRACE)
debug("onEventPageTurn: goPREVIOUS + isPaged + reduceMotion + scroll?...");
targetObj[targetProp] = scrollOffset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, (_cancelled) => {
_ignoreScrollEvent = false;
if (DEBUG_TRACE)
debug("onEventPageTurn: goPREVIOUS + isPaged + !reduceMotion + onScrollDebounced()...");
onScrollDebounced();
}, targetProp, animationTime, targetObj, scrollOffset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if (isVWM && (Math.abs(scrollElement.scrollLeft) > CSS_PIXEL_TOLERANCE) ||
!isVWM && (Math.abs(scrollElement.scrollTop) > CSS_PIXEL_TOLERANCE)) {
const newVal = isVWM ?
(scrollElement.scrollLeft - ((0, readium_css_1.isRTL)() ? -1 : 1) * win.document.documentElement.clientWidth) :
(scrollElement.scrollTop - win.document.documentElement.clientHeight);
const targetObj = scrollElement;
const targetProp = isVWM ? "scrollLeft" : "scrollTop";
if (reduceMotion) {
_lastAnimState = undefined;
if (DEBUG_TRACE)
debug("onEventPageTurn: goPREVIOUS + !isPaged + reduceMotion + scroll?...");
targetObj[targetProp] = newVal;
}
else {
_ignoreScrollEvent = true;
_lastAnimState = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, (_cancelled) => {
_ignoreScrollEvent = false;
if (DEBUG_TRACE)
debug("onEventPageTurn: goPREVIOUS + !isPaged + !reduceMotion + onScrollDebounced()...");
onScrollDebounced();
}, targetProp, animationTime, targetObj, newVal, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
payload.go = "";
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, (_event, payload) => {
if (DEBUG_TRACE)
debug("R2_EVENT_PAGE_TURN");
focusScrollDebounced.clear();
processXYDebouncedImmediate.clear();
notifyReadingLocationDebounced.clear();
notifyReadingLocationDebouncedImmediate.clear();
scrollToHashDebounced.clear();
onScrollDebounced.clear();
handleFocusInDebounced.clear();
setTimeout(() => {
if (DEBUG_TRACE)
debug("R2_EVENT_PAGE_TURN: onEventPageTurn()...");
onEventPageTurn(payload);
}, 100);
});
function focusElement(element, preventScroll) {
if (DEBUG_TRACE)
debug("focusElement", getCssSelector(element));
if (preventScroll &&
(element === win.document.activeElement)) {
if (DEBUG_TRACE)
debug("focusElement: preventScroll && document.activeElement");
return;
}
if (element === win.document.body || !(0, tabbable_1.isFocusable)(element)) {
const attr = element.getAttribute("tabindex");
if (!attr) {
element.setAttribute("tabindex", "-1");
element.classList.add(styles_2.CSS_CLASS_NO_FOCUS_OUTLINE);
if (DEBUG_TRACE)
debug("focusElement: tabindex -1");
}
}
if (element === win.document.body) {
if (DEBUG_TRACE)
debug("focusElement: body, preventScroll");
_ignoreFocusInEvent = true;
element.focus({ preventScroll: true });
}
else {
if (DEBUG_TRACE)
debug("focusElement: !body, preventScroll?", preventScroll);
_ignoreFocusInEvent = true;
element.focus({ preventScroll });
}
}
const tempLinkTargetOutline = (element, time, alt) => {
if (DEBUG_TRACE)
debug("tempLinkTargetOutline", getCssSelector(element));
if (win.document.documentElement.classList.contains(styles_1.DISABLE_TEMPORARY_NAV_TARGET_OUTLINE_CLASS)
||
win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PLAYING)
||
win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PAUSED)) {
return;
}
let skip = false;
const targets = win.document.querySelectorAll(`.${styles_2.LINK_TARGET_CLASS}`);
targets.forEach((t) => {
if (alt && !t.classList.contains(styles_2.LINK_TARGET_ALT_CLASS)) {
skip = true;
return;
}
t.classList.remove(styles_2.LINK_TARGET_CLASS);
t.classList.remove(styles_2.LINK_TARGET_ALT_CLASS);
});
if (skip) {
return;
}
element.style.animation = "none";
void element.offsetWidth;
element.style.animation = "";
element.classList.add(styles_2.LINK_TARGET_CLASS);
if (alt) {
element.classList.add(styles_2.LINK_TARGET_ALT_CLASS);
}
if (element._timeoutTargetClass) {
clearTimeout(element._timeoutTargetClass);
element._timeoutTargetClass = undefined;
}
element._timeoutTargetClass = setTimeout(() => {
element.classList.remove(styles_2.LINK_TARGET_CLASS);
element.classList.remove(styles_2.LINK_TARGET_ALT_CLASS);
}, time);
};
let _lastAnimState2;
const animationTime2 = 400;
function scrollElementIntoView(element, doFocus, animate, domRect, center) {
if (DEBUG_TRACE)
debug("scrollElementIntoView", getCssSelector(element));
if (win.READIUM2.DEBUG_VISUALS) {
const existings = win.document.querySelectorAll(`*[${styles_2.readPosCssStylesAttr3}]`);
existings.forEach((existing) => {
existing.removeAttribute(`${styles_2.readPosCssStylesAttr3}`);
});
element.setAttribute(styles_2.readPosCssStylesAttr3, "scrollElementIntoView");
}
if (win.READIUM2.isFixedLayout) {
if (DEBUG_TRACE)
debug("scrollElementIntoView: isFixedLayout");
return;
}
if (doFocus) {
tempLinkTargetOutline(element, 2000, false);
if (DEBUG_TRACE)
debug("scrollElementIntoView: doFocus + focusElement()");
focusElement(element, !!domRect);
}
setTimeout(() => {
const isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
if (isPaged) {
if (DEBUG_TRACE)
debug("scrollElementIntoView: isPaged + scrollIntoView()");
scrollIntoView(element, domRect);
}
else {
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const rect = domRect || element.getBoundingClientRect();
if (!center && isVisible(false, element, domRect)) {
if (DEBUG_TRACE)
debug("scrollElementIntoView: !center && isVisible");
}
else {
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
const scrollTopMax = isVWM ?
((0, readium_css_1.isRTL)() ? -1 : 1) * (scrollElement.scrollWidth - win.document.documentElement.clientWidth) :
scrollElement.scrollHeight - win.document.documentElement.clientHeight;
let offset = isVWM ?
scrollElement.scrollLeft + (rect.left - (win.document.documentElement.clientWidth / 2) + (center ? (rect.width / 2) : 0)) :
scrollElement.scrollTop + (rect.top - (win.document.documentElement.clientHeight / 2) + (center ? (rect.height / 2) : 0));
if (isVWM && (0, readium_css_1.isRTL)()) {
if (offset < scrollTopMax) {
offset = scrollTopMax;
}
else if (offset > 0) {
offset = 0;
}
}
else {
if (offset > scrollTopMax) {
offset = scrollTopMax;
}
else if (offset < 0) {
offset = 0;
}
}
const diff = Math.abs((isVWM ? scrollElement.scrollLeft : scrollElement.scrollTop) - offset);
if (diff < 10) {
return;
}
const targetProp = isVWM ? "scrollLeft" : "scrollTop";
if (animate) {
const reduceMotion = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_REDUCE_MOTION);
if (_lastAnimState2 && _lastAnimState2.animating) {
win.cancelAnimationFrame(_lastAnimState2.id);
_lastAnimState2.object[_lastAnimState2.property] = _lastAnimState2.destVal;
}
const targetObj = scrollElement;
if (reduceMotion) {
_lastAnimState2 = undefined;
if (DEBUG_TRACE)
debug("scrollElementIntoView: animate + reduceMotion + scroll?...");
targetObj[targetProp] = offset;
}
else {
_ignoreScrollEvent = true;
_lastAnimState2 = (0, animateProperty_1.animateProperty)(win.cancelAnimationFrame, (_cancelled) => {
_ignoreScrollEvent = false;
if (DEBUG_TRACE)
debug("scrollElementIntoView: animate + !reduceMotion + onScrollDebounced()...");
onScrollDebounced();
}, targetProp, animationTime2, targetObj, offset, win.requestAnimationFrame, easings_1.easings.easeInOutQuad);
}
}
else {
if (DEBUG_TRACE)
debug("scrollElementIntoView: !animate + scroll?...");
scrollElement[targetProp] = offset;
}
}
}
}, 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, 0];
}
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const rect = domRect || element.getBoundingClientRect();
const columnDimension = (0, readium_css_1.calculateColumnDimension)();
const isTwoPage = (0, readium_css_1.isTwoPageSpread)();
const 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);
const columnIndex = Math.floor(fullOffset / columnDimension);
const spreadIndex = isTwoPage ? Math.floor(columnIndex / 2) : columnIndex;
const off = ((0, readium_css_1.isRTL)() ? -1 : 1) * (spreadIndex * (columnDimension * (isTwoPage ? 2 : 1)));
const fullOffsetEnd = fullOffset + (((0, readium_css_1.isRTL)() ? 1 : 1) * rect.width);
const columnIndexEnd = Math.floor(fullOffsetEnd / columnDimension);
const spreadIndexEnd = isTwoPage ? Math.floor(columnIndexEnd / 2) : columnIndexEnd;
const offEnd = ((0, readium_css_1.isRTL)() ? -1 : 1) * (spreadIndexEnd * (columnDimension * (isTwoPage ? 2 : 1)));
return [off, offEnd];
}
function scrollIntoView(element, domRect) {
if (!win.document || !win.document.documentElement || !win.document.body || !(0, readium_css_inject_1.isPaginated)(win.document)) {
return;
}
const maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
const scrollLeftPotentiallyExcessive = getScrollOffsetIntoView(element, domRect);
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollLeftPotentiallyExcessive[0], maxScrollShift);
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const scrollOffset = (scrollLeftPotentiallyExcessive[0] < 0 ? -1 : 1) *
Math.min(Math.abs(scrollLeftPotentiallyExcessive[0]), maxScrollShift);
scrollElement.scrollLeft = scrollOffset;
scrollElement.scrollTop = 0;
}
const scrollToHashRaw = (animate, skipRedraw) => {
var _a;
if (DEBUG_TRACE)
debug("scrollToHashRaw");
if (!win.document || !win.document.body || !win.document.documentElement) {
return;
}
if (!skipRedraw) {
if (DEBUG_TRACE)
debug("scrollToHashRaw: recreateAllHighlightsRaw()...");
(0, highlight_2.recreateAllHighlightsRaw)(win);
}
const isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
if (win.READIUM2.locationHashOverride) {
if (DEBUG_TRACE)
debug("scrollToHashRaw: locationHashOverride + scrollElementIntoView()...");
scrollElementIntoView(win.READIUM2.locationHashOverride, true, animate, undefined);
if (DEBUG_TRACE)
debug("scrollToHashRaw: locationHashOverride + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
return;
}
else if (win.READIUM2.hashElement) {
win.READIUM2.locationHashOverride = win.READIUM2.hashElement;
if (DEBUG_TRACE)
debug("scrollToHashRaw: hashElement + scrollElementIntoView()...");
scrollElementIntoView(win.READIUM2.hashElement, true, animate, undefined);
if (DEBUG_TRACE)
debug("scrollToHashRaw: hashElement + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
return;
}
else {
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
if (win.READIUM2.urlQueryParams) {
const previous = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_PREVIOUS];
const isPreviousNavDirection = previous === "true";
if (isPreviousNavDirection) {
const { maxScrollShift, maxScrollShiftAdjusted } = (0, readium_css_1.calculateMaxScrollShift)();
_ignoreScrollEvent = true;
if (isPaged) {
if (isVWM) {
scrollElement.scrollLeft = 0;
scrollElement.scrollTop = maxScrollShift;
}
else {
const scrollLeftPotentiallyExcessive = ((0, readium_css_1.isRTL)() ? -1 : 1) * maxScrollShiftAdjusted;
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollLeftPotentiallyExcessive, maxScrollShift);
const scrollLeft = ((0, readium_css_1.isRTL)() ? -1 : 1) * maxScrollShift;
scrollElement.scrollLeft = scrollLeft;
scrollElement.scrollTop = 0;
}
}
else {
if (isVWM) {
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(() => {
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + isPreviousNavDirection + processXYRaw()...");
processXYRaw(x, y, false, false);
showHideContentMask(false, win.READIUM2.isFixedLayout);
if (!win.READIUM2.locationHashOverride) {
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + isPreviousNavDirection + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
}
setTimeout(() => {
_ignoreScrollEvent = false;
}, 10);
}, 60);
return;
}
const gto = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO];
let gotoCssSelector;
let gotoProgression;
if (gto) {
const locStr = Buffer.from(gto, "base64").toString("utf8");
const locObj = JSON.parse(locStr);
gotoCssSelector = locObj.cssSelector;
gotoProgression = locObj.progression;
}
if (gotoCssSelector) {
gotoCssSelector = gotoCssSelector.replace(/\+/g, " ");
let doHyperlink = false;
if (gotoCssSelector.startsWith(url_params_1.FRAG_ID_CSS_SELECTOR_HYPERLINK)) {
doHyperlink = true;
gotoCssSelector = gotoCssSelector.replace(url_params_1.FRAG_ID_CSS_SELECTOR_HYPERLINK, "");
}
let 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;
}
let domRect;
const gtoDomRange = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_GOTO_DOM_RANGE];
if (gtoDomRange) {
try {
const rangeInfoStr = Buffer.from(gtoDomRange, "base64").toString("utf8");
const rangeInfo = JSON.parse(rangeInfoStr);
debug("rangeInfo", rangeInfo);
const domRange = (0, selection_2.convertRangeInfo)(win.document, rangeInfo);
if (domRange) {
domRect = domRange.getBoundingClientRect();
}
}
catch (err) {
debug("gtoDomRange", err);
}
}
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoCssSelector + scrollElementIntoView()...");
scrollElementIntoView(selected, true, animate, domRect);
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoCssSelector + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
if (doHyperlink && ((_a = selected.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "a") {
setTimeout(() => {
selected.__skipHistory = true;
selected.click();
}, 100);
}
return;
}
}
else if (typeof gotoProgression !== "undefined") {
const { maxScrollShift } = (0, readium_css_1.calculateMaxScrollShift)();
if (isPaged) {
const isTwoPage = (0, readium_css_1.isTwoPageSpread)();
const nColumns = (0, readium_css_1.calculateTotalColumns)();
const nUnits = isTwoPage ? Math.ceil(nColumns / 2) : nColumns;
const unitIndex = Math.floor(gotoProgression * nUnits);
const unit = isVWM ?
scrollElement.offsetHeight :
scrollElement.offsetWidth;
const scrollOffsetPotentiallyExcessive = isVWM ?
(unitIndex * unit) :
(((0, readium_css_1.isRTL)() ? -1 : 1) * unitIndex * unit);
ensureTwoPageSpreadWithOddColumnsIsOffset(scrollOffsetPotentiallyExcessive, maxScrollShift);
const scrollOffsetPaged = (scrollOffsetPotentiallyExcessive < 0 ? -1 : 1) *
Math.min(Math.abs(scrollOffsetPotentiallyExcessive), maxScrollShift);
debug("gotoProgression, set scroll left/top (paged): ", scrollOffsetPaged);
_ignoreScrollEvent = true;
if (isVWM) {
scrollElement.scrollTop = scrollOffsetPaged;
scrollElement.scrollLeft = 0;
}
else {
scrollElement.scrollTop = 0;
scrollElement.scrollLeft = scrollOffsetPaged;
}
setTimeout(() => {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + isPaged + focusElement()...");
focusElement(win.READIUM2.locationHashOverride, false);
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + isPaged + processXYRaw()...");
processXYRaw(x, y, false, false);
if (!win.READIUM2.locationHashOverride) {
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + isPaged + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
}
return;
}
const scrollOffset = gotoProgression * maxScrollShift;
debug("gotoProgression, set scroll left/top (scrolled): ", scrollOffset);
_ignoreScrollEvent = true;
if (isVWM) {
scrollElement.scrollTop = 0;
scrollElement.scrollLeft = ((0, readium_css_1.isRTL)() ? -1 : 1) * scrollOffset;
}
else {
scrollElement.scrollTop = scrollOffset;
scrollElement.scrollLeft = 0;
}
setTimeout(() => {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + !isPaged + focusElement()...");
focusElement(win.READIUM2.locationHashOverride, false);
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + !isPaged + processXYRaw()...");
processXYRaw(x, y, false, false);
if (!win.READIUM2.locationHashOverride) {
if (DEBUG_TRACE)
debug("scrollToHashRaw: urlQueryParams + gotoProgression + !isPaged + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
}
return;
}
}
_ignoreScrollEvent = true;
scrollElement.scrollLeft = 0;
scrollElement.scrollTop = 0;
setTimeout(() => {
_ignoreScrollEvent = false;
}, 10);
win.READIUM2.locationHashOverride = win.document.body;
resetLocationHashOverrideInfo();
if (DEBUG_TRACE)
debug("scrollToHashRaw: !urlQueryParams focusElement()...");
focusElement(win.READIUM2.locationHashOverride, false);
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("scrollToHashRaw: !urlQueryParams processXYRaw()...");
processXYRaw(x, y, false, false);
}
if (DEBUG_TRACE)
debug("scrollToHashRaw: notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
};
const scrollToHashDebounced = debounce((animate) => {
if (DEBUG_TRACE)
debug("scrollToHashDebounced: scrollToHashRaw()...");
scrollToHashRaw(animate);
}, 100);
let _ignoreScrollEvent = false;
function showHideContentMask(doHide, isFixedLayout) {
if (!styles_2.ENABLE_VISIBILITY_MASK) {
return;
}
if (doHide) {
win.document.documentElement.classList.add(styles_2.ROOT_CLASS_INVISIBLE_MASK);
win.document.documentElement.classList.remove(styles_2.ROOT_CLASS_INVISIBLE_MASK_REMOVED);
}
else {
if (styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD) {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_SHOW, null);
}
if (isFixedLayout) {
win.document.documentElement.classList.add(styles_2.ROOT_CLASS_INVISIBLE_MASK_REMOVED);
}
win.document.documentElement.classList.remove(styles_2.ROOT_CLASS_INVISIBLE_MASK);
}
}
function focusScrollRaw(el, doFocus, animate, domRect, center) {
if (DEBUG_TRACE)
debug("focusScrollRaw: ", getCssSelector(el));
if ((!(0, readium_css_inject_1.isPaginated)(win.document) && !win.READIUM2.isFixedLayout && center) ||
!isVisible(false, el, domRect)) {
if (DEBUG_TRACE)
debug("focusScrollRaw: scrollElementIntoView()...");
scrollElementIntoView(el, doFocus, animate, domRect, center);
}
if (win.READIUM2.locationHashOverride === el) {
return;
}
const blacklisted = checkBlacklisted(el);
if (blacklisted) {
return;
}
win.READIUM2.hashElement = doFocus ? el : win.READIUM2.hashElement;
win.READIUM2.locationHashOverride = el;
if (DEBUG_TRACE)
debug("focusScrollRaw: notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
}
const focusScrollDebounced = debounce((el, doFocus, animate, domRect) => {
if (DEBUG_TRACE)
debug("focusScrollDebounced: focusScrollRaw()...", getCssSelector(el));
focusScrollRaw(el, doFocus, animate, domRect);
}, 100);
let _ignoreFocusInEvent = false;
const handleFocusInDebounced = debounce((target, tabKeyDownEvent) => {
if (DEBUG_TRACE)
debug("handleFocusInDebounced: handleFocusInRaw()...", getCssSelector(target));
handleFocusInRaw(target, tabKeyDownEvent);
}, 100);
function handleFocusInRaw(target, _tabKeyDownEvent) {
if (DEBUG_TRACE)
debug("handleFocusInRaw:", getCssSelector(target));
if (!target || !win.document.body) {
return;
}
if (DEBUG_TRACE)
debug("handleFocusInRaw: focusScrollRaw()...");
focusScrollRaw(target, false, false, undefined);
}
electron_1.ipcRenderer.on(events_1.R2_EVENT_READIUMCSS, (_event, payload) => {
showHideContentMask(true, payload.isFixedLayout || win.READIUM2.isFixedLayout);
(0, readium_css_1.readiumCSS)(win.document, payload);
(0, highlight_2.recreateAllHighlights)(win);
showHideContentMask(false, payload.isFixedLayout || win.READIUM2.isFixedLayout);
});
let _docTitle;
win.addEventListener("DOMContentLoaded", () => {
debug("############# DOMContentLoaded");
const 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_2.readPosCssStylesAttr1, "DOMContentLoaded hashElement");
}
}
}
win.READIUM2.locationHashOverride = undefined;
win.READIUM2.ttsHighlightStyle = highlight_1.HighlightDrawTypeBackground;
win.READIUM2.ttsHighlightColor = undefined;
win.READIUM2.ttsHighlightColor_WORD = undefined;
win.READIUM2.ttsHighlightStyle_WORD = undefined;
win.READIUM2.ttsClickEnabled = false;
win.READIUM2.ttsAndMediaOverlaysManualPlayNext = false;
win.READIUM2.ttsSkippabilityEnabled = false;
win.READIUM2.ttsSentenceDetectionEnabled = true;
win.READIUM2.ttsOverlayEnabled = false;
let readiumcssJson;
if (win.READIUM2.urlQueryParams) {
const publicationHasMediaOverlays = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_EPUBMEDIAOVERLAYS] === "1";
if (publicationHasMediaOverlays) {
win.document.documentElement.classList.add(styles_2.R2_MO_CLASS_STOPPED);
}
const base64ReadiumCSS = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_CSS];
if (base64ReadiumCSS) {
let str;
try {
str = Buffer.from(base64ReadiumCSS, "base64").toString("utf8");
readiumcssJson = JSON.parse(str);
}
catch (err) {
debug("################## READIUM CSS PARSE ERROR?!");
debug(base64ReadiumCSS);
debug(err);
debug(str);
}
}
}
if (win.READIUM2.isAudio) {
(0, audiobook_1.setupAudioBook)(_docTitle, undefined);
}
if (readiumcssJson) {
win.READIUM2.isFixedLayout = (typeof readiumcssJson.isFixedLayout !== "undefined") ?
readiumcssJson.isFixedLayout : false;
}
if (!win.READIUM2.isFixedLayout && !win.READIUM2.isAudio) {
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
if (!scrollElement.classList.contains(styles_2.ZERO_TRANSFORM_CLASS)) {
scrollElement.classList.add(styles_2.ZERO_TRANSFORM_CLASS);
}
}
const w = (readiumcssJson && readiumcssJson.fixedLayoutWebViewWidth) || win.innerWidth;
const h = (readiumcssJson && readiumcssJson.fixedLayoutWebViewHeight) || win.innerHeight;
win.READIUM2.fxlZoomPercent = (readiumcssJson && readiumcssJson.fixedLayoutZoomPercent) || 0;
const wh = (0, readium_css_inject_1.configureFixedLayout)(win.document, win.READIUM2.isFixedLayout, win.READIUM2.fxlViewportWidth, win.READIUM2.fxlViewportHeight, w, h, win.READIUM2.webViewSlot, win.READIUM2.fxlZoomPercent);
if (wh) {
win.READIUM2.fxlViewportWidth = wh.width;
win.READIUM2.fxlViewportHeight = wh.height;
win.READIUM2.fxlViewportScale = wh.scale;
const payload = {
fxl: wh,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_FXL_CONFIGURE, payload);
}
else {
const payload = {
fxl: null,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_FXL_CONFIGURE, payload);
}
const alreadedInjected = win.document.documentElement.hasAttribute("data-readiumcss-injected");
if (alreadedInjected) {
debug(">>>>> ReadiumCSS already injected by streamer");
}
(0, readium_css_1.computeVerticalRTL)();
if (readiumcssJson) {
if ((0, readium_css_1.isVerticalWritingMode)() ||
!alreadedInjected) {
debug(">>>>>> ReadiumCSS inject again");
(0, readium_css_1.readiumCSS)(win.document, readiumcssJson);
}
}
if (!win.READIUM2.isFixedLayout) {
if (!alreadedInjected) {
(0, readium_css_inject_1.injectDefaultCSS)(win.document);
if (IS_DEV) {
(0, readium_css_inject_1.injectReadPosCSS)(win.document);
}
}
if (alreadedInjected) {
(0, readium_css_1.checkHiddenFootNotes)(win.document);
}
}
setTimeout(() => {
loaded(true);
}, 500);
});
function checkSoundtrack(documant) {
const audioNodeList = documant.querySelectorAll("audio");
if (!audioNodeList || !audioNodeList.length) {
return;
}
const audio = audioNodeList[0];
let epubType = audio.getAttribute("epub:type");
if (!epubType) {
epubType = audio.getAttributeNS("http://www.idpf.org/2007/ops", "type");
if (!epubType) {
epubType = audio.getAttribute("role");
}
}
if (!epubType) {
return;
}
epubType = epubType.trim().replace(/\s\s+/g, " ");
if (epubType.indexOf("ibooks:soundtrack") < 0) {
return;
}
let src = audio.getAttribute("src");
if (!src) {
if (!audio.childNodes) {
return;
}
for (let i = 0; i < audio.childNodes.length; i++) {
const childNode = audio.childNodes[i];
if (childNode.nodeType === 1) {
const el = childNode;
const elName = el.nodeName.toLowerCase();
if (elName === "source") {
src = el.getAttribute("src");
if (src) {
break;
}
}
}
}
}
if (!src) {
return;
}
debug(`AUDIO SOUNDTRACK: ${src} ---> ${audio.src}`);
if (!audio.src) {
return;
}
const payload = {
url: audio.src,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_AUDIO_SOUNDTRACK, payload);
}
function mediaOverlaysClickRaw(element, userInteract) {
const textFragmentIDChain = [];
if (element) {
let curEl = element;
do {
const id = curEl.getAttribute("id");
textFragmentIDChain.push(id ? id : null);
curEl = curEl.parentNode;
} while (curEl && curEl.nodeType === Node.ELEMENT_NODE);
}
const payload = {
locationHashOverrideInfo: win.READIUM2.locationHashOverrideInfo,
textFragmentIDChain,
userInteract,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_MEDIA_OVERLAY_CLICK, payload);
}
const onScrollRaw = (fromScrollEvent) => {
if (DEBUG_TRACE)
debug("onScrollRaw: fromScrollEvent", fromScrollEvent);
if (!win.document || !win.document.documentElement) {
return;
}
if (win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PLAYING)) {
debug("onScrollRaw Media OVerlays PLAYING/PAUSED ... skip");
return;
}
if (!win.READIUM2.ttsClickEnabled &&
!win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PLAYING) &&
!win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PAUSED)) {
const el = win.READIUM2.locationHashOverride;
if (el && isVisible(false, el, undefined)) {
debug("onScrollRaw VISIBLE SKIP");
if (fromScrollEvent && !(0, readium_css_inject_1.isPaginated)(win.document)) {
if (DEBUG_TRACE)
debug("onScrollRaw: notifyReadingLocationRaw()...");
notifyReadingLocationRaw(true, true, true);
}
return;
}
}
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
const x = ((isVWM || (0, readium_css_1.isRTL)()) ? win.document.documentElement.clientWidth - 2 : 1);
const y = 1;
if (DEBUG_TRACE)
debug("onScrollRaw: processXYRaw()...");
processXYRaw(x, y, false, false, true);
};
const onScrollDebounced = debounce((fromScrollEvent) => {
if (DEBUG_TRACE)
debug("onScrollDebounced: onScrollRaw()...");
onScrollRaw(fromScrollEvent);
}, 300);
const appendExtraColumnPadIfNecessary = (skipResizeObserver) => {
if (styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD) {
return;
}
let elPad = win.document.getElementById(styles_2.EXTRA_COLUMN_PAD_ID);
const isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
const isTwo = (0, readium_css_1.isTwoPageSpread)();
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
if (isVWM || !isPaged || !isTwo) {
}
else {
const { maxScrollShift, maxScrollShiftAdjusted } = (0, readium_css_1.calculateMaxScrollShift)();
if (maxScrollShiftAdjusted > maxScrollShift) {
elPad = win.document.createElement("div");
elPad.setAttribute("id", styles_2.EXTRA_COLUMN_PAD_ID);
elPad.style.breakBefore = "column";
elPad.innerHTML = "​";
if (!skipResizeObserver) {
debug("appendExtraColumnPadIfNecessary !skipResizeObserver");
_firstResizeObserver = true;
_firstResizeObserverTimeout = win.setTimeout(() => {
_firstResizeObserverTimeout = undefined;
if (_firstResizeObserver) {
_firstResizeObserver = false;
debug("ResizeObserver CANCEL SKIP FIRST (extra col pad)");
}
}, 400);
}
debug("appendExtraColumnPadIfNecessary APPEND DIV");
win.document.body.appendChild(elPad);
}
}
};
function focusCurrentReadingLocationElement(invert) {
if (IS_DEV) {
debug(">>>> focus link click: ");
debug(win.READIUM2.hashElement ?
getCssSelector(win.READIUM2.hashElement) : "!hashElement");
debug(win.READIUM2.locationHashOverride ?
getCssSelector(win.READIUM2.locationHashOverride) : "!locationHashOverride");
}
const el = invert ?
(win.READIUM2.locationHashOverride || win.READIUM2.hashElement) :
(win.READIUM2.hashElement || win.READIUM2.locationHashOverride);
if (el) {
if (DEBUG_TRACE)
debug("focusCurrentReadingLocationElement: focusScrollDebounced()...");
focusScrollDebounced(el, true, false, undefined);
}
}
let _firstResizeObserver = true;
let _firstResizeObserverTimeout = undefined;
let _loaded = false;
function loaded(forced) {
if (_loaded) {
return;
}
_loaded = true;
if (forced) {
debug(">>> LOAD EVENT WAS FORCED!");
}
else {
debug(">>> LOAD EVENT was not forced.");
}
const systemVoices = win.speechSynthesis.getVoices();
if (!!(systemVoices === null || systemVoices === void 0 ? void 0 : systemVoices.length) && false) {
console.log("loaded() -- window.speechSynthesis.getVoices()", JSON.stringify(systemVoices.map(v => ({
name: v.name,
lang: v.lang,
voiceURI: v.voiceURI,
default: v.default,
localService: v.localService,
})), null, 4));
}
_elementsWithID = undefined;
_allEpubPageBreaks = undefined;
_allHeadings = undefined;
if (win.READIUM2.urlQueryParams) {
const b64Highlights = win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_HIGHLIGHTS];
if (b64Highlights) {
setTimeout(async () => {
let jsonStr;
try {
const buff = Buffer.from(b64Highlights, "base64");
const cs = new DecompressionStream("gzip");
const csWriter = cs.writable.getWriter();
csWriter.write(buff);
csWriter.close();
const buffer = Buffer.from(await new Response(cs.readable).arrayBuffer());
const jsonStr = new TextDecoder().decode(buffer);
const highlights = JSON.parse(jsonStr);
(0, highlight_2.setDrawMargin)(win, highlights.margin);
(0, highlight_2.recreateAllHighlightsRaw)(win, highlights.list);
}
catch (err) {
debug("################## HIGHLIGHTS PARSE ERROR?!");
debug(b64Highlights);
debug(err);
debug(jsonStr);
}
}, 10);
}
}
if (win.READIUM2.isAudio) {
showHideContentMask(false, win.READIUM2.isFixedLayout);
}
else {
if (!win.READIUM2.isFixedLayout) {
appendExtraColumnPadIfNecessary(true);
showHideContentMask(false, win.READIUM2.isFixedLayout);
if (DEBUG_TRACE)
debug("LOADED !FXL: scrollToHashDebounced()...");
scrollToHashDebounced(false);
if (styles_1.ENABLE_SKIP_LINK && win.document.body) {
const focusLink = win.document.createElement("a");
focusLink.setAttribute("id", styles_2.SKIP_LINK_ID);
focusLink.appendChild(win.document.createTextNode(" "));
focusLink.setAttribute("title", INJECTED_LINK_TXT);
focusLink.setAttribute("aria-label", INJECTED_LINK_TXT);
focusLink.setAttribute("href", "javascript:;");
focusLink.setAttribute("tabindex", "0");
win.document.body.insertAdjacentElement("afterbegin", focusLink);
setTimeout(() => {
focusLink.addEventListener("click", (ev) => {
ev.preventDefault();
if (DEBUG_TRACE)
debug("focusLink CLICK: focusCurrentReadingLocationElement()...");
focusCurrentReadingLocationElement(false);
});
}, 200);
}
}
else {
showHideContentMask(false, win.READIUM2.isFixedLayout);
win.READIUM2.locationHashOverride = win.document.body;
if (DEBUG_TRACE)
debug("loaded() FXL: notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced();
}
checkSoundtrack(win.document);
}
win.document.documentElement.addEventListener("keydown", (ev) => {
if (win.document && win.document.documentElement) {
win.document.documentElement.classList.add(styles_2.ROOT_CLASS_KEYBOARD_INTERACT);
}
if (ev.code === "ArrowLeft" || ev.code === "ArrowRight") {
if (ev.target && elementCapturesKeyboardArrowKeys(ev.target)) {
ev.target.r2_leftrightKeyboardTimeStamp = new Date();
}
else {
ev.preventDefault();
}
}
}, true);
win.document.documentElement.addEventListener("mousedown", (_ev) => {
if (win.document && win.document.documentElement) {
win.document.documentElement.classList.remove(styles_2.ROOT_CLASS_KEYBOARD_INTERACT);
}
}, true);
if (win.READIUM2.isAudio) {
debug("AUDIOBOOK RENDER ...");
return;
}
win.document.body.addEventListener("focusin", (ev) => {
if (_ignoreFocusInEvent) {
debug("focusin --- IGNORE");
_ignoreFocusInEvent = false;
return;
}
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
return;
}
if (ev.target) {
let ignoreIncomingMouseClickOnFocusable = false;
if (win.document && win.document.documentElement) {
const low = ev.target.tagName.toLowerCase();
if (low === "body") {
ignoreIncomingMouseClickOnFocusable = true;
}
else if (!win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_KEYBOARD_INTERACT)) {
if (low === "a" &&
ev.target.href
||
ev.target.getAttribute("tabindex") === "-1" &&
ev.target.classList.contains(styles_2.CSS_CLASS_NO_FOCUS_OUTLINE)) {
ignoreIncomingMouseClickOnFocusable = true;
}
}
}
if (!ignoreIncomingMouseClickOnFocusable) {
if (DEBUG_TRACE)
debug("loaded() FOCUSIN: handleFocusInDebounced()...");
handleFocusInDebounced(ev.target, undefined);
}
else {
debug("focusin mouse click --- IGNORE");
}
}
});
const useResizeObserver = !win.READIUM2.isFixedLayout;
if (useResizeObserver && win.document.body) {
setTimeout(() => {
const resizeObserver = new win.ResizeObserver((entries) => {
if (DEBUG_TRACE)
debug("ResizeObserver ...");
for (const entry of entries) {
const rect = entry.contentRect;
const element = entry.target;
if (DEBUG_TRACE)
debug("element.id", element.id);
if (DEBUG_TRACE)
debug("element.innerHTML", element.innerHTML.substring(0, 100));
if (DEBUG_TRACE)
debug("rect", rect.x, rect.y, rect.width, rect.height);
}
if (_firstResizeObserverTimeout !== undefined) {
win.clearTimeout(_firstResizeObserverTimeout);
_firstResizeObserverTimeout = undefined;
}
if (_firstResizeObserver) {
_firstResizeObserver = false;
debug("ResizeObserver SKIP FIRST");
return;
}
win.document.body.tabbables = undefined;
const elPad = win.document.getElementById(styles_2.EXTRA_COLUMN_PAD_ID);
if (elPad) {
debug("ResizeObserver appendExtraColumnPadIfNecessary EXTRA_COLUMN_PAD_ID will remove...");
setTimeout(() => {
debug("ResizeObserver appendExtraColumnPadIfNecessary EXTRA_COLUMN_PAD_ID removing");
elPad === null || elPad === void 0 ? void 0 : elPad.remove();
}, 100);
return;
}
appendExtraColumnPadIfNecessary(false);
if (DEBUG_TRACE)
debug("ResizeObserver: scrollToHashDebounced()...");
scrollToHashDebounced(false);
});
resizeObserver.observe(win.document.body);
_firstResizeObserverTimeout = win.setTimeout(() => {
_firstResizeObserverTimeout = undefined;
if (_firstResizeObserver) {
_firstResizeObserver = false;
debug("ResizeObserver CANCEL SKIP FIRST");
}
}, 700);
}, 1000);
}
let _mouseMoveTimeout;
win.document.documentElement.addEventListener("mousemove", (_ev) => {
if (_mouseMoveTimeout !== undefined) {
win.clearTimeout(_mouseMoveTimeout);
_mouseMoveTimeout = undefined;
}
win.document.documentElement.classList.remove(styles_2.HIDE_CURSOR_CLASS);
_mouseMoveTimeout = win.setTimeout(() => {
_mouseMoveTimeout = undefined;
win.document.documentElement.classList.add(styles_2.HIDE_CURSOR_CLASS);
}, 1000);
});
win.document.addEventListener("auxclick", async (ev) => {
debug(`AUX __CLICK: ${ev.button} (SKIP middle)`);
if (ev.button === 1) {
ev.preventDefault();
ev.stopPropagation();
}
}, true);
win.document.addEventListener("click", async (ev) => {
debug(`!AUX __CLICK: ${ev.button} ...`);
if (win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PAUSED) || win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PLAYING)) {
debug("!AUX __CLICK skip because MO playing/paused");
ev.preventDefault();
ev.stopPropagation();
return;
}
if (!(0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
const x = ev.clientX;
const y = ev.clientY;
debug("CLICK ev.clientX/Y", ev.clientX, ev.clientY, win.READIUM2.ttsClickEnabled);
const domPointData = domDataFromPoint(x, y);
if (!domPointData.element) {
debug("CLICK !domPointData.element");
}
const visible = domPointData.element ? isVisible(true, domPointData.element, undefined) : false;
debug("CLICK visible " + (visible ? "YES" : "NO"));
if (domPointData.element && win.READIUM2.ttsClickEnabled && visible) {
debug("!AUX __CLICK domPointData.element && win.READIUM2.ttsClickEnabled");
ev.preventDefault();
ev.stopPropagation();
if (ev.altKey) {
(0, readaloud_1.ttsPlay)(win.READIUM2.ttsPlaybackRate, win.READIUM2.ttsVoices, focusScrollRaw, domPointData.element, undefined, undefined, -1, ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable, ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable);
return;
}
(0, readaloud_1.ttsPlay)(win.READIUM2.ttsPlaybackRate, win.READIUM2.ttsVoices, focusScrollRaw, domPointData.element.ownerDocument.body, domPointData.element, domPointData.textNode, domPointData.textNodeOffset, ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable, ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable);
return;
}
}
if (win.READIUM2.ttsClickEnabled || win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PAUSED) || win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PLAYING)) {
debug("!AUX __CLICK skip because TTS playing/paused");
ev.preventDefault();
return;
}
let linkElement;
let HTMLImg_SVGImage_SVGFragment;
let href_src;
let href_src_image_nested_in_link;
let isSVGFragment = false;
let isSVGImage = false;
let globalSVGDefs;
let currentElement = ev.target;
while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {
const tagName = currentElement.tagName.toLowerCase();
if ((tagName === "img" || tagName === "image" || tagName === "svg")
&& !currentElement.classList.contains(styles_2.POPOUTIMAGE_CONTAINER_ID)) {
isSVGFragment = false;
if (tagName === "svg") {
if (HTMLImg_SVGImage_SVGFragment) {
currentElement = currentElement.parentNode;
isSVGImage = true;
continue;
}
isSVGFragment = true;
href_src = currentElement.outerHTML;
const defs = currentElement.querySelectorAll("defs > *[id]");
debug("SVG INNER defs: ", defs.length);
const uses = currentElement.querySelectorAll("use");
debug("SVG INNER uses: ", uses.length);
const useIDs = [];
uses.forEach((useElem) => {
const href = useElem.getAttribute("href") || useElem.getAttributeNS("http://www.w3.org/1999/xlink", "href");
if (href === null || href === void 0 ? void 0 : href.startsWith("#")) {
const id = href.substring(1);
let found = false;
for (let i = 0; i < defs.length; i++) {
const defElem = defs[i];
if (defElem.getAttribute("id") === id) {
found = true;
break;
}
}
if (!found) {
debug("SVG INNER use (need inject def): ", id);
useIDs.push(id);
}
else {
debug("SVG INNER use (already has def): ", id);
}
}
});
let defsToInject = "";
for (const useID of useIDs) {
if (!globalSVGDefs) {
globalSVGDefs = win.document.querySelectorAll("defs > *[id]");
}
debug("SVG GLOBAL defs: ", globalSVGDefs.length);
let found = false;
globalSVGDefs.forEach((globalSVGDef) => {
if (globalSVGDef.getAttribute("id") === useID) {
found = true;
const outer = globalSVGDef.outerHTML;
if (outer.includes("<use")) {
debug("!!!!!! SVG WARNING use inside def: " + outer);
}
defsToInject += outer;
}
});
if (found) {
debug("SVG GLOBAL def for INNER use id: ", useID);
}
else {
debug("no SVG GLOBAL def for INNER use id!! ", useID);
}
}
if (href_src.indexOf("<defs") >= 0) {
href_src = href_src.replace(/<\/defs>/, `${defsToInject} </defs>`);
}
else {
href_src = href_src.replace(/>/, `> <defs> ${defsToInject} </defs>`);
}
href_src = href_src.replace(/:href[\s]*=(["|'])(.+?)(["|'])/g, (match, ...args) => {
const l = args[1].trim();
const ret = l.startsWith("#") || l.startsWith("/") || l.startsWith("data:") || /https?:/.test(l) ? match :
`:href=${args[0]}${new URL(l, win.location.origin + win.location.pathname)}${args[2]}`;
debug("SVG URL REPLACE: ", match, ret);
return ret;
});
href_src = href_src.replace(/url[\s]*\((.+?)\)/g, (match, ...args) => {
const l = args[0].trim();
const ret = l.startsWith("#") || l.startsWith("/") || l.startsWith("data:") || /https?:/.test(l) ? match :
`url(${new URL(l, win.location.origin + win.location.pathname)})`;
debug("SVG URL REPLACE: ", match, ret);
return ret;
});
href_src = href_src.replace(/[\r\n]/g, " ").replace(/\s\s+/g, " ").trim();
href_src = href_src.replace(/<desc[^<]+<\/desc>/g, "");
debug(`SVG CLICK: ${href_src}`);
}
else {
href_src = currentElement.src;
let href_src_ = currentElement.getAttribute("src");
if (!href_src) {
href_src = currentElement.href;
href_src_ = currentElement.getAttribute("href") || currentElement.getAttributeNS("http://www.w3.org/1999/xlink", "href");
}
debug(`IMG CLICK: ${href_src} (${href_src_})`);
}
HTMLImg_SVGImage_SVGFragment = currentElement;
}
else if (tagName === "a") {
if (href_src) {
href_src_image_nested_in_link = href_src;
}
href_src = currentElement.href;
const href_ = currentElement.getAttribute("href") || currentElement.getAttributeNS("http://www.w3.org/1999/xlink", "href");
linkElement = currentElement;
debug(`A LINK CLICK: ${href_src} (${href_})`);
break;
}
currentElement = currentElement.parentNode;
}
currentElement = undefined;
if (!href_src || (!HTMLImg_SVGImage_SVGFragment && !linkElement)) {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
if (href_src_image_nested_in_link && href_src_image_nested_in_link.animVal) {
href_src_image_nested_in_link = href_src_image_nested_in_link.animVal;
if (!href_src_image_nested_in_link) {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
}
if (href_src.animVal) {
href_src = href_src.animVal;
if (!href_src) {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
}
if (typeof href_src !== "string") {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
if (href_src_image_nested_in_link && typeof href_src_image_nested_in_link !== "string") {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
debug(`HREF SRC: ${href_src} ${href_src_image_nested_in_link} (${win.location.href})`);
const has = HTMLImg_SVGImage_SVGFragment === null || HTMLImg_SVGImage_SVGFragment === void 0 ? void 0 : HTMLImg_SVGImage_SVGFragment.hasAttribute(`data-${styles_2.POPOUTIMAGE_CONTAINER_ID}`);
if (HTMLImg_SVGImage_SVGFragment && href_src && (has ||
((!linkElement && !win.READIUM2.isFixedLayout && !isSVGFragment) || ev.shiftKey))) {
if (linkElement && href_src_image_nested_in_link) {
href_src = href_src_image_nested_in_link;
}
(0, readium_css_1.clearImageZoomOutline)();
ev.preventDefault();
ev.stopPropagation();
if (has) {
if (!isSVGFragment &&
!/^(https?|thoriumhttps):\/\//.test(href_src) &&
!href_src.startsWith((sessions_1.READIUM2_ELECTRON_HTTP_PROTOCOL + "://"))) {
const destUrl = new URL(href_src, win.location.origin + win.location.pathname);
href_src = destUrl.toString();
debug(`IMG CLICK ABSOLUTE-ized: ${href_src}`);
}
const cssSelectorOf_HTMLImg_SVGImage_SVGFragment = getCssSelector(HTMLImg_SVGImage_SVGFragment);
debug("R2_EVENT_IMAGE_CLICK (ipcRenderer.sendToHost) href: " + href_src + " ___ " + cssSelectorOf_HTMLImg_SVGImage_SVGFragment);
let hostDocumentURL = `${win.document.location.protocol}//${win.document.location.host}${win.document.location.pathname}`;
if (hostDocumentURL.startsWith(sessions_1.READIUM2_ELECTRON_HTTP_PROTOCOL)) {
hostDocumentURL = (0, sessions_1.convertCustomSchemeToHttpUrl)(hostDocumentURL);
const u = new URL(hostDocumentURL);
hostDocumentURL = u.pathname.replace("/pub/", "");
hostDocumentURL = hostDocumentURL.substring(hostDocumentURL.indexOf("/") + 1);
}
const payload = {
hostDocumentURL,
isSVGFragment,
isSVGImage,
HTMLImgSrc_SVGImageHref_SVGFragmentMarkup: href_src,
cssSelectorOf_HTMLImg_SVGImage_SVGFragment,
languageOf_HTMLImg_SVGImage_SVGFragment: (0, dom_text_utils_1.getLanguage)(HTMLImg_SVGImage_SVGFragment),
directionOf_HTMLImg_SVGImage_SVGFragment: (0, dom_text_utils_1.getDirection)(HTMLImg_SVGImage_SVGFragment),
altAttributeOf_HTMLImg_SVGImage_SVGFragment: HTMLImg_SVGImage_SVGFragment.getAttribute("alt"),
titleAttributeOf_HTMLImg_SVGImage_SVGFragment: HTMLImg_SVGImage_SVGFragment.getAttribute("title"),
ariaLabelAttributeOf_HTMLImg_SVGImage_SVGFragment: HTMLImg_SVGImage_SVGFragment.getAttribute("aria-label"),
naturalWidthOf_HTMLImg_SVGImage: isSVGFragment ? undefined :
isSVGImage ? (HTMLImg_SVGImage_SVGFragment.naturalWidth || undefined) :
HTMLImg_SVGImage_SVGFragment.naturalWidth,
naturalHeightOf_HTMLImg_SVGImage: isSVGFragment ? undefined :
isSVGImage ? (HTMLImg_SVGImage_SVGFragment.naturalHeight || undefined) :
HTMLImg_SVGImage_SVGFragment.naturalHeight,
};
payload.naturalWidthOf_HTMLImg_SVGImage = payload.naturalWidthOf_HTMLImg_SVGImage || undefined;
payload.naturalHeightOf_HTMLImg_SVGImage = payload.naturalHeightOf_HTMLImg_SVGImage || undefined;
if (!isSVGFragment &&
!payload.naturalWidthOf_HTMLImg_SVGImage || !payload.naturalHeightOf_HTMLImg_SVGImage) {
const imageObject = new Image();
imageObject.onload = function () {
payload.naturalWidthOf_HTMLImg_SVGImage = imageObject.naturalWidth || undefined;
payload.naturalHeightOf_HTMLImg_SVGImage = imageObject.naturalHeight || undefined;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_IMAGE_CLICK, payload);
};
imageObject.onerror = function () {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_IMAGE_CLICK, payload);
};
imageObject.src = href_src;
}
else {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_IMAGE_CLICK, payload);
}
}
else {
HTMLImg_SVGImage_SVGFragment.setAttribute(`data-${styles_2.POPOUTIMAGE_CONTAINER_ID}`, "1");
}
return;
}
if (!linkElement || !href_src) {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
const hrefStr = href_src;
if (/^javascript:/.test(hrefStr)) {
(0, readium_css_1.clearImageZoomOutline)();
return;
}
(0, readium_css_1.clearImageZoomOutline)();
ev.preventDefault();
ev.stopPropagation();
const skipHistory = !!linkElement.__skipHistory;
linkElement.__skipHistory = undefined;
const encCssSel = (0, UrlUtils_1.encodeURIComponent_RFC3986)(getCssSelector(linkElement));
if (!skipHistory) {
const payload = {
url: "#" + url_params_1.FRAG_ID_CSS_SELECTOR + encCssSel,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_LINK, payload);
}
const done = await (0, popupFootNotes_1.popupFootNote)(linkElement, focusScrollRaw, hrefStr, ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable, ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable);
if (done) {
if (!skipHistory) {
const payload = {
url: "#" + url_params_1.FRAG_ID_CSS_SELECTOR_ACTIVATE_LINK + encCssSel,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_LINK, payload);
}
}
else {
focusScrollDebounced.clear();
processXYDebouncedImmediate.clear();
notifyReadingLocationDebounced.clear();
notifyReadingLocationDebouncedImmediate.clear();
scrollToHashDebounced.clear();
onScrollDebounced.clear();
onResizeDebounced.clear();
handleFocusInDebounced.clear();
if (!skipHistory) {
const payload = {
url: hrefStr,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_LINK, payload);
}
}
}, true);
electron_1.ipcRenderer.on("R2_EVENT_IMAGE_CLICK", (_event, payload) => {
debug("R2_EVENT_IMAGE_CLICK (ipcRenderer.on) href: " + JSON.stringify(payload, null, 4));
const HTMLImg_SVGImage_SVGFragment = win.document.querySelector(payload.cssSelectorOf_HTMLImg_SVGImage_SVGFragment);
if (HTMLImg_SVGImage_SVGFragment) {
(0, popoutImages_1.popoutImage)(win, payload.cssSelectorOf_HTMLImg_SVGImage_SVGFragment, HTMLImg_SVGImage_SVGFragment, payload.HTMLImgSrc_SVGImageHref_SVGFragmentMarkup, payload.isSVGFragment, payload.isSVGImage, focusScrollRaw, ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable, ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable);
}
});
electron_1.ipcRenderer.on("R2_EVENT_WINDOW_RESIZE", (_event, zoomPercent) => {
debug("R2_EVENT_WINDOW_RESIZE zoomPercent " + zoomPercent);
win.READIUM2.fxlZoomPercent = zoomPercent;
if (!win.READIUM2.isFixedLayout) {
debug("R2_EVENT_WINDOW_RESIZE skipped, !FXL");
return;
}
const wh = (0, readium_css_inject_1.configureFixedLayout)(win.document, win.READIUM2.isFixedLayout, win.READIUM2.fxlViewportWidth, win.READIUM2.fxlViewportHeight, win.innerWidth, win.innerHeight, win.READIUM2.webViewSlot, win.READIUM2.fxlZoomPercent);
if (wh) {
win.READIUM2.fxlViewportWidth = wh.width;
win.READIUM2.fxlViewportHeight = wh.height;
win.READIUM2.fxlViewportScale = wh.scale;
const payload = {
fxl: wh,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_FXL_CONFIGURE, payload);
}
else {
const payload = {
fxl: null,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_FXL_CONFIGURE, payload);
}
(0, highlight_2.recreateAllHighlightsRaw)(win);
});
const onResizeRaw = () => {
if (win.READIUM2.isFixedLayout) {
debug("scrollToHashRaw skipped, FXL");
return;
}
if (DEBUG_TRACE)
debug("onResizeRaw: scrollToHashDebounced()...");
scrollToHashDebounced(false);
};
const onResizeDebounced = debounce(() => {
if (DEBUG_TRACE)
debug("onResizeDebounced: onResizeRaw()...");
onResizeRaw();
}, 200);
let _firstWindowResize = true;
win.addEventListener("resize", () => {
if (_firstWindowResize) {
debug("Window resize (WEBVIEW), SKIP FIRST");
_firstWindowResize = false;
(0, highlight_2.recreateAllHighlights)(win);
return;
}
if (DEBUG_TRACE)
debug(" loaded() RESIZE: onResizeDebounced()...");
onResizeDebounced();
});
let _wheelTimeStamp = -1;
let _wheelSpin = 0;
const wheelDebounced = (ev) => {
const now = (new Date()).getTime();
if (_wheelTimeStamp === -1) {
_wheelTimeStamp = now;
}
else {
const msDiff = now - _wheelTimeStamp;
if (msDiff < 500) {
return;
}
}
if (win.READIUM2.isAudio || win.READIUM2.isFixedLayout || !win.document.body) {
return;
}
if (!win.document || !win.document.documentElement) {
return;
}
const documant = win.document;
const isPaged = (0, readium_css_inject_1.isPaginated)(documant);
if (isPaged) {
return;
}
const delta = Math.abs(ev.deltaY);
_wheelSpin += delta;
if (_wheelSpin < 300) {
return;
}
_wheelSpin = 0;
_wheelTimeStamp = -1;
const scrollElement = (0, readium_css_1.getScrollingElement)(documant);
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
const goPREVIOUS = ev.deltaY < 0;
if (!goPREVIOUS) {
const maxScrollShift = (0, readium_css_1.calculateMaxScrollShift)().maxScrollShift;
const maxScrollShiftTolerated = maxScrollShift - CSS_PIXEL_TOLERANCE;
if (isPaged) {
const unit = isVWM ?
scrollElement.offsetHeight :
scrollElement.offsetWidth;
let scrollElementOffset = Math.round(isVWM ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
const isNegative = scrollElementOffset < 0;
const scrollElementOffsetAbs = Math.abs(scrollElementOffset);
const fractional = scrollElementOffsetAbs / unit;
const integral = Math.floor(fractional);
const decimal = fractional - integral;
const 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 (isVWM && (scrollElementOffsetAbs >= maxScrollShiftTolerated) ||
!isVWM && (scrollElementOffsetAbs >= maxScrollShiftTolerated)) {
const payload = {
go: "NEXT",
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if (isVWM && (Math.abs(scrollElement.scrollLeft) >= maxScrollShiftTolerated) ||
!isVWM && (Math.abs(scrollElement.scrollTop) >= maxScrollShiftTolerated)) {
const payload = {
go: "NEXT",
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
}
else if (goPREVIOUS) {
if (isPaged) {
const unit = isVWM ?
scrollElement.offsetHeight :
scrollElement.offsetWidth;
let scrollElementOffset = Math.round(isVWM ?
scrollElement.scrollTop :
scrollElement.scrollLeft);
const isNegative = scrollElementOffset < 0;
const scrollElementOffsetAbs = Math.abs(scrollElementOffset);
const fractional = scrollElementOffsetAbs / unit;
const integral = Math.floor(fractional);
const decimal = fractional - integral;
const 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 (isVWM && (scrollElementOffsetAbs <= 0) ||
!isVWM && (scrollElementOffsetAbs <= 0)) {
const payload = {
go: "PREVIOUS",
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
else {
if (isVWM && (Math.abs(scrollElement.scrollLeft) <= 0) ||
!isVWM && (Math.abs(scrollElement.scrollTop) <= 0)) {
const payload = {
go: "PREVIOUS",
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_PAGE_TURN_RES, payload);
return;
}
}
}
};
win.document.addEventListener("wheel", wheelDebounced);
win.document.addEventListener("scroll", (_ev) => {
_wheelSpin = 0;
_wheelTimeStamp = -1;
});
setTimeout(() => {
win.addEventListener("scroll", (_ev) => {
if (_ignoreScrollEvent) {
return;
}
if (_lastAnimState && _lastAnimState.animating) {
debug("_lastAnimState");
return;
}
if (_lastAnimState2 && _lastAnimState2.animating) {
debug("_lastAnimState2");
return;
}
if (!win.document || !win.document.documentElement) {
return;
}
onScrollDebounced(true);
});
}, 200);
function handleMouseEvent(ev) {
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
return;
}
if (styles_1.ENABLE_SKIP_LINK && win.document.activeElement &&
win.document.activeElement === win.document.getElementById(styles_2.SKIP_LINK_ID)) {
debug(".hashElement = 5 => SKIP_LINK_ID mouse click event - screen reader VoiceOver generates mouse click / non-keyboard event");
return;
}
const x = ev.clientX;
const y = ev.clientY;
console.log("MOUSEUP ev.clientX/Y", ev.clientX, ev.clientY);
if (DEBUG_TRACE)
debug("handleMouseEvent: processXYDebouncedImmediate()...");
processXYDebouncedImmediate(x, y, false, true);
}
win.document.documentElement.addEventListener("mouseup", (ev) => {
handleMouseEvent(ev);
});
win.document.addEventListener("mouseup", (ev) => {
if (ev.target && ev.target.getAttribute) {
const iBooksMO = ev.target.getAttribute("ibooks:readaloud") ||
ev.target.getAttribute("readaloud");
if (iBooksMO) {
const payload = {
start: iBooksMO === "start" ? true : undefined,
startstop: iBooksMO === "startstop" ? true : undefined,
stop: iBooksMO === "stop" ? true : undefined,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_MEDIA_OVERLAY_STARTSTOP, payload);
}
}
}, true);
win.document.body.addEventListener("copy", (evt) => {
if (win.READIUM2.isClipboardIntercept) {
const selection = win.document.getSelection();
if (selection) {
const str = selection.toString();
if (str) {
evt.preventDefault();
setTimeout(() => {
const payload = {
locator: win.READIUM2.locationHashOverrideInfo,
txt: str,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_CLIPBOARD_COPY, payload);
}, 500);
}
}
}
});
}
win.addEventListener("load", () => {
debug("############# load");
loaded(false);
});
function checkBlacklisted(el) {
const id = el.getAttribute("id");
if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {
if (IS_DEV && id !== styles_2.SKIP_LINK_ID) {
debug("checkBlacklisted ID: " + id);
}
return true;
}
for (const item of _blacklistIdClassForCFI) {
if (el.classList.contains(item)) {
if (IS_DEV) {
debug("checkBlacklisted CLASS: " + item);
}
return true;
}
}
const mathJax = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_MATHJAX);
if (mathJax) {
const low = el.tagName.toLowerCase();
for (const item of _blacklistIdClassForCFIMathJax) {
if (low.startsWith(item)) {
if (IS_DEV) {
debug("checkBlacklisted MathJax ELEMENT NAME: " + el.tagName);
}
return true;
}
}
if (id) {
const lowId = id.toLowerCase();
for (const item of _blacklistIdClassForCFIMathJax) {
if (lowId.startsWith(item)) {
if (IS_DEV) {
debug("checkBlacklisted MathJax ID: " + id);
}
return true;
}
}
}
for (let i = 0; i < el.classList.length; i++) {
const cl = el.classList[i];
const lowCl = cl.toLowerCase();
for (const item of _blacklistIdClassForCFIMathJax) {
if (lowCl.startsWith(item)) {
if (IS_DEV) {
debug("checkBlacklisted MathJax CLASS: " + cl);
}
return true;
}
}
}
}
return false;
}
function findFirstVisibleElement(rootElement) {
const blacklisted = checkBlacklisted(rootElement);
if (blacklisted) {
return undefined;
}
for (let i = 0; i < rootElement.children.length; i++) {
const child = rootElement.children[i];
if (child.nodeType !== Node.ELEMENT_NODE) {
continue;
}
const visibleElement = findFirstVisibleElement(child);
if (visibleElement) {
return visibleElement;
}
}
if (rootElement !== win.document.body &&
rootElement !== win.document.documentElement) {
if (isVisible(false, rootElement, undefined)) {
return rootElement;
}
}
return undefined;
}
const domDataFromPoint = (x, y) => {
var _a;
const domPointData = {
textNode: undefined,
textNodeOffset: -1,
element: undefined,
};
const range = win.document.caretRangeFromPoint(x, y);
if (range) {
const node = range.startContainer;
if (node) {
if (node.nodeType === Node.ELEMENT_NODE) {
domPointData.element = node;
const childrenCount = (_a = domPointData.element.childNodes) === null || _a === void 0 ? void 0 : _a.length;
if (childrenCount > 0 &&
range.startOffset > 0 &&
range.startOffset === range.endOffset &&
range.startOffset < childrenCount) {
let c = domPointData.element.childNodes[range.startOffset];
if (c.nodeType === Node.ELEMENT_NODE) {
domPointData.element = c;
}
else if (c.nodeType === Node.TEXT_NODE && range.startOffset > 0) {
c = domPointData.element.childNodes[range.startOffset - 1];
if ((c === null || c === void 0 ? void 0 : c.nodeType) === Node.ELEMENT_NODE) {
domPointData.element = c;
}
}
}
}
else if (node.nodeType === Node.TEXT_NODE) {
domPointData.textNode = node;
domPointData.textNodeOffset = range.startOffset;
if (node.parentNode && node.parentNode.nodeType === Node.ELEMENT_NODE) {
domPointData.element = node.parentNode;
}
if (!domPointData.element && node.parentElement) {
domPointData.element = node.parentElement;
}
}
}
}
return domPointData;
};
const processXYRaw = (x, y, reverse, userInteract, fromViewportScroll) => {
var _a, _b, _c, _d, _e, _f;
if (DEBUG_TRACE)
debug("processXYRaw");
if (DEBUG_TRACE)
debug("reverse", reverse);
if (DEBUG_TRACE)
debug("userInteract", userInteract);
if (DEBUG_TRACE)
debug("fromViewportScroll", fromViewportScroll);
if (DEBUG_TRACE)
debug("x y: ", x, y);
if (DEBUG_TRACE)
debug("document.documentElement.clientWidth/Height: ", win.document.documentElement.clientWidth, win.document.documentElement.clientHeight);
if (DEBUG_TRACE)
debug("document.documentElement.offsetWidth/Height: ", win.document.documentElement.offsetWidth, win.document.documentElement.offsetHeight);
if (DEBUG_TRACE)
debug("document.documentElement.scrollWidth/Height: ", win.document.documentElement.scrollWidth, win.document.documentElement.scrollHeight);
if (DEBUG_TRACE)
debug("document.documentElement.scrollTop/Left: ", win.document.documentElement.scrollTop, win.document.documentElement.scrollLeft);
if (DEBUG_TRACE)
debug("document.body.clientWidth/Height: ", win.document.body.clientWidth, win.document.body.clientHeight);
if (DEBUG_TRACE)
debug("document.body.offsetWidth/Height: ", win.document.body.offsetWidth, win.document.body.offsetHeight);
if (DEBUG_TRACE)
debug("document.body.scrollWidth/Height: ", win.document.body.scrollWidth, win.document.body.scrollHeight);
if (DEBUG_TRACE)
debug("document.body.scrollTop/Left: ", win.document.body.scrollTop, win.document.body.scrollLeft);
if (DEBUG_TRACE) {
const bodyComputedStyle = win.getComputedStyle(win.document.body);
const zoomStr = bodyComputedStyle.zoom || "1";
const zoomFactor = parseFloat(zoomStr);
debug("document.body.style.zoom", zoomFactor);
}
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
debug("processXYRaw: isPopupDialogOpen SKIP");
return;
}
win.READIUM2.lastClickedTextChar = undefined;
const domPointData = domDataFromPoint(x, y);
if (DEBUG_TRACE)
debug("processXYRaw: domDataFromPoint => ", domPointData.element ? getCssSelector(domPointData.element) : "!!!? domPointData.element");
if (!domPointData.element ||
domPointData.element === win.document.body ||
domPointData.element === win.document.documentElement) {
const root = win.document.body;
domPointData.element = findFirstVisibleElement(root);
if (!domPointData.element) {
if (DEBUG_TRACE)
debug("processXYRaw: findFirstVisibleElement1 FAIL? (BODY fallback)");
domPointData.element = win.document.body;
domPointData.textNode = undefined;
domPointData.textNodeOffset = -1;
}
else {
if (DEBUG_TRACE)
debug("processXYRaw: findFirstVisibleElement1 => ", getCssSelector(domPointData.element));
}
}
else if (!userInteract &&
domPointData.element &&
!isVisible(false, domPointData.element, undefined)) {
let next = domPointData.element;
let found;
while (next) {
const firstInside = findFirstVisibleElement(next);
if (firstInside) {
found = firstInside;
break;
}
let sibling = reverse ? next.previousElementSibling : next.nextElementSibling;
let parent = next;
while (!sibling) {
parent = parent.parentNode;
if (!parent || parent.nodeType !== Node.ELEMENT_NODE) {
break;
}
sibling = reverse ?
parent.previousElementSibling :
parent.nextElementSibling;
}
next = sibling ? sibling : undefined;
}
if (found) {
if (DEBUG_TRACE)
debug("processXYRaw: findFirstVisibleElement2 => ", getCssSelector(domPointData.element));
domPointData.element = found;
domPointData.textNode = undefined;
domPointData.textNodeOffset = -1;
}
else {
if (DEBUG_TRACE)
debug("processXYRaw: findFirstVisibleElement *AFTER* FAIL?");
}
}
if (domPointData.element === win.document.body ||
domPointData.element === win.document.documentElement) {
if (DEBUG_TRACE)
debug("processXYRaw: domPointData.element HTML BODY?");
}
if (domPointData.element) {
if (DEBUG_TRACE)
debug("processXYRaw: branch1 => ", getCssSelector(domPointData.element), win.READIUM2.locationHashOverride ? getCssSelector(win.READIUM2.locationHashOverride) : "!!!win.READIUM2.locationHashOverride");
if (userInteract ||
!win.READIUM2.locationHashOverride ||
win.READIUM2.locationHashOverride === win.document.body ||
win.READIUM2.locationHashOverride === win.document.documentElement) {
if (DEBUG_TRACE)
debug("processXYRaw: branch1.1");
if (((_b = (_a = domPointData.textNode) === null || _a === void 0 ? void 0 : _a.nodeValue) === null || _b === void 0 ? void 0 : _b.length) && domPointData.textNodeOffset >= 0 && domPointData.textNodeOffset <= domPointData.textNode.nodeValue.length) {
win.READIUM2.lastClickedTextChar = {
textNode: domPointData.textNode,
textNodeOffset: domPointData.textNodeOffset,
};
}
win.READIUM2.hashElement = userInteract ? domPointData.element : win.READIUM2.hashElement;
win.READIUM2.locationHashOverride = domPointData.element;
}
else {
if (DEBUG_TRACE)
debug("processXYRaw: branch1.2");
if (!isVisible(false, win.READIUM2.locationHashOverride, undefined)) {
if (DEBUG_TRACE)
debug("processXYRaw: branch1.2.1");
if (((_d = (_c = domPointData.textNode) === null || _c === void 0 ? void 0 : _c.nodeValue) === null || _d === void 0 ? void 0 : _d.length) && domPointData.textNodeOffset >= 0 && domPointData.textNodeOffset <= domPointData.textNode.nodeValue.length) {
win.READIUM2.lastClickedTextChar = {
textNode: domPointData.textNode,
textNodeOffset: domPointData.textNodeOffset,
};
}
win.READIUM2.hashElement = userInteract ? domPointData.element : win.READIUM2.hashElement;
win.READIUM2.locationHashOverride = domPointData.element;
}
else if (win.READIUM2.hashElement !== win.READIUM2.locationHashOverride &&
(win.READIUM2.ttsClickEnabled ||
win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PLAYING) ||
win.document.documentElement.classList.contains(styles_2.TTS_CLASS_PAUSED))) {
if (DEBUG_TRACE)
debug("processXYRaw: branch1.2.2");
if (((_f = (_e = domPointData.textNode) === null || _e === void 0 ? void 0 : _e.nodeValue) === null || _f === void 0 ? void 0 : _f.length) && domPointData.textNodeOffset >= 0 && domPointData.textNodeOffset <= domPointData.textNode.nodeValue.length) {
win.READIUM2.lastClickedTextChar = {
textNode: domPointData.textNode,
textNodeOffset: domPointData.textNodeOffset,
};
}
win.READIUM2.hashElement = userInteract ? domPointData.element : win.READIUM2.hashElement;
win.READIUM2.locationHashOverride = domPointData.element;
}
}
if (userInteract && win.READIUM2.DEBUG_VISUALS) {
if (DEBUG_TRACE)
debug("processXYRaw: notifyReadingLocationDebouncedImmediate()...");
notifyReadingLocationDebouncedImmediate(userInteract);
}
else {
if (fromViewportScroll && win.READIUM2.accessibilitySupportEnabled) {
if (DEBUG_TRACE)
debug("processXYRaw: scroll-screen-reader + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced(userInteract, false, true);
}
else {
if (DEBUG_TRACE)
debug("processXYRaw: !scroll-screen-reader + notifyReadingLocationDebounced()...");
notifyReadingLocationDebounced(userInteract);
}
}
if (userInteract && win.READIUM2.locationHashOverride) {
if (DEBUG_TRACE)
debug("processXYRaw: focusElement()...");
focusElement(win.READIUM2.locationHashOverride, true);
}
if (win.READIUM2.DEBUG_VISUALS) {
const el = win.READIUM2.locationHashOverride ? win.READIUM2.locationHashOverride : domPointData.element;
const existings = win.document.querySelectorAll(`*[${styles_2.readPosCssStylesAttr2}]`);
existings.forEach((existing) => {
existing.removeAttribute(`${styles_2.readPosCssStylesAttr2}`);
});
el.setAttribute(styles_2.readPosCssStylesAttr2, "processXYRaw");
}
}
debug("processXYRaw EXIT");
};
const processXYDebouncedImmediate = debounce((x, y, reverse, userInteract) => {
if (DEBUG_TRACE)
debug("processXYDebouncedImmediate: processXYRaw()...");
if (DEBUG_TRACE)
debug("x y: ", x, y);
processXYRaw(x, y, reverse, userInteract);
}, 300, { immediate: true });
const computeProgressionData = () => {
const isPaged = (0, readium_css_inject_1.isPaginated)(win.document);
const isTwoPage = (0, readium_css_1.isTwoPageSpread)();
const { maxScrollShift, maxScrollShiftAdjusted } = (0, readium_css_1.calculateMaxScrollShift)();
const totalColumns = (0, readium_css_1.calculateTotalColumns)();
let progressionRatio = 0;
let currentColumn = 0;
const scrollElement = (0, readium_css_1.getScrollingElement)(win.document);
const isVWM = (0, readium_css_1.isVerticalWritingMode)();
let extraShift = 0;
if (isPaged) {
if (maxScrollShift > 0) {
if (isVWM) {
progressionRatio = scrollElement.scrollTop / maxScrollShift;
}
else {
extraShift = styles_2.ENABLE_EXTRA_COLUMN_SHIFT_METHOD ? scrollElement.scrollLeftExtra : 0;
if (extraShift) {
progressionRatio = ((((0, readium_css_1.isRTL)() ? -1 : 1) * scrollElement.scrollLeft) + extraShift) /
maxScrollShiftAdjusted;
}
else {
progressionRatio = (((0, readium_css_1.isRTL)() ? -1 : 1) * scrollElement.scrollLeft) / maxScrollShift;
}
}
}
const adjustedTotalColumns = (extraShift ? (totalColumns + 1) : totalColumns) - (isTwoPage ? 2 : 1);
currentColumn = adjustedTotalColumns * progressionRatio;
currentColumn = Math.round(currentColumn);
}
else {
if (maxScrollShift > 0) {
if (isVWM) {
progressionRatio = Math.abs(scrollElement.scrollLeft) / maxScrollShift;
}
else {
progressionRatio = scrollElement.scrollTop / maxScrollShift;
}
}
}
if (win.READIUM2.locationHashOverride) {
const element = win.READIUM2.locationHashOverride;
let offset = 0;
if (isPaged) {
if (isVisible(false, element, undefined)) {
const curCol = extraShift ? (currentColumn - 1) : currentColumn;
const columnDimension = (0, readium_css_1.calculateColumnDimension)();
if (isVWM) {
const rect = element.getBoundingClientRect();
offset = (curCol * scrollElement.scrollWidth) + rect.left +
(rect.top >= columnDimension ? scrollElement.scrollWidth : 0);
}
else {
const boundingRect = element.getBoundingClientRect();
const clientRects = (0, rect_utils_1.getClientRectsNoOverlap)((0, rect_utils_1.DOMRectListToArray)(element.getClientRects()), false, isVWM);
let rectangle;
for (const rect of clientRects) {
if (!rectangle) {
rectangle = rect;
continue;
}
if ((0, readium_css_1.isRTL)()) {
if ((rect.left + rect.width) > (columnDimension * (isTwoPage ? 2 : 1))) {
continue;
}
if (isTwoPage) {
if ((boundingRect.left + boundingRect.width) >= columnDimension &&
(rect.left + rect.width) < columnDimension) {
continue;
}
}
if ((boundingRect.left + boundingRect.width) >= 0 &&
(rect.left + rect.width) < 0) {
continue;
}
}
else {
if (rect.left < 0) {
continue;
}
if (boundingRect.left < columnDimension &&
rect.left >= columnDimension) {
continue;
}
if (isTwoPage) {
const boundary = 2 * columnDimension;
if (boundingRect.left < boundary &&
rect.left >= boundary) {
continue;
}
}
}
if (rect.top < rectangle.top) {
rectangle = rect;
continue;
}
}
if (!rectangle) {
rectangle = element.getBoundingClientRect();
}
offset = (curCol * scrollElement.scrollHeight) + rectangle.top;
if (isTwoPage) {
if ((0, readium_css_1.isRTL)()) {
if (rectangle.left < columnDimension) {
offset += scrollElement.scrollHeight;
}
}
else {
if (rectangle.left >= columnDimension) {
offset += scrollElement.scrollHeight;
}
}
}
}
const totalDocumentDimension = ((isVWM ? scrollElement.scrollWidth :
scrollElement.scrollHeight) * totalColumns);
progressionRatio = offset / totalDocumentDimension;
currentColumn = totalColumns * progressionRatio;
currentColumn = Math.floor(currentColumn);
}
}
else {
const rect = element.getBoundingClientRect();
if (isVWM) {
offset = scrollElement.scrollLeft + rect.left;
}
else {
offset = scrollElement.scrollTop + rect.top;
}
progressionRatio =
(isVWM ? Math.abs(offset - win.document.documentElement.clientWidth) : offset)
/
(isVWM ? scrollElement.scrollWidth : scrollElement.scrollHeight);
}
}
let spreadIndex = 0;
if (isPaged) {
spreadIndex = isTwoPage ? Math.floor(currentColumn / 2) : currentColumn;
}
return {
paginationInfo: isPaged ? {
currentColumn,
isTwoPageSpread: isTwoPage,
spreadIndex,
totalColumns,
} : undefined,
percentRatio: progressionRatio,
};
};
const _blacklistIdClassForCssSelectors = [styles_2.EXTRA_COLUMN_PAD_ID, styles_2.LINK_TARGET_CLASS, styles_2.LINK_TARGET_ALT_CLASS, styles_2.CSS_CLASS_NO_FOCUS_OUTLINE, styles_2.SKIP_LINK_ID, styles_2.POPUP_DIALOG_CLASS, styles_2.ID_HIGHLIGHTS_CONTAINER, styles_1.ID_HIGHLIGHTS_FLOATING, styles_1.ID_HIGHLIGHTS_FLOATING + "_", styles_2.CLASS_HIGHLIGHT_CONTAINER, styles_2.CLASS_HIGHLIGHT_CONTOUR, styles_2.CLASS_HIGHLIGHT_CONTOUR_MARGIN, styles_2.TTS_ID_SPEAKING_DOC_ELEMENT, styles_2.ROOT_CLASS_KEYBOARD_INTERACT, styles_2.ROOT_CLASS_INVISIBLE_MASK, styles_2.ROOT_CLASS_INVISIBLE_MASK_REMOVED, styles_2.CLASS_PAGINATED, styles_2.ROOT_CLASS_NO_FOOTNOTES, styles_2.ROOT_CLASS_NO_RUBY];
const _blacklistIdClassForCssSelectorsMathJax = ["mathjax", "ctxt", "mjx", "r2-wbr"];
const _blacklistIdClassForCFI = [styles_2.EXTRA_COLUMN_PAD_ID, styles_2.SKIP_LINK_ID, styles_2.POPUP_DIALOG_CLASS, styles_2.ID_HIGHLIGHTS_CONTAINER, styles_1.ID_HIGHLIGHTS_FLOATING, styles_1.ID_HIGHLIGHTS_FLOATING + "_", styles_2.CLASS_HIGHLIGHT_CONTAINER, styles_2.CLASS_HIGHLIGHT_CONTOUR, styles_2.CLASS_HIGHLIGHT_CONTOUR_MARGIN];
const _blacklistIdClassForCFIMathJax = ["mathjax", "ctxt", "mjx", "r2-wbr"];
const computeCFI = (node) => {
if (node.nodeType !== Node.ELEMENT_NODE) {
return undefined;
}
if (node.__r2Cfi) {
return node.__r2Cfi;
}
let cfi = "";
let currentElement = node;
while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {
const blacklisted = checkBlacklisted(currentElement);
if (!blacklisted) {
const currentElementParentChildren = currentElement.parentNode.children;
let currentElementIndex = -1;
let j = 0;
for (let i = 0; i < currentElementParentChildren.length; i++) {
const childBlacklisted = checkBlacklisted(currentElementParentChildren[i]);
if (childBlacklisted) {
j++;
}
if (currentElement === currentElementParentChildren[i]) {
currentElementIndex = i;
break;
}
}
if (currentElementIndex >= 0) {
const cfiIndex = (currentElementIndex - j + 1) * 2;
cfi = cfiIndex +
(currentElement.id ? ("[" + currentElement.id + "]") : "") +
(cfi.length ? ("/" + cfi) : "");
}
}
else {
cfi = "";
}
currentElement = currentElement.parentNode;
}
node.__r2Cfi = "/" + cfi;
return node.__r2Cfi;
};
const computeXPath = (node) => {
if (node.nodeType !== Node.ELEMENT_NODE) {
return undefined;
}
if (node.__r2Xpath) {
return node.__r2Xpath;
}
let xpath = "";
let currentElement = node;
while (currentElement.parentNode && (currentElement.parentNode.nodeType === Node.ELEMENT_NODE || currentElement.parentNode.nodeType === Node.DOCUMENT_NODE)) {
const blacklisted = checkBlacklisted(currentElement);
if (!blacklisted) {
const currentElementParentChildren = currentElement.parentNode.nodeType === Node.ELEMENT_NODE ?
currentElement.parentNode.children :
[currentElement.parentNode.documentElement];
let currentElementIndex = -1;
let j = 0;
let k = -1;
for (let i = 0; i < currentElementParentChildren.length; i++) {
const child = currentElementParentChildren[i];
if (child.tagName === currentElement.tagName) {
k++;
const childBlacklisted = checkBlacklisted(child);
if (childBlacklisted) {
j++;
}
}
if (currentElement === child) {
currentElementIndex = k;
break;
}
}
if (currentElementIndex >= 0) {
const nodeIndex = currentElementIndex - j + 1;
const nsPrefix = currentElement.namespaceURI === "http://www.w3.org/1999/xhtml" ? "" :
currentElement.namespaceURI === "http://www.w3.org/2000/svg" ? "svg:" :
currentElement.namespaceURI === "http://www.w3.org/1998/Math/MathML" ? "m:" :
"";
const idAssertion = currentElement.id ? `[@id="${currentElement.id}"]` : "";
const qname = `${nsPrefix}${currentElement.tagName}`;
xpath = `${qname}[${nodeIndex}]${idAssertion}` +
(xpath.length ? ("/" + xpath) : "");
}
}
else {
xpath = "";
}
currentElement = currentElement.parentNode;
}
node.__r2Xpath = "/" + xpath;
return node.__r2Xpath;
};
const _getCssSelectorOptions = {
className: (str) => {
if (_blacklistIdClassForCssSelectors.indexOf(str) >= 0) {
return false;
}
const mathJax = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_MATHJAX);
if (mathJax) {
const low = str.toLowerCase();
for (const item of _blacklistIdClassForCssSelectorsMathJax) {
if (low.startsWith(item)) {
return false;
}
}
}
return true;
},
idName: (str) => {
if (_blacklistIdClassForCssSelectors.indexOf(str) >= 0) {
return false;
}
const mathJax = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_MATHJAX);
if (mathJax) {
const low = str.toLowerCase();
for (const item of _blacklistIdClassForCssSelectorsMathJax) {
if (low.startsWith(item)) {
return false;
}
}
}
return true;
},
tagName: (str) => {
const mathJax = win.document.documentElement.classList.contains(styles_2.ROOT_CLASS_MATHJAX);
if (mathJax) {
for (const item of _blacklistIdClassForCssSelectorsMathJax) {
if (str.startsWith(item)) {
return false;
}
}
}
return true;
},
};
function getCssSelector(element) {
try {
return (0, cssselector3_1.uniqueCssSelector)(element, win.document, _getCssSelectorOptions);
}
catch (err) {
debug("uniqueCssSelector:");
debug(err);
return "";
}
}
const _htmlNamespaces = {
epub: "http://www.idpf.org/2007/ops",
xhtml: "http://www.w3.org/1999/xhtml",
};
const _namespaceResolver = (prefix) => {
if (!prefix) {
return null;
}
return _htmlNamespaces[prefix] || null;
};
let _allHeadings;
const findPrecedingAncestorSiblingHeadings = (element) => {
if (!_allHeadings) {
const headingElements = Array.from(win.document.querySelectorAll("h1,h2,h3,h4,h5,h6"));
for (const n of headingElements) {
if (n) {
const el = n;
const t = el.textContent || el.getAttribute("title") || el.getAttribute("aria-label");
let i = el.getAttribute("id");
if (!i) {
let cur = el;
let p;
while ((p = cur.parentNode) &&
(p === null || p === void 0 ? void 0 : p.nodeType) === Node.ELEMENT_NODE) {
if (p.firstElementChild !== cur) {
break;
}
const di = p.getAttribute("id");
if (di) {
i = di;
break;
}
cur = p;
}
}
const heading = {
element: el,
id: i ? i : undefined,
level: parseInt(el.localName.substring(1), 10),
text: t ? t : undefined,
};
if (!_allHeadings) {
_allHeadings = [];
}
_allHeadings.push(heading);
}
}
if (!_allHeadings) {
_allHeadings = [];
}
debug("_allHeadings", _allHeadings.length, headingElements.length);
}
let arr;
for (let i = _allHeadings.length - 1; i >= 0; i--) {
const heading = _allHeadings[i];
const c = element.compareDocumentPosition(heading.element);
if (c === 0 || (c & Node.DOCUMENT_POSITION_PRECEDING) || (c & Node.DOCUMENT_POSITION_CONTAINS)) {
debug("preceding or containing heading", heading.id, heading.text);
if (!arr) {
arr = [];
}
arr.push({
id: heading.id,
level: heading.level,
txt: heading.text,
});
}
}
return arr;
};
let _allEpubPageBreaks;
const findPrecedingAncestorSiblingEpubPageBreak = (element) => {
if (!_allEpubPageBreaks) {
const xpathResult = win.document.evaluate("//*[contains(concat(' ', normalize-space(@role), ' '), ' doc-pagebreak ')] | //*[contains(concat(' ', normalize-space(@epub:type), ' '), ' pagebreak ')]", win.document.body, _namespaceResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < xpathResult.snapshotLength; i++) {
const n = xpathResult.snapshotItem(i);
if (n) {
const el = n;
const elTitle = el.getAttribute("title");
const elLabel = el.getAttribute("aria-label");
const elText = el.textContent;
const pageLabel = elTitle || elLabel || elText || " ";
if (pageLabel) {
const pageBreak = {
element: el,
text: pageLabel,
};
if (!_allEpubPageBreaks) {
_allEpubPageBreaks = [];
}
_allEpubPageBreaks.push(pageBreak);
}
}
}
if (!_allEpubPageBreaks) {
_allEpubPageBreaks = [];
}
debug("_allEpubPageBreaks XPath", _allEpubPageBreaks.length, xpathResult.snapshotLength);
if (highlight_2.ENABLE_PAGEBREAK_MARGIN_TEXT_EXPERIMENT) {
(0, highlight_2.destroyHighlightsGroup)(win.document, highlight_2.HIGHLIGHT_GROUP_PAGEBREAK);
const highlightDefinitions = [];
for (const pageBreak of _allEpubPageBreaks) {
const range = new Range();
range.selectNode(pageBreak.element);
highlightDefinitions.push({
color: {
blue: 60,
green: 76,
red: 231,
},
drawType: highlight_1.HighlightDrawTypeOutline,
expand: 1,
selectionInfo: undefined,
group: highlight_2.HIGHLIGHT_GROUP_PAGEBREAK,
range,
marginText: pageBreak.text ? pageBreak.text : undefined,
textPopup: undefined,
});
}
(0, highlight_2.createHighlights)(win, highlightDefinitions, true);
}
}
for (let i = _allEpubPageBreaks.length - 1; i >= 0; i--) {
const pageBreak = _allEpubPageBreaks[i];
const c = element.compareDocumentPosition(pageBreak.element);
if (c === 0 || (c & Node.DOCUMENT_POSITION_PRECEDING) || (c & Node.DOCUMENT_POSITION_CONTAINS)) {
debug("preceding or containing EPUB page break", pageBreak.text);
return { epubPage: pageBreak.text, epubPageID: pageBreak.element.getAttribute("id") || undefined };
}
}
const nil = { epubPage: undefined, epubPageID: undefined };
if (_allEpubPageBreaks.length > 0) {
const first = { epubPage: _allEpubPageBreaks[0].text, epubPageID: _allEpubPageBreaks[0].element.getAttribute("id") || undefined };
if (win.document.body.firstChild === _allEpubPageBreaks[0].element) {
debug("pagebreak first", first);
return first;
}
const range = new Range();
range.setStart(win.document.body, 0);
range.setEnd(_allEpubPageBreaks[0].element, 0);
let txt = range.toString() || "";
if (txt) {
txt = txt.trim();
}
const pass = txt.length <= 10;
debug("pagebreak first? txt", first, txt.length, pass ? txt : "");
return pass ? first : nil;
}
return nil;
};
const MAX_FOLLOWING_ELEMENTS_IDS = 100;
let _elementsWithID;
const findFollowingDescendantSiblingElementsWithID = (el) => {
let followingElementIDs;
if (win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PLAYING) ||
win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PAUSED) ||
win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_STOPPED)) {
if (!_elementsWithID) {
const elHighlightsContainer = win.document.getElementById(styles_2.ID_HIGHLIGHTS_CONTAINER);
const elPopupDialog = win.document.getElementById(styles_2.POPUP_DIALOG_CLASS);
const elSkipLink = styles_1.ENABLE_SKIP_LINK ? win.document.getElementById(styles_2.SKIP_LINK_ID) : null;
const elPad = win.document.getElementById(styles_2.EXTRA_COLUMN_PAD_ID);
_elementsWithID = Array.from(win.document.querySelectorAll(`*:not(#${styles_2.ID_HIGHLIGHTS_CONTAINER}):not(#${styles_1.ID_HIGHLIGHTS_FLOATING}):not(#${styles_1.ID_HIGHLIGHTS_FLOATING}_):not(#${styles_2.POPUP_DIALOG_CLASS}):not(#${styles_2.EXTRA_COLUMN_PAD_ID}):not(#${styles_2.SKIP_LINK_ID}) *[id]:not(#${styles_2.ID_HIGHLIGHTS_CONTAINER}):not(#${styles_1.ID_HIGHLIGHTS_FLOATING}):not(#${styles_1.ID_HIGHLIGHTS_FLOATING}_):not(#${styles_2.POPUP_DIALOG_CLASS}):not(#${styles_2.EXTRA_COLUMN_PAD_ID}):not(#${styles_2.SKIP_LINK_ID})`));
for (let i = 0; i < _elementsWithID.length; i++) {
const elementWithID = _elementsWithID[i];
const id = elementWithID.id || elementWithID.getAttribute("id");
if (!id) {
_elementsWithID[i] = null;
continue;
}
let keep = true;
if (elHighlightsContainer) {
const c1 = elHighlightsContainer.compareDocumentPosition(elementWithID);
if (c1 === 0 || (c1 & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
keep = false;
debug("findFollowingDescendantSiblingElementsWithID CSS selector failed? (highlights) " + id);
}
}
if (elPopupDialog) {
const c2 = elPopupDialog.compareDocumentPosition(elementWithID);
if (c2 === 0 || (c2 & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
keep = false;
debug("findFollowingDescendantSiblingElementsWithID CSS selector failed? (popup dialog) " + id);
}
}
if (elSkipLink) {
const c3 = elSkipLink.compareDocumentPosition(elementWithID);
if (c3 === 0 || (c3 & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
keep = false;
debug("findFollowingDescendantSiblingElementsWithID CSS selector failed? (skip link) " + id);
}
}
if (elPad) {
const c4 = elPad.compareDocumentPosition(elementWithID);
if (c4 === 0 || (c4 & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
keep = false;
debug("findFollowingDescendantSiblingElementsWithID CSS selector failed? (extra col pad) " + id);
}
}
if (!keep) {
_elementsWithID[i] = null;
}
}
_elementsWithID = _elementsWithID.filter((el) => !!el);
}
followingElementIDs = [];
for (let i = 0; i < _elementsWithID.length; i++) {
const elementWithID = _elementsWithID[i];
const id = elementWithID.id || elementWithID.getAttribute("id");
if (!id) {
continue;
}
const c = el.compareDocumentPosition(elementWithID);
if ((c & Node.DOCUMENT_POSITION_FOLLOWING) || (c & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
followingElementIDs.push(id);
if (followingElementIDs.length >= MAX_FOLLOWING_ELEMENTS_IDS) {
return followingElementIDs;
}
}
}
}
return followingElementIDs;
};
const $_htmlNamespaces = {
xhtml: "http://www.w3.org/1999/xhtml",
svg: "http://www.w3.org/2000/svg",
m: "http://www.w3.org/1998/Math/MathML",
};
const $_namespaceResolver = (prefix) => {
if (!prefix) {
return null;
}
return $_htmlNamespaces[prefix] || null;
};
const notifyReadingLocationRaw = (userInteract, ignoreMediaOverlays, doNotFocus) => {
var _a, _b;
if (DEBUG_TRACE)
debug("notifyReadingLocationRaw", win.READIUM2.locationHashOverride ? getCssSelector(win.READIUM2.locationHashOverride) : "!!!? win.READIUM2.locationHashOverride");
if (!win.READIUM2.locationHashOverride) {
return;
}
if (win.READIUM2.urlQueryParams && win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW] === "1") {
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW] = "2";
return;
}
const blacklisted = checkBlacklisted(win.READIUM2.locationHashOverride);
if (blacklisted) {
return;
}
let progressionData;
const cssSelector = getCssSelector(win.READIUM2.locationHashOverride);
const cfi = computeCFI(win.READIUM2.locationHashOverride);
const xpathalreadychecked = !!win.READIUM2.locationHashOverride.__r2Xpath;
const xpath = computeXPath(win.READIUM2.locationHashOverride);
if (IS_DEV && xpath && !xpathalreadychecked) {
debug(">>> XPATH original: " + xpath);
const xpath_ = xpath.replace(/\/([^\/]+)/g, (m) => {
if (m.startsWith("/*") ||
/^\/[a-zA-Z0-9\-_]+:[a-zA-Z0-9\-_]+.*$/.test(m)) {
return m;
}
return m.replace(/\/(.+)/g, "/xhtml:$1");
});
debug(">>> XPATH adapted: " + xpath_);
const xpathResult = win.document.evaluate(xpath_, win.document, $_namespaceResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
debug(">>> XPATH snap: " + xpathResult.snapshotLength);
if (xpathResult.snapshotLength === 1 && xpathResult.snapshotItem(0) === win.READIUM2.locationHashOverride) {
debug(">>> XPATH OK :)");
}
else {
debug(">>> XPATH NOK :(");
}
}
let progression = 0;
if (win.READIUM2.isFixedLayout) {
progression = 1;
}
else {
progressionData = computeProgressionData();
progression = progressionData.percentRatio;
}
const pinfo = (progressionData && progressionData.paginationInfo) ?
progressionData.paginationInfo : undefined;
const selInfo = (0, selection_2.getCurrentSelectionInfo)(win, getCssSelector, computeXPath);
const text = selInfo ? {
after: selInfo.cleanAfter,
before: selInfo.cleanBefore,
highlight: selInfo.cleanText,
afterRaw: selInfo.rawAfter,
beforeRaw: selInfo.rawBefore,
highlightRaw: selInfo.rawText,
} : undefined;
let selectionIsNew;
if (selInfo) {
selectionIsNew =
!win.READIUM2.locationHashOverrideInfo ||
!win.READIUM2.locationHashOverrideInfo.selectionInfo ||
!(0, selection_1.sameSelections)(win.READIUM2.locationHashOverrideInfo.selectionInfo, selInfo);
}
const { epubPage, epubPageID } = findPrecedingAncestorSiblingEpubPageBreak(win.READIUM2.locationHashOverride);
const headings = findPrecedingAncestorSiblingHeadings(win.READIUM2.locationHashOverride);
const followingElementIDs = findFollowingDescendantSiblingElementsWithID(win.READIUM2.locationHashOverride);
let secondWebViewHref = win.READIUM2.urlQueryParams &&
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW] &&
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW].length > 1 &&
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW].startsWith("0") ?
win.READIUM2.urlQueryParams[url_params_1.URL_PARAM_SECOND_WEBVIEW].substr(1) :
undefined;
if (!secondWebViewHref) {
secondWebViewHref = undefined;
}
let caretInfo;
if (win.READIUM2.lastClickedTextChar && ((_b = (_a = win.READIUM2.lastClickedTextChar.textNode) === null || _a === void 0 ? void 0 : _a.nodeValue) === null || _b === void 0 ? void 0 : _b.length)) {
const range = win.document.createRange();
const startOffset = win.READIUM2.lastClickedTextChar.textNodeOffset >= win.READIUM2.lastClickedTextChar.textNode.nodeValue.length ? win.READIUM2.lastClickedTextChar.textNodeOffset - 1 : win.READIUM2.lastClickedTextChar.textNodeOffset;
range.setStart(win.READIUM2.lastClickedTextChar.textNode, startOffset);
range.setEnd(win.READIUM2.lastClickedTextChar.textNode, startOffset + 1);
const tuple = (0, selection_2.convertRange)(range, getCssSelector, computeXPath);
if (tuple) {
const rangeInfo = tuple[0];
const textInfo = tuple[1];
if (rangeInfo && textInfo) {
caretInfo = {
textFragment: undefined,
rangeInfo,
cleanBefore: textInfo.cleanBefore,
cleanText: textInfo.cleanText,
cleanAfter: textInfo.cleanAfter,
rawBefore: textInfo.rawBefore,
rawText: textInfo.rawText,
rawAfter: textInfo.rawAfter,
};
}
}
}
if (__locEventID >= Number.MAX_SAFE_INTEGER) {
__locEventID = 0;
}
win.READIUM2.locationHashOverrideInfo = {
locEventID: ++__locEventID,
audioPlaybackInfo: undefined,
docInfo: {
isFixedLayout: win.READIUM2.isFixedLayout,
isRightToLeft: (0, readium_css_1.isRTL)(),
isVerticalWritingMode: (0, readium_css_1.isVerticalWritingMode)(),
},
epubPage,
epubPageID,
headings,
href: "",
locations: {
cfi,
cssSelector,
position: undefined,
progression,
caretInfo,
xpath,
},
paginationInfo: pinfo,
secondWebViewHref,
selectionInfo: selInfo,
selectionIsNew,
text,
title: _docTitle,
userInteract: userInteract ? true : false,
followingElementIDs,
};
if (DEBUG_TRACE)
debug("notifyReadingLocationRaw: locationHashOverrideInfo", win.READIUM2.locationHashOverrideInfo);
const payload = win.READIUM2.locationHashOverrideInfo;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_READING_LOCATION, payload);
if (!ignoreMediaOverlays) {
mediaOverlaysClickRaw(win.READIUM2.locationHashOverride, userInteract ? true : false);
}
if (!win.document.documentElement.classList.contains(styles_2.R2_MO_CLASS_PLAYING)) {
tempLinkTargetOutline(win.READIUM2.locationHashOverride, 1000, true);
}
if (!doNotFocus) {
if (DEBUG_TRACE)
debug("notifyReadingLocationRaw: focusElement()...");
focusElement(win.READIUM2.locationHashOverride, true);
}
if (win.READIUM2.DEBUG_VISUALS) {
const existings = win.document.querySelectorAll(`*[${styles_2.readPosCssStylesAttr4}]`);
existings.forEach((existing) => {
existing.removeAttribute(`${styles_2.readPosCssStylesAttr4}`);
});
win.READIUM2.locationHashOverride.setAttribute(styles_2.readPosCssStylesAttr4, "notifyReadingLocationRaw");
}
};
const notifyReadingLocationDebounced = debounce((userInteract, ignoreMediaOverlays, doNotFocus) => {
if (DEBUG_TRACE)
debug("notifyReadingLocationDebounced: notifyReadingLocationRaw()...");
notifyReadingLocationRaw(userInteract, ignoreMediaOverlays, doNotFocus);
}, 250);
const notifyReadingLocationDebouncedImmediate = debounce((userInteract, ignoreMediaOverlays) => {
if (DEBUG_TRACE)
debug("notifyReadingLocationDebouncedImmediate: notifyReadingLocationRaw()...");
notifyReadingLocationRaw(userInteract, ignoreMediaOverlays);
}, 250, { immediate: true });
if (!win.READIUM2.isAudio) {
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_PLAY, (_event, payload) => {
const rootElement = win.document.querySelector(payload.rootElement);
const startElement = payload.startElement ? win.document.querySelector(payload.startElement) : null;
let startTextNode;
let startTextNodeOffset = -1;
if (payload.rangeInfo) {
if (DEBUG_TRACE)
debug("R2_EVENT_TTS_DO_PLAY: payload.rangeInfo", payload.rangeInfo);
const textNodeParentElement = win.document.querySelector(payload.rangeInfo.startContainerElementCssSelector);
if (textNodeParentElement && payload.rangeInfo.startContainerChildTextNodeIndex >= 0 && payload.rangeInfo.startContainerChildTextNodeIndex < textNodeParentElement.childNodes.length) {
const textNode = textNodeParentElement.childNodes[payload.rangeInfo.startContainerChildTextNodeIndex];
if (textNode && textNode.nodeValue && payload.rangeInfo.startOffset >= 0 && payload.rangeInfo.startOffset < textNode.nodeValue.length) {
startTextNode = textNode;
startTextNodeOffset = payload.rangeInfo.startOffset;
}
}
}
if (!startTextNode && startElement) {
if (DEBUG_TRACE)
debug("R2_EVENT_TTS_DO_PLAY: payload.rangeInfo fallback");
const rects = startElement.getClientRects();
if (rects === null || rects === void 0 ? void 0 : rects.length) {
for (const rect of rects) {
if (rect.width <= 2 || rect.height <= 2) {
continue;
}
const domPointData = domDataFromPoint(rect.x + 1, rect.y + 1);
if (DEBUG_TRACE && domPointData.element)
debug("R2_EVENT_TTS_DO_PLAY: domDataFromPoint clientrects method", rect.x, rect.y, " ==> ", getCssSelector(domPointData.element), " --- ", getCssSelector(startElement));
if (!domPointData.element || domPointData.element !== startElement) {
continue;
}
startTextNode = domPointData.textNode;
startTextNodeOffset = domPointData.textNodeOffset;
break;
}
}
if (!startTextNode) {
const bbox = startElement.getBoundingClientRect();
if (bbox.width > 2 && bbox.height > 2) {
const domPointData = domDataFromPoint(bbox.x + 1, bbox.y + 1);
if (DEBUG_TRACE && domPointData.element)
debug("R2_EVENT_TTS_DO_PLAY: domDataFromPoint clientrects method", bbox.x, bbox.y, " ==> ", getCssSelector(domPointData.element), " --- ", getCssSelector(startElement));
if (domPointData.element && domPointData.element === startElement) {
startTextNode = domPointData.textNode;
startTextNodeOffset = domPointData.textNodeOffset;
}
}
if (!startTextNode) {
let el = startElement;
let top = 0;
let left = 0;
while (el) {
top += el.offsetTop || 0;
left += el.offsetLeft || 0;
el = el.offsetParent;
}
const domPointData = domDataFromPoint(left, top);
if (DEBUG_TRACE && domPointData.element)
debug("R2_EVENT_TTS_DO_PLAY: domDataFromPoint offset method", left, top, " ==> ", getCssSelector(domPointData.element), " --- ", getCssSelector(startElement));
if (domPointData.element && domPointData.element === startElement) {
startTextNode = domPointData.textNode;
startTextNodeOffset = domPointData.textNodeOffset;
}
}
}
}
(0, readaloud_1.ttsPlay)(payload.speed, payload.voices, focusScrollRaw, rootElement ? rootElement : undefined, startElement ? startElement : undefined, startTextNode, startTextNodeOffset, ensureTwoPageSpreadWithOddColumnsIsOffsetTempDisable, ensureTwoPageSpreadWithOddColumnsIsOffsetReEnable);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_STOP, (_event) => {
(0, readaloud_1.ttsStop)();
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_PAUSE, (_event) => {
(0, readaloud_1.ttsPause)();
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_RESUME, (_event) => {
(0, readaloud_1.ttsResume)();
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_NEXT, (_event, payload) => {
(0, readaloud_1.ttsNext)((payload === null || payload === void 0 ? void 0 : payload.skipSentences) || false, (payload === null || payload === void 0 ? void 0 : payload.escape) || false);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_DO_PREVIOUS, (_event, payload) => {
(0, readaloud_1.ttsPrevious)((payload === null || payload === void 0 ? void 0 : payload.skipSentences) || false, (payload === null || payload === void 0 ? void 0 : payload.escape) || false);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_PLAYBACK_RATE, (_event, payload) => {
(0, readaloud_1.ttsPlaybackRate)(payload.speed);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_VOICE, (_event, payload) => {
(0, readaloud_1.ttsVoices)(payload.voices);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_MEDIAOVERLAYS_MANUAL_PLAY_NEXT, (_event, payload) => {
win.READIUM2.ttsAndMediaOverlaysManualPlayNext = payload.doEnable;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_SKIP_ENABLE, (_event, payload) => {
win.READIUM2.ttsSkippabilityEnabled = payload.doEnable;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_HIGHLIGHT_STYLE, (_event, payload) => {
win.READIUM2.ttsHighlightStyle = payload.ttsHighlightStyle;
win.READIUM2.ttsHighlightColor = payload.ttsHighlightColor;
win.READIUM2.ttsHighlightStyle_WORD = payload.ttsHighlightStyle_WORD;
win.READIUM2.ttsHighlightColor_WORD = payload.ttsHighlightColor_WORD;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_SENTENCE_DETECT_ENABLE, (_event, payload) => {
win.READIUM2.ttsSentenceDetectionEnabled = payload.doEnable;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_CLICK_ENABLE, (_event, payload) => {
win.READIUM2.ttsClickEnabled = payload.doEnable;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_TTS_OVERLAY_ENABLE, (_event, payload) => {
win.READIUM2.ttsOverlayEnabled = payload.doEnable;
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_MEDIA_OVERLAY_STATE, (_event, payload) => {
(0, readium_css_1.clearImageZoomOutlineDebounced)();
win.document.documentElement.classList.remove(styles_2.R2_MO_CLASS_PAUSED, styles_2.R2_MO_CLASS_PLAYING, styles_2.R2_MO_CLASS_STOPPED);
win.document.documentElement.classList.add(payload.state === events_1.MediaOverlaysStateEnum.PAUSED ? styles_2.R2_MO_CLASS_PAUSED :
(payload.state === events_1.MediaOverlaysStateEnum.PLAYING ? styles_2.R2_MO_CLASS_PLAYING : styles_2.R2_MO_CLASS_STOPPED));
});
let _textToSpeechUtterance;
electron_1.ipcRenderer.on(events_1.R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT, (_event, payload, eventID) => {
const styleAttr = win.document.documentElement.getAttribute("style");
const isNight = styleAttr ? styleAttr.indexOf("readium-night-on") > 0 : false;
const isSepia = styleAttr ? styleAttr.indexOf("readium-sepia-on") > 0 : false;
const activeClass = (isNight || isSepia) ? styles_2.R2_MO_CLASS_ACTIVE :
(payload.classActive ? payload.classActive : styles_2.R2_MO_CLASS_ACTIVE);
const activeClassPlayback = payload.classActivePlayback ? payload.classActivePlayback : styles_2.R2_MO_CLASS_ACTIVE_PLAYBACK;
if (payload.classActive) {
const activeMoElements = win.document.body.querySelectorAll(`.${payload.classActive}`);
activeMoElements.forEach((elem) => {
if (payload.classActive) {
elem.classList.remove(payload.classActive);
}
});
}
const activeMoElements_ = win.document.body.querySelectorAll(`.${styles_2.R2_MO_CLASS_ACTIVE}`);
activeMoElements_.forEach((elem) => {
elem.classList.remove(styles_2.R2_MO_CLASS_ACTIVE);
});
if (_textToSpeechUtterance) {
const p = _textToSpeechUtterance._textToSpeechPayload;
_textToSpeechUtterance = undefined;
if (p) {
p.id = undefined;
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT, p, eventID);
}
try {
if (true || win.speechSynthesis.speaking || win.speechSynthesis.pending || win.speechSynthesis.paused) {
win.speechSynthesis.cancel();
}
}
catch (_ex) {
}
}
let removeCaptionContainer = true;
if (!payload.id) {
win.document.documentElement.classList.remove(styles_2.R2_MO_CLASS_ACTIVE_PLAYBACK, activeClassPlayback);
}
else {
if (true || !payload.captionsMode) {
(0, selection_2.clearCurrentSelection)(win);
if ((0, popup_dialog_1.isPopupDialogOpen)(win.document)) {
(0, popup_dialog_1.closePopupDialogs)(win.document);
}
}
win.document.documentElement.classList.add(activeClassPlayback);
const targetEl = win.document.getElementById(payload.id);
if (targetEl) {
targetEl.classList.add(activeClass);
let text = null;
if (payload.captionsMode || payload.speech) {
text = targetEl.textContent;
}
if (payload.speech) {
if (text) {
const utterance = new SpeechSynthesisUtterance(text);
_textToSpeechUtterance = utterance;
const lang = (0, dom_text_utils_1.getLanguage)(targetEl);
utterance.lang = lang;
(0, readaloud_1.assignUtteranceVoice)(utterance);
if (payload.speechRate) {
utterance.rate = payload.speechRate;
}
else if (win.READIUM2.ttsPlaybackRate >= 0.1 && win.READIUM2.ttsPlaybackRate <= 10) {
utterance.rate = win.READIUM2.ttsPlaybackRate;
}
utterance.onend = (_ev) => {
var _a;
if (utterance === _textToSpeechUtterance) {
_textToSpeechUtterance = undefined;
if ((_a = utterance._textToSpeechPayload) === null || _a === void 0 ? void 0 : _a.id) {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT, utterance._textToSpeechPayload, eventID);
}
}
};
utterance._textToSpeechPayload = payload;
win.speechSynthesis.speak(utterance);
}
else {
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT, payload, eventID);
}
}
if (payload.captionsMode) {
if (text) {
text = (0, dom_text_utils_1.normalizeText)(text).trim();
if (text) {
removeCaptionContainer = false;
const isUserBackground = styleAttr ?
styleAttr.indexOf("--USER__backgroundColor") >= 0 : false;
const isUserColor = styleAttr ?
styleAttr.indexOf("--USER__textColor") >= 0 : false;
const docStyle = win.getComputedStyle(win.document.documentElement);
let containerStyle = "background-color: white; color: black;";
if (isNight || isSepia) {
const rsBackground = docStyle.getPropertyValue("--RS__backgroundColor");
const rsColor = docStyle.getPropertyValue("--RS__textColor");
containerStyle = `background-color: ${rsBackground}; color: ${rsColor};`;
}
else {
if (isUserBackground || isUserColor) {
containerStyle = "";
}
if (isUserBackground) {
const usrBackground = docStyle.getPropertyValue("--USER__backgroundColor");
containerStyle += `background-color: ${usrBackground};`;
}
if (isUserColor) {
const usrColor = docStyle.getPropertyValue("--USER__textColor");
containerStyle += `color: ${usrColor};`;
}
}
const isUserFontSize = styleAttr ?
styleAttr.indexOf("--USER__fontSize") >= 0 : false;
if (isUserFontSize) {
const usrFontSize = docStyle.getPropertyValue("--USER__fontSize");
containerStyle += `font-size: ${usrFontSize};`;
}
else {
containerStyle += "font-size: 120%;";
}
const isUserLineHeight = styleAttr ?
styleAttr.indexOf("--USER__lineHeight") >= 0 : false;
if (isUserLineHeight) {
const usrLineHeight = docStyle.getPropertyValue("--USER__lineHeight");
containerStyle += `line-height: ${usrLineHeight};`;
}
else {
containerStyle += "line-height: 1.2;";
}
const isUserFont = styleAttr ?
styleAttr.indexOf("--USER__fontFamily") >= 0 : false;
if (isUserFont) {
const usrFont = docStyle.getPropertyValue("--USER__fontFamily");
containerStyle += `font-family: ${usrFont};`;
}
const payloadCaptions = {
containerStyle,
text,
textStyle: "font-size: 120%;",
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_CAPTIONS, payloadCaptions);
}
}
}
debug(".hashElement = 7");
win.READIUM2.hashElement = targetEl;
win.READIUM2.locationHashOverride = targetEl;
if (!isVisible(false, targetEl, undefined)) {
if (DEBUG_TRACE)
debug("R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT: scrollElementIntoView()...");
scrollElementIntoView(targetEl, false, true, undefined);
}
scrollToHashDebounced.clear();
if (DEBUG_TRACE)
debug("R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT: notifyReadingLocationRaw()...");
notifyReadingLocationRaw(false, true);
if (win.READIUM2.DEBUG_VISUALS) {
const el = win.READIUM2.locationHashOverride;
const existings = win.document.querySelectorAll(`*[${styles_2.readPosCssStylesAttr2}]`);
existings.forEach((existing) => {
existing.removeAttribute(`${styles_2.readPosCssStylesAttr2}`);
});
el.setAttribute(styles_2.readPosCssStylesAttr2, "R2_EVENT_MEDIA_OVERLAY_HIGHLIGHT");
}
}
}
if (removeCaptionContainer) {
const payloadCaptions = {
containerStyle: undefined,
text: undefined,
textStyle: undefined,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_CAPTIONS, payloadCaptions);
}
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_HIGHLIGHT_CREATE, (_event, payloadPing, eventID) => {
if (payloadPing.highlightDefinitions &&
payloadPing.highlightDefinitions.length === 1 &&
payloadPing.highlightDefinitions[0].selectionInfo) {
(0, selection_2.clearCurrentSelection)(win);
}
const highlightDefinitions = !payloadPing.highlightDefinitions ?
[
{
color: undefined,
drawType: undefined,
expand: undefined,
selectionInfo: undefined,
group: undefined,
},
] :
payloadPing.highlightDefinitions;
const selInfo = (0, selection_2.getCurrentSelectionInfo)(win, getCssSelector, computeXPath);
for (const highlightDefinition of highlightDefinitions) {
if (!highlightDefinition.selectionInfo) {
highlightDefinition.selectionInfo = selInfo;
}
}
const highlights = (0, highlight_2.createHighlights)(win, highlightDefinitions, true);
const payloadPong = {
highlightDefinitions: payloadPing.highlightDefinitions,
highlights: highlights.length ? highlights : undefined,
};
electron_1.ipcRenderer.sendToHost(events_1.R2_EVENT_HIGHLIGHT_CREATE, payloadPong, eventID);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_HIGHLIGHT_REMOVE, (_event, payload) => {
payload.highlightIDs.forEach((highlightID) => {
(0, highlight_2.destroyHighlight)(win.document, highlightID);
});
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_HIGHLIGHT_DRAW_MARGIN, (_event, payload) => {
(0, highlight_2.setDrawMargin)(win, payload.drawMargin);
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_HIGHLIGHT_REMOVE_ALL, (_event, payload) => {
if (payload.groups) {
for (const group of payload.groups) {
(0, highlight_2.destroyHighlightsGroup)(win.document, group);
}
}
else {
(0, highlight_2.destroyAllhighlights)(win.document);
}
});
electron_1.ipcRenderer.on(events_1.R2_EVENT_FOCUS_READING_LOC, (_event, _payload) => {
if (DEBUG_TRACE)
debug("R2_EVENT_FOCUS_READING_LOC: focusCurrentReadingLocationElement()...");
focusCurrentReadingLocationElement(true);
});
}
//# sourceMappingURL=preload.js.map