Skip to content

Commit b70cf11

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 b70cf11

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/core/services/interimElement/interimElement.js

Lines changed: 28 additions & 8 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,12 @@ 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(function(resolve, reject) {
296+
reject("Too many interim elements in queue!");
297+
})
298+
}
299+
294300
hideExisting.finally(function() {
295301

296302
stack.push(interimElement);
@@ -323,30 +329,40 @@ function InterimElementProvider() {
323329
*/
324330
function hide(reason, options) {
325331
if ( !stack.length ) return $q.when(reason);
332+
if (hideQueue >= stack.length) return;
326333
options = options || {};
327334

328335
if (options.closeAll) {
329-
var promise = $q.all(stack.reverse().map(closeElement));
330-
stack = [];
331-
return promise;
336+
return $q.all(stack.reverse().map(closeElement));
332337
} else if (options.closeTo !== undefined) {
333-
return $q.all(stack.splice(options.closeTo).map(closeElement));
338+
return $q.all(stack.slice(options.closeTo).map(closeElement));
334339
} else {
335-
var interim = stack.pop();
336-
return closeElement(interim);
340+
return closeElement(stack[hideQueue]);
337341
}
338342

339343
function closeElement(interim) {
344+
hideQueue++;
340345
interim
341346
.remove(reason, false, options || { })
342347
.catch(function( reason ) {
343348
//$log.error("InterimElement.hide() error: " + reason );
344349
return reason;
350+
})
351+
.finally(function() {
352+
handleElementHide(interim);
345353
});
346354
return interim.deferred.promise;
347355
}
348356
}
349357

358+
function handleElementHide(element) {
359+
var index = stack.indexOf(element);
360+
if (index != -1) {
361+
stack.splice(index, 1);
362+
}
363+
hideQueue--;
364+
}
365+
350366
/*
351367
* @ngdoc method
352368
* @name $$interimElement.$service#cancel
@@ -363,11 +379,15 @@ function InterimElementProvider() {
363379
var interim = stack.shift();
364380
if ( !interim ) return $q.when(reason);
365381

382+
hideQueue++;
366383
interim
367384
.remove(reason, true, options || { })
368385
.catch(function( reason ) {
369386
//$log.error("InterimElement.cancel() error: " + reason );
370387
return reason;
388+
})
389+
.finally(function() {
390+
hideQueue--;
371391
});
372392

373393
return interim.deferred.promise;
@@ -378,7 +398,7 @@ function InterimElementProvider() {
378398
* Note: interim elements are in "interim containers"
379399
*/
380400
function destroy(target) {
381-
var interim = !target ? stack.shift() : null;
401+
var interim = !target ? stack.splice(hideQueue, 1)[0] : null;
382402
var cntr = angular.element(target).length ? angular.element(target)[0].parentNode : null;
383403

384404
if (cntr) {

0 commit comments

Comments
 (0)