| ... | ... | @@ -2,10 +2,21 @@ |
| 2 | 2 | |
| 3 | 3 | var zigAnalysis; |
| 4 | 4 | |
| 5 | const NAV_MODES = { |
| 6 | API: "#A;", |
| 7 | API_INTERNAL: "#a;", |
| 8 | GUIDES: "#G;", |
| 9 | }; |
| 10 | |
| 5 | 11 | (function () { |
| 6 | 12 | const domStatus = document.getElementById("status"); |
| 7 | 13 | const domSectNav = document.getElementById("sectNav"); |
| 8 | 14 | const domListNav = document.getElementById("listNav"); |
| 15 | const domApiSwitch = document.getElementById("ApiSwitch"); |
| 16 | const domGuideSwitch = document.getElementById("guideSwitch"); |
| 17 | const domGuidesMenu = document.getElementById("guidesMenu"); |
| 18 | const domApiMenu = document.getElementById("apiMenu"); |
| 19 | const domGuidesList = document.getElementById("guidesList"); |
| 9 | 20 | const domSectMainPkg = document.getElementById("sectMainPkg"); |
| 10 | 21 | const domSectPkgs = document.getElementById("sectPkgs"); |
| 11 | 22 | const domListPkgs = document.getElementById("listPkgs"); |
| ... | ... | @@ -45,6 +56,7 @@ var zigAnalysis; |
| 45 | 56 | const domSectSearchResults = document.getElementById("sectSearchResults"); |
| 46 | 57 | const domSectSearchAllResultsLink = document.getElementById("sectSearchAllResultsLink"); |
| 47 | 58 | const domDocs = document.getElementById("docs"); |
| 59 | const domGuides = document.getElementById("guides"); |
| 48 | 60 | const domListSearchResults = document.getElementById("listSearchResults"); |
| 49 | 61 | const domSectSearchNoResults = document.getElementById("sectSearchNoResults"); |
| 50 | 62 | const domSectInfo = document.getElementById("sectInfo"); |
| ... | ... | @@ -83,7 +95,8 @@ var zigAnalysis; |
| 83 | 95 | let canonTypeDecls = null; // lazy; use getCanonTypeDecl |
| 84 | 96 | |
| 85 | 97 | let curNav = { |
| 86 | | showPrivDecls: false, |
| 98 | mode: NAV_MODES.API, |
| 99 | activeGuide: "", |
| 87 | 100 | // each element is a package name, e.g. @import("a") then within there @import("b") |
| 88 | 101 | // starting implicitly from root package |
| 89 | 102 | pkgNames: [], |
| ... | ... | @@ -152,7 +165,7 @@ var zigAnalysis; |
| 152 | 165 | ); |
| 153 | 166 | |
| 154 | 167 | if (location.hash == "") { |
| 155 | | location.hash = "#root"; |
| 168 | location.hash = "#A;"; |
| 156 | 169 | } |
| 157 | 170 | |
| 158 | 171 | // make the modal disappear if you click outside it |
| ... | ... | @@ -173,17 +186,21 @@ var zigAnalysis; |
| 173 | 186 | domLangRefLink.href = `https://ziglang.org/documentation/${langRefVersion}/`; |
| 174 | 187 | |
| 175 | 188 | function renderTitle() { |
| 176 | | let list = curNav.pkgNames.concat(curNav.declNames); |
| 177 | 189 | let suffix = " - Zig"; |
| 178 | | if (list.length === 0) { |
| 179 | | if (rootIsStd) { |
| 180 | | document.title = "std" + suffix; |
| 181 | | } else { |
| 182 | | document.title = zigAnalysis.params.rootName + suffix; |
| 183 | | } |
| 184 | | } else { |
| 185 | | document.title = list.join(".") + suffix; |
| 186 | | } |
| 190 | switch (curNav.mode) { |
| 191 | case NAV_MODES.API: |
| 192 | case NAV_MODES.API_INTERNAL: |
| 193 | let list = curNav.pkgNames.concat(curNav.declNames); |
| 194 | if (list.length === 0) { |
| 195 | document.title = zigAnalysis.packages[zigAnalysis.rootPkg].name + suffix; |
| 196 | } else { |
| 197 | document.title = list.join(".") + suffix; |
| 198 | } |
| 199 | return; |
| 200 | case NAV_MODES.GUIDES: |
| 201 | document.title = "[G] " + curNav.activeGuide + suffix; |
| 202 | return; |
| 203 | } |
| 187 | 204 | } |
| 188 | 205 | |
| 189 | 206 | function isDecl(x) { |
| ... | ... | @@ -377,8 +394,80 @@ var zigAnalysis; |
| 377 | 394 | // console.assert(false); |
| 378 | 395 | // return ({}); |
| 379 | 396 | // } |
| 397 | function renderGuides() { |
| 398 | renderTitle(); |
| 380 | 399 | |
| 381 | | function render() { |
| 400 | // set guide mode |
| 401 | domGuideSwitch.classList.add("active"); |
| 402 | domApiSwitch.classList.remove("active"); |
| 403 | domDocs.classList.add("hidden"); |
| 404 | domGuides.classList.remove("hidden"); |
| 405 | domApiMenu.classList.add("hidden"); |
| 406 | |
| 407 | // sidebar guides list |
| 408 | const list = Object.keys(zigAnalysis.guides); |
| 409 | resizeDomList(domGuidesList, list.length, '<li><a href="#"></a></li>'); |
| 410 | for (let i = 0; i < list.length; i += 1) { |
| 411 | let liDom = domGuidesList.children[i]; |
| 412 | let aDom = liDom.children[0]; |
| 413 | aDom.textContent = list[i]; |
| 414 | aDom.setAttribute("href", NAV_MODES.GUIDES + list[i]); |
| 415 | if (list[i] === curNav.activeGuide) { |
| 416 | aDom.classList.add("active"); |
| 417 | } else { |
| 418 | aDom.classList.remove("active"); |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | if (list.length > 0) { |
| 423 | domGuidesMenu.classList.remove("hidden"); |
| 424 | } |
| 425 | |
| 426 | // main content |
| 427 | const activeGuide = zigAnalysis.guides[curNav.activeGuide]; |
| 428 | if (activeGuide == undefined) { |
| 429 | const root_file_idx = zigAnalysis.packages[zigAnalysis.rootPkg].file; |
| 430 | const root_file_name = zigAnalysis.files[root_file_idx]; |
| 431 | domGuides.innerHTML = markdown(` |
| 432 | # Zig Guides |
| 433 | These autodocs don't contain any guide. |
| 434 | |
| 435 | While the API section is a reference guide autogenerated from Zig source code, |
| 436 | guides are meant to be handwritten explanations that provide for example: |
| 437 | |
| 438 | - how-to explanations for common use-cases |
| 439 | - technical documentation |
| 440 | - information about advanced usage patterns |
| 441 | |
| 442 | You can add guides by specifying which markdown files to include |
| 443 | in the top level doc comment of your root file, like so: |
| 444 | |
| 445 | (At the top of \`${root_file_name}\`) |
| 446 | \`\`\` |
| 447 | //!zig-autodoc-guide: intro.md |
| 448 | //!zig-autodoc-guide: quickstart.md |
| 449 | //!zig-autodoc-guide: ../advanced-docs/advanced-stuff.md |
| 450 | \`\`\` |
| 451 | |
| 452 | **Note that this feature is still under heavy development so expect bugs** |
| 453 | **and missing features!** |
| 454 | |
| 455 | Happy writing! |
| 456 | `); |
| 457 | } else { |
| 458 | domGuides.innerHTML = markdown(activeGuide); |
| 459 | } |
| 460 | } |
| 461 | |
| 462 | function renderApi() { |
| 463 | // set Api mode |
| 464 | domApiSwitch.classList.add("active"); |
| 465 | domGuideSwitch.classList.remove("active"); |
| 466 | domGuides.classList.add("hidden"); |
| 467 | domDocs.classList.remove("hidden"); |
| 468 | domApiMenu.classList.remove("hidden"); |
| 469 | domGuidesMenu.classList.add("hidden"); |
| 470 | |
| 382 | 471 | domStatus.classList.add("hidden"); |
| 383 | 472 | domFnProto.classList.add("hidden"); |
| 384 | 473 | domSectParams.classList.add("hidden"); |
| ... | ... | @@ -411,17 +500,16 @@ var zigAnalysis; |
| 411 | 500 | renderInfo(); |
| 412 | 501 | renderPkgList(); |
| 413 | 502 | |
| 414 | | domPrivDeclsBox.checked = curNav.showPrivDecls; |
| 503 | domPrivDeclsBox.checked = curNav.mode == NAV_MODES.API_INTERNAL; |
| 415 | 504 | |
| 416 | 505 | if (curNavSearch !== "") { |
| 417 | 506 | return renderSearch(); |
| 418 | 507 | } |
| 419 | 508 | |
| 420 | | |
| 421 | 509 | let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg]; |
| 422 | 510 | let pkg = rootPkg; |
| 423 | 511 | curNav.pkgObjs = [pkg]; |
| 424 | | for (let i = 0; i < curNav.pkgNames.length; i += 1) { |
| 512 | for (let i = 1; i < curNav.pkgNames.length; i += 1) { |
| 425 | 513 | let childPkg = zigAnalysis.packages[pkg.table[curNav.pkgNames[i]]]; |
| 426 | 514 | if (childPkg == null) { |
| 427 | 515 | return render404(); |
| ... | ... | @@ -494,6 +582,19 @@ var zigAnalysis; |
| 494 | 582 | |
| 495 | 583 | } |
| 496 | 584 | |
| 585 | function render() { |
| 586 | switch (curNav.mode) { |
| 587 | case NAV_MODES.API: |
| 588 | case NAV_MODES.API_INTERNAL: |
| 589 | return renderApi(); |
| 590 | case NAV_MODES.GUIDES: |
| 591 | return renderGuides(); |
| 592 | default: |
| 593 | throw "?"; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | |
| 497 | 598 | function renderDocTest(decl) { |
| 498 | 599 | if (!decl.decltest) return; |
| 499 | 600 | const astNode = getAstNode(decl.decltest); |
| ... | ... | @@ -705,7 +806,6 @@ var zigAnalysis; |
| 705 | 806 | for (let i = 0; i < curNav.pkgNames.length; i += 1) { |
| 706 | 807 | hrefPkgNames.push(curNav.pkgNames[i]); |
| 707 | 808 | let name = curNav.pkgNames[i]; |
| 708 | | if (name == "root") name = zigAnalysis.rootPkgName; |
| 709 | 809 | list.push({ |
| 710 | 810 | name: name, |
| 711 | 811 | link: navLink(hrefPkgNames, hrefDeclNames), |
| ... | ... | @@ -747,12 +847,12 @@ var zigAnalysis; |
| 747 | 847 | } |
| 748 | 848 | |
| 749 | 849 | function renderPkgList() { |
| 750 | | let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg]; |
| 850 | const rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg]; |
| 751 | 851 | let list = []; |
| 752 | 852 | for (let key in rootPkg.table) { |
| 753 | 853 | let pkgIndex = rootPkg.table[key]; |
| 754 | 854 | if (zigAnalysis.packages[pkgIndex] == null) continue; |
| 755 | | if (key == zigAnalysis.params.rootName) continue; |
| 855 | if (key == rootPkg.name) continue; |
| 756 | 856 | list.push({ |
| 757 | 857 | name: key, |
| 758 | 858 | pkg: pkgIndex, |
| ... | ... | @@ -761,9 +861,9 @@ var zigAnalysis; |
| 761 | 861 | |
| 762 | 862 | { |
| 763 | 863 | let aDom = domSectMainPkg.children[1].children[0].children[0]; |
| 764 | | aDom.textContent = zigAnalysis.rootPkgName; |
| 864 | aDom.textContent = rootPkg.name; |
| 765 | 865 | aDom.setAttribute("href", navLinkPkg(zigAnalysis.rootPkg)); |
| 766 | | if (zigAnalysis.params.rootName === curNav.pkgNames[0]) { |
| 866 | if (rootPkg.name === curNav.pkgNames[0]) { |
| 767 | 867 | aDom.classList.add("active"); |
| 768 | 868 | } else { |
| 769 | 869 | aDom.classList.remove("active"); |
| ... | ... | @@ -794,20 +894,17 @@ var zigAnalysis; |
| 794 | 894 | } |
| 795 | 895 | |
| 796 | 896 | function navLink(pkgNames, declNames, callName) { |
| 797 | | let base = "#"; |
| 798 | | if (curNav.showPrivDecls) { |
| 799 | | base += "*"; |
| 800 | | } |
| 801 | | |
| 897 | let base = curNav.mode; |
| 898 | |
| 802 | 899 | if (pkgNames.length === 0 && declNames.length === 0) { |
| 803 | 900 | return base; |
| 804 | 901 | } else if (declNames.length === 0 && callName == null) { |
| 805 | 902 | return base + pkgNames.join("."); |
| 806 | 903 | } else if (callName == null) { |
| 807 | | return base + pkgNames.join(".") + ";" + declNames.join("."); |
| 904 | return base + pkgNames.join(".") + ":" + declNames.join("."); |
| 808 | 905 | } else { |
| 809 | 906 | return ( |
| 810 | | base + pkgNames.join(".") + ";" + declNames.join(".") + ";" + callName |
| 907 | base + pkgNames.join(".") + ":" + declNames.join(".") + ";" + callName |
| 811 | 908 | ); |
| 812 | 909 | } |
| 813 | 910 | } |
| ... | ... | @@ -2734,9 +2831,10 @@ var zigAnalysis; |
| 2734 | 2831 | throw new Error("No type 'type' found"); |
| 2735 | 2832 | } |
| 2736 | 2833 | |
| 2737 | | function updateCurNav() { |
| 2834 | |
| 2835 | function updateCurNav() { |
| 2738 | 2836 | curNav = { |
| 2739 | | showPrivDecls: false, |
| 2837 | mode: NAV_MODES.API, |
| 2740 | 2838 | pkgNames: [], |
| 2741 | 2839 | pkgObjs: [], |
| 2742 | 2840 | declNames: [], |
| ... | ... | @@ -2745,30 +2843,54 @@ var zigAnalysis; |
| 2745 | 2843 | }; |
| 2746 | 2844 | curNavSearch = ""; |
| 2747 | 2845 | |
| 2748 | | if (location.hash[0] === "#" && location.hash.length > 1) { |
| 2749 | | let query = location.hash.substring(1); |
| 2750 | | if (query[0] === "*") { |
| 2751 | | curNav.showPrivDecls = true; |
| 2752 | | query = query.substring(1); |
| 2753 | | } |
| 2846 | const mode = location.hash.substring(0, 3); |
| 2847 | let query = location.hash.substring(3); |
| 2848 | |
| 2849 | const DEFAULT_HASH = NAV_MODES.API + zigAnalysis.packages[zigAnalysis.rootPkg].name; |
| 2850 | switch (mode) { |
| 2851 | case NAV_MODES.API: |
| 2852 | case NAV_MODES.API_INTERNAL: |
| 2853 | // #A;PACKAGE:decl.decl.decl?search-term |
| 2854 | curNav.mode = mode; |
| 2855 | |
| 2856 | let qpos = query.indexOf("?"); |
| 2857 | let nonSearchPart; |
| 2858 | if (qpos === -1) { |
| 2859 | nonSearchPart = query; |
| 2860 | } else { |
| 2861 | nonSearchPart = query.substring(0, qpos); |
| 2862 | curNavSearch = decodeURIComponent(query.substring(qpos + 1)); |
| 2863 | } |
| 2864 | |
| 2865 | let parts = nonSearchPart.split(":"); |
| 2866 | if (parts[0] == "") { |
| 2867 | location.hash = DEFAULT_HASH; |
| 2868 | } else { |
| 2869 | curNav.pkgNames = decodeURIComponent(parts[0]).split("."); |
| 2870 | } |
| 2754 | 2871 | |
| 2755 | | let qpos = query.indexOf("?"); |
| 2756 | | let nonSearchPart; |
| 2757 | | if (qpos === -1) { |
| 2758 | | nonSearchPart = query; |
| 2759 | | } else { |
| 2760 | | nonSearchPart = query.substring(0, qpos); |
| 2761 | | curNavSearch = decodeURIComponent(query.substring(qpos + 1)); |
| 2762 | | } |
| 2872 | if (parts[1] != null) { |
| 2873 | curNav.declNames = decodeURIComponent(parts[1]).split("."); |
| 2874 | } |
| 2763 | 2875 | |
| 2764 | | let parts = nonSearchPart.split(";"); |
| 2765 | | curNav.pkgNames = decodeURIComponent(parts[0]).split("."); |
| 2766 | | if (parts[1] != null) { |
| 2767 | | curNav.declNames = decodeURIComponent(parts[1]).split("."); |
| 2768 | | } |
| 2769 | | } |
| 2770 | | } |
| 2876 | return; |
| 2877 | case NAV_MODES.GUIDES: |
| 2878 | const guides = Object.keys(zigAnalysis.guides); |
| 2879 | if (guides.length != 0 && query == "") { |
| 2880 | location.hash = NAV_MODES.GUIDES + guides[0]; |
| 2881 | return; |
| 2882 | } |
| 2771 | 2883 | |
| 2884 | curNav.mode = mode; |
| 2885 | curNav.activeGuide = query; |
| 2886 | |
| 2887 | return; |
| 2888 | default: |
| 2889 | location.hash = DEFAULT_HASH; |
| 2890 | return; |
| 2891 | } |
| 2892 | } |
| 2893 | |
| 2772 | 2894 | function onHashChange() { |
| 2773 | 2895 | updateCurNav(); |
| 2774 | 2896 | if (domSearch.value !== curNavSearch) { |