(text via translator, so that readers’ eyes won’t be too hurt by my English writing skills)
I’m new to both JavaScript (typescript) and plugin writing. I tried to find an answer to my question in the documentation, but it’s shockingly incomplete. The gist of the question is this: I’m developing a post processor for custom code blocks that look like this:
style: positive
prop: track
1:5
HTML is re-rendered every time a property specified in the code block changes. Everything works fine as long as there is only one code block in the file. If there are two or more, only the conditionally “active” one is rendered (in live preview mode, the one with the cursor last). I suspect that the solution to the problem lies in MarkdownRenderChild, but I have absolutely no idea how to use it.
Dirty code with very bad style, in the middle of finding a solution (I would appreciate hints on what can be changed in the structure or syntax):
import { Plugin, FileManager, Workspace } from 'obsidian';
const colors = {
'positive': ['blue', 'green', 'yellow', 'orange', 'red']
}
export default class SegmentedProgressBar extends Plugin {
fileManager: FileManager;
async onload() {
this.registerMarkdownCodeBlockProcessor('seg-bar', async (source, el, ctx) => {
const file = this.app.workspace.getActiveFile();
this.element = el;
this.context = ctx;
this.row = this.element.createEl('div', { cls: 'segments-row' });
const args = source.split('\n').filter((arg) => arg.length > 0);
this.style = args[0].replace('style: ', '');
this.prop_name = args[1].replace('prop: ', '');
this.seg = args[2].split(':');
const cache = this.app.metadataCache;
if (file) {
await this.drawContent();
}
});
this.app.metadataCache.on('changed', this.handleMetadata.bind(this));
}
async processFrontMatter(file: TFile) {
const frontMatter = this.app.metadataCache.getFileCache(file)?.frontmatter
return frontMatter;
}
async drawContent() {
const stats = await this.processFrontMatter(this.app.workspace.getActiveFile());
console.log(this.element.getElementsByTagName('div'));
const row = this.element.createEl('div', { cls: 'segments-row' });
const segments = [];
let class_sig = 'segment ' + colors[this.style][stats[this.prop_name]-1];
for (let i = 1; i <= this.seg[1]; i++) {
if (i > stats[this.prop_name]) {
class_sig = 'segment empty';
}
segments.push(row.createEl('div', { cls: class_sig }));
}
for (let el of this.element.getElementsByTagName('div')) {
if (el.className == 'segments-row') {
console.log(el.className);
el.replaceWith(row);
}
}
}
handleMetadata(file: TFile) {
if (file === this.app.workspace.getActiveFile()) {
this.drawContent();
}
}
}