@harbour-enterprises/superdoc 0.23.0-next.25 → 0.23.0-next.27

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 (34) hide show
  1. package/dist/chunks/{PdfViewer-D5j64OT4.es.js → PdfViewer-C8baB1bn.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-CYMwWMP6.cjs → PdfViewer-DJ7UGyBT.cjs} +1 -1
  3. package/dist/chunks/{index-CIz8zQ3h.cjs → index-BjwQD_um.cjs} +2 -2
  4. package/dist/chunks/{index-ePxDRT3A.es.js → index-DScOqhcx.es.js} +2 -2
  5. package/dist/chunks/{super-editor.es-BhyobyII.es.js → super-editor.es-D0-dqxm2.es.js} +328 -133
  6. package/dist/chunks/{super-editor.es-DZWnc89F.cjs → super-editor.es-DpCRbxmi.cjs} +328 -133
  7. package/dist/style.css +6 -1
  8. package/dist/super-editor/ai-writer.es.js +2 -2
  9. package/dist/super-editor/chunks/{converter-CL8NqbzP.js → converter-B2Y-pDXk.js} +120 -24
  10. package/dist/super-editor/chunks/{docx-zipper-Ab__pf6Y.js → docx-zipper-bhLh8OB6.js} +1 -1
  11. package/dist/super-editor/chunks/{editor-DDXA7n3I.js → editor-GN9xFFdh.js} +2 -2
  12. package/dist/super-editor/chunks/{toolbar-BkZURoPS.js → toolbar-Bq8miKER.js} +14 -12
  13. package/dist/super-editor/converter.es.js +1 -1
  14. package/dist/super-editor/docx-zipper.es.js +2 -2
  15. package/dist/super-editor/editor.es.js +3 -3
  16. package/dist/super-editor/file-zipper.es.js +1 -1
  17. package/dist/super-editor/style.css +6 -1
  18. package/dist/super-editor/super-editor/src/components/slash-menu/constants.d.ts +4 -0
  19. package/dist/super-editor/super-editor/src/components/slash-menu/menuItems.d.ts +4 -36
  20. package/dist/super-editor/super-editor/src/components/slash-menu/tests/testHelpers.d.ts +5 -12
  21. package/dist/super-editor/super-editor/src/core/super-converter/field-references/fld-preprocessors/num-pages-preprocessor.d.ts +1 -3
  22. package/dist/super-editor/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-preprocessor.d.ts +1 -3
  23. package/dist/super-editor/super-editor/src/core/super-converter/field-references/fld-preprocessors/page-ref-preprocessor.d.ts +1 -2
  24. package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/pict/helpers/handle-shape-textbox-import.d.ts +1 -1
  25. package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/pict/helpers/handle-v-rect-import.d.ts +1 -1
  26. package/dist/super-editor/super-editor.es.js +212 -113
  27. package/dist/super-editor/toolbar.es.js +2 -2
  28. package/dist/super-editor.cjs +1 -1
  29. package/dist/super-editor.es.js +1 -1
  30. package/dist/superdoc.cjs +2 -2
  31. package/dist/superdoc.es.js +2 -2
  32. package/dist/superdoc.umd.js +328 -133
  33. package/dist/superdoc.umd.js.map +1 -1
  34. package/package.json +1 -1
@@ -35813,9 +35813,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35813
35813
  const tagValue = tag?.attributes["w:val"];
35814
35814
  const shouldProcessAsJson = tagValue?.startsWith("{") && tagValue?.endsWith("}");
35815
35815
  let attrs = {};
35816
+ const aliasLabel = getSafeString(alias?.attributes?.["w:val"]);
35816
35817
  if (shouldProcessAsJson) {
35817
35818
  const parsedAttrs = parseTagValueJSON(tagValue);
35818
- const attrsFromJSON = {
35819
+ attrs = {
35819
35820
  type: parsedAttrs.fieldTypeShort,
35820
35821
  fieldId: parsedAttrs.fieldId,
35821
35822
  displayLabel: parsedAttrs.displayLabel,
@@ -35829,10 +35830,27 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35829
35830
  textHighlight: parsedAttrs.fieldTextHighlight,
35830
35831
  hash: parsedAttrs.hash
35831
35832
  };
35832
- attrs = attrsFromJSON;
35833
35833
  } else {
35834
- const attrsFromElements = getAttrsFromElements({ sdtPr, tag, alias, sdtId });
35835
- attrs = attrsFromElements;
35834
+ attrs = getAttrsFromElements({ sdtPr, tag, alias, sdtId });
35835
+ }
35836
+ const initialDisplayLabel = getSafeString(attrs.displayLabel);
35837
+ const extractedContent = getTextFromSdtContent(sdtContent);
35838
+ if (!attrs.defaultDisplayLabel) {
35839
+ if (initialDisplayLabel) {
35840
+ attrs.defaultDisplayLabel = initialDisplayLabel;
35841
+ } else if (aliasLabel) {
35842
+ attrs.defaultDisplayLabel = aliasLabel;
35843
+ }
35844
+ }
35845
+ const placeholderLabel = getPlaceholderLabel(attrs, aliasLabel);
35846
+ const placeholderText = ensurePlaceholderFormat(placeholderLabel);
35847
+ const isAnnotationsEnabled = Boolean(params2.editor?.options?.annotations);
35848
+ const contentIsDistinct = shouldUseSdtContent(extractedContent, placeholderText);
35849
+ const shouldUseContent = !isAnnotationsEnabled && contentIsDistinct && (hasMoustache(extractedContent) || !placeholderText);
35850
+ if (contentIsDistinct) {
35851
+ attrs.displayLabel = extractedContent;
35852
+ } else if (!attrs.displayLabel && placeholderLabel) {
35853
+ attrs.displayLabel = placeholderLabel;
35836
35854
  }
35837
35855
  const { attrs: marksAsAttrs, marks } = parseAnnotationMarks(sdtContent);
35838
35856
  const allAttrs = { ...attrs, ...marksAsAttrs };
@@ -35840,13 +35858,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35840
35858
  if (!attrs.fieldId || !attrs.type) {
35841
35859
  return null;
35842
35860
  }
35861
+ const textContent2 = shouldUseContent ? extractedContent : placeholderText;
35843
35862
  let result = {
35844
35863
  type: "text",
35845
- text: `{{${attrs.displayLabel}}}`,
35864
+ text: textContent2,
35846
35865
  attrs: allAttrs,
35847
35866
  marks
35848
35867
  };
35849
- if (params2.editor.options.annotations) {
35868
+ if (isAnnotationsEnabled) {
35850
35869
  result = {
35851
35870
  type: "fieldAnnotation",
35852
35871
  attrs: allAttrs
@@ -35907,6 +35926,84 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35907
35926
  };
35908
35927
  return attrs;
35909
35928
  }
35929
+ function getTextFromSdtContent(sdtContent) {
35930
+ if (!sdtContent?.elements?.length) return "";
35931
+ const chunks = [];
35932
+ collectTextChunks(sdtContent.elements, chunks);
35933
+ if (chunks.length && chunks[chunks.length - 1] === "\n") {
35934
+ chunks.pop();
35935
+ }
35936
+ const text = chunks.join("");
35937
+ return text.replace(/\u00a0/g, " ");
35938
+ }
35939
+ function getPlaceholderLabel(attrs, aliasValue) {
35940
+ const displayLabel = trimSafeString(attrs.displayLabel);
35941
+ if (displayLabel) return displayLabel;
35942
+ const defaultLabel = trimSafeString(attrs.defaultDisplayLabel);
35943
+ if (defaultLabel) return defaultLabel;
35944
+ return trimSafeString(aliasValue);
35945
+ }
35946
+ function shouldUseSdtContent(extractedContent, placeholderText) {
35947
+ const normalizedContent = normalizePlaceholderText(extractedContent);
35948
+ if (!normalizedContent) return false;
35949
+ const normalizedPlaceholder = normalizePlaceholderText(placeholderText);
35950
+ return normalizedContent !== normalizedPlaceholder;
35951
+ }
35952
+ function ensurePlaceholderFormat(label) {
35953
+ const trimmed = trimSafeString(label);
35954
+ if (!trimmed) return "";
35955
+ if (trimmed.startsWith("{{") && trimmed.endsWith("}}")) {
35956
+ return trimmed;
35957
+ }
35958
+ return `{{${trimmed}}}`;
35959
+ }
35960
+ function normalizePlaceholderText(value = "") {
35961
+ const trimmed = trimSafeString(value);
35962
+ if (!trimmed) return "";
35963
+ return stripPlaceholderBraces(trimmed).toLowerCase();
35964
+ }
35965
+ function stripPlaceholderBraces(value = "") {
35966
+ if (value.startsWith("{{") && value.endsWith("}}")) {
35967
+ return trimSafeString(value.slice(2, -2));
35968
+ }
35969
+ return value;
35970
+ }
35971
+ function hasMoustache(value = "") {
35972
+ return /\{\{\s*.+?\s*\}\}/.test(getSafeString(value));
35973
+ }
35974
+ function collectTextChunks(elements, chunks) {
35975
+ if (!elements) return;
35976
+ elements.forEach((element) => {
35977
+ if (!element) return;
35978
+ if (element.type === "text") {
35979
+ chunks.push(element.text || "");
35980
+ return;
35981
+ }
35982
+ if (element.name === "w:tab") {
35983
+ chunks.push(" ");
35984
+ return;
35985
+ }
35986
+ if (element.name === "w:br") {
35987
+ chunks.push("\n");
35988
+ return;
35989
+ }
35990
+ const isParagraph = element.name === "w:p";
35991
+ const initialLength = chunks.length;
35992
+ if (element.elements?.length) {
35993
+ collectTextChunks(element.elements, chunks);
35994
+ }
35995
+ if (isParagraph && chunks.length > initialLength) {
35996
+ chunks.push("\n");
35997
+ }
35998
+ });
35999
+ }
36000
+ function getSafeString(value) {
36001
+ if (typeof value !== "string") return "";
36002
+ return value;
36003
+ }
36004
+ function trimSafeString(value) {
36005
+ return getSafeString(value).replace(/\u00a0/g, " ").trim();
36006
+ }
35910
36007
  function handleDocPartObj(params2) {
35911
36008
  const { nodes } = params2;
35912
36009
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
@@ -38566,7 +38663,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38566
38663
  });
38567
38664
  const XML_NODE_NAME$4 = "w:commentRange";
38568
38665
  const SD_NODE_NAME$4 = "commentRange";
38569
- const decode$4 = (params2, decodedAttrs) => {
38666
+ const decode$4 = (params2) => {
38570
38667
  const { node, comments, commentsExportType, exportedCommentDefs } = params2;
38571
38668
  if (!node) return;
38572
38669
  if (!comments) return;
@@ -38621,7 +38718,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38621
38718
  const commentRangeEndTranslator = NodeTranslator.from(getConfig("End"));
38622
38719
  const XML_NODE_NAME$3 = "sd:pageReference";
38623
38720
  const SD_NODE_NAME$3 = "pageReference";
38624
- const encode$3 = (params2, _2) => {
38721
+ const encode$3 = (params2) => {
38625
38722
  const { nodes = [], nodeListHandler } = params2 || {};
38626
38723
  const node = nodes[0];
38627
38724
  const processedText = nodeListHandler.handler({
@@ -38638,7 +38735,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38638
38735
  };
38639
38736
  return processedNode;
38640
38737
  };
38641
- const decode$3 = (params2, _2) => {
38738
+ const decode$3 = (params2) => {
38642
38739
  const { node } = params2;
38643
38740
  const outputMarks = processOutputMarks(node.attrs?.marksAsAttrs || []);
38644
38741
  const contentNodes = (node.content ?? []).flatMap((n) => exportSchemaToJson({ ...params2, node: n }));
@@ -38721,7 +38818,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38721
38818
  const translator$3 = NodeTranslator.from(config$3);
38722
38819
  const XML_NODE_NAME$2 = "sd:tableOfContents";
38723
38820
  const SD_NODE_NAME$2 = "tableOfContents";
38724
- const encode$2 = (params2, _2) => {
38821
+ const encode$2 = (params2) => {
38725
38822
  const { nodes = [], nodeListHandler } = params2 || {};
38726
38823
  const node = nodes[0];
38727
38824
  const processedContent = nodeListHandler.handler({
@@ -38737,7 +38834,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38737
38834
  };
38738
38835
  return processedNode;
38739
38836
  };
38740
- const decode$2 = (params2, _2) => {
38837
+ const decode$2 = (params2) => {
38741
38838
  const { node } = params2;
38742
38839
  const contentNodes = node.content.map((n) => exportSchemaToJson({ ...params2, node: n }));
38743
38840
  const tocBeginElements = [
@@ -38800,7 +38897,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38800
38897
  return acc;
38801
38898
  }, {});
38802
38899
  }
38803
- function handleVRectImport({ params: params2, pNode, pict }) {
38900
+ function handleVRectImport({ pNode, pict }) {
38804
38901
  const rect = pict.elements?.find((el) => el.name === "v:rect");
38805
38902
  const schemaAttrs = {};
38806
38903
  const rectAttrs = rect.attributes || {};
@@ -39779,7 +39876,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39779
39876
  handler: handleTabNode
39780
39877
  };
39781
39878
  const tableOfContentsHandlerEntity = generateV2HandlerEntity("tableOfContentsHandler", translator$2);
39782
- function preProcessPageInstruction(nodesToCombine, _2, __) {
39879
+ function preProcessPageInstruction(nodesToCombine) {
39783
39880
  const pageNumNode = {
39784
39881
  name: "sd:autoPageNumber",
39785
39882
  type: "element"
@@ -39790,7 +39887,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39790
39887
  });
39791
39888
  return [pageNumNode];
39792
39889
  }
39793
- function preProcessNumPagesInstruction(nodesToCombine, _2, __) {
39890
+ function preProcessNumPagesInstruction(nodesToCombine) {
39794
39891
  const totalPageNumNode = {
39795
39892
  name: "sd:totalPageNumber",
39796
39893
  type: "element"
@@ -39801,7 +39898,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39801
39898
  });
39802
39899
  return [totalPageNumNode];
39803
39900
  }
39804
- function preProcessPageRefInstruction(nodesToCombine, instrText, _2) {
39901
+ function preProcessPageRefInstruction(nodesToCombine, instrText) {
39805
39902
  const pageRefNode = {
39806
39903
  name: "sd:pageReference",
39807
39904
  type: "element",
@@ -39837,15 +39934,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39837
39934
  }
39838
39935
  } else {
39839
39936
  const availableSwitches = {
39840
- "w:anchor": `l "(?<value>[^"]+)"`,
39841
- new_window: `
39842
- `,
39843
- "w:tgtFrame": ` "(?<value>[^"]+)"`,
39844
- "w:tooltip": `o "(?<value>[^"]+)"`
39937
+ "w:anchor": /(?:\\)?l "(?<value>[^"]+)"/,
39938
+ new_window: /(?:\\n|\n)/,
39939
+ "w:tgtFrame": /(?:\\t|\t) "(?<value>[^"]+)"/,
39940
+ "w:tooltip": /(?:\\)?o "(?<value>[^"]+)"/
39845
39941
  };
39846
39942
  const parsedSwitches = {};
39847
- for (const [key2, regex] of Object.entries(availableSwitches)) {
39848
- const match = instruction.match(new RegExp(regex));
39943
+ for (const [key2, pattern] of Object.entries(availableSwitches)) {
39944
+ const match = instruction.match(pattern);
39849
39945
  if (match) {
39850
39946
  parsedSwitches[key2] = match.groups?.value || true;
39851
39947
  }
@@ -40009,7 +40105,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40009
40105
  } else {
40010
40106
  trackStructure(identifierResult);
40011
40107
  }
40012
- } catch (error) {
40108
+ } catch {
40013
40109
  trackStructure();
40014
40110
  }
40015
40111
  }
@@ -40487,7 +40583,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40487
40583
  const evenOdd = elements.find((el) => el.name === "w:evenAndOddHeaders");
40488
40584
  return !!evenOdd;
40489
40585
  };
40490
- function handleShapeTextboxImport({ params: params2, pNode, pict }) {
40586
+ function handleShapeTextboxImport({ params: params2, pict }) {
40491
40587
  const shape = pict.elements?.find((el) => el.name === "v:shape");
40492
40588
  const schemaAttrs = {};
40493
40589
  const schemaTextboxAttrs = {};
@@ -79591,7 +79687,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79591
79687
  const commentIconSvg$1 = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M512 240c0 114.9-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6C73.6 471.1 44.7 480 16 480c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c0 0 0 0 0 0s0 0 0 0s0 0 0 0c0 0 0 0 0 0l.3-.3c.3-.3 .7-.7 1.3-1.4c1.1-1.2 2.8-3.1 4.9-5.7c4.1-5 9.6-12.4 15.2-21.6c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208z"/></svg>';
79592
79688
  const circleIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/></svg>';
79593
79689
  const checkIconSvg$2 = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>';
79594
- const xmarkIconSvg$1 = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>';
79690
+ const xMarkIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>';
79595
79691
  const upRightFromSquareIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M352 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L370.7 96 201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 141.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6l0-128c0-17.7-14.3-32-32-32L352 0zM80 32C35.8 32 0 67.8 0 112L0 432c0 44.2 35.8 80 80 80l320 0c44.2 0 80-35.8 80-80l0-112c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 112c0 8.8-7.2 16-16 16L80 448c-8.8 0-16-7.2-16-16l0-320c0-8.8 7.2-16 16-16l112 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L80 32z"/></svg>';
79596
79692
  const ellipsisVerticalIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z"/></svg>';
79597
79693
  const caretUpIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l256 0c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z"/></svg>';
@@ -79646,7 +79742,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79646
79742
  colorOption: circleIconSvg,
79647
79743
  colorOptionCheck: checkIconSvg$2,
79648
79744
  linkInput: linkIconSvg,
79649
- removeLink: xmarkIconSvg$1,
79745
+ removeLink: xMarkIconSvg,
79650
79746
  openLink: upRightFromSquareIconSvg,
79651
79747
  overflow: ellipsisVerticalIconSvg,
79652
79748
  dropdownCaretUp: caretUpIconSvg,
@@ -93485,7 +93581,9 @@ ${style2}
93485
93581
  copy: copyIconSvg,
93486
93582
  paste: pasteIconSvg,
93487
93583
  addDocumentSection: plusIconSvg,
93488
- removeDocumentSection: trashIconSvg
93584
+ removeDocumentSection: trashIconSvg,
93585
+ trackChangesAccept: checkIconSvg$2,
93586
+ trackChangesReject: xMarkIconSvg
93489
93587
  };
93490
93588
  const TEXTS = {
93491
93589
  addRowBefore: "Insert row above",
@@ -93508,7 +93606,9 @@ ${style2}
93508
93606
  copy: "Copy",
93509
93607
  paste: "Paste",
93510
93608
  removeDocumentSection: "Remove section",
93511
- createDocumentSection: "Create section"
93609
+ createDocumentSection: "Create section",
93610
+ trackChangesAccept: "Accept change",
93611
+ trackChangesReject: "Reject change"
93512
93612
  };
93513
93613
  const tableActionsOptions = [
93514
93614
  {
@@ -93712,34 +93812,37 @@ ${style2}
93712
93812
  const isInSectionNode = structureFromResolvedPos?.isInSectionNode ?? selectionHasNodeOrMark(state2, "documentSection", { requireEnds: true });
93713
93813
  const currentNodeType = node?.type?.name || null;
93714
93814
  const activeMarks = [];
93815
+ let trackedChangeId = null;
93715
93816
  if (event && pos !== null) {
93716
93817
  const $pos = state2.doc.resolve(pos);
93717
- if ($pos.marks && typeof $pos.marks === "function") {
93718
- $pos.marks().forEach((mark) => activeMarks.push(mark.type.name));
93818
+ const processMark = (mark) => {
93819
+ if (!activeMarks.includes(mark.type.name)) {
93820
+ activeMarks.push(mark.type.name);
93821
+ }
93822
+ if (!trackedChangeId && (mark.type.name === "trackInsert" || mark.type.name === "trackDelete" || mark.type.name === "trackFormat")) {
93823
+ trackedChangeId = mark.attrs.id;
93824
+ }
93825
+ };
93826
+ for (let depth = 0; depth <= $pos.depth; depth++) {
93827
+ const nodeAtDepth = $pos.node(depth);
93828
+ if (nodeAtDepth && nodeAtDepth.marks) {
93829
+ nodeAtDepth.marks.forEach(processMark);
93830
+ }
93719
93831
  }
93720
- if (node && node.marks) {
93721
- node.marks.forEach((mark) => activeMarks.push(mark.type.name));
93832
+ if (state2.storedMarks) {
93833
+ state2.storedMarks.forEach(processMark);
93722
93834
  }
93723
93835
  } else {
93724
93836
  state2.storedMarks?.forEach((mark) => activeMarks.push(mark.type.name));
93725
93837
  state2.selection.$head.marks().forEach((mark) => activeMarks.push(mark.type.name));
93726
93838
  }
93727
- const isTrackedChange = activeMarks.includes("trackInsert") || activeMarks.includes("trackDelete");
93728
- let trackedChangeId = null;
93729
- if (isTrackedChange && event && pos !== null) {
93730
- const $pos = state2.doc.resolve(pos);
93731
- const marksAtPos = $pos.marks();
93732
- const trackedMark = marksAtPos.find((mark) => mark.type.name === "trackInsert" || mark.type.name === "trackDelete");
93733
- if (trackedMark) {
93734
- trackedChangeId = trackedMark.attrs.id;
93735
- }
93736
- }
93839
+ const isTrackedChange = activeMarks.includes("trackInsert") || activeMarks.includes("trackDelete") || activeMarks.includes("trackFormat");
93737
93840
  const cursorCoords = pos ? view.coordsAtPos(pos) : null;
93738
93841
  const cursorPosition = cursorCoords ? {
93739
93842
  x: cursorCoords.left,
93740
93843
  y: cursorCoords.top
93741
93844
  } : null;
93742
- return {
93845
+ const context = {
93743
93846
  // Selection info
93744
93847
  selectedText,
93745
93848
  hasSelection: !empty2,
@@ -93765,9 +93868,11 @@ ${style2}
93765
93868
  pos,
93766
93869
  node,
93767
93870
  event,
93871
+ trigger: event ? "click" : "slash",
93768
93872
  // Editor reference for advanced use cases
93769
93873
  editor
93770
93874
  };
93875
+ return context;
93771
93876
  }
93772
93877
  function computeCanUndo(editor, state2) {
93773
93878
  if (typeof editor?.can === "function") {
@@ -93848,160 +93953,209 @@ ${style2}
93848
93953
  switch (moduleName) {
93849
93954
  case "ai":
93850
93955
  return !!editorOptions?.isAiEnabled;
93851
- // Example for future use cases
93852
- // case 'comments':
93853
- // return !!editorOptions?.isCommentsEnabled;
93854
93956
  default:
93855
93957
  return true;
93856
93958
  }
93857
93959
  };
93858
- function applyCustomMenuConfiguration(defaultSections, context) {
93859
- const { editor } = context;
93860
- const slashMenuConfig = editor.options?.slashMenuConfig;
93861
- if (!slashMenuConfig) {
93862
- return defaultSections;
93863
- }
93864
- let sections = [];
93865
- if (slashMenuConfig.includeDefaultItems !== false) {
93866
- sections = [...defaultSections];
93867
- }
93868
- if (slashMenuConfig.customItems && Array.isArray(slashMenuConfig.customItems)) {
93869
- sections = [...sections, ...slashMenuConfig.customItems];
93870
- }
93871
- if (typeof slashMenuConfig.menuProvider === "function") {
93960
+ const shouldShowItem = (item, context) => {
93961
+ if (typeof item.showWhen === "function") {
93872
93962
  try {
93873
- sections = slashMenuConfig.menuProvider(context, sections) || sections;
93963
+ return item.showWhen(context);
93874
93964
  } catch (error) {
93875
- console.warn("[SlashMenu] Error in custom menuProvider:", error);
93965
+ console.warn("[SlashMenu] showWhen error for item", item.id, ":", error);
93966
+ return false;
93876
93967
  }
93877
93968
  }
93878
- return sections;
93879
- }
93880
- function filterCustomItems(sections, context) {
93881
- return sections.map((section) => {
93882
- const filteredItems = section.items.filter((item) => {
93883
- if (typeof item.showWhen === "function") {
93884
- try {
93885
- return item.showWhen(context);
93886
- } catch (error) {
93887
- console.warn(`[SlashMenu] Error in showWhen for item ${item.id}:`, error);
93888
- return false;
93889
- }
93890
- }
93891
- return true;
93892
- });
93893
- return {
93894
- ...section,
93895
- items: filteredItems
93896
- };
93897
- }).filter((section) => section.items.length > 0);
93898
- }
93899
- function getItems(context) {
93900
- const { editor, selectedText, trigger: trigger2, clipboardContent } = context;
93901
- const clipboardHasContent = Boolean(
93902
- clipboardContent?.hasContent || clipboardContent?.html || clipboardContent?.text || typeof clipboardContent?.size === "number" && clipboardContent.size > 0 || clipboardContent && typeof clipboardContent?.content?.size === "number" && clipboardContent.content.size > 0 || clipboardContent?.raw && typeof clipboardContent.raw.size === "number" && clipboardContent.raw.size > 0 || clipboardContent?.raw && typeof clipboardContent.raw?.content?.size === "number" && clipboardContent.raw.content.size > 0
93903
- );
93904
- const isInTable2 = selectionHasNodeOrMark(editor.view.state, "table", { requireEnds: true });
93905
- const isInSectionNode = selectionHasNodeOrMark(editor.view.state, "documentSection", { requireEnds: true });
93906
- const sections = [
93969
+ };
93970
+ function getItems(context, customItems = [], includeDefaultItems = true) {
93971
+ const { selectedText, editor } = context;
93972
+ if (arguments.length === 1 && editor?.options?.slashMenuConfig) {
93973
+ customItems = editor.options.slashMenuConfig.items || editor.options.slashMenuConfig.customItems || [];
93974
+ includeDefaultItems = editor.options.slashMenuConfig.includeDefaultItems !== false;
93975
+ }
93976
+ const enhancedContext = {
93977
+ ...context,
93978
+ isInTable: context.isInTable ?? false,
93979
+ isInSectionNode: context.isInSectionNode ?? false,
93980
+ isTrackedChange: context.isTrackedChange ?? false,
93981
+ clipboardContent: context.clipboardContent ?? { hasContent: false },
93982
+ selectedText: context.selectedText ?? "",
93983
+ hasSelection: context.hasSelection ?? Boolean(context.selectedText)
93984
+ };
93985
+ const defaultSections = [
93907
93986
  {
93908
93987
  id: "ai-content",
93988
+ isDefault: true,
93909
93989
  items: [
93910
93990
  {
93911
93991
  id: "insert-text",
93912
93992
  label: selectedText ? TEXTS.replaceText : TEXTS.insertText,
93913
93993
  icon: ICONS.ai,
93914
93994
  component: AIWriter,
93995
+ isDefault: true,
93915
93996
  action: (editor2) => {
93916
93997
  if (editor2?.commands && typeof editor2.commands?.insertAiMark === "function") {
93917
93998
  editor2.commands.insertAiMark();
93918
93999
  }
93919
94000
  },
93920
- allowedTriggers: [TRIGGERS.slash, TRIGGERS.click],
93921
- requiresModule: "ai"
94001
+ showWhen: (context2) => {
94002
+ const { trigger: trigger2 } = context2;
94003
+ const allowedTriggers = [TRIGGERS.slash, TRIGGERS.click];
94004
+ return allowedTriggers.includes(trigger2) && isModuleEnabled(context2.editor?.options, "ai");
94005
+ }
94006
+ }
94007
+ ]
94008
+ },
94009
+ {
94010
+ id: "track-changes",
94011
+ isDefault: true,
94012
+ items: [
94013
+ {
94014
+ id: "track-changes-accept",
94015
+ icon: ICONS.trackChangesAccept,
94016
+ label: TEXTS.trackChangesAccept,
94017
+ isDefault: true,
94018
+ action: (editor2, context2) => {
94019
+ if (context2?.trackedChangeId) {
94020
+ editor2.commands.acceptTrackedChangeById(context2.trackedChangeId);
94021
+ } else {
94022
+ editor2.commands.acceptTrackedChangeBySelection();
94023
+ }
94024
+ },
94025
+ showWhen: (context2) => {
94026
+ const { trigger: trigger2, isTrackedChange } = context2;
94027
+ return trigger2 === TRIGGERS.click && isTrackedChange;
94028
+ }
94029
+ },
94030
+ {
94031
+ id: "track-changes-reject",
94032
+ label: TEXTS.trackChangesReject,
94033
+ icon: ICONS.trackChangesReject,
94034
+ isDefault: true,
94035
+ action: (editor2, context2) => {
94036
+ if (context2?.trackedChangeId) {
94037
+ editor2.commands.rejectTrackedChangeById(context2.trackedChangeId);
94038
+ } else {
94039
+ editor2.commands.rejectTrackedChangeOnSelection();
94040
+ }
94041
+ },
94042
+ showWhen: (context2) => {
94043
+ const { trigger: trigger2, isTrackedChange } = context2;
94044
+ return trigger2 === TRIGGERS.click && isTrackedChange;
94045
+ }
93922
94046
  }
93923
94047
  ]
93924
94048
  },
93925
94049
  {
93926
94050
  id: "document-sections",
94051
+ isDefault: true,
93927
94052
  items: [
93928
94053
  {
93929
94054
  id: "insert-document-section",
93930
94055
  label: TEXTS.createDocumentSection,
93931
94056
  icon: ICONS.addDocumentSection,
94057
+ isDefault: true,
93932
94058
  action: (editor2) => {
93933
94059
  editor2.commands.createDocumentSection();
93934
94060
  },
93935
- allowedTriggers: [TRIGGERS.click]
94061
+ showWhen: (context2) => {
94062
+ const { trigger: trigger2 } = context2;
94063
+ return trigger2 === TRIGGERS.click;
94064
+ }
93936
94065
  },
93937
94066
  {
93938
94067
  id: "remove-section",
93939
94068
  label: TEXTS.removeDocumentSection,
93940
94069
  icon: ICONS.removeDocumentSection,
94070
+ isDefault: true,
93941
94071
  action: (editor2) => {
93942
94072
  editor2.commands.removeSectionAtSelection();
93943
94073
  },
93944
- allowedTriggers: [TRIGGERS.click],
93945
- requiresSectionParent: true
94074
+ showWhen: (context2) => {
94075
+ const { trigger: trigger2, isInSectionNode } = context2;
94076
+ return trigger2 === TRIGGERS.click && isInSectionNode;
94077
+ }
93946
94078
  }
93947
94079
  ]
93948
94080
  },
93949
94081
  {
93950
94082
  id: "general",
94083
+ isDefault: true,
93951
94084
  items: [
93952
94085
  {
93953
94086
  id: "insert-link",
93954
94087
  label: TEXTS.insertLink,
93955
94088
  icon: ICONS.link,
93956
94089
  component: LinkInput,
93957
- allowedTriggers: [TRIGGERS.click]
94090
+ isDefault: true,
94091
+ showWhen: (context2) => {
94092
+ const { trigger: trigger2 } = context2;
94093
+ return trigger2 === TRIGGERS.click;
94094
+ }
93958
94095
  },
93959
94096
  {
93960
94097
  id: "insert-table",
93961
94098
  label: TEXTS.insertTable,
93962
94099
  icon: ICONS.table,
93963
94100
  component: TableGrid,
93964
- allowedTriggers: [TRIGGERS.slash, TRIGGERS.click]
94101
+ isDefault: true,
94102
+ showWhen: (context2) => {
94103
+ const { trigger: trigger2, isInTable: isInTable2 } = context2;
94104
+ const allowedTriggers = [TRIGGERS.slash, TRIGGERS.click];
94105
+ return allowedTriggers.includes(trigger2) && !isInTable2;
94106
+ }
93965
94107
  },
93966
94108
  {
93967
94109
  id: "edit-table",
93968
94110
  label: TEXTS.editTable,
93969
94111
  icon: ICONS.table,
93970
94112
  component: TableActions,
93971
- allowedTriggers: [TRIGGERS.slash, TRIGGERS.click],
93972
- requiresTableParent: true
94113
+ isDefault: true,
94114
+ showWhen: (context2) => {
94115
+ const { trigger: trigger2, isInTable: isInTable2 } = context2;
94116
+ const allowedTriggers = [TRIGGERS.slash, TRIGGERS.click];
94117
+ return allowedTriggers.includes(trigger2) && isInTable2;
94118
+ }
93973
94119
  }
93974
94120
  ]
93975
94121
  },
93976
94122
  {
93977
94123
  id: "clipboard",
94124
+ isDefault: true,
93978
94125
  items: [
93979
94126
  {
93980
94127
  id: "cut",
93981
94128
  label: TEXTS.cut,
93982
94129
  icon: ICONS.cut,
94130
+ isDefault: true,
93983
94131
  action: (editor2) => {
93984
94132
  editor2.view.focus();
93985
94133
  document.execCommand("cut");
93986
94134
  },
93987
- allowedTriggers: [TRIGGERS.click],
93988
- requiresSelection: true
94135
+ showWhen: (context2) => {
94136
+ const { trigger: trigger2, selectedText: selectedText2 } = context2;
94137
+ return trigger2 === TRIGGERS.click && selectedText2;
94138
+ }
93989
94139
  },
93990
94140
  {
93991
94141
  id: "copy",
93992
94142
  label: TEXTS.copy,
93993
94143
  icon: ICONS.copy,
94144
+ isDefault: true,
93994
94145
  action: (editor2) => {
93995
94146
  editor2.view.focus();
93996
94147
  document.execCommand("copy");
93997
94148
  },
93998
- allowedTriggers: [TRIGGERS.click],
93999
- requiresSelection: true
94149
+ showWhen: (context2) => {
94150
+ const { trigger: trigger2, selectedText: selectedText2 } = context2;
94151
+ return trigger2 === TRIGGERS.click && selectedText2;
94152
+ }
94000
94153
  },
94001
94154
  {
94002
94155
  id: "paste",
94003
94156
  label: TEXTS.paste,
94004
94157
  icon: ICONS.paste,
94158
+ isDefault: true,
94005
94159
  action: async (editor2) => {
94006
94160
  try {
94007
94161
  const clipboardItems = await navigator.clipboard.read();
@@ -94015,7 +94169,7 @@ ${style2}
94015
94169
  text = await (await item.getType("text/plain")).text();
94016
94170
  }
94017
94171
  }
94018
- const handled = handleClipboardPaste({ editor: editor2, view: editor2.view }, html, text);
94172
+ const handled = handleClipboardPaste({ editor: editor2, view: editor2.view }, html);
94019
94173
  if (!handled) {
94020
94174
  const dataTransfer = new DataTransfer();
94021
94175
  if (html) dataTransfer.setData("text/html", html);
@@ -94031,30 +94185,52 @@ ${style2}
94031
94185
  console.warn("Failed to paste:", error);
94032
94186
  }
94033
94187
  },
94034
- allowedTriggers: [TRIGGERS.click, TRIGGERS.slash],
94035
- requiresClipboard: true
94188
+ showWhen: (context2) => {
94189
+ const { trigger: trigger2, clipboardContent } = context2;
94190
+ const allowedTriggers = [TRIGGERS.click, TRIGGERS.slash];
94191
+ const hasContent = clipboardContent?.hasContent || clipboardContent?.size > 0 || clipboardContent?.content?.size > 0;
94192
+ return allowedTriggers.includes(trigger2) && hasContent;
94193
+ }
94036
94194
  }
94037
94195
  ]
94038
94196
  }
94039
94197
  ];
94040
- let allSections = applyCustomMenuConfiguration(sections, context);
94041
- const filteredSections = allSections.map((section) => {
94042
- const filteredItems = section.items.filter((item) => {
94043
- if (item.requiresModule && !isModuleEnabled(editor?.options, item.requiresModule)) return false;
94044
- if (item.requiresSelection && !selectedText) return false;
94045
- if (!item.allowedTriggers.includes(trigger2)) return false;
94046
- if (item.requiresClipboard && !clipboardHasContent) return false;
94047
- if (item.requiresTableParent && !isInTable2 || item.id === "insert-table" && isInTable2) return false;
94048
- if (item.requiresSectionParent && !isInSectionNode) return false;
94049
- return true;
94198
+ let allSections = [];
94199
+ if (includeDefaultItems) {
94200
+ allSections = [...defaultSections];
94201
+ }
94202
+ if (customItems.length > 0) {
94203
+ customItems.forEach((customSection) => {
94204
+ const existingSectionIndex = allSections.findIndex((section) => section.id === customSection.id);
94205
+ if (existingSectionIndex !== -1) {
94206
+ allSections[existingSectionIndex].items = [
94207
+ ...allSections[existingSectionIndex].items,
94208
+ ...customSection.items.map((item) => ({ ...item, isDefault: false }))
94209
+ ];
94210
+ } else {
94211
+ allSections.push({
94212
+ ...customSection,
94213
+ isDefault: false,
94214
+ items: customSection.items.map((item) => ({ ...item, isDefault: false }))
94215
+ });
94216
+ }
94050
94217
  });
94218
+ }
94219
+ if (editor?.options?.slashMenuConfig?.menuProvider) {
94220
+ try {
94221
+ allSections = editor.options.slashMenuConfig.menuProvider(enhancedContext, allSections) || allSections;
94222
+ } catch (error) {
94223
+ console.warn("[SlashMenu] menuProvider error:", error);
94224
+ }
94225
+ }
94226
+ const filteredSections = allSections.map((section) => {
94227
+ const filteredItems = section.items.filter((item) => shouldShowItem(item, enhancedContext));
94051
94228
  return {
94052
94229
  ...section,
94053
94230
  items: filteredItems
94054
94231
  };
94055
94232
  }).filter((section) => section.items.length > 0);
94056
- const finalSections = filterCustomItems(filteredSections, context);
94057
- return finalSections;
94233
+ return filteredSections;
94058
94234
  }
94059
94235
  const _hoisted_1$3$1 = { class: "slash-menu-items" };
94060
94236
  const _hoisted_2$1$1 = {
@@ -94137,13 +94313,28 @@ ${style2}
94137
94313
  });
94138
94314
  const customItemRefs = /* @__PURE__ */ new Map();
94139
94315
  const setCustomItemRef = (el, item) => {
94140
- if (el && item.render) {
94316
+ if (el) {
94141
94317
  customItemRefs.set(item.id, { element: el, item });
94142
94318
  nextTick(() => {
94143
94319
  renderCustomItem(item.id);
94144
94320
  });
94145
94321
  }
94146
94322
  };
94323
+ const defaultRender = (context) => {
94324
+ const item = context.item || context.currentItem;
94325
+ const container = document.createElement("div");
94326
+ container.className = "slash-menu-default-content";
94327
+ if (item.icon) {
94328
+ const iconSpan = document.createElement("span");
94329
+ iconSpan.className = "slash-menu-item-icon";
94330
+ iconSpan.innerHTML = item.icon;
94331
+ container.appendChild(iconSpan);
94332
+ }
94333
+ const labelSpan = document.createElement("span");
94334
+ labelSpan.textContent = item.label;
94335
+ container.appendChild(labelSpan);
94336
+ return container;
94337
+ };
94147
94338
  const renderCustomItem = async (itemId) => {
94148
94339
  const refData = customItemRefs.get(itemId);
94149
94340
  if (!refData || refData.element.hasCustomContent) return;
@@ -94152,8 +94343,9 @@ ${style2}
94152
94343
  if (!currentContext.value) {
94153
94344
  currentContext.value = await getEditorContext(props.editor);
94154
94345
  }
94155
- const context = currentContext.value;
94156
- const customElement = item.render(context);
94346
+ const contextWithItem = { ...currentContext.value, currentItem: item };
94347
+ const renderFunction = item.render || defaultRender;
94348
+ const customElement = renderFunction(contextWithItem);
94157
94349
  if (customElement instanceof HTMLElement) {
94158
94350
  element.innerHTML = "";
94159
94351
  element.appendChild(customElement);
@@ -94161,7 +94353,9 @@ ${style2}
94161
94353
  }
94162
94354
  } catch (error) {
94163
94355
  console.warn(`[SlashMenu] Error rendering custom item ${itemId}:`, error);
94164
- element.innerHTML = `<span>${item.label || "Custom Item"}</span>`;
94356
+ const fallbackElement = defaultRender({ ...currentContext.value || {}, currentItem: item });
94357
+ element.innerHTML = "";
94358
+ element.appendChild(fallbackElement);
94165
94359
  element.hasCustomContent = true;
94166
94360
  }
94167
94361
  };
@@ -94356,19 +94550,20 @@ ${style2}
94356
94550
  class: normalizeClass(["slash-menu-item", { "is-selected": item.id === selectedId.value }]),
94357
94551
  onClick: ($event) => executeCommand(item)
94358
94552
  }, [
94359
- item.render ? (openBlock(), createElementBlock("div", {
94360
- key: 0,
94553
+ createBaseVNode("div", {
94361
94554
  ref_for: true,
94362
94555
  ref: (el) => setCustomItemRef(el, item),
94363
94556
  class: "slash-menu-custom-item"
94364
- }, null, 512)) : (openBlock(), createElementBlock(Fragment$1, { key: 1 }, [
94365
- item.icon ? (openBlock(), createElementBlock("span", {
94366
- key: 0,
94367
- class: "slash-menu-item-icon",
94368
- innerHTML: item.icon
94369
- }, null, 8, _hoisted_4$5)) : createCommentVNode("", true),
94370
- createBaseVNode("span", null, toDisplayString(item.label), 1)
94371
- ], 64))
94557
+ }, [
94558
+ !item.render ? (openBlock(), createElementBlock(Fragment$1, { key: 0 }, [
94559
+ item.icon ? (openBlock(), createElementBlock("span", {
94560
+ key: 0,
94561
+ class: "slash-menu-item-icon",
94562
+ innerHTML: item.icon
94563
+ }, null, 8, _hoisted_4$5)) : createCommentVNode("", true),
94564
+ createBaseVNode("span", null, toDisplayString(item.label), 1)
94565
+ ], 64)) : createCommentVNode("", true)
94566
+ ], 512)
94372
94567
  ], 10, _hoisted_3$1$1);
94373
94568
  }), 128))
94374
94569
  ], 64);