wasm-html-to-image 1.0.7 → 1.0.8
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/core-resources.d.ts
CHANGED
|
@@ -69,6 +69,14 @@ export declare function limitCodeForReason(reason: string): string;
|
|
|
69
69
|
* together, so this bounds the connection burst for many-page documents.
|
|
70
70
|
*/
|
|
71
71
|
export declare const FETCH_CONCURRENCY = 16;
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the relative `url(...)` and `@import` references of a fetched stylesheet against
|
|
74
|
+
* the stylesheet's own URL. The engine resolves them against the page, which is wrong as soon
|
|
75
|
+
* as the sheet lives in another directory (`url(../fonts/a.woff)` in `/static/css/a.css`).
|
|
76
|
+
* Absolute, protocol-relative, `data:`, `#` and root-relative references are left alone, and a
|
|
77
|
+
* root-relative sheet URL keeps its root-relative form.
|
|
78
|
+
*/
|
|
79
|
+
export declare function absolutizeCssUrls(css: string, cssUrl: string): string;
|
|
72
80
|
/** Run `fn` over `items` with at most `limit` calls in flight (`fn` must not reject). */
|
|
73
81
|
export declare function mapWithLimit<T>(items: readonly T[], limit: number, fn: (item: T) => Promise<void>): Promise<void>;
|
|
74
82
|
/**
|
package/dist/core-resources.js
CHANGED
|
@@ -270,6 +270,50 @@ export function limitCodeForReason(reason) {
|
|
|
270
270
|
* together, so this bounds the connection burst for many-page documents.
|
|
271
271
|
*/
|
|
272
272
|
export const FETCH_CONCURRENCY = 16;
|
|
273
|
+
/**
|
|
274
|
+
* Resolve the relative `url(...)` and `@import` references of a fetched stylesheet against
|
|
275
|
+
* the stylesheet's own URL. The engine resolves them against the page, which is wrong as soon
|
|
276
|
+
* as the sheet lives in another directory (`url(../fonts/a.woff)` in `/static/css/a.css`).
|
|
277
|
+
* Absolute, protocol-relative, `data:`, `#` and root-relative references are left alone, and a
|
|
278
|
+
* root-relative sheet URL keeps its root-relative form.
|
|
279
|
+
*/
|
|
280
|
+
export function absolutizeCssUrls(css, cssUrl) {
|
|
281
|
+
if (!css.includes("url(") && !css.includes("@import"))
|
|
282
|
+
return css;
|
|
283
|
+
const dummy = "http://css-base.invalid/";
|
|
284
|
+
let base;
|
|
285
|
+
try {
|
|
286
|
+
base = new URL(cssUrl, dummy);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return css;
|
|
290
|
+
}
|
|
291
|
+
const keepRootRelative = cssUrl.startsWith("/");
|
|
292
|
+
const absoluteCssUrl = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(cssUrl);
|
|
293
|
+
const resolve = (ref) => {
|
|
294
|
+
const t = ref.trim();
|
|
295
|
+
if (t === "" ||
|
|
296
|
+
t.startsWith("#") ||
|
|
297
|
+
t.startsWith("/") ||
|
|
298
|
+
/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(t))
|
|
299
|
+
return ref;
|
|
300
|
+
try {
|
|
301
|
+
const u = new URL(t, base);
|
|
302
|
+
if (absoluteCssUrl)
|
|
303
|
+
return u.href;
|
|
304
|
+
if (u.origin !== base.origin)
|
|
305
|
+
return u.href;
|
|
306
|
+
const path = u.pathname + u.search + u.hash;
|
|
307
|
+
return keepRootRelative ? path : path.slice(1);
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
return ref;
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
return css
|
|
314
|
+
.replace(/url\(\s*(['"]?)([^'")]*)\1\s*\)/g, (_m, q, ref) => `url(${q}${resolve(ref)}${q})`)
|
|
315
|
+
.replace(/@import\s+(['"])([^'"]+)\1/g, (_m, q, ref) => `@import ${q}${resolve(ref)}${q}`);
|
|
316
|
+
}
|
|
273
317
|
/** Run `fn` over `items` with at most `limit` calls in flight (`fn` must not reject). */
|
|
274
318
|
export async function mapWithLimit(items, limit, fn) {
|
|
275
319
|
let next = 0;
|
|
@@ -392,6 +436,10 @@ export async function resolveHtmlResources(module, satoruInst, htmls, width, hei
|
|
|
392
436
|
const pending = parsePendingResources(bin instanceof Uint8Array ? bin : undefined);
|
|
393
437
|
if (pending.length === 0)
|
|
394
438
|
break;
|
|
439
|
+
// Stylesheets cascade by document order, not by fetch completion order: a small
|
|
440
|
+
// later sheet must not land before (and so lose to) a large earlier one. They are
|
|
441
|
+
// buffered here and injected in discovery order once the whole round has settled.
|
|
442
|
+
const loadedCss = [];
|
|
395
443
|
await mapWithLimit(pending, FETCH_CONCURRENCY, async (r) => {
|
|
396
444
|
const diag = ctx.diag;
|
|
397
445
|
const entry = diag
|
|
@@ -470,7 +518,11 @@ export async function resolveHtmlResources(module, satoruInst, htmls, width, hei
|
|
|
470
518
|
}
|
|
471
519
|
ctx.usage.totalResourceBytes += bytes.length;
|
|
472
520
|
settle("loaded", bytes.length);
|
|
473
|
-
|
|
521
|
+
if (r.type === "css") {
|
|
522
|
+
loadedCss.push({ index: pending.indexOf(r), url: r.url, bytes });
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
(await addRes(satoruInst, r.url, r.type === "image" ? 2 : 1, bytes));
|
|
474
526
|
if (r.type === "font") {
|
|
475
527
|
diag?.fonts.push({
|
|
476
528
|
family: r.name || r.url,
|
|
@@ -486,6 +538,13 @@ export async function resolveHtmlResources(module, satoruInst, htmls, width, hei
|
|
|
486
538
|
diag?.warnings.push(d);
|
|
487
539
|
}
|
|
488
540
|
});
|
|
541
|
+
loadedCss.sort((a, b) => a.index - b.index);
|
|
542
|
+
for (const css of loadedCss) {
|
|
543
|
+
const text = new TextDecoder().decode(css.bytes);
|
|
544
|
+
const fixed = absolutizeCssUrls(text, css.url);
|
|
545
|
+
const bytes = fixed === text ? css.bytes : new TextEncoder().encode(fixed);
|
|
546
|
+
(await addRes(satoruInst, css.url, 3, bytes));
|
|
547
|
+
}
|
|
489
548
|
}
|
|
490
549
|
// Merge the C++ collect-phase breakdown into the JS timings.
|
|
491
550
|
if (profileEnabled && ctx.diag) {
|