@ecency/render-helper 2.5.5 → 2.5.7

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.
@@ -64,19 +64,20 @@ var INTERNAL_POST_TAG_REGEX = /^(.+?)\/(@[\w.\d-]+)\/(.*)$/i;
64
64
  var INTERNAL_POST_REGEX = /^\/(@[\w.\d-]+)\/(.*)$/i;
65
65
  var CUSTOM_COMMUNITY_REGEX = /^https?:\/\/(.*)\/c\/(hive-\d+)(.*)/i;
66
66
  var YOUTUBE_REGEX = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|shorts\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i;
67
- var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www.youtube.com\/(embed|shorts)\/.*/i;
67
+ var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www\.youtube\.com\/(embed|shorts)\/.*/i;
68
68
  var VIMEO_REGEX = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i;
69
69
  var VIMEO_EMBED_REGEX = /https:\/\/player\.vimeo\.com\/video\/([0-9]+)(?:$|[?#])/;
70
- var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute.com\/(?:video|embed)\/([a-z0-9]+)/i;
70
+ var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute\.com\/(?:video|embed)\/([a-z0-9]+)/i;
71
71
  var D_TUBE_REGEX = /(https?:\/\/d\.tube\/#!\/v\/)(\w+)\/(\w+)/g;
72
72
  var D_TUBE_REGEX2 = /(https?:\/\/d\.tube\/v\/)(\w+)\/(\w+)/g;
73
73
  var D_TUBE_EMBED_REGEX = /^https:\/\/emb.d.tube\/#!\/[^/?#]+\/[^/?#]+(?:$|[?#])/i;
74
- var TWITCH_REGEX = /https?:\/\/(?:www.)?twitch.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
74
+ var TWITCH_REGEX = /https?:\/\/(?:www\.)?twitch\.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
75
75
  var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr.in\/file\/dapplr-videos\/.*/i;
76
76
  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;
@@ -84,15 +85,15 @@ var SPEAK_AUDIO_REGEX = /https?:\/\/audio\.3speak\.tv\/play\?[^\s]+/i;
84
85
  var SPEAK_AUDIO_EMBED_REGEX = /^https?:\/\/audio\.3speak\.tv\/play\?.+$/i;
85
86
  var TWITTER_REGEX = /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/gi;
86
87
  var SPOTIFY_REGEX = /^https:\/\/open\.spotify\.com\/playlist\/(.*)?$/gi;
87
- var RUMBLE_REGEX = /^https:\/\/rumble.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
88
+ var RUMBLE_REGEX = /^https:\/\/rumble\.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
88
89
  var BRIGHTEON_REGEX = /^https?:\/\/(www\.)?brighteon\.com\/(?:embed\/)?(.*[0-9].*)/i;
89
- var VIMM_EMBED_REGEX = /^https:\/\/www.vimm.tv\/[^?#]+(?:$|[?#])/i;
90
+ var VIMM_EMBED_REGEX = /^https:\/\/www\.vimm\.tv\/[^?#]+(?:$|[?#])/i;
90
91
  var SPOTIFY_EMBED_REGEX = /^https:\/\/open\.spotify\.com\/(embed|embed-podcast)\/(playlist|show|episode|track|album)\/([^/?#]+)(?:$|[?#])/i;
91
- var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w.soundcloud.com\/player\/\?[^#]+$/i;
92
- var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player.twitch.tv\/(?:\?[^/]+)?$/i;
92
+ var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w\.soundcloud\.com\/player\/\?[^#]+$/i;
93
+ var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player\.twitch\.tv\/(?:\?[^/]+)?$/i;
93
94
  var BRAND_NEW_TUBE_REGEX = /^https:\/\/brandnewtube\.com\/embed\/[a-z0-9]+$/i;
94
- var LOOM_REGEX = /^(https?:)?\/\/www.loom.com\/share\/([^/?#]+)(?:$|[?#])/i;
95
- var LOOM_EMBED_REGEX = /^(https?:)?\/\/www.loom.com\/embed\/([^/?#]+)(?:$|[?#])/i;
95
+ var LOOM_REGEX = /^(https?:)?\/\/www\.loom\.com\/share\/([^/?#]+)(?:$|[?#])/i;
96
+ var LOOM_EMBED_REGEX = /^(https?:)?\/\/www\.loom\.com\/embed\/([^/?#]+)(?:$|[?#])/i;
96
97
  var AUREAL_EMBED_REGEX = /^(https?:)?\/\/(www\.)?(?:aureal-embed)\.web\.app\/([0-9]+)(?:$|[?#])/i;
97
98
  var ENTITY_REGEX = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/ig;
98
99
  var SECTION_REGEX = /\B(\#[\da-zA-Z-_]+\b)(?!;)/i;
@@ -444,12 +445,12 @@ function sanitizeHtml(html) {
444
445
  const decoded = decodeEntities(value.trim());
445
446
  const decodedLower = decoded.toLowerCase();
446
447
  if (name.startsWith("on")) return "";
447
- if (tag === "img" && name === "src" && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
448
+ if (tag === "img" && name === "src" && !/^https?:\/\//.test(decodedLower)) return "";
448
449
  if (tag === "img" && name === "srcset") {
449
450
  const candidates = decoded.split(",").map((c) => c.trim().split(/\s+/)[0]);
450
- if (candidates.some((url) => !/^https?:\/\//.test(url))) return "";
451
+ if (candidates.some((url) => !/^https?:\/\//i.test(url))) return "";
451
452
  }
452
- if (tag === "video" && ["src", "poster"].includes(name) && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
453
+ if (tag === "video" && ["src", "poster"].includes(name) && !/^https?:\/\//.test(decodedLower)) return "";
453
454
  if (tag === "img" && ["dynsrc", "lowsrc"].includes(name)) return "";
454
455
  if (tag === "span" && name === "class" && decoded.toLowerCase().trim() === "wr") return "";
455
456
  if (name === "id") {
@@ -527,11 +528,11 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
527
528
  var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
528
529
  function buildSrcSet(url) {
529
530
  if (!url || typeof url !== "string") return "";
530
- const escapedBase = proxyBase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
531
- const proxyPattern = new RegExp(`^${escapedBase}/p/([^?]+)`);
532
- const match = url.match(proxyPattern);
533
- if (match) {
534
- const phash = extractPHash(url) || match[1];
531
+ const proxyPrefix = `${proxyBase}/p/`;
532
+ if (url.startsWith(proxyPrefix)) {
533
+ const rest = url.slice(proxyPrefix.length);
534
+ const q = rest.indexOf("?");
535
+ const phash = extractPHash(url) || (q >= 0 ? rest.slice(0, q) : rest);
535
536
  return SRCSET_WIDTHS.map((w) => `${proxyBase}/p/${phash}?format=match&mode=fit&width=${w} ${w}w`).join(", ");
536
537
  }
537
538
  return SRCSET_WIDTHS.map((w) => {
@@ -670,7 +671,10 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
670
671
  if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
671
672
  return;
672
673
  }
673
- if (href && href.trim().toLowerCase().startsWith("javascript:")) {
674
+ const trimmed = href.trim().replace(/[\t\n\r\f\v\0]/g, "").toLowerCase();
675
+ const isSafeScheme = /^(https?|mailto|hive|tel|web\+[a-z0-9.+-]+):/i.test(trimmed);
676
+ const isRelative = /^(\/\/|\/[^/]?|#|\?|[a-z0-9._\-]+(\/|$))/i.test(trimmed);
677
+ if (!isSafeScheme && !isRelative) {
674
678
  el.removeAttribute("href");
675
679
  return;
676
680
  }
@@ -1393,6 +1397,13 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1393
1397
  el.setAttribute("allowfullscreen", "true");
1394
1398
  return;
1395
1399
  }
1400
+ if (src.match(SKATEHYPE_EMBED_REGEX)) {
1401
+ const normalizedSrc = src.replace(/^(https?:)?\/\//i, "https://");
1402
+ el.setAttribute("src", normalizedSrc);
1403
+ el.setAttribute("frameborder", "0");
1404
+ el.setAttribute("allowfullscreen", "true");
1405
+ return;
1406
+ }
1396
1407
  if (src.match(ARCH_REGEX)) {
1397
1408
  el.setAttribute("src", src);
1398
1409
  return;
@@ -1445,7 +1456,7 @@ function linkify(content, forApp, renderOptions) {
1445
1456
  content = content.replace(/(^|\s|>)(#[-a-z\d]+)/gi, (tag) => {
1446
1457
  if (/#[\d]+$/.test(tag)) return tag;
1447
1458
  const preceding = /^\s|>/.test(tag) ? tag[0] : "";
1448
- tag = tag.replace(">", "");
1459
+ tag = tag.replace(/^>/, "");
1449
1460
  const tag2 = tag.trim().substring(1);
1450
1461
  const tagLower = tag2.toLowerCase();
1451
1462
  if (!forApp) {