tiny update
This commit is contained in:
@@ -10,7 +10,7 @@ export async function loadPluginNavItems(activeMap) {
|
||||
if (!plugins || !Array.isArray(plugins)) return;
|
||||
|
||||
const navPlugins = plugins.filter(
|
||||
(p) => p.navbar && p.enabled
|
||||
(p) => p && typeof p === "object" && p.navbar && p.enabled
|
||||
);
|
||||
|
||||
if (navPlugins.length === 0) return;
|
||||
@@ -28,11 +28,17 @@ export async function loadPluginNavItems(activeMap) {
|
||||
if (!childContainer) return;
|
||||
|
||||
const itemsHtml = navPlugins.map((p) => {
|
||||
const linkId = `plugin-nav-${p.id}`;
|
||||
activeMap[`/plugins/${p.id}`] = linkId;
|
||||
const pluginId = String(p.id || "").trim();
|
||||
if (
|
||||
!/^[A-Za-z0-9_-][A-Za-z0-9._-]{0,127}$/.test(pluginId) ||
|
||||
pluginId.includes("..") ||
|
||||
pluginId.endsWith(".")
|
||||
) return "";
|
||||
const linkId = `plugin-nav-${pluginId}`;
|
||||
activeMap[`/plugins/${pluginId}`] = linkId;
|
||||
|
||||
const childObj = {
|
||||
href: `/plugins/${p.id}`,
|
||||
href: `/plugins/${pluginId}`,
|
||||
label: p.navbar.label || p.name,
|
||||
icon: p.navbar.icon || "fa-cube",
|
||||
iconColor: "text-slate-300",
|
||||
|
||||
@@ -81,16 +81,45 @@ export const NAV_GROUPS = [
|
||||
TOPBAR — dropdown menus
|
||||
────────────────────────────────────────────── */
|
||||
|
||||
function escapeNavHtml(value) {
|
||||
return String(value ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function safeNavHref(value) {
|
||||
const href = String(value ?? "").trim();
|
||||
if (!href.startsWith("/") || href.startsWith("//") || /[\u0000-\u001f\u007f]/.test(href)) {
|
||||
return "#";
|
||||
}
|
||||
return escapeNavHtml(href);
|
||||
}
|
||||
|
||||
function safeNavId(value) {
|
||||
return String(value ?? "").replace(/[^A-Za-z0-9_.:-]/g, "-").slice(0, 192);
|
||||
}
|
||||
|
||||
function safeNavClassList(value) {
|
||||
return String(value ?? "")
|
||||
.split(/\s+/)
|
||||
.filter((token) => /^[A-Za-z0-9_-]+$/.test(token))
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
export function dropdownItem(child) {
|
||||
const hiddenCls = child.hidden ? " hidden" : "";
|
||||
const prefetchAttr = child.turboPrefetch === false ? ' data-turbo-prefetch="false"' : "";
|
||||
const badgeHtml = child.hasBadge
|
||||
? `<span id="enrollment-badge" class="nav-dd-badge hidden"></span>`
|
||||
: "";
|
||||
return `<a href="${child.href}" id="${child.linkId}"${prefetchAttr}
|
||||
class="nav-dd-item${hiddenCls}" data-link-id="${child.linkId}">
|
||||
<i class="fa-solid ${child.icon} ${child.iconColor} nav-dd-item-icon"></i>
|
||||
<span>${child.label}</span>
|
||||
const linkId = safeNavId(child.linkId);
|
||||
return `<a href="${safeNavHref(child.href)}" id="${linkId}"${prefetchAttr}
|
||||
class="nav-dd-item${hiddenCls}" data-link-id="${linkId}">
|
||||
<i class="fa-solid ${safeNavClassList(child.icon)} ${safeNavClassList(child.iconColor)} nav-dd-item-icon"></i>
|
||||
<span>${escapeNavHtml(child.label)}</span>
|
||||
${badgeHtml}
|
||||
</a>`;
|
||||
}
|
||||
@@ -241,10 +270,12 @@ export function sidebarChild(child) {
|
||||
const badgeHtml = child.hasBadge
|
||||
? `<span id="enrollment-badge" class="sb-badge hidden"></span>`
|
||||
: "";
|
||||
return `<a href="${child.href}" id="${child.linkId}"
|
||||
class="sb-link sb-link-child${hiddenCls}" data-link-id="${child.linkId}" title="${child.label}">
|
||||
<i class="fa-solid ${child.icon} ${child.iconColor} sb-icon"></i>
|
||||
<span class="sb-text">${child.label}</span>
|
||||
const linkId = safeNavId(child.linkId);
|
||||
const label = escapeNavHtml(child.label);
|
||||
return `<a href="${safeNavHref(child.href)}" id="${linkId}"
|
||||
class="sb-link sb-link-child${hiddenCls}" data-link-id="${linkId}" title="${label}">
|
||||
<i class="fa-solid ${safeNavClassList(child.icon)} ${safeNavClassList(child.iconColor)} sb-icon"></i>
|
||||
<span class="sb-text">${label}</span>
|
||||
${badgeHtml}
|
||||
</a>`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user