mProjectsCode / obsidian-meta-bind-plugin

A plugin for Obsidian to make your notes interactive with inline input fields, metadata displays, and buttons.
https://www.moritzjung.dev/obsidian-meta-bind-plugin-docs/
GNU General Public License v3.0
536 stars 43 forks source link

`MarkdownRenderer.render` cause render fail #428

Closed LincZero closed 1 month ago

LincZero commented 1 month ago

Please fill out these Check-boxes

Is your Feature Request related to a Problem or Annoyance?

No response

Describe the Feature you'd like

The effect I want

(Used with other plugins (anyblock plugin, I am the author of this plugin))

image

Actual result

The collaboration with buttons plugin was successful (See picture above), but there were some problems with metabind (see image below):

Analysis of causes

image

Anyblock Plugin use the MarkdownRenderer.render, it can renders a piece of markdown text and return element. (Note: The result of re-rendering is the result of reading mode. so in reading mode, it might be better to work with plugins)

But there may be some differences between the ctx of 'MarkdownRenderer.render' and the ctx in reading mode, which may be the reason why it doesn't work: (See the bottom of the picture)

Alternatives

No response

Additional Context

No response

LincZero commented 1 month ago

Repeat tips

when use

```anyblock

And the first line in the code block is not `[...]`

All he does is call the contents of the code block through 'MarkdownRenderer.render', and little else is done.

So you can use this feature to facilitate debugging

## test demo

`````md
````anyblock
test1
```meta-bind-button
style: primary
label: Meta Bind Help
action:
  type: command
  command: obsidian-meta-bind-plugin:open-faq

test2

INPUT[inputType]

test3 INPUT[toggle]

test4 INPUT[inputType]

test5

name Toggle spellcheck
type comand
action Toggle spellcheck
color blue

^button-spellcheck

mProjectsCode commented 1 month ago

Are you passing a loaded component to the render function?

mProjectsCode commented 1 month ago

Can you send me the errors that should appear in the console? What does it say when you click on the error message I the rendered content?

LincZero commented 1 month ago

console message

The console did not report an error or print any other information

It simplifies what I do

this.registerMarkdownCodeBlockProcessor("anyblock", ABReplacer_CodeBlock.processor);
...
export class ABReplacer_CodeBlock{
  static processor(
    src: string,
    blockEl: HTMLElement,
    ctx: MarkdownPostProcessorContext,
  ) {
    let dom_replaceEl = blockEl.createDiv({
      cls: ["ab-replaceEl"]
    })
    MarkdownRenderer.render(app, src, dom_replaceEl, app.workspace.activeLeaf?.view?.file.path, new MarkdownRenderChild(dom_replaceEl));
  }
}

This way it can be matched with the plugin

https://github.com/LincZero/obsidian-any-block/issues/74

buttons、dataview、mindmap nextgen、and many other rendering-related plugins.

LincZero commented 1 month ago

A better demo

image

mProjectsCode commented 1 month ago

Like I suspected, you are not correctly passing a component to the render function. Try something like this.

export class ABReplacer_CodeBlock{
  static processor(
    src: string,
    blockEl: HTMLElement,
    ctx: MarkdownPostProcessorContext,
  ) {
    let dom_replaceEl = blockEl.createDiv({
      cls: ["ab-replaceEl"]
    });
    const mdrc = new MarkdownRenderChild(dom_replaceEl);
    ctx.addChild(mdrc); // you must register your mdrc to the context object. Otherwise stuff won't work correctly any will leak memory
    MarkdownRenderer.render(app, src, dom_replaceEl, app.workspace.activeLeaf?.view?.file.path, mdrc);
  }
}
LincZero commented 1 month ago

Yes, you are right. When I add ctx.addChild, everything goes back to normal.

I've done this in the past, but later removed it for compatibility when migrating to markdown-it (not sure what this step does at the time T_T).

Thank you very much for your help.