@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.
@@ -105,6 +105,7 @@ var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr\.in\/file\/dapplr-videos\/.*/i
105
105
  var TRUVVL_REGEX = /^https?:\/\/embed\.truvvl\.com\/(@[\w.\d-]+)\/(.*)/i;
106
106
  var LBRY_REGEX = /^(https?:)?\/\/lbry\.tv\/\$\/embed\/[^?#]+(?:$|[?#])/i;
107
107
  var ODYSEE_REGEX = /^(https?:)?\/\/odysee\.com\/(?:\$|%24)\/embed\/[^?#]+(?:$|[?#])/i;
108
+ var ODYSEE_WATCH_REGEX = /^(?:https?:)?\/\/odysee\.com\/(@[^/?#\s:"'<>\\]+:[^/?#\s:"'<>\\]+\/[^/?#\s:"'<>\\]+:[^/?#\s:"'<>\\]+|[^@/?#\s:"'<>\\][^/?#\s:"'<>\\]*:[^/?#\s:"'<>\\]+)(?:$|[?#])/i;
108
109
  var SKATEHIVE_IPFS_REGEX = /^https?:\/\/ipfs\.skatehive\.app\/ipfs\/([^/?#]+)/i;
109
110
  var SKATEHYPE_EMBED_REGEX = /^(https?:)?\/\/(www\.)?skatehype\.com\/ifplay\.php\?v=\d+(?:$|[&#])/i;
110
111
  var ARCH_REGEX = /^(https?:)?\/\/archive\.org\/embed\/[^/?#]+(?:$|[?#])/i;
@@ -278,7 +279,13 @@ var EMBED_HOST_PATH_PATTERNS = {
278
279
  "www.rumble.com": /^\/embed\//,
279
280
  "rumble.com": /^\/embed\//,
280
281
  "www.brighteon.com": /^\/embed\//,
281
- "brighteon.com": /^\/embed\//
282
+ "brighteon.com": /^\/embed\//,
283
+ // Odysee's embed route is /$/embed/<claim path>. Both the literal `$` and its
284
+ // percent-encoded spelling occur in the wild: the renderer emits the literal
285
+ // form, while Odysee's own share dialog hands out fully-encoded URLs, and
286
+ // `URL.pathname` does not decode either. ODYSEE_REGEX accepts both for the
287
+ // same reason.
288
+ "odysee.com": /^\/(?:\$|%24)\/embed\//
282
289
  };
283
290
  function isAllowedEmbedSrc(value) {
284
291
  if (!value) return false;
@@ -622,6 +629,40 @@ function isValidUrl(url) {
622
629
  return false;
623
630
  }
624
631
  }
632
+ var MAX_PROXIED_URL_LENGTH = 2048;
633
+ var LEGACY_SIZED_PROXY_RE = /^https:\/\/(?:images\.hive\.blog|steemitimages\.com)\/\d+x\d+\/(.+)$/;
634
+ function isLegacySizedProxyUrl(url) {
635
+ if (!url || typeof url !== "string") return false;
636
+ return LEGACY_SIZED_PROXY_RE.test(url);
637
+ }
638
+ function extractLegacySizedSource(url) {
639
+ const m = LEGACY_SIZED_PROXY_RE.exec(url);
640
+ if (!m) return null;
641
+ const rest = m[1];
642
+ const hashIndex = rest.indexOf("#");
643
+ const addressable = hashIndex >= 0 ? rest.slice(0, hashIndex) : rest;
644
+ const qIndex = addressable.indexOf("?");
645
+ const path = qIndex >= 0 ? addressable.slice(0, qIndex) : addressable;
646
+ const query = qIndex >= 0 ? addressable.slice(qIndex + 1) : "";
647
+ let end = path.length;
648
+ while (end > 0 && path.charCodeAt(end - 1) === 47) {
649
+ end--;
650
+ }
651
+ try {
652
+ const inner = new URL(path.slice(0, end));
653
+ if (query) {
654
+ for (const [key, value] of new URLSearchParams(query)) {
655
+ inner.searchParams.append(key, value);
656
+ }
657
+ }
658
+ return inner.toString();
659
+ } catch {
660
+ return null;
661
+ }
662
+ }
663
+ function isLegacyForeignProxyUrl(url) {
664
+ 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;
665
+ }
625
666
  function getLatestUrl(str) {
626
667
  const [last] = [...str.replace(/https?:\/\//g, "\n$&").trim().split("\n")].reverse();
627
668
  return last;
@@ -630,17 +671,17 @@ function proxifyForFormat(url, width = 0, height = 0, format = "match", opts = {
630
671
  if (!url || typeof url !== "string" || !isValidUrl(url)) {
631
672
  return "";
632
673
  }
633
- const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
634
- if (url.indexOf("https://images.hive.blog/") === 0 && url.indexOf("https://images.hive.blog/D") !== 0) {
635
- return url.replace("https://images.hive.blog", proxyBase);
674
+ if (url.length > MAX_PROXIED_URL_LENGTH) {
675
+ return "";
636
676
  }
637
- if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
638
- return url.replace("https://steemitimages.com", proxyBase);
677
+ const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
678
+ if (isLegacyForeignProxyUrl(url) && !(isLegacySizedProxyUrl(url) && routeThroughProxy)) {
679
+ return url.replace("https://images.hive.blog", proxyBase).replace("https://steemitimages.com", proxyBase);
639
680
  }
640
681
  if (url.indexOf("https://images.ecency.com/") === 0 && !routeThroughProxy) {
641
682
  return url.replace("https://images.ecency.com", proxyBase);
642
683
  }
643
- const realUrl = getLatestUrl(url);
684
+ const realUrl = extractLegacySizedSource(url) ?? getLatestUrl(url);
644
685
  const pHash = extractPHash(realUrl);
645
686
  const options = {
646
687
  format,
@@ -700,6 +741,7 @@ function isPictureEligibleRawUrl(rawUrl) {
700
741
  return false;
701
742
  }
702
743
  if (u.protocol !== "http:" && u.protocol !== "https:") return false;
744
+ if (isLegacySizedProxyUrl(rawUrl)) return true;
703
745
  const host = `${u.protocol}//${u.host}`;
704
746
  const isProxyHost = host === proxyBase || host === "https://images.ecency.com";
705
747
  if (isProxyHost && (u.pathname.startsWith("/p/") || u.pathname.startsWith("/u/") || SIZED_PROXY_PATH.test(u.pathname))) {
@@ -882,6 +924,33 @@ function getExternalLinkRel(seoContext) {
882
924
  }
883
925
  return "nofollow ugc noopener";
884
926
  }
927
+ function renderPlainVideoLink(el, provider, embedSrc, renderOptions) {
928
+ const baseClass = `markdown-video-link markdown-video-link-${provider}`;
929
+ el.setAttribute("class", baseClass);
930
+ el.removeAttribute("href");
931
+ el.textContent = "";
932
+ el.setAttribute("data-embed-src", embedSrc);
933
+ if (renderOptions?.embedVideosDirectly) {
934
+ const wrapper = el.ownerDocument.createElement("span");
935
+ wrapper.setAttribute("class", "er-embed-frame");
936
+ wrapper.setAttribute("style", "display:block");
937
+ const frame = el.ownerDocument.createElement("iframe");
938
+ frame.setAttribute("src", embedSrc);
939
+ frame.setAttribute("title", "Video player");
940
+ frame.setAttribute(
941
+ "allow",
942
+ "accelerometer; encrypted-media; gyroscope; picture-in-picture; web-share"
943
+ );
944
+ frame.setAttribute("allowfullscreen", "");
945
+ wrapper.appendChild(frame);
946
+ el.appendChild(wrapper);
947
+ el.setAttribute("class", `${baseClass} er-embed`);
948
+ return;
949
+ }
950
+ const play = el.ownerDocument.createElement("span");
951
+ play.setAttribute("class", "markdown-video-play");
952
+ el.appendChild(play);
953
+ }
885
954
  var normalizeValue = (value) => value ? value.trim() : "";
886
955
  var matchesHref = (href, value) => {
887
956
  const normalizedHref = normalizeValue(href);
@@ -1220,41 +1289,22 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1220
1289
  }
1221
1290
  const BCmatch = href.match(BITCHUTE_REGEX);
1222
1291
  if (BCmatch && BCmatch[1] && el.textContent.trim() === href) {
1223
- const vid = BCmatch[1];
1224
- el.setAttribute("class", "markdown-video-link");
1225
- el.removeAttribute("href");
1226
- const embedSrc = `https://www.bitchute.com/embed/${vid}/`;
1227
- el.textContent = "";
1228
- el.setAttribute("data-embed-src", embedSrc);
1229
- const play = el.ownerDocument.createElement("span");
1230
- play.setAttribute("class", "markdown-video-play");
1231
- el.appendChild(play);
1292
+ renderPlainVideoLink(el, "bitchute", `https://www.bitchute.com/embed/${BCmatch[1]}/`, renderOptions);
1232
1293
  return;
1233
1294
  }
1234
1295
  const RBmatch = href.match(RUMBLE_REGEX);
1235
1296
  if (RBmatch && RBmatch[1] && el.textContent.trim() === href) {
1236
- const vid = RBmatch[1];
1237
- const embedSrc = `https://www.rumble.com/embed/${vid}/?pub=4`;
1238
- el.setAttribute("class", "markdown-video-link");
1239
- el.removeAttribute("href");
1240
- el.textContent = "";
1241
- el.setAttribute("data-embed-src", embedSrc);
1242
- const play = el.ownerDocument.createElement("span");
1243
- play.setAttribute("class", "markdown-video-play");
1244
- el.appendChild(play);
1297
+ renderPlainVideoLink(el, "rumble", `https://www.rumble.com/embed/${RBmatch[1]}/?pub=4`, renderOptions);
1245
1298
  return;
1246
1299
  }
1247
1300
  const BNmatch = href.match(BRIGHTEON_REGEX);
1248
1301
  if (BNmatch && BNmatch[2] && el.textContent.trim() === href) {
1249
- const vid = BNmatch[2];
1250
- const embedSrc = `https://www.brighteon.com/embed/${vid}`;
1251
- el.setAttribute("class", "markdown-video-link");
1252
- el.removeAttribute("href");
1253
- el.textContent = "";
1254
- el.setAttribute("data-embed-src", embedSrc);
1255
- const play = el.ownerDocument.createElement("span");
1256
- play.setAttribute("class", "markdown-video-play");
1257
- el.appendChild(play);
1302
+ renderPlainVideoLink(el, "brighteon", `https://www.brighteon.com/embed/${BNmatch[2]}`, renderOptions);
1303
+ return;
1304
+ }
1305
+ const ODmatch = href.match(ODYSEE_WATCH_REGEX);
1306
+ if (ODmatch && ODmatch[1] && el.textContent.trim() === href) {
1307
+ renderPlainVideoLink(el, "odysee", `https://odysee.com/$/embed/${ODmatch[1]}`, renderOptions);
1258
1308
  return;
1259
1309
  }
1260
1310
  let match = href.match(YOUTUBE_REGEX);
@@ -2399,6 +2449,7 @@ exports.buildSrcSetForFormat = buildSrcSetForFormat;
2399
2449
  exports.catchPostImage = catchPostImage;
2400
2450
  exports.getEntryImageRawUrl = getEntryImageRawUrl;
2401
2451
  exports.isAllowedEmbedSrc = isAllowedEmbedSrc;
2452
+ exports.isLegacySizedProxyUrl = isLegacySizedProxyUrl;
2402
2453
  exports.isPictureEligibleRawUrl = isPictureEligibleRawUrl;
2403
2454
  exports.isValidPermlink = isValidPermlink;
2404
2455
  exports.postBodySummary = getPostBodySummary;