@ecency/render-helper 2.5.21 → 2.5.23

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.
@@ -99,15 +99,16 @@ var VIMEO_EMBED_REGEX = /https:\/\/player\.vimeo\.com\/video\/([0-9]+)(?:$|[?#])
99
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
- var D_TUBE_EMBED_REGEX = /^https:\/\/emb.d.tube\/#!\/[^/?#]+\/[^/?#]+(?:$|[?#])/i;
102
+ var D_TUBE_EMBED_REGEX = /^https:\/\/emb\.d\.tube\/#!\/[^/?#]+\/[^/?#]+(?:$|[?#])/i;
103
103
  var TWITCH_REGEX = /https?:\/\/(?:www\.)?twitch\.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
104
- var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr.in\/file\/dapplr-videos\/.*/i;
105
- var TRUVVL_REGEX = /^https?:\/\/embed.truvvl.com\/(@[\w.\d-]+)\/(.*)/i;
106
- var LBRY_REGEX = /^(https?:)?\/\/lbry.tv\/\$\/embed\/[^?#]+(?:$|[?#])/i;
104
+ var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr\.in\/file\/dapplr-videos\/.*/i;
105
+ var TRUVVL_REGEX = /^https?:\/\/embed\.truvvl\.com\/(@[\w.\d-]+)\/(.*)/i;
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
- var ARCH_REGEX = /^(https?:)?\/\/archive.org\/embed\/[^/?#]+(?:$|[?#])/i;
111
+ var ARCH_REGEX = /^(https?:)?\/\/archive\.org\/embed\/[^/?#]+(?:$|[?#])/i;
111
112
  var SPEAK_REGEX = /(?:https?:\/\/(?:(?:play\.)?3speak\.([a-z]+)\/watch\?v=)|(?:(?:play\.)?3speak\.([a-z]+)\/embed\?v=))([A-Za-z0-9_\-\.\/]+)(&.*)?/i;
112
113
  var SPEAK_EMBED_REGEX = /^(https?:)?\/\/(?:play\.)?3speak\.([a-z]+)\/(?:embed|watch)\?.+$/i;
113
114
  var SPEAK_AUDIO_REGEX = /https?:\/\/audio\.3speak\.tv\/play\?[^\s]+/i;
@@ -126,7 +127,6 @@ var LOOM_REGEX = /^(https?:)?\/\/www\.loom\.com\/share\/([^/?#]+)(?:$|[?#])/i;
126
127
  var LOOM_EMBED_REGEX = /^(https?:)?\/\/www\.loom\.com\/embed\/([^/?#]+)(?:$|[?#])/i;
127
128
  var AUREAL_EMBED_REGEX = /^(https?:)?\/\/(www\.)?(?:aureal-embed)\.web\.app\/([0-9]+)(?:$|[?#])/i;
128
129
  var ENTITY_REGEX = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/ig;
129
- var SECTION_REGEX = /\B(\#[\da-zA-Z-_]+\b)(?!;)/i;
130
130
  var ID_WHITELIST = /^[A-Za-z][-A-Za-z0-9_]*$/;
131
131
 
132
132
  // src/consts/allowed-attributes.const.ts
@@ -279,7 +279,13 @@ var EMBED_HOST_PATH_PATTERNS = {
279
279
  "www.rumble.com": /^\/embed\//,
280
280
  "rumble.com": /^\/embed\//,
281
281
  "www.brighteon.com": /^\/embed\//,
282
- "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\//
283
289
  };
284
290
  function isAllowedEmbedSrc(value) {
285
291
  if (!value) return false;
@@ -883,6 +889,33 @@ function getExternalLinkRel(seoContext) {
883
889
  }
884
890
  return "nofollow ugc noopener";
885
891
  }
892
+ function renderPlainVideoLink(el, provider, embedSrc, renderOptions) {
893
+ const baseClass = `markdown-video-link markdown-video-link-${provider}`;
894
+ el.setAttribute("class", baseClass);
895
+ el.removeAttribute("href");
896
+ el.textContent = "";
897
+ el.setAttribute("data-embed-src", embedSrc);
898
+ if (renderOptions?.embedVideosDirectly) {
899
+ const wrapper = el.ownerDocument.createElement("span");
900
+ wrapper.setAttribute("class", "er-embed-frame");
901
+ wrapper.setAttribute("style", "display:block");
902
+ const frame = el.ownerDocument.createElement("iframe");
903
+ frame.setAttribute("src", embedSrc);
904
+ frame.setAttribute("title", "Video player");
905
+ frame.setAttribute(
906
+ "allow",
907
+ "accelerometer; encrypted-media; gyroscope; picture-in-picture; web-share"
908
+ );
909
+ frame.setAttribute("allowfullscreen", "");
910
+ wrapper.appendChild(frame);
911
+ el.appendChild(wrapper);
912
+ el.setAttribute("class", `${baseClass} er-embed`);
913
+ return;
914
+ }
915
+ const play = el.ownerDocument.createElement("span");
916
+ play.setAttribute("class", "markdown-video-play");
917
+ el.appendChild(play);
918
+ }
886
919
  var normalizeValue = (value) => value ? value.trim() : "";
887
920
  var matchesHref = (href, value) => {
888
921
  const normalizedHref = normalizeValue(href);
@@ -925,10 +958,6 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
925
958
  if (!href) {
926
959
  return;
927
960
  }
928
- const className = el.getAttribute("class");
929
- if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
930
- return;
931
- }
932
961
  const trimmed = href.trim().replace(/[\t\n\r\f\v\0]/g, "").toLowerCase();
933
962
  const isSafeScheme = /^(https?|mailto|hive|tel|web\+[a-z0-9.+-]+):/i.test(trimmed);
934
963
  const isRelative = /^(\/\/|\/[^/]?|#|\?|[a-z0-9._\-]+(\/|$))/i.test(trimmed);
@@ -936,6 +965,13 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
936
965
  el.removeAttribute("href");
937
966
  return;
938
967
  }
968
+ const className = el.getAttribute("class");
969
+ if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
970
+ if (el.getAttribute("target")) {
971
+ el.setAttribute("rel", getExternalLinkRel(seoContext));
972
+ }
973
+ return;
974
+ }
939
975
  if (href.match(IMG_REGEX) && href.trim().replace(/&amp;/g, "&") === getSerializedInnerHTML(el).trim().replace(/&amp;/g, "&")) {
940
976
  const isLCP = false;
941
977
  const imgHTML = createImageHTML(href, isLCP, forApp);
@@ -1218,41 +1254,22 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1218
1254
  }
1219
1255
  const BCmatch = href.match(BITCHUTE_REGEX);
1220
1256
  if (BCmatch && BCmatch[1] && el.textContent.trim() === href) {
1221
- const vid = BCmatch[1];
1222
- el.setAttribute("class", "markdown-video-link");
1223
- el.removeAttribute("href");
1224
- const embedSrc = `https://www.bitchute.com/embed/${vid}/`;
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);
1257
+ renderPlainVideoLink(el, "bitchute", `https://www.bitchute.com/embed/${BCmatch[1]}/`, renderOptions);
1230
1258
  return;
1231
1259
  }
1232
1260
  const RBmatch = href.match(RUMBLE_REGEX);
1233
1261
  if (RBmatch && RBmatch[1] && el.textContent.trim() === href) {
1234
- const vid = RBmatch[1];
1235
- const embedSrc = `https://www.rumble.com/embed/${vid}/?pub=4`;
1236
- el.setAttribute("class", "markdown-video-link");
1237
- el.removeAttribute("href");
1238
- el.textContent = "";
1239
- el.setAttribute("data-embed-src", embedSrc);
1240
- const play = el.ownerDocument.createElement("span");
1241
- play.setAttribute("class", "markdown-video-play");
1242
- el.appendChild(play);
1262
+ renderPlainVideoLink(el, "rumble", `https://www.rumble.com/embed/${RBmatch[1]}/?pub=4`, renderOptions);
1243
1263
  return;
1244
1264
  }
1245
1265
  const BNmatch = href.match(BRIGHTEON_REGEX);
1246
1266
  if (BNmatch && BNmatch[2] && el.textContent.trim() === href) {
1247
- const vid = BNmatch[2];
1248
- const embedSrc = `https://www.brighteon.com/embed/${vid}`;
1249
- el.setAttribute("class", "markdown-video-link");
1250
- el.removeAttribute("href");
1251
- el.textContent = "";
1252
- el.setAttribute("data-embed-src", embedSrc);
1253
- const play = el.ownerDocument.createElement("span");
1254
- play.setAttribute("class", "markdown-video-play");
1255
- el.appendChild(play);
1267
+ renderPlainVideoLink(el, "brighteon", `https://www.brighteon.com/embed/${BNmatch[2]}`, renderOptions);
1268
+ return;
1269
+ }
1270
+ const ODmatch = href.match(ODYSEE_WATCH_REGEX);
1271
+ if (ODmatch && ODmatch[1] && el.textContent.trim() === href) {
1272
+ renderPlainVideoLink(el, "odysee", `https://odysee.com/$/embed/${ODmatch[1]}`, renderOptions);
1256
1273
  return;
1257
1274
  }
1258
1275
  let match = href.match(YOUTUBE_REGEX);
@@ -1533,7 +1550,7 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1533
1550
  }
1534
1551
  el.removeAttribute("href");
1535
1552
  } else {
1536
- const matchS = href.match(SECTION_REGEX);
1553
+ const matchS = href.trim().startsWith("#");
1537
1554
  if (matchS) {
1538
1555
  el.setAttribute("class", "markdown-internal-link");
1539
1556
  } else {