Add an Obsidian event for whenever a leaf changes from source mode to preview mode

Use case or problem

I am developing a plugin that needs to know when a leaf changes from source mode to preview mode.

registerMarkdownPostProcessor is not suitable for me as it is being called dozens of times. This happens because I am replacing the placeholder content (the grey rectangle) of an embedded link with a React 18 app. Whenever the React application updates, the markdown post processor will return the element has been changed.

Proposed solution

Make an event callback in the workspace that returns the markdown leaf that has had its mode changed.

		this.registerEvent(
			this.app.workspace.on("mode-change", (leaf: WorkspaceLeaf, mode: "source" | "preview") => {
			});
		);

Current workaround (optional)

Currently I am using the on("layout-change") event because it will run when a leaf changes modes. However, it also runs when a leaf is opened, a leaf is closed, etc.

		this.registerEvent(
			this.app.workspace.on("layout-change", () => {
				const leaves = this.app.workspace.getLeavesOfType("markdown");

				//Wait for the DOM to update before loading the preview mode apps
				setTimeout(() => {
					loadPreviewModeApps(leaves);
				}, 2);
			})
		);

Another issue that I am running into is that I need to use setTimeout() with a delay of 2ms because embedded markdown links aren’t fully loaded in time.

Related feature requests (optional)

1 Like

I thought I noticed this in the console, namely that Dataloom was running when I did unrelated changes in Obsidian.