Page MenuHomePhorge

mouse.js
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None

mouse.js

const ESC = '\x1b';
const CSI = `${ESC}[`;
const codes = {
altScreenOn: `${CSI}?1049h`,
altScreenOff: `${CSI}?1049l`,
hideCursor: `${CSI}?25l`,
showCursor: `${CSI}?25h`,
clear: `${CSI}2J`,
home: `${CSI}H`,
reset: `${CSI}0m`,
mouseOn: `${CSI}?1000h${CSI}?1006h`,
mouseOff: `${CSI}?1000l${CSI}?1006l`
};
const state = {
x: 0,
y: 0,
button: 'none',
action: 'move',
lastEvent: ''
};
function write(text) {
process.stdout.write(text);
}
function render() {
const width = process.stdout.columns || 80;
const height = process.stdout.rows || 24;
const lines = [];
lines.push(' Simple Mouse TUI');
lines.push('');
lines.push(` Position: ${state.x}, ${state.y}`);
lines.push(` Button: ${state.button}`);
lines.push(` Action: ${state.action}`);
lines.push('');
lines.push(' Last event:');
lines.push(` ${state.lastEvent || 'none'}`);
lines.push('');
lines.push(' Move or click in the terminal. Press q or Ctrl-C to exit.');
while (lines.length < height) {
lines.push('');
}
const padded = lines.map(line => {
if (line.length >= width) return line.slice(0, width);
return line + ' '.repeat(width - line.length);
});
write(codes.home + codes.clear + padded.join('\n') + codes.reset);
}
function parseMouseEvent(seq) {
const match = seq.match(/^\x1b\[<([0-9]+);([0-9]+);([0-9]+)([mM])$/);
if (!match) return false;
const [, codeStr, xStr, yStr, action] = match;
const code = Number(codeStr);
const x = Number(xStr);
const y = Number(yStr);
const buttonCode = code & 3;
let button = 'none';
if (buttonCode === 0) button = 'left';
if (buttonCode === 1) button = 'middle';
if (buttonCode === 2) button = 'right';
let actionLabel = 'move';
if (action === 'M' && (code & 32) === 0) actionLabel = 'press';
if (action === 'm') actionLabel = 'release';
state.x = x;
state.y = y;
state.button = button;
state.action = actionLabel;
state.lastEvent = `code=${code} x=${x} y=${y} action=${action}`;
return true;
}
function handleInput(chunk) {
const str = chunk.toString();
if (str === 'q' || str === '\x03') {
cleanup();
return;
}
if (str.startsWith('\x1b[<')) {
if (parseMouseEvent(str)) {
render();
return;
}
}
}
function cleanup() {
process.stdin.setRawMode(false);
process.stdin.pause();
process.stdin.removeListener('data', handleInput);
process.stdout.removeListener('resize', render);
write(codes.mouseOff + codes.showCursor + codes.altScreenOff);
process.exit(0);
}
function start() {
if (process.stdin.isTTY) {
process.stdin.setRawMode(true);
}
process.stdin.resume();
process.stdin.on('data', handleInput);
process.stdout.on('resize', render);
write(codes.altScreenOn + codes.hideCursor + codes.mouseOn);
render();
}
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
start();

File Metadata

Mime Type
text/plain
Expires
Sun, May 3, 8:17 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
518036
Default Alt Text
mouse.js (2 KB)

Event Timeline