Skip to content

Commit d7896f6

Browse files
committed
fix(tooltip): link on demand
- Calling $digest is enough as we only need to digest the watchers in this scope and its children. No need to call $apply. - Set invokeApply to false on $timeout for popUpDelay - No need to test for cached reference when tooltip isn't visible as the tooltip has no scope. Fixes angular-ui#1450 and angular-ui#1191
1 parent 0eb196a commit d7896f6

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

Diff for: src/tooltip/test/tooltip.spec.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -348,18 +348,12 @@ describe('tooltip', function() {
348348

349349
elm = elmBody.find('input');
350350
elmScope = elm.scope();
351+
elm.trigger('fooTrigger');
351352
tooltipScope = elmScope.$$childTail;
352353
}));
353354

354-
it( 'should not contain a cached reference', function() {
355-
expect( inCache() ).toBeTruthy();
356-
elmScope.$destroy();
357-
expect( inCache() ).toBeFalsy();
358-
});
359-
360355
it( 'should not contain a cached reference when visible', inject( function( $timeout ) {
361356
expect( inCache() ).toBeTruthy();
362-
elm.trigger('fooTrigger');
363357
elmScope.$destroy();
364358
expect( inCache() ).toBeFalsy();
365359
}));

Diff for: src/tooltip/tooltip.js

+31-10
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,11 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
108108
return {
109109
restrict: 'EA',
110110
scope: true,
111-
link: function link ( scope, element, attrs ) {
112-
var tooltip = $compile( template )( scope );
111+
compile: function (tElem, tAttrs) {
112+
var tooltipLinker = $compile( template );
113+
114+
return function link ( scope, element, attrs ) {
115+
var tooltip;
113116
var transitionTimeout;
114117
var popupTimeout;
115118
var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
@@ -184,10 +187,10 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
184187
return;
185188
}
186189
if ( scope.tt_popupDelay ) {
187-
popupTimeout = $timeout( show, scope.tt_popupDelay );
190+
popupTimeout = $timeout( show, scope.tt_popupDelay, false );
188191
popupTimeout.then(function(reposition){reposition();});
189192
} else {
190-
scope.$apply( show )();
193+
show()();
191194
}
192195
}
193196

@@ -206,6 +209,8 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
206209
return angular.noop;
207210
}
208211

212+
createTooltip();
213+
209214
// If there is a pending remove transition, we must cancel it, lest the
210215
// tooltip be mysteriously removed.
211216
if ( transitionTimeout ) {
@@ -227,6 +232,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
227232

228233
// And show the tooltip.
229234
scope.tt_isOpen = true;
235+
scope.$digest(); // digest required as $apply is not called
230236

231237
// Return positioning function as promise callback for correct
232238
// positioning after draw.
@@ -245,11 +251,27 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
245251
// need to wait for it to expire beforehand.
246252
// FIXME: this is a placeholder for a port of the transitions library.
247253
if ( scope.tt_animation ) {
248-
transitionTimeout = $timeout(function () {
249-
tooltip.remove();
250-
}, 500);
254+
transitionTimeout = $timeout(removeTooltip, 500);
251255
} else {
256+
removeTooltip();
257+
}
258+
}
259+
260+
function createTooltip() {
261+
// There can only be one tooltip element per directive shown at once.
262+
if (tooltip) {
263+
removeTooltip();
264+
}
265+
tooltip = tooltipLinker(scope, function () {});
266+
267+
// Get contents rendered into the tooltip
268+
scope.$digest();
269+
}
270+
271+
function removeTooltip() {
272+
if (tooltip) {
252273
tooltip.remove();
274+
tooltip = null;
253275
}
254276
}
255277

@@ -322,10 +344,9 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
322344
$timeout.cancel( transitionTimeout );
323345
$timeout.cancel( popupTimeout );
324346
unregisterTriggers();
325-
tooltip.remove();
326-
tooltip.unbind();
327-
tooltip = null;
347+
removeTooltip();
328348
});
349+
};
329350
}
330351
};
331352
};

0 commit comments

Comments
 (0)