Browse Source

readline: Remove event listeners on close

Fix #3756
v0.8.7-release
isaacs 13 years ago
parent
commit
e4c9c9f412
  1. 36
      lib/readline.js
  2. 9
      test/simple/test-readline-interface.js
  3. 4
      test/simple/test-readline-set-raw-mode.js

36
lib/readline.js

@ -86,12 +86,28 @@ function Interface(input, output, completer, terminal) {
this.terminal = !!terminal;
function ondata(data) {
self._normalWrite(data);
}
function onend() {
self.close();
}
function onkeypress(s, key) {
self._ttyWrite(s, key);
}
function onresize() {
self._refreshLine();
}
if (!this.terminal) {
input.on('data', function(data) {
self._normalWrite(data);
});
input.on('end', function() {
self.close();
input.on('data', ondata);
input.on('end', onend);
self.once('close', function() {
input.removeListener('data', ondata);
input.removeListener('end', onend);
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');
@ -101,9 +117,7 @@ function Interface(input, output, completer, terminal) {
exports.emitKeypressEvents(input);
// input usually refers to stdin
input.on('keypress', function(s, key) {
self._ttyWrite(s, key);
});
input.on('keypress', onkeypress);
// Current line
this.line = '';
@ -117,8 +131,10 @@ function Interface(input, output, completer, terminal) {
this.history = [];
this.historyIndex = -1;
output.on('resize', function() {
self._refreshLine();
output.on('resize', onresize);
self.once('close', function() {
input.removeListener('keypress', onkeypress);
output.removeListener('resize', onresize);
});
}
}

9
test/simple/test-readline-interface.js

@ -31,6 +31,7 @@ function FakeInput() {
}
inherits(FakeInput, EventEmitter);
FakeInput.prototype.resume = function() {};
FakeInput.prototype.pause = function() {};
var fi;
var rli;
@ -67,6 +68,7 @@ rli.on('line', function(line) {
});
fi.emit('data', 'a');
assert.ok(!called);
rli.close();
// sending a single character with no newline and then a newline
fi = new FakeInput();
@ -80,6 +82,7 @@ fi.emit('data', 'a');
assert.ok(!called);
fi.emit('data', '\n');
assert.ok(called);
rli.close();
// sending multiple newlines at once
fi = new FakeInput();
@ -92,6 +95,7 @@ rli.on('line', function(line) {
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length);
rli.close();
// sending multiple newlines at once that does not end with a new line
fi = new FakeInput();
@ -104,6 +108,7 @@ rli.on('line', function(line) {
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length - 1);
rli.close();
// sending a multi-byte utf8 char over multiple writes
var buf = Buffer('☮', 'utf8');
@ -120,3 +125,7 @@ rli.on('line', function(line) {
assert.equal(callCount, 0);
fi.emit('data', '\n');
assert.equal(callCount, 1);
rli.close();
assert.deepEqual(fi.listeners('end'), []);
assert.deepEqual(fi.listeners('data'), []);

4
test/simple/test-readline-set-raw-mode.js

@ -85,3 +85,7 @@ assert(rawModeCalled);
assert(!resumeCalled);
assert(pauseCalled);
assert.deepEqual(stream.listeners('end'), []);
assert.deepEqual(stream.listeners('keypress'), []);
// one data listener for the keypress events.
assert.equal(stream.listeners('data').length, 1);

Loading…
Cancel
Save