clean up event listeners in proxy (#50)

This commit is contained in:
Lynn
2017-03-30 16:20:51 -07:00
committed by GitHub
parent 7989bcc044
commit 7ee0418c82
5 changed files with 57 additions and 18 deletions

View File

@@ -73,27 +73,19 @@
function onclick(event) {
event.target.data.then(function(value) {
alert('notification clicked: ' + value.hello);
event.target.close();
})
}
notf.addEventListener('close', onclose);
function onclose() {
alert('notification closed');
removeEvents();
};
notf.addEventListener('error', onerror);
function onerror(event) {
alert('error=' + event.result);
};
// be sure to remove all events when closed, otherwise leaks
// will occur.
function removeEvents() {
notf.removeEventListener('click', onclick)
notf.removeEventListener('close', onclose)
notf.removeEventListener('error', onerror)
}
});
var badgeCount = 0;

View File

@@ -133,13 +133,34 @@ electron.ipcMain.on(apiProxyCmds.createObject, function(event, args) {
let objId = uniqueId();
liveObjs[objId] = obj;
if (typeof obj.addEventListener === 'function') {
obj.addEventListener('destroy', function() {
// special destroy event listener so implementation can raise event to
// clean up everything.
if (typeof obj.addEventListener === 'function' &&
typeof obj.removeEventListener === 'function') {
let destroy = function() {
var callbackIds = Object.keys(obj._callbacks);
callbackIds.forEach(function(callbackId) {
let callback = obj._callbacks[ callbackId ];
if (typeof callback === 'function') {
// invoke callback to proxy so it clean up itself.
callback(null, 'destroy');
if (callback.eventName) {
obj.removeEventListener(callback.eventName, callback);
}
}
});
obj.removeEventListener('destroy', destroy);
obj._callbacks = null;
var liveObj = liveObjs[objId];
if (liveObj) {
delete liveObjs[objId];
}
});
}
obj.addEventListener('destroy', destroy);
}
setResult(objId);
@@ -383,12 +404,17 @@ electron.ipcMain.on(apiProxyCmds.addEvent, function(event, args) {
/* eslint-enable no-console */
let obj = liveObjs[args.objId];
let callbackFunc = function(result) {
// callback invoked from implementation or locally in destroy to
// clean up event handlers.
let callbackFunc = function(result, type) {
event.sender.send(apiProxyCmds.eventCallback, {
callbackId: args.callbackId,
result: result
result: result,
type: type
});
}
callbackFunc.eventName = args.eventName;
obj._callbacks[args.callbackId] = callbackFunc;
obj.addEventListener(args.eventName, callbackFunc);
});

View File

@@ -37,7 +37,6 @@ class Notify {
function onClick(arg) {
if (arg.id === this._id) {
this.emitter.emit('click');
arg.closeNotification();
}
}
@@ -92,9 +91,9 @@ class Notify {
//
destroy() {
this.emitter.removeAllListeners();
// allow live instance to be destroyed
this.emitter.emit('destroy');
this.emitter.removeAllListeners();
}
}

View File

@@ -110,6 +110,13 @@ function addEventHandler(target) {
let callbackFunc = function(arg) {
if (arg.callbackId === callbackId) {
// special destroy callback so we can clean up event listeners.
if (arg.type === 'destroy') {
ipcRenderer.removeListener(proxyCmds.eventCallback,
callbackFunc);
target._callbacks.delete(callbackFunc);
return;
}
callback({
target: this,
type: eventName,
@@ -122,7 +129,7 @@ function addEventHandler(target) {
target._callbacks.set(callback, {
callbackId: callbackId,
callbackbackFunc: callbackFunc
callbackFunc: callbackFunc
});
}
@@ -140,7 +147,7 @@ function removeEventHandler(target) {
}
ipcRenderer.removeListener(proxyCmds.eventCallback,
callbackObj.callbackbackFunc);
callbackObj.callbackFunc);
ipcRenderer.send(proxyCmds.removeEvent, args);

View File

@@ -301,4 +301,19 @@ describe('proxy destroy tests...', function() {
done();
});
});
test('after destroy should not raise events', function(done) {
inst.destroy();
var clickedCalled = false;
inst.addEventListener('click', function() {
clickedCalled = true;
});
inst.emitEvent('click');
setTimeout(function() {
if (!clickedCalled) {
done();
}
}, 200);
})
});