superdoc 1.0.0-beta.3 → 1.0.0-beta.4

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-CKzs9Ct5.es.js → PdfViewer-DUns3s8O.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-CxHbcDGx.cjs → PdfViewer-ZtwLhE_8.cjs} +1 -1
  3. package/dist/chunks/{index-CJUy3fVi-D8zt9F3Z.es.js → index-BNGaD3Up-CQuoo1EF.es.js} +1 -1
  4. package/dist/chunks/{index-CJUy3fVi-BGLfCP5B.cjs → index-BNGaD3Up-D2cRHMMk.cjs} +1 -1
  5. package/dist/chunks/{index-Dp3rVMnX.cjs → index-BW38mdZF.cjs} +3 -3
  6. package/dist/chunks/{index-DukSDI8_.es.js → index-DIccWgYh.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-CDiTp9Fe.cjs → super-editor.es-C06-V-Iy.cjs} +155 -27
  8. package/dist/chunks/{super-editor.es-BRKZG90h.es.js → super-editor.es-CtCHBIPE.es.js} +155 -27
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-B9YfBdcc.js → converter-ZJiSHoiq.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-V16OzZ7a.js → docx-zipper-B7FStorN.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-DlvlVSbc.js → editor-DvepAjbe.js} +156 -28
  13. package/dist/super-editor/chunks/{index-CJUy3fVi.js → index-BNGaD3Up.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-cNDvtryE.js → toolbar-CKXXbIQO.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 +157 -29
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { y as defineComponent, z as h, O as Transition, $ as process$1, J as watchEffect, a as computed, r as ref, j as onMounted, W as onUnmounted, b as createElementBlock, o as openBlock, f as createBaseVNode, e as createCommentVNode, u as createVNode, v as unref } from "./vue-CztqUvm1.es.js";
2
- import { d as derived, c, a as cB, f as fadeInTransition, b as cM, N as NBaseLoading, w as warnOnce, u as useConfig, e as useTheme, p as pxfy, g as createKey, h as useThemeClass, i as useCompitable, _ as _export_sfc, j as useSuperdocStore, s as storeToRefs, k as useSelection } from "./index-DukSDI8_.es.js";
2
+ import { d as derived, c, a as cB, f as fadeInTransition, b as cM, N as NBaseLoading, w as warnOnce, u as useConfig, e as useTheme, p as pxfy, g as createKey, h as useThemeClass, i as useCompitable, _ as _export_sfc, j as useSuperdocStore, s as storeToRefs, k as useSelection } from "./index-DIccWgYh.es.js";
3
3
  function self(vars) {
4
4
  const {
5
5
  opacityDisabled,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("./vue-ARQSyfaw.cjs");
4
- const superdoc = require("./index-Dp3rVMnX.cjs");
4
+ const superdoc = require("./index-BW38mdZF.cjs");
5
5
  function self(vars) {
6
6
  const {
7
7
  opacityDisabled,
@@ -1,4 +1,4 @@
1
- import { s as getDefaultExportFromCjs$2 } from "./super-editor.es-BRKZG90h.es.js";
1
+ import { s as getDefaultExportFromCjs$2 } from "./super-editor.es-CtCHBIPE.es.js";
2
2
  import { V as VFile } from "./index-CvBqQJbG-CvBqQJbG.es.js";
3
3
  function bail(error) {
4
4
  if (error) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const superEditor_es = require("./super-editor.es-CDiTp9Fe.cjs");
3
+ const superEditor_es = require("./super-editor.es-C06-V-Iy.cjs");
4
4
  const indexCvBqQJbG = require("./index-CvBqQJbG-Dwm0THD7.cjs");
5
5
  function bail(error) {
6
6
  if (error) {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const superEditor_es = require("./super-editor.es-CDiTp9Fe.cjs");
2
+ const superEditor_es = require("./super-editor.es-C06-V-Iy.cjs");
3
3
  const blankDocx = require("./blank-docx-DfW3Eeh2.cjs");
4
4
  const eventemitter3 = require("./eventemitter3-CFCpOk3d.cjs");
5
5
  const provider = require("@hocuspocus/provider");
@@ -17227,7 +17227,7 @@ const _sfc_main = {
17227
17227
  __name: "SuperDoc",
17228
17228
  emits: ["selection-update"],
17229
17229
  setup(__props, { emit: __emit }) {
17230
- const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-CxHbcDGx.cjs")));
17230
+ const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-ZtwLhE_8.cjs")));
17231
17231
  const superdocStore = useSuperdocStore();
17232
17232
  const commentsStore = useCommentsStore();
17233
17233
  const {
@@ -18080,7 +18080,7 @@ class SuperDoc extends eventemitter3.EventEmitter {
18080
18080
  this.config.colors = shuffleArray(this.config.colors);
18081
18081
  this.userColorMap = /* @__PURE__ */ new Map();
18082
18082
  this.colorIndex = 0;
18083
- this.version = "1.0.0-beta.3";
18083
+ this.version = "1.0.0-beta.4";
18084
18084
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
18085
18085
  this.superdocId = config.superdocId || uuid.v4();
18086
18086
  this.colors = this.config.colors;
@@ -1,4 +1,4 @@
1
- import { q as index, C as CommentsPluginKey, h as TrackChangesBasePluginKey, E as Editor, n as getRichTextExtensions, f as SuperInput, P as PresentationEditor, e as SuperEditor, A as AIWriter, g as SuperToolbar, i as createZip } from "./super-editor.es-BRKZG90h.es.js";
1
+ import { q as index, C as CommentsPluginKey, h as TrackChangesBasePluginKey, E as Editor, n as getRichTextExtensions, f as SuperInput, P as PresentationEditor, e as SuperEditor, A as AIWriter, g as SuperToolbar, i as createZip } from "./super-editor.es-CtCHBIPE.es.js";
2
2
  import { B as BlankDOCX } from "./blank-docx-ABm6XYAA.es.js";
3
3
  import { E as EventEmitter } from "./eventemitter3-ByBH0NYV.es.js";
4
4
  import { HocuspocusProvider, HocuspocusProviderWebsocket } from "@hocuspocus/provider";
@@ -17210,7 +17210,7 @@ const _sfc_main = {
17210
17210
  __name: "SuperDoc",
17211
17211
  emits: ["selection-update"],
17212
17212
  setup(__props, { emit: __emit }) {
17213
- const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-CKzs9Ct5.es.js"));
17213
+ const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-DUns3s8O.es.js"));
17214
17214
  const superdocStore = useSuperdocStore();
17215
17215
  const commentsStore = useCommentsStore();
17216
17216
  const {
@@ -18063,7 +18063,7 @@ class SuperDoc extends EventEmitter {
18063
18063
  this.config.colors = shuffleArray(this.config.colors);
18064
18064
  this.userColorMap = /* @__PURE__ */ new Map();
18065
18065
  this.colorIndex = 0;
18066
- this.version = "1.0.0-beta.3";
18066
+ this.version = "1.0.0-beta.4";
18067
18067
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
18068
18068
  this.superdocId = config.superdocId || v4();
18069
18069
  this.colors = this.config.colors;
@@ -35580,7 +35580,7 @@ const _SuperConverter = class _SuperConverter2 {
35580
35580
  static getStoredSuperdocVersion(docx) {
35581
35581
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
35582
35582
  }
35583
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.3") {
35583
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.4") {
35584
35584
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
35585
35585
  }
35586
35586
  /**
@@ -52287,7 +52287,7 @@ const isHeadless = (editor) => {
52287
52287
  const shouldSkipNodeView = (editor) => {
52288
52288
  return isHeadless(editor);
52289
52289
  };
52290
- const summaryVersion = "1.0.0-beta.3";
52290
+ const summaryVersion = "1.0.0-beta.4";
52291
52291
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
52292
52292
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
52293
52293
  function mapAttributes(attrs) {
@@ -53066,7 +53066,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53066
53066
  { default: remarkStringify },
53067
53067
  { default: remarkGfm }
53068
53068
  ] = await Promise.all([
53069
- Promise.resolve().then(() => require("./index-CJUy3fVi-BGLfCP5B.cjs")),
53069
+ Promise.resolve().then(() => require("./index-BNGaD3Up-D2cRHMMk.cjs")),
53070
53070
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
53071
53071
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
53072
53072
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -53271,7 +53271,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53271
53271
  * Process collaboration migrations
53272
53272
  */
53273
53273
  processCollaborationMigrations() {
53274
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.3");
53274
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.4");
53275
53275
  if (!this.options.ydoc) return;
53276
53276
  const metaMap = this.options.ydoc.getMap("meta");
53277
53277
  let docVersion = metaMap.get("version");
@@ -55102,6 +55102,19 @@ const sanitizeFontFamily = (fontFamily2) => {
55102
55102
  }
55103
55103
  return sanitized;
55104
55104
  };
55105
+ const normalizeFontSizePx = (value) => {
55106
+ if (isFiniteNumber(value)) return value;
55107
+ if (typeof value !== "string") return void 0;
55108
+ const trimmed = value.trim();
55109
+ if (!trimmed) return void 0;
55110
+ const numeric = Number.parseFloat(trimmed);
55111
+ if (!Number.isFinite(numeric)) return void 0;
55112
+ const unit = trimmed.match(/[a-zA-Z%]+$/)?.[0]?.toLowerCase();
55113
+ if (unit === "pt") {
55114
+ return ptToPx(numeric);
55115
+ }
55116
+ return numeric;
55117
+ };
55105
55118
  const applyTextStyleMark = (run2, attrs, themeColors) => {
55106
55119
  const resolvedColor = resolveColorFromAttributes(attrs, themeColors);
55107
55120
  if (resolvedColor) {
@@ -55113,9 +55126,9 @@ const applyTextStyleMark = (run2, attrs, themeColors) => {
55113
55126
  run2.fontFamily = sanitized;
55114
55127
  }
55115
55128
  }
55116
- const fontSizeValue = pickNumber(attrs.fontSize);
55117
- if (fontSizeValue !== void 0 && fontSizeValue >= 1 && fontSizeValue <= 1e3) {
55118
- run2.fontSize = fontSizeValue;
55129
+ const fontSizePx = normalizeFontSizePx(attrs.fontSize);
55130
+ if (fontSizePx !== void 0 && fontSizePx >= 1 && fontSizePx <= 1e3) {
55131
+ run2.fontSize = fontSizePx;
55119
55132
  }
55120
55133
  if (isFiniteNumber(attrs.letterSpacing)) {
55121
55134
  const spacing = Number(attrs.letterSpacing);
@@ -65375,8 +65388,59 @@ const _DomPainter = class _DomPainter2 {
65375
65388
  this.headerProvider = header;
65376
65389
  this.footerProvider = footer;
65377
65390
  }
65378
- setData(blocks, measures) {
65391
+ /**
65392
+ * Updates the painter's block and measure data.
65393
+ *
65394
+ * @param blocks - Main document blocks
65395
+ * @param measures - Measures corresponding to main document blocks
65396
+ * @param headerBlocks - Optional header blocks from header/footer layout results
65397
+ * @param headerMeasures - Optional measures corresponding to header blocks
65398
+ * @param footerBlocks - Optional footer blocks from header/footer layout results
65399
+ * @param footerMeasures - Optional measures corresponding to footer blocks
65400
+ */
65401
+ setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures) {
65402
+ if (blocks.length !== measures.length) {
65403
+ throw new Error(
65404
+ `setData: blocks and measures arrays must have the same length. Got blocks.length=${blocks.length}, measures.length=${measures.length}`
65405
+ );
65406
+ }
65407
+ const hasHeaderBlocks = headerBlocks !== void 0;
65408
+ const hasHeaderMeasures = headerMeasures !== void 0;
65409
+ if (hasHeaderBlocks !== hasHeaderMeasures) {
65410
+ throw new Error(
65411
+ `setData: headerBlocks and headerMeasures must both be provided or both be omitted. Got headerBlocks=${hasHeaderBlocks ? "provided" : "omitted"}, headerMeasures=${hasHeaderMeasures ? "provided" : "omitted"}`
65412
+ );
65413
+ }
65414
+ if (hasHeaderBlocks && hasHeaderMeasures && headerBlocks.length !== headerMeasures.length) {
65415
+ throw new Error(
65416
+ `setData: headerBlocks and headerMeasures arrays must have the same length. Got headerBlocks.length=${headerBlocks.length}, headerMeasures.length=${headerMeasures.length}`
65417
+ );
65418
+ }
65419
+ const hasFooterBlocks = footerBlocks !== void 0;
65420
+ const hasFooterMeasures = footerMeasures !== void 0;
65421
+ if (hasFooterBlocks !== hasFooterMeasures) {
65422
+ throw new Error(
65423
+ `setData: footerBlocks and footerMeasures must both be provided or both be omitted. Got footerBlocks=${hasFooterBlocks ? "provided" : "omitted"}, footerMeasures=${hasFooterMeasures ? "provided" : "omitted"}`
65424
+ );
65425
+ }
65426
+ if (hasFooterBlocks && hasFooterMeasures && footerBlocks.length !== footerMeasures.length) {
65427
+ throw new Error(
65428
+ `setData: footerBlocks and footerMeasures arrays must have the same length. Got footerBlocks.length=${footerBlocks.length}, footerMeasures.length=${footerMeasures.length}`
65429
+ );
65430
+ }
65379
65431
  const nextLookup = this.buildBlockLookup(blocks, measures);
65432
+ if (headerBlocks && headerMeasures) {
65433
+ const headerLookup = this.buildBlockLookup(headerBlocks, headerMeasures);
65434
+ headerLookup.forEach((entry, id) => {
65435
+ nextLookup.set(id, entry);
65436
+ });
65437
+ }
65438
+ if (footerBlocks && footerMeasures) {
65439
+ const footerLookup = this.buildBlockLookup(footerBlocks, footerMeasures);
65440
+ footerLookup.forEach((entry, id) => {
65441
+ nextLookup.set(id, entry);
65442
+ });
65443
+ }
65380
65444
  const changed = /* @__PURE__ */ new Set();
65381
65445
  nextLookup.forEach((entry, id) => {
65382
65446
  const previous = this.blockLookup.get(id);
@@ -65699,6 +65763,14 @@ const _DomPainter = class _DomPainter2 {
65699
65763
  container.style.height = `${data.height}px`;
65700
65764
  container.style.top = `${Math.max(0, offset2)}px`;
65701
65765
  container.style.zIndex = "1";
65766
+ let footerYOffset = 0;
65767
+ if (kind === "footer" && data.fragments.length > 0) {
65768
+ const contentHeight = typeof data.contentHeight === "number" ? data.contentHeight : data.fragments.reduce((max2, f2) => {
65769
+ const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
65770
+ return Math.max(max2, f2.y + Math.max(0, fragHeight));
65771
+ }, 0);
65772
+ footerYOffset = Math.max(0, data.height - contentHeight);
65773
+ }
65702
65774
  const context = {
65703
65775
  pageNumber: page.number,
65704
65776
  totalPages: this.totalPages,
@@ -65707,6 +65779,10 @@ const _DomPainter = class _DomPainter2 {
65707
65779
  };
65708
65780
  data.fragments.forEach((fragment) => {
65709
65781
  const fragEl = this.renderFragment(fragment, context);
65782
+ if (footerYOffset > 0) {
65783
+ const currentTop = parseFloat(fragEl.style.top) || fragment.y;
65784
+ fragEl.style.top = `${currentTop + footerYOffset}px`;
65785
+ }
65710
65786
  container.appendChild(fragEl);
65711
65787
  });
65712
65788
  if (!existing) {
@@ -66018,13 +66094,13 @@ const _DomPainter = class _DomPainter2 {
66018
66094
  const markerEl = this.doc.createElement("span");
66019
66095
  markerEl.classList.add("superdoc-list-marker");
66020
66096
  const wordLayout = item.paragraph.attrs?.wordLayout;
66021
- if (wordLayout?.marker) {
66022
- const marker = wordLayout.marker;
66023
- markerEl.textContent = marker.markerText;
66097
+ const marker = wordLayout?.marker;
66098
+ if (marker) {
66099
+ markerEl.textContent = marker.markerText ?? null;
66024
66100
  markerEl.style.display = "inline-block";
66025
66101
  markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66026
66102
  markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66027
- markerEl.style.textAlign = marker.justification;
66103
+ markerEl.style.textAlign = marker.justification ?? "";
66028
66104
  markerEl.style.fontFamily = marker.run.fontFamily;
66029
66105
  markerEl.style.fontSize = `${marker.run.fontSize}px`;
66030
66106
  if (marker.run.bold) markerEl.style.fontWeight = "bold";
@@ -66773,6 +66849,33 @@ const _DomPainter = class _DomPainter2 {
66773
66849
  }
66774
66850
  }
66775
66851
  }
66852
+ /**
66853
+ * Estimates the height of a fragment when explicit height is not available.
66854
+ *
66855
+ * This method provides fallback height calculations for footer bottom-alignment
66856
+ * by consulting measure data for paragraphs and list items, or using the
66857
+ * fragment's height property for tables, images, and drawings.
66858
+ *
66859
+ * @param fragment - The fragment to estimate height for
66860
+ * @returns Estimated height in pixels, or 0 if height cannot be determined
66861
+ */
66862
+ estimateFragmentHeight(fragment) {
66863
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66864
+ const measure = lookup2?.measure;
66865
+ if (fragment.kind === "para" && measure?.kind === "paragraph") {
66866
+ return measure.totalHeight;
66867
+ }
66868
+ if (fragment.kind === "list-item" && measure?.kind === "list") {
66869
+ return measure.totalHeight;
66870
+ }
66871
+ if (fragment.kind === "table") {
66872
+ return fragment.height;
66873
+ }
66874
+ if (fragment.kind === "image" || fragment.kind === "drawing") {
66875
+ return fragment.height;
66876
+ }
66877
+ return 0;
66878
+ }
66776
66879
  buildBlockLookup(blocks, measures) {
66777
66880
  if (blocks.length !== measures.length) {
66778
66881
  throw new Error("DomPainter requires the same number of blocks and measures");
@@ -67241,8 +67344,8 @@ const createDomPainter = (options) => {
67241
67344
  paint(layout, mount2) {
67242
67345
  painter.paint(layout, mount2);
67243
67346
  },
67244
- setData(blocks, measures) {
67245
- painter.setData(blocks, measures);
67347
+ setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures) {
67348
+ painter.setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures);
67246
67349
  },
67247
67350
  // Non-standard extension for demo app to avoid re-instantiating on provider changes
67248
67351
  setProviders(header, footer) {
@@ -70631,7 +70734,30 @@ rerender_fn = async function() {
70631
70734
  if (typeof painter.setProviders === "function") {
70632
70735
  painter.setProviders(__privateGet$1(this, _headerDecorationProvider), __privateGet$1(this, _footerDecorationProvider));
70633
70736
  }
70634
- painter.setData?.(blocks, measures);
70737
+ const headerBlocks = [];
70738
+ const headerMeasures = [];
70739
+ if (headerLayouts) {
70740
+ for (const headerResult of headerLayouts) {
70741
+ headerBlocks.push(...headerResult.blocks);
70742
+ headerMeasures.push(...headerResult.measures);
70743
+ }
70744
+ }
70745
+ const footerBlocks = [];
70746
+ const footerMeasures = [];
70747
+ if (footerLayouts) {
70748
+ for (const footerResult of footerLayouts) {
70749
+ footerBlocks.push(...footerResult.blocks);
70750
+ footerMeasures.push(...footerResult.measures);
70751
+ }
70752
+ }
70753
+ painter.setData?.(
70754
+ blocks,
70755
+ measures,
70756
+ headerBlocks.length > 0 ? headerBlocks : void 0,
70757
+ headerMeasures.length > 0 ? headerMeasures : void 0,
70758
+ footerBlocks.length > 0 ? footerBlocks : void 0,
70759
+ footerMeasures.length > 0 ? footerMeasures : void 0
70760
+ );
70635
70761
  painter.paint(layout, __privateGet$1(this, _painterHost));
70636
70762
  __privateSet(this, _layoutError, null);
70637
70763
  __privateSet(this, _layoutErrorState, "healthy");
@@ -70801,7 +70927,8 @@ createDecorationProvider_fn = function(kind, layout) {
70801
70927
  const finalHeaderId = headerId ?? fallbackId ?? void 0;
70802
70928
  return {
70803
70929
  fragments: slotPage.fragments,
70804
- height: variant.layout.height ?? box.height,
70930
+ height: box.height,
70931
+ contentHeight: variant.layout.height ?? box.height,
70805
70932
  offset: box.offset,
70806
70933
  marginLeft: box.x,
70807
70934
  contentWidth: box.width,
@@ -70828,18 +70955,19 @@ computeDecorationBox_fn = function(kind, pageMargins, pageHeight) {
70828
70955
  const left2 = margins.left ?? DEFAULT_MARGINS.left;
70829
70956
  const right2 = margins.right ?? DEFAULT_MARGINS.right;
70830
70957
  const width = Math.max(pageSize.w - (left2 + right2), 1);
70831
- const defaultHeight = kind === "header" ? margins.top ?? DEFAULT_MARGINS.top : margins.bottom ?? DEFAULT_MARGINS.bottom;
70832
- const { headerSpace, footerSpace } = extractHeaderFooterSpace(margins);
70833
- const target = kind === "header" ? headerSpace : footerSpace;
70834
- const height = Math.max(target || defaultHeight || 1, 1);
70835
70958
  const totalHeight = pageHeight ?? pageSize.h;
70836
- const offset2 = kind === "header" ? 0 : Math.max(0, totalHeight - height);
70837
- return {
70838
- x: left2,
70839
- width,
70840
- height,
70841
- offset: offset2
70842
- };
70959
+ if (kind === "header") {
70960
+ const headerMargin = margins.header ?? 0;
70961
+ const topMargin = margins.top ?? DEFAULT_MARGINS.top ?? 0;
70962
+ const height = Math.max(topMargin - headerMargin, 1);
70963
+ return { x: left2, width, height, offset: headerMargin };
70964
+ } else {
70965
+ const footerMargin = margins.footer ?? 0;
70966
+ const bottomMargin = margins.bottom ?? DEFAULT_MARGINS.bottom ?? 0;
70967
+ const height = Math.max(bottomMargin - footerMargin, 1);
70968
+ const offset2 = Math.max(0, totalHeight - footerMargin - height);
70969
+ return { x: left2, width, height, offset: offset2 };
70970
+ }
70843
70971
  };
70844
70972
  rebuildHeaderFooterRegions_fn = function(layout) {
70845
70973
  __privateGet$1(this, _headerRegions).clear();
@@ -35563,7 +35563,7 @@ const _SuperConverter = class _SuperConverter2 {
35563
35563
  static getStoredSuperdocVersion(docx) {
35564
35564
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
35565
35565
  }
35566
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.3") {
35566
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.4") {
35567
35567
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
35568
35568
  }
35569
35569
  /**
@@ -52270,7 +52270,7 @@ const isHeadless = (editor) => {
52270
52270
  const shouldSkipNodeView = (editor) => {
52271
52271
  return isHeadless(editor);
52272
52272
  };
52273
- const summaryVersion = "1.0.0-beta.3";
52273
+ const summaryVersion = "1.0.0-beta.4";
52274
52274
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
52275
52275
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
52276
52276
  function mapAttributes(attrs) {
@@ -53049,7 +53049,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53049
53049
  { default: remarkStringify },
53050
53050
  { default: remarkGfm }
53051
53051
  ] = await Promise.all([
53052
- import("./index-CJUy3fVi-D8zt9F3Z.es.js"),
53052
+ import("./index-BNGaD3Up-CQuoo1EF.es.js"),
53053
53053
  import("./index-DRCvimau-Cw339678.es.js"),
53054
53054
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
53055
53055
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -53254,7 +53254,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53254
53254
  * Process collaboration migrations
53255
53255
  */
53256
53256
  processCollaborationMigrations() {
53257
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.3");
53257
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.4");
53258
53258
  if (!this.options.ydoc) return;
53259
53259
  const metaMap = this.options.ydoc.getMap("meta");
53260
53260
  let docVersion = metaMap.get("version");
@@ -55085,6 +55085,19 @@ const sanitizeFontFamily = (fontFamily2) => {
55085
55085
  }
55086
55086
  return sanitized;
55087
55087
  };
55088
+ const normalizeFontSizePx = (value) => {
55089
+ if (isFiniteNumber(value)) return value;
55090
+ if (typeof value !== "string") return void 0;
55091
+ const trimmed = value.trim();
55092
+ if (!trimmed) return void 0;
55093
+ const numeric = Number.parseFloat(trimmed);
55094
+ if (!Number.isFinite(numeric)) return void 0;
55095
+ const unit = trimmed.match(/[a-zA-Z%]+$/)?.[0]?.toLowerCase();
55096
+ if (unit === "pt") {
55097
+ return ptToPx(numeric);
55098
+ }
55099
+ return numeric;
55100
+ };
55088
55101
  const applyTextStyleMark = (run2, attrs, themeColors) => {
55089
55102
  const resolvedColor = resolveColorFromAttributes(attrs, themeColors);
55090
55103
  if (resolvedColor) {
@@ -55096,9 +55109,9 @@ const applyTextStyleMark = (run2, attrs, themeColors) => {
55096
55109
  run2.fontFamily = sanitized;
55097
55110
  }
55098
55111
  }
55099
- const fontSizeValue = pickNumber(attrs.fontSize);
55100
- if (fontSizeValue !== void 0 && fontSizeValue >= 1 && fontSizeValue <= 1e3) {
55101
- run2.fontSize = fontSizeValue;
55112
+ const fontSizePx = normalizeFontSizePx(attrs.fontSize);
55113
+ if (fontSizePx !== void 0 && fontSizePx >= 1 && fontSizePx <= 1e3) {
55114
+ run2.fontSize = fontSizePx;
55102
55115
  }
55103
55116
  if (isFiniteNumber(attrs.letterSpacing)) {
55104
55117
  const spacing = Number(attrs.letterSpacing);
@@ -65358,8 +65371,59 @@ const _DomPainter = class _DomPainter2 {
65358
65371
  this.headerProvider = header;
65359
65372
  this.footerProvider = footer;
65360
65373
  }
65361
- setData(blocks, measures) {
65374
+ /**
65375
+ * Updates the painter's block and measure data.
65376
+ *
65377
+ * @param blocks - Main document blocks
65378
+ * @param measures - Measures corresponding to main document blocks
65379
+ * @param headerBlocks - Optional header blocks from header/footer layout results
65380
+ * @param headerMeasures - Optional measures corresponding to header blocks
65381
+ * @param footerBlocks - Optional footer blocks from header/footer layout results
65382
+ * @param footerMeasures - Optional measures corresponding to footer blocks
65383
+ */
65384
+ setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures) {
65385
+ if (blocks.length !== measures.length) {
65386
+ throw new Error(
65387
+ `setData: blocks and measures arrays must have the same length. Got blocks.length=${blocks.length}, measures.length=${measures.length}`
65388
+ );
65389
+ }
65390
+ const hasHeaderBlocks = headerBlocks !== void 0;
65391
+ const hasHeaderMeasures = headerMeasures !== void 0;
65392
+ if (hasHeaderBlocks !== hasHeaderMeasures) {
65393
+ throw new Error(
65394
+ `setData: headerBlocks and headerMeasures must both be provided or both be omitted. Got headerBlocks=${hasHeaderBlocks ? "provided" : "omitted"}, headerMeasures=${hasHeaderMeasures ? "provided" : "omitted"}`
65395
+ );
65396
+ }
65397
+ if (hasHeaderBlocks && hasHeaderMeasures && headerBlocks.length !== headerMeasures.length) {
65398
+ throw new Error(
65399
+ `setData: headerBlocks and headerMeasures arrays must have the same length. Got headerBlocks.length=${headerBlocks.length}, headerMeasures.length=${headerMeasures.length}`
65400
+ );
65401
+ }
65402
+ const hasFooterBlocks = footerBlocks !== void 0;
65403
+ const hasFooterMeasures = footerMeasures !== void 0;
65404
+ if (hasFooterBlocks !== hasFooterMeasures) {
65405
+ throw new Error(
65406
+ `setData: footerBlocks and footerMeasures must both be provided or both be omitted. Got footerBlocks=${hasFooterBlocks ? "provided" : "omitted"}, footerMeasures=${hasFooterMeasures ? "provided" : "omitted"}`
65407
+ );
65408
+ }
65409
+ if (hasFooterBlocks && hasFooterMeasures && footerBlocks.length !== footerMeasures.length) {
65410
+ throw new Error(
65411
+ `setData: footerBlocks and footerMeasures arrays must have the same length. Got footerBlocks.length=${footerBlocks.length}, footerMeasures.length=${footerMeasures.length}`
65412
+ );
65413
+ }
65362
65414
  const nextLookup = this.buildBlockLookup(blocks, measures);
65415
+ if (headerBlocks && headerMeasures) {
65416
+ const headerLookup = this.buildBlockLookup(headerBlocks, headerMeasures);
65417
+ headerLookup.forEach((entry, id) => {
65418
+ nextLookup.set(id, entry);
65419
+ });
65420
+ }
65421
+ if (footerBlocks && footerMeasures) {
65422
+ const footerLookup = this.buildBlockLookup(footerBlocks, footerMeasures);
65423
+ footerLookup.forEach((entry, id) => {
65424
+ nextLookup.set(id, entry);
65425
+ });
65426
+ }
65363
65427
  const changed = /* @__PURE__ */ new Set();
65364
65428
  nextLookup.forEach((entry, id) => {
65365
65429
  const previous = this.blockLookup.get(id);
@@ -65682,6 +65746,14 @@ const _DomPainter = class _DomPainter2 {
65682
65746
  container.style.height = `${data.height}px`;
65683
65747
  container.style.top = `${Math.max(0, offset2)}px`;
65684
65748
  container.style.zIndex = "1";
65749
+ let footerYOffset = 0;
65750
+ if (kind === "footer" && data.fragments.length > 0) {
65751
+ const contentHeight = typeof data.contentHeight === "number" ? data.contentHeight : data.fragments.reduce((max2, f2) => {
65752
+ const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
65753
+ return Math.max(max2, f2.y + Math.max(0, fragHeight));
65754
+ }, 0);
65755
+ footerYOffset = Math.max(0, data.height - contentHeight);
65756
+ }
65685
65757
  const context = {
65686
65758
  pageNumber: page.number,
65687
65759
  totalPages: this.totalPages,
@@ -65690,6 +65762,10 @@ const _DomPainter = class _DomPainter2 {
65690
65762
  };
65691
65763
  data.fragments.forEach((fragment) => {
65692
65764
  const fragEl = this.renderFragment(fragment, context);
65765
+ if (footerYOffset > 0) {
65766
+ const currentTop = parseFloat(fragEl.style.top) || fragment.y;
65767
+ fragEl.style.top = `${currentTop + footerYOffset}px`;
65768
+ }
65693
65769
  container.appendChild(fragEl);
65694
65770
  });
65695
65771
  if (!existing) {
@@ -66001,13 +66077,13 @@ const _DomPainter = class _DomPainter2 {
66001
66077
  const markerEl = this.doc.createElement("span");
66002
66078
  markerEl.classList.add("superdoc-list-marker");
66003
66079
  const wordLayout = item.paragraph.attrs?.wordLayout;
66004
- if (wordLayout?.marker) {
66005
- const marker = wordLayout.marker;
66006
- markerEl.textContent = marker.markerText;
66080
+ const marker = wordLayout?.marker;
66081
+ if (marker) {
66082
+ markerEl.textContent = marker.markerText ?? null;
66007
66083
  markerEl.style.display = "inline-block";
66008
66084
  markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66009
66085
  markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66010
- markerEl.style.textAlign = marker.justification;
66086
+ markerEl.style.textAlign = marker.justification ?? "";
66011
66087
  markerEl.style.fontFamily = marker.run.fontFamily;
66012
66088
  markerEl.style.fontSize = `${marker.run.fontSize}px`;
66013
66089
  if (marker.run.bold) markerEl.style.fontWeight = "bold";
@@ -66756,6 +66832,33 @@ const _DomPainter = class _DomPainter2 {
66756
66832
  }
66757
66833
  }
66758
66834
  }
66835
+ /**
66836
+ * Estimates the height of a fragment when explicit height is not available.
66837
+ *
66838
+ * This method provides fallback height calculations for footer bottom-alignment
66839
+ * by consulting measure data for paragraphs and list items, or using the
66840
+ * fragment's height property for tables, images, and drawings.
66841
+ *
66842
+ * @param fragment - The fragment to estimate height for
66843
+ * @returns Estimated height in pixels, or 0 if height cannot be determined
66844
+ */
66845
+ estimateFragmentHeight(fragment) {
66846
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66847
+ const measure = lookup2?.measure;
66848
+ if (fragment.kind === "para" && measure?.kind === "paragraph") {
66849
+ return measure.totalHeight;
66850
+ }
66851
+ if (fragment.kind === "list-item" && measure?.kind === "list") {
66852
+ return measure.totalHeight;
66853
+ }
66854
+ if (fragment.kind === "table") {
66855
+ return fragment.height;
66856
+ }
66857
+ if (fragment.kind === "image" || fragment.kind === "drawing") {
66858
+ return fragment.height;
66859
+ }
66860
+ return 0;
66861
+ }
66759
66862
  buildBlockLookup(blocks, measures) {
66760
66863
  if (blocks.length !== measures.length) {
66761
66864
  throw new Error("DomPainter requires the same number of blocks and measures");
@@ -67224,8 +67327,8 @@ const createDomPainter = (options) => {
67224
67327
  paint(layout, mount2) {
67225
67328
  painter.paint(layout, mount2);
67226
67329
  },
67227
- setData(blocks, measures) {
67228
- painter.setData(blocks, measures);
67330
+ setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures) {
67331
+ painter.setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures);
67229
67332
  },
67230
67333
  // Non-standard extension for demo app to avoid re-instantiating on provider changes
67231
67334
  setProviders(header, footer) {
@@ -70614,7 +70717,30 @@ rerender_fn = async function() {
70614
70717
  if (typeof painter.setProviders === "function") {
70615
70718
  painter.setProviders(__privateGet$1(this, _headerDecorationProvider), __privateGet$1(this, _footerDecorationProvider));
70616
70719
  }
70617
- painter.setData?.(blocks, measures);
70720
+ const headerBlocks = [];
70721
+ const headerMeasures = [];
70722
+ if (headerLayouts) {
70723
+ for (const headerResult of headerLayouts) {
70724
+ headerBlocks.push(...headerResult.blocks);
70725
+ headerMeasures.push(...headerResult.measures);
70726
+ }
70727
+ }
70728
+ const footerBlocks = [];
70729
+ const footerMeasures = [];
70730
+ if (footerLayouts) {
70731
+ for (const footerResult of footerLayouts) {
70732
+ footerBlocks.push(...footerResult.blocks);
70733
+ footerMeasures.push(...footerResult.measures);
70734
+ }
70735
+ }
70736
+ painter.setData?.(
70737
+ blocks,
70738
+ measures,
70739
+ headerBlocks.length > 0 ? headerBlocks : void 0,
70740
+ headerMeasures.length > 0 ? headerMeasures : void 0,
70741
+ footerBlocks.length > 0 ? footerBlocks : void 0,
70742
+ footerMeasures.length > 0 ? footerMeasures : void 0
70743
+ );
70618
70744
  painter.paint(layout, __privateGet$1(this, _painterHost));
70619
70745
  __privateSet(this, _layoutError, null);
70620
70746
  __privateSet(this, _layoutErrorState, "healthy");
@@ -70784,7 +70910,8 @@ createDecorationProvider_fn = function(kind, layout) {
70784
70910
  const finalHeaderId = headerId ?? fallbackId ?? void 0;
70785
70911
  return {
70786
70912
  fragments: slotPage.fragments,
70787
- height: variant.layout.height ?? box.height,
70913
+ height: box.height,
70914
+ contentHeight: variant.layout.height ?? box.height,
70788
70915
  offset: box.offset,
70789
70916
  marginLeft: box.x,
70790
70917
  contentWidth: box.width,
@@ -70811,18 +70938,19 @@ computeDecorationBox_fn = function(kind, pageMargins, pageHeight) {
70811
70938
  const left2 = margins.left ?? DEFAULT_MARGINS.left;
70812
70939
  const right2 = margins.right ?? DEFAULT_MARGINS.right;
70813
70940
  const width = Math.max(pageSize.w - (left2 + right2), 1);
70814
- const defaultHeight = kind === "header" ? margins.top ?? DEFAULT_MARGINS.top : margins.bottom ?? DEFAULT_MARGINS.bottom;
70815
- const { headerSpace, footerSpace } = extractHeaderFooterSpace(margins);
70816
- const target = kind === "header" ? headerSpace : footerSpace;
70817
- const height = Math.max(target || defaultHeight || 1, 1);
70818
70941
  const totalHeight = pageHeight ?? pageSize.h;
70819
- const offset2 = kind === "header" ? 0 : Math.max(0, totalHeight - height);
70820
- return {
70821
- x: left2,
70822
- width,
70823
- height,
70824
- offset: offset2
70825
- };
70942
+ if (kind === "header") {
70943
+ const headerMargin = margins.header ?? 0;
70944
+ const topMargin = margins.top ?? DEFAULT_MARGINS.top ?? 0;
70945
+ const height = Math.max(topMargin - headerMargin, 1);
70946
+ return { x: left2, width, height, offset: headerMargin };
70947
+ } else {
70948
+ const footerMargin = margins.footer ?? 0;
70949
+ const bottomMargin = margins.bottom ?? DEFAULT_MARGINS.bottom ?? 0;
70950
+ const height = Math.max(bottomMargin - footerMargin, 1);
70951
+ const offset2 = Math.max(0, totalHeight - footerMargin - height);
70952
+ return { x: left2, width, height, offset: offset2 };
70953
+ }
70826
70954
  };
70827
70955
  rebuildHeaderFooterRegions_fn = function(layout) {
70828
70956
  __privateGet$1(this, _headerRegions).clear();