@silurus/ooxml 0.24.3 → 0.26.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.
- package/README.md +31 -27
- package/dist/autoResize-C6N7p_Or.cjs +1 -0
- package/dist/{autoResize-U2-IRmNE.js → autoResize-D-Yz7Izt.js} +25 -3
- package/dist/docx-DVe_bky9.cjs +1 -0
- package/dist/docx-x2SoqFCP.js +871 -0
- package/dist/docx.cjs +1 -1
- package/dist/docx.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +3 -3
- package/dist/pptx-DMP47DvZ.cjs +1 -0
- package/dist/{pptx-nyHInjlO.js → pptx-Dr6cMPL2.js} +227 -244
- package/dist/pptx.cjs +1 -1
- package/dist/pptx.mjs +2 -2
- package/dist/types/docx.d.ts +32 -2
- package/dist/types/index.d.ts +40 -28
- package/dist/types/pptx.d.ts +25 -11
- package/dist/types/xlsx.d.ts +20 -10
- package/dist/{xlsx-BCjsF2z0.cjs → xlsx-B6wdX3-M.cjs} +6 -6
- package/dist/{xlsx-BMED2kI6.js → xlsx-R5CcrPHg.js} +592 -580
- package/dist/xlsx.cjs +1 -1
- package/dist/xlsx.mjs +2 -2
- package/package.json +1 -1
- package/dist/autoResize-ggn4hzd8.cjs +0 -1
- package/dist/docx-C_zG3e0V.js +0 -853
- package/dist/docx-DKPVLT6O.cjs +0 -1
- package/dist/pptx-Ywwc_EMp.cjs +0 -1
package/README.md
CHANGED
|
@@ -48,11 +48,13 @@ await docx.load('/document.docx');
|
|
|
48
48
|
docx.nextPage();
|
|
49
49
|
|
|
50
50
|
// XLSX — viewer manages its own <canvas> + tab bar
|
|
51
|
-
const
|
|
51
|
+
const container = document.getElementById('xlsx-container') as HTMLElement;
|
|
52
|
+
const xlsx = new XlsxViewer(container);
|
|
52
53
|
await xlsx.load('/workbook.xlsx');
|
|
53
54
|
|
|
54
|
-
// PPTX —
|
|
55
|
-
const
|
|
55
|
+
// PPTX — caller provides the <canvas>
|
|
56
|
+
const canvas = document.getElementById('pptx-canvas') as HTMLCanvasElement;
|
|
57
|
+
const pptx = new PptxViewer(canvas);
|
|
56
58
|
await pptx.load('/deck.pptx');
|
|
57
59
|
pptx.nextSlide();
|
|
58
60
|
```
|
|
@@ -137,15 +139,15 @@ import { useEffect, useRef, useState } from 'react';
|
|
|
137
139
|
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
138
140
|
|
|
139
141
|
export function PptxViewerComponent({ src }: { src: string }) {
|
|
140
|
-
const
|
|
141
|
-
const viewerRef
|
|
142
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
143
|
+
const viewerRef = useRef<PptxViewer | null>(null);
|
|
142
144
|
const [slide, setSlide] = useState({ current: 0, total: 0 });
|
|
143
145
|
|
|
144
146
|
useEffect(() => {
|
|
145
|
-
const
|
|
146
|
-
if (!
|
|
147
|
+
const canvas = canvasRef.current;
|
|
148
|
+
if (!canvas) return;
|
|
147
149
|
|
|
148
|
-
const viewer = new PptxViewer(
|
|
150
|
+
const viewer = new PptxViewer(canvas, {
|
|
149
151
|
onSlideChange: (i, total) => setSlide({ current: i, total }),
|
|
150
152
|
});
|
|
151
153
|
viewerRef.current = viewer;
|
|
@@ -154,7 +156,7 @@ export function PptxViewerComponent({ src }: { src: string }) {
|
|
|
154
156
|
|
|
155
157
|
return (
|
|
156
158
|
<div>
|
|
157
|
-
<
|
|
159
|
+
<canvas ref={canvasRef} style={{ width: 800 }} />
|
|
158
160
|
<button onClick={() => viewerRef.current?.prevSlide()}>‹ Prev</button>
|
|
159
161
|
<span> {slide.current + 1} / {slide.total} </span>
|
|
160
162
|
<button onClick={() => viewerRef.current?.nextSlide()}>Next ›</button>
|
|
@@ -176,13 +178,13 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
176
178
|
|
|
177
179
|
const props = defineProps<{ src: string }>();
|
|
178
180
|
|
|
179
|
-
const
|
|
181
|
+
const canvas = useTemplateRef<HTMLCanvasElement>('canvas');
|
|
180
182
|
let viewer: PptxViewer | null = null;
|
|
181
183
|
const current = ref(0);
|
|
182
184
|
const total = ref(0);
|
|
183
185
|
|
|
184
186
|
onMounted(async () => {
|
|
185
|
-
viewer = new PptxViewer(
|
|
187
|
+
viewer = new PptxViewer(canvas.value!, {
|
|
186
188
|
onSlideChange: (i, t) => { current.value = i; total.value = t; },
|
|
187
189
|
});
|
|
188
190
|
await viewer.load(props.src);
|
|
@@ -191,7 +193,7 @@ onMounted(async () => {
|
|
|
191
193
|
|
|
192
194
|
<template>
|
|
193
195
|
<div>
|
|
194
|
-
<
|
|
196
|
+
<canvas ref="canvas" style="width: 800px" />
|
|
195
197
|
<button @click="viewer?.prevSlide()">‹ Prev</button>
|
|
196
198
|
<span> {{ current + 1 }} / {{ total }} </span>
|
|
197
199
|
<button @click="viewer?.nextSlide()">Next ›</button>
|
|
@@ -217,7 +219,7 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
217
219
|
standalone: true,
|
|
218
220
|
template: `
|
|
219
221
|
<div>
|
|
220
|
-
<
|
|
222
|
+
<canvas #canvas style="width: 800px"></canvas>
|
|
221
223
|
<button (click)="prev()">‹ Prev</button>
|
|
222
224
|
<span> {{ current() + 1 }} / {{ total() }} </span>
|
|
223
225
|
<button (click)="next()">Next ›</button>
|
|
@@ -225,13 +227,13 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
225
227
|
`,
|
|
226
228
|
})
|
|
227
229
|
export class PptxViewerComponent implements AfterViewInit {
|
|
228
|
-
|
|
230
|
+
canvasEl = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');
|
|
229
231
|
current = signal(0);
|
|
230
232
|
total = signal(0);
|
|
231
233
|
private viewer?: PptxViewer;
|
|
232
234
|
|
|
233
235
|
ngAfterViewInit(): void {
|
|
234
|
-
this.viewer = new PptxViewer(this.
|
|
236
|
+
this.viewer = new PptxViewer(this.canvasEl().nativeElement, {
|
|
235
237
|
onSlideChange: (i, t) => { this.current.set(i); this.total.set(t); },
|
|
236
238
|
});
|
|
237
239
|
this.viewer.load('/deck.pptx');
|
|
@@ -257,13 +259,13 @@ export class PptxViewerComponent implements AfterViewInit {
|
|
|
257
259
|
|
|
258
260
|
let { src }: { src: string } = $props();
|
|
259
261
|
|
|
260
|
-
let
|
|
262
|
+
let canvas: HTMLCanvasElement;
|
|
261
263
|
let viewer: PptxViewer;
|
|
262
264
|
let current = $state(0);
|
|
263
265
|
let total = $state(0);
|
|
264
266
|
|
|
265
267
|
onMount(async () => {
|
|
266
|
-
viewer = new PptxViewer(
|
|
268
|
+
viewer = new PptxViewer(canvas, {
|
|
267
269
|
onSlideChange: (i, t) => { current = i; total = t; },
|
|
268
270
|
});
|
|
269
271
|
await viewer.load(src);
|
|
@@ -271,7 +273,7 @@ export class PptxViewerComponent implements AfterViewInit {
|
|
|
271
273
|
</script>
|
|
272
274
|
|
|
273
275
|
<div>
|
|
274
|
-
<
|
|
276
|
+
<canvas bind:this={canvas} style="width: 800px"></canvas>
|
|
275
277
|
<button onclick={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
276
278
|
<span> {current + 1} / {total} </span>
|
|
277
279
|
<button onclick={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -289,13 +291,13 @@ import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
|
289
291
|
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
290
292
|
|
|
291
293
|
export function PptxViewerComponent(props: { src: string }) {
|
|
292
|
-
let
|
|
294
|
+
let canvasEl!: HTMLCanvasElement;
|
|
293
295
|
let viewer: PptxViewer | undefined;
|
|
294
296
|
const [current, setCurrent] = createSignal(0);
|
|
295
297
|
const [total, setTotal ] = createSignal(0);
|
|
296
298
|
|
|
297
299
|
onMount(async () => {
|
|
298
|
-
viewer = new PptxViewer(
|
|
300
|
+
viewer = new PptxViewer(canvasEl, {
|
|
299
301
|
onSlideChange: (i, t) => { setCurrent(i); setTotal(t); },
|
|
300
302
|
});
|
|
301
303
|
await viewer.load(props.src);
|
|
@@ -305,7 +307,7 @@ export function PptxViewerComponent(props: { src: string }) {
|
|
|
305
307
|
|
|
306
308
|
return (
|
|
307
309
|
<div>
|
|
308
|
-
<
|
|
310
|
+
<canvas ref={canvasEl} style={{ width: '800px' }} />
|
|
309
311
|
<button onClick={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
310
312
|
<span> {current() + 1} / {total()} </span>
|
|
311
313
|
<button onClick={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -325,16 +327,16 @@ import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik';
|
|
|
325
327
|
import type { PptxViewer as PptxViewerType } from '@silurus/ooxml/pptx';
|
|
326
328
|
|
|
327
329
|
export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
328
|
-
const
|
|
330
|
+
const canvasRef = useSignal<HTMLCanvasElement>();
|
|
329
331
|
const current = useSignal(0);
|
|
330
332
|
const total = useSignal(0);
|
|
331
333
|
let viewer: PptxViewerType | undefined;
|
|
332
334
|
|
|
333
335
|
// useVisibleTask$ runs only in the browser, never during SSR
|
|
334
336
|
useVisibleTask$(async () => {
|
|
335
|
-
if (!
|
|
337
|
+
if (!canvasRef.value) return;
|
|
336
338
|
const { PptxViewer } = await import('@silurus/ooxml/pptx');
|
|
337
|
-
viewer = new PptxViewer(
|
|
339
|
+
viewer = new PptxViewer(canvasRef.value, {
|
|
338
340
|
onSlideChange: (i, t) => { current.value = i; total.value = t; },
|
|
339
341
|
});
|
|
340
342
|
await viewer.load(src);
|
|
@@ -342,7 +344,7 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
342
344
|
|
|
343
345
|
return (
|
|
344
346
|
<div>
|
|
345
|
-
<
|
|
347
|
+
<canvas ref={canvasRef} style={{ width: '800px' }} />
|
|
346
348
|
<button onClick$={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
347
349
|
<span> {current.value + 1} / {total.value} </span>
|
|
348
350
|
<button onClick$={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -522,8 +524,10 @@ pnpm storybook
|
|
|
522
524
|
# Type-check all packages
|
|
523
525
|
pnpm typecheck
|
|
524
526
|
|
|
525
|
-
# Run visual regression tests
|
|
527
|
+
# Run visual regression tests (local only — not run in CI)
|
|
526
528
|
pnpm vrt
|
|
529
|
+
# Adopt the current rendering as the new reference baseline
|
|
530
|
+
UPDATE_REFS=1 pnpm vrt
|
|
527
531
|
|
|
528
532
|
# Build the library
|
|
529
533
|
pnpm build
|
|
@@ -541,7 +545,7 @@ cd packages/pptx/parser && wasm-pack build --target web && cp pkg/pptx_parser_bg
|
|
|
541
545
|
|
|
542
546
|
- **Canvas-only rendering.** Documents are decoded and drawn to an `HTMLCanvasElement`. No script, link, form, or other active content from the source file is executed or injected into the DOM.
|
|
543
547
|
- **ZIP decompression cap.** Each entry in the source archive is limited to 512 MiB of uncompressed output to block zip-bomb DoS.
|
|
544
|
-
- **No network by default.** The library does not send telemetry or analytics, and does not contact third-party services unless you ask it to. In particular,
|
|
548
|
+
- **No network by default.** The library does not send telemetry or analytics, and does not contact third-party services unless you ask it to. In particular, theme webfonts (and Office font metric substitutes for XLSX) are **not** loaded from Google Fonts unless you pass `useGoogleFonts: true` to the relevant `Viewer` / `load(...)` options — supported uniformly by `DocxViewer`, `PptxViewer`, and `XlsxViewer`. Enabling that option causes the end-user's browser to send an HTTP request (IP and User-Agent) to `fonts.googleapis.com`, which may have GDPR implications for your application — consider self-hosting the required fonts via `@font-face` instead.
|
|
545
549
|
- **XML parsing.** Uses `roxmltree`, which does not resolve external entities (XXE-safe by default).
|
|
546
550
|
|
|
547
551
|
## License
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r},n=3e3,r=20,i=25;async function a(e,t){if(typeof document>`u`)return;let a=new Set,o=new Set;for(let n of e){if(!n)continue;let e=n.toLowerCase();if(a.has(e))continue;a.add(e);let r=t[e];if(r){if(!document.querySelector(`link[href="${r.url}"]`))try{let e=document.createElement(`link`);e.rel=`stylesheet`,e.href=r.url,document.head.appendChild(e)}catch{}o.add((r.loadFamily??n).toLowerCase())}}if(o.size===0)return;let s=[];for(let e=0;e<i&&(s=[...document.fonts].filter(e=>o.has(e.family.toLowerCase())),!(s.length>0));e++)await new Promise(e=>setTimeout(e,r));await Promise.race([Promise.allSettled(s.map(e=>e.load())).then(()=>document.fonts.ready),new Promise(e=>setTimeout(e,n))])}function o(e,t,n={}){let r=n.pauseWhenHidden??!0,i=null,a=0,o=0,s=null,c=!1,l=!1,u=()=>{if(!l&&!(r&&typeof document<`u`&&document.hidden)){if(s){c=!0;return}i===null&&(i=requestAnimationFrame(d))}},d=async()=>{if(i=null,l)return;let t=a,n=o;try{let r=e(t,n);s=r instanceof Promise?r:Promise.resolve(),await s}catch(e){console.error(`[autoResize] render failed:`,e)}finally{s=null,c&&!l&&(c=!1,u())}},f=new ResizeObserver(e=>{for(let t of e){let e=t.contentRect;a=e.width,o=e.height}u()});f.observe(t);let p=()=>{typeof document<`u`&&!document.hidden&&u()};return r&&typeof document<`u`&&document.addEventListener(`visibilitychange`,p),()=>{l=!0,f.disconnect(),i!==null&&(cancelAnimationFrame(i),i=null),r&&typeof document<`u`&&document.removeEventListener(`visibilitychange`,p)}}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return o}});
|
|
@@ -6,10 +6,32 @@ var e = Object.defineProperty, t = (t, n) => {
|
|
|
6
6
|
enumerable: !0
|
|
7
7
|
});
|
|
8
8
|
return n || e(r, Symbol.toStringTag, { value: "Module" }), r;
|
|
9
|
-
};
|
|
9
|
+
}, n = 3e3, r = 20, i = 25;
|
|
10
|
+
async function a(e, t) {
|
|
11
|
+
if (typeof document > "u") return;
|
|
12
|
+
let a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set();
|
|
13
|
+
for (let n of e) {
|
|
14
|
+
if (!n) continue;
|
|
15
|
+
let e = n.toLowerCase();
|
|
16
|
+
if (a.has(e)) continue;
|
|
17
|
+
a.add(e);
|
|
18
|
+
let r = t[e];
|
|
19
|
+
if (r) {
|
|
20
|
+
if (!document.querySelector(`link[href="${r.url}"]`)) try {
|
|
21
|
+
let e = document.createElement("link");
|
|
22
|
+
e.rel = "stylesheet", e.href = r.url, document.head.appendChild(e);
|
|
23
|
+
} catch {}
|
|
24
|
+
o.add((r.loadFamily ?? n).toLowerCase());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (o.size === 0) return;
|
|
28
|
+
let s = [];
|
|
29
|
+
for (let e = 0; e < i && (s = [...document.fonts].filter((e) => o.has(e.family.toLowerCase())), !(s.length > 0)); e++) await new Promise((e) => setTimeout(e, r));
|
|
30
|
+
await Promise.race([Promise.allSettled(s.map((e) => e.load())).then(() => document.fonts.ready), new Promise((e) => setTimeout(e, n))]);
|
|
31
|
+
}
|
|
10
32
|
//#endregion
|
|
11
33
|
//#region packages/core/src/autoResize.ts
|
|
12
|
-
function
|
|
34
|
+
function o(e, t, n = {}) {
|
|
13
35
|
let r = n.pauseWhenHidden ?? !0, i = null, a = 0, o = 0, s = null, c = !1, l = !1, u = () => {
|
|
14
36
|
if (!l && !(r && typeof document < "u" && document.hidden)) {
|
|
15
37
|
if (s) {
|
|
@@ -45,4 +67,4 @@ function n(e, t, n = {}) {
|
|
|
45
67
|
};
|
|
46
68
|
}
|
|
47
69
|
//#endregion
|
|
48
|
-
export {
|
|
70
|
+
export { a as n, t as r, o as t };
|