react-test-renderer 15.5.0 → 15.5.4

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.
Files changed (168) hide show
  1. package/lib/ReactShallowRenderer.js +6 -0
  2. package/lib/shallow/ARIADOMPropertyConfig.js +73 -0
  3. package/lib/shallow/AutoFocusUtils.js +23 -0
  4. package/lib/shallow/BeforeInputEventPlugin.js +384 -0
  5. package/lib/shallow/CSSProperty.js +147 -0
  6. package/lib/shallow/CSSPropertyOperations.js +208 -0
  7. package/lib/shallow/CallbackQueue.js +118 -0
  8. package/lib/shallow/ChangeEventPlugin.js +345 -0
  9. package/lib/shallow/DOMChildrenOperations.js +224 -0
  10. package/lib/shallow/DOMLazyTree.js +117 -0
  11. package/lib/shallow/DOMNamespaces.js +19 -0
  12. package/lib/shallow/DOMProperty.js +209 -0
  13. package/lib/shallow/DOMPropertyOperations.js +236 -0
  14. package/lib/shallow/Danger.js +47 -0
  15. package/lib/shallow/DefaultEventPluginOrder.js +25 -0
  16. package/lib/shallow/EnterLeaveEventPlugin.js +99 -0
  17. package/lib/shallow/EventConstants.js +91 -0
  18. package/lib/shallow/EventPluginHub.js +277 -0
  19. package/lib/shallow/EventPluginRegistry.js +254 -0
  20. package/lib/shallow/EventPluginUtils.js +225 -0
  21. package/lib/shallow/EventPropagators.js +133 -0
  22. package/lib/shallow/FallbackCompositionState.js +94 -0
  23. package/lib/shallow/HTMLDOMPropertyConfig.js +235 -0
  24. package/lib/shallow/KeyEscapeUtils.js +58 -0
  25. package/lib/shallow/LinkedValueUtils.js +137 -0
  26. package/lib/shallow/PluginModuleType.js +12 -0
  27. package/lib/shallow/PooledClass.js +111 -0
  28. package/lib/shallow/ReactBrowserEventEmitter.js +327 -0
  29. package/lib/shallow/ReactChildFiber.js +243 -0
  30. package/lib/shallow/ReactChildReconciler.js +153 -0
  31. package/lib/shallow/ReactComponentBrowserEnvironment.js +29 -0
  32. package/lib/shallow/ReactComponentEnvironment.js +45 -0
  33. package/lib/shallow/ReactCompositeComponent.js +901 -0
  34. package/lib/shallow/ReactCoroutine.js +80 -0
  35. package/lib/shallow/ReactDOM.js +110 -0
  36. package/lib/shallow/ReactDOMComponent.js +1000 -0
  37. package/lib/shallow/ReactDOMComponentFlags.js +17 -0
  38. package/lib/shallow/ReactDOMComponentTree.js +194 -0
  39. package/lib/shallow/ReactDOMContainerInfo.js +32 -0
  40. package/lib/shallow/ReactDOMEmptyComponent.js +59 -0
  41. package/lib/shallow/ReactDOMFeatureFlags.js +18 -0
  42. package/lib/shallow/ReactDOMFiber.js +97 -0
  43. package/lib/shallow/ReactDOMIDOperations.js +33 -0
  44. package/lib/shallow/ReactDOMInput.js +284 -0
  45. package/lib/shallow/ReactDOMInvalidARIAHook.js +92 -0
  46. package/lib/shallow/ReactDOMNullInputValuePropHook.js +42 -0
  47. package/lib/shallow/ReactDOMOption.js +122 -0
  48. package/lib/shallow/ReactDOMSelect.js +199 -0
  49. package/lib/shallow/ReactDOMSelection.js +211 -0
  50. package/lib/shallow/ReactDOMServer.js +25 -0
  51. package/lib/shallow/ReactDOMTextComponent.js +163 -0
  52. package/lib/shallow/ReactDOMTextarea.js +159 -0
  53. package/lib/shallow/ReactDOMTreeTraversal.js +135 -0
  54. package/lib/shallow/ReactDOMUnknownPropertyHook.js +111 -0
  55. package/lib/shallow/ReactDebugTool.js +358 -0
  56. package/lib/shallow/ReactDefaultBatchingStrategy.js +67 -0
  57. package/lib/shallow/ReactDefaultInjection.js +85 -0
  58. package/lib/shallow/ReactElementSymbol.js +19 -0
  59. package/lib/shallow/ReactEmptyComponent.js +29 -0
  60. package/lib/shallow/ReactErrorUtils.js +75 -0
  61. package/lib/shallow/ReactEventEmitterMixin.js +32 -0
  62. package/lib/shallow/ReactEventListener.js +154 -0
  63. package/lib/shallow/ReactFeatureFlags.js +21 -0
  64. package/lib/shallow/ReactFiber.js +190 -0
  65. package/lib/shallow/ReactFiberBeginWork.js +380 -0
  66. package/lib/shallow/ReactFiberCommitWork.js +78 -0
  67. package/lib/shallow/ReactFiberCompleteWork.js +208 -0
  68. package/lib/shallow/ReactFiberReconciler.js +64 -0
  69. package/lib/shallow/ReactFiberRoot.js +29 -0
  70. package/lib/shallow/ReactFiberScheduler.js +331 -0
  71. package/lib/shallow/ReactFiberUpdateQueue.js +77 -0
  72. package/lib/shallow/ReactHostComponent.js +67 -0
  73. package/lib/shallow/ReactHostOperationHistoryHook.js +33 -0
  74. package/lib/shallow/ReactInjection.js +33 -0
  75. package/lib/shallow/ReactInputSelection.js +123 -0
  76. package/lib/shallow/ReactInstanceMap.js +47 -0
  77. package/lib/shallow/ReactInstanceType.js +12 -0
  78. package/lib/shallow/ReactInstrumentation.js +23 -0
  79. package/lib/shallow/ReactInvalidSetStateWarningHook.js +36 -0
  80. package/lib/shallow/ReactMarkupChecksum.js +49 -0
  81. package/lib/shallow/ReactMount.js +537 -0
  82. package/lib/shallow/ReactMultiChild.js +449 -0
  83. package/lib/shallow/ReactMultiChildUpdateTypes.js +18 -0
  84. package/lib/shallow/ReactNodeTypes.js +39 -0
  85. package/lib/shallow/ReactOwner.js +93 -0
  86. package/lib/shallow/ReactPerf.js +500 -0
  87. package/lib/shallow/ReactPriorityLevel.js +20 -0
  88. package/lib/shallow/ReactPropTypeLocationNames.js +24 -0
  89. package/lib/shallow/ReactPropTypeLocations.js +12 -0
  90. package/lib/shallow/ReactPropTypesSecret.js +16 -0
  91. package/lib/shallow/ReactReconcileTransaction.js +177 -0
  92. package/lib/shallow/ReactReconciler.js +167 -0
  93. package/lib/shallow/ReactRef.js +88 -0
  94. package/lib/shallow/ReactReifiedYield.js +30 -0
  95. package/lib/shallow/ReactServerBatchingStrategy.js +21 -0
  96. package/lib/shallow/ReactServerRendering.js +89 -0
  97. package/lib/shallow/ReactServerRenderingTransaction.js +89 -0
  98. package/lib/shallow/ReactServerUpdateQueue.js +138 -0
  99. package/lib/shallow/ReactShallowRenderer.js +150 -0
  100. package/lib/shallow/ReactSimpleEmptyComponent.js +36 -0
  101. package/lib/shallow/ReactSyntheticEventType.js +14 -0
  102. package/lib/shallow/ReactTestEmptyComponent.js +36 -0
  103. package/lib/shallow/ReactTestMount.js +131 -0
  104. package/lib/shallow/ReactTestReconcileTransaction.js +128 -0
  105. package/lib/shallow/ReactTestRenderer.js +139 -0
  106. package/lib/shallow/ReactTestTextComponent.js +40 -0
  107. package/lib/shallow/ReactTypeOfWork.js +23 -0
  108. package/lib/shallow/ReactTypes.js +12 -0
  109. package/lib/shallow/ReactUpdateQueue.js +235 -0
  110. package/lib/shallow/ReactUpdates.js +250 -0
  111. package/lib/shallow/ReactVersion.js +13 -0
  112. package/lib/shallow/ResponderEventPlugin.js +507 -0
  113. package/lib/shallow/ResponderSyntheticEvent.js +38 -0
  114. package/lib/shallow/ResponderTouchHistoryStore.js +183 -0
  115. package/lib/shallow/SVGDOMPropertyConfig.js +301 -0
  116. package/lib/shallow/SelectEventPlugin.js +190 -0
  117. package/lib/shallow/SimpleEventPlugin.js +227 -0
  118. package/lib/shallow/SyntheticAnimationEvent.js +38 -0
  119. package/lib/shallow/SyntheticClipboardEvent.js +37 -0
  120. package/lib/shallow/SyntheticCompositionEvent.js +35 -0
  121. package/lib/shallow/SyntheticDragEvent.js +35 -0
  122. package/lib/shallow/SyntheticEvent.js +267 -0
  123. package/lib/shallow/SyntheticFocusEvent.js +35 -0
  124. package/lib/shallow/SyntheticInputEvent.js +36 -0
  125. package/lib/shallow/SyntheticKeyboardEvent.js +83 -0
  126. package/lib/shallow/SyntheticMouseEvent.js +71 -0
  127. package/lib/shallow/SyntheticTouchEvent.js +44 -0
  128. package/lib/shallow/SyntheticTransitionEvent.js +38 -0
  129. package/lib/shallow/SyntheticUIEvent.js +58 -0
  130. package/lib/shallow/SyntheticWheelEvent.js +53 -0
  131. package/lib/shallow/TapEventPlugin.js +115 -0
  132. package/lib/shallow/TouchHistoryMath.js +98 -0
  133. package/lib/shallow/Transaction.js +224 -0
  134. package/lib/shallow/ViewportMetrics.js +26 -0
  135. package/lib/shallow/accumulate.js +45 -0
  136. package/lib/shallow/accumulateInto.js +57 -0
  137. package/lib/shallow/adler32.js +43 -0
  138. package/lib/shallow/canDefineProperty.js +25 -0
  139. package/lib/shallow/checkReactTypeSpec.js +86 -0
  140. package/lib/shallow/createMicrosoftUnsafeLocalFunction.js +31 -0
  141. package/lib/shallow/dangerousStyleValue.js +78 -0
  142. package/lib/shallow/deprecated.js +56 -0
  143. package/lib/shallow/escapeTextContentForBrowser.js +122 -0
  144. package/lib/shallow/findDOMNode.js +59 -0
  145. package/lib/shallow/flattenChildren.js +75 -0
  146. package/lib/shallow/forEachAccumulated.js +30 -0
  147. package/lib/shallow/getEventCharCode.js +49 -0
  148. package/lib/shallow/getEventKey.js +101 -0
  149. package/lib/shallow/getEventModifierState.js +42 -0
  150. package/lib/shallow/getEventTarget.js +34 -0
  151. package/lib/shallow/getHostComponentFromComposite.js +29 -0
  152. package/lib/shallow/getIteratorFn.js +40 -0
  153. package/lib/shallow/getNodeForCharacterOffset.js +73 -0
  154. package/lib/shallow/getTextContentAccessor.js +32 -0
  155. package/lib/shallow/getVendorPrefixedEventName.js +100 -0
  156. package/lib/shallow/instantiateReactComponent.js +128 -0
  157. package/lib/shallow/isEventSupported.js +59 -0
  158. package/lib/shallow/isTextInputElement.js +50 -0
  159. package/lib/shallow/quoteAttributeValueForBrowser.js +25 -0
  160. package/lib/shallow/reactProdInvariant.js +38 -0
  161. package/lib/shallow/renderSubtreeIntoContainer.js +15 -0
  162. package/lib/shallow/setInnerHTML.js +97 -0
  163. package/lib/shallow/setTextContent.js +51 -0
  164. package/lib/shallow/shouldUpdateReactComponent.js +41 -0
  165. package/lib/shallow/traverseAllChildren.js +175 -0
  166. package/lib/shallow/validateDOMNesting.js +376 -0
  167. package/package.json +1 -1
  168. package/shallow.js +1 -1
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ *
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var _require = require('./ReactChildFiber'),
15
+ reconcileChildFibers = _require.reconcileChildFibers,
16
+ reconcileChildFibersInPlace = _require.reconcileChildFibersInPlace,
17
+ cloneChildFibers = _require.cloneChildFibers;
18
+
19
+ var _require2 = require('./ReactPriorityLevel'),
20
+ LowPriority = _require2.LowPriority;
21
+
22
+ var ReactTypeOfWork = require('./ReactTypeOfWork');
23
+ var IndeterminateComponent = ReactTypeOfWork.IndeterminateComponent,
24
+ FunctionalComponent = ReactTypeOfWork.FunctionalComponent,
25
+ ClassComponent = ReactTypeOfWork.ClassComponent,
26
+ HostContainer = ReactTypeOfWork.HostContainer,
27
+ HostComponent = ReactTypeOfWork.HostComponent,
28
+ CoroutineComponent = ReactTypeOfWork.CoroutineComponent,
29
+ CoroutineHandlerPhase = ReactTypeOfWork.CoroutineHandlerPhase,
30
+ YieldComponent = ReactTypeOfWork.YieldComponent;
31
+
32
+ var _require3 = require('./ReactPriorityLevel'),
33
+ NoWork = _require3.NoWork,
34
+ OffscreenPriority = _require3.OffscreenPriority;
35
+
36
+ var _require4 = require('./ReactFiberUpdateQueue'),
37
+ createUpdateQueue = _require4.createUpdateQueue,
38
+ addToQueue = _require4.addToQueue,
39
+ addCallbackToQueue = _require4.addCallbackToQueue,
40
+ mergeUpdateQueue = _require4.mergeUpdateQueue;
41
+
42
+ var ReactInstanceMap = require('./ReactInstanceMap');
43
+
44
+ module.exports = function (config, getScheduler) {
45
+
46
+ function markChildAsProgressed(current, workInProgress, priorityLevel) {
47
+ // We now have clones. Let's store them as the currently progressed work.
48
+ workInProgress.progressedChild = workInProgress.child;
49
+ workInProgress.progressedPriority = priorityLevel;
50
+ if (current) {
51
+ // We also store it on the current. When the alternate swaps in we can
52
+ // continue from this point.
53
+ current.progressedChild = workInProgress.progressedChild;
54
+ current.progressedPriority = workInProgress.progressedPriority;
55
+ }
56
+ }
57
+
58
+ function reconcileChildren(current, workInProgress, nextChildren) {
59
+ var priorityLevel = workInProgress.pendingWorkPriority;
60
+ reconcileChildrenAtPriority(current, workInProgress, nextChildren, priorityLevel);
61
+ }
62
+
63
+ function reconcileChildrenAtPriority(current, workInProgress, nextChildren, priorityLevel) {
64
+ // At this point any memoization is no longer valid since we'll have changed
65
+ // the children.
66
+ workInProgress.memoizedProps = null;
67
+ if (current && current.child === workInProgress.child) {
68
+ // If the current child is the same as the work in progress, it means that
69
+ // we haven't yet started any work on these children. Therefore, we use
70
+ // the clone algorithm to create a copy of all the current children.
71
+ workInProgress.child = reconcileChildFibers(workInProgress, workInProgress.child, nextChildren, priorityLevel);
72
+ } else {
73
+ // If, on the other hand, we don't have a current fiber or if it is
74
+ // already using a clone, that means we've already begun some work on this
75
+ // tree and we can continue where we left off by reconciling against the
76
+ // existing children.
77
+ workInProgress.child = reconcileChildFibersInPlace(workInProgress, workInProgress.child, nextChildren, priorityLevel);
78
+ }
79
+ markChildAsProgressed(current, workInProgress, priorityLevel);
80
+ }
81
+
82
+ function updateFunctionalComponent(current, workInProgress) {
83
+ var fn = workInProgress.type;
84
+ var props = workInProgress.pendingProps;
85
+
86
+ // TODO: Disable this before release, since it is not part of the public API
87
+ // I use this for testing to compare the relative overhead of classes.
88
+ if (typeof fn.shouldComponentUpdate === 'function') {
89
+ if (workInProgress.memoizedProps !== null) {
90
+ if (!fn.shouldComponentUpdate(workInProgress.memoizedProps, props)) {
91
+ return bailoutOnAlreadyFinishedWork(current, workInProgress);
92
+ }
93
+ }
94
+ }
95
+
96
+ var nextChildren = fn(props);
97
+ reconcileChildren(current, workInProgress, nextChildren);
98
+ return workInProgress.child;
99
+ }
100
+
101
+ function scheduleUpdate(fiber, updateQueue, priorityLevel) {
102
+ var _getScheduler = getScheduler(),
103
+ scheduleDeferredWork = _getScheduler.scheduleDeferredWork;
104
+
105
+ fiber.updateQueue = updateQueue;
106
+ // Schedule update on the alternate as well, since we don't know which tree
107
+ // is current.
108
+ if (fiber.alternate) {
109
+ fiber.alternate.updateQueue = updateQueue;
110
+ }
111
+ while (true) {
112
+ if (fiber.pendingWorkPriority === NoWork || fiber.pendingWorkPriority >= priorityLevel) {
113
+ fiber.pendingWorkPriority = priorityLevel;
114
+ }
115
+ if (fiber.alternate) {
116
+ if (fiber.alternate.pendingWorkPriority === NoWork || fiber.alternate.pendingWorkPriority >= priorityLevel) {
117
+ fiber.alternate.pendingWorkPriority = priorityLevel;
118
+ }
119
+ }
120
+ // Duck type root
121
+ if (fiber.stateNode && fiber.stateNode.containerInfo) {
122
+ var root = fiber.stateNode;
123
+ scheduleDeferredWork(root, priorityLevel);
124
+ return;
125
+ }
126
+ if (!fiber['return']) {
127
+ throw new Error('No root!');
128
+ }
129
+ fiber = fiber['return'];
130
+ }
131
+ }
132
+
133
+ // Class component state updater
134
+ var updater = {
135
+ enqueueSetState: function (instance, partialState) {
136
+ var fiber = ReactInstanceMap.get(instance);
137
+ var updateQueue = fiber.updateQueue ? addToQueue(fiber.updateQueue, partialState) : createUpdateQueue(partialState);
138
+ scheduleUpdate(fiber, updateQueue, LowPriority);
139
+ },
140
+ enqueueReplaceState: function (instance, state) {
141
+ var fiber = ReactInstanceMap.get(instance);
142
+ var updateQueue = createUpdateQueue(state);
143
+ updateQueue.isReplace = true;
144
+ scheduleUpdate(fiber, updateQueue, LowPriority);
145
+ },
146
+ enqueueForceUpdate: function (instance) {
147
+ var fiber = ReactInstanceMap.get(instance);
148
+ var updateQueue = fiber.updateQueue || createUpdateQueue(null);
149
+ updateQueue.isForced = true;
150
+ scheduleUpdate(fiber, updateQueue, LowPriority);
151
+ },
152
+ enqueueCallback: function (instance, callback) {
153
+ var fiber = ReactInstanceMap.get(instance);
154
+ var updateQueue = fiber.updateQueue ? fiber.updateQueue : createUpdateQueue(null);
155
+ addCallbackToQueue(updateQueue, callback);
156
+ fiber.updateQueue = updateQueue;
157
+ if (fiber.alternate) {
158
+ fiber.alternate.updateQueue = updateQueue;
159
+ }
160
+ }
161
+ };
162
+
163
+ function updateClassComponent(current, workInProgress) {
164
+ // A class component update is the result of either new props or new state.
165
+ // Account for the possibly of missing pending props by falling back to the
166
+ // memoized props.
167
+ var props = workInProgress.pendingProps;
168
+ if (!props && current) {
169
+ props = current.memoizedProps;
170
+ }
171
+ // Compute the state using the memoized state and the update queue.
172
+ var updateQueue = workInProgress.updateQueue;
173
+ var previousState = current ? current.memoizedState : null;
174
+ var state = updateQueue ? mergeUpdateQueue(updateQueue, previousState, props) : previousState;
175
+
176
+ var instance = workInProgress.stateNode;
177
+ if (!instance) {
178
+ var ctor = workInProgress.type;
179
+ workInProgress.stateNode = instance = new ctor(props);
180
+ state = instance.state || null;
181
+ // The initial state must be added to the update queue in case
182
+ // setState is called before the initial render.
183
+ if (state !== null) {
184
+ workInProgress.updateQueue = createUpdateQueue(state);
185
+ }
186
+ // The instance needs access to the fiber so that it can schedule updates
187
+ ReactInstanceMap.set(instance, workInProgress);
188
+ instance.updater = updater;
189
+ } else if (typeof instance.shouldComponentUpdate === 'function' && !(updateQueue && updateQueue.isForced)) {
190
+ if (workInProgress.memoizedProps !== null) {
191
+ // Reset the props, in case this is a ping-pong case rather than a
192
+ // completed update case. For the completed update case, the instance
193
+ // props will already be the memoizedProps.
194
+ instance.props = workInProgress.memoizedProps;
195
+ instance.state = workInProgress.memoizedState;
196
+ if (!instance.shouldComponentUpdate(props, state)) {
197
+ return bailoutOnAlreadyFinishedWork(current, workInProgress);
198
+ }
199
+ }
200
+ }
201
+
202
+ instance.props = props;
203
+ instance.state = state;
204
+ var nextChildren = instance.render();
205
+ reconcileChildren(current, workInProgress, nextChildren);
206
+
207
+ return workInProgress.child;
208
+ }
209
+
210
+ function updateHostComponent(current, workInProgress) {
211
+ var nextChildren = workInProgress.pendingProps.children;
212
+ if (workInProgress.pendingProps.hidden && workInProgress.pendingWorkPriority !== OffscreenPriority) {
213
+ // If this host component is hidden, we can bail out on the children.
214
+ // We'll rerender the children later at the lower priority.
215
+
216
+ // It is unfortunate that we have to do the reconciliation of these
217
+ // children already since that will add them to the tree even though
218
+ // they are not actually done yet. If this is a large set it is also
219
+ // confusing that this takes time to do right now instead of later.
220
+
221
+ if (workInProgress.progressedPriority === OffscreenPriority) {
222
+ // If we already made some progress on the offscreen priority before,
223
+ // then we should continue from where we left off.
224
+ workInProgress.child = workInProgress.progressedChild;
225
+ }
226
+
227
+ // Reconcile the children and stash them for later work.
228
+ reconcileChildrenAtPriority(current, workInProgress, nextChildren, OffscreenPriority);
229
+ workInProgress.child = current ? current.child : null;
230
+ // Abort and don't process children yet.
231
+ return null;
232
+ } else {
233
+ reconcileChildren(current, workInProgress, nextChildren);
234
+ return workInProgress.child;
235
+ }
236
+ }
237
+
238
+ function mountIndeterminateComponent(current, workInProgress) {
239
+ var fn = workInProgress.type;
240
+ var props = workInProgress.pendingProps;
241
+ var value = fn(props);
242
+ if (typeof value === 'object' && value && typeof value.render === 'function') {
243
+ // Proceed under the assumption that this is a class instance
244
+ workInProgress.tag = ClassComponent;
245
+ if (current) {
246
+ current.tag = ClassComponent;
247
+ }
248
+ value = value.render();
249
+ } else {
250
+ // Proceed under the assumption that this is a functional component
251
+ workInProgress.tag = FunctionalComponent;
252
+ if (current) {
253
+ current.tag = FunctionalComponent;
254
+ }
255
+ }
256
+ reconcileChildren(current, workInProgress, value);
257
+ return workInProgress.child;
258
+ }
259
+
260
+ function updateCoroutineComponent(current, workInProgress) {
261
+ var coroutine = workInProgress.pendingProps;
262
+ if (!coroutine) {
263
+ throw new Error('Should be resolved by now');
264
+ }
265
+ reconcileChildren(current, workInProgress, coroutine.children);
266
+ }
267
+
268
+ /*
269
+ function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
270
+ let child = firstChild;
271
+ do {
272
+ // Ensure that the first and last effect of the parent corresponds
273
+ // to the children's first and last effect.
274
+ if (!returnFiber.firstEffect) {
275
+ returnFiber.firstEffect = child.firstEffect;
276
+ }
277
+ if (child.lastEffect) {
278
+ if (returnFiber.lastEffect) {
279
+ returnFiber.lastEffect.nextEffect = child.firstEffect;
280
+ }
281
+ returnFiber.lastEffect = child.lastEffect;
282
+ }
283
+ } while (child = child.sibling);
284
+ }
285
+ */
286
+
287
+ function bailoutOnAlreadyFinishedWork(current, workInProgress) {
288
+ var priorityLevel = workInProgress.pendingWorkPriority;
289
+
290
+ // TODO: We should ideally be able to bail out early if the children have no
291
+ // more work to do. However, since we don't have a separation of this
292
+ // Fiber's priority and its children yet - we don't know without doing lots
293
+ // of the same work we do anyway. Once we have that separation we can just
294
+ // bail out here if the children has no more work at this priority level.
295
+ // if (workInProgress.priorityOfChildren <= priorityLevel) {
296
+ // // If there are side-effects in these children that have not yet been
297
+ // // committed we need to ensure that they get properly transferred up.
298
+ // if (current && current.child !== workInProgress.child) {
299
+ // reuseChildrenEffects(workInProgress, child);
300
+ // }
301
+ // return null;
302
+ // }
303
+
304
+ cloneChildFibers(current, workInProgress);
305
+ markChildAsProgressed(current, workInProgress, priorityLevel);
306
+ return workInProgress.child;
307
+ }
308
+
309
+ function bailoutOnLowPriority(current, workInProgress) {
310
+ if (current) {
311
+ workInProgress.child = current.child;
312
+ workInProgress.memoizedProps = current.memoizedProps;
313
+ workInProgress.output = current.output;
314
+ }
315
+ return null;
316
+ }
317
+
318
+ function beginWork(current, workInProgress, priorityLevel) {
319
+ if (workInProgress.pendingWorkPriority === NoWork || workInProgress.pendingWorkPriority > priorityLevel) {
320
+ return bailoutOnLowPriority(current, workInProgress);
321
+ }
322
+
323
+ if (workInProgress.progressedPriority === priorityLevel) {
324
+ // If we have progressed work on this priority level already, we can
325
+ // proceed this that as the child.
326
+ workInProgress.child = workInProgress.progressedChild;
327
+ }
328
+
329
+ if ((workInProgress.pendingProps === null || workInProgress.memoizedProps !== null && workInProgress.pendingProps === workInProgress.memoizedProps) && workInProgress.updateQueue === null) {
330
+ return bailoutOnAlreadyFinishedWork(current, workInProgress);
331
+ }
332
+
333
+ switch (workInProgress.tag) {
334
+ case IndeterminateComponent:
335
+ return mountIndeterminateComponent(current, workInProgress);
336
+ case FunctionalComponent:
337
+ return updateFunctionalComponent(current, workInProgress);
338
+ case ClassComponent:
339
+ return updateClassComponent(current, workInProgress);
340
+ case HostContainer:
341
+ reconcileChildren(current, workInProgress, workInProgress.pendingProps);
342
+ // A yield component is just a placeholder, we can just run through the
343
+ // next one immediately.
344
+ if (workInProgress.child) {
345
+ return beginWork(workInProgress.child.alternate, workInProgress.child, priorityLevel);
346
+ }
347
+ return null;
348
+ case HostComponent:
349
+ if (workInProgress.stateNode && typeof config.beginUpdate === 'function') {
350
+ config.beginUpdate(workInProgress.stateNode);
351
+ }
352
+ return updateHostComponent(current, workInProgress);
353
+ case CoroutineHandlerPhase:
354
+ // This is a restart. Reset the tag to the initial phase.
355
+ workInProgress.tag = CoroutineComponent;
356
+ // Intentionally fall through since this is now the same.
357
+ case CoroutineComponent:
358
+ updateCoroutineComponent(current, workInProgress);
359
+ // This doesn't take arbitrary time so we could synchronously just begin
360
+ // eagerly do the work of workInProgress.child as an optimization.
361
+ if (workInProgress.child) {
362
+ return beginWork(workInProgress.child.alternate, workInProgress.child, priorityLevel);
363
+ }
364
+ return workInProgress.child;
365
+ case YieldComponent:
366
+ // A yield component is just a placeholder, we can just run through the
367
+ // next one immediately.
368
+ if (workInProgress.sibling) {
369
+ return beginWork(workInProgress.sibling.alternate, workInProgress.sibling, priorityLevel);
370
+ }
371
+ return null;
372
+ default:
373
+ throw new Error('Unknown unit of work tag');
374
+ }
375
+ }
376
+
377
+ return {
378
+ beginWork: beginWork
379
+ };
380
+ };
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ *
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var ReactTypeOfWork = require('./ReactTypeOfWork');
15
+ var ClassComponent = ReactTypeOfWork.ClassComponent,
16
+ HostContainer = ReactTypeOfWork.HostContainer,
17
+ HostComponent = ReactTypeOfWork.HostComponent;
18
+
19
+ var _require = require('./ReactFiberUpdateQueue'),
20
+ callCallbacks = _require.callCallbacks;
21
+
22
+ module.exports = function (config) {
23
+
24
+ var updateContainer = config.updateContainer;
25
+ var commitUpdate = config.commitUpdate;
26
+
27
+ function commitWork(current, finishedWork) {
28
+ switch (finishedWork.tag) {
29
+ case ClassComponent:
30
+ {
31
+ // Clear updates from current fiber. This must go before the callbacks
32
+ // are reset, in case an update is triggered from inside a callback. Is
33
+ // this safe? Relies on the assumption that work is only committed if
34
+ // the update queue is empty.
35
+ if (finishedWork.alternate) {
36
+ finishedWork.alternate.updateQueue = null;
37
+ }
38
+ if (finishedWork.callbackList) {
39
+ var callbackList = finishedWork.callbackList;
40
+
41
+ finishedWork.callbackList = null;
42
+ callCallbacks(callbackList, finishedWork.stateNode);
43
+ }
44
+ // TODO: Fire componentDidMount/componentDidUpdate, update refs
45
+ return;
46
+ }
47
+ case HostContainer:
48
+ {
49
+ // TODO: Attach children to root container.
50
+ var children = finishedWork.output;
51
+ var root = finishedWork.stateNode;
52
+ var containerInfo = root.containerInfo;
53
+ updateContainer(containerInfo, children);
54
+ return;
55
+ }
56
+ case HostComponent:
57
+ {
58
+ if (finishedWork.stateNode == null || !current) {
59
+ throw new Error('This should only be done during updates.');
60
+ }
61
+ // Commit the work prepared earlier.
62
+ var child = finishedWork.child;
63
+ var _children = child && !child.sibling ? child.output : child;
64
+ var newProps = finishedWork.memoizedProps;
65
+ var oldProps = current.memoizedProps;
66
+ var instance = finishedWork.stateNode;
67
+ commitUpdate(instance, oldProps, newProps, _children);
68
+ return;
69
+ }
70
+ default:
71
+ throw new Error('This unit of work tag should not have side-effects.');
72
+ }
73
+ }
74
+
75
+ return {
76
+ commitWork: commitWork
77
+ };
78
+ };
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ *
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var _require = require('./ReactChildFiber'),
15
+ reconcileChildFibers = _require.reconcileChildFibers;
16
+
17
+ var ReactTypeOfWork = require('./ReactTypeOfWork');
18
+ var IndeterminateComponent = ReactTypeOfWork.IndeterminateComponent,
19
+ FunctionalComponent = ReactTypeOfWork.FunctionalComponent,
20
+ ClassComponent = ReactTypeOfWork.ClassComponent,
21
+ HostContainer = ReactTypeOfWork.HostContainer,
22
+ HostComponent = ReactTypeOfWork.HostComponent,
23
+ CoroutineComponent = ReactTypeOfWork.CoroutineComponent,
24
+ CoroutineHandlerPhase = ReactTypeOfWork.CoroutineHandlerPhase,
25
+ YieldComponent = ReactTypeOfWork.YieldComponent;
26
+
27
+
28
+ module.exports = function (config) {
29
+
30
+ var createInstance = config.createInstance;
31
+ var prepareUpdate = config.prepareUpdate;
32
+
33
+ function markForPreEffect(workInProgress) {
34
+ // Schedule a side-effect on this fiber, BEFORE the children's side-effects.
35
+ if (workInProgress.firstEffect) {
36
+ workInProgress.nextEffect = workInProgress.firstEffect;
37
+ workInProgress.firstEffect = workInProgress;
38
+ } else {
39
+ workInProgress.firstEffect = workInProgress;
40
+ workInProgress.lastEffect = workInProgress;
41
+ }
42
+ }
43
+
44
+ // TODO: It's possible this will create layout thrash issues because mutations
45
+ // of the DOM and life-cycles are interleaved. E.g. if a componentDidMount
46
+ // of a sibling reads, then the next sibling updates and reads etc.
47
+ function markForPostEffect(workInProgress) {
48
+ // Schedule a side-effect on this fiber, AFTER the children's side-effects.
49
+ if (workInProgress.lastEffect) {
50
+ workInProgress.lastEffect.nextEffect = workInProgress;
51
+ } else {
52
+ workInProgress.firstEffect = workInProgress;
53
+ }
54
+ workInProgress.lastEffect = workInProgress;
55
+ }
56
+
57
+ function transferOutput(child, returnFiber) {
58
+ // If we have a single result, we just pass that through as the output to
59
+ // avoid unnecessary traversal. When we have multiple output, we just pass
60
+ // the linked list of fibers that has the individual output values.
61
+ returnFiber.output = child && !child.sibling ? child.output : child;
62
+ returnFiber.memoizedProps = returnFiber.pendingProps;
63
+ }
64
+
65
+ function recursivelyFillYields(yields, output) {
66
+ if (!output) {
67
+ // Ignore nulls etc.
68
+ } else if (output.tag !== undefined) {
69
+ // TODO: Fix this fragile duck test.
70
+ // Detect if this is a fiber, if so it is a fragment result.
71
+ // $FlowFixMe: Refinement issue.
72
+ var item = output;
73
+ do {
74
+ recursivelyFillYields(yields, item.output);
75
+ item = item.sibling;
76
+ } while (item);
77
+ } else {
78
+ // $FlowFixMe: Refinement issue. If it is not a Fiber or null, it is a yield
79
+ yields.push(output);
80
+ }
81
+ }
82
+
83
+ function moveCoroutineToHandlerPhase(current, workInProgress) {
84
+ var coroutine = workInProgress.pendingProps;
85
+ if (!coroutine) {
86
+ throw new Error('Should be resolved by now');
87
+ }
88
+
89
+ // First step of the coroutine has completed. Now we need to do the second.
90
+ // TODO: It would be nice to have a multi stage coroutine represented by a
91
+ // single component, or at least tail call optimize nested ones. Currently
92
+ // that requires additional fields that we don't want to add to the fiber.
93
+ // So this requires nested handlers.
94
+ // Note: This doesn't mutate the alternate node. I don't think it needs to
95
+ // since this stage is reset for every pass.
96
+ workInProgress.tag = CoroutineHandlerPhase;
97
+
98
+ // Build up the yields.
99
+ // TODO: Compare this to a generator or opaque helpers like Children.
100
+ var yields = [];
101
+ var child = workInProgress.child;
102
+ while (child) {
103
+ recursivelyFillYields(yields, child.output);
104
+ child = child.sibling;
105
+ }
106
+ var fn = coroutine.handler;
107
+ var props = coroutine.props;
108
+ var nextChildren = fn(props, yields);
109
+
110
+ var currentFirstChild = current ? current.stateNode : null;
111
+ // Inherit the priority of the returnFiber.
112
+ var priority = workInProgress.pendingWorkPriority;
113
+ workInProgress.stateNode = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, priority);
114
+ return workInProgress.stateNode;
115
+ }
116
+
117
+ function completeWork(current, workInProgress) {
118
+ switch (workInProgress.tag) {
119
+ case FunctionalComponent:
120
+ transferOutput(workInProgress.child, workInProgress);
121
+ return null;
122
+ case ClassComponent:
123
+ transferOutput(workInProgress.child, workInProgress);
124
+ // Don't use the state queue to compute the memoized state. We already
125
+ // merged it and assigned it to the instance. Transfer it from there.
126
+ // Also need to transfer the props, because pendingProps will be null
127
+ // in the case of an update
128
+ var _workInProgress$state = workInProgress.stateNode,
129
+ state = _workInProgress$state.state,
130
+ props = _workInProgress$state.props;
131
+
132
+ workInProgress.memoizedState = state;
133
+ workInProgress.memoizedProps = props;
134
+ // Transfer update queue to callbackList field so callbacks can be
135
+ // called during commit phase.
136
+ workInProgress.callbackList = workInProgress.updateQueue;
137
+ markForPostEffect(workInProgress);
138
+ return null;
139
+ case HostContainer:
140
+ transferOutput(workInProgress.child, workInProgress);
141
+ // We don't know if a container has updated any children so we always
142
+ // need to update it right now. We schedule this side-effect before
143
+ // all the other side-effects in the subtree. We need to schedule it
144
+ // before so that the entire tree is up-to-date before the life-cycles
145
+ // are invoked.
146
+ markForPreEffect(workInProgress);
147
+ return null;
148
+ case HostComponent:
149
+ var newProps = workInProgress.pendingProps;
150
+ var child = workInProgress.child;
151
+ var children = child && !child.sibling ? child.output : child;
152
+ if (current && workInProgress.stateNode != null) {
153
+ // If we have an alternate, that means this is an update and we need to
154
+ // schedule a side-effect to do the updates.
155
+ var oldProps = current.memoizedProps;
156
+ // If we get updated because one of our children updated, we don't
157
+ // have newProps so we'll have to reuse them.
158
+ // TODO: Split the update API as separate for the props vs. children.
159
+ // Even better would be if children weren't special cased at all tho.
160
+ if (!newProps) {
161
+ newProps = oldProps;
162
+ }
163
+ var instance = workInProgress.stateNode;
164
+ if (prepareUpdate(instance, oldProps, newProps, children)) {
165
+ // This returns true if there was something to update.
166
+ markForPreEffect(workInProgress);
167
+ }
168
+ // TODO: Is this actually ever going to change? Why set it every time?
169
+ workInProgress.output = instance;
170
+ } else {
171
+ if (!newProps) {
172
+ if (workInProgress.stateNode === null) {
173
+ throw new Error('We must have new props for new mounts.');
174
+ } else {
175
+ // This can happen when we abort work.
176
+ return null;
177
+ }
178
+ }
179
+ var _instance = createInstance(workInProgress.type, newProps, children);
180
+ // TODO: This seems like unnecessary duplication.
181
+ workInProgress.stateNode = _instance;
182
+ workInProgress.output = _instance;
183
+ }
184
+ workInProgress.memoizedProps = newProps;
185
+ return null;
186
+ case CoroutineComponent:
187
+ return moveCoroutineToHandlerPhase(current, workInProgress);
188
+ case CoroutineHandlerPhase:
189
+ transferOutput(workInProgress.stateNode, workInProgress);
190
+ // Reset the tag to now be a first phase coroutine.
191
+ workInProgress.tag = CoroutineComponent;
192
+ return null;
193
+ case YieldComponent:
194
+ // Does nothing.
195
+ return null;
196
+
197
+ // Error cases
198
+ case IndeterminateComponent:
199
+ throw new Error('An indeterminate component should have become determinate before completing.');
200
+ default:
201
+ throw new Error('Unknown unit of work tag');
202
+ }
203
+ }
204
+
205
+ return {
206
+ completeWork: completeWork
207
+ };
208
+ };