@ecency/render-helper 2.5.0 → 2.5.1

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.
@@ -83,13 +83,13 @@ var SECTION_LIST = [
83
83
  // src/consts/regexes.const.ts
84
84
  var IMG_REGEX = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico|heic|webp|arw))(.*)/gim;
85
85
  var IPFS_REGEX = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/gim;
86
- var POST_REGEX = /^https?:\/\/(.*)\/(.*)\/(@[\w.\d-]+)\/(.*)/i;
86
+ var POST_REGEX = /^https?:\/\/([^/]+)\/([^/]+)\/(@[\w.\d-]+)\/(.+)$/i;
87
87
  var CCC_REGEX = /^https?:\/\/(.*)\/ccc\/([\w.\d-]+)\/(.*)/i;
88
88
  var MENTION_REGEX = /^https?:\/\/(.*)\/(@[\w.\d-]+)$/i;
89
89
  var TOPIC_REGEX = /^https?:\/\/(.*)\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
90
90
  var INTERNAL_MENTION_REGEX = /^\/@[\w.\d-]+$/i;
91
91
  var INTERNAL_TOPIC_REGEX = /^\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
92
- var INTERNAL_POST_TAG_REGEX = /(.*)\/(@[\w.\d-]+)\/(.*)/i;
92
+ 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;
@@ -327,6 +327,81 @@ function createDoc(html) {
327
327
  function makeEntryCacheKey(entry) {
328
328
  return `${entry.author}-${entry.permlink}-${entry.last_update}-${entry.updated}`;
329
329
  }
330
+ function stripHtmlTags(s) {
331
+ const n = s.length;
332
+ let out = "";
333
+ let i = 0;
334
+ while (i < n) {
335
+ const lt = s.indexOf("<", i);
336
+ if (lt < 0) {
337
+ out += s.slice(i);
338
+ break;
339
+ }
340
+ out += s.slice(i, lt);
341
+ const gt = s.indexOf(">", lt + 1);
342
+ if (gt < 0) {
343
+ out += s.slice(lt);
344
+ break;
345
+ }
346
+ if (gt === lt + 1) {
347
+ out += s.slice(lt, gt + 1);
348
+ i = gt + 1;
349
+ continue;
350
+ }
351
+ i = gt + 1;
352
+ }
353
+ return out;
354
+ }
355
+ function trimTrailingSlash(s) {
356
+ let end = s.length;
357
+ while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
358
+ return s.slice(0, end);
359
+ }
360
+ function stripQueryString(s) {
361
+ const q = s.indexOf("?");
362
+ return q >= 0 && q < s.length - 1 ? s.slice(0, q) : s;
363
+ }
364
+ function isHtmlWhitespace(c) {
365
+ return c === 32 || c === 9 || c === 10 || c === 13 || c === 12;
366
+ }
367
+ function moveBlockClosingTagOutOfParagraph(html, blockTags) {
368
+ const n = html.length;
369
+ let out = "";
370
+ let i = 0;
371
+ while (i < n) {
372
+ const pStart = html.indexOf("</p>", i);
373
+ if (pStart < 0) {
374
+ out += html.slice(i);
375
+ break;
376
+ }
377
+ if (pStart === i || html.charCodeAt(pStart - 1) !== 62) {
378
+ out += html.slice(i, pStart + 4);
379
+ i = pStart + 4;
380
+ continue;
381
+ }
382
+ const closingStart = html.lastIndexOf("</", pStart - 2);
383
+ if (closingStart < i) {
384
+ out += html.slice(i, pStart + 4);
385
+ i = pStart + 4;
386
+ continue;
387
+ }
388
+ const tagName = html.slice(closingStart + 2, pStart - 1).toLowerCase();
389
+ if (!blockTags.has(tagName)) {
390
+ out += html.slice(i, pStart + 4);
391
+ i = pStart + 4;
392
+ continue;
393
+ }
394
+ let k = closingStart;
395
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
396
+ if (k - 4 >= i && html.slice(k - 4, k).toLowerCase() === "<br>") {
397
+ k -= 4;
398
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
399
+ }
400
+ out += html.slice(i, k) + "</p>" + html.slice(closingStart, pStart);
401
+ i = pStart + 4;
402
+ }
403
+ return out;
404
+ }
330
405
  function extractYtStartTime(url) {
331
406
  try {
332
407
  const urlObj = new URL(url);
@@ -525,7 +600,7 @@ function img(el, state) {
525
600
  }
526
601
  const cls = el.getAttribute("class") || "";
527
602
  const shouldReplace = !cls.includes("no-replace");
528
- const base = getProxyBase().replace(/\/+$/, "");
603
+ const base = trimTrailingSlash(getProxyBase());
529
604
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
530
605
  if (shouldReplace && !hasAlreadyProxied) {
531
606
  const proxified = proxifyImageSrc(decodedSrc);
@@ -550,7 +625,7 @@ function img(el, state) {
550
625
  function createImageHTML(src, isLCP) {
551
626
  const proxified = proxifyImageSrc(src);
552
627
  if (!proxified) return "";
553
- const base = getProxyBase().replace(/\/+$/, "");
628
+ const base = trimTrailingSlash(getProxyBase());
554
629
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
555
630
  const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
556
631
  const loading = isLCP ? "eager" : "lazy";
@@ -584,7 +659,8 @@ var matchesHref = (href, value) => {
584
659
  return normalizeValue(value) === normalizedHref;
585
660
  };
586
661
  var normalizeDisplayText = (text2) => {
587
- return text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "").replace(/\/+$/, "").toLowerCase();
662
+ const beforeTrailingSlash = text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "");
663
+ return trimTrailingSlash(beforeTrailingSlash).toLowerCase();
588
664
  };
589
665
  var getInlineMeta = (el, href, author, permlink, communityTag) => {
590
666
  const textMatches = matchesHref(href, el.textContent);
@@ -1153,8 +1229,8 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1153
1229
  TWITTER_REGEX.lastIndex = 0;
1154
1230
  const e = TWITTER_REGEX.exec(href);
1155
1231
  if (e) {
1156
- const url = e[0].replace(/(<([^>]+)>)/gi, "");
1157
- const author = e[1].replace(/(<([^>]+)>)/gi, "");
1232
+ const url = stripHtmlTags(e[0]);
1233
+ const author = stripHtmlTags(e[1]);
1158
1234
  const blockquote = el.ownerDocument.createElement("blockquote");
1159
1235
  blockquote.setAttribute("class", "twitter-tweet");
1160
1236
  const p2 = el.ownerDocument.createElement("p");
@@ -1230,8 +1306,7 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1230
1306
  return;
1231
1307
  }
1232
1308
  if (src.match(YOUTUBE_EMBED_REGEX)) {
1233
- const s = src.replace(/\?.+$/, "");
1234
- el.setAttribute("src", s);
1309
+ el.setAttribute("src", stripQueryString(src));
1235
1310
  return;
1236
1311
  }
1237
1312
  if (src.match(BITCHUTE_REGEX)) {
@@ -1626,16 +1701,16 @@ if (typeof window === "undefined") {
1626
1701
  loadLolight().catch(() => {
1627
1702
  });
1628
1703
  }
1704
+ var BLOCK_TAGS_ALTERNATION = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1705
+ var BLOCK_TAGS_SET = new Set(BLOCK_TAGS_ALTERNATION.split("|"));
1629
1706
  function fixBlockLevelTagsInParagraphs(html) {
1630
- const blockTags = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1631
- const openingPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1707
+ const openingPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1632
1708
  html = html.replace(openingPattern, "$1");
1633
- const closingPattern = new RegExp(`<p>(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1709
+ const closingPattern = new RegExp(`<p>(<\\/(?:${BLOCK_TAGS_ALTERNATION})>)<\\/p>`, "gi");
1634
1710
  html = html.replace(closingPattern, "$1");
1635
- const startPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1711
+ const startPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1636
1712
  html = html.replace(startPattern, "$1<p>");
1637
- const endPattern = new RegExp(`\\s*(?:<br>)?\\s*(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1638
- html = html.replace(endPattern, "</p>$1");
1713
+ html = moveBlockClosingTagOutOfParagraph(html, BLOCK_TAGS_SET);
1639
1714
  html = html.replace(/<p>\s*<\/p>/g, "");
1640
1715
  html = html.replace(/<p><br>\s*<\/p>/g, "");
1641
1716
  return html;
@@ -1974,7 +2049,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1974
2049
  text2 = text2.split(placeholder).join(entity);
1975
2050
  });
1976
2051
  }
1977
- text2 = text2.replace(/(<([^>]+)>)/gi, "").replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ +(?= )/g, "");
2052
+ text2 = stripHtmlTags(text2).replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ {2,}/g, " ");
1978
2053
  if (length > 0) {
1979
2054
  text2 = joint(text2.split(" "), length);
1980
2055
  }