@silurus/ooxml 0.24.2 → 0.25.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 +35 -46
- 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-BMED2kI6.js → xlsx-C_hFLsOb.js} +487 -504
- package/dist/{xlsx-BCjsF2z0.cjs → xlsx-hfpAt0PA.cjs} +3 -3
- 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,13 +48,14 @@ 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
|
|
56
|
-
const
|
|
57
|
-
await pptx.load(
|
|
55
|
+
// PPTX — caller provides the <canvas>
|
|
56
|
+
const canvas = document.getElementById('pptx-canvas') as HTMLCanvasElement;
|
|
57
|
+
const pptx = new PptxViewer(canvas);
|
|
58
|
+
await pptx.load('/deck.pptx');
|
|
58
59
|
pptx.nextSlide();
|
|
59
60
|
```
|
|
60
61
|
|
|
@@ -138,30 +139,24 @@ import { useEffect, useRef, useState } from 'react';
|
|
|
138
139
|
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
139
140
|
|
|
140
141
|
export function PptxViewerComponent({ src }: { src: string }) {
|
|
141
|
-
const
|
|
142
|
-
const viewerRef
|
|
142
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
143
|
+
const viewerRef = useRef<PptxViewer | null>(null);
|
|
143
144
|
const [slide, setSlide] = useState({ current: 0, total: 0 });
|
|
144
145
|
|
|
145
146
|
useEffect(() => {
|
|
146
|
-
const
|
|
147
|
-
if (!
|
|
147
|
+
const canvas = canvasRef.current;
|
|
148
|
+
if (!canvas) return;
|
|
148
149
|
|
|
149
|
-
const viewer = new PptxViewer(
|
|
150
|
+
const viewer = new PptxViewer(canvas, {
|
|
150
151
|
onSlideChange: (i, total) => setSlide({ current: i, total }),
|
|
151
152
|
});
|
|
152
153
|
viewerRef.current = viewer;
|
|
153
|
-
|
|
154
|
-
let cancelled = false;
|
|
155
|
-
fetch(src)
|
|
156
|
-
.then(r => r.arrayBuffer())
|
|
157
|
-
.then(buf => { if (!cancelled) viewer.load(buf); });
|
|
158
|
-
|
|
159
|
-
return () => { cancelled = true; };
|
|
154
|
+
viewer.load(src);
|
|
160
155
|
}, [src]);
|
|
161
156
|
|
|
162
157
|
return (
|
|
163
158
|
<div>
|
|
164
|
-
<
|
|
159
|
+
<canvas ref={canvasRef} style={{ width: 800 }} />
|
|
165
160
|
<button onClick={() => viewerRef.current?.prevSlide()}>‹ Prev</button>
|
|
166
161
|
<span> {slide.current + 1} / {slide.total} </span>
|
|
167
162
|
<button onClick={() => viewerRef.current?.nextSlide()}>Next ›</button>
|
|
@@ -183,23 +178,22 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
183
178
|
|
|
184
179
|
const props = defineProps<{ src: string }>();
|
|
185
180
|
|
|
186
|
-
const
|
|
181
|
+
const canvas = useTemplateRef<HTMLCanvasElement>('canvas');
|
|
187
182
|
let viewer: PptxViewer | null = null;
|
|
188
183
|
const current = ref(0);
|
|
189
184
|
const total = ref(0);
|
|
190
185
|
|
|
191
186
|
onMounted(async () => {
|
|
192
|
-
viewer = new PptxViewer(
|
|
187
|
+
viewer = new PptxViewer(canvas.value!, {
|
|
193
188
|
onSlideChange: (i, t) => { current.value = i; total.value = t; },
|
|
194
189
|
});
|
|
195
|
-
|
|
196
|
-
await viewer.load(buf);
|
|
190
|
+
await viewer.load(props.src);
|
|
197
191
|
});
|
|
198
192
|
</script>
|
|
199
193
|
|
|
200
194
|
<template>
|
|
201
195
|
<div>
|
|
202
|
-
<
|
|
196
|
+
<canvas ref="canvas" style="width: 800px" />
|
|
203
197
|
<button @click="viewer?.prevSlide()">‹ Prev</button>
|
|
204
198
|
<span> {{ current + 1 }} / {{ total }} </span>
|
|
205
199
|
<button @click="viewer?.nextSlide()">Next ›</button>
|
|
@@ -225,7 +219,7 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
225
219
|
standalone: true,
|
|
226
220
|
template: `
|
|
227
221
|
<div>
|
|
228
|
-
<
|
|
222
|
+
<canvas #canvas style="width: 800px"></canvas>
|
|
229
223
|
<button (click)="prev()">‹ Prev</button>
|
|
230
224
|
<span> {{ current() + 1 }} / {{ total() }} </span>
|
|
231
225
|
<button (click)="next()">Next ›</button>
|
|
@@ -233,18 +227,16 @@ import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
|
233
227
|
`,
|
|
234
228
|
})
|
|
235
229
|
export class PptxViewerComponent implements AfterViewInit {
|
|
236
|
-
|
|
230
|
+
canvasEl = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');
|
|
237
231
|
current = signal(0);
|
|
238
232
|
total = signal(0);
|
|
239
233
|
private viewer?: PptxViewer;
|
|
240
234
|
|
|
241
235
|
ngAfterViewInit(): void {
|
|
242
|
-
this.viewer = new PptxViewer(this.
|
|
236
|
+
this.viewer = new PptxViewer(this.canvasEl().nativeElement, {
|
|
243
237
|
onSlideChange: (i, t) => { this.current.set(i); this.total.set(t); },
|
|
244
238
|
});
|
|
245
|
-
|
|
246
|
-
.then(r => r.arrayBuffer())
|
|
247
|
-
.then(buf => this.viewer!.load(buf));
|
|
239
|
+
this.viewer.load('/deck.pptx');
|
|
248
240
|
}
|
|
249
241
|
|
|
250
242
|
prev(): void { this.viewer?.prevSlide(); }
|
|
@@ -267,22 +259,21 @@ export class PptxViewerComponent implements AfterViewInit {
|
|
|
267
259
|
|
|
268
260
|
let { src }: { src: string } = $props();
|
|
269
261
|
|
|
270
|
-
let
|
|
262
|
+
let canvas: HTMLCanvasElement;
|
|
271
263
|
let viewer: PptxViewer;
|
|
272
264
|
let current = $state(0);
|
|
273
265
|
let total = $state(0);
|
|
274
266
|
|
|
275
267
|
onMount(async () => {
|
|
276
|
-
viewer = new PptxViewer(
|
|
268
|
+
viewer = new PptxViewer(canvas, {
|
|
277
269
|
onSlideChange: (i, t) => { current = i; total = t; },
|
|
278
270
|
});
|
|
279
|
-
|
|
280
|
-
await viewer.load(buf);
|
|
271
|
+
await viewer.load(src);
|
|
281
272
|
});
|
|
282
273
|
</script>
|
|
283
274
|
|
|
284
275
|
<div>
|
|
285
|
-
<
|
|
276
|
+
<canvas bind:this={canvas} style="width: 800px"></canvas>
|
|
286
277
|
<button onclick={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
287
278
|
<span> {current + 1} / {total} </span>
|
|
288
279
|
<button onclick={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -300,24 +291,23 @@ import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
|
300
291
|
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
301
292
|
|
|
302
293
|
export function PptxViewerComponent(props: { src: string }) {
|
|
303
|
-
let
|
|
294
|
+
let canvasEl!: HTMLCanvasElement;
|
|
304
295
|
let viewer: PptxViewer | undefined;
|
|
305
296
|
const [current, setCurrent] = createSignal(0);
|
|
306
297
|
const [total, setTotal ] = createSignal(0);
|
|
307
298
|
|
|
308
299
|
onMount(async () => {
|
|
309
|
-
viewer = new PptxViewer(
|
|
300
|
+
viewer = new PptxViewer(canvasEl, {
|
|
310
301
|
onSlideChange: (i, t) => { setCurrent(i); setTotal(t); },
|
|
311
302
|
});
|
|
312
|
-
|
|
313
|
-
await viewer.load(buf);
|
|
303
|
+
await viewer.load(props.src);
|
|
314
304
|
});
|
|
315
305
|
|
|
316
306
|
onCleanup(() => { /* viewer?.destroy?.() */ });
|
|
317
307
|
|
|
318
308
|
return (
|
|
319
309
|
<div>
|
|
320
|
-
<
|
|
310
|
+
<canvas ref={canvasEl} style={{ width: '800px' }} />
|
|
321
311
|
<button onClick={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
322
312
|
<span> {current() + 1} / {total()} </span>
|
|
323
313
|
<button onClick={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -337,25 +327,24 @@ import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik';
|
|
|
337
327
|
import type { PptxViewer as PptxViewerType } from '@silurus/ooxml/pptx';
|
|
338
328
|
|
|
339
329
|
export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
340
|
-
const
|
|
330
|
+
const canvasRef = useSignal<HTMLCanvasElement>();
|
|
341
331
|
const current = useSignal(0);
|
|
342
332
|
const total = useSignal(0);
|
|
343
333
|
let viewer: PptxViewerType | undefined;
|
|
344
334
|
|
|
345
335
|
// useVisibleTask$ runs only in the browser, never during SSR
|
|
346
336
|
useVisibleTask$(async () => {
|
|
347
|
-
if (!
|
|
337
|
+
if (!canvasRef.value) return;
|
|
348
338
|
const { PptxViewer } = await import('@silurus/ooxml/pptx');
|
|
349
|
-
viewer = new PptxViewer(
|
|
339
|
+
viewer = new PptxViewer(canvasRef.value, {
|
|
350
340
|
onSlideChange: (i, t) => { current.value = i; total.value = t; },
|
|
351
341
|
});
|
|
352
|
-
|
|
353
|
-
await viewer.load(buf);
|
|
342
|
+
await viewer.load(src);
|
|
354
343
|
});
|
|
355
344
|
|
|
356
345
|
return (
|
|
357
346
|
<div>
|
|
358
|
-
<
|
|
347
|
+
<canvas ref={canvasRef} style={{ width: '800px' }} />
|
|
359
348
|
<button onClick$={() => viewer?.prevSlide()}>‹ Prev</button>
|
|
360
349
|
<span> {current.value + 1} / {total.value} </span>
|
|
361
350
|
<button onClick$={() => viewer?.nextSlide()}>Next ›</button>
|
|
@@ -554,7 +543,7 @@ cd packages/pptx/parser && wasm-pack build --target web && cp pkg/pptx_parser_bg
|
|
|
554
543
|
|
|
555
544
|
- **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.
|
|
556
545
|
- **ZIP decompression cap.** Each entry in the source archive is limited to 512 MiB of uncompressed output to block zip-bomb DoS.
|
|
557
|
-
- **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,
|
|
546
|
+
- **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.
|
|
558
547
|
- **XML parsing.** Uses `roxmltree`, which does not resolve external entities (XXE-safe by default).
|
|
559
548
|
|
|
560
549
|
## 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 };
|