@harbour-enterprises/superdoc 0.20.0-next.13 → 0.20.0-next.15

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 (108) hide show
  1. package/README.md +4 -4
  2. package/dist/chunks/{PdfViewer-Beoed5G0.es.js → PdfViewer-D3gJ5ozH.es.js} +1 -1
  3. package/dist/chunks/{PdfViewer-Dh2tr2ag.cjs → PdfViewer-DuEWa8ox.cjs} +1 -1
  4. package/dist/chunks/{index-BFe2eMYK.cjs → index-D2h9q27o.cjs} +32 -9
  5. package/dist/chunks/{index-OC4NDn1G.es.js → index-DiSIyVKk.es.js} +32 -9
  6. package/dist/chunks/{super-editor.es-cgub83Px.es.js → super-editor.es-4Ig7dBJr.es.js} +2901 -902
  7. package/dist/chunks/{super-editor.es-4ltXjey_.cjs → super-editor.es-lzaBZOn2.cjs} +2901 -902
  8. package/dist/core/SuperDoc.d.ts.map +1 -1
  9. package/dist/stores/comments-store.d.ts.map +1 -1
  10. package/dist/super-editor/ai-writer.es.js +2 -2
  11. package/dist/super-editor/chunks/{converter-CTJIyTAA.js → converter-BJVy6JMW.js} +1996 -657
  12. package/dist/super-editor/chunks/{docx-zipper-BwicJKh2.js → docx-zipper-DWDJGX0b.js} +1 -1
  13. package/dist/super-editor/chunks/{editor-B97u3IuY.js → editor-BUCOmU2Y.js} +1027 -411
  14. package/dist/super-editor/chunks/{toolbar-BcdsHEOP.js → toolbar-CiBIcgiI.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/src/components/toolbar/format-negation.d.ts +5 -0
  20. package/dist/super-editor/src/core/commands/index.d.ts +1 -0
  21. package/dist/super-editor/src/core/commands/toggleMarkCascade.d.ts +42 -0
  22. package/dist/super-editor/src/core/commands/types/index.d.ts +29 -1
  23. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +5 -0
  24. package/dist/super-editor/src/core/super-converter/exporter.d.ts +8 -0
  25. package/dist/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  26. package/dist/super-editor/src/core/super-converter/v2/importer/markImporter.d.ts +12 -0
  27. package/dist/super-editor/src/core/super-converter/v2/importer/runNodeImporter.d.ts +6 -6
  28. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/east-asian-regex.d.ts +1 -0
  29. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/index.d.ts +1 -0
  30. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +2 -12
  31. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/index.d.ts +3 -0
  32. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/w-val.d.ts +4 -0
  33. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/b-translator.d.ts +7 -0
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/index.d.ts +1 -0
  35. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/index.d.ts +2 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-color.d.ts +4 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-shade.d.ts +4 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-tint.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-val.d.ts +4 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/color-translator.d.ts +7 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/index.d.ts +2 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/w-val.d.ts +4 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/highlight-translator.d.ts +4 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/index.d.ts +2 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/w-val.d.ts +4 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/i-translator.d.ts +7 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/index.d.ts +2 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-del.d.ts +4 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r-pr.d.ts +4 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r.d.ts +4 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/helpers.d.ts +40 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/index.d.ts +3 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/split-run-properties.d.ts +9 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/track-change-helpers.d.ts +5 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/index.d.ts +1 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/r-translator.d.ts +4 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/index.d.ts +2 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-ascii.d.ts +4 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-cs.d.ts +4 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-east-asia.d.ts +4 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-hansi.d.ts +4 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-val.d.ts +4 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/index.d.ts +1 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/rFonts-translator.d.ts +5 -0
  65. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/index.d.ts +2 -0
  66. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/w-val.d.ts +4 -0
  67. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/index.d.ts +1 -0
  68. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/rstyle-translator.d.ts +7 -0
  69. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/index.d.ts +1 -0
  70. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/rpr-translator.d.ts +5 -0
  71. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/run-property-translators.d.ts +11 -0
  72. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/index.d.ts +2 -0
  73. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/w-val.d.ts +4 -0
  74. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/strike-translator.d.ts +7 -0
  75. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/index.d.ts +2 -0
  76. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/w-val.d.ts +4 -0
  77. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/sz-translator.d.ts +4 -0
  78. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/index.d.ts +2 -0
  79. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/w-val.d.ts +4 -0
  80. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/szcs-translator.d.ts +4 -0
  81. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/index.d.ts +2 -0
  82. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-color.d.ts +4 -0
  83. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-color.d.ts +4 -0
  84. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-shade.d.ts +4 -0
  85. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-tint.d.ts +4 -0
  86. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-val.d.ts +4 -0
  87. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/u-translator.d.ts +7 -0
  88. package/dist/super-editor/src/extensions/index.d.ts +2 -2
  89. package/dist/super-editor/src/extensions/linked-styles/index.d.ts +1 -0
  90. package/dist/super-editor/src/extensions/linked-styles/underline-css.d.ts +17 -0
  91. package/dist/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts +62 -0
  92. package/dist/super-editor/src/extensions/run/commands/index.d.ts +1 -0
  93. package/dist/super-editor/src/extensions/run/commands/split-run.d.ts +1 -0
  94. package/dist/super-editor/src/extensions/run/index.d.ts +1 -0
  95. package/dist/super-editor/src/extensions/run/run.d.ts +6 -0
  96. package/dist/super-editor/src/extensions/shared/cascade-toggle.d.ts +8 -0
  97. package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +12 -0
  98. package/dist/super-editor/src/extensions/tab/tab.d.ts +4 -0
  99. package/dist/super-editor/src/tests/helpers/getParagraphText.d.ts +2 -0
  100. package/dist/super-editor/super-editor.es.js +90 -21
  101. package/dist/super-editor/toolbar.es.js +2 -2
  102. package/dist/super-editor.cjs +1 -1
  103. package/dist/super-editor.es.js +1 -1
  104. package/dist/superdoc.cjs +2 -2
  105. package/dist/superdoc.es.js +2 -2
  106. package/dist/superdoc.umd.js +2933 -911
  107. package/dist/superdoc.umd.js.map +1 -1
  108. package/package.json +7 -4
@@ -12,9 +12,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
12
12
  var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _ListItemNodeView_instances, init_fn2, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _DocumentSectionView_instances, init_fn3, addToolTip_fn;
13
13
  import * as Y from "yjs";
14
14
  import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
15
- import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as InputRule, ah as kebabCase, ai as findParentNodeClosestToPos, aj as getListItemStyleDefinitions, ak as docxNumberigHelpers, al as parseIndentElement, am as combineIndents, an as StepMap, ao as SelectionRange, ap as Transform, aq as isInTable$1, ar as generateDocxRandomId, as as insertNewRelationship, at as updateDOMAttributes, au as htmlHandler } from "./converter-CTJIyTAA.js";
15
+ import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as InputRule, ah as kebabCase, ai as findParentNodeClosestToPos, aj as getListItemStyleDefinitions, ak as docxNumberigHelpers, al as parseIndentElement, am as combineIndents, an as SelectionRange, ao as Transform, ap as isInTable$1, aq as generateDocxRandomId, ar as insertNewRelationship, as as updateDOMAttributes, at as htmlHandler } from "./converter-BJVy6JMW.js";
16
16
  import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
17
- import { D as DocxZipper } from "./docx-zipper-BwicJKh2.js";
17
+ import { D as DocxZipper } from "./docx-zipper-DWDJGX0b.js";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
20
20
  };
@@ -8849,6 +8849,96 @@ const toggleMark = (typeOrName, attrs = {}, options = {}) => ({ state, commands:
8849
8849
  if (isActive2) return commands2.unsetMark(type, { extendEmptyMarkRange });
8850
8850
  return commands2.setMark(type, attrs);
8851
8851
  };
8852
+ const toggleMarkCascade = (markName, options = {}) => ({ state, chain, editor }) => {
8853
+ const {
8854
+ negationAttrs = { value: "0" },
8855
+ isNegation = (attrs) => attrs?.value === "0",
8856
+ styleDetector = defaultStyleDetector,
8857
+ extendEmptyMarkRange = true
8858
+ } = options;
8859
+ const selectionMarks = getMarksFromSelection(state) || [];
8860
+ const inlineMarks = selectionMarks.filter((m) => m.type?.name === markName);
8861
+ const hasNegation = inlineMarks.some((m) => isNegation(m.attrs || {}));
8862
+ const hasInline = inlineMarks.some((m) => !isNegation(m.attrs || {}));
8863
+ const styleOn = styleDetector({ state, selectionMarks, markName, editor });
8864
+ const cmdChain = chain();
8865
+ if (hasNegation) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
8866
+ if (hasInline && styleOn) {
8867
+ return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
8868
+ }
8869
+ if (hasInline) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
8870
+ if (styleOn) return cmdChain.setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
8871
+ return cmdChain.setMark(markName, {}, { extendEmptyMarkRange }).run();
8872
+ };
8873
+ function defaultStyleDetector({ state, selectionMarks, markName, editor }) {
8874
+ try {
8875
+ const styleId = getEffectiveStyleId(state, selectionMarks);
8876
+ if (!styleId || !editor?.converter?.linkedStyles) return false;
8877
+ const styles = editor.converter.linkedStyles;
8878
+ const seen = /* @__PURE__ */ new Set();
8879
+ let current = styleId;
8880
+ const key2 = mapMarkToStyleKey(markName);
8881
+ while (current && !seen.has(current)) {
8882
+ seen.add(current);
8883
+ const style = styles.find((s) => s.id === current);
8884
+ const def = style?.definition?.styles || {};
8885
+ if (key2 in def) {
8886
+ const raw = def[key2];
8887
+ if (raw === void 0) return true;
8888
+ const val = raw?.value ?? raw;
8889
+ return isStyleTokenEnabled(val);
8890
+ }
8891
+ current = style?.definition?.attrs?.basedOn || null;
8892
+ }
8893
+ return false;
8894
+ } catch {
8895
+ return false;
8896
+ }
8897
+ }
8898
+ function getEffectiveStyleId(state, selectionMarks) {
8899
+ const sidFromMarks = getStyleIdFromMarks(selectionMarks);
8900
+ if (sidFromMarks) return sidFromMarks;
8901
+ const $from = state.selection.$from;
8902
+ const before = $from.nodeBefore;
8903
+ const after = $from.nodeAfter;
8904
+ if (before && before.marks) {
8905
+ const sid = getStyleIdFromMarks(before.marks);
8906
+ if (sid) return sid;
8907
+ }
8908
+ if (after && after.marks) {
8909
+ const sid = getStyleIdFromMarks(after.marks);
8910
+ if (sid) return sid;
8911
+ }
8912
+ const ts = selectionMarks.find((m) => m.type?.name === "textStyle" && m.attrs?.styleId);
8913
+ if (ts) return ts.attrs.styleId;
8914
+ const pos = state.selection.$from.pos;
8915
+ const $pos = state.doc.resolve(pos);
8916
+ for (let d = $pos.depth; d >= 0; d--) {
8917
+ const n = $pos.node(d);
8918
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
8919
+ }
8920
+ return null;
8921
+ }
8922
+ function getStyleIdFromMarks(marks) {
8923
+ if (!Array.isArray(marks)) return null;
8924
+ const textStyleMark = marks.find((m) => m.type?.name === "textStyle" && m.attrs?.styleId);
8925
+ if (textStyleMark) return textStyleMark.attrs.styleId;
8926
+ return null;
8927
+ }
8928
+ function mapMarkToStyleKey(markName) {
8929
+ if (markName === "textStyle" || markName === "color") return "color";
8930
+ return markName;
8931
+ }
8932
+ function isStyleTokenEnabled(val) {
8933
+ if (val === false || val === 0) return false;
8934
+ if (typeof val === "string") {
8935
+ const normalized = val.trim().toLowerCase();
8936
+ if (!normalized) return false;
8937
+ if (["0", "false", "none", "inherit", "transparent"].includes(normalized)) return false;
8938
+ return true;
8939
+ }
8940
+ return !!val;
8941
+ }
8852
8942
  const clearNodes = () => ({ state, tr, dispatch }) => {
8853
8943
  const { selection } = tr;
8854
8944
  const { ranges } = selection;
@@ -10194,11 +10284,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10194
10284
  command,
10195
10285
  createParagraphNear,
10196
10286
  decreaseListIndent,
10287
+ defaultStyleDetector,
10197
10288
  deleteListItem,
10198
10289
  deleteSelection,
10199
10290
  exitCode,
10200
10291
  first,
10292
+ getEffectiveStyleId,
10201
10293
  getParaCtx,
10294
+ getStyleIdFromMarks,
10202
10295
  handleBackspaceNextToList,
10203
10296
  handleDeleteNextToList,
10204
10297
  increaseListIndent,
@@ -10207,12 +10300,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10207
10300
  insertTabChar,
10208
10301
  insertTabCharacter,
10209
10302
  insertTabNode,
10303
+ isStyleTokenEnabled,
10210
10304
  joinBackward,
10211
10305
  joinDown,
10212
10306
  joinForward,
10213
10307
  joinUp,
10214
10308
  liftEmptyBlock,
10215
10309
  liftListItem,
10310
+ mapMarkToStyleKey,
10216
10311
  nearestListAt,
10217
10312
  newlineInCode,
10218
10313
  rebuildListNodeWithNewNum,
@@ -10232,6 +10327,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10232
10327
  splitListItem,
10233
10328
  toggleList,
10234
10329
  toggleMark,
10330
+ toggleMarkCascade,
10235
10331
  toggleNode,
10236
10332
  undoInputRule,
10237
10333
  unsetAllMarks,
@@ -10247,6 +10343,7 @@ const Commands = Extension.create({
10247
10343
  });
10248
10344
  const handleEnter = (editor) => {
10249
10345
  return editor.commands.first(({ commands: commands2 }) => [
10346
+ () => commands2.splitRun(),
10250
10347
  () => commands2.newlineInCode(),
10251
10348
  () => commands2.createParagraphNear(),
10252
10349
  () => commands2.liftEmptyBlock(),
@@ -10280,6 +10377,7 @@ const Keymap = Extension.create({
10280
10377
  addShortcuts() {
10281
10378
  const baseKeymap = {
10282
10379
  Enter: () => handleEnter(this.editor),
10380
+ "Shift-Enter": () => this.editor.commands.insertLineBreak(),
10283
10381
  "Mod-Enter": () => this.editor.commands.exitCode(),
10284
10382
  Backspace: () => handleBackspace(this.editor),
10285
10383
  "Mod-Backspace": () => handleBackspace(this.editor),
@@ -11366,7 +11464,18 @@ const updateYdocDocxData = async (editor, ydoc) => {
11366
11464
  ydoc = ydoc || editor.options.ydoc;
11367
11465
  if (!ydoc) return;
11368
11466
  const metaMap = ydoc.getMap("meta");
11369
- const docx = [...metaMap.get("docx")];
11467
+ const docxValue = metaMap.get("docx");
11468
+ let docx = [];
11469
+ if (Array.isArray(docxValue)) {
11470
+ docx = [...docxValue];
11471
+ } else if (docxValue && typeof docxValue.toArray === "function") {
11472
+ docx = docxValue.toArray();
11473
+ } else if (docxValue && typeof docxValue[Symbol.iterator] === "function") {
11474
+ docx = Array.from(docxValue);
11475
+ }
11476
+ if (!docx.length && Array.isArray(editor.options.content)) {
11477
+ docx = [...editor.options.content];
11478
+ }
11370
11479
  const newXml = await editor.exportDocx({ getUpdatedDocs: true });
11371
11480
  Object.keys(newXml).forEach((key2) => {
11372
11481
  const fileIndex = docx.findIndex((item) => item.name === key2);
@@ -11444,7 +11553,7 @@ const createHeaderFooterEditor = ({
11444
11553
  currentPageNumber
11445
11554
  }) => {
11446
11555
  const parentStyles = editor.converter.getDocumentDefaultStyles();
11447
- const { fontSizePt, typeface } = parentStyles;
11556
+ const { fontSizePt, typeface, fontFamilyCss } = parentStyles;
11448
11557
  const fontSizeInPixles = fontSizePt * 1.3333;
11449
11558
  const lineHeight = fontSizeInPixles * 1.2;
11450
11559
  Object.assign(editorContainer.style, {
@@ -11457,7 +11566,7 @@ const createHeaderFooterEditor = ({
11457
11566
  left: "0",
11458
11567
  width: "auto",
11459
11568
  maxWidth: "none",
11460
- fontFamily: typeface,
11569
+ fontFamily: fontFamilyCss || typeface,
11461
11570
  fontSize: `${fontSizeInPixles}px`,
11462
11571
  lineHeight: `${lineHeight}px`
11463
11572
  });
@@ -12287,7 +12396,6 @@ const trackedTransaction = ({ tr, state, user }) => {
12287
12396
  originalStep,
12288
12397
  originalStepIndex
12289
12398
  });
12290
- console.debug("[track-changes]: replaceStep");
12291
12399
  } else if (step instanceof AddMarkStep) {
12292
12400
  addMarkStep({
12293
12401
  state,
@@ -12297,7 +12405,6 @@ const trackedTransaction = ({ tr, state, user }) => {
12297
12405
  user,
12298
12406
  date
12299
12407
  });
12300
- console.debug("[track-changes]: addMarkStep");
12301
12408
  } else if (step instanceof RemoveMarkStep) {
12302
12409
  removeMarkStep({
12303
12410
  state,
@@ -12307,10 +12414,8 @@ const trackedTransaction = ({ tr, state, user }) => {
12307
12414
  user,
12308
12415
  date
12309
12416
  });
12310
- console.debug("[track-changes]: removeMarkStep");
12311
12417
  } else {
12312
12418
  newTr.step(step);
12313
- console.log("[track-changes]: otherStep");
12314
12419
  }
12315
12420
  });
12316
12421
  if (tr.getMeta("inputType")) {
@@ -14423,9 +14528,10 @@ const _Editor = class _Editor extends EventEmitter {
14423
14528
  element.style.isolation = "isolate";
14424
14529
  proseMirror.style.outline = "none";
14425
14530
  proseMirror.style.border = "none";
14426
- const { typeface, fontSizePt } = this.converter.getDocumentDefaultStyles() ?? {};
14427
- if (typeface) {
14428
- element.style.fontFamily = typeface;
14531
+ const { typeface, fontSizePt, fontFamilyCss } = this.converter.getDocumentDefaultStyles() ?? {};
14532
+ const resolvedFontFamily = fontFamilyCss || typeface;
14533
+ if (resolvedFontFamily) {
14534
+ element.style.fontFamily = resolvedFontFamily;
14429
14535
  }
14430
14536
  if (fontSizePt) {
14431
14537
  element.style.fontSize = `${fontSizePt}pt`;
@@ -14713,12 +14819,15 @@ const _Editor = class _Editor extends EventEmitter {
14713
14819
  }
14714
14820
  destroyHeaderFooterEditors() {
14715
14821
  try {
14716
- const editors = [...this.converter.headerEditors, ...this.converter.footerEditors];
14822
+ const headerEditors = this.converter?.headerEditors ?? [];
14823
+ const footerEditors = this.converter?.footerEditors ?? [];
14824
+ if (!headerEditors.length && !footerEditors.length) return;
14825
+ const editors = [...headerEditors, ...footerEditors].filter(Boolean);
14717
14826
  for (let editorData of editors) {
14718
- editorData.editor.destroy();
14827
+ editorData?.editor?.destroy?.();
14719
14828
  }
14720
- this.converter.headerEditors.length = 0;
14721
- this.converter.footerEditors.length = 0;
14829
+ if (headerEditors.length) headerEditors.length = 0;
14830
+ if (footerEditors.length) footerEditors.length = 0;
14722
14831
  } catch (error) {
14723
14832
  this.emit("exception", { error, editor: this });
14724
14833
  console.error(error);
@@ -14741,7 +14850,7 @@ const _Editor = class _Editor extends EventEmitter {
14741
14850
  * @returns {Object | void} Migration results
14742
14851
  */
14743
14852
  processCollaborationMigrations() {
14744
- console.debug("[checkVersionMigrations] Current editor version", "0.20.0");
14853
+ console.debug("[checkVersionMigrations] Current editor version", "0.20.0-next.13");
14745
14854
  if (!this.options.ydoc) return;
14746
14855
  const metaMap = this.options.ydoc.getMap("meta");
14747
14856
  let docVersion = metaMap.get("version");
@@ -15909,6 +16018,7 @@ const FormatCommands = Extension.create({
15909
16018
  },
15910
16019
  addCommands() {
15911
16020
  return {
16021
+ toggleMarkCascade,
15912
16022
  /**
15913
16023
  * Clear all formatting (nodes and marks)
15914
16024
  * @category Command
@@ -16888,27 +16998,69 @@ const Text = Node$1.create({
16888
16998
  return {};
16889
16999
  }
16890
17000
  });
16891
- const RunItem = Node$1.create({
17001
+ const splitRun = () => (props) => {
17002
+ const { state, view, tr } = props;
17003
+ const { $from, empty: empty2 } = state.selection;
17004
+ if (!empty2) return false;
17005
+ if ($from.parent.type.name !== "run") return false;
17006
+ const handled = splitBlock(state, (transaction) => {
17007
+ view.dispatch(transaction);
17008
+ });
17009
+ if (handled) {
17010
+ tr.setMeta("preventDispatch", true);
17011
+ }
17012
+ return handled;
17013
+ };
17014
+ const Run = OxmlNode.create({
16892
17015
  name: "run",
17016
+ oXmlName: "w:r",
16893
17017
  group: "inline",
16894
- content: "text*",
16895
17018
  inline: true,
17019
+ content: "inline*",
17020
+ selectable: false,
17021
+ childToAttributes: ["runProperties"],
16896
17022
  addOptions() {
16897
- return {};
16898
- },
16899
- parseDOM() {
16900
- return [{ tag: "run" }];
16901
- },
16902
- renderDOM() {
16903
- return ["run", 0];
17023
+ return {
17024
+ htmlAttributes: {
17025
+ "data-run": "1"
17026
+ }
17027
+ };
16904
17028
  },
16905
17029
  addAttributes() {
16906
17030
  return {
16907
- attributes: {
17031
+ runProperties: {
17032
+ default: null,
17033
+ rendered: false,
17034
+ keepOnSplit: true
17035
+ },
17036
+ rsidR: {
17037
+ default: null,
17038
+ rendered: false,
17039
+ keepOnSplit: true
17040
+ },
17041
+ rsidRPr: {
17042
+ default: null,
16908
17043
  rendered: false,
16909
- "aria-label": "Run node"
17044
+ keepOnSplit: true
17045
+ },
17046
+ rsidDel: {
17047
+ default: null,
17048
+ rendered: false,
17049
+ keepOnSplit: true
16910
17050
  }
16911
17051
  };
17052
+ },
17053
+ addCommands() {
17054
+ return {
17055
+ splitRun
17056
+ };
17057
+ },
17058
+ parseDOM() {
17059
+ return [{ tag: "span[data-run]" }];
17060
+ },
17061
+ renderDOM({ htmlAttributes }) {
17062
+ const base2 = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
17063
+ return ["span", base2, 0];
16912
17064
  }
16913
17065
  });
16914
17066
  const inputRegex$1 = /^\s*([-+*])\s$/;
@@ -17183,6 +17335,115 @@ const OrderedList = Node$1.create({
17183
17335
  ];
17184
17336
  }
17185
17337
  });
17338
+ const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
17339
+ const handler = listIndexMap[listNumberingType];
17340
+ return handler ? handler(listLevel, lvlText, customFormat) : null;
17341
+ };
17342
+ const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
17343
+ const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
17344
+ const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
17345
+ const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
17346
+ const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
17347
+ const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
17348
+ const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
17349
+ const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
17350
+ const listIndexMap = {
17351
+ decimal: handleDecimal,
17352
+ lowerRoman: handleLowerRoman,
17353
+ upperRoman: handleRoman,
17354
+ lowerLetter: handleLowerAlpha,
17355
+ upperLetter: handleAlpha,
17356
+ ordinal: handleOrdinal,
17357
+ custom: handleCustom,
17358
+ japaneseCounting: handleJapaneseCounting
17359
+ };
17360
+ const createNumbering = (values, lvlText) => {
17361
+ return values.reduce((acc, value, index2) => {
17362
+ return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
17363
+ }, lvlText);
17364
+ };
17365
+ const generateNumbering = (path, lvlText, formatter) => {
17366
+ const formattedValues = path.map(formatter);
17367
+ return createNumbering(formattedValues, lvlText);
17368
+ };
17369
+ const ordinalFormatter = (level) => {
17370
+ const suffixes = ["th", "st", "nd", "rd"];
17371
+ const value = level % 100;
17372
+ const suffix = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
17373
+ const p = level + suffix;
17374
+ return p;
17375
+ };
17376
+ const generateFromCustom = (path, lvlText, customFormat) => {
17377
+ if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
17378
+ const match = customFormat.match(/(\d+)/);
17379
+ if (!match) throw new Error("Invalid format string: no numeric pattern found");
17380
+ const sample = match[1];
17381
+ const digitCount = sample.length;
17382
+ const index2 = path.pop();
17383
+ return String(index2).padStart(digitCount, "0");
17384
+ };
17385
+ const intToRoman = (num) => {
17386
+ const romanNumeralMap = [
17387
+ { value: 1e3, numeral: "M" },
17388
+ { value: 900, numeral: "CM" },
17389
+ { value: 500, numeral: "D" },
17390
+ { value: 400, numeral: "CD" },
17391
+ { value: 100, numeral: "C" },
17392
+ { value: 90, numeral: "XC" },
17393
+ { value: 50, numeral: "L" },
17394
+ { value: 40, numeral: "XL" },
17395
+ { value: 10, numeral: "X" },
17396
+ { value: 9, numeral: "IX" },
17397
+ { value: 5, numeral: "V" },
17398
+ { value: 4, numeral: "IV" },
17399
+ { value: 1, numeral: "I" }
17400
+ ];
17401
+ let result = "";
17402
+ for (const { value, numeral } of romanNumeralMap) {
17403
+ while (num >= value) {
17404
+ result += numeral;
17405
+ num -= value;
17406
+ }
17407
+ }
17408
+ return result;
17409
+ };
17410
+ const intToAlpha = (num) => {
17411
+ let result = "";
17412
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
17413
+ while (num > 0) {
17414
+ let index2 = (num - 1) % 26;
17415
+ result = alphabet[index2] + result;
17416
+ num = Math.floor((num - 1) / 26);
17417
+ }
17418
+ return result;
17419
+ };
17420
+ const intToJapaneseCounting = (num) => {
17421
+ const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
17422
+ const units = ["", "十", "百", "千"];
17423
+ if (num === 0) return "零";
17424
+ if (num < 10) return digits[num];
17425
+ let result = "";
17426
+ let tempNum = num;
17427
+ let unitIndex = 0;
17428
+ while (tempNum > 0) {
17429
+ const digit = tempNum % 10;
17430
+ if (digit !== 0) {
17431
+ const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
17432
+ result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
17433
+ } else if (result && tempNum > 0) {
17434
+ if (!result.startsWith("零") && tempNum % 100 !== 0) {
17435
+ result = "零" + result;
17436
+ }
17437
+ }
17438
+ tempNum = Math.floor(tempNum / 10);
17439
+ unitIndex++;
17440
+ if (unitIndex > 3) break;
17441
+ }
17442
+ if (num >= 10 && num < 20) {
17443
+ result = result.replace(/^一十/, "十");
17444
+ }
17445
+ return result;
17446
+ };
17186
17447
  const CustomSelectionPluginKey = new PluginKey("CustomSelection");
17187
17448
  const handleClickOutside = (event, editor) => {
17188
17449
  const editorElem = editor?.options?.element;
@@ -17463,6 +17724,7 @@ const getMarksStyle = (attrs) => {
17463
17724
  case "textStyle":
17464
17725
  const { fontFamily, fontSize } = attr.attrs;
17465
17726
  styles += `${fontFamily ? `font-family: ${fontFamily};` : ""} ${fontSize ? `font-size: ${fontSize};` : ""}`;
17727
+ break;
17466
17728
  }
17467
17729
  }
17468
17730
  return styles.trim();
@@ -17481,12 +17743,22 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17481
17743
  const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
17482
17744
  const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
17483
17745
  const resultStyles = { ...linkedDefinitionStyles };
17484
- if (!linkedDefinitionStyles["font-size"] && basedOnDefinitionStyles["font-size"]) {
17485
- resultStyles["font-size"] = basedOnDefinitionStyles["font-size"];
17486
- }
17487
- if (!linkedDefinitionStyles["text-transform"] && basedOnDefinitionStyles["text-transform"]) {
17488
- resultStyles["text-transform"] = basedOnDefinitionStyles["text-transform"];
17489
- }
17746
+ const inheritKeys = [
17747
+ "font-size",
17748
+ "font-family",
17749
+ "text-transform",
17750
+ "bold",
17751
+ "italic",
17752
+ "underline",
17753
+ "strike",
17754
+ "color",
17755
+ "highlight"
17756
+ ];
17757
+ inheritKeys.forEach((k) => {
17758
+ if (!linkedDefinitionStyles[k] && basedOnDefinitionStyles[k]) {
17759
+ resultStyles[k] = basedOnDefinitionStyles[k];
17760
+ }
17761
+ });
17490
17762
  Object.entries(resultStyles).forEach(([k, value]) => {
17491
17763
  const key2 = kebabCase(k);
17492
17764
  const flattenedMarks = [];
@@ -17501,6 +17773,10 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17501
17773
  }
17502
17774
  flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
17503
17775
  });
17776
+ const underlineNone = node?.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType === "none");
17777
+ if (underlineNone) {
17778
+ markValue["text-decoration"] = "none";
17779
+ }
17504
17780
  const mark = flattenedMarks.find((n) => n.key === key2);
17505
17781
  const hasParentIndent = Object.keys(parent?.attrs?.indent || {});
17506
17782
  const hasParentSpacing = Object.keys(parent?.attrs?.spacing || {});
@@ -17517,10 +17793,28 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17517
17793
  if (rightIndent) markValue["margin-right"] = rightIndent + "px";
17518
17794
  if (firstLine) markValue["text-indent"] = firstLine + "px";
17519
17795
  } else if (key2 === "bold" && node) {
17520
- const val = value?.value;
17521
- if (!listTypes.includes(node.type.name) && val !== "0") {
17796
+ const boldValue = typeof value === "object" && value !== null ? value.value : value;
17797
+ const hasInlineBoldOff = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value === "0");
17798
+ const hasInlineBoldOn = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value !== "0");
17799
+ if (!listTypes.includes(node.type.name) && !hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) {
17522
17800
  markValue["font-weight"] = "bold";
17523
17801
  }
17802
+ } else if (key2 === "italic" && node) {
17803
+ const italicValue = typeof value === "object" && value !== null ? value.value : value;
17804
+ const hasInlineItalicOff = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value === "0");
17805
+ const hasInlineItalicOn = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value !== "0");
17806
+ if (!listTypes.includes(node.type.name) && !hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) {
17807
+ markValue["font-style"] = "italic";
17808
+ }
17809
+ } else if (key2 === "strike" && node) {
17810
+ const strikeValue = typeof value === "object" && value !== null ? value.value : value;
17811
+ const hasInlineStrikeOff = node.marks?.some((m) => m.type?.name === "strike" && m.attrs?.value === "0");
17812
+ const hasInlineStrikeOn = node.marks?.some(
17813
+ (m) => m.type?.name === "strike" && (m.attrs?.value === void 0 || m.attrs?.value !== "0")
17814
+ );
17815
+ if (!listTypes.includes(node.type.name) && !hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) {
17816
+ markValue["text-decoration"] = "line-through";
17817
+ }
17524
17818
  } else if (key2 === "text-transform" && node) {
17525
17819
  if (!listTypes.includes(node.type.name)) {
17526
17820
  markValue[key2] = value;
@@ -17529,10 +17823,44 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17529
17823
  if (!listTypes.includes(node.type.name)) {
17530
17824
  markValue[key2] = value;
17531
17825
  }
17826
+ } else if (key2 === "font-family" && node) {
17827
+ if (!listTypes.includes(node.type.name)) {
17828
+ markValue[key2] = value;
17829
+ }
17532
17830
  } else if (key2 === "color" && node) {
17533
17831
  if (!listTypes.includes(node.type.name)) {
17534
17832
  markValue[key2] = value;
17535
17833
  }
17834
+ } else if (key2 === "highlight" && node) {
17835
+ const hasInlineHighlight = node.marks?.some((m) => m.type?.name === "highlight");
17836
+ if (!listTypes.includes(node.type.name) && !hasInlineHighlight) {
17837
+ const color = typeof value === "string" ? value : value?.color;
17838
+ if (color) markValue["background-color"] = color;
17839
+ }
17840
+ } else if (key2 === "underline" && node) {
17841
+ const styleValRaw = value?.value ?? value ?? "";
17842
+ const styleVal = styleValRaw.toString().toLowerCase();
17843
+ const hasInlineUnderlineOff = node.marks?.some(
17844
+ (m) => m.type?.name === "underline" && m.attrs?.underlineType === "none"
17845
+ );
17846
+ const hasInlineUnderlineOn = node.marks?.some(
17847
+ (m) => m.type?.name === "underline" && m.attrs?.underlineType && m.attrs.underlineType !== "none"
17848
+ );
17849
+ if (!listTypes.includes(node.type.name) && !hasInlineUnderlineOff && !hasInlineUnderlineOn) {
17850
+ if (styleVal && styleVal !== "none" && styleVal !== "0") {
17851
+ const colorVal = value && typeof value === "object" ? value.color || value.underlineColor || null : null;
17852
+ const css = getUnderlineCssString({ type: styleVal, color: colorVal });
17853
+ css.split(";").forEach((decl) => {
17854
+ const d = decl.trim();
17855
+ if (!d) return;
17856
+ const idx = d.indexOf(":");
17857
+ if (idx === -1) return;
17858
+ const k2 = d.slice(0, idx).trim();
17859
+ const v = d.slice(idx + 1).trim();
17860
+ markValue[k2] = v;
17861
+ });
17862
+ }
17863
+ }
17536
17864
  } else if (typeof value === "string") {
17537
17865
  markValue[key2] = value;
17538
17866
  }
@@ -17665,23 +17993,51 @@ const createLinkedStylesPlugin = (editor) => {
17665
17993
  };
17666
17994
  const generateDecorations = (state, styles) => {
17667
17995
  const decorations = [];
17668
- let lastStyleId = null;
17669
17996
  const doc2 = state?.doc;
17997
+ const getParagraphStyleId = (pos) => {
17998
+ const $pos = state.doc.resolve(pos);
17999
+ for (let d = $pos.depth; d >= 0; d--) {
18000
+ const n = $pos.node(d);
18001
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
18002
+ }
18003
+ return null;
18004
+ };
17670
18005
  doc2.descendants((node, pos) => {
17671
18006
  const { name } = node.type;
17672
- if (node?.attrs?.styleId) lastStyleId = node.attrs.styleId;
17673
- if (name === "paragraph" && !node.attrs?.styleId) lastStyleId = null;
17674
- if (name !== "text" && name !== "listItem" && name !== "orderedList") return;
18007
+ if (name !== "text") return;
18008
+ const paragraphStyleId = getParagraphStyleId(pos);
18009
+ let runStyleId = null;
18010
+ let inlineTextStyleId = null;
17675
18011
  for (const mark of node.marks) {
17676
- if (mark.type.name === "textStyle" && mark.attrs.styleId) {
17677
- lastStyleId = mark.attrs.styleId;
17678
- }
17679
- }
17680
- const { linkedStyle, basedOnStyle } = getLinkedStyle(lastStyleId, styles);
17681
- if (!linkedStyle) return;
18012
+ if (mark.type.name === "run") {
18013
+ const rp = mark.attrs?.runProperties;
18014
+ if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
18015
+ else if (Array.isArray(rp)) {
18016
+ const ent = rp.find((e) => e?.xmlName === "w:rStyle");
18017
+ const sid = ent?.attributes?.["w:val"];
18018
+ if (sid) runStyleId = sid;
18019
+ }
18020
+ } else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
18021
+ inlineTextStyleId = mark.attrs.styleId;
18022
+ }
18023
+ }
18024
+ const buildStyleMap = (sid) => {
18025
+ if (!sid) return {};
18026
+ const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
18027
+ if (!linkedStyle) return {};
18028
+ const base2 = { ...basedOnStyle2?.definition?.styles || {} };
18029
+ return { ...base2, ...linkedStyle.definition?.styles || {} };
18030
+ };
18031
+ const pMap = buildStyleMap(paragraphStyleId);
18032
+ const tMap = buildStyleMap(inlineTextStyleId);
18033
+ const rMap = buildStyleMap(runStyleId);
18034
+ const finalStyles = { ...pMap, ...tMap, ...rMap };
18035
+ if (Object.keys(finalStyles).length === 0) return;
18036
+ const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
18037
+ const basedOnStyle = null;
17682
18038
  const $pos = state.doc.resolve(pos);
17683
18039
  const parent = $pos.parent;
17684
- const styleString = generateLinkedStyleString(linkedStyle, basedOnStyle, node, parent);
18040
+ const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
17685
18041
  if (!styleString) return;
17686
18042
  const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
17687
18043
  decorations.push(decoration);
@@ -17810,115 +18166,298 @@ const LinkedStyles = Extension.create({
17810
18166
  };
17811
18167
  }
17812
18168
  });
17813
- const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
17814
- const handler = listIndexMap[listNumberingType];
17815
- return handler ? handler(listLevel, lvlText, customFormat) : null;
17816
- };
17817
- const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
17818
- const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
17819
- const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
17820
- const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
17821
- const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
17822
- const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
17823
- const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
17824
- const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
17825
- const listIndexMap = {
17826
- decimal: handleDecimal,
17827
- lowerRoman: handleLowerRoman,
17828
- upperRoman: handleRoman,
17829
- lowerLetter: handleLowerAlpha,
17830
- upperLetter: handleAlpha,
17831
- ordinal: handleOrdinal,
17832
- custom: handleCustom,
17833
- japaneseCounting: handleJapaneseCounting
17834
- };
17835
- const createNumbering = (values, lvlText) => {
17836
- return values.reduce((acc, value, index2) => {
17837
- return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
17838
- }, lvlText);
17839
- };
17840
- const generateNumbering = (path, lvlText, formatter) => {
17841
- const formattedValues = path.map(formatter);
17842
- return createNumbering(formattedValues, lvlText);
17843
- };
17844
- const ordinalFormatter = (level) => {
17845
- const suffixes = ["th", "st", "nd", "rd"];
17846
- const value = level % 100;
17847
- const suffix = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
17848
- const p = level + suffix;
17849
- return p;
17850
- };
17851
- const generateFromCustom = (path, lvlText, customFormat) => {
17852
- if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
17853
- const match = customFormat.match(/(\d+)/);
17854
- if (!match) throw new Error("Invalid format string: no numeric pattern found");
17855
- const sample = match[1];
17856
- const digitCount = sample.length;
17857
- const index2 = path.pop();
17858
- return String(index2).padStart(digitCount, "0");
17859
- };
17860
- const intToRoman = (num) => {
17861
- const romanNumeralMap = [
17862
- { value: 1e3, numeral: "M" },
17863
- { value: 900, numeral: "CM" },
17864
- { value: 500, numeral: "D" },
17865
- { value: 400, numeral: "CD" },
17866
- { value: 100, numeral: "C" },
17867
- { value: 90, numeral: "XC" },
17868
- { value: 50, numeral: "L" },
17869
- { value: 40, numeral: "XL" },
17870
- { value: 10, numeral: "X" },
17871
- { value: 9, numeral: "IX" },
17872
- { value: 5, numeral: "V" },
17873
- { value: 4, numeral: "IV" },
17874
- { value: 1, numeral: "I" }
17875
- ];
17876
- let result = "";
17877
- for (const { value, numeral } of romanNumeralMap) {
17878
- while (num >= value) {
17879
- result += numeral;
17880
- num -= value;
18169
+ function getUnderlineCssString({ type = "single", color = null, thickness = null, approximate = true } = {}) {
18170
+ const parts = [];
18171
+ const add = (k, v) => {
18172
+ if (!v) return;
18173
+ parts.push(`${k}: ${v}`);
18174
+ };
18175
+ const lower = String(type || "single").toLowerCase();
18176
+ if (lower === "none" || lower === "0") {
18177
+ add("text-decoration", "none");
18178
+ return parts.join("; ");
18179
+ }
18180
+ add("text-decoration-line", "underline");
18181
+ const HEAVY = thickness || "0.2em";
18182
+ const THICK = thickness || "0.15em";
18183
+ switch (lower) {
18184
+ case "single":
18185
+ break;
18186
+ case "double":
18187
+ add("text-decoration-style", "double");
18188
+ break;
18189
+ case "thick":
18190
+ add("text-decoration-thickness", THICK);
18191
+ break;
18192
+ case "dotted":
18193
+ add("text-decoration-style", "dotted");
18194
+ break;
18195
+ case "dash":
18196
+ case "dashed":
18197
+ add("text-decoration-style", "dashed");
18198
+ break;
18199
+ case "dotdash":
18200
+ case "dotdotdash":
18201
+ case "dashlong":
18202
+ case "dashlongheavy":
18203
+ if (approximate) {
18204
+ add("text-decoration-style", "dashed");
18205
+ if (lower.includes("heavy")) add("text-decoration-thickness", HEAVY);
18206
+ }
18207
+ break;
18208
+ case "dottedheavy":
18209
+ add("text-decoration-style", "dotted");
18210
+ add("text-decoration-thickness", HEAVY);
18211
+ break;
18212
+ case "dashedheavy":
18213
+ add("text-decoration-style", "dashed");
18214
+ add("text-decoration-thickness", HEAVY);
18215
+ break;
18216
+ case "wavy":
18217
+ add("text-decoration-style", "wavy");
18218
+ break;
18219
+ case "wavyheavy":
18220
+ add("text-decoration-style", "wavy");
18221
+ add("text-decoration-thickness", HEAVY);
18222
+ break;
18223
+ case "wavydouble":
18224
+ if (approximate) {
18225
+ add("text-decoration-style", "wavy");
18226
+ add("text-decoration-thickness", HEAVY);
18227
+ }
18228
+ break;
18229
+ }
18230
+ if (color) add("text-decoration-color", color);
18231
+ return parts.join("; ");
18232
+ }
18233
+ function collectTextStyleMarks(listItem, markType) {
18234
+ const textStyleMarks = [];
18235
+ const seenMarks = /* @__PURE__ */ new Set();
18236
+ const attrs = {};
18237
+ if (!markType) {
18238
+ return {
18239
+ marks: textStyleMarks,
18240
+ attrs
18241
+ };
18242
+ }
18243
+ const collectMarks = (node) => {
18244
+ if (!node) return;
18245
+ const candidateMarks = Array.isArray(node.marks) ? node.marks : [];
18246
+ if (candidateMarks.length && typeof markType.isInSet === "function" && markType.isInSet(candidateMarks)) {
18247
+ candidateMarks.forEach((mark) => {
18248
+ if (mark.type === markType && !seenMarks.has(mark)) {
18249
+ seenMarks.add(mark);
18250
+ textStyleMarks.push(mark);
18251
+ }
18252
+ });
18253
+ }
18254
+ if (!node.isText && node.childCount) {
18255
+ node.forEach((child) => collectMarks(child));
18256
+ }
18257
+ };
18258
+ listItem.forEach((childNode) => {
18259
+ if (childNode.type?.name !== "paragraph") return;
18260
+ if (childNode.attrs?.lineHeight !== void 0) {
18261
+ attrs.lineHeight = childNode.attrs.lineHeight;
17881
18262
  }
18263
+ collectMarks(childNode);
18264
+ });
18265
+ return {
18266
+ marks: textStyleMarks,
18267
+ attrs
18268
+ };
18269
+ }
18270
+ function parseSizeFromRunProperties(listRunProperties) {
18271
+ const val = listRunProperties?.["w:val"] || listRunProperties?.["w:sz"];
18272
+ if (val == null) return null;
18273
+ const numeric = Number(val);
18274
+ if (Number.isNaN(numeric) || numeric <= 0) return null;
18275
+ const sizeInPoints = numeric / 2;
18276
+ return `${sizeInPoints}pt`;
18277
+ }
18278
+ function parseFontFamilyFromRunProperties(listRunProperties) {
18279
+ const ascii = listRunProperties?.["w:ascii"];
18280
+ const hAnsi = listRunProperties?.["w:hAnsi"];
18281
+ const eastAsia = listRunProperties?.["w:eastAsia"];
18282
+ return ascii || hAnsi || eastAsia || null;
18283
+ }
18284
+ function readNodeViewStyles(view) {
18285
+ const fallback = { fontSize: null, fontFamily: null, lineHeight: null };
18286
+ if (!view?.dom) return fallback;
18287
+ const inline = {
18288
+ fontSize: view.dom.style?.fontSize || null,
18289
+ fontFamily: view.dom.style?.fontFamily || null,
18290
+ lineHeight: view.dom.style?.lineHeight || null
18291
+ };
18292
+ if (inline.fontSize && inline.fontFamily && inline.lineHeight) return inline;
18293
+ const globalWindow = typeof window !== "undefined" ? window : void 0;
18294
+ if (globalWindow?.getComputedStyle) {
18295
+ const computed2 = globalWindow.getComputedStyle(view.dom);
18296
+ return {
18297
+ fontSize: inline.fontSize || computed2.fontSize,
18298
+ fontFamily: inline.fontFamily || computed2.fontFamily,
18299
+ lineHeight: inline.lineHeight || computed2.lineHeight
18300
+ };
17882
18301
  }
17883
- return result;
17884
- };
17885
- const intToAlpha = (num) => {
17886
- let result = "";
17887
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
17888
- while (num > 0) {
17889
- let index2 = (num - 1) % 26;
17890
- result = alphabet[index2] + result;
17891
- num = Math.floor((num - 1) / 26);
18302
+ return inline;
18303
+ }
18304
+ function getAdjacentListItemNodeView({ nodeView, pos, direction, activeNodeViews }) {
18305
+ if (!activeNodeViews) return null;
18306
+ let candidate = null;
18307
+ activeNodeViews.forEach((view) => {
18308
+ if (view === nodeView) return;
18309
+ let viewPos;
18310
+ try {
18311
+ viewPos = view.getPos();
18312
+ } catch {
18313
+ return;
18314
+ }
18315
+ if (typeof viewPos !== "number") return;
18316
+ if (viewPos < pos) {
18317
+ if (!candidate || viewPos > candidate.pos) candidate = { view, pos: viewPos };
18318
+ }
18319
+ });
18320
+ return candidate?.view ?? null;
18321
+ }
18322
+ function findSiblingListItem({ editor, pos, direction }) {
18323
+ if (typeof pos !== "number" || !editor?.view) return null;
18324
+ const { state } = editor.view;
18325
+ const $pos = state.doc.resolve(pos);
18326
+ const parentDepth = $pos.depth - 1;
18327
+ if (parentDepth < 0) return null;
18328
+ const parent = $pos.node(parentDepth);
18329
+ if (!parent) return null;
18330
+ const indexInsideParent = $pos.index(parentDepth);
18331
+ const siblingIndex = indexInsideParent + direction;
18332
+ if (siblingIndex < 0 || siblingIndex >= parent.childCount) return null;
18333
+ const sibling = parent.child(siblingIndex);
18334
+ return sibling?.type?.name === "listItem" ? sibling : null;
18335
+ }
18336
+ function deriveFontStylesFromNode({ node, textStyleType, defaultFont, defaultSize, listRunProperties }) {
18337
+ const { marks: allMarks, attrs } = collectTextStyleMarks(node, textStyleType);
18338
+ const styleMarks = textStyleType ? allMarks.filter((m) => m.type === textStyleType) : [];
18339
+ const sizeMark = styleMarks.find((m) => m.attrs?.fontSize);
18340
+ const familyMark = styleMarks.find((m) => m.attrs?.fontFamily);
18341
+ let fontSize = defaultSize;
18342
+ if (sizeMark) {
18343
+ const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
18344
+ if (!Number.isNaN(value)) {
18345
+ fontSize = `${value}${unit}`;
18346
+ }
17892
18347
  }
17893
- return result;
17894
- };
17895
- const intToJapaneseCounting = (num) => {
17896
- const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
17897
- const units = ["", "十", "百", "千"];
17898
- if (num === 0) return "零";
17899
- if (num < 10) return digits[num];
17900
- let result = "";
17901
- let tempNum = num;
17902
- let unitIndex = 0;
17903
- while (tempNum > 0) {
17904
- const digit = tempNum % 10;
17905
- if (digit !== 0) {
17906
- const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
17907
- result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
17908
- } else if (result && tempNum > 0) {
17909
- if (!result.startsWith("零") && tempNum % 100 !== 0) {
17910
- result = "零" + result;
17911
- }
18348
+ let hasSize = Boolean(sizeMark);
18349
+ if (!hasSize && listRunProperties) {
18350
+ const sizeFromList = parseSizeFromRunProperties(listRunProperties);
18351
+ if (sizeFromList) {
18352
+ fontSize = sizeFromList;
18353
+ hasSize = true;
17912
18354
  }
17913
- tempNum = Math.floor(tempNum / 10);
17914
- unitIndex++;
17915
- if (unitIndex > 3) break;
17916
18355
  }
17917
- if (num >= 10 && num < 20) {
17918
- result = result.replace(/^一十/, "十");
18356
+ let fontFamily = familyMark?.attrs?.fontFamily ?? defaultFont;
18357
+ let hasFamily = Boolean(familyMark);
18358
+ if (!hasFamily && listRunProperties) {
18359
+ const fontFromList = parseFontFamilyFromRunProperties(listRunProperties);
18360
+ if (fontFromList) {
18361
+ fontFamily = fontFromList;
18362
+ hasFamily = true;
18363
+ }
17919
18364
  }
17920
- return result;
17921
- };
18365
+ let lineHeight = attrs.lineHeight;
18366
+ const firstChild = node.firstChild;
18367
+ const hasOnlyOnePar = node.childCount === 1 && firstChild?.type?.name === "paragraph";
18368
+ if (hasOnlyOnePar) {
18369
+ const par = firstChild;
18370
+ const parFirstChild = par?.firstChild;
18371
+ if (par?.childCount === 1 && parFirstChild?.type?.name === "fieldAnnotation") {
18372
+ const aFontSize = parFirstChild.attrs?.fontSize;
18373
+ const aFontFamily = parFirstChild.attrs?.fontFamily;
18374
+ if (!sizeMark && aFontSize) fontSize = aFontSize;
18375
+ if (!familyMark && aFontFamily) fontFamily = aFontFamily;
18376
+ }
18377
+ }
18378
+ return {
18379
+ fontSize,
18380
+ fontFamily,
18381
+ lineHeight,
18382
+ hasSize,
18383
+ hasFamily
18384
+ };
18385
+ }
18386
+ function getStylesFromLinkedStyles({ node, pos, editor }) {
18387
+ const { state } = editor.view;
18388
+ const linkedStyles = LinkedStylesPluginKey.getState(state)?.decorations;
18389
+ const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
18390
+ const predicates = [
18391
+ (style2) => style2.includes("font-size") && style2.includes("font-family"),
18392
+ (style2) => style2.includes("font-size"),
18393
+ (style2) => style2.includes("font-family")
18394
+ ];
18395
+ let styleDeco;
18396
+ for (const predicateFn of predicates) {
18397
+ styleDeco = decorationsInPlace?.find((dec) => {
18398
+ const style2 = dec.type?.attrs?.style || "";
18399
+ return style2 && predicateFn(style2);
18400
+ });
18401
+ if (styleDeco) break;
18402
+ }
18403
+ const style = styleDeco?.type?.attrs?.style;
18404
+ const stylesArray = style?.split(";") || [];
18405
+ const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1]?.trim();
18406
+ const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1]?.trim();
18407
+ return {
18408
+ font: fontFamilyFromStyles,
18409
+ size: fontSizeFromStyles
18410
+ };
18411
+ }
18412
+ function resolveListItemTypography({ node, pos, editor, nodeView, activeNodeViews }) {
18413
+ const defaults = getStylesFromLinkedStyles({ node, pos, editor });
18414
+ const textStyleType = getMarkType("textStyle", editor.schema);
18415
+ const currentStyles = deriveFontStylesFromNode({
18416
+ node,
18417
+ textStyleType,
18418
+ defaultFont: defaults.font,
18419
+ defaultSize: defaults.size,
18420
+ listRunProperties: node.attrs?.listRunProperties
18421
+ });
18422
+ if ((!currentStyles.hasSize || !currentStyles.hasFamily || !currentStyles.lineHeight) && editor?.view) {
18423
+ const previousListItem = findSiblingListItem({ editor, pos, direction: -1 });
18424
+ if (previousListItem) {
18425
+ const previousStyles = deriveFontStylesFromNode({
18426
+ node: previousListItem,
18427
+ textStyleType,
18428
+ defaultFont: defaults.font,
18429
+ defaultSize: defaults.size,
18430
+ listRunProperties: previousListItem.attrs?.listRunProperties
18431
+ });
18432
+ if (!currentStyles.hasSize && previousStyles.fontSize) currentStyles.fontSize = previousStyles.fontSize;
18433
+ if (!currentStyles.hasFamily && previousStyles.fontFamily) currentStyles.fontFamily = previousStyles.fontFamily;
18434
+ if (!currentStyles.lineHeight && previousStyles.lineHeight) currentStyles.lineHeight = previousStyles.lineHeight;
18435
+ }
18436
+ }
18437
+ if ((!currentStyles.fontSize || !currentStyles.fontFamily || !currentStyles.lineHeight) && nodeView) {
18438
+ const previousView = getAdjacentListItemNodeView({
18439
+ nodeView,
18440
+ pos,
18441
+ direction: -1,
18442
+ activeNodeViews
18443
+ });
18444
+ if (previousView) {
18445
+ const {
18446
+ fontSize: prevSize,
18447
+ fontFamily: prevFamily,
18448
+ lineHeight: prevLineHeight
18449
+ } = readNodeViewStyles(previousView);
18450
+ if (!currentStyles.fontSize && prevSize) currentStyles.fontSize = prevSize;
18451
+ if (!currentStyles.fontFamily && prevFamily) currentStyles.fontFamily = prevFamily;
18452
+ if (!currentStyles.lineHeight && prevLineHeight) currentStyles.lineHeight = prevLineHeight;
18453
+ }
18454
+ }
18455
+ return {
18456
+ fontSize: currentStyles.fontSize,
18457
+ fontFamily: currentStyles.fontFamily,
18458
+ lineHeight: currentStyles.lineHeight
18459
+ };
18460
+ }
17922
18461
  const MARKER_PADDING = 6;
17923
18462
  const MARKER_OFFSET_RIGHT = 4;
17924
18463
  const MIN_MARKER_WIDTH = 20;
@@ -17936,8 +18475,8 @@ class ListItemNodeView {
17936
18475
  this.decorations = decorations;
17937
18476
  this.view = editor.view;
17938
18477
  this.getPos = getPos;
17939
- activeListItemNodeViews.add(this);
17940
18478
  __privateMethod(this, _ListItemNodeView_instances, init_fn2).call(this);
18479
+ activeListItemNodeViews.add(this);
17941
18480
  }
17942
18481
  refreshIndentStyling() {
17943
18482
  const { attrs } = this.node;
@@ -17980,10 +18519,12 @@ class ListItemNodeView {
17980
18519
  update(node, decorations) {
17981
18520
  this.node = node;
17982
18521
  this.decorations = decorations;
17983
- const { fontSize, fontFamily, lineHeight } = getTextStyleMarksFromLinkedStyles({
18522
+ const { fontSize, fontFamily, lineHeight } = resolveListItemTypography({
17984
18523
  node,
17985
18524
  pos: this.getPos(),
17986
- editor: this.editor
18525
+ editor: this.editor,
18526
+ nodeView: this,
18527
+ activeNodeViews: activeListItemNodeViews
17987
18528
  });
17988
18529
  this.dom.style.fontSize = fontSize;
17989
18530
  this.dom.style.fontFamily = fontFamily || "inherit";
@@ -18012,10 +18553,12 @@ init_fn2 = function() {
18012
18553
  }
18013
18554
  }
18014
18555
  const pos = this.getPos();
18015
- const { fontSize, fontFamily, lineHeight } = getTextStyleMarksFromLinkedStyles({
18556
+ const { fontSize, fontFamily, lineHeight } = resolveListItemTypography({
18016
18557
  node: this.node,
18017
18558
  pos,
18018
- editor: this.editor
18559
+ editor: this.editor,
18560
+ nodeView: this,
18561
+ activeNodeViews: activeListItemNodeViews
18019
18562
  });
18020
18563
  this.dom = document.createElement("li");
18021
18564
  this.dom.className = "sd-editor-list-item-node-view";
@@ -18048,79 +18591,6 @@ function refreshAllListItemNodeViews() {
18048
18591
  }
18049
18592
  });
18050
18593
  }
18051
- function getListItemTextStyleMarks(listItem, markType) {
18052
- let textStyleMarks = [];
18053
- let attrs = {};
18054
- listItem.forEach((childNode) => {
18055
- if (childNode.type.name !== "paragraph") return;
18056
- attrs.lineHeight = childNode.attrs.lineHeight;
18057
- childNode.forEach((textNode) => {
18058
- let isTextNode = textNode.type.name === "text";
18059
- let hasTextStyleMarks = markType.isInSet(textNode.marks);
18060
- if (isTextNode && hasTextStyleMarks) {
18061
- let marks = textNode.marks.filter((mark) => mark.type === markType);
18062
- textStyleMarks.push(...marks);
18063
- }
18064
- });
18065
- });
18066
- return {
18067
- marks: textStyleMarks,
18068
- attrs
18069
- };
18070
- }
18071
- function getTextStyleMarksFromLinkedStyles({ node, pos, editor }) {
18072
- const { font: defaultFont, size: defaultSize } = getStylesFromLinkedStyles({ node, pos, editor });
18073
- const textStyleType = getMarkType("textStyle", editor.schema);
18074
- const { marks: allMarks, attrs: allAttrs } = getListItemTextStyleMarks(node, textStyleType);
18075
- const styleMarks = allMarks.filter((m) => m.type === textStyleType);
18076
- const sizeMark = styleMarks.find((m) => m.attrs.fontSize);
18077
- const familyMark = styleMarks.find((m) => m.attrs.fontFamily);
18078
- const lineHeight = allAttrs.lineHeight;
18079
- let fontSize = sizeMark ? (() => {
18080
- const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
18081
- return Number.isNaN(value) ? defaultSize : `${value}${unit}`;
18082
- })() : defaultSize;
18083
- let fontFamily = familyMark?.attrs.fontFamily ?? defaultFont;
18084
- const firstChild = node.firstChild;
18085
- const hasOnlyOnePar = node.childCount === 1 && firstChild?.type.name === "paragraph";
18086
- if (hasOnlyOnePar) {
18087
- const par = firstChild;
18088
- const parFirstChild = par?.firstChild;
18089
- if (par?.childCount === 1 && parFirstChild?.type.name === "fieldAnnotation") {
18090
- const aFontSize = parFirstChild.attrs.fontSize;
18091
- const aFontFamily = parFirstChild.attrs.fontFamily;
18092
- if (!sizeMark && aFontSize) fontSize = aFontSize;
18093
- if (!familyMark && aFontFamily) fontFamily = aFontFamily;
18094
- }
18095
- }
18096
- return { fontSize, fontFamily, lineHeight };
18097
- }
18098
- const getStylesFromLinkedStyles = ({ node, pos, editor }) => {
18099
- const { state } = editor.view;
18100
- const linkedStyles = LinkedStylesPluginKey.getState(state)?.decorations;
18101
- const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
18102
- const predicates = [
18103
- (style2) => style2.includes("font-size") && style2.includes("font-family"),
18104
- (style2) => style2.includes("font-size"),
18105
- (style2) => style2.includes("font-family")
18106
- ];
18107
- let styleDeco;
18108
- for (const predicateFn of predicates) {
18109
- styleDeco = decorationsInPlace?.find((dec) => {
18110
- const style2 = dec.type.attrs?.style || "";
18111
- return style2 && predicateFn(style2);
18112
- });
18113
- if (styleDeco) break;
18114
- }
18115
- const style = styleDeco?.type.attrs?.style;
18116
- const stylesArray = style?.split(";") || [];
18117
- const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1].trim();
18118
- const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1].trim();
18119
- return {
18120
- font: fontFamilyFromStyles,
18121
- size: fontSizeFromStyles
18122
- };
18123
- };
18124
18594
  const getVisibleIndent = (stylePpr, numDefPpr, inlineIndent) => {
18125
18595
  const styleIndentTag = stylePpr?.elements?.find((el) => el.name === "w:ind") || {};
18126
18596
  const styleIndent = parseIndentElement(styleIndentTag);
@@ -18854,6 +19324,211 @@ const CommentsMark = Mark.create({
18854
19324
  return [CommentMarkName, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
18855
19325
  }
18856
19326
  });
19327
+ const defaultTabDistance = 48;
19328
+ const defaultLineLength = 816;
19329
+ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
19330
+ const decorations = [];
19331
+ const paragraphCache = /* @__PURE__ */ new Map();
19332
+ const end2 = to ?? doc2.content.size;
19333
+ doc2.nodesBetween(from2, end2, (node, pos) => {
19334
+ if (node.type.name !== "tab") return;
19335
+ let extraStyles = "";
19336
+ const $pos = doc2.resolve(pos);
19337
+ const paragraphContext = getParagraphContext($pos, paragraphCache);
19338
+ if (!paragraphContext) return;
19339
+ try {
19340
+ const { tabStops, flattened, startPos } = paragraphContext;
19341
+ const entryIndex = flattened.findIndex((entry) => entry.pos === pos);
19342
+ if (entryIndex === -1) return;
19343
+ const indentWidth = getIndentWidth(view, startPos, paragraphContext.indent);
19344
+ const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
19345
+ const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos) + accumulatedTabWidth;
19346
+ let tabWidth;
19347
+ if (tabStops.length) {
19348
+ const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
19349
+ if (tabStop) {
19350
+ tabWidth = tabStop.pos - currentWidth;
19351
+ if (tabStop.val === "center" || tabStop.val === "end" || tabStop.val === "right") {
19352
+ const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
19353
+ const segmentStartPos = pos + node.nodeSize;
19354
+ const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
19355
+ const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos);
19356
+ tabWidth -= tabStop.val === "center" ? segmentWidth / 2 : segmentWidth;
19357
+ } else if (tabStop.val === "decimal" || tabStop.val === "num") {
19358
+ const breakChar = tabStop.decimalChar || ".";
19359
+ const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
19360
+ const integralWidth = decimalPos ? measureRangeWidth(view, pos + node.nodeSize, decimalPos) : measureRangeWidth(view, pos + node.nodeSize, startPos + paragraphContext.paragraph.nodeSize - 1);
19361
+ tabWidth -= integralWidth;
19362
+ }
19363
+ if (tabStop.leader) {
19364
+ const leaderStyles = {
19365
+ dot: "border-bottom: 1px dotted black;",
19366
+ heavy: "border-bottom: 2px solid black;",
19367
+ hyphen: "border-bottom: 1px solid black;",
19368
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
19369
+ underscore: "border-bottom: 1px solid black;"
19370
+ };
19371
+ extraStyles += leaderStyles[tabStop.leader] || "";
19372
+ }
19373
+ }
19374
+ }
19375
+ if (!tabWidth || tabWidth < 1) {
19376
+ tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
19377
+ if (tabWidth === 0) tabWidth = defaultTabDistance;
19378
+ }
19379
+ const tabHeight = calcTabHeight($pos);
19380
+ decorations.push(
19381
+ Decoration.node(pos, pos + node.nodeSize, {
19382
+ style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
19383
+ })
19384
+ );
19385
+ paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
19386
+ } catch (error) {
19387
+ console.error("tab decoration error", error);
19388
+ }
19389
+ });
19390
+ return decorations;
19391
+ };
19392
+ function getParagraphContext($pos, cache) {
19393
+ for (let depth = $pos.depth; depth >= 0; depth--) {
19394
+ const node = $pos.node(depth);
19395
+ if (node?.type?.name === "paragraph") {
19396
+ const startPos = $pos.start(depth);
19397
+ if (!cache.has(startPos)) {
19398
+ cache.set(startPos, {
19399
+ paragraph: node,
19400
+ paragraphDepth: depth,
19401
+ startPos,
19402
+ indent: node.attrs?.indent || {},
19403
+ tabStops: Array.isArray(node.attrs?.tabStops) ? node.attrs.tabStops : [],
19404
+ flattened: flattenParagraph(node, startPos),
19405
+ accumulatedTabWidth: 0
19406
+ });
19407
+ }
19408
+ return cache.get(startPos);
19409
+ }
19410
+ }
19411
+ return null;
19412
+ }
19413
+ function flattenParagraph(paragraph, paragraphStartPos) {
19414
+ const entries = [];
19415
+ const walk = (node, basePos) => {
19416
+ if (!node) return;
19417
+ if (node.type?.name === "run") {
19418
+ node.forEach((child, offset2) => {
19419
+ const childPos = basePos + offset2 + 1;
19420
+ walk(child, childPos);
19421
+ });
19422
+ return;
19423
+ }
19424
+ entries.push({ node, pos: basePos - 1 });
19425
+ };
19426
+ paragraph.forEach((child, offset2) => {
19427
+ const childPos = paragraphStartPos + offset2 + 1;
19428
+ walk(child, childPos);
19429
+ });
19430
+ return entries;
19431
+ }
19432
+ function findNextTabIndex(flattened, fromIndex) {
19433
+ for (let i = fromIndex; i < flattened.length; i++) {
19434
+ if (flattened[i]?.node?.type?.name === "tab") {
19435
+ return i;
19436
+ }
19437
+ }
19438
+ return -1;
19439
+ }
19440
+ function findDecimalBreakPos(flattened, startIndex, breakChar) {
19441
+ for (let i = startIndex; i < flattened.length; i++) {
19442
+ const entry = flattened[i];
19443
+ if (!entry) break;
19444
+ if (entry.node.type?.name === "tab") break;
19445
+ if (entry.node.type?.name === "text") {
19446
+ const index2 = entry.node.text?.indexOf(breakChar);
19447
+ if (index2 !== void 0 && index2 !== -1) {
19448
+ return entry.pos + index2 + 1;
19449
+ }
19450
+ }
19451
+ }
19452
+ return null;
19453
+ }
19454
+ function measureRangeWidth(view, from2, to) {
19455
+ if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
19456
+ try {
19457
+ const range = document.createRange();
19458
+ const fromRef = view.domAtPos(from2);
19459
+ const toRef = view.domAtPos(to);
19460
+ range.setStart(fromRef.node, fromRef.offset);
19461
+ range.setEnd(toRef.node, toRef.offset);
19462
+ const rect = range.getBoundingClientRect();
19463
+ range.detach?.();
19464
+ return rect.width || 0;
19465
+ } catch {
19466
+ const startLeft = getLeftCoord(view, from2);
19467
+ const endLeft = getLeftCoord(view, to);
19468
+ if (startLeft == null || endLeft == null) return 0;
19469
+ return Math.max(0, endLeft - startLeft);
19470
+ }
19471
+ }
19472
+ function getIndentWidth(view, paragraphStartPos, indentAttrs = {}) {
19473
+ const marginLeft = getLeftCoord(view, paragraphStartPos);
19474
+ const lineLeft = getLeftCoord(view, paragraphStartPos + 1);
19475
+ if (marginLeft != null && lineLeft != null) {
19476
+ const diff = lineLeft - marginLeft;
19477
+ if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
19478
+ return diff;
19479
+ }
19480
+ }
19481
+ return calculateIndentFallback(indentAttrs);
19482
+ }
19483
+ function calculateIndentFallback(indentAttrs = {}) {
19484
+ if (!indentAttrs) return 0;
19485
+ const left2 = Number(indentAttrs.left) || 0;
19486
+ const firstLine = Number(indentAttrs.firstLine) || 0;
19487
+ const hanging = Number(indentAttrs.hanging) || 0;
19488
+ let textIndent = 0;
19489
+ if (firstLine && hanging) {
19490
+ textIndent = firstLine - hanging;
19491
+ } else if (firstLine) {
19492
+ textIndent = firstLine;
19493
+ } else if (hanging) {
19494
+ textIndent = -hanging;
19495
+ } else if (typeof indentAttrs.textIndent === "string") {
19496
+ const match = indentAttrs.textIndent.match(/(-?\d*\.?\d+)in$/);
19497
+ if (match) {
19498
+ textIndent = Number(match[1]) * 96;
19499
+ }
19500
+ }
19501
+ if (textIndent) return left2 + textIndent;
19502
+ if (left2) return left2;
19503
+ return 0;
19504
+ }
19505
+ function getLeftCoord(view, pos) {
19506
+ if (!Number.isFinite(pos)) return null;
19507
+ try {
19508
+ return view.coordsAtPos(pos).left;
19509
+ } catch {
19510
+ try {
19511
+ const ref2 = view.domAtPos(pos);
19512
+ const range = document.createRange();
19513
+ range.setStart(ref2.node, ref2.offset);
19514
+ range.setEnd(ref2.node, ref2.offset);
19515
+ const rect = range.getBoundingClientRect();
19516
+ range.detach?.();
19517
+ return rect.left;
19518
+ } catch {
19519
+ return null;
19520
+ }
19521
+ }
19522
+ }
19523
+ function calcTabHeight(pos) {
19524
+ const ptToPxRatio = 1.333;
19525
+ const defaultFontSize = 16;
19526
+ const defaultLineHeight = 1.1;
19527
+ const blockParent2 = pos.node(1);
19528
+ const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
19529
+ const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
19530
+ return `${fontSize * defaultLineHeight}px`;
19531
+ }
18857
19532
  const TabNode = Node$1.create({
18858
19533
  name: "tab",
18859
19534
  group: "inline",
@@ -18891,8 +19566,7 @@ const TabNode = Node$1.create({
18891
19566
  };
18892
19567
  },
18893
19568
  addPmPlugins() {
18894
- const { view, schema } = this.editor;
18895
- const domSerializer = DOMSerializer.fromSchema(schema);
19569
+ const { view } = this.editor;
18896
19570
  const tabPlugin = new Plugin({
18897
19571
  name: "tabPlugin",
18898
19572
  key: new PluginKey("tabPlugin"),
@@ -18902,10 +19576,7 @@ const TabNode = Node$1.create({
18902
19576
  },
18903
19577
  apply(tr, { decorations }, _oldState, newState) {
18904
19578
  if (!decorations) {
18905
- decorations = DecorationSet.create(
18906
- newState.doc,
18907
- getTabDecorations(newState.doc, StepMap.empty, view, domSerializer)
18908
- );
19579
+ decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
18909
19580
  }
18910
19581
  if (!tr.docChanged) {
18911
19582
  return { decorations };
@@ -18945,8 +19616,7 @@ const TabNode = Node$1.create({
18945
19616
  rangesToRecalculate.forEach(([start2, end2]) => {
18946
19617
  const oldDecorations = decorations.find(start2, end2);
18947
19618
  decorations = decorations.remove(oldDecorations);
18948
- const invertMapping = tr.mapping.invert();
18949
- const newDecorations = getTabDecorations(newState.doc, invertMapping, view, domSerializer, start2, end2);
19619
+ const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
18950
19620
  decorations = decorations.add(newState.doc, newDecorations);
18951
19621
  });
18952
19622
  return { decorations };
@@ -18961,156 +19631,6 @@ const TabNode = Node$1.create({
18961
19631
  return [tabPlugin];
18962
19632
  }
18963
19633
  });
18964
- const defaultTabDistance = 48;
18965
- const defaultLineLength = 816;
18966
- const getTabDecorations = (doc2, invertMapping, view, domSerializer, from2 = 0, to = null) => {
18967
- if (!to) {
18968
- to = doc2.content.size;
18969
- }
18970
- const nodeWidthCache = {};
18971
- let decorations = [];
18972
- doc2.nodesBetween(from2, to, (node, pos, parent) => {
18973
- if (node.type.name === "tab") {
18974
- let extraStyles = "";
18975
- const $pos = doc2.resolve(pos);
18976
- const tabIndex = $pos.index($pos.depth);
18977
- const fistlineIndent = parent.attrs?.indent?.firstLine || 0;
18978
- const currentWidth = calcChildNodesWidth(
18979
- parent,
18980
- pos - $pos.parentOffset,
18981
- 0,
18982
- tabIndex,
18983
- domSerializer,
18984
- view,
18985
- invertMapping,
18986
- nodeWidthCache
18987
- ) + fistlineIndent;
18988
- let tabWidth;
18989
- if ($pos.depth === 1 && parent.attrs.tabStops && parent.attrs.tabStops.length > 0) {
18990
- const tabStop = parent.attrs.tabStops.find((tabStop2) => tabStop2.pos > currentWidth && tabStop2.val !== "clear");
18991
- if (tabStop) {
18992
- tabWidth = tabStop.pos - currentWidth;
18993
- if (["end", "center"].includes(tabStop.val)) {
18994
- let nextTabIndex = tabIndex + 1;
18995
- while (nextTabIndex < parent.childCount && parent.child(nextTabIndex).type.name !== "tab") {
18996
- nextTabIndex++;
18997
- }
18998
- const tabSectionWidth = calcChildNodesWidth(
18999
- parent,
19000
- pos - $pos.parentOffset,
19001
- tabIndex,
19002
- nextTabIndex,
19003
- domSerializer,
19004
- view,
19005
- invertMapping,
19006
- nodeWidthCache
19007
- );
19008
- tabWidth -= tabStop.val === "end" ? tabSectionWidth : tabSectionWidth / 2;
19009
- } else if (["decimal", "num"].includes(tabStop.val)) {
19010
- const breakChar = ".";
19011
- let nodeIndex = tabIndex + 1;
19012
- let integralWidth = 0;
19013
- let nodePos = pos - $pos.parentOffset;
19014
- while (nodeIndex < parent.childCount) {
19015
- const node2 = parent.child(nodeIndex);
19016
- if (node2.type.name === "tab") {
19017
- break;
19018
- }
19019
- const oldPos = invertMapping.map(nodePos);
19020
- if (node2.type.name === "text" && node2.text.includes(breakChar)) {
19021
- const modifiedNode = node2.cut(0, node2.text.indexOf(breakChar));
19022
- integralWidth += calcNodeWidth(domSerializer, modifiedNode, view, oldPos);
19023
- break;
19024
- }
19025
- integralWidth += calcNodeWidth(domSerializer, node2, view, oldPos);
19026
- nodeWidthCache[nodePos] = integralWidth;
19027
- nodePos += node2.nodeSize;
19028
- nodeIndex += 1;
19029
- }
19030
- tabWidth -= integralWidth;
19031
- }
19032
- if (tabStop.leader) {
19033
- if (tabStop.leader === "dot") {
19034
- extraStyles += `border-bottom: 1px dotted black;`;
19035
- } else if (tabStop.leader === "heavy") {
19036
- extraStyles += `border-bottom: 2px solid black;`;
19037
- } else if (tabStop.leader === "hyphen") {
19038
- extraStyles += `border-bottom: 1px solid black;`;
19039
- } else if (tabStop.leader === "middleDot") {
19040
- extraStyles += `border-bottom: 1px dotted black; margin-bottom: 2px;`;
19041
- } else if (tabStop.leader === "underscore") {
19042
- extraStyles += `border-bottom: 1px solid black;`;
19043
- }
19044
- }
19045
- }
19046
- }
19047
- if (!tabWidth || tabWidth < 1) {
19048
- tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
19049
- if (tabWidth === 0) {
19050
- tabWidth = defaultTabDistance;
19051
- }
19052
- }
19053
- nodeWidthCache[pos] = tabWidth;
19054
- const tabHeight = calcTabHeight($pos);
19055
- decorations.push(
19056
- Decoration.node(pos, pos + node.nodeSize, {
19057
- style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
19058
- })
19059
- );
19060
- }
19061
- });
19062
- return decorations;
19063
- };
19064
- function calcNodeWidth(domSerializer, node, view, oldPos) {
19065
- const oldDomNode = view.nodeDOM(oldPos);
19066
- const styleReference = oldDomNode ? oldDomNode.nodeName === "#text" ? oldDomNode.parentNode : oldDomNode : view.dom;
19067
- const temp = document.createElement("div");
19068
- const style = window.getComputedStyle(styleReference);
19069
- temp.style.cssText = `
19070
- position: absolute;
19071
- top: -9999px;
19072
- left: -9999px;
19073
- white-space: nowrap;
19074
- font-family: ${style.fontFamily};
19075
- font-size: ${style.fontSize};
19076
- font-weight: ${style.fontWeight};
19077
- font-style: ${style.fontStyle};
19078
- letter-spacing: ${style.letterSpacing};
19079
- word-spacing: ${style.wordSpacing};
19080
- text-transform: ${style.textTransform};
19081
- display: inline-block;
19082
- `;
19083
- const domNode = domSerializer.serializeNode(node);
19084
- temp.appendChild(domNode);
19085
- document.body.appendChild(temp);
19086
- const width = temp.offsetWidth;
19087
- document.body.removeChild(temp);
19088
- return width;
19089
- }
19090
- function calcChildNodesWidth(parent, parentPos, startIndex, endIndex, domSerializer, view, invertMapping, nodeWidthCache) {
19091
- let pos = parentPos;
19092
- let width = 0;
19093
- for (let i = 0; i < endIndex; i++) {
19094
- const node = parent.child(i);
19095
- if (i >= startIndex) {
19096
- if (!nodeWidthCache[pos]) {
19097
- nodeWidthCache[pos] = calcNodeWidth(domSerializer, node, view, invertMapping.map(pos));
19098
- }
19099
- width += nodeWidthCache[pos];
19100
- }
19101
- pos += node.nodeSize;
19102
- }
19103
- return width;
19104
- }
19105
- function calcTabHeight(pos) {
19106
- const ptToPxRatio = 1.333;
19107
- const defaultFontSize = 16;
19108
- const defaultLineHeight = 1.1;
19109
- const blockParent2 = pos.node(1);
19110
- const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
19111
- const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
19112
- return `${fontSize * defaultLineHeight}px`;
19113
- }
19114
19634
  const LineBreak = Node$1.create({
19115
19635
  name: "lineBreak",
19116
19636
  group: "inline",
@@ -24777,10 +25297,10 @@ const Image = Node$1.create({
24777
25297
  },
24778
25298
  padding: {
24779
25299
  default: {},
24780
- renderDOM: ({ size = {}, padding, marginOffset, transformData }) => {
25300
+ renderDOM: ({ size = {}, padding, marginOffset, transformData = {} }) => {
24781
25301
  let { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
24782
- const { rotation } = transformData ?? {};
24783
- const { height, width } = size ?? {};
25302
+ const { rotation } = transformData;
25303
+ const { height, width } = size;
24784
25304
  if (rotation && height && width) {
24785
25305
  const { horizontal, vertical } = getRotationMargins(width, height, rotation);
24786
25306
  left2 += horizontal;
@@ -26571,6 +27091,30 @@ const TextStyle = Mark.create({
26571
27091
  };
26572
27092
  }
26573
27093
  });
27094
+ function createCascadeToggleCommands({
27095
+ markName,
27096
+ setCommand,
27097
+ unsetCommand,
27098
+ toggleCommand,
27099
+ negationAttrs,
27100
+ isNegation,
27101
+ extendEmptyMarkRange
27102
+ } = {}) {
27103
+ if (!markName) throw new Error("createCascadeToggleCommands requires a markName");
27104
+ const capitalized = markName.charAt(0).toUpperCase() + markName.slice(1);
27105
+ const setName = setCommand ?? `set${capitalized}`;
27106
+ const unsetName = unsetCommand ?? `unset${capitalized}`;
27107
+ const toggleName = toggleCommand ?? `toggle${capitalized}`;
27108
+ const cascadeOptions = {};
27109
+ if (negationAttrs) cascadeOptions.negationAttrs = negationAttrs;
27110
+ if (typeof isNegation === "function") cascadeOptions.isNegation = isNegation;
27111
+ if (extendEmptyMarkRange !== void 0) cascadeOptions.extendEmptyMarkRange = extendEmptyMarkRange;
27112
+ return {
27113
+ [setName]: () => ({ commands: commands2 }) => commands2.setMark(markName),
27114
+ [unsetName]: () => ({ commands: commands2 }) => commands2.unsetMark(markName),
27115
+ [toggleName]: () => ({ commands: commands2 }) => commands2.toggleMarkCascade(markName, cascadeOptions)
27116
+ };
27117
+ }
26574
27118
  const Bold = Mark.create({
26575
27119
  name: "bold",
26576
27120
  addOptions() {
@@ -26601,9 +27145,18 @@ const Bold = Mark.create({
26601
27145
  ];
26602
27146
  },
26603
27147
  renderDOM({ htmlAttributes }) {
26604
- return ["strong", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
27148
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
27149
+ const { value, ...rest } = merged || {};
27150
+ if (value === "0") {
27151
+ return ["span", rest, 0];
27152
+ }
27153
+ return ["strong", rest, 0];
26605
27154
  },
26606
27155
  addCommands() {
27156
+ const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
27157
+ markName: this.name,
27158
+ negationAttrs: { value: "0" }
27159
+ });
26607
27160
  return {
26608
27161
  /**
26609
27162
  * Apply bold formatting
@@ -26612,21 +27165,21 @@ const Bold = Mark.create({
26612
27165
  * editor.commands.setBold()
26613
27166
  * @note '0' renders as normal weight
26614
27167
  */
26615
- setBold: () => ({ commands: commands2 }) => commands2.setMark(this.name),
27168
+ setBold,
26616
27169
  /**
26617
27170
  * Remove bold formatting
26618
27171
  * @category Command
26619
27172
  * @example
26620
27173
  * editor.commands.unsetBold()
26621
27174
  */
26622
- unsetBold: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
27175
+ unsetBold,
26623
27176
  /**
26624
27177
  * Toggle bold formatting
26625
27178
  * @category Command
26626
27179
  * @example
26627
27180
  * editor.commands.toggleBold()
26628
27181
  */
26629
- toggleBold: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
27182
+ toggleBold
26630
27183
  };
26631
27184
  },
26632
27185
  addShortcuts() {
@@ -26643,6 +27196,22 @@ const Italic = Mark.create({
26643
27196
  htmlAttributes: {}
26644
27197
  };
26645
27198
  },
27199
+ addAttributes() {
27200
+ return {
27201
+ /**
27202
+ * @category Attribute
27203
+ * @param {string} [value] - Italic toggle value ('0' renders as normal)
27204
+ */
27205
+ value: {
27206
+ default: null,
27207
+ renderDOM: (attrs) => {
27208
+ if (!attrs.value) return {};
27209
+ if (attrs.value === "0") return { style: "font-style: normal" };
27210
+ return {};
27211
+ }
27212
+ }
27213
+ };
27214
+ },
26646
27215
  parseDOM() {
26647
27216
  return [
26648
27217
  { tag: "i" },
@@ -26652,9 +27221,18 @@ const Italic = Mark.create({
26652
27221
  ];
26653
27222
  },
26654
27223
  renderDOM({ htmlAttributes }) {
26655
- return ["em", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
27224
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
27225
+ const { value, ...rest } = merged || {};
27226
+ if (value === "0") {
27227
+ return ["span", rest, 0];
27228
+ }
27229
+ return ["em", rest, 0];
26656
27230
  },
26657
27231
  addCommands() {
27232
+ const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
27233
+ markName: this.name,
27234
+ negationAttrs: { value: "0" }
27235
+ });
26658
27236
  return {
26659
27237
  /**
26660
27238
  * Apply italic formatting
@@ -26662,21 +27240,21 @@ const Italic = Mark.create({
26662
27240
  * @example
26663
27241
  * editor.commands.setItalic()
26664
27242
  */
26665
- setItalic: () => ({ commands: commands2 }) => commands2.setMark(this.name),
27243
+ setItalic,
26666
27244
  /**
26667
27245
  * Remove italic formatting
26668
27246
  * @category Command
26669
27247
  * @example
26670
27248
  * editor.commands.unsetItalic()
26671
27249
  */
26672
- unsetItalic: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
27250
+ unsetItalic,
26673
27251
  /**
26674
27252
  * Toggle italic formatting
26675
27253
  * @category Command
26676
27254
  * @example
26677
27255
  * editor.commands.toggleItalic()
26678
27256
  */
26679
- toggleItalic: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
27257
+ toggleItalic
26680
27258
  };
26681
27259
  },
26682
27260
  addShortcuts() {
@@ -26701,7 +27279,16 @@ const Underline = Mark.create({
26701
27279
  ];
26702
27280
  },
26703
27281
  renderDOM({ htmlAttributes }) {
26704
- return ["u", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
27282
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
27283
+ const type = merged?.underlineType;
27284
+ const color = merged?.underlineColor;
27285
+ const css = getUnderlineCssString({ type, color });
27286
+ const { style, ...rest } = merged || {};
27287
+ const styleString = [style, css].filter(Boolean).join("; ");
27288
+ if (type === "none") {
27289
+ return ["span", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
27290
+ }
27291
+ return ["u", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
26705
27292
  },
26706
27293
  addAttributes() {
26707
27294
  return {
@@ -26711,10 +27298,18 @@ const Underline = Mark.create({
26711
27298
  */
26712
27299
  underlineType: {
26713
27300
  default: "single"
27301
+ },
27302
+ underlineColor: {
27303
+ default: null
26714
27304
  }
26715
27305
  };
26716
27306
  },
26717
27307
  addCommands() {
27308
+ const { setUnderline, unsetUnderline, toggleUnderline } = createCascadeToggleCommands({
27309
+ markName: this.name,
27310
+ negationAttrs: { underlineType: "none" },
27311
+ isNegation: (attrs) => attrs?.underlineType === "none"
27312
+ });
26718
27313
  return {
26719
27314
  /**
26720
27315
  * Apply underline formatting
@@ -26723,7 +27318,7 @@ const Underline = Mark.create({
26723
27318
  * @example
26724
27319
  * setUnderline()
26725
27320
  */
26726
- setUnderline: () => ({ commands: commands2 }) => commands2.setMark(this.name),
27321
+ setUnderline,
26727
27322
  /**
26728
27323
  * Remove underline formatting
26729
27324
  * @category Command
@@ -26731,7 +27326,7 @@ const Underline = Mark.create({
26731
27326
  * @example
26732
27327
  * unsetUnderline()
26733
27328
  */
26734
- unsetUnderline: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
27329
+ unsetUnderline,
26735
27330
  /**
26736
27331
  * Toggle underline formatting
26737
27332
  * @category Command
@@ -26739,7 +27334,7 @@ const Underline = Mark.create({
26739
27334
  * @example
26740
27335
  * toggleUnderline()
26741
27336
  */
26742
- toggleUnderline: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
27337
+ toggleUnderline
26743
27338
  };
26744
27339
  },
26745
27340
  addShortcuts() {
@@ -26827,9 +27422,18 @@ const Strike = Mark.create({
26827
27422
  ];
26828
27423
  },
26829
27424
  renderDOM({ htmlAttributes }) {
26830
- return ["s", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
27425
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
27426
+ const { value, ...rest } = merged || {};
27427
+ if (value === "0") {
27428
+ return ["span", rest, 0];
27429
+ }
27430
+ return ["s", rest, 0];
26831
27431
  },
26832
27432
  addCommands() {
27433
+ const { setStrike, unsetStrike, toggleStrike } = createCascadeToggleCommands({
27434
+ markName: this.name,
27435
+ negationAttrs: { value: "0" }
27436
+ });
26833
27437
  return {
26834
27438
  /**
26835
27439
  * Apply strikethrough formatting
@@ -26837,26 +27441,38 @@ const Strike = Mark.create({
26837
27441
  * @example
26838
27442
  * editor.commands.setStrike()
26839
27443
  */
26840
- setStrike: () => ({ commands: commands2 }) => {
26841
- return commands2.setMark(this.name);
26842
- },
27444
+ setStrike,
26843
27445
  /**
26844
27446
  * Remove strikethrough formatting
26845
27447
  * @category Command
26846
27448
  * @example
26847
27449
  * editor.commands.unsetStrike()
26848
27450
  */
26849
- unsetStrike: () => ({ commands: commands2 }) => {
26850
- return commands2.unsetMark(this.name);
26851
- },
27451
+ unsetStrike,
26852
27452
  /**
26853
27453
  * Toggle strikethrough formatting
26854
27454
  * @category Command
26855
27455
  * @example
26856
27456
  * editor.commands.toggleStrike()
26857
27457
  */
26858
- toggleStrike: () => ({ commands: commands2 }) => {
26859
- return commands2.toggleMark(this.name);
27458
+ toggleStrike
27459
+ };
27460
+ },
27461
+ addAttributes() {
27462
+ return {
27463
+ /**
27464
+ * @category Attribute
27465
+ * @param {string} [value] - Strike toggle value ('0' renders as normal)
27466
+ */
27467
+ value: {
27468
+ default: null,
27469
+ renderDOM: (attrs) => {
27470
+ if (!attrs.value) return {};
27471
+ if (attrs.value === "0") {
27472
+ return { style: "text-decoration: none" };
27473
+ }
27474
+ return {};
27475
+ }
26860
27476
  }
26861
27477
  };
26862
27478
  },
@@ -32997,7 +33613,7 @@ const getStarterExtensions = () => {
32997
33613
  Paragraph,
32998
33614
  LineBreak,
32999
33615
  HardBreak,
33000
- RunItem,
33616
+ Run,
33001
33617
  SlashMenu,
33002
33618
  Strike,
33003
33619
  TabNode,