From 00859777a189a19eb301db2bc018b7b4d000589d Mon Sep 17 00:00:00 2001 From: xrmb Date: Sat, 4 Jul 2026 23:55:28 -0400 Subject: [PATCH 1/2] Remove duplicate shAll/initCollapse onload calls window.onload invoked shAll() and initCollapse() twice. This produced a second Show more button / fade overlay on every collapsible code block and blockquote, and the second syntax-highlighting pass corrupted the DOM and exposed internal CSS class names as visible text. --- mdview.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mdview.c b/mdview.c index 23f6a9a..6316b4b 100644 --- a/mdview.c +++ b/mdview.c @@ -1491,7 +1491,6 @@ static void build_js(StrBuf* sb) { /* Init */ "window.onload=function(){" "shAll();initCollapse();" - "shAll();initCollapse();" "if(ln)tl();" /* apply line numbers if saved */ "up()};" ""); From 2dd30a2d8c6fc8f390cd2f2cd043f2a2222cbdd4 Mon Sep 17 00:00:00 2001 From: xrmb Date: Sun, 5 Jul 2026 00:52:19 -0400 Subject: [PATCH 2/2] Prevent syntax highlighting from corrupting its own span tags The regex-based highlighter was matching keywords, numbers, and attribute names inside the tags it had just created, producing visible fragments like class="sh-cm"> in the rendered code block. Split each replacement so it only applies to text outside existing HTML tags. --- mdview.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mdview.c b/mdview.c index 6316b4b..55af27a 100644 --- a/mdview.c +++ b/mdview.c @@ -1421,12 +1421,12 @@ static void build_js(StrBuf* sb) { "h=h.replace(/(`(?:[^`\\\\]|\\\\.)*?`)/g,'$1');" /* Numbers */ - "h=h.replace(/\\b(\\d+\\.?\\d*(?:e[+-]?\\d+)?|0x[0-9a-fA-F]+)\\b/g,'$1');" + "h=h.replace(/(<[^>]+>)|([^<]+)/g,function(m,tag,text){return tag?tag:text.replace(/\\b(\\d+\\.?\\d*(?:e[+-]?\\d+)?|0x[0-9a-fA-F]+)\\b/g,'$1');});" /* HTML/XML tags */ "if(lang==='html'||lang==='xml'){" "h=h.replace(/(<\\/?)([a-zA-Z][a-zA-Z0-9]*)/g,'$1$2');" - "h=h.replace(/\\s([a-zA-Z-]+)(=)/g,' $1$2');" + "h=h.replace(/(<[^>]+>)|([^<]+)/g,function(m,tag,text){return tag?tag:text.replace(/\\s([a-zA-Z-]+)(=)/g,' $1$2');});" "}else{" /* Keywords per language family */ @@ -1445,10 +1445,10 @@ static void build_js(StrBuf* sb) { "kws='\\\\b(color|background|margin|padding|border|font|display|position|width|height|top|left|right|bottom|flex|grid|none|block|inline|relative|absolute|fixed|inherit|auto|important|solid|transparent)\\\\b';" "else if(lang==='php')" "kws='\\\\b(function|return|if|else|elseif|for|foreach|while|do|switch|case|break|continue|class|public|private|protected|static|new|echo|print|null|true|false|array|isset|empty|unset|require|include|use|namespace|try|catch|finally|throw|var)\\\\b';" - "if(kws){var re=new RegExp(kws,'g');h=h.replace(re,'$1');}" + "if(kws){var re=new RegExp(kws,'g');h=h.replace(/(<[^>]+>)|([^<]+)/g,function(m,tag,text){return tag?tag:text.replace(re,'$1');});}" /* Function calls: word followed by ( */ - "h=h.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\(/g,'$1(');" + "h=h.replace(/(<[^>]+>)|([^<]+)/g,function(m,tag,text){return tag?tag:text.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\(/g,'$1(');});" "}" "el.innerHTML=h;}}"