From feafd98f86b87c354604a2f9c2dba526ccde6205 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 10 Jul 2022 19:39:36 -0600 Subject: [PATCH 01/92] Clean up some properties --- CHANGELOG.md | 8 ++ .../comments/declarationReferenceResolver.ts | 2 +- src/lib/converter/plugins/CommentPlugin.ts | 17 ++-- src/lib/converter/plugins/GroupPlugin.ts | 70 +---------------- src/lib/models/comments/comment.ts | 18 +++++ src/lib/models/reflections/abstract.ts | 33 -------- src/lib/models/reflections/kind.ts | 78 ++++++++++++++++++- .../output/plugins/JavascriptIndexPlugin.ts | 10 --- .../assets/typedoc/components/Search.ts | 1 - .../output/themes/default/partials/header.tsx | 2 +- .../output/themes/default/partials/index.tsx | 4 +- .../output/themes/default/partials/type.tsx | 8 +- src/lib/output/themes/lib.tsx | 3 +- src/lib/serialization/schema.ts | 6 +- src/lib/utils/options/declaration.ts | 2 +- src/lib/validation/documentation.ts | 2 +- src/test/behaviorTests.ts | 2 +- src/test/converter/function/specs.json | 1 - 18 files changed, 123 insertions(+), 144 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a886da89a..a495040b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Beta + +### Breaking Changes + +- The `label` property on `Reflection` has moved to `Comment`. +- Removed unused `Reflection#originalName`. +- Removed `Reflection#kindString`, use `ReflectionKind.singularString(reflection.kind)` or `ReflectionKind.pluralString(reflection.kind)` instead. + # Unreleased ## v0.23.7 (2022-07-09) diff --git a/src/lib/converter/comments/declarationReferenceResolver.ts b/src/lib/converter/comments/declarationReferenceResolver.ts index 9184e4540..46ef84379 100644 --- a/src/lib/converter/comments/declarationReferenceResolver.ts +++ b/src/lib/converter/comments/declarationReferenceResolver.ts @@ -93,7 +93,7 @@ function filterMapByMeaning( return filterMap(reflections, (refl): Reflection | undefined => { const kwResolved = resolveKeyword(refl, meaning.keyword) || []; if (meaning.label) { - return kwResolved.find((r) => r.label === meaning.label); + return kwResolved.find((r) => r.comment?.label === meaning.label); } return kwResolved[meaning.index || 0]; }); diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index e39e46d67..e8e13036f 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -267,11 +267,13 @@ export class CommentPlugin extends ConverterComponent { */ private onResolve(context: Context, reflection: Reflection) { if (reflection.comment) { - reflection.label = extractLabelTag(reflection.comment); - if (reflection.label && !/[A-Z_][A-Z0-9_]/.test(reflection.label)) { + if ( + reflection.comment.label && + !/[A-Z_][A-Z0-9_]/.test(reflection.comment.label) + ) { context.logger.warn( `The label "${ - reflection.label + reflection.comment.label }" for ${reflection.getFriendlyFullName()} cannot be referenced with a declaration reference. ` + `Labels may only contain A-Z, 0-9, and _, and may not start with a number.` ); @@ -483,15 +485,6 @@ function moveNestedParamTags(comment: Comment, parameter: ParameterReflection) { parameter.type?.visit(visitor); } -function extractLabelTag(comment: Comment): string | undefined { - const index = comment.summary.findIndex( - (part) => part.kind === "inline-tag" && part.tag === "@label" - ); - - if (index !== -1) { - return comment.summary.splice(index, 1)[0].text; - } -} function mergeSeeTags(comment: Comment) { const see = comment.getTags("@see"); diff --git a/src/lib/converter/plugins/GroupPlugin.ts b/src/lib/converter/plugins/GroupPlugin.ts index 33d54c7d3..10db3dd76 100644 --- a/src/lib/converter/plugins/GroupPlugin.ts +++ b/src/lib/converter/plugins/GroupPlugin.ts @@ -19,25 +19,6 @@ import { Comment } from "../../models"; */ @Component({ name: "group" }) export class GroupPlugin extends ConverterComponent { - /** - * Define the singular name of individual reflection kinds. - */ - static SINGULARS = { - [ReflectionKind.Enum]: "Enumeration", - [ReflectionKind.EnumMember]: "Enumeration Member", - }; - - /** - * Define the plural name of individual reflection kinds. - */ - static PLURALS = { - [ReflectionKind.Class]: "Classes", - [ReflectionKind.Property]: "Properties", - [ReflectionKind.Enum]: "Enumerations", - [ReflectionKind.EnumMember]: "Enumeration Members", - [ReflectionKind.TypeAlias]: "Type Aliases", - }; - /** @internal */ @BindOption("sort") sortStrategies!: SortStrategy[]; @@ -64,8 +45,6 @@ export class GroupPlugin extends ConverterComponent { * @param reflection The reflection that is currently resolved. */ private onResolve(_context: Context, reflection: Reflection) { - reflection.kindString = GroupPlugin.getKindSingular(reflection.kind); - if (reflection instanceof ContainerReflection) { this.group(reflection); } @@ -143,7 +122,7 @@ export class GroupPlugin extends ConverterComponent { groups.delete(""); if (groups.size === 0) { - groups.add(GroupPlugin.getKindPlural(reflection.kind)); + groups.add(ReflectionKind.pluralString(reflection.kind)); } for (const group of groups) { @@ -184,51 +163,4 @@ export class GroupPlugin extends ConverterComponent { return Array.from(groups.values()); } - - /** - * Transform the internal typescript kind identifier into a human readable version. - * - * @param kind The original typescript kind identifier. - * @returns A human readable version of the given typescript kind identifier. - */ - private static getKindString(kind: ReflectionKind): string { - let str = ReflectionKind[kind]; - str = str.replace( - /(.)([A-Z])/g, - (_m, a, b) => a + " " + b.toLowerCase() - ); - return str; - } - - /** - * Return the singular name of a internal typescript kind identifier. - * - * @param kind The original internal typescript kind identifier. - * @returns The singular name of the given internal typescript kind identifier - */ - static getKindSingular(kind: ReflectionKind): string { - if (kind in GroupPlugin.SINGULARS) { - return GroupPlugin.SINGULARS[ - kind as keyof typeof GroupPlugin.SINGULARS - ]; - } else { - return GroupPlugin.getKindString(kind); - } - } - - /** - * Return the plural name of a internal typescript kind identifier. - * - * @param kind The original internal typescript kind identifier. - * @returns The plural name of the given internal typescript kind identifier - */ - static getKindPlural(kind: ReflectionKind): string { - if (kind in GroupPlugin.PLURALS) { - return GroupPlugin.PLURALS[ - kind as keyof typeof GroupPlugin.PLURALS - ]; - } else { - return this.getKindString(kind) + "s"; - } - } } diff --git a/src/lib/models/comments/comment.ts b/src/lib/models/comments/comment.ts index 37079324c..e55e1eee6 100644 --- a/src/lib/models/comments/comment.ts +++ b/src/lib/models/comments/comment.ts @@ -143,6 +143,12 @@ export class Comment { */ modifierTags: Set = new Set(); + /** + * Label associated with this reflection, if any (https://tsdoc.org/pages/tags/label/) + * Added by the CommentPlugin during resolution. + */ + label?: string; + /** * Creates a new Comment instance. */ @@ -154,6 +160,7 @@ export class Comment { this.summary = summary; this.blockTags = blockTags; this.modifierTags = modifierTags; + extractLabelTag(this); } /** @@ -241,6 +248,17 @@ export class Comment { this.modifierTags.size > 0 ? Array.from(this.modifierTags) : undefined, + label: this.label, }; } } + +function extractLabelTag(comment: Comment) { + const index = comment.summary.findIndex( + (part) => part.kind === "inline-tag" && part.tag === "@label" + ); + + if (index !== -1) { + comment.label = comment.summary.splice(index, 1)[0].text; + } +} diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index 6105eca25..975fbc807 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -7,18 +7,6 @@ import type { NeverIfInternal } from "../../utils"; import { ReflectionKind } from "./kind"; import type { Serializer, JSONOutput } from "../../serialization"; -/** - * Holds all data models used by TypeDoc. - * - * The {@link BaseReflection} is base class of all reflection models. The subclass {@link ProjectReflection} - * serves as the root container for the current project while {@link DeclarationReflection} instances - * form the structure of the project. Most of the other classes in this namespace are referenced by this - * two base classes. - * - * The models {@link NavigationItem} and {@link UrlMapping} are special as they are only used by the {@link Renderer} - * while creating the final output. - */ - /** * Current reflection id. */ @@ -252,28 +240,11 @@ export abstract class Reflection { */ name: string; - /** - * The original name of the TypeScript declaration. - */ - originalName: string; - - /** - * Label associated with this reflection, if any (https://tsdoc.org/pages/tags/label/) - * Added by the CommentPlugin during resolution. - */ - label?: string; - /** * The kind of this reflection. */ kind: ReflectionKind; - /** - * The human readable string representation of the kind of this reflection. - * Set during the resolution phase by GroupPlugin - */ - kindString?: string; - flags: ReflectionFlags = new ReflectionFlags(); /** @@ -340,7 +311,6 @@ export abstract class Reflection { this.id = REFLECTION_ID++; this.parent = parent; this.name = name; - this.originalName = name; this.kind = kind; // If our parent is external, we are too. @@ -558,14 +528,11 @@ export abstract class Reflection { id: this.id, name: this.name, kind: this.kind, - kindString: this.kindString, flags: this.flags.toObject(), comment: this.comment && !this.comment.isEmpty() ? serializer.toObject(this.comment) : undefined, - originalName: - this.originalName !== this.name ? this.originalName : undefined, }; } } diff --git a/src/lib/models/reflections/kind.ts b/src/lib/models/reflections/kind.ts index f96043428..cce064c95 100644 --- a/src/lib/models/reflections/kind.ts +++ b/src/lib/models/reflections/kind.ts @@ -28,44 +28,78 @@ export enum ReflectionKind { Reference = 0x800000, } -/** @hidden */ export namespace ReflectionKind { + // Would be nice to derive this... + export type KindString = + | "Project" + | "Module" + | "Namespace" + | "Enum" + | "EnumMember" + | "Variable" + | "Function" + | "Class" + | "Interface" + | "Constructor" + | "Property" + | "Method" + | "CallSignature" + | "IndexSignature" + | "ConstructorSignature" + | "Parameter" + | "TypeLiteral" + | "TypeParameter" + | "Accessor" + | "GetSignature" + | "SetSignature" + | "ObjectLiteral" + | "TypeAlias" + | "Reference"; + export const All = ReflectionKind.Reference * 2 - 1; + /** @internal */ export const ClassOrInterface = ReflectionKind.Class | ReflectionKind.Interface; + /** @internal */ export const VariableOrProperty = ReflectionKind.Variable | ReflectionKind.Property; + /** @internal */ export const FunctionOrMethod = ReflectionKind.Function | ReflectionKind.Method; + /** @internal */ export const ClassMember = ReflectionKind.Accessor | ReflectionKind.Constructor | ReflectionKind.Method | ReflectionKind.Property; + /** @internal */ export const SomeSignature = ReflectionKind.CallSignature | ReflectionKind.IndexSignature | ReflectionKind.ConstructorSignature | ReflectionKind.GetSignature | ReflectionKind.SetSignature; + /** @internal */ export const SomeModule = ReflectionKind.Namespace | ReflectionKind.Module; + /** @internal */ export const SomeType = ReflectionKind.Interface | ReflectionKind.TypeLiteral | ReflectionKind.TypeParameter | ReflectionKind.TypeAlias; + /** @internal */ export const SomeValue = ReflectionKind.Variable | ReflectionKind.Function | ReflectionKind.ObjectLiteral; - + /** @internal */ export const SomeMember = ReflectionKind.EnumMember | ReflectionKind.Property | ReflectionKind.Method | ReflectionKind.Accessor; - + /** @internal */ export const SomeExport = ReflectionKind.Module | ReflectionKind.Namespace | @@ -76,7 +110,7 @@ export namespace ReflectionKind { ReflectionKind.Interface | ReflectionKind.TypeAlias | ReflectionKind.Reference; - + /** @internal */ export const ExportContainer = ReflectionKind.SomeModule | ReflectionKind.Project; @@ -93,4 +127,40 @@ export namespace ReflectionKind { ReflectionKind.Constructor | ReflectionKind.Function | ReflectionKind.Method; + + const SINGULARS = { + [ReflectionKind.Enum]: "Enumeration", + [ReflectionKind.EnumMember]: "Enumeration Member", + }; + + const PLURALS = { + [ReflectionKind.Class]: "Classes", + [ReflectionKind.Property]: "Properties", + [ReflectionKind.Enum]: "Enumerations", + [ReflectionKind.EnumMember]: "Enumeration Members", + [ReflectionKind.TypeAlias]: "Type Aliases", + }; + + export function singularString(kind: ReflectionKind): string { + if (kind in SINGULARS) { + return SINGULARS[kind as keyof typeof SINGULARS]; + } else { + return getKindString(kind); + } + } + + export function pluralString(kind: ReflectionKind): string { + if (kind in PLURALS) { + return PLURALS[kind as keyof typeof PLURALS]; + } else { + return getKindString(kind) + "s"; + } + } +} + +function getKindString(kind: ReflectionKind): string { + return ReflectionKind[kind].replace( + /(.)([A-Z])/g, + (_m, a, b) => a + " " + b.toLowerCase() + ); } diff --git a/src/lib/output/plugins/JavascriptIndexPlugin.ts b/src/lib/output/plugins/JavascriptIndexPlugin.ts index e4466eb82..fd5a648f4 100644 --- a/src/lib/output/plugins/JavascriptIndexPlugin.ts +++ b/src/lib/output/plugins/JavascriptIndexPlugin.ts @@ -5,9 +5,7 @@ import { Comment, DeclarationReflection, ProjectReflection, - ReflectionKind, } from "../../models"; -import { GroupPlugin } from "../../converter/plugins"; import { Component, RendererComponent } from "../components"; import { IndexEvent, RendererEvent } from "../events"; import { BindOption, writeFileSync } from "../../utils"; @@ -55,7 +53,6 @@ export class JavascriptIndexPlugin extends RendererComponent { } const rows: SearchDocument[] = []; - const kinds: { [K in ReflectionKind]?: string } = {}; const initialSearchResults = Object.values( event.project.reflections @@ -104,12 +101,6 @@ export class JavascriptIndexPlugin extends RendererComponent { parent = undefined; } - if (!kinds[reflection.kind]) { - kinds[reflection.kind] = GroupPlugin.getKindSingular( - reflection.kind - ); - } - const row: SearchDocument = { kind: reflection.kind, name: reflection.name, @@ -142,7 +133,6 @@ export class JavascriptIndexPlugin extends RendererComponent { ); const jsonData = JSON.stringify({ - kinds, rows, index, }); diff --git a/src/lib/output/themes/default/assets/typedoc/components/Search.ts b/src/lib/output/themes/default/assets/typedoc/components/Search.ts index 0fcc1a6e5..7f508d462 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Search.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Search.ts @@ -16,7 +16,6 @@ interface SearchDocument { } interface IData { - kinds: { [kind: number]: string }; rows: SearchDocument[]; index: object; } diff --git a/src/lib/output/themes/default/partials/header.tsx b/src/lib/output/themes/default/partials/header.tsx index 904e44691..e6bebdf6f 100644 --- a/src/lib/output/themes/default/partials/header.tsx +++ b/src/lib/output/themes/default/partials/header.tsx @@ -10,7 +10,7 @@ export const header = (context: DefaultThemeRenderContext, props: PageEvent {!!props.model.parent &&
    {context.breadcrumb(props.model)}
} - {props.model.kind !== ReflectionKind.Project && `${props.model.kindString ?? ""} `} + {props.model.kind !== ReflectionKind.Project && `${ReflectionKind.singularString(props.model.kind)} `} {props.model.name} {props.model instanceof DeclarationReflection && props.model.version !== undefined && diff --git a/src/lib/output/themes/default/partials/index.tsx b/src/lib/output/themes/default/partials/index.tsx index ff0e46945..26e629d4d 100644 --- a/src/lib/output/themes/default/partials/index.tsx +++ b/src/lib/output/themes/default/partials/index.tsx @@ -1,4 +1,4 @@ -import { classNames, displayPartsToMarkdown, wbr } from "../../lib"; +import { classNames, displayPartsToMarkdown } from "../../lib"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; import { JSX, Raw } from "../../../../utils"; import { ContainerReflection, DeclarationReflection, ReflectionCategory, ReflectionKind } from "../../../../models"; @@ -18,7 +18,7 @@ function renderCategory({ urlTo, icons }: DefaultThemeRenderContext, item: Refle )} > {icons[item.kind]()} - {item.name ? wbr(item.name) : {wbr(item.kindString!)}} + {item.name} {"\n"} diff --git a/src/lib/output/themes/default/partials/type.tsx b/src/lib/output/themes/default/partials/type.tsx index 1a5745e38..d1d95ae20 100644 --- a/src/lib/output/themes/default/partials/type.tsx +++ b/src/lib/output/themes/default/partials/type.tsx @@ -61,7 +61,11 @@ function getNamespacedPath(reflection: Reflection): Reflection[] { } function renderUniquePath(context: DefaultThemeRenderContext, reflection: Reflection): JSX.Element { return join(., getUniquePath(reflection), (item) => ( - + {item.name} )); @@ -243,7 +247,7 @@ const typeRenderers: { if (reflection.kindOf(ReflectionKind.TypeParameter)) { // Don't generate a link will always point to this page, but do set the kind. name = ( - + {reflection.name} ); diff --git a/src/lib/output/themes/lib.tsx b/src/lib/output/themes/lib.tsx index d2e0f7972..c93f7be91 100644 --- a/src/lib/output/themes/lib.tsx +++ b/src/lib/output/themes/lib.tsx @@ -4,6 +4,7 @@ import { DeclarationReflection, Reflection, ReflectionFlags, + ReflectionKind, SignatureReflection, TypeParameterReflection, } from "../../models"; @@ -101,7 +102,7 @@ export function renderTypeParametersSignature( {join({", "}, typeParameters, (item) => ( <> {item.varianceModifier ? `${item.varianceModifier} ` : ""} - + {item.name} diff --git a/src/lib/serialization/schema.ts b/src/lib/serialization/schema.ts index 53a80cff7..350d6e4cf 100644 --- a/src/lib/serialization/schema.ts +++ b/src/lib/serialization/schema.ts @@ -171,9 +171,7 @@ export interface ContainerReflection > {} export interface Reflection - extends S { - /** Will not be present if name === originalName */ - originalName?: M.Reflection["originalName"]; + extends S { flags: ReflectionFlags; } @@ -302,7 +300,7 @@ type BoolKeys = { export interface ReflectionFlags extends Partial>> {} -export interface Comment extends Partial> { +export interface Comment extends Partial> { summary: CommentDisplayPart[]; modifierTags?: string[]; } diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index 6f8288e58..b87be10a5 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -150,7 +150,7 @@ export interface TypeDocOptionMap { treatWarningsAsErrors: boolean; intentionallyNotExported: string[]; validation: ValidationOptions; - requiredToBeDocumented: (keyof typeof ReflectionKind)[]; + requiredToBeDocumented: ReflectionKind.KindString[]; } /** diff --git a/src/lib/validation/documentation.ts b/src/lib/validation/documentation.ts index 767a1fffb..822ce6cd3 100644 --- a/src/lib/validation/documentation.ts +++ b/src/lib/validation/documentation.ts @@ -12,7 +12,7 @@ import { removeFlag } from "../utils/enum"; export function validateDocumentation( project: ProjectReflection, logger: Logger, - requiredToBeDocumented: readonly (keyof typeof ReflectionKind)[] + requiredToBeDocumented: readonly ReflectionKind.KindString[] ): void { let kinds = requiredToBeDocumented.reduce( (prev, cur) => prev | ReflectionKind[cur], diff --git a/src/test/behaviorTests.ts b/src/test/behaviorTests.ts index 62f35f60e..e67038dfc 100644 --- a/src/test/behaviorTests.ts +++ b/src/test/behaviorTests.ts @@ -488,7 +488,7 @@ export const behaviorTests: { equal(foo.comment, undefined); equal( - foo.signatures?.map((s) => s.label), + foo.signatures?.map((s) => s.comment?.label), ["NO_ARGS", "WITH_X"] ); diff --git a/src/test/converter/function/specs.json b/src/test/converter/function/specs.json index eea266563..6e7ffd29e 100644 --- a/src/test/converter/function/specs.json +++ b/src/test/converter/function/specs.json @@ -993,7 +993,6 @@ } ] }, - "originalName": "__namedParameters", "type": { "type": "reflection", "declaration": { From fc31e7d7b2425fac1fe6166629a6ae764db80fc0 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 10 Jul 2022 20:16:02 -0600 Subject: [PATCH 02/92] Remove cssClasses --- CHANGELOG.md | 1 + src/lib/models/reflections/abstract.ts | 7 -- .../output/plugins/JavascriptIndexPlugin.ts | 4 +- .../output/themes/default/DefaultTheme.tsx | 84 ++----------------- .../default/DefaultThemeRenderContext.ts | 76 ++++++++++++++++- .../output/themes/default/partials/index.tsx | 8 +- .../default/partials/member.getterSetter.tsx | 14 +++- .../default/partials/member.signatures.tsx | 3 +- .../output/themes/default/partials/member.tsx | 2 +- .../themes/default/partials/members.tsx | 10 ++- .../themes/default/partials/navigation.tsx | 13 ++- .../themes/default/partials/parameter.tsx | 4 +- .../themes/default/templates/reflection.tsx | 4 +- 13 files changed, 126 insertions(+), 104 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a495040b9..40a256b48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - The `label` property on `Reflection` has moved to `Comment`. - Removed unused `Reflection#originalName`. - Removed `Reflection#kindString`, use `ReflectionKind.singularString(reflection.kind)` or `ReflectionKind.pluralString(reflection.kind)` instead. +- Properties related to rendering are no longer stored on `Reflection`, including `url`, `anchor`, `hasOwnDocument`, and `cssClasses`. # Unreleased diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index 975fbc807..65917c4dc 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -291,13 +291,6 @@ export abstract class Reflection { */ hasOwnDocument?: boolean; - /** - * A list of generated css classes that should be applied to representations of this - * reflection in the generated markup. - * TODO: Reflections shouldn't know about CSS. Move this property to the correct serializer. - */ - cssClasses?: string; - /** * Url safe alias for this reflection. * diff --git a/src/lib/output/plugins/JavascriptIndexPlugin.ts b/src/lib/output/plugins/JavascriptIndexPlugin.ts index fd5a648f4..427ae3d2f 100644 --- a/src/lib/output/plugins/JavascriptIndexPlugin.ts +++ b/src/lib/output/plugins/JavascriptIndexPlugin.ts @@ -105,7 +105,9 @@ export class JavascriptIndexPlugin extends RendererComponent { kind: reflection.kind, name: reflection.name, url: reflection.url, - classes: reflection.cssClasses, + classes: this.owner.theme + .getRenderContext() + .getReflectionClasses(reflection), }; if (parent) { diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index 6e51ef24a..bd4ad1443 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -9,7 +9,7 @@ import { SignatureReflection, } from "../../../models"; import { RenderTemplate, UrlMapping } from "../../models/UrlMapping"; -import { PageEvent, RendererEvent } from "../../events"; +import type { PageEvent } from "../../events"; import type { MarkedPlugin } from "../../plugins"; import { DefaultThemeRenderContext } from "./DefaultThemeRenderContext"; import { JSX } from "../../../utils"; @@ -45,7 +45,7 @@ export class DefaultTheme extends Theme { markedPlugin: MarkedPlugin; private _renderContext?: DefaultThemeRenderContext; - getRenderContext(_pageEvent: PageEvent) { + getRenderContext() { if (!this._renderContext) { this._renderContext = new DefaultThemeRenderContext(this, this.application.options); } @@ -53,13 +53,13 @@ export class DefaultTheme extends Theme { } reflectionTemplate = (pageEvent: PageEvent) => { - return this.getRenderContext(pageEvent).reflectionTemplate(pageEvent); + return this.getRenderContext().reflectionTemplate(pageEvent); }; indexTemplate = (pageEvent: PageEvent) => { - return this.getRenderContext(pageEvent).indexTemplate(pageEvent); + return this.getRenderContext().indexTemplate(pageEvent); }; defaultLayoutTemplate = (pageEvent: PageEvent) => { - return this.getRenderContext(pageEvent).defaultLayout(pageEvent); + return this.getRenderContext().defaultLayout(pageEvent); }; /** @@ -114,7 +114,6 @@ export class DefaultTheme extends Theme { constructor(renderer: Renderer) { super(renderer); this.markedPlugin = renderer.getComponent("marked") as MarkedPlugin; - this.listenTo(renderer, RendererEvent.BEGIN, this.onRendererBegin, 1024); } /** @@ -145,20 +144,6 @@ export class DefaultTheme extends Theme { return urls; } - /** - * Triggered before the renderer starts rendering a project. - * - * @param event An event object describing the current render operation. - */ - private onRendererBegin(event: RendererEvent) { - const filters = this.application.options.getValue("visibilityFilters") as Record; - for (const reflection of Object.values(event.project.reflections)) { - if (reflection instanceof DeclarationReflection) { - DefaultTheme.applyReflectionClasses(reflection, filters); - } - } - } - /** * Return a url for the given reflection. * @@ -249,65 +234,6 @@ export class DefaultTheme extends Theme { return true; }); } - - /** - * Generate the css classes for the given reflection and apply them to the - * {@link DeclarationReflection.cssClasses} property. - * - * @param reflection The reflection whose cssClasses property should be generated. - */ - static applyReflectionClasses(reflection: DeclarationReflection, filters: Record) { - const classes: string[] = []; - - classes.push(DefaultTheme.toStyleClass("tsd-kind-" + ReflectionKind[reflection.kind])); - - if (reflection.parent && reflection.parent instanceof DeclarationReflection) { - classes.push(DefaultTheme.toStyleClass(`tsd-parent-kind-${ReflectionKind[reflection.parent.kind]}`)); - } - - // Filter classes should match up with the settings function in - // partials/navigation.tsx. - for (const key of Object.keys(filters)) { - if (key === "inherited") { - if (reflection.inheritedFrom) { - classes.push("tsd-is-inherited"); - } - } else if (key === "protected") { - if (reflection.flags.isProtected) { - classes.push("tsd-is-protected"); - } - } else if (key === "private") { - if (reflection.flags.isPrivate) { - classes.push("tsd-is-private"); - } - } else if (key === "external") { - if (reflection.flags.isExternal) { - classes.push("tsd-is-external"); - } - } else if (key.startsWith("@")) { - if (key === "@deprecated") { - if (reflection.isDeprecated()) { - classes.push(DefaultTheme.toStyleClass(`tsd-is-${key.substring(1)}`)); - } - } else if ( - reflection.comment?.hasModifier(key as `@${string}`) || - reflection.comment?.getTag(key as `@${string}`) - ) { - classes.push(DefaultTheme.toStyleClass(`tsd-is-${key.substring(1)}`)); - } - } - } - - reflection.cssClasses = classes.join(" "); - } - - /** - * Transform a space separated string into a string suitable to be used as a - * css class, e.g. "constructor method" > "constructor-method". - */ - static toStyleClass(str: string) { - return str.replace(/(\w)([A-Z])/g, (_m, m1, m2) => m1 + "-" + m2).toLowerCase(); - } } function hasReadme(readme: string) { diff --git a/src/lib/output/themes/default/DefaultThemeRenderContext.ts b/src/lib/output/themes/default/DefaultThemeRenderContext.ts index 4cc19dbd8..69c3f0a64 100644 --- a/src/lib/output/themes/default/DefaultThemeRenderContext.ts +++ b/src/lib/output/themes/default/DefaultThemeRenderContext.ts @@ -1,5 +1,10 @@ import type { RendererHooks } from "../.."; -import type { ReferenceType, Reflection } from "../../../models"; +import { + DeclarationReflection, + ReferenceType, + Reflection, + ReflectionKind, +} from "../../../models"; import type { Options } from "../../../utils"; import type { DefaultTheme } from "./DefaultTheme"; import { defaultLayout } from "./layouts/default"; @@ -66,6 +71,14 @@ export class DefaultThemeRenderContext { return this.theme.owner.attemptExternalResolution(type); }; + getReflectionClasses = (reflection: DeclarationReflection) => { + const filters = this.options.getValue("visibilityFilters") as Record< + string, + boolean + >; + return getReflectionClasses(reflection, filters); + }; + reflectionTemplate = bind(reflectionTemplate, this); indexTemplate = bind(indexTemplate, this); defaultLayout = bind(defaultLayout, this); @@ -97,3 +110,64 @@ export class DefaultThemeRenderContext { typeAndParent = bind(typeAndParent, this); typeParameters = bind(typeParameters, this); } + +function getReflectionClasses( + reflection: DeclarationReflection, + filters: Record +) { + const classes: string[] = []; + + classes.push(toStyleClass("tsd-kind-" + ReflectionKind[reflection.kind])); + + if ( + reflection.parent && + reflection.parent instanceof DeclarationReflection + ) { + classes.push( + toStyleClass( + `tsd-parent-kind-${ReflectionKind[reflection.parent.kind]}` + ) + ); + } + + // Filter classes should match up with the settings function in + // partials/navigation.tsx. + for (const key of Object.keys(filters)) { + if (key === "inherited") { + if (reflection.inheritedFrom) { + classes.push("tsd-is-inherited"); + } + } else if (key === "protected") { + if (reflection.flags.isProtected) { + classes.push("tsd-is-protected"); + } + } else if (key === "private") { + if (reflection.flags.isPrivate) { + classes.push("tsd-is-private"); + } + } else if (key === "external") { + if (reflection.flags.isExternal) { + classes.push("tsd-is-external"); + } + } else if (key.startsWith("@")) { + if (key === "@deprecated") { + if (reflection.isDeprecated()) { + classes.push(toStyleClass(`tsd-is-${key.substring(1)}`)); + } + } else if ( + reflection.comment?.hasModifier(key as `@${string}`) || + reflection.comment?.getTag(key as `@${string}`) + ) { + classes.push(toStyleClass(`tsd-is-${key.substring(1)}`)); + } + } + } + + return classes.join(" "); +} + +function toStyleClass(str: string) { + return str + .replace(/(\w)([A-Z])/g, (_m, m1, m2) => m1 + "-" + m2) + .toLowerCase(); +} diff --git a/src/lib/output/themes/default/partials/index.tsx b/src/lib/output/themes/default/partials/index.tsx index 26e629d4d..6c918e6da 100644 --- a/src/lib/output/themes/default/partials/index.tsx +++ b/src/lib/output/themes/default/partials/index.tsx @@ -3,7 +3,11 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; import { JSX, Raw } from "../../../../utils"; import { ContainerReflection, DeclarationReflection, ReflectionCategory, ReflectionKind } from "../../../../models"; -function renderCategory({ urlTo, icons }: DefaultThemeRenderContext, item: ReflectionCategory, prependName = "") { +function renderCategory( + { urlTo, icons, getReflectionClasses }: DefaultThemeRenderContext, + item: ReflectionCategory, + prependName = "" +) { return (

{prependName ? `${prependName} - ${item.title}` : item.title}

@@ -14,7 +18,7 @@ function renderCategory({ urlTo, icons }: DefaultThemeRenderContext, item: Refle href={urlTo(item)} class={classNames( { "tsd-index-link": true, deprecated: item.isDeprecated() }, - item.cssClasses + getReflectionClasses(item) )} > {icons[item.kind]()} diff --git a/src/lib/output/themes/default/partials/member.getterSetter.tsx b/src/lib/output/themes/default/partials/member.getterSetter.tsx index 48f93d9e9..e1305b61e 100644 --- a/src/lib/output/themes/default/partials/member.getterSetter.tsx +++ b/src/lib/output/themes/default/partials/member.getterSetter.tsx @@ -1,10 +1,18 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; import type { DeclarationReflection } from "../../../../models"; +import { JSX } from "../../../../utils"; +import { classNames } from "../../lib"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; export const memberGetterSetter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <> -