@libresign/pdf-elements 0.2.5 → 0.3.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/README.md +1 -1
- package/dist/pdf-elements.common.js +110 -15
- package/dist/pdf-elements.common.js.map +1 -1
- package/dist/pdf-elements.css +1 -1
- package/dist/pdf-elements.umd.js +110 -15
- package/dist/pdf-elements.umd.js.map +1 -1
- package/dist/pdf-elements.umd.min.js +2 -2
- package/dist/pdf-elements.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DraggableElement.vue +23 -2
- package/src/components/PDFElements.vue +65 -0
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 2",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"author": "LibreCode <contact@librecode.coop>",
|
|
6
6
|
"private": false,
|
|
7
7
|
"main": "dist/pdf-elements.umd.js",
|
|
@@ -10,7 +10,12 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
10
10
|
class="actions-toolbar"
|
|
11
11
|
:style="toolbarStyle"
|
|
12
12
|
>
|
|
13
|
-
<slot name="actions" :object="object" :onDelete="onDelete">
|
|
13
|
+
<slot name="actions" :object="object" :onDelete="onDelete" :onDuplicate="onDuplicate">
|
|
14
|
+
<button class="action-btn" type="button" title="Duplicate" @click.stop="onDuplicate">
|
|
15
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
|
16
|
+
<path d="M16 1H6a2 2 0 0 0-2 2v12h2V3h10V1zm3 4H10a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 16H10V7h9v14z"/>
|
|
17
|
+
</svg>
|
|
18
|
+
</button>
|
|
14
19
|
<button class="action-btn" type="button" title="Delete" @click.stop="onDelete">
|
|
15
20
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
|
16
21
|
<path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.5a.5.5 0 0 0 0 1h.5v10.5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5V3.5h.5a.5.5 0 0 0 0-1H11Zm1 1v10.5a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5V3.5h8Z"/>
|
|
@@ -77,6 +82,10 @@ export default {
|
|
|
77
82
|
type: Function,
|
|
78
83
|
default: () => {},
|
|
79
84
|
},
|
|
85
|
+
onDuplicate: {
|
|
86
|
+
type: Function,
|
|
87
|
+
default: () => {},
|
|
88
|
+
},
|
|
80
89
|
onDragStart: {
|
|
81
90
|
type: Function,
|
|
82
91
|
default: () => {},
|
|
@@ -124,7 +133,11 @@ export default {
|
|
|
124
133
|
readOnly: {
|
|
125
134
|
type: Boolean,
|
|
126
135
|
default: false,
|
|
127
|
-
}
|
|
136
|
+
},
|
|
137
|
+
ignoreClickOutsideSelectors: {
|
|
138
|
+
type: Array,
|
|
139
|
+
default: () => [],
|
|
140
|
+
},
|
|
128
141
|
},
|
|
129
142
|
data() {
|
|
130
143
|
return {
|
|
@@ -237,6 +250,14 @@ export default {
|
|
|
237
250
|
this.startDrag(event)
|
|
238
251
|
},
|
|
239
252
|
handleClickOutside(event) {
|
|
253
|
+
const selectors = Array.isArray(this.ignoreClickOutsideSelectors)
|
|
254
|
+
? this.ignoreClickOutsideSelectors
|
|
255
|
+
: []
|
|
256
|
+
for (const selector of selectors) {
|
|
257
|
+
if (selector && event?.target?.closest?.(selector)) {
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
}
|
|
240
261
|
if (this.$el && !this.$el.contains(event.target)) {
|
|
241
262
|
this.isSelected = false
|
|
242
263
|
}
|
|
@@ -60,6 +60,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
60
60
|
:read-only="readOnly"
|
|
61
61
|
:on-update="(payload) => updateObject(docIndex, object.id, payload)"
|
|
62
62
|
:on-delete="() => deleteObject(docIndex, object.id)"
|
|
63
|
+
:on-duplicate="() => duplicateObject(docIndex, object.id)"
|
|
63
64
|
:on-drag-start="(mouseX, mouseY, pointerOffset, dragShift) => startDraggingElement(docIndex, pIndex, object, mouseX, mouseY, pointerOffset, dragShift)"
|
|
64
65
|
:on-drag-move="updateDraggingPosition"
|
|
65
66
|
:on-drag-end="stopDraggingElement"
|
|
@@ -71,6 +72,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
71
72
|
:global-drag-page-index="draggingPageIndex"
|
|
72
73
|
:show-selection-ui="showSelectionHandles && !hideSelectionUI && object.resizable !== false"
|
|
73
74
|
:show-default-actions="showElementActions && !hideSelectionUI"
|
|
75
|
+
:ignore-click-outside-selectors="ignoreClickOutsideSelectors"
|
|
74
76
|
>
|
|
75
77
|
<template #default="slotProps">
|
|
76
78
|
<slot
|
|
@@ -92,6 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
92
94
|
name="actions"
|
|
93
95
|
:object="slotProps.object"
|
|
94
96
|
:onDelete="slotProps.onDelete"
|
|
97
|
+
:onDuplicate="slotProps.onDuplicate"
|
|
95
98
|
/>
|
|
96
99
|
</template>
|
|
97
100
|
</DraggableElement>
|
|
@@ -191,6 +194,10 @@ export default {
|
|
|
191
194
|
type: Boolean,
|
|
192
195
|
default: false,
|
|
193
196
|
},
|
|
197
|
+
ignoreClickOutsideSelectors: {
|
|
198
|
+
type: Array,
|
|
199
|
+
default: () => [],
|
|
200
|
+
},
|
|
194
201
|
pageCountFormat: {
|
|
195
202
|
type: String,
|
|
196
203
|
default: '{currentPage} of {totalPages}',
|
|
@@ -940,6 +947,64 @@ export default {
|
|
|
940
947
|
})
|
|
941
948
|
}
|
|
942
949
|
},
|
|
950
|
+
duplicateObject(docIndex, objectId) {
|
|
951
|
+
if (docIndex < 0 || docIndex >= this.pdfDocuments.length) return
|
|
952
|
+
const doc = this.pdfDocuments[docIndex]
|
|
953
|
+
|
|
954
|
+
const cacheKey = `${docIndex}-${objectId}`
|
|
955
|
+
let pageIndex = this.objectIndexCache[cacheKey]
|
|
956
|
+
|
|
957
|
+
if (pageIndex === undefined) {
|
|
958
|
+
pageIndex = findObjectPageIndex(doc, objectId)
|
|
959
|
+
if (pageIndex !== undefined) {
|
|
960
|
+
this.objectIndexCache[cacheKey] = pageIndex
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (pageIndex === undefined) return
|
|
965
|
+
|
|
966
|
+
const sourceObject = doc.allObjects[pageIndex]?.find(o => o.id === objectId)
|
|
967
|
+
if (!sourceObject) return
|
|
968
|
+
|
|
969
|
+
const { width: pageWidth, height: pageHeight } = this.getPageSize(docIndex, pageIndex)
|
|
970
|
+
const offset = 12
|
|
971
|
+
const { x, y } = clampPosition(
|
|
972
|
+
sourceObject.x + offset,
|
|
973
|
+
sourceObject.y + offset,
|
|
974
|
+
sourceObject.width,
|
|
975
|
+
sourceObject.height,
|
|
976
|
+
pageWidth,
|
|
977
|
+
pageHeight,
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
let duplicatedSigner = sourceObject.signer
|
|
981
|
+
if (duplicatedSigner?.element && Object.prototype.hasOwnProperty.call(duplicatedSigner.element, 'elementId')) {
|
|
982
|
+
duplicatedSigner = {
|
|
983
|
+
...duplicatedSigner,
|
|
984
|
+
element: { ...duplicatedSigner.element },
|
|
985
|
+
}
|
|
986
|
+
delete duplicatedSigner.element.elementId
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
const duplicatedObject = {
|
|
990
|
+
...sourceObject,
|
|
991
|
+
id: this.generateObjectId(),
|
|
992
|
+
x,
|
|
993
|
+
y,
|
|
994
|
+
signer: duplicatedSigner,
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
doc.allObjects[pageIndex].push(duplicatedObject)
|
|
998
|
+
this.objectIndexCache[`${docIndex}-${duplicatedObject.id}`] = pageIndex
|
|
999
|
+
|
|
1000
|
+
this.$nextTick(() => {
|
|
1001
|
+
const refKey = `draggable${docIndex}-${pageIndex}-${duplicatedObject.id}`
|
|
1002
|
+
const draggableRefs = this.$refs[refKey]
|
|
1003
|
+
if (draggableRefs && Array.isArray(draggableRefs) && draggableRefs[0]) {
|
|
1004
|
+
draggableRefs[0].isSelected = true
|
|
1005
|
+
}
|
|
1006
|
+
})
|
|
1007
|
+
},
|
|
943
1008
|
|
|
944
1009
|
checkAndMoveObjectPage(docIndex, objectId, mouseX, mouseY) {
|
|
945
1010
|
if (docIndex < 0 || docIndex >= this.pdfDocuments.length) return undefined
|