@readium/navigator-html-injectables 2.5.0 → 2.6.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/dist/Loader.js +1 -0
- package/dist/comms/comms.js +1 -0
- package/dist/comms/mid.js +1 -0
- package/dist/helpers/animation.js +1 -0
- package/dist/helpers/css.js +1 -0
- package/dist/helpers/document.js +1 -0
- package/dist/helpers/dom.js +1 -0
- package/dist/helpers/locator.js +1 -0
- package/dist/helpers/rect.js +1 -0
- package/dist/helpers/sanitize.js +1 -0
- package/dist/index.js +1 -4601
- package/dist/keyboard/KeyCombinationManager.js +1 -0
- package/dist/keyboard/KeyboardCombinations.js +1 -0
- package/dist/modules/Decorator.js +24 -0
- package/dist/modules/Module.js +1 -0
- package/dist/modules/ModuleLibrary.js +1 -0
- package/dist/modules/Peripherals.js +1 -0
- package/dist/modules/setup/FixedSetup.js +13 -0
- package/dist/modules/setup/ReflowableSetup.js +1 -0
- package/dist/modules/setup/Setup.js +1 -0
- package/dist/modules/setup/WebPubSetup.js +1 -0
- package/dist/modules/snapper/CJKVerticalSnapper.js +12 -0
- package/dist/modules/snapper/ColumnSnapper.js +35 -0
- package/dist/modules/snapper/ScrollSnapper.js +9 -0
- package/dist/modules/snapper/Snapper.js +5 -0
- package/dist/modules/snapper/WebPubSnapper.js +1 -0
- package/dist/protection/BulkCopyProtector.js +1 -0
- package/dist/protection/PatternAnalyzer.js +1 -0
- package/dist/protection/PrintProtector.js +15 -0
- package/dist/protection/SelectionAnalyzer.js +1 -0
- package/dist/protection/config.js +1 -0
- package/dist/vendor/approx-string-match/index.js +1 -0
- package/dist/vendor/hypothesis/anchoring/match-quote.js +1 -0
- package/dist/vendor/hypothesis/anchoring/text-range.js +1 -0
- package/dist/vendor/hypothesis/anchoring/trim-range.js +1 -0
- package/dist/vendor/hypothesis/anchoring/types.js +1 -0
- package/package.json +14 -13
- package/src/comms/comms.ts +11 -1
- package/src/comms/keys.ts +6 -2
- package/src/helpers/css.ts +1 -1
- package/src/helpers/document.ts +5 -5
- package/src/helpers/locator.ts +5 -5
- package/src/helpers/rect.ts +79 -18
- package/src/index.ts +1 -1
- package/src/modules/Decorator.ts +404 -107
- package/src/modules/snapper/CJKVerticalSnapper.ts +34 -7
- package/src/modules/snapper/ColumnSnapper.ts +54 -6
- package/src/modules/snapper/ScrollSnapper.ts +30 -7
- package/src/modules/snapper/Snapper.ts +144 -0
- package/src/modules/snapper/WebPubSnapper.ts +31 -7
- package/types/src/comms/comms.d.ts +10 -1
- package/types/src/comms/keys.d.ts +2 -2
- package/types/src/helpers/css.d.ts +1 -1
- package/types/src/helpers/document.d.ts +5 -5
- package/types/src/helpers/rect.d.ts +2 -1
- package/types/src/index.d.ts +1 -1
- package/types/src/modules/Decorator.d.ts +33 -7
- package/types/src/modules/snapper/CJKVerticalSnapper.d.ts +1 -0
- package/types/src/modules/snapper/ColumnSnapper.d.ts +14 -1
- package/types/src/modules/snapper/ScrollSnapper.d.ts +1 -0
- package/types/src/modules/snapper/Snapper.d.ts +58 -0
- package/types/src/modules/snapper/WebPubSnapper.d.ts +1 -0
- 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 -96
- package/dist/it-DFOBoXGy.js +0 -7
- package/dist/pt_PT-Di3sVjze.js +0 -7
- package/dist/sv-BfzAFsVN.js +0 -7
- package/src/helpers/color.ts +0 -268
- package/src/helpers/sML.ts +0 -143
- package/types/src/helpers/color.d.ts +0 -27
- package/types/src/helpers/sML.d.ts +0 -56
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nearestInteractiveElement as m,isInteractiveElement as y}from"../helpers/dom.js";class u{match(t,e){for(const r of e)if(this.matchesCombo(t,r))return!0;return!1}matchesCombo(t,e){return t.keyCode===e.keyCode&&this.matchesModifier(t.ctrlKey,e.ctrl)&&this.matchesModifier(t.shiftKey,e.shift)&&this.matchesModifier(t.altKey,e.alt)&&this.matchesModifier(t.metaKey,e.meta)}matchesModifier(t,e){return e===void 0?!t:t===e}createKeyHandler(t,e){return r=>{this.match(r,t)&&(r.preventDefault(),r.stopPropagation(),e(r))}}createActivityEvent(t,e,r,a){let n,i;if(a){const s=a.getSelection(),c=s?.toString()||"",o=(c&&s?.rangeCount?s.getRangeAt(0)?.getClientRects():null)?.[0];o&&c&&(n={text:c,x:o.x,y:o.y,width:o.width,height:o.height});const h=a.document.activeElement;h&&h!==a.document.body&&(i=m(h)?.outerHTML)}return{type:e,timestamp:Date.now(),key:t.key,code:t.code,keyCode:t.keyCode,ctrlKey:t.ctrlKey,altKey:t.altKey,shiftKey:t.shiftKey,metaKey:t.metaKey,targetFrameSrc:r,selectedText:n,interactiveElement:i}}createKeyboardHandlers(t,e,r,a){const n=[];return e.forEach(i=>{n.push(...i.keyCombos.map(s=>({...s,handler:c=>{const l=i.type,o=this.createActivityEvent(c,l,t,a);r(o)}})))}),n}createUnifiedHandler(t,e,r,a){const n=this.createKeyboardHandlers(t,e,r,a);return i=>{if(i.isTrusted){for(const s of n)if(this.match(i,[s])){const c=s.suppressOnInteractiveElement;if(c){const l=(a?.document??document).activeElement;if(Array.isArray(c)?c.some(o=>l?.matches(o)):y(l))return}i.preventDefault(),i.stopPropagation(),s.handler(i);return}}}}}export{u as KeyCombinationManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={type:"developer_tools",keyCombos:[{keyCode:73,meta:!0,alt:!0},{keyCode:73,ctrl:!0,shift:!0},{keyCode:74,meta:!0,alt:!0},{keyCode:74,ctrl:!0,shift:!0},{keyCode:85,meta:!0,alt:!0},{keyCode:67,meta:!0,alt:!0},{keyCode:67,meta:!0,shift:!0},{keyCode:67,ctrl:!0,shift:!0},{keyCode:65,meta:!0,alt:!0},{keyCode:84,meta:!0,shift:!0,alt:!0},{keyCode:67,shift:!0,alt:!0},{keyCode:123},{keyCode:123,shift:!0},{keyCode:123,ctrl:!0,shift:!0},{keyCode:123,meta:!0,alt:!0}]},t={type:"select_all",keyCombos:[{keyCode:65,meta:!0},{keyCode:65,ctrl:!0}]},r={type:"print",keyCombos:[{keyCode:80,meta:!0},{keyCode:80,ctrl:!0},{keyCode:80,meta:!0,shift:!0},{keyCode:80,ctrl:!0,shift:!0},{keyCode:80,meta:!0,alt:!0},{keyCode:80,ctrl:!0,alt:!0}]},u={type:"save",keyCombos:[{keyCode:83,meta:!0},{keyCode:83,ctrl:!0}]};export{e as DEV_TOOLS,r as PRINT,u as SAVE,t as SELECT_ALL};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{Locator as P}from"@readium/shared";import{Module as N}from"./Module.js";import{rangeFromLocator as D}from"../helpers/locator.js";import{getClientRectsNoOverlap as $,rectContainsPoint as z,getTextClientRects as U}from"../helpers/rect.js";import{getProperty as I}from"../helpers/css.js";import{sML as j,adjustColorForContrast as R,getContrastingTextColor as O,colorToRgba as M,isDarkColor as V}from"@readium/helpers";import{makeWritingContext as H}from"../helpers/document.js";import{sanitizeHTML as q}from"../helpers/sanitize.js";function T(k){switch(k){case c.Mask:return"rgba(255, 255, 255, 0.5)";case c.Highlight:case c.HighlightUnderline:return"#FFFF00";default:return"#FF0000"}}const c={Highlight:"highlight",HighlightUnderline:"highlightUnderline",Underline:"underline",Strikethrough:"strikethrough",Outline:"outline",TextColor:"textColor",Mask:"mask",Template:"template"};var X=(k=>(k.Wrap="wrap",k.Viewport="viewport",k.Bounds="bounds",k.Page="page",k))(X||{}),G=(k=>(k.Boxes="boxes",k.Bounds="bounds",k))(G||{});const Y=()=>"Highlight"in window,F=["IMG","IMAGE","AUDIO","VIDEO","SVG"];class Z{constructor(t,i,e,s){this.wnd=t,this.comms=i,this.id=e,this.name=s,this.items=[],this.lastItemId=0,this.container=void 0,this._activatable=!1,this._hoverable=!1,this.hoveredItem=void 0,this.experimentalHighlights=!1,this._tintSubKeys=new Map,this._subKeyCounter=0,this.maskSvg=void 0,this.shadowHost=void 0,this.shadowRoot=void 0,this.currentRender=0,Y()&&(this.experimentalHighlights=!0,this.notTextFlag=new Map),this.activationHandler=this.handleActivation.bind(this),this.wnd.document.addEventListener("pointerup",this.activationHandler),this.hoverHandler=this.handleHover.bind(this),this.wnd.document.addEventListener("pointermove",this.hoverHandler)}get activatable(){return this._activatable}set activatable(t){this._activatable=t}get hoverable(){return this._hoverable}set hoverable(t){if(this._hoverable=t,!t&&this.hoveredItem){const i=this.hoveredItem.range.getBoundingClientRect(),e=this.wnd.devicePixelRatio;this.comms.send("decoration_pointer_leave",{decorationId:this.hoveredItem.decoration.id,group:this.name,rect:{top:i.top*e,left:i.left*e,width:i.width*e,height:i.height*e}}),this.hoveredItem=void 0}}add(t){const i=`${this.id}-${this.lastItemId++}`,e=D(this.wnd.document,t.locator);if(!e){this.comms.log("Can't locate DOM range for decoration",t);return}const s=e.commonAncestorContainer;if(s.nodeType!==Node.TEXT_NODE&&this.experimentalHighlights&&(F.includes(s.nodeName.toUpperCase())&&this.notTextFlag?.set(i,!0),e.cloneContents().querySelector(F.join(", ").toLowerCase())&&this.notTextFlag?.set(i,!0),(s.textContent?.trim()||"").length===0&&this.notTextFlag?.set(i,!0)),this.experimentalHighlights&&!this.notTextFlag?.has(i)){const r=a=>{for(;a&&a.nodeType===Node.ELEMENT_NODE;){if(a.namespaceURI?.includes("svg"))return!0;a=a.parentNode}return!1};(r(e.startContainer)||r(e.endContainer))&&this.notTextFlag?.set(i,!0)}if(this.experimentalHighlights){const{type:r}=t.style,{layout:a,width:g,expand:f}=t.style;r!==c.TextColor&&(r===c.Outline||r===c.Template||r===c.Mask||a!==void 0&&a!=="boxes"||g!==void 0&&g!=="wrap"||f)&&this.notTextFlag?.set(i,!0)}const o={decoration:t,id:i,range:e,hitRects:[],clickableElements:void 0,container:void 0};this.items.push(o),this.layout(o),o.hitRects=this.clientRectsToDocCoords($(o.range,!1,!1,(o.decoration.style.expand??0)+this.hitGap())),this.renderLayout([o])}remove(t){const i=this.items.findIndex(o=>o.decoration.id===t);if(i<0)return;const e=this.items[i],s=e.decoration.style?.type===c.Mask;if(this.items.splice(i,1),e.clickableElements=void 0,e.container&&(e.container.remove(),e.container=void 0),this.experimentalHighlights&&!this.notTextFlag?.has(e.id)&&e.highlightSubKey){const o=this.wnd.CSS.highlights;o.get(e.highlightSubKey)?.delete(e.range),this.items.some(a=>a.highlightSubKey===e.highlightSubKey)||o.delete(e.highlightSubKey);const r=this.wnd.document.getElementById(`${this.id}-style`);r&&this._rebuildHighlightStylesheet(r)}this.notTextFlag?.delete(e.id),this.hoveredItem===e&&(this.hoveredItem=void 0),s&&this.updateSharedMask()}update(t){this.remove(t.id),this.add(t)}clear(){this.clearContainer(),this.items.length=0,this.notTextFlag?.clear(),this.hoveredItem=void 0,this.maskSvg&&(this.maskSvg.remove(),this.maskSvg=void 0),this.shadowHost&&(this.shadowHost.remove(),this.shadowHost=void 0,this.shadowRoot=void 0)}destroy(){this.clear(),this.wnd.document.removeEventListener("pointerup",this.activationHandler),this.wnd.document.removeEventListener("pointermove",this.hoverHandler)}clientRectsToDocCoords(t){const i=H(this.wnd),e=i.xDocOffset,s=i.yDocOffset;return e===0&&s===0?t:t.map(o=>({left:o.left+e,top:o.top+s,right:o.right+e,bottom:o.bottom+s,width:o.width,height:o.height}))}pointerToDocCoords(t){const i=H(this.wnd);return{docX:t.clientX+i.xDocOffset,docY:t.clientY+i.yDocOffset}}effectiveZoom(){if(!j.UA.Blink)return 1;const t=parseFloat(this.wnd.getComputedStyle(this.wnd.document.documentElement).zoom),i=parseFloat(this.wnd.getComputedStyle(this.wnd.document.body).zoom);return(t||1)*(i||1)}hitGap(){return 2*this.effectiveZoom()}handleActivation(t){if(!this._activatable)return;const{docX:i,docY:e}=this.pointerToDocCoords(t),s=this.wnd.devicePixelRatio;for(const o of this.items){let r;if(o.decoration.style.type===c.Template)for(const a of o.clickableElements??[]){const g=a.getBoundingClientRect();if(z(g,t.clientX,t.clientY,0)){r=g;break}}else for(const a of o.hitRects)if(z(a,i,e,0)){r=o.range.getBoundingClientRect();break}if(r){this.comms.send("decoration_activated",{decorationId:o.decoration.id,group:this.name,rect:{top:r.top*s,left:r.left*s,width:r.width*s,height:r.height*s},point:{x:t.clientX*s,y:t.clientY*s}});return}}}handleHover(t){if(!this._hoverable)return;const{docX:i,docY:e}=this.pointerToDocCoords(t),s=this.wnd.devicePixelRatio;let o,r;for(const a of this.items){if(a.decoration.style.type===c.Template)for(const g of a.clickableElements??[]){const f=g.getBoundingClientRect();if(z(f,t.clientX,t.clientY,0)){o=a,r=f;break}}else for(const g of a.hitRects)if(z(g,i,e,0)){o=a,r=a.range.getBoundingClientRect();break}if(o)break}if(o!==this.hoveredItem){if(this.hoveredItem){const g=this.hoveredItem.range.commonAncestorContainer.isConnected?this.hoveredItem.range.getBoundingClientRect():null;this.comms.send("decoration_pointer_leave",{decorationId:this.hoveredItem.decoration.id,group:this.name,rect:g?{top:g.top*s,left:g.left*s,width:g.width*s,height:g.height*s}:void 0,point:{x:t.clientX*s,y:t.clientY*s}})}this.hoveredItem=o,o&&r&&this.comms.send("decoration_pointer_enter",{decorationId:o.decoration.id,group:this.name,rect:{top:r.top*s,left:r.left*s,width:r.width*s,height:r.height*s},point:{x:t.clientX*s,y:t.clientY*s}})}}requestLayout(){this.wnd.cancelAnimationFrame(this.currentRender),this.clearContainer(),this.wnd.document.fonts.ready.then(()=>{this.currentRender=this.wnd.requestAnimationFrame(()=>{this.items.forEach(t=>{this.layout(t),t.hitRects=this.clientRectsToDocCoords($(t.range,!1,!1,(t.decoration.style.expand??0)+this.hitGap()))}),this.renderLayout(this.items),this.updateSharedMask()})})}experimentalLayout(t){const i=this.requireContainer(!0),e=this.wnd.CSS.highlights,s=t.decoration.style,o=s.type??c.Highlight,r=s.tint??T(o),a=s.width,g=s.layout,f=this._getSubKey(o,r);t.highlightSubKey&&(e.get(t.highlightSubKey)?.delete(t.range),t.highlightSubKey!==f&&!this.items.some(l=>l!==t&&l.highlightSubKey===t.highlightSubKey)&&e.delete(t.highlightSubKey)),t.highlightSubKey=f;let w;e.has(f)?w=e.get(f):(w=new this.wnd.Highlight,e.set(f,w));const h=(n,l)=>this.wnd.document.caretPositionFromPoint?.(n,l)??null;if(o===c.TextColor&&(g==="bounds"||a==="bounds"||a==="page")){const n=H(this.wnd);if(n.isVertical)console.warn("Vertical writing detected: caretPositionFromPoint has known bugs, falling back to original range"),w.add(t.range);else{const l=t.range.getBoundingClientRect();let y,b;a==="page"?(y=Math.floor(n.inlineStart(l)/n.pageInlineSize)*n.pageInlineSize,b=n.pageInlineSize):(y=n.inlineStart(l),b=n.inlineSize(l));const v=h(y,n.blockStart(l)+1),S=h(y+b,n.blockStart(l)+n.blockSize(l)-1);if(v&&S){const x=this.wnd.document.createRange();x.setStart(v.offsetNode,v.offset),x.setEnd(S.offsetNode,S.offset),w.add(x),t.range=x}else w.add(t.range)}}else w.add(t.range);const d=this.getBackgroundColor(),m=s.enforceContrast!==!1?R(r,d):r;let p;switch(o){case c.Underline:p=`::highlight(${f}) {
|
|
2
|
+
text-decoration: underline;
|
|
3
|
+
text-decoration-color: ${m};
|
|
4
|
+
text-decoration-thickness: 0.1em;
|
|
5
|
+
}`;break;case c.Strikethrough:p=`::highlight(${f}) {
|
|
6
|
+
text-decoration: line-through;
|
|
7
|
+
text-decoration-color: ${m};
|
|
8
|
+
text-decoration-thickness: 0.1em;
|
|
9
|
+
}`;break;case c.Outline:p=`::highlight(${f}) {
|
|
10
|
+
outline: 2px solid ${m};
|
|
11
|
+
outline-offset: 1px;
|
|
12
|
+
}`;break;case c.TextColor:p=`::highlight(${f}) {
|
|
13
|
+
color: ${m};
|
|
14
|
+
}`;break;case c.HighlightUnderline:{const{r:n,g:l,b:y}=M(m),b=`rgba(${n}, ${l}, ${y}, 0.3)`;p=`::highlight(${f}) {
|
|
15
|
+
color: ${O(m,d)};
|
|
16
|
+
background-color: ${b};
|
|
17
|
+
text-decoration: underline;
|
|
18
|
+
text-decoration-color: ${m};
|
|
19
|
+
text-decoration-thickness: 0.1em;
|
|
20
|
+
}`;break}case c.Highlight:default:p=`::highlight(${f}) {
|
|
21
|
+
color: ${O(m,d)};
|
|
22
|
+
background-color: ${m};
|
|
23
|
+
}`}t.highlightCSS=p,this._rebuildHighlightStylesheet(i)}_getSubKey(t,i){const e=`${t}::${i}`;let s=this._tintSubKeys.get(e);return s||(s=`${this.id}--${this._subKeyCounter++}`,this._tintSubKeys.set(e,s)),s}_rebuildHighlightStylesheet(t){const i=new Set,e=[];for(const s of this.items)s.highlightSubKey&&s.highlightCSS&&!i.has(s.highlightSubKey)&&(i.add(s.highlightSubKey),e.push(s.highlightCSS));t.innerHTML=e.join(`
|
|
24
|
+
`)}layout(t){if(this.experimentalHighlights&&!this.notTextFlag?.has(t.id))return this.experimentalLayout(t);const i=this.wnd.document.createElement("div");i.setAttribute("id",t.id),i.dataset.highlightId=t.decoration.id,i.style.setProperty("pointer-events","none");const e=H(this.wnd),s=1/this.effectiveZoom(),o=t.decoration.style.expand??0,r=(h,d,u,m=0)=>{const p=t.decoration?.style?.width,n=d;switch(p){case"viewport":{const l=Math.floor(e.inlineStart(n)/e.viewportInlineSize)*e.viewportInlineSize;e.applyPosition(h,l+e.inlineScrollOffset+m,e.blockStart(n)+e.blockScrollOffset,e.viewportInlineSize-2*m,e.blockSize(n),s);break}case"page":{const l=Math.floor(e.inlineStart(n)/e.pageInlineSize)*e.pageInlineSize;e.applyPosition(h,l+e.inlineScrollOffset+m,e.blockStart(n)+e.blockScrollOffset,e.pageInlineSize-2*m,e.blockSize(n),s);break}case"bounds":{e.applyPosition(h,e.inlineStart(u)+e.inlineScrollOffset,e.blockStart(n)+e.blockScrollOffset,e.inlineSize(u),e.blockSize(n),s);break}default:e.applyPosition(h,e.inlineStart(n)+e.inlineScrollOffset,e.blockStart(n)+e.blockScrollOffset,e.inlineSize(n),e.blockSize(n),s)}},a=t.range.getBoundingClientRect(),g=t.decoration.style,f=(()=>{if(g.type!==c.Outline)return 0;const h=g.width;return h==="page"||h==="viewport"?3:0})();let w;if(g.type===c.Template){g.stylesheet&&this.injectCustomStylesheet(g.stylesheet);const h=q(this.wnd,g.element);if(!h){t.container=i,t.clickableElements=[];return}h.style.setProperty("pointer-events","none"),w=h}else{const h=g,d=h.type??c.Highlight,u=h.tint??T(d);if(d===c.TextColor){t.container=i,t.clickableElements=[];return}if(d===c.Mask){t.container=i,t.clickableElements=[],this.updateSharedMask();return}const m=this.getCurrentDarkMode(),p=this.getBackgroundColor(),n=h.enforceContrast!==!1,l=(()=>{switch(d){case c.Underline:{const v=n?R(u,p):u,S=h.layout==="bounds",[x,E]=e.isVertical?["border-right","border-left"]:["border-bottom","border-top"];return[S?`${E}: 0.1em solid ${v} !important`:null,`${x}: 0.1em solid ${v} !important`,"background-color: transparent !important","box-sizing: border-box !important"].filter(Boolean).join("; ")}case c.Strikethrough:{const v=n?R(u,p):u;return h.layout==="bounds"?[`background: repeating-linear-gradient(-45deg, transparent, transparent 19px, ${v} 19px, ${v} 20px) !important`,"background-color: transparent !important","box-sizing: border-box !important"].join("; "):[`background-color: ${v} !important`,"box-sizing: border-box !important"].join("; ")}case c.Outline:return[`outline: 2px solid ${n?R(u,p):u} !important`,"outline-offset: 1px !important","background-color: transparent !important","box-sizing: border-box !important"].join("; ");case c.HighlightUnderline:{const v=n?R(u,p):u,{r:S,g:x,b:E}=M(v),_=`rgba(${S}, ${x}, ${E}, 0.3)`,B=h.layout==="bounds",[K,L]=e.isVertical?["border-right","border-left"]:["border-bottom","border-top"];return[`background-color: ${_} !important`,B?`${L}: 0.1em solid ${v} !important`:null,`${K}: 0.1em solid ${v} !important`,"box-sizing: border-box !important"].filter(Boolean).join("; ")}case c.Highlight:default:return[`background-color: ${n?R(u,p):u} !important`,`mix-blend-mode: ${m?"exclusion":"multiply"} !important`,"opacity: 1 !important","box-sizing: border-box !important"].join("; ")}})(),y=this.wnd.document.createElement("template");y.innerHTML=`<div data-readium="true" class="readium-${d}" style="${l}"></div>`.trim(),w=y.content.firstElementChild}if(t.decoration?.style?.layout==="bounds"){const h=w.cloneNode(!0);h.style.setProperty("pointer-events","none");const d=o?{left:a.left-o,right:a.right+o,top:a.top-o,bottom:a.bottom+o,width:a.width+o*2,height:a.height+o*2}:a;r(h,d,a,f),i.append(h)}else{const h=g.type,d=h===c.Underline||h===c.Strikethrough,u=h===c.Strikethrough,m=d?U(t.range,["rt","rp"]):t.range;let p=$(m,!0,e.isVertical,d?0:o);p=p.sort((n,l)=>e.isVertical?(e.isVertLR?1:-1)*(n.left-l.left):n.top-l.top);for(let n of p){const l=w.cloneNode(!0);l.style.setProperty("pointer-events","none");let y=n;if(u){const b=e.blockSize(n)*.1,S=e.blockStart(n)+e.blockSize(n)/2-b/2;y=e.isVertical?{left:S,right:S+b,top:n.top,bottom:n.bottom,width:b,height:n.height}:{top:S,bottom:S+b,left:n.left,right:n.right,height:b,width:n.width}}o&&d&&(y=e.isVertical?{...y,top:y.top-o,bottom:y.bottom+o,height:y.height+o*2}:{...y,left:y.left-o,right:y.right+o,width:y.width+o*2}),r(l,y,a,f),i.append(l)}}t.container=i,t.clickableElements=Array.from(i.querySelectorAll("[data-activable='1']")),t.clickableElements.length||(t.clickableElements=Array.from(i.children))}renderLayout(t){this.wnd.cancelAnimationFrame(this.currentRender),this.currentRender=this.wnd.requestAnimationFrame(()=>{if(t=t.filter(e=>!this.experimentalHighlights||!!this.notTextFlag?.has(e.id)),!t||t.length===0)return;this.requireContainer().append(...t.map(e=>e.container).filter(e=>!!e))})}requireContainer(t=!1){if(t){let i;return this.wnd.document.getElementById(`${this.id}-style`)?i=this.wnd.document.getElementById(`${this.id}-style`):(i=this.wnd.document.createElement("style"),i.dataset.readium="true",i.id=`${this.id}-style`,this.wnd.document.head.appendChild(i)),i}return this.container||(this.shadowRoot||(this.shadowHost=this.wnd.document.createElement("div"),this.shadowHost.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none",this.wnd.document.body.appendChild(this.shadowHost),this.shadowRoot=this.shadowHost.attachShadow({mode:"open"})),this.container=this.wnd.document.createElement("div"),this.container.setAttribute("id",this.id),this.container.dataset.group=this.name,this.container.dataset.readium="true",this.container.style.setProperty("pointer-events","none"),this.container.style.display="contents",this.shadowRoot.appendChild(this.container)),this.container}getCurrentDarkMode(){return I(this.wnd,"--USER__appearance")==="readium-night-on"||V(this.getBackgroundColor())}getBackgroundColor(){return I(this.wnd,"--USER__backgroundColor")||this.wnd.getComputedStyle(this.wnd.document.documentElement).getPropertyValue("background-color")}updateSharedMask(){const t=this.items.filter(d=>d.decoration.style?.type===c.Mask);if(t.length===0){this.maskSvg&&(this.maskSvg.remove(),this.maskSvg=void 0),this.shadowRoot&&(this.shadowRoot.innerHTML="");return}const i=H(this.wnd),e=1/this.effectiveZoom(),s=this.wnd.document.documentElement,o=s.scrollWidth,r=s.scrollHeight,a=[];for(const d of t){const u=d.decoration.style,m=u.layout??"boxes",p=u.width??"wrap",n=u.expand??0,l=d.range.getBoundingClientRect(),y=m==="bounds"?[n?{left:l.left-n,top:l.top-n,right:l.right+n,bottom:l.bottom+n,width:l.width+n*2,height:l.height+n*2}:l]:$(d.range,!1,!1,n);for(const b of y){let v;switch(p){case"viewport":{const S=Math.floor(i.inlineStart(b)/i.viewportInlineSize)*i.viewportInlineSize;v=i.toRect(S,i.blockStart(b),i.viewportInlineSize,i.blockSize(b));break}case"page":{const S=Math.floor(i.inlineStart(b)/i.pageInlineSize)*i.pageInlineSize;v=i.toRect(S,i.blockStart(b),i.pageInlineSize,i.blockSize(b));break}case"bounds":{v=i.toRect(i.inlineStart(l),i.blockStart(b),i.inlineSize(l),i.blockSize(b));break}default:v=i.toRect(i.inlineStart(b),i.blockStart(b),i.inlineSize(b),i.blockSize(b))}a.push(v)}}const g=[`M0 0 H${o} V${r} H0 Z`,...a.map(d=>{const u=(d.left+i.xDocOffset)*e,m=(d.top+i.yDocOffset)*e,p=(d.right+i.xDocOffset)*e,n=(d.bottom+i.yDocOffset)*e;return`M${u} ${m} H${p} V${n} H${u} Z`})].join(" "),f="http://www.w3.org/2000/svg";if(!this.maskSvg){this.shadowRoot||(this.shadowHost=this.wnd.document.createElement("div"),this.shadowHost.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none",this.wnd.document.body.appendChild(this.shadowHost),this.shadowRoot=this.shadowHost.attachShadow({mode:"open"})),this.maskSvg=this.wnd.document.createElementNS(f,"svg"),this.maskSvg.style.cssText=`position:absolute;top:0;left:0;width:${o}px;height:${r}px;pointer-events:none;z-index:9999`,this.maskSvg.dataset.readium="true";const d=this.wnd.document.createElementNS(f,"defs"),u=this.wnd.document.createElementNS(f,"clipPath"),m=`${this.id}-mask-clip`;u.setAttribute("id",m),u.setAttribute("clipPathUnits","userSpaceOnUse");const p=this.wnd.document.createElementNS(f,"path");p.setAttribute("clip-rule","evenodd"),u.appendChild(p),d.appendChild(u),this.maskSvg.appendChild(d);const n=this.wnd.document.createElementNS(f,"rect");n.setAttribute("id",`${this.id}-mask-rect`),n.setAttribute("clip-path",`url(#${m})`),n.style.pointerEvents="none",this.maskSvg.appendChild(n),this.shadowRoot.appendChild(this.maskSvg)}this.maskSvg.style.width=`${o}px`,this.maskSvg.style.height=`${r}px`;const w=this.maskSvg.querySelector("path");w&&w.setAttribute("d",g);const h=this.maskSvg.querySelector("rect");if(h){const u=t[0].decoration.style.tint,m=u??this.getBackgroundColor()??T(c.Mask),p=u?"1":"0.5";h.setAttribute("x","0"),h.setAttribute("y","0"),h.setAttribute("width",String(o)),h.setAttribute("height",String(r)),h.setAttribute("fill",m),h.setAttribute("fill-opacity",p)}}injectCustomStylesheet(t){const i=`${this.id}-custom-style`;let e=this.wnd.document.getElementById(i);e||(e=this.wnd.document.createElement("style"),e.id=i,e.dataset.readium="true",this.wnd.document.head.appendChild(e)),e.innerHTML=t}clearContainer(){if(this.experimentalHighlights){const t=this.wnd.CSS.highlights;for(const i of this._tintSubKeys.values())t.delete(i);this._tintSubKeys.clear(),this._subKeyCounter=0}this.wnd.document.getElementById(`${this.id}-custom-style`)?.remove(),this.container&&(this.container.remove(),this.container=void 0)}}const C=class C extends N{constructor(){super(...arguments),this.resizeFrame=0,this.lastGroupId=0,this.groups=new Map,this.handleResizer=this.handleResize.bind(this)}cleanup(){this.groups.forEach(t=>t.destroy()),this.groups.clear()}updateHighlightStyles(){this.groups.forEach(t=>{t.requestLayout()})}handleResize(){this.wnd.clearTimeout(this.resizeFrame),this.resizeFrame=this.wnd.setTimeout(()=>{this.groups.forEach(t=>{t.experimentalHighlights||t.requestLayout()})},50)}mount(t,i){return this.wnd=t,i.register("decorate",C.moduleName,(e,s)=>{const o=e;(o.action==="add"||o.action==="update")&&o.decoration.locator&&(o.decoration.locator=P.deserialize(o.decoration.locator)),this.groups.has(o.group)||this.groups.set(o.group,new Z(t,i,`readium-decoration-${this.lastGroupId++}`,o.group));const r=this.groups.get(o.group);switch(o.action){case"add":r?.add(o.decoration);break;case"remove":r?.remove(o.decoration.id);break;case"clear":r?.clear();break;case"update":r?.update(o.decoration);break}s(!0)}),i.register("decoration_activatable",C.moduleName,(e,s)=>{const o=e,r=this.groups.get(o.group);r&&(r.activatable=o.activatable),s(!0)}),i.register("decoration_hoverable",C.moduleName,(e,s)=>{const o=e,r=this.groups.get(o.group);r&&(r.hoverable=o.hoverable),s(!0)}),this.resizeObserver=new ResizeObserver(()=>t.requestAnimationFrame(()=>this.handleResize())),this.resizeObserver.observe(t.document.documentElement),t.addEventListener("orientationchange",this.handleResizer),t.addEventListener("resize",this.handleResizer),this.styleObserver=new MutationObserver(e=>{e.some(o=>o.type==="attributes"&&o.attributeName==="style"&&o.oldValue!==o.target.getAttribute("style"))&&this.updateHighlightStyles()}),this.styleObserver.observe(t.document.documentElement,{attributes:!0,attributeFilter:["style"],attributeOldValue:!0}),i.log("Decorator Mounted"),!0}unmount(t,i){return t.removeEventListener("orientationchange",this.handleResizer),t.removeEventListener("resize",this.handleResizer),i.unregisterAll(C.moduleName),this.resizeObserver.disconnect(),this.styleObserver.disconnect(),this.cleanup(),i.log("Decorator Unmounted"),!0}};C.moduleName="decorator";let A=C;export{G as DecorationLayout,c as DecorationStyleType,X as DecorationWidth,A as Decorator};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class l{}export{l as Module};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ColumnSnapper as e}from"./snapper/ColumnSnapper.js";import{ScrollSnapper as o}from"./snapper/ScrollSnapper.js";import{WebPubSnapper as p}from"./snapper/WebPubSnapper.js";import{Peripherals as t}from"./Peripherals.js";import{ReflowableSetup as i}from"./setup/ReflowableSetup.js";import{FixedSetup as a}from"./setup/FixedSetup.js";import{Decorator as m}from"./Decorator.js";import{WebPubSetup as l}from"./setup/WebPubSetup.js";import{PrintProtector as n}from"../protection/PrintProtector.js";import{CJKVerticalSnapper as s}from"./snapper/CJKVerticalSnapper.js";const h=["fixed_setup","decorator","peripherals","print_protection"],x=["reflowable_setup","decorator","peripherals","column_snapper","scroll_snapper","cjk_vertical_snapper","print_protection"],W=["webpub_setup","webpub_snapper","decorator","peripherals","print_protection"],C=new Map([a,i,l,p,t,m,e,o,s,n].map(r=>[r.moduleName,r]));export{h as FXLModules,C as ModuleLibrary,x as ReflowableModules,W as WebPubModules};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Module as c}from"./Module.js";import{nearestInteractiveElement as h}from"../helpers/dom.js";import{BulkCopyProtector as u}from"../protection/BulkCopyProtector.js";import{SelectionAnalyzer as p}from"../protection/SelectionAnalyzer.js";import{BULK_COPY_CONFIG as m,SELECTION_ANALYZER_CONFIG as g}from"../protection/config.js";import{KeyCombinationManager as y}from"../keyboard/KeyCombinationManager.js";const r=class r extends c{constructor(){super(...arguments),this.configApplied=!1,this.cleanupCallbacks=[],this.pointerMoved=!1,this.isContextMenuEnabled=!1,this.isDragAndDropEnabled=!1,this.isSelectionMonitoringEnabled=!1,this.isBulkCopyProtectionEnabled=!1,this.selectionAnalyzer=null,this.currentSelection=null,this.bulkCopyProtector=null,this.keyManager=new y,this.keyDownHandler=null,this.preventBulkCopy=e=>{if(!this.isBulkCopyProtectionEnabled||!this.bulkCopyProtector)return!0;if(!this.bulkCopyProtector.shouldAllowCopy(e)){e.preventDefault();const t=this.wnd.getSelection(),n=t?.toString()||"",i=(n?t?.getRangeAt(0)?.getClientRects():null)?.[0],s={type:"bulk_copy",timestamp:Date.now(),clipboardTypes:e.clipboardData?.types?[...e.clipboardData.types]:[],selectedText:i?{text:n,x:i.x,y:i.y,width:i.width,height:i.height}:void 0,selectionLength:n.length,targetFrameSrc:this.wnd.location.href};return this.comms?.send("content_protection",s),!1}return!0},this.handleSelection=e=>{if(!this.isSelectionMonitoringEnabled||!this.wnd||!this.selectionAnalyzer)return;const t=this.wnd.getSelection();if(t){if(this.currentSelection=t.toString(),this.selectionAnalyzer.analyze(t)&&this.currentSelection){const o=this.wnd.getSelection(),i=o?.toString()||"",a=(i&&o?.rangeCount?o.getRangeAt(0)?.getClientRects():null)?.[0],d={type:"suspicious_selection",timestamp:Date.now(),selectionLength:i.length,selectedText:{text:i,x:a?.x??0,y:a?.y??0,width:a?.width??0,height:a?.height??0},eventType:e?.type||"selectionchange",targetFrameSrc:this.wnd.location.href};this.comms?.send("content_protection",d)}}else this.currentSelection=null},this.onDragOver=e=>{this.isDragAndDropEnabled&&(e.preventDefault(),e.stopPropagation())},this.onDragStart=e=>{if(this.isDragAndDropEnabled){e.preventDefault();const t={type:"drag_detected",timestamp:Date.now(),dataTransferTypes:e.dataTransfer?.types?[...e.dataTransfer.types]:[],targetFrameSrc:this.wnd.location.href};return this.comms?.send("content_protection",t),!1}else return!0},this.onDrop=e=>{if(this.isDragAndDropEnabled){e.preventDefault();const t=e.dataTransfer,n={type:"drop_detected",timestamp:Date.now(),dataTransferTypes:t?.types?[...t.types]:[],fileCount:t?.files?.length||0,targetFrameSrc:this.wnd.location.href};return this.comms?.send("content_protection",n),!1}else return!0},this.onContext=e=>{if(this.isContextMenuEnabled){e.preventDefault();const t=this.wnd.getSelection(),n=t?.toString()||"",i=(n&&t?.rangeCount?t.getRangeAt(0)?.getClientRects():null)?.[0],s={timestamp:Date.now(),clientX:e.clientX,clientY:e.clientY,...i&&{selectedText:{text:n,x:i.x,y:i.y,width:i.width,height:i.height}},targetFrameSrc:this.wnd.location.href};this.comms?.send("context_menu",s)}},this.onPointerUp=this.onPointUp.bind(this),this.onPointerMove=this.onPointMove.bind(this),this.onPointerDown=this.onPointDown.bind(this),this.onClicker=this.onClick.bind(this)}addContextMenuPrevention(){this.isContextMenuEnabled||!this.wnd||(this.wnd.document.addEventListener("contextmenu",this.onContext),this.isContextMenuEnabled=!0)}removeContextMenuPrevention(){!this.isContextMenuEnabled||!this.wnd||(this.wnd.document.removeEventListener("contextmenu",this.onContext),this.isContextMenuEnabled=!1)}addDragAndDropPrevention(){this.isDragAndDropEnabled||!this.wnd||(this.wnd.document.addEventListener("dragstart",this.onDragStart),this.wnd.document.addEventListener("dragover",this.onDragOver),this.wnd.document.addEventListener("drop",this.onDrop),this.isDragAndDropEnabled=!0)}removeDragAndDropPrevention(){!this.isDragAndDropEnabled||!this.wnd||(this.wnd.document.removeEventListener("dragstart",this.onDragStart),this.wnd.document.removeEventListener("dragover",this.onDragOver),this.wnd.document.removeEventListener("drop",this.onDrop),this.isDragAndDropEnabled=!1)}enableKeyboardPeripherals(e=[]){this.disableKeyboardPeripherals();const t=n=>{this.comms?.send("keyboard_peripherals",n)};this.keyDownHandler=this.keyManager.createUnifiedHandler(this.wnd.location.href,e,t,this.wnd),this.wnd&&this.wnd.document.addEventListener("keydown",this.keyDownHandler,{capture:!0})}disableKeyboardPeripherals(){this.wnd&&this.keyDownHandler&&(this.wnd.document.removeEventListener("keydown",this.keyDownHandler,{capture:!0}),this.keyDownHandler=null)}addBulkCopyProtection(e={}){if(this.isBulkCopyProtectionEnabled||!this.wnd)return;const t=m,n=e?{...t,...e}:t;this.bulkCopyProtector=new u(this.wnd,n),this.wnd.document.addEventListener("copy",this.preventBulkCopy,!0),this.wnd.document.addEventListener("cut",this.preventBulkCopy,!0),this.isBulkCopyProtectionEnabled=!0}removeBulkCopyProtection(){!this.isBulkCopyProtectionEnabled||!this.wnd||(this.wnd.document.removeEventListener("copy",this.preventBulkCopy,!0),this.wnd.document.removeEventListener("cut",this.preventBulkCopy,!0),this.bulkCopyProtector?.destroy(),this.bulkCopyProtector=null,this.isBulkCopyProtectionEnabled=!1)}addSelectionMonitoring(e){if(this.isSelectionMonitoringEnabled||!this.wnd)return;const t=e||g;this.selectionAnalyzer=new p(t),this.wnd.document.addEventListener("selectionchange",this.handleSelection),this.isSelectionMonitoringEnabled=!0}removeSelectionMonitoring(){!this.isSelectionMonitoringEnabled||!this.wnd||(this.wnd.document.removeEventListener("selectionchange",this.handleSelection),this.selectionAnalyzer?.clear(),this.selectionAnalyzer=null,this.isSelectionMonitoringEnabled=!1)}onPointUp(e){const t=this.wnd.getSelection();if(t&&t.toString()?.length>0){const o=t.getRangeAt(0)?.getClientRects();if(!o||o.length===0)return;const i=o[0],s={text:t.toString(),x:i.x,y:i.y,width:i.width,height:i.height,targetFrameSrc:this.wnd?.location?.href};this.comms.send("text_selected",s)}if(this.pointerMoved){this.pointerMoved=!1;return}if(!t?.isCollapsed||!e.isPrimary)return;const n=this.wnd.devicePixelRatio;e.preventDefault(),this.comms.send(e.pointerType==="touch"?"tap":"click",{defaultPrevented:e.defaultPrevented,x:e.clientX*n,y:e.clientY*n,targetFrameSrc:this.wnd.location.href,targetElement:e.target.outerHTML,interactiveElement:h(e.target)?.outerHTML,cssSelector:this.wnd._readium_cssSelectorGenerator.getCssSelector(e.target)}),this.pointerMoved=!1}onPointMove(e){if(e.movementY!==void 0&&e.movementX!==void 0){(Math.abs(e.movementX)>1||Math.abs(e.movementY)>1)&&(this.pointerMoved=!0);return}this.pointerMoved=!0}onPointDown(){this.pointerMoved=!1}onClick(e){if(e.preventDefault(),!e.isTrusted){const t=new PointerEvent("pointerup",{isPrimary:!0,pointerType:"mouse",clientX:e.clientX,clientY:e.clientY});Object.defineProperty(t,"target",{writable:!1,value:e.target}),Object.defineProperty(t,"defaultPrevented",{writable:!1,value:e.defaultPrevented}),this.onPointUp(t)}}registerProtectionHandlers(){this.comms?.register("peripherals_protection",r.moduleName,(e,t)=>{const n=e;if(!this.configApplied){if(this.configApplied=!0,n.monitorSelection){const o=typeof n.monitorSelection=="boolean"?void 0:n.monitorSelection;this.addSelectionMonitoring(o),this.comms?.log("Selection monitoring enabled")}typeof n.protectCopy=="object"?(this.addBulkCopyProtection({enabled:!0,...n.protectCopy}),this.comms?.log("Copy protection enabled (limited)")):n.protectCopy===!0&&(this.addBulkCopyProtection({enabled:!0,maxSelectionPercent:0,minThreshold:0,absoluteMaxChars:0}),this.comms?.log("Copy protection enabled")),n.disableContextMenu&&(this.addContextMenuPrevention(),this.comms?.log("Context menu protection enabled")),n.disableDragAndDrop&&(this.addDragAndDropPrevention(),this.comms?.log("Drag and drop protection enabled"))}t(!0)}),this.comms?.register("unfocus",r.moduleName,(e,t)=>{this.disableKeyboardPeripherals(),t(!0)}),this.comms?.register("keyboard_peripherals",r.moduleName,(e,t)=>{const n=e;n&&n.length>0&&(this.enableKeyboardPeripherals(n),this.comms?.log(`Keyboard peripherals enabled: ${n.map(o=>o.type).join(", ")}`)),t(!0)})}mount(e,t){return this.wnd=e,this.comms=t,this.registerProtectionHandlers(),e.document.addEventListener("pointerdown",this.onPointerDown),e.document.addEventListener("pointerup",this.onPointerUp),e.document.addEventListener("pointermove",this.onPointerMove),e.document.addEventListener("click",this.onClicker),t.log("Peripherals Mounted"),!0}unmount(e,t){return this.removeBulkCopyProtection(),this.removeSelectionMonitoring(),this.removeContextMenuPrevention(),this.removeDragAndDropPrevention(),this.disableKeyboardPeripherals(),this.cleanupCallbacks.forEach(n=>n()),this.cleanupCallbacks=[],e.document.removeEventListener("pointerdown",this.onPointerDown),e.document.removeEventListener("pointerup",this.onPointerUp),e.document.removeEventListener("pointermove",this.onPointerMove),e.document.removeEventListener("click",this.onClicker),t.unregisterAll(r.moduleName),this.configApplied=!1,t.log("Peripherals Unmounted"),!0}};r.moduleName="peripherals";let l=r;export{l as Peripherals};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{Setup as l}from"./Setup.js";import{setProperty as d,removeProperty as m}from"../../helpers/css.js";import{deselect as g}from"../../helpers/dom.js";const n="readium-fixed-style",o=class o extends l{mount(e,t){if(!super.mount(e,t))return!1;e.navigator.epubReadingSystem&&(e.navigator.epubReadingSystem.layoutStyle="paginated");const i=e.document.createElement("style");return i.id=n,i.dataset.readium="true",i.textContent=`
|
|
2
|
+
html, body {
|
|
3
|
+
text-size-adjust: none;
|
|
4
|
+
-ms-text-size-adjust: none;
|
|
5
|
+
-webkit-text-size-adjust: none;
|
|
6
|
+
-moz-text-size-adjust: none;
|
|
7
|
+
|
|
8
|
+
/* Fight Safari pinches */
|
|
9
|
+
touch-action: none !important;
|
|
10
|
+
min-height: 100%;
|
|
11
|
+
|
|
12
|
+
/*cursor: var() TODO*/
|
|
13
|
+
}`,e.document.head.appendChild(i),t.register("set_property",o.moduleName,(u,r)=>{const a=u;d(e,a[0],a[1]),r(!0)}),t.register("remove_property",o.moduleName,(u,r)=>{m(e,u),r(!0)}),t.register("first_visible_locator",o.moduleName,(u,r)=>r(!1)),t.register("unfocus",o.moduleName,(u,r)=>{g(e),r(!0)}),t.register(["focus","go_next","go_prev","go_id","go_end","go_start","go_text","go_progression"],o.moduleName,(u,r)=>r(!0)),t.register("activate",o.moduleName,(u,r)=>{this.unblock(e),r(!0)}),t.log("FixedSetup Mounted"),!0}unmount(e,t){return t.unregisterAll(o.moduleName),e.document.getElementById(n)?.remove(),t.log("FixedSetup Unmounted"),super.unmount(e,t)}};o.moduleName="fixed_setup";let s=o;export{s as FixedSetup};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Setup as d}from"./Setup.js";import{setProperty as a,getProperties as h,updateProperties as l,removeProperty as m}from"../../helpers/css.js";const s="readium-viewport",i=class i extends d{onViewportWidthChanged(e){const t=e.target;a(t,"--RS__viewportWidth",`${t.innerWidth}px`)}mount(e,t){if(!super.mount(e,t))return!1;const n=e.document.createElement("meta");return n.dataset.readium="true",n.setAttribute("name","viewport"),n.setAttribute("id",s),n.setAttribute("content","width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no"),e.document.head.appendChild(n),e.addEventListener("orientationchange",this.onViewportWidthChanged),e.addEventListener("resize",this.onViewportWidthChanged),this.onViewportWidthChanged({target:e}),t.register("get_properties",i.moduleName,(o,r)=>{h(e),r(!0)}),t.register("update_properties",i.moduleName,(o,r)=>{o["--RS__viewportWidth"]=`${e.innerWidth}px`,l(e,o),r(!0)}),t.register("set_property",i.moduleName,(o,r)=>{const u=o;a(e,u[0],u[1]),r(!0)}),t.register("remove_property",i.moduleName,(o,r)=>{m(e,o),r(!0)}),t.register("activate",i.moduleName,(o,r)=>{this.unblock(e),r(!0)}),t.log("ReflowableSetup Mounted"),!0}unmount(e,t){return t.unregisterAll(i.moduleName),e.document.head.querySelector(`#${s}`)?.remove(),e.removeEventListener("orientationchange",this.onViewportWidthChanged),t.log("ReflowableSetup Unmounted"),super.unmount(e,t)}};i.moduleName="reflowable_setup";let p=i;export{p as ReflowableSetup};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Module as l}from"../Module.js";const i=class i extends l{constructor(){super(...arguments),this.mediaPlayingCount=0,this.allAnimations=new Set}wndOnErr(e){this.comms?.send("error",{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno})}unblock(e){for(e._readium_blockEvents=!1;e._readium_blockedEvents?.length>0;){const t=e._readium_blockedEvents.shift();switch(t[0]){case 0:Reflect.apply(t[1],t[2],t[3]);break;case 1:const a=t[1],n=t[2];e.removeEventListener(a.type,e._readium_eventBlocker,!0);const s=new Event(a.type,{bubbles:a.bubbles,cancelable:a.cancelable});n?n.dispatchEvent(s):e.dispatchEvent(s);break}}}onMediaPlayEvent(){this.mediaPlayingCount++,this.comms?.send("media_play",this.mediaPlayingCount)}onMediaPauseEvent(){this.mediaPlayingCount>0&&this.mediaPlayingCount--,this.comms?.send("media_pause",this.mediaPlayingCount)}pauseAllMedia(e){const t=e.document.querySelectorAll("audio,video");for(let a=0;a<t.length;a++)t[a].pause()}mount(e,t){this.comms=t,e.addEventListener("error",this.wndOnErr,!1),Reflect.defineProperty(e.navigator,"epubReadingSystem",{value:{name:"readium-ts-toolkit",version:"2.6.1",hasFeature:(n,s="")=>{switch(n){case"dom-manipulation":return!0;case"layout-changes":return!0;case"touch-events":return!0;case"mouse-events":return!0;case"keyboard-events":return!0;case"spine-scripting":return!0;case"embedded-web-content":return!0;default:return!1}}},writable:!1}),"getAnimations"in e.document&&e.document.getAnimations().forEach(n=>{n.cancel(),this.allAnimations.add(n)}),t.register("activate",i.moduleName,(n,s)=>{this.allAnimations.forEach(r=>{r.cancel(),r.play()}),s(!0)}),t.register("unfocus",i.moduleName,(n,s)=>{this.pauseAllMedia(e),this.allAnimations.forEach(r=>r.pause()),s(!0)});const a=e.document.querySelectorAll("audio,video");for(let n=0;n<a.length;n++){const s=a[n];s.addEventListener("play",this.onMediaPlayEvent,{passive:!0}),s.addEventListener("pause",this.onMediaPauseEvent,{passive:!0})}return t.log("Setup Mounted"),!0}unmount(e,t){return e.removeEventListener("error",this.wndOnErr),e.removeEventListener("play",this.onMediaPlayEvent),e.removeEventListener("pause",this.onMediaPauseEvent),this.allAnimations.forEach(a=>a.cancel()),this.allAnimations.clear(),t.log("Setup Unmounted"),!0}};i.moduleName="setup";let o=i;export{o as Setup};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Module as n}from"../Module.js";import{getProperties as l,updateProperties as a,setProperty as p,removeProperty as m}from"../../helpers/css.js";const o=class o extends n{wndOnErr(e){this.comms?.send("error",{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno})}mount(e,r){return this.comms=r,e.addEventListener("error",this.wndOnErr,!1),r.register("get_properties",o.moduleName,(u,t)=>{l(e),t(!0)}),r.register("update_properties",o.moduleName,(u,t)=>{a(e,u),t(!0)}),r.register("set_property",o.moduleName,(u,t)=>{const s=u;p(e,s[0],s[1]),t(!0)}),r.register("remove_property",o.moduleName,(u,t)=>{m(e,u),t(!0)}),r.register("activate",o.moduleName,(u,t)=>{t(!0)}),r.log("WebPubSetup Mounted"),!0}unmount(e,r){return r.unregisterAll(o.moduleName),e.removeEventListener("error",this.wndOnErr),r.log("WebPubSetup Unmounted"),!0}};o.moduleName="webpub_setup";let i=o;export{i as WebPubSetup};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{LocatorText as u,Locator as m,LocatorLocations as g}from"@readium/shared";import{deselect as a,findFirstVisibleLocator as f}from"../../helpers/dom.js";import{Snapper as p}from"./Snapper.js";import{rangeFromLocator as b}from"../../helpers/locator.js";import{isVerticalLR as L,forceWebkitRecalc as S}from"../../helpers/document.js";import{PatternAnalyzer as v}from"../../protection/PatternAnalyzer.js";import{SCROLL_PROTECTION_CONFIG as y}from"../../protection/config.js";const h="readium-cjk-vertical-snapper-style",l=class l extends p{constructor(){super(...arguments),this.patternAnalyzer=null,this.lastScrollTime=0,this.isScrollProtectionEnabled=!1,this.initialScrollHandled=!1,this.isScrolling=!1,this.lastScrollLeft=0,this.isResizing=!1,this.resizeDebounce=null,this.verticalLR=!1,this.handleScroll=i=>{if(this.comms.ready&&!this.isResizing){if(!this.initialScrollHandled){this.lastScrollLeft=Math.abs(this.doc().scrollLeft),this.initialScrollHandled=!0,this.reportProgress();return}this.isScrolling||(this.isScrolling=!0,this.wnd.requestAnimationFrame(()=>{this.reportProgress();const r=Math.abs(this.doc().scrollLeft),o=r-this.lastScrollLeft;if(this.lastScrollLeft=r,this.isScrollProtectionEnabled&&Math.abs(o)>5){const e=Date.now(),t=e-(this.lastScrollTime||e);if(this.patternAnalyzer&&this.patternAnalyzer.analyze(o>0?"down":"up",Math.abs(o),t)){const n=i.target&&"tagName"in i.target?{tagName:i.target.tagName}:null;this.comms?.send("content_protection",{type:"suspicious_scrolling",timestamp:Date.now(),scrollDelta:o,scrollDirection:o>0?"left":"right",targetElement:n})}this.lastScrollTime=e}this.comms.send("scroll",o),this.isScrolling=!1}))}}}doc(){return this.wnd.document.scrollingElement}scrollable(){return Math.max(0,this.doc().scrollWidth-this.wnd.innerWidth)}hasScrolledPast(i){const r=i.getBoundingClientRect();return this.verticalLR?r.right<=0:r.left>=this.wnd.innerWidth}reportProgress(i){if(!this.comms.ready)return;const r=this.doc().scrollWidth,o=this.wnd.innerWidth,e=Math.max(1,r-o),t=Math.abs(this.doc().scrollLeft),s=Math.max(0,Math.min(1,t/e)),n=Math.max(0,Math.min(1,(t+o)/r));this.comms.send("progress",{start:s,end:n,fragmentId:i!==void 0?i:this.currentTimelineFragment()})}enableScrollProtection(){this.patternAnalyzer||(this.patternAnalyzer=new v(y),this.isScrollProtectionEnabled=!0,this.comms?.log("Scroll protection enabled"))}mount(i,r){this.wnd=i,this.comms=r,this.setupTimelineObserver(),this.initialScrollHandled=!1,this.lastScrollLeft=0,this.isResizing=!1,this.verticalLR=L(i),this.resizeDebounce&&(this.wnd.clearTimeout(this.resizeDebounce),this.resizeDebounce=null),i.navigator.epubReadingSystem&&(i.navigator.epubReadingSystem.layoutStyle="scrolling");const o=i.document.createElement("style");return o.dataset.readium="true",o.id=h,o.textContent=`
|
|
2
|
+
* {
|
|
3
|
+
scrollbar-width: none;
|
|
4
|
+
}
|
|
5
|
+
body::-webkit-scrollbar {
|
|
6
|
+
display: none;
|
|
7
|
+
}
|
|
8
|
+
html {
|
|
9
|
+
overflow-x: auto !important;
|
|
10
|
+
overflow-y: hidden !important;
|
|
11
|
+
}
|
|
12
|
+
`,i.document.head.appendChild(o),this.resizeObserver=new ResizeObserver(()=>{this.resizeDebounce&&this.wnd.clearTimeout(this.resizeDebounce),this.isResizing=!0,this.resizeDebounce=this.wnd.setTimeout(()=>{this.isResizing=!1,this.resizeDebounce=null,this.reportProgress()},50)}),this.resizeObserver.observe(i.document.body),i.addEventListener("scroll",this.handleScroll,{passive:!0}),r.register("force_webkit_recalc",l.moduleName,()=>{S(this.wnd);const e=this.doc().scrollLeft;this.verticalLR?this.doc().scrollLeft=e>1?e-1:e+1:this.doc().scrollLeft=e<-1?e+1:e-1,this.doc().scrollLeft=e}),r.register("go_progression",l.moduleName,(e,t)=>{const s=e;if(s<0||s>1){r.send("error",{message:"go_progression must be given a position from 0.0 to 1.0"}),t(!1);return}this.wnd.requestAnimationFrame(()=>{const n=this.scrollable()*s;this.doc().scrollLeft=this.verticalLR?n:-n,this.reportProgress(this.fragmentFromGeometry()),a(this.wnd),t(!0)})}),r.register("go_id",l.moduleName,(e,t)=>{const s=i.document.getElementById(e);if(!s){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollLeft+=s.getBoundingClientRect().left-i.innerWidth/2;const n=e;this.reportProgress(this.timelineEntries.has(n)?n:this.nearestPrecedingTimelineEntry(s)),a(this.wnd),t(!0)})}),r.register("go_text",l.moduleName,(e,t)=>{let s;Array.isArray(e)&&(e.length>1&&(s=e[1]),e=e[0]);const n=u.deserialize(e),c=b(this.wnd.document,new m({href:i.location.href,type:"text/html",text:n,locations:s?new g({otherLocations:new Map([["cssSelector",s]])}):void 0}));if(!c){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollLeft+=c.getBoundingClientRect().left-i.innerWidth/2,this.reportProgress(this.nearestPrecedingTimelineEntry(c.startContainer)),a(this.wnd),t(!0)})}),r.register("go_start",l.moduleName,(e,t)=>{if(this.doc().scrollLeft===0)return t(!1);this.doc().scrollLeft=0,this.reportProgress(this.firstFragmentIfReached()),t(!0)}),r.register("go_end",l.moduleName,(e,t)=>{if(Math.abs(this.doc().scrollLeft)===this.scrollable())return t(!1);this.doc().scrollLeft=this.verticalLR?this.scrollable():-this.scrollable(),this.reportProgress(this.sortedFragmentIds[this.sortedFragmentIds.length-1]),t(!0)}),r.register(["go_next","go_prev"],l.moduleName,(e,t)=>t(!1)),r.register("unfocus",l.moduleName,(e,t)=>{a(this.wnd),t(!0)}),r.register("scroll_protection",l.moduleName,(e,t)=>{this.enableScrollProtection(),t(!0)}),r.register("focus",l.moduleName,(e,t)=>{this.reportProgress(),t(!0)}),r.register("first_visible_locator",l.moduleName,(e,t)=>{const s=f(i,!0);this.comms.send("first_visible_locator",s.serialize()),t(!0)}),r.register("timeline_entries",l.moduleName,(e,t)=>{this.updateTimelineEntries(Array.isArray(e)?e:[],i),t(!0)}),r.log("CJKVerticalSnapper Mounted"),!0}unmount(i,r){return r.unregisterAll(l.moduleName),this.resizeObserver.disconnect(),this.handleScroll&&i.removeEventListener("scroll",this.handleScroll),i.document.getElementById(h)?.remove(),this.patternAnalyzer&&(this.patternAnalyzer.clear(),this.patternAnalyzer=null,this.isScrollProtectionEnabled=!1),this.timelineObserver?.disconnect(),this.timelineObserver=null,this.visibleFragmentIds.clear(),this.timelineEntries.clear(),r.log("CJKVerticalSnapper Unmounted"),!0}};l.moduleName="cjk_vertical_snapper";let d=l;export{d as CJKVerticalSnapper};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import{Snapper as C}from"./Snapper.js";import{getColumnCountPerScreen as x,isRTL as A,appendVirtualColumnIfNeeded as W}from"../../helpers/document.js";import{styleChangeAffectsLayout as P}from"../../helpers/css.js";import{easeInOutQuad as N}from"../../helpers/animation.js";import{LocatorText as F,Locator as M,LocatorLocations as z}from"@readium/shared";import{rangeFromLocator as _}from"../../helpers/locator.js";import{deselect as m,findFirstVisibleLocator as X}from"../../helpers/dom.js";import{PatternAnalyzer as q}from"../../protection/PatternAnalyzer.js";const T="readium-column-snapper-style",w=200,h=class h extends C{constructor(){super(...arguments),this.isSnapProtectionEnabled=!1,this.patternAnalyzer=null,this.lastTurnTime=0,this.rtl=!1,this.shakeTimeout=0,this.snappingCancelled=!1,this.alreadyScrollLeft=0,this.overscroll=0,this.cachedScrollWidth=0,this.touchState=0,this.startingX=void 0,this.endingX=void 0,this.onTouchStarter=this.onTouchStart.bind(this),this.onTouchEnder=this.onTouchEnd.bind(this),this.onWidthChanger=this.onWidthChange.bind(this),this.onTouchMover=this.onTouchMove.bind(this)}doc(){return this.wnd.document.scrollingElement}scrollOffset(){const t=this.doc().scrollLeft;return t!==0?t:this.alreadyScrollLeft}snapOffset(t){const e=t+(this.rtl?-1:1);return e-e%this.wnd.innerWidth}snapNormOffset(t){const e=t+1;return e-e%this.wnd.innerWidth}normScroll(){const t=this.doc().scrollLeft||this.alreadyScrollLeft;return this.rtl?Math.abs(t):Math.max(0,this.wnd.scrollX>0?this.wnd.scrollX:t)}hasScrolledPast(t){const e=t.getBoundingClientRect();return this.rtl?e.left>=this.wnd.innerWidth:e.right<=0}currentTimelineFragment(){if(this.timelineEntries.size===0)return;const t=this.wnd.innerWidth;let e;for(const o of this.sortedFragmentIds){const l=this.timelineEntries.get(o).getBoundingClientRect();if(this.rtl?l.right>0:l.left<t)e=o;else break}return e}reportProgress(t){const e=this.cachedScrollWidth,o=this.wnd.innerWidth,n=this.normScroll(),l=Math.max(1,e-o),r=Math.max(0,Math.min(1,n/l)),s=Math.max(0,Math.min(1,(n+o)/e));this.comms.send("progress",{start:r,end:s,fragmentId:t!==void 0?t:this.currentTimelineFragment()})}shake(){if(this.overscroll!==0||this.shakeTimeout!==0)return;const t=this.doc(),e=this.normScroll()<5,o=this.rtl?e?"readium-bounce-r":"readium-bounce-l":"readium-bounce-r";t.classList.add(o);const n=this.scrollOffset();this.shakeTimeout=this.wnd.setTimeout(()=>{t.classList.remove(o),this.shakeTimeout=0,this.doc().scrollLeft=n},150)}takeOverSnap(){this.snappingCancelled=!0,this.clearTouches();const t=this.doc();this.overscroll=t.style.transform?.length>12?parseFloat(t.style.transform.slice(12).split("px")[0]):0}snapCurrentOffset(t=!1,e=!1){const o=this.doc(),n=x(this.wnd),l=this.cachedScrollWidth-this.wnd.innerWidth,r=Math.min(Math.max(0,this.normScroll()),l),s=this.dragOffset(),i=this.rtl?-s:s,d=this.wnd.innerWidth/3*(i>0?2:1),a=Math.min(l,Math.max(0,this.snapNormOffset(r+d))),c=this.rtl?-a:a,u=this.rtl?-r:r,O=c>u?"right":"left";if(this.checkSuspiciousSnap(O,Math.abs(c-u)),t&&c!==u){this.snappingCancelled=!1;const L=(p,f,g,S)=>g>S?f:p+(f-p)*N(g/S),v=w*n;let b;const y=p=>{if(this.snappingCancelled)return;b||(b=p);const f=p-b,g=L(this.overscroll,0,f,v),S=L(u,c,f,v);o.scrollLeft=S,this.overscroll!==0&&(o.style.transform=`translate3d(${-g}px, 0px, 0px)`),f<v?this.wnd.requestAnimationFrame(y):(this.clearTouches(),o.style.removeProperty("transform"),o.scrollLeft=c,e||this.reportProgress())};this.wnd.requestAnimationFrame(y)}else o.style.removeProperty("transform"),this.wnd.requestAnimationFrame(()=>{o.scrollLeft=c,this.clearTouches(),e||this.reportProgress()})}dragOffset(){return(this.startingX??0)-(this.endingX??0)}clearTouches(){this.startingX=void 0,this.endingX=void 0,this.overscroll=0}onTouchStart(t){switch(t.stopPropagation(),this.takeOverSnap(),t.touches.length){case 1:break;case 2:this.onTouchEnd(t);return;default:{this.onTouchEnd(t),this.comms.send("tap_more",t.touches.length);return}}this.startingX=t.touches[0].clientX,this.alreadyScrollLeft=this.doc().scrollLeft,this.touchState=1}onTouchEnd(t){if(this.touchState===2){const e=this.dragOffset(),o=this.normScroll(),n=this.cachedScrollWidth-this.wnd.innerWidth,l=this.rtl?-e:e;this.cachedScrollWidth<=this.wnd.innerWidth?(this.reportProgress(),l>5&&this.comms.send("no_more",void 0),l<-5&&this.comms.send("no_less",void 0)):o<5&&l<5?(this.alreadyScrollLeft=0,this.comms.send("no_less",void 0)):n-o<5&&l>5&&(this.alreadyScrollLeft=this.rtl?-n:n,this.comms.send("no_more",void 0)),this.snapCurrentOffset(!0),this.comms.send("swipe",e)}this.touchState=0}onWidthChange(){this.cachedScrollWidth=this.doc().scrollWidth,this.comms.ready&&this.snapCurrentOffset()}onTouchMove(t){if(this.touchState===0)return;this.touchState===1&&(this.touchState=2,m(this.wnd)),this.endingX=t.touches[0].clientX;const e=this.dragOffset(),o=this.alreadyScrollLeft+e,n=this.rtl?-(this.cachedScrollWidth-this.wnd.innerWidth):0,l=this.rtl?0:this.cachedScrollWidth-this.wnd.innerWidth;o<n?(this.overscroll=o,this.doc().style.transform=`translate3d(${-this.overscroll}px, 0px, 0px)`):o>l?(this.overscroll=o,this.doc().style.transform=`translate3d(${-o}px, 0px, 0px)`):(this.overscroll=0,this.doc().style.removeProperty("transform"),this.doc().scrollLeft=o)}enableSnapProtection(){this.patternAnalyzer||(this.patternAnalyzer=new q({maxVelocity:this.wnd.innerWidth,minVariance:.1,historySize:5,maxConsistentScrolls:3,minDirectionChanges:.3}),this.isSnapProtectionEnabled=!0,this.comms?.log("Snap protection enabled"))}checkSuspiciousSnap(t,e){if(!this.isSnapProtectionEnabled||!this.patternAnalyzer)return;const o=Date.now(),n=o-(this.lastTurnTime||o);this.lastTurnTime=o,this.patternAnalyzer.analyze(t,e,n)&&this.comms?.send("content_protection",{type:"suspicious_snapping",timestamp:Date.now(),event:null})}mount(t,e){if(this.wnd=t,this.comms=e,this.rtl=A(t),!super.mount(t,e))return!1;t.navigator.epubReadingSystem&&(t.navigator.epubReadingSystem.layoutStyle="paginated");const o=t.document.createElement("style");o.dataset.readium="true",o.id=T,o.textContent=`
|
|
2
|
+
@keyframes readium-bounce-l-animation {
|
|
3
|
+
0%, 100% {transform: translate3d(0, 0, 0);}
|
|
4
|
+
50% {transform: translate3d(-50px, 0, 0);}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@keyframes readium-bounce-r-animation {
|
|
8
|
+
0%, 100% {transform: translate3d(0, 0, 0);}
|
|
9
|
+
50% {transform: translate3d(50px, 0, 0);}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.readium-bounce-l {
|
|
13
|
+
animation: readium-bounce-l-animation 150ms ease-out 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.readium-bounce-r {
|
|
17
|
+
animation: readium-bounce-r-animation 150ms ease-out 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
html {
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body {
|
|
25
|
+
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
* {
|
|
29
|
+
scrollbar-width: none; /* for Firefox */
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body::-webkit-scrollbar {
|
|
33
|
+
display: none; /* for Chrome, Safari, and Opera */
|
|
34
|
+
}
|
|
35
|
+
`,t.document.head.appendChild(o),this.resizeObserver=new ResizeObserver(()=>{t.requestAnimationFrame(()=>{t&&W(t)}),this.onWidthChange()}),this.resizeObserver.observe(t.document.body),this.mutationObserver=new MutationObserver(r=>{for(const s of r)if(s.target===this.wnd.document.documentElement){const i=s.oldValue,d=s.target.getAttribute("style"),a=/transform\s*:\s*([^;]+)/,c=i?.match(a),u=d?.match(a);(!c&&!u&&P(i,d)||c&&!u||c&&u&&c[1]!==u[1])&&(t.requestAnimationFrame(()=>{t&&W(t)}),this.onWidthChange())}else t.requestAnimationFrame(()=>this.cachedScrollWidth=this.doc().scrollWidth)}),t.frameElement&&this.mutationObserver.observe(t.frameElement,{attributes:!0,attributeFilter:["style"]}),this.mutationObserver.observe(t.document,{attributes:!0,attributeFilter:["style"]}),this.mutationObserver.observe(t.document.documentElement,{attributes:!0,attributeFilter:["style"]}),e.register("scroll_protection",h.moduleName,(r,s)=>{this.enableSnapProtection(),s(!0)});const n=r=>{const s=this.doc().scrollLeft;return this.doc().scrollLeft=this.snapOffset(r),s!==this.doc().scrollLeft},l=r=>{const s=this.doc().scrollLeft,i=this.snapNormOffset(Math.max(0,Math.min(this.cachedScrollWidth-t.innerWidth,r)));return this.doc().scrollLeft=-i,s!==this.doc().scrollLeft};return t.addEventListener("orientationchange",this.onWidthChanger),t.addEventListener("resize",this.onWidthChanger),t.requestAnimationFrame(()=>this.cachedScrollWidth=this.doc().scrollWidth),e.register("go_progression",h.moduleName,(r,s)=>{const i=r;if(i<0||i>1){e.send("error",{message:"go_progression must be given a position from 0.0 to 1.0"}),s(!1);return}this.wnd.requestAnimationFrame(()=>{this.cachedScrollWidth=this.doc().scrollWidth;const a=(this.cachedScrollWidth-t.innerWidth)*i;this.rtl?this.doc().scrollLeft=-this.snapNormOffset(a):this.doc().scrollLeft=this.snapOffset(a),this.reportProgress(),m(this.wnd),s(!0)})}),e.register("go_id",h.moduleName,(r,s)=>{const i=t.document.getElementById(r);if(!i){s(!1);return}this.wnd.requestAnimationFrame(()=>{this.rtl?this.doc().scrollLeft=-this.snapNormOffset(i.getBoundingClientRect().left+t.scrollX):this.doc().scrollLeft=this.snapOffset(i.getBoundingClientRect().left+t.scrollX);const d=r;this.reportProgress(this.timelineEntries.has(d)?d:this.nearestPrecedingTimelineEntry(i)),m(this.wnd),s(!0)})}),e.register("go_text",h.moduleName,(r,s)=>{let i;Array.isArray(r)&&(r.length>1&&(i=r[1]),r=r[0]);const d=F.deserialize(r),a=_(this.wnd.document,new M({href:t.location.href,type:"text/html",text:d,locations:i?new z({otherLocations:new Map([["cssSelector",i]])}):void 0}));if(!a){s(!1);return}this.wnd.requestAnimationFrame(()=>{this.rtl?this.doc().scrollLeft=-this.snapNormOffset(a.getBoundingClientRect().left+t.scrollX):this.doc().scrollLeft=this.snapOffset(a.getBoundingClientRect().left+t.scrollX),this.reportProgress(this.nearestPrecedingTimelineEntry(a.startContainer)),m(this.wnd),s(!0)})}),e.register("go_end",h.moduleName,(r,s)=>{this.wnd.requestAnimationFrame(()=>{this.cachedScrollWidth=this.doc().scrollWidth;let i;if(this.rtl?i=-this.snapNormOffset(this.cachedScrollWidth-t.innerWidth):i=this.snapOffset(this.cachedScrollWidth),this.doc().scrollLeft===i)return s(!1);this.doc().scrollLeft=i,this.reportProgress(this.sortedFragmentIds[this.sortedFragmentIds.length-1]),m(this.wnd),s(!0)})}),e.register("go_start",h.moduleName,(r,s)=>{this.wnd.requestAnimationFrame(()=>{if(this.doc().scrollLeft===0)return s(!1);this.doc().scrollLeft=0,this.reportProgress(this.firstFragmentIfReached()),m(this.wnd),s(!0)})}),e.register("go_prev",h.moduleName,(r,s)=>{this.wnd.requestAnimationFrame(()=>{this.cachedScrollWidth=this.doc().scrollWidth;let i;this.rtl?i=l(this.normScroll()-t.innerWidth):i=n(t.scrollX-t.innerWidth),this.reportProgress(),i&&(m(this.wnd),this.checkSuspiciousSnap("left",this.wnd.innerWidth)),s(i)})}),e.register("go_next",h.moduleName,(r,s)=>{this.wnd.requestAnimationFrame(()=>{this.cachedScrollWidth=this.doc().scrollWidth;let i;this.rtl?i=l(this.normScroll()+t.innerWidth):i=n(t.scrollX+t.innerWidth),this.reportProgress(),i&&(m(this.wnd),this.checkSuspiciousSnap("right",this.wnd.innerWidth)),s(i)})}),e.register("unfocus",h.moduleName,(r,s)=>{this.snappingCancelled=!0,m(this.wnd),s(!0)}),e.register("shake",h.moduleName,(r,s)=>{this.shake(),s(!0)}),e.register("focus",h.moduleName,(r,s)=>{this.wnd.requestAnimationFrame(()=>{this.cachedScrollWidth=this.doc().scrollWidth,this.snapCurrentOffset(!1,!0),this.reportProgress(),s(!0)})}),e.register("first_visible_locator",h.moduleName,(r,s)=>{const i=X(t,!1);this.comms.send("first_visible_locator",i.serialize()),s(!0)}),e.register("timeline_entries",h.moduleName,(r,s)=>{this.updateTimelineEntries(Array.isArray(r)?r:[],t),t.requestAnimationFrame(()=>this.reportProgress()),s(!0)}),t.addEventListener("touchstart",this.onTouchStarter,{passive:!0}),t.addEventListener("touchend",this.onTouchEnder,{passive:!0}),t.addEventListener("touchmove",this.onTouchMover,{passive:!0}),t.document.addEventListener("touchstart",()=>{}),e.log("ColumnSnapper Mounted"),!0}unmount(t,e){return this.snappingCancelled=!0,e.unregisterAll(h.moduleName),this.resizeObserver.disconnect(),this.mutationObserver.disconnect(),this.patternAnalyzer&&(this.patternAnalyzer.clear(),this.patternAnalyzer=null,this.isSnapProtectionEnabled=!1),t.removeEventListener("touchstart",this.onTouchStarter),t.removeEventListener("touchend",this.onTouchEnder),t.removeEventListener("touchmove",this.onTouchMover),t.removeEventListener("orientationchange",this.onWidthChanger),t.removeEventListener("resize",this.onWidthChanger),t.document.getElementById(T)?.remove(),this.timelineEntries.clear(),e.log("ColumnSnapper Unmounted"),super.unmount(t,e)}};h.moduleName="column_snapper";let E=h;export{E as ColumnSnapper};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{LocatorText as u,Locator as m,LocatorLocations as g}from"@readium/shared";import{deselect as a,findFirstVisibleLocator as p}from"../../helpers/dom.js";import{Snapper as f}from"./Snapper.js";import{rangeFromLocator as S}from"../../helpers/locator.js";import{forceWebkitRecalc as b}from"../../helpers/document.js";import{PatternAnalyzer as T}from"../../protection/PatternAnalyzer.js";import{SCROLL_PROTECTION_CONFIG as y}from"../../protection/config.js";const h="readium-scroll-snapper-style",o=class o extends f{constructor(){super(...arguments),this.patternAnalyzer=null,this.lastScrollTime=0,this.isScrollProtectionEnabled=!1,this.initialScrollHandled=!1,this.isScrolling=!1,this.lastScrollTop=0,this.isResizing=!1,this.resizeDebounce=null,this.handleScroll=r=>{if(this.comms.ready&&!this.isResizing){if(!this.initialScrollHandled){this.lastScrollTop=this.doc().scrollTop,this.initialScrollHandled=!0,this.reportProgress();return}this.isScrolling||(this.isScrolling=!0,this.wnd.requestAnimationFrame(()=>{this.reportProgress();const s=this.doc().scrollTop,l=s-this.lastScrollTop;if(this.lastScrollTop=s,this.isScrollProtectionEnabled&&Math.abs(l)>5){const e=Date.now(),t=e-(this.lastScrollTime||e);if(this.patternAnalyzer&&this.patternAnalyzer.analyze(l>0?"down":"up",Math.abs(l),t)){const n=r.target&&"tagName"in r.target?{tagName:r.target.tagName}:null;this.comms?.send("content_protection",{type:"suspicious_scrolling",timestamp:Date.now(),scrollDelta:l,scrollDirection:l>0?"down":"up",targetElement:n})}this.lastScrollTime=e}this.comms.send("scroll",l),this.isScrolling=!1}))}}}doc(){return this.wnd.document.scrollingElement}hasScrolledPast(r){return r.getBoundingClientRect().bottom<=0}reportProgress(r){if(!this.comms.ready)return;const s=Math.ceil(this.doc().scrollTop),l=this.doc().scrollHeight,e=this.wnd.innerHeight,t=Math.max(0,Math.min(1,s/l)),i=Math.max(0,Math.min(1,(s+e)/l));this.comms.send("progress",{start:t,end:i,fragmentId:r!==void 0?r:this.currentTimelineFragment()})}enableScrollProtection(){this.patternAnalyzer||(this.patternAnalyzer=new T(y),this.isScrollProtectionEnabled=!0,this.comms?.log("Scroll protection enabled"))}mount(r,s){this.wnd=r,this.comms=s,this.setupTimelineObserver(),this.initialScrollHandled=!1,this.lastScrollTop=0,this.isResizing=!1,this.resizeDebounce&&(this.wnd.clearTimeout(this.resizeDebounce),this.resizeDebounce=null),r.navigator.epubReadingSystem&&(r.navigator.epubReadingSystem.layoutStyle="scrolling");const l=r.document.createElement("style");return l.dataset.readium="true",l.id=h,l.textContent=`
|
|
2
|
+
* {
|
|
3
|
+
scrollbar-width: none; /* for Firefox */
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
body::-webkit-scrollbar {
|
|
7
|
+
display: none; /* for Chrome, Safari, and Opera */
|
|
8
|
+
}
|
|
9
|
+
`,r.document.head.appendChild(l),this.resizeObserver=new ResizeObserver(()=>{this.resizeDebounce&&this.wnd.clearTimeout(this.resizeDebounce),this.isResizing=!0,this.resizeDebounce=this.wnd.setTimeout(()=>{this.isResizing=!1,this.resizeDebounce=null,this.reportProgress()},50)}),this.resizeObserver.observe(r.document.body),r.addEventListener("scroll",this.handleScroll,{passive:!0}),s.register("force_webkit_recalc",o.moduleName,()=>{b(this.wnd);const e=this.doc().scrollTop;e>1?this.doc().scrollTop=e-1:this.doc().scrollTop=e+1,this.doc().scrollTop=e}),s.register("go_progression",o.moduleName,(e,t)=>{const i=e;if(i<0||i>1){s.send("error",{message:"go_progression must be given a position from 0.0 to 1.0"}),t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=this.doc().offsetHeight*i,this.reportProgress(this.fragmentFromGeometry()),a(this.wnd),t(!0)})}),s.register("go_id",o.moduleName,(e,t)=>{const i=r.document.getElementById(e);if(!i){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=i.getBoundingClientRect().top+r.scrollY-r.innerHeight/2;const n=e;this.reportProgress(this.timelineEntries.has(n)?n:this.nearestPrecedingTimelineEntry(i)),a(this.wnd),t(!0)})}),s.register("go_text",o.moduleName,(e,t)=>{let i;Array.isArray(e)&&(e.length>1&&(i=e[1]),e=e[0]);const n=u.deserialize(e),c=S(this.wnd.document,new m({href:r.location.href,type:"text/html",text:n,locations:i?new g({otherLocations:new Map([["cssSelector",i]])}):void 0}));if(!c){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=c.getBoundingClientRect().top+r.scrollY-r.innerHeight/2,this.reportProgress(this.nearestPrecedingTimelineEntry(c.startContainer)),a(this.wnd),t(!0)})}),s.register("go_start",o.moduleName,(e,t)=>{if(this.doc().scrollTop===0)return t(!1);this.doc().scrollTop=0,this.reportProgress(this.firstFragmentIfReached()),t(!0)}),s.register("go_end",o.moduleName,(e,t)=>{if(this.doc().scrollTop===this.doc().scrollHeight-this.doc().offsetHeight)return t(!1);this.doc().scrollTop=this.doc().scrollHeight-this.doc().offsetHeight,this.reportProgress(this.sortedFragmentIds[this.sortedFragmentIds.length-1]),t(!0)}),s.register("unfocus",o.moduleName,(e,t)=>{a(this.wnd),t(!0)}),s.register("scroll_protection",o.moduleName,(e,t)=>{this.enableScrollProtection(),t(!0)}),s.register(["go_next","go_prev"],o.moduleName,(e,t)=>t(!1)),s.register("focus",o.moduleName,(e,t)=>{this.reportProgress(),t(!0)}),s.register("first_visible_locator",o.moduleName,(e,t)=>{const i=p(r,!0);this.comms.send("first_visible_locator",i.serialize()),t(!0)}),s.register("timeline_entries",o.moduleName,(e,t)=>{this.updateTimelineEntries(Array.isArray(e)?e:[],r),t(!0)}),s.log("ScrollSnapper Mounted"),!0}unmount(r,s){return s.unregisterAll(o.moduleName),this.resizeObserver.disconnect(),this.handleScroll&&r.removeEventListener("scroll",this.handleScroll),r.document.getElementById(h)?.remove(),this.timelineObserver?.disconnect(),this.timelineObserver=null,this.visibleFragmentIds.clear(),this.timelineEntries.clear(),this.patternAnalyzer&&(this.patternAnalyzer.clear(),this.patternAnalyzer=null,this.isScrollProtectionEnabled=!1),s.log("ScrollSnapper Unmounted"),!0}};o.moduleName="scroll_snapper";let d=o;export{d as ScrollSnapper};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{Module as m}from"../Module.js";const o="readium-snapper-style",n=class n extends m{constructor(){super(...arguments),this.protected=!1,this.timelineObserver=null,this.timelineEntries=new Map,this.visibleFragmentIds=new Set,this.cachedFragmentIds=[],this.sortedFragmentIds=[]}static inDomOrder(e,t,i){const r=e.get(t),s=e.get(i);return!r||!s?0:r.compareDocumentPosition(s)&Node.DOCUMENT_POSITION_FOLLOWING?-1:1}static isVisibleEntry(e){const t=e.boundingClientRect;if(t.width>0&&t.height>0)return e.isIntersecting;const i=e.rootBounds;return i?t.left<=i.right&&t.right>=i.left&&t.top<=i.bottom&&t.bottom>=i.top:e.isIntersecting}setupTimelineObserver(){this.timelineObserver&&this.timelineObserver.disconnect(),this.timelineObserver=new IntersectionObserver(e=>{for(const t of e)n.isVisibleEntry(t)?this.visibleFragmentIds.add(t.target.id):this.visibleFragmentIds.delete(t.target.id)},{threshold:[.01]})}updateTimelineEntries(e,t){this.cachedFragmentIds=e,this.timelineObserver?.disconnect(),this.visibleFragmentIds.clear(),this.timelineEntries.clear();for(const i of e){const r=t.document.getElementById(i);r&&(this.timelineEntries.set(i,r),this.timelineObserver?.observe(r))}this.sortedFragmentIds=Array.from(this.timelineEntries.keys()).sort((i,r)=>n.inDomOrder(this.timelineEntries,i,r))}nearestPrecedingTimelineEntry(e){let t;for(const i of this.sortedFragmentIds){const r=this.timelineEntries.get(i),s=r.compareDocumentPosition(e);if(r===e||r.contains(e)||(s&Node.DOCUMENT_POSITION_FOLLOWING)!==0)t=i;else break}return t}fragmentFromGeometry(){let e;for(const t of this.sortedFragmentIds){const i=this.timelineEntries.get(t);if(this.hasScrolledPast(i))e=t;else break}return e}firstFragmentIfReached(){const e=this.sortedFragmentIds[0];if(e===void 0)return;const t=this.timelineEntries.get(e);return this.hasScrolledPast(t)?e:void 0}currentTimelineFragment(){return this.visibleFragmentIds.size>0?Array.from(this.visibleFragmentIds).sort((e,t)=>n.inDomOrder(this.timelineEntries,e,t))[0]:this.fragmentFromGeometry()}buildStyles(){return`
|
|
2
|
+
html, body {
|
|
3
|
+
touch-action: manipulation;
|
|
4
|
+
user-select: ${this.protected?"none":"auto"};
|
|
5
|
+
}`}mount(e,t){const i=e.document.createElement("style");return i.dataset.readium="true",i.id=o,i.textContent=this.buildStyles(),e.document.head.appendChild(i),t.register("protect",n.moduleName,(r,s)=>{this.protected=!0,i.textContent=this.buildStyles(),s(!0)}),t.register("unprotect",n.moduleName,(r,s)=>{this.protected=!1,i.textContent=this.buildStyles(),s(!0)}),t.log("Snapper Mounted"),!0}unmount(e,t){return e.document.getElementById(o)?.remove(),t.log("Snapper Unmounted"),!0}};n.moduleName="snapper";let l=n;export{l as Snapper};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LocatorText as h,Locator as u,LocatorLocations as d}from"@readium/shared";import{deselect as c,findFirstVisibleLocator as g}from"../../helpers/dom.js";import{Snapper as m}from"./Snapper.js";import{rangeFromLocator as p}from"../../helpers/locator.js";import{forceWebkitRecalc as f}from"../../helpers/document.js";import{PatternAnalyzer as b}from"../../protection/PatternAnalyzer.js";import{SCROLL_PROTECTION_CONFIG as S}from"../../protection/config.js";const o=class o extends m{constructor(){super(...arguments),this.patternAnalyzer=null,this.lastScrollTime=0,this.isScrollProtectionEnabled=!1,this.initialScrollHandled=!1,this.isScrolling=!1,this.lastScrollTop=0,this.isResizing=!1,this.resizeDebounce=null,this.handleScroll=s=>{if(this.comms.ready&&!this.isResizing){if(!this.initialScrollHandled){this.lastScrollTop=this.doc().scrollTop,this.initialScrollHandled=!0,this.reportProgress();return}this.isScrolling||(this.isScrolling=!0,this.wnd.requestAnimationFrame(()=>{this.reportProgress();const r=this.doc().scrollTop,e=r-this.lastScrollTop;if(this.lastScrollTop=r,this.isScrollProtectionEnabled&&Math.abs(e)>5){const t=Date.now(),i=t-(this.lastScrollTime||t);if(this.patternAnalyzer&&this.patternAnalyzer.analyze(e>0?"down":"up",Math.abs(e),i)){const n=s.target&&"tagName"in s.target?{tagName:s.target.tagName}:null;this.comms?.send("content_protection",{type:"suspicious_scrolling",timestamp:Date.now(),scrollDelta:e,scrollDirection:e>0?"down":"up",targetElement:n})}this.lastScrollTime=t}this.comms.send("scroll",e),this.isScrolling=!1}))}}}doc(){return this.wnd.document.scrollingElement}hasScrolledPast(s){return s.getBoundingClientRect().bottom<=0}reportProgress(s){if(!this.comms.ready)return;const r=Math.ceil(this.doc().scrollTop),e=this.doc().scrollHeight,t=this.wnd.innerHeight,i=Math.max(0,Math.min(1,r/e)),l=Math.max(0,Math.min(1,(r+t)/e));this.comms.send("progress",{start:i,end:l,fragmentId:s!==void 0?s:this.currentTimelineFragment()})}enableScrollProtection(){this.patternAnalyzer||(this.patternAnalyzer=new b(S),this.isScrollProtectionEnabled=!0,this.comms?.log("Scroll protection enabled"))}mount(s,r){return this.wnd=s,this.comms=r,this.setupTimelineObserver(),this.initialScrollHandled=!1,this.lastScrollTop=0,this.isResizing=!1,this.resizeDebounce&&(this.wnd.clearTimeout(this.resizeDebounce),this.resizeDebounce=null),this.resizeObserver=new ResizeObserver(()=>{this.resizeDebounce&&this.wnd.clearTimeout(this.resizeDebounce),this.isResizing=!0,this.resizeDebounce=this.wnd.setTimeout(()=>{this.isResizing=!1,this.resizeDebounce=null,this.reportProgress()},50)}),this.resizeObserver.observe(s.document.body),s.addEventListener("scroll",this.handleScroll,{passive:!0}),r.register("force_webkit_recalc",o.moduleName,()=>{f(this.wnd);const e=this.doc().scrollTop;e>1?this.doc().scrollTop=e-1:this.doc().scrollTop=e+1,this.doc().scrollTop=e}),r.register("go_progression",o.moduleName,(e,t)=>{const i=e;if(i<0||i>1){r.send("error",{message:"go_progression must be given a position from 0.0 to 1.0"}),t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=this.doc().offsetHeight*i,this.reportProgress(this.fragmentFromGeometry()),c(this.wnd),t(!0)})}),r.register("go_id",o.moduleName,(e,t)=>{const i=s.document.getElementById(e);if(!i){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=i.getBoundingClientRect().top+s.scrollY-s.innerHeight/2;const l=e;this.reportProgress(this.timelineEntries.has(l)?l:this.nearestPrecedingTimelineEntry(i)),c(this.wnd),t(!0)})}),r.register("go_text",o.moduleName,(e,t)=>{let i;Array.isArray(e)&&(e.length>1&&(i=e[1]),e=e[0]);const l=h.deserialize(e),n=p(this.wnd.document,new u({href:s.location.href,type:"text/html",text:l,locations:i?new d({otherLocations:new Map([["cssSelector",i]])}):void 0}));if(!n){t(!1);return}this.wnd.requestAnimationFrame(()=>{this.doc().scrollTop=n.getBoundingClientRect().top+s.scrollY-s.innerHeight/2,this.reportProgress(this.nearestPrecedingTimelineEntry(n.startContainer)),c(this.wnd),t(!0)})}),r.register("go_start",o.moduleName,(e,t)=>{if(this.doc().scrollTop===0)return t(!1);this.doc().scrollTop=0,this.reportProgress(this.firstFragmentIfReached()),t(!0)}),r.register("go_end",o.moduleName,(e,t)=>{if(this.doc().scrollTop===this.doc().scrollHeight-this.doc().offsetHeight)return t(!1);this.doc().scrollTop=this.doc().scrollHeight-this.doc().offsetHeight,this.reportProgress(this.sortedFragmentIds[this.sortedFragmentIds.length-1]),t(!0)}),r.register("unfocus",o.moduleName,(e,t)=>{c(this.wnd),t(!0)}),r.register("scroll_protection",o.moduleName,(e,t)=>{this.enableScrollProtection(),t(!0)}),r.register(["go_next","go_prev"],o.moduleName,(e,t)=>t(!1)),r.register("focus",o.moduleName,(e,t)=>{this.reportProgress(),t(!0)}),r.register("first_visible_locator",o.moduleName,(e,t)=>{const i=g(s,!0);r.send("first_visible_locator",i.serialize()),t(!0)}),r.register("timeline_entries",o.moduleName,(e,t)=>{this.updateTimelineEntries(Array.isArray(e)?e:[],s),t(!0)}),r.log("WebPubSnapper Mounted"),!0}unmount(s,r){return r.unregisterAll(o.moduleName),this.resizeObserver.disconnect(),this.handleScroll&&s.removeEventListener("scroll",this.handleScroll),this.patternAnalyzer&&(this.patternAnalyzer.clear(),this.patternAnalyzer=null,this.isScrollProtectionEnabled=!1),this.timelineObserver?.disconnect(),this.timelineObserver=null,this.visibleFragmentIds.clear(),this.timelineEntries.clear(),r.log("WebPubSnapper Unmounted"),!0}};o.moduleName="webpub_snapper";let a=o;export{a as WebPubSnapper};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class y{constructor(s,i){this.window=s,this.copyHistory=[],this.lastSelectionLength=0,this.lastSelectionTime=0,this.options=i}cleanupOldHistory(s){this.copyHistory=this.copyHistory.filter(n=>s-n.timestamp<1e4),this.copyHistory.length>this.options.historySize&&(this.copyHistory=this.copyHistory.slice(-this.options.historySize))}isSuspiciousPattern(s){return this.copyHistory.length<3?!1:this.copyHistory.filter(t=>s-t.timestamp<2e3).length>=3?!0:this.copyHistory.slice().sort((t,o)=>t.timestamp-o.timestamp).every((t,o,e)=>o===0?!0:t.length>e[o-1].length*1.5)}shouldAllowCopy(s){if(!this.options.enabled)return!0;const i=this.window.getSelection();if(!i)return!0;const t=i.toString().length,o=this.window.document.body.innerText.length,e=Date.now();if(this.cleanupOldHistory(e),t<this.options.minThreshold)return this.copyHistory.push({timestamp:e,length:t,wasBlocked:!1}),!0;const r=e-this.lastSelectionTime<100&&t>this.lastSelectionLength*1.5,l=Math.min(o*this.options.maxSelectionPercent,this.options.absoluteMaxChars),h=this.isSuspiciousPattern(e),c=t>l||r||h;return this.copyHistory.push({timestamp:e,length:t,wasBlocked:c}),c?(s?.preventDefault(),!1):(this.lastSelectionLength=t,this.lastSelectionTime=e,!0)}destroy(){this.lastSelectionLength=0,this.lastSelectionTime=0,this.copyHistory=[],this.options.enabled=!1}}export{y as BulkCopyProtector};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DEFAULT_PATTERN_ANALYZER_CONFIG as m}from"./config.js";class A{constructor(o={}){this.history=[],this.consistentScrollCount=0,this.options={...m,...o}}analyze(o,n,r){if(r<=0)return!1;const h=Math.abs(n)/r,c=Date.now();if(this.history.push({timestamp:c,direction:o,velocity:h,distance:Math.abs(n)}),this.history=this.history.filter(t=>c-t.timestamp<2e3).slice(-(this.options.historySize||20)),this.history.length<3)return!1;if(h>this.options.maxVelocity)return this.resetAfterDetection(),!0;const s=this.history.map(t=>t.velocity),e=this.history.map(t=>t.distance),u=s.reduce((t,i)=>t+i,0)/s.length,l=e.reduce((t,i)=>t+i,0)/e.length,f=s.reduce((t,i)=>t+Math.pow(i-u,2),0)/s.length,p=e.reduce((t,i)=>t+Math.pow(i-l,2),0)/e.length;if(f<this.options.minVariance&&p<l*.1){if(this.consistentScrollCount++,this.consistentScrollCount>=(this.options.maxConsistentScrolls||10))return this.resetAfterDetection(),!0}else this.consistentScrollCount=Math.max(0,this.consistentScrollCount-1);let a=0,y=this.history[0].direction;for(let t=1;t<this.history.length;t++)this.history[t].direction!==y&&(a++,y=this.history[t].direction);return a/this.history.length>(this.options.minDirectionChanges||.3)?(this.resetAfterDetection(),!0):!1}resetAfterDetection(){this.history=this.history.slice(-3),this.consistentScrollCount=0}clear(){this.history=[],this.consistentScrollCount=0}}export{A as PatternAnalyzer};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{Module as l}from"../modules/Module.js";const n=class n extends l{constructor(){super(...arguments),this.styleElement=null,this.beforePrintHandler=null,this.configApplied=!1}setupPrintProtection(e,t){if(!t.disable)return;const i=e.document.createElement("style");i.textContent=`
|
|
2
|
+
@media print {
|
|
3
|
+
body * {
|
|
4
|
+
display: none !important;
|
|
5
|
+
}
|
|
6
|
+
body::after {
|
|
7
|
+
content: "${t.watermark||"Printing has been disabled"}";
|
|
8
|
+
font-size: 200%;
|
|
9
|
+
display: block;
|
|
10
|
+
text-align: center;
|
|
11
|
+
margin-top: 50vh;
|
|
12
|
+
transform: translateY(-50%);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`,e.document.head.appendChild(i),this.styleElement=i,this.beforePrintHandler=s=>(s.preventDefault(),!1),e.addEventListener("beforeprint",this.beforePrintHandler)}registerPrintHandlers(){this.comms?.register("print_protection",n.moduleName,e=>{const t=e;return this.configApplied||(this.configApplied=!0,this.setupPrintProtection(this.wnd,t),this.comms?.log("Print protection configuration applied")),!0})}mount(e,t){return this.wnd=e,this.comms=t,this.registerPrintHandlers(),!0}unmount(e,t){return this.beforePrintHandler&&(e.removeEventListener("beforeprint",this.beforePrintHandler),this.beforePrintHandler=null),this.styleElement?.parentNode&&(this.styleElement.parentNode.removeChild(this.styleElement),this.styleElement=null),this.comms?.unregisterAll(n.moduleName),this.configApplied=!1,!0}};n.moduleName="print_protection";let r=n;export{r as PrintProtector};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SELECTION_ANALYZER_CONFIG as r}from"./config.js";class f{constructor(t=r){this.options=t,this.events=[],this.selectionStartTime=0,this.lastSelectionTime=0,this.lastSelectionPosition=0,this.selectionPatterns=[],this.lastSelectedText=""}analyze(t){if(!t)return this.clear(),!1;const i=t.toString();if(i.length===0)return this.clear(),!1;if(t.type!=="Range"||!t.rangeCount)return!1;const e=Date.now();if(i.length<=50||i===this.lastSelectedText)return!1;if(this.selectionStartTime===0)return this.selectionStartTime=e,this.lastSelectedText=i,!1;if(e-this.selectionStartTime<500)return!1;e-this.lastSelectionTime>1e3&&(this.lastSelectionTime=e),this.selectionStartTime===0&&(this.selectionStartTime=e),this.lastSelectedText=i;const n=this.analyzeSelectionPattern(t,e);return this.cleanup(e),n}analyzeSelectionPattern(t,i){if(!t.rangeCount)return!1;const e=t.getRangeAt(0),s=e.toString(),n=(i-this.selectionStartTime)/1e3;if(s.length/Math.max(1,n)>this.options.maxSelectionsPerSecond)return!0;const a=e.startOffset,l=Math.abs(a-this.lastSelectionPosition);return this.selectionPatterns.push(l),this.selectionPatterns.length>this.options.historySize&&(this.selectionPatterns.shift(),this.calculateVariance(this.selectionPatterns)<this.options.minVariance)?!0:(this.lastSelectionPosition=a,!1)}calculateVariance(t){if(t.length===0)return 0;const i=t.reduce((e,s)=>e+s,0)/t.length;return t.reduce((e,s)=>e+Math.pow(s-i,2),0)/t.length}cleanup(t){this.events=this.events.filter(i=>t-i.timestamp<=1e3)}clear(){this.events=[],this.selectionStartTime=0,this.lastSelectionTime=0,this.lastSelectionPosition=0,this.selectionPatterns=[],this.lastSelectedText=""}}export{f as SelectionAnalyzer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={maxVelocity:200,minVariance:.01,historySize:20,minDirectionChanges:.2,maxConsistentScrolls:15},i={maxVelocity:200,minVariance:1e-5,historySize:100,minDirectionChanges:.1,maxConsistentScrolls:20},n={maxSelectionsPerSecond:500,minVariance:50,historySize:20},o={enabled:!0,maxSelectionPercent:.1,minThreshold:100,absoluteMaxChars:5e3,historySize:20};export{o as BULK_COPY_CONFIG,e as DEFAULT_PATTERN_ANALYZER_CONFIG,i as SCROLL_PROTECTION_CONFIG,n as SELECTION_ANALYZER_CONFIG};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function P(s){return s.split("").reverse().join("")}function R(s,l,o){const d=P(l);return o.map(e=>{const c=Math.max(0,e.end-l.length-e.errors),i=P(s.slice(c,e.end));return{start:v(i,d,e.errors).reduce((M,u)=>e.end-u.end<M?e.end-u.end:M,e.end),end:e.end,errors:e.errors}})}function A(s){return(s|-s)>>31&1}function k(s,l,o,d){let e=s.P[o],c=s.M[o];const i=d>>>31,w=l[o]|i,M=w|c,u=(w&e)+e^e|w;let t=c|~(u|e),r=e&u;const n=A(t&s.lastRowMask[o])-A(r&s.lastRowMask[o]);return t<<=1,r<<=1,r|=i,t|=A(d)-i,e=r|~(M|t),c=t&M,s.P[o]=e,s.M[o]=c,n}function v(s,l,o){if(l.length===0)return[];o=Math.min(o,l.length);const d=[],e=32,c=Math.ceil(l.length/e)-1,i={P:new Uint32Array(c+1),M:new Uint32Array(c+1),lastRowMask:new Uint32Array(c+1)};i.lastRowMask.fill(1<<31),i.lastRowMask[c]=1<<(l.length-1)%e;const w=new Uint32Array(c+1),M=new Map,u=[];for(let n=0;n<256;n++)u.push(w);for(let n=0;n<l.length;n+=1){const g=l.charCodeAt(n);if(M.has(g))continue;const f=new Uint32Array(c+1);M.set(g,f),g<u.length&&(u[g]=f);for(let a=0;a<=c;a+=1){f[a]=0;for(let h=0;h<e;h+=1){const y=a*e+h;if(y>=l.length)continue;l.charCodeAt(y)===g&&(f[a]|=1<<h)}}}let t=Math.max(0,Math.ceil(o/e)-1);const r=new Uint32Array(c+1);for(let n=0;n<=t;n+=1)r[n]=(n+1)*e;r[c]=l.length;for(let n=0;n<=t;n+=1)i.P[n]=-1,i.M[n]=0;for(let n=0;n<s.length;n+=1){const g=s.charCodeAt(n);let f;g<u.length?f=u[g]:(f=M.get(g),typeof f>"u"&&(f=w));let a=0;for(let h=0;h<=t;h+=1)a=k(i,f,h,a),r[h]+=a;if(r[t]-a<=o&&t<c&&(f[t+1]&1||a<0)){t+=1,i.P[t]=-1,i.M[t]=0;let h;if(t===c){const y=l.length%e;h=y===0?e:y}else h=e;r[t]=r[t-1]+h-a+k(i,f,t,a)}else for(;t>0&&r[t]>=o+e;)t-=1;t===c&&r[t]<=o&&(r[t]<o&&d.splice(0,d.length),d.push({start:-1,end:n+1,errors:r[t]}),o=r[t])}return d}function U(s,l,o){const d=v(s,l,o);return R(s,l,d)}export{U as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import W from"../../approx-string-match/index.js";function a(s,e,t){let n=0;const o=[];for(;n!==-1;)n=s.indexOf(e,n),n!==-1&&(o.push({start:n,end:n+e.length,errors:0}),n+=1);return o.length>0?o:W(s,e,t)}function f(s,e){return e.length===0||s.length===0?0:1-a(s,e,e.length)[0].errors/e.length}function q(s,e,t={}){if(e.length===0)return null;const n=Math.min(256,e.length/2),o=a(s,e,n);if(o.length===0)return null;const g=r=>{const l=1-r.errors/e.length,u=t.prefix?f(s.slice(Math.max(0,r.start-t.prefix.length),r.start),t.prefix):1,p=t.suffix?f(s.slice(r.end,r.end+t.suffix.length),t.suffix):1;let h=1;return typeof t.hint=="number"&&(h=1-Math.abs(r.start-t.hint)/s.length),(50*l+20*u+20*p+2*h)/92},i=o.map(r=>({start:r.start,end:r.end,score:g(r)}));return i.sort((r,c)=>c.score-r.score),i[0]}export{q as matchQuote};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{trimRange as u}from"./trim-range.js";function d(s){switch(s.nodeType){case Node.ELEMENT_NODE:case Node.TEXT_NODE:return s.textContent?.length??0;default:return 0}}function h(s){let e=s.previousSibling,t=0;for(;e;)t+=d(e),e=e.previousSibling;return t}function c(s,...e){let t=e.shift();const r=s.ownerDocument.createNodeIterator(s,NodeFilter.SHOW_TEXT),n=[];let i=r.nextNode(),l,f=0;for(;t!==void 0&&i;)l=i,f+l.data.length>t?(n.push({node:l,offset:t-f}),t=e.shift()):(i=r.nextNode(),f+=l.data.length);for(;t!==void 0&&l&&f===t;)n.push({node:l,offset:l.data.length}),t=e.shift();if(t!==void 0)throw new RangeError("Offset exceeds text length");return n}class o{constructor(e,t){if(t<0)throw new Error("Offset is invalid");this.element=e,this.offset=t}relativeTo(e){if(!e.contains(this.element))throw new Error("Parent is not an ancestor of current element");let t=this.element,r=this.offset;for(;t!==e;)r+=h(t),t=t.parentElement;return new o(t,r)}resolve(e={}){try{return c(this.element,this.offset)[0]}catch(t){if(this.offset===0&&e.direction!==void 0){const r=document.createTreeWalker(this.element.getRootNode(),NodeFilter.SHOW_TEXT);r.currentNode=this.element;const n=e.direction===1,i=n?r.nextNode():r.previousNode();if(!i)throw t;return{node:i,offset:n?0:i.data.length}}else throw t}}static fromCharOffset(e,t){switch(e.nodeType){case Node.TEXT_NODE:return o.fromPoint(e,t);case Node.ELEMENT_NODE:return new o(e,t);default:throw new Error("Node is not an element or text node")}}static fromPoint(e,t){switch(e.nodeType){case Node.TEXT_NODE:{if(t<0||t>e.data.length)throw new Error("Text node offset is out of range");if(!e.parentElement)throw new Error("Text node has no parent");const r=h(e)+t;return new o(e.parentElement,r)}case Node.ELEMENT_NODE:{if(t<0||t>e.childNodes.length)throw new Error("Child node offset is out of range");let r=0;for(let n=0;n<t;n++)r+=d(e.childNodes[n]);return new o(e,r)}default:throw new Error("Point is not in an element or text node")}}}class a{constructor(e,t){this.start=e,this.end=t}relativeTo(e){return new a(this.start.relativeTo(e),this.end.relativeTo(e))}toRange(){let e,t;this.start.element===this.end.element&&this.start.offset<=this.end.offset?[e,t]=c(this.start.element,this.start.offset,this.end.offset):(e=this.start.resolve({direction:1}),t=this.end.resolve({direction:2}));const r=new Range;return r.setStart(e.node,e.offset),r.setEnd(t.node,t.offset),r}static fromRange(e){const t=o.fromPoint(e.startContainer,e.startOffset),r=o.fromPoint(e.endContainer,e.endOffset);return new a(t,r)}static fromOffsets(e,t,r){return new a(new o(e,t),new o(e,r))}static trimmedRange(e){return u(a.fromRange(e).toRange())}}export{o as TextPosition,a as TextRange};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function s(n,t,o){const a=o===1?t:t-1;if(n.charAt(a).trim()!=="")return t;let i,e;if(o===2?(i=n.substring(0,t),e=i.trimEnd()):(i=n.substring(t),e=i.trimStart()),!e.length)return-1;const r=i.length-e.length;return o===2?t-r:t+r}function f(n,t){const o=n.commonAncestorContainer.ownerDocument.createNodeIterator(n.commonAncestorContainer,NodeFilter.SHOW_TEXT),a=t===1?n.startContainer:n.endContainer,i=t===1?n.endContainer:n.startContainer;let e=o.nextNode();for(;e&&e!==a;)e=o.nextNode();t===2&&(e=o.previousNode());let r=-1;const l=()=>{if(e=t===1?o.nextNode():o.previousNode(),e){const d=e.textContent,c=t===1?0:d.length;r=s(d,c,t)}};for(;e&&r===-1&&e!==i;)l();if(e&&r>=0)return{node:e,offset:r};throw new RangeError("No text nodes with non-whitespace text found in range")}function m(n){if(!n.toString().trim().length)throw new RangeError("Range contains no non-whitespace text");if(n.startContainer.nodeType!==Node.TEXT_NODE)throw new RangeError("Range startContainer is not a text node");if(n.endContainer.nodeType!==Node.TEXT_NODE)throw new RangeError("Range endContainer is not a text node");const t=n.cloneRange();let o=!1,a=!1;const i={start:s(n.startContainer.textContent,n.startOffset,1),end:s(n.endContainer.textContent,n.endOffset,2)};if(i.start>=0&&(t.setStart(n.startContainer,i.start),o=!0),i.end>0&&(t.setEnd(n.endContainer,i.end),a=!0),o&&a)return t;if(!o){const{node:e,offset:r}=f(t,1);e&&r>=0&&t.setStart(e,r)}if(!a){const{node:e,offset:r}=f(t,2);e&&r>0&&t.setEnd(e,r)}return t}export{m as trimRange};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{matchQuote as h}from"./match-quote.js";import{TextRange as a}from"./text-range.js";class s{constructor(t,n,e){this.root=t,this.start=n,this.end=e}static fromRange(t,n){const e=a.fromRange(n).relativeTo(t);return new s(t,e.start.offset,e.end.offset)}static fromSelector(t,n){return new s(t,n.start,n.end)}toSelector(){return{type:"TextPositionSelector",start:this.start,end:this.end}}toRange(){return a.fromOffsets(this.root,this.start,this.end).toRange()}}class c{constructor(t,n,e={}){this.root=t,this.exact=n,this.context=e}static fromRange(t,n){const e=t.textContent,o=a.fromRange(n).relativeTo(t),r=o.start.offset,i=o.end.offset,f=32;return new c(t,e.slice(r,i),{prefix:e.slice(Math.max(0,r-f),r),suffix:e.slice(i,Math.min(e.length,i+f))})}static fromSelector(t,n){const{prefix:e,suffix:o}=n;return new c(t,n.exact,{prefix:e,suffix:o})}toSelector(){return{type:"TextQuoteSelector",exact:this.exact,prefix:this.context.prefix,suffix:this.context.suffix}}toRange(t={}){return this.toPositionAnchor(t).toRange()}toPositionAnchor(t={}){const n=this.root.textContent,e=h(n,this.exact,{...this.context,hint:t.hint});if(!e)throw new Error("Quote not found");return new s(this.root,e.start,e.end)}}export{s as TextPositionAnchor,c as TextQuoteAnchor};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@readium/navigator-html-injectables",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An embeddable solution for connecting frames of HTML publications with a Readium Navigator",
|
|
6
6
|
"author": "readium",
|
|
@@ -26,20 +26,15 @@
|
|
|
26
26
|
"reader",
|
|
27
27
|
"viewer"
|
|
28
28
|
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"clean": "rimraf types dist",
|
|
31
|
-
"build": "pnpm clean && tsc && vite build"
|
|
32
|
-
},
|
|
33
|
-
"main": "./dist/index.umd.cjs",
|
|
34
|
-
"module": "./dist/index.js",
|
|
35
29
|
"types": "./types/src/index.d.ts",
|
|
36
30
|
"exports": {
|
|
37
31
|
".": {
|
|
32
|
+
"ts-toolkit-source": "./src/index.ts",
|
|
38
33
|
"types": "./types/src/index.d.ts",
|
|
39
|
-
"import": "./dist/index.js"
|
|
40
|
-
"require": "./dist/index.umd.cjs"
|
|
34
|
+
"import": "./dist/index.js"
|
|
41
35
|
}
|
|
42
36
|
},
|
|
37
|
+
"sideEffects": false,
|
|
43
38
|
"files": [
|
|
44
39
|
"dist",
|
|
45
40
|
"src",
|
|
@@ -48,13 +43,19 @@
|
|
|
48
43
|
"engines": {
|
|
49
44
|
"node": ">=18"
|
|
50
45
|
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@readium/helpers": "1.0.0",
|
|
48
|
+
"@readium/shared": "2.3.0"
|
|
49
|
+
},
|
|
51
50
|
"devDependencies": {
|
|
52
|
-
"@readium/shared": "workspace:*",
|
|
53
51
|
"css-selector-generator": "^3.8.0",
|
|
54
|
-
"rimraf": "^6.1.
|
|
52
|
+
"rimraf": "^6.1.3",
|
|
55
53
|
"tslib": "^2.8.1",
|
|
56
54
|
"typescript": "^5.9.3",
|
|
57
|
-
"user-agent-data-types": "^0.4.2",
|
|
58
55
|
"vite": "^7.3.1"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"clean": "rimraf types dist",
|
|
59
|
+
"build": "pnpm clean && tsc && vite build"
|
|
59
60
|
}
|
|
60
|
-
}
|
|
61
|
+
}
|
package/src/comms/comms.ts
CHANGED
|
@@ -20,11 +20,21 @@ export interface Registrant {
|
|
|
20
20
|
export type CommsAck = (ok: boolean) => void;
|
|
21
21
|
export type CommsCallback = (data: unknown, ack: CommsAck) => void; // TODO: maybe more than void?
|
|
22
22
|
|
|
23
|
+
export interface IComms {
|
|
24
|
+
register(key: CommsCommandKey | CommsCommandKey[], module: string, callback: CommsCallback): void;
|
|
25
|
+
unregister(key: CommsCommandKey | CommsCommandKey[], module: string): void;
|
|
26
|
+
unregisterAll(module: string): void;
|
|
27
|
+
send(key: CommsEventKey, data: unknown, id?: unknown, transfer?: Transferable[]): void;
|
|
28
|
+
log(...data: any[]): void;
|
|
29
|
+
readonly ready: boolean;
|
|
30
|
+
destroy(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* Comms is basically a wrapper around window.postMessage that
|
|
25
35
|
* adds structure to the messages and lets modules register callbacks.
|
|
26
36
|
*/
|
|
27
|
-
export class Comms {
|
|
37
|
+
export class Comms implements IComms {
|
|
28
38
|
private readonly wnd: ReadiumWindow;
|
|
29
39
|
private destination: ReadiumWindow | null = null;
|
|
30
40
|
private registrar = new Map<CommsCommandKey, Registrant[]>();
|
package/src/comms/keys.ts
CHANGED
|
@@ -21,7 +21,9 @@ export type CommsEventKey =
|
|
|
21
21
|
"media_pause" |
|
|
22
22
|
"content_protection" |
|
|
23
23
|
"keyboard_peripherals" |
|
|
24
|
-
"decoration_activated"
|
|
24
|
+
"decoration_activated" |
|
|
25
|
+
"decoration_pointer_enter" |
|
|
26
|
+
"decoration_pointer_leave";
|
|
25
27
|
|
|
26
28
|
export type CommsCommandKey =
|
|
27
29
|
"_ping" |
|
|
@@ -40,6 +42,7 @@ export type CommsCommandKey =
|
|
|
40
42
|
"first_visible_locator" |
|
|
41
43
|
"decorate" |
|
|
42
44
|
"decoration_activatable" |
|
|
45
|
+
"decoration_hoverable" |
|
|
43
46
|
"protect" |
|
|
44
47
|
"unprotect" |
|
|
45
48
|
"unfocus" |
|
|
@@ -50,7 +53,8 @@ export type CommsCommandKey =
|
|
|
50
53
|
"peripherals_protection" |
|
|
51
54
|
"keyboard_peripherals" |
|
|
52
55
|
"scroll_protection" |
|
|
53
|
-
"print_protection"
|
|
56
|
+
"print_protection" |
|
|
57
|
+
"timeline_entries";
|
|
54
58
|
;
|
|
55
59
|
|
|
56
60
|
export type SuspiciousActivityType =
|
package/src/helpers/css.ts
CHANGED
|
@@ -67,7 +67,7 @@ export function updateProperties(wnd: ReadiumWindow, properties: { [key: string]
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// Easy way to get a CSS property
|
|
70
|
-
export function getProperty(wnd:
|
|
70
|
+
export function getProperty(wnd: Window, key: string) {
|
|
71
71
|
return wnd.document.documentElement.style.getPropertyValue(key);
|
|
72
72
|
}
|
|
73
73
|
|
package/src/helpers/document.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { ReadiumWindow } from "./dom.ts";
|
|
2
2
|
|
|
3
|
-
export function isRTL(wnd:
|
|
3
|
+
export function isRTL(wnd: Window): boolean {
|
|
4
4
|
// Check documentElement first, then fall back to body.
|
|
5
5
|
const dir = wnd.document.documentElement.dir || wnd.document.body.dir;
|
|
6
6
|
return dir.toLowerCase() === "rtl";
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function isVerticalLR(wnd:
|
|
9
|
+
export function isVerticalLR(wnd: Window): boolean {
|
|
10
10
|
// Check documentElement first, then fall back to body.
|
|
11
11
|
const writingMode = wnd.getComputedStyle(wnd.document.documentElement).writingMode
|
|
12
12
|
|| wnd.getComputedStyle(wnd.document.body).writingMode;
|
|
13
13
|
return writingMode === 'vertical-lr';
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function isVerticalWriting(wnd:
|
|
16
|
+
export function isVerticalWriting(wnd: Window): boolean {
|
|
17
17
|
const writingMode = wnd.getComputedStyle(wnd.document.documentElement).writingMode
|
|
18
18
|
|| wnd.getComputedStyle(wnd.document.body).writingMode;
|
|
19
19
|
return writingMode === 'vertical-rl' || writingMode === 'vertical-lr';
|
|
@@ -75,7 +75,7 @@ export interface WritingContext {
|
|
|
75
75
|
toRect(inlineStart: number, blockStart: number, inlineSize: number, blockSize: number): DOMRect;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
export function makeWritingContext(wnd:
|
|
78
|
+
export function makeWritingContext(wnd: Window): WritingContext {
|
|
79
79
|
const isVert = isVerticalWriting(wnd);
|
|
80
80
|
const isVLR = isVert && isVerticalLR(wnd);
|
|
81
81
|
const vw = wnd.innerWidth;
|
|
@@ -133,7 +133,7 @@ export function makeWritingContext(wnd: ReadiumWindow): WritingContext {
|
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
export function getColumnCountPerScreen(wnd:
|
|
136
|
+
export function getColumnCountPerScreen(wnd: Window): number {
|
|
137
137
|
return parseInt(
|
|
138
138
|
wnd.getComputedStyle(
|
|
139
139
|
wnd.document.documentElement
|
package/src/helpers/locator.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Locator } from "@readium/shared";
|
|
1
|
+
import { getCssSelector, Locator } from "@readium/shared";
|
|
2
2
|
import { TextQuoteAnchor } from "../vendor/hypothesis/anchoring/types.ts";
|
|
3
3
|
|
|
4
4
|
function isReplacedLikeElement(element: Element): boolean {
|
|
@@ -13,8 +13,8 @@ export function rangeFromLocator(doc: Document, locator: Locator) {
|
|
|
13
13
|
const text = locator.text;
|
|
14
14
|
if (text && text.highlight) {
|
|
15
15
|
let root;
|
|
16
|
-
if (locations &&
|
|
17
|
-
root = doc.querySelector(
|
|
16
|
+
if (locations && getCssSelector(locations)) {
|
|
17
|
+
root = doc.querySelector(getCssSelector(locations)!);
|
|
18
18
|
}
|
|
19
19
|
if (!root) {
|
|
20
20
|
root = doc.body;
|
|
@@ -36,8 +36,8 @@ export function rangeFromLocator(doc: Document, locator: Locator) {
|
|
|
36
36
|
if (locations) {
|
|
37
37
|
let element = null;
|
|
38
38
|
|
|
39
|
-
if (!element &&
|
|
40
|
-
element = doc.querySelector(
|
|
39
|
+
if (!element && getCssSelector(locations)) {
|
|
40
|
+
element = doc.querySelector(getCssSelector(locations)!);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (!element && locations.fragments) {
|