superdoc 1.0.0-beta.2 → 1.0.0-beta.21

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 (44) hide show
  1. package/dist/chunks/{PdfViewer-saAhozRR.es.js → PdfViewer-CEwbF85g.es.js} +2 -2
  2. package/dist/chunks/{PdfViewer-CeuX3gOe.cjs → PdfViewer-CqAQvFv3.cjs} +2 -2
  3. package/dist/chunks/{eventemitter3-BZXKb7j7.es.js → eventemitter3-CcXAdeql.es.js} +1 -1
  4. package/dist/chunks/{eventemitter3-CFCpOk3d.cjs → eventemitter3-DQmQUge-.cjs} +1 -1
  5. package/dist/chunks/{index-C0OeGje6.es.js → index-BFobqgP4.es.js} +11 -7
  6. package/dist/chunks/{index-Sn-JVHIg-BCItIT88.es.js → index-DSuc12CK-DH_DeF0B.es.js} +1 -1
  7. package/dist/chunks/{index-Sn-JVHIg-BxOp3gSx.cjs → index-DSuc12CK-Dpg5Hd9W.cjs} +1 -1
  8. package/dist/chunks/{index-Dh5oVJua.cjs → index-Dy-eAVHL.cjs} +11 -7
  9. package/dist/chunks/{jszip-Duxs2YMV.es.js → jszip-5vvIqAEE.es.js} +1 -1
  10. package/dist/chunks/{jszip-B99MTu59.cjs → jszip-BdEez1WM.cjs} +1 -1
  11. package/dist/chunks/{super-editor.es-Dcz39nKY.es.js → super-editor.es-B5YJmpPg.es.js} +11822 -2719
  12. package/dist/chunks/{super-editor.es-BKljkYUU.cjs → super-editor.es-C2UuUFg3.cjs} +11822 -2719
  13. package/dist/chunks/{vue-B5QAf5pA.es.js → vue-Dysv_7z5.es.js} +118 -29
  14. package/dist/chunks/{vue-ARQSyfaw.cjs → vue-jWLMl8Ts.cjs} +89 -0
  15. package/dist/chunks/xml-js-ClO_jHnq.es.js +2 -0
  16. package/dist/chunks/xml-js-Dz51sEbr.cjs +3 -0
  17. package/dist/packages/superdoc/src/components/CommentsLayer/use-comment.d.ts.map +1 -1
  18. package/dist/packages/superdoc/src/core/SuperDoc.d.ts +37 -4
  19. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  20. package/dist/packages/superdoc/src/core/types/index.d.ts +2 -2
  21. package/dist/packages/superdoc/src/stores/comments-store.d.ts.map +1 -1
  22. package/dist/style.css +66 -27
  23. package/dist/super-editor/ai-writer.es.js +2 -2
  24. package/dist/super-editor/chunks/{converter-BFGB7hqj.js → converter-Cw0V00On.js} +1217 -387
  25. package/dist/super-editor/chunks/{docx-zipper-OPbzIk16.js → docx-zipper-D7k6lS5l.js} +1 -1
  26. package/dist/super-editor/chunks/{editor-CtI4XnMw.js → editor-CDWzRc4H.js} +9747 -2175
  27. package/dist/super-editor/chunks/{index-Sn-JVHIg.js → index-DSuc12CK.js} +1 -1
  28. package/dist/super-editor/chunks/{toolbar-BydALv4o.js → toolbar-CHJspeuY.js} +39 -24
  29. package/dist/super-editor/converter.es.js +1 -1
  30. package/dist/super-editor/docx-zipper.es.js +2 -2
  31. package/dist/super-editor/editor.es.js +3 -3
  32. package/dist/super-editor/file-zipper.es.js +2 -2
  33. package/dist/super-editor/style.css +66 -27
  34. package/dist/super-editor/super-editor.es.js +1085 -250
  35. package/dist/super-editor/toolbar.es.js +2 -2
  36. package/dist/super-editor.cjs +4 -4
  37. package/dist/super-editor.es.js +2 -2
  38. package/dist/superdoc.cjs +2 -2
  39. package/dist/superdoc.es.js +2 -2
  40. package/dist/superdoc.umd.js +11894 -2711
  41. package/dist/superdoc.umd.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunks/xml-js-CVyfrKaV.es.js +0 -2
  44. package/dist/chunks/xml-js-DQa4Ye5C.cjs +0 -3
@@ -18972,7 +18972,6 @@ const encode$B = (params, encodedAttrs = {}) => {
18972
18972
  }
18973
18973
  }
18974
18974
  });
18975
- console.log("subs:", subs);
18976
18975
  return subs;
18977
18976
  };
18978
18977
  function decode$D(params) {
@@ -19181,6 +19180,7 @@ function getUnderlineCssString({ type: type2 = "single", color = null, thickness
19181
19180
  if (color) add("text-decoration-color", color);
19182
19181
  return parts.join("; ");
19183
19182
  }
19183
+ const INLINE_OVERRIDE_PROPERTIES = ["fontSize", "bold", "italic", "strike", "underline", "letterSpacing"];
19184
19184
  const resolveRunProperties = (params, inlineRpr, resolvedPpr, isListNumber = false, numberingDefinedInline = false) => {
19185
19185
  const paragraphStyleId = resolvedPpr?.styleId;
19186
19186
  const paragraphStyleProps = resolveStyleChain(params, paragraphStyleId, translator$1N);
@@ -19217,6 +19217,11 @@ const resolveRunProperties = (params, inlineRpr, resolvedPpr, isListNumber = fal
19217
19217
  styleChain = [...styleChain, paragraphStyleProps, runStyleProps, inlineRpr];
19218
19218
  }
19219
19219
  const finalProps = combineProperties(styleChain, ["fontFamily", "color"]);
19220
+ for (const prop of INLINE_OVERRIDE_PROPERTIES) {
19221
+ if (inlineRpr?.[prop] != null) {
19222
+ finalProps[prop] = inlineRpr[prop];
19223
+ }
19224
+ }
19220
19225
  return finalProps;
19221
19226
  };
19222
19227
  function resolveParagraphProperties(params, inlineProps, insideTable = false, overrideInlineStyleId = false, tableStyleId = null) {
@@ -19518,18 +19523,43 @@ function encodeMarksFromRPr(runProperties, docx) {
19518
19523
  }
19519
19524
  return marks;
19520
19525
  }
19521
- function encodeCSSFromPPr(paragraphProperties) {
19526
+ function encodeCSSFromPPr(paragraphProperties, hasPreviousParagraph, nextParagraphProps) {
19522
19527
  if (!paragraphProperties || typeof paragraphProperties !== "object") {
19523
19528
  return {};
19524
19529
  }
19525
19530
  let css = {};
19526
19531
  const { spacing, indent, borders, justification } = paragraphProperties;
19532
+ const nextStyleId = nextParagraphProps?.styleId;
19527
19533
  if (spacing) {
19534
+ const getEffectiveBefore = (nextSpacing, isListItem) => {
19535
+ if (!nextSpacing) return 0;
19536
+ if (nextSpacing.beforeAutospacing && isListItem) {
19537
+ return 0;
19538
+ }
19539
+ return nextSpacing.before || 0;
19540
+ };
19528
19541
  const isDropCap = Boolean(paragraphProperties.framePr?.dropCap);
19529
19542
  const spacingCopy = { ...spacing };
19543
+ if (hasPreviousParagraph) {
19544
+ delete spacingCopy.before;
19545
+ }
19530
19546
  if (isDropCap) {
19531
19547
  spacingCopy.line = linesToTwips(1);
19532
19548
  spacingCopy.lineRule = "auto";
19549
+ delete spacingCopy.after;
19550
+ } else {
19551
+ const nextBefore = getEffectiveBefore(
19552
+ nextParagraphProps?.spacing,
19553
+ Boolean(nextParagraphProps?.numberingProperties)
19554
+ );
19555
+ spacingCopy.after = Math.max(spacingCopy.after || 0, nextBefore);
19556
+ if (paragraphProperties.contextualSpacing && nextStyleId != null && nextStyleId === paragraphProperties.styleId) {
19557
+ spacingCopy.after -= paragraphProperties.spacing?.after || 0;
19558
+ }
19559
+ if (nextParagraphProps?.contextualSpacing && nextStyleId != null && nextStyleId === paragraphProperties.styleId) {
19560
+ spacingCopy.after -= nextBefore;
19561
+ }
19562
+ spacingCopy.after = Math.max(spacingCopy.after, 0);
19533
19563
  }
19534
19564
  const spacingStyle = getSpacingStyle(spacingCopy, Boolean(paragraphProperties.numberingProperties));
19535
19565
  css = { ...css, ...spacingStyle };
@@ -19749,7 +19779,7 @@ function decodeRPrFromMarks(marks) {
19749
19779
  return runProperties;
19750
19780
  }
19751
19781
  marks.forEach((mark) => {
19752
- switch (mark.type) {
19782
+ switch (mark.type.name ?? mark.type) {
19753
19783
  case "strike":
19754
19784
  case "italic":
19755
19785
  case "bold":
@@ -20106,6 +20136,51 @@ function getStrikeValue(attributes) {
20106
20136
  if (value === "0" || value === "false" || value === "off") return "0";
20107
20137
  return "1";
20108
20138
  }
20139
+ function parseProperties(node) {
20140
+ const marks = [];
20141
+ const unknownMarks = [];
20142
+ const { attributes = {}, elements = [] } = node;
20143
+ const { nodes, paragraphProperties = {}, runProperties = {} } = splitElementsAndProperties(elements);
20144
+ const hasRun = elements.find((element) => element.name === "w:r");
20145
+ if (hasRun) paragraphProperties.elements = paragraphProperties?.elements?.filter((el) => el.name !== "w:rPr");
20146
+ if (runProperties && runProperties?.elements?.length) {
20147
+ marks.push(...parseMarks(runProperties, unknownMarks));
20148
+ }
20149
+ if (paragraphProperties && paragraphProperties.elements?.length) {
20150
+ const disallowedParagraphProperties = ["w:u"];
20151
+ const filteredParagraphProperties = {
20152
+ ...paragraphProperties,
20153
+ elements: paragraphProperties.elements?.filter((el) => !disallowedParagraphProperties.includes(el.name))
20154
+ };
20155
+ marks.push(...parseMarks(filteredParagraphProperties, unknownMarks));
20156
+ }
20157
+ marks.push(...handleStyleChangeMarks(runProperties, marks));
20158
+ if (paragraphProperties && paragraphProperties.elements?.length) {
20159
+ attributes["paragraphProperties"] = paragraphProperties;
20160
+ }
20161
+ if (marks && node.name === "w:p") {
20162
+ marks.forEach((mark) => {
20163
+ const attrValue = Object.keys(mark.attrs ?? {})[0];
20164
+ if (attrValue) {
20165
+ const value = mark.attrs[attrValue];
20166
+ attributes[attrValue] = value;
20167
+ }
20168
+ });
20169
+ }
20170
+ return { elements: nodes, attributes, marks, unknownMarks };
20171
+ }
20172
+ function splitElementsAndProperties(elements) {
20173
+ const pPr = elements.find((el) => el.name === "w:pPr");
20174
+ const rPr = elements.find((el) => el.name === "w:rPr");
20175
+ const sectPr = elements.find((el) => el.name === "w:sectPr");
20176
+ const els = elements.filter((el) => el.name !== "w:pPr" && el.name !== "w:rPr" && el.name !== "w:sectPr");
20177
+ return {
20178
+ nodes: els,
20179
+ paragraphProperties: pPr,
20180
+ runProperties: rPr,
20181
+ sectionProperties: sectPr
20182
+ };
20183
+ }
20109
20184
  function getTableStyleId(path) {
20110
20185
  const tbl = path.find((ancestor) => ancestor.name === "w:tbl");
20111
20186
  if (!tbl) {
@@ -20130,13 +20205,6 @@ const handleParagraphNode$1 = (params) => {
20130
20205
  if (pPr) {
20131
20206
  inlineParagraphProperties = translator$12.encode({ ...params, nodes: [pPr] }) || {};
20132
20207
  }
20133
- const handleStandardNode2 = nodeListHandler.handlerEntities.find(
20134
- (e) => e.handlerName === "standardNodeHandler"
20135
- )?.handler;
20136
- if (!handleStandardNode2) {
20137
- console.error("Standard node handler not found");
20138
- return null;
20139
- }
20140
20208
  const insideTable = (params.path || []).some((ancestor) => ancestor.name === "w:tc");
20141
20209
  const tableStyleId = getTableStyleId(params.path || []);
20142
20210
  const resolvedParagraphProperties = resolveParagraphProperties(
@@ -20145,15 +20213,29 @@ const handleParagraphNode$1 = (params) => {
20145
20213
  insideTable,
20146
20214
  tableStyleId
20147
20215
  );
20148
- const updatedParams = {
20149
- ...params,
20150
- nodes: [node],
20151
- extraParams: { ...params.extraParams, paragraphProperties: resolvedParagraphProperties }
20152
- };
20153
- const result = handleStandardNode2(updatedParams);
20154
- if (result.nodes.length === 1) {
20155
- schemaNode = result.nodes[0];
20216
+ const { elements = [], attributes = {}, marks = [] } = parseProperties(node, params.docx);
20217
+ const childContent = [];
20218
+ if (elements.length) {
20219
+ const updatedElements = elements.map((el) => {
20220
+ if (!el.marks) el.marks = [];
20221
+ el.marks.push(...marks);
20222
+ return el;
20223
+ });
20224
+ const childParams = {
20225
+ ...params,
20226
+ nodes: updatedElements,
20227
+ extraParams: { ...params.extraParams, paragraphProperties: resolvedParagraphProperties },
20228
+ path: [...params.path || [], node]
20229
+ };
20230
+ const translatedChildren = nodeListHandler.handler(childParams);
20231
+ childContent.push(...translatedChildren);
20156
20232
  }
20233
+ schemaNode = {
20234
+ type: "paragraph",
20235
+ content: childContent,
20236
+ attrs: { ...attributes },
20237
+ marks: []
20238
+ };
20157
20239
  schemaNode.type = "paragraph";
20158
20240
  schemaNode.attrs.paragraphProperties = inlineParagraphProperties;
20159
20241
  schemaNode.attrs.rsidRDefault = node.attributes?.["w:rsidRDefault"];
@@ -20763,6 +20845,11 @@ const decode$q = (params, decodedAttrs = {}) => {
20763
20845
  runs.push(trackedClone);
20764
20846
  return;
20765
20847
  }
20848
+ if (child.name === "w:commentRangeStart" || child.name === "w:commentRangeEnd") {
20849
+ const commentRangeClone = cloneXmlNode(child);
20850
+ runs.push(commentRangeClone);
20851
+ return;
20852
+ }
20766
20853
  const runWrapper = { name: XML_NODE_NAME$i, elements: [] };
20767
20854
  applyBaseRunProps(runWrapper);
20768
20855
  if (!Array.isArray(runWrapper.elements)) runWrapper.elements = [];
@@ -21624,7 +21711,7 @@ function handleAnnotationNode(params) {
21624
21711
  attrs.displayLabel = placeholderLabel;
21625
21712
  }
21626
21713
  const { attrs: marksAsAttrs, marks } = parseAnnotationMarks(sdtContent);
21627
- const allAttrs = { ...attrs, ...marksAsAttrs };
21714
+ const allAttrs = { ...attrs, ...marksAsAttrs, ...sdtPr && { sdtPr } };
21628
21715
  if (!allAttrs.hash) allAttrs.hash = generateDocxRandomId(4);
21629
21716
  if (!attrs.fieldId || !attrs.type) {
21630
21717
  return null;
@@ -21784,16 +21871,13 @@ function handleDocPartObj(params) {
21784
21871
  const sdtPr = node.elements.find((el) => el.name === "w:sdtPr");
21785
21872
  const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21786
21873
  const docPartGallery = docPartObj?.elements.find((el) => el.name === "w:docPartGallery");
21787
- const docPartGalleryType = docPartGallery?.attributes["w:val"];
21788
- if (!docPartGalleryType || !validGalleryTypeMap[docPartGalleryType]) {
21789
- return null;
21790
- }
21874
+ const docPartGalleryType = docPartGallery?.attributes?.["w:val"] ?? null;
21791
21875
  const content = node?.elements.find((el) => el.name === "w:sdtContent");
21792
- const handler2 = validGalleryTypeMap[docPartGalleryType];
21876
+ const handler2 = validGalleryTypeMap[docPartGalleryType] || genericDocPartHandler;
21793
21877
  const result = handler2({
21794
21878
  ...params,
21795
21879
  nodes: [content],
21796
- extraParams: { ...params.extraParams || {}, sdtPr }
21880
+ extraParams: { ...params.extraParams || {}, sdtPr, docPartGalleryType }
21797
21881
  });
21798
21882
  return result;
21799
21883
  }
@@ -21804,15 +21888,46 @@ const tableOfContentsHandler = (params) => {
21804
21888
  nodes: node.elements,
21805
21889
  path: [...params.path || [], node]
21806
21890
  });
21891
+ const normalizedContent = normalizeDocPartContent(translatedContent);
21807
21892
  const sdtPr = params.extraParams.sdtPr;
21808
21893
  const id = sdtPr.elements?.find((el) => el.name === "w:id")?.attributes["w:val"] || "";
21894
+ const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21895
+ const docPartUnique = docPartObj?.elements.some((el) => el.name === "w:docPartUnique") ?? false;
21809
21896
  const result = {
21810
21897
  type: "documentPartObject",
21811
- content: translatedContent,
21898
+ content: normalizedContent,
21812
21899
  attrs: {
21813
21900
  id,
21814
21901
  docPartGallery: "Table of Contents",
21815
- docPartUnique: true
21902
+ docPartUnique,
21903
+ sdtPr
21904
+ // Passthrough for round-trip preservation
21905
+ }
21906
+ };
21907
+ return result;
21908
+ };
21909
+ const genericDocPartHandler = (params) => {
21910
+ const node = params.nodes[0];
21911
+ const translatedContent = params.nodeListHandler.handler({
21912
+ ...params,
21913
+ nodes: node.elements,
21914
+ path: [...params.path || [], node]
21915
+ });
21916
+ const sdtPr = params.extraParams.sdtPr;
21917
+ const docPartGalleryType = params.extraParams.docPartGalleryType;
21918
+ const id = sdtPr?.elements?.find((el) => el.name === "w:id")?.attributes["w:val"] || "";
21919
+ const docPartObj = sdtPr?.elements.find((el) => el.name === "w:docPartObj");
21920
+ const docPartGallery = docPartGalleryType ?? docPartObj?.elements?.find((el) => el.name === "w:docPartGallery")?.attributes?.["w:val"] ?? null;
21921
+ const docPartUnique = docPartObj?.elements.some((el) => el.name === "w:docPartUnique") ?? false;
21922
+ const result = {
21923
+ type: "documentPartObject",
21924
+ content: translatedContent,
21925
+ attrs: {
21926
+ id,
21927
+ docPartGallery,
21928
+ docPartUnique,
21929
+ sdtPr
21930
+ // Passthrough for round-trip preservation of all sdtPr elements
21816
21931
  }
21817
21932
  };
21818
21933
  return result;
@@ -21820,6 +21935,22 @@ const tableOfContentsHandler = (params) => {
21820
21935
  const validGalleryTypeMap = {
21821
21936
  "Table of Contents": tableOfContentsHandler
21822
21937
  };
21938
+ const inlineNodeTypes = /* @__PURE__ */ new Set(["bookmarkStart", "bookmarkEnd"]);
21939
+ const wrapInlineNode = (node) => ({
21940
+ type: "paragraph",
21941
+ content: [node]
21942
+ });
21943
+ const normalizeDocPartContent = (nodes = []) => {
21944
+ const normalized = [];
21945
+ nodes.forEach((node) => {
21946
+ if (inlineNodeTypes.has(node?.type)) {
21947
+ normalized.push(wrapInlineNode(node));
21948
+ } else {
21949
+ normalized.push(node);
21950
+ }
21951
+ });
21952
+ return normalized;
21953
+ };
21823
21954
  function handleDocumentSectionNode(params) {
21824
21955
  const { nodes, nodeListHandler } = params;
21825
21956
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
@@ -21834,6 +21965,9 @@ function handleDocumentSectionNode(params) {
21834
21965
  const titleTag = sdtPr?.elements.find((el) => el.name === "w:alias");
21835
21966
  const title = titleTag?.attributes?.["w:val"] || tagValue.title || null;
21836
21967
  const { description } = tagValue;
21968
+ const lockTag = sdtPr?.elements.find((el) => el.name === "w:lock");
21969
+ const lockValue = lockTag?.attributes?.["w:val"];
21970
+ const isLocked = lockValue === "sdtContentLocked";
21837
21971
  const sdtContent = node.elements.find((el) => el.name === "w:sdtContent");
21838
21972
  const translatedContent = nodeListHandler.handler({
21839
21973
  ...params,
@@ -21846,7 +21980,10 @@ function handleDocumentSectionNode(params) {
21846
21980
  attrs: {
21847
21981
  id,
21848
21982
  title,
21849
- description
21983
+ description,
21984
+ isLocked,
21985
+ ...sdtPr && { sdtPr }
21986
+ // Passthrough for round-trip preservation of unknown elements only if it exists
21850
21987
  }
21851
21988
  };
21852
21989
  return result;
@@ -24639,7 +24776,10 @@ function getThemeColor(name) {
24639
24776
  text1: "#000000",
24640
24777
  text2: "#1f497d",
24641
24778
  background1: "#ffffff",
24642
- background2: "#eeece1"
24779
+ background2: "#eeece1",
24780
+ // Office XML shortcuts
24781
+ bg1: "#ffffff",
24782
+ bg2: "#eeece1"
24643
24783
  };
24644
24784
  return colors[name] ?? "#000000";
24645
24785
  }
@@ -24676,7 +24816,10 @@ function applyColorModifier(hexColor, modifier, value) {
24676
24816
  function extractStrokeWidth(spPr) {
24677
24817
  const ln = spPr?.elements?.find((el) => el.name === "a:ln");
24678
24818
  const w2 = ln?.attributes?.["w"];
24679
- return w2 ? emuToPixels(w2) : 1;
24819
+ if (!w2) return 1;
24820
+ const emu = typeof w2 === "string" ? parseFloat(w2) : w2;
24821
+ const STROKE_DPI = 72;
24822
+ return emu * STROKE_DPI / 914400;
24680
24823
  }
24681
24824
  function extractStrokeColor(spPr, style) {
24682
24825
  const ln = spPr?.elements?.find((el) => el.name === "a:ln");
@@ -24737,6 +24880,7 @@ function extractFillColor(spPr, style) {
24737
24880
  if (schemeClr2) {
24738
24881
  const themeName2 = schemeClr2.attributes?.["val"];
24739
24882
  let color2 = getThemeColor(themeName2);
24883
+ let alpha = null;
24740
24884
  const modifiers2 = schemeClr2.elements || [];
24741
24885
  modifiers2.forEach((mod) => {
24742
24886
  if (mod.name === "a:shade") {
@@ -24747,18 +24891,32 @@ function extractFillColor(spPr, style) {
24747
24891
  color2 = applyColorModifier(color2, "lumMod", mod.attributes["val"]);
24748
24892
  } else if (mod.name === "a:lumOff") {
24749
24893
  color2 = applyColorModifier(color2, "lumOff", mod.attributes["val"]);
24894
+ } else if (mod.name === "a:alpha") {
24895
+ alpha = parseInt(mod.attributes["val"]) / 1e5;
24750
24896
  }
24751
24897
  });
24898
+ if (alpha !== null && alpha < 1) {
24899
+ return { type: "solidWithAlpha", color: color2, alpha };
24900
+ }
24752
24901
  return color2;
24753
24902
  }
24754
24903
  const srgbClr = solidFill.elements?.find((el) => el.name === "a:srgbClr");
24755
24904
  if (srgbClr) {
24756
- return "#" + srgbClr.attributes?.["val"];
24905
+ let alpha = null;
24906
+ const alphaEl = srgbClr.elements?.find((el) => el.name === "a:alpha");
24907
+ if (alphaEl) {
24908
+ alpha = parseInt(alphaEl.attributes?.["val"] || "100000", 10) / 1e5;
24909
+ }
24910
+ const color2 = "#" + srgbClr.attributes?.["val"];
24911
+ if (alpha !== null && alpha < 1) {
24912
+ return { type: "solidWithAlpha", color: color2, alpha };
24913
+ }
24914
+ return color2;
24757
24915
  }
24758
24916
  }
24759
24917
  const gradFill = spPr?.elements?.find((el) => el.name === "a:gradFill");
24760
24918
  if (gradFill) {
24761
- return "#cccccc";
24919
+ return extractGradientFill(gradFill);
24762
24920
  }
24763
24921
  const blipFill = spPr?.elements?.find((el) => el.name === "a:blipFill");
24764
24922
  if (blipFill) {
@@ -24767,6 +24925,8 @@ function extractFillColor(spPr, style) {
24767
24925
  if (!style) return "#5b9bd5";
24768
24926
  const fillRef = style.elements?.find((el) => el.name === "a:fillRef");
24769
24927
  if (!fillRef) return "#5b9bd5";
24928
+ const fillRefIdx = fillRef.attributes?.["idx"];
24929
+ if (fillRefIdx === "0") return null;
24770
24930
  const schemeClr = fillRef.elements?.find((el) => el.name === "a:schemeClr");
24771
24931
  if (!schemeClr) return "#5b9bd5";
24772
24932
  const themeName = schemeClr.attributes?.["val"];
@@ -24783,9 +24943,49 @@ function extractFillColor(spPr, style) {
24783
24943
  });
24784
24944
  return color;
24785
24945
  }
24946
+ function extractGradientFill(gradFill) {
24947
+ const gradient = {
24948
+ type: "gradient",
24949
+ stops: [],
24950
+ angle: 0
24951
+ };
24952
+ const gsLst = gradFill.elements?.find((el) => el.name === "a:gsLst");
24953
+ if (gsLst) {
24954
+ const stops = gsLst.elements?.filter((el) => el.name === "a:gs") || [];
24955
+ gradient.stops = stops.map((stop) => {
24956
+ const pos = parseInt(stop.attributes?.["pos"] || "0", 10) / 1e5;
24957
+ const srgbClr = stop.elements?.find((el) => el.name === "a:srgbClr");
24958
+ let color = "#000000";
24959
+ let alpha = 1;
24960
+ if (srgbClr) {
24961
+ color = "#" + srgbClr.attributes?.["val"];
24962
+ const alphaEl = srgbClr.elements?.find((el) => el.name === "a:alpha");
24963
+ if (alphaEl) {
24964
+ alpha = parseInt(alphaEl.attributes?.["val"] || "100000", 10) / 1e5;
24965
+ }
24966
+ }
24967
+ return { position: pos, color, alpha };
24968
+ });
24969
+ }
24970
+ const lin = gradFill.elements?.find((el) => el.name === "a:lin");
24971
+ if (lin) {
24972
+ const ang = parseInt(lin.attributes?.["ang"] || "0", 10) / 6e4;
24973
+ gradient.angle = ang;
24974
+ }
24975
+ const path = gradFill.elements?.find((el) => el.name === "a:path");
24976
+ if (path) {
24977
+ gradient.gradientType = "radial";
24978
+ gradient.path = path.attributes?.["path"] || "circle";
24979
+ } else {
24980
+ gradient.gradientType = "linear";
24981
+ }
24982
+ return gradient;
24983
+ }
24786
24984
  const DRAWING_XML_TAG = "w:drawing";
24787
24985
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
24788
24986
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
24987
+ const DEFAULT_SHAPE_WIDTH = 100;
24988
+ const DEFAULT_SHAPE_HEIGHT = 100;
24789
24989
  function handleImageNode(node, params, isAnchor) {
24790
24990
  const { docx, filename } = params;
24791
24991
  const { attributes } = node;
@@ -24829,7 +25029,8 @@ function handleImageNode(node, params, isAnchor) {
24829
25029
  horizontal: positionHValue,
24830
25030
  top: positionVValue
24831
25031
  };
24832
- const simplePos = node.elements.find((el) => el.name === "wp:simplePos");
25032
+ const useSimplePos = attributes["simplePos"] === "1" || attributes["simplePos"] === 1 || attributes["simplePos"] === true;
25033
+ const simplePosNode = node.elements.find((el) => el.name === "wp:simplePos");
24833
25034
  const wrapNode = isAnchor ? node.elements.find(
24834
25035
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
24835
25036
  ) : null;
@@ -24909,7 +25110,7 @@ function handleImageNode(node, params, isAnchor) {
24909
25110
  horizontal: positionHValue,
24910
25111
  top: positionVValue
24911
25112
  };
24912
- return handleShapeDrawing(params, node, graphicData, size, padding, shapeMarginOffset);
25113
+ return handleShapeDrawing(params, node, graphicData, size, padding, shapeMarginOffset, anchorData, wrap2, isAnchor);
24913
25114
  }
24914
25115
  if (uri2 === GROUP_URI) {
24915
25116
  const shapeMarginOffset = {
@@ -24917,13 +25118,16 @@ function handleImageNode(node, params, isAnchor) {
24917
25118
  horizontal: positionHValue,
24918
25119
  top: positionVValue
24919
25120
  };
24920
- return handleShapeGroup(params, node, graphicData, size, padding, shapeMarginOffset);
25121
+ return handleShapeGroup(params, node, graphicData, size, padding, shapeMarginOffset, anchorData, wrap2);
24921
25122
  }
24922
25123
  const picture = graphicData?.elements.find((el) => el.name === "pic:pic");
24923
25124
  if (!picture || !picture.elements) return null;
24924
25125
  const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
24925
25126
  const blip = blipFill?.elements.find((el) => el.name === "a:blip");
24926
25127
  if (!blip) return null;
25128
+ const stretch = blipFill?.elements.find((el) => el.name === "a:stretch");
25129
+ const fillRect = stretch?.elements.find((el) => el.name === "a:fillRect");
25130
+ const shouldStretch = Boolean(stretch && fillRect);
24927
25131
  const spPr = picture.elements.find((el) => el.name === "pic:spPr");
24928
25132
  if (spPr) {
24929
25133
  const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
@@ -24966,10 +25170,10 @@ function handleImageNode(node, params, isAnchor) {
24966
25170
  anchorData,
24967
25171
  isAnchor,
24968
25172
  transformData,
24969
- ...simplePos && {
25173
+ ...useSimplePos && {
24970
25174
  simplePos: {
24971
- x: simplePos.attributes.x,
24972
- y: simplePos.attributes.y
25175
+ x: simplePosNode.attributes?.x,
25176
+ y: simplePosNode.attributes?.y
24973
25177
  }
24974
25178
  },
24975
25179
  wrap: wrap2,
@@ -24977,6 +25181,7 @@ function handleImageNode(node, params, isAnchor) {
24977
25181
  wrapText: wrap2.attrs.wrapText
24978
25182
  } : {},
24979
25183
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
25184
+ shouldStretch,
24980
25185
  originalPadding: {
24981
25186
  distT: attributes["distT"],
24982
25187
  distB: attributes["distB"],
@@ -24988,26 +25193,25 @@ function handleImageNode(node, params, isAnchor) {
24988
25193
  }
24989
25194
  };
24990
25195
  }
24991
- const handleShapeDrawing = (params, node, graphicData, size, padding, marginOffset) => {
25196
+ const handleShapeDrawing = (params, node, graphicData, size, padding, marginOffset, anchorData, wrap2, isAnchor) => {
24992
25197
  const wsp = graphicData.elements.find((el) => el.name === "wps:wsp");
24993
25198
  const textBox = wsp.elements.find((el) => el.name === "wps:txbx");
24994
25199
  const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
24995
25200
  const spPr = wsp.elements.find((el) => el.name === "wps:spPr");
24996
25201
  const prstGeom = spPr?.elements.find((el) => el.name === "a:prstGeom");
24997
25202
  const shapeType = prstGeom?.attributes["prst"];
24998
- if (shapeType === "rect" && !textBoxContent) {
24999
- return getRectangleShape(params, spPr);
25203
+ const hasGradientFill = spPr?.elements?.find((el) => el.name === "a:gradFill");
25204
+ if (shapeType === "rect" && !textBoxContent && !hasGradientFill) {
25205
+ return getRectangleShape(params, spPr, node, marginOffset, anchorData, wrap2, isAnchor);
25000
25206
  }
25001
- if (shapeType && !textBoxContent) {
25002
- const result = getVectorShape({ params, graphicData });
25207
+ if (shapeType) {
25208
+ const result = getVectorShape({ params, node, graphicData, size, marginOffset, anchorData, wrap: wrap2, isAnchor });
25003
25209
  if (result) return result;
25004
25210
  }
25005
- if (!textBoxContent) {
25006
- return buildShapePlaceholder(node, size, padding, marginOffset, "drawing");
25007
- }
25008
- return buildShapePlaceholder(node, size, padding, marginOffset, "textbox");
25211
+ const fallbackType = textBoxContent ? "textbox" : "drawing";
25212
+ return buildShapePlaceholder(node, size, padding, marginOffset, fallbackType);
25009
25213
  };
25010
- const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset) => {
25214
+ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset, anchorData, wrap2) => {
25011
25215
  const wgp = graphicData.elements.find((el) => el.name === "wpg:wgp");
25012
25216
  if (!wgp) {
25013
25217
  return buildShapePlaceholder(node, size, padding, marginOffset, "group");
@@ -25040,6 +25244,7 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25040
25244
  }
25041
25245
  }
25042
25246
  const childShapes = wgp.elements.filter((el) => el.name === "wps:wsp");
25247
+ const childPictures = wgp.elements.filter((el) => el.name === "pic:pic");
25043
25248
  const shapes = childShapes.map((wsp) => {
25044
25249
  const spPr = wsp.elements?.find((el) => el.name === "wps:spPr");
25045
25250
  if (!spPr) return null;
@@ -25078,6 +25283,14 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25078
25283
  const cNvPr = wsp.elements?.find((el) => el.name === "wps:cNvPr");
25079
25284
  const shapeId = cNvPr?.attributes?.["id"];
25080
25285
  const shapeName = cNvPr?.attributes?.["name"];
25286
+ const textBox = wsp.elements?.find((el) => el.name === "wps:txbx");
25287
+ const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
25288
+ const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
25289
+ let textContent = null;
25290
+ if (textBoxContent) {
25291
+ textContent = extractTextFromTextBox(textBoxContent, bodyPr);
25292
+ }
25293
+ const textAlign = textContent?.horizontalAlign || "left";
25081
25294
  return {
25082
25295
  shapeType: "vectorShape",
25083
25296
  attrs: {
@@ -25093,10 +25306,75 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25093
25306
  strokeColor,
25094
25307
  strokeWidth,
25095
25308
  shapeId,
25096
- shapeName
25309
+ shapeName,
25310
+ textContent,
25311
+ textAlign,
25312
+ textVerticalAlign: textContent?.verticalAlign,
25313
+ textInsets: textContent?.insets
25314
+ }
25315
+ };
25316
+ }).filter(Boolean);
25317
+ const pictures = childPictures.map((pic) => {
25318
+ const spPr = pic.elements?.find((el) => el.name === "pic:spPr");
25319
+ if (!spPr) return null;
25320
+ const xfrm2 = spPr.elements?.find((el) => el.name === "a:xfrm");
25321
+ const off = xfrm2?.elements?.find((el) => el.name === "a:off");
25322
+ const ext = xfrm2?.elements?.find((el) => el.name === "a:ext");
25323
+ const rawX = off?.attributes?.["x"] ? parseFloat(off.attributes["x"]) : 0;
25324
+ const rawY = off?.attributes?.["y"] ? parseFloat(off.attributes["y"]) : 0;
25325
+ const rawWidth = ext?.attributes?.["cx"] ? parseFloat(ext.attributes["cx"]) : 914400;
25326
+ const rawHeight = ext?.attributes?.["cy"] ? parseFloat(ext.attributes["cy"]) : 914400;
25327
+ let x2, y2, width, height;
25328
+ if (groupTransform.childWidth && groupTransform.childHeight) {
25329
+ const scaleX = groupTransform.width / groupTransform.childWidth;
25330
+ const scaleY = groupTransform.height / groupTransform.childHeight;
25331
+ const childOriginX = groupTransform.childOriginXEmu || 0;
25332
+ const childOriginY = groupTransform.childOriginYEmu || 0;
25333
+ x2 = groupTransform.x + emuToPixels((rawX - childOriginX) * scaleX);
25334
+ y2 = groupTransform.y + emuToPixels((rawY - childOriginY) * scaleY);
25335
+ width = emuToPixels(rawWidth * scaleX);
25336
+ height = emuToPixels(rawHeight * scaleY);
25337
+ } else {
25338
+ x2 = emuToPixels(rawX);
25339
+ y2 = emuToPixels(rawY);
25340
+ width = emuToPixels(rawWidth);
25341
+ height = emuToPixels(rawHeight);
25342
+ }
25343
+ const blipFill = pic.elements?.find((el) => el.name === "pic:blipFill");
25344
+ const blip = blipFill?.elements?.find((el) => el.name === "a:blip");
25345
+ if (!blip) return null;
25346
+ const rEmbed = blip.attributes?.["r:embed"];
25347
+ if (!rEmbed) return null;
25348
+ const currentFile = params.filename || "document.xml";
25349
+ let rels = params.docx[`word/_rels/${currentFile}.rels`];
25350
+ if (!rels) rels = params.docx[`word/_rels/document.xml.rels`];
25351
+ const relationships = rels?.elements.find((el) => el.name === "Relationships");
25352
+ const { elements } = relationships || [];
25353
+ const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
25354
+ if (!rel) return null;
25355
+ const targetPath = rel.attributes?.["Target"];
25356
+ let path = `word/${targetPath}`;
25357
+ if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) {
25358
+ path = targetPath.substring(1);
25359
+ }
25360
+ const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
25361
+ const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
25362
+ const picId = cNvPr?.attributes?.["id"];
25363
+ const picName = cNvPr?.attributes?.["name"];
25364
+ return {
25365
+ shapeType: "image",
25366
+ attrs: {
25367
+ x: x2,
25368
+ y: y2,
25369
+ width,
25370
+ height,
25371
+ src: path,
25372
+ imageId: picId,
25373
+ imageName: picName
25097
25374
  }
25098
25375
  };
25099
25376
  }).filter(Boolean);
25377
+ const allShapes = [...pictures, ...shapes];
25100
25378
  const schemaAttrs = {};
25101
25379
  const drawingNode = params.nodes?.[0];
25102
25380
  if (drawingNode?.name === DRAWING_XML_TAG) {
@@ -25107,38 +25385,137 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
25107
25385
  attrs: {
25108
25386
  ...schemaAttrs,
25109
25387
  groupTransform,
25110
- shapes,
25388
+ shapes: allShapes,
25111
25389
  size,
25112
25390
  padding,
25113
- marginOffset
25391
+ marginOffset,
25392
+ anchorData,
25393
+ wrap: wrap2,
25394
+ originalAttributes: node?.attributes
25114
25395
  }
25115
25396
  };
25116
25397
  return result;
25117
25398
  };
25118
- const getRectangleShape = (params, node) => {
25399
+ function extractTextFromTextBox(textBoxContent, bodyPr) {
25400
+ if (!textBoxContent || !textBoxContent.elements) return null;
25401
+ const paragraphs = textBoxContent.elements.filter((el) => el.name === "w:p");
25402
+ const textParts = [];
25403
+ let horizontalAlign = null;
25404
+ paragraphs.forEach((paragraph, paragraphIndex) => {
25405
+ if (!horizontalAlign) {
25406
+ const pPr = paragraph.elements?.find((el) => el.name === "w:pPr");
25407
+ const jc = pPr?.elements?.find((el) => el.name === "w:jc");
25408
+ if (jc) {
25409
+ const jcVal = jc.attributes?.["val"] || jc.attributes?.["w:val"];
25410
+ if (jcVal === "left" || jcVal === "start") horizontalAlign = "left";
25411
+ else if (jcVal === "right" || jcVal === "end") horizontalAlign = "right";
25412
+ else if (jcVal === "center") horizontalAlign = "center";
25413
+ }
25414
+ }
25415
+ const runs = paragraph.elements?.filter((el) => el.name === "w:r") || [];
25416
+ let paragraphHasText = false;
25417
+ runs.forEach((run2) => {
25418
+ const textEl = run2.elements?.find((el) => el.name === "w:t");
25419
+ if (textEl && textEl.elements) {
25420
+ const text = textEl.elements.find((el) => el.type === "text");
25421
+ if (text) {
25422
+ paragraphHasText = true;
25423
+ const cleanedText = typeof text.text === "string" ? text.text.replace(/\[\[sdspace\]\]/g, " ") : text.text;
25424
+ const rPr = run2.elements?.find((el) => el.name === "w:rPr");
25425
+ const formatting = {};
25426
+ if (rPr) {
25427
+ const bold = rPr.elements?.find((el) => el.name === "w:b");
25428
+ const italic = rPr.elements?.find((el) => el.name === "w:i");
25429
+ const color = rPr.elements?.find((el) => el.name === "w:color");
25430
+ const sz = rPr.elements?.find((el) => el.name === "w:sz");
25431
+ if (bold) formatting.bold = true;
25432
+ if (italic) formatting.italic = true;
25433
+ if (color) formatting.color = color.attributes?.["val"] || color.attributes?.["w:val"];
25434
+ if (sz) {
25435
+ const szVal = sz.attributes?.["val"] || sz.attributes?.["w:val"];
25436
+ formatting.fontSize = parseInt(szVal, 10) / 2;
25437
+ }
25438
+ }
25439
+ textParts.push({
25440
+ text: cleanedText,
25441
+ formatting
25442
+ });
25443
+ }
25444
+ }
25445
+ });
25446
+ if (paragraphIndex < paragraphs.length - 1) {
25447
+ textParts.push({
25448
+ text: "\n",
25449
+ formatting: {},
25450
+ isLineBreak: true,
25451
+ isEmptyParagraph: !paragraphHasText
25452
+ // Mark empty paragraphs for extra spacing
25453
+ });
25454
+ }
25455
+ });
25456
+ if (textParts.length === 0) return null;
25457
+ const bodyPrAttrs = bodyPr?.attributes || {};
25458
+ let verticalAlign = "center";
25459
+ const anchorAttr = bodyPrAttrs["anchor"];
25460
+ if (anchorAttr === "t") verticalAlign = "top";
25461
+ else if (anchorAttr === "ctr") verticalAlign = "center";
25462
+ else if (anchorAttr === "b") verticalAlign = "bottom";
25463
+ const EMU_TO_PX = 96 / 914400;
25464
+ const DEFAULT_HORIZONTAL_INSET_EMU = 91440;
25465
+ const DEFAULT_VERTICAL_INSET_EMU = 45720;
25466
+ const lIns = bodyPrAttrs["lIns"] != null ? parseFloat(bodyPrAttrs["lIns"]) : DEFAULT_HORIZONTAL_INSET_EMU;
25467
+ const tIns = bodyPrAttrs["tIns"] != null ? parseFloat(bodyPrAttrs["tIns"]) : DEFAULT_VERTICAL_INSET_EMU;
25468
+ const rIns = bodyPrAttrs["rIns"] != null ? parseFloat(bodyPrAttrs["rIns"]) : DEFAULT_HORIZONTAL_INSET_EMU;
25469
+ const bIns = bodyPrAttrs["bIns"] != null ? parseFloat(bodyPrAttrs["bIns"]) : DEFAULT_VERTICAL_INSET_EMU;
25470
+ const insets = {
25471
+ top: tIns * EMU_TO_PX,
25472
+ right: rIns * EMU_TO_PX,
25473
+ bottom: bIns * EMU_TO_PX,
25474
+ left: lIns * EMU_TO_PX
25475
+ };
25476
+ const wrap2 = bodyPrAttrs["wrap"] || "square";
25477
+ return {
25478
+ parts: textParts,
25479
+ horizontalAlign: horizontalAlign || "left",
25480
+ // Default to left if not specified
25481
+ verticalAlign,
25482
+ insets,
25483
+ wrap: wrap2
25484
+ };
25485
+ }
25486
+ const getRectangleShape = (params, spPr, node, marginOffset, anchorData, wrap2, isAnchor) => {
25119
25487
  const schemaAttrs = {};
25120
- const [drawingNode] = params.nodes;
25488
+ const drawingNode = params.nodes?.[0];
25121
25489
  if (drawingNode?.name === DRAWING_XML_TAG) {
25122
25490
  schemaAttrs.drawingContent = drawingNode;
25123
25491
  }
25124
- const xfrm = node.elements.find((el) => el.name === "a:xfrm");
25125
- const start = xfrm.elements.find((el) => el.name === "a:off");
25126
- const size = xfrm.elements.find((el) => el.name === "a:ext");
25127
- const solidFill = node.elements.find((el) => el.name === "a:solidFill");
25128
- const rectangleSize = {
25129
- top: emuToPixels(start.attributes["y"]),
25130
- left: emuToPixels(start.attributes["x"]),
25131
- width: emuToPixels(size.attributes["cx"]),
25132
- height: emuToPixels(size.attributes["cy"])
25133
- };
25134
- schemaAttrs.size = rectangleSize;
25492
+ const xfrm = spPr?.elements?.find((el) => el.name === "a:xfrm");
25493
+ const start = xfrm?.elements?.find((el) => el.name === "a:off");
25494
+ const size = xfrm?.elements?.find((el) => el.name === "a:ext");
25495
+ const solidFill = spPr?.elements?.find((el) => el.name === "a:solidFill");
25496
+ if (start && size) {
25497
+ const rectangleSize = {
25498
+ top: emuToPixels(start.attributes?.["y"] || 0),
25499
+ left: emuToPixels(start.attributes?.["x"] || 0),
25500
+ width: emuToPixels(size.attributes?.["cx"] || 0),
25501
+ height: emuToPixels(size.attributes?.["cy"] || 0)
25502
+ };
25503
+ schemaAttrs.size = rectangleSize;
25504
+ }
25135
25505
  const background = solidFill?.elements[0]?.attributes["val"];
25136
25506
  if (background) {
25137
25507
  schemaAttrs.background = "#" + background;
25138
25508
  }
25139
25509
  return {
25140
25510
  type: "contentBlock",
25141
- attrs: schemaAttrs
25511
+ attrs: {
25512
+ ...schemaAttrs,
25513
+ marginOffset,
25514
+ anchorData,
25515
+ wrap: wrap2,
25516
+ isAnchor,
25517
+ originalAttributes: node?.attributes
25518
+ }
25142
25519
  };
25143
25520
  };
25144
25521
  const buildShapePlaceholder = (node, size, padding, marginOffset, shapeType) => {
@@ -25187,7 +25564,7 @@ const buildShapePlaceholder = (node, size, padding, marginOffset, shapeType) =>
25187
25564
  attrs
25188
25565
  };
25189
25566
  };
25190
- function getVectorShape({ params, graphicData }) {
25567
+ function getVectorShape({ params, node, graphicData, size, marginOffset, anchorData, wrap: wrap2, isAnchor }) {
25191
25568
  const schemaAttrs = {};
25192
25569
  const drawingNode = params.nodes?.[0];
25193
25570
  if (drawingNode?.name === "w:drawing") {
@@ -25207,10 +25584,9 @@ function getVectorShape({ params, graphicData }) {
25207
25584
  console.warn("Shape kind not found");
25208
25585
  }
25209
25586
  schemaAttrs.kind = shapeKind;
25587
+ const width = size?.width ?? DEFAULT_SHAPE_WIDTH;
25588
+ const height = size?.height ?? DEFAULT_SHAPE_HEIGHT;
25210
25589
  const xfrm = spPr.elements?.find((el) => el.name === "a:xfrm");
25211
- const extent = xfrm?.elements?.find((el) => el.name === "a:ext");
25212
- const width = extent?.attributes?.["cx"] ? emuToPixels(extent.attributes["cx"]) : 100;
25213
- const height = extent?.attributes?.["cy"] ? emuToPixels(extent.attributes["cy"]) : 100;
25214
25590
  const rotation = xfrm?.attributes?.["rot"] ? rotToDegrees(xfrm.attributes["rot"]) : 0;
25215
25591
  const flipH = xfrm?.attributes?.["flipH"] === "1";
25216
25592
  const flipV = xfrm?.attributes?.["flipV"] === "1";
@@ -25218,6 +25594,15 @@ function getVectorShape({ params, graphicData }) {
25218
25594
  const fillColor = extractFillColor(spPr, style);
25219
25595
  const strokeColor = extractStrokeColor(spPr, style);
25220
25596
  const strokeWidth = extractStrokeWidth(spPr);
25597
+ const textBox = wsp.elements?.find((el) => el.name === "wps:txbx");
25598
+ const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
25599
+ const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
25600
+ let textContent = null;
25601
+ let textAlign = "left";
25602
+ if (textBoxContent) {
25603
+ textContent = extractTextFromTextBox(textBoxContent, bodyPr);
25604
+ textAlign = textContent?.horizontalAlign || "left";
25605
+ }
25221
25606
  return {
25222
25607
  type: "vectorShape",
25223
25608
  attrs: {
@@ -25229,7 +25614,16 @@ function getVectorShape({ params, graphicData }) {
25229
25614
  flipV,
25230
25615
  fillColor,
25231
25616
  strokeColor,
25232
- strokeWidth
25617
+ strokeWidth,
25618
+ marginOffset,
25619
+ anchorData,
25620
+ wrap: wrap2,
25621
+ isAnchor,
25622
+ textContent,
25623
+ textAlign,
25624
+ textVerticalAlign: textContent?.verticalAlign,
25625
+ textInsets: textContent?.insets,
25626
+ originalAttributes: node?.attributes
25233
25627
  }
25234
25628
  };
25235
25629
  }
@@ -27581,9 +27975,11 @@ function updateNumberingProperties(newNumberingProperties, paragraphNode, pos, e
27581
27975
  const newAttrs = {
27582
27976
  ...paragraphNode.attrs,
27583
27977
  paragraphProperties: newProperties,
27584
- numberingProperties: newProperties.numberingProperties,
27585
- listRendering: null
27978
+ numberingProperties: newProperties.numberingProperties
27586
27979
  };
27980
+ if (!newNumberingProperties) {
27981
+ newAttrs.listRendering = null;
27982
+ }
27587
27983
  tr.setNodeMarkup(pos, null, newAttrs);
27588
27984
  }
27589
27985
  const generateNewListDefinition = ({ numId, listType, level, start, text, fmt, editor }) => {
@@ -28115,13 +28511,36 @@ const handleDocxPaste = (html, editor, view) => {
28115
28511
  extractAndRemoveConditionalPrefix(item);
28116
28512
  });
28117
28513
  transformWordLists(tempDiv, editor);
28118
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
28514
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(tempDiv);
28515
+ doc2 = wrapTextsInRuns(doc2);
28119
28516
  tempDiv.remove();
28120
28517
  const { dispatch } = editor.view;
28121
28518
  if (!dispatch) return false;
28122
28519
  dispatch(view.state.tr.replaceSelectionWith(doc2, true));
28123
28520
  return true;
28124
28521
  };
28522
+ const wrapTextsInRuns = (doc2) => {
28523
+ const runType = doc2.type?.schema?.nodes?.run;
28524
+ if (!runType) return doc2;
28525
+ const wrapNode = (node, parent) => {
28526
+ if (node.isText) {
28527
+ if (parent?.type?.name === "run") return node;
28528
+ const runProperties = decodeRPrFromMarks(node.marks);
28529
+ return runType.create({ runProperties }, [node]);
28530
+ }
28531
+ if (!node.childCount) return node;
28532
+ let changed = false;
28533
+ const wrappedChildren = [];
28534
+ node.forEach((child) => {
28535
+ const wrappedChild = wrapNode(child, node);
28536
+ if (wrappedChild !== child) changed = true;
28537
+ wrappedChildren.push(wrappedChild);
28538
+ });
28539
+ if (!changed) return node;
28540
+ return node.copy(Fragment.fromArray(wrappedChildren));
28541
+ };
28542
+ return wrapNode(doc2, null);
28543
+ };
28125
28544
  const transformWordLists = (container, editor) => {
28126
28545
  const listItems = Array.from(container.querySelectorAll("[data-num-id]"));
28127
28546
  const lists = {};
@@ -28551,7 +28970,8 @@ const handleGoogleDocsHtml = (html, editor, view) => {
28551
28970
  tempDiv.innerHTML = cleanedHtml;
28552
28971
  const htmlWithMergedLists = mergeSeparateLists(tempDiv);
28553
28972
  const flattenHtml = flattenListsInHtml(htmlWithMergedLists, editor);
28554
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(flattenHtml);
28973
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(flattenHtml);
28974
+ doc2 = wrapTextsInRuns(doc2);
28555
28975
  tempDiv.remove();
28556
28976
  const { dispatch } = editor.view;
28557
28977
  if (!dispatch) return false;
@@ -28884,7 +29304,8 @@ function isGoogleDocsHtml(html) {
28884
29304
  function handleHtmlPaste(html, editor, source) {
28885
29305
  let cleanedHtml;
28886
29306
  cleanedHtml = htmlHandler(html, editor);
28887
- const doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
29307
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(cleanedHtml);
29308
+ doc2 = wrapTextsInRuns(doc2);
28888
29309
  const { dispatch, state: state2 } = editor.view;
28889
29310
  if (!dispatch) return false;
28890
29311
  const { $from } = state2.selection;
@@ -28989,7 +29410,9 @@ function createDocFromHTML(content, editor, options = {}) {
28989
29410
  } else {
28990
29411
  parsedContent = content;
28991
29412
  }
28992
- return DOMParser$1.fromSchema(editor.schema).parse(parsedContent);
29413
+ let doc2 = DOMParser$1.fromSchema(editor.schema).parse(parsedContent);
29414
+ doc2 = wrapTextsInRuns(doc2);
29415
+ return doc2;
28993
29416
  }
28994
29417
  function L() {
28995
29418
  return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
@@ -30113,9 +30536,11 @@ function processContent({ content, type: type2, editor }) {
30113
30536
  para.textContent = content;
30114
30537
  wrapper.appendChild(para);
30115
30538
  doc2 = DOMParser$1.fromSchema(editor.schema).parse(wrapper);
30539
+ doc2 = wrapTextsInRuns(doc2);
30116
30540
  break;
30117
30541
  case "schema":
30118
30542
  doc2 = editor.schema.nodeFromJSON(content);
30543
+ doc2 = wrapTextsInRuns(doc2);
30119
30544
  break;
30120
30545
  default:
30121
30546
  throw new Error(`Unknown content type: ${type2}`);
@@ -30506,12 +30931,13 @@ function translateShapeGroup(params) {
30506
30931
  function translateAnchorNode(params) {
30507
30932
  const { attrs } = params.node;
30508
30933
  const anchorElements = [];
30509
- if (attrs.simplePos) {
30934
+ const hasSimplePos = attrs.simplePos || attrs.originalAttributes?.simplePos;
30935
+ if (hasSimplePos) {
30510
30936
  anchorElements.push({
30511
30937
  name: "wp:simplePos",
30512
30938
  attributes: {
30513
- x: 0,
30514
- y: 0
30939
+ x: attrs.simplePos?.x ?? 0,
30940
+ y: attrs.simplePos?.y ?? 0
30515
30941
  }
30516
30942
  });
30517
30943
  }
@@ -30563,8 +30989,8 @@ function translateAnchorNode(params) {
30563
30989
  }
30564
30990
  if (attrs.originalAttributes?.simplePos !== void 0) {
30565
30991
  inlineAttrs.simplePos = attrs.originalAttributes.simplePos;
30566
- } else if (attrs.simplePos !== void 0) {
30567
- inlineAttrs.simplePos = attrs.simplePos;
30992
+ } else if (hasSimplePos) {
30993
+ inlineAttrs.simplePos = "1";
30568
30994
  }
30569
30995
  if (attrs.originalAttributes?.locked !== void 0) {
30570
30996
  inlineAttrs.locked = attrs.originalAttributes.locked;
@@ -31123,16 +31549,24 @@ function translateFieldAnnotation(params) {
31123
31549
  hash: attrs.hash
31124
31550
  };
31125
31551
  const annotationAttrsJson = JSON.stringify(annotationAttrs);
31552
+ const sdtPrElements = [
31553
+ { name: "w:alias", attributes: { "w:val": attrs.displayLabel } },
31554
+ { name: "w:tag", attributes: { "w:val": annotationAttrsJson } },
31555
+ { name: "w:id", attributes: { "w:val": id } }
31556
+ ];
31557
+ if (attrs.sdtPr?.elements && Array.isArray(attrs.sdtPr.elements)) {
31558
+ const elementsToExclude = ["w:alias", "w:tag", "w:id"];
31559
+ const passthroughElements = attrs.sdtPr.elements.filter(
31560
+ (el) => el && el.name && !elementsToExclude.includes(el.name)
31561
+ );
31562
+ sdtPrElements.push(...passthroughElements);
31563
+ }
31126
31564
  const result = {
31127
31565
  name: "w:sdt",
31128
31566
  elements: [
31129
31567
  {
31130
31568
  name: "w:sdtPr",
31131
- elements: [
31132
- { name: "w:alias", attributes: { "w:val": attrs.displayLabel } },
31133
- { name: "w:tag", attributes: { "w:val": annotationAttrsJson } },
31134
- { name: "w:id", attributes: { "w:val": id } }
31135
- ]
31569
+ elements: sdtPrElements
31136
31570
  },
31137
31571
  {
31138
31572
  name: "w:sdtContent",
@@ -31364,7 +31798,7 @@ function translateDocumentSection(params) {
31364
31798
  type: "documentSection",
31365
31799
  description: attrs.description
31366
31800
  });
31367
- const sdtPr = generateSdtPrTagForDocumentSection(attrs.id, attrs.title, exportedTag);
31801
+ const sdtPr = generateSdtPrTagForDocumentSection(attrs.id, attrs.title, exportedTag, attrs.sdtPr);
31368
31802
  const { isLocked } = attrs;
31369
31803
  if (isLocked) {
31370
31804
  sdtPr.elements.push({
@@ -31381,73 +31815,115 @@ function translateDocumentSection(params) {
31381
31815
  };
31382
31816
  return result;
31383
31817
  }
31384
- const generateSdtPrTagForDocumentSection = (id, title, tag) => {
31818
+ const generateSdtPrTagForDocumentSection = (id, title, tag, sdtPr) => {
31819
+ const coreElements = [
31820
+ {
31821
+ name: "w:id",
31822
+ attributes: {
31823
+ "w:val": id
31824
+ }
31825
+ },
31826
+ {
31827
+ name: "w:alias",
31828
+ attributes: {
31829
+ "w:val": title
31830
+ }
31831
+ },
31832
+ {
31833
+ name: "w:tag",
31834
+ attributes: {
31835
+ "w:val": tag
31836
+ }
31837
+ }
31838
+ ];
31839
+ if (sdtPr?.elements && Array.isArray(sdtPr.elements)) {
31840
+ const elementsToExclude = ["w:id", "w:alias", "w:tag", "w:lock"];
31841
+ const passthroughElements = sdtPr.elements.filter((el) => el && el.name && !elementsToExclude.includes(el.name));
31842
+ coreElements.push(...passthroughElements);
31843
+ }
31385
31844
  return {
31386
31845
  name: "w:sdtPr",
31387
- elements: [
31388
- {
31389
- name: "w:id",
31390
- attributes: {
31391
- "w:val": id
31392
- }
31393
- },
31394
- {
31395
- name: "w:alias",
31396
- attributes: {
31397
- "w:val": title
31398
- }
31399
- },
31400
- {
31401
- name: "w:tag",
31402
- attributes: {
31403
- "w:val": tag
31404
- }
31405
- }
31406
- ]
31846
+ elements: coreElements
31407
31847
  };
31408
31848
  };
31409
31849
  function translateDocumentPartObj(params) {
31410
31850
  const { node } = params;
31411
31851
  const { attrs = {} } = node;
31412
31852
  const childContent = translateChildNodes({ ...params, nodes: node.content });
31853
+ const sdtPr = generateSdtPrForDocPartObj(attrs);
31413
31854
  const nodeElements = [
31855
+ sdtPr,
31414
31856
  {
31857
+ name: "w:sdtContent",
31858
+ elements: childContent
31859
+ }
31860
+ ];
31861
+ const result = {
31862
+ name: "w:sdt",
31863
+ elements: nodeElements
31864
+ };
31865
+ return result;
31866
+ }
31867
+ function generateSdtPrForDocPartObj(attrs) {
31868
+ const existingDocPartObj = attrs.sdtPr?.elements?.find((el) => el.name === "w:docPartObj");
31869
+ const existingDocPartGallery = existingDocPartObj?.elements?.find((el) => el.name === "w:docPartGallery")?.attributes?.["w:val"];
31870
+ const docPartGallery = attrs.docPartGallery ?? existingDocPartGallery ?? null;
31871
+ const id = attrs.id ?? attrs.sdtPr?.elements?.find((el) => el.name === "w:id")?.attributes?.["w:val"] ?? "";
31872
+ const docPartUnique = attrs.docPartUnique ?? existingDocPartObj?.elements?.some((el) => el.name === "w:docPartUnique") ?? false;
31873
+ if (docPartGallery === null) {
31874
+ if (attrs.sdtPr) {
31875
+ return attrs.sdtPr;
31876
+ }
31877
+ return {
31415
31878
  name: "w:sdtPr",
31416
31879
  elements: [
31417
31880
  {
31418
31881
  name: "w:id",
31419
31882
  attributes: {
31420
- "w:val": attrs.id
31883
+ "w:val": id
31421
31884
  }
31422
31885
  },
31423
31886
  {
31424
31887
  name: "w:docPartObj",
31425
- elements: [
31426
- {
31427
- name: "w:docPartGallery",
31428
- attributes: {
31429
- "w:val": attrs.docPartGallery
31430
- }
31431
- },
31432
- ...attrs.docPartUnique ? [
31433
- {
31434
- name: "w:docPartUnique"
31435
- }
31436
- ] : []
31437
- ]
31888
+ elements: []
31438
31889
  }
31439
31890
  ]
31891
+ };
31892
+ }
31893
+ const docPartObjElements = [
31894
+ {
31895
+ name: "w:docPartGallery",
31896
+ attributes: {
31897
+ "w:val": docPartGallery
31898
+ }
31899
+ }
31900
+ ];
31901
+ if (docPartUnique) {
31902
+ docPartObjElements.push({ name: "w:docPartUnique" });
31903
+ }
31904
+ const sdtPrElements = [
31905
+ {
31906
+ name: "w:id",
31907
+ attributes: {
31908
+ "w:val": id
31909
+ }
31440
31910
  },
31441
31911
  {
31442
- name: "w:sdtContent",
31443
- elements: childContent
31912
+ name: "w:docPartObj",
31913
+ elements: docPartObjElements
31444
31914
  }
31445
31915
  ];
31446
- const result = {
31447
- name: "w:sdt",
31448
- elements: nodeElements
31916
+ if (attrs.sdtPr?.elements && Array.isArray(attrs.sdtPr.elements)) {
31917
+ const elementsToExclude = ["w:id", "w:docPartObj"];
31918
+ const passthroughElements = attrs.sdtPr.elements.filter(
31919
+ (el) => el && el.name && !elementsToExclude.includes(el.name)
31920
+ );
31921
+ sdtPrElements.push(...passthroughElements);
31922
+ }
31923
+ return {
31924
+ name: "w:sdtPr",
31925
+ elements: sdtPrElements
31449
31926
  };
31450
- return result;
31451
31927
  }
31452
31928
  const RUN_LEVEL_WRAPPERS = /* @__PURE__ */ new Set(["w:hyperlink", "w:ins", "w:del"]);
31453
31929
  function convertSdtContentToRuns(elements) {
@@ -32354,15 +32830,26 @@ const getCommentSchema = (type2, commentIndex) => {
32354
32830
  }
32355
32831
  };
32356
32832
  };
32357
- const getConfig = (type2) => ({
32358
- xmlName: `${XML_NODE_NAME$7}${type2}`,
32359
- sdNodeOrKeyName: `${SD_NODE_NAME$6}${type2}`,
32360
- type: NodeTranslator.translatorTypes.NODE,
32361
- encode: () => {
32362
- },
32363
- decode: decode$7,
32364
- attributes: [attrConfig]
32365
- });
32833
+ const getConfig = (type2) => {
32834
+ const sdName = `${SD_NODE_NAME$6}${type2}`;
32835
+ const isStart = type2 === "Start";
32836
+ return {
32837
+ xmlName: `${XML_NODE_NAME$7}${type2}`,
32838
+ sdNodeOrKeyName: sdName,
32839
+ type: NodeTranslator.translatorTypes.NODE,
32840
+ encode: ({ nodes }) => {
32841
+ const node = nodes?.[0];
32842
+ if (!node) return void 0;
32843
+ const attrs = node.attributes ? { ...node.attributes } : {};
32844
+ return {
32845
+ type: isStart ? "commentRangeStart" : "commentRangeEnd",
32846
+ attrs
32847
+ };
32848
+ },
32849
+ decode: decode$7,
32850
+ attributes: [attrConfig]
32851
+ };
32852
+ };
32366
32853
  const commentRangeStartTranslator = NodeTranslator.from(getConfig("Start"));
32367
32854
  const commentRangeEndTranslator = NodeTranslator.from(getConfig("End"));
32368
32855
  const XML_NODE_NAME$6 = "sd:pageReference";
@@ -32987,7 +33474,7 @@ const encode$1 = (params, encodedAttrs = {}) => {
32987
33474
  text = elements[0].text;
32988
33475
  const xmlSpace = encodedAttrs.xmlSpace ?? elements[0]?.attributes?.["xml:space"];
32989
33476
  if (xmlSpace !== "preserve" && typeof text === "string") {
32990
- text = text.replace(/^\s+/, "").replace(/\s+$/, "");
33477
+ text = text.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
32991
33478
  }
32992
33479
  text = text.replace(/\[\[sdspace\]\]/g, "");
32993
33480
  } else if (!elements.length && encodedAttrs.xmlSpace === "preserve") {
@@ -33086,127 +33573,224 @@ const sdtNodeHandlerEntity = {
33086
33573
  handlerName: "sdtNodeHandler",
33087
33574
  handler: handleSdtNode
33088
33575
  };
33089
- function parseProperties(node) {
33090
- const marks = [];
33091
- const unknownMarks = [];
33092
- const { attributes = {}, elements = [] } = node;
33093
- const { nodes, paragraphProperties = {}, runProperties = {} } = splitElementsAndProperties(elements);
33094
- const hasRun = elements.find((element) => element.name === "w:r");
33095
- if (hasRun) paragraphProperties.elements = paragraphProperties?.elements?.filter((el) => el.name !== "w:rPr");
33096
- if (runProperties && runProperties?.elements?.length) {
33097
- marks.push(...parseMarks(runProperties, unknownMarks));
33098
- }
33099
- if (paragraphProperties && paragraphProperties.elements?.length) {
33100
- const disallowedParagraphProperties = ["w:u"];
33101
- const filteredParagraphProperties = {
33102
- ...paragraphProperties,
33103
- elements: paragraphProperties.elements?.filter((el) => !disallowedParagraphProperties.includes(el.name))
33104
- };
33105
- marks.push(...parseMarks(filteredParagraphProperties, unknownMarks));
33106
- }
33107
- marks.push(...handleStyleChangeMarks(runProperties, marks));
33108
- if (paragraphProperties && paragraphProperties.elements?.length) {
33109
- attributes["paragraphProperties"] = paragraphProperties;
33576
+ const translatorList = Array.from(
33577
+ /* @__PURE__ */ new Set([
33578
+ translator$1M,
33579
+ translator$6,
33580
+ translator$5,
33581
+ translator$4,
33582
+ translator$3,
33583
+ translator$1L,
33584
+ translator$1K,
33585
+ translator$1J,
33586
+ translator$20,
33587
+ translator$1r,
33588
+ translator$1$,
33589
+ translator$q,
33590
+ translator$7,
33591
+ translator$8,
33592
+ translator$1p,
33593
+ translator$23,
33594
+ translator$F,
33595
+ translator$1R,
33596
+ translator$1H,
33597
+ translator$1W,
33598
+ translator$1G,
33599
+ translator$2,
33600
+ translator$1F,
33601
+ translator$s,
33602
+ translator$1X,
33603
+ translator$X,
33604
+ translator$1E,
33605
+ translator$E,
33606
+ translator$D,
33607
+ translator$b,
33608
+ translator$Z,
33609
+ translator$J,
33610
+ translator$I,
33611
+ translator$C,
33612
+ translator$K,
33613
+ translator$22,
33614
+ translator$10,
33615
+ translator$1_,
33616
+ translator$1x,
33617
+ translator$1D,
33618
+ translator$1w,
33619
+ translator$V,
33620
+ translator$U,
33621
+ translator$1C,
33622
+ translator$1B,
33623
+ translator$1A,
33624
+ translator$1z,
33625
+ translator$1P,
33626
+ translator$1n,
33627
+ translator$1y,
33628
+ translator$O,
33629
+ translator$1v,
33630
+ translator$1u,
33631
+ translator$1t,
33632
+ translator$1s,
33633
+ translator$11,
33634
+ translator$1f,
33635
+ translator$1h,
33636
+ translator$12,
33637
+ translator$1g,
33638
+ translator$$,
33639
+ translator$1V,
33640
+ translator$1N,
33641
+ translator$1U,
33642
+ translator$1l,
33643
+ translator$r,
33644
+ translator$1Q,
33645
+ translator$1e,
33646
+ translator$1d,
33647
+ translator$1c,
33648
+ translator$1b,
33649
+ translator$1a,
33650
+ translator$T,
33651
+ translator$1Y,
33652
+ translator$1T,
33653
+ translator$1S,
33654
+ translator$1,
33655
+ translator$21,
33656
+ translator$19,
33657
+ translator$9,
33658
+ translator$e,
33659
+ translator$p,
33660
+ translator$d,
33661
+ translator$B,
33662
+ translator$o,
33663
+ translator$a,
33664
+ translator$A,
33665
+ translator$n,
33666
+ translator$m,
33667
+ translator$l,
33668
+ translator$k,
33669
+ translator$c,
33670
+ translator$j,
33671
+ translator$i,
33672
+ translator$h,
33673
+ translator$g,
33674
+ translator$f,
33675
+ translator$G,
33676
+ translator$P,
33677
+ translator$M,
33678
+ translator$N,
33679
+ translator$H,
33680
+ translator$_,
33681
+ translator$17,
33682
+ translator$R,
33683
+ translator$v,
33684
+ translator$Q,
33685
+ translator$z,
33686
+ translator$w,
33687
+ translator$18,
33688
+ translator$16,
33689
+ translator$15,
33690
+ translator$1j,
33691
+ translator$1Z,
33692
+ translator$L,
33693
+ translator$Y,
33694
+ translator$y,
33695
+ translator$x,
33696
+ translator$14,
33697
+ translator$13,
33698
+ translator$u,
33699
+ translator$t,
33700
+ commentRangeStartTranslator,
33701
+ commentRangeEndTranslator
33702
+ ])
33703
+ );
33704
+ const additionalHandlers = Object.freeze(
33705
+ translatorList.reduce((acc, translator2) => {
33706
+ const key = translator2?.xmlName;
33707
+ if (!key) return acc;
33708
+ acc[key] = translator2;
33709
+ return acc;
33710
+ }, {})
33711
+ );
33712
+ const baseHandlers = {
33713
+ ...additionalHandlers
33714
+ };
33715
+ const registeredHandlers = Object.freeze(baseHandlers);
33716
+ const INLINE_PARENT_NAMES = /* @__PURE__ */ new Set([
33717
+ "w:r",
33718
+ "w:hyperlink",
33719
+ "w:smartTag",
33720
+ "w:fldSimple",
33721
+ "w:proofErr",
33722
+ "w:del",
33723
+ "w:ins"
33724
+ ]);
33725
+ const INLINE_NODE_NAMES = /* @__PURE__ */ new Set([
33726
+ "m:oMathPara",
33727
+ "m:oMath",
33728
+ "m:t",
33729
+ "m:r",
33730
+ "m:ctrlPr",
33731
+ "m:sSupPr",
33732
+ "m:e",
33733
+ "m:sup",
33734
+ "m:sSup"
33735
+ ]);
33736
+ const BLOCK_BOUNDARY_NAMES = /* @__PURE__ */ new Set(["w:p", "w:body", "w:tbl", "w:tc", "w:tr"]);
33737
+ const isInlineContext = (path = [], currentNodeName) => {
33738
+ if (currentNodeName && INLINE_NODE_NAMES.has(currentNodeName)) {
33739
+ return true;
33110
33740
  }
33111
- if (marks && node.name === "w:p") {
33112
- marks.forEach((mark) => {
33113
- const attrValue = Object.keys(mark.attrs ?? {})[0];
33114
- if (attrValue) {
33115
- const value = mark.attrs[attrValue];
33116
- attributes[attrValue] = value;
33117
- }
33118
- });
33741
+ if (!Array.isArray(path) || path.length === 0) return false;
33742
+ for (let i = path.length - 1; i >= 0; i--) {
33743
+ const ancestorName = path[i]?.name;
33744
+ if (!ancestorName) continue;
33745
+ if (INLINE_NODE_NAMES.has(ancestorName) || INLINE_PARENT_NAMES.has(ancestorName)) {
33746
+ return true;
33747
+ }
33748
+ if (BLOCK_BOUNDARY_NAMES.has(ancestorName)) {
33749
+ return false;
33750
+ }
33119
33751
  }
33120
- return { elements: nodes, attributes, marks, unknownMarks };
33121
- }
33122
- function splitElementsAndProperties(elements) {
33123
- const pPr = elements.find((el) => el.name === "w:pPr");
33124
- const rPr = elements.find((el) => el.name === "w:rPr");
33125
- const sectPr = elements.find((el) => el.name === "w:sectPr");
33126
- const els = elements.filter((el) => el.name !== "w:pPr" && el.name !== "w:rPr" && el.name !== "w:sectPr");
33127
- return {
33128
- nodes: els,
33129
- paragraphProperties: pPr,
33130
- runProperties: rPr,
33131
- sectionProperties: sectPr
33132
- };
33133
- }
33134
- function getElementName(element) {
33135
- return SuperConverter.allowedElements[element.name || element.type];
33136
- }
33137
- const isPropertiesElement = (element) => {
33138
- return !!SuperConverter.propertyTypes[element.name || element.type];
33752
+ return false;
33139
33753
  };
33140
- const handleStandardNode = (params) => {
33141
- const { nodes, docx, nodeListHandler } = params;
33142
- if (!nodes || nodes.length === 0) {
33143
- return { nodes: [], consumed: 0 };
33144
- }
33754
+ const handlePassthroughNode = (params) => {
33755
+ const { nodes = [] } = params;
33145
33756
  const node = nodes[0];
33146
- const { name } = node;
33147
- const { attributes, elements, marks = [] } = parseProperties(node);
33148
- if (name === "w:sdt") {
33757
+ if (!node) return { nodes: [], consumed: 0 };
33758
+ if (registeredHandlers[node.name] || node.name === "w:commentReference") {
33149
33759
  return { nodes: [], consumed: 0 };
33150
33760
  }
33151
- if (isPropertiesElement(node)) {
33152
- return {
33153
- nodes: [
33154
- {
33155
- type: getElementName(node),
33156
- attrs: { ...attributes },
33157
- marks: []
33158
- }
33159
- ],
33160
- consumed: 0
33161
- };
33162
- }
33163
- if (!getElementName(node)) {
33164
- return {
33165
- nodes: [
33166
- {
33167
- type: name,
33168
- content: elements,
33169
- attrs: { ...attributes },
33170
- marks
33171
- }
33172
- ],
33173
- consumed: 0,
33174
- unhandled: true
33175
- };
33176
- }
33177
- const content = [];
33178
- const parentStyleId = getParentStyleId(node);
33179
- if (elements && elements.length) {
33180
- const updatedElements = elements.map((el) => {
33181
- if (!el.marks) el.marks = [];
33182
- el.marks.push(...marks);
33183
- return el;
33184
- });
33761
+ const originalXml = carbonCopy(node) || {};
33762
+ const originalElementsSource = originalXml.elements;
33763
+ const originalElements = originalElementsSource ? carbonCopy(originalElementsSource) : [];
33764
+ const childElements = Array.isArray(node.elements) ? node.elements : [];
33765
+ let childContent = [];
33766
+ if (childElements.length && params.nodeListHandler?.handler) {
33185
33767
  const childParams = {
33186
33768
  ...params,
33187
- nodes: updatedElements,
33188
- parentStyleId,
33769
+ nodes: childElements,
33189
33770
  path: [...params.path || [], node]
33190
33771
  };
33191
- const childContent = nodeListHandler.handler(childParams);
33192
- content.push(...childContent);
33772
+ childContent = params.nodeListHandler.handler(childParams) || [];
33193
33773
  }
33194
- const resultNode = {
33195
- type: getElementName(node),
33196
- content,
33197
- attrs: { ...attributes },
33198
- marks: []
33774
+ if (originalElements?.length) {
33775
+ originalXml.elements = originalElements;
33776
+ }
33777
+ const passthroughNode = {
33778
+ type: isInlineContext(params.path, node.name) ? "passthroughInline" : "passthroughBlock",
33779
+ attrs: {
33780
+ originalName: node.name,
33781
+ originalXml
33782
+ },
33783
+ marks: [],
33784
+ content: childContent
33785
+ };
33786
+ return {
33787
+ nodes: [passthroughNode],
33788
+ consumed: 1
33199
33789
  };
33200
- return { nodes: [resultNode], consumed: 1 };
33201
- };
33202
- const getParentStyleId = (node) => {
33203
- const pPr = node.elements?.find((el) => el.name === "w:pPr");
33204
- const styleTag = pPr?.elements?.find((el) => el.name === "w:pStyle");
33205
- return styleTag ? styleTag.attributes["w:val"] : null;
33206
33790
  };
33207
- const standardNodeHandlerEntity = {
33208
- handlerName: "standardNodeHandler",
33209
- handler: handleStandardNode
33791
+ const passthroughNodeHandlerEntity = {
33792
+ handlerName: "passthroughNodeHandler",
33793
+ handler: handlePassthroughNode
33210
33794
  };
33211
33795
  const handler = (params) => {
33212
33796
  const { nodes } = params;
@@ -33230,13 +33814,6 @@ const handleBookmarkNode = (params) => {
33230
33814
  return { nodes: [], consumed: 0 };
33231
33815
  }
33232
33816
  const node = nodes[0];
33233
- const handleStandardNode2 = nodeListHandler.handlerEntities.find(
33234
- (e) => e.handlerName === "standardNodeHandler"
33235
- )?.handler;
33236
- if (!handleStandardNode2) {
33237
- console.error("Standard node handler not found");
33238
- return { nodes: [], consumed: 0 };
33239
- }
33240
33817
  const customMarks = editor?.extensionService?.extensions?.filter((e) => e.isExternal === true) || [];
33241
33818
  const bookmarkName = node.attributes["w:name"]?.split(";")[0];
33242
33819
  const customMark = customMarks.find((mark) => mark.name === bookmarkName);
@@ -33245,7 +33822,6 @@ const handleBookmarkNode = (params) => {
33245
33822
  (n) => n.name === "w:bookmarkEnd" && n.attributes["w:id"] === node.attributes["w:id"]
33246
33823
  );
33247
33824
  const textNodes = nodes.slice(1, bookmarkEndIndex);
33248
- const nodeListHandler2 = params.nodeListHandler;
33249
33825
  const attrs = {};
33250
33826
  node.attributes["w:name"].split(";").forEach((name) => {
33251
33827
  const [key, value] = name.split("=");
@@ -33253,7 +33829,7 @@ const handleBookmarkNode = (params) => {
33253
33829
  attrs[key] = value;
33254
33830
  }
33255
33831
  });
33256
- const translatedText = nodeListHandler2.handler({
33832
+ const translatedText = nodeListHandler.handler({
33257
33833
  ...params,
33258
33834
  nodes: textNodes,
33259
33835
  path: [...params.path || [], node]
@@ -33269,13 +33845,11 @@ const handleBookmarkNode = (params) => {
33269
33845
  consumed: translatedText.length + 2
33270
33846
  };
33271
33847
  }
33272
- const updatedParams = { ...params, nodes: [node] };
33273
- const result = handleStandardNode2(updatedParams);
33274
- if (result.nodes.length === 1) {
33275
- result.nodes[0].attrs.name = node.attributes["w:name"];
33276
- result.nodes[0].attrs.id = node.attributes["w:id"];
33848
+ const encoded = translator$8.encode({ ...params, nodes: [node] });
33849
+ if (!encoded) {
33850
+ return { nodes: [], consumed: 0 };
33277
33851
  }
33278
- return result;
33852
+ return { nodes: [encoded], consumed: 1 };
33279
33853
  };
33280
33854
  const handleBookmarkStartNode = (params) => {
33281
33855
  const { nodes } = params;
@@ -33481,7 +34055,11 @@ function importCommentData({ docx, editor, converter }) {
33481
34055
  const generateCommentsWithExtendedData = ({ docx, comments }) => {
33482
34056
  if (!comments?.length) return [];
33483
34057
  const commentsExtended = docx["word/commentsExtended.xml"];
33484
- if (!commentsExtended) return comments.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
34058
+ if (!commentsExtended) {
34059
+ const commentRanges = extractCommentRangesFromDocument(docx);
34060
+ const commentsWithThreading = detectThreadingFromRanges(comments, commentRanges);
34061
+ return commentsWithThreading.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
34062
+ }
33485
34063
  const { elements: initialElements = [] } = commentsExtended;
33486
34064
  if (!initialElements?.length) return comments.map((comment) => ({ ...comment, isDone: comment.isDone ?? false }));
33487
34065
  const { elements = [] } = initialElements[0] ?? {};
@@ -33507,6 +34085,79 @@ const getExtendedDetails = (commentEx) => {
33507
34085
  const paraIdParent = attributes["w15:paraIdParent"];
33508
34086
  return { paraId, isDone, paraIdParent };
33509
34087
  };
34088
+ const extractCommentRangesFromDocument = (docx) => {
34089
+ const documentXml = docx["word/document.xml"];
34090
+ if (!documentXml) {
34091
+ return [];
34092
+ }
34093
+ const pendingComments = [];
34094
+ const walkElements = (elements) => {
34095
+ if (!elements || !Array.isArray(elements)) return;
34096
+ elements.forEach((element) => {
34097
+ if (element.name === "w:commentRangeStart") {
34098
+ const commentId = element.attributes?.["w:id"];
34099
+ if (commentId !== void 0) {
34100
+ pendingComments.push({
34101
+ type: "start",
34102
+ commentId: String(commentId)
34103
+ });
34104
+ }
34105
+ } else if (element.name === "w:commentRangeEnd") {
34106
+ const commentId = element.attributes?.["w:id"];
34107
+ if (commentId !== void 0) {
34108
+ pendingComments.push({
34109
+ type: "end",
34110
+ commentId: String(commentId)
34111
+ });
34112
+ }
34113
+ }
34114
+ if (element.elements && Array.isArray(element.elements)) {
34115
+ walkElements(element.elements);
34116
+ }
34117
+ });
34118
+ };
34119
+ if (documentXml.elements && documentXml.elements.length > 0) {
34120
+ const body = documentXml.elements[0];
34121
+ if (body.elements) {
34122
+ walkElements(body.elements);
34123
+ }
34124
+ }
34125
+ return pendingComments;
34126
+ };
34127
+ const detectThreadingFromRanges = (comments, rangeEvents) => {
34128
+ if (!rangeEvents || rangeEvents.length === 0) {
34129
+ return comments;
34130
+ }
34131
+ const openRanges = [];
34132
+ const parentMap = /* @__PURE__ */ new Map();
34133
+ rangeEvents.forEach((event) => {
34134
+ if (event.type === "start") {
34135
+ if (openRanges.length > 0) {
34136
+ const parentCommentId = openRanges[openRanges.length - 1];
34137
+ parentMap.set(event.commentId, parentCommentId);
34138
+ }
34139
+ openRanges.push(event.commentId);
34140
+ } else if (event.type === "end") {
34141
+ const index2 = openRanges.lastIndexOf(event.commentId);
34142
+ if (index2 !== -1) {
34143
+ openRanges.splice(index2, 1);
34144
+ }
34145
+ }
34146
+ });
34147
+ return comments.map((comment) => {
34148
+ const parentCommentId = parentMap.get(comment.importedId);
34149
+ if (parentCommentId) {
34150
+ const parentComment = comments.find((c) => c.importedId === parentCommentId);
34151
+ if (parentComment) {
34152
+ return {
34153
+ ...comment,
34154
+ parentCommentId: parentComment.commentId
34155
+ };
34156
+ }
34157
+ }
34158
+ return comment;
34159
+ });
34160
+ };
33510
34161
  const RELATIONSHIP_TYPES = (
33511
34162
  /** @type {const} */
33512
34163
  {
@@ -34197,18 +34848,22 @@ const getInstructionPreProcessor = (instruction) => {
34197
34848
  const preProcessNodesForFldChar = (nodes = [], docx) => {
34198
34849
  const processedNodes = [];
34199
34850
  let collectedNodesStack = [];
34851
+ let rawCollectedNodesStack = [];
34200
34852
  let currentFieldStack = [];
34201
34853
  let unpairedEnd = null;
34202
34854
  let collecting = false;
34203
34855
  const finalizeField = () => {
34204
34856
  if (collecting) {
34205
34857
  const collectedNodes = collectedNodesStack.pop().filter((n) => n !== null);
34858
+ const rawCollectedNodes = rawCollectedNodesStack.pop().filter((n) => n !== null);
34206
34859
  const currentField = currentFieldStack.pop();
34207
- const combined = _processCombinedNodesForFldChar(collectedNodes, currentField.instrText.trim(), docx);
34860
+ const combinedResult = _processCombinedNodesForFldChar(collectedNodes, currentField.instrText.trim(), docx);
34861
+ const outputNodes = combinedResult.handled ? combinedResult.nodes : rawCollectedNodes;
34208
34862
  if (collectedNodesStack.length === 0) {
34209
- processedNodes.push(...combined);
34863
+ processedNodes.push(...outputNodes);
34210
34864
  } else {
34211
- collectedNodesStack[collectedNodesStack.length - 1].push(...combined);
34865
+ collectedNodesStack[collectedNodesStack.length - 1].push(...outputNodes);
34866
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(...outputNodes);
34212
34867
  }
34213
34868
  } else {
34214
34869
  unpairedEnd = true;
@@ -34220,18 +34875,26 @@ const preProcessNodesForFldChar = (nodes = [], docx) => {
34220
34875
  const instrTextEl = node.elements?.find((el) => el.name === "w:instrText");
34221
34876
  collecting = collectedNodesStack.length > 0;
34222
34877
  if (fldType === "begin") {
34223
- collectedNodesStack.push([null]);
34878
+ collectedNodesStack.push([]);
34879
+ rawCollectedNodesStack.push([node]);
34224
34880
  currentFieldStack.push({ instrText: "" });
34225
34881
  continue;
34226
34882
  }
34227
34883
  if (instrTextEl && collecting && currentFieldStack.length > 0) {
34884
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34228
34885
  currentFieldStack[currentFieldStack.length - 1].instrText += (instrTextEl.elements?.[0]?.text || "") + " ";
34229
34886
  continue;
34230
34887
  }
34231
34888
  if (fldType === "end") {
34889
+ if (collecting) {
34890
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34891
+ }
34232
34892
  finalizeField();
34233
34893
  continue;
34234
34894
  } else if (fldType === "separate") {
34895
+ if (collecting) {
34896
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34897
+ }
34235
34898
  continue;
34236
34899
  }
34237
34900
  if (Array.isArray(node.elements)) {
@@ -34241,17 +34904,21 @@ const preProcessNodesForFldChar = (nodes = [], docx) => {
34241
34904
  childResult.unpairedBegin.forEach((pendingField) => {
34242
34905
  currentFieldStack.push(pendingField.fieldInfo);
34243
34906
  collectedNodesStack.push([node]);
34907
+ rawCollectedNodesStack.push([node]);
34244
34908
  });
34245
34909
  } else if (childResult.unpairedEnd) {
34246
34910
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34911
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34247
34912
  finalizeField();
34248
34913
  } else if (collecting) {
34249
34914
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34915
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34250
34916
  } else {
34251
34917
  processedNodes.push(node);
34252
34918
  }
34253
34919
  } else if (collecting) {
34254
34920
  collectedNodesStack[collectedNodesStack.length - 1].push(node);
34921
+ rawCollectedNodesStack[rawCollectedNodesStack.length - 1].push(node);
34255
34922
  } else {
34256
34923
  processedNodes.push(node);
34257
34924
  }
@@ -34273,11 +34940,91 @@ const _processCombinedNodesForFldChar = (nodesToCombine = [], instrText, docx) =
34273
34940
  const instructionType = instrText.trim().split(" ")[0];
34274
34941
  const instructionPreProcessor = getInstructionPreProcessor(instructionType);
34275
34942
  if (instructionPreProcessor) {
34276
- return instructionPreProcessor(nodesToCombine, instrText, docx);
34277
- } else {
34278
- return nodesToCombine;
34943
+ return { nodes: instructionPreProcessor(nodesToCombine, instrText, docx), handled: true };
34944
+ }
34945
+ return { nodes: nodesToCombine, handled: false };
34946
+ };
34947
+ const preProcessPageFieldsOnly = (nodes = [], depth = 0) => {
34948
+ const processedNodes = [];
34949
+ let i = 0;
34950
+ while (i < nodes.length) {
34951
+ const node = nodes[i];
34952
+ const fldCharEl = node.elements?.find((el) => el.name === "w:fldChar");
34953
+ const fldType = fldCharEl?.attributes?.["w:fldCharType"];
34954
+ if (fldType === "begin") {
34955
+ const fieldInfo = scanFieldSequence(nodes, i);
34956
+ if (fieldInfo && (fieldInfo.fieldType === "PAGE" || fieldInfo.fieldType === "NUMPAGES")) {
34957
+ const preprocessor = fieldInfo.fieldType === "PAGE" ? preProcessPageInstruction : preProcessNumPagesInstruction;
34958
+ const contentNodes = fieldInfo.contentNodes;
34959
+ const processedField = preprocessor(contentNodes, fieldInfo.instrText);
34960
+ processedNodes.push(...processedField);
34961
+ i = fieldInfo.endIndex + 1;
34962
+ continue;
34963
+ } else {
34964
+ if (fieldInfo) {
34965
+ for (let j2 = i; j2 <= fieldInfo.endIndex; j2++) {
34966
+ const passNode = nodes[j2];
34967
+ if (Array.isArray(passNode.elements)) {
34968
+ const childResult = preProcessPageFieldsOnly(passNode.elements, depth + 1);
34969
+ passNode.elements = childResult.processedNodes;
34970
+ }
34971
+ processedNodes.push(passNode);
34972
+ }
34973
+ i = fieldInfo.endIndex + 1;
34974
+ continue;
34975
+ }
34976
+ }
34977
+ }
34978
+ if (Array.isArray(node.elements)) {
34979
+ const childResult = preProcessPageFieldsOnly(node.elements, depth + 1);
34980
+ node.elements = childResult.processedNodes;
34981
+ }
34982
+ processedNodes.push(node);
34983
+ i++;
34279
34984
  }
34985
+ return { processedNodes };
34280
34986
  };
34987
+ function scanFieldSequence(nodes, beginIndex) {
34988
+ let instrText = "";
34989
+ let separateIndex = -1;
34990
+ let endIndex = -1;
34991
+ const contentNodes = [];
34992
+ for (let i = beginIndex + 1; i < nodes.length; i++) {
34993
+ const node = nodes[i];
34994
+ const fldCharEl = node.elements?.find((el) => el.name === "w:fldChar");
34995
+ const fldType = fldCharEl?.attributes?.["w:fldCharType"];
34996
+ const instrTextEl = node.elements?.find((el) => el.name === "w:instrText");
34997
+ if (instrTextEl) {
34998
+ instrText += (instrTextEl.elements?.[0]?.text || "") + " ";
34999
+ }
35000
+ if (fldType === "separate") {
35001
+ separateIndex = i;
35002
+ } else if (fldType === "end") {
35003
+ endIndex = i;
35004
+ break;
35005
+ } else if (separateIndex !== -1 && fldType !== "begin") {
35006
+ contentNodes.push(node);
35007
+ }
35008
+ }
35009
+ if (endIndex === -1) {
35010
+ return null;
35011
+ }
35012
+ const fieldType = instrText.trim().split(" ")[0];
35013
+ return {
35014
+ fieldType,
35015
+ instrText: instrText.trim(),
35016
+ contentNodes,
35017
+ endIndex
35018
+ };
35019
+ }
35020
+ const commentRangeStartHandlerEntity = generateV2HandlerEntity(
35021
+ "commentRangeStartHandler",
35022
+ commentRangeStartTranslator
35023
+ );
35024
+ const commentRangeEndHandlerEntity = generateV2HandlerEntity(
35025
+ "commentRangeEndHandler",
35026
+ commentRangeEndTranslator
35027
+ );
34281
35028
  const createDocumentJson = (docx, converter, editor) => {
34282
35029
  const json = carbonCopy(getInitialJSON(docx));
34283
35030
  if (!json) return null;
@@ -34339,6 +35086,7 @@ const createDocumentJson = (docx, converter, editor) => {
34339
35086
  path: []
34340
35087
  });
34341
35088
  parsedContent = filterOutRootInlineNodes(parsedContent);
35089
+ collapseWhitespaceNextToInlinePassthrough(parsedContent);
34342
35090
  const result = {
34343
35091
  type: "doc",
34344
35092
  content: parsedContent,
@@ -34379,6 +35127,8 @@ const defaultNodeListHandler = () => {
34379
35127
  bookmarkStartNodeHandlerEntity,
34380
35128
  bookmarkEndNodeHandlerEntity,
34381
35129
  hyperlinkNodeHandlerEntity,
35130
+ commentRangeStartHandlerEntity,
35131
+ commentRangeEndHandlerEntity,
34382
35132
  drawingNodeHandlerEntity,
34383
35133
  trackChangeNodeHandlerEntity,
34384
35134
  tableNodeHandlerEntity,
@@ -34387,7 +35137,7 @@ const defaultNodeListHandler = () => {
34387
35137
  autoPageHandlerEntity,
34388
35138
  autoTotalPageCountEntity,
34389
35139
  pageReferenceEntity,
34390
- standardNodeHandlerEntity
35140
+ passthroughNodeHandlerEntity
34391
35141
  ];
34392
35142
  const handler2 = createNodeListHandler(entities);
34393
35143
  return {
@@ -34674,6 +35424,8 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34674
35424
  editor.options.annotations = true;
34675
35425
  headers.forEach((header) => {
34676
35426
  const { rId, referenceFile, currentFileName } = getHeaderFooterSectionData(header, docx);
35427
+ const headerNodes = carbonCopy(referenceFile.elements[0].elements ?? []);
35428
+ const { processedNodes: headerProcessedNodes } = preProcessPageFieldsOnly(headerNodes);
34677
35429
  const sectPrHeader = allSectPrElements.find(
34678
35430
  (el) => el.name === "w:headerReference" && el.attributes["r:id"] === rId
34679
35431
  );
@@ -34681,7 +35433,7 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34681
35433
  if (converter.headerIds[sectionType]) sectionType = null;
34682
35434
  const nodeListHandler = defaultNodeListHandler();
34683
35435
  let schema = nodeListHandler.handler({
34684
- nodes: referenceFile.elements[0].elements,
35436
+ nodes: headerProcessedNodes,
34685
35437
  nodeListHandler,
34686
35438
  docx,
34687
35439
  converter,
@@ -34702,13 +35454,15 @@ const importHeadersFooters = (docx, converter, mainEditor) => {
34702
35454
  if (titlePg) converter.headerIds.titlePg = true;
34703
35455
  footers.forEach((footer) => {
34704
35456
  const { rId, referenceFile, currentFileName } = getHeaderFooterSectionData(footer, docx);
35457
+ const footerNodes = carbonCopy(referenceFile.elements[0].elements ?? []);
35458
+ const { processedNodes: footerProcessedNodes } = preProcessPageFieldsOnly(footerNodes);
34705
35459
  const sectPrFooter = allSectPrElements.find(
34706
35460
  (el) => el.name === "w:footerReference" && el.attributes["r:id"] === rId
34707
35461
  );
34708
35462
  const sectionType = sectPrFooter?.attributes["w:type"];
34709
35463
  const nodeListHandler = defaultNodeListHandler();
34710
35464
  let schema = nodeListHandler.handler({
34711
- nodes: referenceFile.elements[0].elements,
35465
+ nodes: footerProcessedNodes,
34712
35466
  nodeListHandler,
34713
35467
  docx,
34714
35468
  converter,
@@ -34771,6 +35525,51 @@ function filterOutRootInlineNodes(content = []) {
34771
35525
  ]);
34772
35526
  return content.filter((node) => node && typeof node.type === "string" && !INLINE_TYPES.has(node.type));
34773
35527
  }
35528
+ function collapseWhitespaceNextToInlinePassthrough(content = []) {
35529
+ if (!Array.isArray(content) || content.length === 0) return;
35530
+ const sequence = collectInlineSequence(content);
35531
+ sequence.forEach((entry, index2) => {
35532
+ if (entry.kind !== "passthrough") return;
35533
+ const prev = findNeighborText(sequence, index2, -1);
35534
+ const next = findNeighborText(sequence, index2, 1);
35535
+ if (!prev || !next) return;
35536
+ if (!prev.node.text.endsWith(" ") || !next.node.text.startsWith(" ")) return;
35537
+ prev.node.text = prev.node.text.replace(/ +$/, " ");
35538
+ next.node.text = next.node.text.replace(/^ +/, "");
35539
+ if (next.node.text.length === 0) {
35540
+ next.parent.splice(next.index, 1);
35541
+ }
35542
+ });
35543
+ }
35544
+ function collectInlineSequence(nodes, result = [], insidePassthrough = false) {
35545
+ if (!Array.isArray(nodes) || nodes.length === 0) return result;
35546
+ nodes.forEach((node, index2) => {
35547
+ if (!node) return;
35548
+ const isPassthrough = node.type === "passthroughInline";
35549
+ if (isPassthrough && !insidePassthrough) {
35550
+ result.push({ kind: "passthrough", parent: nodes, index: index2 });
35551
+ }
35552
+ if (node.type === "text" && typeof node.text === "string" && !insidePassthrough) {
35553
+ result.push({ kind: "text", node, parent: nodes, index: index2 });
35554
+ }
35555
+ if (Array.isArray(node.content) && node.content.length) {
35556
+ const nextInside = insidePassthrough || isPassthrough;
35557
+ collectInlineSequence(node.content, result, nextInside);
35558
+ }
35559
+ });
35560
+ return result;
35561
+ }
35562
+ function findNeighborText(sequence, startIndex, direction) {
35563
+ let cursor = startIndex + direction;
35564
+ while (cursor >= 0 && cursor < sequence.length) {
35565
+ const entry = sequence[cursor];
35566
+ if (entry.kind === "text") {
35567
+ return entry;
35568
+ }
35569
+ cursor += direction;
35570
+ }
35571
+ return null;
35572
+ }
34774
35573
  function getThemeColorPalette(docx) {
34775
35574
  const themePart = docx?.["word/theme/theme1.xml"];
34776
35575
  if (!themePart || !Array.isArray(themePart.elements)) return void 0;
@@ -35133,7 +35932,9 @@ function exportSchemaToJson(params) {
35133
35932
  "page-number": translator$4,
35134
35933
  "total-page-number": translator$3,
35135
35934
  pageReference: translator$6,
35136
- tableOfContents: translator$5
35935
+ tableOfContents: translator$5,
35936
+ passthroughBlock: translatePassthroughNode,
35937
+ passthroughInline: translatePassthroughNode
35137
35938
  };
35138
35939
  let handler2 = router[type2];
35139
35940
  if (handler2 && "decode" in handler2 && typeof handler2.decode === "function") {
@@ -35145,6 +35946,11 @@ function exportSchemaToJson(params) {
35145
35946
  }
35146
35947
  return handler2(params);
35147
35948
  }
35949
+ function translatePassthroughNode(params) {
35950
+ const original = params?.node?.attrs?.originalXml;
35951
+ if (!original) return null;
35952
+ return carbonCopy(original);
35953
+ }
35148
35954
  function translateBodyNode(params) {
35149
35955
  let sectPr = params.bodyNode?.elements?.find((n) => n.name === "w:sectPr");
35150
35956
  if (!sectPr) {
@@ -35467,10 +36273,12 @@ const toIsoNoFractional = (unixMillis) => {
35467
36273
  const updateCommentsXml = (commentDefs = [], commentsXml) => {
35468
36274
  const newCommentsXml = carbonCopy(commentsXml);
35469
36275
  commentDefs.forEach((commentDef) => {
35470
- const elements = commentDef.elements[0].elements;
36276
+ const paraNode = commentDef.elements[0];
36277
+ if (!paraNode.attributes) paraNode.attributes = {};
36278
+ const elements = paraNode.elements;
35471
36279
  elements.unshift(COMMENT_REF);
35472
36280
  const paraId = commentDef.attributes["w15:paraId"];
35473
- commentDef.elements[0].attributes["w14:paraId"] = paraId;
36281
+ paraNode.attributes["w14:paraId"] = paraId;
35474
36282
  commentDef.attributes = {
35475
36283
  "w:id": commentDef.attributes["w:id"],
35476
36284
  "w:author": commentDef.attributes["w:author"],
@@ -35844,7 +36652,7 @@ const _SuperConverter = class _SuperConverter {
35844
36652
  static getStoredSuperdocVersion(docx) {
35845
36653
  return _SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
35846
36654
  }
35847
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.0.0-beta.2") {
36655
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.0.0-beta.21") {
35848
36656
  return _SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
35849
36657
  }
35850
36658
  /**
@@ -36185,6 +36993,112 @@ const _SuperConverter = class _SuperConverter {
36185
36993
  });
36186
36994
  return { result, params };
36187
36995
  }
36996
+ /**
36997
+ * Creates a default empty header for the specified variant.
36998
+ *
36999
+ * This method programmatically creates a new header section with an empty ProseMirror
37000
+ * document. The header is added to the converter's data structures and will be included
37001
+ * in subsequent DOCX exports.
37002
+ *
37003
+ * @param {('default' | 'first' | 'even' | 'odd')} variant - The header variant to create
37004
+ * @returns {string} The relationship ID of the created header
37005
+ *
37006
+ * @throws {Error} If variant is invalid or header already exists for this variant
37007
+ *
37008
+ * @example
37009
+ * ```javascript
37010
+ * const headerId = converter.createDefaultHeader('default');
37011
+ * // headerId: 'rId-header-default'
37012
+ * // converter.headers['rId-header-default'] contains empty PM doc
37013
+ * // converter.headerIds.default === 'rId-header-default'
37014
+ * ```
37015
+ */
37016
+ createDefaultHeader(variant = "default") {
37017
+ if (typeof variant !== "string") {
37018
+ throw new TypeError(`variant must be a string, received ${typeof variant}`);
37019
+ }
37020
+ const validVariants = ["default", "first", "even", "odd"];
37021
+ if (!validVariants.includes(variant)) {
37022
+ throw new Error(`Invalid header variant: ${variant}. Must be one of: ${validVariants.join(", ")}`);
37023
+ }
37024
+ if (this.headerIds[variant]) {
37025
+ console.warn(`[SuperConverter] Header already exists for variant '${variant}': ${this.headerIds[variant]}`);
37026
+ return this.headerIds[variant];
37027
+ }
37028
+ const rId = `rId-header-${variant}`;
37029
+ const emptyDoc = {
37030
+ type: "doc",
37031
+ content: [
37032
+ {
37033
+ type: "paragraph",
37034
+ content: []
37035
+ }
37036
+ ]
37037
+ };
37038
+ this.headers[rId] = emptyDoc;
37039
+ this.headerIds[variant] = rId;
37040
+ if (!this.headerIds.ids) {
37041
+ this.headerIds.ids = [];
37042
+ }
37043
+ if (!this.headerIds.ids.includes(rId)) {
37044
+ this.headerIds.ids.push(rId);
37045
+ }
37046
+ this.documentModified = true;
37047
+ return rId;
37048
+ }
37049
+ /**
37050
+ * Creates a default empty footer for the specified variant.
37051
+ *
37052
+ * This method programmatically creates a new footer section with an empty ProseMirror
37053
+ * document. The footer is added to the converter's data structures and will be included
37054
+ * in subsequent DOCX exports.
37055
+ *
37056
+ * @param {('default' | 'first' | 'even' | 'odd')} variant - The footer variant to create
37057
+ * @returns {string} The relationship ID of the created footer
37058
+ *
37059
+ * @throws {Error} If variant is invalid or footer already exists for this variant
37060
+ *
37061
+ * @example
37062
+ * ```javascript
37063
+ * const footerId = converter.createDefaultFooter('default');
37064
+ * // footerId: 'rId-footer-default'
37065
+ * // converter.footers['rId-footer-default'] contains empty PM doc
37066
+ * // converter.footerIds.default === 'rId-footer-default'
37067
+ * ```
37068
+ */
37069
+ createDefaultFooter(variant = "default") {
37070
+ if (typeof variant !== "string") {
37071
+ throw new TypeError(`variant must be a string, received ${typeof variant}`);
37072
+ }
37073
+ const validVariants = ["default", "first", "even", "odd"];
37074
+ if (!validVariants.includes(variant)) {
37075
+ throw new Error(`Invalid footer variant: ${variant}. Must be one of: ${validVariants.join(", ")}`);
37076
+ }
37077
+ if (this.footerIds[variant]) {
37078
+ console.warn(`[SuperConverter] Footer already exists for variant '${variant}': ${this.footerIds[variant]}`);
37079
+ return this.footerIds[variant];
37080
+ }
37081
+ const rId = `rId-footer-${variant}`;
37082
+ const emptyDoc = {
37083
+ type: "doc",
37084
+ content: [
37085
+ {
37086
+ type: "paragraph",
37087
+ content: []
37088
+ }
37089
+ ]
37090
+ };
37091
+ this.footers[rId] = emptyDoc;
37092
+ this.footerIds[variant] = rId;
37093
+ if (!this.footerIds.ids) {
37094
+ this.footerIds.ids = [];
37095
+ }
37096
+ if (!this.footerIds.ids.includes(rId)) {
37097
+ this.footerIds.ids.push(rId);
37098
+ }
37099
+ this.documentModified = true;
37100
+ return rId;
37101
+ }
36188
37102
  // Deprecated methods for backward compatibility
36189
37103
  static getStoredSuperdocId(docx) {
36190
37104
  console.warn("getStoredSuperdocId is deprecated, use getDocumentGuid instead");
@@ -36458,7 +37372,6 @@ export {
36458
37372
  inputRulesPlugin as Z,
36459
37373
  TrackDeleteMarkName as _,
36460
37374
  Plugin as a,
36461
- translator$L as a$,
36462
37375
  v4 as a0,
36463
37376
  TrackFormatMarkName as a1,
36464
37377
  comments_module_events as a2,
@@ -36469,33 +37382,23 @@ export {
36469
37382
  twipsToLines as a7,
36470
37383
  pixelsToTwips as a8,
36471
37384
  helpers as a9,
36472
- Transform as aA,
36473
- findParentNodeClosestToPos as aB,
36474
- isInTable as aC,
36475
- generateDocxRandomId as aD,
36476
- insertNewRelationship as aE,
36477
- inchesToPixels as aF,
36478
- kebabCase as aG,
36479
- getUnderlineCssString as aH,
36480
- commonjsGlobal as aI,
36481
- getDefaultExportFromCjs$2 as aJ,
36482
- getContentTypesFromXml as aK,
36483
- xmljs as aL,
36484
- vClickOutside as aM,
36485
- getActiveFormatting as aN,
36486
- getFileObject as aO,
36487
- translator$H as aP,
36488
- translator$N as aQ,
36489
- translator$P as aR,
36490
- translator$I as aS,
36491
- translator$J as aT,
36492
- translator$Q as aU,
36493
- translator$R as aV,
36494
- translator$17 as aW,
36495
- translator$K as aX,
36496
- translator$_ as aY,
36497
- translator$M as aZ,
36498
- translator$O as a_,
37385
+ SelectionRange as aA,
37386
+ Transform as aB,
37387
+ findParentNodeClosestToPos as aC,
37388
+ isInTable as aD,
37389
+ generateDocxRandomId as aE,
37390
+ insertNewRelationship as aF,
37391
+ inchesToPixels as aG,
37392
+ kebabCase as aH,
37393
+ getUnderlineCssString as aI,
37394
+ commonjsGlobal as aJ,
37395
+ getDefaultExportFromCjs$2 as aK,
37396
+ getContentTypesFromXml as aL,
37397
+ xmljs as aM,
37398
+ vClickOutside as aN,
37399
+ getActiveFormatting as aO,
37400
+ getFileObject as aP,
37401
+ registeredHandlers as aQ,
36499
37402
  posToDOMRect as aa,
36500
37403
  CommandService as ab,
36501
37404
  SuperConverter as ac,
@@ -36512,91 +37415,18 @@ export {
36512
37415
  updateDOMAttributes as an,
36513
37416
  findChildren as ao,
36514
37417
  generateRandomSigned32BitIntStrId as ap,
36515
- calculateResolvedParagraphProperties as aq,
36516
- encodeCSSFromPPr as ar,
36517
- twipsToPixels as as,
36518
- resolveRunProperties as at,
36519
- encodeCSSFromRPr as au,
36520
- generateOrderedListIndex as av,
36521
- docxNumberingHelpers as aw,
36522
- InputRule as ax,
36523
- convertSizeToCSS as ay,
36524
- SelectionRange as az,
37418
+ decodeRPrFromMarks as aq,
37419
+ calculateResolvedParagraphProperties as ar,
37420
+ encodeCSSFromPPr as as,
37421
+ twipsToPixels as at,
37422
+ resolveRunProperties as au,
37423
+ encodeCSSFromRPr as av,
37424
+ generateOrderedListIndex as aw,
37425
+ docxNumberingHelpers as ax,
37426
+ InputRule as ay,
37427
+ convertSizeToCSS as az,
36525
37428
  Slice as b,
36526
- translator$23 as b$,
36527
- translator$Z as b0,
36528
- translator$Y as b1,
36529
- commentRangeEndTranslator as b2,
36530
- commentRangeStartTranslator as b3,
36531
- translator$t as b4,
36532
- translator$u as b5,
36533
- translator$x as b6,
36534
- translator$y as b7,
36535
- translator$1Z as b8,
36536
- translator$w as b9,
36537
- translator$T as bA,
36538
- translator$1Q as bB,
36539
- translator$r as bC,
36540
- translator$1l as bD,
36541
- translator$1U as bE,
36542
- translator$1N as bF,
36543
- translator$1V as bG,
36544
- translator$$ as bH,
36545
- translator$11 as bI,
36546
- translator$1n as bJ,
36547
- translator$1C as bK,
36548
- translator$U as bL,
36549
- translator$V as bM,
36550
- translator$1_ as bN,
36551
- translator$10 as bO,
36552
- translator$22 as bP,
36553
- translator$C as bQ,
36554
- translator$b as bR,
36555
- translator$D as bS,
36556
- translator$E as bT,
36557
- translator$X as bU,
36558
- translator$s as bV,
36559
- translator$1F as bW,
36560
- translator$1W as bX,
36561
- translator$1H as bY,
36562
- translator$1R as bZ,
36563
- translator$F as b_,
36564
- translator$z as ba,
36565
- translator$v as bb,
36566
- translator$1j as bc,
36567
- translator$G as bd,
36568
- translator$f as be,
36569
- translator$g as bf,
36570
- translator$h as bg,
36571
- translator$i as bh,
36572
- translator$j as bi,
36573
- translator$c as bj,
36574
- translator$k as bk,
36575
- translator$l as bl,
36576
- translator$m as bm,
36577
- translator$n as bn,
36578
- translator$A as bo,
36579
- translator$a as bp,
36580
- translator$o as bq,
36581
- translator$B as br,
36582
- translator$d as bs,
36583
- translator$p as bt,
36584
- translator$e as bu,
36585
- translator$9 as bv,
36586
- translator$21 as bw,
36587
- translator$1S as bx,
36588
- translator$1T as by,
36589
- translator$1Y as bz,
36590
37429
  DOMParser$1 as c,
36591
- translator$1p as c0,
36592
- translator$8 as c1,
36593
- translator$7 as c2,
36594
- translator$q as c3,
36595
- translator$1$ as c4,
36596
- translator$20 as c5,
36597
- translator$5 as c6,
36598
- translator$6 as c7,
36599
- translator$1M as c8,
36600
37430
  Mark as d,
36601
37431
  dropPoint as e,
36602
37432
  callOrGet as f,