From 0d810acdb9f075245aaece032283f706c4baaf3f Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Sun, 17 Nov 2013 14:08:01 +0100 Subject: [PATCH] fix(tooltip): tackle DOM node and event handlers leak Closes #1133 --- src/tooltip/test/tooltip.spec.js | 1 - src/tooltip/tooltip.js | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/tooltip/test/tooltip.spec.js b/src/tooltip/test/tooltip.spec.js index d2b7d7a2b9..cac92712f2 100644 --- a/src/tooltip/test/tooltip.spec.js +++ b/src/tooltip/test/tooltip.spec.js @@ -332,7 +332,6 @@ describe('tooltip', function() { expect( inCache() ).toBeTruthy(); elm.trigger('fooTrigger'); elmScope.$destroy(); - $timeout.flush(); expect( inCache() ).toBeFalsy(); })); }); diff --git a/src/tooltip/tooltip.js b/src/tooltip/tooltip.js index cf6256c7e3..987cb410dc 100644 --- a/src/tooltip/tooltip.js +++ b/src/tooltip/tooltip.js @@ -100,7 +100,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap 'title="'+startSym+'tt_title'+endSym+'" '+ 'content="'+startSym+'tt_content'+endSym+'" '+ 'placement="'+startSym+'tt_placement'+endSym+'" '+ - 'animation="tt_animation()" '+ + 'animation="tt_animation" '+ 'is-open="tt_isOpen"'+ '>'+ ''; @@ -112,7 +112,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap var tooltip = $compile( template )( scope ); var transitionTimeout; var popupTimeout; - var $body; + var $body = $document.find( 'body' ); var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false; var triggers = getTriggers( undefined ); var hasRegisteredTriggers = false; @@ -172,7 +172,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap // Now we add it to the DOM because need some info about it. But it's not // visible yet anyway. if ( appendToBody ) { - $body = $body || $document.find( 'body' ); $body.append( tooltip ); } else { element.after( tooltip ); @@ -235,8 +234,10 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap // And now we remove it from the DOM. However, if we have animation, we // need to wait for it to expire beforehand. // FIXME: this is a placeholder for a port of the transitions library. - if ( angular.isDefined( scope.tt_animation ) && scope.tt_animation() ) { - transitionTimeout = $timeout( function () { tooltip.remove(); }, 500 ); + if ( scope.tt_animation ) { + transitionTimeout = $timeout(function () { + tooltip.remove(); + }, 500); } else { tooltip.remove(); } @@ -263,8 +264,8 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap scope.tt_placement = angular.isDefined( val ) ? val : options.placement; }); - attrs.$observe( prefix+'Animation', function ( val ) { - scope.tt_animation = angular.isDefined( val ) ? $parse( val ) : function(){ return options.animation; }; + attrs.$observe(prefix + 'Animation', function (val) { + scope.tt_animation = angular.isDefined(val) ? !!val : options.animation; }); attrs.$observe( prefix+'PopupDelay', function ( val ) { @@ -308,11 +309,11 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap // Make sure tooltip is destroyed and removed. scope.$on('$destroy', function onDestroyTooltip() { - if ( scope.tt_isOpen ) { - hide(); - } else { - tooltip.remove(); - } + $timeout.cancel( popupTimeout ); + tooltip.remove(); + tooltip.unbind(); + tooltip = null; + $body = null; }); } };