@ecency/render-helper 2.4.33 → 2.4.34

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.
@@ -4,11 +4,11 @@ var xmldom = require('@xmldom/xmldom');
4
4
  var xss = require('xss');
5
5
  var multihash = require('multihashes');
6
6
  var querystring = require('querystring');
7
+ var lruCache = require('lru-cache');
7
8
  var remarkable = require('remarkable');
8
9
  var linkify$1 = require('remarkable/linkify');
9
10
  var htmlparser2 = require('htmlparser2');
10
11
  var domSerializerModule = require('dom-serializer');
11
- var lruCache = require('lru-cache');
12
12
  var he = require('he');
13
13
 
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -325,6 +325,14 @@ function sanitizeHtml(html) {
325
325
  });
326
326
  }
327
327
  var proxyBase = "https://images.ecency.com";
328
+ var urlHashCache = new lruCache.LRUCache({ max: 500 });
329
+ function getUrlHash(url) {
330
+ const cached = urlHashCache.get(url);
331
+ if (cached) return cached;
332
+ const hash = multihash__default.default.toB58String(Buffer.from(url));
333
+ urlHashCache.set(url, hash);
334
+ return hash;
335
+ }
328
336
  function setProxyBase(p2) {
329
337
  proxyBase = p2;
330
338
  }
@@ -375,7 +383,7 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
375
383
  if (pHash) {
376
384
  return `${proxyBase}/p/${pHash}?${qs}`;
377
385
  }
378
- const b58url = multihash__default.default.toB58String(Buffer.from(realUrl.toString()));
386
+ const b58url = getUrlHash(realUrl.toString());
379
387
  return `${proxyBase}/p/${b58url}?${qs}`;
380
388
  }
381
389
  var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
@@ -1647,7 +1655,7 @@ function simpleMarkdownToHTML(input) {
1647
1655
  const html = getMd().render(input);
1648
1656
  return sanitizeHtml(html);
1649
1657
  }
1650
- var cache = new lruCache.LRUCache({ max: 60 });
1658
+ var cache = new lruCache.LRUCache({ max: 500 });
1651
1659
  function setCacheSize(size) {
1652
1660
  cache = new lruCache.LRUCache({ max: size });
1653
1661
  }
@@ -1678,6 +1686,40 @@ var gifLinkRegex = /\.(gif)$/i;
1678
1686
  function isGifLink(link) {
1679
1687
  return gifLinkRegex.test(link);
1680
1688
  }
1689
+ var BACKTICK_FENCE_RE = /```[\s\S]*?```/g;
1690
+ var TILDE_FENCE_RE = /~~~[\s\S]*?~~~/g;
1691
+ var INLINE_CODE_RE = /`[^`\n]*`/g;
1692
+ var INDENTED_CODE_RE = /^(?: {4}|\t).+$/gm;
1693
+ var MD_IMAGE_RE = /!\[[^\]]*\]\(\s*([^)\s]+)(?:\s+["'][^"']*["'])?\s*\)/;
1694
+ var HTML_IMAGE_RE = /<img\b[^>]*?\bsrc\s*=\s*["']([^"']+)["']/i;
1695
+ var SAFE_URL_RE = /^https?:\/\//i;
1696
+ function findFirstImageUrl(body) {
1697
+ if (!body) return null;
1698
+ const cleaned = body.replace(BACKTICK_FENCE_RE, "").replace(TILDE_FENCE_RE, "").replace(INLINE_CODE_RE, "").replace(INDENTED_CODE_RE, "");
1699
+ const mdMatch = cleaned.match(MD_IMAGE_RE);
1700
+ const htmlMatch = cleaned.match(HTML_IMAGE_RE);
1701
+ if (mdMatch) {
1702
+ const url = mdMatch[1];
1703
+ if (!url || !SAFE_URL_RE.test(url) || url.includes("(")) {
1704
+ return null;
1705
+ }
1706
+ }
1707
+ const mdValid = !!mdMatch;
1708
+ const htmlValid = !!(htmlMatch && htmlMatch[1] && SAFE_URL_RE.test(htmlMatch[1]));
1709
+ if (mdValid && htmlValid) {
1710
+ return (mdMatch.index ?? 0) < (htmlMatch.index ?? 0) ? mdMatch[1] : htmlMatch[1];
1711
+ }
1712
+ if (mdValid) return mdMatch[1];
1713
+ if (htmlValid) return htmlMatch[1];
1714
+ return null;
1715
+ }
1716
+ function proxifyFound(src, width, height, format) {
1717
+ const decoded = he__default.default.decode(src);
1718
+ if (isGifLink(decoded)) {
1719
+ return proxifyImageSrc(decoded, 0, 0, format);
1720
+ }
1721
+ return proxifyImageSrc(decoded, width, height, format);
1722
+ }
1681
1723
  function getImage(entry, width = 0, height = 0, format = "match") {
1682
1724
  let meta;
1683
1725
  if (typeof entry.json_metadata === "object") {
@@ -1709,6 +1751,10 @@ function getImage(entry, width = 0, height = 0, format = "match") {
1709
1751
  }
1710
1752
  return proxifyImageSrc(meta.image[0], width, height, format);
1711
1753
  }
1754
+ const fast = findFirstImageUrl(entry.body);
1755
+ if (fast) {
1756
+ return proxifyFound(fast, width, height, format);
1757
+ }
1712
1758
  const html = markdown2Html(entry);
1713
1759
  const doc = createDoc(html);
1714
1760
  if (!doc) {
@@ -1720,16 +1766,16 @@ function getImage(entry, width = 0, height = 0, format = "match") {
1720
1766
  if (!src) {
1721
1767
  return null;
1722
1768
  }
1723
- const decodedSrc = he__default.default.decode(src);
1724
- if (isGifLink(decodedSrc)) {
1725
- return proxifyImageSrc(decodedSrc, 0, 0, format);
1726
- }
1727
- return proxifyImageSrc(decodedSrc, width, height, format);
1769
+ return proxifyFound(src, width, height, format);
1728
1770
  }
1729
1771
  return null;
1730
1772
  }
1731
1773
  function catchPostImage(obj, width = 0, height = 0, format = "match") {
1732
1774
  if (typeof obj === "string") {
1775
+ const fast = findFirstImageUrl(obj);
1776
+ if (fast) {
1777
+ return proxifyFound(fast, width, height, format);
1778
+ }
1733
1779
  const html = markdown2Html(obj);
1734
1780
  const doc = createDoc(html);
1735
1781
  if (!doc) {
@@ -1741,11 +1787,7 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
1741
1787
  if (!src) {
1742
1788
  return null;
1743
1789
  }
1744
- const decodedSrc = he__default.default.decode(src);
1745
- if (isGifLink(decodedSrc)) {
1746
- return proxifyImageSrc(decodedSrc, 0, 0, format);
1747
- }
1748
- return proxifyImageSrc(decodedSrc, width, height, format);
1790
+ return proxifyFound(src, width, height, format);
1749
1791
  }
1750
1792
  return null;
1751
1793
  }
@@ -1758,6 +1800,20 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
1758
1800
  cacheSet(key, res);
1759
1801
  return res;
1760
1802
  }
1803
+ var summaryRenderer = new remarkable.Remarkable({
1804
+ html: true,
1805
+ breaks: true,
1806
+ typographer: false
1807
+ });
1808
+ summaryRenderer.core.ruler.enable(["abbr"]);
1809
+ summaryRenderer.block.ruler.enable(["footnote", "deflist"]);
1810
+ summaryRenderer.inline.ruler.enable([
1811
+ "footnote_inline",
1812
+ "ins",
1813
+ "mark",
1814
+ "sub",
1815
+ "sup"
1816
+ ]);
1761
1817
  var joint = (arr, limit = 200) => {
1762
1818
  let result = "";
1763
1819
  if (arr) {
@@ -1783,25 +1839,6 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1783
1839
  return "";
1784
1840
  }
1785
1841
  entryBody = cleanReply(entryBody);
1786
- const mdd = new remarkable.Remarkable({
1787
- html: true,
1788
- breaks: true,
1789
- typographer: false
1790
- }).use(linkify$1.linkify);
1791
- mdd.core.ruler.enable([
1792
- "abbr"
1793
- ]);
1794
- mdd.block.ruler.enable([
1795
- "footnote",
1796
- "deflist"
1797
- ]);
1798
- mdd.inline.ruler.enable([
1799
- "footnote_inline",
1800
- "ins",
1801
- "mark",
1802
- "sub",
1803
- "sup"
1804
- ]);
1805
1842
  const entities = entryBody.match(ENTITY_REGEX);
1806
1843
  const entityPlaceholders = [];
1807
1844
  if (entities && platform !== "web") {
@@ -1814,7 +1851,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1814
1851
  }
1815
1852
  let text2 = "";
1816
1853
  try {
1817
- text2 = mdd.render(entryBody);
1854
+ text2 = summaryRenderer.render(entryBody);
1818
1855
  } catch (err) {
1819
1856
  console.error("[postBodySummary] Failed to render markdown:", {
1820
1857
  error: err instanceof Error ? err.message : String(err),