Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4500067
mouse.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
mouse.js
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Sun, May 3, 8:15 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
518036
Default Alt Text
mouse.js (2 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment