@@ -358,16 +358,179 @@ angular.module('ui.bootstrap.dropdown')
358358 angular . extend ( this , uibDropdownService ) ;
359359} ] )
360360
361- . controller ( 'DropdownController' , [ '$scope' , '$element' , '$attrs' , '$log ' , '$dropdownSuppressWarning ' , '$controller ' , function ( $scope , $element , $attrs , $log , $dropdownSuppressWarning , $controller ) {
361+ . controller ( 'DropdownController' , [ '$scope' , '$element' , '$attrs' , '$parse ' , 'uibDropdownConfig' , 'uibDropdownService' , '$animate ', '$uibPosition ' , '$document' , '$compile' , '$templateRequest' , '$log' , '$dropdownSuppressWarning' , function ( $scope , $element , $attrs , $parse , dropdownConfig , uibDropdownService , $animate , $position , $document , $compile , $templateRequest , $log , $dropdownSuppressWarning ) {
362362 if ( ! $dropdownSuppressWarning ) {
363363 $log . warn ( 'DropdownController is now deprecated. Use UibDropdownController instead.' ) ;
364364 }
365365
366- return $controller ( 'UibDropdownController' , {
367- $scope : $scope ,
368- $element : $element ,
369- $attrs : $attrs
366+ var self = this ,
367+ scope = $scope . $new ( ) , // create a child scope so we are not polluting original one
368+ templateScope ,
369+ openClass = dropdownConfig . openClass ,
370+ getIsOpen ,
371+ setIsOpen = angular . noop ,
372+ toggleInvoker = $attrs . onToggle ? $parse ( $attrs . onToggle ) : angular . noop ,
373+ appendToBody = false ,
374+ keynavEnabled = false ,
375+ selectedOption = null ;
376+
377+
378+ $element . addClass ( 'dropdown' ) ;
379+
380+ this . init = function ( ) {
381+ if ( $attrs . isOpen ) {
382+ getIsOpen = $parse ( $attrs . isOpen ) ;
383+ setIsOpen = getIsOpen . assign ;
384+
385+ $scope . $watch ( getIsOpen , function ( value ) {
386+ scope . isOpen = ! ! value ;
387+ } ) ;
388+ }
389+
390+ appendToBody = angular . isDefined ( $attrs . dropdownAppendToBody ) ;
391+ keynavEnabled = angular . isDefined ( $attrs . uibKeyboardNav ) ;
392+
393+ if ( appendToBody && self . dropdownMenu ) {
394+ $document . find ( 'body' ) . append ( self . dropdownMenu ) ;
395+ $element . on ( '$destroy' , function handleDestroyEvent ( ) {
396+ self . dropdownMenu . remove ( ) ;
397+ } ) ;
398+ }
399+ } ;
400+
401+ this . toggle = function ( open ) {
402+ return scope . isOpen = arguments . length ? ! ! open : ! scope . isOpen ;
403+ } ;
404+
405+ // Allow other directives to watch status
406+ this . isOpen = function ( ) {
407+ return scope . isOpen ;
408+ } ;
409+
410+ scope . getToggleElement = function ( ) {
411+ return self . toggleElement ;
412+ } ;
413+
414+ scope . getAutoClose = function ( ) {
415+ return $attrs . autoClose || 'always' ; //or 'outsideClick' or 'disabled'
416+ } ;
417+
418+ scope . getElement = function ( ) {
419+ return $element ;
420+ } ;
421+
422+ scope . isKeynavEnabled = function ( ) {
423+ return keynavEnabled ;
424+ } ;
425+
426+ scope . focusDropdownEntry = function ( keyCode ) {
427+ var elems = self . dropdownMenu ? //If append to body is used.
428+ ( angular . element ( self . dropdownMenu ) . find ( 'a' ) ) :
429+ ( angular . element ( $element ) . find ( 'ul' ) . eq ( 0 ) . find ( 'a' ) ) ;
430+
431+ switch ( keyCode ) {
432+ case ( 40 ) : {
433+ if ( ! angular . isNumber ( self . selectedOption ) ) {
434+ self . selectedOption = 0 ;
435+ } else {
436+ self . selectedOption = ( self . selectedOption === elems . length - 1 ?
437+ self . selectedOption :
438+ self . selectedOption + 1 ) ;
439+ }
440+ break ;
441+ }
442+ case ( 38 ) : {
443+ if ( ! angular . isNumber ( self . selectedOption ) ) {
444+ self . selectedOption = elems . length - 1 ;
445+ } else {
446+ self . selectedOption = self . selectedOption === 0 ?
447+ 0 : self . selectedOption - 1 ;
448+ }
449+ break ;
450+ }
451+ }
452+ elems [ self . selectedOption ] . focus ( ) ;
453+ } ;
454+
455+ scope . getDropdownElement = function ( ) {
456+ return self . dropdownMenu ;
457+ } ;
458+
459+ scope . focusToggleElement = function ( ) {
460+ if ( self . toggleElement ) {
461+ self . toggleElement [ 0 ] . focus ( ) ;
462+ }
463+ } ;
464+
465+ scope . $watch ( 'isOpen' , function ( isOpen , wasOpen ) {
466+ if ( appendToBody && self . dropdownMenu ) {
467+ var pos = $position . positionElements ( $element , self . dropdownMenu , 'bottom-left' , true ) ;
468+ var css = {
469+ top : pos . top + 'px' ,
470+ display : isOpen ? 'block' : 'none'
471+ } ;
472+
473+ var rightalign = self . dropdownMenu . hasClass ( 'dropdown-menu-right' ) ;
474+ if ( ! rightalign ) {
475+ css . left = pos . left + 'px' ;
476+ css . right = 'auto' ;
477+ } else {
478+ css . left = 'auto' ;
479+ css . right = ( window . innerWidth - ( pos . left + $element . prop ( 'offsetWidth' ) ) ) + 'px' ;
480+ }
481+
482+ self . dropdownMenu . css ( css ) ;
483+ }
484+
485+ $animate [ isOpen ? 'addClass' : 'removeClass' ] ( $element , openClass ) . then ( function ( ) {
486+ if ( angular . isDefined ( isOpen ) && isOpen !== wasOpen ) {
487+ toggleInvoker ( $scope , { open : ! ! isOpen } ) ;
488+ }
489+ } ) ;
490+
491+ if ( isOpen ) {
492+ if ( self . dropdownMenuTemplateUrl ) {
493+ $templateRequest ( self . dropdownMenuTemplateUrl ) . then ( function ( tplContent ) {
494+ templateScope = scope . $new ( ) ;
495+ $compile ( tplContent . trim ( ) ) ( templateScope , function ( dropdownElement ) {
496+ var newEl = dropdownElement ;
497+ self . dropdownMenu . replaceWith ( newEl ) ;
498+ self . dropdownMenu = newEl ;
499+ } ) ;
500+ } ) ;
501+ }
502+
503+ scope . focusToggleElement ( ) ;
504+ uibDropdownService . open ( scope ) ;
505+ } else {
506+ if ( self . dropdownMenuTemplateUrl ) {
507+ if ( templateScope ) {
508+ templateScope . $destroy ( ) ;
509+ }
510+ var newEl = angular . element ( '<ul class="dropdown-menu"></ul>' ) ;
511+ self . dropdownMenu . replaceWith ( newEl ) ;
512+ self . dropdownMenu = newEl ;
513+ }
514+
515+ uibDropdownService . close ( scope ) ;
516+ self . selectedOption = null ;
517+ }
518+
519+ if ( angular . isFunction ( setIsOpen ) ) {
520+ setIsOpen ( $scope , isOpen ) ;
521+ }
522+ } ) ;
523+
524+ $scope . $on ( '$locationChangeSuccess' , function ( ) {
525+ if ( scope . getAutoClose ( ) !== 'disabled' ) {
526+ scope . isOpen = false ;
527+ }
370528 } ) ;
529+
530+ var offDestroy = $scope . $on ( '$destroy' , function ( ) {
531+ scope . $destroy ( ) ;
532+ } ) ;
533+ scope . $on ( '$destroy' , offDestroy ) ;
371534} ] )
372535
373536. directive ( 'dropdown' , [ '$log' , '$dropdownSuppressWarning' , function ( $log , $dropdownSuppressWarning ) {
0 commit comments