superdoc 1.0.0-beta.22 → 1.0.0-beta.23

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 (27) hide show
  1. package/dist/chunks/{PdfViewer-CswYWp1h.cjs → PdfViewer-C9mryfp4.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-B42JCeYb.es.js → PdfViewer-umOKwA1g.es.js} +1 -1
  3. package/dist/chunks/{index-895wSAjT-CWlZl8zz.cjs → index-DYBG7Xab-CoI6fike.cjs} +1 -1
  4. package/dist/chunks/{index-895wSAjT-C4ksiI6n.es.js → index-DYBG7Xab-mIeLdlWI.es.js} +1 -1
  5. package/dist/chunks/{index-DBmh710D.es.js → index-DyY842H4.es.js} +3 -3
  6. package/dist/chunks/{index-CK4eX_iu.cjs → index-Q-l_lwcU.cjs} +3 -3
  7. package/dist/chunks/{super-editor.es-BkRizaIE.cjs → super-editor.es-49DW4_-r.cjs} +243 -62
  8. package/dist/chunks/{super-editor.es-V792hb-6.es.js → super-editor.es-Cj9Sb-Qv.es.js} +243 -62
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-DhkZt4Pv.js → converter-DJyfDFNm.js} +33 -29
  11. package/dist/super-editor/chunks/{docx-zipper-Bajmc-RM.js → docx-zipper-C-9Tqy8I.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-oZjoYNA0.js → editor-f37DOCIX.js} +212 -35
  13. package/dist/super-editor/chunks/{index-895wSAjT.js → index-DYBG7Xab.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-Bn5LTbq9.js → toolbar-Devgq8w3.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +6 -6
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +245 -64
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import { a, E, b, S, d, i, j, n, r, p, q } from "./chunks/super-editor.es-V792hb-6.es.js";
2
- import { D, H, P, S as S2, m, l } from "./chunks/index-DBmh710D.es.js";
1
+ import { a, E, b, S, d, i, j, n, r, p, q } from "./chunks/super-editor.es-Cj9Sb-Qv.es.js";
2
+ import { D, H, P, S as S2, m, l } from "./chunks/index-DyY842H4.es.js";
3
3
  import { B } from "./chunks/blank-docx-ABm6XYAA.es.js";
4
4
  export {
5
5
  a as AnnotatorHelpers,
@@ -24996,24 +24996,32 @@
24996
24996
  const DRAWING_XML_TAG = "w:drawing";
24997
24997
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
24998
24998
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
24999
+ const normalizeTargetPath = (targetPath = "") => {
25000
+ if (!targetPath) return targetPath;
25001
+ const trimmed = targetPath.replace(/^\/+/, "");
25002
+ if (trimmed.startsWith("word/")) return trimmed;
25003
+ if (trimmed.startsWith("media/")) return `word/${trimmed}`;
25004
+ return `word/${trimmed}`;
25005
+ };
24999
25006
  const DEFAULT_SHAPE_WIDTH = 100;
25000
25007
  const DEFAULT_SHAPE_HEIGHT = 100;
25001
25008
  function handleImageNode$1(node2, params2, isAnchor) {
25009
+ if (!node2) return null;
25002
25010
  const { docx, filename } = params2;
25003
- const { attributes } = node2;
25011
+ const attributes = node2?.attributes || {};
25004
25012
  const padding = {
25005
- top: emuToPixels(attributes["distT"]),
25006
- bottom: emuToPixels(attributes["distB"]),
25007
- left: emuToPixels(attributes["distL"]),
25008
- right: emuToPixels(attributes["distR"])
25013
+ top: emuToPixels(attributes?.["distT"]),
25014
+ bottom: emuToPixels(attributes?.["distB"]),
25015
+ left: emuToPixels(attributes?.["distL"]),
25016
+ right: emuToPixels(attributes?.["distR"])
25009
25017
  };
25010
- const extent = node2.elements.find((el) => el.name === "wp:extent");
25018
+ const extent = node2?.elements?.find((el) => el.name === "wp:extent");
25011
25019
  const size2 = {
25012
25020
  width: emuToPixels(extent?.attributes?.cx),
25013
25021
  height: emuToPixels(extent?.attributes?.cy)
25014
25022
  };
25015
25023
  let transformData = {};
25016
- const effectExtent = node2.elements.find((el) => el.name === "wp:effectExtent");
25024
+ const effectExtent = node2?.elements?.find((el) => el.name === "wp:effectExtent");
25017
25025
  if (effectExtent) {
25018
25026
  const sanitizeEmuValue = (value) => {
25019
25027
  if (value === null || value === void 0) return 0;
@@ -25027,12 +25035,12 @@
25027
25035
  bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["b"]))
25028
25036
  };
25029
25037
  }
25030
- const positionHTag = node2.elements.find((el) => el.name === "wp:positionH");
25031
- const positionH = positionHTag?.elements.find((el) => el.name === "wp:posOffset");
25038
+ const positionHTag = node2?.elements?.find((el) => el.name === "wp:positionH");
25039
+ const positionH = positionHTag?.elements?.find((el) => el.name === "wp:posOffset");
25032
25040
  const positionHValue = emuToPixels(positionH?.elements[0]?.text);
25033
25041
  const hRelativeFrom = positionHTag?.attributes?.relativeFrom;
25034
- const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
25035
- const positionVTag = node2.elements.find((el) => el.name === "wp:positionV");
25042
+ const alignH = positionHTag?.elements?.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
25043
+ const positionVTag = node2?.elements?.find((el) => el.name === "wp:positionV");
25036
25044
  const positionV = positionVTag?.elements?.find((el) => el.name === "wp:posOffset");
25037
25045
  const positionVValue = emuToPixels(positionV?.elements[0]?.text);
25038
25046
  const vRelativeFrom = positionVTag?.attributes?.relativeFrom;
@@ -25042,8 +25050,8 @@
25042
25050
  top: positionVValue
25043
25051
  };
25044
25052
  const useSimplePos = attributes["simplePos"] === "1" || attributes["simplePos"] === 1 || attributes["simplePos"] === true;
25045
- const simplePosNode = node2.elements.find((el) => el.name === "wp:simplePos");
25046
- const wrapNode = isAnchor ? node2.elements.find(
25053
+ const simplePosNode = node2?.elements?.find((el) => el.name === "wp:simplePos");
25054
+ const wrapNode = isAnchor ? node2?.elements?.find(
25047
25055
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
25048
25056
  ) : null;
25049
25057
  const wrap2 = isAnchor ? { type: wrapNode?.name.slice(7) || "None", attrs: {} } : { type: "Inline" };
@@ -25164,9 +25172,8 @@
25164
25172
  if (!rel) return null;
25165
25173
  const { attributes: relAttributes } = rel;
25166
25174
  const targetPath = relAttributes["Target"];
25167
- let path2 = `word/${targetPath}`;
25168
- if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) path2 = targetPath.substring(1);
25169
- const extension = targetPath.substring(targetPath.lastIndexOf(".") + 1);
25175
+ const path2 = normalizeTargetPath(targetPath);
25176
+ const extension = path2.substring(path2.lastIndexOf(".") + 1);
25170
25177
  return {
25171
25178
  type: "image",
25172
25179
  attrs: {
@@ -25184,8 +25191,8 @@
25184
25191
  transformData,
25185
25192
  ...useSimplePos && {
25186
25193
  simplePos: {
25187
- x: simplePosNode.attributes?.x,
25188
- y: simplePosNode.attributes?.y
25194
+ x: simplePosNode?.attributes?.x,
25195
+ y: simplePosNode?.attributes?.y
25189
25196
  }
25190
25197
  },
25191
25198
  wrap: wrap2,
@@ -25195,12 +25202,12 @@
25195
25202
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
25196
25203
  shouldStretch,
25197
25204
  originalPadding: {
25198
- distT: attributes["distT"],
25199
- distB: attributes["distB"],
25200
- distL: attributes["distL"],
25201
- distR: attributes["distR"]
25205
+ distT: attributes?.["distT"],
25206
+ distB: attributes?.["distB"],
25207
+ distL: attributes?.["distL"],
25208
+ distR: attributes?.["distR"]
25202
25209
  },
25203
- originalAttributes: node2.attributes,
25210
+ originalAttributes: node2?.attributes || {},
25204
25211
  rId: relAttributes["Id"]
25205
25212
  }
25206
25213
  };
@@ -25364,11 +25371,8 @@
25364
25371
  const { elements } = relationships || [];
25365
25372
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
25366
25373
  if (!rel) return null;
25367
- const targetPath = rel.attributes?.["Target"];
25368
- let path2 = `word/${targetPath}`;
25369
- if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) {
25370
- path2 = targetPath.substring(1);
25371
- }
25374
+ const targetPath = normalizeTargetPath(rel.attributes?.["Target"]);
25375
+ const path2 = targetPath;
25372
25376
  const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
25373
25377
  const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
25374
25378
  const picId = cNvPr?.attributes?.["id"];
@@ -36389,7 +36393,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36389
36393
  static getStoredSuperdocVersion(docx) {
36390
36394
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
36391
36395
  }
36392
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.22") {
36396
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.23") {
36393
36397
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36394
36398
  }
36395
36399
  /**
@@ -61411,7 +61415,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61411
61415
  const shouldSkipNodeView = (editor) => {
61412
61416
  return isHeadless(editor);
61413
61417
  };
61414
- const summaryVersion = "1.0.0-beta.22";
61418
+ const summaryVersion = "1.0.0-beta.23";
61415
61419
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
61416
61420
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
61417
61421
  function mapAttributes(attrs) {
@@ -62200,7 +62204,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62200
62204
  { default: remarkStringify2 },
62201
62205
  { default: remarkGfm2 }
62202
62206
  ] = await Promise.all([
62203
- Promise.resolve().then(() => index895wSAjT),
62207
+ Promise.resolve().then(() => indexDYBG7Xab),
62204
62208
  Promise.resolve().then(() => indexDRCvimau),
62205
62209
  Promise.resolve().then(() => indexC_x_N6Uh),
62206
62210
  Promise.resolve().then(() => indexD_sWOSiG),
@@ -62405,7 +62409,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62405
62409
  * Process collaboration migrations
62406
62410
  */
62407
62411
  processCollaborationMigrations() {
62408
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.22");
62412
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.23");
62409
62413
  if (!this.options.ydoc) return;
62410
62414
  const metaMap = this.options.ydoc.getMap("meta");
62411
62415
  let docVersion = metaMap.get("version");
@@ -64857,6 +64861,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64857
64861
  case "right":
64858
64862
  case "justify":
64859
64863
  return value;
64864
+ case "both":
64865
+ case "distribute":
64866
+ case "numTab":
64867
+ case "thaiDistribute":
64868
+ return "justify";
64860
64869
  case "end":
64861
64870
  return "right";
64862
64871
  case "start":
@@ -67071,6 +67080,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67071
67080
  } else if (computed2.paragraph.alignment) {
67072
67081
  paragraphAttrs.alignment = computed2.paragraph.alignment;
67073
67082
  }
67083
+ const isJustified = paragraphAttrs.alignment === "justify" || paragraphAttrs.alignment === "both";
67084
+ const hasFirstLineIndent = normalizedIndent?.firstLine && normalizedIndent.firstLine > 0;
67085
+ if (isJustified && hasFirstLineIndent) {
67086
+ paragraphAttrs.suppressFirstLineIndent = true;
67087
+ }
67074
67088
  const spacingPx = spacingPtToPx(spacing, normalizedSpacing);
67075
67089
  if (spacingPx) paragraphAttrs.spacing = spacingPx;
67076
67090
  if (normalizedSpacing?.beforeAutospacing != null || normalizedSpacing?.afterAutospacing != null) {
@@ -67288,7 +67302,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67288
67302
  }
67289
67303
  }
67290
67304
  paragraphAttrs.wordLayout = wordLayout;
67291
- if (enrichedNumberingProps.resolvedLevelIndent) {
67305
+ if (enrichedNumberingProps.resolvedLevelIndent && !hasExplicitIndent) {
67292
67306
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
67293
67307
  paragraphAttrs.indent = {
67294
67308
  ...paragraphAttrs.indent,
@@ -70654,8 +70668,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
70654
70668
  });
70655
70669
  return nextSectionPropsAtBreak;
70656
70670
  }
70657
- function scheduleSectionBreak(block, state2, baseMargins) {
70671
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
70658
70672
  const next2 = { ...state2 };
70673
+ const calcRequiredTopMargin = (headerDistance, baseTop) => {
70674
+ if (maxHeaderContentHeight > 0) {
70675
+ return Math.max(baseTop, headerDistance + maxHeaderContentHeight);
70676
+ }
70677
+ return Math.max(baseTop, headerDistance);
70678
+ };
70659
70679
  if (block.attrs?.isFirstSection && !next2.hasAnyPages) {
70660
70680
  if (block.pageSize) {
70661
70681
  next2.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -70669,7 +70689,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
70669
70689
  const headerDistance = Math.max(0, block.margins.header);
70670
70690
  next2.activeHeaderDistance = headerDistance;
70671
70691
  next2.pendingHeaderDistance = headerDistance;
70672
- next2.activeTopMargin = Math.max(baseMargins.top, headerDistance);
70692
+ next2.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
70673
70693
  next2.pendingTopMargin = next2.activeTopMargin;
70674
70694
  }
70675
70695
  if (block.margins?.footer !== void 0) {
@@ -70691,9 +70711,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
70691
70711
  const nextBottom = next2.pendingBottomMargin ?? next2.activeBottomMargin;
70692
70712
  const nextHeader = next2.pendingHeaderDistance ?? next2.activeHeaderDistance;
70693
70713
  const nextFooter = next2.pendingFooterDistance ?? next2.activeFooterDistance;
70694
- next2.pendingTopMargin = typeof headerPx === "number" ? Math.max(baseMargins.top, headerPx) : nextTop;
70714
+ if (typeof headerPx === "number") {
70715
+ const newHeaderDist = Math.max(0, headerPx);
70716
+ next2.pendingHeaderDistance = newHeaderDist;
70717
+ next2.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
70718
+ } else {
70719
+ next2.pendingTopMargin = nextTop;
70720
+ next2.pendingHeaderDistance = nextHeader;
70721
+ }
70695
70722
  next2.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
70696
- next2.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
70697
70723
  next2.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
70698
70724
  if (block.pageSize) {
70699
70725
  next2.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -72158,7 +72184,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72158
72184
  if (contentWidth <= 0) {
72159
72185
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
72160
72186
  }
72161
- let activeTopMargin = margins.top;
72187
+ const validateHeaderHeight = (height) => {
72188
+ if (height === void 0) return 0;
72189
+ if (!Number.isFinite(height) || height < 0) return 0;
72190
+ return height;
72191
+ };
72192
+ const headerContentHeights = options.headerContentHeights;
72193
+ const maxHeaderContentHeight = headerContentHeights ? Math.max(
72194
+ 0,
72195
+ validateHeaderHeight(headerContentHeights.default),
72196
+ validateHeaderHeight(headerContentHeights.first),
72197
+ validateHeaderHeight(headerContentHeights.even),
72198
+ validateHeaderHeight(headerContentHeights.odd)
72199
+ ) : 0;
72200
+ const headerDistance = margins.header ?? margins.top;
72201
+ const effectiveTopMargin = maxHeaderContentHeight > 0 ? Math.max(margins.top, headerDistance + maxHeaderContentHeight) : margins.top;
72202
+ let activeTopMargin = effectiveTopMargin;
72162
72203
  let activeBottomMargin = margins.bottom;
72163
72204
  let pendingTopMargin = null;
72164
72205
  let pendingBottomMargin = null;
@@ -72182,7 +72223,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72182
72223
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks2);
72183
72224
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
72184
72225
  if (typeof scheduleSectionBreak === "function") {
72185
- return scheduleSectionBreak(block, state2, baseMargins);
72226
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
72186
72227
  }
72187
72228
  const next2 = { ...state2 };
72188
72229
  if (block.attrs?.isFirstSection && !next2.hasAnyPages) {
@@ -72195,10 +72236,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72195
72236
  next2.pendingOrientation = null;
72196
72237
  }
72197
72238
  if (block.margins?.header !== void 0) {
72198
- const headerDistance = Math.max(0, block.margins.header);
72199
- next2.activeHeaderDistance = headerDistance;
72200
- next2.pendingHeaderDistance = headerDistance;
72201
- next2.activeTopMargin = Math.max(baseMargins.top, headerDistance);
72239
+ const headerDist = Math.max(0, block.margins.header);
72240
+ next2.activeHeaderDistance = headerDist;
72241
+ next2.pendingHeaderDistance = headerDist;
72242
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
72243
+ next2.activeTopMargin = Math.max(baseMargins.top, requiredTop);
72202
72244
  next2.pendingTopMargin = next2.activeTopMargin;
72203
72245
  }
72204
72246
  if (block.margins?.footer !== void 0) {
@@ -72235,14 +72277,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72235
72277
  }
72236
72278
  const headerPx = block.margins?.header;
72237
72279
  const footerPx = block.margins?.footer;
72280
+ const topPx = block.margins?.top;
72238
72281
  const nextTop = next2.pendingTopMargin ?? next2.activeTopMargin;
72239
72282
  const nextBottom = next2.pendingBottomMargin ?? next2.activeBottomMargin;
72240
72283
  const nextHeader = next2.pendingHeaderDistance ?? next2.activeHeaderDistance;
72241
72284
  const nextFooter = next2.pendingFooterDistance ?? next2.activeFooterDistance;
72242
- next2.pendingTopMargin = typeof headerPx === "number" ? Math.max(baseMargins.top, headerPx) : nextTop;
72243
- next2.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
72244
72285
  next2.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
72245
72286
  next2.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
72287
+ if (typeof headerPx === "number" || typeof topPx === "number") {
72288
+ const sectionTop = topPx ?? baseMargins.top;
72289
+ const sectionHeader = next2.pendingHeaderDistance;
72290
+ const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
72291
+ next2.pendingTopMargin = Math.max(sectionTop, requiredTop);
72292
+ } else {
72293
+ next2.pendingTopMargin = nextTop;
72294
+ }
72295
+ next2.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
72246
72296
  if (block.pageSize) next2.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
72247
72297
  if (block.orientation) next2.pendingOrientation = block.orientation;
72248
72298
  const sectionType = block.type ?? "continuous";
@@ -72993,7 +73043,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72993
73043
  }
72994
73044
  return attrs.trackedChangesEnabled !== false;
72995
73045
  };
72996
- const MAX_CACHE_SIZE = 1e4;
73046
+ const MAX_CACHE_SIZE$1 = 1e4;
72997
73047
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
72998
73048
  const NORMALIZED_WHITESPACE = /\s+/g;
72999
73049
  const normalizeText = (text2) => text2.replace(NORMALIZED_WHITESPACE, " ");
@@ -73093,7 +73143,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
73093
73143
  if (this.cache.has(key2)) {
73094
73144
  this.cache.delete(key2);
73095
73145
  }
73096
- if (this.cache.size >= MAX_CACHE_SIZE) {
73146
+ if (this.cache.size >= MAX_CACHE_SIZE$1) {
73097
73147
  const oldestKey = this.cache.keys().next().value;
73098
73148
  if (oldestKey !== void 0) {
73099
73149
  this.cache.delete(oldestKey);
@@ -73167,13 +73217,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
73167
73217
  * Get maximum cache size
73168
73218
  */
73169
73219
  getMaxSize() {
73170
- return MAX_CACHE_SIZE;
73220
+ return MAX_CACHE_SIZE$1;
73171
73221
  }
73172
73222
  /**
73173
73223
  * Check if cache is near capacity
73174
73224
  */
73175
73225
  isNearCapacity(threshold = 0.9) {
73176
- return this.cache.size >= MAX_CACHE_SIZE * threshold;
73226
+ return this.cache.size >= MAX_CACHE_SIZE$1 * threshold;
73177
73227
  }
73178
73228
  /**
73179
73229
  * Update size statistics
@@ -74185,9 +74235,46 @@ Please report this to https://github.com/markedjs/marked.`, e) {
74185
74235
  perfLog(
74186
74236
  `[Perf] 4.1 Measure all blocks: ${(measureEnd - measureStart).toFixed(2)}ms (${cacheMisses} measured, ${cacheHits} cached)`
74187
74237
  );
74238
+ let headerContentHeights;
74239
+ if (headerFooter?.constraints && headerFooter.headerBlocks) {
74240
+ const hfPreStart = performance.now();
74241
+ const measureFn = headerFooter.measure ?? measureBlock2;
74242
+ invalidateHeaderFooterCache(
74243
+ headerMeasureCache,
74244
+ headerFooterCacheState,
74245
+ headerFooter.headerBlocks,
74246
+ headerFooter.footerBlocks,
74247
+ headerFooter.constraints,
74248
+ options.sectionMetadata
74249
+ );
74250
+ const HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT = 1;
74251
+ const preHeaderLayouts = await layoutHeaderFooterWithCache(
74252
+ headerFooter.headerBlocks,
74253
+ headerFooter.constraints,
74254
+ measureFn,
74255
+ headerMeasureCache,
74256
+ HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT,
74257
+ void 0
74258
+ // No page resolver needed for height calculation
74259
+ );
74260
+ const isValidHeaderType = (key2) => {
74261
+ return ["default", "first", "even", "odd"].includes(key2);
74262
+ };
74263
+ headerContentHeights = {};
74264
+ for (const [type2, value] of Object.entries(preHeaderLayouts)) {
74265
+ if (!isValidHeaderType(type2)) continue;
74266
+ if (value?.layout && typeof value.layout.height === "number") {
74267
+ headerContentHeights[type2] = value.layout.height;
74268
+ }
74269
+ }
74270
+ const hfPreEnd = performance.now();
74271
+ perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
74272
+ }
74188
74273
  const layoutStart = performance.now();
74189
74274
  let layout = layoutDocument(nextBlocks, measures, {
74190
74275
  ...options,
74276
+ headerContentHeights,
74277
+ // Pass header heights to prevent overlap
74191
74278
  remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
74192
74279
  });
74193
74280
  const layoutEnd = performance.now();
@@ -74234,6 +74321,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
74234
74321
  const relayoutStart = performance.now();
74235
74322
  layout = layoutDocument(currentBlocks, currentMeasures, {
74236
74323
  ...options,
74324
+ headerContentHeights,
74325
+ // Pass header heights to prevent overlap
74237
74326
  remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
74238
74327
  });
74239
74328
  const relayoutEnd = performance.now();
@@ -77283,7 +77372,12 @@ ${l}
77283
77372
  height: `${lineHeight2}px`,
77284
77373
  position: "relative",
77285
77374
  display: "block",
77286
- whiteSpace: "pre"
77375
+ whiteSpace: "pre",
77376
+ // Allow text to overflow the line container as a safety net.
77377
+ // The primary fix uses accurate font metrics from Canvas API, but this
77378
+ // provides defense-in-depth against any remaining sub-pixel rendering
77379
+ // differences between measurement and display.
77380
+ overflow: "visible"
77287
77381
  });
77288
77382
  const PRINT_STYLES = `
77289
77383
  @media print {
@@ -78849,7 +78943,8 @@ ${l}
78849
78943
  const paraIndent = block.attrs?.indent;
78850
78944
  const paraIndentLeft = paraIndent?.left ?? 0;
78851
78945
  const paraIndentRight = paraIndent?.right ?? 0;
78852
- const firstLineOffset = (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
78946
+ const suppressFirstLineIndent = block.attrs?.suppressFirstLineIndent === true;
78947
+ const firstLineOffset = suppressFirstLineIndent ? 0 : (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
78853
78948
  lines.forEach((line, index2) => {
78854
78949
  const lineEl = this.renderLine(block, line, context);
78855
78950
  const isListFirstLine = index2 === 0 && !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
@@ -81038,6 +81133,61 @@ ${l}
81038
81133
  cache$1$1.delete(oldestKey);
81039
81134
  }
81040
81135
  }
81136
+ const fontMetricsCache = /* @__PURE__ */ new Map();
81137
+ const MAX_CACHE_SIZE = 1e3;
81138
+ const METRICS_TEST_STRING = "MHgypbdlÁÉÍ";
81139
+ function getFontKey(fontInfo) {
81140
+ return `${fontInfo.fontFamily}|${fontInfo.fontSize}|${fontInfo.bold ?? false}|${fontInfo.italic ?? false}`;
81141
+ }
81142
+ function buildFontStringForMetrics(fontInfo, mode, fonts) {
81143
+ const parts = [];
81144
+ if (fontInfo.italic) parts.push("italic");
81145
+ if (fontInfo.bold) parts.push("bold");
81146
+ parts.push(`${fontInfo.fontSize}px`);
81147
+ {
81148
+ parts.push(fontInfo.fontFamily);
81149
+ }
81150
+ return parts.join(" ");
81151
+ }
81152
+ function getFontMetrics(ctx2, fontInfo, mode, fonts) {
81153
+ if (!ctx2 || typeof ctx2 !== "object") {
81154
+ throw new TypeError("Canvas context must be a valid CanvasRenderingContext2D object");
81155
+ }
81156
+ if (typeof fontInfo.fontSize !== "number" || !Number.isFinite(fontInfo.fontSize) || fontInfo.fontSize <= 0) {
81157
+ throw new TypeError(
81158
+ `Font size must be a positive finite number, got: ${typeof fontInfo.fontSize === "number" ? fontInfo.fontSize : typeof fontInfo.fontSize}`
81159
+ );
81160
+ }
81161
+ if (typeof fontInfo.fontFamily !== "string" || fontInfo.fontFamily.trim().length === 0) {
81162
+ throw new TypeError("Font family must be a non-empty string");
81163
+ }
81164
+ const key2 = getFontKey(fontInfo);
81165
+ const cached = fontMetricsCache.get(key2);
81166
+ if (cached) {
81167
+ return cached;
81168
+ }
81169
+ const font = buildFontStringForMetrics(fontInfo);
81170
+ ctx2.font = font;
81171
+ const textMetrics = ctx2.measureText(METRICS_TEST_STRING);
81172
+ let ascent;
81173
+ let descent;
81174
+ if (typeof textMetrics.actualBoundingBoxAscent === "number" && typeof textMetrics.actualBoundingBoxDescent === "number" && textMetrics.actualBoundingBoxAscent > 0) {
81175
+ ascent = textMetrics.actualBoundingBoxAscent;
81176
+ descent = textMetrics.actualBoundingBoxDescent;
81177
+ } else {
81178
+ ascent = fontInfo.fontSize * 0.8;
81179
+ descent = fontInfo.fontSize * 0.2;
81180
+ }
81181
+ const result = { ascent, descent };
81182
+ if (fontMetricsCache.size >= MAX_CACHE_SIZE) {
81183
+ const firstKey = fontMetricsCache.keys().next().value;
81184
+ if (firstKey) {
81185
+ fontMetricsCache.delete(firstKey);
81186
+ }
81187
+ }
81188
+ fontMetricsCache.set(key2, result);
81189
+ return result;
81190
+ }
81041
81191
  const { computeTabStops } = Engines;
81042
81192
  let canvasContext = null;
81043
81193
  const DEFAULT_TAB_INTERVAL_TWIPS = 720;
@@ -81085,10 +81235,20 @@ ${l}
81085
81235
  return Math.max(advanceWidth, paintedWidth);
81086
81236
  }
81087
81237
  const MIN_SINGLE_LINE_PX = 12 * 96 / 72;
81088
- function calculateTypographyMetrics(fontSize2, spacing) {
81089
- const ascent = roundValue(fontSize2 * 0.8);
81090
- const descent = roundValue(fontSize2 * 0.2);
81091
- const baseLineHeight = Math.max(fontSize2, MIN_SINGLE_LINE_PX);
81238
+ const LINE_HEIGHT_SAFETY_MARGIN_PX = 1;
81239
+ function calculateTypographyMetrics(fontSize2, spacing, fontInfo) {
81240
+ let ascent;
81241
+ let descent;
81242
+ if (fontInfo) {
81243
+ const ctx2 = getCanvasContext();
81244
+ const metrics = getFontMetrics(ctx2, fontInfo);
81245
+ ascent = roundValue(metrics.ascent);
81246
+ descent = roundValue(metrics.descent);
81247
+ } else {
81248
+ ascent = roundValue(fontSize2 * 0.8);
81249
+ descent = roundValue(fontSize2 * 0.2);
81250
+ }
81251
+ const baseLineHeight = Math.max(ascent + descent + LINE_HEIGHT_SAFETY_MARGIN_PX, MIN_SINGLE_LINE_PX);
81092
81252
  const lineHeight2 = roundValue(resolveLineHeight(spacing, baseLineHeight));
81093
81253
  return {
81094
81254
  ascent,
@@ -81096,6 +81256,20 @@ ${l}
81096
81256
  lineHeight: lineHeight2
81097
81257
  };
81098
81258
  }
81259
+ function getFontInfoFromRun(run2) {
81260
+ return {
81261
+ fontFamily: run2.fontFamily,
81262
+ fontSize: run2.fontSize,
81263
+ bold: run2.bold,
81264
+ italic: run2.italic
81265
+ };
81266
+ }
81267
+ function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun) {
81268
+ if (newRun.fontSize >= currentMaxSize) {
81269
+ return getFontInfoFromRun(newRun);
81270
+ }
81271
+ return currentMaxInfo;
81272
+ }
81099
81273
  function isTabRun(run2) {
81100
81274
  return run2.kind === "tab";
81101
81275
  }
@@ -81141,7 +81315,8 @@ ${l}
81141
81315
  const indentRight = sanitizePositive(indent2?.right);
81142
81316
  const firstLine = indent2?.firstLine ?? 0;
81143
81317
  const hanging = indent2?.hanging ?? 0;
81144
- const firstLineOffset = firstLine - hanging;
81318
+ const suppressFirstLine = block.attrs?.suppressFirstLineIndent === true;
81319
+ const firstLineOffset = suppressFirstLine ? 0 : firstLine - hanging;
81145
81320
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
81146
81321
  const initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
81147
81322
  const tabStops = buildTabStopsPx(
@@ -81277,7 +81452,7 @@ ${l}
81277
81452
  const run2 = runsToProcess[runIndex];
81278
81453
  if (run2.kind === "break") {
81279
81454
  if (currentLine) {
81280
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81455
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81281
81456
  const completedLine = { ...currentLine, ...metrics };
81282
81457
  addBarTabsToLine(completedLine);
81283
81458
  lines.push(completedLine);
@@ -81307,7 +81482,7 @@ ${l}
81307
81482
  }
81308
81483
  if (isLineBreakRun(run2)) {
81309
81484
  if (currentLine) {
81310
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81485
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81311
81486
  const completedLine = {
81312
81487
  ...currentLine,
81313
81488
  ...metrics
@@ -81420,7 +81595,7 @@ ${l}
81420
81595
  }
81421
81596
  const appliedTabAlign = lastAppliedTabAlign;
81422
81597
  if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
81423
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81598
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81424
81599
  const completedLine = {
81425
81600
  ...currentLine,
81426
81601
  ...metrics
@@ -81508,6 +81683,7 @@ ${l}
81508
81683
  toChar: wordEndNoSpace,
81509
81684
  width: wordOnlyWidth,
81510
81685
  maxFontSize: run2.fontSize,
81686
+ maxFontInfo: getFontInfoFromRun(run2),
81511
81687
  maxWidth: getEffectiveWidth(initialAvailableWidth),
81512
81688
  segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
81513
81689
  };
@@ -81524,7 +81700,7 @@ ${l}
81524
81700
  const isTocEntry = block.attrs?.isTocEntry;
81525
81701
  const boundarySpacing = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
81526
81702
  if (currentLine.width + boundarySpacing + wordOnlyWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0 && !isTocEntry) {
81527
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81703
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81528
81704
  const completedLine = {
81529
81705
  ...currentLine,
81530
81706
  ...metrics
@@ -81540,6 +81716,7 @@ ${l}
81540
81716
  toChar: wordEndNoSpace,
81541
81717
  width: wordOnlyWidth,
81542
81718
  maxFontSize: run2.fontSize,
81719
+ maxFontInfo: getFontInfoFromRun(run2),
81543
81720
  maxWidth: getEffectiveWidth(contentWidth),
81544
81721
  segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
81545
81722
  };
@@ -81555,9 +81732,10 @@ ${l}
81555
81732
  if (!isLastWord && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX) {
81556
81733
  currentLine.toChar = wordEndNoSpace;
81557
81734
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
81735
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
81558
81736
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
81559
81737
  appendSegment(currentLine.segments, runIndex, wordStartChar, wordEndNoSpace, wordOnlyWidth, segmentStartX);
81560
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81738
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81561
81739
  const completedLine = { ...currentLine, ...metrics };
81562
81740
  addBarTabsToLine(completedLine);
81563
81741
  lines.push(completedLine);
@@ -81574,6 +81752,7 @@ ${l}
81574
81752
  currentLine.width = roundValue(
81575
81753
  currentLine.width + boundarySpacing + wordCommitWidth + (isLastWord ? 0 : run2.letterSpacing ?? 0)
81576
81754
  );
81755
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
81577
81756
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
81578
81757
  appendSegment(currentLine.segments, runIndex, wordStartChar, newToChar, wordCommitWidth, explicitX);
81579
81758
  }
@@ -81596,6 +81775,7 @@ ${l}
81596
81775
  toChar: charPosInRun,
81597
81776
  width: 0,
81598
81777
  maxFontSize: run2.fontSize,
81778
+ maxFontInfo: getFontInfoFromRun(run2),
81599
81779
  maxWidth: getEffectiveWidth(initialAvailableWidth),
81600
81780
  segments: []
81601
81781
  };
@@ -81605,6 +81785,7 @@ ${l}
81605
81785
  tabStopCursor = nextIndex;
81606
81786
  const tabAdvance = Math.max(0, target - currentLine.width);
81607
81787
  currentLine.width = roundValue(currentLine.width + tabAdvance);
81788
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
81608
81789
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
81609
81790
  currentLine.toRun = runIndex;
81610
81791
  currentLine.toChar = charPosInRun;
@@ -81641,7 +81822,7 @@ ${l}
81641
81822
  lines.push(fallbackLine);
81642
81823
  }
81643
81824
  if (currentLine) {
81644
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
81825
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
81645
81826
  const finalLine = {
81646
81827
  ...currentLine,
81647
81828
  ...metrics
@@ -139965,7 +140146,7 @@ ${style2}
139965
140146
  this.config.colors = shuffleArray(this.config.colors);
139966
140147
  this.userColorMap = /* @__PURE__ */ new Map();
139967
140148
  this.colorIndex = 0;
139968
- this.version = "1.0.0-beta.22";
140149
+ this.version = "1.0.0-beta.23";
139969
140150
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
139970
140151
  this.superdocId = config2.superdocId || v4();
139971
140152
  this.colors = this.config.colors;
@@ -142410,7 +142591,7 @@ ${style2}
142410
142591
  value && typeof value === "object" && "byteLength" in value && "byteOffset" in value
142411
142592
  );
142412
142593
  }
142413
- const index895wSAjT = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
142594
+ const indexDYBG7Xab = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
142414
142595
  __proto__: null,
142415
142596
  unified
142416
142597
  }, Symbol.toStringTag, { value: "Module" }));