@ecency/render-helper 2.4.32 → 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.
- package/dist/browser/index.js +84 -48
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +86 -53
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.mjs +84 -51
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { DOMParser as DOMParser$1, XMLSerializer
|
|
1
|
+
import { DOMParser as DOMParser$1, XMLSerializer } from '@xmldom/xmldom';
|
|
2
2
|
import xss from 'xss';
|
|
3
3
|
import multihash from 'multihashes';
|
|
4
4
|
import querystring from 'querystring';
|
|
5
|
+
import { LRUCache } from 'lru-cache';
|
|
5
6
|
import { Remarkable } from 'remarkable';
|
|
6
7
|
import { linkify as linkify$1 } from 'remarkable/linkify';
|
|
7
|
-
import he2 from 'he';
|
|
8
8
|
import * as htmlparser2 from 'htmlparser2';
|
|
9
9
|
import * as domSerializerModule from 'dom-serializer';
|
|
10
|
-
import
|
|
10
|
+
import he from 'he';
|
|
11
11
|
|
|
12
12
|
// src/consts/white-list.const.ts
|
|
13
13
|
var WHITE_LIST = [
|
|
@@ -168,16 +168,13 @@ var ALLOWED_ATTRIBUTES = {
|
|
|
168
168
|
"del": [],
|
|
169
169
|
"ins": []
|
|
170
170
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
179
|
-
var DOMParser = hasDOMParser ? new globalThis.DOMParser() : new DOMParser$1({ onError: lenientErrorHandler });
|
|
180
|
-
var XMLSerializer = hasXMLSerializer ? globalThis.XMLSerializer : XMLSerializer$1;
|
|
171
|
+
function createParser() {
|
|
172
|
+
return new DOMParser$1({
|
|
173
|
+
onError(level, msg) {
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
var DOMParser = createParser();
|
|
181
178
|
|
|
182
179
|
// src/helper.ts
|
|
183
180
|
function removeDuplicateAttributes(html) {
|
|
@@ -299,6 +296,14 @@ function sanitizeHtml(html) {
|
|
|
299
296
|
});
|
|
300
297
|
}
|
|
301
298
|
var proxyBase = "https://images.ecency.com";
|
|
299
|
+
var urlHashCache = new LRUCache({ max: 500 });
|
|
300
|
+
function getUrlHash(url) {
|
|
301
|
+
const cached = urlHashCache.get(url);
|
|
302
|
+
if (cached) return cached;
|
|
303
|
+
const hash = multihash.toB58String(Buffer.from(url));
|
|
304
|
+
urlHashCache.set(url, hash);
|
|
305
|
+
return hash;
|
|
306
|
+
}
|
|
302
307
|
function setProxyBase(p2) {
|
|
303
308
|
proxyBase = p2;
|
|
304
309
|
}
|
|
@@ -349,7 +354,7 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
|
|
|
349
354
|
if (pHash) {
|
|
350
355
|
return `${proxyBase}/p/${pHash}?${qs}`;
|
|
351
356
|
}
|
|
352
|
-
const b58url =
|
|
357
|
+
const b58url = getUrlHash(realUrl.toString());
|
|
353
358
|
return `${proxyBase}/p/${b58url}?${qs}`;
|
|
354
359
|
}
|
|
355
360
|
var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
|
|
@@ -1593,8 +1598,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext,
|
|
|
1593
1598
|
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext, renderOptions);
|
|
1594
1599
|
output = serializer.serializeToString(doc);
|
|
1595
1600
|
} catch (fallbackError) {
|
|
1596
|
-
|
|
1597
|
-
output = `<p dir="auto">${escapedContent}</p>`;
|
|
1601
|
+
output = sanitizeHtml(output || md.render(input));
|
|
1598
1602
|
}
|
|
1599
1603
|
}
|
|
1600
1604
|
if (forApp && output && entityPlaceholders.length > 0) {
|
|
@@ -1603,7 +1607,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext,
|
|
|
1603
1607
|
output = output.split(placeholder).join(entity);
|
|
1604
1608
|
});
|
|
1605
1609
|
}
|
|
1606
|
-
output = output.replace(/ xmlns="http:\/\/www.w3.org\/1999\/xhtml"/g, "").replace('<body id="root">', "").replace("</body>", "").trim();
|
|
1610
|
+
output = output.replace(/ xmlns="http:\/\/www.w3.org\/1999\/xhtml"/g, "").replace(/^<\?xml[^?]*\?>/, "").replace(/^<!DOCTYPE[^>]*>/i, "").replace(/<\/?html[^>]*>/g, "").replace(/<head[^>]*>[\s\S]*?<\/head>/g, "").replace('<body id="root">', "").replace("</body>", "").trim();
|
|
1607
1611
|
return sanitizeHtml(output);
|
|
1608
1612
|
}
|
|
1609
1613
|
var mdInstance = null;
|
|
@@ -1622,7 +1626,7 @@ function simpleMarkdownToHTML(input) {
|
|
|
1622
1626
|
const html = getMd().render(input);
|
|
1623
1627
|
return sanitizeHtml(html);
|
|
1624
1628
|
}
|
|
1625
|
-
var cache = new LRUCache({ max:
|
|
1629
|
+
var cache = new LRUCache({ max: 500 });
|
|
1626
1630
|
function setCacheSize(size) {
|
|
1627
1631
|
cache = new LRUCache({ max: size });
|
|
1628
1632
|
}
|
|
@@ -1653,6 +1657,40 @@ var gifLinkRegex = /\.(gif)$/i;
|
|
|
1653
1657
|
function isGifLink(link) {
|
|
1654
1658
|
return gifLinkRegex.test(link);
|
|
1655
1659
|
}
|
|
1660
|
+
var BACKTICK_FENCE_RE = /```[\s\S]*?```/g;
|
|
1661
|
+
var TILDE_FENCE_RE = /~~~[\s\S]*?~~~/g;
|
|
1662
|
+
var INLINE_CODE_RE = /`[^`\n]*`/g;
|
|
1663
|
+
var INDENTED_CODE_RE = /^(?: {4}|\t).+$/gm;
|
|
1664
|
+
var MD_IMAGE_RE = /!\[[^\]]*\]\(\s*([^)\s]+)(?:\s+["'][^"']*["'])?\s*\)/;
|
|
1665
|
+
var HTML_IMAGE_RE = /<img\b[^>]*?\bsrc\s*=\s*["']([^"']+)["']/i;
|
|
1666
|
+
var SAFE_URL_RE = /^https?:\/\//i;
|
|
1667
|
+
function findFirstImageUrl(body) {
|
|
1668
|
+
if (!body) return null;
|
|
1669
|
+
const cleaned = body.replace(BACKTICK_FENCE_RE, "").replace(TILDE_FENCE_RE, "").replace(INLINE_CODE_RE, "").replace(INDENTED_CODE_RE, "");
|
|
1670
|
+
const mdMatch = cleaned.match(MD_IMAGE_RE);
|
|
1671
|
+
const htmlMatch = cleaned.match(HTML_IMAGE_RE);
|
|
1672
|
+
if (mdMatch) {
|
|
1673
|
+
const url = mdMatch[1];
|
|
1674
|
+
if (!url || !SAFE_URL_RE.test(url) || url.includes("(")) {
|
|
1675
|
+
return null;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
const mdValid = !!mdMatch;
|
|
1679
|
+
const htmlValid = !!(htmlMatch && htmlMatch[1] && SAFE_URL_RE.test(htmlMatch[1]));
|
|
1680
|
+
if (mdValid && htmlValid) {
|
|
1681
|
+
return (mdMatch.index ?? 0) < (htmlMatch.index ?? 0) ? mdMatch[1] : htmlMatch[1];
|
|
1682
|
+
}
|
|
1683
|
+
if (mdValid) return mdMatch[1];
|
|
1684
|
+
if (htmlValid) return htmlMatch[1];
|
|
1685
|
+
return null;
|
|
1686
|
+
}
|
|
1687
|
+
function proxifyFound(src, width, height, format) {
|
|
1688
|
+
const decoded = he.decode(src);
|
|
1689
|
+
if (isGifLink(decoded)) {
|
|
1690
|
+
return proxifyImageSrc(decoded, 0, 0, format);
|
|
1691
|
+
}
|
|
1692
|
+
return proxifyImageSrc(decoded, width, height, format);
|
|
1693
|
+
}
|
|
1656
1694
|
function getImage(entry, width = 0, height = 0, format = "match") {
|
|
1657
1695
|
let meta;
|
|
1658
1696
|
if (typeof entry.json_metadata === "object") {
|
|
@@ -1665,7 +1703,7 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1665
1703
|
}
|
|
1666
1704
|
}
|
|
1667
1705
|
if (meta && typeof meta.image === "string" && meta.image.length > 0) {
|
|
1668
|
-
const decodedImage =
|
|
1706
|
+
const decodedImage = he.decode(meta.image);
|
|
1669
1707
|
if (isGifLink(decodedImage)) {
|
|
1670
1708
|
return proxifyImageSrc(decodedImage, 0, 0, format);
|
|
1671
1709
|
}
|
|
@@ -1673,7 +1711,7 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1673
1711
|
}
|
|
1674
1712
|
if (meta && meta.image && !!meta.image.length && meta.image[0]) {
|
|
1675
1713
|
if (typeof meta.image[0] === "string") {
|
|
1676
|
-
const decodedImage =
|
|
1714
|
+
const decodedImage = he.decode(meta.image[0]);
|
|
1677
1715
|
if (isGifLink(decodedImage)) {
|
|
1678
1716
|
return proxifyImageSrc(decodedImage, 0, 0, format);
|
|
1679
1717
|
}
|
|
@@ -1684,6 +1722,10 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1684
1722
|
}
|
|
1685
1723
|
return proxifyImageSrc(meta.image[0], width, height, format);
|
|
1686
1724
|
}
|
|
1725
|
+
const fast = findFirstImageUrl(entry.body);
|
|
1726
|
+
if (fast) {
|
|
1727
|
+
return proxifyFound(fast, width, height, format);
|
|
1728
|
+
}
|
|
1687
1729
|
const html = markdown2Html(entry);
|
|
1688
1730
|
const doc = createDoc(html);
|
|
1689
1731
|
if (!doc) {
|
|
@@ -1695,16 +1737,16 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1695
1737
|
if (!src) {
|
|
1696
1738
|
return null;
|
|
1697
1739
|
}
|
|
1698
|
-
|
|
1699
|
-
if (isGifLink(decodedSrc)) {
|
|
1700
|
-
return proxifyImageSrc(decodedSrc, 0, 0, format);
|
|
1701
|
-
}
|
|
1702
|
-
return proxifyImageSrc(decodedSrc, width, height, format);
|
|
1740
|
+
return proxifyFound(src, width, height, format);
|
|
1703
1741
|
}
|
|
1704
1742
|
return null;
|
|
1705
1743
|
}
|
|
1706
1744
|
function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
1707
1745
|
if (typeof obj === "string") {
|
|
1746
|
+
const fast = findFirstImageUrl(obj);
|
|
1747
|
+
if (fast) {
|
|
1748
|
+
return proxifyFound(fast, width, height, format);
|
|
1749
|
+
}
|
|
1708
1750
|
const html = markdown2Html(obj);
|
|
1709
1751
|
const doc = createDoc(html);
|
|
1710
1752
|
if (!doc) {
|
|
@@ -1716,11 +1758,7 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
|
1716
1758
|
if (!src) {
|
|
1717
1759
|
return null;
|
|
1718
1760
|
}
|
|
1719
|
-
|
|
1720
|
-
if (isGifLink(decodedSrc)) {
|
|
1721
|
-
return proxifyImageSrc(decodedSrc, 0, 0, format);
|
|
1722
|
-
}
|
|
1723
|
-
return proxifyImageSrc(decodedSrc, width, height, format);
|
|
1761
|
+
return proxifyFound(src, width, height, format);
|
|
1724
1762
|
}
|
|
1725
1763
|
return null;
|
|
1726
1764
|
}
|
|
@@ -1733,6 +1771,20 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
|
1733
1771
|
cacheSet(key, res);
|
|
1734
1772
|
return res;
|
|
1735
1773
|
}
|
|
1774
|
+
var summaryRenderer = new Remarkable({
|
|
1775
|
+
html: true,
|
|
1776
|
+
breaks: true,
|
|
1777
|
+
typographer: false
|
|
1778
|
+
});
|
|
1779
|
+
summaryRenderer.core.ruler.enable(["abbr"]);
|
|
1780
|
+
summaryRenderer.block.ruler.enable(["footnote", "deflist"]);
|
|
1781
|
+
summaryRenderer.inline.ruler.enable([
|
|
1782
|
+
"footnote_inline",
|
|
1783
|
+
"ins",
|
|
1784
|
+
"mark",
|
|
1785
|
+
"sub",
|
|
1786
|
+
"sup"
|
|
1787
|
+
]);
|
|
1736
1788
|
var joint = (arr, limit = 200) => {
|
|
1737
1789
|
let result = "";
|
|
1738
1790
|
if (arr) {
|
|
@@ -1758,25 +1810,6 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1758
1810
|
return "";
|
|
1759
1811
|
}
|
|
1760
1812
|
entryBody = cleanReply(entryBody);
|
|
1761
|
-
const mdd = new Remarkable({
|
|
1762
|
-
html: true,
|
|
1763
|
-
breaks: true,
|
|
1764
|
-
typographer: false
|
|
1765
|
-
}).use(linkify$1);
|
|
1766
|
-
mdd.core.ruler.enable([
|
|
1767
|
-
"abbr"
|
|
1768
|
-
]);
|
|
1769
|
-
mdd.block.ruler.enable([
|
|
1770
|
-
"footnote",
|
|
1771
|
-
"deflist"
|
|
1772
|
-
]);
|
|
1773
|
-
mdd.inline.ruler.enable([
|
|
1774
|
-
"footnote_inline",
|
|
1775
|
-
"ins",
|
|
1776
|
-
"mark",
|
|
1777
|
-
"sub",
|
|
1778
|
-
"sup"
|
|
1779
|
-
]);
|
|
1780
1813
|
const entities = entryBody.match(ENTITY_REGEX);
|
|
1781
1814
|
const entityPlaceholders = [];
|
|
1782
1815
|
if (entities && platform !== "web") {
|
|
@@ -1789,7 +1822,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1789
1822
|
}
|
|
1790
1823
|
let text2 = "";
|
|
1791
1824
|
try {
|
|
1792
|
-
text2 =
|
|
1825
|
+
text2 = summaryRenderer.render(entryBody);
|
|
1793
1826
|
} catch (err) {
|
|
1794
1827
|
console.error("[postBodySummary] Failed to render markdown:", {
|
|
1795
1828
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -1809,7 +1842,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1809
1842
|
text2 = joint(text2.split(" "), length);
|
|
1810
1843
|
}
|
|
1811
1844
|
if (text2) {
|
|
1812
|
-
text2 =
|
|
1845
|
+
text2 = he.decode(text2);
|
|
1813
1846
|
}
|
|
1814
1847
|
return text2;
|
|
1815
1848
|
}
|