generated docs: navigable search results

This commit is contained in:
Andrew Kelley 2019-10-07 17:46:22 -04:00
parent d46234ef72
commit 4a97558ae8
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 146 additions and 12 deletions

View File

@ -139,6 +139,10 @@
cursor: default;
}
#listSearchResults li.selected {
background-color: #93e196;
}
@media (prefers-color-scheme: dark) {
body{
background-color: #111;
@ -150,6 +154,12 @@
pre{
background-color:#2A2A2A;
}
#listNav li a:hover {
background-color: #000;
}
#listNav li a.active {
background-color: #4CAF50;
}
#listPkgs {
background-color: #333;
}
@ -160,6 +170,12 @@
background-color: #555;
color: #fff;
}
#listSearchResults li.selected {
background-color: #000;
}
#listSearchResults li.selected a {
color: #fff;
}
}
</style>
</head>

View File

@ -31,6 +31,7 @@
// for each package, is an array with packages to get to this one
var canonPkgPaths = computeCanonicalPackagePaths();
var canonDeclPaths = null; // lazy; use getCanonDeclPath
var curNav = {
// each element is a package name, e.g. @import("a") then within there @import("b")
@ -45,6 +46,7 @@
declObjs: [],
};
var curNavSearch = "";
var curSearchIndex = -1;
var rootIsStd = detectRootIsStd();
var typeTypeId = findTypeTypeId();
@ -78,6 +80,7 @@
domSectSearchNoResults.classList.add("hidden");
domSectInfo.classList.add("hidden");
domHdrName.classList.add("hidden");
domSectNav.classList.add("hidden");
renderTitle();
renderInfo();
@ -413,7 +416,7 @@
pkg: rootPkg,
}];
while (stack.length !== 0) {
var item = stack.pop();
var item = stack.shift();
for (var key in item.pkg.table) {
var childPkgIndex = item.pkg.table[key];
if (list[childPkgIndex] != null) continue;
@ -430,6 +433,51 @@
return list;
}
function computeCanonDeclPaths() {
var list = new Array(zigAnalysis.decls.length);
for (var pkgI = 0; pkgI < zigAnalysis.packages.length; pkgI += 1) {
var pkg = zigAnalysis.packages[pkgI];
var pkgNames = canonPkgPaths[pkgI];
var stack = [{
declNames: [],
type: zigAnalysis.types[pkg.main],
}];
while (stack.length !== 0) {
var item = stack.shift();
if (item.type.pubDecls != null) {
for (var declI = 0; declI < item.type.pubDecls.length; declI += 1) {
var mainDeclIndex = item.type.pubDecls[declI];
if (list[mainDeclIndex] != null) continue;
var decl = zigAnalysis.decls[mainDeclIndex];
var declNames = item.declNames.concat([decl.name]);
list[mainDeclIndex] = {
pkgNames: pkgNames,
declNames: declNames,
};
var containerType = getDeclContainerType(decl);
if (containerType != null) {
stack.push({
declNames: declNames,
type: containerType,
});
}
}
}
}
}
return list;
}
function getCanonDeclPath(index) {
if (canonDeclPaths == null) {
canonDeclPaths = computeCanonDeclPaths();
}
return canonDeclPaths[index];
}
function markdown(mdText) {
return mdText.replace(/[&"<>]/g, function (m) {
return escapeHtmlReplacements[m];
@ -438,14 +486,63 @@
function onSearchKeyDown(ev) {
switch (ev.which) {
case 13:
var liDom = null;
if (domListSearchResults.children.length === 1) {
liDom = domListSearchResults.children[0];
} else {
liDom = domListSearchResults.children[curSearchIndex];
}
if (liDom != null) {
var aDom = liDom.children[0];
location.href = aDom.getAttribute("href");
curSearchIndex = -1;
ev.preventDefault();
ev.stopPropagation();
return;
}
case 27:
domSearch.value = "";
domSearch.blur();
curSearchIndex = -1;
ev.preventDefault();
break;
ev.stopPropagation();
startSearch();
return;
case 38:
moveSearchCursor(-1);
ev.preventDefault();
ev.stopPropagation();
return;
case 40:
moveSearchCursor(1);
ev.preventDefault();
ev.stopPropagation();
return;
default:
curSearchIndex = -1;
ev.stopPropagation();
startAsyncSearch();
}
ev.stopPropagation();
startAsyncSearch();
}
function moveSearchCursor(dir) {
if (curSearchIndex < 0 || curSearchIndex >= domListSearchResults.children.length) {
if (dir > 0) {
curSearchIndex = -1 + dir;
} else if (dir < 0) {
curSearchIndex = domListSearchResults.children.length + dir;
}
} else {
curSearchIndex += dir;
}
if (curSearchIndex < 0) {
curSearchIndex = 0;
}
if (curSearchIndex >= domListSearchResults.children.length) {
curSearchIndex = domListSearchResults.children.length - 1;
}
renderSearchCursor();
}
function onWindowKeyDown(ev) {
@ -496,16 +593,20 @@
}
}
function renderSearch() {
var matchedDecls = [];
var matchedItems = [];
var terms = curNavSearch.split(/[ \r\n\t]+/);
decl_loop: for (var declIndex = 0; declIndex < zigAnalysis.decls.length; declIndex += 1) {
var canonPath = getCanonDeclPath(declIndex);
if (canonPath == null) continue;
var decl = zigAnalysis.decls[declIndex];
for (var termIndex = 0; termIndex < terms.length; termIndex += 1) {
var term = terms[termIndex];
if (decl.name.indexOf(term) >= 0) {
continue;
}
var astNode = zigAnalysis.astNodes[decl.src]
var astNode = zigAnalysis.astNodes[decl.src];
if (astNode.docs != null && astNode.docs.indexOf(term) >= 0) {
continue;
}
@ -517,21 +618,38 @@
continue decl_loop;
}
matchedDecls.push(decl);
matchedItems.push({
decl: decl,
path: canonPath,
});
}
if (matchedDecls.length !== 0) {
resizeDomList(domListSearchResults, matchedDecls.length, '<li></li>');
if (matchedItems.length !== 0) {
resizeDomList(domListSearchResults, matchedItems.length, '<li><a href="#"></a></li>');
for (var i = 0; i < matchedDecls.length; i += 1) {
for (var i = 0; i < matchedItems.length; i += 1) {
var liDom = domListSearchResults.children[i];
var decl = matchedDecls[i];
liDom.textContent = decl.name;
var aDom = liDom.children[0];
var match = matchedItems[i];
aDom.textContent = match.path.declNames.join('.');
aDom.setAttribute('href', navLink(match.path.pkgNames, match.path.declNames));
}
renderSearchCursor();
domSectSearchResults.classList.remove("hidden");
} else {
domSectSearchNoResults.classList.remove("hidden");
}
}
function renderSearchCursor() {
for (var i = 0; i < domListSearchResults.children.length; i += 1) {
var liDom = domListSearchResults.children[i];
if (curSearchIndex === i) {
liDom.classList.add("selected");
} else {
liDom.classList.remove("selected");
}
}
}
})();