@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.
@@ -93,19 +93,20 @@ var INTERNAL_POST_TAG_REGEX = /^(.+?)\/(@[\w.\d-]+)\/(.*)$/i;
93
93
  var INTERNAL_POST_REGEX = /^\/(@[\w.\d-]+)\/(.*)$/i;
94
94
  var CUSTOM_COMMUNITY_REGEX = /^https?:\/\/(.*)\/c\/(hive-\d+)(.*)/i;
95
95
  var YOUTUBE_REGEX = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|shorts\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i;
96
- var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www.youtube.com\/(embed|shorts)\/.*/i;
96
+ var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www\.youtube\.com\/(embed|shorts)\/.*/i;
97
97
  var VIMEO_REGEX = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i;
98
98
  var VIMEO_EMBED_REGEX = /https:\/\/player\.vimeo\.com\/video\/([0-9]+)(?:$|[?#])/;
99
- var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute.com\/(?:video|embed)\/([a-z0-9]+)/i;
99
+ var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute\.com\/(?:video|embed)\/([a-z0-9]+)/i;
100
100
  var D_TUBE_REGEX = /(https?:\/\/d\.tube\/#!\/v\/)(\w+)\/(\w+)/g;
101
101
  var D_TUBE_REGEX2 = /(https?:\/\/d\.tube\/v\/)(\w+)\/(\w+)/g;
102
102
  var D_TUBE_EMBED_REGEX = /^https:\/\/emb.d.tube\/#!\/[^/?#]+\/[^/?#]+(?:$|[?#])/i;
103
- var TWITCH_REGEX = /https?:\/\/(?:www.)?twitch.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
103
+ var TWITCH_REGEX = /https?:\/\/(?:www\.)?twitch\.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
104
104
  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
108
  var SKATEHIVE_IPFS_REGEX = /^https?:\/\/ipfs\.skatehive\.app\/ipfs\/([^/?#]+)/i;
109
+ var SKATEHYPE_EMBED_REGEX = /^(https?:)?\/\/(www\.)?skatehype\.com\/ifplay\.php\?v=\d+(?:$|[&#])/i;
109
110
  var ARCH_REGEX = /^(https?:)?\/\/archive.org\/embed\/[^/?#]+(?:$|[?#])/i;
110
111
  var SPEAK_REGEX = /(?:https?:\/\/(?:(?:play\.)?3speak\.([a-z]+)\/watch\?v=)|(?:(?:play\.)?3speak\.([a-z]+)\/embed\?v=))([A-Za-z0-9_\-\.\/]+)(&.*)?/i;
111
112
  var SPEAK_EMBED_REGEX = /^(https?:)?\/\/(?:play\.)?3speak\.([a-z]+)\/(?:embed|watch)\?.+$/i;
@@ -113,15 +114,15 @@ var SPEAK_AUDIO_REGEX = /https?:\/\/audio\.3speak\.tv\/play\?[^\s]+/i;
113
114
  var SPEAK_AUDIO_EMBED_REGEX = /^https?:\/\/audio\.3speak\.tv\/play\?.+$/i;
114
115
  var TWITTER_REGEX = /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/gi;
115
116
  var SPOTIFY_REGEX = /^https:\/\/open\.spotify\.com\/playlist\/(.*)?$/gi;
116
- var RUMBLE_REGEX = /^https:\/\/rumble.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
117
+ var RUMBLE_REGEX = /^https:\/\/rumble\.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
117
118
  var BRIGHTEON_REGEX = /^https?:\/\/(www\.)?brighteon\.com\/(?:embed\/)?(.*[0-9].*)/i;
118
- var VIMM_EMBED_REGEX = /^https:\/\/www.vimm.tv\/[^?#]+(?:$|[?#])/i;
119
+ var VIMM_EMBED_REGEX = /^https:\/\/www\.vimm\.tv\/[^?#]+(?:$|[?#])/i;
119
120
  var SPOTIFY_EMBED_REGEX = /^https:\/\/open\.spotify\.com\/(embed|embed-podcast)\/(playlist|show|episode|track|album)\/([^/?#]+)(?:$|[?#])/i;
120
- var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w.soundcloud.com\/player\/\?[^#]+$/i;
121
- var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player.twitch.tv\/(?:\?[^/]+)?$/i;
121
+ var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w\.soundcloud\.com\/player\/\?[^#]+$/i;
122
+ var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player\.twitch\.tv\/(?:\?[^/]+)?$/i;
122
123
  var BRAND_NEW_TUBE_REGEX = /^https:\/\/brandnewtube\.com\/embed\/[a-z0-9]+$/i;
123
- var LOOM_REGEX = /^(https?:)?\/\/www.loom.com\/share\/([^/?#]+)(?:$|[?#])/i;
124
- var LOOM_EMBED_REGEX = /^(https?:)?\/\/www.loom.com\/embed\/([^/?#]+)(?:$|[?#])/i;
124
+ var LOOM_REGEX = /^(https?:)?\/\/www\.loom\.com\/share\/([^/?#]+)(?:$|[?#])/i;
125
+ var LOOM_EMBED_REGEX = /^(https?:)?\/\/www\.loom\.com\/embed\/([^/?#]+)(?:$|[?#])/i;
125
126
  var AUREAL_EMBED_REGEX = /^(https?:)?\/\/(www\.)?(?:aureal-embed)\.web\.app\/([0-9]+)(?:$|[?#])/i;
126
127
  var ENTITY_REGEX = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/ig;
127
128
  var SECTION_REGEX = /\B(\#[\da-zA-Z-_]+\b)(?!;)/i;
@@ -473,12 +474,12 @@ function sanitizeHtml(html) {
473
474
  const decoded = decodeEntities(value.trim());
474
475
  const decodedLower = decoded.toLowerCase();
475
476
  if (name.startsWith("on")) return "";
476
- if (tag === "img" && name === "src" && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
477
+ if (tag === "img" && name === "src" && !/^https?:\/\//.test(decodedLower)) return "";
477
478
  if (tag === "img" && name === "srcset") {
478
479
  const candidates = decoded.split(",").map((c) => c.trim().split(/\s+/)[0]);
479
- if (candidates.some((url) => !/^https?:\/\//.test(url))) return "";
480
+ if (candidates.some((url) => !/^https?:\/\//i.test(url))) return "";
480
481
  }
481
- if (tag === "video" && ["src", "poster"].includes(name) && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
482
+ if (tag === "video" && ["src", "poster"].includes(name) && !/^https?:\/\//.test(decodedLower)) return "";
482
483
  if (tag === "img" && ["dynsrc", "lowsrc"].includes(name)) return "";
483
484
  if (tag === "span" && name === "class" && decoded.toLowerCase().trim() === "wr") return "";
484
485
  if (name === "id") {
@@ -556,11 +557,11 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
556
557
  var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
557
558
  function buildSrcSet(url) {
558
559
  if (!url || typeof url !== "string") return "";
559
- const escapedBase = proxyBase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
560
- const proxyPattern = new RegExp(`^${escapedBase}/p/([^?]+)`);
561
- const match = url.match(proxyPattern);
562
- if (match) {
563
- const phash = extractPHash(url) || match[1];
560
+ const proxyPrefix = `${proxyBase}/p/`;
561
+ if (url.startsWith(proxyPrefix)) {
562
+ const rest = url.slice(proxyPrefix.length);
563
+ const q = rest.indexOf("?");
564
+ const phash = extractPHash(url) || (q >= 0 ? rest.slice(0, q) : rest);
564
565
  return SRCSET_WIDTHS.map((w) => `${proxyBase}/p/${phash}?format=match&mode=fit&width=${w} ${w}w`).join(", ");
565
566
  }
566
567
  return SRCSET_WIDTHS.map((w) => {
@@ -699,7 +700,10 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
699
700
  if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
700
701
  return;
701
702
  }
702
- if (href && href.trim().toLowerCase().startsWith("javascript:")) {
703
+ const trimmed = href.trim().replace(/[\t\n\r\f\v\0]/g, "").toLowerCase();
704
+ const isSafeScheme = /^(https?|mailto|hive|tel|web\+[a-z0-9.+-]+):/i.test(trimmed);
705
+ const isRelative = /^(\/\/|\/[^/]?|#|\?|[a-z0-9._\-]+(\/|$))/i.test(trimmed);
706
+ if (!isSafeScheme && !isRelative) {
703
707
  el.removeAttribute("href");
704
708
  return;
705
709
  }
@@ -1422,6 +1426,13 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1422
1426
  el.setAttribute("allowfullscreen", "true");
1423
1427
  return;
1424
1428
  }
1429
+ if (src.match(SKATEHYPE_EMBED_REGEX)) {
1430
+ const normalizedSrc = src.replace(/^(https?:)?\/\//i, "https://");
1431
+ el.setAttribute("src", normalizedSrc);
1432
+ el.setAttribute("frameborder", "0");
1433
+ el.setAttribute("allowfullscreen", "true");
1434
+ return;
1435
+ }
1425
1436
  if (src.match(ARCH_REGEX)) {
1426
1437
  el.setAttribute("src", src);
1427
1438
  return;
@@ -1474,7 +1485,7 @@ function linkify(content, forApp, renderOptions) {
1474
1485
  content = content.replace(/(^|\s|>)(#[-a-z\d]+)/gi, (tag) => {
1475
1486
  if (/#[\d]+$/.test(tag)) return tag;
1476
1487
  const preceding = /^\s|>/.test(tag) ? tag[0] : "";
1477
- tag = tag.replace(">", "");
1488
+ tag = tag.replace(/^>/, "");
1478
1489
  const tag2 = tag.trim().substring(1);
1479
1490
  const tagLower = tag2.toLowerCase();
1480
1491
  if (!forApp) {