1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | 'use strict';
|
11 |
|
12 | var _require = require('./ReactChildFiber'),
|
13 | reconcileChildFibers = _require.reconcileChildFibers;
|
14 |
|
15 | var ReactTypeOfWork = require('./ReactTypeOfWork');
|
16 | var IndeterminateComponent = ReactTypeOfWork.IndeterminateComponent,
|
17 | FunctionalComponent = ReactTypeOfWork.FunctionalComponent,
|
18 | ClassComponent = ReactTypeOfWork.ClassComponent,
|
19 | HostContainer = ReactTypeOfWork.HostContainer,
|
20 | HostComponent = ReactTypeOfWork.HostComponent,
|
21 | CoroutineComponent = ReactTypeOfWork.CoroutineComponent,
|
22 | CoroutineHandlerPhase = ReactTypeOfWork.CoroutineHandlerPhase,
|
23 | YieldComponent = ReactTypeOfWork.YieldComponent;
|
24 |
|
25 |
|
26 | module.exports = function (config) {
|
27 | var createInstance = config.createInstance;
|
28 | var prepareUpdate = config.prepareUpdate;
|
29 |
|
30 | function markForPreEffect(workInProgress) {
|
31 |
|
32 | if (workInProgress.firstEffect) {
|
33 | workInProgress.nextEffect = workInProgress.firstEffect;
|
34 | workInProgress.firstEffect = workInProgress;
|
35 | } else {
|
36 | workInProgress.firstEffect = workInProgress;
|
37 | workInProgress.lastEffect = workInProgress;
|
38 | }
|
39 | }
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | function markForPostEffect(workInProgress) {
|
45 |
|
46 | if (workInProgress.lastEffect) {
|
47 | workInProgress.lastEffect.nextEffect = workInProgress;
|
48 | } else {
|
49 | workInProgress.firstEffect = workInProgress;
|
50 | }
|
51 | workInProgress.lastEffect = workInProgress;
|
52 | }
|
53 |
|
54 | function transferOutput(child, returnFiber) {
|
55 |
|
56 |
|
57 |
|
58 | returnFiber.output = child && !child.sibling ? child.output : child;
|
59 | returnFiber.memoizedProps = returnFiber.pendingProps;
|
60 | }
|
61 |
|
62 | function recursivelyFillYields(yields, output) {
|
63 | if (!output) {
|
64 |
|
65 | } else if (output.tag !== undefined) {
|
66 |
|
67 |
|
68 |
|
69 | var item = output;
|
70 | do {
|
71 | recursivelyFillYields(yields, item.output);
|
72 | item = item.sibling;
|
73 | } while (item);
|
74 | } else {
|
75 |
|
76 | yields.push(output);
|
77 | }
|
78 | }
|
79 |
|
80 | function moveCoroutineToHandlerPhase(current, workInProgress) {
|
81 | var coroutine = workInProgress.pendingProps;
|
82 | if (!coroutine) {
|
83 | throw new Error('Should be resolved by now');
|
84 | }
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | workInProgress.tag = CoroutineHandlerPhase;
|
94 |
|
95 |
|
96 |
|
97 | var yields = [];
|
98 | var child = workInProgress.child;
|
99 | while (child) {
|
100 | recursivelyFillYields(yields, child.output);
|
101 | child = child.sibling;
|
102 | }
|
103 | var fn = coroutine.handler;
|
104 | var props = coroutine.props;
|
105 | var nextChildren = fn(props, yields);
|
106 |
|
107 | var currentFirstChild = current ? current.stateNode : null;
|
108 |
|
109 | var priority = workInProgress.pendingWorkPriority;
|
110 | workInProgress.stateNode = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, priority);
|
111 | return workInProgress.stateNode;
|
112 | }
|
113 |
|
114 | function completeWork(current, workInProgress) {
|
115 | switch (workInProgress.tag) {
|
116 | case FunctionalComponent:
|
117 | transferOutput(workInProgress.child, workInProgress);
|
118 | return null;
|
119 | case ClassComponent:
|
120 | transferOutput(workInProgress.child, workInProgress);
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | var _workInProgress$state = workInProgress.stateNode,
|
126 | state = _workInProgress$state.state,
|
127 | props = _workInProgress$state.props;
|
128 |
|
129 | workInProgress.memoizedState = state;
|
130 | workInProgress.memoizedProps = props;
|
131 |
|
132 |
|
133 | workInProgress.callbackList = workInProgress.updateQueue;
|
134 | markForPostEffect(workInProgress);
|
135 | return null;
|
136 | case HostContainer:
|
137 | transferOutput(workInProgress.child, workInProgress);
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | markForPreEffect(workInProgress);
|
144 | return null;
|
145 | case HostComponent:
|
146 | var newProps = workInProgress.pendingProps;
|
147 | var child = workInProgress.child;
|
148 | var children = child && !child.sibling ? child.output : child;
|
149 | if (current && workInProgress.stateNode != null) {
|
150 |
|
151 |
|
152 | var oldProps = current.memoizedProps;
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | if (!newProps) {
|
158 | newProps = oldProps;
|
159 | }
|
160 | var instance = workInProgress.stateNode;
|
161 | if (prepareUpdate(instance, oldProps, newProps, children)) {
|
162 |
|
163 | markForPreEffect(workInProgress);
|
164 | }
|
165 |
|
166 | workInProgress.output = instance;
|
167 | } else {
|
168 | if (!newProps) {
|
169 | if (workInProgress.stateNode === null) {
|
170 | throw new Error('We must have new props for new mounts.');
|
171 | } else {
|
172 |
|
173 | return null;
|
174 | }
|
175 | }
|
176 | var _instance = createInstance(workInProgress.type, newProps, children);
|
177 |
|
178 | workInProgress.stateNode = _instance;
|
179 | workInProgress.output = _instance;
|
180 | }
|
181 | workInProgress.memoizedProps = newProps;
|
182 | return null;
|
183 | case CoroutineComponent:
|
184 | return moveCoroutineToHandlerPhase(current, workInProgress);
|
185 | case CoroutineHandlerPhase:
|
186 | transferOutput(workInProgress.stateNode, workInProgress);
|
187 |
|
188 | workInProgress.tag = CoroutineComponent;
|
189 | return null;
|
190 | case YieldComponent:
|
191 |
|
192 | return null;
|
193 |
|
194 | case IndeterminateComponent:
|
195 | throw new Error('An indeterminate component should have become determinate before completing.');
|
196 | default:
|
197 | throw new Error('Unknown unit of work tag');
|
198 | }
|
199 | }
|
200 |
|
201 | return {
|
202 | completeWork: completeWork
|
203 | };
|
204 | }; |
\ | No newline at end of file |