Skip to content

Commit a2dbd0a

Browse files
committed
fix(interim): add hide queue to prevent multiple interims at same time
After this patch, the interim stack will pick up the latest element which is not in hide process. At the moment we always take the first, but this one can be in hide progress. Fixes angular#6633 Fixes angular#4822
1 parent 938179b commit a2dbd0a

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

src/core/services/interimElement/interimElement.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ function InterimElementProvider() {
257257
* A service used to control inserting and removing an element into the DOM.
258258
*
259259
*/
260-
var service, stack = [];
260+
var service, stack = [], hideQueue = 0;
261261

262262
// Publish instance $$interimElement service;
263263
// ... used as $mdDialog, $mdToast, $mdMenu, and $mdSelect
@@ -291,6 +291,10 @@ function InterimElementProvider() {
291291
// This hide()s only the current interim element before showing the next, new one
292292
// NOTE: this is not reversible (e.g. interim elements are not stackable)
293293

294+
if (!hideExisting) {
295+
return $q.reject('Too many interim elements in queue!');
296+
}
297+
294298
hideExisting.finally(function() {
295299

296300
stack.push(interimElement);
@@ -323,30 +327,40 @@ function InterimElementProvider() {
323327
*/
324328
function hide(reason, options) {
325329
if ( !stack.length ) return $q.when(reason);
330+
if (hideQueue >= stack.length) return;
326331
options = options || {};
327332

328333
if (options.closeAll) {
329-
var promise = $q.all(stack.reverse().map(closeElement));
330-
stack = [];
331-
return promise;
332-
} else if (options.closeTo !== undefined) {
333-
return $q.all(stack.splice(options.closeTo).map(closeElement));
334+
return $q.all(stack.reverse().map(closeElement));
335+
} else if (options.closeTo) {
336+
return $q.all(stack.slice(options.closeTo).map(closeElement));
334337
} else {
335-
var interim = stack.pop();
336-
return closeElement(interim);
338+
return closeElement(stack[hideQueue]);
337339
}
338340

339341
function closeElement(interim) {
342+
hideQueue++;
340343
interim
341344
.remove(reason, false, options || { })
342345
.catch(function( reason ) {
343346
//$log.error("InterimElement.hide() error: " + reason );
344347
return reason;
348+
})
349+
.finally(function() {
350+
handleElementHide(interim);
345351
});
346352
return interim.deferred.promise;
347353
}
348354
}
349355

356+
function handleElementHide(element) {
357+
var index = stack.indexOf(element);
358+
if (index != -1) {
359+
stack.splice(index, 1);
360+
}
361+
hideQueue--;
362+
}
363+
350364
/*
351365
* @ngdoc method
352366
* @name $$interimElement.$service#cancel
@@ -363,11 +377,15 @@ function InterimElementProvider() {
363377
var interim = stack.shift();
364378
if ( !interim ) return $q.when(reason);
365379

380+
hideQueue++;
366381
interim
367382
.remove(reason, true, options || { })
368383
.catch(function( reason ) {
369384
//$log.error("InterimElement.cancel() error: " + reason );
370385
return reason;
386+
})
387+
.finally(function() {
388+
hideQueue--;
371389
});
372390

373391
return interim.deferred.promise;
@@ -378,7 +396,7 @@ function InterimElementProvider() {
378396
* Note: interim elements are in "interim containers"
379397
*/
380398
function destroy(target) {
381-
var interim = !target ? stack.shift() : null;
399+
var interim = !target ? stack.splice(hideQueue, 1)[0] : null;
382400
var cntr = angular.element(target).length ? angular.element(target)[0].parentNode : null;
383401

384402
if (cntr) {

0 commit comments

Comments
 (0)