@ecency/render-helper 2.4.25 → 2.4.27
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.d.ts +8 -2
- package/dist/browser/index.js +82 -40
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +82 -40
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.mjs +82 -40
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -433,7 +433,7 @@ var addLineBreakBeforePostLink = (el, forApp, isInline) => {
|
|
|
433
433
|
el.parentNode.insertBefore(br, el);
|
|
434
434
|
}
|
|
435
435
|
};
|
|
436
|
-
function a(el, forApp, parentDomain = "ecency.com", seoContext) {
|
|
436
|
+
function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
|
|
437
437
|
if (!el || !el.parentNode) {
|
|
438
438
|
return;
|
|
439
439
|
}
|
|
@@ -442,7 +442,7 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext) {
|
|
|
442
442
|
return;
|
|
443
443
|
}
|
|
444
444
|
const className = el.getAttribute("class");
|
|
445
|
-
if (["markdown-author-link", "markdown-tag-link"].
|
|
445
|
+
if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
|
|
446
446
|
return;
|
|
447
447
|
}
|
|
448
448
|
if (href && href.trim().toLowerCase().startsWith("javascript:")) {
|
|
@@ -782,14 +782,29 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext) {
|
|
|
782
782
|
if (startTime) {
|
|
783
783
|
el.setAttribute("data-start-time", startTime);
|
|
784
784
|
}
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
785
|
+
if (renderOptions?.embedVideosDirectly) {
|
|
786
|
+
const wrapper = el.ownerDocument.createElement("span");
|
|
787
|
+
wrapper.setAttribute("class", "er-youtube-frame");
|
|
788
|
+
wrapper.setAttribute("style", "display:block");
|
|
789
|
+
const iframe2 = el.ownerDocument.createElement("iframe");
|
|
790
|
+
iframe2.setAttribute("class", "youtube-player");
|
|
791
|
+
iframe2.setAttribute("src", embedSrc);
|
|
792
|
+
iframe2.setAttribute("title", "YouTube video");
|
|
793
|
+
iframe2.setAttribute("allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share");
|
|
794
|
+
iframe2.setAttribute("allowfullscreen", "");
|
|
795
|
+
wrapper.appendChild(iframe2);
|
|
796
|
+
el.appendChild(wrapper);
|
|
797
|
+
el.setAttribute("class", "markdown-video-link markdown-video-link-youtube er-youtube");
|
|
798
|
+
} else {
|
|
799
|
+
const thumbImg = el.ownerDocument.createElement("img");
|
|
800
|
+
thumbImg.setAttribute("class", "no-replace video-thumbnail");
|
|
801
|
+
thumbImg.setAttribute("itemprop", "thumbnailUrl");
|
|
802
|
+
thumbImg.setAttribute("src", thumbnail);
|
|
803
|
+
const play = el.ownerDocument.createElement("span");
|
|
804
|
+
play.setAttribute("class", "markdown-video-play");
|
|
805
|
+
el.appendChild(thumbImg);
|
|
806
|
+
el.appendChild(play);
|
|
807
|
+
}
|
|
793
808
|
return;
|
|
794
809
|
}
|
|
795
810
|
match = href.match(VIMEO_REGEX);
|
|
@@ -911,21 +926,36 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext) {
|
|
|
911
926
|
if (el.textContent.trim() === href) {
|
|
912
927
|
el.textContent = "";
|
|
913
928
|
}
|
|
914
|
-
if (
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
929
|
+
if (renderOptions?.embedVideosDirectly) {
|
|
930
|
+
const wrapper = el.ownerDocument.createElement("span");
|
|
931
|
+
wrapper.setAttribute("class", "er-speak-frame");
|
|
932
|
+
wrapper.setAttribute("style", "display:block");
|
|
933
|
+
const iframe2 = el.ownerDocument.createElement("iframe");
|
|
934
|
+
iframe2.setAttribute("class", "speak-iframe");
|
|
935
|
+
iframe2.setAttribute("src", videoHref);
|
|
936
|
+
iframe2.setAttribute("title", "3Speak video");
|
|
937
|
+
iframe2.setAttribute("allow", "accelerometer; encrypted-media; gyroscope; picture-in-picture; web-share");
|
|
938
|
+
iframe2.setAttribute("allowfullscreen", "");
|
|
939
|
+
wrapper.appendChild(iframe2);
|
|
940
|
+
el.appendChild(wrapper);
|
|
941
|
+
el.setAttribute("class", "markdown-video-link markdown-video-link-speak er-speak");
|
|
942
|
+
} else {
|
|
943
|
+
if (imgEls2.length === 1) {
|
|
944
|
+
const src = imgEls2[0].getAttribute("src");
|
|
945
|
+
if (src) {
|
|
946
|
+
const thumbnail = proxifyImageSrc(src.replace(/\s+/g, ""), 0, 0, "match");
|
|
947
|
+
const thumbImg = el.ownerDocument.createElement("img");
|
|
948
|
+
thumbImg.setAttribute("class", "no-replace video-thumbnail");
|
|
949
|
+
thumbImg.setAttribute("itemprop", "thumbnailUrl");
|
|
950
|
+
thumbImg.setAttribute("src", thumbnail);
|
|
951
|
+
el.appendChild(thumbImg);
|
|
952
|
+
el.removeChild(imgEls2[0]);
|
|
953
|
+
}
|
|
924
954
|
}
|
|
955
|
+
const play = el.ownerDocument.createElement("span");
|
|
956
|
+
play.setAttribute("class", "markdown-video-play");
|
|
957
|
+
el.appendChild(play);
|
|
925
958
|
}
|
|
926
|
-
const play = el.ownerDocument.createElement("span");
|
|
927
|
-
play.setAttribute("class", "markdown-video-play");
|
|
928
|
-
el.appendChild(play);
|
|
929
959
|
return;
|
|
930
960
|
}
|
|
931
961
|
}
|
|
@@ -1187,24 +1217,33 @@ function p(el) {
|
|
|
1187
1217
|
}
|
|
1188
1218
|
|
|
1189
1219
|
// src/methods/linkify.method.ts
|
|
1190
|
-
function linkify(content, forApp) {
|
|
1220
|
+
function linkify(content, forApp, renderOptions) {
|
|
1191
1221
|
content = content.replace(/(^|\s|>)(#[-a-z\d]+)/gi, (tag) => {
|
|
1192
1222
|
if (/#[\d]+$/.test(tag)) return tag;
|
|
1193
1223
|
const preceding = /^\s|>/.test(tag) ? tag[0] : "";
|
|
1194
1224
|
tag = tag.replace(">", "");
|
|
1195
1225
|
const tag2 = tag.trim().substring(1);
|
|
1196
1226
|
const tagLower = tag2.toLowerCase();
|
|
1197
|
-
|
|
1198
|
-
|
|
1227
|
+
if (!forApp) {
|
|
1228
|
+
return `${preceding}<a class="er-tag er-tag-link" href="/trending/${tagLower}">${tag.trim()}</a>`;
|
|
1229
|
+
}
|
|
1230
|
+
return `${preceding}<a class="markdown-tag-link" data-tag="${tagLower}">${tag.trim()}</a>`;
|
|
1199
1231
|
});
|
|
1232
|
+
const authorPlaceholders = [];
|
|
1200
1233
|
content = content.replace(
|
|
1201
1234
|
/(^|[^a-zA-Z0-9_!#$%&*@@/]|(^|[^a-zA-Z0-9_+~.-/]))[@@]([a-z][-.a-z\d^/]+[a-z\d])/gi,
|
|
1202
1235
|
(match, preceeding1, preceeding2, user) => {
|
|
1203
1236
|
const userLower = user.toLowerCase();
|
|
1204
1237
|
const preceedings = (preceeding1 || "") + (preceeding2 || "");
|
|
1205
1238
|
if (userLower.indexOf("/") === -1 && isValidUsername(user)) {
|
|
1206
|
-
|
|
1207
|
-
|
|
1239
|
+
if (!forApp) {
|
|
1240
|
+
const avatarSrc = `https://images.ecency.com/u/${userLower}/avatar/small`;
|
|
1241
|
+
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>`;
|
|
1242
|
+
const placeholder = `\u200C${authorPlaceholders.length}\u200C`;
|
|
1243
|
+
authorPlaceholders.push({ placeholder, html });
|
|
1244
|
+
return placeholder;
|
|
1245
|
+
}
|
|
1246
|
+
return `${preceedings}<a class="markdown-author-link" data-author="${userLower}">@${user}</a>`;
|
|
1208
1247
|
} else {
|
|
1209
1248
|
return match;
|
|
1210
1249
|
}
|
|
@@ -1247,6 +1286,9 @@ function linkify(content, forApp) {
|
|
|
1247
1286
|
firstImageUsed = true;
|
|
1248
1287
|
return createImageHTML(imglink, isLCP);
|
|
1249
1288
|
});
|
|
1289
|
+
authorPlaceholders.forEach(({ placeholder, html }) => {
|
|
1290
|
+
content = content.replace(placeholder, html);
|
|
1291
|
+
});
|
|
1250
1292
|
return content;
|
|
1251
1293
|
}
|
|
1252
1294
|
|
|
@@ -1261,7 +1303,7 @@ function hasAncestor(node, tagNames) {
|
|
|
1261
1303
|
}
|
|
1262
1304
|
return false;
|
|
1263
1305
|
}
|
|
1264
|
-
function text(node, forApp) {
|
|
1306
|
+
function text(node, forApp, renderOptions) {
|
|
1265
1307
|
if (!node || !node.parentNode) {
|
|
1266
1308
|
return;
|
|
1267
1309
|
}
|
|
@@ -1342,7 +1384,7 @@ function text(node, forApp) {
|
|
|
1342
1384
|
}
|
|
1343
1385
|
|
|
1344
1386
|
// src/methods/traverse.method.ts
|
|
1345
|
-
function traverse(node, forApp, depth = 0, state = { firstImageFound: false }, parentDomain = "ecency.com", seoContext) {
|
|
1387
|
+
function traverse(node, forApp, depth = 0, state = { firstImageFound: false }, parentDomain = "ecency.com", seoContext, renderOptions) {
|
|
1346
1388
|
if (!node || !node.childNodes) {
|
|
1347
1389
|
return;
|
|
1348
1390
|
}
|
|
@@ -1351,7 +1393,7 @@ function traverse(node, forApp, depth = 0, state = { firstImageFound: false }, p
|
|
|
1351
1393
|
const next = child.nextSibling;
|
|
1352
1394
|
const prev = child.previousSibling;
|
|
1353
1395
|
if (child.nodeName.toLowerCase() === "a") {
|
|
1354
|
-
a(child, forApp, parentDomain, seoContext);
|
|
1396
|
+
a(child, forApp, parentDomain, seoContext, renderOptions);
|
|
1355
1397
|
}
|
|
1356
1398
|
if (child.nodeName.toLowerCase() === "iframe") {
|
|
1357
1399
|
iframe(child, parentDomain, forApp);
|
|
@@ -1366,11 +1408,11 @@ function traverse(node, forApp, depth = 0, state = { firstImageFound: false }, p
|
|
|
1366
1408
|
p(child);
|
|
1367
1409
|
}
|
|
1368
1410
|
if (child.parentNode) {
|
|
1369
|
-
traverse(child, forApp, depth + 1, state, parentDomain, seoContext);
|
|
1411
|
+
traverse(child, forApp, depth + 1, state, parentDomain, seoContext, renderOptions);
|
|
1370
1412
|
} else {
|
|
1371
1413
|
const possibleReplacement = next ? next.previousSibling : node.lastChild;
|
|
1372
1414
|
if (possibleReplacement && possibleReplacement !== prev && possibleReplacement.parentNode === node) {
|
|
1373
|
-
traverse(possibleReplacement, forApp, depth + 1, state, parentDomain, seoContext);
|
|
1415
|
+
traverse(possibleReplacement, forApp, depth + 1, state, parentDomain, seoContext, renderOptions);
|
|
1374
1416
|
}
|
|
1375
1417
|
}
|
|
1376
1418
|
child = next;
|
|
@@ -1423,7 +1465,7 @@ function fixBlockLevelTagsInParagraphs(html) {
|
|
|
1423
1465
|
html = html.replace(/<p><br>\s*<\/p>/g, "");
|
|
1424
1466
|
return html;
|
|
1425
1467
|
}
|
|
1426
|
-
function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext) {
|
|
1468
|
+
function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
|
|
1427
1469
|
input = input.replace(new RegExp("https://leofinance.io/threads/view/", "g"), "/@");
|
|
1428
1470
|
input = input.replace(new RegExp("https://leofinance.io/posts/", "g"), "/@");
|
|
1429
1471
|
input = input.replace(new RegExp("https://leofinance.io/threads/", "g"), "/@");
|
|
@@ -1483,7 +1525,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext)
|
|
|
1483
1525
|
output = md.render(input);
|
|
1484
1526
|
output = fixBlockLevelTagsInParagraphs(output);
|
|
1485
1527
|
const doc = DOMParser.parseFromString(`<body id="root">${removeDuplicateAttributes(output)}</body>`, "text/html");
|
|
1486
|
-
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext);
|
|
1528
|
+
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext, renderOptions);
|
|
1487
1529
|
output = serializer.serializeToString(doc);
|
|
1488
1530
|
} catch (error) {
|
|
1489
1531
|
try {
|
|
@@ -1496,7 +1538,7 @@ function markdownToHTML(input, forApp, parentDomain = "ecency.com", seoContext)
|
|
|
1496
1538
|
});
|
|
1497
1539
|
const repairedHtml = domSerializer(dom.children);
|
|
1498
1540
|
const doc = DOMParser.parseFromString(`<body id="root">${removeDuplicateAttributes(repairedHtml)}</body>`, "text/html");
|
|
1499
|
-
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext);
|
|
1541
|
+
traverse(doc, forApp, 0, { firstImageFound: false }, parentDomain, seoContext, renderOptions);
|
|
1500
1542
|
output = serializer.serializeToString(doc);
|
|
1501
1543
|
} catch (fallbackError) {
|
|
1502
1544
|
const escapedContent = he2.encode(output || md.render(input));
|
|
@@ -1524,18 +1566,18 @@ function cacheSet(key, value) {
|
|
|
1524
1566
|
}
|
|
1525
1567
|
|
|
1526
1568
|
// src/markdown-2-html.ts
|
|
1527
|
-
function markdown2Html(obj, forApp = true, _webp = false, parentDomain = "ecency.com", seoContext) {
|
|
1569
|
+
function markdown2Html(obj, forApp = true, _webp = false, parentDomain = "ecency.com", seoContext, renderOptions) {
|
|
1528
1570
|
if (typeof obj === "string") {
|
|
1529
1571
|
const cleanedStr = cleanReply(obj);
|
|
1530
|
-
return markdownToHTML(cleanedStr, forApp, parentDomain, seoContext);
|
|
1572
|
+
return markdownToHTML(cleanedStr, forApp, parentDomain, seoContext, renderOptions);
|
|
1531
1573
|
}
|
|
1532
|
-
const key = `${makeEntryCacheKey(obj)}-md-${forApp ? "app" : "site"}-${parentDomain}${seoContext ? `-seo${seoContext.authorReputation ?? ""}-${seoContext.postPayout ?? ""}` : ""}`;
|
|
1574
|
+
const key = `${makeEntryCacheKey(obj)}-md-${forApp ? "app" : "site"}-${parentDomain}${seoContext ? `-seo${seoContext.authorReputation ?? ""}-${seoContext.postPayout ?? ""}` : ""}${renderOptions?.embedVideosDirectly ? "-embed" : ""}`;
|
|
1533
1575
|
const item = cacheGet(key);
|
|
1534
1576
|
if (item) {
|
|
1535
1577
|
return item;
|
|
1536
1578
|
}
|
|
1537
1579
|
const cleanBody = cleanReply(obj.body);
|
|
1538
|
-
const res = markdownToHTML(cleanBody, forApp, parentDomain, seoContext);
|
|
1580
|
+
const res = markdownToHTML(cleanBody, forApp, parentDomain, seoContext, renderOptions);
|
|
1539
1581
|
cacheSet(key, res);
|
|
1540
1582
|
return res;
|
|
1541
1583
|
}
|