Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API for plugins to add scripts and styles to pages #1773

Closed
RunDevelopment opened this issue Oct 30, 2021 · 5 comments
Closed

Add API for plugins to add scripts and styles to pages #1773

RunDevelopment opened this issue Oct 30, 2021 · 5 comments
Labels
enhancement Improved functionality

Comments

@RunDevelopment
Copy link
Contributor

Search Terms

API. plugins

Problem

The plugin typedoc-plugin-mermaid has to insert some JavaScript (and soon CSS) to do its bidding. Right now, this is done via very brittle string operations to avoid the performance impact (and complexity) of having to parse every page. Obviously, this is not ideal.

TypeDoc should support an API for plugins to add JS and CSS (both external and inline) to pages.

Suggested Solution

defaultLayout could easily insert Plugin scripts and styles. My suggestion is to extend PageEvent like this:

type JS = { inline: string } | { url: string, async?: boolean };
type CSS = { inline: string } | { url: string };

export class PageEvent<Model = unknown> extends Event {
    // ... 

    /**
     * Should be inserted by layout templates and can be modified by plugins.
     *
     * This array is only defined during the `PageEvent.BEGIN` event.
     */
    scripts?: JS[];
    /**
     * Should be inserted by layout templates and can be modified by plugins.
     *
     * This array is only defined during the `PageEvent.BEGIN` event.
     */
    styles?: CSS[];
}

RenderEvent could also be extended. This would allow TypeDoc (or themes?) to do some clever optimizations like appending all inline CSS/JS to main.js and style.css instead of adding a bunch of <script> and <style> tags to each page.

That being said, there are still some details that have to be figured out.

The biggest one is ordering. The order of styles and (non-async) scripts is important. Should TypeDoc be allowed to order scripts and styles in any way it wants? Ignoring script/style order would allow more optimizations but might make it harder for others to implement plugins.

@RunDevelopment RunDevelopment added the enhancement Improved functionality label Oct 30, 2021
@Gerrit0
Copy link
Collaborator

Gerrit0 commented Nov 1, 2021

I do want to make it possible for people to do this - but I don't think this is the way it should work. Plugins won't just want to add JS and CSS. A plugin might also want to add a new button to the navigation, extra text to the header... etc.

The way I was originally planning on doing this was with "hooks"... which React kinda stole my term for... haven't come up with a better one. Hooks were going to be event handlers which returned a value, so a plugin could do something like this:

app.renderer.hooks.on("head.end", () => (
    <style dangerouslySetInnerHTML={{ __html: myStyle }} />
));

Custom themes could define their own hooks, in addition to the ones provided by the default theme, or a custom theme might literally be the default theme, with some hooks added during construction to inject just a bit of HTML.

I actually implemented this more than a year ago when attempting a full rewrite (that of course didn't go well)... but it never made it to master.

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Nov 1, 2021

I should also mention - Ordering didn't seem terribly important to me at the time. I added support for it in that implementation, but most of my use cases ended up not caring.

@RunDevelopment
Copy link
Contributor Author

Looks interesting. A lot more general than my very narrow solution. Are there plans to re-add hooks? Anything I could help with?

which React kinda stole my term for... haven't come up with a better one

Yeah, "hooks" could be confusing in combination with React but I still think it's a good name.

I added support for it in that implementation, but most of my use cases ended up not caring.

Even in that implementation, ordering is optionally set. So we could always add support for ordering later (if needed).

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Nov 6, 2021

I've been kind of waiting to add hooks for https://github.com/futurGH/typedoc to be ready, but would be fine adding a few basic ones now, just haven't done it since nobody's asked for it before this ;)

@Gerrit0 Gerrit0 closed this as completed in 8c707b3 Nov 7, 2021
@Gerrit0
Copy link
Collaborator

Gerrit0 commented Nov 7, 2021

Very minimal implementation in place for now - I'll wait and see what other locations people ask for before adding them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improved functionality
Projects
None yet
Development

No branches or pull requests

2 participants