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();
|
|||
|
|
}
|
|||
|
|
})();
|