Properly injecting HTML into MarkdownView preview

Hi everybody,

I’m working on a simple plugin that, upon opening a file with a certain frontmatter configuration, will inject some buttons into the preview view that will execute commands upon clicking them. I’m a little stuck on figuring out what the “proper” way to hook myself into the rendering process is and could use some help.

As of now I’ve successfully written a function that can search through the active leaves of the workspace, identify the files that I want to inject the HTML into, and do so. This works great if I attach the function to a command manually trigger it while I’m looking at a file, however I’m struggling to get this to automatically happen when I open a new file. I’ve tried adding this to my plugin’s onload function:

		this.app.workspace.on('file-open', () => {
			this.injectContent();
		});

however it appears the file-open event is unrelated to the actual markdown rendering process. My function will get called, but the injected HTML will get wiped away as the markdown view re-renders a few times before settling down.

Is there some event that I’m missing which can be attached to the MarkdownView that corresponds to “I’m finished rendering, it’s safe to modify the DOM now”? Or is there an official way to inject elements into the HTML preview in a safe way?

Thanks in advance!

Patching onRenderComplete method of MarkdownPreviewView:

import {around} from "monkey-around"

// ...

this.register(around(MarkdownPreviewView.prototype, {
	// @ts-ignore
	onRenderComplete: (next) => {
		return function(...args: any[]) {
			let self = this as any

			if(!self.injected) {
				self.injected = true

				const button = document.createElement("button");
				button.textContent = "Click Me";
				self.containerEl.prepend(button)
			}

			return next.call(this, ...args)
		}	
	}
}))

image

Heck yeah! That seems to have done the trick.

For those who are reading this thread later on, this is the NPM package that provides the around dependency. I’m a bit npm-adverse these days so I was able to include it into my janky plugin (aimed only for my own use) by copying index.ts to ./around.ts, as it’s a very small npm package anyways.

Thanks a bunch for the help @the_tree!!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.