2
2
* angular-ui-bootstrap
3
3
* http://angular-ui.github.io/bootstrap/
4
4
5
- * Version: 2.1.4 - 2016-09-23
5
+ * Version: 2.2.0 - 2016-10-10
6
6
* License: MIT
7
7
*/ angular . module ( "ui.bootstrap" , [ "ui.bootstrap.tpls" , "ui.bootstrap.collapse" , "ui.bootstrap.tabindex" , "ui.bootstrap.accordion" , "ui.bootstrap.alert" , "ui.bootstrap.buttons" , "ui.bootstrap.carousel" , "ui.bootstrap.dateparser" , "ui.bootstrap.isClass" , "ui.bootstrap.datepicker" , "ui.bootstrap.position" , "ui.bootstrap.datepickerPopup" , "ui.bootstrap.debounce" , "ui.bootstrap.dropdown" , "ui.bootstrap.stackedMap" , "ui.bootstrap.modal" , "ui.bootstrap.paging" , "ui.bootstrap.pager" , "ui.bootstrap.pagination" , "ui.bootstrap.tooltip" , "ui.bootstrap.popover" , "ui.bootstrap.progressbar" , "ui.bootstrap.rating" , "ui.bootstrap.tabs" , "ui.bootstrap.timepicker" , "ui.bootstrap.typeahead" ] ) ;
8
8
angular . module ( "ui.bootstrap.tpls" , [ "uib/template/accordion/accordion-group.html" , "uib/template/accordion/accordion.html" , "uib/template/alert/alert.html" , "uib/template/carousel/carousel.html" , "uib/template/carousel/slide.html" , "uib/template/datepicker/datepicker.html" , "uib/template/datepicker/day.html" , "uib/template/datepicker/month.html" , "uib/template/datepicker/year.html" , "uib/template/datepickerPopup/popup.html" , "uib/template/modal/window.html" , "uib/template/pager/pager.html" , "uib/template/pagination/pagination.html" , "uib/template/tooltip/tooltip-html-popup.html" , "uib/template/tooltip/tooltip-popup.html" , "uib/template/tooltip/tooltip-template-popup.html" , "uib/template/popover/popover-html.html" , "uib/template/popover/popover-template.html" , "uib/template/popover/popover.html" , "uib/template/progressbar/bar.html" , "uib/template/progressbar/progress.html" , "uib/template/progressbar/progressbar.html" , "uib/template/rating/rating.html" , "uib/template/tabs/tab.html" , "uib/template/tabs/tabset.html" , "uib/template/timepicker/timepicker.html" , "uib/template/typeahead/typeahead-match.html" , "uib/template/typeahead/typeahead-popup.html" ] ) ;
@@ -2208,7 +2208,7 @@ angular.module('ui.bootstrap.position', [])
2208
2208
var paddingRight = this . parseStyle ( elemStyle . paddingRight ) ;
2209
2209
var paddingBottom = this . parseStyle ( elemStyle . paddingBottom ) ;
2210
2210
var scrollParent = this . scrollParent ( elem , false , true ) ;
2211
- var scrollbarWidth = this . scrollbarWidth ( scrollParent , BODY_REGEX . test ( scrollParent . tagName ) ) ;
2211
+ var scrollbarWidth = this . scrollbarWidth ( BODY_REGEX . test ( scrollParent . tagName ) ) ;
2212
2212
2213
2213
return {
2214
2214
scrollbarWidth : scrollbarWidth ,
@@ -3192,9 +3192,9 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
3192
3192
3193
3193
this . close = function ( dropdownScope , element ) {
3194
3194
if ( openScope === dropdownScope ) {
3195
- openScope = null ;
3196
3195
$document . off ( 'click' , closeDropdown ) ;
3197
3196
$document . off ( 'keydown' , this . keybindFilter ) ;
3197
+ openScope = null ;
3198
3198
}
3199
3199
} ;
3200
3200
@@ -3227,6 +3227,11 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
3227
3227
} ;
3228
3228
3229
3229
this . keybindFilter = function ( evt ) {
3230
+ if ( ! openScope ) {
3231
+ // see this.close as ESC could have been pressed which kills the scope so we can not proceed
3232
+ return ;
3233
+ }
3234
+
3230
3235
var dropdownElement = openScope . getDropdownElement ( ) ;
3231
3236
var toggleElement = openScope . getToggleElement ( ) ;
3232
3237
var dropdownElementTargeted = dropdownElement && dropdownElement [ 0 ] . contains ( evt . target ) ;
@@ -3744,7 +3749,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
3744
3749
// {@link Attribute#$observe } on it. For more details please see {@link TableColumnResize }.
3745
3750
scope . $isRendered = true ;
3746
3751
3747
- // Deferred object that will be resolved when this modal is render .
3752
+ // Deferred object that will be resolved when this modal is rendered .
3748
3753
var modalRenderDeferObj = $q . defer ( ) ;
3749
3754
// Resolve render promise post-digest
3750
3755
scope . $$postDigest ( function ( ) {
@@ -3777,7 +3782,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
3777
3782
3778
3783
/**
3779
3784
* If something within the freshly-opened modal already has focus (perhaps via a
3780
- * directive that causes focus). then no need to try and focus anything.
3785
+ * directive that causes focus) then there's no need to try to focus anything.
3781
3786
*/
3782
3787
if ( ! ( $document [ 0 ] . activeElement && element [ 0 ] . contains ( $document [ 0 ] . activeElement ) ) ) {
3783
3788
var inputWithAutofocus = element [ 0 ] . querySelector ( '[autofocus]' ) ;
@@ -3835,6 +3840,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
3835
3840
} ;
3836
3841
var topModalIndex = 0 ;
3837
3842
var previousTopOpenedModal = null ;
3843
+ var ARIA_HIDDEN_ATTRIBUTE_NAME = 'data-bootstrap-modal-aria-hidden-count' ;
3838
3844
3839
3845
//Modal focus behavior
3840
3846
var tabbableSelector = 'a[href], area[href], input:not([disabled]):not([tabindex=\'-1\']), ' +
@@ -4136,25 +4142,74 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
4136
4142
4137
4143
openedWindows . top ( ) . value . modalDomEl = angularDomEl ;
4138
4144
openedWindows . top ( ) . value . modalOpener = modalOpener ;
4145
+
4146
+ applyAriaHidden ( angularDomEl ) ;
4147
+
4148
+ function applyAriaHidden ( el ) {
4149
+ if ( ! el || el [ 0 ] . tagName === 'BODY' ) {
4150
+ return ;
4151
+ }
4152
+
4153
+ getSiblings ( el ) . forEach ( function ( sibling ) {
4154
+ var elemIsAlreadyHidden = sibling . getAttribute ( 'aria-hidden' ) === 'true' ,
4155
+ ariaHiddenCount = parseInt ( sibling . getAttribute ( ARIA_HIDDEN_ATTRIBUTE_NAME ) , 10 ) ;
4156
+
4157
+ if ( ! ariaHiddenCount ) {
4158
+ ariaHiddenCount = elemIsAlreadyHidden ? 1 : 0 ;
4159
+ }
4160
+
4161
+ sibling . setAttribute ( ARIA_HIDDEN_ATTRIBUTE_NAME , ariaHiddenCount + 1 ) ;
4162
+ sibling . setAttribute ( 'aria-hidden' , 'true' ) ;
4163
+ } ) ;
4164
+
4165
+ return applyAriaHidden ( el . parent ( ) ) ;
4166
+
4167
+ function getSiblings ( el ) {
4168
+ var children = el . parent ( ) ? el . parent ( ) . children ( ) : [ ] ;
4169
+
4170
+ return Array . prototype . filter . call ( children , function ( child ) {
4171
+ return child !== el [ 0 ] ;
4172
+ } ) ;
4173
+ }
4174
+ }
4139
4175
} ;
4140
4176
4141
4177
function broadcastClosing ( modalWindow , resultOrReason , closing ) {
4142
4178
return ! modalWindow . value . modalScope . $broadcast ( 'modal.closing' , resultOrReason , closing ) . defaultPrevented ;
4143
4179
}
4144
4180
4181
+ function unhideBackgroundElements ( ) {
4182
+ Array . prototype . forEach . call (
4183
+ document . querySelectorAll ( '[' + ARIA_HIDDEN_ATTRIBUTE_NAME + ']' ) ,
4184
+ function ( hiddenEl ) {
4185
+ var ariaHiddenCount = parseInt ( hiddenEl . getAttribute ( ARIA_HIDDEN_ATTRIBUTE_NAME ) , 10 ) ,
4186
+ newHiddenCount = ariaHiddenCount - 1 ;
4187
+ hiddenEl . setAttribute ( ARIA_HIDDEN_ATTRIBUTE_NAME , newHiddenCount ) ;
4188
+
4189
+ if ( ! newHiddenCount ) {
4190
+ hiddenEl . removeAttribute ( ARIA_HIDDEN_ATTRIBUTE_NAME ) ;
4191
+ hiddenEl . removeAttribute ( 'aria-hidden' ) ;
4192
+ }
4193
+ }
4194
+ ) ;
4195
+ }
4196
+
4145
4197
$modalStack . close = function ( modalInstance , result ) {
4146
4198
var modalWindow = openedWindows . get ( modalInstance ) ;
4199
+ unhideBackgroundElements ( ) ;
4147
4200
if ( modalWindow && broadcastClosing ( modalWindow , result , true ) ) {
4148
4201
modalWindow . value . modalScope . $$uibDestructionScheduled = true ;
4149
4202
modalWindow . value . deferred . resolve ( result ) ;
4150
4203
removeModalWindow ( modalInstance , modalWindow . value . modalOpener ) ;
4151
4204
return true ;
4152
4205
}
4206
+
4153
4207
return ! modalWindow ;
4154
4208
} ;
4155
4209
4156
4210
$modalStack . dismiss = function ( modalInstance , reason ) {
4157
4211
var modalWindow = openedWindows . get ( modalInstance ) ;
4212
+ unhideBackgroundElements ( ) ;
4158
4213
if ( modalWindow && broadcastClosing ( modalWindow , reason , false ) ) {
4159
4214
modalWindow . value . modalScope . $$uibDestructionScheduled = true ;
4160
4215
modalWindow . value . deferred . reject ( reason ) ;
@@ -4177,6 +4232,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
4177
4232
4178
4233
$modalStack . modalRendered = function ( modalInstance ) {
4179
4234
var modalWindow = openedWindows . get ( modalInstance ) ;
4235
+ $modalStack . focusFirstFocusableElement ( $modalStack . loadFocusElementList ( modalWindow ) ) ;
4180
4236
if ( modalWindow ) {
4181
4237
modalWindow . value . renderDeferred . resolve ( ) ;
4182
4238
}
@@ -4850,6 +4906,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
4850
4906
var showTimeout ;
4851
4907
var hideTimeout ;
4852
4908
var positionTimeout ;
4909
+ var adjustmentTimeout ;
4853
4910
var appendToBody = angular . isDefined ( options . appendToBody ) ? options . appendToBody : false ;
4854
4911
var triggers = getTriggers ( undefined ) ;
4855
4912
var hasEnableExp = angular . isDefined ( attrs [ prefix + 'Enable' ] ) ;
@@ -4882,12 +4939,13 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
4882
4939
tooltip . addClass ( options . placementClassPrefix + ttPosition . placement ) ;
4883
4940
}
4884
4941
4885
- $timeout ( function ( ) {
4942
+ adjustmentTimeout = $timeout ( function ( ) {
4886
4943
var currentHeight = angular . isDefined ( tooltip . offsetHeight ) ? tooltip . offsetHeight : tooltip . prop ( 'offsetHeight' ) ;
4887
4944
var adjustment = $position . adjustTop ( placementClasses , elementPos , initialHeight , currentHeight ) ;
4888
4945
if ( adjustment ) {
4889
4946
tooltip . css ( adjustment ) ;
4890
4947
}
4948
+ adjustmentTimeout = null ;
4891
4949
} , 0 , false ) ;
4892
4950
4893
4951
// first time through tt element will have the
@@ -5052,7 +5110,11 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
5052
5110
5053
5111
if ( tooltip ) {
5054
5112
tooltip . remove ( ) ;
5113
+
5055
5114
tooltip = null ;
5115
+ if ( adjustmentTimeout ) {
5116
+ $timeout . cancel ( adjustmentTimeout ) ;
5117
+ }
5056
5118
}
5057
5119
5058
5120
openedTooltips . remove ( ttScope ) ;
@@ -5940,6 +6002,7 @@ angular.module('ui.bootstrap.timepicker', [])
5940
6002
} )
5941
6003
5942
6004
. controller ( 'UibTimepickerController' , [ '$scope' , '$element' , '$attrs' , '$parse' , '$log' , '$locale' , 'uibTimepickerConfig' , function ( $scope , $element , $attrs , $parse , $log , $locale , timepickerConfig ) {
6005
+ var hoursModelCtrl , minutesModelCtrl , secondsModelCtrl ;
5943
6006
var selected = new Date ( ) ,
5944
6007
watchers = [ ] ,
5945
6008
ngModelCtrl = { $setViewValue : angular . noop } , // nullModelCtrl
@@ -5961,6 +6024,10 @@ angular.module('ui.bootstrap.timepicker', [])
5961
6024
minutesInputEl = inputs . eq ( 1 ) ,
5962
6025
secondsInputEl = inputs . eq ( 2 ) ;
5963
6026
6027
+ hoursModelCtrl = hoursInputEl . controller ( 'ngModel' ) ;
6028
+ minutesModelCtrl = minutesInputEl . controller ( 'ngModel' ) ;
6029
+ secondsModelCtrl = secondsInputEl . controller ( 'ngModel' ) ;
6030
+
5964
6031
var mousewheel = angular . isDefined ( $attrs . mousewheel ) ? $scope . $parent . $eval ( $attrs . mousewheel ) : timepickerConfig . mousewheel ;
5965
6032
5966
6033
if ( mousewheel ) {
@@ -6220,14 +6287,23 @@ angular.module('ui.bootstrap.timepicker', [])
6220
6287
ngModelCtrl . $setValidity ( 'time' , false ) ;
6221
6288
if ( angular . isDefined ( invalidHours ) ) {
6222
6289
$scope . invalidHours = invalidHours ;
6290
+ if ( hoursModelCtrl ) {
6291
+ hoursModelCtrl . $setValidity ( 'hours' , false ) ;
6292
+ }
6223
6293
}
6224
6294
6225
6295
if ( angular . isDefined ( invalidMinutes ) ) {
6226
6296
$scope . invalidMinutes = invalidMinutes ;
6297
+ if ( minutesModelCtrl ) {
6298
+ minutesModelCtrl . $setValidity ( 'minutes' , false ) ;
6299
+ }
6227
6300
}
6228
6301
6229
6302
if ( angular . isDefined ( invalidSeconds ) ) {
6230
6303
$scope . invalidSeconds = invalidSeconds ;
6304
+ if ( secondsModelCtrl ) {
6305
+ secondsModelCtrl . $setValidity ( 'seconds' , false ) ;
6306
+ }
6231
6307
}
6232
6308
} ;
6233
6309
@@ -6350,6 +6426,18 @@ angular.module('ui.bootstrap.timepicker', [])
6350
6426
}
6351
6427
6352
6428
function makeValid ( ) {
6429
+ if ( hoursModelCtrl ) {
6430
+ hoursModelCtrl . $setValidity ( 'hours' , true ) ;
6431
+ }
6432
+
6433
+ if ( minutesModelCtrl ) {
6434
+ minutesModelCtrl . $setValidity ( 'minutes' , true ) ;
6435
+ }
6436
+
6437
+ if ( secondsModelCtrl ) {
6438
+ secondsModelCtrl . $setValidity ( 'seconds' , true ) ;
6439
+ }
6440
+
6353
6441
ngModelCtrl . $setValidity ( 'time' , true ) ;
6354
6442
$scope . invalidHours = false ;
6355
6443
$scope . invalidMinutes = false ;
0 commit comments