1- angular . module ( "ui.bootstrap" , [ "ui.bootstrap.accordion" , "ui.bootstrap.alert" , "ui.bootstrap.carousel" , "ui.bootstrap.collapse" , "ui.bootstrap.dialog" , "ui.bootstrap.dropdownToggle" , "ui.bootstrap.modal" , "ui.bootstrap.pagination" , "ui.bootstrap.tabs" , "ui.bootstrap.tooltip" , "ui.bootstrap.transition" ] ) ;
1+ angular . module ( "ui.bootstrap" , [ "ui.bootstrap.accordion" , "ui.bootstrap.alert" , "ui.bootstrap.carousel" , "ui.bootstrap.collapse" , "ui.bootstrap.dialog" , "ui.bootstrap.dropdownToggle" , "ui.bootstrap.modal" , "ui.bootstrap.pagination" , "ui.bootstrap.popover" , "ui.bootstrap. tabs", "ui.bootstrap.tooltip" , "ui.bootstrap.transition" ] ) ;
22
33angular . module ( 'ui.bootstrap.accordion' , [ 'ui.bootstrap.collapse' ] )
44
@@ -316,7 +316,20 @@ angular.module('ui.bootstrap.collapse',['ui.bootstrap.transition'])
316316 link : function ( scope , element , attrs ) {
317317
318318 var isCollapsed ;
319-
319+ var initialAnimSkip = true ;
320+ scope . $watch ( function ( ) { return element [ 0 ] . scrollHeight ; } , function ( value ) {
321+ //The listener is called when scollHeight changes
322+ //It actually does on 2 scenarios:
323+ // 1. Parent is set to display none
324+ // 2. angular bindings inside are resolved
325+ //When we have a change of scrollHeight we are setting again the correct height if the group is opened
326+ if ( element [ 0 ] . scrollHeight !== 0 ) {
327+ if ( ! isCollapsed ) {
328+ fixUpHeight ( scope , element , element [ 0 ] . scrollHeight + 'px' ) ;
329+ }
330+ }
331+ } ) ;
332+
320333 scope . $watch ( attrs . collapse , function ( value ) {
321334 if ( value ) {
322335 collapse ( ) ;
@@ -340,21 +353,33 @@ angular.module('ui.bootstrap.collapse',['ui.bootstrap.transition'])
340353 } ;
341354
342355 var expand = function ( ) {
343- doTransition ( { height : element [ 0 ] . scrollHeight + 'px' } )
344- . then ( function ( ) {
345- // This check ensures that we don't accidentally update the height if the user has closed
346- // the group while the animation was still running
356+ if ( initialAnimSkip ) {
357+ initialAnimSkip = false ;
347358 if ( ! isCollapsed ) {
348359 fixUpHeight ( scope , element , 'auto' ) ;
349360 }
350- } ) ;
361+ } else {
362+ doTransition ( { height : element [ 0 ] . scrollHeight + 'px' } )
363+ . then ( function ( ) {
364+ // This check ensures that we don't accidentally update the height if the user has closed
365+ // the group while the animation was still running
366+ if ( ! isCollapsed ) {
367+ fixUpHeight ( scope , element , 'auto' ) ;
368+ }
369+ } ) ;
370+ }
351371 isCollapsed = false ;
352372 } ;
353373
354374 var collapse = function ( ) {
355375 isCollapsed = true ;
356- fixUpHeight ( scope , element , element [ 0 ] . scrollHeight + 'px' ) ;
357- doTransition ( { 'height' :'0' } ) ;
376+ if ( initialAnimSkip ) {
377+ initialAnimSkip = false ;
378+ fixUpHeight ( scope , element , 0 ) ;
379+ } else {
380+ fixUpHeight ( scope , element , element [ 0 ] . scrollHeight + 'px' ) ;
381+ doTransition ( { 'height' :'0' } ) ;
382+ }
358383 } ;
359384 }
360385 } ;
@@ -828,6 +853,161 @@ angular.module('ui.bootstrap.pagination', [])
828853 }
829854 } ;
830855} ) ;
856+ /**
857+ * The following features are still outstanding: popup delay, animation as a
858+ * function, placement as a function, inside, support for more triggers than
859+ * just mouse enter/leave, html popovers, and selector delegatation.
860+ */
861+ angular . module ( 'ui.bootstrap.popover' , [ ] )
862+ . directive ( 'popoverPopup' , function ( ) {
863+ return {
864+ restrict : 'EA' ,
865+ replace : true ,
866+ scope : { popoverTitle : '@' , popoverContent : '@' , placement : '@' , animation : '&' , isOpen : '&' } ,
867+ templateUrl : 'template/popover/popover.html'
868+ } ;
869+ } )
870+ . directive ( 'popover' , [ '$compile' , '$timeout' , '$parse' , function ( $compile , $timeout , $parse ) {
871+
872+ var template =
873+ '<popover-popup ' +
874+ 'popover-title="{{tt_title}}" ' +
875+ 'popover-content="{{tt_popover}}" ' +
876+ 'placement="{{tt_placement}}" ' +
877+ 'animation="tt_animation()" ' +
878+ 'is-open="tt_isOpen"' +
879+ '>' +
880+ '</popover-popup>' ;
881+
882+ return {
883+ scope : true ,
884+ link : function ( scope , element , attr ) {
885+ var popover = $compile ( template ) ( scope ) ,
886+ transitionTimeout ;
887+
888+ attr . $observe ( 'popover' , function ( val ) {
889+ scope . tt_popover = val ;
890+ } ) ;
891+
892+ attr . $observe ( 'popoverTitle' , function ( val ) {
893+ scope . tt_title = val ;
894+ } ) ;
895+
896+ attr . $observe ( 'popoverPlacement' , function ( val ) {
897+ // If no placement was provided, default to 'top'.
898+ scope . tt_placement = val || 'top' ;
899+ } ) ;
900+
901+ attr . $observe ( 'popoverAnimation' , function ( val ) {
902+ scope . tt_animation = $parse ( val ) ;
903+ } ) ;
904+
905+ // By default, the popover is not open.
906+ scope . tt_isOpen = false ;
907+
908+ // Calculate the current position and size of the directive element.
909+ function getPosition ( ) {
910+ return {
911+ width : element . prop ( 'offsetWidth' ) ,
912+ height : element . prop ( 'offsetHeight' ) ,
913+ top : element . prop ( 'offsetTop' ) ,
914+ left : element . prop ( 'offsetLeft' )
915+ } ;
916+ }
917+
918+ // Show the popover popup element.
919+ function show ( ) {
920+ var position ,
921+ ttWidth ,
922+ ttHeight ,
923+ ttPosition ;
924+
925+ // If there is a pending remove transition, we must cancel it, lest the
926+ // toolip be mysteriously removed.
927+ if ( transitionTimeout ) {
928+ $timeout . cancel ( transitionTimeout ) ;
929+ }
930+
931+ // Set the initial positioning.
932+ popover . css ( { top : 0 , left : 0 , display : 'block' } ) ;
933+
934+ // Now we add it to the DOM because need some info about it. But it's not
935+ // visible yet anyway.
936+ element . after ( popover ) ;
937+
938+ // Get the position of the directive element.
939+ position = getPosition ( ) ;
940+
941+ // Get the height and width of the popover so we can center it.
942+ ttWidth = popover . prop ( 'offsetWidth' ) ;
943+ ttHeight = popover . prop ( 'offsetHeight' ) ;
944+
945+ // Calculate the popover's top and left coordinates to center it with
946+ // this directive.
947+ switch ( scope . tt_placement ) {
948+ case 'right' :
949+ ttPosition = {
950+ top : ( position . top + position . height / 2 - ttHeight / 2 ) + 'px' ,
951+ left : ( position . left + position . width ) + 'px'
952+ } ;
953+ break ;
954+ case 'bottom' :
955+ ttPosition = {
956+ top : ( position . top + position . height ) + 'px' ,
957+ left : ( position . left + position . width / 2 - ttWidth / 2 ) + 'px'
958+ } ;
959+ break ;
960+ case 'left' :
961+ ttPosition = {
962+ top : ( position . top + position . height / 2 - ttHeight / 2 ) + 'px' ,
963+ left : ( position . left - ttWidth ) + 'px'
964+ } ;
965+ break ;
966+ default :
967+ ttPosition = {
968+ top : ( position . top - ttHeight ) + 'px' ,
969+ left : ( position . left + position . width / 2 - ttWidth / 2 ) + 'px'
970+ } ;
971+ break ;
972+ }
973+
974+ // Now set the calculated positioning.
975+ popover . css ( ttPosition ) ;
976+
977+ // And show the popover.
978+ scope . tt_isOpen = true ;
979+ }
980+
981+ // Hide the popover popup element.
982+ function hide ( ) {
983+ // First things first: we don't show it anymore.
984+ //popover.removeClass( 'in' );
985+ scope . tt_isOpen = false ;
986+
987+ // And now we remove it from the DOM. However, if we have animation, we
988+ // need to wait for it to expire beforehand.
989+ // FIXME: this is a placeholder for a port of the transitions library.
990+ if ( angular . isDefined ( scope . tt_animation ) && scope . tt_animation ( ) ) {
991+ transitionTimeout = $timeout ( function ( ) { popover . remove ( ) ; } , 500 ) ;
992+ } else {
993+ popover . remove ( ) ;
994+ }
995+ }
996+
997+ // Register the event listeners.
998+ element . bind ( 'click' , function ( ) {
999+ if ( scope . tt_isOpen ) {
1000+ scope . $apply ( hide ) ;
1001+ } else {
1002+ scope . $apply ( show ) ;
1003+ }
1004+
1005+ } ) ;
1006+ }
1007+ } ;
1008+ } ] ) ;
1009+
1010+
8311011angular . module ( 'ui.bootstrap.tabs' , [ ] )
8321012. controller ( 'TabsController' , [ '$scope' , '$element' , function ( $scope , $element ) {
8331013 var panes = $scope . panes = [ ] ;
0 commit comments