mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 14:43:46 +01:00
[web] Cleanup PDFjs instances in visual editor (#33022)
GitOrigin-RevId: 2aa9ab01f88196fb56dc41749977ca33295c964f
This commit is contained in:
committed by
Copybot
parent
5c7db11d9b
commit
5e675664c6
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Coordinates PDF.js document destroys across GraphicsWidget instances.
|
||||
*
|
||||
* PDF.js uses a single shared worker (GlobalWorkerOptions.workerPort) and
|
||||
* rejects getDocument while any previous PDFDocumentLoadingTask.destroy()
|
||||
* are in flight.
|
||||
*/
|
||||
export class PdfDestroyLock {
|
||||
private readonly pendingDestroys = new Set<Promise<unknown>>()
|
||||
|
||||
/** Resolves once no pdf.destroy() is in flight. */
|
||||
async waitForPending(): Promise<void> {
|
||||
// Loop in case a new destroy is scheduled while we await existing ones.
|
||||
while (this.pendingDestroys.size > 0) {
|
||||
await Promise.all(this.pendingDestroys)
|
||||
}
|
||||
}
|
||||
|
||||
/** Registers an in-flight destroy so waitForPending() will wait for it. */
|
||||
schedule<T>(destroyFn: () => Promise<T>): Promise<T> {
|
||||
const task = destroyFn()
|
||||
this.pendingDestroys.add(task)
|
||||
task.finally(() => this.pendingDestroys.delete(task))
|
||||
return task
|
||||
}
|
||||
}
|
||||
+41
-2
@@ -4,10 +4,24 @@ import { isEqual } from 'lodash'
|
||||
import { FigureData } from '../../figure-modal'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import { PreviewPath } from '../../../../../../../types/preview-path'
|
||||
import type { PDFDocumentProxy } from 'pdfjs-dist/types/src/display/api'
|
||||
import { PdfDestroyLock } from '../utils/pdf-destroy-lock'
|
||||
|
||||
// Module level to synchronize across all GraphicsWidgets
|
||||
const pdfDestroyLock = new PdfDestroyLock()
|
||||
|
||||
function schedulePdfDestroy(pdf: PDFDocumentProxy) {
|
||||
pdfDestroyLock.schedule(() =>
|
||||
pdf.destroy().catch(() => {
|
||||
debugConsole.warn('Failed to destroy PDFjs instance')
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export class GraphicsWidget extends WidgetType {
|
||||
destroyed = false
|
||||
height = 300 // for estimatedHeight, updated when the image is loaded
|
||||
pdfInstance: PDFDocumentProxy | null = null
|
||||
|
||||
constructor(
|
||||
public filePath: string,
|
||||
@@ -54,6 +68,10 @@ export class GraphicsWidget extends WidgetType {
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if (this.pdfInstance) {
|
||||
schedulePdfDestroy(this.pdfInstance)
|
||||
this.pdfInstance = null
|
||||
}
|
||||
this.renderGraphic(element, view)
|
||||
view.requestMeasure()
|
||||
return true
|
||||
@@ -72,6 +90,10 @@ export class GraphicsWidget extends WidgetType {
|
||||
|
||||
destroy() {
|
||||
this.destroyed = true
|
||||
if (this.pdfInstance) {
|
||||
schedulePdfDestroy(this.pdfInstance)
|
||||
this.pdfInstance = null
|
||||
}
|
||||
}
|
||||
|
||||
coordsAt(element: HTMLElement) {
|
||||
@@ -104,7 +126,11 @@ export class GraphicsWidget extends WidgetType {
|
||||
{
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.classList.add('ol-cm-graphics')
|
||||
this.renderPDF(view, canvas, preview.url).catch(debugConsole.error)
|
||||
this.renderPDF(view, canvas, preview.url).catch(err => {
|
||||
if (!this.destroyed) {
|
||||
debugConsole.error('Failed to render PDF graphics widget', err)
|
||||
}
|
||||
})
|
||||
element.append(canvas)
|
||||
}
|
||||
break
|
||||
@@ -249,10 +275,23 @@ export class GraphicsWidget extends WidgetType {
|
||||
return
|
||||
}
|
||||
|
||||
await pdfDestroyLock.waitForPending()
|
||||
if (this.destroyed) {
|
||||
return
|
||||
}
|
||||
|
||||
const pdf = await loadPdfDocumentFromUrl(url).promise
|
||||
const page = await pdf.getPage(1)
|
||||
this.pdfInstance = pdf
|
||||
|
||||
// bail out if loading the PDF took too long
|
||||
if (this.destroyed) {
|
||||
schedulePdfDestroy(pdf)
|
||||
this.pdfInstance = null
|
||||
return
|
||||
}
|
||||
|
||||
const page = await pdf.getPage(1)
|
||||
|
||||
if (this.destroyed) {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user