SOURCE / PINNED RELEASE
Made of little things.
Black Site Map Editor
- Release
- 32a57733b7e9…
- Author-recorded commit
- 3f54890f542f…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.shakespeare.diy%2F/black-site-map-editor
Archive hash verified: 7a4b1abbac7db5b0…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import ts from 'typescript';
const load = async (file, replacements = []) => {
let js = ts.transpileModule(
await readFile(new URL(`../src/${file}`, import.meta.url), 'utf8'),
{ compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext } },
).outputText;
for (const [from, to] of replacements) {
assert.ok(js.includes(from), `${file}: missing ${from}`);
js = js.replace(from, to);
}
return import(`data:text/javascript,${encodeURIComponent(`${js}\n// ${Math.random()}`)}`);
};
const combo = await load('key-combo.ts');
const key = (value, mods = {}) => ({
key: value,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
...mods,
});
test('matches built-in combos in the NAP-KEYS shim format', () => {
const { matchesCombo } = combo;
assert.ok(matchesCombo('Ctrl+Z', key('z', { ctrlKey: true })));
assert.ok(matchesCombo('Ctrl+Z', key('z', { metaKey: true })), 'Cmd stands in for Ctrl');
assert.ok(!matchesCombo('Ctrl+Z', key('z', { ctrlKey: true, shiftKey: true })));
assert.ok(matchesCombo('Ctrl+Shift+Z', key('Z', { ctrlKey: true, shiftKey: true })));
assert.ok(matchesCombo('W', key('w')) && !matchesCombo('W', key('w', { ctrlKey: true })));
assert.ok(
matchesCombo('Shift+?', key('?', { shiftKey: true })) && matchesCombo('Shift+?', key('?')),
'shifted symbols ignore layout Shift',
);
assert.ok(
matchesCombo('+', key('+', { shiftKey: true })) &&
matchesCombo('Ctrl+,', key(',', { ctrlKey: true })),
);
assert.ok(
matchesCombo('Shift+ArrowUp', key('ArrowUp', { shiftKey: true })) &&
!matchesCombo('ArrowUp', key('ArrowUp', { shiftKey: true })),
);
assert.ok(matchesCombo('Delete', key('Delete')) && !matchesCombo('Bogus+X', key('x')));
});
test('formats bindings for people and assistive technology', () => {
assert.equal(combo.formatCombo('Ctrl+Shift+z'), 'Ctrl+Shift+Z');
assert.equal(combo.formatCombo('Shift+?'), '?');
assert.equal(combo.formatCombo('Shift+ArrowLeft'), 'Shift+←');
assert.equal(combo.ariaCombo('Ctrl+Enter'), 'Control+Enter');
assert.equal(combo.ariaCombo('Delete'), 'Delete');
});
test('typing targets keep their keystrokes', () => {
const { isTypingTarget } = combo;
assert.ok(isTypingTarget({ tagName: 'INPUT', type: 'number' }));
assert.ok(
isTypingTarget({ tagName: 'TEXTAREA' }) &&
isTypingTarget({ tagName: 'DIV', isContentEditable: true }),
);
assert.ok(
!isTypingTarget({ tagName: 'INPUT', type: 'checkbox' }) &&
!isTypingTarget({ tagName: 'BUTTON' }) &&
!isTypingTarget(null),
);
});
function fakeDocument() {
const listeners = new Set();
return {
listeners,
addEventListener: (_type, fn) => listeners.add(fn),
removeEventListener: (_type, fn) => listeners.delete(fn),
press(event) {
const e = {
defaultPrevented: false,
isComposing: false,
target: { tagName: 'CANVAS' },
preventDefault() {
this.defaultPrevented = true;
},
...key(event.key, event),
...event,
};
for (const fn of listeners) fn(e);
return e;
},
};
}
async function loadShortcuts(fixture) {
globalThis.__keysFixture = fixture;
return load('shortcuts.ts', [
["import { keys } from '@napplet/sdk';", 'const {keys}=globalThis.__keysFixture;'],
[
"import { runtimeHasDomain } from './domain-availability.js';",
'const runtimeHasDomain=globalThis.__keysFixture.hasDomain;',
],
[
"import { isTypingTarget, matchesCombo } from './key-combo';",
`const {isTypingTarget,matchesCombo}=globalThis.__keysFixture.combo;`,
],
]);
}
test('without the keys domain built-in keys drive actions locally', async () => {
const document = (globalThis.document = fakeDocument());
const { installShortcuts } = await loadShortcuts({ combo, hasDomain: () => false, keys: {} });
let undo = 0;
const shortcuts = installShortcuts(
[
{
id: 'edit.undo',
label: 'Undo',
group: 'Edit',
defaultKey: 'Ctrl+Z',
run: () => undo++,
},
],
() => {},
);
assert.equal(shortcuts.get('edit.undo').source, 'default');
assert.ok(document.press({ key: 'z', ctrlKey: true }).defaultPrevented);
document.press({ key: 'z', ctrlKey: true, target: { tagName: 'INPUT', type: 'text' } });
document.press({ key: 'z', ctrlKey: true, defaultPrevented: true });
assert.equal(undo, 1, 'text fields and shim-handled keys are skipped');
shortcuts.close();
assert.equal(document.listeners.size, 0);
});
test('host bindings replace built-in keys; unbound or failed registrations keep them', async () => {
const document = (globalThis.document = fakeDocument());
const handlers = new Map(),
closed = [];
const keys = {
register: async (action, handler) => {
if (action.id === 'map.fail') throw new Error('duplicate action ID');
handlers.set(action.id, handler);
return {
actionId: action.id,
binding: action.id === 'edit.undo' ? 'Alt+U' : undefined,
close: () => closed.push(action.id),
};
},
};
const { installShortcuts } = await loadShortcuts({
combo,
hasDomain: (domain) => domain === 'keys',
keys,
});
const runs = [];
let changes = 0;
const actions = ['edit.undo', 'view.grid', 'map.fail'].map((id, index) => ({
id,
label: id,
group: 'G',
defaultKey: ['Ctrl+Z', 'G', 'Ctrl+S'][index],
run: () => runs.push(id),
}));
const shortcuts = installShortcuts(actions, () => changes++);
assert.ok(shortcuts.states().every((state) => state.source === 'pending'));
document.press({ key: 'g' });
assert.deepEqual(runs, [], 'nothing fires while registration is pending');
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(changes, 3);
assert.deepEqual(
shortcuts.states().map((state) => [state.action.id, state.source, state.binding]),
[
['edit.undo', 'host', 'Alt+U'],
['view.grid', 'default', 'G'],
['map.fail', 'default', 'Ctrl+S'],
],
);
document.press({ key: 'z', ctrlKey: true });
document.press({ key: 'g' });
document.press({ key: 's', ctrlKey: true });
handlers.get('edit.undo')();
assert.deepEqual(
runs,
['view.grid', 'map.fail', 'edit.undo'],
'host-bound undo only runs when the host delivers it',
);
shortcuts.close();
assert.deepEqual(closed.sort(), ['edit.undo', 'view.grid']);
handlers.get('edit.undo')();
assert.equal(runs.length, 3, 'closed shortcuts ignore late host actions');
});
