react-dom 17.0.0-rc.2 → 17.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /** @license React v17.0.0-rc.2
1
+ /** @license React v17.0.2
2
2
  * react-dom.development.js
3
3
  *
4
4
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -4130,7 +4130,7 @@ function set(key, value) {
4130
4130
 
4131
4131
  // Don't change these two values. They're used by React Dev Tools.
4132
4132
  var NoFlags =
4133
- /* */
4133
+ /* */
4134
4134
  0;
4135
4135
  var PerformedWork =
4136
4136
  /* */
@@ -4166,6 +4166,10 @@ var Snapshot =
4166
4166
  var Passive =
4167
4167
  /* */
4168
4168
  512; // TODO (effects) Remove this bit once the new reconciler is synced to the old.
4169
+
4170
+ var PassiveUnmountPendingDev =
4171
+ /* */
4172
+ 8192;
4169
4173
  var Hydrating =
4170
4174
  /* */
4171
4175
  1024;
@@ -4190,33 +4194,6 @@ var ShouldCapture =
4190
4194
  var ForceUpdateForLegacySuspense =
4191
4195
  /* */
4192
4196
  16384; // Static tags describe aspects of a fiber that are not specific to a render,
4193
- // e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
4194
- // This enables us to defer more work in the unmount case,
4195
- // since we can defer traversing the tree during layout to look for Passive effects,
4196
- // and instead rely on the static flag as a signal that there may be cleanup work.
4197
-
4198
- var PassiveStatic =
4199
- /* */
4200
- 32768; // Union of side effect groupings as pertains to subtreeFlags
4201
-
4202
- var BeforeMutationMask =
4203
- /* */
4204
- 778;
4205
- var MutationMask =
4206
- /* */
4207
- 1182;
4208
- var LayoutMask =
4209
- /* */
4210
- 164;
4211
- var PassiveMask =
4212
- /* */
4213
- 520; // Union of tags that don't get reset on clones.
4214
- // This allows certain concepts to persist without recalculting them,
4215
- // e.g. whether a subtree contains passive effects or portals.
4216
-
4217
- var StaticMask =
4218
- /* */
4219
- 32768;
4220
4197
 
4221
4198
  var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4222
4199
  function getNearestMountedFiber(fiber) {
@@ -5760,7 +5737,15 @@ function higherPriorityLane(a, b) {
5760
5737
  return a !== NoLane && a < b ? a : b;
5761
5738
  }
5762
5739
  function createLaneMap(initial) {
5763
- return new Array(TotalLanes).fill(initial);
5740
+ // Intentionally pushing one by one.
5741
+ // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5742
+ var laneMap = [];
5743
+
5744
+ for (var i = 0; i < TotalLanes; i++) {
5745
+ laneMap.push(initial);
5746
+ }
5747
+
5748
+ return laneMap;
5764
5749
  }
5765
5750
  function markRootUpdated(root, updateLane, eventTime) {
5766
5751
  root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But
@@ -5801,9 +5786,6 @@ function markRootSuspended(root, suspendedLanes) {
5801
5786
  function markRootPinged(root, pingedLanes, eventTime) {
5802
5787
  root.pingedLanes |= root.suspendedLanes & pingedLanes;
5803
5788
  }
5804
- function markRootExpired(root, expiredLanes) {
5805
- root.expiredLanes |= expiredLanes & root.pendingLanes;
5806
- }
5807
5789
  function markDiscreteUpdatesExpired(root) {
5808
5790
  root.expiredLanes |= InputDiscreteLanes & root.pendingLanes;
5809
5791
  }
@@ -6149,136 +6131,144 @@ function getEventCharCode(nativeEvent) {
6149
6131
  return 0;
6150
6132
  }
6151
6133
 
6152
- /**
6153
- * @interface Event
6154
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
6155
- */
6156
- var EventInterface = {
6157
- eventPhase: 0,
6158
- bubbles: 0,
6159
- cancelable: 0,
6160
- timeStamp: function (event) {
6161
- return event.timeStamp || Date.now();
6162
- },
6163
- defaultPrevented: 0,
6164
- isTrusted: 0
6165
- };
6166
-
6167
6134
  function functionThatReturnsTrue() {
6168
6135
  return true;
6169
6136
  }
6170
6137
 
6171
6138
  function functionThatReturnsFalse() {
6172
6139
  return false;
6173
- }
6174
- /**
6175
- * Synthetic events are dispatched by event plugins, typically in response to a
6176
- * top-level event delegation handler.
6177
- *
6178
- * These systems should generally use pooling to reduce the frequency of garbage
6179
- * collection. The system should check `isPersistent` to determine whether the
6180
- * event should be released into the pool after being dispatched. Users that
6181
- * need a persisted event should invoke `persist`.
6182
- *
6183
- * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6184
- * normalizing browser quirks. Subclasses do not necessarily have to implement a
6185
- * DOM interface; custom application-specific events can also subclass this.
6186
- */
6140
+ } // This is intentionally a factory so that we have different returned constructors.
6141
+ // If we had a single constructor, it would be megamorphic and engines would deopt.
6187
6142
 
6188
6143
 
6189
- function SyntheticEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6190
- var Interface = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : EventInterface;
6191
- this._reactName = reactName;
6192
- this._targetInst = targetInst;
6193
- this.type = reactEventType;
6194
- this.nativeEvent = nativeEvent;
6195
- this.target = nativeEventTarget;
6196
- this.currentTarget = null;
6144
+ function createSyntheticEvent(Interface) {
6145
+ /**
6146
+ * Synthetic events are dispatched by event plugins, typically in response to a
6147
+ * top-level event delegation handler.
6148
+ *
6149
+ * These systems should generally use pooling to reduce the frequency of garbage
6150
+ * collection. The system should check `isPersistent` to determine whether the
6151
+ * event should be released into the pool after being dispatched. Users that
6152
+ * need a persisted event should invoke `persist`.
6153
+ *
6154
+ * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6155
+ * normalizing browser quirks. Subclasses do not necessarily have to implement a
6156
+ * DOM interface; custom application-specific events can also subclass this.
6157
+ */
6158
+ function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6159
+ this._reactName = reactName;
6160
+ this._targetInst = targetInst;
6161
+ this.type = reactEventType;
6162
+ this.nativeEvent = nativeEvent;
6163
+ this.target = nativeEventTarget;
6164
+ this.currentTarget = null;
6165
+
6166
+ for (var _propName in Interface) {
6167
+ if (!Interface.hasOwnProperty(_propName)) {
6168
+ continue;
6169
+ }
6170
+
6171
+ var normalize = Interface[_propName];
6197
6172
 
6198
- for (var _propName in Interface) {
6199
- if (!Interface.hasOwnProperty(_propName)) {
6200
- continue;
6173
+ if (normalize) {
6174
+ this[_propName] = normalize(nativeEvent);
6175
+ } else {
6176
+ this[_propName] = nativeEvent[_propName];
6177
+ }
6201
6178
  }
6202
6179
 
6203
- var normalize = Interface[_propName];
6180
+ var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6204
6181
 
6205
- if (normalize) {
6206
- this[_propName] = normalize(nativeEvent);
6182
+ if (defaultPrevented) {
6183
+ this.isDefaultPrevented = functionThatReturnsTrue;
6207
6184
  } else {
6208
- this[_propName] = nativeEvent[_propName];
6185
+ this.isDefaultPrevented = functionThatReturnsFalse;
6209
6186
  }
6187
+
6188
+ this.isPropagationStopped = functionThatReturnsFalse;
6189
+ return this;
6210
6190
  }
6211
6191
 
6212
- var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6192
+ _assign(SyntheticBaseEvent.prototype, {
6193
+ preventDefault: function () {
6194
+ this.defaultPrevented = true;
6195
+ var event = this.nativeEvent;
6213
6196
 
6214
- if (defaultPrevented) {
6215
- this.isDefaultPrevented = functionThatReturnsTrue;
6216
- } else {
6217
- this.isDefaultPrevented = functionThatReturnsFalse;
6218
- }
6197
+ if (!event) {
6198
+ return;
6199
+ }
6219
6200
 
6220
- this.isPropagationStopped = functionThatReturnsFalse;
6221
- return this;
6222
- }
6201
+ if (event.preventDefault) {
6202
+ event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6203
+ } else if (typeof event.returnValue !== 'unknown') {
6204
+ event.returnValue = false;
6205
+ }
6223
6206
 
6224
- _assign(SyntheticEvent.prototype, {
6225
- preventDefault: function () {
6226
- this.defaultPrevented = true;
6227
- var event = this.nativeEvent;
6207
+ this.isDefaultPrevented = functionThatReturnsTrue;
6208
+ },
6209
+ stopPropagation: function () {
6210
+ var event = this.nativeEvent;
6228
6211
 
6229
- if (!event) {
6230
- return;
6231
- }
6212
+ if (!event) {
6213
+ return;
6214
+ }
6232
6215
 
6233
- if (event.preventDefault) {
6234
- event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6235
- } else if (typeof event.returnValue !== 'unknown') {
6236
- event.returnValue = false;
6237
- }
6216
+ if (event.stopPropagation) {
6217
+ event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6218
+ } else if (typeof event.cancelBubble !== 'unknown') {
6219
+ // The ChangeEventPlugin registers a "propertychange" event for
6220
+ // IE. This event does not support bubbling or cancelling, and
6221
+ // any references to cancelBubble throw "Member not found". A
6222
+ // typeof check of "unknown" circumvents this issue (and is also
6223
+ // IE specific).
6224
+ event.cancelBubble = true;
6225
+ }
6238
6226
 
6239
- this.isDefaultPrevented = functionThatReturnsTrue;
6240
- },
6241
- stopPropagation: function () {
6242
- var event = this.nativeEvent;
6227
+ this.isPropagationStopped = functionThatReturnsTrue;
6228
+ },
6243
6229
 
6244
- if (!event) {
6245
- return;
6246
- }
6230
+ /**
6231
+ * We release all dispatched `SyntheticEvent`s after each event loop, adding
6232
+ * them back into the pool. This allows a way to hold onto a reference that
6233
+ * won't be added back into the pool.
6234
+ */
6235
+ persist: function () {// Modern event system doesn't use pooling.
6236
+ },
6247
6237
 
6248
- if (event.stopPropagation) {
6249
- event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6250
- } else if (typeof event.cancelBubble !== 'unknown') {
6251
- // The ChangeEventPlugin registers a "propertychange" event for
6252
- // IE. This event does not support bubbling or cancelling, and
6253
- // any references to cancelBubble throw "Member not found". A
6254
- // typeof check of "unknown" circumvents this issue (and is also
6255
- // IE specific).
6256
- event.cancelBubble = true;
6257
- }
6238
+ /**
6239
+ * Checks if this event should be released back into the pool.
6240
+ *
6241
+ * @return {boolean} True if this should not be released, false otherwise.
6242
+ */
6243
+ isPersistent: functionThatReturnsTrue
6244
+ });
6258
6245
 
6259
- this.isPropagationStopped = functionThatReturnsTrue;
6260
- },
6246
+ return SyntheticBaseEvent;
6247
+ }
6248
+ /**
6249
+ * @interface Event
6250
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
6251
+ */
6261
6252
 
6262
- /**
6263
- * We release all dispatched `SyntheticEvent`s after each event loop, adding
6264
- * them back into the pool. This allows a way to hold onto a reference that
6265
- * won't be added back into the pool.
6266
- */
6267
- persist: function () {// Modern event system doesn't use pooling.
6268
- },
6269
6253
 
6270
- /**
6271
- * Checks if this event should be released back into the pool.
6272
- *
6273
- * @return {boolean} True if this should not be released, false otherwise.
6274
- */
6275
- isPersistent: functionThatReturnsTrue
6276
- });
6254
+ var EventInterface = {
6255
+ eventPhase: 0,
6256
+ bubbles: 0,
6257
+ cancelable: 0,
6258
+ timeStamp: function (event) {
6259
+ return event.timeStamp || Date.now();
6260
+ },
6261
+ defaultPrevented: 0,
6262
+ isTrusted: 0
6263
+ };
6264
+ var SyntheticEvent = createSyntheticEvent(EventInterface);
6277
6265
 
6278
6266
  var UIEventInterface = _assign({}, EventInterface, {
6279
6267
  view: 0,
6280
6268
  detail: 0
6281
6269
  });
6270
+
6271
+ var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6282
6272
  var lastMovementX;
6283
6273
  var lastMovementY;
6284
6274
  var lastMouseEvent;
@@ -6339,6 +6329,8 @@ var MouseEventInterface = _assign({}, UIEventInterface, {
6339
6329
  return lastMovementY;
6340
6330
  }
6341
6331
  });
6332
+
6333
+ var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
6342
6334
  /**
6343
6335
  * @interface DragEvent
6344
6336
  * @see http://www.w3.org/TR/DOM-Level-3-Events/
@@ -6347,6 +6339,8 @@ var MouseEventInterface = _assign({}, UIEventInterface, {
6347
6339
  var DragEventInterface = _assign({}, MouseEventInterface, {
6348
6340
  dataTransfer: 0
6349
6341
  });
6342
+
6343
+ var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
6350
6344
  /**
6351
6345
  * @interface FocusEvent
6352
6346
  * @see http://www.w3.org/TR/DOM-Level-3-Events/
@@ -6355,6 +6349,8 @@ var DragEventInterface = _assign({}, MouseEventInterface, {
6355
6349
  var FocusEventInterface = _assign({}, UIEventInterface, {
6356
6350
  relatedTarget: 0
6357
6351
  });
6352
+
6353
+ var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
6358
6354
  /**
6359
6355
  * @interface Event
6360
6356
  * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
@@ -6366,6 +6362,8 @@ var AnimationEventInterface = _assign({}, EventInterface, {
6366
6362
  elapsedTime: 0,
6367
6363
  pseudoElement: 0
6368
6364
  });
6365
+
6366
+ var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
6369
6367
  /**
6370
6368
  * @interface Event
6371
6369
  * @see http://www.w3.org/TR/clipboard-apis/
@@ -6376,6 +6374,8 @@ var ClipboardEventInterface = _assign({}, EventInterface, {
6376
6374
  return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
6377
6375
  }
6378
6376
  });
6377
+
6378
+ var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
6379
6379
  /**
6380
6380
  * @interface Event
6381
6381
  * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
@@ -6384,6 +6384,8 @@ var ClipboardEventInterface = _assign({}, EventInterface, {
6384
6384
  var CompositionEventInterface = _assign({}, EventInterface, {
6385
6385
  data: 0
6386
6386
  });
6387
+
6388
+ var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
6387
6389
  /**
6388
6390
  * @interface Event
6389
6391
  * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
@@ -6391,7 +6393,7 @@ var CompositionEventInterface = _assign({}, EventInterface, {
6391
6393
  */
6392
6394
  // Happens to share the same list for now.
6393
6395
 
6394
- var InputEventInterface = CompositionEventInterface;
6396
+ var SyntheticInputEvent = SyntheticCompositionEvent;
6395
6397
  /**
6396
6398
  * Normalization of deprecated HTML5 `key` values
6397
6399
  * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
@@ -6575,6 +6577,8 @@ var KeyboardEventInterface = _assign({}, UIEventInterface, {
6575
6577
  return 0;
6576
6578
  }
6577
6579
  });
6580
+
6581
+ var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
6578
6582
  /**
6579
6583
  * @interface PointerEvent
6580
6584
  * @see http://www.w3.org/TR/pointerevents/
@@ -6592,6 +6596,8 @@ var PointerEventInterface = _assign({}, MouseEventInterface, {
6592
6596
  pointerType: 0,
6593
6597
  isPrimary: 0
6594
6598
  });
6599
+
6600
+ var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
6595
6601
  /**
6596
6602
  * @interface TouchEvent
6597
6603
  * @see http://www.w3.org/TR/touch-events/
@@ -6607,6 +6613,8 @@ var TouchEventInterface = _assign({}, UIEventInterface, {
6607
6613
  shiftKey: 0,
6608
6614
  getModifierState: getEventModifierState
6609
6615
  });
6616
+
6617
+ var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
6610
6618
  /**
6611
6619
  * @interface Event
6612
6620
  * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
@@ -6618,6 +6626,8 @@ var TransitionEventInterface = _assign({}, EventInterface, {
6618
6626
  elapsedTime: 0,
6619
6627
  pseudoElement: 0
6620
6628
  });
6629
+
6630
+ var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
6621
6631
  /**
6622
6632
  * @interface WheelEvent
6623
6633
  * @see http://www.w3.org/TR/DOM-Level-3-Events/
@@ -6641,6 +6651,8 @@ var WheelEventInterface = _assign({}, MouseEventInterface, {
6641
6651
  deltaMode: 0
6642
6652
  });
6643
6653
 
6654
+ var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
6655
+
6644
6656
  var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
6645
6657
 
6646
6658
  var START_KEYCODE = 229;
@@ -6805,18 +6817,25 @@ function extractCompositionEvent(dispatchQueue, domEventName, targetInst, native
6805
6817
  }
6806
6818
  }
6807
6819
 
6808
- var event = new SyntheticEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget, CompositionEventInterface);
6809
- accumulateTwoPhaseListeners(targetInst, dispatchQueue, event);
6820
+ var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
6810
6821
 
6811
- if (fallbackData) {
6812
- // Inject data generated from fallback path into the synthetic event.
6813
- // This matches the property of native CompositionEventInterface.
6814
- event.data = fallbackData;
6815
- } else {
6816
- var customData = getDataFromCustomEvent(nativeEvent);
6822
+ if (listeners.length > 0) {
6823
+ var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
6824
+ dispatchQueue.push({
6825
+ event: event,
6826
+ listeners: listeners
6827
+ });
6817
6828
 
6818
- if (customData !== null) {
6819
- event.data = customData;
6829
+ if (fallbackData) {
6830
+ // Inject data generated from fallback path into the synthetic event.
6831
+ // This matches the property of native CompositionEventInterface.
6832
+ event.data = fallbackData;
6833
+ } else {
6834
+ var customData = getDataFromCustomEvent(nativeEvent);
6835
+
6836
+ if (customData !== null) {
6837
+ event.data = customData;
6838
+ }
6820
6839
  }
6821
6840
  }
6822
6841
  }
@@ -6958,9 +6977,16 @@ function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, native
6958
6977
  return null;
6959
6978
  }
6960
6979
 
6961
- var event = new SyntheticEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget, InputEventInterface);
6962
- accumulateTwoPhaseListeners(targetInst, dispatchQueue, event);
6963
- event.data = chars;
6980
+ var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
6981
+
6982
+ if (listeners.length > 0) {
6983
+ var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
6984
+ dispatchQueue.push({
6985
+ event: event,
6986
+ listeners: listeners
6987
+ });
6988
+ event.data = chars;
6989
+ }
6964
6990
  }
6965
6991
  /**
6966
6992
  * Create an `onBeforeInput` event to match
@@ -7058,10 +7084,17 @@ function registerEvents$1() {
7058
7084
  }
7059
7085
 
7060
7086
  function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7061
- var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target); // Flag this event loop as needing state restore.
7062
-
7087
+ // Flag this event loop as needing state restore.
7063
7088
  enqueueStateRestore(target);
7064
- accumulateTwoPhaseListeners(inst, dispatchQueue, event);
7089
+ var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7090
+
7091
+ if (listeners.length > 0) {
7092
+ var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7093
+ dispatchQueue.push({
7094
+ event: event,
7095
+ listeners: listeners
7096
+ });
7097
+ }
7065
7098
  }
7066
7099
  /**
7067
7100
  * For IE shims
@@ -7371,13 +7404,13 @@ function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, n
7371
7404
  return;
7372
7405
  }
7373
7406
 
7374
- var eventInterface = MouseEventInterface;
7407
+ var SyntheticEventCtor = SyntheticMouseEvent;
7375
7408
  var leaveEventType = 'onMouseLeave';
7376
7409
  var enterEventType = 'onMouseEnter';
7377
7410
  var eventTypePrefix = 'mouse';
7378
7411
 
7379
7412
  if (domEventName === 'pointerout' || domEventName === 'pointerover') {
7380
- eventInterface = PointerEventInterface;
7413
+ SyntheticEventCtor = SyntheticPointerEvent;
7381
7414
  leaveEventType = 'onPointerLeave';
7382
7415
  enterEventType = 'onPointerEnter';
7383
7416
  eventTypePrefix = 'pointer';
@@ -7385,7 +7418,7 @@ function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, n
7385
7418
 
7386
7419
  var fromNode = from == null ? win : getNodeFromInstance(from);
7387
7420
  var toNode = to == null ? win : getNodeFromInstance(to);
7388
- var leave = new SyntheticEvent(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget, eventInterface);
7421
+ var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
7389
7422
  leave.target = fromNode;
7390
7423
  leave.relatedTarget = toNode;
7391
7424
  var enter = null; // We should only process this nativeEvent if we are processing
@@ -7394,7 +7427,7 @@ function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, n
7394
7427
  var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
7395
7428
 
7396
7429
  if (nativeTargetInst === targetInst) {
7397
- var enterEvent = new SyntheticEvent(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget, eventInterface);
7430
+ var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
7398
7431
  enterEvent.target = toNode;
7399
7432
  enterEvent.relatedTarget = fromNode;
7400
7433
  enter = enterEvent;
@@ -7927,9 +7960,16 @@ function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
7927
7960
 
7928
7961
  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
7929
7962
  lastSelection = currentSelection;
7930
- var syntheticEvent = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
7931
- syntheticEvent.target = activeElement$1;
7932
- accumulateTwoPhaseListeners(activeElementInst$1, dispatchQueue, syntheticEvent);
7963
+ var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
7964
+
7965
+ if (listeners.length > 0) {
7966
+ var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
7967
+ dispatchQueue.push({
7968
+ event: event,
7969
+ listeners: listeners
7970
+ });
7971
+ event.target = activeElement$1;
7972
+ }
7933
7973
  }
7934
7974
  }
7935
7975
  /**
@@ -8011,7 +8051,7 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8011
8051
  return;
8012
8052
  }
8013
8053
 
8014
- var EventInterface;
8054
+ var SyntheticEventCtor = SyntheticEvent;
8015
8055
  var reactEventType = domEventName;
8016
8056
 
8017
8057
  switch (domEventName) {
@@ -8027,22 +8067,22 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8027
8067
 
8028
8068
  case 'keydown':
8029
8069
  case 'keyup':
8030
- EventInterface = KeyboardEventInterface;
8070
+ SyntheticEventCtor = SyntheticKeyboardEvent;
8031
8071
  break;
8032
8072
 
8033
8073
  case 'focusin':
8034
8074
  reactEventType = 'focus';
8035
- EventInterface = FocusEventInterface;
8075
+ SyntheticEventCtor = SyntheticFocusEvent;
8036
8076
  break;
8037
8077
 
8038
8078
  case 'focusout':
8039
8079
  reactEventType = 'blur';
8040
- EventInterface = FocusEventInterface;
8080
+ SyntheticEventCtor = SyntheticFocusEvent;
8041
8081
  break;
8042
8082
 
8043
8083
  case 'beforeblur':
8044
8084
  case 'afterblur':
8045
- EventInterface = FocusEventInterface;
8085
+ SyntheticEventCtor = SyntheticFocusEvent;
8046
8086
  break;
8047
8087
 
8048
8088
  case 'click':
@@ -8065,7 +8105,7 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8065
8105
  case 'mouseout':
8066
8106
  case 'mouseover':
8067
8107
  case 'contextmenu':
8068
- EventInterface = MouseEventInterface;
8108
+ SyntheticEventCtor = SyntheticMouseEvent;
8069
8109
  break;
8070
8110
 
8071
8111
  case 'drag':
@@ -8076,38 +8116,38 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8076
8116
  case 'dragover':
8077
8117
  case 'dragstart':
8078
8118
  case 'drop':
8079
- EventInterface = DragEventInterface;
8119
+ SyntheticEventCtor = SyntheticDragEvent;
8080
8120
  break;
8081
8121
 
8082
8122
  case 'touchcancel':
8083
8123
  case 'touchend':
8084
8124
  case 'touchmove':
8085
8125
  case 'touchstart':
8086
- EventInterface = TouchEventInterface;
8126
+ SyntheticEventCtor = SyntheticTouchEvent;
8087
8127
  break;
8088
8128
 
8089
8129
  case ANIMATION_END:
8090
8130
  case ANIMATION_ITERATION:
8091
8131
  case ANIMATION_START:
8092
- EventInterface = AnimationEventInterface;
8132
+ SyntheticEventCtor = SyntheticAnimationEvent;
8093
8133
  break;
8094
8134
 
8095
8135
  case TRANSITION_END:
8096
- EventInterface = TransitionEventInterface;
8136
+ SyntheticEventCtor = SyntheticTransitionEvent;
8097
8137
  break;
8098
8138
 
8099
8139
  case 'scroll':
8100
- EventInterface = UIEventInterface;
8140
+ SyntheticEventCtor = SyntheticUIEvent;
8101
8141
  break;
8102
8142
 
8103
8143
  case 'wheel':
8104
- EventInterface = WheelEventInterface;
8144
+ SyntheticEventCtor = SyntheticWheelEvent;
8105
8145
  break;
8106
8146
 
8107
8147
  case 'copy':
8108
8148
  case 'cut':
8109
8149
  case 'paste':
8110
- EventInterface = ClipboardEventInterface;
8150
+ SyntheticEventCtor = SyntheticClipboardEvent;
8111
8151
  break;
8112
8152
 
8113
8153
  case 'gotpointercapture':
@@ -8118,11 +8158,10 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8118
8158
  case 'pointerout':
8119
8159
  case 'pointerover':
8120
8160
  case 'pointerup':
8121
- EventInterface = PointerEventInterface;
8161
+ SyntheticEventCtor = SyntheticPointerEvent;
8122
8162
  break;
8123
8163
  }
8124
8164
 
8125
- var event = new SyntheticEvent(reactName, reactEventType, null, nativeEvent, nativeEventTarget, EventInterface);
8126
8165
  var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8127
8166
 
8128
8167
  {
@@ -8135,7 +8174,18 @@ function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, n
8135
8174
  // Then we can remove this special list.
8136
8175
  // This is a breaking change that can wait until React 18.
8137
8176
  domEventName === 'scroll';
8138
- accumulateSinglePhaseListeners(targetInst, dispatchQueue, event, inCapturePhase, accumulateTargetOnly);
8177
+
8178
+ var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8179
+
8180
+ if (_listeners.length > 0) {
8181
+ // Intentionally create event lazily.
8182
+ var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8183
+
8184
+ dispatchQueue.push({
8185
+ event: _event,
8186
+ listeners: _listeners
8187
+ });
8188
+ }
8139
8189
  }
8140
8190
  }
8141
8191
 
@@ -8467,19 +8517,12 @@ function createDispatchListener(instance, listener, currentTarget) {
8467
8517
  };
8468
8518
  }
8469
8519
 
8470
- function createDispatchEntry(event, listeners) {
8471
- return {
8472
- event: event,
8473
- listeners: listeners
8474
- };
8475
- }
8476
-
8477
- function accumulateSinglePhaseListeners(targetFiber, dispatchQueue, event, inCapturePhase, accumulateTargetOnly) {
8478
- var bubbled = event._reactName;
8479
- var captured = bubbled !== null ? bubbled + 'Capture' : null;
8520
+ function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly) {
8521
+ var captureName = reactName !== null ? reactName + 'Capture' : null;
8522
+ var reactEventName = inCapturePhase ? captureName : reactName;
8480
8523
  var listeners = [];
8481
8524
  var instance = targetFiber;
8482
- var targetType = event.nativeEvent.type; // Accumulate all instances and listeners via the target -> root path.
8525
+ var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
8483
8526
 
8484
8527
  while (instance !== null) {
8485
8528
  var _instance2 = instance,
@@ -8487,22 +8530,14 @@ function accumulateSinglePhaseListeners(targetFiber, dispatchQueue, event, inCap
8487
8530
  tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8488
8531
 
8489
8532
  if (tag === HostComponent && stateNode !== null) {
8490
- var currentTarget = stateNode;
8491
-
8533
+ lastHostComponent = stateNode; // createEventHandle listeners
8492
8534
 
8493
- if (captured !== null && inCapturePhase) {
8494
- var captureListener = getListener(instance, captured);
8495
8535
 
8496
- if (captureListener != null) {
8497
- listeners.push(createDispatchListener(instance, captureListener, currentTarget));
8498
- }
8499
- }
8500
-
8501
- if (bubbled !== null && !inCapturePhase) {
8502
- var bubbleListener = getListener(instance, bubbled);
8536
+ if (reactEventName !== null) {
8537
+ var listener = getListener(instance, reactEventName);
8503
8538
 
8504
- if (bubbleListener != null) {
8505
- listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8539
+ if (listener != null) {
8540
+ listeners.push(createDispatchListener(instance, listener, lastHostComponent));
8506
8541
  }
8507
8542
  }
8508
8543
  } // If we are only accumulating events for the target, then we don't
@@ -8517,9 +8552,7 @@ function accumulateSinglePhaseListeners(targetFiber, dispatchQueue, event, inCap
8517
8552
  instance = instance.return;
8518
8553
  }
8519
8554
 
8520
- if (listeners.length !== 0) {
8521
- dispatchQueue.push(createDispatchEntry(event, listeners));
8522
- }
8555
+ return listeners;
8523
8556
  } // We should only use this function for:
8524
8557
  // - BeforeInputEventPlugin
8525
8558
  // - ChangeEventPlugin
@@ -8528,9 +8561,8 @@ function accumulateSinglePhaseListeners(targetFiber, dispatchQueue, event, inCap
8528
8561
  // in the bubble phase, so we need to accumulate two
8529
8562
  // phase event listeners (via emulation).
8530
8563
 
8531
- function accumulateTwoPhaseListeners(targetFiber, dispatchQueue, event) {
8532
- var bubbled = event._reactName;
8533
- var captured = bubbled !== null ? bubbled + 'Capture' : null;
8564
+ function accumulateTwoPhaseListeners(targetFiber, reactName) {
8565
+ var captureName = reactName + 'Capture';
8534
8566
  var listeners = [];
8535
8567
  var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
8536
8568
 
@@ -8540,31 +8572,24 @@ function accumulateTwoPhaseListeners(targetFiber, dispatchQueue, event) {
8540
8572
  tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8541
8573
 
8542
8574
  if (tag === HostComponent && stateNode !== null) {
8543
- var currentTarget = stateNode; // Standard React on* listeners, i.e. onClick prop
8544
-
8545
- if (captured !== null) {
8546
- var captureListener = getListener(instance, captured);
8575
+ var currentTarget = stateNode;
8576
+ var captureListener = getListener(instance, captureName);
8547
8577
 
8548
- if (captureListener != null) {
8549
- listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8550
- }
8578
+ if (captureListener != null) {
8579
+ listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8551
8580
  }
8552
8581
 
8553
- if (bubbled !== null) {
8554
- var bubbleListener = getListener(instance, bubbled);
8582
+ var bubbleListener = getListener(instance, reactName);
8555
8583
 
8556
- if (bubbleListener != null) {
8557
- listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8558
- }
8584
+ if (bubbleListener != null) {
8585
+ listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8559
8586
  }
8560
8587
  }
8561
8588
 
8562
8589
  instance = instance.return;
8563
8590
  }
8564
8591
 
8565
- if (listeners.length !== 0) {
8566
- dispatchQueue.push(createDispatchEntry(event, listeners));
8567
- }
8592
+ return listeners;
8568
8593
  }
8569
8594
 
8570
8595
  function getParent(inst) {
@@ -8675,7 +8700,10 @@ function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, com
8675
8700
  }
8676
8701
 
8677
8702
  if (listeners.length !== 0) {
8678
- dispatchQueue.push(createDispatchEntry(event, listeners));
8703
+ dispatchQueue.push({
8704
+ event: event,
8705
+ listeners: listeners
8706
+ });
8679
8707
  }
8680
8708
  } // We should only use this function for:
8681
8709
  // - EnterLeaveEventPlugin
@@ -8721,11 +8749,6 @@ var normalizeHTML;
8721
8749
 
8722
8750
  {
8723
8751
  warnedUnknownTags = {
8724
- // Chrome is the only major browser not shipping <time>. But as of July
8725
- // 2017 it intends to ship it due to widespread usage. We intentionally
8726
- // *don't* warn for <time> even if it's unrecognized by Chrome because
8727
- // it soon will be, and many apps have been using it anyway.
8728
- time: true,
8729
8752
  // There are working polyfills for <dialog>. Let people use it.
8730
8753
  dialog: true,
8731
8754
  // Electron ships a custom <webview> tag to display external web content in
@@ -11283,7 +11306,7 @@ function flushSyncCallbackQueue() {
11283
11306
  Scheduler_cancelCallback(node);
11284
11307
  }
11285
11308
 
11286
- return flushSyncCallbackQueueImpl();
11309
+ flushSyncCallbackQueueImpl();
11287
11310
  }
11288
11311
 
11289
11312
  function flushSyncCallbackQueueImpl() {
@@ -11319,30 +11342,11 @@ function flushSyncCallbackQueueImpl() {
11319
11342
  isFlushingSyncQueue = false;
11320
11343
  }
11321
11344
  }
11322
-
11323
- return true;
11324
- } else {
11325
- return false;
11326
11345
  }
11327
11346
  }
11328
11347
 
11329
- var NoFlags$1 =
11330
- /* */
11331
- 0; // Represents whether effect should fire.
11332
-
11333
- var HasEffect =
11334
- /* */
11335
- 1; // Represents the phase in which the effect (not the clean-up) fires.
11336
-
11337
- var Layout =
11338
- /* */
11339
- 2;
11340
- var Passive$1 =
11341
- /* */
11342
- 4;
11343
-
11344
11348
  // TODO: this is special because it gets imported during build.
11345
- var ReactVersion = '17.0.0-rc.2';
11349
+ var ReactVersion = '17.0.2';
11346
11350
 
11347
11351
  var NoMode = 0;
11348
11352
  var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
@@ -11401,7 +11405,7 @@ var ReactStrictModeWarnings = {
11401
11405
  var didWarnAboutUnsafeLifecycles = new Set();
11402
11406
 
11403
11407
  ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11404
- // Dedupe strategy: Warn once per component.
11408
+ // Dedup strategy: Warn once per component.
11405
11409
  if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11406
11410
  return;
11407
11411
  }
@@ -13253,16 +13257,24 @@ function ChildReconciler(shouldTrackSideEffects) {
13253
13257
  if (!shouldTrackSideEffects) {
13254
13258
  // Noop.
13255
13259
  return;
13256
- }
13260
+ } // Deletions are added in reversed order so we add it to the front.
13261
+ // At this point, the return fiber's effect list is empty except for
13262
+ // deletions, so we can just append the deletion to the list. The remaining
13263
+ // effects aren't added until the complete phase. Once we implement
13264
+ // resuming, this may not be true.
13265
+
13257
13266
 
13258
- var deletions = returnFiber.deletions;
13267
+ var last = returnFiber.lastEffect;
13259
13268
 
13260
- if (deletions === null) {
13261
- returnFiber.deletions = [childToDelete];
13262
- returnFiber.flags |= Deletion;
13269
+ if (last !== null) {
13270
+ last.nextEffect = childToDelete;
13271
+ returnFiber.lastEffect = childToDelete;
13263
13272
  } else {
13264
- deletions.push(childToDelete);
13273
+ returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13265
13274
  }
13275
+
13276
+ childToDelete.nextEffect = null;
13277
+ childToDelete.flags = Deletion;
13266
13278
  }
13267
13279
 
13268
13280
  function deleteRemainingChildren(returnFiber, currentFirstChild) {
@@ -14318,13 +14330,6 @@ function popSuspenseContext(fiber) {
14318
14330
  pop(suspenseStackCursor, fiber);
14319
14331
  }
14320
14332
 
14321
- // A non-null SuspenseState means that it is blocked for one reason or another.
14322
- // - A non-null dehydrated field means it's blocked pending hydration.
14323
- // - A non-null dehydrated field can use isSuspenseInstancePending or
14324
- // isSuspenseInstanceFallback to query the reason for being dehydrated.
14325
- // - A null dehydrated field means it's blocked by something suspending and
14326
- // we're currently showing a fallback instead.
14327
-
14328
14333
  function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14329
14334
  // If it was the primary children that just suspended, capture and render the
14330
14335
  // fallback. Otherwise, don't capture and bubble to the next boundary.
@@ -14406,6 +14411,21 @@ function findFirstSuspended(row) {
14406
14411
  return null;
14407
14412
  }
14408
14413
 
14414
+ var NoFlags$1 =
14415
+ /* */
14416
+ 0; // Represents whether effect should fire.
14417
+
14418
+ var HasEffect =
14419
+ /* */
14420
+ 1; // Represents the phase in which the effect (not the clean-up) fires.
14421
+
14422
+ var Layout =
14423
+ /* */
14424
+ 2;
14425
+ var Passive$1 =
14426
+ /* */
14427
+ 4;
14428
+
14409
14429
  // This may have been an insertion or a hydration.
14410
14430
 
14411
14431
  var hydrationParentFiber = null;
@@ -14437,14 +14457,17 @@ function deleteHydratableInstance(returnFiber, instance) {
14437
14457
  var childToDelete = createFiberFromHostInstanceForDeletion();
14438
14458
  childToDelete.stateNode = instance;
14439
14459
  childToDelete.return = returnFiber;
14440
- var deletions = returnFiber.deletions;
14441
-
14442
- if (deletions === null) {
14443
- returnFiber.deletions = [childToDelete]; // TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
14444
-
14445
- returnFiber.flags |= Deletion;
14460
+ childToDelete.flags = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
14461
+ // these children are not part of the reconciliation list of children.
14462
+ // Even if we abort and rereconcile the children, that will try to hydrate
14463
+ // again and the nodes are still in the host tree so these will be
14464
+ // recreated.
14465
+
14466
+ if (returnFiber.lastEffect !== null) {
14467
+ returnFiber.lastEffect.nextEffect = childToDelete;
14468
+ returnFiber.lastEffect = childToDelete;
14446
14469
  } else {
14447
- deletions.push(childToDelete);
14470
+ returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14448
14471
  }
14449
14472
  }
14450
14473
 
@@ -15710,7 +15733,7 @@ function mountEffect(create, deps) {
15710
15733
  }
15711
15734
  }
15712
15735
 
15713
- return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
15736
+ return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15714
15737
  }
15715
15738
 
15716
15739
  function updateEffect(create, deps) {
@@ -15721,7 +15744,7 @@ function updateEffect(create, deps) {
15721
15744
  }
15722
15745
  }
15723
15746
 
15724
- return updateEffectImpl(Passive, Passive$1, create, deps);
15747
+ return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15725
15748
  }
15726
15749
 
15727
15750
  function mountLayoutEffect(create, deps) {
@@ -16004,7 +16027,7 @@ function mountOpaqueIdentifier() {
16004
16027
  var setId = mountState(id)[1];
16005
16028
 
16006
16029
  if ((currentlyRenderingFiber$1.mode & BlockingMode) === NoMode) {
16007
- currentlyRenderingFiber$1.flags |= Passive | PassiveStatic;
16030
+ currentlyRenderingFiber$1.flags |= Update | Passive;
16008
16031
  pushEffect(HasEffect | Passive$1, function () {
16009
16032
  setId(makeId());
16010
16033
  }, undefined, null);
@@ -17280,8 +17303,7 @@ function updateMode(current, workInProgress, renderLanes) {
17280
17303
 
17281
17304
  function updateProfiler(current, workInProgress, renderLanes) {
17282
17305
  {
17283
- // TODO: Only call onRender et al if subtree has effects
17284
- workInProgress.flags |= Update | Passive; // Reset effect durations for the next eventual effect phase.
17306
+ workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase.
17285
17307
  // These are reset during render to allow the DevTools commit hook a chance to read them,
17286
17308
 
17287
17309
  var stateNode = workInProgress.stateNode;
@@ -17942,7 +17964,8 @@ function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
17942
17964
  return {
17943
17965
  baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes)
17944
17966
  };
17945
- }
17967
+ } // TODO: Probably should inline this back
17968
+
17946
17969
 
17947
17970
  function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
17948
17971
  // If we're already showing a fallback, there are cases where we need to
@@ -18033,17 +18056,41 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
18033
18056
  tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
18034
18057
  }
18035
18058
 
18059
+ var nextPrimaryChildren = nextProps.children;
18060
+ var nextFallbackChildren = nextProps.fallback;
18061
+
18036
18062
  if (showFallback) {
18037
- var nextPrimaryChildren = nextProps.children;
18038
- var nextFallbackChildren = nextProps.fallback;
18039
18063
  var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18040
18064
  var primaryChildFragment = workInProgress.child;
18041
18065
  primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18042
18066
  workInProgress.memoizedState = SUSPENDED_MARKER;
18043
18067
  return fallbackFragment;
18068
+ } else if (typeof nextProps.unstable_expectedLoadTime === 'number') {
18069
+ // This is a CPU-bound tree. Skip this tree and show a placeholder to
18070
+ // unblock the surrounding content. Then immediately retry after the
18071
+ // initial commit.
18072
+ var _fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18073
+
18074
+ var _primaryChildFragment = workInProgress.child;
18075
+ _primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18076
+ workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to
18077
+ // get it started back up to attempt the next item. While in terms of
18078
+ // priority this work has the same priority as this current render, it's
18079
+ // not part of the same transition once the transition has committed. If
18080
+ // it's sync, we still want to yield so that it can be painted.
18081
+ // Conceptually, this is really the same as pinging. We can use any
18082
+ // RetryLane even if it's the one currently rendering since we're leaving
18083
+ // it behind on this node.
18084
+
18085
+ workInProgress.lanes = SomeRetryLane;
18086
+
18087
+ {
18088
+ markSpawnedWork(SomeRetryLane);
18089
+ }
18090
+
18091
+ return _fallbackFragment;
18044
18092
  } else {
18045
- var _nextPrimaryChildren = nextProps.children;
18046
- return mountSuspensePrimaryChildren(workInProgress, _nextPrimaryChildren, renderLanes);
18093
+ return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren, renderLanes);
18047
18094
  }
18048
18095
  } else {
18049
18096
  // This is an update.
@@ -18055,37 +18102,37 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
18055
18102
 
18056
18103
  if (showFallback) {
18057
18104
  var _nextFallbackChildren2 = nextProps.fallback;
18058
- var _nextPrimaryChildren3 = nextProps.children;
18105
+ var _nextPrimaryChildren2 = nextProps.children;
18059
18106
 
18060
- var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren3, _nextFallbackChildren2, renderLanes);
18107
+ var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes);
18061
18108
 
18062
- var _primaryChildFragment2 = workInProgress.child;
18109
+ var _primaryChildFragment3 = workInProgress.child;
18063
18110
  var prevOffscreenState = current.child.memoizedState;
18064
- _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
18065
- _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
18111
+ _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
18112
+ _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
18066
18113
  workInProgress.memoizedState = SUSPENDED_MARKER;
18067
18114
  return _fallbackChildFragment;
18068
18115
  } else {
18069
- var _nextPrimaryChildren4 = nextProps.children;
18116
+ var _nextPrimaryChildren3 = nextProps.children;
18070
18117
 
18071
- var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren4, renderLanes);
18118
+ var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes);
18072
18119
 
18073
18120
  workInProgress.memoizedState = null;
18074
- return _primaryChildFragment3;
18121
+ return _primaryChildFragment4;
18075
18122
  }
18076
18123
  } else {
18077
18124
  // The current tree is not already showing a fallback.
18078
18125
  if (showFallback) {
18079
18126
  // Timed out.
18080
18127
  var _nextFallbackChildren3 = nextProps.fallback;
18081
- var _nextPrimaryChildren5 = nextProps.children;
18128
+ var _nextPrimaryChildren4 = nextProps.children;
18082
18129
 
18083
- var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren5, _nextFallbackChildren3, renderLanes);
18130
+ var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes);
18084
18131
 
18085
- var _primaryChildFragment4 = workInProgress.child;
18132
+ var _primaryChildFragment5 = workInProgress.child;
18086
18133
  var _prevOffscreenState = current.child.memoizedState;
18087
- _primaryChildFragment4.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
18088
- _primaryChildFragment4.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
18134
+ _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
18135
+ _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
18089
18136
  // fallback children.
18090
18137
 
18091
18138
  workInProgress.memoizedState = SUSPENDED_MARKER;
@@ -18093,12 +18140,12 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
18093
18140
  } else {
18094
18141
  // Still haven't timed out. Continue rendering the children, like we
18095
18142
  // normally do.
18096
- var _nextPrimaryChildren6 = nextProps.children;
18143
+ var _nextPrimaryChildren5 = nextProps.children;
18097
18144
 
18098
- var _primaryChildFragment5 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren6, renderLanes);
18145
+ var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes);
18099
18146
 
18100
18147
  workInProgress.memoizedState = null;
18101
- return _primaryChildFragment5;
18148
+ return _primaryChildFragment6;
18102
18149
  }
18103
18150
  }
18104
18151
  }
@@ -18180,15 +18227,9 @@ function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren,
18180
18227
 
18181
18228
  if (currentFallbackChildFragment !== null) {
18182
18229
  // Delete the fallback child fragment
18183
- var deletions = workInProgress.deletions;
18184
-
18185
- if (deletions === null) {
18186
- workInProgress.deletions = [currentFallbackChildFragment]; // TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
18187
-
18188
- workInProgress.flags |= Deletion;
18189
- } else {
18190
- deletions.push(currentFallbackChildFragment);
18191
- }
18230
+ currentFallbackChildFragment.nextEffect = null;
18231
+ currentFallbackChildFragment.flags = Deletion;
18232
+ workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment;
18192
18233
  }
18193
18234
 
18194
18235
  workInProgress.child = primaryChildFragment;
@@ -18230,16 +18271,24 @@ function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren
18230
18271
  primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
18231
18272
  } // The fallback fiber was added as a deletion effect during the first pass.
18232
18273
  // However, since we're going to remain on the fallback, we no longer want
18233
- // to delete it.
18274
+ // to delete it. So we need to remove it from the list. Deletions are stored
18275
+ // on the same list as effects. We want to keep the effects from the primary
18276
+ // tree. So we copy the primary child fragment's effect list, which does not
18277
+ // include the fallback deletion effect.
18234
18278
 
18235
18279
 
18236
- workInProgress.deletions = null;
18237
- } else {
18238
- primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
18239
- // (We don't do this in legacy mode, because in legacy mode we don't re-use
18240
- // the current tree; see previous branch.)
18280
+ var progressedLastEffect = primaryChildFragment.lastEffect;
18241
18281
 
18242
- primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
18282
+ if (progressedLastEffect !== null) {
18283
+ workInProgress.firstEffect = primaryChildFragment.firstEffect;
18284
+ workInProgress.lastEffect = progressedLastEffect;
18285
+ progressedLastEffect.nextEffect = null;
18286
+ } else {
18287
+ // TODO: Reset this somewhere else? Lol legacy mode is so weird.
18288
+ workInProgress.firstEffect = workInProgress.lastEffect = null;
18289
+ }
18290
+ } else {
18291
+ primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
18243
18292
  }
18244
18293
 
18245
18294
  var fallbackChildFragment;
@@ -18442,7 +18491,7 @@ function validateSuspenseListChildren(children, revealOrder) {
18442
18491
  }
18443
18492
  }
18444
18493
 
18445
- function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
18494
+ function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18446
18495
  var renderState = workInProgress.memoizedState;
18447
18496
 
18448
18497
  if (renderState === null) {
@@ -18452,7 +18501,8 @@ function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastCont
18452
18501
  renderingStartTime: 0,
18453
18502
  last: lastContentRow,
18454
18503
  tail: tail,
18455
- tailMode: tailMode
18504
+ tailMode: tailMode,
18505
+ lastEffect: lastEffectBeforeRendering
18456
18506
  };
18457
18507
  } else {
18458
18508
  // We can reuse the existing object from previous renders.
@@ -18462,6 +18512,7 @@ function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastCont
18462
18512
  renderState.last = lastContentRow;
18463
18513
  renderState.tail = tail;
18464
18514
  renderState.tailMode = tailMode;
18515
+ renderState.lastEffect = lastEffectBeforeRendering;
18465
18516
  }
18466
18517
  } // This can end up rendering this component multiple passes.
18467
18518
  // The first pass splits the children fibers into two sets. A head and tail.
@@ -18526,7 +18577,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) {
18526
18577
  }
18527
18578
 
18528
18579
  initSuspenseListRenderState(workInProgress, false, // isBackwards
18529
- tail, lastContentRow, tailMode);
18580
+ tail, lastContentRow, tailMode, workInProgress.lastEffect);
18530
18581
  break;
18531
18582
  }
18532
18583
 
@@ -18558,7 +18609,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) {
18558
18609
 
18559
18610
  initSuspenseListRenderState(workInProgress, true, // isBackwards
18560
18611
  _tail, null, // last
18561
- tailMode);
18612
+ tailMode, workInProgress.lastEffect);
18562
18613
  break;
18563
18614
  }
18564
18615
 
@@ -18567,7 +18618,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) {
18567
18618
  initSuspenseListRenderState(workInProgress, false, // isBackwards
18568
18619
  null, // tail
18569
18620
  null, // last
18570
- undefined);
18621
+ undefined, workInProgress.lastEffect);
18571
18622
  break;
18572
18623
  }
18573
18624
 
@@ -18773,16 +18824,17 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18773
18824
  // Since the old fiber is disconnected, we have to schedule it manually.
18774
18825
 
18775
18826
 
18776
- var deletions = returnFiber.deletions;
18827
+ var last = returnFiber.lastEffect;
18777
18828
 
18778
- if (deletions === null) {
18779
- returnFiber.deletions = [current]; // TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
18780
-
18781
- returnFiber.flags |= Deletion;
18829
+ if (last !== null) {
18830
+ last.nextEffect = current;
18831
+ returnFiber.lastEffect = current;
18782
18832
  } else {
18783
- deletions.push(current);
18833
+ returnFiber.firstEffect = returnFiber.lastEffect = current;
18784
18834
  }
18785
18835
 
18836
+ current.nextEffect = null;
18837
+ current.flags = Deletion;
18786
18838
  newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
18787
18839
 
18788
18840
  return newWorkInProgress;
@@ -18848,11 +18900,10 @@ function beginWork(current, workInProgress, renderLanes) {
18848
18900
  case Profiler:
18849
18901
  {
18850
18902
  // Profiler should only call onRender when one of its descendants actually rendered.
18851
- // TODO: Only call onRender et al if subtree has effects
18852
18903
  var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
18853
18904
 
18854
18905
  if (hasChildWork) {
18855
- workInProgress.flags |= Passive | Update;
18906
+ workInProgress.flags |= Update;
18856
18907
  } // Reset effect durations for the next eventual effect phase.
18857
18908
  // These are reset during render to allow the DevTools commit hook a chance to read them,
18858
18909
 
@@ -18936,6 +18987,7 @@ function beginWork(current, workInProgress, renderLanes) {
18936
18987
  // update in the past but didn't complete it.
18937
18988
  renderState.rendering = null;
18938
18989
  renderState.tail = null;
18990
+ renderState.lastEffect = null;
18939
18991
  }
18940
18992
 
18941
18993
  pushSuspenseContext(workInProgress, suspenseStackCursor.current);
@@ -19187,7 +19239,7 @@ var updateHostText$1;
19187
19239
  }
19188
19240
  };
19189
19241
 
19190
- updateHostContainer = function (current, workInProgress) {// Noop
19242
+ updateHostContainer = function (workInProgress) {// Noop
19191
19243
  };
19192
19244
 
19193
19245
  updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
@@ -19308,92 +19360,6 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
19308
19360
  }
19309
19361
  }
19310
19362
 
19311
- function bubbleProperties(completedWork) {
19312
- var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
19313
- var newChildLanes = NoLanes;
19314
- var subtreeFlags = NoFlags;
19315
-
19316
- if (!didBailout) {
19317
- // Bubble up the earliest expiration time.
19318
- if ( (completedWork.mode & ProfileMode) !== NoMode) {
19319
- // In profiling mode, resetChildExpirationTime is also used to reset
19320
- // profiler durations.
19321
- var actualDuration = completedWork.actualDuration;
19322
- var treeBaseDuration = completedWork.selfBaseDuration;
19323
- var child = completedWork.child;
19324
-
19325
- while (child !== null) {
19326
- newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
19327
- subtreeFlags |= child.subtreeFlags;
19328
- subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
19329
- // only be updated if work is done on the fiber (i.e. it doesn't bailout).
19330
- // When work is done, it should bubble to the parent's actualDuration. If
19331
- // the fiber has not been cloned though, (meaning no work was done), then
19332
- // this value will reflect the amount of time spent working on a previous
19333
- // render. In that case it should not bubble. We determine whether it was
19334
- // cloned by comparing the child pointer.
19335
-
19336
- actualDuration += child.actualDuration;
19337
- treeBaseDuration += child.treeBaseDuration;
19338
- child = child.sibling;
19339
- }
19340
-
19341
- completedWork.actualDuration = actualDuration;
19342
- completedWork.treeBaseDuration = treeBaseDuration;
19343
- } else {
19344
- var _child = completedWork.child;
19345
-
19346
- while (_child !== null) {
19347
- newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
19348
- subtreeFlags |= _child.subtreeFlags;
19349
- subtreeFlags |= _child.flags;
19350
- _child = _child.sibling;
19351
- }
19352
- }
19353
-
19354
- completedWork.subtreeFlags |= subtreeFlags;
19355
- } else {
19356
- // Bubble up the earliest expiration time.
19357
- if ( (completedWork.mode & ProfileMode) !== NoMode) {
19358
- // In profiling mode, resetChildExpirationTime is also used to reset
19359
- // profiler durations.
19360
- var _treeBaseDuration = completedWork.selfBaseDuration;
19361
- var _child2 = completedWork.child;
19362
-
19363
- while (_child2 !== null) {
19364
- newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
19365
- // so we should bubble those up even during a bailout. All the other
19366
- // flags have a lifetime only of a single render + commit, so we should
19367
- // ignore them.
19368
-
19369
- subtreeFlags |= _child2.subtreeFlags & StaticMask;
19370
- subtreeFlags |= _child2.flags & StaticMask;
19371
- _treeBaseDuration += _child2.treeBaseDuration;
19372
- _child2 = _child2.sibling;
19373
- }
19374
-
19375
- completedWork.treeBaseDuration = _treeBaseDuration;
19376
- } else {
19377
- var _child3 = completedWork.child;
19378
-
19379
- while (_child3 !== null) {
19380
- newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
19381
- // so we should bubble those up even during a bailout. All the other
19382
- // flags have a lifetime only of a single render + commit, so we should
19383
- // ignore them.
19384
-
19385
- subtreeFlags |= _child3.subtreeFlags & StaticMask;
19386
- subtreeFlags |= _child3.flags & StaticMask;
19387
- _child3 = _child3.sibling;
19388
- }
19389
- }
19390
-
19391
- completedWork.subtreeFlags |= subtreeFlags;
19392
- }
19393
-
19394
- completedWork.childLanes = newChildLanes;
19395
- }
19396
-
19397
19363
  function completeWork(current, workInProgress, renderLanes) {
19398
19364
  var newProps = workInProgress.pendingProps;
19399
19365
 
@@ -19408,7 +19374,6 @@ function completeWork(current, workInProgress, renderLanes) {
19408
19374
  case Profiler:
19409
19375
  case ContextConsumer:
19410
19376
  case MemoComponent:
19411
- bubbleProperties(workInProgress);
19412
19377
  return null;
19413
19378
 
19414
19379
  case ClassComponent:
@@ -19419,7 +19384,6 @@ function completeWork(current, workInProgress, renderLanes) {
19419
19384
  popContext(workInProgress);
19420
19385
  }
19421
19386
 
19422
- bubbleProperties(workInProgress);
19423
19387
  return null;
19424
19388
  }
19425
19389
 
@@ -19453,8 +19417,7 @@ function completeWork(current, workInProgress, renderLanes) {
19453
19417
  }
19454
19418
  }
19455
19419
 
19456
- updateHostContainer(current, workInProgress);
19457
- bubbleProperties(workInProgress);
19420
+ updateHostContainer(workInProgress);
19458
19421
  return null;
19459
19422
  }
19460
19423
 
@@ -19479,7 +19442,6 @@ function completeWork(current, workInProgress, renderLanes) {
19479
19442
  } // This can happen when we abort work.
19480
19443
 
19481
19444
 
19482
- bubbleProperties(workInProgress);
19483
19445
  return null;
19484
19446
  }
19485
19447
 
@@ -19516,7 +19478,6 @@ function completeWork(current, workInProgress, renderLanes) {
19516
19478
  }
19517
19479
  }
19518
19480
 
19519
- bubbleProperties(workInProgress);
19520
19481
  return null;
19521
19482
  }
19522
19483
 
@@ -19554,7 +19515,6 @@ function completeWork(current, workInProgress, renderLanes) {
19554
19515
  }
19555
19516
  }
19556
19517
 
19557
- bubbleProperties(workInProgress);
19558
19518
  return null;
19559
19519
  }
19560
19520
 
@@ -19569,8 +19529,7 @@ function completeWork(current, workInProgress, renderLanes) {
19569
19529
 
19570
19530
  if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19571
19531
  transferActualDuration(workInProgress);
19572
- } // Don't bubble properties in this case.
19573
-
19532
+ }
19574
19533
 
19575
19534
  return workInProgress;
19576
19535
  }
@@ -19627,40 +19586,22 @@ function completeWork(current, workInProgress, renderLanes) {
19627
19586
  }
19628
19587
  }
19629
19588
 
19630
- bubbleProperties(workInProgress);
19631
-
19632
- {
19633
- if ((workInProgress.mode & ProfileMode) !== NoMode) {
19634
- if (nextDidTimeout) {
19635
- // Don't count time spent in a timed out Suspense subtree as part of the base duration.
19636
- var _primaryChildFragment2 = workInProgress.child;
19637
-
19638
- if (_primaryChildFragment2 !== null) {
19639
- // $FlowFixMe Flow doens't support type casting in combiation with the -= operator
19640
- workInProgress.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration;
19641
- }
19642
- }
19643
- }
19644
- }
19645
-
19646
19589
  return null;
19647
19590
  }
19648
19591
 
19649
19592
  case HostPortal:
19650
19593
  popHostContainer(workInProgress);
19651
- updateHostContainer(current, workInProgress);
19594
+ updateHostContainer(workInProgress);
19652
19595
 
19653
19596
  if (current === null) {
19654
19597
  preparePortalMount(workInProgress.stateNode.containerInfo);
19655
19598
  }
19656
19599
 
19657
- bubbleProperties(workInProgress);
19658
19600
  return null;
19659
19601
 
19660
19602
  case ContextProvider:
19661
19603
  // Pop provider fiber
19662
19604
  popProvider(workInProgress);
19663
- bubbleProperties(workInProgress);
19664
19605
  return null;
19665
19606
 
19666
19607
  case IncompleteClassComponent:
@@ -19673,7 +19614,6 @@ function completeWork(current, workInProgress, renderLanes) {
19673
19614
  popContext(workInProgress);
19674
19615
  }
19675
19616
 
19676
- bubbleProperties(workInProgress);
19677
19617
  return null;
19678
19618
  }
19679
19619
 
@@ -19685,7 +19625,6 @@ function completeWork(current, workInProgress, renderLanes) {
19685
19625
  if (renderState === null) {
19686
19626
  // We're running in the default, "independent" mode.
19687
19627
  // We don't do anything in this mode.
19688
- bubbleProperties(workInProgress);
19689
19628
  return null;
19690
19629
  }
19691
19630
 
@@ -19735,15 +19674,19 @@ function completeWork(current, workInProgress, renderLanes) {
19735
19674
  workInProgress.flags |= Update;
19736
19675
  } // Rerender the whole list, but this time, we'll force fallbacks
19737
19676
  // to stay in place.
19738
- // Reset the child fibers to their original state.
19677
+ // Reset the effect list before doing the second pass since that's now invalid.
19678
+
19739
19679
 
19680
+ if (renderState.lastEffect === null) {
19681
+ workInProgress.firstEffect = null;
19682
+ }
19683
+
19684
+ workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19740
19685
 
19741
- workInProgress.subtreeFlags = NoFlags;
19742
19686
  resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
19743
19687
  // rerender the children.
19744
19688
 
19745
- pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
19746
-
19689
+ pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19747
19690
  return workInProgress.child;
19748
19691
  }
19749
19692
 
@@ -19797,8 +19740,16 @@ function completeWork(current, workInProgress, renderLanes) {
19797
19740
 
19798
19741
  if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
19799
19742
  ) {
19800
- // We're done.
19801
- bubbleProperties(workInProgress);
19743
+ // We need to delete the row we just rendered.
19744
+ // Reset the effect list to what it was before we rendered this
19745
+ // child. The nested children have already appended themselves.
19746
+ var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19747
+
19748
+ if (lastEffect !== null) {
19749
+ lastEffect.nextEffect = null;
19750
+ } // We're done.
19751
+
19752
+
19802
19753
  return null;
19803
19754
  }
19804
19755
  } else if ( // The time it took to render last row is greater than the remaining
@@ -19811,16 +19762,19 @@ function completeWork(current, workInProgress, renderLanes) {
19811
19762
  workInProgress.flags |= DidCapture;
19812
19763
  didSuspendAlready = true;
19813
19764
  cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19814
- // to get it started back up to attempt the next item. If we can show
19815
- // them, then they really have the same priority as this render.
19816
- // So we'll pick it back up the very next render pass once we've had
19817
- // an opportunity to yield for paint.
19818
-
19819
- workInProgress.lanes = SomeRetryLane;
19820
-
19821
- {
19822
- markSpawnedWork(SomeRetryLane);
19823
- }
19765
+ // to get it started back up to attempt the next item. While in terms
19766
+ // of priority this work has the same priority as this current render,
19767
+ // it's not part of the same transition once the transition has
19768
+ // committed. If it's sync, we still want to yield so that it can be
19769
+ // painted. Conceptually, this is really the same as pinging.
19770
+ // We can use any RetryLane even if it's the one currently rendering
19771
+ // since we're leaving it behind on this node.
19772
+
19773
+ workInProgress.lanes = SomeRetryLane;
19774
+
19775
+ {
19776
+ markSpawnedWork(SomeRetryLane);
19777
+ }
19824
19778
  }
19825
19779
  }
19826
19780
 
@@ -19851,6 +19805,7 @@ function completeWork(current, workInProgress, renderLanes) {
19851
19805
  var next = renderState.tail;
19852
19806
  renderState.rendering = next;
19853
19807
  renderState.tail = next.sibling;
19808
+ renderState.lastEffect = workInProgress.lastEffect;
19854
19809
  renderState.renderingStartTime = now();
19855
19810
  next.sibling = null; // Restore the context.
19856
19811
  // TODO: We can probably just avoid popping it instead and only
@@ -19865,12 +19820,10 @@ function completeWork(current, workInProgress, renderLanes) {
19865
19820
  }
19866
19821
 
19867
19822
  pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19868
- // Don't bubble properties in this case.
19869
19823
 
19870
19824
  return next;
19871
19825
  }
19872
19826
 
19873
- bubbleProperties(workInProgress);
19874
19827
  return null;
19875
19828
  }
19876
19829
 
@@ -19894,21 +19847,16 @@ function completeWork(current, workInProgress, renderLanes) {
19894
19847
  case LegacyHiddenComponent:
19895
19848
  {
19896
19849
  popRenderLanes(workInProgress);
19897
- var _nextState = workInProgress.memoizedState;
19898
- var nextIsHidden = _nextState !== null;
19899
19850
 
19900
19851
  if (current !== null) {
19852
+ var _nextState = workInProgress.memoizedState;
19901
19853
  var _prevState = current.memoizedState;
19902
19854
  var prevIsHidden = _prevState !== null;
19855
+ var nextIsHidden = _nextState !== null;
19903
19856
 
19904
19857
  if (prevIsHidden !== nextIsHidden && newProps.mode !== 'unstable-defer-without-hiding') {
19905
19858
  workInProgress.flags |= Update;
19906
19859
  }
19907
- } // Don't bubble properties for hidden children.
19908
-
19909
-
19910
- if (!nextIsHidden || includesSomeLane(subtreeRenderLanes, OffscreenLane) || (workInProgress.mode & ConcurrentMode) === NoMode) {
19911
- bubbleProperties(workInProgress);
19912
19860
  }
19913
19861
 
19914
19862
  return null;
@@ -20262,7 +20210,9 @@ function attachPingListener(root, wakeable, lanes) {
20262
20210
 
20263
20211
  function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
20264
20212
  // The source fiber did not complete.
20265
- sourceFiber.flags |= Incomplete;
20213
+ sourceFiber.flags |= Incomplete; // Its effect list is no longer valid.
20214
+
20215
+ sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20266
20216
 
20267
20217
  if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20268
20218
  // This is a wakeable.
@@ -20465,18 +20415,18 @@ var callComponentWillUnmountWithTimer = function (current, instance) {
20465
20415
  }; // Capture errors so they don't interrupt unmounting.
20466
20416
 
20467
20417
 
20468
- function safelyCallComponentWillUnmount(current, instance, nearestMountedAncestor) {
20418
+ function safelyCallComponentWillUnmount(current, instance) {
20469
20419
  {
20470
20420
  invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
20471
20421
 
20472
20422
  if (hasCaughtError()) {
20473
20423
  var unmountError = clearCaughtError();
20474
- captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
20424
+ captureCommitPhaseError(current, unmountError);
20475
20425
  }
20476
20426
  }
20477
20427
  }
20478
20428
 
20479
- function safelyDetachRef(current, nearestMountedAncestor) {
20429
+ function safelyDetachRef(current) {
20480
20430
  var ref = current.ref;
20481
20431
 
20482
20432
  if (ref !== null) {
@@ -20486,7 +20436,7 @@ function safelyDetachRef(current, nearestMountedAncestor) {
20486
20436
 
20487
20437
  if (hasCaughtError()) {
20488
20438
  var refError = clearCaughtError();
20489
- captureCommitPhaseError(current, nearestMountedAncestor, refError);
20439
+ captureCommitPhaseError(current, refError);
20490
20440
  }
20491
20441
  }
20492
20442
  } else {
@@ -20495,13 +20445,13 @@ function safelyDetachRef(current, nearestMountedAncestor) {
20495
20445
  }
20496
20446
  }
20497
20447
 
20498
- function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
20448
+ function safelyCallDestroy(current, destroy) {
20499
20449
  {
20500
20450
  invokeGuardedCallback(null, destroy, null);
20501
20451
 
20502
20452
  if (hasCaughtError()) {
20503
20453
  var error = clearCaughtError();
20504
- captureCommitPhaseError(current, nearestMountedAncestor, error);
20454
+ captureCommitPhaseError(current, error);
20505
20455
  }
20506
20456
  }
20507
20457
  }
@@ -20584,7 +20534,7 @@ function commitBeforeMutationLifeCycles(current, finishedWork) {
20584
20534
  }
20585
20535
  }
20586
20536
 
20587
- function commitHookEffectListUnmount(tag, finishedWork, nearestMountedAncestor) {
20537
+ function commitHookEffectListUnmount(tag, finishedWork) {
20588
20538
  var updateQueue = finishedWork.updateQueue;
20589
20539
  var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20590
20540
 
@@ -20599,45 +20549,13 @@ function commitHookEffectListUnmount(tag, finishedWork, nearestMountedAncestor)
20599
20549
  effect.destroy = undefined;
20600
20550
 
20601
20551
  if (destroy !== undefined) {
20602
- safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
20552
+ destroy();
20603
20553
  }
20604
20554
  }
20605
20555
 
20606
20556
  effect = effect.next;
20607
20557
  } while (effect !== firstEffect);
20608
20558
  }
20609
- } // TODO: Remove this duplication.
20610
-
20611
-
20612
- function commitHookEffectListUnmount2( // Tags to check for when deciding whether to unmount. e.g. to skip over layout effects
20613
- hookFlags, fiber, nearestMountedAncestor) {
20614
- var updateQueue = fiber.updateQueue;
20615
- var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20616
-
20617
- if (lastEffect !== null) {
20618
- var firstEffect = lastEffect.next;
20619
- var effect = firstEffect;
20620
-
20621
- do {
20622
- var _effect = effect,
20623
- next = _effect.next,
20624
- tag = _effect.tag;
20625
-
20626
- if ((tag & hookFlags) === hookFlags) {
20627
- var destroy = effect.destroy;
20628
-
20629
- if (destroy !== undefined) {
20630
- effect.destroy = undefined;
20631
-
20632
- {
20633
- safelyCallDestroy(fiber, nearestMountedAncestor, destroy);
20634
- }
20635
- }
20636
- }
20637
-
20638
- effect = next;
20639
- } while (effect !== firstEffect);
20640
- }
20641
20559
  }
20642
20560
 
20643
20561
  function commitHookEffectListMount(tag, finishedWork) {
@@ -20678,14 +20596,8 @@ function commitHookEffectListMount(tag, finishedWork) {
20678
20596
  }
20679
20597
  }
20680
20598
 
20681
- function invokePassiveEffectCreate(effect) {
20682
- var create = effect.create;
20683
- effect.destroy = create();
20684
- } // TODO: Remove this duplication.
20685
-
20686
-
20687
- function commitHookEffectListMount2(fiber) {
20688
- var updateQueue = fiber.updateQueue;
20599
+ function schedulePassiveEffects(finishedWork) {
20600
+ var updateQueue = finishedWork.updateQueue;
20689
20601
  var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20690
20602
 
20691
20603
  if (lastEffect !== null) {
@@ -20693,27 +20605,13 @@ function commitHookEffectListMount2(fiber) {
20693
20605
  var effect = firstEffect;
20694
20606
 
20695
20607
  do {
20696
- var _effect2 = effect,
20697
- next = _effect2.next,
20698
- tag = _effect2.tag;
20608
+ var _effect = effect,
20609
+ next = _effect.next,
20610
+ tag = _effect.tag;
20699
20611
 
20700
20612
  if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) {
20701
- {
20702
- {
20703
- invokeGuardedCallback(null, invokePassiveEffectCreate, null, effect);
20704
- }
20705
-
20706
- if (hasCaughtError()) {
20707
- if (!(fiber !== null)) {
20708
- {
20709
- throw Error( "Should be working on an effect." );
20710
- }
20711
- }
20712
-
20713
- var error = clearCaughtError();
20714
- captureCommitPhaseError(fiber, fiber.return, error);
20715
- }
20716
- }
20613
+ enqueuePendingPassiveHookEffectUnmount(finishedWork, effect);
20614
+ enqueuePendingPassiveHookEffectMount(finishedWork, effect);
20717
20615
  }
20718
20616
 
20719
20617
  effect = next;
@@ -20736,10 +20634,7 @@ function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) {
20736
20634
  commitHookEffectListMount(Layout | HasEffect, finishedWork);
20737
20635
  }
20738
20636
 
20739
- if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags) {
20740
- schedulePassiveEffectCallback();
20741
- }
20742
-
20637
+ schedulePassiveEffects(finishedWork);
20743
20638
  return;
20744
20639
  }
20745
20640
 
@@ -21005,7 +20900,7 @@ function commitDetachRef(current) {
21005
20900
  // interrupt deletion, so it's okay
21006
20901
 
21007
20902
 
21008
- function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPriorityLevel) {
20903
+ function commitUnmount(finishedRoot, current, renderPriorityLevel) {
21009
20904
  onCommitUnmount(current);
21010
20905
 
21011
20906
  switch (current.tag) {
@@ -21025,14 +20920,16 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPrio
21025
20920
  var effect = firstEffect;
21026
20921
 
21027
20922
  do {
21028
- var _effect3 = effect,
21029
- destroy = _effect3.destroy,
21030
- tag = _effect3.tag;
20923
+ var _effect2 = effect,
20924
+ destroy = _effect2.destroy,
20925
+ tag = _effect2.tag;
21031
20926
 
21032
20927
  if (destroy !== undefined) {
21033
- if ((tag & Layout) !== NoFlags$1) {
20928
+ if ((tag & Passive$1) !== NoFlags$1) {
20929
+ enqueuePendingPassiveHookEffectUnmount(current, effect);
20930
+ } else {
21034
20931
  {
21035
- safelyCallDestroy(current, nearestMountedAncestor, destroy);
20932
+ safelyCallDestroy(current, destroy);
21036
20933
  }
21037
20934
  }
21038
20935
  }
@@ -21047,11 +20944,11 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPrio
21047
20944
 
21048
20945
  case ClassComponent:
21049
20946
  {
21050
- safelyDetachRef(current, nearestMountedAncestor);
20947
+ safelyDetachRef(current);
21051
20948
  var instance = current.stateNode;
21052
20949
 
21053
20950
  if (typeof instance.componentWillUnmount === 'function') {
21054
- safelyCallComponentWillUnmount(current, instance, nearestMountedAncestor);
20951
+ safelyCallComponentWillUnmount(current, instance);
21055
20952
  }
21056
20953
 
21057
20954
  return;
@@ -21059,7 +20956,7 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPrio
21059
20956
 
21060
20957
  case HostComponent:
21061
20958
  {
21062
- safelyDetachRef(current, nearestMountedAncestor);
20959
+ safelyDetachRef(current);
21063
20960
  return;
21064
20961
  }
21065
20962
 
@@ -21069,7 +20966,7 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPrio
21069
20966
  // We are also not using this parent because
21070
20967
  // the portal will get pushed immediately.
21071
20968
  {
21072
- unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
20969
+ unmountHostComponents(finishedRoot, current);
21073
20970
  }
21074
20971
 
21075
20972
  return;
@@ -21095,7 +20992,7 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor, renderPrio
21095
20992
  }
21096
20993
  }
21097
20994
 
21098
- function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor, renderPriorityLevel) {
20995
+ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
21099
20996
  // While we're inside a removed host node we don't want to call
21100
20997
  // removeChild on the inner nodes because they're removed by the top
21101
20998
  // call anyway. We also want to call componentWillUnmount on all
@@ -21104,7 +21001,7 @@ function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor, render
21104
21001
  var node = root;
21105
21002
 
21106
21003
  while (true) {
21107
- commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes.
21004
+ commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes.
21108
21005
  // Skip portals because commitUnmount() currently visits them recursively.
21109
21006
 
21110
21007
  if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
@@ -21133,26 +21030,33 @@ function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor, render
21133
21030
  }
21134
21031
 
21135
21032
  function detachFiberMutation(fiber) {
21136
- // Cut off the return pointer to disconnect it from the tree.
21137
- // This enables us to detect and warn against state updates on an unmounted component.
21138
- // It also prevents events from bubbling from within disconnected components.
21139
- //
21140
- // Ideally, we should also clear the child pointer of the parent alternate to let this
21033
+ // Cut off the return pointers to disconnect it from the tree. Ideally, we
21034
+ // should clear the child pointer of the parent alternate to let this
21141
21035
  // get GC:ed but we don't know which for sure which parent is the current
21142
- // one so we'll settle for GC:ing the subtree of this child.
21143
- // This child itself will be GC:ed when the parent updates the next time.
21036
+ // one so we'll settle for GC:ing the subtree of this child. This child
21037
+ // itself will be GC:ed when the parent updates the next time.
21038
+ // Note: we cannot null out sibling here, otherwise it can cause issues
21039
+ // with findDOMNode and how it requires the sibling field to carry out
21040
+ // traversal in a later effect. See PR #16820. We now clear the sibling
21041
+ // field after effects, see: detachFiberAfterEffects.
21144
21042
  //
21145
- // Note that we can't clear child or sibling pointers yet.
21146
- // They're needed for passive effects and for findDOMNode.
21147
- // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
21148
- var alternate = fiber.alternate;
21043
+ // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects.
21044
+ // It may be required if the current component is an error boundary,
21045
+ // and one of its descendants throws while unmounting a passive effect.
21046
+ fiber.alternate = null;
21047
+ fiber.child = null;
21048
+ fiber.dependencies = null;
21049
+ fiber.firstEffect = null;
21050
+ fiber.lastEffect = null;
21051
+ fiber.memoizedProps = null;
21052
+ fiber.memoizedState = null;
21053
+ fiber.pendingProps = null;
21054
+ fiber.return = null;
21055
+ fiber.updateQueue = null;
21149
21056
 
21150
- if (alternate !== null) {
21151
- alternate.return = null;
21152
- fiber.alternate = null;
21057
+ {
21058
+ fiber._debugOwner = null;
21153
21059
  }
21154
-
21155
- fiber.return = null;
21156
21060
  }
21157
21061
 
21158
21062
  function getHostParentFiber(fiber) {
@@ -21334,7 +21238,7 @@ function insertOrAppendPlacementNode(node, before, parent) {
21334
21238
  }
21335
21239
  }
21336
21240
 
21337
- function unmountHostComponents(finishedRoot, current, nearestMountedAncestor, renderPriorityLevel) {
21241
+ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
21338
21242
  // We only have the top Fiber that was deleted but we need to recurse down its
21339
21243
  // children to find all the terminal nodes.
21340
21244
  var node = current; // Each iteration, currentParent is populated with node's host parent if not
@@ -21383,7 +21287,7 @@ function unmountHostComponents(finishedRoot, current, nearestMountedAncestor, re
21383
21287
  }
21384
21288
 
21385
21289
  if (node.tag === HostComponent || node.tag === HostText) {
21386
- commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the
21290
+ commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the
21387
21291
  // node from the tree.
21388
21292
 
21389
21293
  if (currentParentIsContainer) {
@@ -21404,7 +21308,7 @@ function unmountHostComponents(finishedRoot, current, nearestMountedAncestor, re
21404
21308
  continue;
21405
21309
  }
21406
21310
  } else {
21407
- commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below.
21311
+ commitUnmount(finishedRoot, node); // Visit children because we may find more host components below.
21408
21312
 
21409
21313
  if (node.child !== null) {
21410
21314
  node.child.return = node;
@@ -21436,11 +21340,11 @@ function unmountHostComponents(finishedRoot, current, nearestMountedAncestor, re
21436
21340
  }
21437
21341
  }
21438
21342
 
21439
- function commitDeletion(finishedRoot, current, nearestMountedAncestor, renderPriorityLevel) {
21343
+ function commitDeletion(finishedRoot, current, renderPriorityLevel) {
21440
21344
  {
21441
21345
  // Recursively delete all host nodes from the parent.
21442
21346
  // Detach refs and call componentWillUnmount() on the whole subtree.
21443
- unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
21347
+ unmountHostComponents(finishedRoot, current);
21444
21348
  }
21445
21349
 
21446
21350
  var alternate = current.alternate;
@@ -21466,7 +21370,7 @@ function commitWork(current, finishedWork) {
21466
21370
  // e.g. a destroy function in one component should never override a ref set
21467
21371
  // by a create function in another component during the same commit.
21468
21372
  {
21469
- commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
21373
+ commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
21470
21374
  }
21471
21375
 
21472
21376
  return;
@@ -21682,42 +21586,6 @@ function commitResetTextContent(current) {
21682
21586
  resetTextContent(current.stateNode);
21683
21587
  }
21684
21588
 
21685
- function commitPassiveWork(finishedWork) {
21686
- switch (finishedWork.tag) {
21687
- case FunctionComponent:
21688
- case ForwardRef:
21689
- case SimpleMemoComponent:
21690
- case Block:
21691
- {
21692
- commitHookEffectListUnmount2(Passive$1 | HasEffect, finishedWork, finishedWork.return);
21693
- break;
21694
- }
21695
- }
21696
- }
21697
-
21698
- function commitPassiveUnmount(current, nearestMountedAncestor) {
21699
- switch (current.tag) {
21700
- case FunctionComponent:
21701
- case ForwardRef:
21702
- case SimpleMemoComponent:
21703
- case Block:
21704
- commitHookEffectListUnmount2(Passive$1, current, nearestMountedAncestor);
21705
- }
21706
- }
21707
-
21708
- function commitPassiveLifeCycles(finishedRoot, finishedWork) {
21709
- switch (finishedWork.tag) {
21710
- case FunctionComponent:
21711
- case ForwardRef:
21712
- case SimpleMemoComponent:
21713
- case Block:
21714
- {
21715
- commitHookEffectListMount2(finishedWork);
21716
- break;
21717
- }
21718
- }
21719
- }
21720
-
21721
21589
  var COMPONENT_TYPE = 0;
21722
21590
  var HAS_PSEUDO_CLASS_TYPE = 1;
21723
21591
  var ROLE_TYPE = 2;
@@ -21828,6 +21696,7 @@ function resetRenderTimer() {
21828
21696
  function getRenderTargetTime() {
21829
21697
  return workInProgressRootRenderTargetTime;
21830
21698
  }
21699
+ var nextEffect = null;
21831
21700
  var hasUncaughtError = false;
21832
21701
  var firstUncaughtError = null;
21833
21702
  var legacyErrorBoundariesThatAlreadyFailed = null;
@@ -21835,6 +21704,8 @@ var rootDoesHavePassiveEffects = false;
21835
21704
  var rootWithPendingPassiveEffects = null;
21836
21705
  var pendingPassiveEffectsRenderPriority = NoPriority$1;
21837
21706
  var pendingPassiveEffectsLanes = NoLanes;
21707
+ var pendingPassiveHookEffectsMount = [];
21708
+ var pendingPassiveHookEffectsUnmount = [];
21838
21709
  var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21839
21710
 
21840
21711
  var NESTED_UPDATE_LIMIT = 50;
@@ -22157,7 +22028,7 @@ function ensureRootIsScheduled(root, currentTime) {
22157
22028
  // goes through Scheduler.
22158
22029
 
22159
22030
 
22160
- function performConcurrentWorkOnRoot(root, didTimeout) {
22031
+ function performConcurrentWorkOnRoot(root) {
22161
22032
  // Since we know we're in a React event, we can clear the current
22162
22033
  // event time. The next update will compute a new event time.
22163
22034
  currentEventTime = NoTimestamp;
@@ -22193,18 +22064,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
22193
22064
  if (lanes === NoLanes) {
22194
22065
  // Defensive coding. This is never expected to happen.
22195
22066
  return null;
22196
- } // TODO: We only check `didTimeout` defensively, to account for a Scheduler
22197
- // bug we're still investigating. Once the bug in Scheduler is fixed,
22198
- // we can remove this, since we track expiration ourselves.
22199
-
22200
-
22201
- if ( didTimeout) {
22202
- // Something expired. Flush synchronously until there's no expired
22203
- // work left.
22204
- markRootExpired(root, lanes); // This will schedule a synchronous callback.
22205
-
22206
- ensureRootIsScheduled(root, now());
22207
- return null;
22208
22067
  }
22209
22068
 
22210
22069
  var exitStatus = renderRootConcurrent(root, lanes);
@@ -22965,6 +22824,46 @@ function completeUnitOfWork(unitOfWork) {
22965
22824
  workInProgress = next;
22966
22825
  return;
22967
22826
  }
22827
+
22828
+ resetChildLanes(completedWork);
22829
+
22830
+ if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22831
+ (returnFiber.flags & Incomplete) === NoFlags) {
22832
+ // Append all the effects of the subtree and this fiber onto the effect
22833
+ // list of the parent. The completion order of the children affects the
22834
+ // side-effect order.
22835
+ if (returnFiber.firstEffect === null) {
22836
+ returnFiber.firstEffect = completedWork.firstEffect;
22837
+ }
22838
+
22839
+ if (completedWork.lastEffect !== null) {
22840
+ if (returnFiber.lastEffect !== null) {
22841
+ returnFiber.lastEffect.nextEffect = completedWork.firstEffect;
22842
+ }
22843
+
22844
+ returnFiber.lastEffect = completedWork.lastEffect;
22845
+ } // If this fiber had side-effects, we append it AFTER the children's
22846
+ // side-effects. We can perform certain side-effects earlier if needed,
22847
+ // by doing multiple passes over the effect list. We don't want to
22848
+ // schedule our own side-effect on our own list because if end up
22849
+ // reusing children we'll schedule this effect onto itself since we're
22850
+ // at the end.
22851
+
22852
+
22853
+ var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect
22854
+ // list. PerformedWork effect is read by React DevTools but shouldn't be
22855
+ // committed.
22856
+
22857
+ if (flags > PerformedWork) {
22858
+ if (returnFiber.lastEffect !== null) {
22859
+ returnFiber.lastEffect.nextEffect = completedWork;
22860
+ } else {
22861
+ returnFiber.firstEffect = completedWork;
22862
+ }
22863
+
22864
+ returnFiber.lastEffect = completedWork;
22865
+ }
22866
+ }
22968
22867
  } else {
22969
22868
  // This fiber did not complete because something threw. Pop values off
22970
22869
  // the stack without entering the complete phase. If this is a boundary,
@@ -22998,10 +22897,9 @@ function completeUnitOfWork(unitOfWork) {
22998
22897
  }
22999
22898
 
23000
22899
  if (returnFiber !== null) {
23001
- // Mark the parent fiber as incomplete
22900
+ // Mark the parent fiber as incomplete and clear its effect list.
22901
+ returnFiber.firstEffect = returnFiber.lastEffect = null;
23002
22902
  returnFiber.flags |= Incomplete;
23003
- returnFiber.subtreeFlags = NoFlags;
23004
- returnFiber.deletions = null;
23005
22903
  }
23006
22904
  }
23007
22905
 
@@ -23025,6 +22923,68 @@ function completeUnitOfWork(unitOfWork) {
23025
22923
  }
23026
22924
  }
23027
22925
 
22926
+ function resetChildLanes(completedWork) {
22927
+ if ( // TODO: Move this check out of the hot path by moving `resetChildLanes`
22928
+ // to switch statement in `completeWork`.
22929
+ (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) {
22930
+ // The children of this component are hidden. Don't bubble their
22931
+ // expiration times.
22932
+ return;
22933
+ }
22934
+
22935
+ var newChildLanes = NoLanes; // Bubble up the earliest expiration time.
22936
+
22937
+ if ( (completedWork.mode & ProfileMode) !== NoMode) {
22938
+ // In profiling mode, resetChildExpirationTime is also used to reset
22939
+ // profiler durations.
22940
+ var actualDuration = completedWork.actualDuration;
22941
+ var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22942
+ // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22943
+ // When work is done, it should bubble to the parent's actualDuration. If
22944
+ // the fiber has not been cloned though, (meaning no work was done), then
22945
+ // this value will reflect the amount of time spent working on a previous
22946
+ // render. In that case it should not bubble. We determine whether it was
22947
+ // cloned by comparing the child pointer.
22948
+
22949
+ var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22950
+ var child = completedWork.child;
22951
+
22952
+ while (child !== null) {
22953
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
22954
+
22955
+ if (shouldBubbleActualDurations) {
22956
+ actualDuration += child.actualDuration;
22957
+ }
22958
+
22959
+ treeBaseDuration += child.treeBaseDuration;
22960
+ child = child.sibling;
22961
+ }
22962
+
22963
+ var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null;
22964
+
22965
+ if (isTimedOutSuspense) {
22966
+ // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22967
+ var primaryChildFragment = completedWork.child;
22968
+
22969
+ if (primaryChildFragment !== null) {
22970
+ treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22971
+ }
22972
+ }
22973
+
22974
+ completedWork.actualDuration = actualDuration;
22975
+ completedWork.treeBaseDuration = treeBaseDuration;
22976
+ } else {
22977
+ var _child = completedWork.child;
22978
+
22979
+ while (_child !== null) {
22980
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
22981
+ _child = _child.sibling;
22982
+ }
22983
+ }
22984
+
22985
+ completedWork.childLanes = newChildLanes;
22986
+ }
22987
+
23028
22988
  function commitRoot(root) {
23029
22989
  var renderPriorityLevel = getCurrentPriorityLevel();
23030
22990
  runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));
@@ -23088,17 +23048,28 @@ function commitRootImpl(root, renderPriorityLevel) {
23088
23048
  workInProgressRoot = null;
23089
23049
  workInProgress = null;
23090
23050
  workInProgressRootRenderLanes = NoLanes;
23091
- } // Check if there are any effects in the whole tree.
23092
- // TODO: This is left over from the effect list implementation, where we had
23093
- // to check for the existence of `firstEffect` to satsify Flow. I think the
23094
- // only other reason this optimization exists is because it affects profiling.
23095
- // Reconsider whether this is necessary.
23051
+ } // Get the list of effects.
23096
23052
 
23097
23053
 
23098
- var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
23099
- var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
23054
+ var firstEffect;
23100
23055
 
23101
- if (subtreeHasEffects || rootHasEffect) {
23056
+ if (finishedWork.flags > PerformedWork) {
23057
+ // A fiber's effect list consists only of its children, not itself. So if
23058
+ // the root has an effect, we need to add it to the end of the list. The
23059
+ // resulting list is the set that would belong to the root's parent, if it
23060
+ // had one; that is, all the effects in the tree including the root.
23061
+ if (finishedWork.lastEffect !== null) {
23062
+ finishedWork.lastEffect.nextEffect = finishedWork;
23063
+ firstEffect = finishedWork.firstEffect;
23064
+ } else {
23065
+ firstEffect = finishedWork;
23066
+ }
23067
+ } else {
23068
+ // There is no effect on the root.
23069
+ firstEffect = finishedWork.firstEffect;
23070
+ }
23071
+
23072
+ if (firstEffect !== null) {
23102
23073
 
23103
23074
  var prevExecutionContext = executionContext;
23104
23075
  executionContext |= CommitContext;
@@ -23113,7 +23084,26 @@ function commitRootImpl(root, renderPriorityLevel) {
23113
23084
 
23114
23085
  focusedInstanceHandle = prepareForCommit(root.containerInfo);
23115
23086
  shouldFireAfterActiveInstanceBlur = false;
23116
- commitBeforeMutationEffects(finishedWork); // We no longer need to track the active instance fiber
23087
+ nextEffect = firstEffect;
23088
+
23089
+ do {
23090
+ {
23091
+ invokeGuardedCallback(null, commitBeforeMutationEffects, null);
23092
+
23093
+ if (hasCaughtError()) {
23094
+ if (!(nextEffect !== null)) {
23095
+ {
23096
+ throw Error( "Should be working on an effect." );
23097
+ }
23098
+ }
23099
+
23100
+ var error = clearCaughtError();
23101
+ captureCommitPhaseError(nextEffect, error);
23102
+ nextEffect = nextEffect.nextEffect;
23103
+ }
23104
+ }
23105
+ } while (nextEffect !== null); // We no longer need to track the active instance fiber
23106
+
23117
23107
 
23118
23108
  focusedInstanceHandle = null;
23119
23109
 
@@ -23124,7 +23114,26 @@ function commitRootImpl(root, renderPriorityLevel) {
23124
23114
  } // The next phase is the mutation phase, where we mutate the host tree.
23125
23115
 
23126
23116
 
23127
- commitMutationEffects(finishedWork, root, renderPriorityLevel);
23117
+ nextEffect = firstEffect;
23118
+
23119
+ do {
23120
+ {
23121
+ invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
23122
+
23123
+ if (hasCaughtError()) {
23124
+ if (!(nextEffect !== null)) {
23125
+ {
23126
+ throw Error( "Should be working on an effect." );
23127
+ }
23128
+ }
23129
+
23130
+ var _error = clearCaughtError();
23131
+
23132
+ captureCommitPhaseError(nextEffect, _error);
23133
+ nextEffect = nextEffect.nextEffect;
23134
+ }
23135
+ }
23136
+ } while (nextEffect !== null);
23128
23137
 
23129
23138
  resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
23130
23139
  // the mutation phase, so that the previous tree is still current during
@@ -23132,21 +23141,32 @@ function commitRootImpl(root, renderPriorityLevel) {
23132
23141
  // work is current during componentDidMount/Update.
23133
23142
 
23134
23143
  root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
23144
+ // the host tree after it's been mutated. The idiomatic use case for this is
23145
+ // layout, but class component lifecycles also fire here for legacy reasons.
23135
23146
 
23136
- commitLayoutEffects(finishedWork, root, lanes);
23147
+ nextEffect = firstEffect;
23137
23148
 
23149
+ do {
23150
+ {
23151
+ invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes);
23138
23152
 
23139
- if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
23140
- if (!rootDoesHavePassiveEffects) {
23141
- rootDoesHavePassiveEffects = true;
23142
- scheduleCallback(NormalPriority$1, function () {
23143
- flushPassiveEffects();
23144
- return null;
23145
- });
23153
+ if (hasCaughtError()) {
23154
+ if (!(nextEffect !== null)) {
23155
+ {
23156
+ throw Error( "Should be working on an effect." );
23157
+ }
23158
+ }
23159
+
23160
+ var _error2 = clearCaughtError();
23161
+
23162
+ captureCommitPhaseError(nextEffect, _error2);
23163
+ nextEffect = nextEffect.nextEffect;
23164
+ }
23146
23165
  }
23147
- } // Tell Scheduler to yield at the end of the frame, so the browser has an
23148
- // opportunity to paint.
23166
+ } while (nextEffect !== null);
23149
23167
 
23168
+ nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
23169
+ // opportunity to paint.
23150
23170
 
23151
23171
  requestPaint();
23152
23172
 
@@ -23175,6 +23195,22 @@ function commitRootImpl(root, renderPriorityLevel) {
23175
23195
  rootWithPendingPassiveEffects = root;
23176
23196
  pendingPassiveEffectsLanes = lanes;
23177
23197
  pendingPassiveEffectsRenderPriority = renderPriorityLevel;
23198
+ } else {
23199
+ // We are done with the effect chain at this point so let's clear the
23200
+ // nextEffect pointers to assist with GC. If we have passive effects, we'll
23201
+ // clear this in flushPassiveEffects.
23202
+ nextEffect = firstEffect;
23203
+
23204
+ while (nextEffect !== null) {
23205
+ var nextNextEffect = nextEffect.nextEffect;
23206
+ nextEffect.nextEffect = null;
23207
+
23208
+ if (nextEffect.flags & Deletion) {
23209
+ detachFiberAfterEffects(nextEffect);
23210
+ }
23211
+
23212
+ nextEffect = nextNextEffect;
23213
+ }
23178
23214
  } // Read this again, since an effect might have updated it
23179
23215
 
23180
23216
 
@@ -23234,9 +23270,9 @@ function commitRootImpl(root, renderPriorityLevel) {
23234
23270
 
23235
23271
  if (hasUncaughtError) {
23236
23272
  hasUncaughtError = false;
23237
- var error = firstUncaughtError;
23273
+ var _error3 = firstUncaughtError;
23238
23274
  firstUncaughtError = null;
23239
- throw error;
23275
+ throw _error3;
23240
23276
  }
23241
23277
 
23242
23278
  if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
@@ -23254,255 +23290,151 @@ function commitRootImpl(root, renderPriorityLevel) {
23254
23290
  return null;
23255
23291
  }
23256
23292
 
23257
- function commitBeforeMutationEffects(firstChild) {
23258
- var fiber = firstChild;
23259
-
23260
- while (fiber !== null) {
23261
- if (fiber.deletions !== null) {
23262
- commitBeforeMutationEffectsDeletions(fiber.deletions);
23263
- }
23264
-
23265
- if (fiber.child !== null) {
23266
- var primarySubtreeFlags = fiber.subtreeFlags & BeforeMutationMask;
23293
+ function commitBeforeMutationEffects() {
23294
+ while (nextEffect !== null) {
23295
+ var current = nextEffect.alternate;
23267
23296
 
23268
- if (primarySubtreeFlags !== NoFlags) {
23269
- commitBeforeMutationEffects(fiber.child);
23297
+ if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {
23298
+ if ((nextEffect.flags & Deletion) !== NoFlags) {
23299
+ if (doesFiberContain(nextEffect, focusedInstanceHandle)) {
23300
+ shouldFireAfterActiveInstanceBlur = true;
23301
+ }
23302
+ } else {
23303
+ // TODO: Move this out of the hot path using a dedicated effect tag.
23304
+ if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) {
23305
+ shouldFireAfterActiveInstanceBlur = true;
23306
+ }
23270
23307
  }
23271
23308
  }
23272
23309
 
23273
- {
23274
- setCurrentFiber(fiber);
23275
- invokeGuardedCallback(null, commitBeforeMutationEffectsImpl, null, fiber);
23276
-
23277
- if (hasCaughtError()) {
23278
- var error = clearCaughtError();
23279
- captureCommitPhaseError(fiber, fiber.return, error);
23280
- }
23310
+ var flags = nextEffect.flags;
23281
23311
 
23312
+ if ((flags & Snapshot) !== NoFlags) {
23313
+ setCurrentFiber(nextEffect);
23314
+ commitBeforeMutationLifeCycles(current, nextEffect);
23282
23315
  resetCurrentFiber();
23283
23316
  }
23284
23317
 
23285
- fiber = fiber.sibling;
23286
- }
23287
- }
23288
-
23289
- function commitBeforeMutationEffectsImpl(fiber) {
23290
- var current = fiber.alternate;
23291
- var flags = fiber.flags;
23292
-
23293
- if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {
23294
- // Check to see if the focused element was inside of a hidden (Suspense) subtree.
23295
- // TODO: Move this out of the hot path using a dedicated effect tag.
23296
- if (fiber.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, fiber) && doesFiberContain(fiber, focusedInstanceHandle)) {
23297
- shouldFireAfterActiveInstanceBlur = true;
23298
- }
23299
- }
23300
-
23301
- if ((flags & Snapshot) !== NoFlags) {
23302
- setCurrentFiber(fiber);
23303
- commitBeforeMutationLifeCycles(current, fiber);
23304
- resetCurrentFiber();
23305
- }
23306
-
23307
- if ((flags & Passive) !== NoFlags) {
23308
- // If there are passive effects, schedule a callback to flush at
23309
- // the earliest opportunity.
23310
- if (!rootDoesHavePassiveEffects) {
23311
- rootDoesHavePassiveEffects = true;
23312
- scheduleCallback(NormalPriority$1, function () {
23313
- flushPassiveEffects();
23314
- return null;
23315
- });
23316
- }
23317
- }
23318
- }
23319
-
23320
- function commitBeforeMutationEffectsDeletions(deletions) {
23321
- for (var i = 0; i < deletions.length; i++) {
23322
- var fiber = deletions[i]; // TODO (effects) It would be nice to avoid calling doesFiberContain()
23323
- // Maybe we can repurpose one of the subtreeFlags positions for this instead?
23324
- // Use it to store which part of the tree the focused instance is in?
23325
- // This assumes we can safely determine that instance during the "render" phase.
23326
-
23327
- if (doesFiberContain(fiber, focusedInstanceHandle)) {
23328
- shouldFireAfterActiveInstanceBlur = true;
23329
- }
23330
- }
23331
- }
23332
-
23333
- function commitMutationEffects(firstChild, root, renderPriorityLevel) {
23334
- var fiber = firstChild;
23335
-
23336
- while (fiber !== null) {
23337
- var deletions = fiber.deletions;
23338
-
23339
- if (deletions !== null) {
23340
- commitMutationEffectsDeletions(deletions, fiber, root, renderPriorityLevel);
23341
- }
23342
-
23343
- if (fiber.child !== null) {
23344
- var mutationFlags = fiber.subtreeFlags & MutationMask;
23345
-
23346
- if (mutationFlags !== NoFlags) {
23347
- commitMutationEffects(fiber.child, root, renderPriorityLevel);
23348
- }
23349
- }
23350
-
23351
- {
23352
- setCurrentFiber(fiber);
23353
- invokeGuardedCallback(null, commitMutationEffectsImpl, null, fiber, root, renderPriorityLevel);
23354
-
23355
- if (hasCaughtError()) {
23356
- var error = clearCaughtError();
23357
- captureCommitPhaseError(fiber, fiber.return, error);
23318
+ if ((flags & Passive) !== NoFlags) {
23319
+ // If there are passive effects, schedule a callback to flush at
23320
+ // the earliest opportunity.
23321
+ if (!rootDoesHavePassiveEffects) {
23322
+ rootDoesHavePassiveEffects = true;
23323
+ scheduleCallback(NormalPriority$1, function () {
23324
+ flushPassiveEffects();
23325
+ return null;
23326
+ });
23358
23327
  }
23359
-
23360
- resetCurrentFiber();
23361
23328
  }
23362
23329
 
23363
- fiber = fiber.sibling;
23330
+ nextEffect = nextEffect.nextEffect;
23364
23331
  }
23365
23332
  }
23366
23333
 
23367
- function commitMutationEffectsImpl(fiber, root, renderPriorityLevel) {
23368
- var flags = fiber.flags;
23369
-
23370
- if (flags & ContentReset) {
23371
- commitResetTextContent(fiber);
23372
- }
23373
-
23374
- if (flags & Ref) {
23375
- var current = fiber.alternate;
23334
+ function commitMutationEffects(root, renderPriorityLevel) {
23335
+ // TODO: Should probably move the bulk of this function to commitWork.
23336
+ while (nextEffect !== null) {
23337
+ setCurrentFiber(nextEffect);
23338
+ var flags = nextEffect.flags;
23376
23339
 
23377
- if (current !== null) {
23378
- commitDetachRef(current);
23340
+ if (flags & ContentReset) {
23341
+ commitResetTextContent(nextEffect);
23379
23342
  }
23380
- } // The following switch statement is only concerned about placement,
23381
- // updates, and deletions. To avoid needing to add a case for every possible
23382
- // bitmap value, we remove the secondary effects from the effect tag and
23383
- // switch on that value.
23384
23343
 
23344
+ if (flags & Ref) {
23345
+ var current = nextEffect.alternate;
23385
23346
 
23386
- var primaryFlags = flags & (Placement | Update | Hydrating);
23347
+ if (current !== null) {
23348
+ commitDetachRef(current);
23349
+ }
23350
+ } // The following switch statement is only concerned about placement,
23351
+ // updates, and deletions. To avoid needing to add a case for every possible
23352
+ // bitmap value, we remove the secondary effects from the effect tag and
23353
+ // switch on that value.
23387
23354
 
23388
- switch (primaryFlags) {
23389
- case Placement:
23390
- {
23391
- commitPlacement(fiber); // Clear the "placement" from effect tag so that we know that this is
23392
- // inserted, before any life-cycles like componentDidMount gets called.
23393
- // TODO: findDOMNode doesn't rely on this any more but isMounted does
23394
- // and isMounted is deprecated anyway so we should be able to kill this.
23395
23355
 
23396
- fiber.flags &= ~Placement;
23397
- break;
23398
- }
23356
+ var primaryFlags = flags & (Placement | Update | Deletion | Hydrating);
23399
23357
 
23400
- case PlacementAndUpdate:
23401
- {
23402
- // Placement
23403
- commitPlacement(fiber); // Clear the "placement" from effect tag so that we know that this is
23404
- // inserted, before any life-cycles like componentDidMount gets called.
23358
+ switch (primaryFlags) {
23359
+ case Placement:
23360
+ {
23361
+ commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23362
+ // inserted, before any life-cycles like componentDidMount gets called.
23363
+ // TODO: findDOMNode doesn't rely on this any more but isMounted does
23364
+ // and isMounted is deprecated anyway so we should be able to kill this.
23405
23365
 
23406
- fiber.flags &= ~Placement; // Update
23366
+ nextEffect.flags &= ~Placement;
23367
+ break;
23368
+ }
23407
23369
 
23408
- var _current = fiber.alternate;
23409
- commitWork(_current, fiber);
23410
- break;
23411
- }
23370
+ case PlacementAndUpdate:
23371
+ {
23372
+ // Placement
23373
+ commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23374
+ // inserted, before any life-cycles like componentDidMount gets called.
23412
23375
 
23413
- case Hydrating:
23414
- {
23415
- fiber.flags &= ~Hydrating;
23416
- break;
23417
- }
23376
+ nextEffect.flags &= ~Placement; // Update
23418
23377
 
23419
- case HydratingAndUpdate:
23420
- {
23421
- fiber.flags &= ~Hydrating; // Update
23378
+ var _current = nextEffect.alternate;
23379
+ commitWork(_current, nextEffect);
23380
+ break;
23381
+ }
23422
23382
 
23423
- var _current2 = fiber.alternate;
23424
- commitWork(_current2, fiber);
23425
- break;
23426
- }
23383
+ case Hydrating:
23384
+ {
23385
+ nextEffect.flags &= ~Hydrating;
23386
+ break;
23387
+ }
23427
23388
 
23428
- case Update:
23429
- {
23430
- var _current3 = fiber.alternate;
23431
- commitWork(_current3, fiber);
23432
- break;
23433
- }
23434
- }
23435
- }
23389
+ case HydratingAndUpdate:
23390
+ {
23391
+ nextEffect.flags &= ~Hydrating; // Update
23436
23392
 
23437
- function commitMutationEffectsDeletions(deletions, nearestMountedAncestor, root, renderPriorityLevel) {
23438
- for (var i = 0; i < deletions.length; i++) {
23439
- var childToDelete = deletions[i];
23393
+ var _current2 = nextEffect.alternate;
23394
+ commitWork(_current2, nextEffect);
23395
+ break;
23396
+ }
23440
23397
 
23441
- {
23442
- invokeGuardedCallback(null, commitDeletion, null, root, childToDelete, nearestMountedAncestor, renderPriorityLevel);
23398
+ case Update:
23399
+ {
23400
+ var _current3 = nextEffect.alternate;
23401
+ commitWork(_current3, nextEffect);
23402
+ break;
23403
+ }
23443
23404
 
23444
- if (hasCaughtError()) {
23445
- var error = clearCaughtError();
23446
- captureCommitPhaseError(childToDelete, nearestMountedAncestor, error);
23447
- }
23405
+ case Deletion:
23406
+ {
23407
+ commitDeletion(root, nextEffect);
23408
+ break;
23409
+ }
23448
23410
  }
23449
- }
23450
- }
23451
23411
 
23452
- function schedulePassiveEffectCallback() {
23453
- if (!rootDoesHavePassiveEffects) {
23454
- rootDoesHavePassiveEffects = true;
23455
- scheduleCallback(NormalPriority$1, function () {
23456
- flushPassiveEffects();
23457
- return null;
23458
- });
23412
+ resetCurrentFiber();
23413
+ nextEffect = nextEffect.nextEffect;
23459
23414
  }
23460
23415
  }
23461
23416
 
23462
- function commitLayoutEffects(firstChild, root, committedLanes) {
23463
- var fiber = firstChild;
23417
+ function commitLayoutEffects(root, committedLanes) {
23464
23418
 
23465
- while (fiber !== null) {
23466
- if (fiber.child !== null) {
23467
- var primarySubtreeFlags = fiber.subtreeFlags & LayoutMask;
23468
23419
 
23469
- if (primarySubtreeFlags !== NoFlags) {
23470
- commitLayoutEffects(fiber.child, root, committedLanes);
23471
- }
23420
+ while (nextEffect !== null) {
23421
+ setCurrentFiber(nextEffect);
23422
+ var flags = nextEffect.flags;
23423
+
23424
+ if (flags & (Update | Callback)) {
23425
+ var current = nextEffect.alternate;
23426
+ commitLifeCycles(root, current, nextEffect);
23472
23427
  }
23473
23428
 
23474
23429
  {
23475
- setCurrentFiber(fiber);
23476
- invokeGuardedCallback(null, commitLayoutEffectsImpl, null, fiber, root, committedLanes);
23477
-
23478
- if (hasCaughtError()) {
23479
- var error = clearCaughtError();
23480
- captureCommitPhaseError(fiber, fiber.return, error);
23430
+ if (flags & Ref) {
23431
+ commitAttachRef(nextEffect);
23481
23432
  }
23482
-
23483
- resetCurrentFiber();
23484
23433
  }
23485
23434
 
23486
- fiber = fiber.sibling;
23487
- }
23488
- }
23489
-
23490
- function commitLayoutEffectsImpl(fiber, root, committedLanes) {
23491
- var flags = fiber.flags;
23492
- setCurrentFiber(fiber);
23493
-
23494
- if (flags & (Update | Callback)) {
23495
- var current = fiber.alternate;
23496
- commitLifeCycles(root, current, fiber);
23497
- }
23498
-
23499
- {
23500
- if (flags & Ref) {
23501
- commitAttachRef(fiber);
23502
- }
23435
+ resetCurrentFiber();
23436
+ nextEffect = nextEffect.nextEffect;
23503
23437
  }
23504
-
23505
- resetCurrentFiber();
23506
23438
  }
23507
23439
 
23508
23440
  function flushPassiveEffects() {
@@ -23518,87 +23450,41 @@ function flushPassiveEffects() {
23518
23450
 
23519
23451
  return false;
23520
23452
  }
23453
+ function enqueuePendingPassiveHookEffectMount(fiber, effect) {
23454
+ pendingPassiveHookEffectsMount.push(effect, fiber);
23521
23455
 
23522
- function flushPassiveMountEffects(root, firstChild) {
23523
- var fiber = firstChild;
23524
-
23525
- while (fiber !== null) {
23526
- var primarySubtreeFlags = fiber.subtreeFlags & PassiveMask;
23527
-
23528
- if (fiber.child !== null && primarySubtreeFlags !== NoFlags) {
23529
- flushPassiveMountEffects(root, fiber.child);
23530
- }
23531
-
23532
- if ((fiber.flags & Passive) !== NoFlags) {
23533
- setCurrentFiber(fiber);
23534
- commitPassiveLifeCycles(root, fiber);
23535
- resetCurrentFiber();
23536
- }
23537
-
23538
- fiber = fiber.sibling;
23456
+ if (!rootDoesHavePassiveEffects) {
23457
+ rootDoesHavePassiveEffects = true;
23458
+ scheduleCallback(NormalPriority$1, function () {
23459
+ flushPassiveEffects();
23460
+ return null;
23461
+ });
23539
23462
  }
23540
23463
  }
23464
+ function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {
23465
+ pendingPassiveHookEffectsUnmount.push(effect, fiber);
23541
23466
 
23542
- function flushPassiveUnmountEffects(firstChild) {
23543
- var fiber = firstChild;
23544
-
23545
- while (fiber !== null) {
23546
- var deletions = fiber.deletions;
23547
-
23548
- if (deletions !== null) {
23549
- for (var i = 0; i < deletions.length; i++) {
23550
- var fiberToDelete = deletions[i];
23551
- flushPassiveUnmountEffectsInsideOfDeletedTree(fiberToDelete, fiber); // Now that passive effects have been processed, it's safe to detach lingering pointers.
23552
-
23553
- detachFiberAfterEffects(fiberToDelete);
23554
- }
23555
- }
23556
-
23557
- var child = fiber.child;
23558
-
23559
- if (child !== null) {
23560
- // If any children have passive effects then traverse the subtree.
23561
- // Note that this requires checking subtreeFlags of the current Fiber,
23562
- // rather than the subtreeFlags/effectsTag of the first child,
23563
- // since that would not cover passive effects in siblings.
23564
- var passiveFlags = fiber.subtreeFlags & PassiveMask;
23565
-
23566
- if (passiveFlags !== NoFlags) {
23567
- flushPassiveUnmountEffects(child);
23568
- }
23569
- }
23570
-
23571
- var primaryFlags = fiber.flags & Passive;
23467
+ {
23468
+ fiber.flags |= PassiveUnmountPendingDev;
23469
+ var alternate = fiber.alternate;
23572
23470
 
23573
- if (primaryFlags !== NoFlags) {
23574
- setCurrentFiber(fiber);
23575
- commitPassiveWork(fiber);
23576
- resetCurrentFiber();
23471
+ if (alternate !== null) {
23472
+ alternate.flags |= PassiveUnmountPendingDev;
23577
23473
  }
23578
-
23579
- fiber = fiber.sibling;
23580
23474
  }
23581
- }
23582
-
23583
- function flushPassiveUnmountEffectsInsideOfDeletedTree(fiberToDelete, nearestMountedAncestor) {
23584
- if ((fiberToDelete.subtreeFlags & PassiveStatic) !== NoFlags) {
23585
- // If any children have passive effects then traverse the subtree.
23586
- // Note that this requires checking subtreeFlags of the current Fiber,
23587
- // rather than the subtreeFlags/effectsTag of the first child,
23588
- // since that would not cover passive effects in siblings.
23589
- var child = fiberToDelete.child;
23590
23475
 
23591
- while (child !== null) {
23592
- flushPassiveUnmountEffectsInsideOfDeletedTree(child, nearestMountedAncestor);
23593
- child = child.sibling;
23594
- }
23476
+ if (!rootDoesHavePassiveEffects) {
23477
+ rootDoesHavePassiveEffects = true;
23478
+ scheduleCallback(NormalPriority$1, function () {
23479
+ flushPassiveEffects();
23480
+ return null;
23481
+ });
23595
23482
  }
23483
+ }
23596
23484
 
23597
- if ((fiberToDelete.flags & PassiveStatic) !== NoFlags) {
23598
- setCurrentFiber(fiberToDelete);
23599
- commitPassiveUnmount(fiberToDelete, nearestMountedAncestor);
23600
- resetCurrentFiber();
23601
- }
23485
+ function invokePassiveEffectCreate(effect) {
23486
+ var create = effect.create;
23487
+ effect.destroy = create();
23602
23488
  }
23603
23489
 
23604
23490
  function flushPassiveEffectsImpl() {
@@ -23629,9 +23515,97 @@ function flushPassiveEffectsImpl() {
23629
23515
  // e.g. a destroy function in one component may unintentionally override a ref
23630
23516
  // value set by a create function in another component.
23631
23517
  // Layout effects have the same constraint.
23518
+ // First pass: Destroy stale passive effects.
23519
+
23520
+ var unmountEffects = pendingPassiveHookEffectsUnmount;
23521
+ pendingPassiveHookEffectsUnmount = [];
23522
+
23523
+ for (var i = 0; i < unmountEffects.length; i += 2) {
23524
+ var _effect = unmountEffects[i];
23525
+ var fiber = unmountEffects[i + 1];
23526
+ var destroy = _effect.destroy;
23527
+ _effect.destroy = undefined;
23528
+
23529
+ {
23530
+ fiber.flags &= ~PassiveUnmountPendingDev;
23531
+ var alternate = fiber.alternate;
23532
+
23533
+ if (alternate !== null) {
23534
+ alternate.flags &= ~PassiveUnmountPendingDev;
23535
+ }
23536
+ }
23537
+
23538
+ if (typeof destroy === 'function') {
23539
+ {
23540
+ setCurrentFiber(fiber);
23541
+
23542
+ {
23543
+ invokeGuardedCallback(null, destroy, null);
23544
+ }
23545
+
23546
+ if (hasCaughtError()) {
23547
+ if (!(fiber !== null)) {
23548
+ {
23549
+ throw Error( "Should be working on an effect." );
23550
+ }
23551
+ }
23552
+
23553
+ var error = clearCaughtError();
23554
+ captureCommitPhaseError(fiber, error);
23555
+ }
23556
+
23557
+ resetCurrentFiber();
23558
+ }
23559
+ }
23560
+ } // Second pass: Create new passive effects.
23632
23561
 
23633
- flushPassiveUnmountEffects(root.current);
23634
- flushPassiveMountEffects(root, root.current);
23562
+
23563
+ var mountEffects = pendingPassiveHookEffectsMount;
23564
+ pendingPassiveHookEffectsMount = [];
23565
+
23566
+ for (var _i = 0; _i < mountEffects.length; _i += 2) {
23567
+ var _effect2 = mountEffects[_i];
23568
+ var _fiber = mountEffects[_i + 1];
23569
+
23570
+ {
23571
+ setCurrentFiber(_fiber);
23572
+
23573
+ {
23574
+ invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2);
23575
+ }
23576
+
23577
+ if (hasCaughtError()) {
23578
+ if (!(_fiber !== null)) {
23579
+ {
23580
+ throw Error( "Should be working on an effect." );
23581
+ }
23582
+ }
23583
+
23584
+ var _error4 = clearCaughtError();
23585
+
23586
+ captureCommitPhaseError(_fiber, _error4);
23587
+ }
23588
+
23589
+ resetCurrentFiber();
23590
+ }
23591
+ } // Note: This currently assumes there are no passive effects on the root fiber
23592
+ // because the root is not part of its own effect list.
23593
+ // This could change in the future.
23594
+
23595
+
23596
+ var effect = root.current.firstEffect;
23597
+
23598
+ while (effect !== null) {
23599
+ var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
23600
+
23601
+ effect.nextEffect = null;
23602
+
23603
+ if (effect.flags & Deletion) {
23604
+ detachFiberAfterEffects(effect);
23605
+ }
23606
+
23607
+ effect = nextNextEffect;
23608
+ }
23635
23609
 
23636
23610
  {
23637
23611
  popInteractions(prevInteractions);
@@ -23684,7 +23658,7 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23684
23658
  }
23685
23659
  }
23686
23660
 
23687
- function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) {
23661
+ function captureCommitPhaseError(sourceFiber, error) {
23688
23662
  if (sourceFiber.tag === HostRoot) {
23689
23663
  // Error was thrown at the root. There is no parent, so the root
23690
23664
  // itself should capture it.
@@ -23692,11 +23666,7 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) {
23692
23666
  return;
23693
23667
  }
23694
23668
 
23695
- var fiber = null;
23696
-
23697
- {
23698
- fiber = nearestMountedAncestor;
23699
- }
23669
+ var fiber = sourceFiber.return;
23700
23670
 
23701
23671
  while (fiber !== null) {
23702
23672
  if (fiber.tag === HostRoot) {
@@ -23717,6 +23687,20 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) {
23717
23687
  markRootUpdated(root, SyncLane, eventTime);
23718
23688
  ensureRootIsScheduled(root, eventTime);
23719
23689
  schedulePendingInteractions(root, SyncLane);
23690
+ } else {
23691
+ // This component has already been unmounted.
23692
+ // We can't schedule any follow up work for the root because the fiber is already unmounted,
23693
+ // but we can still call the log-only boundary so the error isn't swallowed.
23694
+ //
23695
+ // TODO This is only a temporary bandaid for the old reconciler fork.
23696
+ // We can delete this special case once the new fork is merged.
23697
+ if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23698
+ try {
23699
+ instance.componentDidCatch(error, errorInfo);
23700
+ } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it?
23701
+ // This is kind of an edge case.
23702
+ }
23703
+ }
23720
23704
  }
23721
23705
 
23722
23706
  return;
@@ -23899,29 +23883,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23899
23883
  if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23900
23884
  // Only warn for user-defined components, not internal ones like Suspense.
23901
23885
  return;
23902
- }
23903
-
23904
- if ((fiber.flags & PassiveStatic) !== NoFlags) {
23905
- var updateQueue = fiber.updateQueue;
23906
-
23907
- if (updateQueue !== null) {
23908
- var lastEffect = updateQueue.lastEffect;
23886
+ } // If there are pending passive effects unmounts for this Fiber,
23887
+ // we can assume that they would have prevented this update.
23909
23888
 
23910
- if (lastEffect !== null) {
23911
- var firstEffect = lastEffect.next;
23912
- var effect = firstEffect;
23913
23889
 
23914
- do {
23915
- if (effect.destroy !== undefined) {
23916
- if ((effect.tag & Passive$1) !== NoFlags$1) {
23917
- return;
23918
- }
23919
- }
23920
-
23921
- effect = effect.next;
23922
- } while (effect !== firstEffect);
23923
- }
23924
- }
23890
+ if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) {
23891
+ return;
23925
23892
  } // We show the whole stack but dedupe on the top component's name because
23926
23893
  // the problematic code almost always lies inside that component.
23927
23894
 
@@ -24276,21 +24243,8 @@ function shouldForceFlushFallbacksInDEV() {
24276
24243
  var actingUpdatesScopeDepth = 0;
24277
24244
 
24278
24245
  function detachFiberAfterEffects(fiber) {
24279
- // Null out fields to improve GC for references that may be lingering (e.g. DevTools).
24280
- // Note that we already cleared the return pointer in detachFiberMutation().
24281
- fiber.child = null;
24282
- fiber.deletions = null;
24283
- fiber.dependencies = null;
24284
- fiber.memoizedProps = null;
24285
- fiber.memoizedState = null;
24286
- fiber.pendingProps = null;
24287
24246
  fiber.sibling = null;
24288
24247
  fiber.stateNode = null;
24289
- fiber.updateQueue = null;
24290
-
24291
- {
24292
- fiber._debugOwner = null;
24293
- }
24294
24248
  }
24295
24249
 
24296
24250
  var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
@@ -24730,8 +24684,9 @@ function FiberNode(tag, pendingProps, key, mode) {
24730
24684
  this.mode = mode; // Effects
24731
24685
 
24732
24686
  this.flags = NoFlags;
24733
- this.subtreeFlags = NoFlags;
24734
- this.deletions = null;
24687
+ this.nextEffect = null;
24688
+ this.firstEffect = null;
24689
+ this.lastEffect = null;
24735
24690
  this.lanes = NoLanes;
24736
24691
  this.childLanes = NoLanes;
24737
24692
  this.alternate = null;
@@ -24848,9 +24803,13 @@ function createWorkInProgress(current, pendingProps) {
24848
24803
  workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
24849
24804
 
24850
24805
  workInProgress.type = current.type; // We already have an alternate.
24806
+ // Reset the effect tag.
24807
+
24808
+ workInProgress.flags = NoFlags; // The effect list is no longer valid.
24851
24809
 
24852
- workInProgress.subtreeFlags = NoFlags;
24853
- workInProgress.deletions = null;
24810
+ workInProgress.nextEffect = null;
24811
+ workInProgress.firstEffect = null;
24812
+ workInProgress.lastEffect = null;
24854
24813
 
24855
24814
  {
24856
24815
  // We intentionally reset, rather than copy, actualDuration & actualStartTime.
@@ -24860,11 +24819,8 @@ function createWorkInProgress(current, pendingProps) {
24860
24819
  workInProgress.actualDuration = 0;
24861
24820
  workInProgress.actualStartTime = -1;
24862
24821
  }
24863
- } // Reset all effects except static ones.
24864
- // Static effects are not specific to a render.
24865
-
24822
+ }
24866
24823
 
24867
- workInProgress.flags = current.flags & StaticMask;
24868
24824
  workInProgress.childLanes = current.childLanes;
24869
24825
  workInProgress.lanes = current.lanes;
24870
24826
  workInProgress.child = current.child;
@@ -24920,7 +24876,11 @@ function resetWorkInProgress(workInProgress, renderLanes) {
24920
24876
  // avoid doing another reconciliation.
24921
24877
  // Reset the effect tag but keep any Placement tags, since that's something
24922
24878
  // that child fiber is setting, not the reconciliation.
24923
- workInProgress.flags &= Placement;
24879
+ workInProgress.flags &= Placement; // The effect list is no longer valid.
24880
+
24881
+ workInProgress.nextEffect = null;
24882
+ workInProgress.firstEffect = null;
24883
+ workInProgress.lastEffect = null;
24924
24884
  var current = workInProgress.alternate;
24925
24885
 
24926
24886
  if (current === null) {
@@ -24928,7 +24888,6 @@ function resetWorkInProgress(workInProgress, renderLanes) {
24928
24888
  workInProgress.childLanes = NoLanes;
24929
24889
  workInProgress.lanes = renderLanes;
24930
24890
  workInProgress.child = null;
24931
- workInProgress.subtreeFlags = NoFlags;
24932
24891
  workInProgress.memoizedProps = null;
24933
24892
  workInProgress.memoizedState = null;
24934
24893
  workInProgress.updateQueue = null;
@@ -24946,8 +24905,6 @@ function resetWorkInProgress(workInProgress, renderLanes) {
24946
24905
  workInProgress.childLanes = current.childLanes;
24947
24906
  workInProgress.lanes = current.lanes;
24948
24907
  workInProgress.child = current.child;
24949
- workInProgress.subtreeFlags = current.subtreeFlags;
24950
- workInProgress.deletions = null;
24951
24908
  workInProgress.memoizedProps = current.memoizedProps;
24952
24909
  workInProgress.memoizedState = current.memoizedState;
24953
24910
  workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
@@ -25268,8 +25225,9 @@ function assignFiberPropertiesInDEV(target, source) {
25268
25225
  target.dependencies = source.dependencies;
25269
25226
  target.mode = source.mode;
25270
25227
  target.flags = source.flags;
25271
- target.subtreeFlags = source.subtreeFlags;
25272
- target.deletions = source.deletions;
25228
+ target.nextEffect = source.nextEffect;
25229
+ target.firstEffect = source.firstEffect;
25230
+ target.lastEffect = source.lastEffect;
25273
25231
  target.lanes = source.lanes;
25274
25232
  target.childLanes = source.childLanes;
25275
25233
  target.alternate = source.alternate;