@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/browser/index.js
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,13 +168,13 @@ var ALLOWED_ATTRIBUTES = {
|
|
|
168
168
|
"del": [],
|
|
169
169
|
"ins": []
|
|
170
170
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
var
|
|
171
|
+
function createParser() {
|
|
172
|
+
return new DOMParser$1({
|
|
173
|
+
onError(level, msg) {
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
var DOMParser = createParser();
|
|
178
178
|
|
|
179
179
|
// src/helper.ts
|
|
180
180
|
function removeDuplicateAttributes(html) {
|
|
@@ -296,6 +296,14 @@ function sanitizeHtml(html) {
|
|
|
296
296
|
});
|
|
297
297
|
}
|
|
298
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
|
+
}
|
|
299
307
|
function setProxyBase(p2) {
|
|
300
308
|
proxyBase = p2;
|
|
301
309
|
}
|
|
@@ -346,7 +354,7 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
|
|
|
346
354
|
if (pHash) {
|
|
347
355
|
return `${proxyBase}/p/${pHash}?${qs}`;
|
|
348
356
|
}
|
|
349
|
-
const b58url =
|
|
357
|
+
const b58url = getUrlHash(realUrl.toString());
|
|
350
358
|
return `${proxyBase}/p/${b58url}?${qs}`;
|
|
351
359
|
}
|
|
352
360
|
var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
|
|
@@ -1590,8 +1598,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext,
|
|
|
1590
1598
|
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext, renderOptions);
|
|
1591
1599
|
output = serializer.serializeToString(doc);
|
|
1592
1600
|
} catch (fallbackError) {
|
|
1593
|
-
|
|
1594
|
-
output = `<p dir="auto">${escapedContent}</p>`;
|
|
1601
|
+
output = sanitizeHtml(output || md.render(input));
|
|
1595
1602
|
}
|
|
1596
1603
|
}
|
|
1597
1604
|
if (forApp && output && entityPlaceholders.length > 0) {
|
|
@@ -1600,7 +1607,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext,
|
|
|
1600
1607
|
output = output.split(placeholder).join(entity);
|
|
1601
1608
|
});
|
|
1602
1609
|
}
|
|
1603
|
-
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();
|
|
1604
1611
|
return sanitizeHtml(output);
|
|
1605
1612
|
}
|
|
1606
1613
|
var mdInstance = null;
|
|
@@ -1619,7 +1626,7 @@ function simpleMarkdownToHTML(input) {
|
|
|
1619
1626
|
const html = getMd().render(input);
|
|
1620
1627
|
return sanitizeHtml(html);
|
|
1621
1628
|
}
|
|
1622
|
-
var cache = new LRUCache({ max:
|
|
1629
|
+
var cache = new LRUCache({ max: 500 });
|
|
1623
1630
|
function setCacheSize(size) {
|
|
1624
1631
|
cache = new LRUCache({ max: size });
|
|
1625
1632
|
}
|
|
@@ -1650,6 +1657,40 @@ var gifLinkRegex = /\.(gif)$/i;
|
|
|
1650
1657
|
function isGifLink(link) {
|
|
1651
1658
|
return gifLinkRegex.test(link);
|
|
1652
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
|
+
}
|
|
1653
1694
|
function getImage(entry, width = 0, height = 0, format = "match") {
|
|
1654
1695
|
let meta;
|
|
1655
1696
|
if (typeof entry.json_metadata === "object") {
|
|
@@ -1662,7 +1703,7 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1662
1703
|
}
|
|
1663
1704
|
}
|
|
1664
1705
|
if (meta && typeof meta.image === "string" && meta.image.length > 0) {
|
|
1665
|
-
const decodedImage =
|
|
1706
|
+
const decodedImage = he.decode(meta.image);
|
|
1666
1707
|
if (isGifLink(decodedImage)) {
|
|
1667
1708
|
return proxifyImageSrc(decodedImage, 0, 0, format);
|
|
1668
1709
|
}
|
|
@@ -1670,7 +1711,7 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1670
1711
|
}
|
|
1671
1712
|
if (meta && meta.image && !!meta.image.length && meta.image[0]) {
|
|
1672
1713
|
if (typeof meta.image[0] === "string") {
|
|
1673
|
-
const decodedImage =
|
|
1714
|
+
const decodedImage = he.decode(meta.image[0]);
|
|
1674
1715
|
if (isGifLink(decodedImage)) {
|
|
1675
1716
|
return proxifyImageSrc(decodedImage, 0, 0, format);
|
|
1676
1717
|
}
|
|
@@ -1681,6 +1722,10 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1681
1722
|
}
|
|
1682
1723
|
return proxifyImageSrc(meta.image[0], width, height, format);
|
|
1683
1724
|
}
|
|
1725
|
+
const fast = findFirstImageUrl(entry.body);
|
|
1726
|
+
if (fast) {
|
|
1727
|
+
return proxifyFound(fast, width, height, format);
|
|
1728
|
+
}
|
|
1684
1729
|
const html = markdown2Html(entry);
|
|
1685
1730
|
const doc = createDoc(html);
|
|
1686
1731
|
if (!doc) {
|
|
@@ -1692,16 +1737,16 @@ function getImage(entry, width = 0, height = 0, format = "match") {
|
|
|
1692
1737
|
if (!src) {
|
|
1693
1738
|
return null;
|
|
1694
1739
|
}
|
|
1695
|
-
|
|
1696
|
-
if (isGifLink(decodedSrc)) {
|
|
1697
|
-
return proxifyImageSrc(decodedSrc, 0, 0, format);
|
|
1698
|
-
}
|
|
1699
|
-
return proxifyImageSrc(decodedSrc, width, height, format);
|
|
1740
|
+
return proxifyFound(src, width, height, format);
|
|
1700
1741
|
}
|
|
1701
1742
|
return null;
|
|
1702
1743
|
}
|
|
1703
1744
|
function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
1704
1745
|
if (typeof obj === "string") {
|
|
1746
|
+
const fast = findFirstImageUrl(obj);
|
|
1747
|
+
if (fast) {
|
|
1748
|
+
return proxifyFound(fast, width, height, format);
|
|
1749
|
+
}
|
|
1705
1750
|
const html = markdown2Html(obj);
|
|
1706
1751
|
const doc = createDoc(html);
|
|
1707
1752
|
if (!doc) {
|
|
@@ -1713,11 +1758,7 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
|
1713
1758
|
if (!src) {
|
|
1714
1759
|
return null;
|
|
1715
1760
|
}
|
|
1716
|
-
|
|
1717
|
-
if (isGifLink(decodedSrc)) {
|
|
1718
|
-
return proxifyImageSrc(decodedSrc, 0, 0, format);
|
|
1719
|
-
}
|
|
1720
|
-
return proxifyImageSrc(decodedSrc, width, height, format);
|
|
1761
|
+
return proxifyFound(src, width, height, format);
|
|
1721
1762
|
}
|
|
1722
1763
|
return null;
|
|
1723
1764
|
}
|
|
@@ -1730,6 +1771,20 @@ function catchPostImage(obj, width = 0, height = 0, format = "match") {
|
|
|
1730
1771
|
cacheSet(key, res);
|
|
1731
1772
|
return res;
|
|
1732
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
|
+
]);
|
|
1733
1788
|
var joint = (arr, limit = 200) => {
|
|
1734
1789
|
let result = "";
|
|
1735
1790
|
if (arr) {
|
|
@@ -1755,25 +1810,6 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1755
1810
|
return "";
|
|
1756
1811
|
}
|
|
1757
1812
|
entryBody = cleanReply(entryBody);
|
|
1758
|
-
const mdd = new Remarkable({
|
|
1759
|
-
html: true,
|
|
1760
|
-
breaks: true,
|
|
1761
|
-
typographer: false
|
|
1762
|
-
}).use(linkify$1);
|
|
1763
|
-
mdd.core.ruler.enable([
|
|
1764
|
-
"abbr"
|
|
1765
|
-
]);
|
|
1766
|
-
mdd.block.ruler.enable([
|
|
1767
|
-
"footnote",
|
|
1768
|
-
"deflist"
|
|
1769
|
-
]);
|
|
1770
|
-
mdd.inline.ruler.enable([
|
|
1771
|
-
"footnote_inline",
|
|
1772
|
-
"ins",
|
|
1773
|
-
"mark",
|
|
1774
|
-
"sub",
|
|
1775
|
-
"sup"
|
|
1776
|
-
]);
|
|
1777
1813
|
const entities = entryBody.match(ENTITY_REGEX);
|
|
1778
1814
|
const entityPlaceholders = [];
|
|
1779
1815
|
if (entities && platform !== "web") {
|
|
@@ -1786,7 +1822,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1786
1822
|
}
|
|
1787
1823
|
let text2 = "";
|
|
1788
1824
|
try {
|
|
1789
|
-
text2 =
|
|
1825
|
+
text2 = summaryRenderer.render(entryBody);
|
|
1790
1826
|
} catch (err) {
|
|
1791
1827
|
console.error("[postBodySummary] Failed to render markdown:", {
|
|
1792
1828
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -1806,7 +1842,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
|
|
|
1806
1842
|
text2 = joint(text2.split(" "), length);
|
|
1807
1843
|
}
|
|
1808
1844
|
if (text2) {
|
|
1809
|
-
text2 =
|
|
1845
|
+
text2 = he.decode(text2);
|
|
1810
1846
|
}
|
|
1811
1847
|
return text2;
|
|
1812
1848
|
}
|