@harbour-enterprises/superdoc 0.23.0-next.26 → 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.
@@ -79687,7 +79687,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79687
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>';
79688
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>';
79689
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>';
79690
- 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>';
79691
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>';
79692
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>';
79693
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>';
@@ -79742,7 +79742,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79742
79742
  colorOption: circleIconSvg,
79743
79743
  colorOptionCheck: checkIconSvg$2,
79744
79744
  linkInput: linkIconSvg,
79745
- removeLink: xmarkIconSvg$1,
79745
+ removeLink: xMarkIconSvg,
79746
79746
  openLink: upRightFromSquareIconSvg,
79747
79747
  overflow: ellipsisVerticalIconSvg,
79748
79748
  dropdownCaretUp: caretUpIconSvg,
@@ -93581,7 +93581,9 @@ ${style2}
93581
93581
  copy: copyIconSvg,
93582
93582
  paste: pasteIconSvg,
93583
93583
  addDocumentSection: plusIconSvg,
93584
- removeDocumentSection: trashIconSvg
93584
+ removeDocumentSection: trashIconSvg,
93585
+ trackChangesAccept: checkIconSvg$2,
93586
+ trackChangesReject: xMarkIconSvg
93585
93587
  };
93586
93588
  const TEXTS = {
93587
93589
  addRowBefore: "Insert row above",
@@ -93604,7 +93606,9 @@ ${style2}
93604
93606
  copy: "Copy",
93605
93607
  paste: "Paste",
93606
93608
  removeDocumentSection: "Remove section",
93607
- createDocumentSection: "Create section"
93609
+ createDocumentSection: "Create section",
93610
+ trackChangesAccept: "Accept change",
93611
+ trackChangesReject: "Reject change"
93608
93612
  };
93609
93613
  const tableActionsOptions = [
93610
93614
  {
@@ -93808,34 +93812,37 @@ ${style2}
93808
93812
  const isInSectionNode = structureFromResolvedPos?.isInSectionNode ?? selectionHasNodeOrMark(state2, "documentSection", { requireEnds: true });
93809
93813
  const currentNodeType = node?.type?.name || null;
93810
93814
  const activeMarks = [];
93815
+ let trackedChangeId = null;
93811
93816
  if (event && pos !== null) {
93812
93817
  const $pos = state2.doc.resolve(pos);
93813
- if ($pos.marks && typeof $pos.marks === "function") {
93814
- $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
+ }
93815
93831
  }
93816
- if (node && node.marks) {
93817
- node.marks.forEach((mark) => activeMarks.push(mark.type.name));
93832
+ if (state2.storedMarks) {
93833
+ state2.storedMarks.forEach(processMark);
93818
93834
  }
93819
93835
  } else {
93820
93836
  state2.storedMarks?.forEach((mark) => activeMarks.push(mark.type.name));
93821
93837
  state2.selection.$head.marks().forEach((mark) => activeMarks.push(mark.type.name));
93822
93838
  }
93823
- const isTrackedChange = activeMarks.includes("trackInsert") || activeMarks.includes("trackDelete");
93824
- let trackedChangeId = null;
93825
- if (isTrackedChange && event && pos !== null) {
93826
- const $pos = state2.doc.resolve(pos);
93827
- const marksAtPos = $pos.marks();
93828
- const trackedMark = marksAtPos.find((mark) => mark.type.name === "trackInsert" || mark.type.name === "trackDelete");
93829
- if (trackedMark) {
93830
- trackedChangeId = trackedMark.attrs.id;
93831
- }
93832
- }
93839
+ const isTrackedChange = activeMarks.includes("trackInsert") || activeMarks.includes("trackDelete") || activeMarks.includes("trackFormat");
93833
93840
  const cursorCoords = pos ? view.coordsAtPos(pos) : null;
93834
93841
  const cursorPosition = cursorCoords ? {
93835
93842
  x: cursorCoords.left,
93836
93843
  y: cursorCoords.top
93837
93844
  } : null;
93838
- return {
93845
+ const context = {
93839
93846
  // Selection info
93840
93847
  selectedText,
93841
93848
  hasSelection: !empty2,
@@ -93861,9 +93868,11 @@ ${style2}
93861
93868
  pos,
93862
93869
  node,
93863
93870
  event,
93871
+ trigger: event ? "click" : "slash",
93864
93872
  // Editor reference for advanced use cases
93865
93873
  editor
93866
93874
  };
93875
+ return context;
93867
93876
  }
93868
93877
  function computeCanUndo(editor, state2) {
93869
93878
  if (typeof editor?.can === "function") {
@@ -93944,160 +93953,209 @@ ${style2}
93944
93953
  switch (moduleName) {
93945
93954
  case "ai":
93946
93955
  return !!editorOptions?.isAiEnabled;
93947
- // Example for future use cases
93948
- // case 'comments':
93949
- // return !!editorOptions?.isCommentsEnabled;
93950
93956
  default:
93951
93957
  return true;
93952
93958
  }
93953
93959
  };
93954
- function applyCustomMenuConfiguration(defaultSections, context) {
93955
- const { editor } = context;
93956
- const slashMenuConfig = editor.options?.slashMenuConfig;
93957
- if (!slashMenuConfig) {
93958
- return defaultSections;
93959
- }
93960
- let sections = [];
93961
- if (slashMenuConfig.includeDefaultItems !== false) {
93962
- sections = [...defaultSections];
93963
- }
93964
- if (slashMenuConfig.customItems && Array.isArray(slashMenuConfig.customItems)) {
93965
- sections = [...sections, ...slashMenuConfig.customItems];
93966
- }
93967
- if (typeof slashMenuConfig.menuProvider === "function") {
93960
+ const shouldShowItem = (item, context) => {
93961
+ if (typeof item.showWhen === "function") {
93968
93962
  try {
93969
- sections = slashMenuConfig.menuProvider(context, sections) || sections;
93963
+ return item.showWhen(context);
93970
93964
  } catch (error) {
93971
- console.warn("[SlashMenu] Error in custom menuProvider:", error);
93965
+ console.warn("[SlashMenu] showWhen error for item", item.id, ":", error);
93966
+ return false;
93972
93967
  }
93973
93968
  }
93974
- return sections;
93975
- }
93976
- function filterCustomItems(sections, context) {
93977
- return sections.map((section) => {
93978
- const filteredItems = section.items.filter((item) => {
93979
- if (typeof item.showWhen === "function") {
93980
- try {
93981
- return item.showWhen(context);
93982
- } catch (error) {
93983
- console.warn(`[SlashMenu] Error in showWhen for item ${item.id}:`, error);
93984
- return false;
93985
- }
93986
- }
93987
- return true;
93988
- });
93989
- return {
93990
- ...section,
93991
- items: filteredItems
93992
- };
93993
- }).filter((section) => section.items.length > 0);
93994
- }
93995
- function getItems(context) {
93996
- const { editor, selectedText, trigger: trigger2, clipboardContent } = context;
93997
- const clipboardHasContent = Boolean(
93998
- 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
93999
- );
94000
- const isInTable2 = selectionHasNodeOrMark(editor.view.state, "table", { requireEnds: true });
94001
- const isInSectionNode = selectionHasNodeOrMark(editor.view.state, "documentSection", { requireEnds: true });
94002
- 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 = [
94003
93986
  {
94004
93987
  id: "ai-content",
93988
+ isDefault: true,
94005
93989
  items: [
94006
93990
  {
94007
93991
  id: "insert-text",
94008
93992
  label: selectedText ? TEXTS.replaceText : TEXTS.insertText,
94009
93993
  icon: ICONS.ai,
94010
93994
  component: AIWriter,
93995
+ isDefault: true,
94011
93996
  action: (editor2) => {
94012
93997
  if (editor2?.commands && typeof editor2.commands?.insertAiMark === "function") {
94013
93998
  editor2.commands.insertAiMark();
94014
93999
  }
94015
94000
  },
94016
- allowedTriggers: [TRIGGERS.slash, TRIGGERS.click],
94017
- 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
+ }
94018
94046
  }
94019
94047
  ]
94020
94048
  },
94021
94049
  {
94022
94050
  id: "document-sections",
94051
+ isDefault: true,
94023
94052
  items: [
94024
94053
  {
94025
94054
  id: "insert-document-section",
94026
94055
  label: TEXTS.createDocumentSection,
94027
94056
  icon: ICONS.addDocumentSection,
94057
+ isDefault: true,
94028
94058
  action: (editor2) => {
94029
94059
  editor2.commands.createDocumentSection();
94030
94060
  },
94031
- allowedTriggers: [TRIGGERS.click]
94061
+ showWhen: (context2) => {
94062
+ const { trigger: trigger2 } = context2;
94063
+ return trigger2 === TRIGGERS.click;
94064
+ }
94032
94065
  },
94033
94066
  {
94034
94067
  id: "remove-section",
94035
94068
  label: TEXTS.removeDocumentSection,
94036
94069
  icon: ICONS.removeDocumentSection,
94070
+ isDefault: true,
94037
94071
  action: (editor2) => {
94038
94072
  editor2.commands.removeSectionAtSelection();
94039
94073
  },
94040
- allowedTriggers: [TRIGGERS.click],
94041
- requiresSectionParent: true
94074
+ showWhen: (context2) => {
94075
+ const { trigger: trigger2, isInSectionNode } = context2;
94076
+ return trigger2 === TRIGGERS.click && isInSectionNode;
94077
+ }
94042
94078
  }
94043
94079
  ]
94044
94080
  },
94045
94081
  {
94046
94082
  id: "general",
94083
+ isDefault: true,
94047
94084
  items: [
94048
94085
  {
94049
94086
  id: "insert-link",
94050
94087
  label: TEXTS.insertLink,
94051
94088
  icon: ICONS.link,
94052
94089
  component: LinkInput,
94053
- allowedTriggers: [TRIGGERS.click]
94090
+ isDefault: true,
94091
+ showWhen: (context2) => {
94092
+ const { trigger: trigger2 } = context2;
94093
+ return trigger2 === TRIGGERS.click;
94094
+ }
94054
94095
  },
94055
94096
  {
94056
94097
  id: "insert-table",
94057
94098
  label: TEXTS.insertTable,
94058
94099
  icon: ICONS.table,
94059
94100
  component: TableGrid,
94060
- 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
+ }
94061
94107
  },
94062
94108
  {
94063
94109
  id: "edit-table",
94064
94110
  label: TEXTS.editTable,
94065
94111
  icon: ICONS.table,
94066
94112
  component: TableActions,
94067
- allowedTriggers: [TRIGGERS.slash, TRIGGERS.click],
94068
- 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
+ }
94069
94119
  }
94070
94120
  ]
94071
94121
  },
94072
94122
  {
94073
94123
  id: "clipboard",
94124
+ isDefault: true,
94074
94125
  items: [
94075
94126
  {
94076
94127
  id: "cut",
94077
94128
  label: TEXTS.cut,
94078
94129
  icon: ICONS.cut,
94130
+ isDefault: true,
94079
94131
  action: (editor2) => {
94080
94132
  editor2.view.focus();
94081
94133
  document.execCommand("cut");
94082
94134
  },
94083
- allowedTriggers: [TRIGGERS.click],
94084
- requiresSelection: true
94135
+ showWhen: (context2) => {
94136
+ const { trigger: trigger2, selectedText: selectedText2 } = context2;
94137
+ return trigger2 === TRIGGERS.click && selectedText2;
94138
+ }
94085
94139
  },
94086
94140
  {
94087
94141
  id: "copy",
94088
94142
  label: TEXTS.copy,
94089
94143
  icon: ICONS.copy,
94144
+ isDefault: true,
94090
94145
  action: (editor2) => {
94091
94146
  editor2.view.focus();
94092
94147
  document.execCommand("copy");
94093
94148
  },
94094
- allowedTriggers: [TRIGGERS.click],
94095
- requiresSelection: true
94149
+ showWhen: (context2) => {
94150
+ const { trigger: trigger2, selectedText: selectedText2 } = context2;
94151
+ return trigger2 === TRIGGERS.click && selectedText2;
94152
+ }
94096
94153
  },
94097
94154
  {
94098
94155
  id: "paste",
94099
94156
  label: TEXTS.paste,
94100
94157
  icon: ICONS.paste,
94158
+ isDefault: true,
94101
94159
  action: async (editor2) => {
94102
94160
  try {
94103
94161
  const clipboardItems = await navigator.clipboard.read();
@@ -94111,7 +94169,7 @@ ${style2}
94111
94169
  text = await (await item.getType("text/plain")).text();
94112
94170
  }
94113
94171
  }
94114
- const handled = handleClipboardPaste({ editor: editor2, view: editor2.view }, html, text);
94172
+ const handled = handleClipboardPaste({ editor: editor2, view: editor2.view }, html);
94115
94173
  if (!handled) {
94116
94174
  const dataTransfer = new DataTransfer();
94117
94175
  if (html) dataTransfer.setData("text/html", html);
@@ -94127,30 +94185,52 @@ ${style2}
94127
94185
  console.warn("Failed to paste:", error);
94128
94186
  }
94129
94187
  },
94130
- allowedTriggers: [TRIGGERS.click, TRIGGERS.slash],
94131
- 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
+ }
94132
94194
  }
94133
94195
  ]
94134
94196
  }
94135
94197
  ];
94136
- let allSections = applyCustomMenuConfiguration(sections, context);
94137
- const filteredSections = allSections.map((section) => {
94138
- const filteredItems = section.items.filter((item) => {
94139
- if (item.requiresModule && !isModuleEnabled(editor?.options, item.requiresModule)) return false;
94140
- if (item.requiresSelection && !selectedText) return false;
94141
- if (!item.allowedTriggers.includes(trigger2)) return false;
94142
- if (item.requiresClipboard && !clipboardHasContent) return false;
94143
- if (item.requiresTableParent && !isInTable2 || item.id === "insert-table" && isInTable2) return false;
94144
- if (item.requiresSectionParent && !isInSectionNode) return false;
94145
- 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
+ }
94146
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));
94147
94228
  return {
94148
94229
  ...section,
94149
94230
  items: filteredItems
94150
94231
  };
94151
94232
  }).filter((section) => section.items.length > 0);
94152
- const finalSections = filterCustomItems(filteredSections, context);
94153
- return finalSections;
94233
+ return filteredSections;
94154
94234
  }
94155
94235
  const _hoisted_1$3$1 = { class: "slash-menu-items" };
94156
94236
  const _hoisted_2$1$1 = {
@@ -94233,13 +94313,28 @@ ${style2}
94233
94313
  });
94234
94314
  const customItemRefs = /* @__PURE__ */ new Map();
94235
94315
  const setCustomItemRef = (el, item) => {
94236
- if (el && item.render) {
94316
+ if (el) {
94237
94317
  customItemRefs.set(item.id, { element: el, item });
94238
94318
  nextTick(() => {
94239
94319
  renderCustomItem(item.id);
94240
94320
  });
94241
94321
  }
94242
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
+ };
94243
94338
  const renderCustomItem = async (itemId) => {
94244
94339
  const refData = customItemRefs.get(itemId);
94245
94340
  if (!refData || refData.element.hasCustomContent) return;
@@ -94248,8 +94343,9 @@ ${style2}
94248
94343
  if (!currentContext.value) {
94249
94344
  currentContext.value = await getEditorContext(props.editor);
94250
94345
  }
94251
- const context = currentContext.value;
94252
- const customElement = item.render(context);
94346
+ const contextWithItem = { ...currentContext.value, currentItem: item };
94347
+ const renderFunction = item.render || defaultRender;
94348
+ const customElement = renderFunction(contextWithItem);
94253
94349
  if (customElement instanceof HTMLElement) {
94254
94350
  element.innerHTML = "";
94255
94351
  element.appendChild(customElement);
@@ -94257,7 +94353,9 @@ ${style2}
94257
94353
  }
94258
94354
  } catch (error) {
94259
94355
  console.warn(`[SlashMenu] Error rendering custom item ${itemId}:`, error);
94260
- element.innerHTML = `<span>${item.label || "Custom Item"}</span>`;
94356
+ const fallbackElement = defaultRender({ ...currentContext.value || {}, currentItem: item });
94357
+ element.innerHTML = "";
94358
+ element.appendChild(fallbackElement);
94261
94359
  element.hasCustomContent = true;
94262
94360
  }
94263
94361
  };
@@ -94452,19 +94550,20 @@ ${style2}
94452
94550
  class: normalizeClass(["slash-menu-item", { "is-selected": item.id === selectedId.value }]),
94453
94551
  onClick: ($event) => executeCommand(item)
94454
94552
  }, [
94455
- item.render ? (openBlock(), createElementBlock("div", {
94456
- key: 0,
94553
+ createBaseVNode("div", {
94457
94554
  ref_for: true,
94458
94555
  ref: (el) => setCustomItemRef(el, item),
94459
94556
  class: "slash-menu-custom-item"
94460
- }, null, 512)) : (openBlock(), createElementBlock(Fragment$1, { key: 1 }, [
94461
- item.icon ? (openBlock(), createElementBlock("span", {
94462
- key: 0,
94463
- class: "slash-menu-item-icon",
94464
- innerHTML: item.icon
94465
- }, null, 8, _hoisted_4$5)) : createCommentVNode("", true),
94466
- createBaseVNode("span", null, toDisplayString(item.label), 1)
94467
- ], 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)
94468
94567
  ], 10, _hoisted_3$1$1);
94469
94568
  }), 128))
94470
94569
  ], 64);