@l1yp/file-viewer 0.1.0 → 0.1.1
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 +1 -0
- package/dist/components/DocxNavigationPane.js +7 -0
- package/dist/components/DocxNavigationPane.vue.d.ts +23 -0
- package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js +96 -0
- package/dist/components/DocxViewer.js +1 -1
- package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +70 -37
- package/dist/components/FileViewerBody.js +1 -1
- package/dist/components/FileViewerBody.vue.d.ts +5 -0
- package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +248 -247
- package/dist/components/PptxNavigationPane.js +7 -0
- package/dist/components/PptxNavigationPane.vue.d.ts +20 -0
- package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js +118 -0
- package/dist/components/PptxViewer.js +1 -1
- package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js +64 -38
- package/dist/components/XlsxViewer.js +1 -1
- package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +299 -304
- package/dist/components/ZipBrowser.js +1 -1
- package/dist/components/ZipBrowser.vue.d.ts +3 -1
- package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js +152 -122
- package/dist/composables/useElementNavigation.d.ts +21 -0
- package/dist/composables/useElementNavigation.js +61 -0
- package/dist/lib/archiveHtml.d.ts +49 -0
- package/dist/lib/archiveHtml.js +375 -0
- package/dist/lib/docxNavigation.d.ts +31 -0
- package/dist/lib/docxNavigation.js +63 -0
- package/dist/lib/pptxNavigation.d.ts +7 -0
- package/dist/lib/pptxNavigation.js +27 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { fileExt as e } from "./fileType.js";
|
|
2
|
+
import { decodeTextSniff as t } from "./encoding.js";
|
|
3
|
+
import { bytesToBinary as n } from "./mime.js";
|
|
4
|
+
//#region src/lib/archiveHtml.ts
|
|
5
|
+
var r = 512, i = 64 * 1024 * 1024, a = 32 * 1024 * 1024, o = {
|
|
6
|
+
css: "text/css",
|
|
7
|
+
js: "text/javascript",
|
|
8
|
+
mjs: "text/javascript",
|
|
9
|
+
cjs: "text/javascript",
|
|
10
|
+
json: "application/json",
|
|
11
|
+
map: "application/json",
|
|
12
|
+
wasm: "application/wasm",
|
|
13
|
+
html: "text/html",
|
|
14
|
+
htm: "text/html",
|
|
15
|
+
xhtml: "application/xhtml+xml",
|
|
16
|
+
xml: "application/xml",
|
|
17
|
+
svg: "image/svg+xml",
|
|
18
|
+
png: "image/png",
|
|
19
|
+
jpg: "image/jpeg",
|
|
20
|
+
jpeg: "image/jpeg",
|
|
21
|
+
gif: "image/gif",
|
|
22
|
+
webp: "image/webp",
|
|
23
|
+
bmp: "image/bmp",
|
|
24
|
+
ico: "image/x-icon",
|
|
25
|
+
avif: "image/avif",
|
|
26
|
+
mp3: "audio/mpeg",
|
|
27
|
+
wav: "audio/wav",
|
|
28
|
+
ogg: "audio/ogg",
|
|
29
|
+
opus: "audio/opus",
|
|
30
|
+
flac: "audio/flac",
|
|
31
|
+
mp4: "video/mp4",
|
|
32
|
+
webm: "video/webm",
|
|
33
|
+
mov: "video/quicktime",
|
|
34
|
+
woff: "font/woff",
|
|
35
|
+
woff2: "font/woff2",
|
|
36
|
+
ttf: "font/ttf",
|
|
37
|
+
otf: "font/otf",
|
|
38
|
+
eot: "application/vnd.ms-fontobject",
|
|
39
|
+
txt: "text/plain"
|
|
40
|
+
};
|
|
41
|
+
function s(t) {
|
|
42
|
+
return o[e(t)] ?? "application/octet-stream";
|
|
43
|
+
}
|
|
44
|
+
function c(e, t) {
|
|
45
|
+
return `data:${t};base64,${btoa(n(e))}`;
|
|
46
|
+
}
|
|
47
|
+
function l(e) {
|
|
48
|
+
let t = e.search(/[?#]/);
|
|
49
|
+
return t < 0 ? e : e.slice(0, t);
|
|
50
|
+
}
|
|
51
|
+
function u(e) {
|
|
52
|
+
try {
|
|
53
|
+
return decodeURIComponent(e);
|
|
54
|
+
} catch {
|
|
55
|
+
return e;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function d(e) {
|
|
59
|
+
let t = [];
|
|
60
|
+
for (let n of u(e).replace(/\\/g, "/").split("/")) if (!(!n || n === ".")) {
|
|
61
|
+
if (n === "..") {
|
|
62
|
+
if (!t.length) return null;
|
|
63
|
+
t.pop();
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
t.push(n);
|
|
67
|
+
}
|
|
68
|
+
return t.join("/");
|
|
69
|
+
}
|
|
70
|
+
function f(e) {
|
|
71
|
+
let t = e.lastIndexOf("/");
|
|
72
|
+
return t < 0 ? "" : e.slice(0, t);
|
|
73
|
+
}
|
|
74
|
+
function p(e) {
|
|
75
|
+
let t = e.trim();
|
|
76
|
+
return !t || t.startsWith("#") || t.startsWith("?") || t.startsWith("//") || /^[a-z][a-z\d+.-]*:/i.test(t);
|
|
77
|
+
}
|
|
78
|
+
function m(e, t) {
|
|
79
|
+
if (p(e)) return [];
|
|
80
|
+
let n = l(e.trim());
|
|
81
|
+
if (!n) return [];
|
|
82
|
+
let r = d(t) ?? "", i = f(r), a = n.replace(/\\/g, "/"), o = [];
|
|
83
|
+
if (a.startsWith("/")) {
|
|
84
|
+
let e = d(a.slice(1));
|
|
85
|
+
e && o.push(e);
|
|
86
|
+
let t = r.split("/")[0];
|
|
87
|
+
if (t && r.includes("/") && e) {
|
|
88
|
+
let n = d(`${t}/${e}`);
|
|
89
|
+
n && o.push(n);
|
|
90
|
+
}
|
|
91
|
+
if (i && e) {
|
|
92
|
+
let t = d(`${i}/${e}`);
|
|
93
|
+
t && o.push(t);
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
let e = d(i ? `${i}/${a}` : a);
|
|
97
|
+
e && o.push(e);
|
|
98
|
+
}
|
|
99
|
+
return o;
|
|
100
|
+
}
|
|
101
|
+
function h(e) {
|
|
102
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
103
|
+
for (let r of e) {
|
|
104
|
+
if (r.isDir) continue;
|
|
105
|
+
let e = d(r.path);
|
|
106
|
+
if (!e) continue;
|
|
107
|
+
t.set(e, r);
|
|
108
|
+
let i = e.toLocaleLowerCase();
|
|
109
|
+
n.has(i) ? n.set(i, null) : n.set(i, r);
|
|
110
|
+
}
|
|
111
|
+
let r = (e) => t.get(e) || (n.get(e.toLocaleLowerCase()) ?? void 0);
|
|
112
|
+
return (e, t) => {
|
|
113
|
+
for (let n of m(e, t)) {
|
|
114
|
+
let e = r(n);
|
|
115
|
+
if (e) return e;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async function g(e, t, n) {
|
|
120
|
+
let r = t.flags.includes("g") ? t.flags : t.flags + "g", i = new RegExp(t.source, r), a = "", o = 0, s;
|
|
121
|
+
for (; (s = i.exec(e)) !== null;) a += e.slice(o, s.index), a += await n(s), o = s.index + s[0].length, s[0].length === 0 && i.lastIndex++;
|
|
122
|
+
return a + e.slice(o);
|
|
123
|
+
}
|
|
124
|
+
async function _(e, t) {
|
|
125
|
+
let n = await g(e, /@import\s+(?:url\(\s*)?(['"]?)([^'"\s)]+)\1\s*\)?/gi, async (e) => {
|
|
126
|
+
let n = await t(e[2], "css");
|
|
127
|
+
return n ? `@import url("${n}")` : e[0];
|
|
128
|
+
});
|
|
129
|
+
return n = await g(n, /url\(\s*(['"]?)([^'")]+)\1\s*\)/gi, async (e) => {
|
|
130
|
+
let n = await t(e[2].trim(), "raw");
|
|
131
|
+
return n ? `url("${n}")` : e[0];
|
|
132
|
+
}), n;
|
|
133
|
+
}
|
|
134
|
+
async function v(e, t) {
|
|
135
|
+
let n = await g(e, /\b((?:import|export)[^'";]*?\bfrom\s*)(['"])([^'"]+)\2/g, async (e) => {
|
|
136
|
+
let n = await t(e[3], "module");
|
|
137
|
+
return n ? `${e[1]}${e[2]}${n}${e[2]}` : e[0];
|
|
138
|
+
});
|
|
139
|
+
return n = await g(n, /\b(import\s*)(['"])([^'"]+)\2/g, async (e) => {
|
|
140
|
+
let n = await t(e[3], "module");
|
|
141
|
+
return n ? `${e[1]}${e[2]}${n}${e[2]}` : e[0];
|
|
142
|
+
}), n = await g(n, /\b(import\s*\(\s*)(['"])([^'"]+)\2(\s*\))/g, async (e) => {
|
|
143
|
+
let n = await t(e[3], "module");
|
|
144
|
+
return n ? `${e[1]}${e[2]}${n}${e[2]}${e[4]}` : e[0];
|
|
145
|
+
}), n = await g(n, /\bnew\s+URL\(\s*(['"])([^'"]+)\1\s*,\s*import\.meta\.url\s*\)/g, async (e) => {
|
|
146
|
+
let n = await t(e[2], "raw");
|
|
147
|
+
return n ? `new URL(${JSON.stringify(n)})` : e[0];
|
|
148
|
+
}), n;
|
|
149
|
+
}
|
|
150
|
+
function y(e) {
|
|
151
|
+
let t = {}, n = {};
|
|
152
|
+
for (let r of e) try {
|
|
153
|
+
let e = JSON.parse(r);
|
|
154
|
+
if (!e || typeof e != "object" || Array.isArray(e)) continue;
|
|
155
|
+
let i = e;
|
|
156
|
+
if (i.imports && typeof i.imports == "object" && !Array.isArray(i.imports)) for (let [e, n] of Object.entries(i.imports)) !(e in t) && (typeof n == "string" || n === null) && (t[e] = n);
|
|
157
|
+
if (i.scopes && typeof i.scopes == "object" && !Array.isArray(i.scopes)) for (let [e, t] of Object.entries(i.scopes)) {
|
|
158
|
+
if (!t || typeof t != "object" || Array.isArray(t)) continue;
|
|
159
|
+
let r = n[e] ??= {};
|
|
160
|
+
for (let [e, n] of Object.entries(t)) !(e in r) && (typeof n == "string" || n === null) && (r[e] = n);
|
|
161
|
+
}
|
|
162
|
+
} catch {}
|
|
163
|
+
return {
|
|
164
|
+
imports: t,
|
|
165
|
+
scopes: n
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function b(e, t) {
|
|
169
|
+
if (Object.prototype.hasOwnProperty.call(e, t)) return e[t];
|
|
170
|
+
let n = "";
|
|
171
|
+
for (let r of Object.keys(e)) r.endsWith("/") && t.startsWith(r) && r.length > n.length && (n = r);
|
|
172
|
+
if (!n) return;
|
|
173
|
+
let r = e[n];
|
|
174
|
+
return r === null || !r.endsWith("/") ? null : r + t.slice(n.length);
|
|
175
|
+
}
|
|
176
|
+
function x(e, t) {
|
|
177
|
+
let n = y(e);
|
|
178
|
+
return (e, r) => {
|
|
179
|
+
let i;
|
|
180
|
+
for (let [e, a] of Object.entries(n.scopes)) for (let n of m(e, t)) {
|
|
181
|
+
let e = n.replace(/\/$/, "");
|
|
182
|
+
(r === e || r.startsWith(`${e}/`)) && (!i || e.length > i.prefix.length) && (i = {
|
|
183
|
+
prefix: e,
|
|
184
|
+
entries: a
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
let a = i ? b(i.entries, e) : void 0;
|
|
188
|
+
return a === void 0 ? b(n.imports, e) : a;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function S(t, n) {
|
|
192
|
+
if (n !== "module") return n;
|
|
193
|
+
let r = e(t.name);
|
|
194
|
+
return r === "css" ? "css" : r === "html" || r === "htm" || r === "xhtml" ? "html" : r === "js" || r === "mjs" || r === "cjs" ? "module" : "raw";
|
|
195
|
+
}
|
|
196
|
+
async function C(e) {
|
|
197
|
+
let n = h(e.entries), o = e.maxResources ?? r, l = e.maxTotalBytes ?? i, u = e.maxEntryBytes ?? a, d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set(), g = 0, y = 0, b = 0, C = 0, w = (t) => {
|
|
198
|
+
let n = d.get(t);
|
|
199
|
+
if (n) return n;
|
|
200
|
+
let r = (async () => {
|
|
201
|
+
if (d.size >= o || t.size > u || y + t.size > l) return C++, null;
|
|
202
|
+
y += t.size;
|
|
203
|
+
try {
|
|
204
|
+
let n = await e.loadEntry(t);
|
|
205
|
+
return n.byteLength > u || y - t.size + n.byteLength > l ? (C++, null) : (y += n.byteLength - t.size, b++, n);
|
|
206
|
+
} catch {
|
|
207
|
+
return C++, null;
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
210
|
+
return d.set(t, r), r;
|
|
211
|
+
}, T = async (e, r, i) => {
|
|
212
|
+
let a = S(e, r), o = `${e.path}\u0000${a}\u0000${a === "module" ? i?.id ?? "" : ""}`;
|
|
213
|
+
if (m.has(o)) return null;
|
|
214
|
+
let l = f.get(o);
|
|
215
|
+
if (l) return l;
|
|
216
|
+
m.add(o);
|
|
217
|
+
let u = (async () => {
|
|
218
|
+
let r = await w(e);
|
|
219
|
+
if (!r) return null;
|
|
220
|
+
if (a === "css") {
|
|
221
|
+
let a = await _(t(r), async (t, r) => {
|
|
222
|
+
let a = n(t, e.path);
|
|
223
|
+
return a ? T(a, r, i) : null;
|
|
224
|
+
});
|
|
225
|
+
return c(new TextEncoder().encode(a), "text/css");
|
|
226
|
+
}
|
|
227
|
+
if (a === "module") {
|
|
228
|
+
let n = await v(t(r), async (t, n) => E(t, e.path, n, i));
|
|
229
|
+
return c(new TextEncoder().encode(n), "text/javascript");
|
|
230
|
+
}
|
|
231
|
+
if (a === "html") {
|
|
232
|
+
let n = await O(t(r), e.path);
|
|
233
|
+
return c(new TextEncoder().encode(n), "text/html");
|
|
234
|
+
}
|
|
235
|
+
return c(r, s(e.name));
|
|
236
|
+
})().finally(() => m.delete(o));
|
|
237
|
+
return f.set(o, u), u;
|
|
238
|
+
}, E = async (e, t, r, i) => {
|
|
239
|
+
let a = e, o = t;
|
|
240
|
+
if (r === "module" && i) {
|
|
241
|
+
let n = i.resolve(e, t);
|
|
242
|
+
if (n === null) return null;
|
|
243
|
+
if (n !== void 0 && (a = n, o = i.documentPath, p(a))) return a;
|
|
244
|
+
}
|
|
245
|
+
let s = n(a, o);
|
|
246
|
+
if (!s) return null;
|
|
247
|
+
let c = await T(s, r, i);
|
|
248
|
+
if (!c) return null;
|
|
249
|
+
let l = a.indexOf("#");
|
|
250
|
+
return l < 0 ? c : c + a.slice(l);
|
|
251
|
+
}, D = async (e, t) => {
|
|
252
|
+
let n = e.split(","), r = [];
|
|
253
|
+
for (let e of n) {
|
|
254
|
+
let n = e.trim();
|
|
255
|
+
if (!n) continue;
|
|
256
|
+
let i = n.split(/\s+/), a = await E(i[0], t, "raw");
|
|
257
|
+
a && (i[0] = a), r.push(i.join(" "));
|
|
258
|
+
}
|
|
259
|
+
return r.join(", ");
|
|
260
|
+
}, O = async (e, t) => {
|
|
261
|
+
let n = new DOMParser().parseFromString(e, "text/html"), r = Array.from(n.querySelectorAll("script[type=\"importmap\"]:not([src])")), i = {
|
|
262
|
+
id: ++g,
|
|
263
|
+
documentPath: t,
|
|
264
|
+
resolve: x(r.map((e) => e.textContent ?? ""), t)
|
|
265
|
+
};
|
|
266
|
+
n.querySelectorAll("base").forEach((e) => e.remove()), n.querySelectorAll("meta[http-equiv]").forEach((e) => {
|
|
267
|
+
let t = (e.getAttribute("http-equiv") ?? "").toLocaleLowerCase();
|
|
268
|
+
(t === "content-security-policy" || t === "refresh") && e.remove();
|
|
269
|
+
});
|
|
270
|
+
for (let e of Array.from(n.querySelectorAll("link[href]"))) {
|
|
271
|
+
let n = e.getAttribute("href");
|
|
272
|
+
if (!n) continue;
|
|
273
|
+
let r = (e.getAttribute("rel") ?? "").toLocaleLowerCase().split(/\s+/), a = r.includes("stylesheet") ? "css" : r.includes("modulepreload") ? "module" : "raw", o = await E(n, t, a, i);
|
|
274
|
+
o && (e.setAttribute("href", o), (a === "css" || a === "module") && e.removeAttribute("integrity"));
|
|
275
|
+
}
|
|
276
|
+
for (let e of Array.from(n.querySelectorAll("script[src]"))) {
|
|
277
|
+
let n = e.getAttribute("src");
|
|
278
|
+
if (!n) continue;
|
|
279
|
+
let r = (e.getAttribute("type") ?? "").toLocaleLowerCase() === "module" ? "module" : "raw", a = await E(n, t, r, i);
|
|
280
|
+
a && (e.setAttribute("src", a), r === "module" && e.removeAttribute("integrity"));
|
|
281
|
+
}
|
|
282
|
+
for (let e of Array.from(n.querySelectorAll("script[type=\"module\"]:not([src])"))) e.textContent = await v(e.textContent ?? "", async (e, n) => E(e, t, n, i));
|
|
283
|
+
r.forEach((e) => e.remove());
|
|
284
|
+
for (let [e, r, i] of [
|
|
285
|
+
[
|
|
286
|
+
"img[src]",
|
|
287
|
+
"src",
|
|
288
|
+
"raw"
|
|
289
|
+
],
|
|
290
|
+
[
|
|
291
|
+
"input[type=\"image\"][src]",
|
|
292
|
+
"src",
|
|
293
|
+
"raw"
|
|
294
|
+
],
|
|
295
|
+
[
|
|
296
|
+
"source[src]",
|
|
297
|
+
"src",
|
|
298
|
+
"raw"
|
|
299
|
+
],
|
|
300
|
+
[
|
|
301
|
+
"video[src]",
|
|
302
|
+
"src",
|
|
303
|
+
"raw"
|
|
304
|
+
],
|
|
305
|
+
[
|
|
306
|
+
"video[poster]",
|
|
307
|
+
"poster",
|
|
308
|
+
"raw"
|
|
309
|
+
],
|
|
310
|
+
[
|
|
311
|
+
"audio[src]",
|
|
312
|
+
"src",
|
|
313
|
+
"raw"
|
|
314
|
+
],
|
|
315
|
+
[
|
|
316
|
+
"track[src]",
|
|
317
|
+
"src",
|
|
318
|
+
"raw"
|
|
319
|
+
],
|
|
320
|
+
[
|
|
321
|
+
"embed[src]",
|
|
322
|
+
"src",
|
|
323
|
+
"raw"
|
|
324
|
+
],
|
|
325
|
+
[
|
|
326
|
+
"object[data]",
|
|
327
|
+
"data",
|
|
328
|
+
"raw"
|
|
329
|
+
],
|
|
330
|
+
[
|
|
331
|
+
"iframe[src]",
|
|
332
|
+
"src",
|
|
333
|
+
"html"
|
|
334
|
+
],
|
|
335
|
+
[
|
|
336
|
+
"image[href]",
|
|
337
|
+
"href",
|
|
338
|
+
"raw"
|
|
339
|
+
],
|
|
340
|
+
[
|
|
341
|
+
"use[href]",
|
|
342
|
+
"href",
|
|
343
|
+
"raw"
|
|
344
|
+
]
|
|
345
|
+
]) for (let a of Array.from(n.querySelectorAll(e))) {
|
|
346
|
+
let e = a.getAttribute(r);
|
|
347
|
+
if (!e) continue;
|
|
348
|
+
let n = await E(e, t, i);
|
|
349
|
+
n && a.setAttribute(r, n);
|
|
350
|
+
}
|
|
351
|
+
for (let e of Array.from(n.querySelectorAll("image, use"))) {
|
|
352
|
+
let n = e.getAttribute("xlink:href");
|
|
353
|
+
if (!n) continue;
|
|
354
|
+
let r = await E(n, t, "raw");
|
|
355
|
+
r && e.setAttribute("xlink:href", r);
|
|
356
|
+
}
|
|
357
|
+
for (let e of Array.from(n.querySelectorAll("img[srcset], source[srcset]"))) {
|
|
358
|
+
let n = e.getAttribute("srcset");
|
|
359
|
+
n && e.setAttribute("srcset", await D(n, t));
|
|
360
|
+
}
|
|
361
|
+
for (let e of Array.from(n.querySelectorAll("[style]"))) {
|
|
362
|
+
let n = e.getAttribute("style");
|
|
363
|
+
n && e.setAttribute("style", await _(n, async (e, n) => E(e, t, n)));
|
|
364
|
+
}
|
|
365
|
+
for (let e of Array.from(n.querySelectorAll("style"))) e.textContent = await _(e.textContent ?? "", async (e, n) => E(e, t, n));
|
|
366
|
+
return "<!doctype html>\n" + n.documentElement.outerHTML;
|
|
367
|
+
};
|
|
368
|
+
return {
|
|
369
|
+
html: await O(e.html, e.documentPath),
|
|
370
|
+
loadedResources: b,
|
|
371
|
+
skippedResources: C
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
export { C as buildArchiveHtmlPreview };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ElementNavigationItem } from '@/composables/useElementNavigation';
|
|
2
|
+
interface DocxNode {
|
|
3
|
+
type?: string;
|
|
4
|
+
styleName?: string;
|
|
5
|
+
outlineLevel?: number;
|
|
6
|
+
children?: DocxNode[];
|
|
7
|
+
}
|
|
8
|
+
interface DocxStyle {
|
|
9
|
+
id?: string | null;
|
|
10
|
+
name?: string | null;
|
|
11
|
+
basedOn?: string | null;
|
|
12
|
+
paragraphProps?: {
|
|
13
|
+
outlineLevel?: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface ParsedDocxModel {
|
|
17
|
+
documentPart?: {
|
|
18
|
+
body?: DocxNode;
|
|
19
|
+
};
|
|
20
|
+
stylesPart?: {
|
|
21
|
+
styles?: DocxStyle[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface DocxNavigation {
|
|
25
|
+
outline: ElementNavigationItem[];
|
|
26
|
+
pages: ElementNavigationItem[];
|
|
27
|
+
}
|
|
28
|
+
export declare function buildDocxPageNavigation(renderRoot: HTMLElement): ElementNavigationItem[];
|
|
29
|
+
/** Build Word-style outline/page navigation from docx-preview's parsed model and rendered DOM. */
|
|
30
|
+
export declare function buildDocxNavigation(document: ParsedDocxModel, renderRoot: HTMLElement): DocxNavigation;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/lib/docxNavigation.ts
|
|
2
|
+
var e = /(?:heading|标题|標題|titre|überschrift|titolo|encabezado|nagłówek)\s*[-_. ]*([1-6])/i;
|
|
3
|
+
function t(e) {
|
|
4
|
+
let t = (e ?? "").replace(/\s+/g, " ").trim();
|
|
5
|
+
return t.length > 120 ? `${t.slice(0, 117)}…` : t;
|
|
6
|
+
}
|
|
7
|
+
function n(e) {
|
|
8
|
+
return typeof e == "number" && Number.isInteger(e) && e >= 0 && e <= 5 ? e : void 0;
|
|
9
|
+
}
|
|
10
|
+
function r(...t) {
|
|
11
|
+
for (let n of t) {
|
|
12
|
+
let t = n?.match(e);
|
|
13
|
+
if (t) return Number(t[1]) - 1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function i(e, t) {
|
|
17
|
+
for (let n of e) {
|
|
18
|
+
if (n.type === "paragraph") {
|
|
19
|
+
t.push(n);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
n.children?.length && i(n.children, t);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function a(e) {
|
|
26
|
+
return Array.from(e.querySelectorAll(".docx-wrapper > section.docx"), (e, t) => ({
|
|
27
|
+
id: `docx-page-${t}`,
|
|
28
|
+
title: `第 ${t + 1} 页`,
|
|
29
|
+
level: 0,
|
|
30
|
+
target: e
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
function o(e, o) {
|
|
34
|
+
let s = e.stylesPart?.styles, c = (Array.isArray(s) ? s : []).filter((e) => !!e.id), l = new Map(c.map((e) => [e.id, e])), u = /* @__PURE__ */ new Map();
|
|
35
|
+
function d(e, t = /* @__PURE__ */ new Set()) {
|
|
36
|
+
if (!e) return;
|
|
37
|
+
if (u.has(e)) return u.get(e);
|
|
38
|
+
if (t.has(e)) return;
|
|
39
|
+
t.add(e);
|
|
40
|
+
let i = l.get(e), a = n(i?.paragraphProps?.outlineLevel) ?? r(e, i?.id, i?.name) ?? d(i?.basedOn ?? void 0, t);
|
|
41
|
+
return u.set(e, a), a;
|
|
42
|
+
}
|
|
43
|
+
let f = [];
|
|
44
|
+
i(e.documentPart?.body?.children ?? [], f);
|
|
45
|
+
let p = Array.from(o.querySelectorAll(".docx-wrapper > section.docx > article p")), m = [];
|
|
46
|
+
for (let e = 0; e < Math.min(f.length, p.length); e += 1) {
|
|
47
|
+
let r = f[e], i = p[e], a = n(r.outlineLevel) ?? d(r.styleName), o = t(i.textContent);
|
|
48
|
+
if (a === void 0 || !o) continue;
|
|
49
|
+
let s = `docx-outline-${m.length}`;
|
|
50
|
+
i.dataset.documentNavId = s, m.push({
|
|
51
|
+
id: s,
|
|
52
|
+
title: o,
|
|
53
|
+
level: a,
|
|
54
|
+
target: i
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
outline: m,
|
|
59
|
+
pages: a(o)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { o as buildDocxNavigation, a as buildDocxPageNavigation };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type PresentationData } from '@aiden0z/pptx-renderer';
|
|
2
|
+
export interface PptxNavigationItem {
|
|
3
|
+
index: number;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
/** Derive one concise label per slide from the renderer's parsed text model. */
|
|
7
|
+
export declare function buildPptxNavigation(presentation: PresentationData): PptxNavigationItem[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { buildTextIndex as e } from "@aiden0z/pptx-renderer";
|
|
2
|
+
//#region src/lib/pptxNavigation.ts
|
|
3
|
+
function t(e) {
|
|
4
|
+
let t = e.replace(/\s+/g, " ").trim();
|
|
5
|
+
return t.length > 72 ? `${t.slice(0, 69)}…` : t;
|
|
6
|
+
}
|
|
7
|
+
function n(e) {
|
|
8
|
+
let n = t(e.text);
|
|
9
|
+
return !!n && !/^(?:slide\s*)?\d+$/i.test(n);
|
|
10
|
+
}
|
|
11
|
+
function r(r) {
|
|
12
|
+
let i = /* @__PURE__ */ new Map();
|
|
13
|
+
for (let t of e(r)) {
|
|
14
|
+
if (!n(t)) continue;
|
|
15
|
+
let e = i.get(t.slideIndex) ?? [];
|
|
16
|
+
e.push(t), i.set(t.slideIndex, e);
|
|
17
|
+
}
|
|
18
|
+
return r.slides.map((e, n) => {
|
|
19
|
+
let a = (i.get(n) ?? []).sort((e, t) => e.bounds.y - t.bounds.y || e.bounds.x - t.bounds.x);
|
|
20
|
+
return {
|
|
21
|
+
index: n,
|
|
22
|
+
title: t((a.find((e) => e.bounds.y < r.height * .4) ?? a[0])?.text ?? "") || `幻灯片 ${n + 1}`
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { r as buildPptxNavigation };
|