@ecency/render-helper 2.5.22 → 2.5.24

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.
@@ -60,6 +60,7 @@ declare function catchPostImage(obj: Entry | string, width?: number, height?: nu
60
60
  declare function getPostBodySummary(obj: Entry | string, length?: number, platform?: 'ios' | 'android' | 'web'): string;
61
61
 
62
62
  declare function setProxyBase(p: string): void;
63
+ declare function isLegacySizedProxyUrl(url?: string): boolean;
63
64
  interface ProxifyOptions {
64
65
  /**
65
66
  * Request a tiny blurred LQIP placeholder. The proxy resizes to ~20px and
@@ -159,4 +160,4 @@ declare function isValidPermlink(permlink: string): boolean;
159
160
  */
160
161
  declare function simpleMarkdownToHTML(input: string): string;
161
162
 
162
- export { type Entry, IMAGE_SIZES, type ProxifyOptions, type RenderOptions, SECTION_LIST, type SeoContext, buildPictureSources, buildSrcSet, buildSrcSetForFormat, catchPostImage, getEntryImageRawUrl, isAllowedEmbedSrc, isPictureEligibleRawUrl, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
163
+ export { type Entry, IMAGE_SIZES, type ProxifyOptions, type RenderOptions, SECTION_LIST, type SeoContext, buildPictureSources, buildSrcSet, buildSrcSetForFormat, catchPostImage, getEntryImageRawUrl, isAllowedEmbedSrc, isLegacySizedProxyUrl, isPictureEligibleRawUrl, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
@@ -77,6 +77,7 @@ var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr\.in\/file\/dapplr-videos\/.*/i
77
77
  var TRUVVL_REGEX = /^https?:\/\/embed\.truvvl\.com\/(@[\w.\d-]+)\/(.*)/i;
78
78
  var LBRY_REGEX = /^(https?:)?\/\/lbry\.tv\/\$\/embed\/[^?#]+(?:$|[?#])/i;
79
79
  var ODYSEE_REGEX = /^(https?:)?\/\/odysee\.com\/(?:\$|%24)\/embed\/[^?#]+(?:$|[?#])/i;
80
+ var ODYSEE_WATCH_REGEX = /^(?:https?:)?\/\/odysee\.com\/(@[^/?#\s:"'<>\\]+:[^/?#\s:"'<>\\]+\/[^/?#\s:"'<>\\]+:[^/?#\s:"'<>\\]+|[^@/?#\s:"'<>\\][^/?#\s:"'<>\\]*:[^/?#\s:"'<>\\]+)(?:$|[?#])/i;
80
81
  var SKATEHIVE_IPFS_REGEX = /^https?:\/\/ipfs\.skatehive\.app\/ipfs\/([^/?#]+)/i;
81
82
  var SKATEHYPE_EMBED_REGEX = /^(https?:)?\/\/(www\.)?skatehype\.com\/ifplay\.php\?v=\d+(?:$|[&#])/i;
82
83
  var ARCH_REGEX = /^(https?:)?\/\/archive\.org\/embed\/[^/?#]+(?:$|[?#])/i;
@@ -250,7 +251,13 @@ var EMBED_HOST_PATH_PATTERNS = {
250
251
  "www.rumble.com": /^\/embed\//,
251
252
  "rumble.com": /^\/embed\//,
252
253
  "www.brighteon.com": /^\/embed\//,
253
- "brighteon.com": /^\/embed\//
254
+ "brighteon.com": /^\/embed\//,
255
+ // Odysee's embed route is /$/embed/<claim path>. Both the literal `$` and its
256
+ // percent-encoded spelling occur in the wild: the renderer emits the literal
257
+ // form, while Odysee's own share dialog hands out fully-encoded URLs, and
258
+ // `URL.pathname` does not decode either. ODYSEE_REGEX accepts both for the
259
+ // same reason.
260
+ "odysee.com": /^\/(?:\$|%24)\/embed\//
254
261
  };
255
262
  function isAllowedEmbedSrc(value) {
256
263
  if (!value) return false;
@@ -594,6 +601,40 @@ function isValidUrl(url) {
594
601
  return false;
595
602
  }
596
603
  }
604
+ var MAX_PROXIED_URL_LENGTH = 2048;
605
+ var LEGACY_SIZED_PROXY_RE = /^https:\/\/(?:images\.hive\.blog|steemitimages\.com)\/\d+x\d+\/(.+)$/;
606
+ function isLegacySizedProxyUrl(url) {
607
+ if (!url || typeof url !== "string") return false;
608
+ return LEGACY_SIZED_PROXY_RE.test(url);
609
+ }
610
+ function extractLegacySizedSource(url) {
611
+ const m = LEGACY_SIZED_PROXY_RE.exec(url);
612
+ if (!m) return null;
613
+ const rest = m[1];
614
+ const hashIndex = rest.indexOf("#");
615
+ const addressable = hashIndex >= 0 ? rest.slice(0, hashIndex) : rest;
616
+ const qIndex = addressable.indexOf("?");
617
+ const path = qIndex >= 0 ? addressable.slice(0, qIndex) : addressable;
618
+ const query = qIndex >= 0 ? addressable.slice(qIndex + 1) : "";
619
+ let end = path.length;
620
+ while (end > 0 && path.charCodeAt(end - 1) === 47) {
621
+ end--;
622
+ }
623
+ try {
624
+ const inner = new URL(path.slice(0, end));
625
+ if (query) {
626
+ for (const [key, value] of new URLSearchParams(query)) {
627
+ inner.searchParams.append(key, value);
628
+ }
629
+ }
630
+ return inner.toString();
631
+ } catch {
632
+ return null;
633
+ }
634
+ }
635
+ function isLegacyForeignProxyUrl(url) {
636
+ return url.indexOf("https://images.hive.blog/") === 0 && url.indexOf("https://images.hive.blog/D") !== 0 || url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0;
637
+ }
597
638
  function getLatestUrl(str) {
598
639
  const [last] = [...str.replace(/https?:\/\//g, "\n$&").trim().split("\n")].reverse();
599
640
  return last;
@@ -602,17 +643,17 @@ function proxifyForFormat(url, width = 0, height = 0, format = "match", opts = {
602
643
  if (!url || typeof url !== "string" || !isValidUrl(url)) {
603
644
  return "";
604
645
  }
605
- const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
606
- if (url.indexOf("https://images.hive.blog/") === 0 && url.indexOf("https://images.hive.blog/D") !== 0) {
607
- return url.replace("https://images.hive.blog", proxyBase);
646
+ if (url.length > MAX_PROXIED_URL_LENGTH) {
647
+ return "";
608
648
  }
609
- if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
610
- return url.replace("https://steemitimages.com", proxyBase);
649
+ const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
650
+ if (isLegacyForeignProxyUrl(url) && !(isLegacySizedProxyUrl(url) && routeThroughProxy)) {
651
+ return url.replace("https://images.hive.blog", proxyBase).replace("https://steemitimages.com", proxyBase);
611
652
  }
612
653
  if (url.indexOf("https://images.ecency.com/") === 0 && !routeThroughProxy) {
613
654
  return url.replace("https://images.ecency.com", proxyBase);
614
655
  }
615
- const realUrl = getLatestUrl(url);
656
+ const realUrl = extractLegacySizedSource(url) ?? getLatestUrl(url);
616
657
  const pHash = extractPHash(realUrl);
617
658
  const options = {
618
659
  format,
@@ -672,6 +713,7 @@ function isPictureEligibleRawUrl(rawUrl) {
672
713
  return false;
673
714
  }
674
715
  if (u.protocol !== "http:" && u.protocol !== "https:") return false;
716
+ if (isLegacySizedProxyUrl(rawUrl)) return true;
675
717
  const host = `${u.protocol}//${u.host}`;
676
718
  const isProxyHost = host === proxyBase || host === "https://images.ecency.com";
677
719
  if (isProxyHost && (u.pathname.startsWith("/p/") || u.pathname.startsWith("/u/") || SIZED_PROXY_PATH.test(u.pathname))) {
@@ -854,6 +896,33 @@ function getExternalLinkRel(seoContext) {
854
896
  }
855
897
  return "nofollow ugc noopener";
856
898
  }
899
+ function renderPlainVideoLink(el, provider, embedSrc, renderOptions) {
900
+ const baseClass = `markdown-video-link markdown-video-link-${provider}`;
901
+ el.setAttribute("class", baseClass);
902
+ el.removeAttribute("href");
903
+ el.textContent = "";
904
+ el.setAttribute("data-embed-src", embedSrc);
905
+ if (renderOptions?.embedVideosDirectly) {
906
+ const wrapper = el.ownerDocument.createElement("span");
907
+ wrapper.setAttribute("class", "er-embed-frame");
908
+ wrapper.setAttribute("style", "display:block");
909
+ const frame = el.ownerDocument.createElement("iframe");
910
+ frame.setAttribute("src", embedSrc);
911
+ frame.setAttribute("title", "Video player");
912
+ frame.setAttribute(
913
+ "allow",
914
+ "accelerometer; encrypted-media; gyroscope; picture-in-picture; web-share"
915
+ );
916
+ frame.setAttribute("allowfullscreen", "");
917
+ wrapper.appendChild(frame);
918
+ el.appendChild(wrapper);
919
+ el.setAttribute("class", `${baseClass} er-embed`);
920
+ return;
921
+ }
922
+ const play = el.ownerDocument.createElement("span");
923
+ play.setAttribute("class", "markdown-video-play");
924
+ el.appendChild(play);
925
+ }
857
926
  var normalizeValue = (value) => value ? value.trim() : "";
858
927
  var matchesHref = (href, value) => {
859
928
  const normalizedHref = normalizeValue(href);
@@ -1192,41 +1261,22 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1192
1261
  }
1193
1262
  const BCmatch = href.match(BITCHUTE_REGEX);
1194
1263
  if (BCmatch && BCmatch[1] && el.textContent.trim() === href) {
1195
- const vid = BCmatch[1];
1196
- el.setAttribute("class", "markdown-video-link");
1197
- el.removeAttribute("href");
1198
- const embedSrc = `https://www.bitchute.com/embed/${vid}/`;
1199
- el.textContent = "";
1200
- el.setAttribute("data-embed-src", embedSrc);
1201
- const play = el.ownerDocument.createElement("span");
1202
- play.setAttribute("class", "markdown-video-play");
1203
- el.appendChild(play);
1264
+ renderPlainVideoLink(el, "bitchute", `https://www.bitchute.com/embed/${BCmatch[1]}/`, renderOptions);
1204
1265
  return;
1205
1266
  }
1206
1267
  const RBmatch = href.match(RUMBLE_REGEX);
1207
1268
  if (RBmatch && RBmatch[1] && el.textContent.trim() === href) {
1208
- const vid = RBmatch[1];
1209
- const embedSrc = `https://www.rumble.com/embed/${vid}/?pub=4`;
1210
- el.setAttribute("class", "markdown-video-link");
1211
- el.removeAttribute("href");
1212
- el.textContent = "";
1213
- el.setAttribute("data-embed-src", embedSrc);
1214
- const play = el.ownerDocument.createElement("span");
1215
- play.setAttribute("class", "markdown-video-play");
1216
- el.appendChild(play);
1269
+ renderPlainVideoLink(el, "rumble", `https://www.rumble.com/embed/${RBmatch[1]}/?pub=4`, renderOptions);
1217
1270
  return;
1218
1271
  }
1219
1272
  const BNmatch = href.match(BRIGHTEON_REGEX);
1220
1273
  if (BNmatch && BNmatch[2] && el.textContent.trim() === href) {
1221
- const vid = BNmatch[2];
1222
- const embedSrc = `https://www.brighteon.com/embed/${vid}`;
1223
- el.setAttribute("class", "markdown-video-link");
1224
- el.removeAttribute("href");
1225
- el.textContent = "";
1226
- el.setAttribute("data-embed-src", embedSrc);
1227
- const play = el.ownerDocument.createElement("span");
1228
- play.setAttribute("class", "markdown-video-play");
1229
- el.appendChild(play);
1274
+ renderPlainVideoLink(el, "brighteon", `https://www.brighteon.com/embed/${BNmatch[2]}`, renderOptions);
1275
+ return;
1276
+ }
1277
+ const ODmatch = href.match(ODYSEE_WATCH_REGEX);
1278
+ if (ODmatch && ODmatch[1] && el.textContent.trim() === href) {
1279
+ renderPlainVideoLink(el, "odysee", `https://odysee.com/$/embed/${ODmatch[1]}`, renderOptions);
1230
1280
  return;
1231
1281
  }
1232
1282
  let match = href.match(YOUTUBE_REGEX);
@@ -2363,6 +2413,6 @@ function getPostBodySummary(obj, length, platform) {
2363
2413
  return res;
2364
2414
  }
2365
2415
 
2366
- export { IMAGE_SIZES, SECTION_LIST, buildPictureSources, buildSrcSet, buildSrcSetForFormat, catchPostImage, getEntryImageRawUrl, isAllowedEmbedSrc, isPictureEligibleRawUrl, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
2416
+ export { IMAGE_SIZES, SECTION_LIST, buildPictureSources, buildSrcSet, buildSrcSetForFormat, catchPostImage, getEntryImageRawUrl, isAllowedEmbedSrc, isLegacySizedProxyUrl, isPictureEligibleRawUrl, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
2367
2417
  //# sourceMappingURL=index.js.map
2368
2418
  //# sourceMappingURL=index.js.map