readline: Remove event listeners on close

Fix #3756
This commit is contained in:
isaacs 2012-07-23 20:44:12 -07:00
Родитель 2c487669f7
Коммит e4c9c9f412
3 изменённых файлов: 39 добавлений и 10 удалений

Просмотреть файл

@ -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);
});
}
}

Просмотреть файл

@ -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'), []);

Просмотреть файл

@ -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);