From 83c6357c8151e9add8112dbd6d4d7c84cc8bdadf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 28 Aug 2026 20:15:34 +0000 Subject: [PATCH 1/3] Add zoom-out color blocks on Graph and Code canvases When zoom drops below 0.4, Graph nodes swap circle/label chrome for folder-tinted rectangles, and Code cards overlay function/import sections. Past 0.22 the card source hides so only the chunks remain. Hover still names the section. Mini-map and the root-file gate stay out of this change. Co-authored-by: Braedon Saunders --- index.html | 155 ++++++++++++++++++++++++++++++++++--- tests/code-canvas.test.mjs | 98 +++++++++++++++++++++++ 2 files changed, 243 insertions(+), 10 deletions(-) diff --git a/index.html b/index.html index 244c3a5..47f55a8 100644 --- a/index.html +++ b/index.html @@ -514,9 +514,17 @@ .code-card-resize-se{right:-3px;bottom:-3px;width:14px;height:14px;cursor:nwse-resize} .code-card.code-far .code-card-body{overflow:hidden} .code-card.code-far .file-preview-linenum{display:none} -.code-card.code-far .file-preview-line{min-height:3px;height:3px;overflow:hidden} -.code-card.code-far .file-preview-text{font-size:3px;line-height:3px;letter-spacing:-0.5px} +.code-card.code-far .file-preview-text{visibility:hidden} .code-card.code-far .code-line-pill{display:none} +.code-card-source{position:relative;min-height:100%} +.code-color-blocks{display:none;position:absolute;inset:0;pointer-events:none;z-index:1} +.code-card.code-blocks .code-color-blocks{display:block} +.code-color-block{position:absolute;left:8px;right:8px;border-radius:3px;min-height:4px;pointer-events:auto;cursor:default} +.code-card.code-blocks:not(.code-far) .code-color-block{opacity:0.38} +.code-card.code-far .code-color-block{opacity:0.88} +.code-color-block:hover{outline:1px solid var(--acc);opacity:1} +svg.color-blocks circle.nc{display:none} +svg.color-blocks text.node-label{display:none} .has-code-card{display:none!important} .has-code-card .nc,.has-code-card .node-label{pointer-events:none} .sym-mark{border-radius:3px;padding:0 1px;cursor:pointer} @@ -5847,6 +5855,34 @@ return Math.min(8,1/zoom); } +var COLOR_BLOCK_ZOOM=0.4; +var CODE_FAR_ZOOM=0.22; + +function zoomShowsColorBlocks(k){ + var zoom=Number(k); + if(!isFinite(zoom)||zoom<=0)return false; + return zoom0)return Math.max(1,lines); + var max=1; + (file&&file.functions||[]).forEach(function(fn){ + var line=Number(fn&&fn.line); + if(isFinite(line)&&line>max)max=line; + }); + return max; +} + +function codeColorBlockSections(file,connections,prefs){ + prefs=normalizeCodeCardPrefs(prefs); + var total=codeColorBlockLineCount(file); + var byLine=Object.create(null); + (file&&file.functions||[]).forEach(function(fn){ + if(!fn||!fn.name||!fn.line)return; + var kind=fn.type==='class'||fn.type==='dataclass'||fn.type==='abstract_class'?'class':(fn.isExported?'export':'fn'); + byLine[fn.line]={name:fn.name,kind:kind,startLine:fn.line}; + }); + extractFileSymbols(file,connections).forEach(function(sym){ + var line=codeCardSymbolLine(file,sym.name); + if(!line||byLine[line])return; + byLine[line]={name:sym.name,kind:sym.kind||'var',startLine:line}; + }); + var starts=Object.keys(byLine).map(Number).filter(isFinite).sort(function(a,b){return a-b;}); + var sections=[]; + if(!starts.length){ + sections.push({name:(file&&(file.name||file.path))||'file',kind:'file',startLine:1,endLine:total}); + }else{ + if(starts[0]>1){ + sections.push({name:(file&&(file.name||file.path))||'file',kind:'file',startLine:1,endLine:starts[0]-1}); + } + starts.forEach(function(start,i){ + var item=byLine[start]; + var end=i+1