@d-i-t-a/reader 2.0.0-beta.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -46005,6 +46005,9 @@ var Publication = class extends import_publication.Publication {
46005
46005
  get readingOrder() {
46006
46006
  return this.Spine ?? [];
46007
46007
  }
46008
+ get resources() {
46009
+ return this.Resources ?? [];
46010
+ }
46008
46011
  get tableOfContents() {
46009
46012
  if (this.sample?.isSampleRead && this.positions?.length > 0) {
46010
46013
  return this.limitedTOC();
@@ -46501,6 +46504,111 @@ var Popup = class {
46501
46504
  }
46502
46505
  }
46503
46506
  }
46507
+ async hidePopover() {
46508
+ let footnote = this.navigator.iframes[0].contentDocument?.getElementById("d2-popover");
46509
+ if (footnote) {
46510
+ footnote.parentElement?.removeChild(footnote);
46511
+ }
46512
+ const wrapper = findRequiredElement(document, "#iframe-wrapper");
46513
+ wrapper.style.overflow = "auto";
46514
+ }
46515
+ async showPopover(link, event) {
46516
+ const href = link.getAttribute("href");
46517
+ const src = link.getAttribute("src");
46518
+ function getAbsoluteHref(href2) {
46519
+ const currentUrl = document.location.href;
46520
+ return new URL(href2, currentUrl).href;
46521
+ }
46522
+ if (href) {
46523
+ let absolute = getAbsoluteHref(href);
46524
+ if (absolute) {
46525
+ event.preventDefault();
46526
+ event.stopPropagation();
46527
+ let popover = this.navigator.iframes[0].contentDocument?.getElementById("d2-popover");
46528
+ if (popover) {
46529
+ popover.parentElement?.removeChild(popover);
46530
+ }
46531
+ const d2popover = document.createElement("div");
46532
+ d2popover.id = "d2-popover";
46533
+ d2popover.className = "d2-popover is-active";
46534
+ const wrapper = findRequiredElement(document, "#iframe-wrapper");
46535
+ wrapper.style.overflow = "hidden";
46536
+ d2popover.style.top = wrapper.scrollTop + "px";
46537
+ d2popover.style.height = wrapper.clientHeight * 0.9 + "px";
46538
+ const d2wrapper = document.createElement("div");
46539
+ d2wrapper.className = "d2-popover-wrapper";
46540
+ d2popover.appendChild(d2wrapper);
46541
+ const d2content = document.createElement("div");
46542
+ d2content.className = "d2-popover-content";
46543
+ d2wrapper.appendChild(d2content);
46544
+ await fetch(absolute).then((r) => r.text()).then(async (data) => {
46545
+ d2content.innerHTML = data;
46546
+ let doc = this.navigator.iframes[0].contentDocument;
46547
+ if (doc) {
46548
+ doc.body.appendChild(d2popover);
46549
+ }
46550
+ });
46551
+ let win = this.navigator.iframes[0].contentWindow;
46552
+ if (!win) {
46553
+ return;
46554
+ }
46555
+ let self2 = this;
46556
+ win.onclick = function(ev) {
46557
+ if (event.target !== ev.target) {
46558
+ if (d2popover.parentElement) {
46559
+ self2.hidePopover();
46560
+ if (win) {
46561
+ win.onclick = null;
46562
+ }
46563
+ }
46564
+ }
46565
+ };
46566
+ }
46567
+ } else if (src) {
46568
+ let absolute = getAbsoluteHref(src);
46569
+ if (absolute) {
46570
+ event.preventDefault();
46571
+ event.stopPropagation();
46572
+ let popover = this.navigator.iframes[0].contentDocument?.getElementById("d2-popover");
46573
+ if (popover) {
46574
+ popover.parentElement?.removeChild(popover);
46575
+ }
46576
+ const d2popover = document.createElement("div");
46577
+ d2popover.id = "d2-popover";
46578
+ d2popover.className = "d2-popover is-active";
46579
+ const wrapper = findRequiredElement(document, "#iframe-wrapper");
46580
+ wrapper.style.overflow = "hidden";
46581
+ d2popover.style.top = wrapper.scrollTop + "px";
46582
+ d2popover.style.height = wrapper.clientHeight * 0.9 + "px";
46583
+ const d2wrapper = document.createElement("div");
46584
+ d2wrapper.className = "d2-popover-wrapper";
46585
+ d2popover.appendChild(d2wrapper);
46586
+ const d2content = document.createElement("img");
46587
+ d2content.className = "d2-popover-content";
46588
+ d2wrapper.appendChild(d2content);
46589
+ d2content.src = src;
46590
+ let doc = this.navigator.iframes[0].contentDocument;
46591
+ if (doc) {
46592
+ doc.body.appendChild(d2popover);
46593
+ }
46594
+ let win = this.navigator.iframes[0].contentWindow;
46595
+ if (!win) {
46596
+ return;
46597
+ }
46598
+ let self2 = this;
46599
+ win.onclick = function(ev) {
46600
+ if (event.target !== ev.target) {
46601
+ if (d2popover.parentElement) {
46602
+ self2.hidePopover();
46603
+ if (win) {
46604
+ win.onclick = null;
46605
+ }
46606
+ }
46607
+ }
46608
+ };
46609
+ }
46610
+ }
46611
+ }
46504
46612
  showPopup(element, event) {
46505
46613
  let footnote = this.navigator.iframes[0].contentDocument?.getElementById("d2-popup");
46506
46614
  if (footnote) {
@@ -46586,11 +46694,19 @@ var EventHandler = class {
46586
46694
  }
46587
46695
  return null;
46588
46696
  };
46589
- this.isEpubInternal = (clickedLink) => {
46697
+ this.linkInPublication = (readingOrder, clickedHref) => readingOrder.some((link) => {
46698
+ return !link.Rel?.includes("external") && this.navigator.publication.getRelativeHref(clickedHref).includes(link.Href);
46699
+ });
46700
+ this.isReadingOrderInternal = (clickedLink) => {
46701
+ if (IS_DEV)
46702
+ console.log("clickedLink: ", clickedLink);
46703
+ const isEpubInternal = this.linkInPublication(this.navigator.publication.readingOrder, clickedLink.href);
46704
+ return isEpubInternal;
46705
+ };
46706
+ this.isResourceInternal = (clickedLink) => {
46590
46707
  if (IS_DEV)
46591
46708
  console.log("clickedLink: ", clickedLink);
46592
- const linkInReadingOrder = (readingOrder, clickedPathname) => readingOrder.some((link) => !link.Rel?.includes("external") && link.Href.includes(clickedPathname));
46593
- const isEpubInternal = linkInReadingOrder(this.navigator.publication.readingOrder, clickedLink.pathname);
46709
+ const isEpubInternal = this.linkInPublication(this.navigator.publication.resources, clickedLink.href);
46594
46710
  return isEpubInternal;
46595
46711
  };
46596
46712
  this.handleLinks = async (event) => {
@@ -46599,9 +46715,13 @@ var EventHandler = class {
46599
46715
  const link = this.checkForLink(event);
46600
46716
  if (link) {
46601
46717
  const isSameOrigin = window.location.protocol === link.protocol && window.location.port === link.port && window.location.hostname === link.hostname;
46602
- const isEpubInternal = this.isEpubInternal(link);
46718
+ const isEpubInternal = this.isReadingOrderInternal(link);
46719
+ const isResourceInternal = this.isResourceInternal(link);
46720
+ if (!isResourceInternal) {
46721
+ await this.popup.hidePopover();
46722
+ }
46603
46723
  const isInternal = link.href.indexOf("#");
46604
- if (!isSameOrigin && !isEpubInternal) {
46724
+ if (!isSameOrigin && !isEpubInternal && !isResourceInternal) {
46605
46725
  window.open(link.href, "_blank");
46606
46726
  event.preventDefault();
46607
46727
  event.stopPropagation();
@@ -46613,6 +46733,8 @@ var EventHandler = class {
46613
46733
  const attribute = link2.getAttribute("epub:type") === "noteref";
46614
46734
  if (attribute) {
46615
46735
  await this.popup.handleFootnote(link2, event);
46736
+ } else if (isResourceInternal && !isEpubInternal) {
46737
+ await this.popup.showPopover(link2, event);
46616
46738
  } else {
46617
46739
  this.onInternalLink(event);
46618
46740
  }
@@ -46632,6 +46754,12 @@ var EventHandler = class {
46632
46754
  }
46633
46755
  setupEvents(element) {
46634
46756
  if (element !== null) {
46757
+ element.addEventListener("dblclick", async (event) => {
46758
+ let htmlElement = event.target;
46759
+ if (event.target && htmlElement.tagName.toLowerCase() === "img") {
46760
+ await this.popup.showPopover(htmlElement, event);
46761
+ }
46762
+ }, true);
46635
46763
  element.addEventListener("click", this.handleLinks.bind(this));
46636
46764
  } else {
46637
46765
  throw "cannot setup events for null";
@@ -46808,10 +46936,9 @@ var ReflowableBookView = class {
46808
46936
  }
46809
46937
  }
46810
46938
  goToElement(element, relative) {
46811
- const wrapper = findRequiredElement(document, "#iframe-wrapper");
46812
46939
  if (this.scrollMode) {
46813
46940
  if (element) {
46814
- wrapper.scrollTop = element.offsetTop;
46941
+ element.scrollIntoView({ block: "center" });
46815
46942
  }
46816
46943
  } else {
46817
46944
  if (element) {
@@ -46855,7 +46982,7 @@ var ReflowableBookView = class {
46855
46982
  const wrapper = findRequiredElement(document, "#iframe-wrapper");
46856
46983
  if (this.scrollMode) {
46857
46984
  const leftHeight = wrapper.scrollTop;
46858
- const height = this.getScreenHeight();
46985
+ const height = this.getScreenHeight() - 40;
46859
46986
  const offset = leftHeight - height;
46860
46987
  if (offset >= 0) {
46861
46988
  wrapper.scrollTop = offset;
@@ -46881,7 +47008,7 @@ var ReflowableBookView = class {
46881
47008
  const wrapper = findRequiredElement(document, "#iframe-wrapper");
46882
47009
  if (this.scrollMode) {
46883
47010
  const leftHeight = wrapper.scrollTop;
46884
- const height = this.getScreenHeight();
47011
+ const height = this.getScreenHeight() - 40;
46885
47012
  const scrollHeight = this.scrollingElement.scrollHeight;
46886
47013
  const offset = leftHeight + height;
46887
47014
  if (offset < scrollHeight) {
@@ -49069,6 +49196,10 @@ var iconTemplate = (id2, title, path, classAttr = `icon`) => `<svg xmlns="http:/
49069
49196
  <title id="${id2}">${title}</title>
49070
49197
  ${path}
49071
49198
  </svg>`;
49199
+ var iconTemplateWithViewBox = (id2, title, path, viewBox, classAttr = `icon`) => `<svg xmlns="http://www.w3.org/2000/svg" width="${WIDTH_ATTR}" height="${WIDTH_ATTR}" viewBox="${viewBox}" preserveAspectRatio="xMidYMid meet" role="img" class="${classAttr}" aria-labelledBy="${id2}">
49200
+ <title id="${id2}">${title}</title>
49201
+ ${path}
49202
+ </svg>`;
49072
49203
  var iconTemplateColored = (id2, title, path, classAttr = `icon`, size, fill) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="${VIEWBOX_ATTR}" style="fill:${fill}" preserveAspectRatio="xMidYMid meet" role="img" class="${classAttr}" aria-labelledBy="${id2}">
49073
49204
  <title id="${id2}">${title}</title>
49074
49205
  ${path}
@@ -49077,7 +49208,7 @@ var icons = {
49077
49208
  error: iconTemplate(`error-icon`, `Warning`, `<path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>`),
49078
49209
  home: `<path d="M12 5.69l5 4.5V18h-2v-6H9v6H7v-7.81l5-4.5M12 3L2 12h3v8h6v-6h2v6h6v-8h3L12 3z"/>`,
49079
49210
  expand: iconTemplate(`expand-icon`, `Enter fullscreen`, `<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>`, `icon active-icon`),
49080
- loading: iconTemplate(`loading-icon`, `Loading`, `<path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"/>`),
49211
+ loading: iconTemplateWithViewBox(`loading-icon`, `Loading`, `<path fill="#BBBBBB" d="M145,241.6c-53.3,0-96.6-43.2-96.6-96.6c0-53.3,43.2-96.6,96.6-96.6c53.3,0,96.6,43.2,96.6,96.6 c0,26.7-10.8,50.9-28.3,68.3l7.6,7.6c19.4-19.4,31.5-46.3,31.5-75.9c0-59.3-48-107.3-107.3-107.3S37.7,85.7,37.7,145 c0,59.3,48,107.3,107.3,107.3V241.6z"/>`, "0 0 290 290"),
49081
49212
  next: iconTemplate(`next-icon`, `Next Chapter`, `<path d="M6.49 20.13l1.77 1.77 9.9-9.9-9.9-9.9-1.77 1.77L14.62 12l-8.13 8.13z"/>`),
49082
49213
  previous: iconTemplate(`previous-icon`, `Previous Chapter`, `<path d="M17.51 3.87L15.73 2.1 5.84 12l9.9 9.9 1.77-1.77L9.38 12l8.13-8.13z"/>`),
49083
49214
  settings: iconTemplate(`settings-icon`, `Settings`, `<path d="M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.09-.16-.26-.25-.44-.25-.06 0-.12.01-.17.03l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.06-.02-.12-.03-.18-.03-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.09.16.26.25.44.25.06 0 .12-.01.17-.03l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/>`, `icon open`),
@@ -49136,7 +49267,6 @@ var _blacklistIdClassForCssSelectors = [
49136
49267
  ];
49137
49268
  var lastMouseDownX = -1;
49138
49269
  var lastMouseDownY = -1;
49139
- var bodyEventListenersSet = false;
49140
49270
  var TextHighlighter = class {
49141
49271
  constructor(delegate, layerSettings, properties, hasEventListener, options, api) {
49142
49272
  this.lastSelectedHighlight = void 0;
@@ -49201,7 +49331,6 @@ var TextHighlighter = class {
49201
49331
  this.initializeToolbox();
49202
49332
  lastMouseDownX = -1;
49203
49333
  lastMouseDownY = -1;
49204
- bodyEventListenersSet = false;
49205
49334
  let self2 = this;
49206
49335
  async function unselect() {
49207
49336
  if (self2.lastSelectedHighlight === void 0) {
@@ -49428,8 +49557,26 @@ var TextHighlighter = class {
49428
49557
  if (this.isAndroid()) {
49429
49558
  el.addEventListener("contextmenu", this.disableContext);
49430
49559
  }
49560
+ el.addEventListener("mousedown", this.mousedown.bind(this));
49561
+ el.addEventListener("mouseup", this.mouseup.bind(this));
49562
+ el.addEventListener("mousemove", this.mousemove.bind(this));
49563
+ el.addEventListener("touchstart", this.mousedown.bind(this));
49564
+ el.addEventListener("touchend", this.mouseup.bind(this));
49565
+ el.addEventListener("touchmove", this.mousemove.bind(this));
49431
49566
  this.hasEventListener = true;
49432
49567
  }
49568
+ async mousedown(ev) {
49569
+ lastMouseDownX = ev.clientX;
49570
+ lastMouseDownY = ev.clientY;
49571
+ }
49572
+ async mouseup(ev) {
49573
+ if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {
49574
+ await this.processMouseEvent(ev);
49575
+ }
49576
+ }
49577
+ async mousemove(ev) {
49578
+ await this.processMouseEvent(ev);
49579
+ }
49433
49580
  unbindEvents(el, _scope) {
49434
49581
  let doc = el.ownerDocument;
49435
49582
  doc.removeEventListener("keyup", this.toolboxShowDelayed.bind(this));
@@ -49443,6 +49590,12 @@ var TextHighlighter = class {
49443
49590
  if (this.isAndroid()) {
49444
49591
  el.removeEventListener("contextmenu", this.disableContext);
49445
49592
  }
49593
+ el.removeEventListener("mousedown", this.mousedown.bind(this));
49594
+ el.removeEventListener("mouseup", this.mouseup.bind(this));
49595
+ el.removeEventListener("mousemove", this.mousemove.bind(this));
49596
+ el.removeEventListener("touchstart", this.mousedown.bind(this));
49597
+ el.removeEventListener("touchend", this.mouseup.bind(this));
49598
+ el.removeEventListener("touchmove", this.mousemove.bind(this));
49446
49599
  this.hasEventListener = false;
49447
49600
  }
49448
49601
  destroy() {
@@ -50219,12 +50372,12 @@ var TextHighlighter = class {
50219
50372
  }
50220
50373
  throw new Error("Bad Hex");
50221
50374
  }
50222
- resetHighlightBoundingStyle(_win, highlightBounding) {
50375
+ resetHighlightBoundingStyle(highlightBounding) {
50223
50376
  highlightBounding.style.outline = "none";
50224
50377
  highlightBounding.style.setProperty("background-color", "transparent", "important");
50225
50378
  }
50226
- resetHighlightAreaStyle(win, highlightArea, id_container) {
50227
- let doc = win.document;
50379
+ resetHighlightAreaStyle(highlightArea, id_container) {
50380
+ let doc = this.delegate.iframes[0].contentWindow?.document;
50228
50381
  const id2 = highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : void 0;
50229
50382
  if (id2) {
50230
50383
  const highlight = _highlights.find((h) => {
@@ -50289,9 +50442,11 @@ var TextHighlighter = class {
50289
50442
  }
50290
50443
  }
50291
50444
  let highlightParent;
50292
- let container = doc.getElementById(id_container);
50293
- if (container) {
50294
- highlightParent = container.querySelector(`#${highlight.id}`);
50445
+ if (doc) {
50446
+ let container = doc.getElementById(id_container);
50447
+ if (container) {
50448
+ highlightParent = container.querySelector(`#${highlight.id}`);
50449
+ }
50295
50450
  }
50296
50451
  if (highlightParent) {
50297
50452
  let nodeList = highlightParent.getElementsByClassName(CLASS_HIGHLIGHT_ICON);
@@ -50305,8 +50460,7 @@ var TextHighlighter = class {
50305
50460
  }
50306
50461
  }
50307
50462
  }
50308
- setHighlightAreaStyle(win, highlightAreas, highlight) {
50309
- let doc = win.document;
50463
+ setHighlightAreaStyle(doc, highlightAreas, highlight) {
50310
50464
  for (const highlightArea of highlightAreas) {
50311
50465
  if (highlight.marker === AnnotationMarker.Custom || highlight.marker === AnnotationMarker.Bookmark) {
50312
50466
  if (highlight.style?.hover) {
@@ -50431,10 +50585,13 @@ var TextHighlighter = class {
50431
50585
  isAndroid() {
50432
50586
  return navigator.userAgent.match(/Android/i) != null;
50433
50587
  }
50434
- async processMouseEvent(win, ev) {
50435
- const doc = win.document;
50588
+ async processMouseEvent(ev) {
50589
+ const doc = this.delegate.iframes[0].contentWindow?.document;
50436
50590
  const x = ev.clientX;
50437
50591
  const y = ev.clientY;
50592
+ if (!doc) {
50593
+ return;
50594
+ }
50438
50595
  if (!doc.getElementById(HighlightContainer.R2_ID_HIGHLIGHTS_CONTAINER) && !doc.getElementById(HighlightContainer.R2_ID_SEARCH_CONTAINER) && !doc.getElementById(HighlightContainer.R2_ID_PAGEBREAK_CONTAINER) && !doc.getElementById(HighlightContainer.R2_ID_READALOUD_CONTAINER) && !doc.getElementById(HighlightContainer.R2_ID_DEFINITIONS_CONTAINER)) {
50439
50596
  return;
50440
50597
  }
@@ -50450,7 +50607,9 @@ var TextHighlighter = class {
50450
50607
  let highlightParent = doc.getElementById(`${highlight.id}`);
50451
50608
  if (!highlightParent) {
50452
50609
  let container = doc.getElementById(HighlightContainer.R2_ID_HIGHLIGHTS_CONTAINER);
50453
- highlightParent = container.querySelector(`#${highlight.id}`);
50610
+ if (container) {
50611
+ highlightParent = container.querySelector(`#${highlight.id}`);
50612
+ }
50454
50613
  }
50455
50614
  if (!highlightParent) {
50456
50615
  continue;
@@ -50478,11 +50637,11 @@ var TextHighlighter = class {
50478
50637
  if (container) {
50479
50638
  const highlightBoundings = container.querySelectorAll(`.${CLASS_HIGHLIGHT_BOUNDING_AREA}`);
50480
50639
  for (const highlightBounding of highlightBoundings) {
50481
- this.resetHighlightBoundingStyle(win, highlightBounding);
50640
+ this.resetHighlightBoundingStyle(highlightBounding);
50482
50641
  }
50483
50642
  const allHighlightAreas = Array.from(container.querySelectorAll(`.${CLASS_HIGHLIGHT_AREA}`));
50484
50643
  for (const highlightArea of allHighlightAreas) {
50485
- this.resetHighlightAreaStyle(win, highlightArea, id2);
50644
+ this.resetHighlightAreaStyle(highlightArea, id2);
50486
50645
  }
50487
50646
  }
50488
50647
  }
@@ -50497,12 +50656,12 @@ var TextHighlighter = class {
50497
50656
  const allHighlightAreas = container.querySelectorAll(`.${CLASS_HIGHLIGHT_AREA}`);
50498
50657
  for (const highlightArea of allHighlightAreas) {
50499
50658
  if (foundElementHighlightAreas.indexOf(highlightArea) < 0) {
50500
- this.resetHighlightAreaStyle(win, highlightArea, id2);
50659
+ this.resetHighlightAreaStyle(highlightArea, id2);
50501
50660
  }
50502
50661
  }
50503
50662
  }
50504
50663
  }
50505
- this.setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);
50664
+ this.setHighlightAreaStyle(doc, foundElementHighlightAreas, foundHighlight);
50506
50665
  const foundElementHighlightBounding = foundElement.querySelector(`.${CLASS_HIGHLIGHT_BOUNDING_AREA}`);
50507
50666
  for (let id2 in HighlightContainer) {
50508
50667
  let container = doc.getElementById(id2);
@@ -50510,7 +50669,7 @@ var TextHighlighter = class {
50510
50669
  const allHighlightBoundings = container.querySelectorAll(`.${CLASS_HIGHLIGHT_BOUNDING_AREA}`);
50511
50670
  for (const highlightBounding of allHighlightBoundings) {
50512
50671
  if (!foundElementHighlightBounding || highlightBounding !== foundElementHighlightBounding) {
50513
- this.resetHighlightBoundingStyle(win, highlightBounding);
50672
+ this.resetHighlightBoundingStyle(highlightBounding);
50514
50673
  }
50515
50674
  }
50516
50675
  }
@@ -50643,6 +50802,7 @@ var TextHighlighter = class {
50643
50802
  popup.showPopup(foundElement.dataset.definition, ev);
50644
50803
  }
50645
50804
  let result = this.delegate.definitionsModule?.properties?.definitions?.filter((el) => el.order === Number(foundElement?.dataset.order))[0];
50805
+ console.log(result);
50646
50806
  if (this.delegate.definitionsModule?.api?.click) {
50647
50807
  this.delegate.definitionsModule.api?.click(lodash.omit(result, "callbacks"), lodash.omit(foundHighlight, "definition"));
50648
50808
  this.delegate.emit("definition.click", result, foundHighlight);
@@ -50658,31 +50818,7 @@ var TextHighlighter = class {
50658
50818
  }
50659
50819
  async ensureHighlightsContainer(win, id2) {
50660
50820
  const doc = win.document;
50661
- let self2 = this;
50662
50821
  if (!doc.getElementById(id2)) {
50663
- if (!bodyEventListenersSet) {
50664
- bodyEventListenersSet = true;
50665
- async function mousedown(ev) {
50666
- lastMouseDownX = ev.clientX;
50667
- lastMouseDownY = ev.clientY;
50668
- }
50669
- async function mouseup(ev) {
50670
- if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {
50671
- self2.processMouseEvent(win, ev);
50672
- }
50673
- }
50674
- async function mousemove(ev) {
50675
- self2.processMouseEvent(win, ev);
50676
- }
50677
- if (doc.body) {
50678
- doc.body.addEventListener("mousedown", mousedown, false);
50679
- doc.body.addEventListener("mouseup", mouseup, false);
50680
- doc.body.addEventListener("mousemove", mousemove, false);
50681
- doc.body.addEventListener("touchstart", mousedown, false);
50682
- doc.body.addEventListener("touchend", mouseup, false);
50683
- doc.body.addEventListener("touchmove", mousemove, false);
50684
- }
50685
- }
50686
50822
  let container = doc.createElement("div");
50687
50823
  container.setAttribute("id", id2);
50688
50824
  container.style.setProperty("pointer-events", "none");
@@ -51131,7 +51267,7 @@ var TextHighlighter = class {
51131
51267
  }
51132
51268
  }
51133
51269
  const foundElementHighlightAreas = Array.from(highlightParent.querySelectorAll(`.${CLASS_HIGHLIGHT_AREA}`));
51134
- self2.setHighlightAreaStyle(win, foundElementHighlightAreas, highlight);
51270
+ self2.setHighlightAreaStyle(doc, foundElementHighlightAreas, highlight);
51135
51271
  });
51136
51272
  }
51137
51273
  if (highlight.note) {
@@ -52390,6 +52526,7 @@ var MediaOverlaySettings = class {
52390
52526
  this.volume = 1;
52391
52527
  this.rate = 1;
52392
52528
  this.playing = false;
52529
+ this.resourceReady = false;
52393
52530
  this.wait = 1;
52394
52531
  this.settingsChangeCallback = () => {
52395
52532
  };
@@ -52687,7 +52824,7 @@ var MediaOverlayModule = class {
52687
52824
  console.log("ontimeupdate");
52688
52825
  this.trackCurrentTime();
52689
52826
  };
52690
- this.ensureOnTimeUpdate = (remove) => {
52827
+ this.ensureOnTimeUpdate = (remove, replace) => {
52691
52828
  if (this.audioElement) {
52692
52829
  if (remove) {
52693
52830
  if (this.__ontimeupdate) {
@@ -52696,8 +52833,11 @@ var MediaOverlayModule = class {
52696
52833
  cancelAnimationFrame(this.myReq);
52697
52834
  }
52698
52835
  } else {
52699
- if (!this.__ontimeupdate) {
52836
+ if (!this.__ontimeupdate || replace) {
52700
52837
  this.__ontimeupdate = true;
52838
+ if (replace) {
52839
+ this.audioElement.removeEventListener("timeupdate", this.ontimeupdate);
52840
+ }
52701
52841
  this.audioElement.addEventListener("timeupdate", this.ontimeupdate);
52702
52842
  }
52703
52843
  }
@@ -52741,7 +52881,7 @@ var MediaOverlayModule = class {
52741
52881
  async playLink() {
52742
52882
  let link = this.currentLinks[this.currentLinkIndex];
52743
52883
  if (link?.Properties?.MediaOverlay) {
52744
- this.ensureOnTimeUpdate(false);
52884
+ this.ensureOnTimeUpdate(false, false);
52745
52885
  const moUrl = link.Properties?.MediaOverlay;
52746
52886
  const moUrlObjFull = new URL(moUrl, this.publication.manifestUrl);
52747
52887
  const moUrlFull = moUrlObjFull.toString();
@@ -52781,6 +52921,7 @@ var MediaOverlayModule = class {
52781
52921
  await this.playLink();
52782
52922
  } else {
52783
52923
  if (this.settings.autoTurn && this.settings.playing) {
52924
+ this.audioElement.pause();
52784
52925
  this.delegate.nextResource();
52785
52926
  } else {
52786
52927
  this.stopReadAloud();
@@ -52795,6 +52936,7 @@ var MediaOverlayModule = class {
52795
52936
  const timeToSeekTo = this.currentAudioBegin ? this.currentAudioBegin : 0;
52796
52937
  this.audioElement.currentTime = timeToSeekTo;
52797
52938
  await this.audioElement.play();
52939
+ this.ensureOnTimeUpdate(false, true);
52798
52940
  this.audioElement.volume = this.settings.volume;
52799
52941
  this.audioElement.playbackRate = this.settings.rate;
52800
52942
  } else {
@@ -52962,6 +53104,7 @@ var MediaOverlayModule = class {
52962
53104
  } else {
52963
53105
  this.audioElement.pause();
52964
53106
  if (this.settings.autoTurn && this.settings.playing) {
53107
+ this.audioElement.pause();
52965
53108
  this.delegate.nextResource();
52966
53109
  } else {
52967
53110
  this.stopReadAloud();
@@ -52999,6 +53142,7 @@ var MediaOverlayModule = class {
52999
53142
  } else {
53000
53143
  this.audioElement.pause();
53001
53144
  if (this.settings.autoTurn && this.settings.playing) {
53145
+ this.audioElement.pause();
53002
53146
  this.delegate.nextResource();
53003
53147
  } else {
53004
53148
  this.stopReadAloud();
@@ -53106,17 +53250,22 @@ var MediaOverlayModule = class {
53106
53250
  if (IS_DEV) {
53107
53251
  console.log("playMediaOverlaysAudio() - playClip() - _currentAudioElement.play()");
53108
53252
  }
53109
- this.ensureOnTimeUpdate(false);
53253
+ this.ensureOnTimeUpdate(false, false);
53110
53254
  this.audioElement.playbackRate = this.settings.rate;
53111
53255
  this.audioElement.volume = this.settings.volume;
53112
53256
  if (this.settings.playing) {
53113
- if (!initial) {
53114
- setTimeout(async () => {
53115
- await this.audioElement.play();
53116
- }, this.settings.wait);
53117
- } else {
53118
- await this.audioElement.play();
53119
- }
53257
+ let checkReady = function() {
53258
+ if (!self2.settings.resourceReady) {
53259
+ setTimeout(checkReady, 200);
53260
+ } else {
53261
+ setTimeout(async () => {
53262
+ await self2.audioElement.play();
53263
+ self2.ensureOnTimeUpdate(false, true);
53264
+ }, self2.settings.wait * 1e3);
53265
+ }
53266
+ };
53267
+ let self2 = this;
53268
+ checkReady();
53120
53269
  }
53121
53270
  } else {
53122
53271
  if (IS_DEV) {
@@ -53127,18 +53276,23 @@ var MediaOverlayModule = class {
53127
53276
  if (IS_DEV) {
53128
53277
  console.log("playMediaOverlaysAudio() - playClip() - ontimeupdateSeeked - .play()");
53129
53278
  }
53130
- this.ensureOnTimeUpdate(false);
53279
+ this.ensureOnTimeUpdate(false, false);
53131
53280
  if (this.audioElement) {
53132
53281
  this.audioElement.playbackRate = this.settings.rate;
53133
53282
  this.audioElement.volume = this.settings.volume;
53134
53283
  if (this.settings.playing) {
53135
- if (!initial) {
53136
- setTimeout(async () => {
53137
- await this.audioElement.play();
53138
- }, this.settings.wait);
53139
- } else {
53140
- await this.audioElement.play();
53141
- }
53284
+ let checkReady = function() {
53285
+ if (!self2.settings.resourceReady) {
53286
+ setTimeout(checkReady, 200);
53287
+ } else {
53288
+ setTimeout(async () => {
53289
+ await self2.audioElement.play();
53290
+ self2.ensureOnTimeUpdate(false, true);
53291
+ }, self2.settings.wait * 1e3);
53292
+ }
53293
+ };
53294
+ let self2 = this;
53295
+ checkReady();
53142
53296
  }
53143
53297
  }
53144
53298
  };
@@ -53147,7 +53301,7 @@ var MediaOverlayModule = class {
53147
53301
  }
53148
53302
  } else {
53149
53303
  const contiguous = this.previousAudioUrl === this.currentAudioUrl && typeof this.previousAudioEnd !== "undefined" && this.previousAudioEnd > timeToSeekTo - 0.02 && this.previousAudioEnd <= timeToSeekTo && this.audioElement.currentTime >= timeToSeekTo - 0.1;
53150
- this.ensureOnTimeUpdate(false);
53304
+ this.ensureOnTimeUpdate(false, false);
53151
53305
  if (contiguous) {
53152
53306
  if (IS_DEV) {
53153
53307
  console.log("playMediaOverlaysAudio() - playClip() - ensureOnTimeUpdate");
@@ -53204,6 +53358,7 @@ var MediaOverlayModule = class {
53204
53358
  await this.playLink();
53205
53359
  } else {
53206
53360
  if (this.settings.autoTurn && this.settings.playing) {
53361
+ this.audioElement.pause();
53207
53362
  this.delegate.nextResource();
53208
53363
  } else {
53209
53364
  this.stopReadAloud();
@@ -53315,7 +53470,7 @@ var TimelineModule = class {
53315
53470
  if (this.delegate.rights.enableMaterial) {
53316
53471
  this.positionSlider = findElement(document, "#positionSlider");
53317
53472
  }
53318
- if (this.delegate.rights.autoGeneratePositions && this.publication.positions) {
53473
+ if (this.publication.positions) {
53319
53474
  if (this.positionSlider)
53320
53475
  this.positionSlider.style.display = "block";
53321
53476
  } else {
@@ -53795,18 +53950,25 @@ var ContentProtectionModule = class {
53795
53950
  }
53796
53951
  }
53797
53952
  recalculate(delay2 = 0) {
53798
- if (this.properties?.enableObfuscation) {
53799
- const onDoResize = (0, import_debounce3.debounce)(() => {
53800
- this.calcRects(this.rects);
53801
- if (this.rects !== void 0) {
53802
- this.rects.forEach((rect) => this.toggleRect(rect, this.securityContainer, this.isHacked));
53953
+ return new Promise((resolve) => {
53954
+ if (this.properties?.enableObfuscation) {
53955
+ const onDoResize = (0, import_debounce3.debounce)(() => {
53956
+ this.calcRects(this.rects);
53957
+ if (this.rects !== void 0) {
53958
+ this.rects.forEach((rect) => this.toggleRect(rect, this.securityContainer, this.isHacked));
53959
+ }
53960
+ resolve(true);
53961
+ }, delay2);
53962
+ if (this.rects) {
53963
+ this.observe();
53964
+ onDoResize();
53965
+ } else {
53966
+ resolve(false);
53803
53967
  }
53804
- }, delay2);
53805
- if (this.rects) {
53806
- this.observe();
53807
- onDoResize();
53968
+ } else {
53969
+ resolve(false);
53808
53970
  }
53809
- }
53971
+ });
53810
53972
  }
53811
53973
  calcRects(rects) {
53812
53974
  if (rects !== void 0) {
@@ -55617,6 +55779,14 @@ var IFrameNavigator = class extends import_events.default {
55617
55779
  this.nextChapterBottomAnchorElement.style.display = "none";
55618
55780
  if (this.previousChapterTopAnchorElement)
55619
55781
  this.previousChapterTopAnchorElement.style.display = "none";
55782
+ if (this.keyboardEventHandler) {
55783
+ this.keyboardEventHandler.onBackwardSwipe = this.handlePreviousChapterClick.bind(this);
55784
+ this.keyboardEventHandler.onForwardSwipe = this.handleNextChapterClick.bind(this);
55785
+ }
55786
+ if (this.touchEventHandler) {
55787
+ this.touchEventHandler.onBackwardSwipe = this.handlePreviousPageClick.bind(this);
55788
+ this.touchEventHandler.onForwardSwipe = this.handleNextPageClick.bind(this);
55789
+ }
55620
55790
  } else {
55621
55791
  this.settings.isPaginated().then((paginated) => {
55622
55792
  if (paginated) {
@@ -56089,6 +56259,11 @@ var IFrameNavigator = class extends import_events.default {
56089
56259
  this.view?.goToProgression(bookViewPosition);
56090
56260
  }
56091
56261
  this.newPosition = void 0;
56262
+ if (this.rights?.enableContentProtection) {
56263
+ if (this.contentProtectionModule !== void 0) {
56264
+ await this.contentProtectionModule.recalculate(10);
56265
+ }
56266
+ }
56092
56267
  this.hideLoadingMessage();
56093
56268
  this.showIframeContents();
56094
56269
  if (this.rights.enableMediaOverlays && this.mediaOverlayModule !== void 0 && this.hasMediaOverlays) {
@@ -56097,6 +56272,11 @@ var IFrameNavigator = class extends import_events.default {
56097
56272
  }
56098
56273
  await this.updatePositionInfo();
56099
56274
  await this.view?.setSize();
56275
+ setTimeout(() => {
56276
+ if (this.mediaOverlayModule !== void 0) {
56277
+ this.mediaOverlayModule.settings.resourceReady = true;
56278
+ }
56279
+ }, 300);
56100
56280
  }, 200);
56101
56281
  return new Promise((resolve) => resolve());
56102
56282
  } catch (err) {
@@ -57401,6 +57581,9 @@ var IFrameNavigator = class extends import_events.default {
57401
57581
  this.loadingMessage.style.display = "block";
57402
57582
  this.loadingMessage.classList.add("is-loading");
57403
57583
  }
57584
+ if (this.mediaOverlayModule !== void 0) {
57585
+ this.mediaOverlayModule.settings.resourceReady = false;
57586
+ }
57404
57587
  }
57405
57588
  hideIframeContents() {
57406
57589
  this.isBeingStyled = true;
@@ -58265,9 +58448,12 @@ var TTSModule = class {
58265
58448
  }
58266
58449
  });
58267
58450
  }
58268
- cancel() {
58269
- if (this.api?.stopped)
58270
- this.api?.stopped();
58451
+ cancel(api = true) {
58452
+ if (api) {
58453
+ if (this.api?.stopped)
58454
+ this.api?.stopped();
58455
+ this.delegate.emit("readaloud.stopped", "stopped");
58456
+ }
58271
58457
  this.userScrolled = false;
58272
58458
  window.speechSynthesis.cancel();
58273
58459
  if (this.splittingResult && this.delegate.tts?.enableSplitter) {
@@ -58296,7 +58482,7 @@ var TTSModule = class {
58296
58482
  this.api?.started();
58297
58483
  var self2 = this;
58298
58484
  this.userScrolled = false;
58299
- this.cancel();
58485
+ this.cancel(false);
58300
58486
  if (this.delegate.tts?.enableSplitter) {
58301
58487
  if (partial) {
58302
58488
  var allWords = self2.body.querySelectorAll("[data-word]");
@@ -58710,10 +58896,12 @@ var TTSModule2 = class {
58710
58896
  }
58711
58897
  });
58712
58898
  }
58713
- cancel() {
58714
- if (this.api?.stopped)
58715
- this.api?.stopped();
58716
- this.delegate.emit("readaloud.stopped", "stopped");
58899
+ cancel(api = true) {
58900
+ if (api) {
58901
+ if (this.api?.stopped)
58902
+ this.api?.stopped();
58903
+ this.delegate.emit("readaloud.stopped", "stopped");
58904
+ }
58717
58905
  this.userScrolled = false;
58718
58906
  this.speaking = false;
58719
58907
  setTimeout(() => {
@@ -58730,7 +58918,7 @@ var TTSModule2 = class {
58730
58918
  this.delegate.emit("readaloud.started", "started");
58731
58919
  const self2 = this;
58732
58920
  this.userScrolled = false;
58733
- this.cancel();
58921
+ this.cancel(false);
58734
58922
  let utterance;
58735
58923
  if (partial) {
58736
58924
  let iframe = document.querySelector("main#iframe-wrapper iframe");
@@ -58870,7 +59058,9 @@ var TTSModule2 = class {
58870
59058
  callback();
58871
59059
  }
58872
59060
  speakPlay() {
58873
- this.cancel();
59061
+ this.cancel(false);
59062
+ if (this.api?.started)
59063
+ this.api?.started();
58874
59064
  this.delegate.emit("readaloud.started", "started");
58875
59065
  let self2 = this;
58876
59066
  let iframe = document.querySelector("main#iframe-wrapper iframe");
@@ -58880,47 +59070,27 @@ var TTSModule2 = class {
58880
59070
  let node = self2.highlighter.visibleTextRects[0];
58881
59071
  let doc = self2.delegate.iframes[0].contentDocument;
58882
59072
  if (doc) {
58883
- let isOutsideViewport = function(rect) {
58884
- const windowLeft = window.scrollX;
58885
- const windowRight = windowLeft + window.innerWidth;
58886
- const right = rect.left + rect.width;
58887
- const bottom = rect.top + rect.height;
58888
- const windowTop = window.scrollY;
58889
- const windowBottom = windowTop + window.innerHeight;
58890
- const isAbove = bottom < windowTop;
58891
- const isBelow = rect.top > windowBottom;
58892
- const isLeft = right < windowLeft;
58893
- const isRight = rect.left > windowRight;
58894
- return isAbove || isBelow || isLeft || isRight;
58895
- };
58896
59073
  const range = self2.highlighter.dom(doc.body).getWindow().document.createRange();
58897
59074
  const selection = self2.highlighter.dom(self2.delegate.iframes[0].contentDocument?.body).getSelection();
58898
59075
  selection.removeAllRanges();
58899
59076
  range.selectNodeContents(node.node);
58900
59077
  selection.addRange(range);
58901
- const clientRects = getClientRectsNoOverlap(range, false);
58902
59078
  let index2 = 0;
58903
- for (const rect of clientRects) {
58904
- if (!isOutsideViewport(rect)) {
58905
- const endNode = selection.focusNode;
58906
- const endOffset = selection.focusOffset;
58907
- selection.collapse(selection.anchorNode, selection.anchorOffset);
58908
- for (let i = 0; i < index2; i++) {
58909
- selection.modify("move", "forward", "line");
58910
- }
58911
- selection.extend(endNode, endOffset);
58912
- selection.collapse(selection.anchorNode, selection.anchorOffset);
58913
- if (rootEl) {
58914
- const idx = self2.findTtsQueueItemIndex(ttsQueue, selection.anchorNode, selection.focusNode, selection.focusOffset, rootEl);
58915
- if (idx >= 0) {
58916
- ttsQueueIndex = idx;
58917
- }
58918
- }
58919
- selection.removeAllRanges();
58920
- break;
59079
+ const endNode = selection.focusNode;
59080
+ const endOffset = selection.focusOffset;
59081
+ selection.collapse(selection.anchorNode, selection.anchorOffset);
59082
+ for (let i = 0; i < index2; i++) {
59083
+ selection.modify("move", "forward", "line");
59084
+ }
59085
+ selection.extend(endNode, endOffset);
59086
+ selection.collapse(selection.anchorNode, selection.anchorOffset);
59087
+ if (rootEl) {
59088
+ const idx = self2.findTtsQueueItemIndex(ttsQueue, selection.anchorNode, selection.focusNode, selection.focusOffset, rootEl);
59089
+ if (idx >= 0) {
59090
+ ttsQueueIndex = idx;
58921
59091
  }
58922
- index2++;
58923
59092
  }
59093
+ selection.removeAllRanges();
58924
59094
  }
58925
59095
  };
58926
59096
  const ttsQueue = this.generateTtsQueue(rootEl, true);
@@ -58934,7 +59104,7 @@ var TTSModule2 = class {
58934
59104
  }
58935
59105
  setTimeout(() => {
58936
59106
  this.startTTSSession(ttsQueue, ttsQueueIndex);
58937
- }, 100);
59107
+ }, 200);
58938
59108
  }
58939
59109
  }
58940
59110
  speakPause() {
@@ -59622,7 +59792,7 @@ var DefinitionsModule = class {
59622
59792
  }
59623
59793
  });
59624
59794
  }, { threshold: 1 });
59625
- if (highlightFragments) {
59795
+ if (highlightFragments && highlightFragments.length > 0) {
59626
59796
  observer.observe(highlightFragments[0]);
59627
59797
  }
59628
59798
  });
@@ -59684,11 +59854,13 @@ init_polyfills();
59684
59854
  var DEFAULT_BACKGROUND_COLOR_OPACITY2 = 0.5;
59685
59855
  var LineFocusModule = class {
59686
59856
  constructor(delegate, properties, highlighter, api) {
59857
+ this.hasEventListener = false;
59687
59858
  this.lines = [];
59688
59859
  this.index = 0;
59689
59860
  this.isActive = false;
59690
59861
  this.isDebug = false;
59691
59862
  this.lineFocusContainer = document.getElementById(`lineFocusContainer`);
59863
+ this.readerContainer = document.getElementById(`D2Reader-Container`);
59692
59864
  this.lineFocusTopBlinder = document.getElementById(`lineFocusTopBlinder`);
59693
59865
  this.lineFocusBottomBlinder = document.getElementById(`lineFocusBottomBlinder`);
59694
59866
  this.wrapperHeight = void 0;
@@ -59706,9 +59878,59 @@ var LineFocusModule = class {
59706
59878
  if (IS_DEV) {
59707
59879
  console.log("Definitions module stop");
59708
59880
  }
59881
+ this.hasEventListener = false;
59882
+ removeEventListenerOptional(document, "keydown", this.keydown.bind(this));
59883
+ removeEventListenerOptional(document, "keyup", this.keyup.bind(this));
59884
+ removeEventListenerOptional(this.delegate.iframes[0].contentDocument, "keydown", this.keydown.bind(this));
59885
+ removeEventListenerOptional(this.delegate.iframes[0].contentDocument, "keyup", this.keyup.bind(this));
59709
59886
  }
59710
59887
  async start() {
59711
59888
  this.delegate.lineFocusModule = this;
59889
+ const wrapper = findRequiredElement(document, "#iframe-wrapper");
59890
+ if (wrapper.style.height.length > 0) {
59891
+ this.wrapperHeight = wrapper.style.height;
59892
+ if (this.lineFocusContainer && this.lineFocusContainer.style.height.length == 0)
59893
+ this.lineFocusContainer.style.height = this.wrapperHeight;
59894
+ if (this.readerContainer && this.readerContainer.style.height.length == 0) {
59895
+ this.readerContainer.style.height = this.wrapperHeight;
59896
+ }
59897
+ if (this.readerContainer) {
59898
+ this.readerContainer.style.overflow = "hidden";
59899
+ }
59900
+ }
59901
+ if (!this.hasEventListener) {
59902
+ this.hasEventListener = true;
59903
+ addEventListenerOptional(document, "keydown", this.keydown.bind(this));
59904
+ addEventListenerOptional(document, "keyup", this.keyup.bind(this));
59905
+ addEventListenerOptional(this.delegate.iframes[0].contentDocument, "keydown", this.keydown.bind(this));
59906
+ addEventListenerOptional(this.delegate.iframes[0].contentDocument, "keyup", this.keyup.bind(this));
59907
+ }
59908
+ }
59909
+ keydown(event) {
59910
+ if (event instanceof KeyboardEvent && this.isActive) {
59911
+ const key = event.key;
59912
+ switch (key) {
59913
+ case "ArrowUp":
59914
+ event.stopPropagation();
59915
+ break;
59916
+ case "ArrowDown":
59917
+ event.stopPropagation();
59918
+ break;
59919
+ }
59920
+ }
59921
+ }
59922
+ keyup(event) {
59923
+ if (event instanceof KeyboardEvent && this.isActive) {
59924
+ const key = event.key;
59925
+ switch (key) {
59926
+ case "ArrowUp":
59927
+ this.lineUp();
59928
+ break;
59929
+ case "ArrowDown":
59930
+ this.lineDown();
59931
+ break;
59932
+ }
59933
+ }
59712
59934
  }
59713
59935
  handleResize() {
59714
59936
  if (this.isActive) {
@@ -59716,14 +59938,6 @@ var LineFocusModule = class {
59716
59938
  }
59717
59939
  }
59718
59940
  async enableLineFocus() {
59719
- if (!this.isActive) {
59720
- const wrapper = findRequiredElement(document, "#iframe-wrapper");
59721
- wrapper.style.overflow = "hidden";
59722
- if (wrapper.style.height.length > 0) {
59723
- this.wrapperHeight = wrapper.style.height;
59724
- }
59725
- wrapper.style.height = "100vh";
59726
- }
59727
59941
  this.isActive = true;
59728
59942
  await this.delegate.settings.scroll(true);
59729
59943
  this.lineFocus();
@@ -59731,12 +59945,15 @@ var LineFocusModule = class {
59731
59945
  disableLineFocus(resetHeight = true) {
59732
59946
  this.isActive = false;
59733
59947
  const wrapper = findRequiredElement(document, "#iframe-wrapper");
59734
- wrapper.style.overflow = "auto";
59735
59948
  if (this.wrapperHeight) {
59736
59949
  wrapper.style.height = this.wrapperHeight;
59737
- } else if (resetHeight) {
59738
- wrapper.style.removeProperty("height");
59739
59950
  }
59951
+ if (!resetHeight) {
59952
+ this.index = 0;
59953
+ }
59954
+ const doc = this.delegate.iframes[0].contentDocument;
59955
+ const html = findIframeElement(doc, "html");
59956
+ html.style.removeProperty("--USER__maxMediaHeight");
59740
59957
  this.wrapperHeight = void 0;
59741
59958
  if (this.lineFocusContainer)
59742
59959
  this.lineFocusContainer.style.display = "none";
@@ -59756,6 +59973,10 @@ var LineFocusModule = class {
59756
59973
  }
59757
59974
  lineFocus() {
59758
59975
  const wrapper = findRequiredElement(document, "#iframe-wrapper");
59976
+ const doc = this.delegate.iframes[0].contentDocument;
59977
+ const html = findIframeElement(doc, "html");
59978
+ let maxHeight = this.properties.maxHeight ? getHeight() * this.properties.maxHeight / 100 : getHeight() / 2;
59979
+ html.style.setProperty("--USER__maxMediaHeight", maxHeight + "px");
59759
59980
  function insertAfter(referenceNode, newNode) {
59760
59981
  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
59761
59982
  }
@@ -59787,8 +60008,6 @@ var LineFocusModule = class {
59787
60008
  insertAfter(wrapper, divAfter2);
59788
60009
  }
59789
60010
  this.lines = [];
59790
- const self2 = this;
59791
- const doc = self2.delegate.iframes[0].contentDocument;
59792
60011
  if (doc) {
59793
60012
  let random_rgba = function() {
59794
60013
  const o = Math.round, r = Math.random, s = 255;
@@ -59951,10 +60170,8 @@ var LineFocusModule = class {
59951
60170
  }
59952
60171
  currentLine() {
59953
60172
  let current = this.lines[this.index];
59954
- let previous = this.lines[this.index];
59955
- let next = this.lines[this.index];
59956
- let top = previous.style.top;
59957
- let bottom = parseInt(next.style.top.replace("px", "")) + parseInt(next.style.height.replace("px", ""));
60173
+ let top = current.style.top;
60174
+ let bottom = parseInt(current.style.top.replace("px", "")) + parseInt(current.style.height.replace("px", ""));
59958
60175
  let height = bottom - parseInt(top.replace("px", ""));
59959
60176
  if (this.lineFocusContainer) {
59960
60177
  let lineFocusHeight = parseInt(getComputedStyle(this.lineFocusContainer).height.replace("px", ""));
@@ -59964,7 +60181,6 @@ var LineFocusModule = class {
59964
60181
  if (this.lineFocusBottomBlinder)
59965
60182
  this.lineFocusBottomBlinder.style.height = blindersHeight + "px";
59966
60183
  }
59967
- current.focus();
59968
60184
  current.scrollIntoView({
59969
60185
  block: "center",
59970
60186
  behavior: "smooth"
@@ -59977,10 +60193,8 @@ var LineFocusModule = class {
59977
60193
  this.index = this.lines.length - 1;
59978
60194
  }
59979
60195
  let current = this.lines[this.index];
59980
- let previous = this.lines[this.index];
59981
- let next = this.lines[this.index];
59982
- let top = previous.style.top;
59983
- let bottom = parseInt(next.style.top.replace("px", "")) + parseInt(next.style.height.replace("px", ""));
60196
+ let top = current.style.top;
60197
+ let bottom = parseInt(current.style.top.replace("px", "")) + parseInt(current.style.height.replace("px", ""));
59984
60198
  let height = bottom - parseInt(top.replace("px", ""));
59985
60199
  if (this.lineFocusContainer) {
59986
60200
  let lineFocusHeight = parseInt(getComputedStyle(this.lineFocusContainer).height.replace("px", ""));
@@ -59990,7 +60204,6 @@ var LineFocusModule = class {
59990
60204
  if (this.lineFocusBottomBlinder)
59991
60205
  this.lineFocusBottomBlinder.style.height = blindersHeight + "px";
59992
60206
  }
59993
- current.focus();
59994
60207
  current.scrollIntoView({
59995
60208
  block: "center",
59996
60209
  behavior: "smooth"
@@ -60004,10 +60217,8 @@ var LineFocusModule = class {
60004
60217
  this.index = 0;
60005
60218
  }
60006
60219
  let current = this.lines[this.index];
60007
- let previous = this.lines[this.index];
60008
- let next = this.lines[this.index];
60009
- let top = previous.style.top;
60010
- let bottom = parseInt(next.style.top.replace("px", "")) + parseInt(next.style.height.replace("px", ""));
60220
+ let top = current.style.top;
60221
+ let bottom = parseInt(current.style.top.replace("px", "")) + parseInt(current.style.height.replace("px", ""));
60011
60222
  let height = bottom - parseInt(top.replace("px", ""));
60012
60223
  if (this.lineFocusContainer) {
60013
60224
  let lineFocusHeight = parseInt(getComputedStyle(this.lineFocusContainer).height.replace("px", ""));
@@ -60017,7 +60228,6 @@ var LineFocusModule = class {
60017
60228
  if (this.lineFocusBottomBlinder)
60018
60229
  this.lineFocusBottomBlinder.style.height = blindersHeight + "px";
60019
60230
  }
60020
- current.focus();
60021
60231
  current.scrollIntoView({
60022
60232
  block: "center",
60023
60233
  behavior: "smooth"
@@ -60029,10 +60239,14 @@ var LineFocusModule = class {
60029
60239
  }
60030
60240
  findRects(parent) {
60031
60241
  const textNodes = this.findTextNodes(parent);
60242
+ const imageNodes = Array.from(parent.getElementsByTagName("img"));
60032
60243
  let newNodes = [];
60033
60244
  textNodes.forEach((node) => {
60034
60245
  newNodes.push(...this.measureTextNodes(node));
60035
60246
  });
60247
+ imageNodes.forEach((node) => {
60248
+ newNodes.push(...this.measureImageNodes(node));
60249
+ });
60036
60250
  return newNodes;
60037
60251
  }
60038
60252
  findTextNodes(parentElement, nodes = []) {
@@ -60065,6 +60279,21 @@ var LineFocusModule = class {
60065
60279
  }
60066
60280
  }
60067
60281
  }
60282
+ measureImageNodes(node) {
60283
+ try {
60284
+ const range = document.createRange();
60285
+ range.selectNode(node);
60286
+ const rect = Array.from(range.getClientRects());
60287
+ range.detach();
60288
+ return rect;
60289
+ } catch (error) {
60290
+ if (IS_DEV) {
60291
+ console.log("measureTextNode " + error);
60292
+ console.log("measureTextNode " + node);
60293
+ console.log(node.textContent);
60294
+ }
60295
+ }
60296
+ }
60068
60297
  };
60069
60298
 
60070
60299
  // src/reader.ts
@@ -60444,6 +60673,9 @@ var D2Reader = class {
60444
60673
  }, initialConfig.lineFocus)) : void 0;
60445
60674
  return new D2Reader(settings, navigator2, highlighter, bookmarkModule, annotationModule, ttsSettings, ttsModule, searchModule, definitionsModule, contentProtectionModule, timelineModule, mediaOverlaySettings, mediaOverlayModule, pageBreakModule, lineFocusModule);
60446
60675
  }
60676
+ get hasMediaOverlays() {
60677
+ return this.navigator.hasMediaOverlays;
60678
+ }
60447
60679
  get tableOfContents() {
60448
60680
  return convertAndCamel(this.navigator.tableOfContents()) ?? [];
60449
60681
  }
@@ -60491,14 +60723,23 @@ var D2Reader = class {
60491
60723
  }
60492
60724
  async applyLineFocusSettings(userSettings) {
60493
60725
  if (userSettings.lines) {
60494
- if (this.lineFocusModule)
60726
+ if (this.lineFocusModule) {
60727
+ const lines = this.lineFocusModule.properties.lines ?? 1;
60728
+ this.lineFocusModule.index = this.lineFocusModule.index * lines / parseInt(userSettings.lines);
60729
+ this.lineFocusModule.index = Math.abs(parseInt(this.lineFocusModule.index.toFixed()));
60495
60730
  this.lineFocusModule.properties.lines = parseInt(userSettings.lines);
60496
- await this.lineFocusModule?.enableLineFocus();
60731
+ if (this.lineFocusModule.isActive) {
60732
+ await this.lineFocusModule.enableLineFocus();
60733
+ }
60734
+ }
60497
60735
  }
60498
60736
  if (userSettings.debug !== void 0) {
60499
- if (this.lineFocusModule)
60737
+ if (this.lineFocusModule) {
60500
60738
  this.lineFocusModule.isDebug = userSettings.debug;
60501
- await this.lineFocusModule?.enableLineFocus();
60739
+ if (this.lineFocusModule.isActive) {
60740
+ await this.lineFocusModule.enableLineFocus();
60741
+ }
60742
+ }
60502
60743
  }
60503
60744
  }
60504
60745
  lineUp() {
@@ -60530,7 +60771,7 @@ function updateConfig(rights, publication) {
60530
60771
  rights.enablePageBreaks = false;
60531
60772
  rights.enableLineFocus = false;
60532
60773
  }
60533
- if (publication.sample) {
60774
+ if (publication.sample?.isSampleRead) {
60534
60775
  rights.enableAnnotations = false;
60535
60776
  rights.enableSearch = false;
60536
60777
  rights.enableTTS = false;