Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 9246905

Browse files
Joe Grundpkozlowski-opensource
Joe Grund
authored andcommitted
fix(tooltip): make sure tooltip scope is evicted from cache
This fix makes sure the tooltip.$scope is cleared from angular.element.cache when $destroy is called, preventing a memory leak. Closes #484
1 parent 3fcb70f commit 9246905

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/tooltip/test/tooltip.spec.js

+40
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,46 @@ describe('tooltip', function() {
238238
}));
239239
});
240240

241+
describe('cleanup', function () {
242+
var elmBody, elm, elmScope, tooltipScope;
243+
244+
function inCache() {
245+
var match = false;
246+
247+
angular.forEach(angular.element.cache, function (item) {
248+
if (item.data && item.data.$scope === tooltipScope) {
249+
match = true;
250+
}
251+
});
252+
253+
return match;
254+
}
255+
256+
beforeEach(inject(function ( $compile, $rootScope ) {
257+
elmBody = angular.element('<div><input tooltip="Hello!" tooltip-trigger="fooTrigger" /></div>');
258+
259+
$compile(elmBody)($rootScope);
260+
$rootScope.$apply();
261+
262+
elm = elmBody.find('input');
263+
elmScope = elm.scope();
264+
tooltipScope = elmScope.$$childTail;
265+
}));
266+
267+
it( 'should not contain a cached reference', function() {
268+
expect( inCache() ).toBeTruthy();
269+
elmScope.$destroy();
270+
expect( inCache() ).toBeFalsy();
271+
});
272+
273+
it( 'should not contain a cached reference when visible', inject( function( $timeout ) {
274+
expect( inCache() ).toBeTruthy();
275+
elm.trigger('fooTrigger');
276+
elmScope.$destroy();
277+
$timeout.flush();
278+
expect( inCache() ).toBeFalsy();
279+
}));
280+
});
241281
});
242282

243283
describe('tooltipWithDifferentSymbols', function() {

src/tooltip/tooltip.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,13 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
303303
}
304304
});
305305
}
306-
307-
// if this trigger element is destroyed while the tooltip is open, we
308-
// need to close the tooltip.
309-
scope.$on('$destroy', function closeTooltipOnDestroy () {
306+
307+
// Make sure tooltip is destroyed and removed.
308+
scope.$on('$destroy', function onDestroyTooltip() {
310309
if ( scope.tt_isOpen ) {
311310
hide();
311+
} else {
312+
tooltip.remove();
312313
}
313314
});
314315
}

0 commit comments

Comments
 (0)