Navigation Menu

Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
readline: Remove event listeners on close
Browse files Browse the repository at this point in the history
Fix #3756
  • Loading branch information
isaacs committed Jul 24, 2012
1 parent 2c48766 commit e4c9c9f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
36 changes: 26 additions & 10 deletions lib/readline.js
Expand Up @@ -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');
Expand All @@ -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 = '';
Expand All @@ -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);
});
}
}
Expand Down
9 changes: 9 additions & 0 deletions test/simple/test-readline-interface.js
Expand Up @@ -31,6 +31,7 @@ function FakeInput() {
}
inherits(FakeInput, EventEmitter);
FakeInput.prototype.resume = function() {};
FakeInput.prototype.pause = function() {};

var fi;
var rli;
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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');
Expand All @@ -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 changes: 4 additions & 0 deletions test/simple/test-readline-set-raw-mode.js
Expand Up @@ -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);

0 comments on commit e4c9c9f

Please sign in to comment.