134 lines
3.9 KiB
JavaScript
134 lines
3.9 KiB
JavaScript
(function ()
|
||
{
|
||
function getCurrentPath()
|
||
{
|
||
var href = window.location.href.replace(/\\/g, '/');
|
||
var marker = 'workspace/';
|
||
var idx = href.lastIndexOf(marker);
|
||
if (idx === -1) return 'index.html';
|
||
var after = href.slice(idx + marker.length);
|
||
return after || 'index.html';
|
||
}
|
||
|
||
function findNode(node, targetPath, ancestors)
|
||
{
|
||
if (node.path === targetPath) return { node: node, ancestors: ancestors };
|
||
var children = node.children || [];
|
||
for (var i = 0; i < children.length; i++)
|
||
{
|
||
var result = findNode(children[i], targetPath, ancestors.concat(node));
|
||
if (result) return result;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function makeLink(node, label)
|
||
{
|
||
var a = document.createElement('a');
|
||
a.href = NAV_ROOT + node.path;
|
||
a.textContent = label || node.title;
|
||
return a;
|
||
}
|
||
|
||
function render()
|
||
{
|
||
var currentPath = getCurrentPath();
|
||
var found = findNode(NAV_DATA, currentPath, []);
|
||
|
||
var nav = document.createElement('nav');
|
||
nav.className = 'wsnav';
|
||
|
||
var inner = document.createElement('div');
|
||
inner.className = 'wsnav-inner';
|
||
nav.appendChild(inner);
|
||
|
||
// ── Breadcrumb ───────────────────────────────────────────────────
|
||
var crumb = document.createElement('div');
|
||
crumb.className = 'wsnav-crumb';
|
||
|
||
var ancestors = found ? found.ancestors : [];
|
||
var currentNode = found ? found.node : null;
|
||
|
||
for (var i = 0; i < ancestors.length; i++)
|
||
{
|
||
var a = makeLink(ancestors[i]);
|
||
crumb.appendChild(a);
|
||
var sep = document.createElement('span');
|
||
sep.className = 'wsnav-sep';
|
||
sep.textContent = '›';
|
||
crumb.appendChild(sep);
|
||
}
|
||
|
||
var current = document.createElement('span');
|
||
current.className = 'wsnav-current';
|
||
current.textContent = currentNode ? currentNode.title : currentPath;
|
||
crumb.appendChild(current);
|
||
|
||
inner.appendChild(crumb);
|
||
|
||
// ── Siblings ─────────────────────────────────────────────────────
|
||
var parent = ancestors.length > 0 ? ancestors[ancestors.length - 1] : null;
|
||
var siblings = parent ? (parent.children || []) : [];
|
||
|
||
if (siblings.length > 1)
|
||
{
|
||
var sibRow = document.createElement('div');
|
||
sibRow.className = 'wsnav-siblings';
|
||
|
||
for (var j = 0; j < siblings.length; j++)
|
||
{
|
||
var sib = siblings[j];
|
||
if (sib.path === currentPath)
|
||
{
|
||
var mark = document.createElement('span');
|
||
mark.className = 'wsnav-sib-current';
|
||
mark.textContent = sib.title;
|
||
sibRow.appendChild(mark);
|
||
}
|
||
else
|
||
{
|
||
sibRow.appendChild(makeLink(sib));
|
||
}
|
||
|
||
if (j < siblings.length - 1)
|
||
{
|
||
var div = document.createElement('span');
|
||
div.className = 'wsnav-sib-sep';
|
||
div.textContent = '·';
|
||
sibRow.appendChild(div);
|
||
}
|
||
}
|
||
|
||
inner.appendChild(sibRow);
|
||
}
|
||
|
||
// ── Children ─────────────────────────────────────────────────────
|
||
var children = currentNode ? (currentNode.children || []) : [];
|
||
|
||
if (children.length > 0)
|
||
{
|
||
var childRow = document.createElement('div');
|
||
childRow.className = 'wsnav-children';
|
||
|
||
for (var k = 0; k < children.length; k++)
|
||
{
|
||
childRow.appendChild(makeLink(children[k]));
|
||
}
|
||
|
||
inner.appendChild(childRow);
|
||
}
|
||
|
||
document.body.insertBefore(nav, document.body.firstChild);
|
||
document.body.style.paddingTop = (nav.offsetHeight + 8) + 'px';
|
||
}
|
||
|
||
if (document.readyState === 'loading')
|
||
{
|
||
document.addEventListener('DOMContentLoaded', render);
|
||
}
|
||
else
|
||
{
|
||
render();
|
||
}
|
||
})();
|