@readium/navigator 2.6.1 → 2.7.1

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.
Files changed (125) hide show
  1. package/LICENSE +28 -0
  2. package/dist/Navigator.js +1 -0
  3. package/dist/_virtual/index.js +1 -0
  4. package/dist/_virtual/preload-helper.js +1 -0
  5. package/dist/audio/AudioNavigator.js +1 -0
  6. package/dist/audio/AudioPoolManager.js +1 -0
  7. package/dist/audio/engine/PreservePitchProcessor.js +215 -0
  8. package/dist/audio/engine/PreservePitchWorklet.js +1 -0
  9. package/dist/audio/engine/WebAudioEngine.js +1 -0
  10. package/dist/audio/preferences/AudioDefaults.js +1 -0
  11. package/dist/audio/preferences/AudioPreferences.js +1 -0
  12. package/dist/audio/preferences/AudioPreferencesEditor.js +1 -0
  13. package/dist/audio/preferences/AudioSettings.js +1 -0
  14. package/dist/audio/protection/AudioNavigatorProtector.js +1 -0
  15. package/dist/css/Properties.js +1 -0
  16. package/dist/dom/_readium_cssSelectorGenerator.js +1 -0
  17. package/dist/dom/_readium_executionCleanup.js +14 -0
  18. package/dist/dom/_readium_executionPrevention.js +66 -0
  19. package/dist/dom/_readium_webpubExecution.js +5 -0
  20. package/dist/epub/EpubNavigator.js +1 -0
  21. package/dist/epub/css/Properties.js +1 -0
  22. package/dist/epub/css/ReadiumCSS.js +1 -0
  23. package/dist/epub/frame/FrameBlobBuilder.js +1 -0
  24. package/dist/epub/frame/FrameComms.js +1 -0
  25. package/dist/epub/frame/FrameManager.js +1 -0
  26. package/dist/epub/frame/FramePoolManager.js +1 -0
  27. package/dist/epub/fxl/FXLCoordinator.js +1 -0
  28. package/dist/epub/fxl/FXLFrameManager.js +1 -0
  29. package/dist/epub/fxl/FXLFramePoolManager.js +1 -0
  30. package/dist/epub/fxl/FXLPeripherals.js +4 -0
  31. package/dist/epub/fxl/FXLPeripheralsDebug.js +1 -0
  32. package/dist/epub/fxl/FXLSpreader.js +1 -0
  33. package/dist/epub/preferences/EpubDefaults.js +1 -0
  34. package/dist/epub/preferences/EpubPreferences.js +1 -0
  35. package/dist/epub/preferences/EpubPreferencesEditor.js +1 -0
  36. package/dist/epub/preferences/EpubSettings.js +1 -0
  37. package/dist/helpers/dimensions.js +1 -0
  38. package/dist/helpers/dist/sML.js +1 -0
  39. package/dist/helpers/lineLength.js +1 -0
  40. package/dist/helpers/minify.js +1 -0
  41. package/dist/helpers/scriptMode.js +1 -0
  42. package/dist/index.js +1 -11006
  43. package/dist/injection/Injector.js +1 -0
  44. package/dist/injection/epubInjectables.js +1 -0
  45. package/dist/injection/webpubInjectables.js +1 -0
  46. package/dist/{ReadiumCSS-after-D7unrNI9.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/ReadiumCSS-after.css.js} +2 -5
  47. package/dist/{ReadiumCSS-before-DwBLxUVH.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/ReadiumCSS-before.css.js} +2 -5
  48. package/dist/{ReadiumCSS-default-AIAk8uwU.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/ReadiumCSS-default.css.js} +2 -5
  49. package/dist/{ReadiumCSS-ebpaj_fonts_patch-Dt2XliTg.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/ReadiumCSS-ebpaj_fonts_patch.css.js} +2 -5
  50. package/dist/{ReadiumCSS-after-XUKPAxfT.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-horizontal/ReadiumCSS-after.css.js} +2 -5
  51. package/dist/{ReadiumCSS-before-8FMq19-x.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-horizontal/ReadiumCSS-before.css.js} +2 -5
  52. package/dist/{ReadiumCSS-default-N65xNiIp.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-horizontal/ReadiumCSS-default.css.js} +2 -5
  53. package/dist/{ReadiumCSS-after-ClF4TBzj.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-vertical/ReadiumCSS-after.css.js} +2 -5
  54. package/dist/{ReadiumCSS-before-BNTwR8Qm.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-vertical/ReadiumCSS-before.css.js} +2 -5
  55. package/dist/{ReadiumCSS-default-BesyZHRU.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/cjk-vertical/ReadiumCSS-default.css.js} +2 -5
  56. package/dist/{ReadiumCSS-after-d5mC4cme.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/rtl/ReadiumCSS-after.css.js} +2 -5
  57. package/dist/{ReadiumCSS-before-CG-KmDa3.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/rtl/ReadiumCSS-before.css.js} +2 -5
  58. package/dist/{ReadiumCSS-default-BhdLiyWp.js → node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/rtl/ReadiumCSS-default.css.js} +2 -5
  59. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/webPub/ReadiumCSS-webPub.css.js +274 -0
  60. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/colors.json.js +1 -0
  61. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/experiments.json.js +1 -0
  62. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/fontStacks.json.js +1 -0
  63. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/i18n.json.js +1 -0
  64. package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/settings.json.js +1 -0
  65. package/dist/node_modules/.pnpm/path-browserify@1.0.1/node_modules/path-browserify/index.js +1 -0
  66. package/dist/peripherals/KeyboardConditionBridge.js +1 -0
  67. package/dist/peripherals/KeyboardPeripherals.js +1 -0
  68. package/dist/preferences/Preference.js +1 -0
  69. package/dist/preferences/Types.js +1 -0
  70. package/dist/preferences/guards.js +1 -0
  71. package/dist/protection/AutomationDetector.js +1 -0
  72. package/dist/protection/ContextMenuProtector.js +1 -0
  73. package/dist/protection/CopyProtector.js +1 -0
  74. package/dist/protection/DevToolsDetector.js +1 -0
  75. package/dist/protection/DragAndDropProtector.js +1 -0
  76. package/dist/protection/IframeEmbeddingDetector.js +1 -0
  77. package/dist/protection/NavigatorProtector.js +1 -0
  78. package/dist/protection/PrintProtector.js +15 -0
  79. package/dist/protection/utils/WorkerConsole.js +12 -0
  80. package/dist/protection/utils/console.js +1 -0
  81. package/dist/protection/utils/match.js +1 -0
  82. package/dist/protection/utils/platform.js +1 -0
  83. package/dist/webpub/WebPubBlobBuilder.js +2 -0
  84. package/dist/webpub/WebPubFrameManager.js +1 -0
  85. package/dist/webpub/WebPubFramePoolManager.js +1 -0
  86. package/dist/webpub/WebPubNavigator.js +1 -0
  87. package/dist/webpub/css/Properties.js +1 -0
  88. package/dist/webpub/css/WebPubCSS.js +1 -0
  89. package/dist/webpub/preferences/WebPubDefaults.js +1 -0
  90. package/dist/webpub/preferences/WebPubPreferences.js +1 -0
  91. package/dist/webpub/preferences/WebPubPreferencesEditor.js +1 -0
  92. package/dist/webpub/preferences/WebPubSettings.js +1 -0
  93. package/package.json +16 -14
  94. package/src/Navigator.ts +4 -1
  95. package/src/audio/AudioNavigator.ts +8 -8
  96. package/src/decorations/index.ts +24 -127
  97. package/src/epub/EpubNavigator.ts +149 -20
  98. package/src/epub/frame/FrameManager.ts +8 -3
  99. package/src/epub/frame/FramePoolManager.ts +5 -2
  100. package/src/epub/fxl/FXLCoordinator.ts +1 -1
  101. package/src/epub/fxl/FXLFrameManager.ts +1 -1
  102. package/src/epub/preferences/EpubDefaults.ts +1 -1
  103. package/src/epub/preferences/EpubSettings.ts +1 -1
  104. package/src/protection/DevToolsDetector.ts +1 -1
  105. package/src/webpub/WebPubFrameManager.ts +9 -3
  106. package/src/webpub/WebPubFramePoolManager.ts +5 -2
  107. package/src/webpub/WebPubNavigator.ts +100 -19
  108. package/src/webpub/preferences/WebPubDefaults.ts +1 -1
  109. package/src/webpub/preferences/WebPubSettings.ts +1 -1
  110. package/types/src/Navigator.d.ts +3 -1
  111. package/types/src/decorations/index.d.ts +5 -59
  112. package/types/src/epub/EpubNavigator.d.ts +13 -3
  113. package/types/src/epub/frame/FrameManager.d.ts +2 -1
  114. package/types/src/epub/frame/FramePoolManager.d.ts +2 -1
  115. package/types/src/epub/fxl/FXLFramePoolManager.d.ts +1 -1
  116. package/types/src/webpub/WebPubFrameManager.d.ts +2 -1
  117. package/types/src/webpub/WebPubFramePoolManager.d.ts +2 -1
  118. package/types/src/webpub/WebPubNavigator.d.ts +12 -3
  119. package/dist/ar-DyHX_uy2.js +0 -7
  120. package/dist/da-Dct0PS3E.js +0 -7
  121. package/dist/fr-C5HEel98.js +0 -7
  122. package/dist/index.umd.cjs +0 -5615
  123. package/dist/it-DFOBoXGy.js +0 -7
  124. package/dist/pt_PT-Di3sVjze.js +0 -7
  125. package/dist/sv-BfzAFsVN.js +0 -7
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2022, Readium Foundation
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ import{ReadingProgression as a}from"@readium/shared";import{SELECT_ALL as p,SAVE as n,DEV_TOOLS as c,PRINT as P}from"@readium/navigator-html-injectables";class d{mergeKeyboardPeripherals(e,r=[]){const s=[],f=r.filter(l=>!["developer_tools","select_all","print","save"].includes(l.type));e.disableSelectAll&&s.push(p),e.disableSave&&s.push(n),e.monitorDevTools&&s.push(c),e.protectPrinting?.disable&&s.push(P);for(const l of f){const h=l.keyCombos.filter(t=>!s.some(g=>g.keyCombos.some(i=>t.keyCode===i.keyCode&&t.ctrl===i.ctrl&&t.shift===i.shift&&t.alt===i.alt&&t.meta===i.meta)));h.length>0&&s.push({...l,keyCombos:h})}return s}}class y extends d{goLeft(e=!1,r){this.readingProgression===a.ltr?this.goBackward(e,r):this.readingProgression===a.rtl&&this.goForward(e,r)}goRight(e=!1,r){this.readingProgression===a.ltr?this.goForward(e,r):this.readingProgression===a.rtl&&this.goBackward(e,r)}}class u extends d{}export{u as MediaNavigator,d as Navigator,y as VisualNavigator};
@@ -0,0 +1 @@
1
+ import{__require as r}from"../node_modules/.pnpm/path-browserify@1.0.1/node_modules/path-browserify/index.js";var o=r();export{o as p};
@@ -0,0 +1 @@
1
+ const p="modulepreload",v=function(l){return"/"+l},u={},y=function(d,c,E){let i=Promise.resolve();if(c&&c.length>0){let f=function(e){return Promise.all(e.map(o=>Promise.resolve(o).then(s=>({status:"fulfilled",value:s}),s=>({status:"rejected",reason:s}))))};document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");i=f(c.map(e=>{if(e=v(e),e in u)return;u[e]=!0;const o=e.endsWith(".css"),s=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${s}`))return;const n=document.createElement("link");if(n.rel=o?"stylesheet":p,o||(n.as="script"),n.crossOrigin="",n.href=e,t&&n.setAttribute("nonce",t),document.head.appendChild(n),o)return new Promise((m,h)=>{n.addEventListener("load",m),n.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${e}`)))})}))}function a(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return i.then(r=>{for(const t of r||[])t.status==="rejected"&&a(t.reason);return d().catch(a)})};export{y as __vitePreload};
@@ -0,0 +1 @@
1
+ import{Locator as p,LocatorLocations as c,getTime as g}from"@readium/shared";import{MediaNavigator as E}from"../Navigator.js";import{AudioPoolManager as P}from"./AudioPoolManager.js";import{AudioNavigatorProtector as L}from"./protection/AudioNavigatorProtector.js";import{NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT as k}from"../protection/NavigatorProtector.js";import{KeyboardPeripherals as w,NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT as _}from"../peripherals/KeyboardPeripherals.js";import{AudioPreferences as T}from"./preferences/AudioPreferences.js";import{AudioDefaults as S}from"./preferences/AudioDefaults.js";import{AudioSettings as y}from"./preferences/AudioSettings.js";import{WebAudioEngine as b}from"./engine/WebAudioEngine.js";import{AudioPreferencesEditor as v}from"./preferences/AudioPreferencesEditor.js";const I=n=>({trackLoaded:n.trackLoaded??(()=>{}),positionChanged:n.positionChanged??(()=>{}),timelineItemChanged:n.timelineItemChanged??(()=>{}),error:n.error??(()=>{}),trackEnded:n.trackEnded??(()=>{}),play:n.play??(()=>{}),pause:n.pause??(()=>{}),metadataLoaded:n.metadataLoaded??(()=>{}),stalled:n.stalled??(()=>{}),seeking:n.seeking??(()=>{}),seekable:n.seekable??(()=>{}),contentProtection:n.contentProtection??(()=>{}),peripheral:n.peripheral??(()=>{}),contextMenu:n.contextMenu??(()=>{}),remotePlaybackStateChanged:n.remotePlaybackStateChanged??(()=>{})});class B extends E{constructor(t,e,i,s={preferences:{},defaults:{}}){if(super(),this.positionPollInterval=null,this.navigationId=0,this._playIntent=!1,this._preferencesEditor=null,this._mediaSessionEnabled=!1,this._navigatorProtector=null,this._keyboardPeripheralsManager=null,this._suspiciousActivityListener=null,this._keyboardPeripheralListener=null,this._isNavigating=!1,this._isStalled=!1,this._stalledWatchdog=null,this._stalledCheckTime=0,this.pub=t,this.listeners=I(e),this._preferences=new T(s.preferences),this._defaults=new S(s.defaults),this._settings=new y(this._preferences,this._defaults),t.readingOrder.items.length===0)throw new Error("AudioNavigator: publication has an empty reading order");if(i)this.currentLocation=this.ensureLocatorLocations(i);else{const l=this.pub.readingOrder.items[0];this.currentLocation=new p({href:l.href,type:l.type||"audio/mpeg",title:l.title,locations:new c({position:1,progression:0,totalProgression:0,fragments:["t=0"]})})}const o=this.currentLocation.href.split("#")[0],r=this.hrefToTrackIndex(o);if(r===-1)throw new Error(`AudioNavigator: initial href "${o}" not found in reading order`);const h=g(this.currentLocation.locations)||0,d=new b({playback:{state:{currentTime:h,duration:0},playWhenReady:!1,index:r}});this.pool=new P(d,t,s.contentProtection);const a=s.contentProtection||{};this._contentProtection=a;const u=this.mergeKeyboardPeripherals(a,s.keyboardPeripherals||[]);(a.disableContextMenu||a.checkAutomation||a.checkIFrameEmbedding||a.monitorDevTools||a.protectPrinting?.disable||a.disableDragAndDrop||a.protectCopy)&&(this._navigatorProtector=new L(a),this._suspiciousActivityListener=l=>{const{type:f,...m}=l.detail;f==="context_menu"?this.listeners.contextMenu(m):this.listeners.contentProtection(f,m)},window.addEventListener(k,this._suspiciousActivityListener)),u.length>0&&(this._keyboardPeripheralsManager=new w({keyboardPeripherals:u}),this._keyboardPeripheralListener=l=>{this.listeners.peripheral(l.detail)},window.addEventListener(_,this._keyboardPeripheralListener)),this.setupEventListeners(),this._isNavigating=!0,this.pool.setCurrentAudio(r,"forward"),this.applyPreferences(),this.waitForLoadedAndSeeked(h).then(()=>{this._isNavigating=!1,this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()),this._notifyTimelineChange(this.currentLocator),this.listeners.positionChanged(this.currentLocator),this._setupRemotePlayback()}).catch(()=>{this._isNavigating=!1})}get settings(){return this._settings}get preferencesEditor(){return this._preferencesEditor===null&&(this._preferencesEditor=new v(this._preferences,this.settings)),this._preferencesEditor}async submitPreferences(t){this._preferences=this._preferences.merging(t),this.applyPreferences()}applyPreferences(){this._settings=new y(this._preferences,this._defaults),this._preferencesEditor!==null&&(this._preferencesEditor=new v(this._preferences,this.settings)),this.pool.audioEngine.setVolume(this._settings.volume),this.pool.audioEngine.setPlaybackRate(this._settings.playbackRate,this._settings.preservePitch),this.positionPollInterval!==null&&this.startPositionPolling(),this._settings.enableMediaSession&&!this._mediaSessionEnabled?(this._mediaSessionEnabled=!0,this.setupMediaSession()):!this._settings.enableMediaSession&&this._mediaSessionEnabled&&(this._mediaSessionEnabled=!1,this.destroyMediaSession())}get publication(){return this.pub}get timeline(){return this.pub.timeline}_notifyTimelineChange(t){const e=this.pub.timeline.locate(t);e!==this._currentTimelineItem&&(this._currentTimelineItem=e,this.listeners.timelineItemChanged(e),this._settings.enableMediaSession&&this.updateMediaSessionMetadata())}ensureLocatorLocations(t){return new p({...t,locations:t.locations instanceof c?t.locations:t.locations?new c(t.locations):void 0})}hrefToTrackIndex(t){const e=t.split("#")[0];return this.pub.readingOrder.items.findIndex(i=>i.href===e)}currentTrackIndex(){return this.hrefToTrackIndex(this.currentLocation.href)}get currentLocator(){return this.currentLocation}get isPlaying(){return this.pool.audioEngine.isPlaying()}get isPaused(){return this.pool.audioEngine.isPaused()}get duration(){return this.pool.audioEngine.duration()}get currentTime(){return this.pool.audioEngine.currentTime()}createLocator(t,e){const i=this.pub.readingOrder.items[t];if(!i)throw new Error(`Invalid track index: ${t}`);const s=this.pool.audioEngine.duration();return new p({href:i.href,type:i.type||"audio/mpeg",title:i.title,locations:new c({progression:s>0?e/s:0,position:t+1,fragments:[`t=${e}`]})})}waitForLoadedAndSeeked(t,e){return new Promise((i,s)=>{const o=()=>{if(e!==void 0&&e!==this.navigationId){i();return}if(t<=0){i();return}const d=()=>{this.pool.audioEngine.off("seeked",d),i()};this.pool.audioEngine.on("seeked",d),this.seek(t)};if(this.pool.audioEngine.isLoaded()){o();return}const r=()=>{this.pool.audioEngine.off("canplaythrough",r),this.pool.audioEngine.off("error",h),o()},h=d=>{this.pool.audioEngine.off("canplaythrough",r),this.pool.audioEngine.off("error",h),s(d)};this.pool.audioEngine.on("canplaythrough",r),this.pool.audioEngine.on("error",h)})}setupEventListeners(){this.pool.audioEngine.on("error",t=>{this.listeners.error(t,this.currentLocator)}),this.pool.audioEngine.on("ended",async()=>{this.stopPositionPolling(),this.currentLocation=this.currentLocation.copyWithLocations(new c({position:this.currentTrackIndex()+1,progression:1,fragments:[`t=${this.duration}`]})),this.listeners.trackEnded(this.currentLocator),this.canGoForward&&(await this.nextTrack(),this._settings.autoPlay&&this.play())}),this.pool.audioEngine.on("play",()=>{this._isNavigating||(this.startPositionPolling(),this.listeners.play(this.currentLocator))}),this.pool.audioEngine.on("playing",()=>{this._isNavigating||this._setStalled(!1)}),this.pool.audioEngine.on("pause",()=>{this._isNavigating||(this.stopPositionPolling(),this.listeners.pause(this.currentLocator))}),this.pool.audioEngine.on("seeked",()=>{if(this._isNavigating)return;this.listeners.seeking(!1);const t=this.currentTime,e=this.duration,i=e>0?t/e:0;this.currentLocation=this.currentLocation.copyWithLocations(new c({position:this.currentTrackIndex()+1,progression:i,fragments:[`t=${t}`]})),this._notifyTimelineChange(this.currentLocation),this.listeners.positionChanged(this.currentLocation)}),this.pool.audioEngine.on("seeking",()=>{this._isNavigating||this.listeners.seeking(!0)}),this.pool.audioEngine.on("waiting",()=>{this._isNavigating||this.listeners.seeking(!0)}),this.pool.audioEngine.on("stalled",()=>{this._isNavigating||this._setStalled(!0)}),this.pool.audioEngine.on("canplaythrough",()=>{this._isNavigating||this._setStalled(!1)}),this.pool.audioEngine.on("progress",t=>{this._isNavigating||this.listeners.seekable(t)}),this.pool.audioEngine.on("loadedmetadata",()=>{const t=this.pool.audioEngine.getMediaElement(),e={duration:this.pool.audioEngine.duration(),textTracks:t.textTracks,readyState:t.readyState,networkState:t.networkState};this.listeners.metadataLoaded(e)})}_setStalled(t){this._isStalled!==t&&(this._isStalled=t,this.listeners.stalled(t),t?(this._stalledCheckTime=this.currentTime,this._startStalledWatchdog()):this._stopStalledWatchdog())}_startStalledWatchdog(){this._stalledWatchdog=setInterval(()=>{if(!this.isPlaying){this._setStalled(!1);return}const t=this.currentTime;t!==this._stalledCheckTime&&this._setStalled(!1),this._stalledCheckTime=t},500)}_stopStalledWatchdog(){this._stalledWatchdog!==null&&(clearInterval(this._stalledWatchdog),this._stalledWatchdog=null)}setupMediaSession(){"mediaSession"in navigator&&(navigator.mediaSession.setActionHandler("play",()=>this.play()),navigator.mediaSession.setActionHandler("pause",()=>this.pause()),navigator.mediaSession.setActionHandler("previoustrack",()=>this.goBackward(!1,()=>{})),navigator.mediaSession.setActionHandler("nexttrack",()=>this.goForward(!1,()=>{})),navigator.mediaSession.setActionHandler("seekbackward",t=>this.jump(-(t.seekOffset||10))),navigator.mediaSession.setActionHandler("seekforward",t=>this.jump(t.seekOffset||10)),this.updateMediaSessionMetadata())}updateMediaSessionMetadata(){if(!("mediaSession"in navigator))return;const t=this.currentTrackIndex(),e=this.pub.readingOrder.items[t],i=this.pub.getCover();navigator.mediaSession.metadata=new MediaMetadata({title:e?.title||`Track ${t+1}`,artist:this.pub.metadata.authors?this.pub.metadata.authors.items.map(s=>s.name.getTranslation()).join(", "):void 0,album:this.pub.metadata.title.getTranslation(),artwork:i?[{src:i.toURL(this.pub.baseURL)??i.href,type:i.type}]:void 0})}startPositionPolling(){this.stopPositionPolling(),this.positionPollInterval=setInterval(()=>{const t=this.currentTime,e=this.duration,i=e>0?t/e:0;this.currentLocation=this.currentLocation.copyWithLocations(new c({position:this.currentTrackIndex()+1,progression:i,fragments:[`t=${t}`]})),this._notifyTimelineChange(this.currentLocation),this.listeners.positionChanged(this.currentLocation)},this._settings.pollInterval)}stopPositionPolling(){this.positionPollInterval!==null&&(clearInterval(this.positionPollInterval),this.positionPollInterval=null)}async go(t,e,i){try{t=this.ensureLocatorLocations(t);const s=t.href.split("#")[0],o=this.hrefToTrackIndex(s),r=g(t.locations)||0;if(o===-1){i(!1);return}const h=++this.navigationId,d=this.currentTrackIndex(),a=o>=d?"forward":"backward",u=this.isPlaying||this._playIntent;if(this._playIntent=u,this._isNavigating=!0,this.stopPositionPolling(),this.pool.setCurrentAudio(o,a),this.currentLocation=t.copyWithLocations(t.locations),await this.waitForLoadedAndSeeked(r,h),this._isNavigating=!1,h!==this.navigationId){i(!1);return}o!==d&&this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()),this._notifyTimelineChange(this.currentLocator),this.listeners.positionChanged(this.currentLocator),this._settings.enableMediaSession&&this.updateMediaSessionMetadata(),u&&this.play(),i(!0)}catch(s){this._isNavigating=!1,console.error("Failed to go to locator:",s),i(!1)}finally{this._playIntent=!1}}async goLink(t,e,i){const s=this.hrefToTrackIndex(t.href);if(s===-1){i(!1);return}const o=g(t.locator.locations)??0,r=this.createLocator(s,o);await this.go(r,e,i)}async goForward(t,e){if(!this.canGoForward){e(!1);return}await this.nextTrack(),e(!0)}async goBackward(t,e){if(!this.canGoBackward){e(!1);return}await this.previousTrack(),e(!0)}play(){this.pool.audioEngine.play()}pause(){this.pool.audioEngine.pause()}stop(){this.pool.audioEngine.stop()}async nextTrack(){if(!this.canGoForward)return;const t=this.createLocator(this.currentTrackIndex()+1,0);await this.go(t,!1,()=>{})}async previousTrack(){if(!this.canGoBackward)return;const t=this.createLocator(this.currentTrackIndex()-1,0);await this.go(t,!1,()=>{})}seek(t){this.pool.audioEngine.skip(t-this.pool.audioEngine.currentTime())}jump(t){this.pool.audioEngine.skip(t)}skipForward(){this.pool.audioEngine.skip(this._settings.skipForwardInterval)}skipBackward(){this.pool.audioEngine.skip(-this._settings.skipBackwardInterval)}get isTrackStart(){return this.currentTrackIndex()===0&&(g(this.currentLocation.locations)||0)===0}get isTrackEnd(){const t=this.currentTrackIndex();if(t!==this.pub.readingOrder.items.length-1)return!1;const e=this.currentLocation.locations?.progression;if(e!==void 0)return e>=1;const i=this.pub.readingOrder.items[t],s=this.duration||i?.duration||0;return s>0&&(g(this.currentLocation.locations)??0)>=s}get canGoBackward(){return this.currentTrackIndex()>0}get canGoForward(){return this.currentTrackIndex()<this.pub.readingOrder.items.length-1}get remotePlayback(){const t=this.pool.audioEngine.getMediaElement();return"remote"in t?t.remote:void 0}_setupRemotePlayback(){if(this._contentProtection.disableRemotePlayback)return;const t=this.remotePlayback;t&&(t.onconnecting=()=>this.listeners.remotePlaybackStateChanged("connecting"),t.onconnect=()=>this.listeners.remotePlaybackStateChanged("connected"),t.ondisconnect=()=>this.listeners.remotePlaybackStateChanged("disconnected"))}destroyMediaSession(){"mediaSession"in navigator&&(navigator.mediaSession.metadata=null,navigator.mediaSession.setActionHandler("play",null),navigator.mediaSession.setActionHandler("pause",null),navigator.mediaSession.setActionHandler("previoustrack",null),navigator.mediaSession.setActionHandler("nexttrack",null),navigator.mediaSession.setActionHandler("seekbackward",null),navigator.mediaSession.setActionHandler("seekforward",null))}destroy(){this.stopPositionPolling(),this._stopStalledWatchdog(),this.destroyMediaSession(),this._suspiciousActivityListener&&window.removeEventListener(k,this._suspiciousActivityListener),this._keyboardPeripheralListener&&window.removeEventListener(_,this._keyboardPeripheralListener),this._navigatorProtector?.destroy(),this._keyboardPeripheralsManager?.destroy(),this.pool.destroy()}}export{B as AudioNavigator};
@@ -0,0 +1 @@
1
+ class d{constructor(t,o,s={}){this.pool=new Map,this._audioEngine=t,this._publication=o,this._supportedAudioTypes=this.detectSupportedAudioTypes(),s.disableRemotePlayback&&(this._audioEngine.getMediaElement().disableRemotePlayback=!0)}detectSupportedAudioTypes(){const t=document.createElement("audio"),o=new Set;for(const e of this._publication.readingOrder.items){e.type&&o.add(e.type);for(const i of e.alternates?.items??[])i.type&&o.add(i.type)}const s=new Map;for(const e of o){const i=t.canPlayType(e);i!==""&&s.set(e,i)}return s}pickPlayableHref(t){const o=this._publication.baseURL,s=[t,...t.alternates?.items??[]];let e;for(const i of s){if(!i.type)continue;const n=this._supportedAudioTypes.get(i.type);if(!n)continue;const a=i.toURL(o)??i.href;if(n==="probably")return a;e||(e={href:a,confidence:n})}return e?.href??t.toURL(o)??t.href}get audioEngine(){return this._audioEngine}ensure(t){let o=this.pool.get(t);return o||(o=document.createElement("audio"),o.preload="auto",this._audioEngine.isWebAudioActive&&(o.crossOrigin="anonymous"),o.src=t,o.load(),this.pool.set(t,o)),o}update(t){const o=this._publication.readingOrder.items,s=new Set;for(let e=0;e<o.length;e++){if(e===t)continue;const i=this.pickPlayableHref(o[e]);e>=t-1&&e<=t+1?(this.ensure(i),s.add(i)):e>=t-1&&e<=t+1&&this.pool.has(i)&&s.add(i)}for(const[e,i]of this.pool)s.has(e)||(i.removeAttribute("src"),i.load(),this.pool.delete(e))}setCurrentAudio(t,o){const s=this.pickPlayableHref(this._publication.readingOrder.items[t]);if(this.audioEngine.changeSrc(s),this.pool.has(s)){const e=this.pool.get(s);e.removeAttribute("src"),e.load(),this.pool.delete(s)}this.update(t)}destroy(){this.audioEngine.stop();for(const[,t]of this.pool)t.removeAttribute("src"),t.load();this.pool.clear()}}export{d as AudioPoolManager};
@@ -0,0 +1,215 @@
1
+ const n=`// PreservePitchProcessor.js
2
+ // AudioWorklet processor for pitch preservation via pitch shifting.
3
+ //
4
+ // Architecture:
5
+ // - Overlap-add (OLA) phase vocoder with an iterative in-place Cooley-Tukey FFT/IFFT.
6
+ // - All intermediate buffers are pre-allocated in the constructor; the hot path
7
+ // (process → _processBuffer → _fft) is allocation-free and GC-safe.
8
+ // - An output ring buffer decouples OLA processing (fires every hopSize input
9
+ // samples) from the Web Audio render quantum (128 frames), so process() always
10
+ // fills outputChannel completely.
11
+
12
+ class PreservePitchProcessor extends AudioWorkletProcessor {
13
+ constructor() {
14
+ super();
15
+ this.bufferSize = 1024;
16
+ this.hopSize = 256;
17
+ this.overlap = this.bufferSize - this.hopSize;
18
+ this.pitchFactor = 1.0;
19
+
20
+ // Sliding input window (always holds the last bufferSize samples)
21
+ this.inputBuffer = new Float32Array(this.bufferSize);
22
+ this.inputFill = 0; // samples loaded during startup (saturates at bufferSize)
23
+ this.hopAccum = 0; // new samples since last OLA step; triggers a step at hopSize
24
+
25
+ // OLA output accumulator: overlap-add results accumulate here; hopSize samples
26
+ // are drained to the ring buffer and the remainder shifts down each OLA step.
27
+ this.olaBuffer = new Float32Array(this.bufferSize);
28
+
29
+ // Output FIFO ring buffer — power-of-2 size for allocation-free modulo wrapping.
30
+ this._ringSize = 4096;
31
+ this._ring = new Float32Array(this._ringSize);
32
+ this._ringMask = this._ringSize - 1;
33
+ this._ringWrite = 0;
34
+ this._ringRead = 0;
35
+ this._ringAvail = 0;
36
+
37
+ // Hann window (pre-computed, never mutated)
38
+ this.window = new Float32Array(this.bufferSize);
39
+ for (let i = 0; i < this.bufferSize; i++) {
40
+ this.window[i] = 0.5 * (1 - Math.cos(2 * Math.PI * i / this.bufferSize));
41
+ }
42
+
43
+ // Pre-allocated FFT work buffers — never re-created in the hot path
44
+ this._re = new Float64Array(this.bufferSize);
45
+ this._im = new Float64Array(this.bufferSize);
46
+ this._shiftedRe = new Float64Array(this.bufferSize);
47
+ this._shiftedIm = new Float64Array(this.bufferSize);
48
+
49
+ this.port.onmessage = (event) => {
50
+ if (event.data.type === 'setPitchFactor') {
51
+ this.pitchFactor = event.data.factor;
52
+ }
53
+ };
54
+ }
55
+
56
+ process(inputs, outputs) {
57
+ const input = inputs[0];
58
+ const output = outputs[0];
59
+ if (!input || !output) return true;
60
+ const inCh = input[0];
61
+ const outCh = output[0];
62
+ if (!inCh || !outCh) return true;
63
+
64
+ const newCount = inCh.length; // always 128 under normal Web Audio conditions
65
+
66
+ // --- 1. Push new samples into the sliding input window ---
67
+ if (this.inputFill < this.bufferSize) {
68
+ // Startup: fill the window until we have a full bufferSize frame.
69
+ // Since bufferSize (1024) is an exact multiple of the render quantum (128)
70
+ // this branch always copies exactly newCount samples.
71
+ this.inputBuffer.set(inCh, this.inputFill);
72
+ this.inputFill += newCount;
73
+ } else {
74
+ // Steady state: slide left by newCount, append the new quantum at the end.
75
+ this.inputBuffer.copyWithin(0, newCount);
76
+ this.inputBuffer.set(inCh, this.bufferSize - newCount);
77
+ }
78
+ this.hopAccum += newCount;
79
+
80
+ // --- 2. Run OLA step(s) whenever hopAccum reaches hopSize ---
81
+ // During startup we skip processing until a full window is available.
82
+ while (this.inputFill >= this.bufferSize && this.hopAccum >= this.hopSize) {
83
+ this.hopAccum -= this.hopSize;
84
+ this._processBuffer(); // drains hopSize samples into _ring
85
+ }
86
+
87
+ // --- 3. Drain output ring into outputChannel ---
88
+ // Output silence during the initial buffering latency (bufferSize samples ≈ 23 ms
89
+ // at 44100 Hz). Once the ring has data it stays ahead of demand.
90
+ if (this._ringAvail >= newCount) {
91
+ for (let i = 0; i < newCount; i++) {
92
+ outCh[i] = this._ring[this._ringRead];
93
+ this._ringRead = (this._ringRead + 1) & this._ringMask;
94
+ }
95
+ this._ringAvail -= newCount;
96
+ } else {
97
+ outCh.fill(0);
98
+ }
99
+
100
+ return true;
101
+ }
102
+
103
+ _processBuffer() {
104
+ const N = this.bufferSize;
105
+ const re = this._re;
106
+ const im = this._im;
107
+ const shiftedRe = this._shiftedRe;
108
+ const shiftedIm = this._shiftedIm;
109
+ const win = this.window;
110
+
111
+ // Load windowed input into real part; zero imaginary part
112
+ for (let i = 0; i < N; i++) {
113
+ re[i] = this.inputBuffer[i] * win[i];
114
+ im[i] = 0;
115
+ }
116
+
117
+ this._fft(re, im, false);
118
+
119
+ // Spectral pitch shift: map bin k → round(k * factor)
120
+ shiftedRe.fill(0);
121
+ shiftedIm.fill(0);
122
+ const half = N >> 1;
123
+ const factor = this.pitchFactor;
124
+ for (let k = 0; k <= half; k++) {
125
+ const newK = Math.round(k * factor);
126
+ if (newK <= half) {
127
+ shiftedRe[newK] += re[k];
128
+ shiftedIm[newK] += im[k];
129
+ // Restore conjugate symmetry so the IFFT yields a real-valued signal
130
+ if (newK > 0 && newK < half) {
131
+ shiftedRe[N - newK] = shiftedRe[newK];
132
+ shiftedIm[N - newK] = -shiftedIm[newK];
133
+ }
134
+ }
135
+ }
136
+
137
+ this._fft(shiftedRe, shiftedIm, true); // in-place IFFT
138
+
139
+ // Overlap-add into olaBuffer
140
+ for (let i = 0; i < N; i++) {
141
+ this.olaBuffer[i] += shiftedRe[i] * win[i];
142
+ }
143
+
144
+ // Push hopSize output samples to the ring buffer
145
+ for (let i = 0; i < this.hopSize; i++) {
146
+ this._ring[this._ringWrite] = this.olaBuffer[i];
147
+ this._ringWrite = (this._ringWrite + 1) & this._ringMask;
148
+ }
149
+ this._ringAvail += this.hopSize;
150
+
151
+ // Shift the OLA accumulator left by hopSize; clear the vacated tail
152
+ this.olaBuffer.copyWithin(0, this.hopSize);
153
+ this.olaBuffer.fill(0, this.bufferSize - this.hopSize);
154
+ }
155
+
156
+ /**
157
+ * In-place iterative Cooley-Tukey FFT / IFFT.
158
+ * Operates entirely on the caller-supplied Float64Arrays — no allocation.
159
+ *
160
+ * @param {Float64Array} re Real parts (mutated in place)
161
+ * @param {Float64Array} im Imaginary parts (mutated in place)
162
+ * @param {boolean} inverse true → IFFT (divides by N), false → FFT
163
+ */
164
+ _fft(re, im, inverse) {
165
+ const N = re.length;
166
+
167
+ // Bit-reversal permutation
168
+ let j = 0;
169
+ for (let i = 1; i < N; i++) {
170
+ let bit = N >> 1;
171
+ for (; j & bit; bit >>= 1) j ^= bit;
172
+ j ^= bit;
173
+ if (i < j) {
174
+ let tmp;
175
+ tmp = re[i]; re[i] = re[j]; re[j] = tmp;
176
+ tmp = im[i]; im[i] = im[j]; im[j] = tmp;
177
+ }
178
+ }
179
+
180
+ // Butterfly stages — O(N log N), no allocation
181
+ const sign = inverse ? 1 : -1;
182
+ for (let len = 2; len <= N; len <<= 1) {
183
+ const halfLen = len >> 1;
184
+ const ang = sign * Math.PI / halfLen;
185
+ const wBaseRe = Math.cos(ang);
186
+ const wBaseIm = Math.sin(ang);
187
+ for (let i = 0; i < N; i += len) {
188
+ let wRe = 1, wIm = 0;
189
+ for (let k = 0; k < halfLen; k++) {
190
+ const uRe = re[i + k];
191
+ const uIm = im[i + k];
192
+ const vRe = re[i + k + halfLen] * wRe - im[i + k + halfLen] * wIm;
193
+ const vIm = re[i + k + halfLen] * wIm + im[i + k + halfLen] * wRe;
194
+ re[i + k] = uRe + vRe;
195
+ im[i + k] = uIm + vIm;
196
+ re[i + k + halfLen] = uRe - vRe;
197
+ im[i + k + halfLen] = uIm - vIm;
198
+ const newWRe = wRe * wBaseRe - wIm * wBaseIm;
199
+ wIm = wRe * wBaseIm + wIm * wBaseRe;
200
+ wRe = newWRe;
201
+ }
202
+ }
203
+ }
204
+
205
+ if (inverse) {
206
+ for (let i = 0; i < N; i++) {
207
+ re[i] /= N;
208
+ im[i] /= N;
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ registerProcessor('preserve-pitch-processor', PreservePitchProcessor);
215
+ `;export{n as default};
@@ -0,0 +1 @@
1
+ import i from"./PreservePitchProcessor.js";class c{constructor(r){this.workletNode=null,this.url=null,this.ctx=r}static async createWorklet(r){const{ctx:o,pitchFactor:l,modulePath:s}=r,t=new c(o);try{if(s)await o.audioWorklet.addModule(s);else{const e=new Blob([i],{type:"text/javascript"});t.url=URL.createObjectURL(e),await o.audioWorklet.addModule(t.url)}}catch(e){throw t.destroy(),new Error(`Error adding module: ${e}`)}try{t.workletNode=new AudioWorkletNode(o,"preserve-pitch-processor"),l&&t.updatePitchFactor(l)}catch(e){throw t.destroy(),new Error(`Error creating worklet node: ${e}`)}return t}updatePitchFactor(r){this.workletNode&&this.workletNode.port.postMessage({type:"setPitchFactor",factor:r})}destroy(){this.workletNode&&(this.workletNode.disconnect(),this.workletNode=null),this.url&&(URL.revokeObjectURL(this.url),this.url=null)}}export{c as PreservePitchWorklet};
@@ -0,0 +1 @@
1
+ import{PreservePitchWorklet as r}from"./PreservePitchWorklet.js";class u{constructor(e){this.audioContext=null,this.sourceNode=null,this.gainNode=null,this.listeners={},this.isMutedValue=!1,this.isPlayingValue=!1,this.isPausedValue=!1,this.isLoadingValue=!1,this.isLoadedValue=!1,this.isEndedValue=!1,this.isStoppedValue=!1,this.worklet=null,this.webAudioActive=!1,this.boundOnCanPlayThrough=this.onCanPlayThrough.bind(this),this.boundOnTimeUpdate=this.onTimeUpdate.bind(this),this.boundOnError=this.onError.bind(this),this.boundOnEnded=this.onEnded.bind(this),this.boundOnStalled=this.onStalled.bind(this),this.boundOnEmptied=this.onEmptied.bind(this),this.boundOnSuspend=this.onSuspend.bind(this),this.boundOnWaiting=this.onWaiting.bind(this),this.boundOnLoadedMetadata=this.onLoadedMetadata.bind(this),this.boundOnSeeking=this.onSeeking.bind(this),this.boundOnSeeked=this.onSeeked.bind(this),this.boundOnPlay=this.onPlay.bind(this),this.boundOnPlaying=this.onPlaying.bind(this),this.boundOnPause=this.onPause.bind(this),this.boundOnProgress=this.onProgress.bind(this),this.playback=e.playback,this.mediaElement=document.createElement("audio"),this.mediaElement.addEventListener("canplaythrough",this.boundOnCanPlayThrough),this.mediaElement.addEventListener("timeupdate",this.boundOnTimeUpdate),this.mediaElement.addEventListener("error",this.boundOnError),this.mediaElement.addEventListener("ended",this.boundOnEnded),this.mediaElement.addEventListener("stalled",this.boundOnStalled),this.mediaElement.addEventListener("emptied",this.boundOnEmptied),this.mediaElement.addEventListener("suspend",this.boundOnSuspend),this.mediaElement.addEventListener("waiting",this.boundOnWaiting),this.mediaElement.addEventListener("loadedmetadata",this.boundOnLoadedMetadata),this.mediaElement.addEventListener("seeking",this.boundOnSeeking),this.mediaElement.addEventListener("seeked",this.boundOnSeeked),this.mediaElement.addEventListener("play",this.boundOnPlay),this.mediaElement.addEventListener("playing",this.boundOnPlaying),this.mediaElement.addEventListener("pause",this.boundOnPause),this.mediaElement.addEventListener("progress",this.boundOnProgress),this.mediaElement.currentTime=this.playback.state.currentTime}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)}off(e,t){this.listeners[e]&&(this.listeners[e]=this.listeners[e].filter(i=>i!==t))}async ensureAudioContextRunning(){this.audioContext||(this.audioContext=new AudioContext),this.audioContext.state==="suspended"&&await this.audioContext.resume()}getOrCreateAudioContext(){return this.audioContext||(this.audioContext=new AudioContext),this.audioContext}onTimeUpdate(){this.emit("timeupdate",this.mediaElement.currentTime)}onCanPlayThrough(){this.isLoadingValue=!1,this.isLoadedValue=!0,this.emit("canplaythrough",null)}onError(){console.error("Error loading media element"),this.emit("error",this.mediaElement.error)}onEnded(){this.isPlayingValue=!1,this.isPausedValue=!1,this.isEndedValue=!0,this.emit("ended",null)}onStalled(e){this.emit("stalled",e)}onEmptied(e){this.emit("emptied",e)}onSuspend(e){this.emit("suspend",e)}onWaiting(e){this.emit("waiting",e)}onLoadedMetadata(e){this.emit("loadedmetadata",e)}onSeeking(e){this.emit("seeking",e)}onSeeked(e){this.emit("seeked",e)}onPlay(){this.emit("play",null)}onPlaying(){this.emit("playing",null)}onPause(){this.emit("pause",null)}onProgress(){this.emit("progress",this.mediaElement.seekable)}emit(e,t){this.listeners[e]&&this.listeners[e].forEach(i=>i(t))}async play(){if(!this.isPlayingValue)try{this.audioContext&&await this.ensureAudioContextRunning(),await this.mediaElement.play(),this.isPlayingValue=!0,this.isPausedValue=!1,this.isStoppedValue=!1}catch(e){if(e?.name==="AbortError")return;console.error("error trying to play media element",e),this.emit("error",e)}}pause(){this.mediaElement.pause(),this.isPlayingValue=!1,this.isPausedValue=!0}stop(){this.mediaElement.pause(),this.mediaElement.currentTime=0,this.isPlayingValue=!1,this.isPausedValue=!1,this.isStoppedValue=!0}setVolume(e){const t=Math.max(0,Math.min(1,e));this.gainNode?(this.mediaElement.volume=1,this.gainNode.gain.value=t):this.mediaElement.volume=t,this.isMutedValue=t===0}skip(e){const t=this.mediaElement.duration;if(!isFinite(t))return;const i=this.mediaElement.currentTime+e;i<0?this.mediaElement.currentTime=0:i>t?this.mediaElement.currentTime=t:this.mediaElement.currentTime=i}currentTime(){return this.mediaElement.currentTime}duration(){return this.mediaElement.duration}isPlaying(){return this.isPlayingValue}isPaused(){return this.isPausedValue}isStopped(){return this.isStoppedValue}isLoading(){return this.isLoadingValue}isLoaded(){return this.isLoadedValue}isEnded(){return this.isEndedValue}isMuted(){return this.isMutedValue}setPlaybackRate(e,t){this.mediaElement.playbackRate=e,t?"preservesPitch"in this.mediaElement?this.mediaElement.preservesPitch=!0:this.activateWebAudio().then(()=>{this.worklet?this.worklet.updatePitchFactor(1/e):r.createWorklet({ctx:this.getOrCreateAudioContext(),pitchFactor:1}).then(i=>{this.sourceNode&&this.sourceNode.disconnect(),this.worklet=i,this.sourceNode?.connect(this.worklet.workletNode),this.worklet.workletNode.connect(this.gainNode),this.worklet.updatePitchFactor(1/e)}).catch(i=>{console.warn("Failed to create preserve pitch worklet",i)})}).catch(i=>{console.warn("Web Audio unavailable, playing without pitch correction:",i)}):("preservesPitch"in this.mediaElement&&(this.mediaElement.preservesPitch=!1),this.worklet&&(this.worklet.destroy(),this.worklet=null,this.webAudioActive&&this.sourceNode&&(this.sourceNode.disconnect(),this.sourceNode.connect(this.gainNode))))}async activateWebAudio(){if(this.webAudioActive)return;const e=this.mediaElement.src;if(!e)return;const t=this.mediaElement.currentTime,i=this.isPlayingValue;i&&(this.mediaElement.pause(),this.isPlayingValue=!1),this.mediaElement.crossOrigin="anonymous",this.mediaElement.src=e,this.mediaElement.load();try{await new Promise((a,d)=>{const s=()=>{this.mediaElement.removeEventListener("canplaythrough",s),this.mediaElement.removeEventListener("error",o),a()},o=()=>{this.mediaElement.removeEventListener("canplaythrough",s),this.mediaElement.removeEventListener("error",o),d(new Error("Audio reload with CORS failed — server may not send Access-Control-Allow-Origin"))};this.mediaElement.addEventListener("canplaythrough",s),this.mediaElement.addEventListener("error",o)})}catch(a){throw this.mediaElement.removeAttribute("crossorigin"),this.mediaElement.src=e,this.mediaElement.load(),i?(await new Promise(d=>{const s=()=>{this.mediaElement.removeEventListener("canplaythrough",s),d()};this.mediaElement.addEventListener("canplaythrough",s)}),this.mediaElement.currentTime=t,await this.mediaElement.play(),this.isPlayingValue=!0,this.isPausedValue=!1):this.mediaElement.currentTime=t,a}this.mediaElement.currentTime=t,this.sourceNode=new MediaElementAudioSourceNode(this.getOrCreateAudioContext(),{mediaElement:this.mediaElement});const n=this.getOrCreateAudioContext();this.gainNode=n.createGain(),this.gainNode.gain.value=this.mediaElement.volume,this.mediaElement.volume=1,this.sourceNode.connect(this.gainNode),this.gainNode.connect(n.destination),this.webAudioActive=!0,i&&(await this.ensureAudioContextRunning(),await this.mediaElement.play(),this.isPlayingValue=!0,this.isPausedValue=!1)}get isWebAudioActive(){return this.webAudioActive}tearDownWebAudio(){this.worklet&&(this.worklet.destroy(),this.worklet=null),this.sourceNode&&(this.sourceNode.disconnect(),this.sourceNode=null),this.gainNode&&(this.mediaElement.volume=this.gainNode.gain.value,this.gainNode.disconnect(),this.gainNode=null),this.webAudioActive=!1}changeSrc(e){if(this.mediaElement.src!==e)if(this.mediaElement.pause(),this.isPlayingValue=!1,this.isPausedValue=!1,this.isLoadedValue=!1,this.isLoadingValue=!0,this.isEndedValue=!1,this.webAudioActive){this.mediaElement.crossOrigin="anonymous",this.mediaElement.src=e,this.mediaElement.load();const t=()=>{n()},i=()=>{n(),console.warn("CORS reload failed for new track — disabling Web Audio graph:",e),this.tearDownWebAudio(),this.mediaElement.removeAttribute("crossorigin"),this.mediaElement.src=e,this.mediaElement.load()},n=()=>{this.mediaElement.removeEventListener("canplaythrough",t),this.mediaElement.removeEventListener("error",i)};this.mediaElement.addEventListener("canplaythrough",t),this.mediaElement.addEventListener("error",i)}else this.mediaElement.src=e,this.mediaElement.load()}getMediaElement(){return this.mediaElement}}export{u as WebAudioEngine};
@@ -0,0 +1 @@
1
+ import{ensureValueInRange as a,ensureBoolean as r,ensureNonNegative as i}from"../../preferences/guards.js";import{volumeRangeConfig as o,playbackRateRangeConfig as t,skipIntervalRangeConfig as n}from"../../preferences/Types.js";class v{constructor(e={}){this.volume=a(e.volume,o.range)??1,this.playbackRate=a(e.playbackRate,t.range)??1,this.preservePitch=r(e.preservePitch)??!0,this.skipBackwardInterval=a(e.skipBackwardInterval,n.range)??10,this.skipForwardInterval=a(e.skipForwardInterval,n.range)??10,this.pollInterval=i(e.pollInterval)??1e3,this.autoPlay=r(e.autoPlay)??!0,this.enableMediaSession=r(e.enableMediaSession)??!0}}export{v as AudioDefaults};
@@ -0,0 +1 @@
1
+ import{ensureValueInRange as t,ensureBoolean as n,ensureNonNegative as s}from"../../preferences/guards.js";import{volumeRangeConfig as r,playbackRateRangeConfig as g,skipIntervalRangeConfig as e}from"../../preferences/Types.js";class l{constructor(a={}){this.volume=t(a.volume,r.range),this.playbackRate=t(a.playbackRate,g.range),this.preservePitch=n(a.preservePitch),this.skipBackwardInterval=t(a.skipBackwardInterval,e.range),this.skipForwardInterval=t(a.skipForwardInterval,e.range),this.pollInterval=s(a.pollInterval),this.autoPlay=n(a.autoPlay),this.enableMediaSession=n(a.enableMediaSession)}merging(a){const o={...this};for(const i of Object.keys(a))a[i]!==void 0&&(o[i]=a[i]);return new l(o)}}export{l as AudioPreferences};
@@ -0,0 +1 @@
1
+ import{AudioPreferences as l}from"./AudioPreferences.js";import{RangePreference as t,BooleanPreference as i,Preference as p}from"../../preferences/Preference.js";import{volumeRangeConfig as a,playbackRateRangeConfig as s,skipIntervalRangeConfig as n}from"../../preferences/Types.js";class h{constructor(e,r){this.preferences=e,this.settings=r}clear(){this.preferences=new l}updatePreference(e,r){this.preferences[e]=r}get volume(){return new t({initialValue:this.preferences.volume,effectiveValue:this.settings.volume,isEffective:this.preferences.volume!==null,onChange:e=>{this.updatePreference("volume",e??null)},supportedRange:a.range,step:a.step})}get playbackRate(){return new t({initialValue:this.preferences.playbackRate,effectiveValue:this.settings.playbackRate,isEffective:this.preferences.playbackRate!==null,onChange:e=>{this.updatePreference("playbackRate",e??null)},supportedRange:s.range,step:s.step})}get preservePitch(){return new i({initialValue:this.preferences.preservePitch,effectiveValue:this.settings.preservePitch,isEffective:this.preferences.preservePitch!==null,onChange:e=>{this.updatePreference("preservePitch",e??null)}})}get skipBackwardInterval(){return new t({initialValue:this.preferences.skipBackwardInterval,effectiveValue:this.settings.skipBackwardInterval,isEffective:this.preferences.skipBackwardInterval!==null,onChange:e=>{this.updatePreference("skipBackwardInterval",e??null)},supportedRange:n.range,step:n.step})}get skipForwardInterval(){return new t({initialValue:this.preferences.skipForwardInterval,effectiveValue:this.settings.skipForwardInterval,isEffective:this.preferences.skipForwardInterval!==null,onChange:e=>{this.updatePreference("skipForwardInterval",e??null)},supportedRange:n.range,step:n.step})}get pollInterval(){return new p({initialValue:this.preferences.pollInterval,effectiveValue:this.settings.pollInterval,isEffective:this.preferences.pollInterval!==null,onChange:e=>{this.updatePreference("pollInterval",e??null)}})}get autoPlay(){return new i({initialValue:this.preferences.autoPlay,effectiveValue:this.settings.autoPlay,isEffective:this.preferences.autoPlay!==null,onChange:e=>{this.updatePreference("autoPlay",e??null)}})}get enableMediaSession(){return new i({initialValue:this.preferences.enableMediaSession,effectiveValue:this.settings.enableMediaSession,isEffective:this.preferences.enableMediaSession!==null,onChange:e=>{this.updatePreference("enableMediaSession",e??null)}})}}export{h as AudioPreferencesEditor};
@@ -0,0 +1 @@
1
+ class l{constructor(a,i){this.volume=a.volume??i.volume,this.playbackRate=a.playbackRate??i.playbackRate,this.preservePitch=a.preservePitch??i.preservePitch,this.skipBackwardInterval=a.skipBackwardInterval??i.skipBackwardInterval,this.skipForwardInterval=a.skipForwardInterval??i.skipForwardInterval,this.pollInterval=a.pollInterval??i.pollInterval,this.autoPlay=a.autoPlay??i.autoPlay,this.enableMediaSession=a.enableMediaSession??i.enableMediaSession}}export{l as AudioSettings};
@@ -0,0 +1 @@
1
+ import{NavigatorProtector as e}from"../../protection/NavigatorProtector.js";import{DragAndDropProtector as c}from"../../protection/DragAndDropProtector.js";import{CopyProtector as i}from"../../protection/CopyProtector.js";class y extends e{constructor(t={}){super(t),t.disableDragAndDrop&&(this.dragAndDropProtector=new c({onDragDetected:r=>{this.dispatchSuspiciousActivity("drag_detected",{dataTransferTypes:r,targetFrameSrc:""})},onDropDetected:(r,o)=>{this.dispatchSuspiciousActivity("drop_detected",{dataTransferTypes:r,fileCount:o,targetFrameSrc:""})}})),t.protectCopy&&(this.copyProtector=new i({onCopyBlocked:()=>{this.dispatchSuspiciousActivity("bulk_copy",{targetFrameSrc:""})}}))}destroy(){super.destroy(),this.dragAndDropProtector?.destroy(),this.copyProtector?.destroy()}}export{y as AudioNavigatorProtector};
@@ -0,0 +1 @@
1
+ class n{constructor(){}toFlag(t){return`readium-${t}-on`}toUnitless(t){return t.toString()}toPercentage(t,r=!1){return r||t>0&&t<=1?`${Math.round(t*100)}%`:`${t}%`}toVw(t){const r=Math.round(t*100);return`${Math.min(r,100)}vw`}toVh(t){const r=Math.round(t*100);return`${Math.min(r,100)}vh`}toPx(t){return`${t}px`}toRem(t){return`${t}rem`}}export{n as Properties};
@@ -0,0 +1 @@
1
+ const t='!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports._readium_cssSelectorGenerator=e():t._readium_cssSelectorGenerator=e()}(self,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function n(t){return"object"==typeof t&&null!==t&&t.nodeType===Node.ELEMENT_NODE}t.r(e),t.d(e,{_readium_cssSelectorGenerator:()=>Z,default:()=>tt,getCssSelector:()=>X});const o={NONE:"",DESCENDANT:" ",CHILD:" > "},r={id:"id",class:"class",tag:"tag",attribute:"attribute",nthchild:"nthchild",nthoftype:"nthoftype"},i="_readium_cssSelectorGenerator";function c(t="unknown problem",...e){console.warn(`${i}: ${t}`,...e)}const s={selectors:[r.id,r.class,r.tag,r.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY,useScope:!1};function u(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||u(t)}function a(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||c("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will not work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&c("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):S(e)}function m(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function p(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function g(t){const e=t.map((t=>{if(u(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(c("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return c("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function h(t,e,n){const o=Array.from(d(n,t[0]).querySelectorAll(e));return o.length===t.length&&t.every((t=>o.includes(t)))}function y(t,e){e=null!=e?e:S(t);const o=[];let r=t;for(;n(r)&&r!==e;)o.push(r),r=r.parentElement;return o}function b(t,e){return p(t.map((t=>y(t,e))))}function S(t){return t.ownerDocument.querySelector(":root")}const N=", ",v=new RegExp(["^$","\\\\s"].join("|")),E=new RegExp(["^$"].join("|")),x=[r.nthoftype,r.tag,r.id,r.class,r.attribute,r.nthchild],w=g(["class","id","ng-*"]);function I({name:t}){return`[${t}]`}function T({name:t,value:e}){return`[${t}=\'${e}\']`}function O({nodeName:t,nodeValue:e}){return{name:F(t),value:F(null!=e?e:void 0)}}function C(t){const e=Array.from(t.attributes).filter((e=>function({nodeName:t,nodeValue:e},n){const o=n.tagName.toLowerCase();return!(["input","option"].includes(o)&&"value"===t||"src"===t&&(null==e?void 0:e.startsWith("data:"))||w(t))}(e,t))).map(O);return[...e.map(I),...e.map(T)]}function j(t){var e;return(null!==(e=t.getAttribute("class"))&&void 0!==e?e:"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${F(t)}`))}function A(t){var e;const n=null!==(e=t.getAttribute("id"))&&void 0!==e?e:"",o=`#${F(n)}`,r=t.getRootNode({composed:!1});return!v.test(n)&&h([t],o,r)?[o]:[]}function R(t){var e;const n=null===(e=t.parentElement)||void 0===e?void 0:e.children;if(n)for(let e=0;e<n.length;e++)if(n[e]===t)return[`:nth-child(${String(e+1)})`];return[]}function $(t){return[F(t.tagName.toLowerCase())]}function D(t){const e=[...new Set((n=t.map($),[].concat(...n)))];var n;return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=D([t])[0],n=t.parentElement;if(n){const o=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)),r=o.indexOf(t);if(r>-1)return[`${e}:nth-of-type(${String(r+1)})`]}return[]}function*P(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){let n=0,o=L(1);for(;o.length<=t.length&&n<e;){n+=1;const e=o.map((e=>t[e]));yield e,o=_(o,t.length-1)}}function _(t=[],e=0){const n=t.length;if(0===n)return[];const o=[...t];o[n-1]+=1;for(let t=n-1;t>=0;t--)if(o[t]>e){if(0===t)return L(n+1);o[t-1]++,o[t]=o[t-1]+1}return o[n-1]>e?L(n+1):o}function L(t=1){return Array.from(Array(t).keys())}const M=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function F(t=""){return CSS?CSS.escape(t):function(t=""){return t.split("").map((t=>":"===t?`\\\\${M} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const Y={tag:D,id:function(t){return 0===t.length||t.length>1?[]:A(t[0])},class:function(t){return p(t.map(j))},attribute:function(t){return p(t.map(C))},nthchild:function(t){return p(t.map(R))},nthoftype:function(t){return p(t.map(k))}},G={tag:$,id:A,class:j,attribute:C,nthchild:R,nthoftype:k};function W(t){return t.includes(r.tag)||t.includes(r.nthoftype)?[...t]:[...t,r.tag]}function*q(t,e){const n={};for(const o of t){const t=e[o];t&&t.length>0&&(n[o]=t)}for(const t of function*(t={}){const e=Object.entries(t);if(0===e.length)return;const n=[{index:e.length-1,partial:{}}];for(;n.length>0;){const t=n.pop();if(!t)break;const{index:o,partial:r}=t;if(o<0){yield r;continue}const[i,c]=e[o];for(let t=c.length-1;t>=0;t--)n.push({index:o-1,partial:Object.assign(Object.assign({},r),{[i]:c[t]})})}}(n))yield B(t)}function B(t={}){const e=[...x];return t[r.tag]&&t[r.nthoftype]&&e.splice(e.indexOf(r.tag),1),e.map((e=>{return(o=t)[n=e]?o[n].join(""):"";var n,o})).join("")}function H(t,e){return[...t.map((t=>e+o.DESCENDANT+t)),...t.map((t=>e+o.CHILD+t))]}function*U(t,e,n="",o){const r=function*(t,e){const n=new Set,o=function(t,e){const{blacklist:n,whitelist:o,combineWithinSelector:r,maxCombinations:i}=e,c=g(n),s=g(o);return function(t){const{selectors:e,includeTag:n}=t,o=[...e];return n&&!o.includes("tag")&&o.push("tag"),o}(e).reduce(((e,n)=>{const o=function(t,e){return(0,Y[e])(t)}(t,n),u=function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(o,c,s),l=function(t=[],e){return t.sort(((t,n)=>{const o=e(t),r=e(n);return o&&!r?-1:!o&&r?1:0}))}(u,s);return e[n]=r?Array.from(P(l,{maxResults:i})):l.map((t=>[t])),e}),{})}(t,e);for(const t of function*(t,e){for(const n of function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:o,maxCandidates:r}=t,i=n?function(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){return Array.from(P(t,{maxResults:e}))}(e,{maxResults:r}):e.map((t=>[t]));return o?i.map(W):i}(e))yield*q(n,t)}(o,e))n.has(t)||(n.add(t),yield t)}(t,o);for(const o of function*(t,e){if(""===e)yield*t;else for(const n of t)yield*H([n],e)}(r,n))h(t,o,e)&&(yield o)}function*z(t,e,n="",o){if(0===t.length)return null;const r=[t.length>1?t:[],...b(t,e).map((t=>[t]))];for(const t of r)for(const r of U(t,e,n,o))yield{foundElements:t,selector:r}}function J(t){return{value:t,include:!1}}function K({selectors:t,operator:e}){let n=[...x];t[r.tag]&&t[r.nthoftype]&&(n=n.filter((t=>t!==r.tag)));let o="";return n.forEach((e=>{var n;(null!==(n=t[e])&&void 0!==n?n:[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),e+o}function Q(t,e){return t.map((t=>function(t,e){return[e?":scope":":root",...y(t,e).reverse().map((t=>{var e;const n=function(t,e,n=o.NONE){const r={};return e.forEach((e=>{Reflect.set(r,e,function(t,e){return G[e](t)}(t,e).map(J))})),{element:t,operator:n,selectors:r}}(t,[r.nthchild],o.CHILD);return(null!==(e=n.selectors.nthchild)&&void 0!==e?e:[]).forEach((t=>{t.include=!0})),n})).map(K)].join("")}(t,e))).join(N)}function X(t,e={}){return Z(t,Object.assign(Object.assign({},e),{maxResults:1})).next().value}function*Z(t,e={}){var o;const i=function(t){(t instanceof NodeList||t instanceof HTMLCollection)&&(t=Array.from(t));const e=(Array.isArray(t)?t:[t]).filter(n);return[...new Set(e)]}(t),c=function(t,e={}){const n=Object.assign(Object.assign({},s),e);return{selectors:(o=n.selectors,Array.isArray(o)?o.filter((t=>{return e=r,n=t,Object.values(e).includes(n);var e,n})):[]),whitelist:a(n.whitelist),blacklist:a(n.blacklist),root:d(n.root,t),combineWithinSelector:!!n.combineWithinSelector,combineBetweenSelectors:!!n.combineBetweenSelectors,includeTag:!!n.includeTag,maxCombinations:m(n.maxCombinations),maxCandidates:m(n.maxCandidates),useScope:!!n.useScope,maxResults:m(n.maxResults)};var o}(i[0],e),u=null!==(o=c.root)&&void 0!==o?o:S(i[0]);let l=0;for(const t of function*({elements:t,root:e,rootSelector:n="",options:o}){let r=e,i=n,c=!0;for(;c;){let n=!1;for(const c of z(t,r,i,o)){const{foundElements:o,selector:s}=c;if(n=!0,!h(t,s,e)){r=o[0],i=s;break}yield s}n||(c=!1)}}({elements:i,options:c,root:u,rootSelector:""}))if(yield t,l++,l>=c.maxResults)return;i.length>1&&(yield i.map((t=>X(t,c))).join(N),l++,l>=c.maxResults)||(yield Q(i,c.useScope?u:void 0))}const tt=X;return e})()));';export{t as default};
@@ -0,0 +1,14 @@
1
+ const n=`(function() {
2
+ if(window.onload) window.onload = new Proxy(window.onload, {
3
+ apply: function(target, receiver, args) {
4
+ if(!window._readium_blockEvents) {
5
+ Reflect.apply(target, receiver, args);
6
+ return;
7
+ }
8
+ _readium_blockedEvents.push([
9
+ 0, target, receiver, args
10
+ ]);
11
+ }
12
+ });
13
+ })();
14
+ `;export{n as default};
@@ -0,0 +1,66 @@
1
+ const e=`// Note: we aren't blocking some of the events right now to try and be as nonintrusive as possible.
2
+ // For a more comprehensive implementation, see https://github.com/hackademix/noscript/blob/3a83c0e4a506f175e38b0342dad50cdca3eae836/src/content/syncFetchPolicy.js#L142
3
+ // The snippet of code at the beginning of this source is an attempt at defence against JS using persistent storage
4
+ (function() {
5
+ const noop = () => {}, emptyObj = {}, emptyPromise = () => Promise.resolve(void 0), fakeStorage = {
6
+ getItem: noop,
7
+ setItem: noop,
8
+ removeItem: noop,
9
+ clear: noop,
10
+ key: noop,
11
+ length: 0
12
+ };
13
+
14
+ ["localStorage", "sessionStorage"].forEach((e) => Object.defineProperty(window, e, {
15
+ get: () => fakeStorage,
16
+ configurable: !0
17
+ }));
18
+
19
+ Object.defineProperty(document, "cookie", {
20
+ get: () => "",
21
+ set: noop,
22
+ configurable: !0
23
+ });
24
+
25
+ Object.defineProperty(window, "indexedDB", {
26
+ get: () => {},
27
+ configurable: !0
28
+ });
29
+
30
+ Object.defineProperty(window, "caches", {
31
+ get: () => emptyObj,
32
+ configurable: !0
33
+ });
34
+
35
+ Object.defineProperty(navigator, "storage", {
36
+ get: () => ({
37
+ persist: emptyPromise,
38
+ persisted: emptyPromise,
39
+ estimate: () => Promise.resolve({quota: 0, usage: 0})
40
+ }),
41
+ configurable: !0
42
+ });
43
+
44
+ Object.defineProperty(navigator, "serviceWorker", {
45
+ get: () => ({
46
+ register: emptyPromise,
47
+ getRegistration: emptyPromise,
48
+ ready: emptyPromise()
49
+ }),
50
+ configurable: !0
51
+ });
52
+
53
+ window._readium_blockedEvents = [];
54
+ window._readium_blockEvents = true;
55
+ window._readium_eventBlocker = (e) => {
56
+ if(!window._readium_blockEvents) return;
57
+ e.preventDefault();
58
+ e.stopImmediatePropagation();
59
+ _readium_blockedEvents.push([
60
+ 1, e, e.currentTarget || e.target
61
+ ]);
62
+ };
63
+ window.addEventListener("DOMContentLoaded", window._readium_eventBlocker, true);
64
+ window.addEventListener("load", window._readium_eventBlocker, true);
65
+ })();
66
+ `;export{e as default};
@@ -0,0 +1,5 @@
1
+ const e=`// WebPub-specific setup - no execution blocking needed
2
+ window._readium_blockedEvents = [];
3
+ window._readium_blockEvents = false; // WebPub doesn't need event blocking
4
+ window._readium_eventBlocker = null;
5
+ `;export{e as default};
@@ -0,0 +1 @@
1
+ import{Layout as d,Profile as E,Link as _,ReadingProgression as g,Locator as v,LocatorText as D,getCssSelector as O,getHtmlId as A}from"@readium/shared";import{VisualNavigator as M}from"../Navigator.js";import{FramePoolManager as I}from"./frame/FramePoolManager.js";import{FXLFramePoolManager as H}from"./fxl/FXLFramePoolManager.js";import{ModuleLibrary as T,FXLModules as F,ReflowableModules as R}from"@readium/navigator-html-injectables";import{p as y}from"../_virtual/index.js";import{FrameManager as N}from"./frame/FrameManager.js";import{EpubPreferences as V}from"./preferences/EpubPreferences.js";import{EpubDefaults as W}from"./preferences/EpubDefaults.js";import{EpubPreferencesEditor as b}from"./preferences/EpubPreferencesEditor.js";import{ReadiumCSS as j}from"./css/ReadiumCSS.js";import{UserProperties as z,RSProperties as B}from"./css/Properties.js";import{getContentWidth as K}from"../helpers/dimensions.js";import{Injector as G}from"../injection/Injector.js";import{createReadiumEpubRules as X}from"../injection/epubInjectables.js";import{NavigatorProtector as J,NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT as x}from"../protection/NavigatorProtector.js";import{KeyboardPeripherals as U,NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT as C}from"../peripherals/KeyboardPeripherals.js";import{getScriptMode as w}from"../helpers/scriptMode.js";import{EpubSettings as k}from"./preferences/EpubSettings.js";import{LineLengths as $}from"../helpers/lineLength.js";import{supportsDecorationStyle as q,decorationsEqual as Y,resolveDecorationForWire as P}from"@readium/decorator";const Q=p=>({frameLoaded:p.frameLoaded||(()=>{}),positionChanged:p.positionChanged||(()=>{}),timelineItemChanged:p.timelineItemChanged||(()=>{}),tap:p.tap||(()=>!1),click:p.click||(()=>!1),zoom:p.zoom||(()=>{}),miscPointer:p.miscPointer||(()=>{}),scroll:p.scroll||(()=>{}),customEvent:p.customEvent||(()=>{}),handleLocator:p.handleLocator||(()=>!1),textSelected:p.textSelected||(()=>{}),contentProtection:p.contentProtection||(()=>{}),contextMenu:p.contextMenu||(()=>{}),peripheral:p.peripheral||(()=>{})});class S extends M{constructor(e,t,i,s=[],r=void 0,o={preferences:{},defaults:{}}){super(),this._timelineAugmented=!1,this._preferencesEditor=null,this._injector=null,this._isNavigating=!1,this._navigatorProtector=null,this._keyboardPeripheralsManager=null,this._suspiciousActivityListener=null,this._keyboardPeripheralListener=null,this._decorations=new Map,this._decorationObservers=new Map,this._decorationHoveredDecorations=new Map,this._decorationActivationState=new Map,this._decorationHoverState=new Map,this._decorationActivationConsumed=!1,this.reflowViewport={readingOrder:[],progressions:new Map,positions:null},this.pub=t,this.container=e,this.listeners=Q(i),this.currentLocation=r,s.length&&(this.positions=s),this._preferences=new V(o.preferences),this._defaults=new W(o.defaults),this._settings=new k(this._preferences,this._defaults);const h=w(t.metadata),f=h==="cjk-horizontal",n=h==="cjk-vertical",c=n||h==="mongolian-vertical",l=f||n;this._css=new j({rsProperties:new B({noVerticalPagination:c||void 0}),userProperties:new z({}),lineLengths:new $({optimalChars:this._settings.optimalLineLength,minChars:this._settings.minimalLineLength,maxChars:this._settings.maximalLineLength,padding:this._settings.scroll?(this._settings.scrollPaddingLeft||0)+(this._settings.scrollPaddingRight||0):(this._settings.pageGutter||0)*2,fontFace:this._settings.fontFamily,letterSpacing:this._settings.letterSpacing,wordSpacing:this._settings.wordSpacing,isCJK:l}),container:e,constraint:this._settings.constraint,isCJKVertical:c}),this._layout=S.determineLayout(t,!!this._settings.scroll),this.currentProgression=t.metadata.effectiveReadingProgression,this._injectablesConfig=o.injectables||{rules:[],allowedDomains:[]},this._readiumRulesPromise=X(t.metadata,t.readingOrder.items),this._contentProtection=o.contentProtection||{},this._decoratorConfig=o.decoratorConfig||{},this._keyboardPeripherals=this.mergeKeyboardPeripherals(this._contentProtection,o.keyboardPeripherals||[]),(this._contentProtection.disableContextMenu||this._contentProtection.checkAutomation||this._contentProtection.checkIFrameEmbedding||this._contentProtection.monitorDevTools||this._contentProtection.protectPrinting?.disable)&&(this._navigatorProtector=new J(this._contentProtection),this._suspiciousActivityListener=u=>{const{type:m,...L}=u.detail;m==="context_menu"?this.listeners.contextMenu(L):this.listeners.contentProtection(m,L)},window.addEventListener(x,this._suspiciousActivityListener)),this._keyboardPeripherals.length>0&&(this._keyboardPeripheralsManager=new U({keyboardPeripherals:this._keyboardPeripherals}),this._keyboardPeripheralListener=u=>{const m=u.detail;this.listeners.peripheral(m)},window.addEventListener(C,this._keyboardPeripheralListener)),this.resizeObserver=new ResizeObserver(()=>this.ownerWindow.requestAnimationFrame(async()=>await this.resizeHandler())),this.resizeObserver.observe(this.container.parentElement||document.documentElement)}static determineLayout(e,t){const i=e.metadata.effectiveLayout;if(i===d.fixed)return d.fixed;if(e.metadata.otherMetadata&&"http://openmangaformat.org/schema/1.0#version"in e.metadata.otherMetadata)return d.fixed;if(e.metadata?.conformsTo?.includes(E.DIVINA))return d.fixed;if(i===d.scrolled)return d.scrolled;const s=w(e.metadata);return s==="cjk-vertical"||s==="mongolian-vertical"?d.scrolled:i===d.reflowable&&t?d.scrolled:d.reflowable}async load(){if(this.positions?.length||(this.positions=await this.pub.positionsFromManifest()),!this._injector){const e=await this._readiumRulesPromise;this._injector=new G({rules:[...e,...this._injectablesConfig.rules],allowedDomains:this._injectablesConfig.allowedDomains})}if(this._layout===d.fixed)this.framePool=new H(this.container,this.positions,this.pub,this._injector,this._contentProtection,this._keyboardPeripherals),this.framePool.listener=(e,t)=>{this.eventListener(e,t)};else{await this.updateCSS(!1);const e=this.compileCSSProperties(this._css);this.framePool=new I(this.container,this.positions,e,this._injector,this._contentProtection,this._keyboardPeripherals,t=>this.pub.timeline.segmentsForHref(t).flatMap(i=>i.references).map(i=>{const s=i.indexOf("#");return s>=0?i.slice(s+1):""}).filter(Boolean))}this.currentLocation===void 0&&(this.currentLocation=this.positions[0]),await this.resizeHandler(),await this.apply()}get settings(){if(this._layout===d.fixed)return Object.freeze({...this._settings});{const e=this._css.userProperties.colCount||this._css.rsProperties.colCount||this._settings.columnCount;return Object.freeze({...this._settings,columnCount:e})}}get preferencesEditor(){return this._preferencesEditor===null&&(this._preferencesEditor=new b(this._preferences,this.settings,this.pub.metadata)),this._preferencesEditor}async submitPreferences(e){this._preferences=this._preferences.merging(e),await this.applyPreferences()}async applyPreferences(){const e=this._settings;this._settings=new k(this._preferences,this._defaults),this._preferencesEditor!==null&&(this._preferencesEditor=new b(this._preferences,this.settings,this.pub.metadata)),this._layout===d.fixed?this.handleFXLPrefs(e,this._settings):await this.updateCSS(!0)}handleFXLPrefs(e,t){e.columnCount!==t.columnCount&&this.framePool.setPerPage(t.columnCount)}async updateCSS(e){this._css.update(this._settings),e&&await this.commitCSS(this._css)}compileCSSProperties(e){const t={};for(const[i,s]of Object.entries(e.rsProperties.toCSSProperties()))t[i]=s;for(const[i,s]of Object.entries(e.userProperties.toCSSProperties()))t[i]=s;return t}async commitCSS(e){if(!this.framePool)return;const t=this.compileCSSProperties(e);this.framePool.setCSSProperties(t),this._css.userProperties.view==="paged"&&this._layout===d.scrolled?await this.setLayout(d.reflowable):this._css.userProperties.view==="scroll"&&this._layout===d.reflowable&&await this.setLayout(d.scrolled),this._css.setContainerWidth()}async resizeHandler(){const e=this.container.parentElement||document.documentElement;if(this._layout===d.fixed){if(this.container.style.width=`${K(e)-this._settings.constraint}px`,!this.framePool)return;this.framePool.resizeHandler()}else{const t=this._css.userProperties.colCount,i=this._css.userProperties.lineLength;this._css.resizeHandler(),(this._css.userProperties.view!=="scroll"&&t!==this._css.userProperties.colCount||i!==this._css.userProperties.lineLength)&&await this.commitCSS(this._css)}}get layout(){return this._layout}get ownerWindow(){return this.container.ownerDocument.defaultView||window}get _cframes(){return(this.framePool?.currentFrames??[]).filter(e=>!(e instanceof N&&e.isDestroyed))}get pool(){return this.framePool}eventListener(e,t,i){switch(e){case"_pong":if(this.listeners.frameLoaded(this._cframes[0].iframe.contentWindow),this.listeners.positionChanged(this.currentLocation),this._notifyTimelineChange(this.currentLocation),i){const a=this._cframes.filter(l=>!!l).indexOf(i),c=a>=0?this.viewport.readingOrder[a]:void 0;c&&this._reapplyDecorationsToFrame(i,c)}else this._reapplyDecorationsToCurrentFrames();break;case"first_visible_locator":const s=v.deserialize(t);if(!s)break;this.currentLocation=new v({href:this.currentLocation.href,type:this.currentLocation.type,title:this.currentLocation.title,locations:s?.locations,text:s?.text}),this.listeners.positionChanged(this.currentLocation),this._notifyTimelineChange(this.currentLocation);break;case"text_selected":{const n=t;if(i){const c=this._cframes.filter(u=>!!u).indexOf(i),l=c>=0?this.viewport.readingOrder[c]:void 0;if(l){const u=this.pub.readingOrder.findWithHref(l);n.locator=new v({href:l,type:u.type||"application/xhtml+xml",text:new D({highlight:n.text})})}}this.listeners.textSelected(n);break}case"decoration_activated":{this._handleDecorationActivated(t)&&(this._decorationActivationConsumed=!0);break}case"decoration_pointer_enter":this._handleDecorationPointerEnter(t);break;case"decoration_pointer_leave":this._handleDecorationPointerLeave(t);break;case"click":case"tap":if(this._decorationActivationConsumed){this._decorationActivationConsumed=!1;break}const r=t;if(r.interactiveElement){const n=new DOMParser().parseFromString(r.interactiveElement,"text/html").body.children[0];if(n.nodeType===n.ELEMENT_NODE&&n.nodeName==="A"&&n.hasAttribute("href")){const a=n.attributes.getNamedItem("href")?.value;if(a.startsWith("#"))this.go(this.currentLocation.copyWithLocations({fragments:[a.substring(1)]}),!1,()=>{});else if(a.startsWith("http://")||a.startsWith("https://")||a.startsWith("mailto:")||a.startsWith("tel:"))this.listeners.handleLocator(new _({href:a}).locator);else try{this.goLink(new _({href:y.join(y.dirname(this.currentLocation.href),a)}),!1,()=>{})}catch(c){console.warn(`Couldn't go to link for ${a}: ${c}`),this.listeners.handleLocator(new _({href:a}).locator)}}else console.log("Clicked on",n)}else{if(this._layout===d.fixed&&this.framePool.doNotDisturb&&(r.doNotDisturb=!0),this._layout===d.fixed&&(this.currentProgression===g.rtl||this.currentProgression===g.ltr)&&this.framePool.currentFrames.length>1){const c=this.framePool.currentFrames;r.targetFrameSrc===c[this.currentProgression===g.rtl?0:1]?.source&&(r.x+=(c[this.currentProgression===g.rtl?1:0]?.iframe.contentWindow?.innerWidth??0)*window.devicePixelRatio)}if(e==="click"?this.listeners.click(r):this.listeners.tap(r))break;const a=(this._cframes.length===2?this._cframes[0].window.innerWidth+this._cframes[1].window.innerWidth:this._cframes[0].window.innerWidth)*window.devicePixelRatio/4;r.x>=a&&r.x<=a*3&&this.listeners.miscPointer(1),r.x<a?this.goLeft(!1,()=>{}):r.x>a*3&&this.goRight(!1,()=>{})}break;case"tap_more":this.listeners.miscPointer(t);break;case"no_more":this.changeResource(1);break;case"no_less":this.changeResource(-1);break;case"swipe":break;case"scroll":this.listeners.scroll(t);break;case"zoom":this.listeners.zoom(t);break;case"progress":this.syncLocation(t);break;case"content_protection":const o=t;this.listeners.contentProtection(o.type,o);break;case"context_menu":this.listeners.contextMenu(t);break;case"keyboard_peripherals":const h=t,f={...h,interactiveElement:void 0};h.interactiveElement&&(f.interactiveElement=new DOMParser().parseFromString(h.interactiveElement,"text/html").body.children[0]),this.listeners.peripheral(f);break;case"log":console.log(this._cframes[0]?.source?.split("/")[3],...t);break;default:this.listeners.customEvent(e,t);break}}determineModules(){let e=Array.from(T.keys());if(this._layout===d.fixed)return e.filter(s=>F.includes(s));e=e.filter(s=>R.includes(s));const t=w(this.pub.metadata);if(t==="cjk-vertical"||t==="mongolian-vertical")return e.filter(s=>s!=="column_snapper"&&s!=="scroll_snapper");const i=e;return this._layout===d.scrolled?e=i.filter(s=>s!=="column_snapper"&&s!=="cjk_vertical_snapper"):e=i.filter(s=>s!=="scroll_snapper"&&s!=="cjk_vertical_snapper"),e}attachListener(){const e=this._cframes.filter(t=>!!t);if(e.length===0)throw Error("no cframe to attach listener to");e.forEach(t=>{t.msg&&(t.msg.listener=(i,s)=>{this.eventListener(i,s,t)})}),this._reapplyDecorationsToCurrentFrames()}async apply(){if(await this.framePool.update(this.pub,this.currentLocator,this.determineModules()),this.attachListener(),this.pub.readingOrder.findIndexWithHref(this.currentLocation.href)<0)throw Error("Link for "+this.currentLocation.href+" not found!")}supportsDecorationStyle(e){return q(e,this._decoratorConfig.decorationTemplates)}registerDecorationObserver(e,t){this._decorationObservers.has(e)||this._decorationObservers.set(e,new Set),this._decorationObservers.get(e).add(t),t.onDecorationActivated&&(this._decorationActivationState.set(e,!0),this._sendDecorationActivationToFrames(e,!0)),(t.onDecorationPointerEnter||t.onDecorationPointerLeave)&&(this._decorationHoverState.set(e,!0),this._sendDecorationHoverToFrames(e,!0))}unregisterDecorationObserver(e){this._decorationObservers.forEach((t,i)=>{if(!t.has(e))return;t.delete(e);const s=[...t].some(o=>o.onDecorationActivated);this._decorationActivationState.has(i)&&!s&&(this._decorationActivationState.delete(i),this._sendDecorationActivationToFrames(i,!1));const r=[...t].some(o=>o.onDecorationPointerEnter||o.onDecorationPointerLeave);this._decorationHoverState.has(i)&&!r&&(this._decorationHoverState.delete(i),this._sendDecorationHoverToFrames(i,!1))})}_sendDecorationActivationToFrames(e,t){this._cframes.filter(s=>!!s).forEach(s=>{s.msg&&s.msg.send("decoration_activatable",{group:e,activatable:t})})}_sendDecorationHoverToFrames(e,t){this._cframes.filter(s=>!!s).forEach(s=>{s.msg&&s.msg.send("decoration_hoverable",{group:e,hoverable:t})})}applyDecorations(e,t){const i=this._decorations.get(t)??[],s=new Map(i.map(c=>[c.id,c])),r=new Map(e.map(c=>[c.id,c])),o=[],h=[],f=[];for(const[c,l]of s)r.has(c)?Y(l,r.get(c))||f.push(r.get(c)):o.push(c);for(const[c,l]of r)s.has(c)||h.push(l);this._decorations.set(t,e),this._sendDecorationOps(t,o,h,f,i);const n=this._decorationActivationState.get(t);n!==void 0&&this._sendDecorationActivationToFrames(t,n);const a=this._decorationHoverState.get(t);a!==void 0&&this._sendDecorationHoverToFrames(t,a)}_sendDecorationOps(e,t,i,s,r){const o=this._cframes.filter(n=>!!n),h=new Map(r.map(n=>[n.id,n])),f=this.viewport.readingOrder;o.forEach((n,a)=>{if(!n.msg)return;const c=f[a];if(c){for(const l of t){const u=h.get(l);!u||u.locator.href!==c||n.msg.send("decorate",{group:e,action:"remove",decoration:{id:l}})}for(const l of i)l.locator.href===c&&n.msg.send("decorate",{group:e,action:"add",decoration:P(l,this._decoratorConfig.decorationTemplates)});for(const l of s)l.locator.href===c&&n.msg.send("decorate",{group:e,action:"update",decoration:P(l,this._decoratorConfig.decorationTemplates)})}})}_reapplyDecorationsToFrame(e,t){if(e.msg){for(const[i,s]of this._decorations){const r=s.filter(o=>o.locator.href===t);if(r.length!==0){e.msg.send("decorate",{group:i,action:"clear"});for(const o of r)e.msg.send("decorate",{group:i,action:"add",decoration:P(o,this._decoratorConfig.decorationTemplates)})}}for(const[i,s]of this._decorationActivationState)e.msg.send("decoration_activatable",{group:i,activatable:s});for(const[i,s]of this._decorationHoverState)e.msg.send("decoration_hoverable",{group:i,hoverable:s})}}_reapplyDecorationsToCurrentFrames(){const e=this._cframes.filter(i=>!!i),t=this.viewport.readingOrder;e.forEach((i,s)=>{const r=t[s];r&&this._reapplyDecorationsToFrame(i,r)})}_handleDecorationActivated(e){const t=this._decorationObservers.get(e.group);if(!t||t.size===0)return!1;const i=(this._decorations.get(e.group)??[]).find(o=>o.id===e.decorationId);if(!i)return!1;const s={decoration:i,group:e.group,rect:e.rect,point:e.point};let r=!1;for(const o of t)o.onDecorationActivated?.(s)&&(r=!0);return r}_handleDecorationPointerEnter(e){const t=this._decorationObservers.get(e.group);if(!t||t.size===0)return;const i=(this._decorations.get(e.group)??[]).find(r=>r.id===e.decorationId);if(!i)return;this._decorationHoveredDecorations.set(e.group,i);const s={decoration:i,group:e.group,rect:e.rect,point:e.point};for(const r of t)r.onDecorationPointerEnter?.(s)}_handleDecorationPointerLeave(e){const t=this._decorationObservers.get(e.group);if(!t||t.size===0)return;const i=(this._decorations.get(e.group)??[]).find(r=>r.id===e.decorationId)??this._decorationHoveredDecorations.get(e.group);if(this._decorationHoveredDecorations.delete(e.group),!i)return;const s={decoration:i,group:e.group,rect:e.rect,point:e.point};for(const r of t)r.onDecorationPointerLeave?.(s)}async destroy(){this._suspiciousActivityListener&&window.removeEventListener(x,this._suspiciousActivityListener),this._keyboardPeripheralListener&&window.removeEventListener(C,this._keyboardPeripheralListener),this._navigatorProtector?.destroy(),this._keyboardPeripheralsManager?.destroy(),await this.framePool?.destroy(),this._decorations.clear(),this._decorationObservers.clear(),this._decorationHoveredDecorations.clear(),this._decorationActivationState.clear(),this._decorationHoverState.clear()}async changeResource(e){if(e===0)return!1;if(this._layout===d.fixed){const s=this.framePool,r=s.viewport.positions[0];if(e===1){if(!s.next(s.perPage))return!1}else if(e===-1){if(!s.prev(s.perPage))return!1}else throw Error("Invalid relative value for FXL");const o=s.viewport.positions[0];if(r>o){for(let h=this.positions.length-1;h>=0;h--)if(this.positions[h].href===this.pub.readingOrder.items[o-1].href){this.currentLocation=this.positions[h].copyWithLocations({progression:.999999999999});break}}else if(r<o){for(let h=0;h<this.positions.length;h++)if(this.positions[h].href===this.pub.readingOrder.items[o-1].href){this.currentLocation=this.positions[h];break}}return await this.apply(),this.listeners.positionChanged(this.currentLocation),this._notifyTimelineChange(this.currentLocation),!0}const t=this.pub.readingOrder.findIndexWithHref(this.currentLocation.href),i=Math.max(0,Math.min(this.pub.readingOrder.items.length-1,t+e));if(i===t)return this._cframes[0]?.msg?.send("shake",void 0,async s=>{}),!1;if(t>i){for(let s=this.positions.length-1;s>=0;s--)if(this.positions[s].href===this.pub.readingOrder.items[i].href){this.currentLocation=this.positions[s].copyWithLocations({progression:.999999999999});break}}else for(let s=0;s<this.positions.length;s++)if(this.positions[s].href===this.pub.readingOrder.items[i].href){this.currentLocation=this.positions[s];break}return await this.apply(),!0}findLastPositionInProgressionRange(e,t){const i=e.findLastIndex(s=>{const r=s.locations.progression;return!!(r&&r>t.start&&r<=t.end)});return i!==-1?e[i]:void 0}findNearestPositions(e){const t=this.positions.filter(o=>o.href===this.currentLocation.href);let i=this.currentLocation,s;const r=t.findLastIndex(o=>(o.locations.progression??0)<=e.start);if(r!==-1){i=t[r];const o=t.slice(r+1);s=this.findLastPositionInProgressionRange(o,e)}return{first:i,last:s}}updateViewport(e){this.reflowViewport.readingOrder=[],this.reflowViewport.progressions.clear(),this.reflowViewport.positions=null,this.currentLocation&&(this.reflowViewport.readingOrder.push(this.currentLocation.href),this.reflowViewport.progressions.set(this.currentLocation.href,e),this.currentLocation.locations?.position!==void 0&&(this.reflowViewport.positions=[this.currentLocation.locations.position],this.lastLocationInView?.locations?.position!==void 0&&this.reflowViewport.positions.push(this.lastLocationInView.locations.position)))}async syncLocation(e){const t=e,i=this.findNearestPositions(t);this.currentLocation=i.first.copyWithLocations({progression:t.start}),this.lastLocationInView=i.last,this.updateViewport(t),this.listeners.positionChanged(this.currentLocation);const s=t.fragmentId?this.currentLocation.copyWithLocations({fragments:[`#${t.fragmentId}`]}):this.currentLocation;this._notifyTimelineChange(s),await this.framePool.update(this.pub,this.currentLocation,this.determineModules())}goBackward(e,t){if(this._isNavigating){t(!1);return}this._isNavigating=!0,this._layout===d.fixed?this.changeResource(-1).then(i=>{this._isNavigating=!1,t(i)}):this._cframes[0]?.msg?.send("go_prev",void 0,async i=>{if(i)this._isNavigating=!1,t(!0);else{const s=await this.changeResource(-1);this._isNavigating=!1,t(s)}})}goForward(e,t){if(this._isNavigating){t(!1);return}this._isNavigating=!0,this._layout===d.fixed?this.changeResource(1).then(i=>{this._isNavigating=!1,t(i)}):this._cframes[0]?.msg?.send("go_next",void 0,async i=>{if(i)this._isNavigating=!1,t(!0);else{const s=await this.changeResource(1);this._isNavigating=!1,t(s)}})}get currentLocator(){return this.currentLocation}get viewport(){return this._layout===d.fixed?this.framePool?this.framePool.viewport:{readingOrder:[],progressions:new Map,positions:null}:this.reflowViewport}get isScrollStart(){const e=this.viewport.readingOrder[0];return this.viewport.progressions.get(e)?.start===0}get isScrollEnd(){const e=this.viewport.readingOrder[this.viewport.readingOrder.length-1];return this.viewport.progressions.get(e)?.end===1}get canGoBackward(){const e=this.pub.readingOrder.items[0]?.href;return!(this.viewport.progressions.has(e)&&this.viewport.progressions.get(e)?.start===0)}get canGoForward(){const e=this.pub.readingOrder.items[this.pub.readingOrder.items.length-1]?.href;return!(this.viewport.progressions.has(e)&&this.viewport.progressions.get(e)?.end===1)}get readingProgression(){return this.currentProgression}async setLayout(e){this._layout!==e&&(this._layout=e,await this.framePool.update(this.pub,this.currentLocator,this.determineModules(),!0),this.attachListener())}get publication(){return this.pub}get timeline(){const e=this.pub.timeline;if(!this._timelineAugmented&&this.positions?.length){const t=this.positions,i=new Set;e.augment((s,r)=>{if(s.children?.length)return{};const o=r.href.indexOf("#"),h=o>=0?r.href.slice(0,o):r.href,f=o>=0?r.href.slice(o+1):void 0,n=t.filter(l=>l.href===h);if(!n.length)return{};const a=f?n.find(l=>l.locations.fragments[0]===f):void 0;let c;return a?c=a:i.has(h)?c=void 0:(i.add(h),c=n.reduce((l,u)=>(u.locations.position??1/0)<(l.locations.position??1/0)?u:l)),c?{position:c.locations.position,scroll:a?.locations.progression}:{}}),this._timelineAugmented=!0}return e}async loadLocator(e,t){let i=!1,s=O(e.locations);if(e.text?.highlight?i=await new Promise((f,n)=>{this._cframes[0].msg.send("go_text",s?[e.text?.serialize(),s]:e.text?.serialize(),a=>f(a))}):s&&(i=await new Promise((f,n)=>{this._cframes[0].msg.send("go_text",["",s],a=>f(a))})),i){t(i);return}const r=A(e.locations);if(r&&(i=await new Promise((f,n)=>{this._cframes[0].msg.send("go_id",r,a=>f(a))})),i){t(i);return}const o=e?.locations?.progression;o&&o>0?i=await new Promise((f,n)=>{this._cframes[0].msg.send("go_progression",o,a=>f(a))}):i=!0,t(i)}go(e,t,i){const s=e.href.split("#")[0];let r=this.pub.readingOrder.findWithHref(s);if(!r)return i(this.listeners.handleLocator(e));if(this._isNavigating){i(!1);return}this._isNavigating=!0,this.currentLocation=this.positions.find(o=>o.href===r.href),this.apply().then(()=>this.loadLocator(e,o=>{this._isNavigating=!1,i(o)})).then(()=>{this.attachListener()})}goLink(e,t,i){return this.go(e.locator,t,i)}_notifyTimelineChange(e){const t=this.timeline.locate(e);t!==this._currentTimelineItem&&(this._currentTimelineItem=t,this.listeners.timelineItemChanged(t))}}export{S as EpubNavigator};
@@ -0,0 +1 @@
1
+ import{experiments as n}from"../../preferences/Types.js";import{Properties as l}from"../../css/Properties.js";class a extends l{constructor(i){super(),this.a11yNormalize=i.a11yNormalize??null,this.backgroundColor=i.backgroundColor??null,this.blendFilter=i.blendFilter??null,this.bodyHyphens=i.bodyHyphens??null,this.colCount=i.colCount??null,this.darkenFilter=i.darkenFilter??null,this.deprecatedFontSize=i.deprecatedFontSize??null,this.fontFamily=i.fontFamily??null,this.fontOpticalSizing=i.fontOpticalSizing??null,this.fontSize=i.fontSize??null,this.fontSizeNormalize=i.fontSizeNormalize??null,this.fontWeight=i.fontWeight??null,this.fontWidth=i.fontWidth??null,this.invertFilter=i.invertFilter??null,this.invertGaijiFilter=i.invertGaijiFilter??null,this.iOSPatch=i.iOSPatch??null,this.iPadOSPatch=i.iPadOSPatch??null,this.letterSpacing=i.letterSpacing??null,this.ligatures=i.ligatures??null,this.lineHeight=i.lineHeight??null,this.lineLength=i.lineLength??null,this.linkColor=i.linkColor??null,this.noRuby=i.noRuby??null,this.paraIndent=i.paraIndent??null,this.paraSpacing=i.paraSpacing??null,this.selectionBackgroundColor=i.selectionBackgroundColor??null,this.selectionTextColor=i.selectionTextColor??null,this.textAlign=i.textAlign??null,this.textColor=i.textColor??null,this.view=i.view??null,this.visitedColor=i.visitedColor??null,this.wordSpacing=i.wordSpacing??null}toCSSProperties(){const i={};return this.a11yNormalize&&(i["--USER__a11yNormalize"]=this.toFlag("a11y")),this.backgroundColor&&(i["--USER__backgroundColor"]=this.backgroundColor),this.blendFilter&&(i["--USER__blendFilter"]=this.toFlag("blend")),this.bodyHyphens&&(i["--USER__bodyHyphens"]=this.bodyHyphens),this.colCount&&(i["--USER__colCount"]=this.toUnitless(this.colCount)),this.darkenFilter===!0?i["--USER__darkenFilter"]=this.toFlag("darken"):typeof this.darkenFilter=="number"&&(i["--USER__darkenFilter"]=this.toPercentage(this.darkenFilter)),this.deprecatedFontSize&&(i["--USER__fontSizeImplementation"]=this.toFlag("deprecatedFontSize")),this.fontFamily&&(i["--USER__fontFamily"]=this.fontFamily),this.fontOpticalSizing!=null&&(i["--USER__fontOpticalSizing"]=this.fontOpticalSizing),this.fontSize!=null&&(i["--USER__fontSize"]=this.toPercentage(this.fontSize,!0)),this.fontSizeNormalize&&(i["--USER__fontSizeNormalize"]=this.toFlag("normalize")),this.fontWeight!=null&&(i["--USER__fontWeight"]=this.toUnitless(this.fontWeight)),this.fontWidth!=null&&(i["--USER__fontWidth"]=typeof this.fontWidth=="string"?this.fontWidth:this.toUnitless(this.fontWidth)),this.invertFilter===!0?i["--USER__invertFilter"]=this.toFlag("invert"):typeof this.invertFilter=="number"&&(i["--USER__invertFilter"]=this.toPercentage(this.invertFilter)),this.invertGaijiFilter===!0?i["--USER__invertGaiji"]=this.toFlag("invertGaiji"):typeof this.invertGaijiFilter=="number"&&(i["--USER__invertGaiji"]=this.toPercentage(this.invertGaijiFilter)),this.iOSPatch&&(i["--USER__iOSPatch"]=this.toFlag("iOSPatch")),this.iPadOSPatch&&(i["--USER__iPadOSPatch"]=this.toFlag("iPadOSPatch")),this.letterSpacing!=null&&(i["--USER__letterSpacing"]=this.toRem(this.letterSpacing)),this.ligatures&&(i["--USER__ligatures"]=this.ligatures),this.lineHeight!=null&&(i["--USER__lineHeight"]=this.toUnitless(this.lineHeight)),this.lineLength!=null&&(i["--USER__lineLength"]=this.toPx(this.lineLength)),this.linkColor&&(i["--USER__linkColor"]=this.linkColor),this.noRuby&&(i["--USER__noRuby"]=this.toFlag("noRuby")),this.paraIndent!=null&&(i["--USER__paraIndent"]=this.toRem(this.paraIndent)),this.paraSpacing!=null&&(i["--USER__paraSpacing"]=this.toRem(this.paraSpacing)),this.selectionBackgroundColor&&(i["--USER__selectionBackgroundColor"]=this.selectionBackgroundColor),this.selectionTextColor&&(i["--USER__selectionTextColor"]=this.selectionTextColor),this.textAlign&&(i["--USER__textAlign"]=this.textAlign),this.textColor&&(i["--USER__textColor"]=this.textColor),this.view&&(i["--USER__view"]=this.toFlag(this.view)),this.visitedColor&&(i["--USER__visitedColor"]=this.visitedColor),this.wordSpacing!=null&&(i["--USER__wordSpacing"]=this.toRem(this.wordSpacing)),i}}class h extends l{constructor(i){super(),this.backgroundColor=i.backgroundColor??null,this.baseFontFamily=i.baseFontFamily??null,this.baseFontSize=i.baseFontSize??null,this.baseLineHeight=i.baseLineHeight??null,this.boxSizingMedia=i.boxSizingMedia??null,this.boxSizingTable=i.boxSizingTable??null,this.colWidth=i.colWidth??null,this.colCount=i.colCount??null,this.colGap=i.colGap??null,this.codeFontFamily=i.codeFontFamily??null,this.compFontFamily=i.compFontFamily??null,this.defaultLineLength=i.defaultLineLength??null,this.flowSpacing=i.flowSpacing??null,this.humanistTf=i.humanistTf??null,this.linkColor=i.linkColor??null,this.maxMediaWidth=i.maxMediaWidth??null,this.maxMediaHeight=i.maxMediaHeight??null,this.modernTf=i.modernTf??null,this.monospaceTf=i.monospaceTf??null,this.noOverflow=i.noOverflow??null,this.noVerticalPagination=i.noVerticalPagination??null,this.oldStyleTf=i.oldStyleTf??null,this.pageGutter=i.pageGutter??null,this.paraIndent=i.paraIndent??null,this.paraSpacing=i.paraSpacing??null,this.primaryColor=i.primaryColor??null,this.scrollPaddingBottom=i.scrollPaddingBottom??null,this.scrollPaddingLeft=i.scrollPaddingLeft??null,this.scrollPaddingRight=i.scrollPaddingRight??null,this.scrollPaddingTop=i.scrollPaddingTop??null,this.sansSerifJa=i.sansSerifJa??null,this.sansSerifJaV=i.sansSerifJaV??null,this.sansTf=i.sansTf??null,this.secondaryColor=i.secondaryColor??null,this.selectionBackgroundColor=i.selectionBackgroundColor??null,this.selectionTextColor=i.selectionTextColor??null,this.serifJa=i.serifJa??null,this.serifJaV=i.serifJaV??null,this.textColor=i.textColor??null,this.typeScale=i.typeScale??null,this.visitedColor=i.visitedColor??null,this.experiments=i.experiments??null}toCSSProperties(){const i={};return this.backgroundColor&&(i["--RS__backgroundColor"]=this.backgroundColor),this.baseFontFamily&&(i["--RS__baseFontFamily"]=this.baseFontFamily),this.baseFontSize!=null&&(i["--RS__baseFontSize"]=this.toRem(this.baseFontSize)),this.baseLineHeight!=null&&(i["--RS__baseLineHeight"]=this.toUnitless(this.baseLineHeight)),this.boxSizingMedia&&(i["--RS__boxSizingMedia"]=this.boxSizingMedia),this.boxSizingTable&&(i["--RS__boxSizingTable"]=this.boxSizingTable),this.colWidth!=null&&(i["--RS__colWidth"]=this.colWidth),this.colCount!=null&&(i["--RS__colCount"]=this.toUnitless(this.colCount)),this.colGap!=null&&(i["--RS__colGap"]=this.toPx(this.colGap)),this.codeFontFamily&&(i["--RS__codeFontFamily"]=this.codeFontFamily),this.compFontFamily&&(i["--RS__compFontFamily"]=this.compFontFamily),this.defaultLineLength!=null&&(i["--RS__defaultLineLength"]=this.toPx(this.defaultLineLength)),this.flowSpacing!=null&&(i["--RS__flowSpacing"]=this.toRem(this.flowSpacing)),this.humanistTf&&(i["--RS__humanistTf"]=this.humanistTf),this.linkColor&&(i["--RS__linkColor"]=this.linkColor),this.maxMediaWidth&&(i["--RS__maxMediaWidth"]=this.toVw(this.maxMediaWidth)),this.maxMediaHeight&&(i["--RS__maxMediaHeight"]=this.toVh(this.maxMediaHeight)),this.modernTf&&(i["--RS__modernTf"]=this.modernTf),this.monospaceTf&&(i["--RS__monospaceTf"]=this.monospaceTf),this.noOverflow&&(i["--RS__disableOverflow"]=this.toFlag("noOverflow")),this.noVerticalPagination&&(i["--RS__disablePagination"]=this.toFlag("noVerticalPagination")),this.oldStyleTf&&(i["--RS__oldStyleTf"]=this.oldStyleTf),this.pageGutter!=null&&(i["--RS__pageGutter"]=this.toPx(this.pageGutter)),this.paraIndent!=null&&(i["--RS__paraIndent"]=this.toRem(this.paraIndent)),this.paraSpacing!=null&&(i["--RS__paraSpacing"]=this.toRem(this.paraSpacing)),this.primaryColor&&(i["--RS__primaryColor"]=this.primaryColor),this.sansSerifJa&&(i["--RS__sans-serif-ja"]=this.sansSerifJa),this.sansSerifJaV&&(i["--RS__sans-serif-ja-v"]=this.sansSerifJaV),this.sansTf&&(i["--RS__sansTf"]=this.sansTf),this.scrollPaddingBottom!=null&&(i["--RS__scrollPaddingBottom"]=this.toPx(this.scrollPaddingBottom)),this.scrollPaddingLeft!=null&&(i["--RS__scrollPaddingLeft"]=this.toPx(this.scrollPaddingLeft)),this.scrollPaddingRight!=null&&(i["--RS__scrollPaddingRight"]=this.toPx(this.scrollPaddingRight)),this.scrollPaddingTop!=null&&(i["--RS__scrollPaddingTop"]=this.toPx(this.scrollPaddingTop)),this.secondaryColor&&(i["--RS__secondaryColor"]=this.secondaryColor),this.selectionBackgroundColor&&(i["--RS__selectionBackgroundColor"]=this.selectionBackgroundColor),this.selectionTextColor&&(i["--RS__selectionTextColor"]=this.selectionTextColor),this.serifJa&&(i["--RS__serif-ja"]=this.serifJa),this.serifJaV&&(i["--RS__serif-ja-v"]=this.serifJaV),this.textColor&&(i["--RS__textColor"]=this.textColor),this.typeScale&&(i["--RS__typeScale"]=this.toUnitless(this.typeScale)),this.visitedColor&&(i["--RS__visitedColor"]=this.visitedColor),this.experiments&&this.experiments.forEach(t=>{i["--RS__"+t]=n[t].value}),i}}export{h as RSProperties,a as UserProperties};
@@ -0,0 +1 @@
1
+ import{getContentWidth as m,getContentHeight as f}from"../../helpers/dimensions.js";import{UserProperties as P}from"./Properties.js";class M{constructor(e){this.rsProperties=e.rsProperties,this.userProperties=e.userProperties,this.lineLengths=e.lineLengths,this.container=e.container,this.containerParent=e.container.parentElement||document.documentElement,this.constraint=e.constraint,this.isCJKVertical=e.isCJKVertical??!1,this.cachedColCount=e.userProperties.colCount,this.effectiveContainerWidth=m(this.containerParent)}update(e){this.cachedColCount=e.columnCount,e.constraint!==this.constraint&&(this.constraint=e.constraint),e.pageGutter!==this.rsProperties.pageGutter&&(this.rsProperties.pageGutter=e.pageGutter),e.scrollPaddingBottom!==this.rsProperties.scrollPaddingBottom&&(this.rsProperties.scrollPaddingBottom=e.scrollPaddingBottom),e.scrollPaddingLeft!==this.rsProperties.scrollPaddingLeft&&(this.rsProperties.scrollPaddingLeft=e.scrollPaddingLeft),e.scrollPaddingRight!==this.rsProperties.scrollPaddingRight&&(this.rsProperties.scrollPaddingRight=e.scrollPaddingRight),e.scrollPaddingTop!==this.rsProperties.scrollPaddingTop&&(this.rsProperties.scrollPaddingTop=e.scrollPaddingTop),e.experiments!==this.rsProperties.experiments&&(this.rsProperties.experiments=e.experiments),this.lineLengths.update({fontFace:e.fontFamily,letterSpacing:e.letterSpacing,padding:e.scroll?(e.scrollPaddingLeft||0)+(e.scrollPaddingRight||0):(e.pageGutter||0)*2,wordSpacing:e.wordSpacing,optimalChars:e.optimalLineLength,minChars:e.minimalLineLength,maxChars:e.maximalLineLength});const o=this.updateLayout(e.fontSize,e.deprecatedFontSize||e.iOSPatch,e.scroll,e.columnCount);o?.effectiveContainerWidth&&(this.effectiveContainerWidth=o?.effectiveContainerWidth);const t={a11yNormalize:e.textNormalization,backgroundColor:e.backgroundColor,blendFilter:e.blendFilter,bodyHyphens:typeof e.hyphens!="boolean"?null:e.hyphens?"auto":"none",colCount:o?.colCount,darkenFilter:e.darkenFilter,deprecatedFontSize:e.deprecatedFontSize,fontFamily:e.fontFamily,fontOpticalSizing:typeof e.fontOpticalSizing!="boolean"?null:e.fontOpticalSizing?"auto":"none",fontSize:e.fontSize,fontSizeNormalize:e.fontSizeNormalize,fontWeight:e.fontWeight,fontWidth:e.fontWidth,invertFilter:e.invertFilter,invertGaijiFilter:e.invertGaijiFilter,iOSPatch:e.iOSPatch,iPadOSPatch:e.iPadOSPatch,letterSpacing:e.letterSpacing,ligatures:typeof e.ligatures!="boolean"?null:e.ligatures?"common-ligatures":"none",lineHeight:e.lineHeight,lineLength:o?.effectiveLineLength,linkColor:e.linkColor,noRuby:e.noRuby,paraIndent:e.paragraphIndent,paraSpacing:e.paragraphSpacing,selectionBackgroundColor:e.selectionBackgroundColor,selectionTextColor:e.selectionTextColor,textAlign:e.textAlign,textColor:e.textColor,view:typeof e.scroll!="boolean"?null:e.scroll?"scroll":"paged",visitedColor:e.visitedColor,wordSpacing:e.wordSpacing};this.userProperties=new P(t)}updateLayout(e,o,t,i){return this.isCJKVertical?this.computeCJKVerticalLength(e,o):t??this.userProperties.view==="scroll"?this.computeScrollLength(e,o):this.paginate(e,o,i)}getCompensatedMetrics(e,o){const t=e||this.userProperties.fontSize||1,i=t<1?1/t:o?t:1;return{zoomFactor:t,zoomCompensation:i,optimal:Math.round(this.lineLengths.optimalLineLength)*t,minimal:this.lineLengths.minimalLineLength!==null?Math.round(this.lineLengths.minimalLineLength*t):null,maximal:this.lineLengths.maximalLineLength!==null?Math.round(this.lineLengths.maximalLineLength*t):null}}paginate(e,o,t){const i=Math.round(m(this.containerParent)-this.constraint),l=this.getCompensatedMetrics(e,o),{zoomCompensation:a,optimal:h,minimal:d,maximal:c}=l,u=()=>i>=h&&c!==null?Math.min(Math.round(c*a),i):i;let r=1,n=i;if(t===void 0)return{colCount:void 0,effectiveContainerWidth:n,effectiveLineLength:Math.round(n/r*a)};if(t===null)if(i>=h&&c!==null){r=Math.floor(i/h);const p=Math.round(r*(c*a));n=Math.min(p,i)}else n=u();else if(t>1){const p=Math.round(t*(d!==null?d:h));if(i>=p)if(r=t,c===null)n=i;else{const s=Math.round(r*(c*a));n=Math.min(s,i)}else if(d!==null&&i<Math.round(t*d))if(r=Math.floor(i/d),r<=1)r=1,n=u();else{const s=Math.round(r*(h*a));n=Math.min(s,i)}else{r=t;const s=Math.round(r*(h*a));n=Math.min(s,i)}}else r=1,n=u();return{colCount:r,effectiveContainerWidth:n,effectiveLineLength:Math.round(n/r/(e&&e>=1?e:1)*a)}}computeCJKVerticalLength(e,o){const t=Math.round(m(this.containerParent)-this.constraint),i=Math.round(f(this.containerParent)),l=this.getCompensatedMetrics(e,o),a=l.maximal!==null?Math.min(Math.round(l.maximal*l.zoomCompensation),i):i;return{colCount:void 0,effectiveContainerWidth:t,effectiveLineLength:a}}computeScrollLength(e,o){const t=Math.round(m(this.containerParent)-this.constraint),i=this.getCompensatedMetrics(e&&(e<1||o)?e:1,o),l=i.zoomCompensation,a=i.optimal,h=i.maximal;let d,c=t,u=Math.round(a*l);if(h===null)u=t;else{const r=Math.min(Math.round(h*l),t);u=o?r:Math.round(r*l)}return{colCount:d,effectiveContainerWidth:c,effectiveLineLength:u}}setContainerWidth(){this.container.style.width=`${this.effectiveContainerWidth}px`}resizeHandler(){const e=this.updateLayout(this.userProperties.fontSize,this.userProperties.deprecatedFontSize||this.userProperties.iOSPatch,this.userProperties.view==="scroll",this.cachedColCount);this.userProperties.colCount=e.colCount,this.userProperties.lineLength=e.effectiveLineLength,this.effectiveContainerWidth=e.effectiveContainerWidth,this.container.style.width=`${this.effectiveContainerWidth}px`}}export{M as ReadiumCSS};
@@ -0,0 +1 @@
1
+ import{MediaType as o,ReadingProgression as d}from"@readium/shared";import{getScriptMode as g}from"../../helpers/scriptMode.js";const f=m=>{const e=m.join(" ");return["upgrade-insecure-requests",`default-src ${e} blob:`,"connect-src 'none'",`script-src ${e} blob: 'unsafe-inline'`,`style-src ${e} blob: 'unsafe-inline'`,`img-src ${e} blob: data:`,`font-src ${e} blob: data:`,`object-src ${e} blob:`,`child-src ${e}`,"form-action 'none'"].join("; ")};class L{constructor(e,i,r,t){this.injector=null,this.pub=e,this.item=r,this.burl=r.toURL(i)||"",this.cssProperties=t.cssProperties,this.injector=t.injector??null}async build(e=!1){if(this.item.mediaType.isHTML)return await this.buildHtmlFrame(e);if(this.item.mediaType.isBitmap||this.item.mediaType.equals(o.SVG))return this.buildImageFrame();throw Error("Unsupported frame mediatype "+this.item.mediaType.string)}async buildHtmlFrame(e=!1){const i=await this.pub.get(this.item).readAsString();if(!i)throw new Error(`Failed reading item ${this.item.href}`);const r=new DOMParser().parseFromString(i,this.item.mediaType.string),t=r.querySelector("parsererror");if(t){const a=t.querySelector("div");throw new Error(`Failed parsing item ${this.item.href}: ${a?.textContent||t.textContent}`)}return this.injector&&await this.injector.injectForDocument(r,this.item),this.finalizeDOM(r,this.pub.baseURL,this.burl,this.item.mediaType,e,this.cssProperties)}buildImageFrame(){const e=document.implementation.createHTMLDocument(this.item.title||this.item.href),i=document.createElement("img");return i.src=this.burl||"",i.alt=this.item.title||"",i.decoding="async",e.body.appendChild(i),this.finalizeDOM(e,this.pub.baseURL,this.burl,this.item.mediaType,!0)}setProperties(e,i){for(const r in e){const t=e[r];t&&i.documentElement.style.setProperty(r,t)}}finalizeDOM(e,i,r,t,a=!1,u){if(!e)return"";const h=this.injector?.getAllowedDomains?.()||[],b=[...new Set([...i?[i]:[],...h])].filter(Boolean);if(u&&!a&&this.setProperties(u,e),e.body.querySelectorAll("img").forEach(n=>{n.setAttribute("fetchpriority","high")}),t.isHTML&&this.pub.metadata.languages?.[0]){const n=this.pub.metadata.languages[0];if(t===o.XHTML){const c=e.documentElement.lang||e.documentElement.getAttribute("xml:lang"),l=e.body.lang||e.body.getAttribute("xml:lang");l&&!c?(e.documentElement.lang=l,e.documentElement.setAttribute("xml:lang",l),e.body.removeAttribute("xml:lang"),e.body.removeAttribute("lang")):c||(e.documentElement.lang=n,e.documentElement.setAttribute("xml:lang",n))}else t===o.HTML&&!e.documentElement.lang&&(e.documentElement.lang=n)}if(g(this.pub.metadata)==="rtl"&&!e.documentElement.dir&&!e.body.dir&&(e.documentElement.dir=d.rtl),r!==void 0){const n=e.createElement("base");n.href=r,n.dataset.readium="true",e.head.firstChild.before(n)}const s=e.createElement("meta");return s.httpEquiv="Content-Security-Policy",s.content=f(b),s.dataset.readium="true",e.head.firstChild.before(s),URL.createObjectURL(new Blob([new XMLSerializer().serializeToString(e)],{type:t.isHTML?t.string:"application/xhtml+xml"}))}}export{L as default};
@@ -0,0 +1 @@
1
+ import{mid as n,COMMS_VERSION as a}from"@readium/navigator-html-injectables";const d=1e4;class f{constructor(t,e){this.registry=new Map,this._ready=!1,this.listenerBuffer=[],this.handler=this.handle.bind(this),this.wnd=t,this.origin=e;try{this.channelId=window.crypto.randomUUID()}catch{this.channelId=n()}this.gc=setInterval(()=>{this.registry.forEach((i,r)=>{performance.now()-i.time>d&&(console.warn(r,"event for",i.key,"was never handled!"),this.registry.delete(r))})},5e3),window.addEventListener("message",this.handler),this.send("_ping",void 0)}set listener(t){this.listenerBuffer.length>0&&this.listenerBuffer.forEach(e=>t(e[0],e[1])),this.listenerBuffer=[],this._listener=t}clearListener(){typeof this._listener=="function"&&(this._listener=void 0)}halt(){this._ready=!1,window.removeEventListener("message",this.handler),clearInterval(this.gc),this._listener=void 0,this.registry.clear()}resume(){window.addEventListener("message",this.handler),this._ready=!0}handle(t){const e=t.data;if(!e._readium){console.warn("Ignoring",e);return}if(e._channel===this.channelId)switch(e.key){case"_ack":{if(!e.id)return;const i=this.registry.get(e.id);if(!i)return;this.registry.delete(e.id),i.cb(!!e.data);return}case"_pong":this._ready=!0;default:{if(!this.ready)return;typeof this._listener=="function"?this._listener(e.key,e.data):this.listenerBuffer.push([e.key,e.data])}}}get ready(){return this._ready}send(t,e,i,r=!1,h=[]){const s=n();return i&&this.registry.set(s,{cb:i,time:performance.now(),key:t}),this.wnd.postMessage({_readium:a,_channel:this.channelId,id:s,data:e,key:t,strict:r},"/",h),s}}export{f as FrameComms};
@@ -0,0 +1 @@
1
+ import{Loader as o}from"@readium/navigator-html-injectables";import{FrameComms as n}from"./FrameComms.js";import{sML as h}from"../../helpers/dist/sML.js";import{KeyboardConditionBridge as m}from"../../peripherals/KeyboardConditionBridge.js";class y{constructor(t,i={},r=[],e=[]){this.timelineFragmentIds=e,this.hidden=!0,this.destroyed=!1,this.currModules=[],this.frame=document.createElement("iframe"),this.frame.sandbox.value="allow-same-origin allow-scripts",this.frame.classList.add("readium-navigator-iframe"),this.frame.style.visibility="hidden",this.frame.style.setProperty("aria-hidden","true"),this.frame.style.opacity="0",this.frame.style.position="absolute",this.frame.style.pointerEvents="none",this.frame.style.transition="visibility 0s, opacity 0.1s linear",this.source=t,this.contentProtectionConfig={...i},this.keyboardPeripheralsConfig=[...r]}async load(t){return new Promise((i,r)=>{if(this.loader){const e=this.frame.contentWindow;if([...this.currModules].sort().join("|")===[...t].sort().join("|")){try{i(e)}catch{}return}this.comms?.halt(),this.loader.destroy(),this.loader=new o(e,t),this.currModules=t,this.comms=void 0;try{i(e)}catch{}return}this.frame.onload=()=>{const e=this.frame.contentWindow;this.loader=new o(e,t),this.currModules=t;try{i(e)}catch{}},this.frame.onerror=e=>{try{r(e)}catch{}},this.frame.contentWindow.location.replace(this.source)})}applyContentProtection(){this.comms||this.comms.resume(),this.comms.send("peripherals_protection",this.contentProtectionConfig),this.keyboardPeripheralsConfig&&this.keyboardPeripheralsConfig.length>0&&(this.conditionBridge?.destroy(),this.conditionBridge=new m(this.keyboardPeripheralsConfig,t=>{t.length>0&&this.comms.send("keyboard_peripherals",t)}),this.conditionBridge.setup()),this.contentProtectionConfig.monitorScrollingExperimental&&this.comms.send("scroll_protection",{}),this.contentProtectionConfig.protectPrinting?.disable&&this.comms.send("print_protection",this.contentProtectionConfig.protectPrinting)}async destroy(){this.conditionBridge?.destroy(),await this.hide(),this.loader?.destroy(),this.frame.remove(),this.destroyed=!0}async hide(){if(!this.destroyed){if(this.frame.style.visibility="hidden",this.frame.style.setProperty("aria-hidden","true"),this.frame.style.opacity="0",this.frame.style.pointerEvents="none",this.hidden=!0,this.frame.blur(),this.frame.parentElement)return this.comms===void 0||!this.comms.ready?void 0:new Promise((t,i)=>{this.comms?.send("unfocus",void 0,r=>{this.comms?.halt(),t()})});this.comms?.halt()}}async show(t){if(this.destroyed)throw Error("Trying to show frame when it doesn't exist");if(!this.frame.parentElement)throw Error("Trying to show frame that is not attached to the DOM");return this.comms?this.comms.resume():this.comms=new n(this.frame.contentWindow,this.source),new Promise((i,r)=>{this.comms?.send("activate",void 0,()=>{this.comms?.send("focus",void 0,()=>{this.applyContentProtection(),this.timelineFragmentIds.length>0&&this.comms?.send("timeline_entries",this.timelineFragmentIds);const e=()=>{this.frame.style.removeProperty("visibility"),this.frame.style.removeProperty("aria-hidden"),this.frame.style.removeProperty("opacity"),this.frame.style.removeProperty("pointer-events"),this.hidden=!1,h.UA.WebKit&&this.comms?.send("force_webkit_recalc",void 0),i()};t!==void 0?this.comms?.send("go_progression",t,e):e()})})})}setCSSProperties(t){this.destroyed||!this.frame.contentWindow||(this.hidden&&(this.comms?this.comms?.resume():this.comms=new n(this.frame.contentWindow,this.source)),this.comms?.send("update_properties",t),this.hidden&&this.comms?.halt())}get iframe(){if(this.destroyed)throw Error("Trying to use frame when it doesn't exist");return this.frame}get realSize(){if(this.destroyed)throw Error("Trying to use frame client rect when it doesn't exist");return this.frame.getBoundingClientRect()}get isDestroyed(){return this.destroyed}get window(){if(this.destroyed||!this.frame.contentWindow)throw Error("Trying to use frame window when it doesn't exist");return this.frame.contentWindow}get atLeft(){return this.window.scrollX<5}get atRight(){return this.window.scrollX>this.window.document.scrollingElement.scrollWidth-this.window.innerWidth-5}get msg(){return this.comms}get ldr(){return this.loader}}export{y as FrameManager};
@@ -0,0 +1 @@
1
+ import y from"./FrameBlobBuilder.js";import{FrameManager as P}from"./FrameManager.js";const b=5,m=3;class B{constructor(e,r,s,n,o,i,l){this.pool=new Map,this.blobs=new Map,this.inprogress=new Map,this.pendingUpdates=new Map,this.injector=null,this.container=e,this.positions=r,this.currentCssProperties=s,this.injector=n??null,this.contentProtectionConfig=o||{},this.keyboardPeripheralsConfig=i||[],this.getFragmentIds=l??(()=>[])}async destroy(){let e=this.inprogress.values(),r=e.next();const s=[];for(;r.value;)s.push(r.value),r=e.next();s.length>0&&await Promise.allSettled(s),this.inprogress.clear();let n=this.pool.values(),o=n.next();for(;o.value;)await o.value.destroy(),o=n.next();this.pool.clear(),this.blobs.forEach(i=>{this.injector?.releaseBlobUrl?.(i),URL.revokeObjectURL(i)}),this.injector?.dispose(),this.container.childNodes.forEach(i=>{(i.nodeType===Node.ELEMENT_NODE||i.nodeType===Node.TEXT_NODE)&&i.remove()})}async update(e,r,s,n=!1){let o=this.positions.findIndex(p=>p.locations.position===r.locations.position);if(o<0)throw Error(`Locator not found in position list: ${r.locations.position} > ${this.positions.reduce((p,d)=>d.locations.position||0>p?d.locations.position||0:p,0)}`);const i=this.positions[o].href;this.inprogress.has(i)&&await this.inprogress.get(i);const l=new Promise(async(p,d)=>{const u=[],f=[];this.positions.forEach((t,c)=>{(c>o+b||c<o-b)&&(u.includes(t.href)||u.push(t.href)),c<o+m&&c>o-m&&(f.includes(t.href)||f.push(t.href))}),u.forEach(async t=>{f.includes(t)||this.pool.has(t)&&(await this.pool.get(t)?.destroy(),this.pool.delete(t),this.pendingUpdates.has(t)&&this.pendingUpdates.set(t,{inPool:!1}))}),this.currentBaseURL!==void 0&&e.baseURL!==this.currentBaseURL&&(this.blobs.forEach(t=>{this.injector?.releaseBlobUrl?.(t),URL.revokeObjectURL(t)}),this.blobs.clear()),this.currentBaseURL=e.baseURL;const w=async t=>{if(n&&(this.blobs.forEach(a=>{this.injector?.releaseBlobUrl?.(a),URL.revokeObjectURL(a)}),this.blobs.clear(),this.pendingUpdates.clear()),this.pendingUpdates.has(t)&&this.pendingUpdates.get(t)?.inPool===!1){const a=this.blobs.get(t);a&&(this.injector?.releaseBlobUrl?.(a),URL.revokeObjectURL(a),this.blobs.delete(t),this.pendingUpdates.delete(t))}if(this.pool.has(t)){const a=this.pool.get(t);if(!this.blobs.has(t))await a.destroy(),this.pool.delete(t),this.pendingUpdates.delete(t);else{await a.load(s);return}}const c=e.readingOrder.findWithHref(t);if(!c)return;if(!this.blobs.has(t)){const U=await new y(e,this.currentBaseURL||"",c,{cssProperties:this.currentCssProperties,injector:this.injector}).build();this.blobs.set(t,U)}const g=new P(this.blobs.get(t),this.contentProtectionConfig,this.keyboardPeripheralsConfig,this.getFragmentIds(t));t!==i&&await g.hide(),this.container.appendChild(g.iframe),await g.load(s),this.pool.set(t,g)};try{await Promise.all(f.map(t=>w(t)))}catch(t){d(t)}const h=this.pool.get(i);if((h?.source!==this._currentFrame?.source||n)&&(await this._currentFrame?.hide(),h&&await h.load(s),h&&await h.show(r.locations.progression),this._currentFrame=h,h)){const t=this.container.ownerDocument.activeElement;t&&t.tagName==="IFRAME"&&t!==h.iframe&&h.iframe.focus({preventScroll:!0})}p()});this.inprogress.set(i,l),await l,this.inprogress.delete(i)}setCSSProperties(e){if(!((s,n)=>{const o=Object.keys(s),i=Object.keys(n);if(o.length!==i.length)return!1;for(const l of o)if(s[l]!==n[l])return!1;return!0})(this.currentCssProperties||{},e)){this.currentCssProperties=e,this.pool.forEach(s=>{s.setCSSProperties(e)});for(const s of this.blobs.keys())this.pendingUpdates.set(s,{inPool:this.pool.has(s)})}}get currentFrames(){return[this._currentFrame]}get currentBounds(){const e={x:0,y:0,width:0,height:0,top:0,right:0,bottom:0,left:0,toJSON(){return this}};return this.currentFrames.forEach(r=>{if(!r)return;const s=r.realSize;e.x=Math.min(e.x,s.x),e.y=Math.min(e.y,s.y),e.width+=s.width,e.height=Math.max(e.height,s.height),e.top=Math.min(e.top,s.top),e.right=Math.min(e.right,s.right),e.bottom=Math.min(e.bottom,s.bottom),e.left=Math.min(e.left,s.left)}),e}}export{B as FramePoolManager};