@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.
@@ -152,6 +152,8 @@ var ALLOWED_ATTRIBUTES = {
152
152
  ],
153
153
  "img": [
154
154
  "src",
155
+ "srcset",
156
+ "sizes",
155
157
  "alt",
156
158
  "class",
157
159
  "loading",
@@ -231,8 +233,11 @@ function createDoc(html) {
231
233
  return null;
232
234
  }
233
235
  const cleanedHtml = removeDuplicateAttributes(html);
234
- const doc = DOMParser.parseFromString(`<body>${cleanedHtml}</body>`, "text/html");
235
- return doc;
236
+ try {
237
+ return DOMParser.parseFromString(`<body>${cleanedHtml}</body>`, "text/html");
238
+ } catch {
239
+ return null;
240
+ }
236
241
  }
237
242
  function makeEntryCacheKey(entry) {
238
243
  return `${entry.author}-${entry.permlink}-${entry.last_update}-${entry.updated}`;
@@ -307,6 +312,10 @@ function sanitizeHtml(html) {
307
312
  const decodedLower = decoded.toLowerCase();
308
313
  if (name.startsWith("on")) return "";
309
314
  if (tag === "img" && name === "src" && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
315
+ if (tag === "img" && name === "srcset") {
316
+ const candidates = decoded.split(",").map((c) => c.trim().split(/\s+/)[0]);
317
+ if (candidates.some((url) => !/^https?:\/\//.test(url))) return "";
318
+ }
310
319
  if (tag === "video" && ["src", "poster"].includes(name) && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
311
320
  if (tag === "img" && ["dynsrc", "lowsrc"].includes(name)) return "";
312
321
  if (tag === "span" && name === "class" && decoded.toLowerCase().trim() === "wr") return "";
@@ -321,6 +330,9 @@ var proxyBase = "https://images.ecency.com";
321
330
  function setProxyBase(p2) {
322
331
  proxyBase = p2;
323
332
  }
333
+ function getProxyBase() {
334
+ return proxyBase;
335
+ }
324
336
  function extractPHash(url) {
325
337
  if (url.startsWith(`${proxyBase}/p/`)) {
326
338
  const [hash] = url.split("/p/")[1].split("?");
@@ -368,8 +380,24 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
368
380
  const b58url = multihash__default.default.toB58String(Buffer.from(realUrl.toString()));
369
381
  return `${proxyBase}/p/${b58url}?${qs}`;
370
382
  }
383
+ var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
384
+ function buildSrcSet(url) {
385
+ if (!url || typeof url !== "string") return "";
386
+ const escapedBase = proxyBase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
387
+ const proxyPattern = new RegExp(`^${escapedBase}/p/([^?]+)`);
388
+ const match = url.match(proxyPattern);
389
+ if (match) {
390
+ const phash = extractPHash(url) || match[1];
391
+ return SRCSET_WIDTHS.map((w) => `${proxyBase}/p/${phash}?format=match&mode=fit&width=${w} ${w}w`).join(", ");
392
+ }
393
+ return SRCSET_WIDTHS.map((w) => {
394
+ const proxied = proxifyImageSrc(url, w);
395
+ return proxied ? `${proxied} ${w}w` : "";
396
+ }).filter(Boolean).join(", ");
397
+ }
371
398
 
372
399
  // src/methods/img.method.ts
400
+ var IMAGE_SIZES = "(max-width: 768px) 100vw, 700px";
373
401
  function img(el, state) {
374
402
  const src = el.getAttribute("src") || "";
375
403
  const decodedSrc = decodeURIComponent(
@@ -379,11 +407,15 @@ function img(el, state) {
379
407
  const isInvalid = !src || decodedSrc.startsWith("javascript") || decodedSrc.startsWith("vbscript") || decodedSrc === "x";
380
408
  if (isInvalid) {
381
409
  el.removeAttribute("src");
410
+ el.removeAttribute("srcset");
411
+ el.removeAttribute("sizes");
382
412
  return;
383
413
  }
384
414
  const isRelative = !/^https?:\/\//i.test(decodedSrc) && !decodedSrc.startsWith("/");
385
415
  if (isRelative) {
386
416
  el.removeAttribute("src");
417
+ el.removeAttribute("srcset");
418
+ el.removeAttribute("sizes");
387
419
  return;
388
420
  }
389
421
  el.setAttribute("itemprop", "image");
@@ -398,22 +430,41 @@ function img(el, state) {
398
430
  }
399
431
  const cls = el.getAttribute("class") || "";
400
432
  const shouldReplace = !cls.includes("no-replace");
401
- const hasAlreadyProxied = src.startsWith("https://images.ecency.com/p/") || src.startsWith("https://images.ecency.com/u/") || /^https:\/\/images\.ecency\.com\/\d+x\d+\//.test(src);
433
+ const base = getProxyBase().replace(/\/+$/, "");
434
+ const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
402
435
  if (shouldReplace && !hasAlreadyProxied) {
403
436
  const proxified = proxifyImageSrc(decodedSrc);
404
437
  if (proxified) {
405
438
  el.setAttribute("src", proxified);
439
+ const srcset = buildSrcSet(decodedSrc);
440
+ if (srcset) {
441
+ el.setAttribute("srcset", srcset);
442
+ el.setAttribute("sizes", IMAGE_SIZES);
443
+ }
444
+ }
445
+ } else if (shouldReplace && hasAlreadyProxied) {
446
+ if (src.startsWith(`${base}/p/`)) {
447
+ const srcset = buildSrcSet(src);
448
+ if (srcset) {
449
+ el.setAttribute("srcset", srcset);
450
+ el.setAttribute("sizes", IMAGE_SIZES);
451
+ }
406
452
  }
407
453
  }
408
454
  }
409
455
  function createImageHTML(src, isLCP) {
410
456
  const proxified = proxifyImageSrc(src);
411
457
  if (!proxified) return "";
458
+ const base = getProxyBase().replace(/\/+$/, "");
459
+ const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
460
+ const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
412
461
  const loading = isLCP ? "eager" : "lazy";
413
462
  const fetch = isLCP ? 'fetchpriority="high"' : 'decoding="async"';
463
+ const srcsetAttr = srcset ? `srcset="${srcset}" sizes="${IMAGE_SIZES}"` : "";
414
464
  return `<img
415
465
  class="markdown-img-link"
416
466
  src="${proxified}"
467
+ ${srcsetAttr}
417
468
  loading="${loading}"
418
469
  ${fetch}
419
470
  itemprop="image"
@@ -1807,6 +1858,7 @@ function getPostBodySummary(obj, length, platform) {
1807
1858
  }
1808
1859
 
1809
1860
  exports.SECTION_LIST = SECTION_LIST;
1861
+ exports.buildSrcSet = buildSrcSet;
1810
1862
  exports.catchPostImage = catchPostImage;
1811
1863
  exports.isValidPermlink = isValidPermlink;
1812
1864
  exports.postBodySummary = getPostBodySummary;