@@ -118,7 +118,17 @@ angular.module('blockUI').directive('blockUi', function(blockUI, blockUIConfig,
118118 var instanceId = ! $attrs . blockUi ? $scope . $id : $attrs . blockUi ;
119119
120120 srvInstance = blockUI . instances . get ( instanceId ) ;
121- srvInstance . addRef ( ) ;
121+
122+ // Locate the parent blockUI instance
123+
124+ var parentInstance = $element . inheritedData ( 'block-ui' ) ;
125+
126+ if ( parentInstance ) {
127+
128+ // TODO: assert if parent is already set to something else
129+
130+ srvInstance . _parent = parentInstance ;
131+ }
122132
123133 // If a pattern is provided assign it to the state
124134
@@ -134,10 +144,14 @@ angular.module('blockUI').directive('blockUi', function(blockUI, blockUIConfig,
134144 $scope . $on ( '$destroy' , function ( ) {
135145 srvInstance . release ( ) ;
136146 } ) ;
147+
148+ // Increase the reference count
149+
150+ srvInstance . addRef ( ) ;
137151 }
138152
139153 $element . addClass ( 'block-ui' ) ;
140- $element . data ( 'block-ui' , srvInstance ) ;
154+ $parent . data ( 'block-ui' , srvInstance ) ;
141155 $scope . state = srvInstance . state ( ) ;
142156 }
143157 } ;
@@ -202,7 +216,9 @@ angular.module('blockUI').factory('blockUIHttpInterceptor', function($q, $inject
202216
203217} ) ;
204218
205- angular . module ( 'blockUI' ) . factory ( 'blockUI' , function ( blockUIConfig , $timeout , blockUIUtils ) {
219+ angular . module ( 'blockUI' ) . factory ( 'blockUI' , function ( blockUIConfig , $timeout , blockUIUtils , $document ) {
220+
221+ var $body = $document . find ( 'body' ) ;
206222
207223 function BlockUI ( id ) {
208224
@@ -222,6 +238,19 @@ angular.module('blockUI').factory('blockUI', function(blockUIConfig, $timeout, b
222238
223239 state . blockCount ++ ;
224240
241+ // Check if the focused element is part of the block scope
242+
243+ var $ae = angular . element ( $document [ 0 ] . activeElement ) ;
244+
245+ if ( $ae . length && blockUIUtils . isElementInBlockScope ( $ae , self ) ) {
246+
247+ // Let the active element lose focus and store a reference
248+ // to restore focus when we're done (reset)
249+
250+ self . _restoreFocus = $ae [ 0 ] ;
251+ self . _restoreFocus . blur ( ) ;
252+ }
253+
225254 if ( ! startPromise ) {
226255 startPromise = $timeout ( function ( ) {
227256 startPromise = null ;
@@ -258,10 +287,21 @@ angular.module('blockUI').factory('blockUI', function(blockUIConfig, $timeout, b
258287 } ;
259288
260289 this . reset = function ( executeCallbacks ) {
290+
261291 self . _cancelStartTimeout ( ) ;
262292 state . blockCount = 0 ;
263293 state . blocking = false ;
264294
295+ // Restore the focus to the element that was active
296+ // before the block start, but not if the user has
297+ // focused something else while the block was active.
298+
299+ if ( self . _restoreFocus &&
300+ ( ! $document [ 0 ] . activeElement || $document [ 0 ] . activeElement === $body [ 0 ] ) ) {
301+ self . _restoreFocus . focus ( ) ;
302+ self . _restoreFocus = null ;
303+ }
304+
265305 try {
266306 if ( executeCallbacks ) {
267307 angular . forEach ( doneCallbacks , function ( cb ) {
@@ -389,6 +429,19 @@ angular.module('blockUI').factory('blockUIUtils', function() {
389429 arr [ fnName ] = function ( ) {
390430 utils . forEachFn ( this , fnName , arguments ) ;
391431 }
432+ } ,
433+ isElementInBlockScope : function ( $element , blockScope ) {
434+ var c = $element . inheritedData ( 'block-ui' ) ;
435+
436+ while ( c ) {
437+ if ( c === blockScope ) {
438+ return true ;
439+ }
440+
441+ c = c . _parent ;
442+ }
443+
444+ return false ;
392445 }
393446 } ;
394447
0 commit comments