@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.
- package/LICENSE +28 -0
- package/dist/Navigator.js +1 -0
- package/dist/_virtual/index.js +1 -0
- package/dist/_virtual/preload-helper.js +1 -0
- package/dist/audio/AudioNavigator.js +1 -0
- package/dist/audio/AudioPoolManager.js +1 -0
- package/dist/audio/engine/PreservePitchProcessor.js +215 -0
- package/dist/audio/engine/PreservePitchWorklet.js +1 -0
- package/dist/audio/engine/WebAudioEngine.js +1 -0
- package/dist/audio/preferences/AudioDefaults.js +1 -0
- package/dist/audio/preferences/AudioPreferences.js +1 -0
- package/dist/audio/preferences/AudioPreferencesEditor.js +1 -0
- package/dist/audio/preferences/AudioSettings.js +1 -0
- package/dist/audio/protection/AudioNavigatorProtector.js +1 -0
- package/dist/css/Properties.js +1 -0
- package/dist/dom/_readium_cssSelectorGenerator.js +1 -0
- package/dist/dom/_readium_executionCleanup.js +14 -0
- package/dist/dom/_readium_executionPrevention.js +66 -0
- package/dist/dom/_readium_webpubExecution.js +5 -0
- package/dist/epub/EpubNavigator.js +1 -0
- package/dist/epub/css/Properties.js +1 -0
- package/dist/epub/css/ReadiumCSS.js +1 -0
- package/dist/epub/frame/FrameBlobBuilder.js +1 -0
- package/dist/epub/frame/FrameComms.js +1 -0
- package/dist/epub/frame/FrameManager.js +1 -0
- package/dist/epub/frame/FramePoolManager.js +1 -0
- package/dist/epub/fxl/FXLCoordinator.js +1 -0
- package/dist/epub/fxl/FXLFrameManager.js +1 -0
- package/dist/epub/fxl/FXLFramePoolManager.js +1 -0
- package/dist/epub/fxl/FXLPeripherals.js +4 -0
- package/dist/epub/fxl/FXLPeripheralsDebug.js +1 -0
- package/dist/epub/fxl/FXLSpreader.js +1 -0
- package/dist/epub/preferences/EpubDefaults.js +1 -0
- package/dist/epub/preferences/EpubPreferences.js +1 -0
- package/dist/epub/preferences/EpubPreferencesEditor.js +1 -0
- package/dist/epub/preferences/EpubSettings.js +1 -0
- package/dist/helpers/dimensions.js +1 -0
- package/dist/helpers/dist/sML.js +1 -0
- package/dist/helpers/lineLength.js +1 -0
- package/dist/helpers/minify.js +1 -0
- package/dist/helpers/scriptMode.js +1 -0
- package/dist/index.js +1 -11006
- package/dist/injection/Injector.js +1 -0
- package/dist/injection/epubInjectables.js +1 -0
- package/dist/injection/webpubInjectables.js +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/dist/webPub/ReadiumCSS-webPub.css.js +274 -0
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/colors.json.js +1 -0
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/experiments.json.js +1 -0
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/fontStacks.json.js +1 -0
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/i18n.json.js +1 -0
- package/dist/node_modules/.pnpm/@readium_css@2.0.5/node_modules/@readium/css/css/vars/settings.json.js +1 -0
- package/dist/node_modules/.pnpm/path-browserify@1.0.1/node_modules/path-browserify/index.js +1 -0
- package/dist/peripherals/KeyboardConditionBridge.js +1 -0
- package/dist/peripherals/KeyboardPeripherals.js +1 -0
- package/dist/preferences/Preference.js +1 -0
- package/dist/preferences/Types.js +1 -0
- package/dist/preferences/guards.js +1 -0
- package/dist/protection/AutomationDetector.js +1 -0
- package/dist/protection/ContextMenuProtector.js +1 -0
- package/dist/protection/CopyProtector.js +1 -0
- package/dist/protection/DevToolsDetector.js +1 -0
- package/dist/protection/DragAndDropProtector.js +1 -0
- package/dist/protection/IframeEmbeddingDetector.js +1 -0
- package/dist/protection/NavigatorProtector.js +1 -0
- package/dist/protection/PrintProtector.js +15 -0
- package/dist/protection/utils/WorkerConsole.js +12 -0
- package/dist/protection/utils/console.js +1 -0
- package/dist/protection/utils/match.js +1 -0
- package/dist/protection/utils/platform.js +1 -0
- package/dist/webpub/WebPubBlobBuilder.js +2 -0
- package/dist/webpub/WebPubFrameManager.js +1 -0
- package/dist/webpub/WebPubFramePoolManager.js +1 -0
- package/dist/webpub/WebPubNavigator.js +1 -0
- package/dist/webpub/css/Properties.js +1 -0
- package/dist/webpub/css/WebPubCSS.js +1 -0
- package/dist/webpub/preferences/WebPubDefaults.js +1 -0
- package/dist/webpub/preferences/WebPubPreferences.js +1 -0
- package/dist/webpub/preferences/WebPubPreferencesEditor.js +1 -0
- package/dist/webpub/preferences/WebPubSettings.js +1 -0
- package/package.json +16 -14
- package/src/Navigator.ts +4 -1
- package/src/audio/AudioNavigator.ts +8 -8
- package/src/decorations/index.ts +24 -127
- package/src/epub/EpubNavigator.ts +149 -20
- package/src/epub/frame/FrameManager.ts +8 -3
- package/src/epub/frame/FramePoolManager.ts +5 -2
- package/src/epub/fxl/FXLCoordinator.ts +1 -1
- package/src/epub/fxl/FXLFrameManager.ts +1 -1
- package/src/epub/preferences/EpubDefaults.ts +1 -1
- package/src/epub/preferences/EpubSettings.ts +1 -1
- package/src/protection/DevToolsDetector.ts +1 -1
- package/src/webpub/WebPubFrameManager.ts +9 -3
- package/src/webpub/WebPubFramePoolManager.ts +5 -2
- package/src/webpub/WebPubNavigator.ts +100 -19
- package/src/webpub/preferences/WebPubDefaults.ts +1 -1
- package/src/webpub/preferences/WebPubSettings.ts +1 -1
- package/types/src/Navigator.d.ts +3 -1
- package/types/src/decorations/index.d.ts +5 -59
- package/types/src/epub/EpubNavigator.d.ts +13 -3
- package/types/src/epub/frame/FrameManager.d.ts +2 -1
- package/types/src/epub/frame/FramePoolManager.d.ts +2 -1
- package/types/src/epub/fxl/FXLFramePoolManager.d.ts +1 -1
- package/types/src/webpub/WebPubFrameManager.d.ts +2 -1
- package/types/src/webpub/WebPubFramePoolManager.d.ts +2 -1
- package/types/src/webpub/WebPubNavigator.d.ts +12 -3
- package/dist/ar-DyHX_uy2.js +0 -7
- package/dist/da-Dct0PS3E.js +0 -7
- package/dist/fr-C5HEel98.js +0 -7
- package/dist/index.umd.cjs +0 -5615
- package/dist/it-DFOBoXGy.js +0 -7
- package/dist/pt_PT-Di3sVjze.js +0 -7
- 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 @@
|
|
|
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};
|