Automatically re-rendering when inline markdown changes
See original GitHub issueHey there!
This is a feature request to add automatic partial re-rendering when the inline markdown changes.
Below is a basic and slightly naive proof of concept in the form of an extension to ZeroMd
, just to provide some working code.
Here’s the gist of it:
- Using a MutationObserver to detect changes in the inline markdown’s
<script>
; - When a change occurs, re-render only the markdown body
- Why not use the existing
render()
? Because it clears the element’s DOM and rebuilds the CSS, which causes an unwanted flash between the old content and the new content.
- Why not use the existing
class ZeroMdExample extends ZeroMd {
connectedCallback()
{
super.connectedCallback();
const script = this.querySelector("script[type='text/markdown']");
if (script) {
const observer = new MutationObserver(() => this.updateFromInlineContent());
observer.observe(script, { characterData: true, attributes: true, childList: true, subtree: true });
}
}
async updateFromInlineContent (opts = {}) {
await this.waitForReady();
const md = await this.buildMd(opts);
this.shadowRoot.querySelector(".markdown-body").replaceWith(md);
}
}
There are plenty of optimizations and improvements to be made, of course, but this is a quick suggestion of how it could be handled.
If this seems like a viable way to implement the feature, or if you have any feedback, just let me know - I would gladly get to work on a PR for this.
Cheers!
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (8 by maintainers)
Top Results From Across the Web
Automatically re-render markdown when renderer settings ...
My workaround was to append the markdown with a zero-width space character, then use a setTimeout to remove it. It would be nicer,...
Read more >How to Safely Render Markdown From a React Component
Step-by-step guide on how to safely render Markdown within your React Component using react-markdown.
Read more >A Story of a React Re-Rendering Bug - Engineering Blog
We know, by default, one React component will only be re-rendered if its state gets changed, either caused by props change, or triggered...
Read more >A (Mostly) Complete Guide to React Rendering Behavior
In normal rendering, React does not care whether "props changed" - it will render child components unconditionally just because the parent ...
Read more >17.3 Render R Markdown with rmarkdown::render() - Bookdown
This means you can programmatically render an R Markdown document in any R script. For example, you could render a series of reports...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hi @EmilePerron, thanks so much for reaching out - I think it’s a great feature and I’d love a PR! 😁
On first pass, this may not be a trivial feature to implement. Some thoughts come to mind:
Probably both
<script>
and style<template>
tags should be observed for changes.I guess mutation callbacks must be debounced so multiple calls will only trigger a re-render once. (I didn’t read in detail on
MutationObserver
specs though, maybe it’s native?)Perhaps the
render()
function can be re-factored to support conditional DOM stamping (or re-building)? Something like ifrender()
is called twice in a row, checks are added so that the second call shouldn’t actually re-stamp i.e.render()
will only render changes.There are probably other optimisations and gotchas too, so let’s keep this thread open for discussion! Also do let me know if there’s anything I can help with. Thanks so much for you time once again. 👍
Hi @EmilePerron
My apologies for the wait. I (finally) reviewed PR #51 and it generally looks very good.
Thanks for adding the tests. They look very good!
I still feel there’s an opportunity to refactor the
render()
method to render changes instead, which removes the need forrefreshStyle()
andrefreshContent()
- and IMO simplifies the codebase as well.Thanks for the recommendation. I’ll document this API change.
Good catch!
Coverage seems OK so far; we can add as and when bug reports surface. 😄
Thanks for doing this! I don’t personally have big opinions on this - as long as it passes
standardjs
linting it’s an OK.I’ll probably merge this upstream in a bit - I’ll also see if there’re opportunities to simplify, if not today then soon. Thanks so much!