Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Encapsulate visualization - #196

Open
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization
Open

Encapsulate visualization#196
simonroeschhso wants to merge 10 commits into
skogsbaer:masterfrom
simonroeschhso:encapsulate-visualization

Conversation

@simonroeschhso

Copy link
Copy Markdown

No description provided.

@skogsbaer
skogsbaer self-requested a review March 20, 2026 10:25

@skogsbaerskogsbaer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good work, it's much better now. I asked Claude Code for more improvements and there are indeed some thing we should make better. Below are Claude's suggestions, I copied them verbatim.

Some comments by myself (Stefan)

  • the intent of most files become much clearer, if there is a short comment at the top of the file explaining the purpose of the file
  • the README is good, but it's a bit to low-level (e.g. mentioning exact line numbers which are obsolete anyway after the next edit). You should describe the architecture on a higher-level. Maybe showing a simple mermaid diagram. Claude Code can help there too.

Frontend Refactoring Suggestions by Claude Code

1. Eliminate the navigation round-trip

Current behaviour: Clicking a navigation button (prev/next/first/last) or moving the slider round-trips through the extension host:

webview click → CustomEvent → adapter → vscode.postMessage({onClick})
→ visualization_panel.ts: updateTraceIndex() + postReset()
→ postMessage({reset, trace: [...all elements...], index})
→ adapter → CustomEvent → webview: traceIndex = msg.index; renderCurrent()

The webview already holds the full trace array and already does local navigation in the if (!isVscode) block for standalone-browser mode. VS Code mode should work the same way.

Fix: Remove the if (!isVscode) guard. Navigation always runs locally in the webview. After updating traceIndex and rendering, send a single lightweight message back for line highlighting only:

// webview.tsfunctionnavigate(type: "first"|"prev"|"next"|"last"){constmax=Math.max(0,trace.length-1);switch(type){case"first": traceIndex=0;break;case"prev": traceIndex=Math.max(0,traceIndex-1);break;case"next": traceIndex=Math.min(max,traceIndex+1);break;case"last": traceIndex=max;break;}renderCurrent();if(isVscode&&trace.length>0){vscode.postMessage({command: "highlight",filePath: trace[traceIndex].filePath,line: trace[traceIndex].line});}}

visualization_panel.ts drops _traceIndex, onClick, onSlide, and updateTraceIndex. It only needs to handle the new "highlight" message and call updateLineHighlight().

postReset() is then only called on: initial load, panel refocus (onDidChangeViewState), and after the trace is fully cached.


2. Stop sending the full trace array on every navigation step

postReset() serializes and transmits the entire accumulated trace array every time the user navigates. For programs with many trace steps this is significant unnecessary IPC overhead.

This is fixed as a direct consequence of suggestion 1 — once navigation is local, postReset() is no longer called on each step. The "reset" message is only ever sent with the full trace on initial load or after trace completion, which is appropriate.


3. Remove dead message types

"updateButtons" and "updateContent" are handled in both vscode-host-adapter.ts and webview.ts but are never posted from visualization_panel.ts. They are dead code.

Fix: Delete the corresponding case blocks in vscode-host-adapter.ts and the two window.addEventListener("programflow:updateButtons", ...) / window.addEventListener("programflow:updateContent", ...) handlers in webview.ts.


4. Simplify the adapter's outgoing direction

After suggestion 1, navigation events no longer need to leave the webview. The programflow:onClick and programflow:onSlide outgoing listeners in vscode-host-adapter.ts become dead code and can be removed.

The adapter's responsibilities shrink to a clear, minimal contract:

  • Incoming (extension → webview): translate window.message events for "reset" and "append" into CustomEvents
  • Outgoing (webview → extension): forward "select" and "highlight" via vscode.postMessage

The standalone-browser use case is fully preserved: acquireVsCodeApi is still mocked, the adapter still loads first, and webview code remains decoupled from the VS Code API.

added comments at the top of files
reworked readme
removed dead code
got rid of communication roundtrip -> only highlight message
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonroeschhso@skogsbaer