Index: safari/ext/common.js |
=================================================================== |
--- a/safari/ext/common.js |
+++ b/safari/ext/common.js |
@@ -31,19 +31,35 @@ |
var response = {}; |
for (var prop in request) |
response[prop] = request[prop]; |
- response.payload = message; |
+ if (typeof message != "undefined") |
+ response.payload = message; |
this._messageDispatcher.dispatchMessage("response", response); |
}, |
handleRequest: function(request, sender) |
{ |
- var sendResponse; |
if ("callbackId" in request) |
- sendResponse = this._sendResponse.bind(this, request); |
+ { |
+ var sent = false; |
+ var sendResponse = function(message) |
+ { |
+ this._sendResponse(request, message); |
+ sent = true; |
+ }.bind(this); |
+ |
+ var results = ext.onMessage._dispatch(request.payload, sender, sendResponse); |
+ |
+ // The onMessage listener has to return true to indicate that a response |
+ // is sent later asynchronously. Otherwise if no response was sent yet, |
+ // we sent a response indicating that there is no response, that |
+ // the other end can remove the callback and doesn't leak memory. |
+ if (!sent && results.indexOf(true) == -1) |
+ this._sendResponse(request, undefined); |
+ } |
else |
- sendResponse = function() {}; |
- |
- ext.onMessage._dispatch(request.payload, sender, sendResponse); |
+ { |
+ ext.onMessage._dispatch(request.payload, sender, function() {}); |
+ } |
}, |
handleResponse: function(response) |
{ |
@@ -52,7 +68,9 @@ |
if (callback) |
{ |
delete this._responseCallbacks[callbackId]; |
- callback(response.payload); |
+ |
+ if ("payload" in response) |
+ callback(response.payload); |
} |
}, |
sendMessage: function(message, responseCallback, extra) |