From 62d15953ffea6932622c771daba56b408a311fee Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 28 Oct 2015 03:45:46 +0530 Subject: [PATCH] remote: track listeners for browser side --- atom/browser/lib/rpc-server.coffee | 7 +++++++ atom/common/api/lib/callbacks-registry.coffee | 4 ++++ spec/api-ipc-spec.coffee | 13 +++++++++++++ 3 files changed, 24 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 6b1f95a841ab..c4d91830b5f1 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -3,6 +3,9 @@ path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' +# caches callback with their registry ID. +rendererCallbacks = {} + # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta = type: typeof value @@ -74,6 +77,8 @@ unwrapArgs = (sender, args) -> objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true + return rendererCallbacks[meta.id] if rendererCallbacks[meta.id]? + ret = -> if rendererReleased throw new Error("Attempting to call a function in a renderer window @@ -81,7 +86,9 @@ unwrapArgs = (sender, args) -> sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased + delete rendererCallbacks[meta.id] sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id + rendererCallbacks[meta.id] = ret ret else throw new TypeError("Unknown type: #{meta.type}") diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index d4c37f087b1e..5151640b2b80 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -7,6 +7,10 @@ class CallbacksRegistry add: (callback) -> id = ++@nextId + for id,value of @callbacks + if value == callback + return id + # Capture the location of the function and put it in the ID string, # so that release errors can be tracked down easily. regexp = /at (.*)/gi diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 142f06c00ff3..1155aa73e83d 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -88,3 +88,16 @@ describe 'ipc module', -> w.destroy() done() w.loadUrl 'file://' + path.join(fixtures, 'api', 'send-sync-message.html') + + describe 'remote listeners', -> + it 'can be added and removed correctly', -> + count = 0 + w = new BrowserWindow(show: false) + listener = () -> + count += 1 + w.removeListener 'blur', listener + w.on 'blur', listener + w.emit 'blur' + w.emit 'blur' + assert.equal count, 1 + w.destroy()