generated docs: logo and basic search proof of concept

master
Andrew Kelley 2019-10-07 13:57:01 -04:00
parent 2ccb48ddc3
commit 9237461b24
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 139 additions and 21 deletions

View File

@ -20,6 +20,7 @@
font-size:1em; font-size:1em;
background-color:#F5F5F5; background-color:#F5F5F5;
padding:1em; padding:1em;
overflow-x: auto;
} }
#listNav { #listNav {
list-style-type: none; list-style-type: none;
@ -45,6 +46,16 @@
background-color: #4CAF50; background-color: #4CAF50;
} }
#logo {
width: 5em;
float: left;
padding: 0 1em 0 0;
}
#search {
width: 90%;
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
body{ body{
background-color: #111; background-color: #111;
@ -60,12 +71,16 @@
</style> </style>
</head> </head>
<body> <body>
<img alt="ZIG" id="logo" src="data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxNTAgMTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxnIGZpbGw9IiNmN2E0MWQiPjxwYXRoIGQ9Im0wIDEwdjgwaDE5bDYtMTAgMTItMTBoLTE3di00MGgxNXYtMjB6bTQwIDB2MjBoNjJ2LTIwem05MSAwLTYgMTAtMTIgMTBoMTd2NDBoLTE1djIwaDM1di04MHptLTgzIDYwdjIwaDYydi0yMHoiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwYXRoIGQ9Im0zNyA3MC0xOCAyMHYtMTV6Ii8+PHBhdGggZD0ibTExMyAzMCAxOC0yMHYxNXoiLz48cGF0aCBkPSJtOTYuOTggMTAuNjMgMzYuMjgtMTAuNC04MC4yOSA4OS4xNy0zNi4yOCAxMC40eiIvPjwvZz48L3N2Zz4K"></img>
<input type="search" id="search" autocomplete="off" spellcheck="false" placeholder="`s` to search, `?` to see more options">
<p id="status">Loading...</p> <p id="status">Loading...</p>
<div id="sectNav" class="hidden"><ul id="listNav"></ul></div> <div id="sectNav" class="hidden"><ul id="listNav"></ul></div>
<div id="fnProto" class="hidden"> <div id="fnProto" class="hidden">
<pre id="fnProtoCode"></pre> <pre id="fnProtoCode"></pre>
</div> </div>
<div id="fnDocs" class="hidden"></div> <div id="fnDocs" class="hidden"></div>
<div id="sectSearchResults" class="hidden"><ul id="listSearchResults"></ul></div>
<div id="sectSearchNoResults" class="hidden"><p>No search results.</p></div>
<div id="sectPkgs" class="hidden"> <div id="sectPkgs" class="hidden">
<h2>Packages</h2> <h2>Packages</h2>
<ul id="listPkgs"> <ul id="listPkgs">

View File

@ -11,6 +11,13 @@
var domFnProto = document.getElementById("fnProto"); var domFnProto = document.getElementById("fnProto");
var domFnProtoCode = document.getElementById("fnProtoCode"); var domFnProtoCode = document.getElementById("fnProtoCode");
var domFnDocs = document.getElementById("fnDocs"); var domFnDocs = document.getElementById("fnDocs");
var domSearch = document.getElementById("search");
var domSectSearchResults = document.getElementById("sectSearchResults");
var domListSearchResults = document.getElementById("listSearchResults");
var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
var searchTimer = null;
var escapeHtmlReplacements = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
var typeKindTypeId; var typeKindTypeId;
var typeKindFnId; var typeKindFnId;
@ -31,10 +38,13 @@
// these will be all types, except the last one may be a type or a decl // these will be all types, except the last one may be a type or a decl
declObjs: [], declObjs: [],
}; };
var curNavSearch = "";
var rootIsStd = detectRootIsStd(); var rootIsStd = detectRootIsStd();
var typeTypeId = findTypeTypeId(); var typeTypeId = findTypeTypeId();
domSearch.addEventListener('keydown', onSearchKeyDown, false);
window.addEventListener('hashchange', onHashChange, false); window.addEventListener('hashchange', onHashChange, false);
window.addEventListener('keydown', onWindowKeyDown, false);
onHashChange(); onHashChange();
function renderTitle() { function renderTitle() {
@ -58,10 +68,14 @@
domSectPkgs.classList.add("hidden"); domSectPkgs.classList.add("hidden");
domSectTypes.classList.add("hidden"); domSectTypes.classList.add("hidden");
domSectFns.classList.add("hidden"); domSectFns.classList.add("hidden");
domSectSearchResults.classList.add("hidden");
renderTitle(); renderTitle();
if (curNavSearch !== "") {
return renderSearch();
}
var pkg = zigAnalysis.packages[zigAnalysis.rootPkg]; var pkg = zigAnalysis.packages[zigAnalysis.rootPkg];
curNav.pkgObjs = [pkg]; curNav.pkgObjs = [pkg];
for (var i = 0; i < curNav.pkgNames.length; i += 1) { for (var i = 0; i < curNav.pkgNames.length; i += 1) {
@ -99,16 +113,16 @@
renderPkgList(lastPkg); renderPkgList(lastPkg);
var lastDecl = curNav.declObjs[curNav.declObjs.length - 1]; var lastDecl = curNav.declObjs[curNav.declObjs.length - 1];
if (lastDecl.pubDecls != null) { if (lastDecl.type != null) {
return renderContainer(lastDecl);
} else if (lastDecl.type != null) {
var typeObj = zigAnalysis.types[lastDecl.type]; var typeObj = zigAnalysis.types[lastDecl.type];
if (typeObj.kind === typeKindFnId) { if (typeObj.kind === typeKindFnId) {
return renderFn(lastDecl); return renderFn(lastDecl);
} }
throw new Error("docs for this decl which is not a container"); throw new Error("docs for this decl which is not a container");
} else { }
throw new Error("docs for this decl which is a type"); renderType(lastDecl);
if (lastDecl.pubDecls != null) {
renderContainer(lastDecl);
} }
} }
@ -164,10 +178,6 @@
function render404() { function render404() {
domStatus.textContent = "404 Not Found"; domStatus.textContent = "404 Not Found";
domStatus.classList.remove("hidden"); domStatus.classList.remove("hidden");
domSectPkgs.classList.add("hidden");
domSectTypes.classList.add("hidden");
domSectFns.classList.add("hidden");
domFnProto.classList.add("hidden");
} }
function renderPkgList(pkg) { function renderPkgList(pkg) {
@ -183,9 +193,7 @@
return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase()); return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
}); });
if (list.length === 0) { if (list.length !== 0) {
domSectPkgs.classList.add("hidden");
} else {
resizeDomList(domListPkgs, list.length, '<li><a href="#"></a></li>'); resizeDomList(domListPkgs, list.length, '<li><a href="#"></a></li>');
for (var i = 0; i < list.length; i += 1) { for (var i = 0; i < list.length; i += 1) {
var liDom = domListPkgs.children[i]; var liDom = domListPkgs.children[i];
@ -228,6 +236,11 @@
} }
} }
function renderType(typeObj) {
domFnDocs.innerText = zigAnalysis.typeKinds[typeObj.kind] + ": " + typeObj.name;
domFnDocs.classList.remove("hidden");
}
function renderContainer(container) { function renderContainer(container) {
var typesList = []; var typesList = [];
var fnsList = []; var fnsList = [];
@ -251,9 +264,7 @@
return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase()); return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
}); });
if (typesList.length === 0) { if (typesList.length !== 0) {
domSectTypes.classList.add("hidden");
} else {
resizeDomList(domListTypes, typesList.length, '<li><a href="#"></a></li>'); resizeDomList(domListTypes, typesList.length, '<li><a href="#"></a></li>');
for (var i = 0; i < typesList.length; i += 1) { for (var i = 0; i < typesList.length; i += 1) {
var liDom = domListTypes.children[i]; var liDom = domListTypes.children[i];
@ -265,9 +276,7 @@
domSectTypes.classList.remove("hidden"); domSectTypes.classList.remove("hidden");
} }
if (fnsList.length === 0) { if (fnsList.length !== 0) {
domSectFns.classList.add("hidden");
} else {
resizeDomList(domListFns, fnsList.length, '<li><a href="#"></a></li>'); resizeDomList(domListFns, fnsList.length, '<li><a href="#"></a></li>');
for (var i = 0; i < fnsList.length; i += 1) { for (var i = 0; i < fnsList.length; i += 1) {
var liDom = domListFns.children[i]; var liDom = domListFns.children[i];
@ -332,8 +341,19 @@
declNames: [], declNames: [],
declObjs: [], declObjs: [],
}; };
curNavSearch = "";
if (location.hash[0] === '#' && location.hash.length > 1) { if (location.hash[0] === '#' && location.hash.length > 1) {
var parts = location.hash.substring(1).split(";"); var nonSearchAndSearchParts = location.hash.substring(1).split("?");
var nonSearchPart;
if (nonSearchAndSearchParts.length === 1) {
nonSearchPart = nonSearchAndSearchParts[0];
} else {
nonSearchPart = nonSearchAndSearchParts[0];
curNavSearch = nonSearchAndSearchParts[1];
}
var parts = nonSearchPart.split(";");
curNav.pkgNames = parts[0].split("."); curNav.pkgNames = parts[0].split(".");
if (parts[1] != null) { if (parts[1] != null) {
curNav.declNames = parts[1].split("."); curNav.declNames = parts[1].split(".");
@ -388,10 +408,93 @@
return list; return list;
} }
var escapeHtmlReplacements = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
function markdown(mdText) { function markdown(mdText) {
return mdText.replace(/[&"<>]/g, function (m) { return mdText.replace(/[&"<>]/g, function (m) {
return escapeHtmlReplacements[m]; return escapeHtmlReplacements[m];
}); });
} }
function onSearchKeyDown(ev) {
switch (ev.which) {
case 27:
domSearch.value = "";
domSearch.blur();
ev.preventDefault();
break;
}
ev.stopPropagation();
startAsyncSearch();
}
function onWindowKeyDown(ev) {
switch (ev.which) {
case 83:
domSearch.focus();
ev.preventDefault();
ev.stopPropagation();
startAsyncSearch();
break;
}
}
function clearAsyncSearch() {
if (searchTimer != null) clearTimeout(searchTimer);
}
function startAsyncSearch() {
clearAsyncSearch();
searchTimer = setTimeout(startSearch, 50);
}
function startSearch() {
var parts = location.hash.split("?");
var newPart2 = (domSearch.value === "") ? "" : ("?" + domSearch.value);
if (parts.length === 1) {
location.hash = location.hash + newPart2;
} else {
location.hash = parts[0] + newPart2;
}
}
function renderSearch() {
if (domSearch.value !== curNavSearch) {
domSearch.value = curNavSearch;
}
var matchedDecls = [];
var terms = curNavSearch.split(/[ \r\n\t]+/);
decl_loop: for (var declIndex = 0; declIndex < zigAnalysis.decls.length; declIndex += 1) {
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]
if (astNode.docs != null && astNode.docs.indexOf(term) >= 0) {
continue;
}
var file = zigAnalysis.files[astNode.file];
if (file.indexOf(term) >= 0) {
continue;
}
continue decl_loop;
}
matchedDecls.push(decl);
}
if (matchedDecls.length !== 0) {
resizeDomList(domListSearchResults, matchedDecls.length, '<li></li>');
for (var i = 0; i < matchedDecls.length; i += 1) {
var liDom = domListSearchResults.children[i];
var decl = matchedDecls[i];
liDom.textContent = decl.name;
}
domSectSearchResults.classList.remove("hidden");
} else {
domSectSearchNoResults.classList.remove("hidden");
}
}
})(); })();