@harbour-enterprises/superdoc 0.21.0-next.8 → 0.21.1

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 (35) hide show
  1. package/dist/chunks/{PdfViewer-BR9iwva-.cjs → PdfViewer-B507M2sz.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-CwVW7MVJ.es.js → PdfViewer-DCKxnML6.es.js} +1 -1
  3. package/dist/chunks/{index-CjQDYBP2.es.js → index-DWR8syta.es.js} +40 -20
  4. package/dist/chunks/{index-BNA5J__D.cjs → index-djqw1MEc.cjs} +40 -20
  5. package/dist/chunks/{super-editor.es-C5dhT0uU.es.js → super-editor.es-D__G4K0i.es.js} +429 -115
  6. package/dist/chunks/{super-editor.es-Ct59l8tt.cjs → super-editor.es-HekVJogH.cjs} +429 -115
  7. package/dist/core/SuperDoc.d.ts +5 -0
  8. package/dist/core/SuperDoc.d.ts.map +1 -1
  9. package/dist/core/types/index.d.ts +4 -4
  10. package/dist/core/types/index.d.ts.map +1 -1
  11. package/dist/super-editor/ai-writer.es.js +2 -2
  12. package/dist/super-editor/chunks/{converter-DYAHhSrg.js → converter-B_pO-5Ls.js} +291 -67
  13. package/dist/super-editor/chunks/{docx-zipper-BDbCmfbE.js → docx-zipper-WaO3WaIz.js} +73 -12
  14. package/dist/super-editor/chunks/{editor-B1W7AdgQ.js → editor-DInvq7gF.js} +68 -30
  15. package/dist/super-editor/chunks/{toolbar-CCvglB_X.js → toolbar-C15EomPB.js} +2 -2
  16. package/dist/super-editor/converter.es.js +1 -1
  17. package/dist/super-editor/docx-zipper.es.js +2 -2
  18. package/dist/super-editor/editor.es.js +3 -3
  19. package/dist/super-editor/file-zipper.es.js +1 -1
  20. package/dist/super-editor/src/core/DocxZipper.d.ts +1 -1
  21. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +1 -13
  22. package/dist/super-editor/src/core/super-converter/exporter.d.ts +1 -0
  23. package/dist/super-editor/src/core/super-converter/helpers/tableFallbackHelpers.d.ts +24 -0
  24. package/dist/super-editor/src/extensions/custom-selection/custom-selection.d.ts +5 -1
  25. package/dist/super-editor/src/utils/contextmenu-helpers.d.ts +24 -0
  26. package/dist/super-editor/super-editor.es.js +7 -15
  27. package/dist/super-editor/toolbar.es.js +2 -2
  28. package/dist/super-editor.cjs +1 -1
  29. package/dist/super-editor.es.js +1 -1
  30. package/dist/superdoc.cjs +2 -2
  31. package/dist/superdoc.es.js +2 -2
  32. package/dist/superdoc.umd.js +467 -133
  33. package/dist/superdoc.umd.js.map +1 -1
  34. package/package.json +2 -5
  35. package/dist/super-editor/src/components/slash-menu/contextmenu-helpers.d.ts +0 -1
@@ -32581,17 +32581,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32581
32581
  };
32582
32582
  const getDefaultParagraphStyle = (docx, styleId = "") => {
32583
32583
  const styles = docx["word/styles.xml"];
32584
- if (!styles) {
32584
+ const rootElements = styles?.elements?.[0]?.elements;
32585
+ if (!rootElements?.length) {
32585
32586
  return {};
32586
32587
  }
32587
- const defaults = styles.elements[0].elements?.find((el) => el.name === "w:docDefaults");
32588
- const pDefault = defaults.elements.find((el) => el.name === "w:pPrDefault");
32588
+ const defaults = rootElements.find((el) => el.name === "w:docDefaults");
32589
+ const pDefault = defaults?.elements?.find((el) => el.name === "w:pPrDefault") || {};
32589
32590
  const pPrDefault = pDefault?.elements?.find((el) => el.name === "w:pPr");
32590
32591
  const pPrDefaultSpacingTag = pPrDefault?.elements?.find((el) => el.name === "w:spacing") || {};
32591
32592
  const pPrDefaultIndentTag = pPrDefault?.elements?.find((el) => el.name === "w:ind") || {};
32592
- const stylesNormal = styles.elements[0].elements?.find(
32593
- (el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal"
32594
- );
32593
+ const stylesNormal = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === "Normal");
32595
32594
  const pPrNormal = stylesNormal?.elements?.find((el) => el.name === "w:pPr");
32596
32595
  const pPrNormalSpacingTag = pPrNormal?.elements?.find((el) => el.name === "w:spacing") || {};
32597
32596
  const pPrNormalIndentTag = pPrNormal?.elements?.find((el) => el.name === "w:ind") || {};
@@ -32600,9 +32599,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32600
32599
  let pPrStyleIdIndentTag = {};
32601
32600
  let pPrStyleJc = {};
32602
32601
  if (styleId) {
32603
- const stylesById = styles.elements[0].elements?.find(
32604
- (el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId
32605
- );
32602
+ const stylesById = rootElements.find((el) => el.name === "w:style" && el.attributes["w:styleId"] === styleId);
32606
32603
  const pPrById = stylesById?.elements?.find((el) => el.name === "w:pPr");
32607
32604
  pPrStyleIdSpacingTag = pPrById?.elements?.find((el) => el.name === "w:spacing") || {};
32608
32605
  pPrStyleIdIndentTag = pPrById?.elements?.find((el) => el.name === "w:ind") || {};
@@ -34905,6 +34902,68 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34905
34902
  decode: decode$h
34906
34903
  };
34907
34904
  const translator$a = NodeTranslator.from(config$a);
34905
+ const DEFAULT_PAGE_WIDTH_TWIPS = 12240;
34906
+ const DEFAULT_PAGE_MARGIN_TWIPS = 1440;
34907
+ const DEFAULT_CONTENT_WIDTH_TWIPS = DEFAULT_PAGE_WIDTH_TWIPS - 2 * DEFAULT_PAGE_MARGIN_TWIPS;
34908
+ const MIN_COLUMN_WIDTH_TWIPS = pixelsToTwips(10);
34909
+ const pctToPercent = (value) => {
34910
+ if (value == null) return null;
34911
+ return value / 50;
34912
+ };
34913
+ const resolveContentWidthTwips = () => DEFAULT_CONTENT_WIDTH_TWIPS;
34914
+ const resolveMeasurementWidthPx = (measurement) => {
34915
+ if (!measurement || typeof measurement.value !== "number" || measurement.value <= 0) return null;
34916
+ const { value, type: type2 } = measurement;
34917
+ if (!type2 || type2 === "auto") return null;
34918
+ if (type2 === "dxa") return twipsToPixels(value);
34919
+ if (type2 === "pct") {
34920
+ const percent2 = pctToPercent(value);
34921
+ if (percent2 == null || percent2 <= 0) return null;
34922
+ const widthTwips = resolveContentWidthTwips() * percent2 / 100;
34923
+ return twipsToPixels(widthTwips);
34924
+ }
34925
+ return null;
34926
+ };
34927
+ const countColumnsInRow = (row) => {
34928
+ if (!row?.elements?.length) return 0;
34929
+ return row.elements.reduce((count, element) => {
34930
+ if (element.name !== "w:tc") return count;
34931
+ const tcPr = element.elements?.find((el) => el.name === "w:tcPr");
34932
+ const gridSpan = tcPr?.elements?.find((el) => el.name === "w:gridSpan");
34933
+ const spanValue = parseInt(gridSpan?.attributes?.["w:val"] || "1", 10);
34934
+ return count + (Number.isFinite(spanValue) && spanValue > 0 ? spanValue : 1);
34935
+ }, 0);
34936
+ };
34937
+ const clampColumnWidthTwips = (value) => Math.max(Math.round(value), MIN_COLUMN_WIDTH_TWIPS);
34938
+ const createFallbackGrid = (columnCount, columnWidthTwips) => Array.from({ length: columnCount }, () => ({ col: clampColumnWidthTwips(columnWidthTwips) }));
34939
+ const buildFallbackGridForTable = ({ params: params2, rows, tableWidth, tableWidthMeasurement }) => {
34940
+ const firstRow = rows.find((row) => row.elements?.some((el) => el.name === "w:tc"));
34941
+ const columnCount = countColumnsInRow(firstRow);
34942
+ if (!columnCount) return null;
34943
+ const schemaDefaultPx = getSchemaDefaultColumnWidthPx(
34944
+ /** @type {any} */
34945
+ params2
34946
+ );
34947
+ const minimumColumnWidthPx = Number.isFinite(schemaDefaultPx) && schemaDefaultPx > 0 ? schemaDefaultPx : DEFAULT_COLUMN_WIDTH_PX;
34948
+ let totalWidthPx;
34949
+ if (tableWidthMeasurement) {
34950
+ const resolved = resolveMeasurementWidthPx(tableWidthMeasurement);
34951
+ if (resolved != null) totalWidthPx = resolved;
34952
+ }
34953
+ if (totalWidthPx == null && tableWidth?.width && tableWidth.width > 0) {
34954
+ totalWidthPx = tableWidth.width;
34955
+ }
34956
+ if (totalWidthPx == null) {
34957
+ totalWidthPx = minimumColumnWidthPx * columnCount;
34958
+ }
34959
+ const rawColumnWidthPx = Math.max(totalWidthPx / columnCount, minimumColumnWidthPx);
34960
+ const columnWidthTwips = clampColumnWidthTwips(pixelsToTwips(rawColumnWidthPx));
34961
+ const fallbackColumnWidthPx = twipsToPixels(columnWidthTwips);
34962
+ return {
34963
+ grid: createFallbackGrid(columnCount, columnWidthTwips),
34964
+ columnWidths: Array(columnCount).fill(fallbackColumnWidthPx)
34965
+ };
34966
+ };
34908
34967
  const XML_NODE_NAME$9 = "w:tbl";
34909
34968
  const SD_NODE_NAME$9 = "table";
34910
34969
  const encode$g = (params2, encodedAttrs) => {
@@ -34924,7 +34983,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34924
34983
  "justification",
34925
34984
  "tableLayout",
34926
34985
  ["tableIndent", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
34927
- ["tableWidth", ({ value, type: type2 }) => ({ width: twipsToPixels(value), type: type2 })],
34928
34986
  ["tableCellSpacing", ({ value, type: type2 }) => ({ w: String(value), type: type2 })]
34929
34987
  ].forEach((prop) => {
34930
34988
  let key2;
@@ -34942,6 +35000,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34942
35000
  if (encodedAttrs.tableCellSpacing) {
34943
35001
  encodedAttrs["borderCollapse"] = "separate";
34944
35002
  }
35003
+ if (encodedAttrs.tableProperties?.tableWidth) {
35004
+ const tableWidthMeasurement = encodedAttrs.tableProperties.tableWidth;
35005
+ const widthPx = twipsToPixels(tableWidthMeasurement.value);
35006
+ if (widthPx != null) {
35007
+ encodedAttrs.tableWidth = {
35008
+ width: widthPx,
35009
+ type: tableWidthMeasurement.type
35010
+ };
35011
+ } else if (tableWidthMeasurement.type === "auto") {
35012
+ encodedAttrs.tableWidth = {
35013
+ width: 0,
35014
+ type: tableWidthMeasurement.type
35015
+ };
35016
+ }
35017
+ }
34945
35018
  const { borders, rowBorders } = _processTableBorders(encodedAttrs.tableProperties?.borders || {});
34946
35019
  const referencedStyles = _getReferencedTableStyles(encodedAttrs.tableStyleId, params2);
34947
35020
  if (referencedStyles?.cellMargins && !encodedAttrs.tableProperties?.cellMargins) {
@@ -34955,7 +35028,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34955
35028
  const borderRowData = Object.assign({}, referencedStyles?.rowBorders || {}, rowBorders || {});
34956
35029
  encodedAttrs["borders"] = borderData;
34957
35030
  const tblStyleTag = tblPr?.elements?.find((el) => el.name === "w:tblStyle");
34958
- const columnWidths = (encodedAttrs["grid"] ?? []).map((item) => twipsToPixels(item.col));
35031
+ let columnWidths = Array.isArray(encodedAttrs["grid"]) ? encodedAttrs["grid"].map((item) => twipsToPixels(item.col)) : [];
35032
+ if (!columnWidths.length) {
35033
+ const fallback = buildFallbackGridForTable({
35034
+ params: params2,
35035
+ rows,
35036
+ tableWidth: encodedAttrs.tableWidth,
35037
+ tableWidthMeasurement: encodedAttrs.tableProperties?.tableWidth
35038
+ });
35039
+ if (fallback) {
35040
+ encodedAttrs.grid = fallback.grid;
35041
+ columnWidths = fallback.columnWidths;
35042
+ }
35043
+ }
34959
35044
  const content = [];
34960
35045
  rows.forEach((row) => {
34961
35046
  const result = translator$G.encode({
@@ -38336,6 +38421,63 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38336
38421
  attributes: validXmlAttributes
38337
38422
  };
38338
38423
  const translator = NodeTranslator.from(config);
38424
+ const DEFAULT_SECTION_PROPS_TWIPS = Object.freeze({
38425
+ pageSize: Object.freeze({ width: "12240", height: "15840" }),
38426
+ pageMargins: Object.freeze({
38427
+ top: "1440",
38428
+ right: "1440",
38429
+ bottom: "1440",
38430
+ left: "1440",
38431
+ header: "720",
38432
+ footer: "720",
38433
+ gutter: "0"
38434
+ })
38435
+ });
38436
+ const ensureSectionLayoutDefaults = (sectPr, converter) => {
38437
+ if (!sectPr) {
38438
+ return {
38439
+ type: "element",
38440
+ name: "w:sectPr",
38441
+ elements: []
38442
+ };
38443
+ }
38444
+ if (!sectPr.elements) sectPr.elements = [];
38445
+ const ensureChild = (name) => {
38446
+ let child = sectPr.elements.find((n) => n.name === name);
38447
+ if (!child) {
38448
+ child = {
38449
+ type: "element",
38450
+ name,
38451
+ elements: [],
38452
+ attributes: {}
38453
+ };
38454
+ sectPr.elements.push(child);
38455
+ } else {
38456
+ if (!child.elements) child.elements = [];
38457
+ if (!child.attributes) child.attributes = {};
38458
+ }
38459
+ return child;
38460
+ };
38461
+ const pageSize = converter?.pageStyles?.pageSize;
38462
+ const pgSz = ensureChild("w:pgSz");
38463
+ if (pageSize?.width != null) pgSz.attributes["w:w"] = String(inchesToTwips(pageSize.width));
38464
+ if (pageSize?.height != null) pgSz.attributes["w:h"] = String(inchesToTwips(pageSize.height));
38465
+ if (pgSz.attributes["w:w"] == null) pgSz.attributes["w:w"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.width;
38466
+ if (pgSz.attributes["w:h"] == null) pgSz.attributes["w:h"] = DEFAULT_SECTION_PROPS_TWIPS.pageSize.height;
38467
+ const pageMargins = converter?.pageStyles?.pageMargins;
38468
+ const pgMar = ensureChild("w:pgMar");
38469
+ if (pageMargins) {
38470
+ Object.entries(pageMargins).forEach(([key2, value]) => {
38471
+ const converted = inchesToTwips(value);
38472
+ if (converted != null) pgMar.attributes[`w:${key2}`] = String(converted);
38473
+ });
38474
+ }
38475
+ Object.entries(DEFAULT_SECTION_PROPS_TWIPS.pageMargins).forEach(([key2, value]) => {
38476
+ const attrKey = `w:${key2}`;
38477
+ if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
38478
+ });
38479
+ return sectPr;
38480
+ };
38339
38481
  const isLineBreakOnlyRun = (node) => {
38340
38482
  if (!node) return false;
38341
38483
  if (node.type === "lineBreak" || node.type === "hardBreak") return true;
@@ -38388,28 +38530,30 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38388
38530
  return handler2(params2);
38389
38531
  }
38390
38532
  function translateBodyNode(params2) {
38391
- let sectPr = params2.bodyNode?.elements.find((n) => n.name === "w:sectPr") || {};
38533
+ let sectPr = params2.bodyNode?.elements?.find((n) => n.name === "w:sectPr");
38534
+ if (!sectPr) {
38535
+ sectPr = {
38536
+ type: "element",
38537
+ name: "w:sectPr",
38538
+ elements: []
38539
+ };
38540
+ } else if (!sectPr.elements) {
38541
+ sectPr = { ...sectPr, elements: [] };
38542
+ }
38543
+ sectPr = ensureSectionLayoutDefaults(sectPr, params2.converter);
38392
38544
  if (params2.converter) {
38393
- const hasHeader = sectPr?.elements?.some((n) => n.name === "w:headerReference");
38545
+ const hasHeader = sectPr.elements?.some((n) => n.name === "w:headerReference");
38394
38546
  const hasDefaultHeader = params2.converter.headerIds?.default;
38395
38547
  if (!hasHeader && hasDefaultHeader && !params2.editor.options.isHeaderOrFooter) {
38396
38548
  const defaultHeader = generateDefaultHeaderFooter("header", params2.converter.headerIds?.default);
38397
38549
  sectPr.elements.push(defaultHeader);
38398
38550
  }
38399
- const hasFooter = sectPr?.elements?.some((n) => n.name === "w:footerReference");
38551
+ const hasFooter = sectPr.elements?.some((n) => n.name === "w:footerReference");
38400
38552
  const hasDefaultFooter = params2.converter.footerIds?.default;
38401
38553
  if (!hasFooter && hasDefaultFooter && !params2.editor.options.isHeaderOrFooter) {
38402
38554
  const defaultFooter = generateDefaultHeaderFooter("footer", params2.converter.footerIds?.default);
38403
38555
  sectPr.elements.push(defaultFooter);
38404
38556
  }
38405
- const newMargins = params2.converter.pageStyles.pageMargins;
38406
- const sectPrMargins = sectPr.elements.find((n) => n.name === "w:pgMar");
38407
- const { attributes } = sectPrMargins;
38408
- Object.entries(newMargins).forEach(([key2, value]) => {
38409
- const convertedValue = inchesToTwips(value);
38410
- attributes[`w:${key2}`] = convertedValue;
38411
- });
38412
- sectPrMargins.attributes = attributes;
38413
38557
  }
38414
38558
  const elements = translateChildNodes(params2);
38415
38559
  if (params2.isHeaderFooter) {
@@ -40397,6 +40541,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40397
40541
  const nodeListHandler = defaultNodeListHandler();
40398
40542
  const bodyNode = json.elements[0].elements.find((el) => el.name === "w:body");
40399
40543
  if (bodyNode) {
40544
+ ensureSectionProperties(bodyNode);
40400
40545
  const node = bodyNode;
40401
40546
  const contentElements = node.elements?.filter((n) => n.name !== "w:sectPr") ?? [];
40402
40547
  const content = pruneIgnoredNodes(contentElements);
@@ -40630,6 +40775,59 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40630
40775
  styles.alternateHeaders = isAlternatingHeadersOddEven(docx);
40631
40776
  return styles;
40632
40777
  }
40778
+ const DEFAULT_SECTION_PROPS = Object.freeze({
40779
+ pageSize: Object.freeze({ width: "12240", height: "15840" }),
40780
+ pageMargins: Object.freeze({
40781
+ top: "1440",
40782
+ right: "1440",
40783
+ bottom: "1440",
40784
+ left: "1440",
40785
+ header: "720",
40786
+ footer: "720",
40787
+ gutter: "0"
40788
+ })
40789
+ });
40790
+ function ensureSectionProperties(bodyNode, converter) {
40791
+ if (!bodyNode.elements) bodyNode.elements = [];
40792
+ let sectPr = bodyNode.elements.find((el) => el.name === "w:sectPr");
40793
+ if (!sectPr) {
40794
+ sectPr = {
40795
+ type: "element",
40796
+ name: "w:sectPr",
40797
+ elements: []
40798
+ };
40799
+ bodyNode.elements.push(sectPr);
40800
+ } else if (!sectPr.elements) {
40801
+ sectPr.elements = [];
40802
+ }
40803
+ const ensureChild = (name, factory) => {
40804
+ let child = sectPr.elements.find((el) => el.name === name);
40805
+ if (!child) {
40806
+ child = factory();
40807
+ sectPr.elements.push(child);
40808
+ } else if (!child.attributes) {
40809
+ child.attributes = {};
40810
+ }
40811
+ return child;
40812
+ };
40813
+ const pgSz = ensureChild("w:pgSz", () => ({
40814
+ type: "element",
40815
+ name: "w:pgSz",
40816
+ attributes: {}
40817
+ }));
40818
+ pgSz.attributes["w:w"] = pgSz.attributes["w:w"] ?? DEFAULT_SECTION_PROPS.pageSize.width;
40819
+ pgSz.attributes["w:h"] = pgSz.attributes["w:h"] ?? DEFAULT_SECTION_PROPS.pageSize.height;
40820
+ const pgMar = ensureChild("w:pgMar", () => ({
40821
+ type: "element",
40822
+ name: "w:pgMar",
40823
+ attributes: {}
40824
+ }));
40825
+ Object.entries(DEFAULT_SECTION_PROPS.pageMargins).forEach(([key2, value]) => {
40826
+ const attrKey = `w:${key2}`;
40827
+ if (pgMar.attributes[attrKey] == null) pgMar.attributes[attrKey] = value;
40828
+ });
40829
+ return sectPr;
40830
+ }
40633
40831
  function getStyleDefinitions(docx) {
40634
40832
  const styles = docx["word/styles.xml"];
40635
40833
  if (!styles) return [];
@@ -40822,6 +41020,36 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40822
41020
  auto: "sans-serif"
40823
41021
  });
40824
41022
  const DEFAULT_GENERIC_FALLBACK = "sans-serif";
41023
+ const DEFAULT_FONT_SIZE_PT = 10;
41024
+ const collectRunDefaultProperties = (runProps, { allowOverrideTypeface = true, allowOverrideSize = true, themeResolver, state: state2 }) => {
41025
+ if (!runProps?.elements?.length || !state2) return;
41026
+ const fontsNode = runProps.elements.find((el) => el.name === "w:rFonts");
41027
+ if (fontsNode?.attributes) {
41028
+ const themeName = fontsNode.attributes["w:asciiTheme"];
41029
+ if (themeName) {
41030
+ const themeInfo = themeResolver?.(themeName) || {};
41031
+ if ((allowOverrideTypeface || !state2.typeface) && themeInfo.typeface) state2.typeface = themeInfo.typeface;
41032
+ if ((allowOverrideTypeface || !state2.panose) && themeInfo.panose) state2.panose = themeInfo.panose;
41033
+ }
41034
+ const ascii = fontsNode.attributes["w:ascii"];
41035
+ if ((allowOverrideTypeface || !state2.typeface) && ascii) {
41036
+ state2.typeface = ascii;
41037
+ }
41038
+ }
41039
+ const sizeNode = runProps.elements.find((el) => el.name === "w:sz");
41040
+ if (sizeNode?.attributes?.["w:val"]) {
41041
+ const sizeTwips = Number(sizeNode.attributes["w:val"]);
41042
+ if (Number.isFinite(sizeTwips)) {
41043
+ if (state2.fallbackSzTwips === void 0) state2.fallbackSzTwips = sizeTwips;
41044
+ const sizePt = sizeTwips / 2;
41045
+ if (allowOverrideSize || state2.fontSizePt === void 0) state2.fontSizePt = sizePt;
41046
+ }
41047
+ }
41048
+ const kernNode = runProps.elements.find((el) => el.name === "w:kern");
41049
+ if (kernNode?.attributes?.["w:val"]) {
41050
+ if (allowOverrideSize || state2.kern === void 0) state2.kern = kernNode.attributes["w:val"];
41051
+ }
41052
+ };
40825
41053
  const _SuperConverter = class _SuperConverter2 {
40826
41054
  constructor(params2 = null) {
40827
41055
  __privateAdd$2(this, _SuperConverter_instances);
@@ -40927,7 +41155,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40927
41155
  return;
40928
41156
  }
40929
41157
  }
40930
- static updateDocumentVersion(docx = this.convertedXml, version2 = "0.20.2") {
41158
+ static updateDocumentVersion(docx = this.convertedXml, version2 = "0.21.1") {
40931
41159
  const customLocation = "docProps/custom.xml";
40932
41160
  if (!docx[customLocation]) {
40933
41161
  docx[customLocation] = generateCustomXml();
@@ -40949,49 +41177,45 @@ Please report this to https://github.com/markedjs/marked.`, e) {
40949
41177
  }
40950
41178
  getDocumentDefaultStyles() {
40951
41179
  const styles = this.convertedXml["word/styles.xml"];
40952
- if (!styles) return {};
40953
- const defaults = styles.elements[0].elements.find((el) => el.name === "w:docDefaults");
40954
- const rDefault = defaults.elements.find((el) => el.name === "w:rPrDefault");
40955
- if (!rDefault.elements) return {};
40956
- const rElements = rDefault.elements[0].elements;
40957
- const rFonts = rElements?.find((el) => el.name === "w:rFonts");
40958
- if ("elements" in rDefault) {
40959
- const fontThemeName = rElements.find((el) => el.name === "w:rFonts")?.attributes["w:asciiTheme"];
40960
- let typeface, panose, fontSizeNormal;
40961
- if (fontThemeName) {
40962
- const fontInfo = this.getThemeInfo(fontThemeName);
40963
- typeface = fontInfo.typeface;
40964
- panose = fontInfo.panose;
40965
- } else if (rFonts) {
40966
- typeface = rFonts?.attributes["w:ascii"];
40967
- }
40968
- const paragraphDefaults = styles.elements[0].elements.filter((el) => {
40969
- return el.name === "w:style" && el.attributes["w:styleId"] === "Normal";
40970
- }) || [];
40971
- paragraphDefaults.forEach((el) => {
40972
- const rPr = el.elements.find((el2) => el2.name === "w:rPr");
40973
- const fonts = rPr?.elements?.find((el2) => el2.name === "w:rFonts");
40974
- typeface = fonts?.attributes["w:ascii"];
40975
- fontSizeNormal = Number(rPr?.elements?.find((el2) => el2.name === "w:sz")?.attributes["w:val"]) / 2;
40976
- });
40977
- const rPrDefaults = defaults?.elements?.find((el) => el.name === "w:rPrDefault");
40978
- if (rPrDefaults) {
40979
- const rPr = rPrDefaults.elements?.find((el) => el.name === "w:rPr");
40980
- const fonts = rPr?.elements?.find((el) => el.name === "w:rFonts");
40981
- if (fonts?.attributes?.["w:ascii"]) {
40982
- typeface = fonts.attributes["w:ascii"];
40983
- }
40984
- const fontSizeRaw = rPr?.elements?.find((el) => el.name === "w:sz")?.attributes?.["w:val"];
40985
- if (!fontSizeNormal && fontSizeRaw) {
40986
- fontSizeNormal = Number(fontSizeRaw) / 2;
40987
- }
40988
- }
40989
- const fallbackSz = Number(rElements.find((el) => el.name === "w:sz")?.attributes?.["w:val"]);
40990
- const fontSizePt = fontSizeNormal ?? (Number.isFinite(fallbackSz) ? fallbackSz / 2 : void 0) ?? 10;
40991
- const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
40992
- const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
40993
- return { fontSizePt, kern, typeface, panose, fontFamilyCss };
40994
- }
41180
+ const styleRoot = styles?.elements?.[0];
41181
+ const styleElements = styleRoot?.elements || [];
41182
+ if (!styleElements.length) return {};
41183
+ const defaults = styleElements.find((el) => el.name === "w:docDefaults");
41184
+ const normalStyle = styleElements.find((el) => el.name === "w:style" && el.attributes?.["w:styleId"] === "Normal");
41185
+ const defaultsState = {
41186
+ typeface: void 0,
41187
+ panose: void 0,
41188
+ fontSizePt: void 0,
41189
+ kern: void 0,
41190
+ fallbackSzTwips: void 0
41191
+ };
41192
+ const docDefaultRun = defaults?.elements?.find((el) => el.name === "w:rPrDefault");
41193
+ const docDefaultProps = docDefaultRun?.elements?.find((el) => el.name === "w:rPr") ?? docDefaultRun;
41194
+ collectRunDefaultProperties(docDefaultProps, {
41195
+ allowOverrideTypeface: true,
41196
+ allowOverrideSize: true,
41197
+ themeResolver: (theme) => this.getThemeInfo(theme),
41198
+ state: defaultsState
41199
+ });
41200
+ const normalRunProps = normalStyle?.elements?.find((el) => el.name === "w:rPr") ?? null;
41201
+ collectRunDefaultProperties(normalRunProps, {
41202
+ allowOverrideTypeface: true,
41203
+ allowOverrideSize: true,
41204
+ themeResolver: (theme) => this.getThemeInfo(theme),
41205
+ state: defaultsState
41206
+ });
41207
+ if (defaultsState.fontSizePt === void 0) {
41208
+ if (Number.isFinite(defaultsState.fallbackSzTwips)) defaultsState.fontSizePt = defaultsState.fallbackSzTwips / 2;
41209
+ else defaultsState.fontSizePt = DEFAULT_FONT_SIZE_PT;
41210
+ }
41211
+ const fontFamilyCss = defaultsState.typeface ? _SuperConverter2.toCssFontFamily(defaultsState.typeface, this.convertedXml) : void 0;
41212
+ const result = {};
41213
+ if (defaultsState.fontSizePt !== void 0) result.fontSizePt = defaultsState.fontSizePt;
41214
+ if (defaultsState.kern !== void 0) result.kern = defaultsState.kern;
41215
+ if (defaultsState.typeface) result.typeface = defaultsState.typeface;
41216
+ if (defaultsState.panose) result.panose = defaultsState.panose;
41217
+ if (fontFamilyCss) result.fontFamilyCss = fontFamilyCss;
41218
+ return result;
40995
41219
  }
40996
41220
  getDocumentFonts() {
40997
41221
  const fontTable = this.convertedXml["word/fontTable.xml"];
@@ -41420,7 +41644,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
41420
41644
  function generateCustomXml() {
41421
41645
  return DEFAULT_CUSTOM_XML;
41422
41646
  }
41423
- function generateSuperdocVersion(pid = 2, version2 = "0.20.2") {
41647
+ function generateSuperdocVersion(pid = 2, version2 = "0.21.1") {
41424
41648
  return {
41425
41649
  type: "element",
41426
41650
  name: "property",
@@ -43858,14 +44082,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
43858
44082
  /**
43859
44083
  * Update [Content_Types].xml with extensions of new Image annotations
43860
44084
  */
43861
- async updateContentTypes(docx, media, fromJson) {
44085
+ async updateContentTypes(docx, media, fromJson, updatedDocs = {}) {
44086
+ const additionalPartNames = Object.keys(updatedDocs || {});
43862
44087
  const newMediaTypes = Object.keys(media).map((name) => {
43863
44088
  return this.getFileExtension(name);
43864
44089
  }).filter(Boolean);
43865
44090
  const contentTypesPath = "[Content_Types].xml";
43866
44091
  let contentTypesXml;
43867
44092
  if (fromJson) {
43868
- contentTypesXml = docx.files.find((file) => file.name === contentTypesPath)?.content || "";
44093
+ if (Array.isArray(docx.files)) {
44094
+ contentTypesXml = docx.files.find((file) => file.name === contentTypesPath)?.content || "";
44095
+ } else {
44096
+ contentTypesXml = docx.files?.[contentTypesPath] || "";
44097
+ }
43869
44098
  } else contentTypesXml = await docx.file(contentTypesPath).async("string");
43870
44099
  let typesString = "";
43871
44100
  const defaultMediaTypes = getContentTypesFromXml(contentTypesXml);
@@ -43891,24 +44120,39 @@ Please report this to https://github.com/markedjs/marked.`, e) {
43891
44120
  const hasCommentsExtensible = types2.elements?.some(
43892
44121
  (el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml"
43893
44122
  );
43894
- if (docx.files["word/comments.xml"]) {
44123
+ const hasFile = (filename) => {
44124
+ if (!docx?.files) return false;
44125
+ if (!fromJson) return Boolean(docx.files[filename]);
44126
+ if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
44127
+ return Boolean(docx.files[filename]);
44128
+ };
44129
+ if (hasFile("word/comments.xml")) {
43895
44130
  const commentsDef = `<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />`;
43896
44131
  if (!hasComments) typesString += commentsDef;
43897
44132
  }
43898
- if (docx.files["word/commentsExtended.xml"]) {
44133
+ if (hasFile("word/commentsExtended.xml")) {
43899
44134
  const commentsExtendedDef = `<Override PartName="/word/commentsExtended.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml" />`;
43900
44135
  if (!hasCommentsExtended) typesString += commentsExtendedDef;
43901
44136
  }
43902
- if (docx.files["word/commentsIds.xml"]) {
44137
+ if (hasFile("word/commentsIds.xml")) {
43903
44138
  const commentsIdsDef = `<Override PartName="/word/commentsIds.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml" />`;
43904
44139
  if (!hasCommentsIds) typesString += commentsIdsDef;
43905
44140
  }
43906
- if (docx.files["word/commentsExtensible.xml"]) {
44141
+ if (hasFile("word/commentsExtensible.xml")) {
43907
44142
  const commentsExtendedDef = `<Override PartName="/word/commentsExtensible.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml" />`;
43908
44143
  if (!hasCommentsExtensible) typesString += commentsExtendedDef;
43909
44144
  }
43910
- Object.keys(docx.files).forEach((name) => {
43911
- if (name.includes(".rels") || !name.includes("header") && !name.includes("footer")) return;
44145
+ const partNames = new Set(additionalPartNames);
44146
+ if (docx?.files) {
44147
+ if (fromJson && Array.isArray(docx.files)) {
44148
+ docx.files.forEach((file) => partNames.add(file.name));
44149
+ } else {
44150
+ Object.keys(docx.files).forEach((key2) => partNames.add(key2));
44151
+ }
44152
+ }
44153
+ partNames.forEach((name) => {
44154
+ if (name.includes(".rels")) return;
44155
+ if (!name.includes("header") && !name.includes("footer")) return;
43912
44156
  const hasExtensible = types2.elements?.some(
43913
44157
  (el) => el.name === "Override" && el.attributes.PartName === `/${name}`
43914
44158
  );
@@ -43919,7 +44163,48 @@ Please report this to https://github.com/markedjs/marked.`, e) {
43919
44163
  }
43920
44164
  });
43921
44165
  const beginningString = '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
43922
- const updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
44166
+ let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
44167
+ let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
44168
+ if (!relationshipsXml) {
44169
+ if (fromJson) {
44170
+ if (Array.isArray(docx.files)) {
44171
+ relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
44172
+ } else {
44173
+ relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
44174
+ }
44175
+ } else {
44176
+ relationshipsXml = await docx.file("word/_rels/document.xml.rels")?.async("string");
44177
+ }
44178
+ }
44179
+ if (relationshipsXml) {
44180
+ try {
44181
+ const relJson = xmljs.xml2js(relationshipsXml, { compact: false });
44182
+ const relationships = relJson.elements?.find((el) => el.name === "Relationships");
44183
+ relationships?.elements?.forEach((rel) => {
44184
+ const type2 = rel.attributes?.Type;
44185
+ const target = rel.attributes?.Target;
44186
+ if (!type2 || !target) return;
44187
+ const isHeader = type2.includes("/header");
44188
+ const isFooter = type2.includes("/footer");
44189
+ if (!isHeader && !isFooter) return;
44190
+ let sanitizedTarget = target.replace(/^\.\//, "");
44191
+ if (sanitizedTarget.startsWith("../")) sanitizedTarget = sanitizedTarget.slice(3);
44192
+ if (sanitizedTarget.startsWith("/")) sanitizedTarget = sanitizedTarget.slice(1);
44193
+ const partName = sanitizedTarget.startsWith("word/") ? sanitizedTarget : `word/${sanitizedTarget}`;
44194
+ partNames.add(partName);
44195
+ });
44196
+ } catch (error) {
44197
+ console.warn("Failed to parse document relationships while updating content types", error);
44198
+ }
44199
+ }
44200
+ partNames.forEach((name) => {
44201
+ if (name.includes(".rels")) return;
44202
+ if (!name.includes("header") && !name.includes("footer")) return;
44203
+ if (updatedContentTypesXml.includes(`PartName="/${name}"`)) return;
44204
+ const type2 = name.includes("header") ? "header" : "footer";
44205
+ const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${type2}+xml"/>`;
44206
+ updatedContentTypesXml = updatedContentTypesXml.replace("</Types>", `${extendedDef}</Types>`);
44207
+ });
43923
44208
  if (fromJson) return updatedContentTypesXml;
43924
44209
  docx.file(contentTypesPath, updatedContentTypesXml);
43925
44210
  }
@@ -43960,7 +44245,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
43960
44245
  for (const [fontName, fontUintArray] of Object.entries(fonts)) {
43961
44246
  zip.file(fontName, fontUintArray);
43962
44247
  }
43963
- await this.updateContentTypes(zip, media);
44248
+ await this.updateContentTypes(zip, media, false, updatedDocs);
43964
44249
  return zip;
43965
44250
  }
43966
44251
  /**
@@ -43986,7 +44271,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
43986
44271
  Object.keys(media).forEach((path) => {
43987
44272
  unzippedOriginalDocx.file(path, media[path]);
43988
44273
  });
43989
- await this.updateContentTypes(unzippedOriginalDocx, media);
44274
+ await this.updateContentTypes(unzippedOriginalDocx, media, false, updatedDocs);
43990
44275
  return unzippedOriginalDocx;
43991
44276
  }
43992
44277
  }
@@ -55644,9 +55929,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
55644
55929
  item.editor.view.dom.setAttribute("documentmode", documentMode);
55645
55930
  });
55646
55931
  if (isEditMode) {
55647
- const pm = document.querySelector(".ProseMirror");
55648
- pm.classList.add("header-footer-edit");
55649
- pm.setAttribute("aria-readonly", true);
55932
+ const pm = editor.view?.dom || editor.options.element?.querySelector?.(".ProseMirror");
55933
+ if (pm) {
55934
+ pm.classList.add("header-footer-edit");
55935
+ pm.setAttribute("aria-readonly", true);
55936
+ }
55650
55937
  }
55651
55938
  if (focusedSectionEditor) {
55652
55939
  focusedSectionEditor.view.focus();
@@ -56676,6 +56963,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
56676
56963
  const mappedRowStart = tr.mapping.map(absoluteRowStart);
56677
56964
  const rowEnd = mappedRowStart + rowNode.nodeSize;
56678
56965
  tr.replaceWith(mappedRowStart, rowEnd, Fragment.from(newRows));
56966
+ tr.setMeta("tableGeneration", true);
56679
56967
  } catch (error) {
56680
56968
  console.error("Error during row generation:", error);
56681
56969
  throw error;
@@ -57080,7 +57368,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
57080
57368
  }
57081
57369
  function findRemovedFieldAnnotations(tr) {
57082
57370
  let removedNodes = [];
57083
- if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true) {
57371
+ if (!tr.steps.length || tr.meta && !Object.keys(tr.meta).every((meta) => ["inputType", "uiEvent", "paste"].includes(meta)) || ["historyUndo", "historyRedo"].includes(tr.getMeta("inputType")) || ["drop"].includes(tr.getMeta("uiEvent")) || tr.getMeta("fieldAnnotationUpdate") === true || tr.getMeta("tableGeneration") === true) {
57084
57372
  return removedNodes;
57085
57373
  }
57086
57374
  const hasDeletion = transactionDeletedAnything(tr);
@@ -58258,7 +58546,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
58258
58546
  setDocumentMode(documentMode) {
58259
58547
  let cleanedMode = documentMode?.toLowerCase() || "editing";
58260
58548
  if (!this.extensionService || !this.state) return;
58261
- const pm = document.querySelector(".ProseMirror");
58549
+ const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
58262
58550
  if (this.options.role === "viewer") cleanedMode = "viewing";
58263
58551
  if (this.options.role === "suggester" && cleanedMode === "editing") cleanedMode = "suggesting";
58264
58552
  if (cleanedMode === "viewing") {
@@ -58746,7 +59034,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
58746
59034
  files: this.options.content
58747
59035
  },
58748
59036
  media,
58749
- true
59037
+ true,
59038
+ updatedDocs
58750
59039
  );
58751
59040
  return updatedDocs;
58752
59041
  }
@@ -58812,7 +59101,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
58812
59101
  * @returns {Object | void} Migration results
58813
59102
  */
58814
59103
  processCollaborationMigrations() {
58815
- console.debug("[checkVersionMigrations] Current editor version", "0.20.2");
59104
+ console.debug("[checkVersionMigrations] Current editor version", "0.21.1");
58816
59105
  if (!this.options.ydoc) return;
58817
59106
  const metaMap = this.options.ydoc.getMap("meta");
58818
59107
  let docVersion = metaMap.get("version");
@@ -59232,9 +59521,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59232
59521
  isEditMode: false,
59233
59522
  documentMode: this.options.documentMode
59234
59523
  });
59235
- const pm = document.querySelector(".ProseMirror");
59236
- pm.classList.remove("header-footer-edit");
59237
- pm.setAttribute("aria-readonly", false);
59524
+ const pm = this.view?.dom || this.options.element?.querySelector?.(".ProseMirror");
59525
+ if (pm) {
59526
+ pm.classList.remove("header-footer-edit");
59527
+ pm.setAttribute("aria-readonly", false);
59528
+ }
59238
59529
  }
59239
59530
  setWordSelection(view, pos);
59240
59531
  }
@@ -61289,15 +61580,31 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61289
61580
  }
61290
61581
  return result;
61291
61582
  };
61292
- const CustomSelectionPluginKey = new PluginKey("CustomSelection");
61293
- const shouldAllowNativeContextMenu = (event) => {
61583
+ const isKeyboardInvocation = (event) => {
61584
+ return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
61585
+ };
61586
+ const prefersNativeMenu = (event) => {
61294
61587
  if (!event) return false;
61295
61588
  if (event.ctrlKey || event.metaKey) {
61296
61589
  return true;
61297
61590
  }
61298
- const isKeyboardInvocation = event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
61299
- return Boolean(isKeyboardInvocation);
61591
+ return isKeyboardInvocation(event);
61300
61592
  };
61593
+ const shouldAllowNativeContextMenu = (event) => {
61594
+ return prefersNativeMenu(event);
61595
+ };
61596
+ const shouldBypassContextMenu = shouldAllowNativeContextMenu;
61597
+ const DEFAULT_SELECTION_STATE = Object.freeze({
61598
+ focused: false,
61599
+ preservedSelection: null,
61600
+ showVisualSelection: false,
61601
+ skipFocusReset: false
61602
+ });
61603
+ const normalizeSelectionState = (state2 = {}) => ({
61604
+ ...DEFAULT_SELECTION_STATE,
61605
+ ...state2
61606
+ });
61607
+ const CustomSelectionPluginKey = new PluginKey("CustomSelection");
61301
61608
  const handleClickOutside = (event, editor) => {
61302
61609
  const editorElem = editor?.options?.element;
61303
61610
  if (!editorElem) return;
@@ -61334,11 +61641,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61334
61641
  const customSelectionPlugin = new Plugin({
61335
61642
  key: CustomSelectionPluginKey,
61336
61643
  state: {
61337
- init: () => ({
61338
- focused: false,
61339
- preservedSelection: null,
61340
- showVisualSelection: false
61341
- }),
61644
+ init: () => ({ ...DEFAULT_SELECTION_STATE }),
61342
61645
  apply: (tr, value) => {
61343
61646
  const meta = getFocusMeta(tr);
61344
61647
  if (meta !== void 0) {
@@ -61369,7 +61672,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61369
61672
  setFocusMeta(view.state.tr, {
61370
61673
  focused: true,
61371
61674
  preservedSelection: selection,
61372
- showVisualSelection: true
61675
+ showVisualSelection: true,
61676
+ skipFocusReset: true
61373
61677
  })
61374
61678
  );
61375
61679
  }
@@ -61390,7 +61694,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61390
61694
  setFocusMeta(view.state.tr, {
61391
61695
  focused: true,
61392
61696
  preservedSelection: selection2,
61393
- showVisualSelection: true
61697
+ showVisualSelection: true,
61698
+ skipFocusReset: true
61394
61699
  })
61395
61700
  );
61396
61701
  this.editor.setOptions({
@@ -61413,7 +61718,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61413
61718
  setFocusMeta(view.state.tr, {
61414
61719
  focused: true,
61415
61720
  preservedSelection: selection,
61416
- showVisualSelection: true
61721
+ showVisualSelection: true,
61722
+ skipFocusReset: false
61417
61723
  })
61418
61724
  );
61419
61725
  this.editor.setOptions({
@@ -61431,7 +61737,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61431
61737
  setFocusMeta(view.state.tr, {
61432
61738
  focused: true,
61433
61739
  preservedSelection: selection,
61434
- showVisualSelection: true
61740
+ showVisualSelection: true,
61741
+ skipFocusReset: false
61435
61742
  })
61436
61743
  );
61437
61744
  }
@@ -61442,7 +61749,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61442
61749
  setFocusMeta(view.state.tr, {
61443
61750
  focused: false,
61444
61751
  preservedSelection: null,
61445
- showVisualSelection: false
61752
+ showVisualSelection: false,
61753
+ skipFocusReset: false
61446
61754
  })
61447
61755
  );
61448
61756
  if (!selection.empty && !this.editor.options.element?.contains(target)) {
@@ -61459,12 +61767,20 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61459
61767
  const isElement2 = target instanceof Element;
61460
61768
  const isToolbarBtn = isElement2 && isToolbarButton(target);
61461
61769
  const isToolbarInp = isElement2 && isToolbarInput(target);
61770
+ const focusState = getFocusState(view.state);
61771
+ if (focusState?.skipFocusReset) {
61772
+ view.dispatch(
61773
+ setFocusMeta(view.state.tr, normalizeSelectionState({ ...focusState, skipFocusReset: false }))
61774
+ );
61775
+ return false;
61776
+ }
61462
61777
  if (!isToolbarBtn && !isToolbarInp) {
61463
61778
  view.dispatch(
61464
61779
  setFocusMeta(view.state.tr, {
61465
61780
  focused: false,
61466
61781
  preservedSelection: null,
61467
- showVisualSelection: false
61782
+ showVisualSelection: false,
61783
+ skipFocusReset: false
61468
61784
  })
61469
61785
  );
61470
61786
  }
@@ -61475,12 +61791,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61475
61791
  const isToolbarBtn = isElement2 && isToolbarButton(target);
61476
61792
  const isToolbarInp = isElement2 && isToolbarInput(target);
61477
61793
  const state2 = getFocusState(view.state);
61794
+ if (state2?.skipFocusReset) {
61795
+ return false;
61796
+ }
61478
61797
  if (isToolbarBtn || isToolbarInp) {
61479
61798
  view.dispatch(
61480
61799
  setFocusMeta(view.state.tr, {
61481
61800
  focused: true,
61482
61801
  preservedSelection: state2.preservedSelection || view.state.selection,
61483
- showVisualSelection: true
61802
+ showVisualSelection: true,
61803
+ skipFocusReset: false
61484
61804
  })
61485
61805
  );
61486
61806
  } else {
@@ -61488,7 +61808,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61488
61808
  setFocusMeta(view.state.tr, {
61489
61809
  focused: false,
61490
61810
  preservedSelection: null,
61491
- showVisualSelection: false
61811
+ showVisualSelection: false,
61812
+ skipFocusReset: false
61492
61813
  })
61493
61814
  );
61494
61815
  }
@@ -77263,7 +77584,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
77263
77584
  const prevSelection = prevState.selection;
77264
77585
  if (selection.from !== prevSelection.from || selection.to !== prevSelection.to) {
77265
77586
  setTimeout(() => {
77266
- const selectedResizableWrapper = document.querySelector(".sd-editor-resizable-wrapper");
77587
+ const searchRoot = editorView?.dom;
77588
+ const selectedResizableWrapper = searchRoot?.querySelector(".sd-editor-resizable-wrapper");
77267
77589
  if (selectedResizableWrapper) {
77268
77590
  showResizeHandles(view2, selectedResizableWrapper);
77269
77591
  } else {
@@ -90799,7 +91121,7 @@ ${style2}
90799
91121
  if (!argument) return;
90800
91122
  item.onActivate({ zoom: argument });
90801
91123
  this.emit("superdoc-command", { item, argument });
90802
- const layers = document.querySelector(this.superdoc.config.selector)?.querySelector(".layers");
91124
+ const layers = this.superdoc.element?.querySelector(".layers");
90803
91125
  if (!layers) return;
90804
91126
  const isMobileDevice = typeof screen.orientation !== "undefined";
90805
91127
  const isSmallScreen = window.matchMedia("(max-width: 834px)").matches;
@@ -91861,14 +92183,6 @@ ${style2}
91861
92183
  return null;
91862
92184
  }
91863
92185
  }
91864
- const shouldBypassContextMenu = (event) => {
91865
- if (!event) return false;
91866
- if (event.ctrlKey || event.metaKey) {
91867
- return true;
91868
- }
91869
- const isKeyboardInvocation = event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
91870
- return Boolean(isKeyboardInvocation);
91871
- };
91872
92186
  const isModuleEnabled = (editorOptions, moduleName) => {
91873
92187
  switch (moduleName) {
91874
92188
  case "ai":
@@ -110461,7 +110775,7 @@ ${style2}
110461
110775
  this.config.colors = shuffleArray(this.config.colors);
110462
110776
  this.userColorMap = /* @__PURE__ */ new Map();
110463
110777
  this.colorIndex = 0;
110464
- this.version = "0.20.2";
110778
+ this.version = "0.21.1";
110465
110779
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
110466
110780
  this.superdocId = config2.superdocId || v4();
110467
110781
  this.colors = this.config.colors;
@@ -110476,6 +110790,9 @@ ${style2}
110476
110790
  this.isDev = this.config.isDev || false;
110477
110791
  this.activeEditor = null;
110478
110792
  this.comments = [];
110793
+ if (!this.config.selector) {
110794
+ throw new Error("SuperDoc: selector is required");
110795
+ }
110479
110796
  this.app.mount(this.config.selector);
110480
110797
  this.readyEditors = 0;
110481
110798
  this.isLocked = this.config.isLocked || false;
@@ -110495,6 +110812,16 @@ ${style2}
110495
110812
  users: this.users
110496
110813
  };
110497
110814
  }
110815
+ /**
110816
+ * Get the SuperDoc container element
110817
+ * @returns {HTMLElement | null}
110818
+ */
110819
+ get element() {
110820
+ if (typeof this.config.selector === "string") {
110821
+ return document.querySelector(this.config.selector);
110822
+ }
110823
+ return this.config.selector;
110824
+ }
110498
110825
  #patchNaiveUIStyles() {
110499
110826
  const cspNonce = this.config.cspNonce;
110500
110827
  const originalCreateElement = document.createElement;
@@ -110518,10 +110845,16 @@ ${style2}
110518
110845
  }
110519
110846
  if (hasDocumentConfig) {
110520
110847
  const normalized = normalizeDocumentEntry(this.config.document);
110521
- this.config.documents = [normalized];
110848
+ this.config.documents = [
110849
+ {
110850
+ id: v4(),
110851
+ ...normalized
110852
+ }
110853
+ ];
110522
110854
  } else if (hasDocumentUrl) {
110523
110855
  this.config.documents = [
110524
110856
  {
110857
+ id: v4(),
110525
110858
  type: DOCX,
110526
110859
  url: this.config.document,
110527
110860
  name: "document.docx",
@@ -110529,33 +110862,34 @@ ${style2}
110529
110862
  }
110530
110863
  ];
110531
110864
  } else if (hasDocumentFile) {
110865
+ const normalized = normalizeDocumentEntry(this.config.document);
110532
110866
  this.config.documents = [
110533
110867
  {
110534
- type: this.config.document.type,
110535
- data: this.config.document,
110536
- name: this.config.document.name,
110537
- isNewFile: true
110868
+ id: v4(),
110869
+ ...normalized
110538
110870
  }
110539
110871
  ];
110540
110872
  } else if (hasDocumentBlob) {
110541
- const docType = this.config.document.type || DOCX;
110542
- let extension = ".docx";
110543
- if (docType === PDF) {
110544
- extension = ".pdf";
110545
- } else if (docType === HTML) {
110546
- extension = ".html";
110547
- }
110873
+ const normalized = normalizeDocumentEntry(this.config.document);
110548
110874
  this.config.documents = [
110549
110875
  {
110550
- type: docType,
110551
- data: this.config.document,
110552
- name: `document${extension}`,
110553
- isNewFile: true
110876
+ id: v4(),
110877
+ ...normalized
110554
110878
  }
110555
110879
  ];
110556
110880
  }
110557
110881
  if (Array.isArray(this.config.documents) && this.config.documents.length > 0) {
110558
- this.config.documents = this.config.documents.map((d2) => normalizeDocumentEntry(d2));
110882
+ this.config.documents = this.config.documents.map((d2) => {
110883
+ const normalized = normalizeDocumentEntry(d2);
110884
+ if (!normalized || typeof normalized !== "object") {
110885
+ return normalized;
110886
+ }
110887
+ const existingId = typeof normalized === "object" && "id" in normalized && normalized.id || d2 && typeof d2 === "object" && "id" in d2 && d2.id;
110888
+ return {
110889
+ ...normalized,
110890
+ id: existingId || v4()
110891
+ };
110892
+ });
110559
110893
  }
110560
110894
  }
110561
110895
  #initVueApp() {