@silurus/ooxml 0.71.0 → 0.72.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.
@@ -61,11 +61,18 @@ export declare interface BlipBullet {
61
61
  /** MIME type of the blip at {@link BlipBullet.imagePath} (e.g. `image/png`). */
62
62
  mimeType: string;
63
63
  /**
64
- * `<a:buSzPct val>` (ECMA-376 §21.1.2.4.3) as a percentage of the text size
64
+ * `<a:buSzPct val>` (ECMA-376 §21.1.2.4.9) as a percentage of the text size
65
65
  * (100 = same size). `null` when no explicit `<a:buSzPct>` is present, in
66
66
  * which case the renderer uses the spec default of 100%.
67
67
  */
68
68
  sizePct: number | null;
69
+ /**
70
+ * `<a:buSzPts val>` (ECMA-376 §21.1.2.4.10) — an ABSOLUTE marker size in
71
+ * points, independent of the text size. Mutually exclusive with {@link
72
+ * BlipBullet.sizePct} (both are the one `EG_TextBulletSize` choice). Omitted
73
+ * when no explicit `<a:buSzPts>` is present; when present it takes precedence.
74
+ */
75
+ sizePts?: number;
69
76
  }
70
77
 
71
78
  /**
@@ -73,11 +80,16 @@ export declare interface BlipBullet {
73
80
  * by shape frame (with the shape's rotation) so each box lands on the drawn
74
81
  * glyphs.
75
82
  *
76
- * @param layer the overlay div (cleared + re-sized here).
83
+ * All coordinates are PERCENTAGES of `cssWidth`/`cssHeight`, and the container's
84
+ * own size is left untouched (`width:100%;height:100%` from the caller), so the
85
+ * highlights track the canvas's ACTUAL rendered box even when a consumer scales
86
+ * the canvas down with external CSS — mirroring {@link buildPptxTextLayer}.
87
+ *
88
+ * @param layer the overlay div (cleared here; sized `100%` by the caller).
77
89
  * @param runs the slide's runs (same array the slide was rendered from).
78
90
  * @param matches the slide's matches (run-slices + active flag).
79
- * @param cssWidth rendered canvas CSS width (px, number).
80
- * @param cssHeight rendered canvas CSS height (px, number).
91
+ * @param cssWidth the slide's intended CSS width (px, number) — the % denominator.
92
+ * @param cssHeight the slide's intended CSS height (px, number) — the % denominator.
81
93
  * @param measureForFont returns a width-measurer primed with a run's font.
82
94
  * @param colors optional colour overrides.
83
95
  */
@@ -102,10 +114,19 @@ export declare function buildPptxHighlightLayer(layer: HTMLDivElement, runs: Ppt
102
114
  * (no hyperlink) is byte-identical to before. A JS click handler is used rather
103
115
  * than an `<a href>` so the URL never bypasses the viewer's sanitisation.
104
116
  *
105
- * @param layer the overlay div.
117
+ * The overlay's coordinates are all PERCENTAGES of `cssWidth`/`cssHeight` (the
118
+ * slide's intended CSS-px box), never literal px, and the container's own
119
+ * `width`/`height` are left untouched (the caller sizes it `width:100%;
120
+ * height:100%` so it fills the wrapper). This lets the overlay track the canvas's
121
+ * ACTUAL rendered box even when a consumer scales the canvas down with external
122
+ * CSS (e.g. `width:100%!important;height:auto`): the wrapper (and therefore the
123
+ * `100%` container) shrinks with the canvas, and every `%`-placed child scales
124
+ * with it, so nothing overflows the wrapper into an ancestor's scroll area.
125
+ *
126
+ * @param layer the overlay div (sized `width:100%;height:100%` by the caller).
106
127
  * @param runs per-run + per-shape geometry from `renderSlide({ onTextRun })`.
107
- * @param cssWidth the rendered canvas's CSS width (px, number).
108
- * @param cssHeight the rendered canvas's CSS height (px, number).
128
+ * @param cssWidth the slide's intended CSS width (px, number) — the % denominator.
129
+ * @param cssHeight the slide's intended CSS height (px, number) — the % denominator.
109
130
  * @param onHyperlinkClick called with the run's resolved {@link HyperlinkTarget}
110
131
  * when a hyperlink span is clicked. Omit to leave links
111
132
  * non-interactive (spans stay plain, selectable text).
@@ -120,6 +141,13 @@ export declare function buildPptxTextLayer(layer: HTMLDivElement, runs: PptxText
120
141
  */
121
142
  export declare type Bullet = Bullet_2 | BlipBullet;
122
143
 
144
+ /**
145
+ * A paragraph's bullet marker. For `char`, the marker size is EITHER `sizePct`
146
+ * (a percentage of the run size — ECMA-376 §21.1.2.4.9 `<a:buSzPct>`) OR `sizePts`
147
+ * (an absolute size in points — §21.1.2.4.10 `<a:buSzPts>`), never both: they are
148
+ * the one `EG_TextBulletSize` xsd:choice. `sizePts` is optional (absent when no
149
+ * `<a:buSzPts>` was declared); when present it takes precedence over `sizePct`.
150
+ */
123
151
  declare type Bullet_2 = {
124
152
  type: 'none';
125
153
  } | {
@@ -129,11 +157,13 @@ declare type Bullet_2 = {
129
157
  char: string;
130
158
  color: string | null;
131
159
  sizePct: number | null;
160
+ sizePts?: number;
132
161
  fontFamily: string | null;
133
162
  } | {
134
163
  type: 'autoNum';
135
164
  numType: string;
136
165
  startAt: number | null;
166
+ color: string | null;
137
167
  };
138
168
 
139
169
  /**
@@ -334,6 +364,14 @@ export declare interface ChartModel {
334
364
  title: string | null;
335
365
  categories: string[];
336
366
  series: ChartSeries[];
367
+ /**
368
+ * §21.2.2.227 `<c:varyColors val="1"/>` on a SINGLE-series bar/column chart:
369
+ * color each data point (bar) from the theme/palette sequence and list one
370
+ * legend entry per point, matching Office. Set by the shared parser ONLY for
371
+ * that non-pie, single-series case (pie/doughnut already vary by point via
372
+ * `chartType` + `dataPointColors`); absent/false otherwise.
373
+ */
374
+ varyColors?: boolean | null;
337
375
  /** Show data labels on bars / points / slices. */
338
376
  showDataLabels: boolean;
339
377
  /** Explicit Y-axis minimum (OOXML `<c:valAx><c:min>`). */
@@ -1103,6 +1141,14 @@ export declare interface ImageFill {
1103
1141
  tile?: TileInfo;
1104
1142
  /** `a:blip > a:alphaModFix@amt` as a fraction (0.0–1.0). Absent = opaque. */
1105
1143
  alpha?: number;
1144
+ /**
1145
+ * ECMA-376 §20.1.8.23 `<a:duotone>` recolour, resolved to its two endpoint
1146
+ * colours (through the slide theme). Absent ⇒ no duotone. When present the
1147
+ * renderer maps the blip's luminance ramp between the two colours (core
1148
+ * `applyDuotone`) — the same recolour a `<p:pic>` duotone applies, wired onto
1149
+ * the picture-FILL path (§20.1.8.14) by issue #889.
1150
+ */
1151
+ duotone?: Duotone;
1106
1152
  }
1107
1153
 
1108
1154
  declare interface LegendManualLayout {
@@ -1540,6 +1586,14 @@ export declare interface Paragraph extends Paragraph_2 {
1540
1586
  * emits an effective boolean.
1541
1587
  */
1542
1588
  eaLnBrk: boolean;
1589
+ /**
1590
+ * `<a:pPr defTabSz>` (ECMA-376 §21.1.2.2.7) — the default tab-stop interval in
1591
+ * EMU. When a `\t` has no reachable explicit `a:tabLst` stop, it advances to
1592
+ * the next multiple of this grid (issue #1006). Absent ⇒ the renderer uses the
1593
+ * PowerPoint universal default of 914400 EMU (1 inch). Omitted from JSON when
1594
+ * the parser found no explicit value.
1595
+ */
1596
+ defTabSz?: number;
1543
1597
  }
1544
1598
 
1545
1599
  declare interface Paragraph_2 {
@@ -2346,6 +2400,15 @@ export declare class PptxScrollViewer implements ZoomableViewer {
2346
2400
  * to the target slide via {@link scrollToSlide} once the action resolves to a
2347
2401
  * slide index (a jump resolving to no reachable slide is a safe no-op).
2348
2402
  */
2403
+ /**
2404
+ * IX1 — the click handler passed to the text-layer overlay, or `undefined` when
2405
+ * `enableHyperlinks` is `false`. This is the single gate that disables hyperlink
2406
+ * interactivity: {@link buildPptxTextLayer} renders link runs exactly like plain
2407
+ * runs when no handler is supplied, so no hit region, cursor, tooltip, listener,
2408
+ * or navigation is wired (a custom `onHyperlinkClick` is suppressed too). When
2409
+ * enabled, the returned handler dispatches through {@link _onHyperlinkClick}.
2410
+ */
2411
+ private _hyperlinkHandler;
2349
2412
  private _onHyperlinkClick;
2350
2413
  /** Populate an internal {@link HyperlinkTarget}'s `slideIndex` from its `ref`
2351
2414
  * via the engine's stamped part names. Relative `hlinkshowjump` verbs are
@@ -2512,6 +2575,13 @@ export declare interface PptxScrollViewerOptions extends Omit<RenderSlideOptions
2512
2575
  * instead and takes NO default action.
2513
2576
  */
2514
2577
  onHyperlinkClick?: (target: HyperlinkTarget) => void;
2578
+ /** IX1 — master switch for hyperlink interactivity. Default `true`. When
2579
+ * `false`, the hyperlink machinery is not wired at all: the overlay's link
2580
+ * spans are non-interactive, so there is no pointer cursor, no title tooltip,
2581
+ * no default navigation (external new-tab / internal slide jump), and
2582
+ * `onHyperlinkClick` is never called. Links still render exactly as authored
2583
+ * but are inert, like plain text. */
2584
+ enableHyperlinks?: boolean;
2515
2585
  }
2516
2586
 
2517
2587
  /** Information about a rendered text segment for building a transparent selection overlay. */
@@ -2751,6 +2821,15 @@ export declare class PptxViewer implements ZoomableViewer {
2751
2821
  /** Rebuild the highlight overlay for the current slide from cached runs. */
2752
2822
  private _redrawHighlights;
2753
2823
  private _buildTextLayer;
2824
+ /**
2825
+ * IX1 — the click handler passed to the text-layer overlay, or `undefined` when
2826
+ * `enableHyperlinks` is `false`. This is the single gate that disables hyperlink
2827
+ * interactivity: {@link buildPptxTextLayer} renders link runs exactly like plain
2828
+ * runs when no handler is supplied, so no hit region, cursor, tooltip, listener,
2829
+ * or navigation is wired (a custom `onHyperlinkClick` is suppressed too). When
2830
+ * enabled, the returned handler dispatches through {@link _onHyperlinkClick}.
2831
+ */
2832
+ private _hyperlinkHandler;
2754
2833
  /**
2755
2834
  * IX1/IX-nav hyperlink click dispatch. An internal target is first *enriched*
2756
2835
  * with its resolved 0-based `slideIndex` (via
@@ -2847,6 +2926,14 @@ export declare interface PptxViewerOptions extends RenderOptions, LoadOptions {
2847
2926
  * viewer calls this instead and takes NO default action.
2848
2927
  */
2849
2928
  onHyperlinkClick?: (target: HyperlinkTarget) => void;
2929
+ /** IX1 — master switch for hyperlink interactivity. Default `true`. When
2930
+ * `false`, the hyperlink machinery is not wired at all: the overlay's link
2931
+ * spans are non-interactive, so there is no pointer cursor, no title tooltip,
2932
+ * no default navigation (external new-tab / internal slide jump), and
2933
+ * `onHyperlinkClick` is never called. Links still render exactly as authored
2934
+ * (theme `hlink` colour + underline are painted on the canvas) but are inert,
2935
+ * like plain text. */
2936
+ enableHyperlinks?: boolean;
2850
2937
  }
2851
2938
 
2852
2939
  export declare interface Presentation {
@@ -3105,6 +3192,14 @@ export declare interface ShapeElement {
3105
3192
  /** `<a:sp3d>` 3D shape properties (ECMA-376 §20.1.5.12). Parsed but not
3106
3193
  * rendered in Phase A. */
3107
3194
  sp3d?: Sp3d;
3195
+ /** `<p:nvSpPr><p:cNvPr @id>` — DrawingML cNvPr id. Present for file-authored
3196
+ * shapes (the attribute is schema-required); absent on parser-synthesized
3197
+ * shapes such as the SmartArt data-model fallback. */
3198
+ id?: string;
3199
+ /** `<p:nvSpPr><p:cNvPr @name>` — author-visible shape name (e.g. "Title 1").
3200
+ * The SmartArt data-model fallback synthesizes `name: "SmartArt"` with no
3201
+ * {@link ShapeElement.id} (see smartart-fallback-contrast.ts). */
3202
+ name?: string;
3108
3203
  /** Shape-level hyperlink target resolved from `<p:cNvPr><a:hlinkClick @r:id>`
3109
3204
  * via slide _rels (ECMA-376 §21.1.2.3.5). For an external link this is the
3110
3205
  * URL; for an internal slide jump it is the resolved internal part name.
@@ -3281,7 +3376,10 @@ export declare interface TableRow {
3281
3376
  }
3282
3377
 
3283
3378
  export declare interface TabStop {
3284
- /** Position in EMU from the left edge of the text area (after lIns) */
3379
+ /** Position in EMU from the LEADING text-inset edge of the text area
3380
+ * logical, not physical (ECMA-376 §21.1.2.1): the left edge (after lIns)
3381
+ * in an LTR paragraph, the right edge (before rIns) in an RTL
3382
+ * (`<a:pPr rtl="1">`) paragraph. */
3285
3383
  pos: number;
3286
3384
  /** Alignment: "l" | "r" | "ctr" | "dec" */
3287
3385
  algn: string;
@@ -400,6 +400,14 @@ export declare interface ChartModel {
400
400
  title: string | null;
401
401
  categories: string[];
402
402
  series: ChartSeries[];
403
+ /**
404
+ * §21.2.2.227 `<c:varyColors val="1"/>` on a SINGLE-series bar/column chart:
405
+ * color each data point (bar) from the theme/palette sequence and list one
406
+ * legend entry per point, matching Office. Set by the shared parser ONLY for
407
+ * that non-pie, single-series case (pie/doughnut already vary by point via
408
+ * `chartType` + `dataPointColors`); absent/false otherwise.
409
+ */
410
+ varyColors?: boolean | null;
403
411
  /** Show data labels on bars / points / slices. */
404
412
  showDataLabels: boolean;
405
413
  /** Explicit Y-axis minimum (OOXML `<c:valAx><c:min>`). */
@@ -2829,7 +2837,13 @@ export declare class XlsxViewer implements ZoomableViewer {
2829
2837
  * match the renderer's `hyperlinkMap` exactly (`${hl.row}:${hl.col}`). */
2830
2838
  private buildHyperlinkMap;
2831
2839
  /** IX1 — the hyperlink at a cell, or null. `getCellAt` returns 1-based
2832
- * {row,col}, matching the parser/renderer keying. */
2840
+ * {row,col}, matching the parser/renderer keying.
2841
+ *
2842
+ * Returns null unconditionally when `enableHyperlinks` is `false`: this is the
2843
+ * single gate that disables hyperlink interactivity. Both consumers — the
2844
+ * pointermove pointer-cursor affordance and the click dispatch
2845
+ * ({@link dispatchHyperlink}) — funnel through this hit-test, so a null result
2846
+ * means no cursor change, no default navigation, and no `onHyperlinkClick`. */
2833
2847
  private hyperlinkAtCell;
2834
2848
  /**
2835
2849
  * IX1 — dispatch a click on a hyperlinked cell. Builds a
@@ -3016,6 +3030,13 @@ export declare interface XlsxViewerOptions extends LoadOptions_2 {
3016
3030
  * default handler's job, so a blocked scheme still reaches a custom callback).
3017
3031
  */
3018
3032
  onHyperlinkClick?: (target: HyperlinkTarget) => void;
3033
+ /** IX1 — master switch for hyperlink interactivity. Default `true`. When
3034
+ * `false`, the cell hit-test reports no hyperlink under any cell, so hyperlink
3035
+ * interactivity is disabled entirely: no pointer cursor over a link, no default
3036
+ * navigation (external new-tab / internal sheet jump), and `onHyperlinkClick`
3037
+ * is never called. Hyperlinked cells still render exactly as authored but are
3038
+ * inert. */
3039
+ enableHyperlinks?: boolean;
3019
3040
  /**
3020
3041
  * Color of the cell-selection highlight. A single CSS color drives both the
3021
3042
  * selection rectangle's border (drawn in this color) and its fill (the same
@@ -3161,6 +3182,14 @@ export declare class XlsxWorkbook {
3161
3182
  * validation-list expansion use). Returns `''` before the workbook is loaded.
3162
3183
  */
3163
3184
  cellText(ws: Worksheet, cell: Cell): string;
3185
+ /**
3186
+ * Render a sheet viewport into `target`. Note: `opts.fetchImage` is ignored
3187
+ * here — image bytes always come from this workbook's own archive through its
3188
+ * stable per-instance loader, whose closure identity keys the shared decoded
3189
+ * caches, the render-pass lease, and {@link destroy}'s cache drops. Callers
3190
+ * needing a custom byte source should use the standalone
3191
+ * `renderWorksheetViewport` orchestrator directly.
3192
+ */
3164
3193
  renderViewport(target: HTMLCanvasElement | OffscreenCanvas, sheetIndex: number, viewport: ViewportRange, opts?: RenderViewportOptions): Promise<void>;
3165
3194
  /**
3166
3195
  * Render a sheet viewport and return it as an ImageBitmap (both modes; in
@@ -0,0 +1,50 @@
1
+ import { Y as e, at as t, et as n, rt as r } from "./find-cursor-DTrEBxjE.js";
2
+ //#region packages/core/src/image/duotone-bitmap-by-path.ts
3
+ function i(e, t) {
4
+ return t ? `${e}|duo:${t.clr1}:${t.clr2}` : e;
5
+ }
6
+ var a = /* @__PURE__ */ new WeakMap();
7
+ function o(e) {
8
+ let t = a.get(e);
9
+ return t || (t = /* @__PURE__ */ new Map(), a.set(e, t)), t;
10
+ }
11
+ async function s(r, a, s, c, l = {}) {
12
+ let { offscreenFactory: u, ...d } = l, f = await t(r, a, c, d);
13
+ if (!s || !f) return f;
14
+ let p = o(c), m = i(r, s), h = p.get(m);
15
+ return h || (h = (async () => {
16
+ let { w: t, h: r } = n(f);
17
+ return t <= 0 || r <= 0 ? f : await e(f, s, {
18
+ width: t,
19
+ height: r,
20
+ offscreenFactory: u
21
+ });
22
+ })(), h.catch(() => p.delete(m)), h.then((e) => {
23
+ e === f && p.delete(m);
24
+ }).catch(() => {}), p.set(m, h)), h;
25
+ }
26
+ function c(e) {
27
+ let t = a.get(e);
28
+ if (t) {
29
+ for (let n of t.values()) r(e, n);
30
+ t.clear(), a.delete(e);
31
+ }
32
+ }
33
+ //#endregion
34
+ //#region packages/core/src/nav/visible-index.ts
35
+ function l(e, t, n, r) {
36
+ for (let i = e + t; i >= 0 && i < r; i += t) if (!n(i)) return i;
37
+ return e;
38
+ }
39
+ function u(e, t, n) {
40
+ if (n === 0 || !t(e)) return e;
41
+ let r = l(e, 1, t, n);
42
+ return r === e ? l(e, -1, t, n) : r;
43
+ }
44
+ function d(e, t) {
45
+ let n = 0;
46
+ for (let r = 0; r < t; r++) e(r) || n++;
47
+ return n;
48
+ }
49
+ //#endregion
50
+ export { s as a, c as i, l as n, u as r, d as t };