@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.
@@ -54,13 +54,13 @@ var SECTION_LIST = [
54
54
  // src/consts/regexes.const.ts
55
55
  var IMG_REGEX = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico|heic|webp|arw))(.*)/gim;
56
56
  var IPFS_REGEX = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/gim;
57
- var POST_REGEX = /^https?:\/\/(.*)\/(.*)\/(@[\w.\d-]+)\/(.*)/i;
57
+ var POST_REGEX = /^https?:\/\/([^/]+)\/([^/]+)\/(@[\w.\d-]+)\/(.+)$/i;
58
58
  var CCC_REGEX = /^https?:\/\/(.*)\/ccc\/([\w.\d-]+)\/(.*)/i;
59
59
  var MENTION_REGEX = /^https?:\/\/(.*)\/(@[\w.\d-]+)$/i;
60
60
  var TOPIC_REGEX = /^https?:\/\/(.*)\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
61
61
  var INTERNAL_MENTION_REGEX = /^\/@[\w.\d-]+$/i;
62
62
  var INTERNAL_TOPIC_REGEX = /^\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
63
- var INTERNAL_POST_TAG_REGEX = /(.*)\/(@[\w.\d-]+)\/(.*)/i;
63
+ 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;
@@ -298,6 +298,81 @@ function createDoc(html) {
298
298
  function makeEntryCacheKey(entry) {
299
299
  return `${entry.author}-${entry.permlink}-${entry.last_update}-${entry.updated}`;
300
300
  }
301
+ function stripHtmlTags(s) {
302
+ const n = s.length;
303
+ let out = "";
304
+ let i = 0;
305
+ while (i < n) {
306
+ const lt = s.indexOf("<", i);
307
+ if (lt < 0) {
308
+ out += s.slice(i);
309
+ break;
310
+ }
311
+ out += s.slice(i, lt);
312
+ const gt = s.indexOf(">", lt + 1);
313
+ if (gt < 0) {
314
+ out += s.slice(lt);
315
+ break;
316
+ }
317
+ if (gt === lt + 1) {
318
+ out += s.slice(lt, gt + 1);
319
+ i = gt + 1;
320
+ continue;
321
+ }
322
+ i = gt + 1;
323
+ }
324
+ return out;
325
+ }
326
+ function trimTrailingSlash(s) {
327
+ let end = s.length;
328
+ while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
329
+ return s.slice(0, end);
330
+ }
331
+ function stripQueryString(s) {
332
+ const q = s.indexOf("?");
333
+ return q >= 0 && q < s.length - 1 ? s.slice(0, q) : s;
334
+ }
335
+ function isHtmlWhitespace(c) {
336
+ return c === 32 || c === 9 || c === 10 || c === 13 || c === 12;
337
+ }
338
+ function moveBlockClosingTagOutOfParagraph(html, blockTags) {
339
+ const n = html.length;
340
+ let out = "";
341
+ let i = 0;
342
+ while (i < n) {
343
+ const pStart = html.indexOf("</p>", i);
344
+ if (pStart < 0) {
345
+ out += html.slice(i);
346
+ break;
347
+ }
348
+ if (pStart === i || html.charCodeAt(pStart - 1) !== 62) {
349
+ out += html.slice(i, pStart + 4);
350
+ i = pStart + 4;
351
+ continue;
352
+ }
353
+ const closingStart = html.lastIndexOf("</", pStart - 2);
354
+ if (closingStart < i) {
355
+ out += html.slice(i, pStart + 4);
356
+ i = pStart + 4;
357
+ continue;
358
+ }
359
+ const tagName = html.slice(closingStart + 2, pStart - 1).toLowerCase();
360
+ if (!blockTags.has(tagName)) {
361
+ out += html.slice(i, pStart + 4);
362
+ i = pStart + 4;
363
+ continue;
364
+ }
365
+ let k = closingStart;
366
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
367
+ if (k - 4 >= i && html.slice(k - 4, k).toLowerCase() === "<br>") {
368
+ k -= 4;
369
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
370
+ }
371
+ out += html.slice(i, k) + "</p>" + html.slice(closingStart, pStart);
372
+ i = pStart + 4;
373
+ }
374
+ return out;
375
+ }
301
376
  function extractYtStartTime(url) {
302
377
  try {
303
378
  const urlObj = new URL(url);
@@ -496,7 +571,7 @@ function img(el, state) {
496
571
  }
497
572
  const cls = el.getAttribute("class") || "";
498
573
  const shouldReplace = !cls.includes("no-replace");
499
- const base = getProxyBase().replace(/\/+$/, "");
574
+ const base = trimTrailingSlash(getProxyBase());
500
575
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
501
576
  if (shouldReplace && !hasAlreadyProxied) {
502
577
  const proxified = proxifyImageSrc(decodedSrc);
@@ -521,7 +596,7 @@ function img(el, state) {
521
596
  function createImageHTML(src, isLCP) {
522
597
  const proxified = proxifyImageSrc(src);
523
598
  if (!proxified) return "";
524
- const base = getProxyBase().replace(/\/+$/, "");
599
+ const base = trimTrailingSlash(getProxyBase());
525
600
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
526
601
  const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
527
602
  const loading = isLCP ? "eager" : "lazy";
@@ -555,7 +630,8 @@ var matchesHref = (href, value) => {
555
630
  return normalizeValue(value) === normalizedHref;
556
631
  };
557
632
  var normalizeDisplayText = (text2) => {
558
- return text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "").replace(/\/+$/, "").toLowerCase();
633
+ const beforeTrailingSlash = text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "");
634
+ return trimTrailingSlash(beforeTrailingSlash).toLowerCase();
559
635
  };
560
636
  var getInlineMeta = (el, href, author, permlink, communityTag) => {
561
637
  const textMatches = matchesHref(href, el.textContent);
@@ -1124,8 +1200,8 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1124
1200
  TWITTER_REGEX.lastIndex = 0;
1125
1201
  const e = TWITTER_REGEX.exec(href);
1126
1202
  if (e) {
1127
- const url = e[0].replace(/(<([^>]+)>)/gi, "");
1128
- const author = e[1].replace(/(<([^>]+)>)/gi, "");
1203
+ const url = stripHtmlTags(e[0]);
1204
+ const author = stripHtmlTags(e[1]);
1129
1205
  const blockquote = el.ownerDocument.createElement("blockquote");
1130
1206
  blockquote.setAttribute("class", "twitter-tweet");
1131
1207
  const p2 = el.ownerDocument.createElement("p");
@@ -1201,8 +1277,7 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1201
1277
  return;
1202
1278
  }
1203
1279
  if (src.match(YOUTUBE_EMBED_REGEX)) {
1204
- const s = src.replace(/\?.+$/, "");
1205
- el.setAttribute("src", s);
1280
+ el.setAttribute("src", stripQueryString(src));
1206
1281
  return;
1207
1282
  }
1208
1283
  if (src.match(BITCHUTE_REGEX)) {
@@ -1597,16 +1672,16 @@ if (typeof window === "undefined") {
1597
1672
  loadLolight().catch(() => {
1598
1673
  });
1599
1674
  }
1675
+ var BLOCK_TAGS_ALTERNATION = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1676
+ var BLOCK_TAGS_SET = new Set(BLOCK_TAGS_ALTERNATION.split("|"));
1600
1677
  function fixBlockLevelTagsInParagraphs(html) {
1601
- const blockTags = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1602
- const openingPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1678
+ const openingPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1603
1679
  html = html.replace(openingPattern, "$1");
1604
- const closingPattern = new RegExp(`<p>(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1680
+ const closingPattern = new RegExp(`<p>(<\\/(?:${BLOCK_TAGS_ALTERNATION})>)<\\/p>`, "gi");
1605
1681
  html = html.replace(closingPattern, "$1");
1606
- const startPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1682
+ const startPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1607
1683
  html = html.replace(startPattern, "$1<p>");
1608
- const endPattern = new RegExp(`\\s*(?:<br>)?\\s*(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1609
- html = html.replace(endPattern, "</p>$1");
1684
+ html = moveBlockClosingTagOutOfParagraph(html, BLOCK_TAGS_SET);
1610
1685
  html = html.replace(/<p>\s*<\/p>/g, "");
1611
1686
  html = html.replace(/<p><br>\s*<\/p>/g, "");
1612
1687
  return html;
@@ -1945,7 +2020,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1945
2020
  text2 = text2.split(placeholder).join(entity);
1946
2021
  });
1947
2022
  }
1948
- text2 = text2.replace(/(<([^>]+)>)/gi, "").replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ +(?= )/g, "");
2023
+ text2 = stripHtmlTags(text2).replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ {2,}/g, " ");
1949
2024
  if (length > 0) {
1950
2025
  text2 = joint(text2.split(" "), length);
1951
2026
  }