2 lines
9.6 KiB
JavaScript
2 lines
9.6 KiB
JavaScript
"use strict";(()=>{var m={PLACEHOLDER:0,RENDERING:1,RENDERED:2};var O=16777216;function G(l,e,s,n){let t=l*s*n,r=e*s*n,i=t*r;return i<=O?s*n:s*n*Math.sqrt(O/i)}var v=class{constructor(e,s,n,t,r){this._wrappers=[];this._renderGen=0;this._inFlight=0;this._zooming=!1;this._wrapper=e,this._dims=s,this._scale=n,this._dpr=t,this._dispatchRender=r,this._states=new Array(s.length).fill(m.PLACEHOLDER),this._canvases=new Array(s.length).fill(null),this._buildPlaceholders()}get pageWrappers(){return this._wrappers}get numPages(){return this._dims.length}get renderGen(){return this._renderGen}get allRendered(){return this._inFlight===0}setZooming(e){this._zooming=e}_buildPlaceholders(){for(let e=0;e<this._dims.length;e++){let s=this._dims[e],n=document.createElement("div");n.className="page-wrapper",n.dataset.page=String(e+1),n.style.width=s.width*this._scale+"px",n.style.height=s.height*this._scale+"px",this._wrapper.appendChild(n),this._wrappers.push(n)}}reconcile(e,s){let n=this._renderGen,t=[...[...s].sort((r,i)=>r-i),...[...e].filter(r=>!s.has(r)).sort((r,i)=>r-i)];for(let r of t){let i=r-1;i<0||i>=this._dims.length||this._states[i]===m.PLACEHOLDER&&this._startRender(i,n)}for(let r=0;r<this._dims.length;r++){let i=r+1;!this._zooming&&!e.has(i)&&this._states[r]===m.RENDERED&&this._cleanup(r),!e.has(i)&&this._states[r]===m.RENDERING&&(this._inFlight--,this._states[r]=m.PLACEHOLDER)}}_startRender(e,s){let n=this._dims[e],t=G(n.width,n.height,this._scale,this._dpr);this._states[e]=m.RENDERING,this._inFlight++,this._dispatchRender(e+1,t,s)}_cleanup(e){this._states[e]===m.RENDERING&&this._inFlight--,this._states[e]=m.PLACEHOLDER;let s=this._canvases[e];s&&(s.remove(),this._canvases[e]=null)}onRendered(e,s,n){if(s!==this._renderGen){n.close();return}let t=e-1;if(t<0||t>=this._dims.length||this._states[t]!==m.RENDERING){n.close();return}this._inFlight--;let r=this._dims[t],i=this._wrappers[t],u=r.width*this._scale,a=r.height*this._scale,o=document.createElement("canvas");o.width=n.width,o.height=n.height,o.style.width=u+"px",o.style.height=a+"px",o.style.display="block";let c=o.getContext("bitmaprenderer");c?c.transferFromImageBitmap(n):(o.getContext("2d").drawImage(n,0,0),n.close()),i.style.width=u+"px",i.style.height=a+"px";let _=this._canvases[t];_&&_.remove(),i.appendChild(o),this._canvases[t]=o,this._states[t]=m.RENDERED}onScaleChange(e,s,n){this._scale=e,this._renderGen++;for(let t=0;t<this._dims.length;t++){let r=t+1,i=this._dims[t],u=this._wrappers[t],a=i.width*e,o=i.height*e;if(u.style.width=a+"px",u.style.height=o+"px",u.style.setProperty("zoom","1"),s.has(r)){let c=this._canvases[t];c&&(c.style.width=a+"px",c.style.height=o+"px"),this._states[t]===m.RENDERING&&this._inFlight--,this._states[t]=m.PLACEHOLDER}else{let c=this._canvases[t];c&&(c.remove(),this._canvases[t]=null),this._states[t]=m.PLACEHOLDER}}this.reconcile(s,n)}getCurrentPage(e){if(e.size>0)return Math.min(...e);let s=this._wrapper.parentElement?.getBoundingClientRect().top??0;for(let n of this._wrappers)if(n.getBoundingClientRect().bottom>s+4)return parseInt(n.dataset.page,10);return 1}};var R=class{constructor(e,s,n){this._visibleSet=new Set;this._bufferSet=new Set;this._visibleObserver=null;this._bufferObserver=null;this._rafPending=null;this._onChange=n,this._observe(e,s)}_observe(e,s){let n=()=>{this._rafPending===null&&(this._rafPending=requestAnimationFrame(()=>{this._rafPending=null;for(let t of this._visibleSet)this._bufferSet.add(t);this._onChange(new Set(this._bufferSet),new Set(this._visibleSet))}))};this._visibleObserver=new IntersectionObserver(t=>{for(let r of t){let i=parseInt(r.target.dataset.page,10);r.isIntersecting?this._visibleSet.add(i):this._visibleSet.delete(i)}n()},{root:e,rootMargin:"0px",threshold:0}),this._bufferObserver=new IntersectionObserver(t=>{for(let r of t){let i=parseInt(r.target.dataset.page,10);r.isIntersecting?this._bufferSet.add(i):this._bufferSet.delete(i)}n()},{root:e,rootMargin:"200% 0px",threshold:0});for(let t of s)this._visibleObserver.observe(t),this._bufferObserver.observe(t)}observe(e){this._visibleObserver?.observe(e),this._bufferObserver?.observe(e)}disconnect(){this._visibleObserver?.disconnect(),this._bufferObserver?.disconnect(),this._visibleSet.clear(),this._bufferSet.clear(),this._rafPending!==null&&(cancelAnimationFrame(this._rafPending),this._rafPending=null)}};var y=class y{constructor(e,s,n,t,r,i){this._debounce=null;this._rafPending=null;this._container=e,this._pm=s,this._onReRender=n,this._getBuffer=t,this._zoomLabel=r,this._scale=i,this._renderScale=i,this._updateLabel(),this._bindScrollZoom()}get scale(){return this._scale}clamp(e){return Math.max(y.ZOOM_MIN,Math.min(y.ZOOM_MAX,e))}_updateLabel(){this._zoomLabel.textContent=Math.round(this._scale*100)+"%"}applyScale(e,s,n){let t=this._container,r=this._scale;this._scale=this.clamp(e),this._updateLabel(),this._pm.setZooming(!0),s===void 0&&(s=t.clientHeight/2),n===void 0&&(n=t.clientWidth/2);let i=t.scrollTop+s,u=20,a=20;for(let h of this._pm.pageWrappers){let W=parseFloat(h.style.getPropertyValue("zoom")||"1")||1,C=parseFloat(h.style.height)*W;if(a+C>i)break;a+=C+12,u+=12}let o=this._scale/this._renderScale;for(let h of this._pm.pageWrappers)h.style.setProperty("zoom",String(o));let c=this._scale/r,_=t.scrollTop+s-u;t.scrollTop=Math.max(0,u+_*c-s),t.scrollLeft=Math.max(0,(t.scrollLeft+n)*c-n),this._scheduleReRender()}_scheduleReRender(){this._rafPending!==null&&cancelAnimationFrame(this._rafPending),this._rafPending=requestAnimationFrame(()=>{this._rafPending=null,this._debounce!==null&&clearTimeout(this._debounce),this._debounce=setTimeout(()=>this._triggerReRender(),250)})}_triggerReRender(){this._pm.setZooming(!1),this._renderScale=this._scale;let{bufferSet:e,visibleSet:s}=this._getBuffer();this._onReRender(this._scale,e,s)}_bindScrollZoom(){this._container.addEventListener("wheel",e=>{if(!e.ctrlKey)return;e.preventDefault();let s=this._container.getBoundingClientRect(),n=e.clientY-s.top,t=e.clientX-s.left;this.applyScale(this._scale*(e.deltaY<0?1.1:1/1.1),n,t)},{passive:!1})}};y.ZOOM_MIN=.1,y.ZOOM_MAX=5;var w=y;typeof requestIdleCallback>"u"&&(self.requestIdleCallback=l=>setTimeout(()=>l({timeRemaining:()=>50,didTimeout:!1}),1));var f=document.getElementById("canvas-container"),z=document.getElementById("pages-wrapper"),F=document.getElementById("status"),K=document.getElementById("zoom-label"),B=document.getElementById("page-indicator"),T=new URLSearchParams(location.search),M=T.get("ref_id")??"",I=parseFloat(T.get("zoom")??""),D=parseFloat(T.get("scroll_top")??""),x=window.devicePixelRatio||1,d=null,k=null,p=null,g=null,E=new Set,b=new Set;function P(l){F.textContent=l}function N(l){let e=document.getElementById("error-banner");e.textContent=l,e.style.display="block",P("Error")}function L(){if(!d)return;let l=d.getCurrentPage(b);B.textContent=`${l} / ${d.numPages}`}function A(l){if(!d)return;let e=d.pageWrappers[l-1];e&&(f.scrollTop+=e.getBoundingClientRect().top-f.getBoundingClientRect().top)}function H(){if(!p||window.parent===window)return;let l={type:"brittle:viewer-state",refId:M,zoom:p.scale,scrollTop:f.scrollTop};window.parent.postMessage(l,"*")}function Z(l,e,s){let n={type:"render",pageNum:l,scale:e,gen:s};g?.postMessage(n)}function V(l,e){E=l,b=e,d?.reconcile(l,e),L()}function S(l){let e=l[0]??{width:595,height:842};return Math.max(.1,Math.min(5,Math.min((f.clientWidth-40)/e.width,(f.clientHeight-40)/e.height)))}async function q(){if(!M){N("No ref_id in URL.");return}P("Loading\u2026");try{let e=await(await fetch("brittle://app/viewer/render-worker.bundle.js")).blob();g=new Worker(URL.createObjectURL(e));let s=await fetch(`brittle://app/pdf?ref_id=${encodeURIComponent(M)}`).then(a=>a.arrayBuffer()),{numPages:n,dims:t}=await new Promise((a,o)=>{g.onmessage=_=>{let h=_.data;h.type==="ready"&&a({numPages:h.numPages,dims:h.dims}),h.type==="error"&&o(new Error(h.message))},g.onerror=_=>o(new Error(_.message));let c={type:"init",pdfData:s};g.postMessage(c,[s])}),r=S(t),i=I>0?Math.max(.1,Math.min(5,I)):r;d=new v(z,t,i,x,Z),g.onmessage=a=>{let o=a.data;o.type==="rendered"?(d?.onRendered(o.pageNum,o.gen,o.bitmap),L(),d?.allRendered&&P("Ready")):o.type==="error"&&console.warn("[viewer] worker error:",o.message)},k=new R(f,[...d.pageWrappers],V),p=new w(f,d,(a,o,c)=>{d.onScaleChange(a,o,c),H()},()=>({bufferSet:E,visibleSet:b}),K,i),document.getElementById("btn-zoom-out").addEventListener("click",()=>p.applyScale(p.scale/1.25)),document.getElementById("btn-zoom-in").addEventListener("click",()=>p.applyScale(p.scale*1.25)),document.getElementById("btn-zoom-fit").addEventListener("click",()=>p.applyScale(S(t))),document.addEventListener("keydown",a=>{if(a.target.tagName!=="INPUT"&&((a.key==="+"||a.key==="=")&&(a.preventDefault(),p.applyScale(p.scale*1.25)),a.key==="-"&&(a.preventDefault(),p.applyScale(p.scale/1.25)),a.key==="0"&&(a.preventDefault(),p.applyScale(S(t))),window.parent!==window)){let o={type:"brittle:keydown",key:a.key,ctrlKey:a.ctrlKey,shiftKey:a.shiftKey,altKey:a.altKey,metaKey:a.metaKey};window.parent.postMessage(o,"*")}});let u=null;f.addEventListener("scroll",()=>{L(),u!==null&&clearTimeout(u),u=setTimeout(H,500)},{passive:!0}),D>0&&requestAnimationFrame(()=>{f.scrollTop=D}),window.addEventListener("message",a=>{a.data==="pdf.page.next"&&A(Math.min(d.getCurrentPage(b)+1,n)),a.data==="pdf.page.prev"&&A(Math.max(d.getCurrentPage(b)-1,1))}),document.addEventListener("visibilitychange",()=>{document.hidden?g?.postMessage({type:"cleanup"}):d?.reconcile(E,b)}),matchMedia(`(resolution: ${x}dppx)`).addEventListener("change",()=>{d&&p&&d.onScaleChange(p.scale,E,b)}),window.addEventListener("beforeunload",()=>{k?.disconnect(),g?.postMessage({type:"destroy"}),g=null}),B.textContent=`1 / ${n}`,P("Rendering\u2026")}catch(l){N("Could not load PDF: "+(l.message??String(l)))}}q();})();
|