docgen-utils 1.0.30 → 1.0.32
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/dist/bundle.js +43 -27
- package/dist/bundle.min.js +78 -78
- package/dist/cli.js +6165 -82
- package/dist/packages/cli/commands/export-slides.d.ts +4 -9
- package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-slides.js +233 -100
- package/dist/packages/cli/commands/export-slides.js.map +1 -1
- package/dist/packages/slides/convert.d.ts +2 -0
- package/dist/packages/slides/convert.d.ts.map +1 -1
- package/dist/packages/slides/convert.js +36 -28
- package/dist/packages/slides/convert.js.map +1 -1
- package/dist/packages/slides/createPresentation.d.ts.map +1 -1
- package/dist/packages/slides/createPresentation.js +18 -18
- package/dist/packages/slides/createPresentation.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Export slides command - converts HTML slides to PPTX using Playwright
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Google Fonts <link> tags load correctly → accurate font names/sizes
|
|
9
|
-
* - --disable-web-security allows cross-origin images on canvas without
|
|
10
|
-
* tainting → CSS filters, mask-image, and icon font rendering all work
|
|
11
|
-
* - No need to pre-embed images as data URIs (avoids regex fragility and
|
|
12
|
-
* potential base64 corruption by transformHtmlForPptx)
|
|
4
|
+
* Architecture: Pipelined processing for maximum speed:
|
|
5
|
+
* - Parse slides in browser (batched for stability)
|
|
6
|
+
* - Start fetching images immediately as slides are parsed
|
|
7
|
+
* - Generate PPTX slides as soon as their images are ready
|
|
13
8
|
*/
|
|
14
9
|
export declare function exportSlides(filePaths: string[], outDir: string, outputName?: string, pdf?: boolean): Promise<void>;
|
|
15
10
|
//# sourceMappingURL=export-slides.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-slides.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"export-slides.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA6EH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwQhI"}
|
|
@@ -1,70 +1,81 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Export slides command - converts HTML slides to PPTX using Playwright
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Google Fonts <link> tags load correctly → accurate font names/sizes
|
|
9
|
-
* - --disable-web-security allows cross-origin images on canvas without
|
|
10
|
-
* tainting → CSS filters, mask-image, and icon font rendering all work
|
|
11
|
-
* - No need to pre-embed images as data URIs (avoids regex fragility and
|
|
12
|
-
* potential base64 corruption by transformHtmlForPptx)
|
|
4
|
+
* Architecture: Pipelined processing for maximum speed:
|
|
5
|
+
* - Parse slides in browser (batched for stability)
|
|
6
|
+
* - Start fetching images immediately as slides are parsed
|
|
7
|
+
* - Generate PPTX slides as soon as their images are ready
|
|
13
8
|
*/
|
|
14
9
|
import * as fs from "node:fs";
|
|
15
10
|
import * as path from "node:path";
|
|
16
11
|
import { fileURLToPath } from "node:url";
|
|
17
12
|
import { chromium } from "playwright";
|
|
18
|
-
import { fetchWithProxy } from "../../shared/fetch-with-proxy";
|
|
19
13
|
import { convertOfficeToPdf } from "../../shared/convert-to-pdf";
|
|
14
|
+
import { fetchWithProxy } from "../../shared/fetch-with-proxy";
|
|
15
|
+
import PptxGenJS from "../../slides/vendor/pptxgen";
|
|
16
|
+
import { addElementsToSlide, applyBackground } from "../../slides/convert";
|
|
20
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
18
|
const __dirname = path.dirname(__filename);
|
|
22
19
|
/**
|
|
23
|
-
*
|
|
24
|
-
* This bypasses CORS restrictions by fetching images in Node.js
|
|
25
|
-
* before passing HTML to the browser context.
|
|
20
|
+
* Fetch an image URL and convert to base64 data URL using Node.js.
|
|
26
21
|
*/
|
|
27
|
-
async function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
22
|
+
async function fetchImageAsDataUrlNode(url) {
|
|
23
|
+
const response = await fetchWithProxy(url);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Failed to fetch image: ${response.status}`);
|
|
26
|
+
}
|
|
27
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
28
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
29
|
+
// Determine MIME type from URL or content-type header
|
|
30
|
+
const contentType = response.headers.get("content-type") || "image/png";
|
|
31
|
+
const base64 = buffer.toString("base64");
|
|
32
|
+
return `data:${contentType};base64,${base64}`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Collect all image URLs from parsed slide data.
|
|
36
|
+
*/
|
|
37
|
+
function collectImageUrls(slideData) {
|
|
35
38
|
const urls = new Set();
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const base64 = Buffer.from(buffer).toString('base64');
|
|
48
|
-
const dataUri = `data:${contentType};base64,${base64}`;
|
|
49
|
-
urlToDataUri.set(url, dataUri);
|
|
39
|
+
// Background image
|
|
40
|
+
if (slideData.background.type === "image" && slideData.background.path) {
|
|
41
|
+
const src = slideData.background.path;
|
|
42
|
+
if (!src.startsWith("data:"))
|
|
43
|
+
urls.add(src);
|
|
44
|
+
}
|
|
45
|
+
// Element images
|
|
46
|
+
for (const el of slideData.elements) {
|
|
47
|
+
if (el.type === "image" || el.type === "backgroundImage" || el.type === "slideBackgroundImage") {
|
|
48
|
+
if (el.src && !el.src.startsWith("data:")) {
|
|
49
|
+
urls.add(el.src);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
}
|
|
53
|
+
return urls;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Replace external image URLs with data URLs in parsed slide data.
|
|
57
|
+
*/
|
|
58
|
+
function injectImageDataUrls(slideData, imageCache) {
|
|
59
|
+
// Background image
|
|
60
|
+
if (slideData.background.type === "image" && slideData.background.path) {
|
|
61
|
+
const dataUrl = imageCache.get(slideData.background.path);
|
|
62
|
+
if (dataUrl)
|
|
63
|
+
slideData.background.path = dataUrl;
|
|
64
|
+
}
|
|
65
|
+
// Element images
|
|
66
|
+
for (const el of slideData.elements) {
|
|
67
|
+
if (el.type === "image" || el.type === "backgroundImage" || el.type === "slideBackgroundImage") {
|
|
68
|
+
if (el.src && !el.src.startsWith("data:")) {
|
|
69
|
+
const dataUrl = imageCache.get(el.src);
|
|
70
|
+
if (dataUrl)
|
|
71
|
+
el.src = dataUrl;
|
|
72
|
+
}
|
|
62
73
|
}
|
|
63
|
-
|
|
64
|
-
});
|
|
65
|
-
return html;
|
|
74
|
+
}
|
|
66
75
|
}
|
|
67
76
|
export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
|
|
77
|
+
// Filter out empty strings (e.g., from trailing commas in --files argument)
|
|
78
|
+
filePaths = filePaths.filter(p => p.trim() !== "");
|
|
68
79
|
if (filePaths.length === 0) {
|
|
69
80
|
throw new Error("No input files provided");
|
|
70
81
|
}
|
|
@@ -78,7 +89,7 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
|
|
|
78
89
|
absolutePaths.push(absolutePath);
|
|
79
90
|
}
|
|
80
91
|
console.log(`Exporting ${absolutePaths.length} slide(s) to ${pdf ? "PDF" : "PPTX"}`);
|
|
81
|
-
// Read the bundle which contains
|
|
92
|
+
// Read the bundle which contains parsing code
|
|
82
93
|
let bundlePath = path.resolve(__dirname, "bundle.min.js");
|
|
83
94
|
if (!fs.existsSync(bundlePath)) {
|
|
84
95
|
bundlePath = path.resolve(__dirname, "..", "..", "..", "dist/bundle.min.js");
|
|
@@ -86,23 +97,70 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
|
|
|
86
97
|
if (!fs.existsSync(bundlePath)) {
|
|
87
98
|
throw new Error(`Bundle not found: ${bundlePath}. Run 'npm run build' first.`);
|
|
88
99
|
}
|
|
89
|
-
const
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
const bundleJs = fs.readFileSync(bundlePath, "utf-8");
|
|
101
|
+
// Shared image cache - populated as images are fetched
|
|
102
|
+
const imageCache = new Map();
|
|
103
|
+
const imageFetchPromises = new Map();
|
|
104
|
+
// Start fetching an image if not already fetching
|
|
105
|
+
function startImageFetch(url) {
|
|
106
|
+
if (imageFetchPromises.has(url))
|
|
107
|
+
return;
|
|
108
|
+
const promise = fetchImageAsDataUrlNode(url)
|
|
109
|
+
.then(dataUrl => { imageCache.set(url, dataUrl); })
|
|
110
|
+
.catch(() => { });
|
|
111
|
+
imageFetchPromises.set(url, promise);
|
|
112
|
+
}
|
|
113
|
+
// Wait for all images needed by a slide
|
|
114
|
+
async function waitForSlideImages(slideData) {
|
|
115
|
+
const urls = collectImageUrls(slideData);
|
|
116
|
+
const promises = Array.from(urls).map(url => imageFetchPromises.get(url)).filter(Boolean);
|
|
117
|
+
await Promise.all(promises);
|
|
118
|
+
}
|
|
119
|
+
// Initialize PPTX early
|
|
120
|
+
const pptx = new PptxGenJS();
|
|
121
|
+
pptx.layout = "LAYOUT_16x9";
|
|
122
|
+
pptx.author = "docgen";
|
|
123
|
+
pptx.title = "Presentation";
|
|
124
|
+
// Pre-create slides to maintain order (PptxGenJS adds slides sequentially)
|
|
125
|
+
const slideSlots = [];
|
|
126
|
+
for (let i = 0; i < absolutePaths.length; i++) {
|
|
127
|
+
slideSlots.push({ slide: pptx.addSlide(), generated: false });
|
|
128
|
+
}
|
|
129
|
+
// Track progress
|
|
130
|
+
let parsedCount = 0;
|
|
131
|
+
let generatedCount = 0;
|
|
132
|
+
// Queue of parsed slides ready for generation
|
|
133
|
+
const parsedSlides = [];
|
|
134
|
+
// Serialized slide generation - only one generation loop runs at a time
|
|
135
|
+
let generationChain = Promise.resolve();
|
|
136
|
+
function queueGeneration() {
|
|
137
|
+
generationChain = generationChain.then(async () => {
|
|
138
|
+
while (true) {
|
|
139
|
+
// Find next slide in order
|
|
140
|
+
const nextIndex = generatedCount;
|
|
141
|
+
const entry = parsedSlides.find(p => p.index === nextIndex);
|
|
142
|
+
if (!entry)
|
|
143
|
+
break;
|
|
144
|
+
// Wait for this slide's images
|
|
145
|
+
await entry.imagesReady;
|
|
146
|
+
// Generate slide
|
|
147
|
+
const { slideData } = entry;
|
|
148
|
+
const slot = slideSlots[nextIndex];
|
|
149
|
+
injectImageDataUrls(slideData, imageCache);
|
|
150
|
+
await applyBackground(slideData.background, slot.slide);
|
|
151
|
+
await addElementsToSlide(slideData.elements, slot.slide, pptx);
|
|
152
|
+
slot.generated = true;
|
|
153
|
+
generatedCount++;
|
|
154
|
+
console.log(` Slide ${generatedCount}/${absolutePaths.length} done`);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Launch browser
|
|
101
159
|
const launchOptions = {
|
|
102
160
|
headless: true,
|
|
103
161
|
args: ["--disable-web-security"],
|
|
104
162
|
};
|
|
105
|
-
const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
163
|
+
const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
|
|
106
164
|
if (proxyServer) {
|
|
107
165
|
launchOptions.proxy = { server: proxyServer };
|
|
108
166
|
}
|
|
@@ -113,51 +171,126 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
|
|
|
113
171
|
viewport: { width: 960, height: 540 },
|
|
114
172
|
ignoreHTTPSErrors: true,
|
|
115
173
|
});
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const script = document.createElement("script");
|
|
126
|
-
script.textContent = code;
|
|
127
|
-
document.head.appendChild(script);
|
|
128
|
-
}, bundleCode);
|
|
129
|
-
// Wait for the bundle to initialise on the page
|
|
130
|
-
await page.waitForFunction(() => !!window.docgen);
|
|
131
|
-
// Generate PPTX in browser
|
|
132
|
-
const pptxBuffer = await page.evaluate(async ({ htmlContents }) => {
|
|
133
|
-
const docgen = window.docgen;
|
|
134
|
-
// Create PptxGenJS instance
|
|
135
|
-
const pptx = new docgen.PptxGenJS();
|
|
136
|
-
pptx.layout = "LAYOUT_16x9";
|
|
137
|
-
pptx.author = "docgen";
|
|
138
|
-
pptx.title = "Presentation";
|
|
139
|
-
// Add each slide
|
|
140
|
-
for (const htmlContent of htmlContents) {
|
|
141
|
-
const transformedHtml = docgen.transformHtmlForPptx(htmlContent);
|
|
142
|
-
await docgen.addSlideFromHtml(transformedHtml, pptx);
|
|
174
|
+
// Block external image loading - we fetch images in Node.js instead
|
|
175
|
+
await context.route('**/*', route => {
|
|
176
|
+
const request = route.request();
|
|
177
|
+
const url = request.url();
|
|
178
|
+
if (url.startsWith('blob:') || url.startsWith('data:')) {
|
|
179
|
+
return route.continue();
|
|
180
|
+
}
|
|
181
|
+
if (request.resourceType() === 'image') {
|
|
182
|
+
return route.abort();
|
|
143
183
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
184
|
+
return route.continue();
|
|
185
|
+
});
|
|
186
|
+
// Parse slides in batches, but start processing immediately
|
|
187
|
+
const MAX_CONCURRENT = 4;
|
|
188
|
+
for (let batchStart = 0; batchStart < absolutePaths.length; batchStart += MAX_CONCURRENT) {
|
|
189
|
+
const batchEnd = Math.min(batchStart + MAX_CONCURRENT, absolutePaths.length);
|
|
190
|
+
const batchPaths = absolutePaths.slice(batchStart, batchEnd);
|
|
191
|
+
const batchPromises = batchPaths.map(async (slidePath, batchIndex) => {
|
|
192
|
+
const index = batchStart + batchIndex;
|
|
193
|
+
const page = await context.newPage();
|
|
194
|
+
page.setDefaultTimeout(60000);
|
|
195
|
+
await page.goto(`file://${slidePath}`, { waitUntil: "domcontentloaded" });
|
|
196
|
+
await page.addScriptTag({ content: bundleJs });
|
|
197
|
+
await page.waitForFunction("typeof window.docgen !== 'undefined'");
|
|
198
|
+
await page.evaluate(`(async function() {
|
|
199
|
+
if (document.fonts && document.fonts.ready) {
|
|
200
|
+
await Promise.race([
|
|
201
|
+
document.fonts.ready,
|
|
202
|
+
new Promise(r => setTimeout(r, 500))
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
})()`);
|
|
206
|
+
const slideDataJson = await page.evaluate(`(async function() {
|
|
207
|
+
const docgen = window.docgen;
|
|
208
|
+
const html = document.documentElement.outerHTML;
|
|
209
|
+
const transformedHtml = docgen.transformHtmlForPptx(html);
|
|
210
|
+
|
|
211
|
+
const iframe = document.createElement('iframe');
|
|
212
|
+
iframe.style.cssText = 'position:absolute;left:-9999px;width:960px;height:540px;border:none;';
|
|
213
|
+
|
|
214
|
+
const blob = new Blob([transformedHtml], { type: 'text/html' });
|
|
215
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
216
|
+
|
|
217
|
+
return new Promise((resolve) => {
|
|
218
|
+
iframe.onload = async () => {
|
|
219
|
+
URL.revokeObjectURL(blobUrl);
|
|
220
|
+
|
|
221
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
222
|
+
const win = iframe.contentWindow;
|
|
223
|
+
|
|
224
|
+
if (win.document.fonts && win.document.fonts.ready) {
|
|
225
|
+
await Promise.race([
|
|
226
|
+
win.document.fonts.ready,
|
|
227
|
+
new Promise(r => setTimeout(r, 500))
|
|
228
|
+
]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
const slideData = docgen.parseSlideHtml(iframeDoc);
|
|
233
|
+
iframe.parentNode.removeChild(iframe);
|
|
234
|
+
resolve(JSON.stringify(slideData));
|
|
235
|
+
} catch(e) {
|
|
236
|
+
iframe.parentNode.removeChild(iframe);
|
|
237
|
+
resolve(JSON.stringify({ error: e.message }));
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
iframe.onerror = () => {
|
|
242
|
+
URL.revokeObjectURL(blobUrl);
|
|
243
|
+
iframe.parentNode?.removeChild(iframe);
|
|
244
|
+
resolve(JSON.stringify({ error: 'iframe load error' }));
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
iframe.src = blobUrl;
|
|
248
|
+
document.body.appendChild(iframe);
|
|
249
|
+
|
|
250
|
+
setTimeout(() => {
|
|
251
|
+
if (iframe.parentNode) {
|
|
252
|
+
iframe.parentNode.removeChild(iframe);
|
|
253
|
+
resolve(JSON.stringify({ error: 'timeout' }));
|
|
254
|
+
}
|
|
255
|
+
}, 10000);
|
|
256
|
+
});
|
|
257
|
+
})()`);
|
|
258
|
+
await page.close();
|
|
259
|
+
if (!slideDataJson) {
|
|
260
|
+
throw new Error(`Failed to parse slide ${index + 1}: ${slidePath} - null result`);
|
|
261
|
+
}
|
|
262
|
+
const parsed = JSON.parse(slideDataJson);
|
|
263
|
+
if (typeof parsed === 'object' && 'error' in parsed) {
|
|
264
|
+
throw new Error(`Failed to parse slide ${index + 1}: ${slidePath} - ${parsed.error}`);
|
|
265
|
+
}
|
|
266
|
+
const slideData = parsed;
|
|
267
|
+
parsedCount++;
|
|
268
|
+
console.log(` Parsed ${parsedCount}/${absolutePaths.length}`);
|
|
269
|
+
// Start fetching images for this slide immediately
|
|
270
|
+
const urls = collectImageUrls(slideData);
|
|
271
|
+
urls.forEach(url => startImageFetch(url));
|
|
272
|
+
// Create promise that resolves when all images for this slide are ready
|
|
273
|
+
const imagesReady = waitForSlideImages(slideData);
|
|
274
|
+
// Add to queue and trigger generation
|
|
275
|
+
parsedSlides.push({ index, slideData, imagesReady });
|
|
276
|
+
queueGeneration();
|
|
277
|
+
});
|
|
278
|
+
await Promise.all(batchPromises);
|
|
279
|
+
}
|
|
149
280
|
await context.close();
|
|
150
|
-
|
|
281
|
+
await browser.close();
|
|
282
|
+
// Wait for all slide generation to complete
|
|
283
|
+
await generationChain;
|
|
284
|
+
// Write final PPTX
|
|
285
|
+
const base64 = await pptx.write({ outputType: "base64" });
|
|
286
|
+
const pptxBuffer = Buffer.from(base64, "base64");
|
|
151
287
|
const firstBaseName = path.basename(absolutePaths[0], ".html");
|
|
152
288
|
const finalName = outputName || (absolutePaths.length === 1 ? firstBaseName : "presentation");
|
|
153
289
|
const pptxOutputPath = path.join(outDir, `${finalName}.pptx`);
|
|
154
|
-
|
|
155
|
-
const buffer = Buffer.from(pptxBuffer, "base64");
|
|
156
|
-
fs.writeFileSync(pptxOutputPath, buffer);
|
|
290
|
+
fs.writeFileSync(pptxOutputPath, pptxBuffer);
|
|
157
291
|
if (pdf) {
|
|
158
292
|
console.log("Converting to PDF via LibreOffice...");
|
|
159
293
|
const pdfPath = convertOfficeToPdf(pptxOutputPath, outDir);
|
|
160
|
-
// Remove intermediate PPTX file
|
|
161
294
|
fs.unlinkSync(pptxOutputPath);
|
|
162
295
|
console.log(`Output: ${pdfPath}`);
|
|
163
296
|
}
|
|
@@ -166,7 +299,7 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
|
|
|
166
299
|
}
|
|
167
300
|
}
|
|
168
301
|
finally {
|
|
169
|
-
await browser.close();
|
|
302
|
+
await browser.close().catch(() => { });
|
|
170
303
|
}
|
|
171
304
|
}
|
|
172
305
|
//# sourceMappingURL=export-slides.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-slides.js","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"export-slides.js","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAiB,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,SAAS,MAAM,6BAA6B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG3E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;GAEG;AACH,KAAK,UAAU,uBAAuB,CAAC,GAAW;IAChD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAExC,sDAAsD;IACtD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,WAAW,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,QAAQ,WAAW,WAAW,MAAM,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAsB;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,mBAAmB;IACnB,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACvE,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,iBAAiB;IACjB,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,IAAI,EAAE,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC/F,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,SAAsB,EAAE,UAA+B;IAClF,mBAAmB;IACnB,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACvE,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,OAAO;YAAE,SAAS,CAAC,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC;IACnD,CAAC;IAED,iBAAiB;IACjB,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,IAAI,EAAE,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC/F,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,OAAO;oBAAE,EAAE,CAAC,GAAG,GAAG,OAAO,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAmB,EAAE,MAAc,EAAE,UAAmB,EAAE,MAAe,KAAK;IAC/G,4EAA4E;IAC5E,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEnD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,2BAA2B;IAC3B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,aAAa,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAErF,8CAA8C;IAC9C,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,8BAA8B,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEtD,uDAAuD;IACvD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE5D,kDAAkD;IAClD,SAAS,eAAe,CAAC,GAAW;QAClC,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QACxC,MAAM,OAAO,GAAG,uBAAuB,CAAC,GAAG,CAAC;aACzC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;aAClD,KAAK,CAAC,GAAG,EAAE,GAAsD,CAAC,CAAC,CAAC;QACvE,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,wCAAwC;IACxC,KAAK,UAAU,kBAAkB,CAAC,SAAsB;QACtD,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1F,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,wBAAwB;IACxB,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;IAC5B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;IACvB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC;IAE5B,2EAA2E;IAC3E,MAAM,UAAU,GAA2E,EAAE,CAAC;IAC9F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,iBAAiB;IACjB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,cAAc,GAAG,CAAC,CAAC;IAEvB,8CAA8C;IAC9C,MAAM,YAAY,GAAiF,EAAE,CAAC;IAEtG,wEAAwE;IACxE,IAAI,eAAe,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEvD,SAAS,eAAe;QACtB,eAAe,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAChD,OAAO,IAAI,EAAE,CAAC;gBACZ,2BAA2B;gBAC3B,MAAM,SAAS,GAAG,cAAc,CAAC;gBACjC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;gBAC5D,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAElB,+BAA+B;gBAC/B,MAAM,KAAK,CAAC,WAAW,CAAC;gBAExB,iBAAiB;gBACjB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAE,CAAC;gBAEpC,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBAC3C,MAAM,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxD,MAAM,kBAAkB,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC/D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,cAAc,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,WAAW,cAAc,IAAI,aAAa,CAAC,MAAM,OAAO,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAkB;QACnC,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,CAAC,wBAAwB,CAAC;KACjC,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IAC3H,IAAI,WAAW,EAAE,CAAC;QAChB,aAAa,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;YACvC,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;YACrC,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QAEH,oEAAoE;QACpE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;YAClC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAE1B,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;YACD,IAAI,OAAO,CAAC,YAAY,EAAE,KAAK,OAAO,EAAE,CAAC;gBACvC,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,4DAA4D;QAC5D,MAAM,cAAc,GAAG,CAAC,CAAC;QAEzB,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC,MAAM,EAAE,UAAU,IAAI,cAAc,EAAE,CAAC;YACzF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC7E,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAE7D,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;gBACnE,MAAM,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;gBACtC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAE9B,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC1E,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC/C,MAAM,IAAI,CAAC,eAAe,CAAC,sCAAsC,CAAC,CAAC;gBAEnE,MAAM,IAAI,CAAC,QAAQ,CAAC;;;;;;;aAOf,CAAC,CAAC;gBAEP,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAmDrC,CAAC,CAAC;gBAEP,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;gBAEnB,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,GAAG,CAAC,KAAK,SAAS,gBAAgB,CAAC,CAAC;gBACpF,CAAC;gBAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAuB,CAAC,CAAC;gBACnD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;oBACpD,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,GAAG,CAAC,KAAK,SAAS,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBACxF,CAAC;gBAED,MAAM,SAAS,GAAG,MAAqB,CAAC;gBACxC,WAAW,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;gBAE/D,mDAAmD;gBACnD,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;gBAE1C,wEAAwE;gBACxE,MAAM,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBAElD,sCAAsC;gBACtC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;gBACrD,eAAe,EAAE,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtB,4CAA4C;QAC5C,MAAM,eAAe,CAAC;QAEtB,mBAAmB;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAW,CAAC;QACpE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEjD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAE,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,UAAU,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC9F,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;QAE9D,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAE7C,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YAC3D,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,WAAW,cAAc,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
|
|
@@ -29,6 +29,8 @@ export declare function applyBackground(background: SlideBackground, slide: Slid
|
|
|
29
29
|
* 1. First pass - adds `slideBackgroundImage` elements (rendered behind everything).
|
|
30
30
|
* 2. Second pass - adds all other element types (image, backgroundImage, line, shape, list, text).
|
|
31
31
|
*
|
|
32
|
+
* Images are prefetched in parallel at the start for better performance.
|
|
33
|
+
*
|
|
32
34
|
* @param elements - The parsed slide elements array.
|
|
33
35
|
* @param slide - The target PptxGenJS Slide instance.
|
|
34
36
|
* @param pres - The PptxGenJS presentation instance (needed for `pres.ShapeType`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../../packages/slides/convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,KAAK,EAKN,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEb,MAAM,UAAU,CAAC;AA0FlB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,UAAU,SAAI,EACd,cAAc,SAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../../packages/slides/convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,KAAK,EAKN,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEb,MAAM,UAAU,CAAC;AA0FlB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,UAAU,SAAI,EACd,cAAc,SAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;AA0DD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,KAAK,EAEZ,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,IAAI,CAAC,CAqhBf"}
|
|
@@ -208,31 +208,6 @@ function clipToSlide(pos) {
|
|
|
208
208
|
// ---------------------------------------------------------------------------
|
|
209
209
|
// addElementsToSlide
|
|
210
210
|
// ---------------------------------------------------------------------------
|
|
211
|
-
/**
|
|
212
|
-
* Resolve an image source to a PptxGenJS-compatible `{ data: string }` object.
|
|
213
|
-
*
|
|
214
|
-
* Data URIs are used directly. External/relative URLs are fetched and converted
|
|
215
|
-
* to data URLs via {@link fetchImageAsDataUrl}.
|
|
216
|
-
*
|
|
217
|
-
* Returns `null` when the fetch fails (e.g. CORS), allowing the caller to skip
|
|
218
|
-
* the image with a warning.
|
|
219
|
-
*/
|
|
220
|
-
async function getImageSource(src) {
|
|
221
|
-
if (src.startsWith('data:')) {
|
|
222
|
-
return { data: src };
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
try {
|
|
226
|
-
const dataUrl = await fetchImageAsDataUrl(src);
|
|
227
|
-
return { data: dataUrl };
|
|
228
|
-
}
|
|
229
|
-
catch (e) {
|
|
230
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
231
|
-
console.warn(`Could not fetch image ${src}: ${message}`);
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
211
|
/**
|
|
237
212
|
* Add all slide elements to a PptxGenJS Slide.
|
|
238
213
|
*
|
|
@@ -240,6 +215,8 @@ async function getImageSource(src) {
|
|
|
240
215
|
* 1. First pass - adds `slideBackgroundImage` elements (rendered behind everything).
|
|
241
216
|
* 2. Second pass - adds all other element types (image, backgroundImage, line, shape, list, text).
|
|
242
217
|
*
|
|
218
|
+
* Images are prefetched in parallel at the start for better performance.
|
|
219
|
+
*
|
|
243
220
|
* @param elements - The parsed slide elements array.
|
|
244
221
|
* @param slide - The target PptxGenJS Slide instance.
|
|
245
222
|
* @param pres - The PptxGenJS presentation instance (needed for `pres.ShapeType`).
|
|
@@ -248,10 +225,41 @@ async function getImageSource(src) {
|
|
|
248
225
|
export async function addElementsToSlide(elements, slide,
|
|
249
226
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
250
227
|
pres) {
|
|
228
|
+
// ---- Prefetch all images in parallel ----
|
|
229
|
+
const imageUrls = new Set();
|
|
230
|
+
for (const el of elements) {
|
|
231
|
+
if (el.type === 'image' || el.type === 'backgroundImage' || el.type === 'slideBackgroundImage') {
|
|
232
|
+
if (el.src && !el.src.startsWith('data:')) {
|
|
233
|
+
imageUrls.add(el.src);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const imageCache = new Map();
|
|
238
|
+
if (imageUrls.size > 0) {
|
|
239
|
+
const fetchPromises = Array.from(imageUrls).map(async (url) => {
|
|
240
|
+
try {
|
|
241
|
+
const dataUrl = await fetchImageAsDataUrl(url);
|
|
242
|
+
imageCache.set(url, { data: dataUrl });
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
246
|
+
console.warn(`Could not fetch image ${url}: ${message}`);
|
|
247
|
+
imageCache.set(url, null);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
await Promise.all(fetchPromises);
|
|
251
|
+
}
|
|
252
|
+
// Helper to get image from cache or return data URI directly
|
|
253
|
+
const getCachedImageSource = (src) => {
|
|
254
|
+
if (src.startsWith('data:')) {
|
|
255
|
+
return { data: src };
|
|
256
|
+
}
|
|
257
|
+
return imageCache.get(src) ?? null;
|
|
258
|
+
};
|
|
251
259
|
// ---- First pass: slide background images ----
|
|
252
260
|
for (const el of elements) {
|
|
253
261
|
if (el.type === 'slideBackgroundImage') {
|
|
254
|
-
const imgSrc =
|
|
262
|
+
const imgSrc = getCachedImageSource(el.src);
|
|
255
263
|
if (!imgSrc) {
|
|
256
264
|
console.warn(`Skipping slide background image (CORS failure): ${el.src}`);
|
|
257
265
|
continue;
|
|
@@ -313,7 +321,7 @@ pres) {
|
|
|
313
321
|
el.position.h = clipped.h;
|
|
314
322
|
}
|
|
315
323
|
if (el.type === 'image') {
|
|
316
|
-
const imgSrc =
|
|
324
|
+
const imgSrc = getCachedImageSource(el.src);
|
|
317
325
|
if (!imgSrc) {
|
|
318
326
|
console.warn(`Skipping image (CORS failure): ${el.src}`);
|
|
319
327
|
continue;
|
|
@@ -353,7 +361,7 @@ pres) {
|
|
|
353
361
|
slide.addImage(imageOptions);
|
|
354
362
|
}
|
|
355
363
|
else if (el.type === 'backgroundImage') {
|
|
356
|
-
const imgSrc =
|
|
364
|
+
const imgSrc = getCachedImageSource(el.src);
|
|
357
365
|
if (!imgSrc) {
|
|
358
366
|
console.warn(`Skipping background image (CORS failure): ${el.src}`);
|
|
359
367
|
continue;
|