Obsidian API - 'layout-ready' and 'layout-change' events

Hi there,

First of all, thanks for creating Obsidian and it is my favourite note-taking editor at the moment, besides VSCode. In fact, it is much better than VSCode in terms of note-taking and note-linking IMHO.

I just started to learn how to interact with the Obsidian API and would like to write a plugin to do some additional HTML rendering in the preview mode.

I registered to listen to both ‘layout-ready’ and ‘layout-change’ events,

		this.registerEvent(
			this.app.workspace.on("layout-ready", this.markupPreview.bind(this))
		);

		this.registerEvent(
			this.app.workspace.on("layout-change", this.markupPreview.bind(this))
		);

Then in markupPreview, I tried to get the DOM elements to perform some manipulations:

		var markdownLeaves = this.app.workspace.getLeavesOfType("markdown");
		for (var i = 0; i < markdownLeaves.length; i++) {

			var markdownLeave = markdownLeaves[i];
			if (markdownLeave.view && markdownLeave.view instanceof MarkdownView) {
				if (markdownLeave.view.getMode() == "preview") {
					console.log(markdownLeave.view);
					var elements = markdownLeave.view.containerEl.querySelectorAll('.markdown-preview-view div>p');
...

Pardon me for my ignorance - I am a newbie with TypeScript and Obsidian API. In my case, I found that I can find the DOM elements under ‘layout-change’ event but empty under ‘layout-ready’. However, I can see the views under these two events contains the HTML code that I am after, but somehow I cannot query them (empty) under ‘layout-ready’ event.

Any help would be much appreciated! Thanks.

I found an alternate solution is to use a custom MarkdownPostProcessor but I am interested to know why ‘layout-ready’ did not work above. Thanks :pray:t3:

It may be because the layout-ready event only fires once, when obsidian starts. Generally, you need to check workspace.layoutReady and only register for the event if it’s false. If the layout is already ready, registering for the event won’t do much.

It’s not really clear to me why you’re registering for that in the first place, though; the layout ready event just means that the loading progress indicator has finished and the app has been displayed. (I haven’t used it at all myself yet, so I’m not really clear on that event’s use cases, aside from e.g. adding things to ribbons or menus.)

Thanks @pjeby. I will try your suggestion about checking the flag workspace.layoutReady. My use case is mostly to do with layout-change (i.e. doing some additional HTML markup in the preview mode), but I found that if the markdown preview is displayed when I open the workspace, then it is not invoking my plugin, thus I may need to register my custom processing in the ‘layout-ready’ event.

Thanks again for your suggestion :pray:t3: