@ecency/render-helper 2.4.29 → 2.4.31
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/browser/index.d.ts +6 -1
- package/dist/browser/index.js +55 -4
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +55 -3
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.mjs +55 -4
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -123,6 +123,8 @@ var ALLOWED_ATTRIBUTES = {
|
|
|
123
123
|
],
|
|
124
124
|
"img": [
|
|
125
125
|
"src",
|
|
126
|
+
"srcset",
|
|
127
|
+
"sizes",
|
|
126
128
|
"alt",
|
|
127
129
|
"class",
|
|
128
130
|
"loading",
|
|
@@ -202,8 +204,11 @@ function createDoc(html) {
|
|
|
202
204
|
return null;
|
|
203
205
|
}
|
|
204
206
|
const cleanedHtml = removeDuplicateAttributes(html);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
try {
|
|
208
|
+
return DOMParser.parseFromString(`<body>${cleanedHtml}</body>`, "text/html");
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
207
212
|
}
|
|
208
213
|
function makeEntryCacheKey(entry) {
|
|
209
214
|
return `${entry.author}-${entry.permlink}-${entry.last_update}-${entry.updated}`;
|
|
@@ -278,6 +283,10 @@ function sanitizeHtml(html) {
|
|
|
278
283
|
const decodedLower = decoded.toLowerCase();
|
|
279
284
|
if (name.startsWith("on")) return "";
|
|
280
285
|
if (tag === "img" && name === "src" && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
|
|
286
|
+
if (tag === "img" && name === "srcset") {
|
|
287
|
+
const candidates = decoded.split(",").map((c) => c.trim().split(/\s+/)[0]);
|
|
288
|
+
if (candidates.some((url) => !/^https?:\/\//.test(url))) return "";
|
|
289
|
+
}
|
|
281
290
|
if (tag === "video" && ["src", "poster"].includes(name) && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
|
|
282
291
|
if (tag === "img" && ["dynsrc", "lowsrc"].includes(name)) return "";
|
|
283
292
|
if (tag === "span" && name === "class" && decoded.toLowerCase().trim() === "wr") return "";
|
|
@@ -292,6 +301,9 @@ var proxyBase = "https://images.ecency.com";
|
|
|
292
301
|
function setProxyBase(p2) {
|
|
293
302
|
proxyBase = p2;
|
|
294
303
|
}
|
|
304
|
+
function getProxyBase() {
|
|
305
|
+
return proxyBase;
|
|
306
|
+
}
|
|
295
307
|
function extractPHash(url) {
|
|
296
308
|
if (url.startsWith(`${proxyBase}/p/`)) {
|
|
297
309
|
const [hash] = url.split("/p/")[1].split("?");
|
|
@@ -339,8 +351,24 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
|
|
|
339
351
|
const b58url = multihash.toB58String(Buffer.from(realUrl.toString()));
|
|
340
352
|
return `${proxyBase}/p/${b58url}?${qs}`;
|
|
341
353
|
}
|
|
354
|
+
var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
|
|
355
|
+
function buildSrcSet(url) {
|
|
356
|
+
if (!url || typeof url !== "string") return "";
|
|
357
|
+
const escapedBase = proxyBase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
358
|
+
const proxyPattern = new RegExp(`^${escapedBase}/p/([^?]+)`);
|
|
359
|
+
const match = url.match(proxyPattern);
|
|
360
|
+
if (match) {
|
|
361
|
+
const phash = extractPHash(url) || match[1];
|
|
362
|
+
return SRCSET_WIDTHS.map((w) => `${proxyBase}/p/${phash}?format=match&mode=fit&width=${w} ${w}w`).join(", ");
|
|
363
|
+
}
|
|
364
|
+
return SRCSET_WIDTHS.map((w) => {
|
|
365
|
+
const proxied = proxifyImageSrc(url, w);
|
|
366
|
+
return proxied ? `${proxied} ${w}w` : "";
|
|
367
|
+
}).filter(Boolean).join(", ");
|
|
368
|
+
}
|
|
342
369
|
|
|
343
370
|
// src/methods/img.method.ts
|
|
371
|
+
var IMAGE_SIZES = "(max-width: 768px) 100vw, 700px";
|
|
344
372
|
function img(el, state) {
|
|
345
373
|
const src = el.getAttribute("src") || "";
|
|
346
374
|
const decodedSrc = decodeURIComponent(
|
|
@@ -350,11 +378,15 @@ function img(el, state) {
|
|
|
350
378
|
const isInvalid = !src || decodedSrc.startsWith("javascript") || decodedSrc.startsWith("vbscript") || decodedSrc === "x";
|
|
351
379
|
if (isInvalid) {
|
|
352
380
|
el.removeAttribute("src");
|
|
381
|
+
el.removeAttribute("srcset");
|
|
382
|
+
el.removeAttribute("sizes");
|
|
353
383
|
return;
|
|
354
384
|
}
|
|
355
385
|
const isRelative = !/^https?:\/\//i.test(decodedSrc) && !decodedSrc.startsWith("/");
|
|
356
386
|
if (isRelative) {
|
|
357
387
|
el.removeAttribute("src");
|
|
388
|
+
el.removeAttribute("srcset");
|
|
389
|
+
el.removeAttribute("sizes");
|
|
358
390
|
return;
|
|
359
391
|
}
|
|
360
392
|
el.setAttribute("itemprop", "image");
|
|
@@ -369,22 +401,41 @@ function img(el, state) {
|
|
|
369
401
|
}
|
|
370
402
|
const cls = el.getAttribute("class") || "";
|
|
371
403
|
const shouldReplace = !cls.includes("no-replace");
|
|
372
|
-
const
|
|
404
|
+
const base = getProxyBase().replace(/\/+$/, "");
|
|
405
|
+
const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
|
|
373
406
|
if (shouldReplace && !hasAlreadyProxied) {
|
|
374
407
|
const proxified = proxifyImageSrc(decodedSrc);
|
|
375
408
|
if (proxified) {
|
|
376
409
|
el.setAttribute("src", proxified);
|
|
410
|
+
const srcset = buildSrcSet(decodedSrc);
|
|
411
|
+
if (srcset) {
|
|
412
|
+
el.setAttribute("srcset", srcset);
|
|
413
|
+
el.setAttribute("sizes", IMAGE_SIZES);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
} else if (shouldReplace && hasAlreadyProxied) {
|
|
417
|
+
if (src.startsWith(`${base}/p/`)) {
|
|
418
|
+
const srcset = buildSrcSet(src);
|
|
419
|
+
if (srcset) {
|
|
420
|
+
el.setAttribute("srcset", srcset);
|
|
421
|
+
el.setAttribute("sizes", IMAGE_SIZES);
|
|
422
|
+
}
|
|
377
423
|
}
|
|
378
424
|
}
|
|
379
425
|
}
|
|
380
426
|
function createImageHTML(src, isLCP) {
|
|
381
427
|
const proxified = proxifyImageSrc(src);
|
|
382
428
|
if (!proxified) return "";
|
|
429
|
+
const base = getProxyBase().replace(/\/+$/, "");
|
|
430
|
+
const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
|
|
431
|
+
const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
|
|
383
432
|
const loading = isLCP ? "eager" : "lazy";
|
|
384
433
|
const fetch = isLCP ? 'fetchpriority="high"' : 'decoding="async"';
|
|
434
|
+
const srcsetAttr = srcset ? `srcset="${srcset}" sizes="${IMAGE_SIZES}"` : "";
|
|
385
435
|
return `<img
|
|
386
436
|
class="markdown-img-link"
|
|
387
437
|
src="${proxified}"
|
|
438
|
+
${srcsetAttr}
|
|
388
439
|
loading="${loading}"
|
|
389
440
|
${fetch}
|
|
390
441
|
itemprop="image"
|
|
@@ -1777,6 +1828,6 @@ function getPostBodySummary(obj, length, platform) {
|
|
|
1777
1828
|
return res;
|
|
1778
1829
|
}
|
|
1779
1830
|
|
|
1780
|
-
export { SECTION_LIST, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, simpleMarkdownToHTML };
|
|
1831
|
+
export { SECTION_LIST, buildSrcSet, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, simpleMarkdownToHTML };
|
|
1781
1832
|
//# sourceMappingURL=index.mjs.map
|
|
1782
1833
|
//# sourceMappingURL=index.mjs.map
|