Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 99d90ab

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 #6633 Fixes #4822
1 parent 938179b commit 99d90ab

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

src/core/services/interimElement/interimElement.js

Lines changed: 32 additions & 11 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,43 @@ function InterimElementProvider() {
323327
*/
324328
function hide(reason, options) {
325329
if ( !stack.length ) return $q.when(reason);
330+
if (stack.length - 1 - hideQueue < 0) 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-
} else {
335-
var interim = stack.pop();
336-
return closeElement(interim);
334+
return $q.all(stack.reverse().map(closeElement));
335+
}
336+
337+
if (options.closeTo) {
338+
return $q.all(stack.slice(options.closeTo).map(closeElement));
337339
}
338340

341+
// Poll the first added interim element, which isn't currently hiding.
342+
return closeElement(stack[stack.length - 1 - hideQueue]);
343+
339344
function closeElement(interim) {
345+
hideQueue++;
340346
interim
341347
.remove(reason, false, options || { })
342348
.catch(function( reason ) {
343349
//$log.error("InterimElement.hide() error: " + reason );
344350
return reason;
351+
})
352+
.finally(function() {
353+
handleElementHide(interim);
345354
});
346355
return interim.deferred.promise;
347356
}
348357
}
349358

359+
function handleElementHide(element) {
360+
var index = stack.indexOf(element);
361+
if (index != -1) {
362+
stack.splice(index, 1);
363+
}
364+
hideQueue--;
365+
}
366+
350367
/*
351368
* @ngdoc method
352369
* @name $$interimElement.$service#cancel
@@ -360,14 +377,18 @@ function InterimElementProvider() {
360377
*
361378
*/
362379
function cancel(reason, options) {
363-
var interim = stack.shift();
380+
var interim = stack.pop();
364381
if ( !interim ) return $q.when(reason);
365382

383+
hideQueue++;
366384
interim
367385
.remove(reason, true, options || { })
368386
.catch(function( reason ) {
369387
//$log.error("InterimElement.cancel() error: " + reason );
370388
return reason;
389+
})
390+
.finally(function() {
391+
hideQueue--;
371392
});
372393

373394
return interim.deferred.promise;
@@ -378,7 +399,7 @@ function InterimElementProvider() {
378399
* Note: interim elements are in "interim containers"
379400
*/
380401
function destroy(target) {
381-
var interim = !target ? stack.shift() : null;
402+
var interim = !target ? stack.splice(hideQueue, 1)[0] : null;
382403
var cntr = angular.element(target).length ? angular.element(target)[0].parentNode : null;
383404

384405
if (cntr) {

0 commit comments

Comments
 (0)