Bug 1288440 P1 Avoid leaking existing windows in sdk/tab/events. r=gabor
authorBen Kelly <ben@wanderview.com>
Fri, 22 Jul 2016 06:26:48 -0700
changeset 348464 44d3308a260e5f3ddb695eed0e708f9c8cedfeca
parent 348463 82e2bfbaf3270ed3237e340e708d6f7838bfcc7e
child 348465 fb9e0b43f99bd1165c40d0b7f6c516d9c36bad0b
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs1288440
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1288440 P1 Avoid leaking existing windows in sdk/tab/events. r=gabor
addon-sdk/source/lib/sdk/tab/events.js
--- a/addon-sdk/source/lib/sdk/tab/events.js
+++ b/addon-sdk/source/lib/sdk/tab/events.js
@@ -34,37 +34,41 @@ const TYPES = ["TabOpen","TabClose","Tab
 function tabEventsFor(window) {
   // Map supported event types to a streams of those events on the given
   // `window` and than merge these streams into single form stream off
   // all events.
   let channels = TYPES.map(type => open(window, type));
   return merge(channels);
 }
 
-// Filter DOMContentLoaded events from all the browser events.
-var readyEvents = filter(events, e => e.type === "DOMContentLoaded");
-// Map DOMContentLoaded events to it's target browser windows.
-var futureWindows = map(readyEvents, e => e.target);
-// Expand all browsers that will become interactive to supported tab events
-// on these windows. Result will be a tab events from all tabs of all windows
-// that will become interactive.
-var eventsFromFuture = expand(futureWindows, tabEventsFor);
+// Create our event channels.  We do this in a separate function to
+// minimize the chance of leaking intermediate objects on the global.
+function makeEvents() {
+  // Filter DOMContentLoaded events from all the browser events.
+  var readyEvents = filter(events, e => e.type === "DOMContentLoaded");
+  // Map DOMContentLoaded events to it's target browser windows.
+  var futureWindows = map(readyEvents, e => e.target);
+  // Expand all browsers that will become interactive to supported tab events
+  // on these windows. Result will be a tab events from all tabs of all windows
+  // that will become interactive.
+  var eventsFromFuture = expand(futureWindows, tabEventsFor);
 
-// Above covers only windows that will become interactive in a future, but some
-// windows may already be interactive so we pick those and expand to supported
-// tab events for them too.
-var interactiveWindows = windows("navigator:browser", { includePrivate: true }).
-                         filter(isInteractive);
-var eventsFromInteractive = merge(interactiveWindows.map(tabEventsFor));
+  // Above covers only windows that will become interactive in a future, but some
+  // windows may already be interactive so we pick those and expand to supported
+  // tab events for them too.
+  var interactiveWindows = windows("navigator:browser", { includePrivate: true }).
+                           filter(isInteractive);
+  var eventsFromInteractive = merge(interactiveWindows.map(tabEventsFor));
 
 
-// Finally merge stream of tab events from future windows and current windows
-// to cover all tab events on all windows that will open.
-var allEvents = merge([eventsFromInteractive, eventsFromFuture]);
+  // Finally merge stream of tab events from future windows and current windows
+  // to cover all tab events on all windows that will open.
+  return merge([eventsFromInteractive, eventsFromFuture]);
+}
 
 // Map events to Fennec format if necessary
-exports.events = map(allEvents, function (event) {
+exports.events = map(makeEvents(), function (event) {
   return !isFennec ? event : {
     type: event.type,
     target: event.target.ownerDocument.defaultView.BrowserApp
             .getTabForBrowser(event.target)
   };
 });