"@types/autosize": "^4.0.0",
"@types/express": "^4.17.13",
"@types/html-to-text": "^8.1.1",
+ "@types/markdown-it": "^12.2.3",
+ "@types/markdown-it-container": "^2.0.5",
"@types/node": "^18.6.2",
"@types/node-fetch": "^2.6.2",
"@types/serialize-javascript": "^5.0.1",
+ "@types/toastify-js": "^1.11.1",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"bootstrap": "^5.2.0",
isBanned,
isMod,
mdToHtml,
+ mdToHtmlNoImages,
numToSI,
setupTippy,
showScores,
enableDownvotes: boolean;
viewType: CommentViewType;
allLanguages: Language[];
+ hideImages?: boolean;
}
export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
) : (
<div
className="md-div"
- dangerouslySetInnerHTML={mdToHtml(
- this.commentUnlessRemoved
- )}
+ dangerouslySetInnerHTML={
+ this.props.hideImages
+ ? mdToHtmlNoImages(this.commentUnlessRemoved)
+ : mdToHtml(this.commentUnlessRemoved)
+ }
/>
)}
<div className="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold">
enableDownvotes={this.props.enableDownvotes}
viewType={this.props.viewType}
allLanguages={this.props.allLanguages}
+ hideImages={this.props.hideImages}
/>
)}
{/* A collapsed clearfix */}
enableDownvotes?: boolean;
viewType: CommentViewType;
allLanguages: Language[];
+ hideImages?: boolean;
}
export class CommentNodes extends Component<CommentNodesProps, any> {
enableDownvotes={this.props.enableDownvotes}
viewType={this.props.viewType}
allLanguages={this.props.allLanguages}
+ hideImages={this.props.hideImages}
/>
))}
</div>
viewOnly={true}
showCommunity={true}
allLanguages={[]}
+ hideImages
/>
<div>
{i18n.t("reporter")}: <PersonListing person={r.creator} />
isImage,
isMod,
isVideo,
- md,
+ mdNoImages,
mdToHtml,
mdToHtmlInline,
numToSI,
<li className="list-inline-item">
<button
className="text-muted btn btn-sm btn-link p-0"
- data-tippy-content={md.render(body)}
+ data-tippy-content={mdNoImages.render(body)}
data-tippy-allowHtml={true}
onClick={linkEvent(this, this.handleShowBody)}
>
Search,
SearchType,
SortType,
+ toUndefined,
} from "lemmy-js-client";
-import markdown_it from "markdown-it";
+import { default as MarkdownIt } from "markdown-it";
import markdown_it_container from "markdown-it-container";
import markdown_it_footnote from "markdown-it-footnote";
import markdown_it_html5_embed from "markdown-it-html5-embed";
.join("");
}
-export const md = new markdown_it({
+const html5EmbedConfig = {
+ html5embed: {
+ useImageSyntax: true, // Enables video/audio embed with ![]() syntax (default)
+ attributes: {
+ audio: 'controls preload="metadata"',
+ video: 'width="100%" max-height="100%" controls loop preload="metadata"',
+ },
+ },
+};
+
+const spoilerConfig = {
+ validate: (params: string) => {
+ return params.trim().match(/^spoiler\s+(.*)$/);
+ },
+
+ render: (tokens: any, idx: any) => {
+ var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/);
+
+ if (tokens[idx].nesting === 1) {
+ // opening tag
+ return `<details><summary> ${md.utils.escapeHtml(m[1])} </summary>\n`;
+ } else {
+ // closing tag
+ return "</details>\n";
+ }
+ },
+};
+
+const markdownItConfig: MarkdownIt.Options = {
html: false,
linkify: true,
typographer: true,
-})
+};
+
+export const md = new MarkdownIt(markdownItConfig)
.use(markdown_it_sub)
.use(markdown_it_sup)
.use(markdown_it_footnote)
- .use(markdown_it_html5_embed, {
- html5embed: {
- useImageSyntax: true, // Enables video/audio embed with ![]() syntax (default)
- attributes: {
- audio: 'controls preload="metadata"',
- video:
- 'width="100%" max-height="100%" controls loop preload="metadata"',
- },
- },
- })
- .use(markdown_it_container, "spoiler", {
- validate: function (params: any) {
- return params.trim().match(/^spoiler\s+(.*)$/);
- },
-
- render: function (tokens: any, idx: any) {
- var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/);
+ .use(markdown_it_html5_embed, html5EmbedConfig)
+ .use(markdown_it_container, "spoiler", spoilerConfig);
- if (tokens[idx].nesting === 1) {
- // opening tag
- return `<details><summary> ${md.utils.escapeHtml(m[1])} </summary>\n`;
- } else {
- // closing tag
- return "</details>\n";
- }
- },
- });
+export const mdNoImages = new MarkdownIt(markdownItConfig)
+ .use(markdown_it_sub)
+ .use(markdown_it_sup)
+ .use(markdown_it_footnote)
+ .use(markdown_it_html5_embed, html5EmbedConfig)
+ .use(markdown_it_container, "spoiler", spoilerConfig)
+ .disable("image");
export function hotRankComment(comment_view: CommentView): number {
return hotRank(comment_view.counts.score, comment_view.comment.published);
return { __html: md.render(text) };
}
+export function mdToHtmlNoImages(text: string) {
+ return { __html: mdNoImages.render(text) };
+}
+
export function mdToHtmlInline(text: string) {
return { __html: md.renderInline(text) };
}
}
},
close: true,
- }).showToast();
+ });
+ toast.showToast();
}
}
let toast = Toastify({
text: `${htmlBody}<br />${info.name}`,
- avatar: info.icon,
+ avatar: toUndefined(info.icon),
backgroundColor: backgroundColor,
className: "text-dark",
close: true,
router.history.push(info.link);
}
},
- }).showToast();
+ });
+ toast.showToast();
}
}
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
+"@types/linkify-it@*":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9"
+ integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==
+
+"@types/markdown-it-container@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@types/markdown-it-container/-/markdown-it-container-2.0.5.tgz#abd793b64c5adc7b2d1e8963eddb388198248152"
+ integrity sha512-8v5jIC5gcCUv+JcD0DExwNBkoKC0kLB4acensF0NoNlTIcXmQxF3RDjzAdIW82sXSoR+n772ePguxIWlq2ELvA==
+ dependencies:
+ "@types/markdown-it" "*"
+
+"@types/markdown-it@*", "@types/markdown-it@^12.2.3":
+ version "12.2.3"
+ resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51"
+ integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==
+ dependencies:
+ "@types/linkify-it" "*"
+ "@types/mdurl" "*"
+
+"@types/mdurl@*":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9"
+ integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
+
"@types/mime@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
dependencies:
"@types/node" "*"
+"@types/toastify-js@^1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@types/toastify-js/-/toastify-js-1.11.1.tgz#48f96596e087025c7f7821668599fd74dcdd8549"
+ integrity sha512-Ef03kGFWseAQYIQwN83WbhRxD+DOd+X6p22j9olA/TnvE0crDMc3fyoctKSpXgEDVWq5l3p98otIdpNX1pOYMA==
+
"@types/ws@^8.5.1":
version "8.5.3"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"