fix(share): HTML tags displayed escaped in headings

This commit is contained in:
Elian Doran
2025-10-23 14:19:54 +03:00
parent 94d62f810a
commit d2b6014b49
4 changed files with 9 additions and 7 deletions

View File

@@ -497,7 +497,7 @@ export function formatSize(size: number | null | undefined) {
} }
} }
export function slugify(text: string) { function slugify(text: string) {
return text return text
.normalize("NFKD") // handles accents like é → e .normalize("NFKD") // handles accents like é → e
.toLowerCase() .toLowerCase()
@@ -540,6 +540,7 @@ export default {
safeExtractMessageAndStackFromError, safeExtractMessageAndStackFromError,
sanitizeSqlIdentifier, sanitizeSqlIdentifier,
stripTags, stripTags,
slugify,
timeLimit, timeLimit,
toBase64, toBase64,
toMap, toMap,

View File

@@ -14,7 +14,7 @@ import log from "../services/log.js";
import type SNote from "./shaca/entities/snote.js"; import type SNote from "./shaca/entities/snote.js";
import type SBranch from "./shaca/entities/sbranch.js"; import type SBranch from "./shaca/entities/sbranch.js";
import type SAttachment from "./shaca/entities/sattachment.js"; import type SAttachment from "./shaca/entities/sattachment.js";
import utils, { isDev, safeExtractMessageAndStackFromError, slugify } from "../services/utils.js"; import utils, { isDev, safeExtractMessageAndStackFromError } from "../services/utils.js";
import options from "../services/options.js"; import options from "../services/options.js";
import { t } from "i18next"; import { t } from "i18next";
import ejs from "ejs"; import ejs from "ejs";
@@ -176,7 +176,7 @@ function register(router: Router) {
showLoginInShareTheme, showLoginInShareTheme,
t, t,
isDev, isDev,
slugify utils
}; };
let useDefaultView = true; let useDefaultView = true;

View File

@@ -91,7 +91,8 @@ const themeClass = currentTheme === "light" ? " theme-light" : " theme-dark";
const headingRe = /(<h[1-6]>)(.+?)(<\/h[1-6]>)/g; const headingRe = /(<h[1-6]>)(.+?)(<\/h[1-6]>)/g;
const headingMatches = [...content.matchAll(headingRe)]; const headingMatches = [...content.matchAll(headingRe)];
content = content.replaceAll(headingRe, (...match) => { content = content.replaceAll(headingRe, (...match) => {
match[0] = match[0].replace(match[3], `<a id="${slugify(match[2])}" class="toc-anchor" name="${slugify(match[2])}" href="#${slugify(match[2])}">#</a>${match[3]}`); const slug = utils.slugify(utils.stripTags(match[2]));
match[0] = match[0].replace(match[3], `<a id="${slug}" class="toc-anchor" name="${slug}" href="#${slug}">#</a>${match[3]}`);
return match[0]; return match[0];
}); });
%> %>

View File

@@ -1,11 +1,11 @@
<% <%
const slug = slugify(entry.name); const strippedName = utils.stripTags(entry.name);
const slug = utils.slugify(strippedName);
%> %>
<li> <li>
<a href="#<%= slug %>"> <a href="#<%= slug %>">
<span><%= entry.name %></span> <span><%= strippedName %></span>
</a> </a>
<% if (entry.children.length) { %> <% if (entry.children.length) { %>