added nested navmenus

This commit is contained in:
boris committed 2026-02-26 01:13:22 +00:00
1 parent a73c5ea002
commit 18734acaad
4 files changed
+525 -85

No files matched your search

+97 -3
View File
@@ -367,6 +367,32 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
return cleanNavLabel(ele.textContent || "");
};
const getNavEntryMeta = (ele) => {
if (!ele) return {};
const out = {};
const dateEle = ele.querySelector(":scope > .page__nav-date");
if (dateEle) {
const datePrefix = cleanNavLabel(dateEle.textContent || "");
if (datePrefix) out.datePrefix = datePrefix;
}
const sourceEle = ele.querySelector(":scope > .nav2-list__disp-source");
if (sourceEle instanceof HTMLElement) {
const computed = getComputedStyle(sourceEle);
const sourceColor = String(computed.backgroundColor || computed.borderLeftColor || "").trim();
if (
sourceColor &&
sourceColor !== "transparent" &&
!/^rgba?\\(\\s*0\\s*,\\s*0\\s*,\\s*0(?:\\s*,\\s*0)?\\s*\\)$/i.test(sourceColor)
) {
out.sourceColor = sourceColor;
}
}
return out;
};
const isActionLikeHref = (hrefRaw) => {
const href = String(hrefRaw || "").trim().toLowerCase();
return !href || href === "#" || href.startsWith("javascript:");
@@ -378,6 +404,9 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
liElements.forEach((li, index) => {
const entryId = \`\${idPrefix}-\${index}\`;
const submenuList = li.querySelector(":scope > ul")
|| (li.classList.contains("nav2-accord__wrp") ? li.querySelector(":scope > .nav2-accord__body") : null);
const submenuChildren = submenuList ? parseNavbarMenuList(submenuList, \`\${entryId}-submenu\`) : [];
if (li.classList.contains("ve-dropdown-divider") || li.classList.contains("divider")) {
entries.push({ id: \`\${entryId}-divider\`, type: "divider" });
@@ -392,7 +421,6 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
if (li.classList.contains("dropdown--navbar")) {
const toggle = li.querySelector(":scope > a");
const submenuList = li.querySelector(":scope > ul");
const label = toggle ? getNavPrimaryText(toggle) : "";
if (!label) return;
@@ -400,7 +428,23 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
id: \`\${entryId}-submenu\`,
type: "submenu",
label,
children: submenuList ? parseNavbarMenuList(submenuList, \`\${entryId}-submenu\`) : []
...getNavEntryMeta(toggle),
children: submenuChildren
});
return;
}
if (li.classList.contains("nav2-accord__wrp")) {
const headPrimary = li.querySelector(":scope > .nav2-accord__head > :first-child");
const label = headPrimary ? getNavPrimaryText(headPrimary) : "";
if (!label || !submenuChildren.length) return;
entries.push({
id: \`\${entryId}-accordion\`,
type: "submenu",
label,
...getNavEntryMeta(headPrimary),
children: submenuChildren
});
return;
}
@@ -409,6 +453,33 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
if (link) {
const label = getNavPrimaryText(link);
const href = String(link.getAttribute("href") || "").trim();
if (submenuChildren.length) {
if (isActionLikeHref(href)) {
const actionId = \`\${entryId}-submenu-action\`;
link.setAttribute(NAVBAR_ACTION_ATTR, actionId);
entries.push({
id: \`\${entryId}-submenu-link\`,
type: "submenu",
label: label || "Section",
...getNavEntryMeta(link),
actionId,
children: submenuChildren
});
return;
}
entries.push({
id: \`\${entryId}-submenu-link\`,
type: "submenu",
label: label || href,
...getNavEntryMeta(link),
href,
isExternal: link.target === "_blank" || /^https?:\\/\\//i.test(href),
children: submenuChildren
});
return;
}
if (isActionLikeHref(href)) {
const actionId = \`\${entryId}-action\`;
link.setAttribute(NAVBAR_ACTION_ATTR, actionId);
@@ -420,6 +491,7 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
id: \`\${entryId}-link\`,
type: "link",
label: label || href,
...getNavEntryMeta(link),
href,
isExternal: link.target === "_blank" || /^https?:\\/\\//i.test(href)
});
@@ -427,11 +499,33 @@ function getDesktopReskinBootstrap(externalImageRoot: string | null): string {
}
const spans = Array.from(li.querySelectorAll(":scope > span")).filter((it) => it instanceof HTMLSpanElement);
if (submenuChildren.length && spans.length) {
const first = spans[0];
const label = cleanNavLabel(first.textContent || first.title || "");
const actionId = \`\${entryId}-submenu-span\`;
first.setAttribute(NAVBAR_ACTION_ATTR, actionId);
entries.push({
id: \`\${entryId}-submenu-span\`,
type: "submenu",
label: label || "Section",
...getNavEntryMeta(first),
actionId,
children: submenuChildren
});
return;
}
spans.forEach((span, spanIndex) => {
const label = cleanNavLabel(span.textContent || span.title || "");
const actionId = \`\${entryId}-span-\${spanIndex}\`;
span.setAttribute(NAVBAR_ACTION_ATTR, actionId);
entries.push({ id: \`\${entryId}-span-\${spanIndex}\`, type: "action", label: label || "Action", actionId });
entries.push({
id: \`\${entryId}-span-\${spanIndex}\`,
type: "action",
label: label || "Action",
...getNavEntryMeta(span),
actionId
});
});
});