oasis-editor 0.0.55 → 0.0.57

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.
@@ -0,0 +1,48 @@
1
+ import { Element as XmlElement } from '@xmldom/xmldom';
2
+ import { EditorNamedStyle, EditorParagraphNode, EditorParagraphStyle, EditorTableConditionalFormat, EditorTextStyle } from '../../core/model.js';
3
+
4
+ export interface TableLook {
5
+ firstRow: boolean;
6
+ lastRow: boolean;
7
+ firstCol: boolean;
8
+ lastCol: boolean;
9
+ noHBand: boolean;
10
+ noVBand: boolean;
11
+ }
12
+ /**
13
+ * Parses `w:tblLook`, which gates which table-style conditional formats apply.
14
+ * Supports both the modern individual attributes (`firstRow`, `firstColumn`,
15
+ * `noVBand`, ...) and the legacy hex bitmask in `@w:val`. When the element is
16
+ * absent we default to Word's common case: first row + first column on, banding
17
+ * on.
18
+ */
19
+ export declare function parseTableLook(tblPr: XmlElement | null): TableLook;
20
+ /**
21
+ * Returns the table-style conditional-format keys that apply to a cell at the
22
+ * given position, ordered low→high precedence (later entries override earlier
23
+ * ones). Mirrors Word's resolution order: whole table < bands < first/last col
24
+ * < first/last row < corner cells. Banding and first/last row/col are gated by
25
+ * `tblLook`; banding parity is computed over the "body" rows/cols that remain
26
+ * after excluding the special first/last row/col.
27
+ */
28
+ export declare function resolveCellConditionalKeys(rowIndex: number, colIndex: number, rowCount: number, colCount: number, look: TableLook, rowBandSize: number, colBandSize: number): string[];
29
+ /** Merges resolved conditional formats (low→high precedence) into one. */
30
+ export declare function mergeConditionalFormats(keys: string[], conditionals: Record<string, EditorTableConditionalFormat> | undefined): EditorTableConditionalFormat;
31
+ /**
32
+ * Applies a conditional run text style (bold/color from the table style)
33
+ * beneath each run's own style, so explicit run formatting still wins.
34
+ */
35
+ export declare function applyConditionalTextStyle(paragraphs: EditorParagraphNode[], textStyle: EditorTextStyle | undefined): void;
36
+ /**
37
+ * Filter a table style's paragraph properties (its `<w:pPr>`) so they sit at the
38
+ * correct OOXML precedence for a given cell paragraph.
39
+ *
40
+ * Per ECMA-376 §17.7.2 the order (low → high) is:
41
+ * docDefaults < table style < paragraph style < direct formatting.
42
+ * So any property the paragraph's own (named) style explicitly defines must win
43
+ * over the table style. We strip those keys from the inherited table-style pPr;
44
+ * what remains only fills gaps the paragraph style leaves open. Without this, a
45
+ * table style like `TableGrid` (which sets `spacing after="0"`) would wrongly
46
+ * override Normal's `after="120"` and collapse cell row height vs Word.
47
+ */
48
+ export declare function tableStyleParagraphInheritance(tableStylePPr: EditorParagraphStyle | undefined, paragraphStyleId: string | undefined, styles: Record<string, EditorNamedStyle> | undefined): EditorParagraphStyle | undefined;
@@ -2483,7 +2483,7 @@ function OasisEditorAppLazy(props = {}) {
2483
2483
  onCleanup(() => {
2484
2484
  cancelled = true;
2485
2485
  });
2486
- import("./OasisEditorApp-BVDeDJUZ.js").then((m) => {
2486
+ import("./OasisEditorApp-BQ5KeU1o.js").then((m) => {
2487
2487
  cancelled = true;
2488
2488
  setProgress(1);
2489
2489
  setTimeout(() => setApp(() => m.OasisEditorApp), 180);
@@ -12943,6 +12943,82 @@ function positionsFinishedRow(row, ends) {
12943
12943
  }
12944
12944
  );
12945
12945
  }
12946
+ const MAX_COLUMN_BALANCE_ITERATIONS = 100;
12947
+ function projectColumnedBlocksLayout(context2, count, runTrackLayout) {
12948
+ var _a, _b;
12949
+ const { pageSettings, maxPageHeight, pageOffset = 0, existingPages = [] } = context2;
12950
+ const colWidth = ((_a = getPageColumnRects(pageSettings)[0]) == null ? void 0 : _a.width) ?? getPageContentWidth(pageSettings);
12951
+ const runTracks = (blocks, trackHeight) => runTrackLayout({
12952
+ ...context2,
12953
+ blocks,
12954
+ maxPageHeight: trackHeight,
12955
+ contentWidthOverride: colWidth,
12956
+ pageOffset: 0,
12957
+ existingPages: [],
12958
+ reservedHeightByPageIndex: void 0
12959
+ });
12960
+ let tracks = runTracks(context2.blocks, maxPageHeight);
12961
+ if (tracks.length > 1 || tracks.length === 1 && count > 1) {
12962
+ const trailingStart = Math.floor((tracks.length - 1) / count) * count;
12963
+ const trailingTracks = tracks.slice(trailingStart);
12964
+ const firstTrailingBlock = (_b = trailingTracks[0]) == null ? void 0 : _b.blocks[0];
12965
+ const prevTrack = trailingStart > 0 ? tracks[trailingStart - 1] : void 0;
12966
+ const prevLastBlock = prevTrack == null ? void 0 : prevTrack.blocks[prevTrack.blocks.length - 1];
12967
+ const cleanBoundary = firstTrailingBlock != null && (prevLastBlock == null || prevLastBlock.globalIndex !== firstTrailingBlock.globalIndex);
12968
+ if (cleanBoundary) {
12969
+ const startIndex = firstTrailingBlock.globalIndex;
12970
+ const sourceSubset = context2.blocks.slice(startIndex);
12971
+ const sumHeight = trailingTracks.reduce(
12972
+ (sum, track) => sum + track.height,
12973
+ 0
12974
+ );
12975
+ let target = Math.max(24, Math.ceil(sumHeight / count));
12976
+ let balanced = runTracks(sourceSubset, target);
12977
+ for (let iteration = 0; balanced.length > count && target < maxPageHeight && iteration < MAX_COLUMN_BALANCE_ITERATIONS; iteration += 1) {
12978
+ target = Math.min(maxPageHeight, Math.ceil(target * 1.05) + 4);
12979
+ balanced = runTracks(sourceSubset, target);
12980
+ }
12981
+ if (balanced.length <= count) {
12982
+ tracks = [...tracks.slice(0, trailingStart), ...balanced];
12983
+ }
12984
+ }
12985
+ }
12986
+ const pages = [...existingPages];
12987
+ const startPageIndex = existingPages.length > 0 ? existingPages[existingPages.length - 1].index + 1 : pageOffset;
12988
+ const physicalPageCount = Math.ceil(tracks.length / count);
12989
+ for (let p = 0; p < physicalPageCount; p += 1) {
12990
+ const pageIndex = startPageIndex + p;
12991
+ const pageTracks = tracks.slice(p * count, p * count + count);
12992
+ const blocks = [];
12993
+ let height = 0;
12994
+ pageTracks.forEach((track, columnIndex) => {
12995
+ for (const block of track.blocks) {
12996
+ block.columnIndex = columnIndex;
12997
+ blocks.push(block);
12998
+ }
12999
+ height = Math.max(height, track.height);
13000
+ });
13001
+ pages.push({
13002
+ id: `page:${pageIndex + 1}`,
13003
+ index: pageIndex,
13004
+ height,
13005
+ maxHeight: maxPageHeight,
13006
+ blocks,
13007
+ pageSettings
13008
+ });
13009
+ }
13010
+ if (pages.length === 0) {
13011
+ pages.push({
13012
+ id: `page:${startPageIndex + 1}`,
13013
+ index: startPageIndex,
13014
+ height: 0,
13015
+ maxHeight: maxPageHeight,
13016
+ blocks: [],
13017
+ pageSettings
13018
+ });
13019
+ }
13020
+ return pages;
13021
+ }
12946
13022
  const TEXT_BOX_AUTOFIT_SAFETY_PX$1 = 2;
12947
13023
  function estimateTextBoxAutoFitHeight(textBox, styles, measurer, pageIndex, totalPages, defaultTabStop) {
12948
13024
  var _a, _b, _c, _d, _e;
@@ -12990,7 +13066,11 @@ function estimateTextBoxAutoFitHeight(textBox, styles, measurer, pageIndex, tota
12990
13066
  function projectBlocksLayout(context2) {
12991
13067
  const columns = context2.pageSettings.columns;
12992
13068
  if (columns && columns.count > 1) {
12993
- return projectColumnedBlocksLayout(context2, columns.count);
13069
+ return projectColumnedBlocksLayout(
13070
+ context2,
13071
+ columns.count,
13072
+ projectColumnTrackLayout
13073
+ );
12994
13074
  }
12995
13075
  return projectColumnTrackLayout(context2);
12996
13076
  }
@@ -13572,82 +13652,6 @@ function projectColumnTrackLayout(context2) {
13572
13652
  }
13573
13653
  return pages;
13574
13654
  }
13575
- const MAX_COLUMN_BALANCE_ITERATIONS = 100;
13576
- function projectColumnedBlocksLayout(context2, count) {
13577
- var _a, _b;
13578
- const { pageSettings, maxPageHeight, pageOffset = 0, existingPages = [] } = context2;
13579
- const colWidth = ((_a = getPageColumnRects(pageSettings)[0]) == null ? void 0 : _a.width) ?? getPageContentWidth(pageSettings);
13580
- const runTracks = (blocks, trackHeight) => projectColumnTrackLayout({
13581
- ...context2,
13582
- blocks,
13583
- maxPageHeight: trackHeight,
13584
- contentWidthOverride: colWidth,
13585
- pageOffset: 0,
13586
- existingPages: [],
13587
- reservedHeightByPageIndex: void 0
13588
- });
13589
- let tracks = runTracks(context2.blocks, maxPageHeight);
13590
- if (tracks.length > 1 || tracks.length === 1 && count > 1) {
13591
- const trailingStart = Math.floor((tracks.length - 1) / count) * count;
13592
- const trailingTracks = tracks.slice(trailingStart);
13593
- const firstTrailingBlock = (_b = trailingTracks[0]) == null ? void 0 : _b.blocks[0];
13594
- const prevTrack = trailingStart > 0 ? tracks[trailingStart - 1] : void 0;
13595
- const prevLastBlock = prevTrack == null ? void 0 : prevTrack.blocks[prevTrack.blocks.length - 1];
13596
- const cleanBoundary = firstTrailingBlock != null && (prevLastBlock == null || prevLastBlock.globalIndex !== firstTrailingBlock.globalIndex);
13597
- if (cleanBoundary) {
13598
- const startIndex = firstTrailingBlock.globalIndex;
13599
- const sourceSubset = context2.blocks.slice(startIndex);
13600
- const sumHeight = trailingTracks.reduce(
13601
- (sum, track) => sum + track.height,
13602
- 0
13603
- );
13604
- let target = Math.max(24, Math.ceil(sumHeight / count));
13605
- let balanced = runTracks(sourceSubset, target);
13606
- for (let iteration = 0; balanced.length > count && target < maxPageHeight && iteration < MAX_COLUMN_BALANCE_ITERATIONS; iteration += 1) {
13607
- target = Math.min(maxPageHeight, Math.ceil(target * 1.05) + 4);
13608
- balanced = runTracks(sourceSubset, target);
13609
- }
13610
- if (balanced.length <= count) {
13611
- tracks = [...tracks.slice(0, trailingStart), ...balanced];
13612
- }
13613
- }
13614
- }
13615
- const pages = [...existingPages];
13616
- const startPageIndex = existingPages.length > 0 ? existingPages[existingPages.length - 1].index + 1 : pageOffset;
13617
- const physicalPageCount = Math.ceil(tracks.length / count);
13618
- for (let p = 0; p < physicalPageCount; p += 1) {
13619
- const pageIndex = startPageIndex + p;
13620
- const pageTracks = tracks.slice(p * count, p * count + count);
13621
- const blocks = [];
13622
- let height = 0;
13623
- pageTracks.forEach((track, columnIndex) => {
13624
- for (const block of track.blocks) {
13625
- block.columnIndex = columnIndex;
13626
- blocks.push(block);
13627
- }
13628
- height = Math.max(height, track.height);
13629
- });
13630
- pages.push({
13631
- id: `page:${pageIndex + 1}`,
13632
- index: pageIndex,
13633
- height,
13634
- maxHeight: maxPageHeight,
13635
- blocks,
13636
- pageSettings
13637
- });
13638
- }
13639
- if (pages.length === 0) {
13640
- pages.push({
13641
- id: `page:${startPageIndex + 1}`,
13642
- index: startPageIndex,
13643
- height: 0,
13644
- maxHeight: maxPageHeight,
13645
- blocks: [],
13646
- pageSettings
13647
- });
13648
- }
13649
- return pages;
13650
- }
13651
13655
  function getProjectedBlocksHeight(blocks) {
13652
13656
  if (!blocks || blocks.length === 0) {
13653
13657
  return 0;
@@ -33814,6 +33818,105 @@ async function parseParagraphNode(paragraphNode, numberingMaps, zip, relsMap, as
33814
33818
  );
33815
33819
  return parsed.paragraphs[0] ?? createEditorParagraphFromRuns([{ text: "" }]);
33816
33820
  }
33821
+ function parseTableLook(tblPr) {
33822
+ const element = getFirstChildByTagNameNS(tblPr, WORD_NS, "tblLook");
33823
+ const attr = (name) => {
33824
+ const value = getAttributeValue(element, name);
33825
+ return value === null || value === "" ? void 0 : isWordTrue(value);
33826
+ };
33827
+ const rawVal = getAttributeValue(element, "val");
33828
+ const mask = rawVal ? Number.parseInt(rawVal, 16) : Number.NaN;
33829
+ const bit = (flag) => Number.isFinite(mask) ? (mask & flag) !== 0 : void 0;
33830
+ return {
33831
+ firstRow: attr("firstRow") ?? bit(32) ?? true,
33832
+ lastRow: attr("lastRow") ?? bit(64) ?? false,
33833
+ firstCol: attr("firstColumn") ?? bit(128) ?? true,
33834
+ lastCol: attr("lastColumn") ?? bit(256) ?? false,
33835
+ noHBand: attr("noHBand") ?? bit(512) ?? false,
33836
+ noVBand: attr("noVBand") ?? bit(1024) ?? false
33837
+ };
33838
+ }
33839
+ function resolveCellConditionalKeys(rowIndex, colIndex, rowCount, colCount, look, rowBandSize, colBandSize) {
33840
+ const isFirstRow = look.firstRow && rowIndex === 0;
33841
+ const isLastRow = look.lastRow && rowIndex === rowCount - 1 && rowIndex !== 0;
33842
+ const isFirstCol = look.firstCol && colIndex === 0;
33843
+ const isLastCol = look.lastCol && colIndex === colCount - 1 && colIndex !== 0;
33844
+ const keys = [];
33845
+ if (!look.noHBand && !isFirstRow && !isLastRow) {
33846
+ const bodyRow = rowIndex - (look.firstRow ? 1 : 0);
33847
+ const band = Math.floor(bodyRow / Math.max(1, rowBandSize)) % 2;
33848
+ keys.push(band === 0 ? "band1Horz" : "band2Horz");
33849
+ }
33850
+ if (!look.noVBand && !isFirstCol && !isLastCol) {
33851
+ const bodyCol = colIndex - (look.firstCol ? 1 : 0);
33852
+ const band = Math.floor(bodyCol / Math.max(1, colBandSize)) % 2;
33853
+ keys.push(band === 0 ? "band1Vert" : "band2Vert");
33854
+ }
33855
+ if (isLastCol) keys.push("lastCol");
33856
+ if (isFirstCol) keys.push("firstCol");
33857
+ if (isLastRow) keys.push("lastRow");
33858
+ if (isFirstRow) keys.push("firstRow");
33859
+ if (isFirstRow && isFirstCol) keys.push("nwCell");
33860
+ if (isFirstRow && isLastCol) keys.push("neCell");
33861
+ if (isLastRow && isFirstCol) keys.push("swCell");
33862
+ if (isLastRow && isLastCol) keys.push("seCell");
33863
+ return keys;
33864
+ }
33865
+ function mergeConditionalFormats(keys, conditionals) {
33866
+ const merged = {};
33867
+ if (!conditionals) {
33868
+ return merged;
33869
+ }
33870
+ for (const key of keys) {
33871
+ const cond = conditionals[key];
33872
+ if (!cond) continue;
33873
+ if (cond.shading) merged.shading = cond.shading;
33874
+ if (cond.textStyle) {
33875
+ merged.textStyle = { ...merged.textStyle, ...cond.textStyle };
33876
+ }
33877
+ if (cond.borders) {
33878
+ merged.borders = { ...merged.borders, ...cond.borders };
33879
+ }
33880
+ if (cond.paragraphStyle) {
33881
+ merged.paragraphStyle = {
33882
+ ...merged.paragraphStyle,
33883
+ ...cond.paragraphStyle
33884
+ };
33885
+ }
33886
+ if (cond.rowStyle) {
33887
+ merged.rowStyle = { ...merged.rowStyle, ...cond.rowStyle };
33888
+ }
33889
+ }
33890
+ return merged;
33891
+ }
33892
+ function applyConditionalTextStyle(paragraphs, textStyle) {
33893
+ if (!textStyle || Object.keys(textStyle).length === 0) {
33894
+ return;
33895
+ }
33896
+ for (const paragraph of paragraphs) {
33897
+ for (const run of paragraph.runs) {
33898
+ run.styles = { ...textStyle, ...run.styles };
33899
+ }
33900
+ }
33901
+ }
33902
+ function tableStyleParagraphInheritance(tableStylePPr, paragraphStyleId, styles) {
33903
+ if (!tableStylePPr) {
33904
+ return void 0;
33905
+ }
33906
+ const effectiveStyleId = paragraphStyleId ?? resolveDefaultParagraphStyleId(styles);
33907
+ const paragraphStyleDelta = resolveNamedParagraphStyle(
33908
+ effectiveStyleId,
33909
+ styles
33910
+ );
33911
+ const definedByParagraphStyle = new Set(Object.keys(paragraphStyleDelta));
33912
+ const filtered = {};
33913
+ for (const [key, value] of Object.entries(tableStylePPr)) {
33914
+ if (!definedByParagraphStyle.has(key)) {
33915
+ filtered[key] = value;
33916
+ }
33917
+ }
33918
+ return emptyOrUndefined(filtered);
33919
+ }
33817
33920
  function parseDocxWidthValue(element) {
33818
33921
  if (!element) {
33819
33922
  return void 0;
@@ -34246,102 +34349,6 @@ function applyTableBordersToRows(rows, tblBorders) {
34246
34349
  }
34247
34350
  }
34248
34351
  }
34249
- function parseTableLook(tblPr) {
34250
- const element = getFirstChildByTagNameNS(tblPr, WORD_NS, "tblLook");
34251
- const attr = (name) => {
34252
- const value = getAttributeValue(element, name);
34253
- return value === null || value === "" ? void 0 : isWordTrue(value);
34254
- };
34255
- const rawVal = getAttributeValue(element, "val");
34256
- const mask = rawVal ? Number.parseInt(rawVal, 16) : Number.NaN;
34257
- const bit = (flag) => Number.isFinite(mask) ? (mask & flag) !== 0 : void 0;
34258
- return {
34259
- firstRow: attr("firstRow") ?? bit(32) ?? true,
34260
- lastRow: attr("lastRow") ?? bit(64) ?? false,
34261
- firstCol: attr("firstColumn") ?? bit(128) ?? true,
34262
- lastCol: attr("lastColumn") ?? bit(256) ?? false,
34263
- noHBand: attr("noHBand") ?? bit(512) ?? false,
34264
- noVBand: attr("noVBand") ?? bit(1024) ?? false
34265
- };
34266
- }
34267
- function resolveCellConditionalKeys(rowIndex, colIndex, rowCount, colCount, look, rowBandSize, colBandSize) {
34268
- const isFirstRow = look.firstRow && rowIndex === 0;
34269
- const isLastRow = look.lastRow && rowIndex === rowCount - 1 && rowIndex !== 0;
34270
- const isFirstCol = look.firstCol && colIndex === 0;
34271
- const isLastCol = look.lastCol && colIndex === colCount - 1 && colIndex !== 0;
34272
- const keys = [];
34273
- if (!look.noHBand && !isFirstRow && !isLastRow) {
34274
- const bodyRow = rowIndex - (look.firstRow ? 1 : 0);
34275
- const band = Math.floor(bodyRow / Math.max(1, rowBandSize)) % 2;
34276
- keys.push(band === 0 ? "band1Horz" : "band2Horz");
34277
- }
34278
- if (!look.noVBand && !isFirstCol && !isLastCol) {
34279
- const bodyCol = colIndex - (look.firstCol ? 1 : 0);
34280
- const band = Math.floor(bodyCol / Math.max(1, colBandSize)) % 2;
34281
- keys.push(band === 0 ? "band1Vert" : "band2Vert");
34282
- }
34283
- if (isLastCol) keys.push("lastCol");
34284
- if (isFirstCol) keys.push("firstCol");
34285
- if (isLastRow) keys.push("lastRow");
34286
- if (isFirstRow) keys.push("firstRow");
34287
- if (isFirstRow && isFirstCol) keys.push("nwCell");
34288
- if (isFirstRow && isLastCol) keys.push("neCell");
34289
- if (isLastRow && isFirstCol) keys.push("swCell");
34290
- if (isLastRow && isLastCol) keys.push("seCell");
34291
- return keys;
34292
- }
34293
- function mergeConditionalFormats(keys, conditionals) {
34294
- const merged = {};
34295
- if (!conditionals) {
34296
- return merged;
34297
- }
34298
- for (const key of keys) {
34299
- const cond = conditionals[key];
34300
- if (!cond) continue;
34301
- if (cond.shading) merged.shading = cond.shading;
34302
- if (cond.textStyle) {
34303
- merged.textStyle = { ...merged.textStyle, ...cond.textStyle };
34304
- }
34305
- if (cond.borders) {
34306
- merged.borders = { ...merged.borders, ...cond.borders };
34307
- }
34308
- if (cond.paragraphStyle) {
34309
- merged.paragraphStyle = { ...merged.paragraphStyle, ...cond.paragraphStyle };
34310
- }
34311
- if (cond.rowStyle) {
34312
- merged.rowStyle = { ...merged.rowStyle, ...cond.rowStyle };
34313
- }
34314
- }
34315
- return merged;
34316
- }
34317
- function applyConditionalTextStyle(paragraphs, textStyle) {
34318
- if (!textStyle || Object.keys(textStyle).length === 0) {
34319
- return;
34320
- }
34321
- for (const paragraph of paragraphs) {
34322
- for (const run of paragraph.runs) {
34323
- run.styles = { ...textStyle, ...run.styles };
34324
- }
34325
- }
34326
- }
34327
- function tableStyleParagraphInheritance(tableStylePPr, paragraphStyleId, styles) {
34328
- if (!tableStylePPr) {
34329
- return void 0;
34330
- }
34331
- const effectiveStyleId = paragraphStyleId ?? resolveDefaultParagraphStyleId(styles);
34332
- const paragraphStyleDelta = resolveNamedParagraphStyle(
34333
- effectiveStyleId,
34334
- styles
34335
- );
34336
- const definedByParagraphStyle = new Set(Object.keys(paragraphStyleDelta));
34337
- const filtered = {};
34338
- for (const [key, value] of Object.entries(tableStylePPr)) {
34339
- if (!definedByParagraphStyle.has(key)) {
34340
- filtered[key] = value;
34341
- }
34342
- }
34343
- return emptyOrUndefined(filtered);
34344
- }
34345
34352
  async function parseTableNode(tableNode, numberingMaps, zip, relsMap, assets, theme, parseNestedBlocks, styles) {
34346
34353
  var _a, _b;
34347
34354
  const gridCols = [];
@@ -35532,7 +35539,7 @@ function importDocxInWorker(buffer, options = {}) {
35532
35539
  const worker = new Worker(
35533
35540
  new URL(
35534
35541
  /* @vite-ignore */
35535
- "" + new URL("assets/importDocxWorker-DbI0FKvR.js", import.meta.url).href,
35542
+ "" + new URL("assets/importDocxWorker-BWyqey19.js", import.meta.url).href,
35536
35543
  import.meta.url
35537
35544
  ),
35538
35545
  {
@@ -1,25 +1,7 @@
1
- import { EditorBlockNode, EditorLayoutPage, EditorLayoutParagraph, EditorNamedStyle, EditorPageSettings } from '../core/model.js';
2
- import { ITextMeasurer } from '../core/engine.js';
1
+ import { EditorLayoutPage } from '../core/model.js';
2
+ import { ProjectBlocksLayoutContext } from './blocksPaginationTypes.js';
3
3
 
4
- export interface ProjectBlocksLayoutContext {
5
- blocks: EditorBlockNode[];
6
- pageSettings: EditorPageSettings;
7
- maxPageHeight: number;
8
- measuredHeights?: Record<string, number>;
9
- measuredParagraphLayouts?: Record<string, EditorLayoutParagraph>;
10
- styles?: Record<string, EditorNamedStyle>;
11
- pageOffset?: number;
12
- totalPages?: number;
13
- existingPages?: EditorLayoutPage[];
14
- measurer?: ITextMeasurer;
15
- reservedHeightByPageIndex?: Map<number, number>;
16
- defaultTabStop?: number;
17
- /**
18
- * Overrides the line-wrapping width (default: full page content width). Used
19
- * by the multi-column flow to wrap at a single column's width.
20
- */
21
- contentWidthOverride?: number;
22
- }
4
+ export type { ProjectBlocksLayoutContext } from './blocksPaginationTypes.js';
23
5
  /**
24
6
  * Entry point used by section pagination. Dispatches to the multi-column flow
25
7
  * when the page declares `columns.count > 1`, otherwise runs the standard
@@ -0,0 +1,22 @@
1
+ import { EditorBlockNode, EditorLayoutPage, EditorLayoutParagraph, EditorNamedStyle, EditorPageSettings } from '../core/model.js';
2
+ import { ITextMeasurer } from '../core/engine.js';
3
+
4
+ export interface ProjectBlocksLayoutContext {
5
+ blocks: EditorBlockNode[];
6
+ pageSettings: EditorPageSettings;
7
+ maxPageHeight: number;
8
+ measuredHeights?: Record<string, number>;
9
+ measuredParagraphLayouts?: Record<string, EditorLayoutParagraph>;
10
+ styles?: Record<string, EditorNamedStyle>;
11
+ pageOffset?: number;
12
+ totalPages?: number;
13
+ existingPages?: EditorLayoutPage[];
14
+ measurer?: ITextMeasurer;
15
+ reservedHeightByPageIndex?: Map<number, number>;
16
+ defaultTabStop?: number;
17
+ /**
18
+ * Overrides the line-wrapping width (default: full page content width). Used
19
+ * by the multi-column flow to wrap at a single column's width.
20
+ */
21
+ contentWidthOverride?: number;
22
+ }
@@ -0,0 +1,14 @@
1
+ import { EditorLayoutPage } from '../core/model.js';
2
+ import { ProjectBlocksLayoutContext } from './blocksPaginationTypes.js';
3
+
4
+ /**
5
+ * Multi-column (newspaper) flow. Lays blocks into single-column tracks, then
6
+ * groups every `count` consecutive tracks side-by-side onto one physical page,
7
+ * tagging each block with its `columnIndex`. The final page of the section is
8
+ * balanced so its columns are near-equal height, matching Word.
9
+ *
10
+ * The single-column track layout is injected as `runTrackLayout` so this module
11
+ * does not import back into blocksPagination (which dispatches to it) — keeping
12
+ * the recursion acyclic (S2).
13
+ */
14
+ export declare function projectColumnedBlocksLayout(context: ProjectBlocksLayoutContext, count: number, runTrackLayout: (context: ProjectBlocksLayoutContext) => EditorLayoutPage[]): EditorLayoutPage[];
@@ -1,4 +1,4 @@
1
- import { b2, bV, bW, bX, bY, bZ, bk, b_, b3, a_, b$, c0, c1, b1, c2, aY, c3, c4, c5, c6, c7, bQ, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, bp, cj, bP, ck, bX as bX2, c0 as c02, c2 as c22, cb as cb2, cd as cd2, ci as ci2, cl, b0, aX, cm, cn, co, aZ, cp, cq, a$ } from "./index-CCkT5Iyw.js";
1
+ import { b2, bV, bW, bX, bY, bZ, bk, b_, b3, a_, b$, c0, c1, b1, c2, aY, c3, c4, c5, c6, c7, bQ, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, bp, cj, bP, ck, bX as bX2, c0 as c02, c2 as c22, cb as cb2, cd as cd2, ci as ci2, cl, b0, aX, cm, cn, co, aZ, cp, cq, a$ } from "./index-DiZU2BUt.js";
2
2
  export {
3
3
  b2 as BalloonShell,
4
4
  bV as Button,