@ecency/render-helper 2.5.0 → 2.5.2

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);
@@ -413,7 +488,7 @@ function sanitizeHtml(html) {
413
488
  }
414
489
  });
415
490
  }
416
- var proxyBase = "https://images.ecency.com";
491
+ var proxyBase = "https://i.ecency.com";
417
492
  var urlHashCache = new lruCache.LRUCache({ max: 500 });
418
493
  function getUrlHash(url) {
419
494
  const cached = urlHashCache.get(url);
@@ -456,6 +531,9 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
456
531
  if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
457
532
  return url.replace("https://steemitimages.com", proxyBase);
458
533
  }
534
+ if (url.indexOf("https://images.ecency.com/") === 0) {
535
+ return url.replace("https://images.ecency.com", proxyBase);
536
+ }
459
537
  const realUrl = getLatestUrl(url);
460
538
  const pHash = extractPHash(realUrl);
461
539
  const options = {
@@ -525,7 +603,7 @@ function img(el, state) {
525
603
  }
526
604
  const cls = el.getAttribute("class") || "";
527
605
  const shouldReplace = !cls.includes("no-replace");
528
- const base = getProxyBase().replace(/\/+$/, "");
606
+ const base = trimTrailingSlash(getProxyBase());
529
607
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
530
608
  if (shouldReplace && !hasAlreadyProxied) {
531
609
  const proxified = proxifyImageSrc(decodedSrc);
@@ -550,7 +628,7 @@ function img(el, state) {
550
628
  function createImageHTML(src, isLCP) {
551
629
  const proxified = proxifyImageSrc(src);
552
630
  if (!proxified) return "";
553
- const base = getProxyBase().replace(/\/+$/, "");
631
+ const base = trimTrailingSlash(getProxyBase());
554
632
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
555
633
  const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
556
634
  const loading = isLCP ? "eager" : "lazy";
@@ -584,7 +662,8 @@ var matchesHref = (href, value) => {
584
662
  return normalizeValue(value) === normalizedHref;
585
663
  };
586
664
  var normalizeDisplayText = (text2) => {
587
- return text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "").replace(/\/+$/, "").toLowerCase();
665
+ const beforeTrailingSlash = text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "");
666
+ return trimTrailingSlash(beforeTrailingSlash).toLowerCase();
588
667
  };
589
668
  var getInlineMeta = (el, href, author, permlink, communityTag) => {
590
669
  const textMatches = matchesHref(href, el.textContent);
@@ -1153,8 +1232,8 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1153
1232
  TWITTER_REGEX.lastIndex = 0;
1154
1233
  const e = TWITTER_REGEX.exec(href);
1155
1234
  if (e) {
1156
- const url = e[0].replace(/(<([^>]+)>)/gi, "");
1157
- const author = e[1].replace(/(<([^>]+)>)/gi, "");
1235
+ const url = stripHtmlTags(e[0]);
1236
+ const author = stripHtmlTags(e[1]);
1158
1237
  const blockquote = el.ownerDocument.createElement("blockquote");
1159
1238
  blockquote.setAttribute("class", "twitter-tweet");
1160
1239
  const p2 = el.ownerDocument.createElement("p");
@@ -1230,8 +1309,7 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1230
1309
  return;
1231
1310
  }
1232
1311
  if (src.match(YOUTUBE_EMBED_REGEX)) {
1233
- const s = src.replace(/\?.+$/, "");
1234
- el.setAttribute("src", s);
1312
+ el.setAttribute("src", stripQueryString(src));
1235
1313
  return;
1236
1314
  }
1237
1315
  if (src.match(BITCHUTE_REGEX)) {
@@ -1412,7 +1490,7 @@ function linkify(content, forApp, renderOptions) {
1412
1490
  const preceedings = (preceeding1 || "") + (preceeding2 || "");
1413
1491
  if (userLower.indexOf("/") === -1 && isValidUsername(user)) {
1414
1492
  if (!forApp) {
1415
- const avatarSrc = `https://images.ecency.com/u/${userLower}/avatar/small`;
1493
+ const avatarSrc = `${getProxyBase()}/u/${userLower}/avatar/small`;
1416
1494
  const html = `${preceedings}<a class="er-author er-author-link" href="/@${userLower}"><img class="er-author-link-image" src="${avatarSrc}" alt="${userLower}"/><span class="er-author-link-content"><span class="er-author-link-label">Hive account</span><span>@${userLower}</span></span></a>`;
1417
1495
  const placeholder = `\u200C${authorPlaceholders.length}\u200C`;
1418
1496
  authorPlaceholders.push({ placeholder, html });
@@ -1626,16 +1704,16 @@ if (typeof window === "undefined") {
1626
1704
  loadLolight().catch(() => {
1627
1705
  });
1628
1706
  }
1707
+ var BLOCK_TAGS_ALTERNATION = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1708
+ var BLOCK_TAGS_SET = new Set(BLOCK_TAGS_ALTERNATION.split("|"));
1629
1709
  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");
1710
+ const openingPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1632
1711
  html = html.replace(openingPattern, "$1");
1633
- const closingPattern = new RegExp(`<p>(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1712
+ const closingPattern = new RegExp(`<p>(<\\/(?:${BLOCK_TAGS_ALTERNATION})>)<\\/p>`, "gi");
1634
1713
  html = html.replace(closingPattern, "$1");
1635
- const startPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1714
+ const startPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1636
1715
  html = html.replace(startPattern, "$1<p>");
1637
- const endPattern = new RegExp(`\\s*(?:<br>)?\\s*(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1638
- html = html.replace(endPattern, "</p>$1");
1716
+ html = moveBlockClosingTagOutOfParagraph(html, BLOCK_TAGS_SET);
1639
1717
  html = html.replace(/<p>\s*<\/p>/g, "");
1640
1718
  html = html.replace(/<p><br>\s*<\/p>/g, "");
1641
1719
  return html;
@@ -1974,7 +2052,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1974
2052
  text2 = text2.split(placeholder).join(entity);
1975
2053
  });
1976
2054
  }
1977
- text2 = text2.replace(/(<([^>]+)>)/gi, "").replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ +(?= )/g, "");
2055
+ text2 = stripHtmlTags(text2).replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ {2,}/g, " ");
1978
2056
  if (length > 0) {
1979
2057
  text2 = joint(text2.split(" "), length);
1980
2058
  }