Skip to content

Commit 0f55187

Browse files
committed
fix(diagrams): a saved SVG has no links to tab to — a link is something only the chat can open
Not from the review: found while fixing what it said about the picture and the linked nodes inside it. A linked node is a focusable `role="link"` group carrying `data-lc-link`. In the chat, a click or Enter asks the host to open the file. "Save as SVG" wrote the same attributes into the file, where nothing can answer them: opened in a browser, the picture had tab stops that announced "Open agent.js at runAgent, link" and did nothing. A standalone build — the one made for a file — now leaves the four attributes off. The node keeps what a picture can use: its file icon, and the tooltip with the path. The picture in the chat and its full-size view are unchanged. The two arch snapshots lose exactly those attributes on their two linked nodes and nothing else; the other four snapshots do not move. diagramScene walks the standalone tree for all four, and checks both nodes are still marked as files.
1 parent 51e4490 commit 0f55187

4 files changed

Lines changed: 17 additions & 4 deletions

File tree

‎extensions/levelcode-ai/diagram/scene.js‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
* @param {any} geo layout.layout(spec, …)
125125
* @param {{ title?: boolean, css?: string, measure?: (t:string, role:string)=>number, standalone?: boolean, background?: boolean }} [opts]
126126
* title: draw the spec's title inside the SVG (exports — in the chat it is HTML above the picture)
127-
* css: a stylesheet to embed (exports) standalone: add xmlns (a file, not inline SVG)
127+
* css: a stylesheet to embed (exports) standalone: a file, not inline SVG — xmlns, and no live links
128128
* background: paint the editor background behind the drawing (exports — a file has no page behind it)
129129
*/
130130
function build(spec, geo, opts) {
@@ -162,7 +162,9 @@
162162
const nodes = geo.nodes.map((n) => {
163163
const cls = 'lcd-node lcd-' + n.shape + (n.accent ? ' lcd-accent' : '') + (n.link ? ' lcd-linked' : '');
164164
const attrs = { class: cls, 'data-lc-node': n.id };
165-
if (n.link) {
165+
if (n.link && !o.standalone) {
166+
// A link is something the CHAT can open. A saved file cannot, so there the node keeps its
167+
// glyph and its tooltip and is not a link: nothing to tab to that does nothing.
166168
// The attribute carries the NODE ID, not the path: the host looks the link up in its own
167169
// copy of the spec, so nothing the webview says can choose which file is opened.
168170
attrs['data-lc-link'] = n.id; attrs.tabindex = '0'; attrs.role = 'link';

‎extensions/levelcode-ai/test/diagramScene.test.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ test('LINKS: a clickable node carries its NODE ID, never the path — the host l
157157
assert.ok(node.children.some((c) => c.attrs.class === 'lcd-link-icon'), 'and a small file glyph marks it');
158158
});
159159
assert.strictEqual(linked, 2);
160+
// A saved file has nothing to open a link WITH: the node keeps its glyph and its tooltip, and is
161+
// not a tab stop or a "link" that does nothing when it is activated.
162+
let marked = 0;
163+
walk(build(spec, { title: true, background: true, standalone: true, css: theme.css({ resolved: theme.PALETTES.light }) }), (node) => {
164+
for (const a of ['data-lc-link', 'tabindex', 'role', 'aria-label']) { if (node.tag !== 'svg') { assert.strictEqual(node.attrs[a], undefined, a + ' on <' + node.tag + '> in a file'); } }
165+
if (/\blcd-linked\b/.test(String(node.attrs.class || ''))) {
166+
marked++;
167+
assert.ok(node.children.some((c) => c.tag === 'title') && node.children.some((c) => c.attrs.class === 'lcd-link-icon'), 'still marked as a file, and still says which');
168+
}
169+
});
170+
assert.strictEqual(marked, 2);
160171
const hostile = repair.prepare(HOSTILE, { final: true }).spec;
161172
walk(build(hostile), (node) => { if (node.attrs['data-lc-link']) { assert.strictEqual(node.attrs['data-lc-link'], 'b', 'the javascript: "path" is nowhere in an attribute the host acts on'); } });
162173
});

‎extensions/levelcode-ai/test/fixtures/diagrams/snapshots/arch.dark.svg‎

Lines changed: 1 addition & 1 deletion
Loading

‎extensions/levelcode-ai/test/fixtures/diagrams/snapshots/arch.light.svg‎

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)