@ecency/render-helper 2.5.6 → 2.5.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.
@@ -51,10 +51,26 @@ declare function catchPostImage(obj: Entry | string, width?: number, height?: nu
51
51
  declare function getPostBodySummary(obj: Entry | string, length?: number, platform?: 'ios' | 'android' | 'web'): string;
52
52
 
53
53
  declare function setProxyBase(p: string): void;
54
+ interface ProxifyOptions {
55
+ /**
56
+ * Request a tiny blurred LQIP placeholder. The proxy resizes to ~20px and
57
+ * gaussian-blurs it (a few hundred bytes), for use behind the real image
58
+ * while it loads.
59
+ */
60
+ blur?: boolean;
61
+ /**
62
+ * Route on-host uploads through the /p/ proxy even when no width/height is
63
+ * requested, so the server still negotiates WebP/AVIF via the Accept header
64
+ * (instead of streaming the original bytes from direct-serve). Use for
65
+ * displayed `<img>` sources; leave off for OG/social images, where the
66
+ * original format is safest.
67
+ */
68
+ forceProxy?: boolean;
69
+ }
54
70
  /**
55
71
  * @param _format - @deprecated Ignored. Always uses 'match' — format is handled server-side via Accept header.
56
72
  */
57
- declare function proxifyImageSrc(url?: string, width?: number, height?: number, _format?: string): string;
73
+ declare function proxifyImageSrc(url?: string, width?: number, height?: number, _format?: string, opts?: ProxifyOptions): string;
58
74
  /**
59
75
  * Builds a srcset string with multiple width variants for responsive images.
60
76
  * Uses the image proxy's width parameter to serve appropriately sized images.
@@ -85,4 +101,4 @@ declare function isValidPermlink(permlink: string): boolean;
85
101
  */
86
102
  declare function simpleMarkdownToHTML(input: string): string;
87
103
 
88
- export { type Entry, IMAGE_SIZES, type RenderOptions, SECTION_LIST, type SeoContext, buildSrcSet, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
104
+ export { type Entry, IMAGE_SIZES, type ProxifyOptions, type RenderOptions, SECTION_LIST, type SeoContext, buildSrcSet, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
@@ -77,6 +77,7 @@ var TRUVVL_REGEX = /^https?:\/\/embed.truvvl.com\/(@[\w.\d-]+)\/(.*)/i;
77
77
  var LBRY_REGEX = /^(https?:)?\/\/lbry.tv\/\$\/embed\/[^?#]+(?:$|[?#])/i;
78
78
  var ODYSEE_REGEX = /^(https?:)?\/\/odysee\.com\/(?:\$|%24)\/embed\/[^?#]+(?:$|[?#])/i;
79
79
  var SKATEHIVE_IPFS_REGEX = /^https?:\/\/ipfs\.skatehive\.app\/ipfs\/([^/?#]+)/i;
80
+ var SKATEHYPE_EMBED_REGEX = /^(https?:)?\/\/(www\.)?skatehype\.com\/ifplay\.php\?v=\d+(?:$|[&#])/i;
80
81
  var ARCH_REGEX = /^(https?:)?\/\/archive.org\/embed\/[^/?#]+(?:$|[?#])/i;
81
82
  var SPEAK_REGEX = /(?:https?:\/\/(?:(?:play\.)?3speak\.([a-z]+)\/watch\?v=)|(?:(?:play\.)?3speak\.([a-z]+)\/embed\?v=))([A-Za-z0-9_\-\.\/]+)(&.*)?/i;
82
83
  var SPEAK_EMBED_REGEX = /^(https?:)?\/\/(?:play\.)?3speak\.([a-z]+)\/(?:embed|watch)\?.+$/i;
@@ -474,9 +475,11 @@ function setProxyBase(p2) {
474
475
  function getProxyBase() {
475
476
  return proxyBase;
476
477
  }
478
+ var PROXY_P_PREFIXES = () => [`${proxyBase}/p/`, "https://images.ecency.com/p/"];
477
479
  function extractPHash(url) {
478
- if (url.startsWith(`${proxyBase}/p/`)) {
479
- const [hash] = url.split("/p/")[1].split("?");
480
+ const prefix = PROXY_P_PREFIXES().find((p2) => url.startsWith(p2));
481
+ if (prefix) {
482
+ const [hash] = url.slice(prefix.length).split("?");
480
483
  return hash.replace(/\.(webp|png)$/, "");
481
484
  }
482
485
  return null;
@@ -492,17 +495,18 @@ function getLatestUrl(str) {
492
495
  const [last] = [...str.replace(/https?:\/\//g, "\n$&").trim().split("\n")].reverse();
493
496
  return last;
494
497
  }
495
- function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
498
+ function proxifyImageSrc(url, width = 0, height = 0, _format = "match", opts = {}) {
496
499
  if (!url || typeof url !== "string" || !isValidUrl(url)) {
497
500
  return "";
498
501
  }
502
+ const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
499
503
  if (url.indexOf("https://images.hive.blog/") === 0 && url.indexOf("https://images.hive.blog/D") !== 0) {
500
504
  return url.replace("https://images.hive.blog", proxyBase);
501
505
  }
502
506
  if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
503
507
  return url.replace("https://steemitimages.com", proxyBase);
504
508
  }
505
- if (url.indexOf("https://images.ecency.com/") === 0) {
509
+ if (url.indexOf("https://images.ecency.com/") === 0 && !routeThroughProxy) {
506
510
  return url.replace("https://images.ecency.com", proxyBase);
507
511
  }
508
512
  const realUrl = getLatestUrl(url);
@@ -517,6 +521,9 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
517
521
  if (height > 0) {
518
522
  options.height = height;
519
523
  }
524
+ if (opts.blur) {
525
+ options.blur = 1;
526
+ }
520
527
  const qs = querystring.stringify(options);
521
528
  if (pHash) {
522
529
  return `${proxyBase}/p/${pHash}?${qs}`;
@@ -577,7 +584,7 @@ function img(el, state) {
577
584
  const base = trimTrailingSlash(getProxyBase());
578
585
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
579
586
  if (shouldReplace && !hasAlreadyProxied) {
580
- const proxified = proxifyImageSrc(decodedSrc);
587
+ const proxified = proxifyImageSrc(decodedSrc, 0, 0, "match", { forceProxy: true });
581
588
  if (proxified) {
582
589
  el.setAttribute("src", proxified);
583
590
  const srcset = buildSrcSet(decodedSrc);
@@ -597,7 +604,7 @@ function img(el, state) {
597
604
  }
598
605
  }
599
606
  function createImageHTML(src, isLCP) {
600
- const proxified = proxifyImageSrc(src);
607
+ const proxified = proxifyImageSrc(src, 0, 0, "match", { forceProxy: true });
601
608
  if (!proxified) return "";
602
609
  const base = trimTrailingSlash(getProxyBase());
603
610
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
@@ -1396,6 +1403,13 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1396
1403
  el.setAttribute("allowfullscreen", "true");
1397
1404
  return;
1398
1405
  }
1406
+ if (src.match(SKATEHYPE_EMBED_REGEX)) {
1407
+ const normalizedSrc = src.replace(/^(https?:)?\/\//i, "https://");
1408
+ el.setAttribute("src", normalizedSrc);
1409
+ el.setAttribute("frameborder", "0");
1410
+ el.setAttribute("allowfullscreen", "true");
1411
+ return;
1412
+ }
1399
1413
  if (src.match(ARCH_REGEX)) {
1400
1414
  el.setAttribute("src", src);
1401
1415
  return;