Skip to content

Commit

Permalink
chore(typedoc-theme): Generate navigation json file for each module
Browse files Browse the repository at this point in the history
  • Loading branch information
JumpLink committed Jun 26, 2023
1 parent 3750e23 commit 977adc7
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 28 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,3 @@
[submodule "@types"]
path = @types
url = https://github.com/gjsify/types.git
[submodule "vendor/ts-for-gjs"]
path = vendor/ts-for-gjs
url = https://github.com/gjsify/ts-for-gir.git
15 changes: 14 additions & 1 deletion packages/typedoc-build-docs/typedoc.try-gjs.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,18 @@
"noScript": true,
"noReplaceElement": true,
"serverBaseUrl": "https://try-gjs-docs.gjsify.org/",
"theme": "gjsify"
"theme": "gjsify",
"navigation": {
"includeCategories": true,
"includeGroups": true
},
"categorizeByGroup": true,
"visibilityFilters": {
"protected": true,
"private": true,
"inherited": true,
"external": true,
"@alpha": true,
"@beta": true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class RemoteSearchIndexPlugin {

private async onRenderDone() {
this.copyScripts();
await this.convertSearch();
// await this.convertSearch();
}

/**
Expand Down
152 changes: 134 additions & 18 deletions packages/typedoc-theme/src/partials/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { classNames, getDisplayName, wbr } from "../lib";

import type { PageEvent } from "typedoc";
import type { GjsifyThemeRenderContext } from "../theme-render-context";
import type { Module } from "../types";
import type { Module, NavigationData } from "../types";

export function sidebarLinks(context: GjsifyThemeRenderContext) {
const links = Object.entries(context.options.getValue("sidebarLinks"));
Expand Down Expand Up @@ -62,7 +62,7 @@ function getNavigationElements(
return parent.children || [];
}

export function getModules(
export function getModulesData(
context: GjsifyThemeRenderContext,
props: PageEvent<Reflection>
) {
Expand All @@ -86,6 +86,111 @@ export function getModules(
return modules;
}

export function navigationData(
context: GjsifyThemeRenderContext,
props: PageEvent<Reflection>,
forceOptions: {
includeCategories?: boolean;
includeGroups?: boolean;
fullTree?: boolean;
} = {}
): NavigationData {
const opts = { ...context.options.getValue("navigation"), ...forceOptions };
// Create the navigation for the current page
// Recurse to children if the parent is some kind of module

return createNavElementData(props.project);

function linksData(
mod: NavigationElement,
parents: string[]
): NavigationData {
const nameClasses = classNames(
{ deprecated: mod instanceof Reflection && mod.isDeprecated() },
mod instanceof DeclarationReflection
? context.getReflectionClasses(mod)
: void 0
);

const _children = getNavigationElements(mod, opts);

if (
!_children.length ||
(!opts.fullTree &&
mod instanceof Reflection &&
!navigationInPath(props, mod))
) {
return createNavElementData(mod, parents, nameClasses);
}

const nav = createNavElementData(mod, parents);

nav.children = _children.map((c) =>
linksData(
c,
mod instanceof Reflection
? [mod.getFullName()]
: [...parents, mod.title]
)
);

return nav;
}

function createNavElementData(
child: NavigationElement | ProjectReflection,
parents: string[] = [],
nameClasses?: string
): NavigationData {
const key =
child instanceof Reflection
? child.getFullName()
: [...parents, child.title].join("$");

// const active = child instanceof Reflection && inPath(child);
// const current = child === props.model;
// const classes = classNames({}, nameClasses);

const children: NavigationData[] = [];

for (const c of getNavigationElements(child, opts)) {
// Ignore root Modules which are not active / in path on not fullTree
if (!opts.fullTree && !navigationInPath(props, c)) continue;

const parentsNext =
child instanceof Reflection
? [child.getFullName()]
: [...parents, child.title];

children.push(linksData(c, parentsNext));
}

if (child instanceof Reflection) {
return {
key,
// active,
// current,
url: context.absoluteUrl(child.url),
title: getDisplayName(child), // TODO wbr
// classes,
kind: child.kind,
children,
};
}

return {
// key,
// active,
// current,
title: child.title,
isGroup: child instanceof ReflectionGroup,

// classes,
children,
};
}
}

export function navigation(
context: GjsifyThemeRenderContext,
props: PageEvent<Reflection>
Expand All @@ -94,13 +199,19 @@ export function navigation(
// Create the navigation for the current page
// Recurse to children if the parent is some kind of module

// console.debug("navigation", navigationData(context, props));

const addTitle = false;

return (
<nav class="tsd-navigation">
{createNavElement(props.project)}
{addTitle ? createNavElement(props.project) : <></>}
<ul class="tsd-small-nested-navigation">
{getNavigationElements(props.project, opts).map((c) => (
<li>{links(c, [])}</li>
))}
{getNavigationElements(props.project, opts).map((c) => {
// Ignore root Modules which are not active / in path
if (!opts.fullTree && !navigationInPath(props, c)) return null;
return <li>{links(c, [])}</li>;
})}
</ul>
</nav>
);
Expand All @@ -117,15 +228,17 @@ export function navigation(

if (
!children.length ||
(!opts.fullTree && mod instanceof Reflection && !inPath(mod))
(!opts.fullTree &&
mod instanceof Reflection &&
!navigationInPath(props, mod))
) {
return createNavElement(mod, nameClasses);
}

return (
<details
class={classNames({ "tsd-index-accordion": true }, nameClasses)}
open={mod instanceof Reflection && inPath(mod)}
open={mod instanceof Reflection && navigationInPath(props, mod)}
data-key={
mod instanceof Reflection
? mod.getFullName()
Expand Down Expand Up @@ -172,15 +285,6 @@ export function navigation(

return <span>{child.title}</span>;
}

function inPath(mod: DeclarationReflection | ProjectReflection) {
let iter: Reflection | undefined = props.model;
do {
if (iter == mod) return true;
iter = iter.parent;
} while (iter);
return false;
}
}

export function pageNavigation(
Expand All @@ -192,7 +296,7 @@ export function pageNavigation(
function finalizeLevel() {
const built = (
<ul>
{levels.pop()!.map((l) => (
{levels.pop()?.map((l) => (
<li>{l}</li>
))}
</ul>
Expand Down Expand Up @@ -284,3 +388,15 @@ function inPath(

return false;
}

function navigationInPath(
props: PageEvent<Reflection>,
mod: NavigationElement
) {
let iter: Reflection | undefined = props.model;
do {
if (iter == mod) return true;
iter = iter.parent;
} while (iter);
return false;
}
6 changes: 4 additions & 2 deletions packages/typedoc-theme/src/theme-render-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ import { members } from "./partials/members";
import { membersGroup } from "./partials/members.group";
import {
navigation,
navigationData,
pageNavigation,
sidebarLinks,
getModules,
getModulesData,
getCurrentModule,
} from "./partials/navigation";
import { gjsifySidebar, gjsifySidebarContent } from "./partials/gjsify-sidebar";
Expand Down Expand Up @@ -162,7 +163,8 @@ export class GjsifyThemeRenderContext {
navigation = bind(navigation, this);
gjsifySidebar = bind(gjsifySidebar, this);
gjsifySidebarContent = bind(gjsifySidebarContent, this);
getModules = bind(getModules, this);
getModulesData = bind(getModulesData, this);
navigationData = bind(navigationData, this);
getCurrentModule = bind(getCurrentModule, this);
pageNavigation = bind(pageNavigation, this);
parameter = bind(parameter, this);
Expand Down
26 changes: 24 additions & 2 deletions packages/typedoc-theme/src/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
PageEvent,
} from "typedoc";
import { JSX } from "./jsx/index.js";
import type { Renderer } from "typedoc";

import { MarkedPlugin } from "typedoc/dist/lib/output/themes/MarkedPlugin";
import { toStyleClass } from "./lib";
Expand All @@ -22,6 +21,9 @@ import { AssetService } from "./services/asset.service";
import { writeFileSync } from "./utils";
import { join } from "path";

import type { Renderer } from "typedoc";
import type { NavigationData } from "./types";

/**
* Defines a mapping of a {@link Models.Kind} to a template file.
*
Expand Down Expand Up @@ -152,6 +154,7 @@ export class GjsifyTheme extends Theme {

onPageHomeEnd(page: PageEvent<Reflection>) {
this.writeModulesJsonFile(page);
this.writeModuleNavigationJsonFiles(page);
}

onRendererEnd(event: RendererEvent) {
Expand Down Expand Up @@ -312,10 +315,29 @@ export class GjsifyTheme extends Theme {

const target = join(outputDirectory, "assets", filename);

const modules = context.getModules(page);
const modules = context.getModulesData(page);
writeFileSync(target, JSON.stringify(modules, null, 0));
}

writeModuleNavigationJsonFiles(page: PageEvent<Reflection>) {
const context = this.getRenderContext(page);
const navData = context.navigationData(page, { fullTree: true });
for (const child of navData.children) {
this.writeModuleNavigationJsonFile(child);
}
}

writeModuleNavigationJsonFile(mod: NavigationData) {
if (mod.kind !== ReflectionKind.Module) {
throw new Error(`Expected module, got ${mod.kind}`);
}
const filename = `navigation-${mod.title.toLowerCase()}.json`;
this.logger.info(`[GjsifyTheme] Generate ${filename}...`);
const outputDirectory = this.application.options.getValue("out");
const target = join(outputDirectory, "assets", filename);
writeFileSync(target, JSON.stringify(mod, null, 0));
}

render(
page: PageEvent<Reflection>,
template: RenderTemplate<PageEvent<Reflection>>
Expand Down
1 change: 1 addition & 0 deletions packages/typedoc-theme/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "@gjsify/typedoc-theme-client/scripts/types/index.js";
export * from "./internal.js";
export * from "./navigation-data.js";
12 changes: 12 additions & 0 deletions packages/typedoc-theme/src/types/navigation-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ReflectionKind } from "typedoc";

export interface NavigationData {
key?: string;
title: string;
url?: string;
// classes?: string | undefined;
kind?: ReflectionKind;
children: NavigationData[];
// active: boolean;
isGroup?: boolean;
}
1 change: 0 additions & 1 deletion vendor/ts-for-gjs
Submodule ts-for-gjs deleted from f5bcfd

0 comments on commit 977adc7

Please sign in to comment.