@arbidocs/coedit 0.4.98 → 0.4.100

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.
@@ -50,6 +50,22 @@ declare function buildingBlockFragment(template: Uint8Array, name: string): Uint
50
50
  /** A fragment's body as clipboard HTML the editor's paste recognises as its own. */
51
51
  declare function fragmentClipboardHtml(fragment: Uint8Array, covered?: boolean): string;
52
52
 
53
+ /** Who made a tracked change and when (`w:author`, `w:date`). */
54
+ interface Revision {
55
+ author: string;
56
+ /** ISO 8601, seconds precision, e.g. `2026-10-19T09:30:00Z`. */
57
+ date: string;
58
+ }
59
+ /**
60
+ * The fragment with every run wrapped in `w:ins` and every new paragraph mark marked inserted. A
61
+ * table row is marked inserted as a whole, its cells left as they are: the editor rejects an
62
+ * inserted row whose content is tracked as well only partly. A run is not descended into, so a
63
+ * text box goes in with its run. `covered`: the fragment's last paragraph mark is pasted too (a
64
+ * block before the caret's paragraph); otherwise the last paragraph runs into the text after the
65
+ * caret and its mark is not new.
66
+ */
67
+ declare function trackInsertion(fragment: Uint8Array, revision: Revision, covered: boolean): Uint8Array;
68
+
53
69
  interface StyleDifference {
54
70
  styleId: string;
55
71
  name: string;
@@ -106,4 +122,4 @@ declare class TemplateError extends Error {
106
122
  constructor(message: string);
107
123
  }
108
124
 
109
- export { type ApplyTemplateOptions, type ApplyTemplateReport, type BuildingBlockInfo, LEGAL_BUILDING_BLOCKS, LEGAL_NUM, type LegalTemplateOptions, type LinkedLevel, type StyleDifference, type StyleDivergence, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence };
125
+ export { type ApplyTemplateOptions, type ApplyTemplateReport, type BuildingBlockInfo, LEGAL_BUILDING_BLOCKS, LEGAL_NUM, type LegalTemplateOptions, type LinkedLevel, type Revision, type StyleDifference, type StyleDivergence, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence, trackInsertion };
@@ -50,6 +50,22 @@ declare function buildingBlockFragment(template: Uint8Array, name: string): Uint
50
50
  /** A fragment's body as clipboard HTML the editor's paste recognises as its own. */
51
51
  declare function fragmentClipboardHtml(fragment: Uint8Array, covered?: boolean): string;
52
52
 
53
+ /** Who made a tracked change and when (`w:author`, `w:date`). */
54
+ interface Revision {
55
+ author: string;
56
+ /** ISO 8601, seconds precision, e.g. `2026-10-19T09:30:00Z`. */
57
+ date: string;
58
+ }
59
+ /**
60
+ * The fragment with every run wrapped in `w:ins` and every new paragraph mark marked inserted. A
61
+ * table row is marked inserted as a whole, its cells left as they are: the editor rejects an
62
+ * inserted row whose content is tracked as well only partly. A run is not descended into, so a
63
+ * text box goes in with its run. `covered`: the fragment's last paragraph mark is pasted too (a
64
+ * block before the caret's paragraph); otherwise the last paragraph runs into the text after the
65
+ * caret and its mark is not new.
66
+ */
67
+ declare function trackInsertion(fragment: Uint8Array, revision: Revision, covered: boolean): Uint8Array;
68
+
53
69
  interface StyleDifference {
54
70
  styleId: string;
55
71
  name: string;
@@ -106,4 +122,4 @@ declare class TemplateError extends Error {
106
122
  constructor(message: string);
107
123
  }
108
124
 
109
- export { type ApplyTemplateOptions, type ApplyTemplateReport, type BuildingBlockInfo, LEGAL_BUILDING_BLOCKS, LEGAL_NUM, type LegalTemplateOptions, type LinkedLevel, type StyleDifference, type StyleDivergence, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence };
125
+ export { type ApplyTemplateOptions, type ApplyTemplateReport, type BuildingBlockInfo, LEGAL_BUILDING_BLOCKS, LEGAL_NUM, type LegalTemplateOptions, type LinkedLevel, type Revision, type StyleDifference, type StyleDivergence, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence, trackInsertion };
package/dist/template.js CHANGED
@@ -811,6 +811,59 @@ function fragmentClipboardHtml(fragment, covered = true) {
811
811
  return `<div data-docx-fragment="${btoa(binary)}" data-docx-fragment-end="${covered ? "covered" : "open"}"></div>`;
812
812
  }
813
813
 
814
+ // src/template/track.ts
815
+ var TRACKED = /* @__PURE__ */ new Set(["w:ins", "w:del", "w:moveFrom", "w:moveTo"]);
816
+ function trackInsertion(fragment, revision, covered) {
817
+ const pkg = Pkg.read(fragment);
818
+ const main = pkg.main;
819
+ const root = pkg.xml(main);
820
+ const body = kid(root, "w:body");
821
+ if (!root || !body) return fragment;
822
+ const attrs = { "w:id": "1", "w:author": revision.author, "w:date": revision.date };
823
+ const lastParagraph = body.children.filter(isEl).findLast((c) => c.name === "w:p");
824
+ const visit = (node) => {
825
+ node.children = node.children.map((child) => {
826
+ if (!isEl(child)) return child;
827
+ if (child.name === "w:r") return TRACKED.has(node.name) ? child : el("w:ins", attrs, [child]);
828
+ if (TRACKED.has(child.name)) return child;
829
+ if (child.name === "w:tr") {
830
+ markRow(child, attrs);
831
+ return child;
832
+ }
833
+ visit(child);
834
+ if (child.name === "w:p" && (covered || child !== lastParagraph)) markParagraph(child, attrs);
835
+ return child;
836
+ });
837
+ };
838
+ visit(body);
839
+ pkg.setXml(main, root);
840
+ return pkg.write();
841
+ }
842
+ function markParagraph(p, attrs) {
843
+ let pPr = kid(p, "w:pPr");
844
+ if (!pPr) p.children.unshift(pPr = el("w:pPr"));
845
+ let rPr = kid(pPr, "w:rPr");
846
+ if (!rPr) {
847
+ rPr = el("w:rPr");
848
+ const at = pPr.children.findIndex(
849
+ (c) => isEl(c) && (c.name === "w:sectPr" || c.name === "w:pPrChange")
850
+ );
851
+ pPr.children.splice(at < 0 ? pPr.children.length : at, 0, rPr);
852
+ }
853
+ if (!kid(rPr, "w:ins")) rPr.children.unshift(el("w:ins", attrs));
854
+ }
855
+ function markRow(tr, attrs) {
856
+ let trPr = kid(tr, "w:trPr");
857
+ if (!trPr) {
858
+ trPr = el("w:trPr");
859
+ const after = tr.children.findIndex((c) => isEl(c) && c.name === "w:tblPrEx");
860
+ tr.children.splice(after + 1, 0, trPr);
861
+ }
862
+ if (kid(trPr, "w:ins")) return;
863
+ const at = trPr.children.findIndex((c) => isEl(c) && c.name === "w:trPrChange");
864
+ trPr.children.splice(at < 0 ? trPr.children.length : at, 0, el("w:ins", attrs));
865
+ }
866
+
814
867
  // src/template/divergence.ts
815
868
  var UI_ONLY = /* @__PURE__ */ new Set([
816
869
  "w:uiPriority",
@@ -1554,6 +1607,6 @@ function linkedLevelStyles(document) {
1554
1607
  return out;
1555
1608
  }
1556
1609
 
1557
- export { LEGAL_BUILDING_BLOCKS, LEGAL_NUM, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence };
1610
+ export { LEGAL_BUILDING_BLOCKS, LEGAL_NUM, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence, trackInsertion };
1558
1611
  //# sourceMappingURL=template.js.map
1559
1612
  //# sourceMappingURL=template.js.map