Index: bridge/lib/window.js =================================================================== --- bridge/lib/window.js (revision 22208) +++ bridge/lib/window.js (working copy) @@ -89,4 +89,11 @@ } : function(e) { listener(Ice.EventModel.Event.adaptToKeyEvent(e)); }; -}; \ No newline at end of file +}; + +//*** +//clean up callback references +window.onUnload(function() { + document.onkeypress = null; + document.onkeyup = null; +}); \ No newline at end of file Index: bridge/lib/logger.js =================================================================== --- bridge/lib/logger.js (revision 22208) +++ bridge/lib/logger.js (working copy) @@ -130,24 +130,23 @@ }); This.WindowLogHandler = Object.subclass({ - initialize: function(logger, parentWindow, lines, thresholdPriority) { + initialize: function(logger, lines, thresholdPriority) { this.lineOptions = [ 25, 50, 100, 200, 400 ]; this.logger = logger; this.logger.handleWith(this); - this.parentWindow = parentWindow; this.lines = lines || this.lineOptions[3]; this.thresholdPriority = thresholdPriority || This.Priority.DEBUG; this.categoryMatcher = /.*/; this.closeOnExit = true; this.toggle(); - this.parentWindow.onKeyUp(function(e) { + window.onKeyUp(function(e) { var key = e.keyCode(); if ((key == 20 || key == 84) && (e.isCtrlPressed() || e.isAltPressed()) && e.isShiftPressed()) { this.enable(); } }.bind(this)); - this.parentWindow.onUnload(function() { + window.onUnload(function() { window.logger.info('page unloaded!'); this.disable(); }.bind(this)); @@ -155,7 +154,7 @@ enable: function() { try { - this.window = this.parentWindow.open('', 'log' + window.identifier, 'scrollbars=1,width=800,height=680'); + this.window = window.open('', 'log' + window.identifier, 'scrollbars=1,width=800,height=680'); var windowDocument = this.window.document; this.log = this.window.document.getElementById('log-window'); @@ -256,6 +255,7 @@ this.logger.threshold(This.Priority.ERROR); this.handle = Function.NOOP; if (this.closeOnExit && this.window) this.window.close(); + this.window = null; }, toggle: function() { Index: bridge/src/focus.js =================================================================== --- bridge/src/focus.js (revision 22208) +++ bridge/src/focus.js (working copy) @@ -97,4 +97,14 @@ window.onLoad(function() { This.captureFocusIn(document); }); + + //*** + //clear registered callbacks to avoid memory leaks + window.onBeforeUnload(function() { + $enumerate(['select', 'input', 'button', 'a']).each(function(type) { + $enumerate(document.body.getElementsByTagName(type)).each(function(element) { + element.onfocus = null; + }); + }); + }); }); Index: bridge/src/application.js =================================================================== --- bridge/src/application.js (revision 22208) +++ bridge/src/application.js (working copy) @@ -31,7 +31,7 @@ */ window.logger = new Ice.Log.Logger([ 'window' ]); -window.console && window.console.firebug ? new Ice.Log.FirebugLogHandler(window.logger) : new Ice.Log.WindowLogHandler(window.logger, window); +window.console && window.console.firebug ? new Ice.Log.FirebugLogHandler(window.logger) : new Ice.Log.WindowLogHandler(window.logger); [ Ice.Community ].as(function(This) { var registerSession = function(sessionID) { @@ -150,9 +150,13 @@ new Ice.Connection.SyncConnection(logger, configuration.connection, parameters) : new This.Connection.AsyncConnection(logger, sessionID, viewID, configuration.connection, parameters, commandDispatcher); var dispose = function() { - dispose = Function.NOOP; - connection.shutdown(); - documentSynchronizer.shutdown(); + try { + dispose = Function.NOOP; + connection.shutdown(); + documentSynchronizer.shutdown(); + } finally { + container.bridge = null; + } }; var sessionExpiredListeners = [];