import {test} from 'node:test';import assert from 'node:assert/strict'; import {routeCanvasKey,canvasKeyContext} from '../../src/lib/canvas-bindings/input-router.ts'; test('text, IME, overlays and already consumed input never execute document shortcuts',()=>{for(const flags of [{textEditing:true},{composing:true},{overlay:true},{defaultPrevented:true}]){let calls=0;const result=routeCanvasKey({key:'Backspace',...flags},{gesture:()=>{calls++;return true;},shortcut:()=>{calls++;return true;}});assert.equal(calls,0);assert.ok(['text','overlay','unclaimed'].includes(result));}}); test('gesture then tool then shortcut claim once; declining handlers fall through',()=>{for(const winner of ['gesture','tool','shortcut']){const calls=[];const handlers=Object.fromEntries(['gesture','tool','shortcut'].map(layer=>[layer,()=>{calls.push(layer);return layer===winner;}]));assert.equal(routeCanvasKey({key:'Escape'},handlers),winner);assert.deepEqual(calls,['gesture','tool','shortcut'].slice(0,['gesture','tool','shortcut'].indexOf(winner)+1));}assert.equal(routeCanvasKey({key:'x'},{}),'unclaimed');}); test('DOM input context recognizes registered overlays and native selects without browser globals',()=>{ const select={closest:selector=>selector.split(',').includes('select')?select:null}; const overlay={closest:selector=>selector.includes('[data-canvas-overlay-view]')?overlay:null}; assert.deepEqual(canvasKeyContext({target:select}),{textEditing:true,overlay:false}); assert.deepEqual(canvasKeyContext({target:overlay}),{textEditing:false,overlay:true}); assert.deepEqual(canvasKeyContext({target:null,composedPath:()=>[null,{},42]}),{textEditing:false,overlay:false}); }); test('retargeted shadow events retain their inner text owner and never reach a gesture',()=>{ const input={closest:selector=>selector.split(',').includes('textarea')?input:null},host={closest:()=>null}; const context=canvasKeyContext({target:host,composedPath:()=>[input,host]});let canceled=false; assert.equal(routeCanvasKey({key:'Escape',...context},{gesture:()=>{canceled=true;return true;}}),'text');assert.equal(canceled,false); });