Bug 1288440 - Part 2: Don't leak existing windows in sdk/window/events. r=gabor, a=sledru
authorBen Kelly <ben@wanderview.com>
Fri, 22 Jul 2016 06:26:49 -0700
changeset 395164 9b232ee6823a5dfbac8aa2d7c627ccfe1fcafff7
parent 395163 a6c2fdd0db159d463966c078502a508b86bf9d51
child 395165 7ead20a4ee6e8d6642ad6a2aa9862761ff1cd324
push id24716
push userbmo:jgilbert@mozilla.com
push dateMon, 01 Aug 2016 19:54:25 +0000
reviewersgabor, sledru
bugs1288440
milestone49.0a2
Bug 1288440 - Part 2: Don't leak existing windows in sdk/window/events. r=gabor, a=sledru
addon-sdk/source/lib/sdk/window/events.js
--- a/addon-sdk/source/lib/sdk/window/events.js
+++ b/addon-sdk/source/lib/sdk/window/events.js
@@ -38,27 +38,31 @@ function eventsFor(window) {
   //       completely closed.
   let interactive = open(window, "DOMContentLoaded", { capture: true });
   let complete = open(window, "load", { capture: true });
   let states = merge([interactive, complete]);
   let changes = filter(states, makeStrictDocumentFilter(window));
   return map(changes, toEventWithDefaultViewTarget);
 }
 
-// In addition to observing windows that are open we also observe windows
-// that are already already opened in case they're in process of loading.
-var opened = windows(null, { includePrivate: true });
-var currentEvents = merge(opened.map(eventsFor));
+// Create our event channels.  We do this in a separate function to
+// minimize the chance of leaking intermediate objects on the global.
+function makeEvents() {
+  // In addition to observing windows that are open we also observe windows
+  // that are already already opened in case they're in process of loading.
+  var opened = windows(null, { includePrivate: true });
+  var currentEvents = merge(opened.map(eventsFor));
 
-// Register system event listeners for top level window open / close.
-function rename({type, target, data}) {
-  return { type: rename[type], target: target, data: data }
+  // Register system event listeners for top level window open / close.
+  function rename({type, target, data}) {
+    return { type: rename[type], target: target, data: data }
+  }
+  rename.domwindowopened = "open";
+  rename.domwindowclosed = "close";
+
+  var openEvents = map(observe("domwindowopened"), rename);
+  var closeEvents = map(observe("domwindowclosed"), rename);
+  var futureEvents = expand(openEvents, ({target}) => eventsFor(target));
+
+  return merge([currentEvents, futureEvents, openEvents, closeEvents]);
 }
-rename.domwindowopened = "open";
-rename.domwindowclosed = "close";
 
-var openEvents = map(observe("domwindowopened"), rename);
-var closeEvents = map(observe("domwindowclosed"), rename);
-var futureEvents = expand(openEvents, ({target}) => eventsFor(target));
-
-var channel = merge([currentEvents, futureEvents,
-                     openEvents, closeEvents]);
-exports.events = channel;
+exports.events = makeEvents();