@harbour-enterprises/superdoc 0.17.3 → 0.18.0-next.10

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 (98) hide show
  1. package/dist/chunks/{PdfViewer-B5bEH-lD.cjs → PdfViewer-DKOAmiXw.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-P3OSs9iX.es.js → PdfViewer-OIo9wAyq.es.js} +1 -1
  3. package/dist/chunks/{index-CHQbeTTv.es.js → index-DEONStGL.es.js} +4 -3
  4. package/dist/chunks/{index-LZjTD5KG.cjs → index-cCWdcGrV.cjs} +4 -3
  5. package/dist/chunks/{super-editor.es-C-nn3bMY.es.js → super-editor.es-Cx5l8JEt.es.js} +4350 -3412
  6. package/dist/chunks/{super-editor.es-D8CRzfwC.cjs → super-editor.es-DyAWPYYh.cjs} +4349 -3411
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/index.d.ts +2 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/super-editor/ai-writer.es.js +2 -2
  11. package/dist/super-editor/chunks/{converter-Bcg2-svq.js → converter-5WOzOHZb.js} +4396 -3862
  12. package/dist/super-editor/chunks/{docx-zipper-X-fYIxPZ.js → docx-zipper-CP-vEy49.js} +1 -1
  13. package/dist/super-editor/chunks/{editor-D4fBb3em.js → editor-CCOqTxyv.js} +454 -42
  14. package/dist/super-editor/chunks/{toolbar-C6KdVRS2.js → toolbar-DjjHAttK.js} +2 -2
  15. package/dist/super-editor/converter.es.js +3 -2
  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/core/commands/insertContent.d.ts +4 -4
  20. package/dist/super-editor/src/core/helpers/contentProcessor.d.ts +13 -0
  21. package/dist/super-editor/src/core/helpers/htmlSanitizer.d.ts +8 -0
  22. package/dist/super-editor/src/core/helpers/importHtml.d.ts +3 -2
  23. package/dist/super-editor/src/core/helpers/importMarkdown.d.ts +2 -1
  24. package/dist/super-editor/src/core/helpers/index.d.ts +1 -0
  25. package/dist/super-editor/src/core/super-converter/docx-helpers/get-default-style-definition.d.ts +1 -0
  26. package/dist/super-editor/src/core/super-converter/docx-helpers/index.d.ts +1 -0
  27. package/dist/super-editor/src/core/super-converter/exporter.d.ts +19 -2
  28. package/dist/super-editor/src/core/super-converter/v2/importer/docxImporter.d.ts +2 -1
  29. package/dist/super-editor/src/core/super-converter/v2/importer/index.d.ts +2 -0
  30. package/dist/super-editor/src/core/super-converter/v2/importer/lineBreakImporter.d.ts +3 -5
  31. package/dist/super-editor/src/core/super-converter/v2/importer/paragraphNodeImporter.d.ts +3 -63
  32. package/dist/super-editor/src/core/super-converter/v2/importer/tabImporter.d.ts +2 -1
  33. package/dist/super-editor/src/core/super-converter/v2/importer/tableImporter.d.ts +17 -6
  34. package/dist/super-editor/src/core/super-converter/v2/importer/types/index.d.ts +73 -0
  35. package/dist/super-editor/src/core/super-converter/v2/types/index.d.ts +8 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +9 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/br/attributes/index.d.ts +2 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/br/attributes/w-clear.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/br/attributes/w-line-break-type.d.ts +4 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/br/br-translator.d.ts +7 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/br/index.d.ts +1 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/index.d.ts +2 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w-rsid-del.d.ts +4 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w-rsid-p.d.ts +4 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w-rsid-r-default.d.ts +4 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w-rsid-r-pr.d.ts +4 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w-rsid-r.d.ts +4 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w14-para-id.d.ts +4 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/attributes/w14-text-id.d.ts +4 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/index.d.ts +1 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/legacy-handle-paragraph-node.d.ts +1 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/w-p-helpers.d.ts +6 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/index.d.ts +1 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/p-translator.d.ts +7 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/attributes/index.d.ts +2 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/attributes/w-tab-leader.d.ts +4 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/attributes/w-tab-pos.d.ts +4 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/attributes/w-tab-size.d.ts +4 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/index.d.ts +1 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tab/tab-translator.d.ts +7 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tc/helpers/legacy-handle-table-cell-node.d.ts +9 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tc/helpers/translate-table-cell.d.ts +17 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tc/index.d.ts +1 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tc/tc-translator.d.ts +6 -0
  65. package/dist/super-editor/src/core/super-converter/v3/node-translator/index.d.ts +1 -0
  66. package/dist/super-editor/src/core/super-converter/v3/node-translator/node-translator.d.ts +203 -0
  67. package/dist/super-editor/src/extensions/block-node/block-node.d.ts +27 -4
  68. package/dist/super-editor/src/extensions/color/color.d.ts +1 -1
  69. package/dist/super-editor/src/extensions/dropcursor/dropcursor.d.ts +5 -0
  70. package/dist/super-editor/src/extensions/gapcursor/gapcursor.d.ts +5 -0
  71. package/dist/super-editor/src/extensions/image/image.d.ts +5 -0
  72. package/dist/super-editor/src/extensions/image/imageHelpers/getFileOpener.d.ts +1 -1
  73. package/dist/super-editor/src/extensions/image/imageHelpers/handleImageUpload.d.ts +1 -1
  74. package/dist/super-editor/src/extensions/image/imageHelpers/imagePlaceholderPlugin.d.ts +2 -3
  75. package/dist/super-editor/src/extensions/image/imageHelpers/imagePositionPlugin.d.ts +1 -2
  76. package/dist/super-editor/src/extensions/image/imageHelpers/processUploadedImage.d.ts +2 -5
  77. package/dist/super-editor/src/extensions/image/imageHelpers/startImageUpload.d.ts +18 -3
  78. package/dist/super-editor/src/extensions/linked-styles/helpers.d.ts +4 -6
  79. package/dist/super-editor/src/extensions/linked-styles/linked-styles.d.ts +29 -0
  80. package/dist/super-editor/src/extensions/linked-styles/plugin.d.ts +4 -2
  81. package/dist/super-editor/src/extensions/paragraph/paragraph.d.ts +2 -2
  82. package/dist/super-editor/src/extensions/text-align/text-align.d.ts +9 -0
  83. package/dist/super-editor/src/extensions/text-indent/text-indent.d.ts +19 -0
  84. package/dist/super-editor/src/extensions/text-transform/text-transform.d.ts +5 -0
  85. package/dist/super-editor/src/index.d.ts +2 -1
  86. package/dist/super-editor/src/tests/export/export-helpers/export-helpers.d.ts +1 -0
  87. package/dist/super-editor/super-editor.es.js +24 -18
  88. package/dist/super-editor/toolbar.es.js +2 -2
  89. package/dist/super-editor.cjs +2 -1
  90. package/dist/super-editor.es.js +2 -1
  91. package/dist/superdoc.cjs +3 -2
  92. package/dist/superdoc.es.js +3 -2
  93. package/dist/superdoc.umd.js +4488 -3549
  94. package/dist/superdoc.umd.js.map +1 -1
  95. package/package.json +1 -1
  96. package/dist/super-editor/src/core/super-converter/v2/handlers/index.d.ts +0 -1
  97. package/dist/super-editor/src/extensions/field-annotation/field-annotation-marks-impl.d.ts +0 -5
  98. /package/dist/super-editor/src/{extensions/document-attributes → core/super-converter/v3/handlers/types}/index.d.ts +0 -0
@@ -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, 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, c as callOrGet, g as getExtensionConfigField, b as getMarkType, d as getMarksFromSelection, e as getNodeType, f as getSchemaTypeNameByName, S as Schema$1, h as cleanSchemaItem, T as TextSelection, N as NodeSelection, i as canSplit, j as defaultBlockAt$1, l as liftTarget, A as AllSelection, k as canJoin, m as joinPoint, n as Selection, r as replaceStep$1, F as Fragment, R as ReplaceAroundStep$1, o as Slice, p as isTextSelection, q as getMarkRange, s as isMarkActive, t as isNodeActive, u as deleteProps, D as DOMParser$1, v as ReplaceStep, w as NodeRange, x as findWrapping, L as ListHelpers, y as findParentNode, z as isMacOS, B as isIOS, C as DOMSerializer, E as Mark$1, G as dropPoint, H as process$1, I as Buffer2, J as getSchemaTypeByName, K as inputRulesPlugin, O as TrackDeleteMarkName, Q as TrackInsertMarkName, U as v4, V as TrackFormatMarkName, W as comments_module_events, X as findMark, Y as objectIncludes, Z as AddMarkStep, _ as RemoveMarkStep, $ as twipsToLines, a0 as pixelsToTwips, a1 as helpers, a2 as posToDOMRect, a3 as CommandService, a4 as SuperConverter, a5 as createDocument, a6 as createDocFromMarkdown, a7 as createDocFromHTML, a8 as EditorState, a9 as hasSomeParentWithClass, aa as isActive, ab as unflattenListsInHtml, ac as parseSizeUnit, ad as minMax, ae as getLineHeightValueString, af as InputRule, ag as kebabCase, ah as findParentNodeClosestToPos, ai as getListItemStyleDefinitions, aj as docxNumberigHelpers, ak as parseIndentElement, al as combineIndents, am as StepMap, an as getColStyleDeclaration, ao as SelectionRange, ap as Transform, aq as isInTable$1, ar as createColGroup, as as generateDocxRandomId, at as insertNewRelationship, au as htmlHandler } from "./converter-Bcg2-svq.js";
15
+ import { P as PluginKey, a as Plugin, M as Mapping, c as callOrGet, g as getExtensionConfigField, b as getMarkType, d as getMarksFromSelection, e as getNodeType, f as getSchemaTypeNameByName, S as Schema$1, h as cleanSchemaItem, T as TextSelection, N as NodeSelection, i as canSplit, j as defaultBlockAt$1, l as liftTarget, A as AllSelection, k as canJoin, m as joinPoint, n as Selection, r as replaceStep$1, o as Slice, F as Fragment, R as ReplaceAroundStep$1, p as isTextSelection, q as getMarkRange, s as isMarkActive, t as isNodeActive, u as deleteProps, v as processContent, D as DOMParser$1, w as ReplaceStep, x as NodeRange, y as findWrapping, L as ListHelpers, z as findParentNode, B as isMacOS, C as isIOS, E as DOMSerializer, G as Mark$1, H as dropPoint, I as process$1, J as Buffer2, 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 getColStyleDeclaration, ap as SelectionRange, aq as Transform, ar as isInTable$1, as as createColGroup, at as generateDocxRandomId, au as insertNewRelationship, av as htmlHandler } from "./converter-5WOzOHZb.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-X-fYIxPZ.js";
17
+ import { D as DocxZipper } from "./docx-zipper-CP-vEy49.js";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
20
20
  };
@@ -1091,6 +1091,26 @@ createMarksSchema_fn = function(markExtensions, attributes, editor) {
1091
1091
  };
1092
1092
  __privateAdd(_Schema, _Schema_static);
1093
1093
  let Schema = _Schema;
1094
+ class OxmlNode extends Node$1 {
1095
+ /**
1096
+ * @param {import('./types/index.js').OxmlNodeConfig} config
1097
+ */
1098
+ constructor(config) {
1099
+ super(config);
1100
+ /** @type {string} */
1101
+ __publicField(this, "oXmlName");
1102
+ this.oXmlName = config.oXmlName;
1103
+ }
1104
+ /**
1105
+ * Factory method to construct a new OxmlNode instance.
1106
+ *
1107
+ * @param {import('./types/index.js').OxmlNodeConfig} config
1108
+ * @returns {OxmlNode} A new OxmlNode instance.
1109
+ */
1110
+ static create(config) {
1111
+ return new OxmlNode(config);
1112
+ }
1113
+ }
1094
1114
  const first = (commands2) => (props) => {
1095
1115
  const items = typeof commands2 === "function" ? commands2(props) : commands2;
1096
1116
  for (let i = 0; i < items.length; i += 1) {
@@ -1900,7 +1920,30 @@ const selectNodeBackward = () => ({ state, dispatch }) => {
1900
1920
  const selectNodeForward = () => ({ state, dispatch }) => selectNodeForward$1(state, dispatch);
1901
1921
  const selectTextblockStart = () => ({ state, dispatch }) => selectTextblockStart$1(state, dispatch);
1902
1922
  const selectTextblockEnd = () => ({ state, dispatch }) => selectTextblockEnd$1(state, dispatch);
1903
- const insertContent = (value, options) => ({ tr, commands: commands2 }) => {
1923
+ const insertContent = (value, options = {}) => ({ tr, state, commands: commands2, editor }) => {
1924
+ if (options.contentType) {
1925
+ const validTypes = ["html", "markdown", "text", "schema"];
1926
+ if (!validTypes.includes(options.contentType)) {
1927
+ console.error(`[insertContent] Invalid contentType: "${options.contentType}". Use: ${validTypes.join(", ")}`);
1928
+ return false;
1929
+ }
1930
+ try {
1931
+ const processedDoc = processContent({
1932
+ content: value,
1933
+ type: options.contentType,
1934
+ schema: state.schema
1935
+ });
1936
+ const jsonContent = processedDoc.toJSON();
1937
+ const ok = commands2.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, jsonContent, options);
1938
+ if (ok && (options.contentType === "html" || options.contentType === "markdown")) {
1939
+ Promise.resolve().then(() => editor.migrateListsToV2?.());
1940
+ }
1941
+ return ok;
1942
+ } catch (error) {
1943
+ console.error(`[insertContent] Failed to process ${options.contentType}:`, error);
1944
+ return false;
1945
+ }
1946
+ }
1904
1947
  return commands2.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value, options);
1905
1948
  };
1906
1949
  const removeWhitespaces = (node) => {
@@ -14353,7 +14396,7 @@ const _Editor = class _Editor extends EventEmitter {
14353
14396
  * @returns {Object | void} Migration results
14354
14397
  */
14355
14398
  processCollaborationMigrations() {
14356
- console.debug("[checkVersionMigrations] Current editor version", "0.17.2");
14399
+ console.debug("[checkVersionMigrations] Current editor version", "0.17.1");
14357
14400
  if (!this.options.ydoc) return;
14358
14401
  const metaMap = this.options.ydoc.getMap("meta");
14359
14402
  let docVersion = metaMap.get("version");
@@ -14780,8 +14823,8 @@ generatePmData_fn = function() {
14780
14823
  doc2 = createDocument(this.converter, this.schema, this);
14781
14824
  doc2 = __privateMethod(this, _Editor_instances, prepareDocumentForImport_fn).call(this, doc2);
14782
14825
  if (this.options.markdown) {
14783
- doc2 = createDocFromMarkdown(this.options.markdown, this.schema);
14784
- } else if (this.options.html) doc2 = createDocFromHTML(this.options.html, this.schema);
14826
+ doc2 = createDocFromMarkdown(this.options.markdown, this.schema, { isImport: true });
14827
+ } else if (this.options.html) doc2 = createDocFromHTML(this.options.html, this.schema, { isImport: true });
14785
14828
  else if (this.options.jsonOverride) doc2 = this.schema.nodeFromJSON(this.options.jsonOverride);
14786
14829
  if (fragment) doc2 = yXmlFragmentToProseMirrorRootNode(fragment, this.schema);
14787
14830
  }
@@ -15279,6 +15322,10 @@ const TextAlign = Extension.create({
15279
15322
  {
15280
15323
  types: this.options.types,
15281
15324
  attributes: {
15325
+ /**
15326
+ * @category Attribute
15327
+ * @param {string} [textAlign='left'] - Text alignment value (left, center, right, justify)
15328
+ */
15282
15329
  textAlign: {
15283
15330
  default: this.options.defaultAlignment,
15284
15331
  parseDOM: (el) => {
@@ -15299,11 +15346,32 @@ const TextAlign = Extension.create({
15299
15346
  },
15300
15347
  addCommands() {
15301
15348
  return {
15349
+ /**
15350
+ * Set text alignment
15351
+ * @category Command
15352
+ * @param {string} alignment - Alignment value (left, center, right, justify)
15353
+ * @returns {Function} Command function
15354
+ * @example
15355
+ * // Set to center
15356
+ * setTextAlign('center')
15357
+ *
15358
+ * // Set to justify
15359
+ * setTextAlign('justify')
15360
+ * @note Applies to all configured node types (heading, paragraph by default)
15361
+ */
15302
15362
  setTextAlign: (alignment) => ({ commands: commands2 }) => {
15303
15363
  const containsAlignment = this.options.alignments.includes(alignment);
15304
15364
  if (!containsAlignment) return false;
15305
15365
  return this.options.types.map((type) => commands2.updateAttributes(type, { textAlign: alignment })).every((result) => result);
15306
15366
  },
15367
+ /**
15368
+ * Remove text alignment (reset to default)
15369
+ * @category Command
15370
+ * @returns {Function} Command function
15371
+ * @example
15372
+ * unsetTextAlign()
15373
+ * @note Resets alignment to the default value
15374
+ */
15307
15375
  unsetTextAlign: () => ({ commands: commands2 }) => {
15308
15376
  return this.options.types.map((type) => commands2.resetAttributes(type, "textAlign")).every((result) => result);
15309
15377
  }
@@ -15334,6 +15402,10 @@ const TextIndent = Extension.create({
15334
15402
  {
15335
15403
  types: this.options.types,
15336
15404
  attributes: {
15405
+ /**
15406
+ * @category Attribute
15407
+ * @param {string} [textIndent] - Text indentation value with unit (e.g., '0.5in')
15408
+ */
15337
15409
  textIndent: {
15338
15410
  default: null,
15339
15411
  parseDOM: (el) => el.style.textIndent,
@@ -15351,13 +15423,43 @@ const TextIndent = Extension.create({
15351
15423
  },
15352
15424
  addCommands() {
15353
15425
  return {
15426
+ /**
15427
+ * Set text indentation
15428
+ * @category Command
15429
+ * @param {string} indent - Indentation value with unit (e.g., '0.5in', '2cm')
15430
+ * @returns {Function} Command function
15431
+ * @example
15432
+ * // Set to 0.5 inches
15433
+ * setTextIndent('0.5in')
15434
+ *
15435
+ * // Set to 2 centimeters
15436
+ * setTextIndent('2cm')
15437
+ * @note Accepts any valid CSS unit (in, cm, px, em, etc.)
15438
+ */
15354
15439
  setTextIndent: (indent) => ({ commands: commands2 }) => {
15355
15440
  if (!indent) return false;
15356
15441
  return this.options.types.map((type) => commands2.updateAttributes(type, { textIndent: indent })).every((result) => result);
15357
15442
  },
15443
+ /**
15444
+ * Remove text indentation
15445
+ * @category Command
15446
+ * @returns {Function} Command function
15447
+ * @example
15448
+ * unsetTextIndent()
15449
+ * @note Removes all indentation from the selected nodes
15450
+ */
15358
15451
  unsetTextIndent: () => ({ commands: commands2 }) => {
15359
15452
  return this.options.types.map((type) => commands2.resetAttributes(type, "textIndent")).every((result) => result);
15360
15453
  },
15454
+ /**
15455
+ * Increase text indentation
15456
+ * @category Command
15457
+ * @returns {Function} Command function
15458
+ * @example
15459
+ * increaseTextIndent()
15460
+ * @note Increments by the default value (0.125in by default)
15461
+ * @note Creates initial indent if none exists
15462
+ */
15361
15463
  increaseTextIndent: () => ({ commands: commands2 }) => {
15362
15464
  return this.options.types.map((type) => {
15363
15465
  let { textIndent } = this.editor.getAttributes(type);
@@ -15368,7 +15470,7 @@ const TextIndent = Extension.create({
15368
15470
  });
15369
15471
  }
15370
15472
  let [value, unit] = parseSizeUnit(textIndent);
15371
- value = value + this.options.defaults.increment;
15473
+ value = Number(value) + this.options.defaults.increment;
15372
15474
  unit = unit ? unit : this.options.defaults.unit;
15373
15475
  if (Number.isNaN(value)) return false;
15374
15476
  return commands2.updateAttributes(type, {
@@ -15376,12 +15478,21 @@ const TextIndent = Extension.create({
15376
15478
  });
15377
15479
  }).every((result) => result);
15378
15480
  },
15481
+ /**
15482
+ * Decrease text indentation
15483
+ * @category Command
15484
+ * @returns {Function} Command function
15485
+ * @example
15486
+ * decreaseTextIndent()
15487
+ * @note Decrements by the default value (0.125in by default)
15488
+ * @note Removes indentation completely if it reaches 0 or below
15489
+ */
15379
15490
  decreaseTextIndent: () => ({ commands: commands2 }) => {
15380
15491
  return this.options.types.map((type) => {
15381
15492
  let { textIndent } = this.editor.getAttributes(type);
15382
15493
  if (!textIndent) return false;
15383
15494
  let [value, unit] = parseSizeUnit(textIndent);
15384
- value = value - this.options.defaults.increment;
15495
+ value = Number(value) - this.options.defaults.increment;
15385
15496
  unit = unit ? unit : this.options.defaults.unit;
15386
15497
  if (Number.isNaN(value)) return false;
15387
15498
  if (value <= 0) {
@@ -15950,8 +16061,17 @@ const Gapcursor = Extension.create({
15950
16061
  addPmPlugins() {
15951
16062
  return [gapCursor()];
15952
16063
  },
16064
+ /**
16065
+ * Extend node schema to allow gap cursor positioning
16066
+ * @returns {Object} Schema extension with allowGapCursor property
16067
+ */
15953
16068
  extendNodeSchema(extension) {
15954
16069
  return {
16070
+ /**
16071
+ * Whether to allow gap cursor before/after this node
16072
+ * Set to false on nodes where gap cursor shouldn't appear
16073
+ * @type {boolean|null}
16074
+ */
15955
16075
  allowGapCursor: callOrGet(
15956
16076
  getExtensionConfigField(extension, "allowGapCursor", {
15957
16077
  name: extension.name,
@@ -17013,10 +17133,12 @@ const getLinkedStyle = (styleId, styles = []) => {
17013
17133
  };
17014
17134
  const getSpacingStyle = (spacing) => {
17015
17135
  const { lineSpaceBefore, lineSpaceAfter, line, lineRule } = spacing;
17136
+ const lineHeightResult = getLineHeightValueString(line, "", lineRule, true);
17137
+ const lineHeightStyles = typeof lineHeightResult === "object" && lineHeightResult !== null ? lineHeightResult : {};
17016
17138
  return {
17017
17139
  "margin-top": lineSpaceBefore + "px",
17018
17140
  "margin-bottom": lineSpaceAfter + "px",
17019
- ...getLineHeightValueString(line, "", lineRule, true)
17141
+ ...lineHeightStyles
17020
17142
  };
17021
17143
  };
17022
17144
  const getSpacingStyleString = (spacing) => {
@@ -17201,6 +17323,11 @@ const createLinkedStylesPlugin = (editor) => {
17201
17323
  return new Plugin({
17202
17324
  key: LinkedStylesPluginKey,
17203
17325
  state: {
17326
+ /**
17327
+ * Initialize plugin state with styles and decorations
17328
+ * @returns {Object} Initial state with styles and decorations
17329
+ * @private
17330
+ */
17204
17331
  init() {
17205
17332
  if (!editor.converter || editor.options.mode !== "docx") return {};
17206
17333
  const styles = editor.converter?.linkedStyles || [];
@@ -17209,6 +17336,15 @@ const createLinkedStylesPlugin = (editor) => {
17209
17336
  decorations: generateDecorations(editor.state, styles)
17210
17337
  };
17211
17338
  },
17339
+ /**
17340
+ * Update decorations when document changes
17341
+ * @param {Object} tr - The transaction
17342
+ * @param {Object} prev - Previous plugin state
17343
+ * @param {Object} oldEditorState - Old editor state
17344
+ * @param {Object} newEditorState - New editor state
17345
+ * @returns {Object} Updated state with styles and decorations
17346
+ * @private
17347
+ */
17212
17348
  apply(tr, prev, oldEditorState, newEditorState) {
17213
17349
  if (!editor.converter || editor.options.mode !== "docx") return { ...prev };
17214
17350
  let decorations = prev.decorations || DecorationSet.empty;
@@ -17220,6 +17356,12 @@ const createLinkedStylesPlugin = (editor) => {
17220
17356
  }
17221
17357
  },
17222
17358
  props: {
17359
+ /**
17360
+ * Provide decorations to the editor view
17361
+ * @param {Object} state - Current editor state
17362
+ * @returns {Object} The decoration set
17363
+ * @private
17364
+ */
17223
17365
  decorations(state) {
17224
17366
  return LinkedStylesPluginKey.getState(state)?.decorations;
17225
17367
  }
@@ -17261,24 +17403,35 @@ const LinkedStyles = Extension.create({
17261
17403
  addCommands() {
17262
17404
  return {
17263
17405
  /**
17264
- * Apply a linked style to the current selection.
17265
- *
17266
- * @param {object} style The linked style to apply
17267
- * @param {string} style.id The style ID (e.g., 'Heading1')
17268
- * @returns {boolean} Whether the style was correctly applied
17406
+ * Apply a linked style to the selected paragraphs
17407
+ * @category Command
17408
+ * @param {Object} style - The style object to apply
17409
+ * @returns {Function} Command function
17410
+ * @example
17411
+ * const style = editor.helpers.linkedStyles.getStyleById('Heading1');
17412
+ * setLinkedStyle(style);
17413
+ * @note Clears existing formatting when applying a style
17414
+ * @note Works with custom selection preservation
17269
17415
  */
17270
17416
  setLinkedStyle: (style) => (params2) => {
17271
17417
  const { tr } = params2;
17272
17418
  return applyLinkedStyleToTransaction(tr, this.editor, style);
17273
17419
  },
17274
17420
  /**
17275
- * Toggle a linked style on the current selection.
17421
+ * Toggle a linked style on the current selection
17422
+ * @category Command
17423
+ * @param {Object} style - The linked style to apply (with id property)
17424
+ * @param {string|null} [nodeType=null] - Node type to restrict toggle to (e.g., 'paragraph')
17425
+ * @returns {Function} Command function
17426
+ * @example
17427
+ * // Toggle a heading style
17428
+ * const style = editor.helpers.linkedStyles.getStyleById('Heading1');
17429
+ * toggleLinkedStyle(style)
17276
17430
  *
17277
- * @param {object} style The linked style to apply
17278
- * @param {string} style.id The style ID (e.g., 'Heading1')
17279
- * @param {string|null} nodeType The node type to restrict the toggle to (e.g., 'paragraph'). If null,
17280
- * the style can be toggled on any node type.
17281
- * @returns {boolean} Whether the style was correctly applied/removed
17431
+ * // Toggle only on paragraph nodes
17432
+ * toggleLinkedStyle(style, 'paragraph')
17433
+ * @note If selection is empty, returns false
17434
+ * @note Removes style if already applied, applies it if not
17282
17435
  */
17283
17436
  toggleLinkedStyle: (style, nodeType = null) => (params2) => {
17284
17437
  const { tr } = params2;
@@ -17301,9 +17454,17 @@ const LinkedStyles = Extension.create({
17301
17454
  return applyLinkedStyleToTransaction(tr, this.editor, style);
17302
17455
  },
17303
17456
  /**
17304
- * Apply a linked style by its ID.
17305
- * @param {string} styleId The style ID (e.g., 'Heading1')
17306
- * @returns {boolean} Whether the style was correctly applied
17457
+ * Apply a linked style by its ID
17458
+ * @category Command
17459
+ * @param {string} styleId - The style ID to apply (e.g., 'Heading1')
17460
+ * @returns {Function} Command function
17461
+ * @example
17462
+ * // Apply a heading style
17463
+ * setStyleById('Heading1')
17464
+ *
17465
+ * // Apply a normal style
17466
+ * setStyleById('Normal')
17467
+ * @note Looks up the style from loaded Word styles
17307
17468
  */
17308
17469
  setStyleById: (styleId) => (params2) => {
17309
17470
  const { state, tr } = params2;
@@ -17318,22 +17479,39 @@ const LinkedStyles = Extension.create({
17318
17479
  addHelpers() {
17319
17480
  return {
17320
17481
  /**
17321
- * Get all linked styles available in the editor
17482
+ * Get all available linked styles
17483
+ * @category Helper
17322
17484
  * @returns {Array} Array of linked style objects
17485
+ * @example
17486
+ * const styles = editor.helpers.linkedStyles.getStyles();
17487
+ * // Returns all styles from the Word document
17323
17488
  */
17324
17489
  getStyles: () => {
17325
17490
  const styles = LinkedStylesPluginKey.getState(this.editor.state)?.styles || [];
17326
17491
  return styles;
17327
17492
  },
17328
17493
  /**
17329
- * Get a linked style by its ID
17330
- * @param {string} styleId The style ID (e.g., 'Heading1')
17331
- * @returns {object|null} The linked style object or null if not found
17494
+ * Get a specific style by ID
17495
+ * @category Helper
17496
+ * @param {string} styleId - The style ID to find
17497
+ * @returns {Object} The style object or undefined
17498
+ * @example
17499
+ * const headingStyle = editor.helpers.linkedStyles.getStyleById('Heading1');
17332
17500
  */
17333
17501
  getStyleById: (styleId) => {
17334
17502
  const styles = this.editor.helpers[this.name].getStyles();
17335
17503
  return styles.find((s) => s.id === styleId);
17336
17504
  },
17505
+ /**
17506
+ * Get the CSS string for a style
17507
+ * @category Helper
17508
+ * @param {string} styleId - The style ID
17509
+ * @returns {string} CSS style string
17510
+ * @example
17511
+ * const css = editor.helpers.linkedStyles.getLinkedStyleString('Heading1');
17512
+ * // Returns: "font-size: 16pt; font-weight: bold; color: #2E74B5"
17513
+ * @private
17514
+ */
17337
17515
  getLinkedStyleString: (styleId) => {
17338
17516
  const styles = this.editor.helpers.linkedStyles.getStyles();
17339
17517
  const style = styles.find((s) => s.id === styleId);
@@ -17983,8 +18161,9 @@ const getDefaultSpacing = () => ({
17983
18161
  line: 0,
17984
18162
  lineRule: null
17985
18163
  });
17986
- const Paragraph = Node$1.create({
18164
+ const Paragraph = OxmlNode.create({
17987
18165
  name: "paragraph",
18166
+ oXmlName: "w:p",
17988
18167
  priority: 1e3,
17989
18168
  group: "block",
17990
18169
  content: "inline*",
@@ -18003,8 +18182,26 @@ const Paragraph = Node$1.create({
18003
18182
  },
18004
18183
  addAttributes() {
18005
18184
  return {
18185
+ paraId: { rendered: false },
18186
+ textId: { rendered: false },
18187
+ rsidR: { rendered: false },
18188
+ rsidRDefault: { rendered: false },
18189
+ rsidP: { rendered: false },
18190
+ rsidRPr: { rendered: false },
18191
+ rsidDel: { rendered: false },
18006
18192
  spacing: {
18007
18193
  default: getDefaultSpacing(),
18194
+ parseDOM: (element) => {
18195
+ if (element && element.closest("[data-superdoc-import]")) {
18196
+ return {
18197
+ lineSpaceAfter: 11,
18198
+ lineSpaceBefore: 0,
18199
+ line: 1.15,
18200
+ lineRule: "auto"
18201
+ };
18202
+ }
18203
+ return void 0;
18204
+ },
18008
18205
  renderDOM: (attrs) => {
18009
18206
  const { spacing } = attrs;
18010
18207
  if (!spacing) return {};
@@ -18101,7 +18298,6 @@ const Paragraph = Node$1.create({
18101
18298
  rendered: false
18102
18299
  },
18103
18300
  filename: { rendered: false },
18104
- rsidRDefault: { rendered: false },
18105
18301
  keepLines: { rendered: false },
18106
18302
  keepNext: { rendered: false },
18107
18303
  paragraphProperties: { rendered: false },
@@ -18640,6 +18836,22 @@ const LineBreak = Node$1.create({
18640
18836
  renderDOM() {
18641
18837
  return ["br", {}];
18642
18838
  },
18839
+ addAttributes() {
18840
+ return {
18841
+ /**
18842
+ * @private
18843
+ * @category Attribute
18844
+ * @param {string} [lineBreakType] - Type of line break - passthrough in this node
18845
+ */
18846
+ lineBreakType: { rendered: false },
18847
+ /**
18848
+ * @private
18849
+ * @category Attribute
18850
+ * @param {string} [clear] - Clear attribute - passthrough in this node
18851
+ */
18852
+ clear: { rendered: false }
18853
+ };
18854
+ },
18643
18855
  addCommands() {
18644
18856
  return {
18645
18857
  /**
@@ -18696,7 +18908,19 @@ const HardBreak = Node$1.create({
18696
18908
  pageBreakType: {
18697
18909
  default: null,
18698
18910
  rendered: false
18699
- }
18911
+ },
18912
+ /**
18913
+ * @private
18914
+ * @category Attribute
18915
+ * @param {string} [lineBreakType] - Type of line break - passthrough in this node
18916
+ */
18917
+ lineBreakType: { rendered: false },
18918
+ /**
18919
+ * @private
18920
+ * @category Attribute
18921
+ * @param {string} [clear] - Clear attribute - passthrough in this node
18922
+ */
18923
+ clear: { rendered: false }
18700
18924
  };
18701
18925
  },
18702
18926
  parseDOM() {
@@ -23684,6 +23908,10 @@ const Image = Node$1.create({
23684
23908
  },
23685
23909
  addAttributes() {
23686
23910
  return {
23911
+ /**
23912
+ * @category Attribute
23913
+ * @param {string} [src] - Image source URL or path
23914
+ */
23687
23915
  src: {
23688
23916
  default: null,
23689
23917
  renderDOM: ({ src }) => {
@@ -23692,40 +23920,110 @@ const Image = Node$1.create({
23692
23920
  };
23693
23921
  }
23694
23922
  },
23923
+ /**
23924
+ * @category Attribute
23925
+ * @param {string} [alt='Uploaded picture'] - Alternative text for accessibility
23926
+ */
23695
23927
  alt: {
23696
23928
  default: "Uploaded picture"
23697
23929
  },
23930
+ /**
23931
+ * @category Attribute
23932
+ * @param {string} [id] - Image element ID
23933
+ * @private
23934
+ */
23698
23935
  id: { rendered: false },
23936
+ /**
23937
+ * @category Attribute
23938
+ * @param {string} [title] - Image title/tooltip text
23939
+ */
23699
23940
  title: {
23700
23941
  default: null
23701
23942
  },
23943
+ /**
23944
+ * @category Attribute
23945
+ * @param {string} [rId] - Relationship ID for Word export
23946
+ * @private
23947
+ */
23702
23948
  rId: {
23703
23949
  default: null,
23704
23950
  rendered: false
23705
23951
  },
23952
+ /**
23953
+ * @category Attribute
23954
+ * @param {Object} [originalPadding] - Original padding values from Word import
23955
+ * @private
23956
+ */
23706
23957
  originalPadding: {
23707
23958
  default: null,
23708
23959
  rendered: false
23709
23960
  },
23961
+ /**
23962
+ * @category Attribute
23963
+ * @param {Object} [originalAttributes] - Original attributes from Word import
23964
+ * @private
23965
+ */
23710
23966
  originalAttributes: { rendered: false },
23967
+ /**
23968
+ * @category Attribute
23969
+ * @param {boolean} [wrapTopAndBottom] - Wrap text above and below image
23970
+ * @private
23971
+ */
23711
23972
  wrapTopAndBottom: { rendered: false },
23973
+ /**
23974
+ * @category Attribute
23975
+ * @param {Object} [anchorData] - Anchor positioning data for Word
23976
+ * @private
23977
+ */
23712
23978
  anchorData: {
23713
23979
  default: null,
23714
23980
  rendered: false
23715
23981
  },
23982
+ /**
23983
+ * @category Attribute
23984
+ * @param {boolean} [isAnchor] - Whether image is anchored
23985
+ * @private
23986
+ */
23716
23987
  isAnchor: { rendered: false },
23988
+ /**
23989
+ * @category Attribute
23990
+ * @param {boolean} [simplePos] - Simple positioning flag
23991
+ * @private
23992
+ */
23717
23993
  simplePos: { rendered: false },
23994
+ /**
23995
+ * @category Attribute
23996
+ * @param {string} [wrapText] - Text wrapping style
23997
+ * @private
23998
+ */
23718
23999
  wrapText: { rendered: false },
24000
+ extension: { rendered: false },
24001
+ /**
24002
+ * @category Attribute
24003
+ * @param {Object} [size] - Image dimensions
24004
+ * @param {number} [size.width] - Width in pixels
24005
+ * @param {number} [size.height] - Height in pixels
24006
+ */
23719
24007
  size: {
23720
24008
  default: {},
23721
- renderDOM: ({ size }) => {
24009
+ renderDOM: ({ size, extension }) => {
23722
24010
  let style = "";
23723
24011
  const { width, height } = size ?? {};
23724
24012
  if (width) style += `width: ${width}px;`;
23725
- if (height) style += "height: auto;";
24013
+ if (height && ["emf", "wmf"].includes(extension))
24014
+ style += `height: ${height}px; border: 1px solid black; position: absolute;`;
24015
+ else if (height) style += "height: auto;";
23726
24016
  return { style };
23727
24017
  }
23728
24018
  },
24019
+ /**
24020
+ * @category Attribute
24021
+ * @param {Object} [padding] - Image padding/margins
24022
+ * @param {number} [padding.left] - Left padding in pixels
24023
+ * @param {number} [padding.top] - Top padding in pixels
24024
+ * @param {number} [padding.bottom] - Bottom padding in pixels
24025
+ * @param {number} [padding.right] - Right padding in pixels
24026
+ */
23729
24027
  padding: {
23730
24028
  default: {},
23731
24029
  renderDOM: ({ padding, marginOffset }) => {
@@ -23738,6 +24036,12 @@ const Image = Node$1.create({
23738
24036
  return { style };
23739
24037
  }
23740
24038
  },
24039
+ /**
24040
+ * @category Attribute
24041
+ * @param {Object} [marginOffset] - Margin offset for anchored images
24042
+ * @param {number} [marginOffset.left] - Left margin offset
24043
+ * @param {number} [marginOffset.top] - Top margin offset
24044
+ */
23741
24045
  marginOffset: {
23742
24046
  default: {},
23743
24047
  renderDOM: ({ marginOffset, anchorData }) => {
@@ -23753,6 +24057,10 @@ const Image = Node$1.create({
23753
24057
  return { style };
23754
24058
  }
23755
24059
  },
24060
+ /**
24061
+ * @category Attribute
24062
+ * @param {string} [style] - Custom inline CSS styles
24063
+ */
23756
24064
  style: {
23757
24065
  default: null,
23758
24066
  rendered: true,
@@ -23775,6 +24083,27 @@ const Image = Node$1.create({
23775
24083
  },
23776
24084
  addCommands() {
23777
24085
  return {
24086
+ /**
24087
+ * Insert an image at the current position
24088
+ * @category Command
24089
+ * @param {Object} options - Image attributes
24090
+ * @param {string} options.src - Image source URL or data URI
24091
+ * @param {string} [options.alt] - Alternative text
24092
+ * @param {string} [options.title] - Image title
24093
+ * @param {Object} [options.size] - Image dimensions
24094
+ * @returns {Function} Command function
24095
+ * @example
24096
+ * // Insert an image from a URL
24097
+ * setImage({ src: 'https://example.com/image.jpg' })
24098
+ *
24099
+ * // Insert a base64 encoded image
24100
+ * setImage({
24101
+ * src: 'data:image/png;base64,...',
24102
+ * alt: 'Company logo',
24103
+ * size: { width: 200 }
24104
+ * })
24105
+ * @note Supports URLs, relative paths, and base64 data URIs
24106
+ */
23778
24107
  setImage: (options) => ({ commands: commands2 }) => {
23779
24108
  return commands2.insertContent({
23780
24109
  type: this.name,
@@ -23812,7 +24141,9 @@ const getFileOpener = () => {
23812
24141
  const handleImageUpload = (file) => {
23813
24142
  return new Promise((resolve, reject) => {
23814
24143
  let reader = new FileReader();
23815
- reader.onload = (event) => resolve(event.target.result);
24144
+ reader.onload = (event) => {
24145
+ resolve(event.target.result);
24146
+ };
23816
24147
  reader.onerror = reject;
23817
24148
  setTimeout(() => reader.readAsDataURL(file), 250);
23818
24149
  });
@@ -24016,8 +24347,8 @@ async function uploadImage({ editor, view, file, size, uploadHandler }) {
24016
24347
  let rId = null;
24017
24348
  if (editor.options.mode === "docx") {
24018
24349
  const [, path] = mediaPath.split("word/");
24019
- const id2 = addImageRelationship({ editor, path });
24020
- if (id2) rId = id2;
24350
+ const imageid = addImageRelationship({ editor, path });
24351
+ if (imageid) rId = imageid;
24021
24352
  }
24022
24353
  let imageNode = schema.nodes.image.create({
24023
24354
  src: mediaPath,
@@ -24040,8 +24371,8 @@ function addImageRelationship({ editor, path }) {
24040
24371
  const target = path;
24041
24372
  const type = "image";
24042
24373
  try {
24043
- const id = insertNewRelationship(target, type, editor);
24044
- return id;
24374
+ const relationshipId = insertNewRelationship(target, type, editor);
24375
+ return relationshipId;
24045
24376
  } catch {
24046
24377
  return null;
24047
24378
  }
@@ -25154,6 +25485,17 @@ const BlockNode = Extension.create({
25154
25485
  name: "blockNode",
25155
25486
  addCommands() {
25156
25487
  return {
25488
+ /**
25489
+ * Replace a block node by its ID with new content
25490
+ * @category Command
25491
+ * @param {string} id - The sdBlockId of the node to replace
25492
+ * @param {Object} contentNode - The replacement ProseMirror node
25493
+ * @returns {Function} Command function
25494
+ * @example
25495
+ * const newParagraph = editor.schema.nodes.paragraph.create({}, editor.schema.text('New content'))
25496
+ * replaceBlockNodeById('block-123', newParagraph)
25497
+ * @note The replacement node should have the same type as the original
25498
+ */
25157
25499
  replaceBlockNodeById: (id, contentNode) => ({ dispatch, tr }) => {
25158
25500
  const blockNode = this.editor.helpers.blockNode.getBlockNodeById(id);
25159
25501
  if (!blockNode || blockNode.length > 1) {
@@ -25170,6 +25512,15 @@ const BlockNode = Extension.create({
25170
25512
  }
25171
25513
  return true;
25172
25514
  },
25515
+ /**
25516
+ * Delete a block node by its ID
25517
+ * @category Command
25518
+ * @param {string} id - The sdBlockId of the node to delete
25519
+ * @returns {Function} Command function
25520
+ * @example
25521
+ * deleteBlockNodeById('block-123')
25522
+ * @note Completely removes the node from the document
25523
+ */
25173
25524
  deleteBlockNodeById: (id) => ({ dispatch, tr }) => {
25174
25525
  const blockNode = this.editor.helpers.blockNode.getBlockNodeById(id);
25175
25526
  if (!blockNode || blockNode.length > 1) {
@@ -25186,6 +25537,18 @@ const BlockNode = Extension.create({
25186
25537
  }
25187
25538
  return true;
25188
25539
  },
25540
+ /**
25541
+ * Update attributes of a block node by its ID
25542
+ * @category Command
25543
+ * @param {string} id - The sdBlockId of the node to update
25544
+ * @param {Object} attrs - Attributes to update
25545
+ * @returns {Function} Command function
25546
+ * @example
25547
+ * updateBlockNodeAttributes('block-123', { textAlign: 'center' })
25548
+ * @example
25549
+ * updateBlockNodeAttributes('block-123', { indent: { left: 20 } })
25550
+ * @note Merges new attributes with existing ones
25551
+ */
25189
25552
  updateBlockNodeAttributes: (id, attrs = {}) => ({ dispatch, tr }) => {
25190
25553
  const blockNode = this.editor.helpers.blockNode.getBlockNodeById(id);
25191
25554
  if (!blockNode || blockNode.length > 1) {
@@ -25208,15 +25571,54 @@ const BlockNode = Extension.create({
25208
25571
  },
25209
25572
  addHelpers() {
25210
25573
  return {
25574
+ /**
25575
+ * Get all block nodes in the document
25576
+ * @category Helper
25577
+ * @returns {Array<BlockNodeInfo>} Array of block node info objects
25578
+ * @example
25579
+ * const blocks = editor.helpers.blockNode.getBlockNodes()
25580
+ * console.log(`Found ${blocks.length} block nodes`)
25581
+ */
25211
25582
  getBlockNodes: () => {
25212
25583
  return findChildren(this.editor.state.doc, (node) => nodeAllowsSdBlockIdAttr(node));
25213
25584
  },
25585
+ /**
25586
+ * Get a specific block node by its ID
25587
+ * @category Helper
25588
+ * @param {string} id - The sdBlockId to search for
25589
+ * @returns {Array<BlockNodeInfo>} Array containing the matching node (or empty)
25590
+ * @example
25591
+ * const block = editor.helpers.blockNode.getBlockNodeById('block-123')
25592
+ * if (block.length) console.log('Found:', block[0].node.type.name)
25593
+ */
25214
25594
  getBlockNodeById: (id) => {
25215
25595
  return findChildren(this.editor.state.doc, (node) => node.attrs.sdBlockId === id);
25216
25596
  },
25597
+ /**
25598
+ * Get all block nodes of a specific type
25599
+ * @category Helper
25600
+ * @param {string} type - The node type name (e.g., 'paragraph', 'heading')
25601
+ * @returns {Array<BlockNodeInfo>} Array of matching block nodes
25602
+ * @example
25603
+ * const paragraphs = editor.helpers.blockNode.getBlockNodesByType('paragraph')
25604
+ * const headings = editor.helpers.blockNode.getBlockNodesByType('heading')
25605
+ */
25217
25606
  getBlockNodesByType: (type) => {
25218
25607
  return findChildren(this.editor.state.doc, (node) => node.type.name === type);
25219
25608
  },
25609
+ /**
25610
+ * Get all block nodes within a position range
25611
+ * @category Helper
25612
+ * @param {number} from - Start position
25613
+ * @param {number} to - End position
25614
+ * @returns {Array<BlockNodeInfo>} Array of block nodes in the range
25615
+ * @example
25616
+ * const selection = editor.state.selection
25617
+ * const blocksInSelection = editor.helpers.blockNode.getBlockNodesInRange(
25618
+ * selection.from,
25619
+ * selection.to
25620
+ * )
25621
+ */
25220
25622
  getBlockNodesInRange: (from2, to) => {
25221
25623
  let blockNodes = [];
25222
25624
  this.editor.state.doc.nodesBetween(from2, to, (node, pos) => {
@@ -25272,10 +25674,11 @@ const nodeNeedsSdBlockId = (node) => {
25272
25674
  return !currentId;
25273
25675
  };
25274
25676
  const checkForNewBlockNodesInTrs = (transactions) => {
25275
- return transactions.some((tr) => {
25677
+ return Array.from(transactions).some((tr) => {
25276
25678
  return tr.steps.some((step) => {
25679
+ if (!(step instanceof ReplaceStep)) return false;
25277
25680
  const hasValidSdBlockNodes = step.slice?.content?.content?.some((node) => nodeAllowsSdBlockIdAttr(node));
25278
- return step instanceof ReplaceStep && hasValidSdBlockNodes;
25681
+ return hasValidSdBlockNodes;
25279
25682
  });
25280
25683
  });
25281
25684
  };
@@ -25304,6 +25707,10 @@ const TextStyle = Mark.create({
25304
25707
  },
25305
25708
  addAttributes() {
25306
25709
  return {
25710
+ /**
25711
+ * @category Attribute
25712
+ * @param {string} [styleId] - Style identifier for referencing predefined styles
25713
+ */
25307
25714
  styleId: {}
25308
25715
  };
25309
25716
  },
@@ -25312,10 +25719,11 @@ const TextStyle = Mark.create({
25312
25719
  /**
25313
25720
  * Remove empty text style marks
25314
25721
  * @category Command
25315
- * @returns {Function} Command - Removes mark if no attributes present
25722
+ * @returns {Function} Command function - Removes mark if no attributes present
25316
25723
  * @example
25317
25724
  * removeEmptyTextStyle()
25318
25725
  * @note Cleanup utility to prevent empty span elements
25726
+ * @note Automatically checks if any style attributes exist before removal
25319
25727
  */
25320
25728
  removeEmptyTextStyle: () => ({ state, commands: commands2 }) => {
25321
25729
  const attributes = Attribute.getMarkAttributes(state, this.type);
@@ -26337,12 +26745,16 @@ const TextTransform = Extension.create({
26337
26745
  {
26338
26746
  types: this.options.types,
26339
26747
  attributes: {
26748
+ /**
26749
+ * @category Attribute
26750
+ * @param {string} [textTransform] - Text transform value (uppercase, lowercase, capitalize, none)
26751
+ */
26340
26752
  textTransform: {
26341
26753
  default: null,
26342
26754
  renderDOM: (attrs) => {
26343
- if (!attrs.textCase) return {};
26755
+ if (!attrs.textTransform) return {};
26344
26756
  return {
26345
- style: `text-transform: ${attrs.textCase}`
26757
+ style: `text-transform: ${attrs.textTransform}`
26346
26758
  };
26347
26759
  }
26348
26760
  }