@libresign/pdf-elements 1.0.1 → 1.1.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@libresign/pdf-elements",
3
3
  "description": "PDF viewer with draggable and resizable element overlays for Vue 3",
4
- "version": "1.0.1",
4
+ "version": "1.1.0",
5
5
  "author": "LibreCode <contact@librecode.coop>",
6
6
  "private": false,
7
7
  "main": "dist/index.js",
@@ -23,14 +23,19 @@ SPDX-License-Identifier: AGPL-3.0-or-later
23
23
  />
24
24
  <div
25
25
  class="overlay"
26
+ :role="isAddingMode ? 'button' : undefined"
27
+ :tabindex="isAddingMode ? 0 : -1"
28
+ :aria-label="getOverlayAriaLabel(docIndex, pIndex)"
26
29
  @mousemove="handleMouseMove"
27
30
  @touchmove="handleMouseMove"
28
31
  @click="handleOverlayClick(docIndex, pIndex, $event)"
29
32
  @touchend="handleOverlayClick(docIndex, pIndex, $event)"
33
+ @keydown="handleOverlayKeyDown(docIndex, pIndex, $event)"
30
34
  >
31
35
  <div
32
36
  v-if="isAddingMode && previewPageDocIndex === docIndex && previewPageIndex === pIndex && previewElement && previewVisible"
33
37
  class="preview-element"
38
+ aria-hidden="true"
34
39
  :style="{
35
40
  left: `${previewPosition.x * previewScale.x}px`,
36
41
  top: `${previewPosition.y * previewScale.y}px`,
@@ -217,6 +222,10 @@ export default defineComponent({
217
222
  type: Boolean,
218
223
  default: false,
219
224
  },
225
+ pageAriaLabel: {
226
+ type: Function as PropType<(info: { docIndex: number; docName: string; totalDocs: number; pageNumber: number; totalPages: number; isAddingMode: boolean }) => string>,
227
+ default: null,
228
+ },
220
229
  pdfjsOptions: {
221
230
  type: Object as PropType<Record<string, unknown>>,
222
231
  default: () => ({}),
@@ -730,6 +739,42 @@ export default defineComponent({
730
739
  }
731
740
  },
732
741
 
742
+ getOverlayAriaLabel(docIndex, pageIndex) {
743
+ const doc = this.pdfDocuments?.[docIndex]
744
+ const docName = doc?.name ?? `Document ${docIndex + 1}`
745
+ const totalDocs = this.pdfDocuments?.length ?? 1
746
+ const totalPages = doc?.numPages ?? 0
747
+ const pageNumber = pageIndex + 1
748
+ if (this.pageAriaLabel) {
749
+ return this.pageAriaLabel({ docIndex, docName, totalDocs, pageNumber, totalPages, isAddingMode: this.isAddingMode })
750
+ }
751
+ const docPrefix = totalDocs > 1 ? `Document ${docIndex + 1} of ${totalDocs} (${docName}), ` : ''
752
+ if (this.isAddingMode) {
753
+ return `${docPrefix}Page ${pageNumber} of ${totalPages}. Press Enter or Space to place here.`
754
+ }
755
+ return `${docPrefix}Page ${pageNumber} of ${totalPages}.`
756
+ },
757
+
758
+ handleOverlayKeyDown(docIndex, pageIndex, event) {
759
+ if (!this.isAddingMode || !this.previewElement) return
760
+ if (event.key !== 'Enter' && event.key !== ' ') return
761
+ event.preventDefault()
762
+
763
+ const pageWidth = this.getPageWidth(docIndex, pageIndex)
764
+ const pageHeight = this.getPageHeight(docIndex, pageIndex)
765
+ const scale = this.getDisplayedPageScale(docIndex, pageIndex) || 1
766
+
767
+ this.previewPageDocIndex = docIndex
768
+ this.previewPageIndex = pageIndex
769
+ this.previewScale = { x: scale, y: scale }
770
+ this.previewPosition = {
771
+ x: Math.round((pageWidth - this.previewElement.width) / 2),
772
+ y: Math.round((pageHeight - this.previewElement.height) / 2),
773
+ }
774
+ this.previewVisible = true
775
+ this.finishAdding()
776
+ },
777
+
733
778
  handleWheel(event) {
734
779
  if (!event.ctrlKey) return
735
780
  event.preventDefault()
@@ -8,9 +8,16 @@ let pdfjsPromise: Promise<typeof import('pdfjs-dist')> | null = null
8
8
  let workerUrlPromise: Promise<string> | null = null
9
9
  let workerSrcOverride: string | null = null
10
10
 
11
+ type PdfjsModule = typeof import('pdfjs-dist')
12
+
13
+ function normalizePdfjs(mod: PdfjsModule): PdfjsModule {
14
+ const m = mod as PdfjsModule & { default?: PdfjsModule }
15
+ return (m.default?.PDFWorker ? m.default : m) as PdfjsModule
16
+ }
17
+
11
18
  function loadPdfjs() {
12
19
  if (!pdfjsPromise) {
13
- pdfjsPromise = import('pdfjs-dist')
20
+ pdfjsPromise = import('pdfjs-dist').then(normalizePdfjs)
14
21
  }
15
22
  return pdfjsPromise
16
23
  }
@@ -24,7 +31,10 @@ function loadWorkerUrl() {
24
31
  return workerUrlPromise
25
32
  }
26
33
 
27
- async function ensureWorkerSrc(pdfjs: typeof import('pdfjs-dist')) {
34
+ async function ensureWorkerSrc(pdfjs: PdfjsModule) {
35
+ if (!pdfjs?.GlobalWorkerOptions) {
36
+ return
37
+ }
28
38
  if (workerSrcOverride) {
29
39
  pdfjs.GlobalWorkerOptions.workerSrc = workerSrcOverride
30
40
  return
@@ -34,7 +44,7 @@ async function ensureWorkerSrc(pdfjs: typeof import('pdfjs-dist')) {
34
44
  }
35
45
  }
36
46
 
37
- async function getSharedWorker(pdfjs: typeof import('pdfjs-dist')): Promise<PDFWorker> {
47
+ async function getSharedWorker(pdfjs: PdfjsModule): Promise<PDFWorker> {
38
48
  if (!sharedWorker) {
39
49
  await ensureWorkerSrc(pdfjs)
40
50
  sharedWorker = new pdfjs.PDFWorker({}) as PDFWorker
@@ -44,9 +54,14 @@ async function getSharedWorker(pdfjs: typeof import('pdfjs-dist')): Promise<PDFW
44
54
 
45
55
  export function setWorkerPath(path: string) {
46
56
  workerSrcOverride = path
57
+ sharedWorker = null
47
58
  if (pdfjsPromise) {
48
59
  pdfjsPromise.then((pdfjs) => {
49
- pdfjs.GlobalWorkerOptions.workerSrc = path
60
+ if (pdfjs?.GlobalWorkerOptions) {
61
+ pdfjs.GlobalWorkerOptions.workerSrc = path
62
+ }
63
+ }).catch((error) => {
64
+ console.warn('setWorkerPath: failed to update pdfjs workerSrc immediately', error)
50
65
  })
51
66
  }
52
67
  }