diff --git a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.scss b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.scss index d5dd05bd9..078c73b38 100644 --- a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.scss +++ b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.scss @@ -154,10 +154,23 @@ & section { position: absolute; text-align: initial; + pointer-events: auto; box-sizing: border-box; transform-origin: 0 0; } + & :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a { + position: absolute; + inset: 0; + font-size: 1em; + } + + & :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) + > a:hover { + opacity: 0.2; + background-color: rgb(255 255 0); + } + & .annotationTextContent { opacity: 0; } diff --git a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts index 93649394a..bb64cee1f 100644 --- a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts +++ b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts @@ -1,7 +1,11 @@ import { SimpleChange } from '@angular/core' import { ComponentFixture, TestBed } from '@angular/core/testing' import * as pdfjs from 'pdfjs-dist/legacy/build/pdf.mjs' -import { PDFSinglePageViewer, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs' +import { + LinkTarget, + PDFSinglePageViewer, + PDFViewer, +} from 'pdfjs-dist/web/pdf_viewer.mjs' import { PngxPdfViewerComponent } from './pdf-viewer.component' import { PdfRenderMode, PdfZoomLevel, PdfZoomScale } from './pdf-viewer.types' @@ -58,6 +62,16 @@ describe('PngxPdfViewerComponent', () => { expect((component as any).pdfViewer).toBeInstanceOf(PDFViewer) }) + it('opens external links in a new tab', () => { + const linkService = (component as any).linkService + expect(linkService.options).toEqual( + expect.objectContaining({ + externalLinkTarget: LinkTarget.BLANK, + externalLinkRel: 'noopener noreferrer nofollow', + }) + ) + }) + it('resolves the worker source relative to the document base URI', async () => { setBaseHref('/paperless/') const getDocumentSpy = jest.spyOn(pdfjs, 'getDocument') diff --git a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts index 959ea3011..a4a9dbd19 100644 --- a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts +++ b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts @@ -21,6 +21,7 @@ import { } from 'pdfjs-dist/legacy/build/pdf.mjs' import { EventBus, + LinkTarget, PDFFindController, PDFLinkService, PDFSinglePageViewer, @@ -75,7 +76,11 @@ export class PngxPdfViewerComponent private lastViewerPage?: number private readonly eventBus = new EventBus() - private readonly linkService = new PDFLinkService({ eventBus: this.eventBus }) + private readonly linkService = new PDFLinkService({ + eventBus: this.eventBus, + externalLinkTarget: LinkTarget.BLANK, + externalLinkRel: 'noopener noreferrer nofollow', + }) private readonly findController = new PDFFindController({ eventBus: this.eventBus, linkService: this.linkService, diff --git a/src-ui/src/test/mocks/pdfjs-web-pdf_viewer.ts b/src-ui/src/test/mocks/pdfjs-web-pdf_viewer.ts index 601b05caf..18e30e8aa 100644 --- a/src-ui/src/test/mocks/pdfjs-web-pdf_viewer.ts +++ b/src-ui/src/test/mocks/pdfjs-web-pdf_viewer.ts @@ -25,10 +25,20 @@ export class PDFFindController { onIsPageVisible?: () => boolean } +export const LinkTarget = { + NONE: 0, + SELF: 1, + BLANK: 2, + PARENT: 3, + TOP: 4, +} + export class PDFLinkService { private document?: unknown private viewer?: unknown + constructor(readonly options: Record = {}) {} + setDocument(document: unknown): void { this.document = document }