Commit 38281c8ed4

Loris Cro <kappaloris@gmail.com>
2022-01-29 20:13:10
autodoc: add declval support to docs js
1 parent 75d39a9
Changed files (2)
lib/docs/index.html
@@ -43,8 +43,6 @@
 
       /* layout */
       .canvas {
-        display: flex;
-        flex-direction: column;
         width: 100vw;
         height: 100vh;
         overflow: hidden;
@@ -55,21 +53,12 @@
         background-color: var(--bg-color);
       }
 
-      .banner {
-        background-color: darkred;
-        text-align: center;
-        color: white;
-        padding: 15px 5px;
-      }
-
-      .banner a {
-        color: bisque;
-        text-decoration: underline;
-      }
-
       .flex-main {
         display: flex;
-        overflow-y: hidden;
+        width: 100%;
+        height: 100%;
+        justify-content: center;
+        
         z-index: 100;
       }
 
@@ -526,7 +515,6 @@
     </style>
   </head>
   <body class="canvas">
-    <div class="banner">These docs are experimental. <a href="https://kristoff.it/blog/zig-new-relationship-llvm/">Progress depends on the self-hosted compiler</a>, <a href="https://github.com/ziglang/zig/wiki/How-to-read-the-standard-library-source-code">consider reading the stdlib source in the meantime</a>.</div>
     <div class="flex-main">
       <div class="flex-filler"></div>
       <div class="flex-left sidebar">
@@ -541,8 +529,14 @@
               </g>
             </svg>
           </div>
+          <div id="sectMainPkg" class="hidden">
+            <h2><span>Main Package</span></h2>
+            <ul class="packages">
+              <li><a id="mainPkg" class="" href=""></a></li>
+            </ul>
+          </div>
           <div id="sectPkgs" class="hidden">
-            <h2><span>Packages</span></h2>
+            <h2><span>Dependencies</span></h2>
             <ul id="listPkgs" class="packages"></ul>
           </div>
           <div id="sectInfo" class="hidden">
@@ -588,7 +582,6 @@
             <div id="sectSearchResults" class="hidden">
               <h2>Search Results</h2>
               <ul id="listSearchResults"></ul>
-              <p id="sectSearchAllResultsLink" class="hidden"><a href="">show all results</a></p>
             </div>
             <div id="sectSearchNoResults" class="hidden">
               <h2>No Results Found</h2>
lib/docs/main.js
@@ -2,6 +2,7 @@
     var domStatus = document.getElementById("status");
     var domSectNav = document.getElementById("sectNav");
     var domListNav = document.getElementById("listNav");
+    var domSectMainPkg = document.getElementById("sectMainPkg");
     var domSectPkgs = document.getElementById("sectPkgs");
     var domListPkgs = document.getElementById("listPkgs");
     var domSectTypes = document.getElementById("sectTypes");
@@ -35,7 +36,6 @@
     var domSectSearchResults = document.getElementById("sectSearchResults");
     var domListSearchResults = document.getElementById("listSearchResults");
     var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
-    var domSectSearchAllResultsLink = document.getElementById("sectSearchAllResultsLink");
     var domSectInfo = document.getElementById("sectInfo");
     var domTdTarget = document.getElementById("tdTarget");
     var domTdZigVer = document.getElementById("tdZigVer");
@@ -43,22 +43,11 @@
     var domHelpModal = document.getElementById("helpDialog");
 
     var searchTimer = null;
-    var searchTrimResults = true;
     var escapeHtmlReplacements = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
 
     var typeKinds = indexTypeKinds();
     var typeTypeId = findTypeTypeId();
     var pointerSizeEnum = { One: 0, Many: 1, Slice: 2, C: 3 };
-    var tokenKinds = {
-        Keyword: 'tok-kw',
-        String: 'tok-str',
-        Builtin: 'tok-builtin',
-        Comment: 'tok-comment',
-        Function: 'tok-fn',
-        Null: 'tok-null',
-        Number: 'tok-number',
-        Type: 'tok-type',
-    };
 
     // for each package, is an array with packages to get to this one
     var canonPkgPaths = computeCanonicalPackagePaths();
@@ -94,8 +83,6 @@
     var nodesToCallsMap = indexNodesToCalls();
 
     domSearch.addEventListener('keydown', onSearchKeyDown, false);
-    domSectSearchAllResultsLink.addEventListener('click', onClickSearchShowAllResults, false);
-
     window.addEventListener('hashchange', onHashChange, false);
     window.addEventListener('keydown', onWindowKeyDown, false);
     onHashChange();
@@ -119,6 +106,7 @@
         domFnProto.classList.add("hidden");
         domSectParams.classList.add("hidden");
         domTldDocs.classList.add("hidden");
+        domSectMainPkg.classList.add("hidden");
         domSectPkgs.classList.add("hidden");
         domSectTypes.classList.add("hidden");
         domSectNamespaces.classList.add("hidden");
@@ -127,7 +115,6 @@
         domSectFields.classList.add("hidden");
         domSectSearchResults.classList.add("hidden");
         domSectSearchNoResults.classList.add("hidden");
-        domSectSearchAllResultsLink.classList.add("hidden");
         domSectInfo.classList.add("hidden");
         domHdrName.classList.add("hidden");
         domSectNav.classList.add("hidden");
@@ -269,19 +256,15 @@
                 domFnNoExamples.classList.remove("hidden");
             } else if (calls != null) {
                 if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
-                if (fnObj.combined != null) {
-                    renderContainer(fnObj.combined, calls.map(function (call) { return zigAnalysis.calls[call].result.value }));
-                }
+                if (fnObj.combined != null) renderContainer(fnObj.combined);
 
-                var domListFnExamplesFragment = createDomListFragment(calls.length, '<li></li>');
+                resizeDomList(domListFnExamples, calls.length, '<li></li>');
 
                 for (var callI = 0; callI < calls.length; callI += 1) {
-                    var liDom = domListFnExamplesFragment.children[callI];
+                    var liDom = domListFnExamples.children[callI];
                     liDom.innerHTML = getCallHtml(fnDecl, calls[callI]);
                 }
 
-                domListFnExamples.innerHTML = "";
-                domListFnExamples.appendChild(domListFnExamplesFragment);
                 domFnExamples.classList.remove("hidden");
             } else if (instantiations != null) {
                 // TODO
@@ -322,7 +305,7 @@
             return;
         }
 
-        var domListParamsFragment = createDomListFragment(docCount, '<div></div>');
+        resizeDomList(domListParams, docCount, '<div></div>');
         var domIndex = 0;
 
         for (var i = 0; i < fields.length; i += 1) {
@@ -331,7 +314,7 @@
             if (fieldNode.docs == null) {
                 continue;
             }
-            var divDom = domListParamsFragment.children[domIndex];
+            var divDom = domListParams.children[domIndex];
             domIndex += 1;
             var argTypeIndex = typeObj.args[i];
 
@@ -352,15 +335,12 @@
             }
             divDom.innerHTML = html;
         }
-
-        domListParams.innerHTML = "";
-        domListParams.appendChild(domListParamsFragment);
         domSectParams.classList.remove("hidden");
     }
 
     function renderNav() {
         var len = curNav.pkgNames.length + curNav.declNames.length;
-        var domListNavFragment = createDomListFragment(len, '<li><a href="#"></a></li>');
+        resizeDomList(domListNav, len, '<li><a href="#"></a></li>');
         var list = [];
         var hrefPkgNames = [];
         var hrefDeclNames = [];
@@ -380,7 +360,7 @@
         }
 
         for (var i = 0; i < list.length; i += 1) {
-            var liDom = domListNavFragment.children[i];
+            var liDom = domListNav.children[i];
             var aDom = liDom.children[0];
             aDom.textContent = list[i].name;
             aDom.setAttribute('href', list[i].link);
@@ -391,8 +371,6 @@
             }
         }
 
-        domListNav.innerHTML = "";
-        domListNav.appendChild(domListNavFragment);
         domSectNav.classList.remove("hidden");
     }
 
@@ -412,7 +390,6 @@
         var rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
         var list = [];
         for (var key in rootPkg.table) {
-            if (key === "root" && rootIsStd) continue;
             var pkgIndex = rootPkg.table[key];
             if (zigAnalysis.packages[pkgIndex] == null) continue;
             list.push({
@@ -420,14 +397,27 @@
                 pkg: pkgIndex,
             });
         }
+
+        {
+            var aDom = domSectMainPkg.children[1].children[0].children[0];
+            aDom.textContent = zigAnalysis.params.rootName;
+            aDom.setAttribute('href', navLinkPkg(zigAnalysis.rootPkg));
+            if (zigAnalysis.params.rootName === curNav.pkgNames[0]) {
+                aDom.classList.add("active");
+            } else {
+                aDom.classList.remove("active");
+            }
+            domSectMainPkg.classList.remove("hidden");
+        }
+
         list.sort(function(a, b) {
             return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
         });
 
         if (list.length !== 0) {
-            var domListPkgsFragment = createDomListFragment(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) {
-                var liDom = domListPkgsFragment.children[i];
+                var liDom = domListPkgs.children[i];
                 var aDom = liDom.children[0];
                 aDom.textContent = list[i].name;
                 aDom.setAttribute('href', navLinkPkg(list[i].pkg));
@@ -438,8 +428,6 @@
                 }
             }
 
-            domListPkgs.innerHTML = "";
-            domListPkgs.appendChild(domListPkgsFragment);
             domSectPkgs.classList.remove("hidden");
         }
     }
@@ -480,34 +468,50 @@
         return navLink(curNav.pkgNames, declNamesCopy);
     }
 
-    function createDomListFragment(desiredLen, templateHtml) {
-        var domTemplate = document.createElement("template");
-        domTemplate.innerHTML = templateHtml.repeat(desiredLen);
-        return domTemplate.content;
+    function resizeDomListDl(dlDom, desiredLen) {
+        // add the missing dom entries
+        var i, ev;
+        for (i = dlDom.childElementCount / 2; i < desiredLen; i += 1) {
+            dlDom.insertAdjacentHTML('beforeend', '<dt></dt><dd></dd>');
+        }
+        // remove extra dom entries
+        while (desiredLen < dlDom.childElementCount / 2) {
+            dlDom.removeChild(dlDom.lastChild);
+            dlDom.removeChild(dlDom.lastChild);
+        }
     }
 
-    function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl, thisTypes) {
-        if(thisTypes && thisTypes.includes(typeIndex)){
-            return token('@This', tokenKinds.Builtin, wantHtml) + '()';
+    function resizeDomList(listDom, desiredLen, templateHtml) {
+        // add the missing dom entries
+        var i, ev;
+        for (i = listDom.childElementCount; i < desiredLen; i += 1) {
+            listDom.insertAdjacentHTML('beforeend', templateHtml);
+        }
+        // remove extra dom entries
+        while (desiredLen < listDom.childElementCount) {
+            listDom.removeChild(listDom.lastChild);
         }
+    }
+
+    function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
         var typeObj = zigAnalysis.types[typeIndex];
         var declNameOk = declCanRepresentTypeKind(typeObj.kind);
         if (wantLink) {
             var declIndex = getCanonTypeDecl(typeIndex);
             var declPath = getCanonDeclPath(declIndex);
             if (declPath == null) {
-                return typeName(typeObj, wantHtml, wantLink, fnDecl, linkFnNameDecl, thisTypes);
+                return typeName(typeObj, wantHtml, wantLink, fnDecl, linkFnNameDecl);
             }
             var name = (wantLink && declCanRepresentTypeKind(typeObj.kind)) ?
                 declPath.declNames[declPath.declNames.length - 1] :
-                typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl, thisTypes);
+                typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl);
             if (wantLink && wantHtml) {
                 return '<a href="' + navLink(declPath.pkgNames, declPath.declNames) + '">' + name + '</a>';
             } else {
                 return name;
             }
         } else {
-            return typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl, thisTypes);
+            return typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl);
         }
     }
 
@@ -545,57 +549,32 @@
                 return typeIndexName(value, wantHtml, wantLink);
             case typeKinds.Fn:
                 var fnObj = zigAnalysis.fns[value];
-                var declPath = fnObj.decl && getCanonDeclPath(fnObj.decl);
-                var fnName = declPath ? declPath.declNames.join('.') : '(unknown)';
-
-                if (!wantHtml) {
-                    return fnName;
-                }
-
-                var str = '<span class="tok-fn">';
-                if (wantLink && declPath != null) {
-                  str += '<a href="' + navLink(declPath.pkgNames, declPath.declNames) + '">';
-                  str += escapeHtml(fnName);
-                  str += '</a>';
-                } else {
-                  str += escapeHtml(fnName);
-                }
-                str += '</span>';
-                return str;
+                return typeIndexName(fnObj.type, wantHtml, wantLink);
             case typeKinds.Int:
-                return token(value, tokenKinds.Number, wantHtml);
-            case typeKinds.Optional:
-                if(value === 'null'){
-                    return token(value, tokenKinds.Null, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-number">' + value + '</span>';
                 } else {
-                    console.trace("TODO non-null optional value printing");
-                    return "TODO";
+                    return value + "";
                 }
-            case typeKinds.Bool:
-                return token(value, tokenKinds.Null, wantHtml);
             default:
                 console.trace("TODO implement getValueText for this type:", zigAnalysis.typeKinds[typeObj.kind]);
-                return "TODO";
         }
     }
 
-    function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl, thisTypes) {
+    function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {
         switch (typeObj.kind) {
             case typeKinds.Array:
                 var name = "[";
-                name += token(typeObj.len, tokenKinds.Number, wantHtml);
+                if (wantHtml) {
+                    name += '<span class="tok-number">' + typeObj.len + '</span>';
+                } else {
+                    name += typeObj.len;
+                }
                 name += "]";
-                name += typeIndexName(typeObj.elem, wantHtml, wantSubLink, null, null, thisTypes);
-                return name;
-            case typeKinds.Vector:
-                var name = "Vector(";
-                name += token(typeObj.len, tokenKinds.Number, wantHtml);
-                name += ", ";
-                name += typeIndexName(typeObj.elem, wantHtml, wantSubLink, null, null, thisTypes);
-                name += ")";
+                name += typeIndexName(typeObj.elem, wantHtml, wantSubLink, null);
                 return name;
             case typeKinds.Optional:
-                return "?" + typeIndexName(typeObj.child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl, thisTypes);
+                return "?" + typeIndexName(typeObj.child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
             case typeKinds.Pointer:
                 var name = "";
                 switch (typeObj.len) {
@@ -614,48 +593,112 @@
                         break;
                 }
                 if (typeObj['const']) {
-                    name += token('const', tokenKinds.Keyword, wantHtml) + ' ';
+                    if (wantHtml) {
+                        name += '<span class="tok-kw">const</span> ';
+                    } else {
+                        name += "const ";
+                    }
                 }
                 if (typeObj['volatile']) {
-                    name += token('volatile', tokenKinds.Keyword, wantHtml) + ' ';
+                    if (wantHtml) {
+                        name += '<span class="tok-kw">volatile</span> ';
+                    } else {
+                        name += "volatile ";
+                    }
                 }
                 if (typeObj.align != null) {
-                    name += token('align', tokenKinds.Keyword, wantHtml) + '(';
-                    name += token(typeObj.align, tokenKinds.Number, wantHtml);
-
+                    if (wantHtml) {
+                        name += '<span class="tok-kw">align</span>(';
+                    } else {
+                        name += "align(";
+                    }
+                    if (wantHtml) {
+                        name += '<span class="tok-number">' + typeObj.align + '</span>';
+                    } else {
+                        name += typeObj.align;
+                    }
                     if (typeObj.hostIntBytes != null) {
                         name += ":";
-                        name += token(typeObj.bitOffsetInHost, tokenKinds.Number, wantHtml);
+                        if (wantHtml) {
+                            name += '<span class="tok-number">' + typeObj.bitOffsetInHost + '</span>';
+                        } else {
+                            name += typeObj.bitOffsetInHost;
+                        }
                         name += ":";
-                        name += token(typeObj.hostIntBytes, tokenKinds.Number, wantHtml);
+                        if (wantHtml) {
+                            name += '<span class="tok-number">' + typeObj.hostIntBytes + '</span>';
+                        } else {
+                            name += typeObj.hostIntBytes;
+                        }
                     }
                     name += ") ";
                 }
-                name += typeIndexName(typeObj.elem, wantHtml, wantSubLink, null, null, thisTypes);
+                name += typeIndexName(typeObj.elem, wantHtml, wantSubLink, null);
                 return name;
             case typeKinds.Float:
-                return token('f' + typeObj.bits, tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">f' + typeObj.bits + '</span>';
+                } else {
+                    return "f" + typeObj.bits;
+                }
             case typeKinds.Int:
-                var signed = (typeObj.i != null) ? 'i' : 'u';
-                var bits = typeObj[signed];
-                return token(signed + bits, tokenKinds.Type, wantHtml);
+                return '<span class="tok-type">' + typeObj.name + '</span>';
+                // var signed = (typeObj.i != null) ? 'i' : 'u';
+                // var bits = typeObj[signed];
+                // if (wantHtml) {
+                //     return '<span class="tok-type">' + signed + bits + '</span>';
+                // } else {
+                //     return signed + bits;
+                // }
             case typeKinds.ComptimeInt:
-                return token('comptime_int', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">comptime_int</span>';
+                } else {
+                    return "comptime_int";
+                }
             case typeKinds.ComptimeFloat:
-                return token('comptime_float', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">comptime_float</span>';
+                } else {
+                    return "comptime_float";
+                }
             case typeKinds.Type:
-                return token('type', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">type</span>';
+                } else {
+                    return "type";
+                }
             case typeKinds.Bool:
-                return token('bool', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">bool</span>';
+                } else {
+                    return "bool";
+                }
             case typeKinds.Void:
-                return token('void', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">void</span>';
+                } else {
+                    return "void";
+                }
             case typeKinds.EnumLiteral:
-                return token('(enum literal)', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">(enum literal)</span>';
+                } else {
+                    return "(enum literal)";
+                }
             case typeKinds.NoReturn:
-                return token('noreturn', tokenKinds.Type, wantHtml);
+                if (wantHtml) {
+                    return '<span class="tok-type">noreturn</span>';
+                } else {
+                    return "noreturn";
+                }
             case typeKinds.ErrorSet:
                 if (typeObj.errors == null) {
-                    return token('anyerror', tokenKinds.Type, wantHtml);
+                    if (wantHtml) {
+                        return '<span class="tok-type">anyerror</span>';
+                    } else {
+                        return "anyerror";
+                    }
                 } else {
                     if (wantHtml) {
                         return escapeHtml(typeObj.name);
@@ -665,12 +708,12 @@
                 }
             case typeKinds.ErrorUnion:
                 var errSetTypeObj = zigAnalysis.types[typeObj.err];
-                var payloadHtml = typeIndexName(typeObj.payload, wantHtml, wantSubLink, null, null, thisTypes);
+                var payloadHtml = typeIndexName(typeObj.payload, wantHtml, wantSubLink, null);
                 if (fnDecl != null && errSetTypeObj.fn === fnDecl.value) {
                     // function index parameter supplied and this is the inferred error set of it
                     return "!" + payloadHtml;
                 } else {
-                    return typeIndexName(typeObj.err, wantHtml, wantSubLink, null, null, thisTypes) + "!" + payloadHtml;
+                    return typeIndexName(typeObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml;
                 }
             case typeKinds.Fn:
                 var payloadHtml = "";
@@ -716,11 +759,19 @@
                             }
 
                             if (paramNode.noalias) {
-                                payloadHtml += token('noalias', tokenKinds.Keyword, wantHtml) + ' ';
+                                if (wantHtml) {
+                                    payloadHtml += '<span class="tok-kw">noalias</span> ';
+                                } else {
+                                    payloadHtml += 'noalias ';
+                                }
                             }
 
                             if (paramNode.comptime) {
-                                payloadHtml += token('comptime', tokenKinds.Keyword, wantHtml) + ' ';
+                                if (wantHtml) {
+                                    payloadHtml += '<span class="tok-kw">comptime</span> ';
+                                } else {
+                                    payloadHtml += 'comptime ';
+                                }
                             }
 
                             var paramName = paramNode.name;
@@ -735,30 +786,24 @@
                         if (isVarArgs && i === typeObj.args.length - 1) {
                             payloadHtml += '...';
                         } else if (argTypeIndex != null) {
-                            payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink, null, null, thisTypes);
+                            payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink);
+                        } else if (wantHtml) {
+                            payloadHtml += '<span class="tok-kw">var</span>';
                         } else {
-                            payloadHtml += token('anytype', tokenKinds.Keyword, wantHtml);
+                            payloadHtml += 'var';
                         }
                     }
                 }
 
                 payloadHtml += ') ';
                 if (typeObj.ret != null) {
-                    payloadHtml += typeIndexName(typeObj.ret, wantHtml, wantSubLink, fnDecl, null, thisTypes);
+                    payloadHtml += typeIndexName(typeObj.ret, wantHtml, wantSubLink, fnDecl);
+                } else if (wantHtml) {
+                    payloadHtml += '<span class="tok-kw">var</span>';
                 } else {
-                    payloadHtml += token('anytype', tokenKinds.Keyword, wantHtml);
+                    payloadHtml += 'var';
                 }
                 return payloadHtml;
-            case typeKinds.Frame:
-                var fnObj = zigAnalysis.fns[typeObj.fn];
-                return '@Frame(' + getValueText(fnObj.type, typeObj.fn, wantHtml, wantSubLink) + ')';
-            case typeKinds.AnyFrame:
-                var name = token('anyframe', tokenKinds.Keyword, wantHtml);
-                if (typeObj.result) {
-                  name += "->";
-                  name += typeIndexName(typeObj.result, wantHtml, wantSubLink, null, null, thisTypes);
-                }
-                return name;
             default:
                 if (wantHtml) {
                     return escapeHtml(typeObj.name);
@@ -801,10 +846,10 @@
                 return operatorCompare(a.err.name.toLowerCase(), b.err.name.toLowerCase());
             });
 
-            var domListFnErrorsFragment = createDomListFragment(errorList.length, "<dt></dt><dd></dd>");
+            resizeDomListDl(domListFnErrors, errorList.length);
             for (var i = 0; i < errorList.length; i += 1) {
-                var nameTdDom = domListFnErrorsFragment.children[i * 2 + 0];
-                var descTdDom = domListFnErrorsFragment.children[i * 2 + 1];
+                var nameTdDom = domListFnErrors.children[i * 2 + 0];
+                var descTdDom = domListFnErrors.children[i * 2 + 1];
                 nameTdDom.textContent = errorList[i].err.name;
                 var docs = errorList[i].docs;
                 if (docs != null) {
@@ -813,8 +858,6 @@
                     descTdDom.textContent = "";
                 }
             }
-            domListFnErrors.innerHTML = "";
-            domListFnErrors.appendChild(domListFnErrorsFragment);
             domTableFnErrors.classList.remove("hidden");
         }
         domSectFnErrors.classList.remove("hidden");
@@ -941,7 +984,7 @@
         domFnProto.classList.remove("hidden");
     }
 
-    function renderContainer(container, thisTypes) {
+    function renderContainer(container) {
         var typesList = [];
         var namespacesList = [];
         var errSetsList = [];
@@ -994,56 +1037,50 @@
         }
 
         if (typesList.length !== 0) {
-            var domListTypesFragment = createDomListFragment(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) {
-                var liDom = domListTypesFragment.children[i];
+                var liDom = domListTypes.children[i];
                 var aDom = liDom.children[0];
                 var decl = typesList[i];
                 aDom.textContent = decl.name;
                 aDom.setAttribute('href', navLinkDecl(decl.name));
             }
-            domListTypes.innerHTML = "";
-            domListTypes.appendChild(domListTypesFragment);
             domSectTypes.classList.remove("hidden");
         }
         if (namespacesList.length !== 0) {
-            var domListNamespacesFragment = createDomListFragment(namespacesList.length, '<li><a href="#"></a></li>');
+            resizeDomList(domListNamespaces, namespacesList.length, '<li><a href="#"></a></li>');
             for (var i = 0; i < namespacesList.length; i += 1) {
-                var liDom = domListNamespacesFragment.children[i];
+                var liDom = domListNamespaces.children[i];
                 var aDom = liDom.children[0];
                 var decl = namespacesList[i];
                 aDom.textContent = decl.name;
                 aDom.setAttribute('href', navLinkDecl(decl.name));
             }
-            domListNamespaces.innerHTML = "";
-            domListNamespaces.appendChild(domListNamespacesFragment);
             domSectNamespaces.classList.remove("hidden");
         }
 
         if (errSetsList.length !== 0) {
-            var domListErrSetsFragment = createDomListFragment(errSetsList.length, '<li><a href="#"></a></li>');
+            resizeDomList(domListErrSets, errSetsList.length, '<li><a href="#"></a></li>');
             for (var i = 0; i < errSetsList.length; i += 1) {
-                var liDom = domListErrSetsFragment.children[i];
+                var liDom = domListErrSets.children[i];
                 var aDom = liDom.children[0];
                 var decl = errSetsList[i];
                 aDom.textContent = decl.name;
                 aDom.setAttribute('href', navLinkDecl(decl.name));
             }
-            domListErrSets.innerHTML = "";
-            domListErrSets.appendChild(domListErrSetsFragment);
             domSectErrSets.classList.remove("hidden");
         }
 
         if (fnsList.length !== 0) {
-            var domListFnsFragment = createDomListFragment(fnsList.length, '<tr><td></td><td></td></tr>');
+            resizeDomList(domListFns, fnsList.length, '<tr><td></td><td></td></tr>');
             for (var i = 0; i < fnsList.length; i += 1) {
                 var decl = fnsList[i];
-                var trDom = domListFnsFragment.children[i];
+                var trDom = domListFns.children[i];
 
                 var tdFnCode = trDom.children[0];
                 var tdDesc = trDom.children[1];
 
-                tdFnCode.innerHTML = typeIndexName(decl.type, true, true, decl, navLinkDecl(decl.name), thisTypes);
+                tdFnCode.innerHTML = typeIndexName(decl.type, true, true, decl, navLinkDecl(decl.name));
 
                 var docs = zigAnalysis.astNodes[decl.src].docs;
                 if (docs != null) {
@@ -1052,19 +1089,17 @@
                     tdDesc.textContent = "";
                 }
             }
-            domListFns.innerHTML = "";
-            domListFns.appendChild(domListFnsFragment);
             domSectFns.classList.remove("hidden");
         }
 
         if (container.fields != null && container.fields.length !== 0) {
-            var domListFieldsFragment = createDomListFragment(container.fields.length, '<div></div>');
+            resizeDomList(domListFields, container.fields.length, '<div></div>');
 
             var containerNode = zigAnalysis.astNodes[container.src];
             for (var i = 0; i < container.fields.length; i += 1) {
                 var field = container.fields[i];
                 var fieldNode = zigAnalysis.astNodes[containerNode.fields[i]];
-                var divDom = domListFieldsFragment.children[i];
+                var divDom = domListFields.children[i];
 
                 var html = '<div class="mobile-scroll-container"><pre class="scroll-item">' + escapeHtml(fieldNode.name);
 
@@ -1073,7 +1108,16 @@
                 } else {
                     html += ": ";
                     if (typeof(field) === 'object') {
-                        html += '<span class="tok-kw">var</span>';
+                        if (field.failure === true) {
+                            html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
+                        } else if ("decl_ref" in field) {
+                            var name = zigAnalysis.decls[field.decl_ref].name;
+                            html += '<a href="'+navLinkDecl(name)+'">';
+                            html += '<span class="tok-kw" style="color:lightblue;">'+ name +'</span>';
+                            html += '</a>';
+                        } else {
+                            html += '<span class="tok-kw">var</span>';
+                        }
                     } else {
                         html += typeIndexName(field, true, true);
                     }
@@ -1087,17 +1131,15 @@
                 }
                 divDom.innerHTML = html;
             }
-            domListFields.innerHTML = "";
-            domListFields.appendChild(domListFieldsFragment);
             domSectFields.classList.remove("hidden");
         }
 
         if (varsList.length !== 0) {
-            var domListGlobalVarsFragment = createDomListFragment(varsList.length,
+            resizeDomList(domListGlobalVars, varsList.length,
                 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');
             for (var i = 0; i < varsList.length; i += 1) {
                 var decl = varsList[i];
-                var trDom = domListGlobalVarsFragment.children[i];
+                var trDom = domListGlobalVars.children[i];
 
                 var tdName = trDom.children[0];
                 var tdNameA = tdName.children[0];
@@ -1116,17 +1158,15 @@
                     tdDesc.textContent = "";
                 }
             }
-            domListGlobalVars.innerHTML = "";
-            domListGlobalVars.appendChild(domListGlobalVarsFragment);
             domSectGlobalVars.classList.remove("hidden");
         }
 
         if (valsList.length !== 0) {
-            var domListValuesFragment = createDomListFragment(valsList.length,
+            resizeDomList(domListValues, valsList.length,
                 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');
             for (var i = 0; i < valsList.length; i += 1) {
                 var decl = valsList[i];
-                var trDom = domListValuesFragment.children[i];
+                var trDom = domListValues.children[i];
 
                 var tdName = trDom.children[0];
                 var tdNameA = tdName.children[0];
@@ -1145,8 +1185,6 @@
                     tdDesc.textContent = "";
                 }
             }
-            domListValues.innerHTML = "";
-            domListValues.appendChild(domListValuesFragment);
             domSectValues.classList.remove("hidden");
         }
     }
@@ -1484,22 +1522,6 @@
                 }
             ];
 
-            // Links, images and inner links don't use the same marker to wrap their content.
-            const linksFormat = [
-                {
-                    prefix: "[",
-                    regex: /\[([^\]]*)\]\(([^\)]*)\)/,
-                    urlIndex: 2, // Index in the match that contains the link URL
-                    textIndex: 1 // Index in the match that contains the link text
-                },
-                {
-                    prefix: "h",
-                    regex: /http[s]?:\/\/[^\s]+/,
-                    urlIndex: 0,
-                    textIndex: 0
-                }
-            ];
-
             const stack = [];
 
             var innerHTML = "";
@@ -1550,29 +1572,6 @@
                     currentRun += innerText[i];
                     in_code = true;
                 } else {
-                    var foundMatches = false;
-
-                    for (var j = 0; j < linksFormat.length; j++) {
-                        const linkFmt = linksFormat[j];
-
-                        if (linkFmt.prefix == innerText[i]) {
-                            var remaining = innerText.substring(i);
-                            var matches = remaining.match(linkFmt.regex);
-
-                            if (matches) {
-                                flushRun();
-                                innerHTML += ' <a href="' + matches[linkFmt.urlIndex] + '">' + matches[linkFmt.textIndex] + '</a> ';
-                                i += matches[0].length; // Skip the fragment we just consumed
-                                foundMatches = true;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (foundMatches) {
-                        continue;
-                    }
-
                     var any = false;
                     for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
                         const fmt = idx >= 0 ? formats[idx] : stack[stack.length - 1];
@@ -1793,7 +1792,7 @@
         if (ev.ctrlKey) name = "Ctrl+" + name;
         return name;
     }
-
+    
     function onWindowKeyDown(ev) {
         switch (getKeyString(ev)) {
             case "Esc":
@@ -1825,13 +1824,6 @@
         domHelpModal.focus();
     }
 
-    function onClickSearchShowAllResults(ev) {
-        ev.preventDefault();
-        ev.stopPropagation();
-        searchTrimResults = false;
-        onHashChange();
-    }
-
     function clearAsyncSearch() {
         if (searchTimer != null) {
             clearTimeout(searchTimer);
@@ -1841,21 +1833,14 @@
 
     function startAsyncSearch() {
         clearAsyncSearch();
-        searchTrimResults = true;
-        searchTimer = setTimeout(startSearch, 10);
+        searchTimer = setTimeout(startSearch, 100);
     }
     function startSearch() {
         clearAsyncSearch();
         var oldHash = location.hash;
         var parts = oldHash.split("?");
         var newPart2 = (domSearch.value === "") ? "" : ("?" + domSearch.value);
-        var newHash = (oldHash === "" ? "#" : parts[0]) + newPart2;
-        // create a history entry only once per search
-        if (parts.length === 1) {
-            location.assign(newHash);
-        } else {
-            location.replace(newHash);
-        }
+        location.hash = (parts.length === 1) ? (oldHash + newPart2) : (parts[0] + newPart2);
     }
     function getSearchTerms() {
         var list = curNavSearch.trim().split(/[ \r\n\t]+/);
@@ -1920,38 +1905,25 @@
         }
 
         if (matchedItems.length !== 0) {
+            resizeDomList(domListSearchResults, matchedItems.length, '<li><a href="#"></a></li>');
+
             matchedItems.sort(function(a, b) {
                 var cmp = operatorCompare(b.points, a.points);
                 if (cmp != 0) return cmp;
                 return operatorCompare(a.decl.name, b.decl.name);
             });
 
-            var searchTrimmed = false
-            var searchTrimResultsMaxItems = 200
-            if (searchTrimResults && matchedItems.length > searchTrimResultsMaxItems) {
-                matchedItems = matchedItems.slice(0, searchTrimResultsMaxItems)
-                searchTrimmed = true
-            }
-
-            var domListSearchResultsFragment = createDomListFragment(matchedItems.length, '<li><a href="#"></a></li>');
             for (var i = 0; i < matchedItems.length; i += 1) {
-                var liDom = domListSearchResultsFragment.children[i];
+                var liDom = domListSearchResults.children[i];
                 var aDom = liDom.children[0];
                 var match = matchedItems[i];
                 var lastPkgName = match.path.pkgNames[match.path.pkgNames.length - 1];
                 aDom.textContent = lastPkgName + "." + match.path.declNames.join('.');
                 aDom.setAttribute('href', navLink(match.path.pkgNames, match.path.declNames));
             }
+            renderSearchCursor();
 
-            domListSearchResults.innerHTML = "";
-            domListSearchResults.appendChild(domListSearchResultsFragment);
             domSectSearchResults.classList.remove("hidden");
-
-            if (searchTrimmed) {
-                domSectSearchAllResultsLink.classList.remove("hidden");
-            }
-
-            renderSearchCursor();
         } else {
             domSectSearchNoResults.classList.remove("hidden");
         }
@@ -2013,12 +1985,4 @@
             return key;
         }
     }
-
-    function token(value, tokenClass, wantHtml){
-        if(wantHtml){
-            return '<span class="' + tokenClass + '">' + value + '</span>';
-        } else {
-            return value + '';
-        }
-    }
 })();