@@ -40,11 +40,15 @@ export class RootLayoutBase extends GridLayout {
40
40
return handled ;
41
41
}
42
42
43
- // ability to add any view instance to composite views like layers
43
+ /**
44
+ * Ability to add any view instance to composite views like layers.
45
+ *
46
+ * @param view
47
+ * @param options
48
+ * @returns
49
+ */
44
50
open ( view : View , options : RootLayoutOptions = { } ) : Promise < void > {
45
- const enterAnimationDefinition = options . animation ? options . animation . enterFrom : null ;
46
-
47
- return new Promise < void > ( ( resolve , reject ) => {
51
+ return new Promise ( ( resolve , reject ) => {
48
52
if ( ! ( view instanceof View ) ) {
49
53
return reject ( new Error ( `Invalid open view: ${ view } ` ) ) ;
50
54
}
@@ -53,57 +57,68 @@ export class RootLayoutBase extends GridLayout {
53
57
return reject ( new Error ( `${ view } has already been added` ) ) ;
54
58
}
55
59
56
- resolve ( ) ;
57
- } )
58
- . then ( ( ) => {
59
- // keep track of the views locally to be able to use their options later
60
- this . popupViews . push ( { view : view , options : options } ) ;
61
-
62
- if ( options . shadeCover ) {
63
- // perf optimization note: we only need 1 layer of shade cover
64
- // we just update properties if needed by additional overlaid views
65
- if ( this . shadeCover ) {
66
- // overwrite current shadeCover options if topmost popupview has additional shadeCover configurations
67
- return this . updateShadeCover ( this . shadeCover , options . shadeCover ) ;
68
- }
69
- return this . openShadeCover ( options . shadeCover ) ;
60
+ const toOpen = [ ] ;
61
+ const enterAnimationDefinition = options . animation ? options . animation . enterFrom : null ;
62
+
63
+ // keep track of the views locally to be able to use their options later
64
+ this . popupViews . push ( { view : view , options : options } ) ;
65
+
66
+ if ( options . shadeCover ) {
67
+ // perf optimization note: we only need 1 layer of shade cover
68
+ // we just update properties if needed by additional overlaid views
69
+ if ( this . shadeCover ) {
70
+ // overwrite current shadeCover options if topmost popupview has additional shadeCover configurations
71
+ toOpen . push ( this . updateShadeCover ( this . shadeCover , options . shadeCover ) ) ;
72
+ } else {
73
+ toOpen . push ( this . openShadeCover ( options . shadeCover ) ) ;
70
74
}
71
- } )
72
- . then ( ( ) => {
73
- view . opacity = 0 ; // always begin with view invisible when adding dynamically
74
- this . insertChild ( view , this . getChildrenCount ( ) + 1 ) ;
75
+ }
75
76
76
- return new Promise ( ( resolve , reject ) => {
77
+ view . opacity = 0 ; // always begin with view invisible when adding dynamically
78
+ this . insertChild ( view , this . getChildrenCount ( ) + 1 ) ;
79
+
80
+ toOpen . push (
81
+ new Promise < void > ( ( res , rej ) => {
77
82
setTimeout ( ( ) => {
78
83
// only apply initial state and animate after the first tick - ensures safe areas and other measurements apply correctly
79
84
this . applyInitialState ( view , enterAnimationDefinition ) ;
80
85
this . getEnterAnimation ( view , enterAnimationDefinition )
81
86
. play ( )
82
- . then ( ( ) => {
83
- this . applyDefaultState ( view ) ;
84
- view . notify ( { eventName : 'opened' , object : view } ) ;
85
- resolve ( ) ;
86
- } )
87
- . catch ( ( ex ) => {
88
- reject ( new Error ( `Error playing enter animation: ${ ex } ` ) ) ;
89
- } ) ;
87
+ . then (
88
+ ( ) => {
89
+ this . applyDefaultState ( view ) ;
90
+ view . notify ( { eventName : 'opened' , object : view } ) ;
91
+ res ( ) ;
92
+ } ,
93
+ ( err ) => {
94
+ rej ( new Error ( `Error playing enter animation: ${ err } ` ) ) ;
95
+ }
96
+ ) ;
90
97
} ) ;
91
- } ) ;
92
- } ) ;
98
+ } )
99
+ ) ;
100
+
101
+ Promise . all ( toOpen ) . then (
102
+ ( ) => {
103
+ resolve ( ) ;
104
+ } ,
105
+ ( err ) => {
106
+ reject ( err ) ;
107
+ }
108
+ ) ;
109
+ } ) ;
93
110
}
94
111
95
- // optional animation parameter to overwrite close animation declared when opening popup
96
- // ability to remove any view instance from composite views
112
+ /**
113
+ * Ability to remove any view instance from composite views.
114
+ * Optional animation parameter to overwrite close animation declared when opening popup.
115
+ *
116
+ * @param view
117
+ * @param exitTo
118
+ * @returns
119
+ */
97
120
close ( view : View , exitTo ?: TransitionAnimation ) : Promise < void > {
98
- const cleanupAndFinish = ( ) => {
99
- view . notify ( { eventName : 'closed' , object : view } ) ;
100
- this . removeChild ( view ) ;
101
- } ;
102
-
103
- // use exitAnimation that is passed in and fallback to the exitAnimation passed in when opening
104
- let exitAnimationDefinition = exitTo ;
105
-
106
- return new Promise < void > ( ( resolve , reject ) => {
121
+ return new Promise ( ( resolve , reject ) => {
107
122
if ( ! ( view instanceof View ) ) {
108
123
return reject ( new Error ( `Invalid close view: ${ view } ` ) ) ;
109
124
}
@@ -112,42 +127,58 @@ export class RootLayoutBase extends GridLayout {
112
127
return reject ( new Error ( `Unable to close popup. ${ view } not found` ) ) ;
113
128
}
114
129
115
- resolve ( ) ;
116
- } )
117
- . then ( ( ) => {
118
- const popupIndex = this . getPopupIndex ( view ) ;
119
- const poppedView = this . popupViews [ popupIndex ] ;
120
-
121
- if ( ! exitAnimationDefinition ) {
122
- exitAnimationDefinition = poppedView ?. options ?. animation ?. exitTo ;
123
- }
124
-
125
- // Remove view from tracked popupviews
126
- this . popupViews . splice ( popupIndex , 1 ) ;
130
+ const toClose = [ ] ;
131
+ const popupIndex = this . getPopupIndex ( view ) ;
132
+ const poppedView = this . popupViews [ popupIndex ] ;
133
+ const cleanupAndFinish = ( ) => {
134
+ view . notify ( { eventName : 'closed' , object : view } ) ;
135
+ this . removeChild ( view ) ;
136
+ resolve ( ) ;
137
+ } ;
138
+ // use exitAnimation that is passed in and fallback to the exitAnimation passed in when opening
139
+ const exitAnimationDefinition = exitTo || poppedView ?. options ?. animation ?. exitTo ;
140
+
141
+ // Remove view from tracked popupviews
142
+ this . popupViews . splice ( popupIndex , 1 ) ;
143
+
144
+ toClose . push (
145
+ new Promise < void > ( ( res , rej ) => {
146
+ if ( exitAnimationDefinition ) {
147
+ this . getExitAnimation ( view , exitAnimationDefinition )
148
+ . play ( )
149
+ . then ( res , ( err ) => {
150
+ rej ( new Error ( `Error playing exit animation: ${ err } ` ) ) ;
151
+ } ) ;
152
+ } else {
153
+ res ( ) ;
154
+ }
155
+ } )
156
+ ) ;
127
157
128
- if ( this . shadeCover ) {
129
- // update shade cover with the topmost popupView options (if not specifically told to ignore)
158
+ if ( this . shadeCover ) {
159
+ // Update shade cover with the topmost popupView options (if not specifically told to ignore)
160
+ if ( this . popupViews . length ) {
130
161
if ( ! poppedView ?. options ?. shadeCover ?. ignoreShadeRestore ) {
131
- const shadeCoverOptions = this . popupViews [ this . popupViews . length - 1 ] ? .options ?. shadeCover ;
162
+ const shadeCoverOptions = this . popupViews [ this . popupViews . length - 1 ] . options ?. shadeCover ;
132
163
if ( shadeCoverOptions ) {
133
- return this . updateShadeCover ( this . shadeCover , shadeCoverOptions ) ;
164
+ toClose . push ( this . updateShadeCover ( this . shadeCover , shadeCoverOptions ) ) ;
134
165
}
135
166
}
136
- // remove shade cover animation if this is the last opened popup view
137
- if ( this . popupViews . length === 0 ) {
138
- return this . closeShadeCover ( poppedView ?. options ?. shadeCover ) ;
139
- }
167
+ } else {
168
+ // Remove shade cover animation if this is the last opened popup view
169
+ toClose . push ( this . closeShadeCover ( poppedView ?. options ?. shadeCover ) ) ;
140
170
}
141
- } )
142
- . then ( ( ) => {
143
- if ( exitAnimationDefinition ) {
144
- return this . getExitAnimation ( view , exitAnimationDefinition )
145
- . play ( )
146
- . then ( cleanupAndFinish . bind ( this ) )
147
- . catch ( ( ex ) => Promise . reject ( new Error ( `Error playing exit animation: ${ ex } ` ) ) ) ;
171
+ }
172
+
173
+ Promise . all ( toClose ) . then (
174
+ ( ) => {
175
+ cleanupAndFinish ( ) ;
176
+ } ,
177
+ ( err ) => {
178
+ reject ( err ) ;
148
179
}
149
- cleanupAndFinish ( ) ;
150
- } ) ;
180
+ ) ;
181
+ } ) ;
151
182
}
152
183
153
184
closeAll ( ) : Promise < void [ ] > {
@@ -165,17 +196,28 @@ export class RootLayoutBase extends GridLayout {
165
196
return this . shadeCover ;
166
197
}
167
198
168
- openShadeCover ( options : ShadeCoverOptions = { } ) {
169
- if ( this . shadeCover ) {
170
- if ( Trace . isEnabled ( ) ) {
171
- Trace . write ( `RootLayout shadeCover already open.` , Trace . categories . Layout , Trace . messageType . warn ) ;
199
+ openShadeCover ( options : ShadeCoverOptions = { } ) : Promise < void > {
200
+ return new Promise ( ( resolve ) => {
201
+ if ( this . shadeCover ) {
202
+ if ( Trace . isEnabled ( ) ) {
203
+ Trace . write ( `RootLayout shadeCover already open.` , Trace . categories . Layout , Trace . messageType . warn ) ;
204
+ }
205
+ resolve ( ) ;
206
+ } else {
207
+ // Create the one and only shade cover
208
+ const shadeCover = this . createShadeCover ( ) ;
209
+ shadeCover . on ( 'loaded' , ( ) => {
210
+ this . _initShadeCover ( shadeCover , options ) ;
211
+ this . updateShadeCover ( shadeCover , options ) . then ( ( ) => {
212
+ resolve ( ) ;
213
+ } ) ;
214
+ } ) ;
215
+
216
+ this . shadeCover = shadeCover ;
217
+ // Insert shade cover at index right above the first layout
218
+ this . insertChild ( this . shadeCover , this . staticChildCount + 1 ) ;
172
219
}
173
- } else {
174
- // create the one and only shade cover
175
- this . shadeCover = this . createShadeCover ( options ) ;
176
- // insert shade cover at index right above the first layout
177
- this . insertChild ( this . shadeCover , this . staticChildCount + 1 ) ;
178
- }
220
+ } ) ;
179
221
}
180
222
181
223
closeShadeCover ( shadeCoverOptions : ShadeCoverOptions = { } ) : Promise < void > {
@@ -345,13 +387,9 @@ export class RootLayoutBase extends GridLayout {
345
387
} ;
346
388
}
347
389
348
- private createShadeCover ( shadeOptions : ShadeCoverOptions = { } ) : View {
390
+ private createShadeCover ( ) : View {
349
391
const shadeCover = new GridLayout ( ) ;
350
392
shadeCover . verticalAlignment = 'bottom' ;
351
- shadeCover . on ( 'loaded' , ( ) => {
352
- this . _initShadeCover ( shadeCover , shadeOptions ) ;
353
- this . updateShadeCover ( shadeCover , shadeOptions ) ;
354
- } ) ;
355
393
return shadeCover ;
356
394
}
357
395
0 commit comments