@@ -250,12 +250,13 @@ const restoringView=ref(false);let currentRecentId=null,readingSaveTimer;
250250function readingView (){
251251 const el = reader .value ,p= pages .value [active .value - 1 ],host= p&& pageEls .get (p .number );if (! el||! host)return null ;
252252 const bounds = el .getBoundingClientRect (),box= host .getBoundingClientRect (),style= getComputedStyle (el);
253- return {page: p .number ,offsetX: Math .max (- 16 ,Math .min (16 ,(bounds .left + parseFloat (style .paddingLeft )- box .left )/ box .width )),offsetY: Math .max (- 16 ,Math .min (16 ,(bounds .top + parseFloat (style .paddingTop )- box .top )/ box .height )),zoom: zoom .value ,fit: fitMode .value ,direction: direction .value ,columns: columns .value ,sidebar: sidebar .value ,showTranslations: showTranslations .value };
253+ return {page: p .number ,offsetX: Math .max (- 16 ,Math .min (16 ,(bounds .left + parseFloat (style .paddingLeft )- box .left )/ box .width )),offsetY: Math .max (- 16 ,Math .min (16 ,(bounds .top + parseFloat (style .paddingTop )- box .top )/ box .height )),zoom: zoom .value ,fit: fitMode .value ,direction: direction .value ,columns: columns .value ,sidebar: sidebar .value ,sidebarMode : sidebarMode . value , showTranslations: showTranslations .value };
254254}
255255async function saveReadingView (){clearTimeout (readingSaveTimer);if (restoringView .value || loading .value )return ;const view = readingView ();if (view)try {if (currentRecentId){const id = currentRecentId,status= translationSnapshot ();await window .previewRecents ? .setView (id,view);await window .previewRecents ? .setTranslationStatus ? .(id,status);}await window .previewDocuments ? .saveView (view);}catch {error .value = t (' error.saveReadingPosition' );}}
256256function scheduleReadingSave (){if (restoringView .value || loading .value ||! currentRecentId)return ;clearTimeout (readingSaveTimer);readingSaveTimer= setTimeout (saveReadingView,180 );}
257257window .previewSaveReadingView = async ()=> {await annotationWrites;await performanceRecorder .finish ();await saveReadingView ();};
258258async function restoreReadingView (view ){
259+ sidebarMode .value = view? .sidebarMode === ' outline' && documentOutline .value .length ? ' outline' : view? .sidebarMode === ' annotations' && annotations .value .length ? ' annotations' : ' thumbnails' ;
259260 if (view){direction .value = view .direction ;columns .value = view .columns ;sidebar .value = view .sidebar ;showTranslations .value = view .showTranslations ;fitMode .value = view .fit ;zoom .value = view .zoom ;active .value = Math .min (pages .value .length ,Math .max (1 ,view .page ));pageEntry .value = active .value ;}
260261 mountAroundPage (active .value );await nextTick ();
261262 if (documentOpening .value )await new Promise (resolve => requestAnimationFrame (resolve));
@@ -557,7 +558,7 @@ async function closeDocument(closeStartPage=false){
557558 }finally{await sidebarMotion;capture?.element.remove();if(documentMotionController===controller)documentMotionController=null;documentClosing.value=false;closingDocument=false;}
558559}
559560async function closeDocumentNow(){
560- referenceReturn.value=null;referenceNavigation++;const documentToken=epoch;await annotationWrites;annotations.value=[];showAnnotations.value=true;annotationKey.value='';sidebarMode.value='thumbnails';documentOutline.value=[];selectedAnnotation.value=null;await performanceRecorder.finish();await saveReadingView ();await window.previewDocuments?.closed();if(documentToken!==epoch)return;currentRecentId=null;
561+ referenceReturn.value=null;referenceNavigation++;const documentToken=epoch;await annotationWrites;await saveReadingView(); annotations.value=[];showAnnotations.value=true;annotationKey.value='';sidebarMode.value='thumbnails';documentOutline.value=[];selectedAnnotation.value=null;await performanceRecorder.finish();await window.previewDocuments?.closed();if(documentToken!==epoch)return;currentRecentId=null;
561562 cancel();const closingToken=epoch;closeSearch();await releaseDocument();if(closingToken!==epoch)return;clearTimeout(timer);clearTimeout(navigatorTimer);cancelAnimationFrame(fitFrame);fitFrame=0;clearTimeout(fitResizeTimer);fitResizing=false;
562563 dismissPopovers();resetBitmaps();
563564 const tasks=new Set([pendingPDFTask,pdf?.loadingTask,...pages.value.map(page=>page.mathDocument?.loadingTask)].filter(Boolean));
@@ -579,16 +580,16 @@ async function importFile(file,ticket,origin){
579580 if(file&&!ticket&&(pages.value.length||loading.value)&&window.previewDocuments?.open){try{await window.previewDocuments.open(file);}catch(e){error.value=e.message;}return;}
580581 if(!file)return;closeSearch();if(testMode&&!['A quieter way to read.pdf','Portrait and landscape.pdf'].includes(file.name)){error.value=t('error.testDocumentsDisabled');return;}if(file.size>50*1024*1024){error.value=t('error.PDFTooLarge');return;}
581582 documentMotionController?.abort();documentOpening.value=!!origin&&!documentMotionReduced();
582- referenceReturn.value=null;referenceNavigation++;await annotationWrites;annotations.value=[];showAnnotations.value=true;annotationKey.value='';sidebarMode.value='thumbnails';documentOutline.value=[];selectedAnnotation.value=null;await performanceRecorder.start(file.size);const runtimeReady=ensurePDF();await saveReadingView ();currentRecentId=null;restoringView.value=true;selectedParagraph.value=null;cancel();const token=epoch;await releaseDocument();if(token!==epoch)return;resetBitmaps();renderMetrics.openedAt=performance.now();renderMetrics.firstPageMs=null;loading.value=true;error.value='';for(const p of pages.value)p.mathDocument?.loadingTask.destroy();pages.value=[];pageEls.clear();canvasEls.clear();thumbEls.clear();
583+ referenceReturn.value=null;referenceNavigation++;await annotationWrites;await saveReadingView(); annotations.value=[];showAnnotations.value=true;annotationKey.value='';sidebarMode.value='thumbnails';documentOutline.value=[];selectedAnnotation.value=null;await performanceRecorder.start(file.size);const runtimeReady=ensurePDF();currentRecentId=null;restoringView.value=true;selectedParagraph.value=null;cancel();const token=epoch;await releaseDocument();if(token!==epoch)return;resetBitmaps();renderMetrics.openedAt=performance.now();renderMetrics.firstPageMs=null;loading.value=true;error.value='';for(const p of pages.value)p.mathDocument?.loadingTask.destroy();pages.value=[];pageEls.clear();canvasEls.clear();thumbEls.clear();
583584 try{
584585 bytes=new Uint8Array(await file.arrayBuffer());let imported={annotations:[],nativeRefs:[]};if(window.previewAnnotations?.prepare){imported=await window.previewAnnotations.prepare(bytes);bytes=imported.bytes;}else if(window.previewAnnotations?.clean)bytes=await window.previewAnnotations.clean(bytes);performanceRecorder.mark('fileRead');if(token!==epoch)return;await pdf?.loadingTask.destroy();if(token!==epoch)return;
585586 const registered=await api('/api/documents',{method:'POST',headers:{'Content-Type':'application/pdf'},body:bytes});if(token!==epoch){await api('/api/documents/'+registered.id,{method:'DELETE'});return;}documentId=registered.id;performanceRecorder.mark('upload');
586- await runtimeReady;const task=getDocument({data:bytes});pendingPDFTask=task;const loaded=await task.promise;if(token!==epoch){void task.destroy();return;}pdf=markRaw(loaded);void loadOutline(pdf,token);performanceRecorder.mark('pdfReady');performanceRecorder.pages(pdf.numPages);bytes=undefined;if(pendingPDFTask===task)pendingPDFTask=undefined;
587+ await runtimeReady;const task=getDocument({data:bytes});pendingPDFTask=task;const loaded=await task.promise;if(token!==epoch){void task.destroy();return;}pdf=markRaw(loaded);const outlineReady= loadOutline(pdf,token);performanceRecorder.mark('pdfReady');performanceRecorder.pages(pdf.numPages);bytes=undefined;if(pendingPDFTask===task)pendingPDFTask=undefined;
587588 showTranslations.value=documentOpenMode.value==='translation';translationDeferred.value=documentOpenMode.value==='manual';title.value=(testMode?'TEST — ':'')+file.name;active.value=1;const list=[];
588589 for(let first=1;first<=pdf.numPages;first+=16){const numbers=Array.from({length:Math.min(16,pdf.numPages-first+1)},(_,i)=>first+i),batch=await Promise.all(numbers.map(n=>pdf.getPage(n)));if(token!==epoch)return;for(let i=0;i<batch.length;i++){const v=batch[i].getViewport({scale:1});list.push(reactive({number:numbers[i],width:v.width,height:v.height,status:'idle',blocks:[],cached:false,translationModel:'',dwell:0}));}}
589590 performanceRecorder.mark('pageGeometry');let saved;
590591 if(window.previewRecents)try{const result=await window.previewRecents.remember(file,ticket);if(token!==epoch)return;recentDocuments.value=result.entries;currentRecentId=result.recentId;saved=result.view;}catch{if(token===epoch)error.value=t('error.saveRecentHistory');}
591- annotationKey.value=currentRecentId||pdf.fingerprints[0];try{const stored=window.previewAnnotations?.loadState?await window.previewAnnotations.loadState(annotationKey.value):{annotations:window.previewAnnotations?await window.previewAnnotations.load(annotationKey.value):JSON.parse(localStorage.getItem('annotations:'+annotationKey.value)||'[]'),nativeRefs:[]};annotationNativeRefs.value=[...new Set([...stored.nativeRefs,...imported.nativeRefs])];annotations.value=[...stored.annotations,...imported.annotations.filter(a=>!stored.annotations.some(b=>b.id===a.id)&&(!a.nativeRef||!stored.nativeRefs.includes(a.nativeRef)))];}catch(e){error.value='无法读取批注:'+e.message;}if(token!==epoch)return;await recoverHighlightedText(pdf,annotations.value);if(token!==epoch)return;performanceRecorder.mark('recentHistory');pages.value=list;await restoreReadingView(saved&&documentOpenMode.value==='manual'?{...saved,showTranslations:false}:saved);if(showTranslations.value)translationDeferred.value=false;performanceRecorder.mark('restoreView');if(token!==epoch)return;observe();observeThumbnails();await renderPages();if(token!==epoch)return;restoringView.value=false;loading.value=false;saveView();await nextTick();
592+ annotationKey.value=currentRecentId||pdf.fingerprints[0];try{const stored=window.previewAnnotations?.loadState?await window.previewAnnotations.loadState(annotationKey.value):{annotations:window.previewAnnotations?await window.previewAnnotations.load(annotationKey.value):JSON.parse(localStorage.getItem('annotations:'+annotationKey.value)||'[]'),nativeRefs:[]};annotationNativeRefs.value=[...new Set([...stored.nativeRefs,...imported.nativeRefs])];annotations.value=[...stored.annotations,...imported.annotations.filter(a=>!stored.annotations.some(b=>b.id===a.id)&&(!a.nativeRef||!stored.nativeRefs.includes(a.nativeRef)))];}catch(e){error.value='无法读取批注:'+e.message;}if(token!==epoch)return;await recoverHighlightedText(pdf,annotations.value);if(token!==epoch)return;performanceRecorder.mark('recentHistory');await outlineReady;if(token!==epoch)return;pages.value=list;await restoreReadingView(saved&&documentOpenMode.value==='manual'?{...saved,showTranslations:false}:saved);if(showTranslations.value)translationDeferred.value=false;performanceRecorder.mark('restoreView');if(token!==epoch)return;observe();observeThumbnails();await renderPages();if(token!==epoch)return;restoringView.value=false;loading.value=false;saveView();await nextTick();
592593 if(origin&&!documentMotionReduced()){
593594 const host=pageEls.get(active.value),capture=captureDocumentPage(host);
594595 if(capture){const controller=new AbortController();documentMotionController=controller;const visibility=host.style.visibility;host.style.visibility='hidden';
@@ -778,7 +779,7 @@ watch(sidebar,()=>{if(!restoringView.value)nextTick(()=>{observeThumbnails();res
778779watch(title,value=>{document.title=value;});
779780watch(zoom,async()=>{if(restoringView.value)return;revealControllers.forEach(c=>c.abort());revealControllers.clear();localStorage.setItem('readerZoom',String(zoom.value));if(document.activeElement!==zoomInput.value)zoomEntry.value=formatPercentValue(zoom.value);const request=zoomRequest;zoomRequest=null;if(request&&!pinching.value&&!fitResizing){await applyRequestedZoom({...request,to:zoom.value});}else if(!pinching.value&&!fitResizing){await nextTick();await renderPages();}});watch(concurrency,pump);watch(automatic,()=>{if(automatic.value)settle();});watch(showTranslations,v=>{if(restoringView.value)return;if(v&&translationDeferred.value){translationDeferred.value=false;settle();}for(const p of pages.value)for(const b of p.blocks)b.translated=v;if(engine.value!=='pdf_inspector'){revealControllers.forEach(c=>c.abort());revealControllers.clear();renderPages(true);}});
780781function visibility(){updateForeground();if(foreground.value){settle();pumpPages();pump();}}
781- watch([active,zoom,direction,columns,fitMode,sidebar,showTranslations],scheduleReadingSave);
782+ watch([active,zoom,direction,columns,fitMode,sidebar,sidebarMode, showTranslations],scheduleReadingSave);
782783onMounted(async()=>{if(window.previewActivity){stopActivity=window.previewActivity.onChange(value=>{activityActive.value=value;visibility();});activityActive.value=await window.previewActivity.current();foreground.value=activityActive.value&&!pageHidden();window.previewActivityActive=foreground.value;}if(window.previewRecents){recentDocuments.value=await window.previewRecents.list();scheduleRecentPreviews();}if(window.previewWindow){stopFullscreen=window.previewWindow.onFullscreen(value=>fullscreen.value=value);if(['win32','linux'].includes(platform)){stopMaximized=window.previewWindow.onMaximized(value=>maximized.value=value);maximized.value=await window.previewWindow.maximized();}fullscreen.value=await window.previewWindow.fullscreen();}reader.value?.addEventListener('wheel',pinchWheel,{passive:false});document.addEventListener('keydown',keyboard);document.addEventListener('pointerdown',outsidePopover);document.addEventListener('focusin',outsidePopover);window.addEventListener('blur',dismissPopovers);stopActions=window.previewActions?.onAction(readerAction);if(window.previewPreferences){const saved=await window.previewPreferences.load();applySavedSettings(saved);stopPreferences=window.previewPreferences.onChange?.(applySavedSettings);applyAppearance(saved);engine.value=saved.engine||'pdf_inspector';direction.value=saved.direction||'vertical';columns.value=saved.columns||1;fitMode.value=saved.fit;translationMode.value=saved.translationMode||'reading';if(saved.fit==='manual'){zoom.value=saved.zoom;zoomEntry.value=formatPercentValue(zoom.value);}}await nextTick();syncScrubInputs();loadingPreferences=false;window.addEventListener('resize',resizeFit);resizeObserver=new ResizeObserver(resizeFit);if(reader.value)resizeObserver.observe(reader.value,{box:'content-box'});if(window.previewAppearance){applyAppearance(await window.previewAppearance.current());stopAppearance=window.previewAppearance.onChange(applyAppearance);}const engineReady=checkEngine().then(()=>settle());const c=await api('/api/config');applyConfig(c);model.value=c.model;if(window.previewDocuments){stopDocuments=window.previewDocuments.onAvailable(receiveDocuments);await receiveDocuments();}document.addEventListener('visibilitychange',visibility);settle();scheduleRecentPreviews();if(testMode){await engineReady;window.previewReady=true;}});
783784onBeforeUnmount(()=>{clearTimeout(recentPreviewTimer);clearInterval(sessionTimer);documentMotionController?.abort();clearTimeout(immersiveLightsTimer);clearTimeout(copyToastTimer);clearTimeout(annotationToastTimer);closeSearch();cancelResize();performanceRecorder.destroy();stopActivity?.();void releaseDocument();void saveReadingView();clearTimeout(readingSaveTimer);delete window.previewSaveReadingView;++recentPreviewGeneration;stopFullscreen?.();stopMaximized?.();reader.value?.removeEventListener('wheel',pinchWheel);cancelAnimationFrame(pinchFrame);clearTimeout(pinchTimer);document.removeEventListener('keydown',keyboard);document.removeEventListener('pointerdown',outsidePopover);document.removeEventListener('focusin',outsidePopover);window.removeEventListener('blur',dismissPopovers);stopActions?.();resizeObserver?.disconnect();window.removeEventListener('resize',resizeFit);cancelAnimationFrame(fitFrame);clearTimeout(fitResizeTimer);clearTimeout(navigatorTimer);scrollbarTimers.forEach(clearTimeout);scrollbarTimers.clear();clearTimeout(previewTimer);clearTimeout(zoomRenderTimer);scrubbers.forEach(entry=>entry.controller.destroy());scrubbers.clear();finishZoomAnimation();cancelAnimationFrame(viewportFrame);resetBitmaps();stopAppearance?.();stopPreferences?.();stopDocuments?.();cancel();clearTimeout(timer);void Promise.allSettled([pdf?.loadingTask,pendingPDFTask,...pages.value.map(p=>p.mathDocument?.loadingTask)].filter(Boolean).map(task=>task.destroy())).then(()=>pdfWorker?.destroy());document.removeEventListener('visibilitychange',visibility);});
784785</script>
0 commit comments