@embedpdf/plugin-redaction 2.4.1 → 2.6.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { clamp, BasePlugin, createBehaviorEmitter, refreshPages } from "@embedpdf/core";
2
- import { PdfAnnotationSubtype, PdfPermissionFlag, PdfTaskHelper, PdfErrorCode, Task, uuidV4 } from "@embedpdf/models";
1
+ import { BasePlugin, createBehaviorEmitter, refreshPages } from "@embedpdf/core";
2
+ import { PdfAnnotationSubtype, PdfPermissionFlag, uuidV4, PdfTaskHelper, PdfErrorCode, Task } from "@embedpdf/models";
3
3
  var RedactionMode = /* @__PURE__ */ ((RedactionMode2) => {
4
4
  RedactionMode2["Redact"] = "redact";
5
5
  RedactionMode2["MarqueeRedact"] = "marqueeRedact";
@@ -56,48 +56,6 @@ const deselectPending = (documentId) => ({
56
56
  type: DESELECT_PENDING,
57
57
  payload: documentId
58
58
  });
59
- function createMarqueeHandler(opts) {
60
- const { pageSize, scale, minDragPx = 5, onPreview, onCommit } = opts;
61
- let start = null;
62
- let last = null;
63
- return {
64
- onPointerDown: (pos, evt) => {
65
- var _a;
66
- start = pos;
67
- last = { origin: { x: pos.x, y: pos.y }, size: { width: 0, height: 0 } };
68
- onPreview == null ? void 0 : onPreview(last);
69
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
70
- },
71
- onPointerMove: (pos) => {
72
- if (!start) return;
73
- const x = clamp(pos.x, 0, pageSize.width);
74
- const y = clamp(pos.y, 0, pageSize.height);
75
- last = {
76
- origin: { x: Math.min(start.x, x), y: Math.min(start.y, y) },
77
- size: { width: Math.abs(x - start.x), height: Math.abs(y - start.y) }
78
- };
79
- onPreview == null ? void 0 : onPreview(last);
80
- },
81
- onPointerUp: (_pos, evt) => {
82
- var _a;
83
- if (last) {
84
- const dragPx = Math.max(last.size.width, last.size.height) * scale;
85
- if (dragPx > minDragPx) onCommit == null ? void 0 : onCommit(last);
86
- }
87
- start = null;
88
- last = null;
89
- onPreview == null ? void 0 : onPreview(null);
90
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
91
- },
92
- onPointerCancel: (_pos, evt) => {
93
- var _a;
94
- start = null;
95
- last = null;
96
- onPreview == null ? void 0 : onPreview(null);
97
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
98
- }
99
- };
100
- }
101
59
  const calculatePendingCount = (pending) => {
102
60
  return Object.values(pending).reduce((total, items) => total + items.length, 0);
103
61
  };
@@ -319,14 +277,16 @@ const redactTool = {
319
277
  if (anno.type !== PdfAnnotationSubtype.REDACT) return true;
320
278
  return !((_a = anno.segmentRects) == null ? void 0 : _a.length);
321
279
  },
280
+ isRotatable: false,
322
281
  lockAspectRatio: false,
323
282
  isGroupDraggable: false,
324
- isGroupResizable: false
283
+ isGroupResizable: false,
284
+ isGroupRotatable: false
325
285
  },
326
286
  defaults: {
327
287
  type: PdfAnnotationSubtype.REDACT,
328
- color: "#E44234",
329
- overlayColor: "#000000",
288
+ color: "#000000",
289
+ overlayColor: "#FFFFFF",
330
290
  strokeColor: "#E44234",
331
291
  opacity: 1
332
292
  }
@@ -337,6 +297,7 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
337
297
  var _a, _b, _c, _d;
338
298
  super(id, registry);
339
299
  this.redactionSelection$ = /* @__PURE__ */ new Map();
300
+ this.redactionMarquee$ = /* @__PURE__ */ new Map();
340
301
  this.pending$ = createBehaviorEmitter();
341
302
  this.selected$ = createBehaviorEmitter();
342
303
  this.state$ = createBehaviorEmitter();
@@ -428,6 +389,10 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
428
389
  })
429
390
  );
430
391
  this.redactionSelection$.set(documentId, createBehaviorEmitter());
392
+ this.redactionMarquee$.set(
393
+ documentId,
394
+ createBehaviorEmitter()
395
+ );
431
396
  const unsubscribers = [];
432
397
  if (this.selectionCapability) {
433
398
  const selectionScope = this.selectionCapability.forDocument(documentId);
@@ -458,7 +423,43 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
458
423
  }
459
424
  );
460
425
  });
461
- unsubscribers.push(unsubSelection, unsubEndSelection);
426
+ const unsubMarqueeChange = selectionScope.onMarqueeChange((event) => {
427
+ var _a;
428
+ const docState = this.getDocumentState(documentId);
429
+ if (!(docState == null ? void 0 : docState.isRedacting)) return;
430
+ (_a = this.redactionMarquee$.get(documentId)) == null ? void 0 : _a.emit({ pageIndex: event.pageIndex, rect: event.rect, modeId: event.modeId });
431
+ });
432
+ const unsubMarqueeEnd = selectionScope.onMarqueeEnd((event) => {
433
+ const docState = this.getDocumentState(documentId);
434
+ if (!(docState == null ? void 0 : docState.isRedacting)) return;
435
+ if (!this.checkPermission(documentId, PdfPermissionFlag.ModifyContents)) return;
436
+ if (this.useAnnotationMode) {
437
+ this.createRedactAnnotationFromArea(documentId, event.pageIndex, event.rect);
438
+ } else {
439
+ const redactionColor = this.config.drawBlackBoxes ? "#000000" : "transparent";
440
+ const item = {
441
+ id: uuidV4(),
442
+ kind: "area",
443
+ page: event.pageIndex,
444
+ rect: event.rect,
445
+ source: "legacy",
446
+ markColor: "#FF0000",
447
+ redactionColor
448
+ };
449
+ this.dispatch(addPending(documentId, [item]));
450
+ this.selectPending(event.pageIndex, item.id, documentId);
451
+ }
452
+ });
453
+ const unsubEmptySpaceClick = selectionScope.onEmptySpaceClick(() => {
454
+ this.deselectPending(documentId);
455
+ });
456
+ unsubscribers.push(
457
+ unsubSelection,
458
+ unsubEndSelection,
459
+ unsubMarqueeChange,
460
+ unsubMarqueeEnd,
461
+ unsubEmptySpaceClick
462
+ );
462
463
  }
463
464
  if (this.useAnnotationMode && this.annotationCapability) {
464
465
  const annoScope = this.annotationCapability.forDocument(documentId);
@@ -511,11 +512,32 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
511
512
  );
512
513
  }
513
514
  onDocumentLoaded(documentId) {
514
- var _a, _b;
515
- (_a = this.selectionCapability) == null ? void 0 : _a.enableForMode(RedactionMode.Redact, { showRects: false }, documentId);
515
+ var _a, _b, _c;
516
+ (_a = this.selectionCapability) == null ? void 0 : _a.enableForMode(
517
+ RedactionMode.Redact,
518
+ {
519
+ enableSelection: true,
520
+ showSelectionRects: false,
521
+ enableMarquee: true,
522
+ showMarqueeRects: false
523
+ },
524
+ documentId
525
+ );
516
526
  (_b = this.selectionCapability) == null ? void 0 : _b.enableForMode(
527
+ RedactionMode.MarqueeRedact,
528
+ {
529
+ enableSelection: false,
530
+ enableMarquee: true,
531
+ showMarqueeRects: false
532
+ },
533
+ documentId
534
+ );
535
+ (_c = this.selectionCapability) == null ? void 0 : _c.enableForMode(
517
536
  RedactionMode.RedactSelection,
518
- { showRects: false },
537
+ {
538
+ enableSelection: true,
539
+ showSelectionRects: false
540
+ },
519
541
  documentId
520
542
  );
521
543
  }
@@ -524,6 +546,9 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
524
546
  const emitter = this.redactionSelection$.get(documentId);
525
547
  emitter == null ? void 0 : emitter.clear();
526
548
  this.redactionSelection$.delete(documentId);
549
+ const marqueeEmitter = this.redactionMarquee$.get(documentId);
550
+ marqueeEmitter == null ? void 0 : marqueeEmitter.clear();
551
+ this.redactionMarquee$.delete(documentId);
527
552
  const unsubscribers = this.documentUnsubscribers.get(documentId);
528
553
  if (unsubscribers) {
529
554
  unsubscribers.forEach((unsub) => unsub());
@@ -777,14 +802,15 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
777
802
  this.events$.emit({ type: "clear", documentId: id });
778
803
  }
779
804
  selectPending(page, itemId, documentId) {
780
- var _a, _b;
805
+ var _a, _b, _c;
781
806
  const id = documentId ?? this.getActiveDocumentId();
782
807
  if (this.useAnnotationMode) {
783
808
  (_a = this.annotationCapability) == null ? void 0 : _a.forDocument(id).selectAnnotation(page, itemId);
784
809
  } else {
785
810
  this.dispatch(selectPending(id, page, itemId));
811
+ (_b = this.interactionManagerCapability) == null ? void 0 : _b.claimPageActivity(id, "redaction-selection", page);
786
812
  }
787
- (_b = this.selectionCapability) == null ? void 0 : _b.forDocument(id).clear();
813
+ (_c = this.selectionCapability) == null ? void 0 : _c.forDocument(id).clear();
788
814
  }
789
815
  getSelectedPending(documentId) {
790
816
  var _a;
@@ -792,12 +818,13 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
792
818
  return ((_a = this.getDocumentState(id)) == null ? void 0 : _a.selected) ?? null;
793
819
  }
794
820
  deselectPending(documentId) {
795
- var _a;
821
+ var _a, _b;
796
822
  const id = documentId ?? this.getActiveDocumentId();
797
823
  if (this.useAnnotationMode) {
798
824
  (_a = this.annotationCapability) == null ? void 0 : _a.forDocument(id).deselectAnnotation();
799
825
  } else {
800
826
  this.dispatch(deselectPending(id));
827
+ (_b = this.interactionManagerCapability) == null ? void 0 : _b.releasePageActivity(id, "redaction-selection");
801
828
  }
802
829
  }
803
830
  // ─────────────────────────────────────────────────────────
@@ -921,6 +948,11 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
921
948
  return (emitter == null ? void 0 : emitter.on(callback)) ?? (() => {
922
949
  });
923
950
  }
951
+ onRedactionMarqueeChange(documentId, callback) {
952
+ const emitter = this.redactionMarquee$.get(documentId);
953
+ return (emitter == null ? void 0 : emitter.on(callback)) ?? (() => {
954
+ });
955
+ }
924
956
  /**
925
957
  * Get the stroke color for redaction previews.
926
958
  * In annotation mode: returns tool's defaults.strokeColor
@@ -933,85 +965,6 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
933
965
  }
934
966
  return "#FF0000";
935
967
  }
936
- registerMarqueeOnPage(opts) {
937
- if (!this.interactionManagerCapability) {
938
- this.logger.warn(
939
- "RedactionPlugin",
940
- "MissingDependency",
941
- "Interaction manager plugin not loaded, marquee redaction disabled"
942
- );
943
- return () => {
944
- };
945
- }
946
- const coreDoc = this.coreState.core.documents[opts.documentId];
947
- if (!(coreDoc == null ? void 0 : coreDoc.document)) {
948
- this.logger.warn("RedactionPlugin", "DocumentNotFound", "Document not found");
949
- return () => {
950
- };
951
- }
952
- const page = coreDoc.document.pages[opts.pageIndex];
953
- if (!page) {
954
- this.logger.warn("RedactionPlugin", "PageNotFound", `Page ${opts.pageIndex} not found`);
955
- return () => {
956
- };
957
- }
958
- const handlers = createMarqueeHandler({
959
- pageSize: page.size,
960
- scale: opts.scale,
961
- onPreview: opts.callback.onPreview,
962
- onCommit: (r) => {
963
- var _a, _b;
964
- (_b = (_a = opts.callback).onCommit) == null ? void 0 : _b.call(_a, r);
965
- if (this.useAnnotationMode) {
966
- this.createRedactAnnotationFromArea(opts.documentId, opts.pageIndex, r);
967
- } else {
968
- const redactionColor = this.config.drawBlackBoxes ? "#000000" : "transparent";
969
- const item = {
970
- id: uuidV4(),
971
- kind: "area",
972
- page: opts.pageIndex,
973
- rect: r,
974
- source: "legacy",
975
- markColor: "#FF0000",
976
- redactionColor
977
- };
978
- this.dispatch(addPending(opts.documentId, [item]));
979
- this.selectPending(opts.pageIndex, item.id, opts.documentId);
980
- }
981
- }
982
- });
983
- const off = this.interactionManagerCapability.registerAlways({
984
- handlers: {
985
- onPointerDown: (_, evt) => {
986
- if (evt.target === evt.currentTarget) {
987
- this.deselectPending(opts.documentId);
988
- }
989
- }
990
- },
991
- scope: {
992
- type: "page",
993
- documentId: opts.documentId,
994
- pageIndex: opts.pageIndex
995
- }
996
- });
997
- const off2 = this.interactionManagerCapability.registerHandlers({
998
- documentId: opts.documentId,
999
- modeId: RedactionMode.Redact,
1000
- handlers,
1001
- pageIndex: opts.pageIndex
1002
- });
1003
- const off3 = this.interactionManagerCapability.registerHandlers({
1004
- documentId: opts.documentId,
1005
- modeId: RedactionMode.MarqueeRedact,
1006
- handlers,
1007
- pageIndex: opts.pageIndex
1008
- });
1009
- return () => {
1010
- off();
1011
- off2();
1012
- off3();
1013
- };
1014
- }
1015
968
  queueCurrentSelectionAsPending(documentId) {
1016
969
  const id = documentId ?? this.getActiveDocumentId();
1017
970
  if (!this.selectionCapability) {
@@ -1508,6 +1461,8 @@ const _RedactionPlugin = class _RedactionPlugin extends BasePlugin {
1508
1461
  this.events$.clear();
1509
1462
  this.redactionSelection$.forEach((emitter) => emitter.clear());
1510
1463
  this.redactionSelection$.clear();
1464
+ this.redactionMarquee$.forEach((emitter) => emitter.clear());
1465
+ this.redactionMarquee$.clear();
1511
1466
  this.documentUnsubscribers.forEach((unsubscribers) => {
1512
1467
  unsubscribers.forEach((unsub) => unsub());
1513
1468
  });