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