@silurus/ooxml 0.66.3 → 0.68.0

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.
@@ -46,11 +46,20 @@ export declare type BodyElement = {
46
46
  * "continuous" (same page), "nextPage" (default; page break), "oddPage" /
47
47
  * "evenPage" (page break + parity padding). The paginator switches its active
48
48
  * newspaper-column geometry per section at each marker — fixing the regression
49
- * where every section inherited the body-level section's columns. */
49
+ * where every section inherited the body-level section's columns.
50
+ *
51
+ * `headers`/`footers` carry the ENDING section's resolved (§17.10.1-inherited)
52
+ * header/footer set, and `titlePage` its own `<w:titlePg>` flag, so the renderer
53
+ * can pick the active section's header/footer per page (mirroring how `columns`
54
+ * drives per-section column geometry). The body-level (final) section's sets
55
+ * live on {@link DocxDocumentModel.section}/`.headers`/`.footers` instead. */
50
56
  | {
51
57
  type: 'sectionBreak';
52
58
  kind: 'continuous' | 'nextPage' | 'oddPage' | 'evenPage' | string;
53
59
  columns?: ColumnsSpec | null;
60
+ headers?: HeadersFooters;
61
+ footers?: HeadersFooters;
62
+ titlePage?: boolean;
54
63
  };
55
64
 
56
65
  export declare interface BorderSpec {
@@ -1242,6 +1251,12 @@ export declare interface ShapeText {
1242
1251
  * paragraphs. */
1243
1252
  runs?: ShapeTextRun[];
1244
1253
  alignment: string;
1254
+ /** ECMA-376 §17.3.1.33 `<w:spacing w:before>` of this text-box paragraph, in
1255
+ * pt — reserved ABOVE the paragraph inside the box. Absent/0 ⇒ no offset. */
1256
+ spaceBefore?: number;
1257
+ /** ECMA-376 §17.3.1.33 `<w:spacing w:after>` of this text-box paragraph, in
1258
+ * pt — reserved BELOW the paragraph. Absent/0 ⇒ no offset. */
1259
+ spaceAfter?: number;
1245
1260
  /** Zip path of an inline image inside this text-box paragraph
1246
1261
  * (`<w:drawing><wp:inline><a:blip r:embed>`), e.g. `word/media/image1.emf`.
1247
1262
  * Absent for a text-only paragraph. */
@@ -91,11 +91,20 @@ declare type BodyElement = {
91
91
  * "continuous" (same page), "nextPage" (default; page break), "oddPage" /
92
92
  * "evenPage" (page break + parity padding). The paginator switches its active
93
93
  * newspaper-column geometry per section at each marker — fixing the regression
94
- * where every section inherited the body-level section's columns. */
94
+ * where every section inherited the body-level section's columns.
95
+ *
96
+ * `headers`/`footers` carry the ENDING section's resolved (§17.10.1-inherited)
97
+ * header/footer set, and `titlePage` its own `<w:titlePg>` flag, so the renderer
98
+ * can pick the active section's header/footer per page (mirroring how `columns`
99
+ * drives per-section column geometry). The body-level (final) section's sets
100
+ * live on {@link DocxDocumentModel.section}/`.headers`/`.footers` instead. */
95
101
  | {
96
102
  type: 'sectionBreak';
97
103
  kind: 'continuous' | 'nextPage' | 'oddPage' | 'evenPage' | string;
98
104
  columns?: ColumnsSpec | null;
105
+ headers?: HeadersFooters;
106
+ footers?: HeadersFooters;
107
+ titlePage?: boolean;
99
108
  };
100
109
 
101
110
  declare interface Border {
@@ -1779,6 +1788,18 @@ declare interface ImageAnchor {
1779
1788
  * svgBlip extension. Its MIME is always `image/svg+xml` and is owned by the
1780
1789
  * SVG decoder. */
1781
1790
  svgImagePath?: string;
1791
+ /** ECMA-376 §20.1.8.55 `<a:srcRect>` source-image crop. Each edge inset is a
1792
+ * fraction `0..1` of the source bitmap, measured inward, so the visible
1793
+ * source region is `[l, t, 1-r, 1-b]`. Absent (the common case) ⇒ the whole
1794
+ * blip fills the anchor rect; when present, the renderer draws only the
1795
+ * cropped sub-rectangle (raster only — a metafile is rasterized to the
1796
+ * display box, so its crop can't be honored faithfully and is skipped). */
1797
+ srcRect?: {
1798
+ l: number;
1799
+ t: number;
1800
+ r: number;
1801
+ b: number;
1802
+ };
1782
1803
  }
1783
1804
 
1784
1805
  /**
@@ -2539,14 +2560,16 @@ declare interface PictureElement {
2539
2560
  */
2540
2561
  prstAdjust?: number[];
2541
2562
  /**
2542
- * ECMA-376 a:srcRect — source image crop as fractions (0..1) of the source
2543
- * width/height. Omitted when the image is not cropped.
2563
+ * ECMA-376 §20.1.8.55 a:srcRect — source image crop as fractions (0..1) of the
2564
+ * source width/height, measured inward from each edge. Omitted when the image
2565
+ * is not cropped; when present the parser emits all four edges (absent edges
2566
+ * default to 0), so the renderer reads them without a fallback.
2544
2567
  */
2545
2568
  srcRect?: {
2546
- l?: number;
2547
- t?: number;
2548
- r?: number;
2549
- b?: number;
2569
+ l: number;
2570
+ t: number;
2571
+ r: number;
2572
+ b: number;
2550
2573
  };
2551
2574
  /** a:blip > a:alphaModFix@amt as 0..1. Undefined = fully opaque. */
2552
2575
  alpha?: number;
@@ -3332,6 +3355,16 @@ declare type ShapeGeom = {
3332
3355
  * when the picture carries no svgBlip extension. Its MIME is always
3333
3356
  * `image/svg+xml` and is owned by the SVG decoder. */
3334
3357
  svgImagePath?: string;
3358
+ /** ECMA-376 §20.1.8.55 `<a:srcRect>` source-image crop on the leaf pic
3359
+ * (fractions `0..1` inward from each edge; visible region `[l, t, 1-r,
3360
+ * 1-b]`). Absent ⇒ the whole blip fills the leaf rect. Honored identically
3361
+ * to the top-level {@link ImageAnchor.srcRect} (raster only). */
3362
+ srcRect?: {
3363
+ l: number;
3364
+ t: number;
3365
+ r: number;
3366
+ b: number;
3367
+ };
3335
3368
  };
3336
3369
 
3337
3370
  declare interface ShapeInfo {
@@ -3472,6 +3505,12 @@ declare interface ShapeText_2 {
3472
3505
  * paragraphs. */
3473
3506
  runs?: ShapeTextRun_2[];
3474
3507
  alignment: string;
3508
+ /** ECMA-376 §17.3.1.33 `<w:spacing w:before>` of this text-box paragraph, in
3509
+ * pt — reserved ABOVE the paragraph inside the box. Absent/0 ⇒ no offset. */
3510
+ spaceBefore?: number;
3511
+ /** ECMA-376 §17.3.1.33 `<w:spacing w:after>` of this text-box paragraph, in
3512
+ * pt — reserved BELOW the paragraph. Absent/0 ⇒ no offset. */
3513
+ spaceAfter?: number;
3475
3514
  /** Zip path of an inline image inside this text-box paragraph
3476
3515
  * (`<w:drawing><wp:inline><a:blip r:embed>`), e.g. `word/media/image1.emf`.
3477
3516
  * Absent for a text-only paragraph. */
@@ -4348,6 +4387,7 @@ declare class XlsxViewer {
4348
4387
  private selectionOverlay;
4349
4388
  private keydownHandler;
4350
4389
  private pendingTap;
4390
+ private resizeDrag;
4351
4391
  /** DOM overlay element that shows the hovered cell's comment. Lives in
4352
4392
  * canvasArea above the scrollHost; `pointer-events:none` so it never blocks
4353
4393
  * cell interaction. */
@@ -4461,6 +4501,33 @@ declare class XlsxViewer {
4461
4501
  * Returns null when the point is in the cell grid (not a header).
4462
4502
  */
4463
4503
  private getHeaderHit;
4504
+ /**
4505
+ * If the pointer sits on a column/row-header border (within {@link
4506
+ * RESIZE_GRAB_PX}), return the resize target: which index to resize and the
4507
+ * fixed LTR edge it grows from (in canvasArea CSS px). Excel resizes the band
4508
+ * whose *trailing* border you grab — the column to the left of a vertical
4509
+ * border, the row above a horizontal one — so both that band and its
4510
+ * neighbour-to-the-far-side are checked. Geometry comes straight from {@link
4511
+ * getCellRect}, so the grab line always coincides with the drawn border at any
4512
+ * scroll offset / zoom / RTL. Returns null off the header borders.
4513
+ */
4514
+ private getResizeTarget;
4515
+ /**
4516
+ * Apply a live resize drag: size the band from its fixed origin edge to the
4517
+ * current pointer, clamp to {@link RESIZE_MIN_PX}, and write the result back
4518
+ * into the in-memory worksheet model in its native unit (Excel column widths /
4519
+ * points). This is a *view-only* mutation — the file is never written. The
4520
+ * memoized axis cache for this sheet is invalidated so every geometry read
4521
+ * (spacer, hit-test, overlay, renderer) sees the new size on the next frame.
4522
+ */
4523
+ private applyResize;
4524
+ /**
4525
+ * Change the cell-selection highlight color at runtime (see {@link
4526
+ * XlsxViewerOptions.selectionColor}). The border takes the color as-is and the
4527
+ * fill becomes a translucent shade of it; the current selection repaints
4528
+ * immediately.
4529
+ */
4530
+ setSelectionColor(color: string): void;
4464
4531
  /** Copy the selected cell range as tab-separated text to the clipboard. */
4465
4532
  private copySelection;
4466
4533
  private updateSelectionOverlay;
@@ -4537,9 +4604,15 @@ declare class XlsxViewer {
4537
4604
  destroy(): void;
4538
4605
  }
4539
4606
 
4540
- declare interface XlsxViewerOptions {
4607
+ declare interface XlsxViewerOptions extends LoadOptions_2 {
4541
4608
  /** Scale factor for cell/header dimensions (default 1). 0.5 = half size. */
4542
4609
  cellScale?: number;
4610
+ /**
4611
+ * Enable drag-to-resize of column widths / row heights by dragging header
4612
+ * borders. Resizing only changes the on-screen view — it never modifies the
4613
+ * loaded file. Default: true.
4614
+ */
4615
+ resizable?: boolean;
4543
4616
  /** Show the Excel-style zoom slider at the right end of the sheet-tab bar.
4544
4617
  * Default `true`. Set `false` to hide it (e.g. when the host supplies its
4545
4618
  * own zoom control). */
@@ -4562,27 +4635,15 @@ declare interface XlsxViewerOptions {
4562
4635
  /** Called when the selected cell range changes. null means no selection. */
4563
4636
  onSelectionChange?: (selection: CellRange_2 | null) => void;
4564
4637
  /**
4565
- * Opt in to Google-Fonts-hosted, metric-compatible substitutes for the
4566
- * Office default fonts (Carlito for Calibri, Caladea for Cambria) so
4567
- * column layouts match Excel on systems without Office installed.
4568
- * Default `false`. See `XlsxWorkbook.LoadOptions.useGoogleFonts` for the
4569
- * privacy implications.
4638
+ * Color of the cell-selection highlight. A single CSS color drives both the
4639
+ * selection rectangle's border (drawn in this color) and its fill (the same
4640
+ * color made translucent see {@link selectionOverlayStyle}), so callers pick
4641
+ * one accent color instead of a separate border + background. Any CSS color
4642
+ * string works (`#1a73e8`, `rgb(...)`, `tomato`, …). Default `#1a73e8`
4643
+ * (Google blue), matching the historical look. Can also be changed at runtime
4644
+ * via {@link XlsxViewer.setSelectionColor}.
4570
4645
  */
4571
- useGoogleFonts?: boolean;
4572
- /**
4573
- * Override the per-entry ZIP decompression cap (bytes) used by the
4574
- * zip-bomb guard in the Rust parser. Defaults to 512 MiB. Zero / negative
4575
- * values fall back to the default.
4576
- */
4577
- maxZipEntryBytes?: number;
4578
- /**
4579
- * Opt-in OMML equation engine for rendering math in shapes/text boxes.
4580
- * Import it from the separate `@silurus/ooxml/math` entry and pass it in
4581
- * (`import { math } from '@silurus/ooxml/math'`). When omitted, equations are
4582
- * skipped and the ~3 MB engine never enters the bundle (tree-shaken). Same
4583
- * dependency-injection contract as the docx/pptx viewers.
4584
- */
4585
- math?: MathRenderer;
4646
+ selectionColor?: string;
4586
4647
  /**
4587
4648
  * `'main'` (default): parse in a worker, render on the main thread. `'worker'`:
4588
4649
  * parse AND render entirely inside the worker and paint the returned
@@ -1077,14 +1077,16 @@ export declare interface PictureElement {
1077
1077
  */
1078
1078
  prstAdjust?: number[];
1079
1079
  /**
1080
- * ECMA-376 a:srcRect — source image crop as fractions (0..1) of the source
1081
- * width/height. Omitted when the image is not cropped.
1080
+ * ECMA-376 §20.1.8.55 a:srcRect — source image crop as fractions (0..1) of the
1081
+ * source width/height, measured inward from each edge. Omitted when the image
1082
+ * is not cropped; when present the parser emits all four edges (absent edges
1083
+ * default to 0), so the renderer reads them without a fallback.
1082
1084
  */
1083
1085
  srcRect?: {
1084
- l?: number;
1085
- t?: number;
1086
- r?: number;
1087
- b?: number;
1086
+ l: number;
1087
+ t: number;
1088
+ r: number;
1089
+ b: number;
1088
1090
  };
1089
1091
  /** a:blip > a:alphaModFix@amt as 0..1. Undefined = fully opaque. */
1090
1092
  alpha?: number;
@@ -476,6 +476,18 @@ export declare interface ImageAnchor {
476
476
  * svgBlip extension. Its MIME is always `image/svg+xml` and is owned by the
477
477
  * SVG decoder. */
478
478
  svgImagePath?: string;
479
+ /** ECMA-376 §20.1.8.55 `<a:srcRect>` source-image crop. Each edge inset is a
480
+ * fraction `0..1` of the source bitmap, measured inward, so the visible
481
+ * source region is `[l, t, 1-r, 1-b]`. Absent (the common case) ⇒ the whole
482
+ * blip fills the anchor rect; when present, the renderer draws only the
483
+ * cropped sub-rectangle (raster only — a metafile is rasterized to the
484
+ * display box, so its crop can't be honored faithfully and is skipped). */
485
+ srcRect?: {
486
+ l: number;
487
+ t: number;
488
+ r: number;
489
+ b: number;
490
+ };
479
491
  }
480
492
 
481
493
  export declare interface LegendManualLayout {
@@ -892,6 +904,16 @@ export declare type ShapeGeom = {
892
904
  * when the picture carries no svgBlip extension. Its MIME is always
893
905
  * `image/svg+xml` and is owned by the SVG decoder. */
894
906
  svgImagePath?: string;
907
+ /** ECMA-376 §20.1.8.55 `<a:srcRect>` source-image crop on the leaf pic
908
+ * (fractions `0..1` inward from each edge; visible region `[l, t, 1-r,
909
+ * 1-b]`). Absent ⇒ the whole blip fills the leaf rect. Honored identically
910
+ * to the top-level {@link ImageAnchor.srcRect} (raster only). */
911
+ srcRect?: {
912
+ l: number;
913
+ t: number;
914
+ r: number;
915
+ b: number;
916
+ };
895
917
  };
896
918
 
897
919
  export declare interface ShapeInfo {
@@ -1307,6 +1329,7 @@ export declare class XlsxViewer {
1307
1329
  private selectionOverlay;
1308
1330
  private keydownHandler;
1309
1331
  private pendingTap;
1332
+ private resizeDrag;
1310
1333
  /** DOM overlay element that shows the hovered cell's comment. Lives in
1311
1334
  * canvasArea above the scrollHost; `pointer-events:none` so it never blocks
1312
1335
  * cell interaction. */
@@ -1420,6 +1443,33 @@ export declare class XlsxViewer {
1420
1443
  * Returns null when the point is in the cell grid (not a header).
1421
1444
  */
1422
1445
  private getHeaderHit;
1446
+ /**
1447
+ * If the pointer sits on a column/row-header border (within {@link
1448
+ * RESIZE_GRAB_PX}), return the resize target: which index to resize and the
1449
+ * fixed LTR edge it grows from (in canvasArea CSS px). Excel resizes the band
1450
+ * whose *trailing* border you grab — the column to the left of a vertical
1451
+ * border, the row above a horizontal one — so both that band and its
1452
+ * neighbour-to-the-far-side are checked. Geometry comes straight from {@link
1453
+ * getCellRect}, so the grab line always coincides with the drawn border at any
1454
+ * scroll offset / zoom / RTL. Returns null off the header borders.
1455
+ */
1456
+ private getResizeTarget;
1457
+ /**
1458
+ * Apply a live resize drag: size the band from its fixed origin edge to the
1459
+ * current pointer, clamp to {@link RESIZE_MIN_PX}, and write the result back
1460
+ * into the in-memory worksheet model in its native unit (Excel column widths /
1461
+ * points). This is a *view-only* mutation — the file is never written. The
1462
+ * memoized axis cache for this sheet is invalidated so every geometry read
1463
+ * (spacer, hit-test, overlay, renderer) sees the new size on the next frame.
1464
+ */
1465
+ private applyResize;
1466
+ /**
1467
+ * Change the cell-selection highlight color at runtime (see {@link
1468
+ * XlsxViewerOptions.selectionColor}). The border takes the color as-is and the
1469
+ * fill becomes a translucent shade of it; the current selection repaints
1470
+ * immediately.
1471
+ */
1472
+ setSelectionColor(color: string): void;
1423
1473
  /** Copy the selected cell range as tab-separated text to the clipboard. */
1424
1474
  private copySelection;
1425
1475
  private updateSelectionOverlay;
@@ -1496,9 +1546,15 @@ export declare class XlsxViewer {
1496
1546
  destroy(): void;
1497
1547
  }
1498
1548
 
1499
- export declare interface XlsxViewerOptions {
1549
+ export declare interface XlsxViewerOptions extends LoadOptions_2 {
1500
1550
  /** Scale factor for cell/header dimensions (default 1). 0.5 = half size. */
1501
1551
  cellScale?: number;
1552
+ /**
1553
+ * Enable drag-to-resize of column widths / row heights by dragging header
1554
+ * borders. Resizing only changes the on-screen view — it never modifies the
1555
+ * loaded file. Default: true.
1556
+ */
1557
+ resizable?: boolean;
1502
1558
  /** Show the Excel-style zoom slider at the right end of the sheet-tab bar.
1503
1559
  * Default `true`. Set `false` to hide it (e.g. when the host supplies its
1504
1560
  * own zoom control). */
@@ -1521,27 +1577,15 @@ export declare interface XlsxViewerOptions {
1521
1577
  /** Called when the selected cell range changes. null means no selection. */
1522
1578
  onSelectionChange?: (selection: CellRange | null) => void;
1523
1579
  /**
1524
- * Opt in to Google-Fonts-hosted, metric-compatible substitutes for the
1525
- * Office default fonts (Carlito for Calibri, Caladea for Cambria) so
1526
- * column layouts match Excel on systems without Office installed.
1527
- * Default `false`. See `XlsxWorkbook.LoadOptions.useGoogleFonts` for the
1528
- * privacy implications.
1580
+ * Color of the cell-selection highlight. A single CSS color drives both the
1581
+ * selection rectangle's border (drawn in this color) and its fill (the same
1582
+ * color made translucent see {@link selectionOverlayStyle}), so callers pick
1583
+ * one accent color instead of a separate border + background. Any CSS color
1584
+ * string works (`#1a73e8`, `rgb(...)`, `tomato`, …). Default `#1a73e8`
1585
+ * (Google blue), matching the historical look. Can also be changed at runtime
1586
+ * via {@link XlsxViewer.setSelectionColor}.
1529
1587
  */
1530
- useGoogleFonts?: boolean;
1531
- /**
1532
- * Override the per-entry ZIP decompression cap (bytes) used by the
1533
- * zip-bomb guard in the Rust parser. Defaults to 512 MiB. Zero / negative
1534
- * values fall back to the default.
1535
- */
1536
- maxZipEntryBytes?: number;
1537
- /**
1538
- * Opt-in OMML equation engine for rendering math in shapes/text boxes.
1539
- * Import it from the separate `@silurus/ooxml/math` entry and pass it in
1540
- * (`import { math } from '@silurus/ooxml/math'`). When omitted, equations are
1541
- * skipped and the ~3 MB engine never enters the bundle (tree-shaken). Same
1542
- * dependency-injection contract as the docx/pptx viewers.
1543
- */
1544
- math?: MathRenderer;
1588
+ selectionColor?: string;
1545
1589
  /**
1546
1590
  * `'main'` (default): parse in a worker, render on the main thread. `'worker'`:
1547
1591
  * parse AND render entirely inside the worker and paint the returned