Codebase list node-keypress / 324bb33
Imported Upstream version 0.2.1 Mike Gabriel 9 years ago
2 changed file(s) with 104 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
0
1 /**
2 * Module dependencies.
3 */
4
5 var EventEmitter = require('events').EventEmitter;
6
7 /**
8 * Module exports.
9 */
10
11 var exports = module.exports = keypress;
012
113 /**
214 * This module offers the internal "keypress" functionality from node-core's
315 * `readline` module, for your own programs and modules to use.
416 *
17 * The `keypress` function accepts a readable Stream instance and makes it
18 * emit "keypress" events.
19 *
520 * Usage:
621 *
7 * require('keypress')(process.stdin);
8 *
9 * process.stdin.on('keypress', function (ch, key) {
10 * console.log(ch, key);
11 * if (key.ctrl && key.name == 'c') {
12 * process.stdin.pause();
13 * }
14 * });
15 * proces.stdin.resume();
16 */
17 var exports = module.exports = keypress;
18
19 exports.enableMouse = function (stream) {
20 stream.write('\x1b' +'[?1000h')
21 }
22
23 exports.disableMouse = function (stream) {
24 stream.write('\x1b' +'[?1000l')
25 }
26
27
28 /**
29 * accepts a readable Stream instance and makes it emit "keypress" events
22 * ``` js
23 * require('keypress')(process.stdin);
24 *
25 * process.stdin.on('keypress', function (ch, key) {
26 * console.log(ch, key);
27 * if (key.ctrl && key.name == 'c') {
28 * process.stdin.pause();
29 * }
30 * });
31 * proces.stdin.resume();
32 * ```
33 *
34 * @param {Stream} stream
35 * @api public
3036 */
3137
3238 function keypress(stream) {
3339 if (isEmittingKeypress(stream)) return;
34 stream._emitKeypress = true;
40
41 var StringDecoder = require('string_decoder').StringDecoder; // lazy load
42 stream._keypressDecoder = new StringDecoder('utf8');
3543
3644 function onData(b) {
37 if (stream.listeners('keypress').length > 0) {
38 emitKey(stream, b);
45 if (listenerCount(stream, 'keypress') > 0) {
46 var r = stream._keypressDecoder.write(b);
47 if (r) emitKey(stream, r);
3948 } else {
4049 // Nobody's watching anyway
4150 stream.removeListener('data', onData);
5059 }
5160 }
5261
53 if (stream.listeners('keypress').length > 0) {
62 if (listenerCount(stream, 'keypress') > 0) {
5463 stream.on('data', onData);
5564 } else {
5665 stream.on('newListener', onNewListener);
6069 /**
6170 * Returns `true` if the stream is already emitting "keypress" events.
6271 * `false` otherwise.
72 *
73 * @param {Stream} stream readable stream
74 * @return {Boolean} `true` if the stream is emitting "keypress" events
75 * @api private
6376 */
6477
6578 function isEmittingKeypress(stream) {
66 var rtn = stream._emitKeypress;
79 var rtn = !!stream._keypressDecoder;
6780 if (!rtn) {
68 // hack: check for the v0.6.x "data" event
69 stream.listeners('data').forEach(function (l) {
81 // XXX: for older versions of node (v0.6.x, v0.8.x) we want to remove the
82 // existing "data" and "newListener" keypress events since they won't include
83 // this `keypress` module extensions (like "mousepress" events).
84 stream.listeners('data').slice(0).forEach(function(l) {
7085 if (l.name == 'onData' && /emitKey/.test(l.toString())) {
71 rtn = true;
72 stream._emitKeypress = true;
86 stream.removeListener('data', l);
7387 }
7488 });
75 }
76 if (!rtn) {
77 // hack: check for the v0.6.x "newListener" event
78 stream.listeners('newListener').forEach(function (l) {
89 stream.listeners('newListener').slice(0).forEach(function(l) {
7990 if (l.name == 'onNewListener' && /keypress/.test(l.toString())) {
80 rtn = true;
81 stream._emitKeypress = true;
91 stream.removeListener('newListener', l);
8292 }
8393 });
8494 }
8595 return rtn;
8696 }
97
98 /**
99 * Enables "mousepress" events on the *input* stream. Note that `stream` must be
100 * an *output* stream (i.e. a Writable Stream instance), usually `process.stdout`.
101 *
102 * @param {Stream} stream writable stream instance
103 * @api public
104 */
105
106 exports.enableMouse = function (stream) {
107 stream.write('\x1b[?1000h');
108 };
109
110 /**
111 * Disables "mousepress" events from being sent to the *input* stream.
112 * Note that `stream` must be an *output* stream (i.e. a Writable Stream instance),
113 * usually `process.stdout`.
114 *
115 * @param {Stream} stream writable stream instance
116 * @api public
117 */
118
119 exports.disableMouse = function (stream) {
120 stream.write('\x1b[?1000l');
121 };
122
123 /**
124 * `EventEmitter.listenerCount()` polyfill, for backwards compat.
125 *
126 * @param {Emitter} emitter event emitter instance
127 * @param {String} event event name
128 * @return {Number} number of listeners for `event`
129 * @api public
130 */
131
132 var listenerCount = EventEmitter.listenerCount;
133 if (!listenerCount) {
134 listenerCount = function(emitter, event) {
135 return emitter.listeners(event).length;
136 };
137 }
138
139
140 ///////////////////////////////////////////////////////////////////////
141 // Below this function is code from node-core's `readline.js` module //
142 ///////////////////////////////////////////////////////////////////////
87143
88144
89145 /*
140196
141197 key.sequence = s;
142198
143 if (s === '\r' || s === '\n') {
144 // enter
199 if (s === '\r') {
200 // carriage return
201 key.name = 'return';
202
203 } else if (s === '\n') {
204 // enter, should have been called linefeed
145205 key.name = 'enter';
146206
147207 } else if (s === '\t') {
304364 return;
305365 }
306366
367 // XXX: this "mouse" parsing code is NOT part of the node-core standard
368 // `readline.js` module, and is a `keypress` module non-standard extension.
307369 if (key.code == '[M') {
308370 key.name = 'mouse';
309371 var s = key.sequence;
338400 }
339401
340402 if (key && key.name == 'mouse') {
341 stream.emit('mousepress', key)
403 stream.emit('mousepress', key);
342404 } else if (key || ch) {
343405 stream.emit('keypress', ch, key);
344406 }
00 {
11 "name": "keypress",
2 "version": "0.1.0",
2 "version": "0.2.1",
33 "description": "Make any Node ReadableStream emit \"keypress\" events",
44 "author": "Nathan Rajlich <nathan@tootallnate.net> (http://tootallnate.net)",
55 "main": "index.js",