@harbour-enterprises/superdoc 1.0.0-beta.88 → 1.0.0-beta.89

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-DBW8dNGO.cjs → PdfViewer-64l7m5Lq.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-2DqlQMKM.es.js → PdfViewer-Dj0ADYo6.es.js} +1 -1
  3. package/dist/chunks/{index-i17b8wYa.cjs → index-Cnq_7qcp.cjs} +3 -3
  4. package/dist/chunks/{index-nvs_L5an.es.js → index-DXKu3E-3.es.js} +3 -3
  5. package/dist/chunks/{index-BLlh97IN-75N3psN2.es.js → index-DcTrJ8db-9XJOggtC.es.js} +1 -1
  6. package/dist/chunks/{index-BLlh97IN-BF_Nyujm.cjs → index-DcTrJ8db-kUMXGs8M.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-DpbjE-x_.es.js → super-editor.es-D0fgEP38.es.js} +145 -38
  8. package/dist/chunks/{super-editor.es-DB49uQPF.cjs → super-editor.es-D8F0msfn.cjs} +145 -38
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-CjKHGzQU.js → converter-DPyEmTPY.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-BDVppBrA.js → docx-zipper-BTkZSGvz.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-CgbApADp.js → editor-4iR-p-_J.js} +146 -39
  13. package/dist/super-editor/chunks/{index-BLlh97IN.js → index-DcTrJ8db.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-BEQMP5-e.js → toolbar-Dx7gHXE2.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 +147 -40
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("./vue-jWLMl8Ts.cjs");
4
- const superdoc = require("./index-i17b8wYa.cjs");
4
+ const superdoc = require("./index-Cnq_7qcp.cjs");
5
5
  function self(vars) {
6
6
  const {
7
7
  opacityDisabled,
@@ -1,5 +1,5 @@
1
1
  import { y as defineComponent, z as h, O as Transition, a0 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-Dysv_7z5.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-nvs_L5an.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-DXKu3E-3.es.js";
3
3
  function self(vars) {
4
4
  const {
5
5
  opacityDisabled,
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const superEditor_es = require("./super-editor.es-DB49uQPF.cjs");
2
+ const superEditor_es = require("./super-editor.es-D8F0msfn.cjs");
3
3
  const blankDocx = require("./blank-docx-DfW3Eeh2.cjs");
4
4
  const eventemitter3 = require("./eventemitter3-DQmQUge-.cjs");
5
5
  const provider = require("@hocuspocus/provider");
@@ -17268,7 +17268,7 @@ const _sfc_main = {
17268
17268
  __name: "SuperDoc",
17269
17269
  emits: ["selection-update"],
17270
17270
  setup(__props, { emit: __emit }) {
17271
- const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-DBW8dNGO.cjs")));
17271
+ const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-64l7m5Lq.cjs")));
17272
17272
  const superdocStore = useSuperdocStore();
17273
17273
  const commentsStore = useCommentsStore();
17274
17274
  const {
@@ -18157,7 +18157,7 @@ class SuperDoc extends eventemitter3.EventEmitter {
18157
18157
  this.config.colors = shuffleArray(this.config.colors);
18158
18158
  this.userColorMap = /* @__PURE__ */ new Map();
18159
18159
  this.colorIndex = 0;
18160
- this.version = "1.0.0-beta.88";
18160
+ this.version = "1.0.0-beta.89";
18161
18161
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
18162
18162
  this.superdocId = config.superdocId || uuid.v4();
18163
18163
  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-DpbjE-x_.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-D0fgEP38.es.js";
2
2
  import { B as BlankDOCX } from "./blank-docx-ABm6XYAA.es.js";
3
3
  import { E as EventEmitter } from "./eventemitter3-CcXAdeql.es.js";
4
4
  import { HocuspocusProvider, HocuspocusProviderWebsocket } from "@hocuspocus/provider";
@@ -17251,7 +17251,7 @@ const _sfc_main = {
17251
17251
  __name: "SuperDoc",
17252
17252
  emits: ["selection-update"],
17253
17253
  setup(__props, { emit: __emit }) {
17254
- const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-2DqlQMKM.es.js"));
17254
+ const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-Dj0ADYo6.es.js"));
17255
17255
  const superdocStore = useSuperdocStore();
17256
17256
  const commentsStore = useCommentsStore();
17257
17257
  const {
@@ -18140,7 +18140,7 @@ class SuperDoc extends EventEmitter {
18140
18140
  this.config.colors = shuffleArray(this.config.colors);
18141
18141
  this.userColorMap = /* @__PURE__ */ new Map();
18142
18142
  this.colorIndex = 0;
18143
- this.version = "1.0.0-beta.88";
18143
+ this.version = "1.0.0-beta.89";
18144
18144
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
18145
18145
  this.superdocId = config.superdocId || v4();
18146
18146
  this.colors = this.config.colors;
@@ -1,4 +1,4 @@
1
- import { s as getDefaultExportFromCjs$2 } from "./super-editor.es-DpbjE-x_.es.js";
1
+ import { s as getDefaultExportFromCjs$2 } from "./super-editor.es-D0fgEP38.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-DB49uQPF.cjs");
3
+ const superEditor_es = require("./super-editor.es-D8F0msfn.cjs");
4
4
  const indexCvBqQJbG = require("./index-CvBqQJbG-Dwm0THD7.cjs");
5
5
  function bail(error) {
6
6
  if (error) {
@@ -42380,7 +42380,7 @@ const _SuperConverter = class _SuperConverter2 {
42380
42380
  static getStoredSuperdocVersion(docx) {
42381
42381
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42382
42382
  }
42383
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.88") {
42383
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.89") {
42384
42384
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42385
42385
  }
42386
42386
  /**
@@ -59586,7 +59586,7 @@ const isHeadless = (editor) => {
59586
59586
  const shouldSkipNodeView = (editor) => {
59587
59587
  return isHeadless(editor);
59588
59588
  };
59589
- const summaryVersion = "1.0.0-beta.88";
59589
+ const summaryVersion = "1.0.0-beta.89";
59590
59590
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59591
59591
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59592
59592
  function mapAttributes(attrs) {
@@ -60375,7 +60375,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60375
60375
  { default: remarkStringify },
60376
60376
  { default: remarkGfm }
60377
60377
  ] = await Promise.all([
60378
- import("./index-BLlh97IN-75N3psN2.es.js"),
60378
+ import("./index-DcTrJ8db-9XJOggtC.es.js"),
60379
60379
  import("./index-DRCvimau-Cw339678.es.js"),
60380
60380
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
60381
60381
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -60580,7 +60580,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60580
60580
  * Process collaboration migrations
60581
60581
  */
60582
60582
  processCollaborationMigrations() {
60583
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.88");
60583
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.89");
60584
60584
  if (!this.options.ydoc) return;
60585
60585
  const metaMap = this.options.ydoc.getMap("meta");
60586
60586
  let docVersion = metaMap.get("version");
@@ -73492,7 +73492,14 @@ const renderTableCell = (deps) => {
73492
73492
  let renderedHeight = 0;
73493
73493
  for (let lineIdx = localStartLine; lineIdx < localEndLine && lineIdx < lines.length; lineIdx++) {
73494
73494
  const line = lines[lineIdx];
73495
- const lineEl = renderLine(block, line, { ...context, section: "body" });
73495
+ const isLastLine = lineIdx === lines.length - 1;
73496
+ const lineEl = renderLine(
73497
+ block,
73498
+ line,
73499
+ { ...context, section: "body" },
73500
+ lineIdx,
73501
+ isLastLine
73502
+ );
73496
73503
  lineEl.style.paddingLeft = "";
73497
73504
  lineEl.style.paddingRight = "";
73498
73505
  lineEl.style.textIndent = "";
@@ -76124,8 +76131,11 @@ const _DomPainter = class _DomPainter2 {
76124
76131
  const applyFragmentFrameWithSection = (el, frag) => {
76125
76132
  this.applyFragmentFrame(el, frag, context.section);
76126
76133
  };
76127
- const renderLineForTableCell = (block, line, ctx2) => {
76128
- return this.renderLine(block, line, ctx2, void 0, void 0, true);
76134
+ const renderLineForTableCell = (block, line, ctx2, lineIndex, isLastLine) => {
76135
+ const lastRun = block.runs.length > 0 ? block.runs[block.runs.length - 1] : null;
76136
+ const paragraphEndsWithLineBreak = lastRun?.kind === "lineBreak";
76137
+ const shouldSkipJustify = isLastLine && !paragraphEndsWithLineBreak;
76138
+ return this.renderLine(block, line, ctx2, void 0, lineIndex, shouldSkipJustify);
76129
76139
  };
76130
76140
  const renderDrawingContentForTableCell = (block) => {
76131
76141
  if (block.drawingKind === "image") {
@@ -76734,9 +76744,10 @@ const _DomPainter = class _DomPainter2 {
76734
76744
  el.setAttribute("styleid", styleId);
76735
76745
  }
76736
76746
  const alignment2 = block.attrs?.alignment;
76737
- if (alignment2 === "center" || alignment2 === "right") {
76738
- el.style.textAlign = alignment2;
76739
- } else if (alignment2 === "justify") {
76747
+ const effectiveAlignment = alignment2;
76748
+ if (effectiveAlignment === "center" || effectiveAlignment === "right") {
76749
+ el.style.textAlign = effectiveAlignment;
76750
+ } else if (effectiveAlignment === "justify") {
76740
76751
  el.style.textAlign = "left";
76741
76752
  } else {
76742
76753
  el.style.textAlign = "left";
@@ -76798,16 +76809,16 @@ const _DomPainter = class _DomPainter2 {
76798
76809
  }
76799
76810
  const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
76800
76811
  const availableWidth = availableWidthOverride ?? line.maxWidth ?? line.width;
76801
- const shouldJustify = !skipJustify && alignment2 === "justify" && !hasExplicitPositioning;
76812
+ const shouldJustify = !skipJustify && effectiveAlignment === "justify" && !hasExplicitPositioning;
76802
76813
  if (shouldJustify) {
76803
76814
  const spaceCount = textSlices.reduce(
76804
76815
  (sum, s2) => sum + Array.from(s2).filter((ch) => ch === " " || ch === " ").length,
76805
76816
  0
76806
76817
  );
76807
- const slack = Math.max(0, availableWidth - line.width);
76808
- if (spaceCount > 0 && slack > 0) {
76809
- const extraPerSpace = slack / spaceCount;
76810
- el.style.wordSpacing = `${extraPerSpace}px`;
76818
+ const slack = availableWidth - line.width;
76819
+ if (spaceCount > 0 && slack !== 0) {
76820
+ const spacingPerSpace = slack / spaceCount;
76821
+ el.style.wordSpacing = `${spacingPerSpace}px`;
76811
76822
  }
76812
76823
  }
76813
76824
  if (hasExplicitPositioning && line.segments) {
@@ -84048,9 +84059,7 @@ function getMeasuredTextWidth(text, font, letterSpacing, ctx2) {
84048
84059
  try {
84049
84060
  ctx2.font = font;
84050
84061
  const metrics = ctx2.measureText(text);
84051
- const advanceWidth = metrics.width;
84052
- const paintedWidth = (metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0);
84053
- const baseWidth = Math.max(advanceWidth, paintedWidth);
84062
+ const baseWidth = metrics.width;
84054
84063
  const extra = letterSpacing ? Math.max(0, text.length - 1) * letterSpacing : 0;
84055
84064
  const width = baseWidth + extra;
84056
84065
  cache$1.set(key2, { width });
@@ -84259,7 +84268,8 @@ async function measureParagraphBlock(block, maxWidth) {
84259
84268
  const isWordLayoutList = Boolean(wordLayout?.marker);
84260
84269
  const suppressFirstLine = block.attrs?.suppressFirstLineIndent === true;
84261
84270
  const rawFirstLineOffset = suppressFirstLine ? 0 : firstLine - hanging;
84262
- const firstLineOffset = isWordLayoutList ? 0 : rawFirstLineOffset;
84271
+ const clampedFirstLineOffset = Math.max(0, rawFirstLineOffset);
84272
+ const firstLineOffset = isWordLayoutList ? 0 : clampedFirstLineOffset;
84263
84273
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
84264
84274
  let leftJustifiedMarkerSpace = 0;
84265
84275
  if (wordLayout?.marker) {
@@ -84412,7 +84422,8 @@ async function measureParagraphBlock(block, maxWidth) {
84412
84422
  if (run2.kind === "break") {
84413
84423
  if (currentLine) {
84414
84424
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84415
- const completedLine = { ...currentLine, ...metrics };
84425
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84426
+ const completedLine = { ...lineBase, ...metrics };
84416
84427
  addBarTabsToLine(completedLine);
84417
84428
  lines.push(completedLine);
84418
84429
  currentLine = null;
@@ -84473,7 +84484,8 @@ async function measureParagraphBlock(block, maxWidth) {
84473
84484
  width: 0,
84474
84485
  maxFontSize: lastFontSize,
84475
84486
  maxWidth: nextLineMaxWidth,
84476
- segments: []
84487
+ segments: [],
84488
+ spaceCount: 0
84477
84489
  };
84478
84490
  tabStopCursor = 0;
84479
84491
  pendingTabAlignment = null;
@@ -84491,7 +84503,8 @@ async function measureParagraphBlock(block, maxWidth) {
84491
84503
  maxFontSize: 12,
84492
84504
  // Default font size for tabs
84493
84505
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84494
- segments: []
84506
+ segments: [],
84507
+ spaceCount: 0
84495
84508
  };
84496
84509
  }
84497
84510
  const originX = currentLine.width;
@@ -84540,6 +84553,7 @@ async function measureParagraphBlock(block, maxWidth) {
84540
84553
  maxFontSize: imageHeight,
84541
84554
  // Use image height for line height calculation
84542
84555
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84556
+ spaceCount: 0,
84543
84557
  segments: [
84544
84558
  {
84545
84559
  runIndex,
@@ -84555,8 +84569,9 @@ async function measureParagraphBlock(block, maxWidth) {
84555
84569
  const appliedTabAlign = lastAppliedTabAlign;
84556
84570
  if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
84557
84571
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84572
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84558
84573
  const completedLine = {
84559
- ...currentLine,
84574
+ ...lineBase,
84560
84575
  ...metrics
84561
84576
  };
84562
84577
  addBarTabsToLine(completedLine);
@@ -84572,6 +84587,7 @@ async function measureParagraphBlock(block, maxWidth) {
84572
84587
  width: imageWidth,
84573
84588
  maxFontSize: imageHeight,
84574
84589
  maxWidth: getEffectiveWidth(contentWidth),
84590
+ spaceCount: 0,
84575
84591
  segments: [
84576
84592
  {
84577
84593
  runIndex,
@@ -84627,6 +84643,7 @@ async function measureParagraphBlock(block, maxWidth) {
84627
84643
  width: annotationWidth,
84628
84644
  maxFontSize: annotationHeight,
84629
84645
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84646
+ spaceCount: 0,
84630
84647
  segments: [
84631
84648
  {
84632
84649
  runIndex,
@@ -84641,8 +84658,9 @@ async function measureParagraphBlock(block, maxWidth) {
84641
84658
  }
84642
84659
  if (currentLine.width + annotationWidth > currentLine.maxWidth && currentLine.width > 0) {
84643
84660
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84661
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84644
84662
  const completedLine = {
84645
- ...currentLine,
84663
+ ...lineBase,
84646
84664
  ...metrics
84647
84665
  };
84648
84666
  addBarTabsToLine(completedLine);
@@ -84658,6 +84676,7 @@ async function measureParagraphBlock(block, maxWidth) {
84658
84676
  width: annotationWidth,
84659
84677
  maxFontSize: annotationHeight,
84660
84678
  maxWidth: getEffectiveWidth(contentWidth),
84679
+ spaceCount: 0,
84661
84680
  segments: [
84662
84681
  {
84663
84682
  runIndex,
@@ -84713,14 +84732,16 @@ async function measureParagraphBlock(block, maxWidth) {
84713
84732
  maxFontSize: run2.fontSize,
84714
84733
  maxFontInfo: getFontInfoFromRun(run2),
84715
84734
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84716
- segments: [{ runIndex, fromChar: spacesStartChar, toChar: spacesEndChar, width: spacesWidth }]
84735
+ segments: [{ runIndex, fromChar: spacesStartChar, toChar: spacesEndChar, width: spacesWidth }],
84736
+ spaceCount: spacesLength
84717
84737
  };
84718
84738
  } else {
84719
84739
  const boundarySpacing = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
84720
84740
  if (currentLine.width + boundarySpacing + spacesWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0) {
84721
84741
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84742
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84722
84743
  const completedLine = {
84723
- ...currentLine,
84744
+ ...lineBase,
84724
84745
  ...metrics
84725
84746
  };
84726
84747
  addBarTabsToLine(completedLine);
@@ -84737,7 +84758,8 @@ async function measureParagraphBlock(block, maxWidth) {
84737
84758
  maxFontSize: run2.fontSize,
84738
84759
  maxFontInfo: getFontInfoFromRun(run2),
84739
84760
  maxWidth: getEffectiveWidth(contentWidth),
84740
- segments: [{ runIndex, fromChar: spacesStartChar, toChar: spacesEndChar, width: spacesWidth }]
84761
+ segments: [{ runIndex, fromChar: spacesStartChar, toChar: spacesEndChar, width: spacesWidth }],
84762
+ spaceCount: spacesLength
84741
84763
  };
84742
84764
  } else {
84743
84765
  currentLine.toRun = runIndex;
@@ -84746,6 +84768,7 @@ async function measureParagraphBlock(block, maxWidth) {
84746
84768
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
84747
84769
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
84748
84770
  appendSegment(currentLine.segments, runIndex, spacesStartChar, spacesEndChar, spacesWidth);
84771
+ currentLine.spaceCount += spacesLength;
84749
84772
  }
84750
84773
  }
84751
84774
  charPosInRun = spacesEndChar;
@@ -84762,7 +84785,56 @@ async function measureParagraphBlock(block, maxWidth) {
84762
84785
  for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
84763
84786
  const word = words[wordIndex];
84764
84787
  if (word === "") {
84765
- charPosInRun += 1;
84788
+ const spaceStartChar = charPosInRun;
84789
+ const spaceEndChar = charPosInRun + 1;
84790
+ const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2);
84791
+ if (!currentLine) {
84792
+ currentLine = {
84793
+ fromRun: runIndex,
84794
+ fromChar: spaceStartChar,
84795
+ toRun: runIndex,
84796
+ toChar: spaceEndChar,
84797
+ width: singleSpaceWidth,
84798
+ maxFontSize: run2.fontSize,
84799
+ maxFontInfo: getFontInfoFromRun(run2),
84800
+ maxWidth: getEffectiveWidth(initialAvailableWidth),
84801
+ segments: [{ runIndex, fromChar: spaceStartChar, toChar: spaceEndChar, width: singleSpaceWidth }],
84802
+ spaceCount: 1
84803
+ };
84804
+ } else {
84805
+ const boundarySpacing2 = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
84806
+ if (currentLine.width + boundarySpacing2 + singleSpaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0) {
84807
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84808
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84809
+ const completedLine = { ...lineBase, ...metrics };
84810
+ addBarTabsToLine(completedLine);
84811
+ lines.push(completedLine);
84812
+ tabStopCursor = 0;
84813
+ pendingTabAlignment = null;
84814
+ lastAppliedTabAlign = null;
84815
+ currentLine = {
84816
+ fromRun: runIndex,
84817
+ fromChar: spaceStartChar,
84818
+ toRun: runIndex,
84819
+ toChar: spaceEndChar,
84820
+ width: singleSpaceWidth,
84821
+ maxFontSize: run2.fontSize,
84822
+ maxFontInfo: getFontInfoFromRun(run2),
84823
+ maxWidth: getEffectiveWidth(contentWidth),
84824
+ segments: [{ runIndex, fromChar: spaceStartChar, toChar: spaceEndChar, width: singleSpaceWidth }],
84825
+ spaceCount: 1
84826
+ };
84827
+ } else {
84828
+ currentLine.toRun = runIndex;
84829
+ currentLine.toChar = spaceEndChar;
84830
+ currentLine.width = roundValue(currentLine.width + boundarySpacing2 + singleSpaceWidth);
84831
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
84832
+ currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
84833
+ appendSegment(currentLine.segments, runIndex, spaceStartChar, spaceEndChar, singleSpaceWidth);
84834
+ currentLine.spaceCount += 1;
84835
+ }
84836
+ }
84837
+ charPosInRun = spaceEndChar;
84766
84838
  continue;
84767
84839
  }
84768
84840
  const isLastWordInSegment = wordIndex === words.length - 1;
@@ -84783,13 +84855,15 @@ async function measureParagraphBlock(block, maxWidth) {
84783
84855
  maxFontSize: run2.fontSize,
84784
84856
  maxFontInfo: getFontInfoFromRun(run2),
84785
84857
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84786
- segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
84858
+ segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }],
84859
+ spaceCount: 0
84787
84860
  };
84788
84861
  const ls = run2.letterSpacing ?? 0;
84789
84862
  if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
84790
84863
  currentLine.toChar = wordEndWithSpace;
84791
84864
  currentLine.width = roundValue(currentLine.width + spaceWidth + ls);
84792
84865
  charPosInRun = wordEndWithSpace;
84866
+ currentLine.spaceCount += 1;
84793
84867
  } else {
84794
84868
  charPosInRun = wordEndWithSpace;
84795
84869
  }
@@ -84797,10 +84871,36 @@ async function measureParagraphBlock(block, maxWidth) {
84797
84871
  }
84798
84872
  const isTocEntry = block.attrs?.isTocEntry;
84799
84873
  const boundarySpacing = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
84800
- if (currentLine.width + boundarySpacing + wordOnlyWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0 && !isTocEntry) {
84874
+ const justifyAlignment = block.attrs?.alignment === "justify";
84875
+ const totalWidthWithWord = currentLine.width + boundarySpacing + wordCommitWidth + // Safe cast: only TextRuns produce word segments from split(), other run types are handled earlier
84876
+ (isLastWord ? 0 : run2.letterSpacing ?? 0);
84877
+ const availableWidth = currentLine.maxWidth - WIDTH_FUDGE_PX;
84878
+ let shouldBreak = currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
84879
+ let compressedWidth = null;
84880
+ if (shouldBreak && justifyAlignment) {
84881
+ const isParagraphLastWord = isLastWord && runIndex === runsToProcess.length - 1;
84882
+ if (!isParagraphLastWord) {
84883
+ const existingSpaces = currentLine.spaceCount ?? 0;
84884
+ const candidateSpaces = existingSpaces + (isLastWord ? 0 : 1);
84885
+ if (candidateSpaces > 0) {
84886
+ const overflow = totalWidthWithWord - availableWidth;
84887
+ if (overflow > 0) {
84888
+ const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2) || Math.max(1, boundarySpacing);
84889
+ const perSpaceCompression = overflow / candidateSpaces;
84890
+ const maxPerSpaceCompression = baseSpaceWidth * 0.25;
84891
+ if (perSpaceCompression <= maxPerSpaceCompression) {
84892
+ shouldBreak = false;
84893
+ compressedWidth = availableWidth;
84894
+ }
84895
+ }
84896
+ }
84897
+ }
84898
+ }
84899
+ if (shouldBreak) {
84801
84900
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84901
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84802
84902
  const completedLine = {
84803
- ...currentLine,
84903
+ ...lineBase,
84804
84904
  ...metrics
84805
84905
  };
84806
84906
  addBarTabsToLine(completedLine);
@@ -84816,12 +84916,14 @@ async function measureParagraphBlock(block, maxWidth) {
84816
84916
  maxFontSize: run2.fontSize,
84817
84917
  maxFontInfo: getFontInfoFromRun(run2),
84818
84918
  maxWidth: getEffectiveWidth(contentWidth),
84819
- segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
84919
+ segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }],
84920
+ spaceCount: 0
84820
84921
  };
84821
84922
  if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
84822
84923
  currentLine.toChar = wordEndWithSpace;
84823
84924
  currentLine.width = roundValue(currentLine.width + spaceWidth + (run2.letterSpacing ?? 0));
84824
84925
  charPosInRun = wordEndWithSpace;
84926
+ currentLine.spaceCount += 1;
84825
84927
  } else {
84826
84928
  charPosInRun = wordEndWithSpace;
84827
84929
  }
@@ -84842,7 +84944,8 @@ async function measureParagraphBlock(block, maxWidth) {
84842
84944
  useExplicitXHere ? segmentStartX : void 0
84843
84945
  );
84844
84946
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84845
- const completedLine = { ...currentLine, ...metrics };
84947
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84948
+ const completedLine = { ...lineBase, ...metrics };
84846
84949
  addBarTabsToLine(completedLine);
84847
84950
  lines.push(completedLine);
84848
84951
  tabStopCursor = 0;
@@ -84855,12 +84958,14 @@ async function measureParagraphBlock(block, maxWidth) {
84855
84958
  currentLine.toChar = newToChar;
84856
84959
  const useExplicitX = wordIndex === 0 && segmentStartX !== void 0;
84857
84960
  const explicitX = useExplicitX ? segmentStartX : void 0;
84858
- currentLine.width = roundValue(
84859
- currentLine.width + boundarySpacing + wordCommitWidth + (isLastWord ? 0 : run2.letterSpacing ?? 0)
84860
- );
84961
+ const targetWidth = compressedWidth != null ? compressedWidth : currentLine.width + boundarySpacing + wordCommitWidth + (isLastWord ? 0 : run2.letterSpacing ?? 0);
84962
+ currentLine.width = roundValue(targetWidth);
84861
84963
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
84862
84964
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
84863
84965
  appendSegment(currentLine.segments, runIndex, wordStartChar, newToChar, wordCommitWidth, explicitX);
84966
+ if (!isLastWord) {
84967
+ currentLine.spaceCount += 1;
84968
+ }
84864
84969
  }
84865
84970
  charPosInRun = isLastWord ? wordEndNoSpace : wordEndWithSpace;
84866
84971
  }
@@ -84883,7 +84988,8 @@ async function measureParagraphBlock(block, maxWidth) {
84883
84988
  maxFontSize: run2.fontSize,
84884
84989
  maxFontInfo: getFontInfoFromRun(run2),
84885
84990
  maxWidth: getEffectiveWidth(initialAvailableWidth),
84886
- segments: []
84991
+ segments: [],
84992
+ spaceCount: 0
84887
84993
  };
84888
84994
  }
84889
84995
  const originX = currentLine.width;
@@ -84929,8 +85035,9 @@ async function measureParagraphBlock(block, maxWidth) {
84929
85035
  }
84930
85036
  if (currentLine) {
84931
85037
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85038
+ const { spaceCount: _sc, ...lineBase } = currentLine;
84932
85039
  const finalLine = {
84933
- ...currentLine,
85040
+ ...lineBase,
84934
85041
  ...metrics
84935
85042
  };
84936
85043
  addBarTabsToLine(finalLine);