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

Commit e22f28b

Browse files
Josh David Millerpkozlowski-opensource
Josh David Miller
authored andcommitted
feat(tooltip,popover): logic moved to $tooltip svc
Popover and tooltip directive creation is now performed through the help of the `$tooltip` service that manages all aspects of directive creation and management based on only the name of the component and their default triggers. The tooltip and popover sub-directives and their templates were refactored to use common scope variables that the new service can provide, yielding even greater flexibility. Animation is now enabled by default. Lastly, the `$tooltipProvider` has been established to allow setting default global options for the tooltip and popover, but these features are not yet public as the API is sure to change drastically as we flesh out which global options to allow. But the framework is in place as this was a logical time to incorporate it.
1 parent 98b5f8e commit e22f28b

File tree

8 files changed

+209
-283
lines changed

8 files changed

+209
-283
lines changed

src/popover/docs/readme.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
A lightweight, extensible directive for fancy popover creation. The popover
22
directive supports multiple placements, optional transition animation, and more.
3+
4+
Like the Twitter Bootstrap jQuery plugin, the popover **requires** the tooltip
5+
module.

src/popover/popover.js

+4-140
Original file line numberDiff line numberDiff line change
@@ -3,152 +3,16 @@
33
* function, placement as a function, inside, support for more triggers than
44
* just mouse enter/leave, html popovers, and selector delegatation.
55
*/
6-
angular.module( 'ui.bootstrap.popover', [] )
6+
angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
77
.directive( 'popoverPopup', function () {
88
return {
99
restrict: 'EA',
1010
replace: true,
11-
scope: { popoverTitle: '@', popoverContent: '@', placement: '@', animation: '&', isOpen: '&' },
11+
scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
1212
templateUrl: 'template/popover/popover.html'
1313
};
1414
})
15-
.directive( 'popover', [ '$compile', '$timeout', '$parse', '$window', function ( $compile, $timeout, $parse, $window ) {
16-
17-
var template =
18-
'<popover-popup '+
19-
'popover-title="{{tt_title}}" '+
20-
'popover-content="{{tt_popover}}" '+
21-
'placement="{{tt_placement}}" '+
22-
'animation="tt_animation()" '+
23-
'is-open="tt_isOpen"'+
24-
'>'+
25-
'</popover-popup>';
26-
27-
return {
28-
scope: true,
29-
link: function ( scope, element, attr ) {
30-
var popover = $compile( template )( scope ),
31-
transitionTimeout;
32-
33-
attr.$observe( 'popover', function ( val ) {
34-
scope.tt_popover = val;
35-
});
36-
37-
attr.$observe( 'popoverTitle', function ( val ) {
38-
scope.tt_title = val;
39-
});
40-
41-
attr.$observe( 'popoverPlacement', function ( val ) {
42-
// If no placement was provided, default to 'top'.
43-
scope.tt_placement = val || 'top';
44-
});
45-
46-
attr.$observe( 'popoverAnimation', function ( val ) {
47-
scope.tt_animation = $parse( val );
48-
});
49-
50-
// By default, the popover is not open.
51-
scope.tt_isOpen = false;
52-
53-
// Calculate the current position and size of the directive element.
54-
function getPosition() {
55-
var boundingClientRect = element[0].getBoundingClientRect();
56-
return {
57-
width: element.prop( 'offsetWidth' ),
58-
height: element.prop( 'offsetHeight' ),
59-
top: boundingClientRect.top + $window.pageYOffset,
60-
left: boundingClientRect.left + $window.pageXOffset
61-
};
62-
}
63-
64-
function show() {
65-
var position,
66-
ttWidth,
67-
ttHeight,
68-
ttPosition;
69-
70-
// If there is a pending remove transition, we must cancel it, lest the
71-
// toolip be mysteriously removed.
72-
if ( transitionTimeout ) {
73-
$timeout.cancel( transitionTimeout );
74-
}
75-
76-
// Set the initial positioning.
77-
popover.css({ top: 0, left: 0, display: 'block' });
78-
79-
// Now we add it to the DOM because need some info about it. But it's not
80-
// visible yet anyway.
81-
element.after( popover );
82-
83-
// Get the position of the directive element.
84-
position = getPosition();
85-
86-
// Get the height and width of the popover so we can center it.
87-
ttWidth = popover.prop( 'offsetWidth' );
88-
ttHeight = popover.prop( 'offsetHeight' );
89-
90-
// Calculate the popover's top and left coordinates to center it with
91-
// this directive.
92-
switch ( scope.tt_placement ) {
93-
case 'right':
94-
ttPosition = {
95-
top: (position.top + position.height / 2 - ttHeight / 2) + 'px',
96-
left: (position.left + position.width) + 'px'
97-
};
98-
break;
99-
case 'bottom':
100-
ttPosition = {
101-
top: (position.top + position.height) + 'px',
102-
left: (position.left + position.width / 2 - ttWidth / 2) + 'px'
103-
};
104-
break;
105-
case 'left':
106-
ttPosition = {
107-
top: (position.top + position.height / 2 - ttHeight / 2) + 'px',
108-
left: (position.left - ttWidth) + 'px'
109-
};
110-
break;
111-
default:
112-
ttPosition = {
113-
top: (position.top - ttHeight) + 'px',
114-
left: (position.left + position.width / 2 - ttWidth / 2) + 'px'
115-
};
116-
break;
117-
}
118-
119-
// Now set the calculated positioning.
120-
popover.css( ttPosition );
121-
122-
// And show the popover.
123-
scope.tt_isOpen = true;
124-
}
125-
126-
// Hide the popover popup element.
127-
function hide() {
128-
// First things first: we don't show it anymore.
129-
//popover.removeClass( 'in' );
130-
scope.tt_isOpen = false;
131-
132-
// And now we remove it from the DOM. However, if we have animation, we
133-
// need to wait for it to expire beforehand.
134-
// FIXME: this is a placeholder for a port of the transitions library.
135-
if ( angular.isDefined( scope.tt_animation ) && scope.tt_animation() ) {
136-
transitionTimeout = $timeout( function () { popover.remove(); }, 500 );
137-
} else {
138-
popover.remove();
139-
}
140-
}
141-
142-
// Register the event listeners.
143-
element.bind( 'click', function() {
144-
if(scope.tt_isOpen){
145-
scope.$apply( hide );
146-
} else {
147-
scope.$apply( show );
148-
}
149-
150-
});
151-
}
152-
};
15+
.directive( 'popover', [ '$compile', '$timeout', '$parse', '$window', '$tooltip', function ( $compile, $timeout, $parse, $window, $tooltip ) {
16+
return $tooltip( 'popover', 'click' );
15317
}]);
15418

src/popover/test/popoverSpec.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,20 @@ describe('popover', function() {
8181
tt.trigger( 'click' );
8282

8383
expect( tt.text() ).toBe( scope.items[0].name );
84-
expect( tt.scope().tt_popover ).toBe( scope.items[0].popover );
84+
expect( tt.scope().tt_content ).toBe( scope.items[0].popover );
8585

8686
tt.trigger( 'click' );
8787
}));
8888

8989
it('should only have an isolate scope on the popup', inject( function ( $compile ) {
9090
var ttScope;
9191

92-
scope.popoverMsg = "popover Text";
93-
scope.popoverTitle = "popover Text";
92+
scope.popoverContent = "Popover Content";
93+
scope.popoverTitle = "Popover Title";
9494
scope.alt = "Alt Message";
9595

9696
elmBody = $compile( angular.element(
97-
'<div><span alt={{alt}} popover="{{popoverMsg}}" popover-title="{{popoverTitle}}">Selector Text</span></div>'
97+
'<div><span alt={{alt}} popover="{{popoverContent}}" popover-title="{{popoverTitle}}">Selector Text</span></div>'
9898
) )( scope );
9999

100100
$compile( elmBody )( scope );
@@ -107,8 +107,8 @@ describe('popover', function() {
107107

108108
ttScope = angular.element( elmBody.children()[1] ).scope();
109109
expect( ttScope.placement ).toBe( 'top' );
110-
expect( ttScope.popoverTitle ).toBe( scope.popoverTitle );
111-
expect( ttScope.popoverContent ).toBe( scope.popoverMsg );
110+
expect( ttScope.title ).toBe( scope.popoverTitle );
111+
expect( ttScope.content ).toBe( scope.popoverContent );
112112

113113
elm.trigger( 'click' );
114114
}));

src/tooltip/docs/demo.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas
1313
<a><span tooltip-placement="bottom" tooltip="On the Bottom!">bottom</span></a>
1414
pharetra convallis posuere morbi leo urna,
15-
<a><span tooltip-animation="true" tooltip="I fade in and out!">fading</span></a>
15+
<a><span tooltip-animation="false" tooltip="I don't fade. :-(">fading</span></a>
1616
at elementum eu, facilisis sed odio morbi quis commodo odio. In cursus
1717
turpis massa tincidunt dui ut.
1818
</p>

src/tooltip/test/tooltip.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('tooltip', function() {
8181
tt.trigger( 'mouseenter' );
8282

8383
expect( tt.text() ).toBe( scope.items[0].name );
84-
expect( tt.scope().tt_tooltip ).toBe( scope.items[0].tooltip );
84+
expect( tt.scope().tt_content ).toBe( scope.items[0].tooltip );
8585

8686
tt.trigger( 'mouseleave' );
8787
}));
@@ -106,7 +106,7 @@ describe('tooltip', function() {
106106

107107
ttScope = angular.element( elmBody.children()[1] ).scope();
108108
expect( ttScope.placement ).toBe( 'top' );
109-
expect( ttScope.tooltipTitle ).toBe( scope.tooltipMsg );
109+
expect( ttScope.content ).toBe( scope.tooltipMsg );
110110

111111
elm.trigger( 'mouseleave' );
112112
}));

0 commit comments

Comments
 (0)