react-dom 16.4.0 → 16.4.1

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 v16.4.0
1
+ /** @license React v16.4.1
2
2
  * react-dom.development.js
3
3
  *
4
4
  * Copyright (c) 2013-present, Facebook, Inc.
@@ -2213,7 +2213,9 @@ var DOCUMENT_FRAGMENT_NODE = 11;
2213
2213
  * @return {DOMEventTarget} Target node.
2214
2214
  */
2215
2215
  function getEventTarget(nativeEvent) {
2216
- var target = nativeEvent.target || window;
2216
+ // Fallback to nativeEvent.srcElement for IE9
2217
+ // https://github.com/facebook/react/issues/12506
2218
+ var target = nativeEvent.target || nativeEvent.srcElement || window;
2217
2219
 
2218
2220
  // Normalize SVG <use> element events #4963
2219
2221
  if (target.correspondingUseElement) {
@@ -3110,20 +3112,28 @@ function updateWrapper(element, props) {
3110
3112
  }
3111
3113
  }
3112
3114
 
3113
- function postMountWrapper(element, props) {
3115
+ function postMountWrapper(element, props, isHydrating) {
3114
3116
  var node = element;
3115
3117
 
3116
3118
  if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3119
+ var _initialValue = '' + node._wrapperState.initialValue;
3120
+ var currentValue = node.value;
3121
+
3117
3122
  // Do not assign value if it is already set. This prevents user text input
3118
3123
  // from being lost during SSR hydration.
3119
- if (node.value === '') {
3120
- node.value = '' + node._wrapperState.initialValue;
3124
+ if (!isHydrating) {
3125
+ // Do not re-assign the value property if there is no change. This
3126
+ // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3127
+ // prematurely marking required inputs as invalid
3128
+ if (_initialValue !== currentValue) {
3129
+ node.value = _initialValue;
3130
+ }
3121
3131
  }
3122
3132
 
3123
3133
  // value must be assigned before defaultValue. This fixes an issue where the
3124
3134
  // visually displayed value of date inputs disappears on mobile Safari and Chrome:
3125
3135
  // https://github.com/facebook/react/issues/7233
3126
- node.defaultValue = '' + node._wrapperState.initialValue;
3136
+ node.defaultValue = _initialValue;
3127
3137
  }
3128
3138
 
3129
3139
  // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
@@ -3396,14 +3406,8 @@ function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3396
3406
  }
3397
3407
  }
3398
3408
 
3399
- function handleControlledInputBlur(inst, node) {
3400
- // TODO: In IE, inst is occasionally null. Why?
3401
- if (inst == null) {
3402
- return;
3403
- }
3404
-
3405
- // Fiber and ReactDOM keep wrapper state in separate places
3406
- var state = inst._wrapperState || node._wrapperState;
3409
+ function handleControlledInputBlur(node) {
3410
+ var state = node._wrapperState;
3407
3411
 
3408
3412
  if (!state || !state.controlled || node.type !== 'number') {
3409
3413
  return;
@@ -3460,7 +3464,7 @@ var ChangeEventPlugin = {
3460
3464
 
3461
3465
  // When blurring, set the value attribute for number inputs
3462
3466
  if (topLevelType === TOP_BLUR) {
3463
- handleControlledInputBlur(targetInst, targetNode);
3467
+ handleControlledInputBlur(targetNode);
3464
3468
  }
3465
3469
  }
3466
3470
  };
@@ -4951,9 +4955,14 @@ function isInDocument(node) {
4951
4955
  * Input selection module for React.
4952
4956
  */
4953
4957
 
4958
+ /**
4959
+ * @hasSelectionCapabilities: we get the element types that support selection
4960
+ * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
4961
+ * and `selectionEnd` rows.
4962
+ */
4954
4963
  function hasSelectionCapabilities(elem) {
4955
4964
  var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
4956
- return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
4965
+ return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
4957
4966
  }
4958
4967
 
4959
4968
  function getSelectionInformation() {
@@ -4974,7 +4983,7 @@ function restoreSelection(priorSelectionInformation) {
4974
4983
  var priorFocusedElem = priorSelectionInformation.focusedElem;
4975
4984
  var priorSelectionRange = priorSelectionInformation.selectionRange;
4976
4985
  if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
4977
- if (hasSelectionCapabilities(priorFocusedElem)) {
4986
+ if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
4978
4987
  setSelection(priorFocusedElem, priorSelectionRange);
4979
4988
  }
4980
4989
 
@@ -4991,7 +5000,9 @@ function restoreSelection(priorSelectionInformation) {
4991
5000
  }
4992
5001
  }
4993
5002
 
4994
- priorFocusedElem.focus();
5003
+ if (typeof priorFocusedElem.focus === 'function') {
5004
+ priorFocusedElem.focus();
5005
+ }
4995
5006
 
4996
5007
  for (var i = 0; i < ancestors.length; i++) {
4997
5008
  var info = ancestors[i];
@@ -5213,11 +5224,11 @@ injection.injectEventPluginsByName({
5213
5224
  BeforeInputEventPlugin: BeforeInputEventPlugin
5214
5225
  });
5215
5226
 
5216
- {
5217
- if (ExecutionEnvironment.canUseDOM && typeof requestAnimationFrame !== 'function') {
5218
- warning(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
5219
- }
5220
- }
5227
+ // We capture a local reference to any global, in case it gets polyfilled after
5228
+ // this module is initially evaluated.
5229
+ // We want to be using a consistent implementation.
5230
+
5231
+ var localRequestAnimationFrame$1 = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : undefined;
5221
5232
 
5222
5233
  /**
5223
5234
  * A scheduling library to allow scheduling work with more granular priority and
@@ -5240,32 +5251,42 @@ injection.injectEventPluginsByName({
5240
5251
  // layout, paint and other browser work is counted against the available time.
5241
5252
  // The frame rate is dynamically adjusted.
5242
5253
 
5254
+ // We capture a local reference to any global, in case it gets polyfilled after
5255
+ // this module is initially evaluated.
5256
+ // We want to be using a consistent implementation.
5257
+ var localDate = Date;
5258
+ var localSetTimeout = setTimeout;
5259
+ var localClearTimeout = clearTimeout;
5260
+
5243
5261
  var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
5244
5262
 
5245
5263
  var now$1 = void 0;
5246
5264
  if (hasNativePerformanceNow) {
5265
+ var Performance = performance;
5247
5266
  now$1 = function () {
5248
- return performance.now();
5267
+ return Performance.now();
5249
5268
  };
5250
5269
  } else {
5251
5270
  now$1 = function () {
5252
- return Date.now();
5271
+ return localDate.now();
5253
5272
  };
5254
5273
  }
5255
5274
 
5256
- // TODO: There's no way to cancel, because Fiber doesn't atm.
5257
5275
  var scheduleWork = void 0;
5258
5276
  var cancelScheduledWork = void 0;
5259
5277
 
5260
5278
  if (!ExecutionEnvironment.canUseDOM) {
5261
- var callbackIdCounter = 0;
5262
- // Timeouts are objects in Node.
5263
- // For consistency, we'll use numbers in the public API anyway.
5264
- var timeoutIds = {};
5279
+ var timeoutIds = new Map();
5265
5280
 
5266
5281
  scheduleWork = function (callback, options) {
5267
- var callbackId = callbackIdCounter++;
5268
- var timeoutId = setTimeout(function () {
5282
+ // keeping return type consistent
5283
+ var callbackConfig = {
5284
+ scheduledCallback: callback,
5285
+ timeoutTime: 0,
5286
+ next: null,
5287
+ prev: null
5288
+ };
5289
+ var timeoutId = localSetTimeout(function () {
5269
5290
  callback({
5270
5291
  timeRemaining: function () {
5271
5292
  return Infinity;
@@ -5274,33 +5295,28 @@ if (!ExecutionEnvironment.canUseDOM) {
5274
5295
  didTimeout: false
5275
5296
  });
5276
5297
  });
5277
- timeoutIds[callbackId] = timeoutId;
5278
- return callbackId;
5298
+ timeoutIds.set(callback, timeoutId);
5299
+ return callbackConfig;
5279
5300
  };
5280
5301
  cancelScheduledWork = function (callbackId) {
5281
- var timeoutId = timeoutIds[callbackId];
5282
- delete timeoutIds[callbackId];
5283
- clearTimeout(timeoutId);
5302
+ var callback = callbackId.scheduledCallback;
5303
+ var timeoutId = timeoutIds.get(callback);
5304
+ timeoutIds.delete(callbackId);
5305
+ localClearTimeout(timeoutId);
5284
5306
  };
5285
5307
  } else {
5286
- // We keep callbacks in a queue.
5287
- // Calling scheduleWork will push in a new callback at the end of the queue.
5288
- // When we get idle time, callbacks are removed from the front of the queue
5289
- var pendingCallbacks = [];
5290
-
5291
- var _callbackIdCounter = 0;
5292
- var getCallbackId = function () {
5293
- _callbackIdCounter++;
5294
- return _callbackIdCounter;
5308
+ {
5309
+ if (typeof localRequestAnimationFrame$1 !== 'function') {
5310
+ warning(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
5311
+ }
5312
+ }
5313
+
5314
+ var localRequestAnimationFrame = typeof localRequestAnimationFrame$1 === 'function' ? localRequestAnimationFrame$1 : function (callback) {
5315
+ invariant(false, 'React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills');
5295
5316
  };
5296
5317
 
5297
- // When a callback is scheduled, we register it by adding it's id to this
5298
- // object.
5299
- // If the user calls 'cancelScheduledWork' with the id of that callback, it will be
5300
- // unregistered by removing the id from this object.
5301
- // Then we skip calling any callback which is not registered.
5302
- // This means cancelling is an O(1) time complexity instead of O(n).
5303
- var registeredCallbackIds = {};
5318
+ var headOfPendingCallbacksLinkedList = null;
5319
+ var tailOfPendingCallbacksLinkedList = null;
5304
5320
 
5305
5321
  // We track what the next soonest timeoutTime is, to be able to quickly tell
5306
5322
  // if none of the scheduled callbacks have timed out.
@@ -5324,17 +5340,27 @@ if (!ExecutionEnvironment.canUseDOM) {
5324
5340
  }
5325
5341
  };
5326
5342
 
5327
- var safelyCallScheduledCallback = function (callback, callbackId) {
5328
- if (!registeredCallbackIds[callbackId]) {
5329
- // ignore cancelled callbacks
5330
- return;
5331
- }
5343
+ /**
5344
+ * Handles the case where a callback errors:
5345
+ * - don't catch the error, because this changes debugging behavior
5346
+ * - do start a new postMessage callback, to call any remaining callbacks,
5347
+ * - but only if there is an error, so there is not extra overhead.
5348
+ */
5349
+ var callUnsafely = function (callbackConfig, arg) {
5350
+ var callback = callbackConfig.scheduledCallback;
5351
+ var finishedCalling = false;
5332
5352
  try {
5333
- callback(frameDeadlineObject);
5334
- // Avoid using 'catch' to keep errors easy to debug
5353
+ callback(arg);
5354
+ finishedCalling = true;
5335
5355
  } finally {
5336
- // always clean up the callbackId, even if the callback throws
5337
- delete registeredCallbackIds[callbackId];
5356
+ // always remove it from linked list
5357
+ cancelScheduledWork(callbackConfig);
5358
+
5359
+ if (!finishedCalling) {
5360
+ // an error must have been thrown
5361
+ isIdleScheduled = true;
5362
+ window.postMessage(messageKey, '*');
5363
+ }
5338
5364
  }
5339
5365
  };
5340
5366
 
@@ -5344,7 +5370,7 @@ if (!ExecutionEnvironment.canUseDOM) {
5344
5370
  * Keeps doing this until there are none which have currently timed out.
5345
5371
  */
5346
5372
  var callTimedOutCallbacks = function () {
5347
- if (pendingCallbacks.length === 0) {
5373
+ if (headOfPendingCallbacksLinkedList === null) {
5348
5374
  return;
5349
5375
  }
5350
5376
 
@@ -5361,24 +5387,38 @@ if (!ExecutionEnvironment.canUseDOM) {
5361
5387
  // We know that none of them have timed out yet.
5362
5388
  return;
5363
5389
  }
5364
- nextSoonestTimeoutTime = -1; // we will reset it below
5390
+ // NOTE: we intentionally wait to update the nextSoonestTimeoutTime until
5391
+ // after successfully calling any timed out callbacks.
5392
+ // If a timed out callback throws an error, we could get stuck in a state
5393
+ // where the nextSoonestTimeoutTime was set wrong.
5394
+ var updatedNextSoonestTimeoutTime = -1; // we will update nextSoonestTimeoutTime below
5395
+ var timedOutCallbacks = [];
5365
5396
 
5366
- // keep checking until we don't find any more timed out callbacks
5367
- frameDeadlineObject.didTimeout = true;
5368
- for (var i = 0, len = pendingCallbacks.length; i < len; i++) {
5369
- var currentCallbackConfig = pendingCallbacks[i];
5397
+ // iterate once to find timed out callbacks and find nextSoonestTimeoutTime
5398
+ var currentCallbackConfig = headOfPendingCallbacksLinkedList;
5399
+ while (currentCallbackConfig !== null) {
5370
5400
  var _timeoutTime = currentCallbackConfig.timeoutTime;
5371
5401
  if (_timeoutTime !== -1 && _timeoutTime <= currentTime) {
5372
5402
  // it has timed out!
5373
- // call it
5374
- var _callback = currentCallbackConfig.scheduledCallback;
5375
- safelyCallScheduledCallback(_callback, currentCallbackConfig.callbackId);
5403
+ timedOutCallbacks.push(currentCallbackConfig);
5376
5404
  } else {
5377
- if (_timeoutTime !== -1 && (nextSoonestTimeoutTime === -1 || _timeoutTime < nextSoonestTimeoutTime)) {
5378
- nextSoonestTimeoutTime = _timeoutTime;
5405
+ if (_timeoutTime !== -1 && (updatedNextSoonestTimeoutTime === -1 || _timeoutTime < updatedNextSoonestTimeoutTime)) {
5406
+ updatedNextSoonestTimeoutTime = _timeoutTime;
5379
5407
  }
5380
5408
  }
5409
+ currentCallbackConfig = currentCallbackConfig.next;
5381
5410
  }
5411
+
5412
+ if (timedOutCallbacks.length > 0) {
5413
+ frameDeadlineObject.didTimeout = true;
5414
+ for (var i = 0, len = timedOutCallbacks.length; i < len; i++) {
5415
+ callUnsafely(timedOutCallbacks[i], frameDeadlineObject);
5416
+ }
5417
+ }
5418
+
5419
+ // NOTE: we intentionally wait to update the nextSoonestTimeoutTime until
5420
+ // after successfully calling any timed out callbacks.
5421
+ nextSoonestTimeoutTime = updatedNextSoonestTimeoutTime;
5382
5422
  };
5383
5423
 
5384
5424
  // We use the postMessage trick to defer idle work until after the repaint.
@@ -5389,7 +5429,7 @@ if (!ExecutionEnvironment.canUseDOM) {
5389
5429
  }
5390
5430
  isIdleScheduled = false;
5391
5431
 
5392
- if (pendingCallbacks.length === 0) {
5432
+ if (headOfPendingCallbacksLinkedList === null) {
5393
5433
  return;
5394
5434
  }
5395
5435
 
@@ -5398,19 +5438,18 @@ if (!ExecutionEnvironment.canUseDOM) {
5398
5438
 
5399
5439
  var currentTime = now$1();
5400
5440
  // Next, as long as we have idle time, try calling more callbacks.
5401
- while (frameDeadline - currentTime > 0 && pendingCallbacks.length > 0) {
5402
- var latestCallbackConfig = pendingCallbacks.shift();
5441
+ while (frameDeadline - currentTime > 0 && headOfPendingCallbacksLinkedList !== null) {
5442
+ var latestCallbackConfig = headOfPendingCallbacksLinkedList;
5403
5443
  frameDeadlineObject.didTimeout = false;
5404
- var latestCallback = latestCallbackConfig.scheduledCallback;
5405
- var newCallbackId = latestCallbackConfig.callbackId;
5406
- safelyCallScheduledCallback(latestCallback, newCallbackId);
5444
+ // callUnsafely will remove it from the head of the linked list
5445
+ callUnsafely(latestCallbackConfig, frameDeadlineObject);
5407
5446
  currentTime = now$1();
5408
5447
  }
5409
- if (pendingCallbacks.length > 0) {
5448
+ if (headOfPendingCallbacksLinkedList !== null) {
5410
5449
  if (!isAnimationFrameScheduled) {
5411
5450
  // Schedule another animation callback so we retry later.
5412
5451
  isAnimationFrameScheduled = true;
5413
- requestAnimationFrame(animationTick);
5452
+ localRequestAnimationFrame(animationTick);
5414
5453
  }
5415
5454
  }
5416
5455
  };
@@ -5445,7 +5484,7 @@ if (!ExecutionEnvironment.canUseDOM) {
5445
5484
  }
5446
5485
  };
5447
5486
 
5448
- scheduleWork = function (callback, options) {
5487
+ scheduleWork = function (callback, options) /* CallbackConfigType */{
5449
5488
  var timeoutTime = -1;
5450
5489
  if (options != null && typeof options.timeout === 'number') {
5451
5490
  timeoutTime = now$1() + options.timeout;
@@ -5454,28 +5493,100 @@ if (!ExecutionEnvironment.canUseDOM) {
5454
5493
  nextSoonestTimeoutTime = timeoutTime;
5455
5494
  }
5456
5495
 
5457
- var newCallbackId = getCallbackId();
5458
5496
  var scheduledCallbackConfig = {
5459
5497
  scheduledCallback: callback,
5460
- callbackId: newCallbackId,
5461
- timeoutTime: timeoutTime
5498
+ timeoutTime: timeoutTime,
5499
+ prev: null,
5500
+ next: null
5462
5501
  };
5463
- pendingCallbacks.push(scheduledCallbackConfig);
5502
+ if (headOfPendingCallbacksLinkedList === null) {
5503
+ // Make this callback the head and tail of our list
5504
+ headOfPendingCallbacksLinkedList = scheduledCallbackConfig;
5505
+ tailOfPendingCallbacksLinkedList = scheduledCallbackConfig;
5506
+ } else {
5507
+ // Add latest callback as the new tail of the list
5508
+ scheduledCallbackConfig.prev = tailOfPendingCallbacksLinkedList;
5509
+ // renaming for clarity
5510
+ var oldTailOfPendingCallbacksLinkedList = tailOfPendingCallbacksLinkedList;
5511
+ if (oldTailOfPendingCallbacksLinkedList !== null) {
5512
+ oldTailOfPendingCallbacksLinkedList.next = scheduledCallbackConfig;
5513
+ }
5514
+ tailOfPendingCallbacksLinkedList = scheduledCallbackConfig;
5515
+ }
5464
5516
 
5465
- registeredCallbackIds[newCallbackId] = true;
5466
5517
  if (!isAnimationFrameScheduled) {
5467
5518
  // If rAF didn't already schedule one, we need to schedule a frame.
5468
5519
  // TODO: If this rAF doesn't materialize because the browser throttles, we
5469
5520
  // might want to still have setTimeout trigger scheduleWork as a backup to ensure
5470
5521
  // that we keep performing work.
5471
5522
  isAnimationFrameScheduled = true;
5472
- requestAnimationFrame(animationTick);
5523
+ localRequestAnimationFrame(animationTick);
5473
5524
  }
5474
- return newCallbackId;
5525
+ return scheduledCallbackConfig;
5475
5526
  };
5476
5527
 
5477
- cancelScheduledWork = function (callbackId) {
5478
- delete registeredCallbackIds[callbackId];
5528
+ cancelScheduledWork = function (callbackConfig /* CallbackConfigType */
5529
+ ) {
5530
+ if (callbackConfig.prev === null && headOfPendingCallbacksLinkedList !== callbackConfig) {
5531
+ // this callbackConfig has already been cancelled.
5532
+ // cancelScheduledWork should be idempotent, a no-op after first call.
5533
+ return;
5534
+ }
5535
+
5536
+ /**
5537
+ * There are four possible cases:
5538
+ * - Head/nodeToRemove/Tail -> null
5539
+ * In this case we set Head and Tail to null.
5540
+ * - Head -> ... middle nodes... -> Tail/nodeToRemove
5541
+ * In this case we point the middle.next to null and put middle as the new
5542
+ * Tail.
5543
+ * - Head/nodeToRemove -> ...middle nodes... -> Tail
5544
+ * In this case we point the middle.prev at null and move the Head to
5545
+ * middle.
5546
+ * - Head -> ... ?some nodes ... -> nodeToRemove -> ... ?some nodes ... -> Tail
5547
+ * In this case we point the Head.next to the Tail and the Tail.prev to
5548
+ * the Head.
5549
+ */
5550
+ var next = callbackConfig.next;
5551
+ var prev = callbackConfig.prev;
5552
+ callbackConfig.next = null;
5553
+ callbackConfig.prev = null;
5554
+ if (next !== null) {
5555
+ // we have a next
5556
+
5557
+ if (prev !== null) {
5558
+ // we have a prev
5559
+
5560
+ // callbackConfig is somewhere in the middle of a list of 3 or more nodes.
5561
+ prev.next = next;
5562
+ next.prev = prev;
5563
+ return;
5564
+ } else {
5565
+ // there is a next but not a previous one;
5566
+ // callbackConfig is the head of a list of 2 or more other nodes.
5567
+ next.prev = null;
5568
+ headOfPendingCallbacksLinkedList = next;
5569
+ return;
5570
+ }
5571
+ } else {
5572
+ // there is no next callback config; this must the tail of the list
5573
+
5574
+ if (prev !== null) {
5575
+ // we have a prev
5576
+
5577
+ // callbackConfig is the tail of a list of 2 or more other nodes.
5578
+ prev.next = null;
5579
+ tailOfPendingCallbacksLinkedList = prev;
5580
+ return;
5581
+ } else {
5582
+ // there is no previous callback config;
5583
+ // callbackConfig is the only thing in the linked list,
5584
+ // so both head and tail point to it.
5585
+ headOfPendingCallbacksLinkedList = null;
5586
+ tailOfPendingCallbacksLinkedList = null;
5587
+ return;
5588
+ }
5589
+ }
5479
5590
  };
5480
5591
  }
5481
5592
 
@@ -7405,7 +7516,7 @@ function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement)
7405
7516
  // TODO: Make sure we check if this is still unmounted or do any clean
7406
7517
  // up necessary since we never stop tracking anymore.
7407
7518
  track(domElement);
7408
- postMountWrapper(domElement, rawProps);
7519
+ postMountWrapper(domElement, rawProps, false);
7409
7520
  break;
7410
7521
  case 'textarea':
7411
7522
  // TODO: Make sure we check if this is still unmounted or do any clean
@@ -7860,7 +7971,7 @@ function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, ro
7860
7971
  // TODO: Make sure we check if this is still unmounted or do any clean
7861
7972
  // up necessary since we never stop tracking anymore.
7862
7973
  track(domElement);
7863
- postMountWrapper(domElement, rawProps);
7974
+ postMountWrapper(domElement, rawProps, true);
7864
7975
  break;
7865
7976
  case 'textarea':
7866
7977
  // TODO: Make sure we check if this is still unmounted or do any clean
@@ -8666,9 +8777,6 @@ var warnAboutLegacyContextAPI = false;
8666
8777
  // Gather advanced timing metrics for Profiler subtrees.
8667
8778
  var enableProfilerTimer = true;
8668
8779
 
8669
- // Fires getDerivedStateFromProps for state *or* props changes
8670
- var fireGetDerivedStateFromPropsOnStateUpdates = true;
8671
-
8672
8780
  // Only used in www builds.
8673
8781
 
8674
8782
  // Prefix measurements so that it's possible to filter them.
@@ -9470,6 +9578,8 @@ function FiberNode(tag, pendingProps, key, mode) {
9470
9578
  this.alternate = null;
9471
9579
 
9472
9580
  if (enableProfilerTimer) {
9581
+ this.actualDuration = 0;
9582
+ this.actualStartTime = 0;
9473
9583
  this.selfBaseTime = 0;
9474
9584
  this.treeBaseTime = 0;
9475
9585
  }
@@ -9540,6 +9650,15 @@ function createWorkInProgress(current, pendingProps, expirationTime) {
9540
9650
  workInProgress.nextEffect = null;
9541
9651
  workInProgress.firstEffect = null;
9542
9652
  workInProgress.lastEffect = null;
9653
+
9654
+ if (enableProfilerTimer) {
9655
+ // We intentionally reset, rather than copy, actualDuration & actualStartTime.
9656
+ // This prevents time from endlessly accumulating in new commits.
9657
+ // This has the downside of resetting values for different priority renders,
9658
+ // But works for yielding (the common case) and should support resuming.
9659
+ workInProgress.actualDuration = 0;
9660
+ workInProgress.actualStartTime = 0;
9661
+ }
9543
9662
  }
9544
9663
 
9545
9664
  workInProgress.expirationTime = expirationTime;
@@ -9665,13 +9784,6 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
9665
9784
  var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
9666
9785
  fiber.type = REACT_PROFILER_TYPE;
9667
9786
  fiber.expirationTime = expirationTime;
9668
- if (enableProfilerTimer) {
9669
- fiber.stateNode = {
9670
- elapsedPauseTimeAtStart: 0,
9671
- duration: 0,
9672
- startTime: 0
9673
- };
9674
- }
9675
9787
 
9676
9788
  return fiber;
9677
9789
  }
@@ -9735,6 +9847,8 @@ function assignFiberPropertiesInDEV(target, source) {
9735
9847
  target.expirationTime = source.expirationTime;
9736
9848
  target.alternate = source.alternate;
9737
9849
  if (enableProfilerTimer) {
9850
+ target.actualDuration = source.actualDuration;
9851
+ target.actualStartTime = source.actualStartTime;
9738
9852
  target.selfBaseTime = source.selfBaseTime;
9739
9853
  target.treeBaseTime = source.treeBaseTime;
9740
9854
  }
@@ -11004,9 +11118,9 @@ function markActualRenderTimeStarted(fiber) {
11004
11118
  {
11005
11119
  fiberStack$1.push(fiber);
11006
11120
  }
11007
- var stateNode = fiber.stateNode;
11008
- stateNode.elapsedPauseTimeAtStart = totalElapsedPauseTime;
11009
- stateNode.startTime = now();
11121
+
11122
+ fiber.actualDuration = now() - fiber.actualDuration - totalElapsedPauseTime;
11123
+ fiber.actualStartTime = now();
11010
11124
  }
11011
11125
 
11012
11126
  function pauseActualRenderTimerIfRunning() {
@@ -11023,10 +11137,10 @@ function recordElapsedActualRenderTime(fiber) {
11023
11137
  return;
11024
11138
  }
11025
11139
  {
11026
- !(fiber === fiberStack$1.pop()) ? warning(false, 'Unexpected Fiber popped.') : void 0;
11140
+ !(fiber === fiberStack$1.pop()) ? warning(false, 'Unexpected Fiber (%s) popped.', getComponentName(fiber)) : void 0;
11027
11141
  }
11028
- var stateNode = fiber.stateNode;
11029
- stateNode.duration += now() - (totalElapsedPauseTime - stateNode.elapsedPauseTimeAtStart) - stateNode.startTime;
11142
+
11143
+ fiber.actualDuration = now() - totalElapsedPauseTime - fiber.actualDuration;
11030
11144
  }
11031
11145
 
11032
11146
  function resetActualRenderTimer() {
@@ -11633,10 +11747,8 @@ function updateClassInstance(current, workInProgress, renderExpirationTime) {
11633
11747
  }
11634
11748
 
11635
11749
  if (typeof getDerivedStateFromProps === 'function') {
11636
- if (fireGetDerivedStateFromPropsOnStateUpdates || oldProps !== newProps) {
11637
- applyDerivedStateFromProps(workInProgress, getDerivedStateFromProps, newProps);
11638
- newState = workInProgress.memoizedState;
11639
- }
11750
+ applyDerivedStateFromProps(workInProgress, getDerivedStateFromProps, newProps);
11751
+ newState = workInProgress.memoizedState;
11640
11752
  }
11641
11753
 
11642
11754
  var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
@@ -12518,7 +12630,8 @@ function ChildReconciler(shouldTrackSideEffects) {
12518
12630
  // Handle top level unkeyed fragments as if they were arrays.
12519
12631
  // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12520
12632
  // We treat the ambiguous cases above the same.
12521
- if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
12633
+ var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12634
+ if (isUnkeyedTopLevelFragment) {
12522
12635
  newChild = newChild.props.children;
12523
12636
  }
12524
12637
 
@@ -12555,7 +12668,7 @@ function ChildReconciler(shouldTrackSideEffects) {
12555
12668
  warnOnFunctionType();
12556
12669
  }
12557
12670
  }
12558
- if (typeof newChild === 'undefined') {
12671
+ if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12559
12672
  // If the new child is undefined, and the return fiber is a composite
12560
12673
  // component, throw an error. If Fiber return types are disabled,
12561
12674
  // we already threw above.
@@ -12967,11 +13080,6 @@ function updateMode(current, workInProgress) {
12967
13080
  function updateProfiler(current, workInProgress) {
12968
13081
  var nextProps = workInProgress.pendingProps;
12969
13082
  if (enableProfilerTimer) {
12970
- // Start render timer here and push start time onto queue
12971
- markActualRenderTimeStarted(workInProgress);
12972
-
12973
- // Let the "complete" phase know to stop the timer,
12974
- // And the scheduler to record the measured time.
12975
13083
  workInProgress.effectTag |= Update;
12976
13084
  }
12977
13085
  if (workInProgress.memoizedProps === nextProps) {
@@ -13679,11 +13787,6 @@ function bailoutOnLowPriority(current, workInProgress) {
13679
13787
  case ContextProvider:
13680
13788
  pushProvider(workInProgress);
13681
13789
  break;
13682
- case Profiler:
13683
- if (enableProfilerTimer) {
13684
- markActualRenderTimeStarted(workInProgress);
13685
- }
13686
- break;
13687
13790
  }
13688
13791
  // TODO: What if this is currently in progress?
13689
13792
  // How can that happen? How is this not being cloned?
@@ -13702,6 +13805,12 @@ function memoizeState(workInProgress, nextState) {
13702
13805
  }
13703
13806
 
13704
13807
  function beginWork(current, workInProgress, renderExpirationTime) {
13808
+ if (enableProfilerTimer) {
13809
+ if (workInProgress.mode & ProfileMode) {
13810
+ markActualRenderTimeStarted(workInProgress);
13811
+ }
13812
+ }
13813
+
13705
13814
  if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
13706
13815
  return bailoutOnLowPriority(current, workInProgress);
13707
13816
  }
@@ -13906,6 +14015,13 @@ if (supportsMutation) {
13906
14015
 
13907
14016
  function completeWork(current, workInProgress, renderExpirationTime) {
13908
14017
  var newProps = workInProgress.pendingProps;
14018
+
14019
+ if (enableProfilerTimer) {
14020
+ if (workInProgress.mode & ProfileMode) {
14021
+ recordElapsedActualRenderTime(workInProgress);
14022
+ }
14023
+ }
14024
+
13909
14025
  switch (workInProgress.tag) {
13910
14026
  case FunctionalComponent:
13911
14027
  return null;
@@ -14038,9 +14154,6 @@ function completeWork(current, workInProgress, renderExpirationTime) {
14038
14154
  case Mode:
14039
14155
  return null;
14040
14156
  case Profiler:
14041
- if (enableProfilerTimer) {
14042
- recordElapsedActualRenderTime(workInProgress);
14043
- }
14044
14157
  return null;
14045
14158
  case HostPortal:
14046
14159
  popHostContainer(workInProgress);
@@ -14770,11 +14883,7 @@ function commitWork(current, finishedWork) {
14770
14883
  {
14771
14884
  if (enableProfilerTimer) {
14772
14885
  var onRender = finishedWork.memoizedProps.onRender;
14773
- onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.stateNode.duration, finishedWork.treeBaseTime, finishedWork.stateNode.startTime, getCommitTime());
14774
-
14775
- // Reset actualTime after successful commit.
14776
- // By default, we append to this time to account for errors and pauses.
14777
- finishedWork.stateNode.duration = 0;
14886
+ onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseTime, finishedWork.actualStartTime, getCommitTime());
14778
14887
  }
14779
14888
  return;
14780
14889
  }
@@ -14981,6 +15090,12 @@ function throwException(root, returnFiber, sourceFiber, value, renderIsExpired,
14981
15090
  }
14982
15091
 
14983
15092
  function unwindWork(workInProgress, renderIsExpired, renderExpirationTime) {
15093
+ if (enableProfilerTimer) {
15094
+ if (workInProgress.mode & ProfileMode) {
15095
+ recordElapsedActualRenderTime(workInProgress);
15096
+ }
15097
+ }
15098
+
14984
15099
  switch (workInProgress.tag) {
14985
15100
  case ClassComponent:
14986
15101
  {
@@ -15029,6 +15144,14 @@ function unwindWork(workInProgress, renderIsExpired, renderExpirationTime) {
15029
15144
  }
15030
15145
 
15031
15146
  function unwindInterruptedWork(interruptedWork) {
15147
+ if (enableProfilerTimer) {
15148
+ if (interruptedWork.mode & ProfileMode) {
15149
+ // Resume in case we're picking up on work that was paused.
15150
+ resumeActualRenderTimerIfPaused();
15151
+ recordElapsedActualRenderTime(interruptedWork);
15152
+ }
15153
+ }
15154
+
15032
15155
  switch (interruptedWork.tag) {
15033
15156
  case ClassComponent:
15034
15157
  {
@@ -15052,13 +15175,6 @@ function unwindInterruptedWork(interruptedWork) {
15052
15175
  case ContextProvider:
15053
15176
  popProvider(interruptedWork);
15054
15177
  break;
15055
- case Profiler:
15056
- if (enableProfilerTimer) {
15057
- // Resume in case we're picking up on work that was paused.
15058
- resumeActualRenderTimerIfPaused();
15059
- recordElapsedActualRenderTime(interruptedWork);
15060
- }
15061
- break;
15062
15178
  default:
15063
15179
  break;
15064
15180
  }
@@ -15198,6 +15314,10 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
15198
15314
  clearCaughtError();
15199
15315
 
15200
15316
  if (enableProfilerTimer) {
15317
+ if (failedUnitOfWork.mode & ProfileMode) {
15318
+ recordElapsedActualRenderTime(failedUnitOfWork);
15319
+ }
15320
+
15201
15321
  // Stop "base" render timer again (after the re-thrown error).
15202
15322
  stopBaseRenderTimerIfRunning();
15203
15323
  }
@@ -15431,6 +15551,8 @@ function commitRoot(finishedWork) {
15431
15551
  stopCommitSnapshotEffectsTimer();
15432
15552
 
15433
15553
  if (enableProfilerTimer) {
15554
+ // Mark the current commit time to be shared by all Profilers in this batch.
15555
+ // This enables them to be grouped later.
15434
15556
  recordCommitTime();
15435
15557
  }
15436
15558
 
@@ -15959,7 +16081,7 @@ function captureCommitPhaseError(fiber, error) {
15959
16081
  function computeAsyncExpiration(currentTime) {
15960
16082
  // Given the current clock time, returns an expiration time. We use rounding
15961
16083
  // to batch like updates together.
15962
- // Should complete within ~1000ms. 1200ms max.
16084
+ // Should complete within ~5000ms. 5250ms max.
15963
16085
  var expirationMs = 5000;
15964
16086
  var bucketSizeMs = 250;
15965
16087
  return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
@@ -16146,7 +16268,7 @@ var firstScheduledRoot = null;
16146
16268
  var lastScheduledRoot = null;
16147
16269
 
16148
16270
  var callbackExpirationTime = NoWork;
16149
- var callbackID = -1;
16271
+ var callbackID = void 0;
16150
16272
  var isRendering = false;
16151
16273
  var nextFlushedRoot = null;
16152
16274
  var nextFlushedExpirationTime = NoWork;
@@ -16175,9 +16297,11 @@ function scheduleCallbackWithExpiration(expirationTime) {
16175
16297
  // Existing callback has sufficient timeout. Exit.
16176
16298
  return;
16177
16299
  } else {
16178
- // Existing callback has insufficient timeout. Cancel and schedule a
16179
- // new one.
16180
- cancelDeferredCallback(callbackID);
16300
+ if (callbackID !== null) {
16301
+ // Existing callback has insufficient timeout. Cancel and schedule a
16302
+ // new one.
16303
+ cancelDeferredCallback(callbackID);
16304
+ }
16181
16305
  }
16182
16306
  // The request callback timer is already running. Don't start a new one.
16183
16307
  } else {
@@ -16366,7 +16490,7 @@ function performWork(minExpirationTime, isAsync, dl) {
16366
16490
  // If we're inside a callback, set this to false since we just completed it.
16367
16491
  if (deadline !== null) {
16368
16492
  callbackExpirationTime = NoWork;
16369
- callbackID = -1;
16493
+ callbackID = null;
16370
16494
  }
16371
16495
  // If there's work left over, schedule a new callback.
16372
16496
  if (nextFlushedExpirationTime !== NoWork) {
@@ -16433,7 +16557,6 @@ function performWorkOnRoot(root, expirationTime, isAsync) {
16433
16557
  // This root is already complete. We can commit it.
16434
16558
  completeRoot(root, finishedWork, expirationTime);
16435
16559
  } else {
16436
- root.finishedWork = null;
16437
16560
  finishedWork = renderRoot(root, expirationTime, false);
16438
16561
  if (finishedWork !== null) {
16439
16562
  // We've completed the root. Commit it.
@@ -16447,7 +16570,6 @@ function performWorkOnRoot(root, expirationTime, isAsync) {
16447
16570
  // This root is already complete. We can commit it.
16448
16571
  completeRoot(root, _finishedWork, expirationTime);
16449
16572
  } else {
16450
- root.finishedWork = null;
16451
16573
  _finishedWork = renderRoot(root, expirationTime, true);
16452
16574
  if (_finishedWork !== null) {
16453
16575
  // We've completed the root. Check the deadline one more time
@@ -16802,7 +16924,7 @@ implementation) {
16802
16924
 
16803
16925
  // TODO: this is special because it gets imported during build.
16804
16926
 
16805
- var ReactVersion = '16.4.0';
16927
+ var ReactVersion = '16.4.1';
16806
16928
 
16807
16929
  // TODO: This type is shared between the reconciler and ReactDOM, but will
16808
16930
  // eventually be lifted out to the renderer.
@@ -17248,6 +17370,8 @@ var ReactDOM = {
17248
17370
 
17249
17371
  unstable_deferredUpdates: deferredUpdates,
17250
17372
 
17373
+ unstable_interactiveUpdates: interactiveUpdates$1,
17374
+
17251
17375
  flushSync: flushSync,
17252
17376
 
17253
17377
  unstable_flushControlled: flushControlled,