@arbidocs/coedit 0.4.157 → 0.4.159

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/commands.cjs CHANGED
@@ -508,11 +508,84 @@ function paragraphRunsXml(paragraph) {
508
508
  }
509
509
  return runs.length ? runs.join("") : null;
510
510
  }
511
+
512
+ // src/commands/signatureFields.ts
513
+ var SIGNATURE_FIELDS_NAMESPACE = "urn:arbi:signature-fields";
514
+ var SIGNATURE_FIELD_TAG_PREFIX = "arbi-signature:";
515
+ var SIGNATURE_FIELD_KINDS = ["signature", "initials", "date", "name"];
516
+ var SIGNATURE_FIELD_LABELS = {
517
+ signature: "Signature",
518
+ initials: "Initials",
519
+ date: "Date signed",
520
+ name: "Name"
521
+ };
522
+ var TAG = /^arbi-signature:(signature|initials|date|name)(?::([0-9a-f]{8}))?$/;
523
+ var EMAIL = /^[^@\s<>,;]{1,64}@[^@\s<>,;]{1,255}\.[^@\s<>,;]{1,63}$/;
524
+ var isSignerEmail = (value) => EMAIL.test(value.trim());
525
+ function newSignatureFieldKey() {
526
+ const bytes = new Uint8Array(4);
527
+ globalThis.crypto.getRandomValues(bytes);
528
+ return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
529
+ }
530
+ var signatureFieldTag = (kind, key) => `${SIGNATURE_FIELD_TAG_PREFIX}${kind}${key ? `:${key}` : ""}`;
531
+ var signatureFieldLabel = (kind, who) => who?.trim() ? `${SIGNATURE_FIELD_LABELS[kind]} \u2014 ${who.trim()}` : SIGNATURE_FIELD_LABELS[kind];
532
+ function parseSignatureFieldTag(tag) {
533
+ const m = TAG.exec(tag ?? "");
534
+ return m ? { kind: m[1], key: m[2] ?? null } : null;
535
+ }
536
+ function signatureFieldWrite(spec, at, key = newSignatureFieldKey()) {
537
+ const email = spec.email?.trim().toLowerCase() || null;
538
+ if (email && !isSignerEmail(email)) throw new Error("Enter the signer\u2019s email address.");
539
+ const name = spec.name?.trim().slice(0, 200) || null;
540
+ const text = signatureFieldLabel(spec.kind, name || email);
541
+ const payload = email ? { key, kind: spec.kind, email, name, required: spec.required !== false } : null;
542
+ return {
543
+ key: payload ? key : null,
544
+ tag: signatureFieldTag(spec.kind, payload ? key : null),
545
+ write: {
546
+ paragraphId: at.paragraphId,
547
+ offset: at.offset,
548
+ tag: signatureFieldTag(spec.kind, payload ? key : null),
549
+ text,
550
+ alias: text,
551
+ lock: "contentLocked",
552
+ ...payload ? {
553
+ payload: {
554
+ namespaceUri: SIGNATURE_FIELDS_NAMESPACE,
555
+ rootLocalName: "fields",
556
+ nodeId: `sig-${key}`,
557
+ label: text,
558
+ data: JSON.stringify(payload)
559
+ }
560
+ } : {}
561
+ }
562
+ };
563
+ }
564
+ var attr2 = (node, name) => node?.attributes?.find((a) => a.localName === name)?.value;
565
+ function signatureFieldControls(root) {
566
+ const out = [];
567
+ const visit = (node) => {
568
+ if (node.localName === "sdt") {
569
+ const props = node.children?.find((c) => c.localName === "sdtPr");
570
+ const tag = attr2(
571
+ props?.children?.find((c) => c.localName === "tag"),
572
+ "val"
573
+ );
574
+ const parsed = parseSignatureFieldTag(tag);
575
+ if (parsed && tag) out.push({ nodeId: node.id, tag, ...parsed });
576
+ }
577
+ if (node.kind !== "textValue") for (const child2 of node.children ?? []) visit(child2);
578
+ };
579
+ visit(root);
580
+ return out;
581
+ }
582
+
583
+ // src/commands/undo.ts
511
584
  var AGENT_UNDO_MAP = "agentUndo";
512
- var attr2 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
585
+ var attr3 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
513
586
  var child = (node, name) => node?.children?.find((c) => c.localName === name);
514
587
  var twips = (node, name) => {
515
- const value = node && attr2(node, name);
588
+ const value = node && attr3(node, name);
516
589
  return value === void 0 ? void 0 : Number(value);
517
590
  };
518
591
  var FLAT = new Set(
@@ -525,7 +598,7 @@ function paragraphIndex(root) {
525
598
  for (const c of node.children ?? []) {
526
599
  parentOf.set(c, node);
527
600
  if (c.kind === "paragraph") {
528
- const id = attr2(c, "paraId");
601
+ const id = attr3(c, "paraId");
529
602
  if (id) byParaId.set(id, c);
530
603
  }
531
604
  if (c.kind !== "textValue") visit(c);
@@ -547,28 +620,28 @@ function paragraphState(paragraph) {
547
620
  attributes: Object.fromEntries((p.attributes ?? []).map((a) => [a.localName, a.value]))
548
621
  });
549
622
  } else if (p.localName === "numPr") {
550
- const numId = attr2(child(p, "numId") ?? p, "val");
551
- if (numId) numbering = { numId, level: Number(attr2(child(p, "ilvl") ?? p, "val") ?? 0) };
623
+ const numId = attr3(child(p, "numId") ?? p, "val");
624
+ if (numId) numbering = { numId, level: Number(attr3(child(p, "ilvl") ?? p, "val") ?? 0) };
552
625
  } else if (p.localName === "tabs") {
553
626
  for (const tab of p.children ?? []) {
554
- const val = attr2(tab, "val");
627
+ const val = attr3(tab, "val");
555
628
  if (!val || val === "clear") continue;
556
629
  tabs.push({
557
- positionTwips: Number(attr2(tab, "pos") ?? 0),
630
+ positionTwips: Number(attr3(tab, "pos") ?? 0),
558
631
  alignment: val === "start" ? "left" : val === "end" ? "right" : val,
559
- ...attr2(tab, "leader") ? { leader: attr2(tab, "leader") } : {}
632
+ ...attr3(tab, "leader") ? { leader: attr3(tab, "leader") } : {}
560
633
  });
561
634
  }
562
635
  }
563
636
  }
564
- return { paraId: attr2(paragraph, "paraId") ?? "", properties, numbering, tabs };
637
+ return { paraId: attr3(paragraph, "paraId") ?? "", properties, numbering, tabs };
565
638
  }
566
639
  function sectionStates(root) {
567
640
  const { body } = paragraphIndex(root);
568
641
  const state = (sectPr, paraId) => {
569
642
  const size = child(sectPr, "pgSz");
570
643
  const margin = child(sectPr, "pgMar");
571
- const orient = size && attr2(size, "orient");
644
+ const orient = size && attr3(size, "orient");
572
645
  return {
573
646
  paraId,
574
647
  pageWidthTwips: twips(size, "w"),
@@ -583,7 +656,7 @@ function sectionStates(root) {
583
656
  const out = [];
584
657
  for (const block of body.children ?? []) {
585
658
  const sectPr = block.kind === "paragraph" ? child(child(block, "pPr"), "sectPr") : void 0;
586
- if (sectPr) out.push(state(sectPr, attr2(block, "paraId") ?? null));
659
+ if (sectPr) out.push(state(sectPr, attr3(block, "paraId") ?? null));
587
660
  else if (block.localName === "sectPr") out.push(state(block, null));
588
661
  }
589
662
  return out;
@@ -602,10 +675,10 @@ function tableState(root, paraId) {
602
675
  for (const row of table.children ?? []) {
603
676
  if (row.localName !== "tr") continue;
604
677
  const header = child(child(row, "trPr"), "tblHeader");
605
- if (!header || ["0", "false", "off"].includes(attr2(header, "val") ?? "")) break;
678
+ if (!header || ["0", "false", "off"].includes(attr3(header, "val") ?? "")) break;
606
679
  headerRowCount++;
607
680
  }
608
- return { kind: "table", paraId, styleId: (style && attr2(style, "val")) ?? null, headerRowCount };
681
+ return { kind: "table", paraId, styleId: (style && attr3(style, "val")) ?? null, headerRowCount };
609
682
  }
610
683
  function fieldNodeIds(paragraph) {
611
684
  const out = [];
@@ -614,7 +687,7 @@ function fieldNodeIds(paragraph) {
614
687
  for (const c of node.children ?? []) {
615
688
  if (c.localName === "del") continue;
616
689
  if (c.localName === "fldChar") {
617
- const type = attr2(c, "fldCharType");
690
+ const type = attr3(c, "fldCharType");
618
691
  if (type === "begin" && depth++ === 0) out.push(c.id);
619
692
  else if (type === "end") depth = Math.max(0, depth - 1);
620
693
  } else if (c.kind !== "textValue") walk(c);
@@ -658,6 +731,15 @@ function undoOps(root, record) {
658
731
  styleId: record.styleId ?? "",
659
732
  headerRowCount: record.headerRowCount
660
733
  });
734
+ } else if (record.kind === "signatureField") {
735
+ const controls = signatureFieldControls(root).filter((c) => c.tag === record.tag);
736
+ if (!controls.length) return null;
737
+ for (const control of controls) {
738
+ ops.push(
739
+ { op: "setContentControlProperties", controlId: control.nodeId, lock: "unlocked" },
740
+ { op: "removeContentControl", controlId: control.nodeId, keepContent: false }
741
+ );
742
+ }
661
743
  } else {
662
744
  const updates = [];
663
745
  for (const { paraId, index, text } of record.fields) {
@@ -1038,12 +1120,12 @@ function fragmentPackage(body, covered, {
1038
1120
  });
1039
1121
  return revision ? trackInsertion(untracked, revision, covered) : untracked;
1040
1122
  }
1041
- var attr3 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1123
+ var attr4 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1042
1124
  function documentStyleIds(root) {
1043
1125
  const ids = /* @__PURE__ */ new Set();
1044
1126
  for (const style of root?.children ?? [])
1045
1127
  if (style.localName === "style") {
1046
- const id = attr3(style, "styleId");
1128
+ const id = attr4(style, "styleId");
1047
1129
  if (id) ids.add(id);
1048
1130
  }
1049
1131
  return ids;
@@ -1365,6 +1447,10 @@ exports.DEFINITIONS_HEADING = DEFINITIONS_HEADING;
1365
1447
  exports.DEFINITION_BOOKMARK_PREFIX = DEFINITION_BOOKMARK_PREFIX;
1366
1448
  exports.FIELD_ATOM = FIELD_ATOM;
1367
1449
  exports.REF_BOOKMARK_PREFIX = REF_BOOKMARK_PREFIX;
1450
+ exports.SIGNATURE_FIELDS_NAMESPACE = SIGNATURE_FIELDS_NAMESPACE;
1451
+ exports.SIGNATURE_FIELD_KINDS = SIGNATURE_FIELD_KINDS;
1452
+ exports.SIGNATURE_FIELD_LABELS = SIGNATURE_FIELD_LABELS;
1453
+ exports.SIGNATURE_FIELD_TAG_PREFIX = SIGNATURE_FIELD_TAG_PREFIX;
1368
1454
  exports.TermEverywhereError = TermEverywhereError;
1369
1455
  exports.WATCHED_STYLES = WATCHED_STYLES;
1370
1456
  exports.W_NAMESPACES = W_NAMESPACES;
@@ -1404,14 +1490,17 @@ exports.insertDefinedTerm = insertDefinedTerm;
1404
1490
  exports.insertDocumentReference = insertDocumentReference;
1405
1491
  exports.insertionIndex = insertionIndex;
1406
1492
  exports.isDefinitionsTitle = isDefinitionsTitle;
1493
+ exports.isSignerEmail = isSignerEmail;
1407
1494
  exports.listTargets = listTargets;
1408
1495
  exports.markCrossReferenceTarget = markCrossReferenceTarget;
1409
1496
  exports.newRefBookmark = newRefBookmark;
1497
+ exports.newSignatureFieldKey = newSignatureFieldKey;
1410
1498
  exports.paragraphIndex = paragraphIndex;
1411
1499
  exports.paragraphNumber = paragraphNumber;
1412
1500
  exports.paragraphRunsXml = paragraphRunsXml;
1413
1501
  exports.paragraphState = paragraphState;
1414
1502
  exports.parseDefinition = parseDefinition;
1503
+ exports.parseSignatureFieldTag = parseSignatureFieldTag;
1415
1504
  exports.readDocument = readDocument;
1416
1505
  exports.readParagraphs = readParagraphs;
1417
1506
  exports.refFieldXml = refFieldXml;
@@ -1421,6 +1510,10 @@ exports.refTooltip = refTooltip;
1421
1510
  exports.refreshCrossReferences = refreshCrossReferences;
1422
1511
  exports.replaceSpan = replaceSpan;
1423
1512
  exports.sectionStates = sectionStates;
1513
+ exports.signatureFieldControls = signatureFieldControls;
1514
+ exports.signatureFieldLabel = signatureFieldLabel;
1515
+ exports.signatureFieldTag = signatureFieldTag;
1516
+ exports.signatureFieldWrite = signatureFieldWrite;
1424
1517
  exports.staleCrossReferences = staleCrossReferences;
1425
1518
  exports.styleNames = styleNames;
1426
1519
  exports.stylesUsed = stylesUsed;