@@ -1140,68 +1140,95 @@ function commitLayoutEffectOnFiber(
1140
1140
}
1141
1141
}
1142
1142
1143
- function abortParentMarkerTransitions (
1143
+ function abortTransitionMarker (
1144
1144
deletedFiber : Fiber ,
1145
- nearestMountedAncestor : Fiber ,
1145
+ currentFiber : Fiber ,
1146
1146
abort : TransitionAbort ,
1147
+ isInDeletedTree : boolean ,
1147
1148
) {
1148
- const deletedFiberInstance : OffscreenInstance = deletedFiber . stateNode ;
1149
-
1150
- let fiber = deletedFiber ;
1151
- let isInDeletedTree = true ;
1152
- while ( fiber !== null ) {
1153
- switch ( fiber . tag ) {
1154
- case TracingMarkerComponent :
1155
- const transitions = deletedFiberInstance . transitions ;
1156
-
1157
- const markerInstance = fiber . stateNode ;
1158
- const markerTransitions = markerInstance . transitions ;
1159
- if ( markerTransitions !== null && transitions !== null ) {
1160
- let abortMarker = false ;
1161
- transitions . forEach ( transition => {
1162
- if ( markerTransitions . has ( transition ) ) {
1163
- abortMarker = true ;
1164
- }
1165
- } ) ;
1149
+ const markerInstance : TracingMarkerInstance = currentFiber . stateNode ;
1150
+ const deletedInstance : OffscreenInstance = deletedFiber . stateNode ;
1151
+ const deletedTransitions = deletedFiber . stateNode . transitions ;
1152
+ const pendingBoundaries = markerInstance . pendingBoundaries ;
1153
+
1154
+ let aborts = markerInstance . aborts ;
1155
+ if ( aborts === null ) {
1156
+ markerInstance . aborts = aborts = [ ] ;
1157
+ }
1166
1158
1167
- if ( abortMarker ) {
1168
- if ( markerInstance . aborts === null ) {
1169
- markerInstance . aborts = new Set ( ) ;
1170
- }
1159
+ aborts . push ( abort ) ;
1160
+ addMarkerIncompleteCallbackToPendingTransition (
1161
+ currentFiber . memoizedProps . name ,
1162
+ deletedTransitions ,
1163
+ aborts ,
1164
+ ) ;
1171
1165
1172
- markerInstance . aborts . add ( abort ) ;
1173
- addMarkerIncompleteCallbackToPendingTransition (
1174
- fiber . memoizedProps . name ,
1175
- transitions ,
1176
- markerInstance . aborts ,
1177
- ) ;
1166
+ // We only want to call onTransitionProgress when the marker hasn't been
1167
+ // deleted
1168
+ if (
1169
+ ! isInDeletedTree &&
1170
+ pendingBoundaries !== null &&
1171
+ pendingBoundaries . has ( deletedInstance )
1172
+ ) {
1173
+ pendingBoundaries . delete ( deletedInstance ) ;
1178
1174
1179
- // We only want to call onTransitionProgress when the marker hasn't been
1180
- // deleted
1181
- if (
1182
- ! isInDeletedTree &&
1183
- markerInstance . pendingBoundaries !== null &&
1184
- markerInstance . pendingBoundaries . has ( deletedFiberInstance )
1185
- ) {
1186
- markerInstance . pendingBoundaries . delete ( deletedFiberInstance ) ;
1175
+ addMarkerProgressCallbackToPendingTransition (
1176
+ currentFiber . memoizedProps . name ,
1177
+ deletedTransitions ,
1178
+ pendingBoundaries ,
1179
+ ) ;
1180
+ }
1181
+ }
1187
1182
1188
- addMarkerProgressCallbackToPendingTransition (
1189
- fiber . memoizedProps . name ,
1190
- transitions ,
1191
- markerInstance . pendingBoundaries ,
1192
- ) ;
1193
- }
1183
+ function abortParentMarkerTransitions (
1184
+ deletedFiber : Fiber ,
1185
+ nearestMountedAncestor : Fiber ,
1186
+ abort : TransitionAbort ,
1187
+ ) {
1188
+ // Find all pending markers that are waiting on child suspense boundaries in the
1189
+ // aborted subtree and cancels them
1190
+ const deletedFiberInstance : OffscreenInstance = deletedFiber . stateNode ;
1191
+ const abortedTransitions = deletedFiberInstance . transitions ;
1192
+ if ( abortedTransitions !== null ) {
1193
+ let fiber = deletedFiber ;
1194
+ let isInDeletedTree = true ;
1195
+ while ( fiber !== null ) {
1196
+ switch ( fiber . tag ) {
1197
+ case TracingMarkerComponent :
1198
+ const markerInstance : TracingMarkerInstance = fiber . stateNode ;
1199
+ const markerTransitions = markerInstance . transitions ;
1200
+ if ( markerTransitions !== null ) {
1201
+ // TODO: Refactor this code. Is there a way to move this code to
1202
+ // the deletions phase instead of calculating it here while making sure
1203
+ // complete is called appropriately?
1204
+ abortedTransitions . forEach ( transition => {
1205
+ // If one of the transitions on the tracing marker is a transition
1206
+ // that was in an aborted subtree, we will abort that tracing marker
1207
+ if (
1208
+ fiber !== null &&
1209
+ markerTransitions . has ( transition ) &&
1210
+ ( markerInstance . aborts === null ||
1211
+ ! markerInstance . aborts . includes ( abort ) )
1212
+ ) {
1213
+ abortTransitionMarker (
1214
+ deletedFiber ,
1215
+ fiber ,
1216
+ abort ,
1217
+ isInDeletedTree ,
1218
+ ) ;
1219
+ }
1220
+ } ) ;
1194
1221
}
1195
- }
1196
- break ;
1197
- case HostRoot :
1198
- const root = fiber . stateNode ;
1199
- const incompleteTransitions = root . incompleteTransitions ;
1200
-
1201
- if ( deletedFiberInstance . transitions !== null ) {
1202
- deletedFiberInstance . transitions . forEach ( transition => {
1203
- if ( incompleteTransitions . has ( transition ) ) {
1204
- const transitionInstance = incompleteTransitions . get ( transition ) ;
1222
+ break ;
1223
+ case HostRoot :
1224
+ const root = fiber . stateNode ;
1225
+ const rootTransitions = root . incompleteTransitions ;
1226
+
1227
+ abortedTransitions . forEach ( transition => {
1228
+ if ( rootTransitions . has ( transition ) ) {
1229
+ const transitionInstance : TracingMarkerInstance = rootTransitions . get (
1230
+ transition ,
1231
+ ) ;
1205
1232
if ( transitionInstance . aborts === null ) {
1206
1233
transitionInstance . aborts = [ ] ;
1207
1234
}
@@ -1217,20 +1244,20 @@ function abortParentMarkerTransitions(
1217
1244
}
1218
1245
}
1219
1246
} ) ;
1220
- }
1221
- break ;
1222
- default :
1223
- break ;
1224
- }
1247
+ break ;
1248
+ default :
1249
+ break ;
1250
+ }
1225
1251
1226
- if (
1227
- nearestMountedAncestor . deletions !== null &&
1228
- nearestMountedAncestor . deletions . includes ( fiber )
1229
- ) {
1230
- isInDeletedTree = false ;
1231
- fiber = nearestMountedAncestor ;
1232
- } else {
1233
- fiber = fiber . return ;
1252
+ if (
1253
+ nearestMountedAncestor . deletions !== null &&
1254
+ nearestMountedAncestor . deletions . includes ( fiber )
1255
+ ) {
1256
+ isInDeletedTree = false ;
1257
+ fiber = nearestMountedAncestor ;
1258
+ } else {
1259
+ fiber = fiber . return ;
1260
+ }
1234
1261
}
1235
1262
}
1236
1263
}
@@ -1280,6 +1307,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1280
1307
pendingMarkers . forEach ( markerInstance => {
1281
1308
const pendingBoundaries = markerInstance . pendingBoundaries ;
1282
1309
const transitions = markerInstance . transitions ;
1310
+ const markerName = markerInstance . name ;
1283
1311
if (
1284
1312
pendingBoundaries !== null &&
1285
1313
! pendingBoundaries . has ( offscreenInstance )
@@ -1290,10 +1318,10 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1290
1318
if ( transitions !== null ) {
1291
1319
if (
1292
1320
markerInstance . tag === TransitionTracingMarker &&
1293
- markerInstance . name !== undefined
1321
+ markerName !== null
1294
1322
) {
1295
1323
addMarkerProgressCallbackToPendingTransition (
1296
- markerInstance . name ,
1324
+ markerName ,
1297
1325
transitions ,
1298
1326
pendingBoundaries ,
1299
1327
) ;
@@ -1317,6 +1345,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1317
1345
pendingMarkers . forEach ( markerInstance => {
1318
1346
const pendingBoundaries = markerInstance . pendingBoundaries ;
1319
1347
const transitions = markerInstance . transitions ;
1348
+ const markerName = markerInstance . name ;
1320
1349
if (
1321
1350
pendingBoundaries !== null &&
1322
1351
pendingBoundaries . has ( offscreenInstance )
@@ -1325,13 +1354,25 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1325
1354
if ( transitions !== null ) {
1326
1355
if (
1327
1356
markerInstance . tag === TransitionTracingMarker &&
1328
- markerInstance . name !== undefined
1357
+ markerName !== null
1329
1358
) {
1330
1359
addMarkerProgressCallbackToPendingTransition (
1331
- markerInstance . name ,
1360
+ markerName ,
1332
1361
transitions ,
1333
1362
pendingBoundaries ,
1334
1363
) ;
1364
+
1365
+ if ( pendingBoundaries . size === 0 ) {
1366
+ if ( markerInstance . aborts === null ) {
1367
+ addMarkerCompleteCallbackToPendingTransition (
1368
+ markerName ,
1369
+ transitions ,
1370
+ ) ;
1371
+ }
1372
+ markerInstance . transitions = null ;
1373
+ markerInstance . pendingBoundaries = null ;
1374
+ markerInstance . aborts = null ;
1375
+ }
1335
1376
} else if ( markerInstance . tag === TransitionRoot ) {
1336
1377
transitions . forEach ( transition => {
1337
1378
addTransitionProgressCallbackToPendingTransition (
@@ -2097,28 +2138,6 @@ function commitDeletionEffectsOnFiber(
2097
2138
offscreenSubtreeWasHidden =
2098
2139
prevOffscreenSubtreeWasHidden || deletedFiber . memoizedState !== null ;
2099
2140
2100
- if ( enableTransitionTracing ) {
2101
- // We need to mark this fiber's parents as deleted
2102
- const instance : OffscreenInstance = deletedFiber . stateNode ;
2103
- const transitions = instance . transitions ;
2104
- if ( transitions !== null ) {
2105
- let name = null ;
2106
- const parent = deletedFiber . return ;
2107
- if (
2108
- parent !== null &&
2109
- parent . tag === SuspenseComponent &&
2110
- parent . memoizedProps . unstable_name
2111
- ) {
2112
- name = parent . memoizedProps . unstable_name ;
2113
- }
2114
-
2115
- abortParentMarkerTransitions ( deletedFiber , nearestMountedAncestor , {
2116
- reason : 'suspense' ,
2117
- name,
2118
- } ) ;
2119
- }
2120
- }
2121
-
2122
2141
recursivelyTraverseDeletionEffects (
2123
2142
finishedRoot ,
2124
2143
nearestMountedAncestor ,
@@ -2134,21 +2153,36 @@ function commitDeletionEffectsOnFiber(
2134
2153
}
2135
2154
break ;
2136
2155
}
2156
+ case SuspenseComponent : {
2157
+ if ( enableTransitionTracing ) {
2158
+ // We need to mark this fiber's parents as deleted
2159
+ const offscreenFiber : Fiber = ( deletedFiber . child : any ) ;
2160
+ const instance : OffscreenInstance = offscreenFiber . stateNode ;
2161
+ const transitions = instance . transitions ;
2162
+ if ( transitions !== null ) {
2163
+ abortParentMarkerTransitions ( offscreenFiber , nearestMountedAncestor , {
2164
+ reason : 'suspense' ,
2165
+ name : deletedFiber . memoizedProps . unstable_name || null ,
2166
+ } ) ;
2167
+ }
2168
+ }
2169
+ recursivelyTraverseDeletionEffects (
2170
+ finishedRoot ,
2171
+ nearestMountedAncestor ,
2172
+ deletedFiber ,
2173
+ ) ;
2174
+ return ;
2175
+ }
2137
2176
case TracingMarkerComponent : {
2138
2177
if ( enableTransitionTracing ) {
2139
2178
// We need to mark this fiber's parents as deleted
2140
2179
const instance : TracingMarkerInstance = deletedFiber . stateNode ;
2141
2180
const transitions = instance . transitions ;
2142
2181
if ( transitions !== null ) {
2143
- const abort = {
2182
+ abortParentMarkerTransitions ( deletedFiber , nearestMountedAncestor , {
2144
2183
reason : 'marker' ,
2145
2184
name : deletedFiber . memoizedProps . name ,
2146
- } ;
2147
- abortParentMarkerTransitions (
2148
- deletedFiber ,
2149
- nearestMountedAncestor ,
2150
- abort ,
2151
- ) ;
2185
+ } ) ;
2152
2186
}
2153
2187
}
2154
2188
recursivelyTraverseDeletionEffects (
@@ -3134,6 +3168,7 @@ function commitOffscreenPassiveMountEffects(
3134
3168
3135
3169
commitTransitionProgress ( finishedWork ) ;
3136
3170
3171
+ // TODO: Refactor this into an if/else branch
3137
3172
if ( ! isHidden ) {
3138
3173
instance . transitions = null ;
3139
3174
instance . pendingMarkers = null ;
@@ -3168,18 +3203,14 @@ function commitCachePassiveMountEffect(
3168
3203
function commitTracingMarkerPassiveMountEffect ( finishedWork : Fiber ) {
3169
3204
// Get the transitions that were initiatized during the render
3170
3205
// and add a start transition callback for each of them
3206
+ // We will only call this on initial mount of the tracing marker
3207
+ // only if there are no suspense children
3171
3208
const instance = finishedWork . stateNode ;
3172
- if (
3173
- instance . transitions !== null &&
3174
- ( instance . pendingBoundaries === null ||
3175
- instance . pendingBoundaries . size === 0 )
3176
- ) {
3177
- if ( instance . aborts === null ) {
3178
- addMarkerCompleteCallbackToPendingTransition (
3179
- finishedWork . memoizedProps . name ,
3180
- instance . transitions ,
3181
- ) ;
3182
- }
3209
+ if ( instance . transitions !== null && instance . pendingBoundaries === null ) {
3210
+ addMarkerCompleteCallbackToPendingTransition (
3211
+ finishedWork . memoizedProps . name ,
3212
+ instance . transitions ,
3213
+ ) ;
3183
3214
instance . transitions = null ;
3184
3215
instance . pendingBoundaries = null ;
3185
3216
instance . aborts = null ;
@@ -3674,21 +3705,6 @@ function commitAtomicPassiveEffects(
3674
3705
}
3675
3706
break ;
3676
3707
}
3677
- case TracingMarkerComponent : {
3678
- if ( enableTransitionTracing ) {
3679
- recursivelyTraverseAtomicPassiveEffects (
3680
- finishedRoot ,
3681
- finishedWork ,
3682
- committedLanes ,
3683
- committedTransitions ,
3684
- ) ;
3685
- if ( flags & Passive ) {
3686
- commitTracingMarkerPassiveMountEffect ( finishedWork ) ;
3687
- }
3688
- break ;
3689
- }
3690
- // Intentional fallthrough to next branch
3691
- }
3692
3708
// eslint-disable-next-line-no-fallthrough
3693
3709
default : {
3694
3710
recursivelyTraverseAtomicPassiveEffects (
0 commit comments