ooxml-core 1.24.0 → 1.24.2

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.
Files changed (66) hide show
  1. package/README.md +2 -2
  2. package/dist/{PptxHandler-FSKKPZZC.mjs → PptxHandler-5TWAQWPK.mjs} +2 -2
  3. package/dist/{PptxHandler-H7MEWJJJ.mjs → PptxHandler-KBJ4TN3T.mjs} +1 -1
  4. package/dist/{PptxHandler-DNSXWTQV.cjs → PptxHandler-KFEE7O7W.cjs} +2 -2
  5. package/dist/{PresentationBuilder-7TSENZTX.mjs → PresentationBuilder-SCT5AQBP.mjs} +1 -1
  6. package/dist/{PresentationBuilder-RIJWQSEU.mjs → PresentationBuilder-SVHIKT4C.mjs} +2 -2
  7. package/dist/{PresentationBuilder-A5NI35VN.cjs → PresentationBuilder-SXLRXYDI.cjs} +4 -4
  8. package/dist/automation/index.cjs +24 -1
  9. package/dist/automation/index.mjs +24 -1
  10. package/dist/{chunk-4QPOJCJG.mjs → chunk-7N7C5BNM.mjs} +1 -1
  11. package/dist/{chunk-DLFMCZZT.mjs → chunk-CWCDFPKN.mjs} +1 -1
  12. package/dist/{chunk-LF5E5ZOH.mjs → chunk-GVP262WE.mjs} +25 -62
  13. package/dist/{chunk-VQF6HQEE.mjs → chunk-KVKTHGIY.mjs} +1 -1
  14. package/dist/{chunk-BA7Z6ATM.mjs → chunk-NE7626A4.mjs} +4 -4
  15. package/dist/{chunk-Q5PKBQXH.mjs → chunk-ON7XVRHQ.mjs} +26 -63
  16. package/dist/{chunk-HL3FBJ6X.cjs → chunk-XK55DEUD.cjs} +25 -62
  17. package/dist/docx/embedded.cjs +24 -1
  18. package/dist/docx/embedded.mjs +24 -1
  19. package/dist/docx/index.cjs +24 -1
  20. package/dist/docx/index.mjs +24 -1
  21. package/dist/docx/load/index.cjs +24 -1
  22. package/dist/docx/load/index.mjs +24 -1
  23. package/dist/docx/ui/content-control-commands.d.ts +1 -1
  24. package/dist/docx/ui/content-control-commands.d.ts.map +1 -1
  25. package/dist/docx/ui/content-control-guard.d.ts.map +1 -1
  26. package/dist/docx/ui/content-control-occurrences.d.ts +17 -0
  27. package/dist/docx/ui/content-control-occurrences.d.ts.map +1 -0
  28. package/dist/docx/ui/content-control-temporary.d.ts +1 -4
  29. package/dist/docx/ui/content-control-temporary.d.ts.map +1 -1
  30. package/dist/docx/ui/form-field-guard.d.ts +10 -4
  31. package/dist/docx/ui/form-field-guard.d.ts.map +1 -1
  32. package/dist/docx/ui/form-protection-sections.d.ts +26 -0
  33. package/dist/docx/ui/form-protection-sections.d.ts.map +1 -0
  34. package/dist/docx/ui/form-text-paste.d.ts +35 -0
  35. package/dist/docx/ui/form-text-paste.d.ts.map +1 -0
  36. package/dist/docx/ui/index.cjs +266 -108
  37. package/dist/docx/ui/index.mjs +266 -108
  38. package/dist/docx/write-table-controls.d.ts +2 -1
  39. package/dist/docx/write-table-controls.d.ts.map +1 -1
  40. package/dist/pptx/automation/index.cjs +25 -67
  41. package/dist/pptx/automation/index.d.ts +3 -2
  42. package/dist/pptx/automation/index.d.ts.map +1 -1
  43. package/dist/pptx/automation/index.mjs +5 -5
  44. package/dist/pptx/chunks/{index-Q5mM8kIR.d.ts → index-4FmgJajb.d.ts} +3 -2
  45. package/dist/pptx/chunks/index-4FmgJajb.d.ts.map +1 -0
  46. package/dist/pptx/chunks/index-C3xhAMSa.d.ts +837 -0
  47. package/dist/pptx/chunks/index-C3xhAMSa.d.ts.map +1 -0
  48. package/dist/pptx/chunks/{index-CPhsd7Df.d.ts → index-nKQ4s7FA.d.ts} +24 -834
  49. package/dist/pptx/chunks/index-nKQ4s7FA.d.ts.map +1 -0
  50. package/dist/pptx/cli/index.cjs +25 -67
  51. package/dist/pptx/cli/index.mjs +4 -4
  52. package/dist/pptx/converter/index.d.ts +1 -1
  53. package/dist/pptx/converter/index.mjs +2 -2
  54. package/dist/pptx/editor/render/find-replace.d.ts +1 -1
  55. package/dist/pptx/editor/render/slide-operations.cjs +1 -1
  56. package/dist/pptx/editor/render/slide-operations.mjs +1 -1
  57. package/dist/pptx/index.cjs +25 -67
  58. package/dist/pptx/index.d.ts +4 -3
  59. package/dist/pptx/index.mjs +5 -5
  60. package/dist/pptx/node/index.cjs +40 -0
  61. package/dist/pptx/node/index.d.ts +13 -0
  62. package/dist/pptx/node/index.d.ts.map +1 -0
  63. package/dist/pptx/node/index.mjs +40 -0
  64. package/package.json +6 -1
  65. package/dist/pptx/chunks/index-CPhsd7Df.d.ts.map +0 -1
  66. package/dist/pptx/chunks/index-Q5mM8kIR.d.ts.map +0 -1
@@ -948,12 +948,56 @@ var isPlaceholderStyle = (mark) => mark.type.name === "characterStyle" && mark.a
948
948
  function firstText(state, span) {
949
949
  if (span.level === "inline") return state.doc.nodeAt(span.from);
950
950
  let found = null;
951
- state.doc.nodesBetween(span.from, span.to, (node) => {
951
+ state.doc.nodesBetween(span.from, span.to, (node, pos) => {
952
952
  if (!found && node.isText) found = node;
953
+ return !found && !(span.level === "cell" && node.type.name === "table" && pos > span.from);
954
+ });
955
+ return found;
956
+ }
957
+ function holdsNothing(doc, from, to) {
958
+ let nothing = true;
959
+ if (from < to)
960
+ doc.nodesBetween(from, to, (node) => {
961
+ if (node.isInline) nothing = false;
962
+ return nothing;
963
+ });
964
+ return nothing;
965
+ }
966
+ function touchesTable(doc, cell, from, to) {
967
+ let found = false;
968
+ doc.nodesBetween(from, to, (node, pos) => {
969
+ found ||= node.type.name === "table" && pos > cell;
953
970
  return !found;
954
971
  });
955
972
  return found;
956
973
  }
974
+ function cellText(doc, pos) {
975
+ const cell = doc.nodeAt(pos);
976
+ const text2 = { from: pos + 2, to: pos + cell.nodeSize - 2 };
977
+ let first3 = true;
978
+ cell.forEach((child, offset) => {
979
+ if (child.type.name !== "paragraph") return;
980
+ if (first3) text2.from = pos + 2 + offset;
981
+ text2.to = pos + offset + child.nodeSize;
982
+ first3 = false;
983
+ });
984
+ return text2;
985
+ }
986
+ function cellContent(state, cell, text2) {
987
+ const nodes = [];
988
+ let placed = false;
989
+ cell.forEach((child) => {
990
+ if (child.type.name !== "paragraph") {
991
+ nodes.push(child);
992
+ return;
993
+ }
994
+ const attrs2 = child.attrs.contentControl ? { ...child.attrs, contentControl: null } : child.attrs;
995
+ nodes.push(child.type.create(attrs2, placed ? null : text2));
996
+ placed = true;
997
+ });
998
+ if (!placed) nodes.push(state.schema.nodes.paragraph.create(null, text2));
999
+ return prosemirrorModel.Fragment.fromArray(nodes);
1000
+ }
957
1001
  function contentMarks(state, span, change) {
958
1002
  const schema = state.schema;
959
1003
  const first3 = firstText(state, span);
@@ -985,10 +1029,7 @@ function replaceControlContent(state, span, edit) {
985
1029
  if (span.level !== "cell")
986
1030
  return state.tr.replaceWith(span.from, span.to, text2 ?? []).setMeta(CONTROL_EDIT_META, true);
987
1031
  const cell = state.doc.nodeAt(span.from);
988
- const first3 = cell.firstChild?.type.name === "paragraph" ? cell.firstChild : void 0;
989
- const attrs2 = first3?.attrs.contentControl ? { ...first3.attrs, contentControl: null } : first3?.attrs;
990
- const paragraph = (first3?.type ?? state.schema.nodes.paragraph).create(attrs2, text2);
991
- const tr = state.tr.replaceWith(span.from + 1, span.to - 1, paragraph);
1032
+ const tr = state.tr.replaceWith(span.from + 1, span.to - 1, cellContent(state, cell, text2));
992
1033
  tr.setNodeMarkup(span.from, void 0, {
993
1034
  ...cell.attrs,
994
1035
  contentControl: change.removed ? null : change.control
@@ -996,7 +1037,7 @@ function replaceControlContent(state, span, edit) {
996
1037
  const { from, to } = state.selection;
997
1038
  if (from > span.from && to < span.to) {
998
1039
  const shown = change.control.showingPlaceholder && !change.removed;
999
- const start = span.from + 2;
1040
+ const start = cellText(tr.doc, span.from).from;
1000
1041
  tr.setSelection(prosemirrorState.TextSelection.create(tr.doc, shown ? start : start + (text2?.nodeSize ?? 0)));
1001
1042
  }
1002
1043
  return tr.setMeta(CONTROL_EDIT_META, true);
@@ -1055,8 +1096,14 @@ function chooseDate(state, id, date, at) {
1055
1096
  return void 0;
1056
1097
  return replaceControlContent(state, span, setControlDate(span.control, date));
1057
1098
  }
1099
+ function inputControlAt(spans, pos) {
1100
+ const span = controlAt(spans, pos, true);
1101
+ if (span?.level !== "block") return span;
1102
+ const cells = spans.filter((other) => other.level === "cell");
1103
+ return controlAt(cells, pos) ?? span;
1104
+ }
1058
1105
  function typeOverPlaceholder(state, from, text2, to = from) {
1059
- const span = controlAt(controlSpans(state.doc), from, true);
1106
+ const span = inputControlAt(controlSpans(state.doc), from);
1060
1107
  if (span?.level === "cell") return typeInCell(state, span, text2, to);
1061
1108
  if (span?.level !== "inline") return void 0;
1062
1109
  const { control } = span;
@@ -1079,7 +1126,9 @@ function typeInCell(state, span, text2, to) {
1079
1126
  return void 0;
1080
1127
  if (!editable(state, span)) return "blocked";
1081
1128
  const tr = replaceControlContent(state, span, afterEdit({ control: withValue(control), text: text2 }));
1082
- return tr.setSelection(prosemirrorState.TextSelection.create(tr.doc, span.from + 2 + text2.length));
1129
+ return tr.setSelection(
1130
+ prosemirrorState.TextSelection.create(tr.doc, cellText(tr.doc, span.from).from + text2.length)
1131
+ );
1083
1132
  }
1084
1133
  function withoutPlaceholderStyle(fragment) {
1085
1134
  const nodes = [];
@@ -1092,7 +1141,7 @@ function withoutPlaceholderStyle(fragment) {
1092
1141
  }
1093
1142
  function pasteInCell(state, slice) {
1094
1143
  const { from, to } = state.selection;
1095
- const span = controlAt(controlSpans(state.doc), from, true);
1144
+ const span = inputControlAt(controlSpans(state.doc), from);
1096
1145
  if (span?.level !== "cell" || to > span.to - 1) return void 0;
1097
1146
  const { control } = span;
1098
1147
  if (control.kind === "checkbox" || control.kind === "dropDownList") return "blocked";
@@ -1103,23 +1152,26 @@ function pasteInCell(state, slice) {
1103
1152
  span,
1104
1153
  afterEdit({ control: withValue(control), text: "" })
1105
1154
  );
1106
- const at = prosemirrorState.TextSelection.create(tr.doc, span.from + 2);
1155
+ const at = prosemirrorState.TextSelection.create(tr.doc, cellText(tr.doc, span.from).from);
1107
1156
  return tr.setSelection(at).replaceSelection(
1108
1157
  new prosemirrorModel.Slice(withoutPlaceholderStyle(slice.content), slice.openStart, slice.openEnd)
1109
1158
  );
1110
1159
  }
1111
1160
  function deleteToPlaceholder(state, direction) {
1112
1161
  const { selection } = state;
1113
- const span = controlAt(controlSpans(state.doc), selection.from, true);
1162
+ const span = inputControlAt(controlSpans(state.doc), selection.from);
1114
1163
  if (!span || span.level === "block" || span.control.showingPlaceholder) return void 0;
1115
1164
  if (!editable(state, span) || span.control.kind === "checkbox") return void 0;
1116
1165
  if (!replaceable(state, span)) return void 0;
1117
1166
  if (removedByEdit(span.control)) return void 0;
1118
1167
  const [from, to] = selection.empty ? direction === "backward" ? [selection.from - 1, selection.from] : [selection.from, selection.from + 1] : [selection.from, selection.to];
1119
1168
  const cell = span.level === "cell";
1120
- const inner = cell ? { from: span.from + 2, to: span.to - 2 } : span;
1169
+ const inner = cell ? cellText(state.doc, span.from) : span;
1121
1170
  const outer = cell ? { from: span.from + 1, to: span.to - 1 } : span;
1122
- if (from > inner.from || to < inner.to || from < outer.from || to > outer.to) return void 0;
1171
+ if (from < outer.from || to > outer.to) return void 0;
1172
+ if (cell && touchesTable(state.doc, span.from, from, to)) return void 0;
1173
+ if (!holdsNothing(state.doc, inner.from, from) || !holdsNothing(state.doc, to, inner.to))
1174
+ return void 0;
1123
1175
  return replaceControlContent(state, span, placeholderChange(span.control));
1124
1176
  }
1125
1177
  var newControlId = (doc) => freshControlId(new Set(everyControlSpan(doc).map((span) => span.control.id)));
@@ -1152,6 +1204,43 @@ function insertContentControl(state, kind, options2 = {}) {
1152
1204
  tr.setSelection(prosemirrorState.TextSelection.create(tr.doc, start, start + change.text.length));
1153
1205
  return tr.setMeta(CONTROL_EDIT_META, true);
1154
1206
  }
1207
+
1208
+ // docx/ui/content-control-occurrences.ts
1209
+ function continues(doc, inline, end, span) {
1210
+ if (span.from === end) return true;
1211
+ if (span.level === "inline") {
1212
+ let at = end;
1213
+ for (const other of inline) if (other.from === at && other.to <= span.from) at = other.to;
1214
+ return at === span.from;
1215
+ }
1216
+ if (span.level !== "block") return false;
1217
+ const $end = doc.resolve(end);
1218
+ if (doc.resolve(span.from).parent !== $end.parent) return false;
1219
+ let split = true;
1220
+ $end.parent.forEach((node, offset) => {
1221
+ const pos = $end.start() + offset;
1222
+ if (pos < end || pos >= span.from || node.type.name !== "paragraph") return;
1223
+ if (!node.attrs.contentControl) split = false;
1224
+ });
1225
+ return split;
1226
+ }
1227
+ function controlOccurrences(doc, spans, inline) {
1228
+ const found = [];
1229
+ const last = /* @__PURE__ */ new Map();
1230
+ for (const span of [...spans].sort((a, b) => a.from - b.from)) {
1231
+ const key = `${span.level}:${span.control.id}`;
1232
+ const previous = last.get(key);
1233
+ if (previous && continues(doc, inline, previous.to, span)) {
1234
+ previous.spans.push(span);
1235
+ previous.to = span.to;
1236
+ continue;
1237
+ }
1238
+ const occurrence = { key, spans: [span], from: span.from, to: span.to };
1239
+ found.push(occurrence);
1240
+ last.set(key, occurrence);
1241
+ }
1242
+ return found;
1243
+ }
1155
1244
  var VERBATIM = ["sourceXml", "endSourceXml"];
1156
1245
  var INLINE = ["endSourceXml"];
1157
1246
  var sourcesOf = (control, fields = VERBATIM) => fields.flatMap((field) => {
@@ -4141,8 +4230,8 @@ function resolveChartStyleDefinition(style, resolve) {
4141
4230
  }
4142
4231
  return Object.keys(out).length ? out : void 0;
4143
4232
  }
4144
- function effectiveBuiltInChartStyle(formatting) {
4145
- return formatting?.builtInStyle ?? (formatting?.sourceXml ? void 0 : 102);
4233
+ function effectiveBuiltInChartStyle(formatting2) {
4234
+ return formatting2?.builtInStyle ?? (formatting2?.sourceXml ? void 0 : 102);
4146
4235
  }
4147
4236
  function builtInChartTextStyle(id) {
4148
4237
  if (id === void 0 || !Number.isInteger(id) || !(id >= 1 && id <= 48 || id >= 101 && id <= 148))
@@ -5915,10 +6004,10 @@ function properties(run) {
5915
6004
  };
5916
6005
  }
5917
6006
  function chartTitleText(chart, theme) {
5918
- const formatting = chart.formatting;
5919
- const entry = formatting?.entries.title;
6007
+ const formatting2 = chart.formatting;
6008
+ const entry = formatting2?.entries.title;
5920
6009
  const body = entry?.textBody;
5921
- if (!formatting || !body || body.text !== chart.title) return void 0;
6010
+ if (!formatting2 || !body || body.text !== chart.title) return void 0;
5922
6011
  if (body.paragraphs.length === 1 && body.paragraphs[0].runs.length <= 1 && !body.text.includes("\n") && !body.paragraphs[0].lineSpacing && !body.paragraphs[0].spaceBefore && !body.paragraphs[0].spaceAfter)
5923
6012
  return void 0;
5924
6013
  return {
@@ -5937,7 +6026,7 @@ function chartTitleText(chart, theme) {
5937
6026
  const appearance = chartAppearance(
5938
6027
  {
5939
6028
  ...chart,
5940
- formatting: { ...formatting, entries: { ...formatting.entries, title: direct } }
6029
+ formatting: { ...formatting2, entries: { ...formatting2.entries, title: direct } }
5941
6030
  },
5942
6031
  theme
5943
6032
  )?.title ?? {};
@@ -7306,9 +7395,9 @@ function chartSpaceKind(space) {
7306
7395
  return { type, drawn: DRAWN_CHART_TYPES.has(type) };
7307
7396
  }
7308
7397
  function renderChartSpaceSvg(space, options2) {
7309
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
7398
+ const { width, height, theme, fonts, formatting: formatting2, colorPalette, styleDefinition, ...svg } = options2;
7310
7399
  const summary = chartSummaryFromSpace(space, {
7311
- ...formatting ? { formatting } : {},
7400
+ ...formatting2 ? { formatting: formatting2 } : {},
7312
7401
  ...colorPalette !== void 0 ? { colorPalette } : {},
7313
7402
  ...styleDefinition ? { styleDefinition } : {}
7314
7403
  });
@@ -8789,12 +8878,12 @@ function resolveTableStyleFormatting(tableStyleId, catalog, look, rowIndex, rowC
8789
8878
  if (style.borders) result.borders = { ...result.borders, ...style.borders };
8790
8879
  if (style.shadingFill) result.shadingFill = style.shadingFill;
8791
8880
  for (const region of regions) {
8792
- const formatting = style.conditional[region];
8793
- if (!formatting) continue;
8794
- if (formatting.borders) result.borders = { ...result.borders, ...formatting.borders };
8795
- if (formatting.shadingFill) result.shadingFill = formatting.shadingFill;
8796
- if (formatting.shadingThemeFill) result.shadingThemeFill = formatting.shadingThemeFill;
8797
- if (formatting.run) result.run = { ...result.run, ...formatting.run };
8881
+ const formatting2 = style.conditional[region];
8882
+ if (!formatting2) continue;
8883
+ if (formatting2.borders) result.borders = { ...result.borders, ...formatting2.borders };
8884
+ if (formatting2.shadingFill) result.shadingFill = formatting2.shadingFill;
8885
+ if (formatting2.shadingThemeFill) result.shadingThemeFill = formatting2.shadingThemeFill;
8886
+ if (formatting2.run) result.run = { ...result.run, ...formatting2.run };
8798
8887
  }
8799
8888
  }
8800
8889
  return result;
@@ -12707,7 +12796,7 @@ function trackChangesPlugin(getAuthor, isEnabled, idGenerator = createCollaborat
12707
12796
  if (boundary) return boundary.setMeta(trackChangesPluginKey, { tracked: true });
12708
12797
  if (!steps.length || !steps.every((step) => step instanceof prosemirrorTransform.ReplaceStep)) {
12709
12798
  if (newState.doc.attrs.trackFormatting === false) return null;
12710
- const formatting = trackRunFormatting(
12799
+ const formatting2 = trackRunFormatting(
12711
12800
  steps,
12712
12801
  oldState,
12713
12802
  newState,
@@ -12722,7 +12811,7 @@ function trackChangesPlugin(getAuthor, isEnabled, idGenerator = createCollaborat
12722
12811
  date,
12723
12812
  () => idGenerator("revision")
12724
12813
  );
12725
- return formatting?.setMeta(trackChangesPluginKey, { tracked: true }) ?? null;
12814
+ return formatting2?.setMeta(trackChangesPluginKey, { tracked: true }) ?? null;
12726
12815
  }
12727
12816
  const transform = new prosemirrorTransform.Transform(oldState.doc);
12728
12817
  const untracked = new prosemirrorTransform.Mapping();
@@ -12809,46 +12898,15 @@ function removeControl(tr, span) {
12809
12898
  return tr;
12810
12899
  }
12811
12900
  var BLOCKS = /* @__PURE__ */ new Set(["paragraph", "table"]);
12812
- function continues(doc, inline, end, span) {
12813
- if (span.from === end) return true;
12814
- if (span.level === "inline") {
12815
- let at = end;
12816
- for (const other of inline) if (other.from === at && other.to <= span.from) at = other.to;
12817
- return at === span.from;
12818
- }
12819
- if (span.level !== "block") return false;
12820
- const $end = doc.resolve(end);
12821
- if (doc.resolve(span.from).parent !== $end.parent) return false;
12822
- let split = true;
12823
- $end.parent.forEach((node, offset) => {
12824
- const pos = $end.start() + offset;
12825
- if (pos < end || pos >= span.from || node.type.name !== "paragraph") return;
12826
- if (!node.attrs.contentControl) split = false;
12827
- });
12828
- return split;
12829
- }
12830
12901
  function temporaryControls(doc) {
12831
12902
  const spans = controlSpans(doc);
12832
12903
  const inline = spans.filter((span) => span.level === "inline");
12833
- const found = [];
12834
- const last = /* @__PURE__ */ new Map();
12835
- const candidates = [...spans, ...tableControlSpans(doc), ...rowControlSpans(doc)].sort(
12836
- (a, b) => a.from - b.from
12904
+ const candidates = [...spans, ...tableControlSpans(doc), ...rowControlSpans(doc)];
12905
+ return controlOccurrences(
12906
+ doc,
12907
+ candidates.filter((span) => removedByEdit(span.control)),
12908
+ inline
12837
12909
  );
12838
- for (const span of candidates) {
12839
- if (!removedByEdit(span.control)) continue;
12840
- const key = `${span.level}:${span.control.id}`;
12841
- const previous = last.get(key);
12842
- if (previous && continues(doc, inline, previous.to, span)) {
12843
- previous.spans.push(span);
12844
- previous.to = span.to;
12845
- continue;
12846
- }
12847
- const occurrence = { key, spans: [span], from: span.from, to: span.to };
12848
- found.push(occurrence);
12849
- last.set(key, occurrence);
12850
- }
12851
- return found;
12852
12910
  }
12853
12911
  function removeEditedTemporaryControls(transactions, before, after) {
12854
12912
  const local = transactions.filter(
@@ -12907,22 +12965,46 @@ function changesAttributesOnly(step, doc) {
12907
12965
  const next = slice.content.firstChild;
12908
12966
  return insert === 1 && gapFrom === from + 1 && gapTo === to - 1 && slice.openStart === 0 && slice.openEnd === 0 && slice.content.childCount === 1 && node !== null && next !== null && !node.isLeaf && next.content.size === 0 && node.nodeSize === to - from && next.type === node.type && sameControl(nodeControlOf(node)?.value, nodeControlOf(next)?.value);
12909
12967
  }
12910
- var isMarkOf = (mark, control) => mark.type.name === "contentControl" && sameControl(controlOfMark(mark), control);
12968
+ function sameId(left, right) {
12969
+ const id = left?.id;
12970
+ return typeof id === "string" && id === right?.id;
12971
+ }
12972
+ var isMarkOf = (mark, control, same2 = sameControl) => mark.type.name === "contentControl" && same2(controlOfMark(mark), control);
12973
+ function holdsControl(node, span, same2 = sameControl) {
12974
+ if (span.level === "inline") return node.marks.some((mark) => isMarkOf(mark, span.control, same2));
12975
+ const held = nodeControlOf(node);
12976
+ return held?.level === span.level && same2(held.value, span.control);
12977
+ }
12978
+ function putsBack(step, span, same2 = sameControl) {
12979
+ let found = false;
12980
+ if (step instanceof prosemirrorTransform.ReplaceStep)
12981
+ step.slice.content.descendants((node) => {
12982
+ found ||= holdsControl(node, span, same2);
12983
+ return !found;
12984
+ });
12985
+ return found;
12986
+ }
12911
12987
  function keepsControl(step, span) {
12912
12988
  if (step instanceof prosemirrorTransform.AddMarkStep)
12913
12989
  return span.level !== "inline" || step.mark.type.name !== "contentControl" || isMarkOf(step.mark, span.control);
12914
12990
  if (step instanceof prosemirrorTransform.RemoveMarkStep)
12915
12991
  return span.level !== "inline" || !isMarkOf(step.mark, span.control);
12916
- let kept = false;
12917
- if (span.level === "inline" && step instanceof prosemirrorTransform.ReplaceStep)
12918
- step.slice.content.descendants((node) => {
12919
- kept ||= node.marks.some((mark) => isMarkOf(mark, span.control));
12920
- return !kept;
12921
- });
12922
- return kept;
12992
+ return putsBack(step, span);
12993
+ }
12994
+ function lockedControls(doc) {
12995
+ const locked = everyControlSpan(doc).filter((span) => span.control.lock);
12996
+ const inline = locked.filter((span) => span.level === "inline");
12997
+ return [
12998
+ ...inline.map((span) => ({ key: "", spans: [span], from: span.from, to: span.to })),
12999
+ ...controlOccurrences(
13000
+ doc,
13001
+ locked.filter((span) => span.level !== "inline"),
13002
+ []
13003
+ )
13004
+ ];
12923
13005
  }
12924
13006
  function violatesControlLock(tr, state, history = false) {
12925
- const locked = everyControlSpan(state.doc).filter((span) => span.control.lock);
13007
+ const locked = lockedControls(state.doc);
12926
13008
  return tr.steps.some((step, index) => {
12927
13009
  const before = tr.mapping.slice(0, index);
12928
13010
  if (step instanceof prosemirrorTransform.AttrStep) {
@@ -12930,18 +13012,20 @@ function violatesControlLock(tr, state, history = false) {
12930
13012
  if (node && isContentControlLocked(inlineRunProperties(node).contentControl, "content"))
12931
13013
  return true;
12932
13014
  return locked.some(
12933
- (span) => isContentControlLocked(span.control, "content") && step.pos >= before.map(span.from, 1) && step.pos < before.map(span.to, -1)
13015
+ (occurrence) => isContentControlLocked(occurrence.spans[0].control, "content") && step.pos >= before.map(occurrence.from, 1) && step.pos < before.map(occurrence.to, -1)
12934
13016
  );
12935
13017
  }
12936
13018
  if (!locked.length || !isRangeStep(step)) return false;
12937
13019
  const { from, to } = step;
12938
13020
  const inserts = from === to;
12939
13021
  const kept = changesAttributesOnly(step, tr.docs[index]);
12940
- return locked.some((span) => {
12941
- const spanFrom = before.map(span.from, 1);
12942
- const spanTo = before.map(span.to, -1);
13022
+ return locked.some((occurrence) => {
13023
+ const span = occurrence.spans[0];
13024
+ const spanFrom = before.map(occurrence.from, 1);
13025
+ const spanTo = before.map(occurrence.to, -1);
12943
13026
  const removesWhole = !inserts && from <= spanFrom && to >= spanTo;
12944
13027
  const keeps = kept || keepsControl(step, span);
13028
+ if (removesWhole && !keeps && putsBack(step, span, sameId)) return true;
12945
13029
  if (isContentControlLocked(span.control, "control") && removesWhole && !keeps && !history)
12946
13030
  return true;
12947
13031
  if (!isContentControlLocked(span.control, "content") || removesWhole && !keeps)
@@ -16379,25 +16463,6 @@ function replacedBlanks(before, beforeResults, after, afterResults, mapping) {
16379
16463
  (space) => filled.some((result) => space.from >= result.from && space.to <= result.to)
16380
16464
  );
16381
16465
  }
16382
-
16383
- // docx/ui/form-field-guard.ts
16384
- var isRemote2 = (tr) => tr.getMeta("y-sync$") !== void 0;
16385
- var isHistory = (tr) => tr.getMeta("history$") !== void 0;
16386
- var isFormsProtected = (protection) => Boolean(protection?.enforced) && protection?.edit === "forms";
16387
- function exceedsFormTextLength(tr) {
16388
- const beforeResults = formTextResults(tr.before);
16389
- const afterResults = formTextResults(tr.doc);
16390
- const replaced = replacedBlanks(tr.before, beforeResults, tr.doc, afterResults, tr.mapping);
16391
- const length = (doc, result, removed = []) => isBlankFormText(doc, result) ? 0 : result.length - removed.filter((space) => space.from >= result.from && space.to <= result.to).length;
16392
- const before = new Map(
16393
- beforeResults.map((result) => [tr.mapping.map(result.begin), length(tr.before, result)])
16394
- );
16395
- return afterResults.some((result) => {
16396
- const max = result.field.textInput?.maxLength;
16397
- const now = length(tr.doc, result, replaced);
16398
- return Boolean(max) && now > max && now > (before.get(result.begin) ?? 0);
16399
- });
16400
- }
16401
16466
  function unprotectedSections(doc) {
16402
16467
  if (typeof doc.attrs.sections !== "string") return [];
16403
16468
  const sections2 = JSON.parse(doc.attrs.sections);
@@ -16450,14 +16515,92 @@ function renamesBlock(step, before, after) {
16450
16515
  )
16451
16516
  );
16452
16517
  }
16453
- function staysInFormFields(tr) {
16518
+ function inProtectedFormText(doc, from, to, free) {
16519
+ return formTextResults(doc).some(
16520
+ (result) => result.field.enabled !== false && from >= result.from && to <= result.to && !free.some((range) => result.from >= range.from && result.to <= range.to)
16521
+ );
16522
+ }
16523
+ function inFormatting(fragment, marks) {
16524
+ const children3 = [];
16525
+ fragment.forEach((node) => {
16526
+ if (node.isText) children3.push(node.mark(marks));
16527
+ else children3.push(node.isLeaf ? node : node.copy(inFormatting(node.content, marks)));
16528
+ });
16529
+ return prosemirrorModel.Fragment.fromArray(children3);
16530
+ }
16531
+ function landingMarks(state) {
16532
+ const { $from, $to, empty } = state.selection;
16533
+ if (state.storedMarks) return state.storedMarks;
16534
+ if (!empty) return $from.marksAcross($to) ?? $from.marks();
16535
+ const after = $from.nodeAfter;
16536
+ return !$from.nodeBefore?.isText && after?.isText ? after.marks : $from.marks();
16537
+ }
16538
+ function pasteIntoFormText(view, slice, free) {
16539
+ const { state } = view;
16540
+ const { from, to } = state.selection;
16541
+ if (!slice.size || !inProtectedFormText(state.doc, from, to, free)) return false;
16542
+ const text2 = new prosemirrorModel.Slice(
16543
+ inFormatting(slice.content, landingMarks(state)),
16544
+ slice.openStart,
16545
+ slice.openEnd
16546
+ );
16547
+ view.dispatch(
16548
+ state.tr.replaceSelection(text2).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")
16549
+ );
16550
+ return true;
16551
+ }
16552
+ var formatting = (marks) => marks.filter((mark) => mark.type.name !== "field");
16553
+ function writesFormatting(step, doc, stored) {
16554
+ const $from = doc.resolve(step.from);
16555
+ const allowed = [...$from.marks(), ...stored ?? []];
16556
+ const around = [$from.nodeBefore, doc.resolve(step.to).nodeAfter];
16557
+ for (const node of around) if (node?.isText) allowed.push(...node.marks);
16558
+ doc.nodesBetween(step.from, step.to, (node) => {
16559
+ if (node.isText) allowed.push(...node.marks);
16560
+ });
16561
+ let found = false;
16562
+ step.slice.content.descendants((node) => {
16563
+ found ||= node.isText && formatting(node.marks).some((mark) => !mark.isInSet(allowed));
16564
+ return !found;
16565
+ });
16566
+ return found;
16567
+ }
16568
+ function storesFormatting(tr, free) {
16569
+ if (tr.docChanged || !tr.storedMarksSet || !tr.storedMarks) return false;
16570
+ const { from, to, $from } = tr.selection;
16571
+ if (prosemirrorModel.Mark.sameSet(formatting(tr.storedMarks), formatting($from.marks()))) return false;
16572
+ return inProtectedFormText(tr.doc, from, to, free());
16573
+ }
16574
+
16575
+ // docx/ui/form-field-guard.ts
16576
+ var isRemote2 = (tr) => tr.getMeta("y-sync$") !== void 0;
16577
+ var isHistory = (tr) => tr.getMeta("history$") !== void 0;
16578
+ var isFormsProtected = (protection) => Boolean(protection?.enforced) && protection?.edit === "forms";
16579
+ function exceedsFormTextLength(tr) {
16580
+ const beforeResults = formTextResults(tr.before);
16581
+ const afterResults = formTextResults(tr.doc);
16582
+ const replaced = replacedBlanks(tr.before, beforeResults, tr.doc, afterResults, tr.mapping);
16583
+ const length = (doc, result, removed = []) => isBlankFormText(doc, result) ? 0 : result.length - removed.filter((space) => space.from >= result.from && space.to <= result.to).length;
16584
+ const before = new Map(
16585
+ beforeResults.map((result) => [tr.mapping.map(result.begin), length(tr.before, result)])
16586
+ );
16587
+ return afterResults.some((result) => {
16588
+ const max = result.field.textInput?.maxLength;
16589
+ const now = length(tr.doc, result, replaced);
16590
+ return Boolean(max) && now > max && now > (before.get(result.begin) ?? 0);
16591
+ });
16592
+ }
16593
+ function staysInFormFields(tr, kept) {
16454
16594
  const doc = tr.before;
16455
- const fields = [
16456
- ...formTextResults(doc).filter(({ field }) => field.enabled !== false).map(({ from, to }) => ({ from, to })),
16457
- ...controlSpans(doc).map(({ from, to }) => ({ from, to }))
16458
- ];
16595
+ const results = formTextResults(doc);
16596
+ const values = results.filter(({ field }) => field.enabled !== false);
16597
+ const fields = [...values, ...controlSpans(doc).map(({ from, to }) => ({ from, to }))];
16459
16598
  const sections2 = unprotectedSections(doc);
16460
- const fixed = formTextResults(doc).filter(({ field }) => field.enabled === false).map(({ begin, to }) => ({ from: begin, to: to + 1 })).filter((range) => !sections2.some((free) => range.from >= free.from && range.to <= free.to));
16599
+ const free = (range) => sections2.some((it) => range.from >= it.from && range.to <= it.to);
16600
+ const fixed = results.filter(({ field }) => field.enabled === false).map(({ begin, to }) => ({ from: begin, to: to + 1 })).filter((range) => !free(range));
16601
+ const plain = values.filter((range) => !free(range));
16602
+ const internal = isHistory(tr) || Boolean(tr.getMeta(FIELD_RESULT_REPAIR_META));
16603
+ const tracked = Boolean(tr.getMeta(trackChangesPluginKey));
16461
16604
  let sectionsAfter;
16462
16605
  return tr.steps.every((step, index) => {
16463
16606
  const after = tr.docs[index + 1] ?? tr.doc;
@@ -16472,16 +16615,23 @@ function staysInFormFields(tr) {
16472
16615
  if (!(step instanceof prosemirrorTransform.ReplaceStep || step instanceof prosemirrorTransform.ReplaceAroundStep || step instanceof prosemirrorTransform.AddMarkStep || step instanceof prosemirrorTransform.RemoveMarkStep))
16473
16616
  return false;
16474
16617
  const { from, to } = step;
16475
- const touchesFixed = (start2, end2) => fixed.some((range) => start2 < map.map(range.to, -1) && end2 > map.map(range.from, 1));
16476
- let changesFixed = (step instanceof prosemirrorTransform.AddMarkStep || step instanceof prosemirrorTransform.RemoveMarkStep) && touchesFixed(from, to);
16618
+ const touches = (ranges, start2, end2) => ranges.some((range) => start2 < map.map(range.to, -1) && end2 > map.map(range.from, 1));
16619
+ const marks = step instanceof prosemirrorTransform.AddMarkStep || step instanceof prosemirrorTransform.RemoveMarkStep;
16620
+ if (!internal && !tracked && (within2(plain, from, to) || touches(plain, from, to))) {
16621
+ if (marks) return false;
16622
+ const stored = kept && from === map.map(kept.at) ? kept.marks : null;
16623
+ if (step instanceof prosemirrorTransform.ReplaceStep && writesFormatting(step, tr.docs[index], stored))
16624
+ return false;
16625
+ }
16626
+ let changesFixed = marks && touches(fixed, from, to);
16477
16627
  step.getMap().forEach((start2, end2) => {
16478
- changesFixed ||= touchesFixed(start2, end2);
16628
+ changesFixed ||= touches(fixed, start2, end2);
16479
16629
  });
16480
16630
  if (changesFixed) return false;
16481
16631
  if (within2(fields, from, to))
16482
16632
  return !sections2.length || keepsSections(step, tr.docs[index], after);
16483
16633
  if (!within2(sections2, from, to)) return false;
16484
- if (step instanceof prosemirrorTransform.AddMarkStep || step instanceof prosemirrorTransform.RemoveMarkStep) return true;
16634
+ if (marks) return true;
16485
16635
  const rest = tr.mapping.slice(index + 1);
16486
16636
  const own2 = step.getMap();
16487
16637
  const start = rest.map(own2.map(from, -1), -1);
@@ -16516,12 +16666,20 @@ function formFieldGuardPlugin(protection) {
16516
16666
  init: (_config, state) => textFieldsOf(state.doc),
16517
16667
  apply: (tr, fields) => insertsFieldMarker(tr) ? textFieldsOf(tr.doc) : fields
16518
16668
  },
16669
+ props: {
16670
+ handlePaste: (view, _event, slice) => isFormsProtected(protection()) && pasteIntoFormText(view, slice, unprotectedSections(view.state.doc))
16671
+ },
16519
16672
  filterTransaction: (tr, state) => {
16673
+ if (isFormsProtected(protection()) && storesFormatting(tr, () => unprotectedSections(tr.doc)))
16674
+ return false;
16520
16675
  if (!tr.docChanged || isRemote2(tr)) return true;
16521
16676
  const limited = textFields.getState(state)?.limited || insertsFieldMarker(tr);
16522
16677
  if (limited && !isHistory(tr) && exceedsFormTextLength(tr)) return false;
16523
16678
  if (!isFormsProtected(protection())) return true;
16524
- return Boolean(tr.getMeta(CONTROL_EDIT_META) || tr.getMeta(FORM_FIELD_EDIT_META)) || staysInFormFields(tr);
16679
+ return Boolean(tr.getMeta(CONTROL_EDIT_META) || tr.getMeta(FORM_FIELD_EDIT_META)) || staysInFormFields(
16680
+ tr,
16681
+ state.storedMarks && { marks: state.storedMarks, at: state.selection.from }
16682
+ );
16525
16683
  },
16526
16684
  appendTransaction: (transactions, old, state) => {
16527
16685
  if (!transactions.some((tr2) => tr2.docChanged) || transactions.some(isRemote2)) return null;