[Bug] Code block keeps the previous language's highlighting after the language is cleared or set to an unknown one · Issue #5515 · marktext/marktext · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Code block keeps the previous language's highlighting after the language is cleared or set to an unknown one #5515
Clearing a code block's language, or changing it to one Prism does not know, leaves the block rendered with the previous language's syntax highlighting. The markdown is written correctly — only what you see is stale, until the block is re-rendered for some other reason (typing in it, reopening the document).
Steps to Reproduce
Create a fenced code block with a known language and some code that highlights, e.g.
```js
const x = 1
```
Click into the language input (the js at the top of the block).
Select it and delete it, so the language is empty.
Expected Behavior
The code block drops the JavaScript highlighting and renders as plain text.
Actual Behavior
const stays keyword-coloured, 1 stays number-coloured — the block keeps rendering as JavaScript. The markdown correctly becomes ``` with no language.
The same happens when the language is replaced with an unknown one (notalanguage): the block keeps the old highlighting even though the fence now says notalanguage.
Changing to another known language (js → python) re-renders correctly, so only these two cases are affected.
Root cause
CodeBlock's lang setter (packages/muya/src/block/commonMark/codeBlock/index.ts) only re-renders when Prism reports the grammar was loaded or already cached:
constlanguage=firstWordOfInfo(value)!!language&&loadLanguage(language).then((infoList)=>{constneedRender=infoList.some(({ status })=>status==='loaded'||status==='cached',)if(needRender)this.lastContentInDescendant()?.update()})
An empty language short-circuits on !!language, so update() is never reached.
An unknown language resolves with status: 'noexist', so needRender is false.
In both cases the DOM is left holding the markup the previous grammar produced. Both are exactly the cases where a re-render is required, because the block has to fall back to plain text.
Measured
Driving the real _updateLanguage path (what the language input calls on every keystroke) against a js block containing const x = 1, counting Prism token spans:
language change
markdown
token spans
js (initial)
```js
3
→ cleared
``` ✅
3 — still JavaScript ❌
→ notalanguage
```notalanguage ✅
3 — still JavaScript ❌
→ python
```python ✅
2 ✅
Environment
Reproduces on current develop. Display-only — no data loss.
Activity
fix(muya): re-render a code block when the grammar it renders with ch…
test(muya): cover the code block's re-render on a language change (#5515
fix(muya): re-render a code block when the grammar it renders with ch…