Commit f78d49c916

Andrew Kelley <andrew@ziglang.org>
2019-10-05 19:07:59
generated docs: navigable packages
1 parent dca6e74
Changed files (2)
lib
std
special
lib/std/special/doc/index.html
@@ -14,6 +14,9 @@
             background-color: #111;
             color: #bbb;
         }
+        a {
+            color: #88f;
+        }
       }
     </style>
   </head>
lib/std/special/doc/main.js
@@ -6,28 +6,76 @@
     var domListTypes = document.getElementById("listTypes");
 
     var curNav = {
-        kind: "pkg",
-        index: zigAnalysis.rootPkg,
+        // each element is a package name, e.g. @import("a") then within there @import("b")
+        // starting implicitly from root package
+        pkgNames: [],
+        // same as above except actual packages, not names
+        pkgObjs: [],
+        // Each element is a decl name, `a.b.c`, a is 0, b is 1, c is 2, etc.
+        // empty array means refers to the package itself
+        declNames: [],
+        // these will be all types, except the last one may be a type or a decl
+        declObjs: [],
     };
 
     var rootIsStd = detectRootIsStd();
     var typeKindTypeId = findTypeKindType();
     var typeTypeId = findTypeTypeId();
-    render();
+    window.addEventListener('hashchange', onHashChange, false);
+    onHashChange();
 
     function render() {
         domStatus.classList.add("hidden");
 
-        if (curNav.kind === "pkg") {
-            var pkg = zigAnalysis.packages[curNav.index];
-            renderPkgList(pkg);
-            var pkgStruct = zigAnalysis.types[pkg.main];
-            renderContainer(pkgStruct);
+        var pkg = zigAnalysis.packages[zigAnalysis.rootPkg];
+        curNav.pkgObjs = [pkg];
+        for (var i = 0; i < curNav.pkgNames.length; i += 1) {
+            var childPkg = zigAnalysis.packages[pkg.table[curNav.pkgNames[i]]];
+            if (childPkg == null) {
+                return render404();
+            }
+            pkg = childPkg;
+            curNav.pkgObjs.push(pkg);
+        }
+
+        var decl = zigAnalysis.types[pkg.main];
+        curNav.declObjs = [decl];
+        for (var i = 0; i < curNav.declNames.length; i += 1) {
+            var childDecl = findSubDecl(decl, curNav.declNames[i]);
+            if (childDecl == null) {
+                return render404();
+            }
+            var container = getDeclContainerType(childDecl);
+            if (container == null) {
+                if (i + 1 === curNav.declNames.length) {
+                    curNav.declObjs.push(childDecl);
+                    break;
+                } else {
+                    return render404();
+                }
+            }
+            decl = container;
+            curNav.declObjs.push(decl);
+        }
+
+        var lastPkg = curNav.pkgObjs[curNav.pkgObjs.length - 1];
+        renderPkgList(lastPkg);
+
+        var lastDecl = curNav.declObjs[curNav.declObjs.length - 1];
+        if (lastDecl.decls != null) {
+            return renderContainer(lastDecl);
         } else {
-            throw new Error("TODO");
+            throw new Error("docs for this decl which is not a container");
         }
     }
 
+    function render404() {
+        domStatus.textContent = "404 Not Found";
+        domStatus.classList.remove("hidden");
+        domSectPkgs.classList.add("hidden");
+        domListPkgs.classList.add("hidden");
+    }
+
     function renderPkgList(pkg) {
         var list = [];
         for (var key in pkg.table) {
@@ -41,14 +89,19 @@
             return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
         });
 
-        resizeDomList(domListPkgs, list.length, '<li></li>');
-        var domItems = domListPkgs.children;
-        for (var i = 0; i < list.length; i += 1) {
-            var domItem = domItems[i];
-            domItem.textContent = list[i].name;
-        }
+        if (list.length === 0) {
+            domSectPkgs.classList.remove("hidden");
+        } else {
+            resizeDomList(domListPkgs, list.length, '<li><a href="#"></a></li>');
+            for (var i = 0; i < list.length; i += 1) {
+                var liDom = domListPkgs.children[i];
+                var aDom = liDom.children[0];
+                aDom.textContent = list[i].name;
+                aDom.setAttribute('href', "#" + list[i].name);
+            }
 
-        domSectPkgs.classList.remove("hidden");
+            domSectPkgs.classList.remove("hidden");
+        }
     }
 
     function resizeDomList(listDom, desiredLen, templateHtml) {
@@ -123,4 +176,40 @@
         }
         throw new Error("No type 'type' found");
     }
+
+    function onHashChange() {
+        curNav = {
+            pkgNames: [],
+            pkgObjs: [],
+            declNames: [],
+            declObjs: [],
+        };
+        if (location.hash[0] === '#') {
+            var parts = location.hash.substring(1).split(";");
+            curNav.pkgNames = parts[0].split(".");
+            if (parts[1] != null) {
+                curNav.declNames = parts[1] ? parts[1].split(".") : [];
+            }
+        }
+        render();
+    }
+
+    function findSubDecl(parentType, childName) {
+        if (parentType.decls == null) throw new Error("parent object has no decls");
+        for (var i = 0; i < parentType.decls.length; i += 1) {
+            var declIndex = parentType.decls[i];
+            var childDecl = zigAnalysis.decls[declIndex];
+            if (childDecl.name === childName) {
+                return childDecl;
+            }
+        }
+        return null;
+    }
+
+    function getDeclContainerType(decl) {
+        if (decl.type === typeTypeId) {
+            return zigAnalysis.types[decl.value];
+        }
+        return null;
+    }
 })();