@samitouri / QOS-React / commits / 2fa38ac1cc

Delete ReactNativeStack 🎉 🎉 🎉 (#10511)

* Removed createReactNativeComponentClassStack and renamed createReactNativeComponentClassFiber => createReactNativeComponentClass * Removed findNumericNodeHandleStack and renamed findNumericNodeHandleFiber => findNumericNodeHandle * Renamed ReactNativeFiberEntry => ReactNativeEntry * Removed all references to ReactNativeFeatureFlags and RN stack * Removed severl RN modules that are no longer used * Renamed ReactNativeEntry => ReactNativeFiberEntry for now. We'll probably remove 'fiber' references later * Update build results json * Deleted snapshot * Re-add accidentally deleted test * Remove now-unnecessary hack in test * Fix lint * RN findNodeHandle no longer adds props directly to read-only owner (#10520) * Added ReactNativeMount-test snapshot for 'renders and reorders children' test

Brian Vaughn committed Aug 23, 2017 at 15:53 UTC 2fa38ac1cce658ce799a162e65fcf782187c8802
33 files changed +145 -3583
scripts/jest/fiber.setup.js
-6
@@ -14,12 +14,6 @@ jest.mock('ReactFeatureFlags', () => {
14 disableNewFiberFeatures: true,
15 });
16 });
17 -jest.mock('ReactNativeFeatureFlags', () => {
18 - const flags = require.requireActual('ReactNativeFeatureFlags');
19 - return Object.assign({}, flags, {
20 - useFiber: true,
21 - });
22 -});
17
18 // Error logging varies between Fiber and Stack;
19 // Rather than fork dozens of tests, mock the error-logging file by default.
scripts/jest/stack.setup.js
-6
@@ -8,12 +8,6 @@ jest.mock('ReactDOMFeatureFlags', () => {
8 useFiber: false,
9 });
10 });
11 -jest.mock('ReactNativeFeatureFlags', () => {
12 - const flags = require.requireActual('ReactNativeFeatureFlags');
13 - return Object.assign({}, flags, {
14 - useFiber: false,
15 - });
16 -});
11
12 // Error logging varies between Fiber and Stack;
13 // Rather than fork dozens of tests, mock the error-logging file by default.
scripts/rollup/bundles.js
-48
@@ -251,48 +251,6 @@ const bundles = [
251 },
252
253 /******* React Native *******/
254 - {
255 - babelOpts: babelOptsReact,
256 - bundleTypes: [RN_DEV, RN_PROD],
257 - config: {
258 - destDir: 'build/',
259 - moduleName: 'ReactNativeStack',
260 - sourceMap: false,
261 - },
262 - entry: 'src/renderers/native/ReactNativeStackEntry',
263 - externals: [
264 - 'ExceptionsManager',
265 - 'InitializeCore',
266 - 'ReactNativeFeatureFlags',
267 - 'RCTEventEmitter',
268 - 'TextInputState',
269 - 'UIManager',
270 - 'View',
271 - 'deepDiffer',
272 - 'deepFreezeAndThrowOnMutationInDev',
273 - 'flattenStyle',
274 - 'prop-types/checkPropTypes',
275 - ],
276 - hasteName: 'ReactNativeStack',
277 - isRenderer: true,
278 - label: 'native-stack',
279 - manglePropertiesOnProd: false,
280 - name: 'react-native-renderer',
281 - paths: [
282 - 'src/renderers/native/**/*.js',
283 - 'src/renderers/shared/**/*.js',
284 -
285 - 'src/ReactVersion.js',
286 - 'src/shared/**/*.js',
287 - ],
288 - useFiber: false,
289 - modulesToStub: [
290 - 'createReactNativeComponentClassFiber',
291 - 'ReactNativeFiberRenderer',
292 - 'findNumericNodeHandleFiber',
293 - 'ReactNativeFiber',
294 - ],
295 - },
254 {
255 babelOpts: babelOptsReact,
256 bundleTypes: [RN_DEV, RN_PROD],
@@ -305,7 +263,6 @@ const bundles = [
263 externals: [
264 'ExceptionsManager',
265 'InitializeCore',
308 - 'ReactNativeFeatureFlags',
266 'RCTEventEmitter',
267 'TextInputState',
268 'UIManager',
@@ -328,11 +285,6 @@ const bundles = [
285 'src/shared/**/*.js',
286 ],
287 useFiber: true,
331 - modulesToStub: [
332 - 'createReactNativeComponentClassStack',
333 - 'findNumericNodeHandleStack',
334 - 'ReactNativeStack',
335 - ],
288 },
289
290 /******* React Test Renderer *******/
scripts/rollup/modules.js
-2
@@ -129,8 +129,6 @@ function ignoreReactNativeModules() {
129 return [
130 // This imports NativeMethodsMixin, causing a circular dependency.
131 'View',
132 - // This file is injected based on a runtime config.
133 - 'ReactNativeFeatureFlags',
132 ];
133 }
134
scripts/rollup/results.json
+10 -18
@@ -57,24 +57,24 @@
57 "gzip": 13357
58 },
59 "react-dom-unstable-native-dependencies.development.js (UMD_DEV)": {
60 - "size": 88285,
61 - "gzip": 22345
60 + "size": 87907,
61 + "gzip": 22195
62 },
63 "react-dom-unstable-native-dependencies.production.min.js (UMD_PROD)": {
64 "size": 15149,
65 "gzip": 4910
66 },
67 "react-dom-unstable-native-dependencies.development.js (NODE_DEV)": {
68 - "size": 81733,
69 - "gzip": 20383
68 + "size": 81355,
69 + "gzip": 20240
70 },
71 "react-dom-unstable-native-dependencies.production.min.js (NODE_PROD)": {
72 "size": 13926,
73 "gzip": 4403
74 },
75 "ReactDOMUnstableNativeDependencies-dev.js (FB_DEV)": {
76 - "size": 81432,
77 - "gzip": 20341
76 + "size": 81054,
77 + "gzip": 20200
78 },
79 "ReactDOMUnstableNativeDependencies-prod.js (FB_PROD)": {
80 "size": 66066,
@@ -136,21 +136,13 @@
136 "size": 220269,
137 "gzip": 45845
138 },
139 - "ReactNativeStack-dev.js (RN_DEV)": {
140 - "size": 201077,
141 - "gzip": 37401
142 - },
143 - "ReactNativeStack-prod.js (RN_PROD)": {
144 - "size": 136715,
145 - "gzip": 26222
146 - },
139 "ReactNativeFiber-dev.js (RN_DEV)": {
148 - "size": 306002,
149 - "gzip": 52993
140 + "size": 303055,
141 + "gzip": 52683
142 },
143 "ReactNativeFiber-prod.js (RN_PROD)": {
152 - "size": 221418,
153 - "gzip": 38321
144 + "size": 218403,
145 + "gzip": 37966
146 },
147 "react-test-renderer.development.js (NODE_DEV)": {
148 "size": 299567,
scripts/rollup/shims/react-native/ReactNative.js
+2 -8
@@ -11,20 +11,14 @@
11 */
12 'use strict';
13
14 -const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15 -
14 import type {ReactNativeType} from 'ReactNativeTypes';
15
16 let ReactNative;
17
18 if (__DEV__) {
21 - ReactNative = ReactNativeFeatureFlags.useFiber
22 - ? require('ReactNativeFiber-dev')
23 - : require('ReactNativeStack-dev');
19 + ReactNative = require('ReactNativeFiber-dev');
20 } else {
25 - ReactNative = ReactNativeFeatureFlags.useFiber
26 - ? require('ReactNativeFiber-prod')
27 - : require('ReactNativeStack-prod');
21 + ReactNative = require('ReactNativeFiber-prod');
22 }
23
24 module.exports = (ReactNative: ReactNativeType);
src/node_modules/react-native/index.js
+1 -6
@@ -6,9 +6,4 @@
6
7 'use strict';
8
9 -var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
10 -var useFiber = ReactNativeFeatureFlags.useFiber;
11 -
12 -module.exports = useFiber
13 - ? require('ReactNativeFiberEntry')
14 - : require('ReactNativeStackEntry');
9 +module.exports = require('ReactNativeFiberEntry');
src/renderers/__tests__/ReactComponentTreeHook-test.native.js deleted
-1999
@@ -1,1999 +0,0 @@
1 -/**
2 - * Copyright 2016-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 - * @emails react-core
10 - */
11 -
12 -'use strict';
13 -
14 -var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15 -var describeStack = ReactNativeFeatureFlags.useFiber ? describe.skip : describe;
16 -
17 -// These tests are only relevant for the Stack version of the tree hook.
18 -// This file is for RN. There is a sibling file that has some tree hook
19 -// tests that are still relevant in Fiber.
20 -// TODO: remove this file when we delete Stack.
21 -
22 -describeStack('ReactComponentTreeHook', () => {
23 - var React;
24 - var ReactNative;
25 - var ReactInstanceMap;
26 - var ReactComponentTreeHook;
27 - var ReactComponentTreeTestUtils;
28 - var createReactNativeComponentClass;
29 - var View;
30 - var Image;
31 - var Text;
32 - var PropTypes;
33 -
34 - beforeEach(() => {
35 - jest.resetModules();
36 -
37 - PropTypes = require('prop-types');
38 - React = require('react');
39 - ReactNative = require('react-native');
40 - ReactInstanceMap = require('ReactInstanceMap');
41 - ReactComponentTreeHook = require('ReactComponentTreeHook');
42 - ReactComponentTreeTestUtils = require('ReactComponentTreeTestUtils');
43 - View = require('View');
44 - createReactNativeComponentClass = require('createReactNativeComponentClass');
45 - Image = createReactNativeComponentClass({
46 - validAttributes: {},
47 - uiViewClassName: 'Image',
48 - });
49 - var RCText = createReactNativeComponentClass({
50 - validAttributes: {},
51 - uiViewClassName: 'RCText',
52 - });
53 - Text = class extends React.Component {
54 - static childContextTypes = {
55 - isInAParentText: PropTypes.bool,
56 - };
57 -
58 - getChildContext() {
59 - return {isInAParentText: true};
60 - }
61 -
62 - render() {
63 - return <RCText {...this.props} />;
64 - }
65 - };
66 - });
67 -
68 - function assertTreeMatches(pairs, options) {
69 - if (!Array.isArray(pairs[0])) {
70 - pairs = [pairs];
71 - }
72 -
73 - var currentElement;
74 - var rootInstance;
75 -
76 - class Wrapper extends React.Component {
77 - render() {
78 - rootInstance = ReactInstanceMap.get(this);
79 - return currentElement;
80 - }
81 - }
82 -
83 - function expectWrapperTreeToEqual(expectedTree, andStayMounted) {
84 - ReactComponentTreeTestUtils.expectTree(rootInstance._debugID, {
85 - displayName: 'Wrapper',
86 - children: expectedTree ? [expectedTree] : [],
87 - });
88 - var rootDisplayNames = ReactComponentTreeTestUtils.getRootDisplayNames();
89 - var registeredDisplayNames = ReactComponentTreeTestUtils.getRegisteredDisplayNames();
90 - if (!expectedTree) {
91 - expectDev(rootDisplayNames).toEqual([]);
92 - expectDev(registeredDisplayNames).toEqual([]);
93 - } else if (andStayMounted) {
94 - expectDev(rootDisplayNames).toContain('Wrapper');
95 - expectDev(registeredDisplayNames).toContain('Wrapper');
96 - }
97 - }
98 -
99 - // Mount once, render updates, then unmount.
100 - // Ensure the tree is correct on every step.
101 - pairs.forEach(([element, expectedTree]) => {
102 - currentElement = element;
103 -
104 - // Mount a new tree or update the existing tree.
105 - ReactNative.render(<Wrapper />, 1);
106 - expectWrapperTreeToEqual(expectedTree, true);
107 -
108 - // Purging should have no effect
109 - // on the tree we expect to see.
110 - ReactComponentTreeHook.purgeUnmountedComponents();
111 - expectWrapperTreeToEqual(expectedTree, true);
112 - });
113 -
114 - // Unmounting the root node should purge
115 - // the whole subtree automatically.
116 - ReactNative.unmountComponentAtNode(1);
117 - expectWrapperTreeToEqual(null);
118 -
119 - // Mount and unmount for every pair.
120 - // Ensure the tree is correct on every step.
121 - pairs.forEach(([element, expectedTree]) => {
122 - currentElement = element;
123 -
124 - // Mount a new tree.
125 - ReactNative.render(<Wrapper />, 1);
126 - expectWrapperTreeToEqual(expectedTree);
127 -
128 - // Unmounting should clean it up.
129 - ReactNative.unmountComponentAtNode(1);
130 - expectWrapperTreeToEqual(null);
131 - });
132 - }
133 -
134 - describe('mount', () => {
135 - it('uses displayName or Unknown for classic components', () => {
136 - class Foo extends React.Component {
137 - render() {
138 - return null;
139 - }
140 - }
141 -
142 - Foo.displayName = 'Bar';
143 -
144 - class Baz extends React.Component {
145 - render() {
146 - return null;
147 - }
148 - }
149 -
150 - class Qux extends React.Component {
151 - render() {
152 - return null;
153 - }
154 - }
155 -
156 - delete Qux.displayName;
157 -
158 - var element = <View><Foo /><Baz /><Qux /></View>;
159 - var tree = {
160 - displayName: 'View',
161 - element,
162 - children: [
163 - {
164 - displayName: 'Bar',
165 - children: [],
166 - },
167 - {
168 - displayName: 'Baz',
169 - children: [],
170 - },
171 - {
172 - displayName: 'Unknown',
173 - children: [],
174 - },
175 - ],
176 - };
177 - assertTreeMatches([element, tree]);
178 - });
179 -
180 - it('uses displayName, name, or ReactComponent for modern components', () => {
181 - class Foo extends React.Component {
182 - render() {
183 - return null;
184 - }
185 - }
186 - Foo.displayName = 'Bar';
187 - class Baz extends React.Component {
188 - render() {
189 - return null;
190 - }
191 - }
192 - class Qux extends React.Component {
193 - render() {
194 - return null;
195 - }
196 - }
197 - delete Qux.name;
198 -
199 - var element = <View><Foo /><Baz /><Qux /></View>;
200 - var tree = {
201 - displayName: 'View',
202 - children: [
203 - {
204 - displayName: 'Bar',
205 - children: [],
206 - },
207 - {
208 - displayName: 'Baz',
209 - children: [],
210 - },
211 - {
212 - // Note: Ideally fallback name should be consistent (e.g. "Unknown")
213 - displayName: 'ReactComponent',
214 - children: [],
215 - },
216 - ],
217 - };
218 - assertTreeMatches([element, tree]);
219 - });
220 -
221 - it('uses displayName, name, or Object for factory components', () => {
222 - function Foo() {
223 - return {
224 - render() {
225 - return null;
226 - },
227 - };
228 - }
229 - Foo.displayName = 'Bar';
230 - function Baz() {
231 - return {
232 - render() {
233 - return null;
234 - },
235 - };
236 - }
237 - function Qux() {
238 - return {
239 - render() {
240 - return null;
241 - },
242 - };
243 - }
244 - delete Qux.name;
245 -
246 - var element = <View><Foo /><Baz /><Qux /></View>;
247 - var tree = {
248 - displayName: 'View',
249 - children: [
250 - {
251 - displayName: 'Bar',
252 - children: [],
253 - },
254 - {
255 - displayName: 'Baz',
256 - children: [],
257 - },
258 - {
259 - displayName: 'Unknown',
260 - children: [],
261 - },
262 - ],
263 - };
264 - assertTreeMatches([element, tree]);
265 - });
266 -
267 - it('uses displayName, name, or StatelessComponent for functional components', () => {
268 - function Foo() {
269 - return null;
270 - }
271 - Foo.displayName = 'Bar';
272 - function Baz() {
273 - return null;
274 - }
275 - function Qux() {
276 - return null;
277 - }
278 - delete Qux.name;
279 -
280 - var element = <View><Foo /><Baz /><Qux /></View>;
281 - var tree = {
282 - displayName: 'View',
283 - children: [
284 - {
285 - displayName: 'Bar',
286 - children: [],
287 - },
288 - {
289 - displayName: 'Baz',
290 - children: [],
291 - },
292 - {
293 - displayName: 'Unknown',
294 - children: [],
295 - },
296 - ],
297 - };
298 - assertTreeMatches([element, tree]);
299 - });
300 -
301 - it('reports a host tree correctly', () => {
302 - var element = (
303 - <View>
304 - <View>
305 - <Text>
306 - Hi!
307 - </Text>
308 - </View>
309 - <Image />
310 - </View>
311 - );
312 - var tree = {
313 - displayName: 'View',
314 - element,
315 - children: [
316 - {
317 - displayName: 'View',
318 - children: [
319 - {
320 - displayName: 'Text',
321 - children: [
322 - {
323 - displayName: 'RCText',
324 - children: [
325 - {
326 - displayName: '#text',
327 - element: 'Hi!',
328 - text: 'Hi!',
329 - },
330 - ],
331 - },
332 - ],
333 - },
334 - ],
335 - },
336 - {
337 - displayName: 'Image',
338 - element: <Image />,
339 - children: [],
340 - },
341 - ],
342 - };
343 - assertTreeMatches([element, tree]);
344 - });
345 -
346 - it('reports a simple tree with composites correctly', () => {
347 - class Foo extends React.Component {
348 - render() {
349 - return <Image />;
350 - }
351 - }
352 -
353 - var element = <Foo />;
354 - var tree = {
355 - displayName: 'Foo',
356 - element,
357 - children: [
358 - {
359 - displayName: 'Image',
360 - element: <Image />,
361 - children: [],
362 - },
363 - ],
364 - };
365 - assertTreeMatches([element, tree]);
366 - });
367 -
368 - it('reports a tree with composites correctly', () => {
369 - class Qux extends React.Component {
370 - render() {
371 - return null;
372 - }
373 - }
374 -
375 - function Foo() {
376 - return {
377 - render() {
378 - return <Qux />;
379 - },
380 - };
381 - }
382 - function Bar({children}) {
383 - return <View>{children}</View>;
384 - }
385 - class Baz extends React.Component {
386 - render() {
387 - return (
388 - <View>
389 - <Foo />
390 - <Bar>
391 - <Text>Hi,</Text>
392 - </Bar>
393 - <Image />
394 - </View>
395 - );
396 - }
397 - }
398 -
399 - var element = <Baz />;
400 - var tree = {
401 - displayName: 'Baz',
402 - element,
403 - children: [
404 - {
405 - displayName: 'View',
406 - children: [
407 - {
408 - displayName: 'Foo',
409 - element: <Foo />,
410 - children: [
411 - {
412 - displayName: 'Qux',
413 - element: <Qux />,
414 - children: [],
415 - },
416 - ],
417 - },
418 - {
419 - displayName: 'Bar',
420 - children: [
421 - {
422 - displayName: 'View',
423 - children: [
424 - {
425 - displayName: 'Text',
426 - children: [
427 - {
428 - displayName: 'RCText',
429 - children: [
430 - {
431 - displayName: '#text',
432 - element: 'Hi,',
433 - text: 'Hi,',
434 - },
435 - ],
436 - },
437 - ],
438 - },
439 - ],
440 - },
441 - ],
442 - },
443 - {
444 - displayName: 'Image',
445 - element: <Image />,
446 - children: [],
447 - },
448 - ],
449 - },
450 - ],
451 - };
452 - assertTreeMatches([element, tree]);
453 - });
454 -
455 - it('ignores null children', () => {
456 - class Foo extends React.Component {
457 - render() {
458 - return null;
459 - }
460 - }
461 - var element = <Foo />;
462 - var tree = {
463 - displayName: 'Foo',
464 - children: [],
465 - };
466 - assertTreeMatches([element, tree]);
467 - });
468 -
469 - it('ignores false children', () => {
470 - class Foo extends React.Component {
471 - render() {
472 - return false;
473 - }
474 - }
475 - var element = <Foo />;
476 - var tree = {
477 - displayName: 'Foo',
478 - children: [],
479 - };
480 - assertTreeMatches([element, tree]);
481 - });
482 -
483 - it('reports text nodes as children', () => {
484 - var element = <Text>{'1'}{2}</Text>;
485 - var tree = {
486 - displayName: 'Text',
487 - children: [
488 - {
489 - displayName: 'RCText',
490 - children: [
491 - {
492 - displayName: '#text',
493 - text: '1',
494 - },
495 - {
496 - displayName: '#text',
497 - text: '2',
498 - },
499 - ],
500 - },
501 - ],
502 - };
503 - assertTreeMatches([element, tree]);
504 - });
505 -
506 - it('reports a single text node as a child', () => {
507 - var element = <Text>{'1'}</Text>;
508 - var tree = {
509 - displayName: 'Text',
510 - children: [
511 - {
512 - displayName: 'RCText',
513 - children: [
514 - {
515 - displayName: '#text',
516 - text: '1',
517 - },
518 - ],
519 - },
520 - ],
521 - };
522 - assertTreeMatches([element, tree]);
523 - });
524 -
525 - it('reports a single number node as a child', () => {
526 - var element = <Text>{42}</Text>;
527 - var tree = {
528 - displayName: 'Text',
529 - children: [
530 - {
531 - displayName: 'RCText',
532 - children: [
533 - {
534 - displayName: '#text',
535 - text: '42',
536 - },
537 - ],
538 - },
539 - ],
540 - };
541 - assertTreeMatches([element, tree]);
542 - });
543 -
544 - it('reports a zero as a child', () => {
545 - var element = <Text>{0}</Text>;
546 - var tree = {
547 - displayName: 'Text',
548 - children: [
549 - {
550 - displayName: 'RCText',
551 - children: [
552 - {
553 - displayName: '#text',
554 - text: '0',
555 - },
556 - ],
557 - },
558 - ],
559 - };
560 - assertTreeMatches([element, tree]);
561 - });
562 -
563 - it('skips empty nodes for multiple children', () => {
564 - function Foo() {
565 - return <Image />;
566 - }
567 - var element = (
568 - <View>
569 - {false}
570 - <Foo />
571 - {null}
572 - <Foo />
573 - </View>
574 - );
575 - var tree = {
576 - displayName: 'View',
577 - element,
578 - children: [
579 - {
580 - displayName: 'Foo',
581 - element: <Foo />,
582 - children: [
583 - {
584 - displayName: 'Image',
585 - element: <Image />,
586 - children: [],
587 - },
588 - ],
589 - },
590 - {
591 - displayName: 'Foo',
592 - element: <Foo />,
593 - children: [
594 - {
595 - displayName: 'Image',
596 - element: <Image />,
597 - children: [],
598 - },
599 - ],
600 - },
601 - ],
602 - };
603 - assertTreeMatches([element, tree]);
604 - });
605 - });
606 -
607 - describe('update', () => {
608 - describe('host component', () => {
609 - it('updates text of a single text child', () => {
610 - var elementBefore = <Text>Hi.</Text>;
611 - var treeBefore = {
612 - displayName: 'Text',
613 - children: [
614 - {
615 - displayName: 'RCText',
616 - children: [
617 - {
618 - displayName: '#text',
619 - text: 'Hi.',
620 - },
621 - ],
622 - },
623 - ],
624 - };
625 -
626 - var elementAfter = <Text>Bye.</Text>;
627 - var treeAfter = {
628 - displayName: 'Text',
629 - children: [
630 - {
631 - displayName: 'RCText',
632 - children: [
633 - {
634 - displayName: '#text',
635 - text: 'Bye.',
636 - },
637 - ],
638 - },
639 - ],
640 - };
641 -
642 - assertTreeMatches([
643 - [elementBefore, treeBefore],
644 - [elementAfter, treeAfter],
645 - ]);
646 - });
647 -
648 - it('updates from no children to a single text child', () => {
649 - var elementBefore = <Text />;
650 - var treeBefore = {
651 - displayName: 'Text',
652 - children: [
653 - {
654 - displayName: 'RCText',
655 - children: [],
656 - },
657 - ],
658 - };
659 -
660 - var elementAfter = <Text>Hi.</Text>;
661 - var treeAfter = {
662 - displayName: 'Text',
663 - children: [
664 - {
665 - displayName: 'RCText',
666 - children: [
667 - {
668 - displayName: '#text',
669 - text: 'Hi.',
670 - },
671 - ],
672 - },
673 - ],
674 - };
675 -
676 - assertTreeMatches([
677 - [elementBefore, treeBefore],
678 - [elementAfter, treeAfter],
679 - ]);
680 - });
681 -
682 - it('updates from a single text child to no children', () => {
683 - var elementBefore = <Text>Hi.</Text>;
684 - var treeBefore = {
685 - displayName: 'Text',
686 - children: [
687 - {
688 - displayName: 'RCText',
689 - children: [
690 - {
691 - displayName: '#text',
692 - text: 'Hi.',
693 - },
694 - ],
695 - },
696 - ],
697 - };
698 -
699 - var elementAfter = <Text />;
700 - var treeAfter = {
701 - displayName: 'Text',
702 - children: [
703 - {
704 - displayName: 'RCText',
705 - children: [],
706 - },
707 - ],
708 - };
709 -
710 - assertTreeMatches([
711 - [elementBefore, treeBefore],
712 - [elementAfter, treeAfter],
713 - ]);
714 - });
715 -
716 - it('updates from no children to multiple text children', () => {
717 - var elementBefore = <Text />;
718 - var treeBefore = {
719 - displayName: 'Text',
720 - children: [
721 - {
722 - displayName: 'RCText',
723 - children: [],
724 - },
725 - ],
726 - };
727 -
728 - var elementAfter = <Text>{'Hi.'}{'Bye.'}</Text>;
729 - var treeAfter = {
730 - displayName: 'Text',
731 - children: [
732 - {
733 - displayName: 'RCText',
734 - children: [
735 - {
736 - displayName: '#text',
737 - text: 'Hi.',
738 - },
739 - {
740 - displayName: '#text',
741 - text: 'Bye.',
742 - },
743 - ],
744 - },
745 - ],
746 - };
747 -
748 - assertTreeMatches([
749 - [elementBefore, treeBefore],
750 - [elementAfter, treeAfter],
751 - ]);
752 - });
753 -
754 - it('updates from multiple text children to no children', () => {
755 - var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
756 - var treeBefore = {
757 - displayName: 'Text',
758 - children: [
759 - {
760 - displayName: 'RCText',
761 - children: [
762 - {
763 - displayName: '#text',
764 - text: 'Hi.',
765 - },
766 - {
767 - displayName: '#text',
768 - text: 'Bye.',
769 - },
770 - ],
771 - },
772 - ],
773 - };
774 -
775 - var elementAfter = <Text />;
776 - var treeAfter = {
777 - displayName: 'Text',
778 - children: [
779 - {
780 - displayName: 'RCText',
781 - children: [],
782 - },
783 - ],
784 - };
785 - assertTreeMatches([
786 - [elementBefore, treeBefore],
787 - [elementAfter, treeAfter],
788 - ]);
789 - });
790 -
791 - it('updates from one text child to multiple text children', () => {
792 - var elementBefore = <Text>Hi.</Text>;
793 - var treeBefore = {
794 - displayName: 'Text',
795 - children: [
796 - {
797 - displayName: 'RCText',
798 - children: [
799 - {
800 - displayName: '#text',
801 - text: 'Hi.',
802 - },
803 - ],
804 - },
805 - ],
806 - };
807 -
808 - var elementAfter = <Text>{'Hi.'}{'Bye.'}</Text>;
809 - var treeAfter = {
810 - displayName: 'Text',
811 - children: [
812 - {
813 - displayName: 'RCText',
814 - children: [
815 - {
816 - displayName: '#text',
817 - text: 'Hi.',
818 - },
819 - {
820 - displayName: '#text',
821 - text: 'Bye.',
822 - },
823 - ],
824 - },
825 - ],
826 - };
827 -
828 - assertTreeMatches([
829 - [elementBefore, treeBefore],
830 - [elementAfter, treeAfter],
831 - ]);
832 - });
833 -
834 - it('updates from multiple text children to one text child', () => {
835 - var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
836 - var treeBefore = {
837 - displayName: 'Text',
838 - children: [
839 - {
840 - displayName: 'RCText',
841 - children: [
842 - {
843 - displayName: '#text',
844 - text: 'Hi.',
845 - },
846 - {
847 - displayName: '#text',
848 - text: 'Bye.',
849 - },
850 - ],
851 - },
852 - ],
853 - };
854 -
855 - var elementAfter = <Text>Hi.</Text>;
856 - var treeAfter = {
857 - displayName: 'Text',
858 - children: [
859 - {
860 - displayName: 'RCText',
861 - children: [
862 - {
863 - displayName: '#text',
864 - text: 'Hi.',
865 - },
866 - ],
867 - },
868 - ],
869 - };
870 - assertTreeMatches([
871 - [elementBefore, treeBefore],
872 - [elementAfter, treeAfter],
873 - ]);
874 - });
875 -
876 - it('updates text nodes when reordering', () => {
877 - var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
878 - var treeBefore = {
879 - displayName: 'Text',
880 - children: [
881 - {
882 - displayName: 'RCText',
883 - children: [
884 - {
885 - displayName: '#text',
886 - text: 'Hi.',
887 - },
888 - {
889 - displayName: '#text',
890 - text: 'Bye.',
891 - },
892 - ],
893 - },
894 - ],
895 - };
896 -
897 - var elementAfter = <Text>{'Bye.'}{'Hi.'}</Text>;
898 - var treeAfter = {
899 - displayName: 'Text',
900 - children: [
901 - {
902 - displayName: 'RCText',
903 - children: [
904 - {
905 - displayName: '#text',
906 - text: 'Bye.',
907 - },
908 - {
909 - displayName: '#text',
910 - text: 'Hi.',
911 - },
912 - ],
913 - },
914 - ],
915 - };
916 - assertTreeMatches([
917 - [elementBefore, treeBefore],
918 - [elementAfter, treeAfter],
919 - ]);
920 - });
921 -
922 - it('updates host nodes when reordering with keys', () => {
923 - var elementBefore = (
924 - <View>
925 - <Text key="a">Hi.</Text>
926 - <Text key="b">Bye.</Text>
927 - </View>
928 - );
929 - var treeBefore = {
930 - displayName: 'View',
931 - children: [
932 - {
933 - displayName: 'Text',
934 - children: [
935 - {
936 - displayName: 'RCText',
937 - children: [
938 - {
939 - displayName: '#text',
940 - text: 'Hi.',
941 - },
942 - ],
943 - },
944 - ],
945 - },
946 - {
947 - displayName: 'Text',
948 - children: [
949 - {
950 - displayName: 'RCText',
951 - children: [
952 - {
953 - displayName: '#text',
954 - text: 'Bye.',
955 - },
956 - ],
957 - },
958 - ],
959 - },
960 - ],
961 - };
962 -
963 - var elementAfter = (
964 - <View>
965 - <Text key="b">Bye.</Text>
966 - <Text key="a">Hi.</Text>
967 - </View>
968 - );
969 - var treeAfter = {
970 - displayName: 'View',
971 - children: [
972 - {
973 - displayName: 'Text',
974 - children: [
975 - {
976 - displayName: 'RCText',
977 - children: [
978 - {
979 - displayName: '#text',
980 - text: 'Bye.',
981 - },
982 - ],
983 - },
984 - ],
985 - },
986 - {
987 - displayName: 'Text',
988 - children: [
989 - {
990 - displayName: 'RCText',
991 - children: [
992 - {
993 - displayName: '#text',
994 - text: 'Hi.',
995 - },
996 - ],
997 - },
998 - ],
999 - },
1000 - ],
1001 - };
1002 -
1003 - assertTreeMatches([
1004 - [elementBefore, treeBefore],
1005 - [elementAfter, treeAfter],
1006 - ]);
1007 - });
1008 -
1009 - it('updates host nodes when reordering with keys', () => {
1010 - var elementBefore = (
1011 - <View>
1012 - <Text>Hi.</Text>
1013 - <Text>Bye.</Text>
1014 - </View>
1015 - );
1016 - var treeBefore = {
1017 - displayName: 'View',
1018 - children: [
1019 - {
1020 - displayName: 'Text',
1021 - children: [
1022 - {
1023 - displayName: 'RCText',
1024 - children: [
1025 - {
1026 - displayName: '#text',
1027 - text: 'Hi.',
1028 - },
1029 - ],
1030 - },
1031 - ],
1032 - },
1033 - {
1034 - displayName: 'Text',
1035 - children: [
1036 - {
1037 - displayName: 'RCText',
1038 - children: [
1039 - {
1040 - displayName: '#text',
1041 - text: 'Bye.',
1042 - },
1043 - ],
1044 - },
1045 - ],
1046 - },
1047 - ],
1048 - };
1049 -
1050 - var elementAfter = (
1051 - <View>
1052 - <Text>Bye.</Text>
1053 - <Text>Hi.</Text>
1054 - </View>
1055 - );
1056 - var treeAfter = {
1057 - displayName: 'View',
1058 - children: [
1059 - {
1060 - displayName: 'Text',
1061 - children: [
1062 - {
1063 - displayName: 'RCText',
1064 - children: [
1065 - {
1066 - displayName: '#text',
1067 - text: 'Bye.',
1068 - },
1069 - ],
1070 - },
1071 - ],
1072 - },
1073 - {
1074 - displayName: 'Text',
1075 - children: [
1076 - {
1077 - displayName: 'RCText',
1078 - children: [
1079 - {
1080 - displayName: '#text',
1081 - text: 'Hi.',
1082 - },
1083 - ],
1084 - },
1085 - ],
1086 - },
1087 - ],
1088 - };
1089 -
1090 - assertTreeMatches([
1091 - [elementBefore, treeBefore],
1092 - [elementAfter, treeAfter],
1093 - ]);
1094 - });
1095 -
1096 - it('updates a single composite child of a different type', () => {
1097 - function Foo() {
1098 - return null;
1099 - }
1100 -
1101 - function Bar() {
1102 - return null;
1103 - }
1104 -
1105 - var elementBefore = <View><Foo /></View>;
1106 - var treeBefore = {
1107 - displayName: 'View',
1108 - children: [
1109 - {
1110 - displayName: 'Foo',
1111 - children: [],
1112 - },
1113 - ],
1114 - };
1115 -
1116 - var elementAfter = <View><Bar /></View>;
1117 - var treeAfter = {
1118 - displayName: 'View',
1119 - children: [
1120 - {
1121 - displayName: 'Bar',
1122 - children: [],
1123 - },
1124 - ],
1125 - };
1126 -
1127 - assertTreeMatches([
1128 - [elementBefore, treeBefore],
1129 - [elementAfter, treeAfter],
1130 - ]);
1131 - });
1132 -
1133 - it('updates a single composite child of the same type', () => {
1134 - function Foo({children}) {
1135 - return children;
1136 - }
1137 -
1138 - var elementBefore = <View><Foo><View /></Foo></View>;
1139 - var treeBefore = {
1140 - displayName: 'View',
1141 - children: [
1142 - {
1143 - displayName: 'Foo',
1144 - children: [
1145 - {
1146 - displayName: 'View',
1147 - children: [],
1148 - },
1149 - ],
1150 - },
1151 - ],
1152 - };
1153 -
1154 - var elementAfter = <View><Foo><Image /></Foo></View>;
1155 - var treeAfter = {
1156 - displayName: 'View',
1157 - children: [
1158 - {
1159 - displayName: 'Foo',
1160 - children: [
1161 - {
1162 - displayName: 'Image',
1163 - children: [],
1164 - },
1165 - ],
1166 - },
1167 - ],
1168 - };
1169 -
1170 - assertTreeMatches([
1171 - [elementBefore, treeBefore],
1172 - [elementAfter, treeAfter],
1173 - ]);
1174 - });
1175 -
1176 - it('updates from no children to a single composite child', () => {
1177 - function Foo() {
1178 - return null;
1179 - }
1180 -
1181 - var elementBefore = <View />;
1182 - var treeBefore = {
1183 - displayName: 'View',
1184 - children: [],
1185 - };
1186 -
1187 - var elementAfter = <View><Foo /></View>;
1188 - var treeAfter = {
1189 - displayName: 'View',
1190 - children: [
1191 - {
1192 - displayName: 'Foo',
1193 - children: [],
1194 - },
1195 - ],
1196 - };
1197 -
1198 - assertTreeMatches([
1199 - [elementBefore, treeBefore],
1200 - [elementAfter, treeAfter],
1201 - ]);
1202 - });
1203 -
1204 - it('updates from a single composite child to no children', () => {
1205 - function Foo() {
1206 - return null;
1207 - }
1208 -
1209 - var elementBefore = <View><Foo /></View>;
1210 - var treeBefore = {
1211 - displayName: 'View',
1212 - children: [
1213 - {
1214 - displayName: 'Foo',
1215 - children: [],
1216 - },
1217 - ],
1218 - };
1219 -
1220 - var elementAfter = <View />;
1221 - var treeAfter = {
1222 - displayName: 'View',
1223 - children: [],
1224 - };
1225 -
1226 - assertTreeMatches([
1227 - [elementBefore, treeBefore],
1228 - [elementAfter, treeAfter],
1229 - ]);
1230 - });
1231 -
1232 - it('updates mixed children', () => {
1233 - function Foo() {
1234 - return <View />;
1235 - }
1236 - var element1 = (
1237 - <View>
1238 - <Text>hi</Text>
1239 - {false}
1240 - <Text>{42}</Text>
1241 - {null}
1242 - <Foo />
1243 - </View>
1244 - );
1245 - var tree1 = {
1246 - displayName: 'View',
1247 - children: [
1248 - {
1249 - displayName: 'Text',
1250 - children: [
1251 - {
1252 - displayName: 'RCText',
1253 - children: [
1254 - {
1255 - displayName: '#text',
1256 - text: 'hi',
1257 - },
1258 - ],
1259 - },
1260 - ],
1261 - },
1262 - {
1263 - displayName: 'Text',
1264 - children: [
1265 - {
1266 - displayName: 'RCText',
1267 - children: [
1268 - {
1269 - displayName: '#text',
1270 - text: '42',
1271 - },
1272 - ],
1273 - },
1274 - ],
1275 - },
1276 - {
1277 - displayName: 'Foo',
1278 - children: [
1279 - {
1280 - displayName: 'View',
1281 - children: [],
1282 - },
1283 - ],
1284 - },
1285 - ],
1286 - };
1287 -
1288 - var element2 = (
1289 - <View>
1290 - <Foo />
1291 - {false}
1292 - <Text>hi</Text>
1293 - {null}
1294 - </View>
1295 - );
1296 - var tree2 = {
1297 - displayName: 'View',
1298 - children: [
1299 - {
1300 - displayName: 'Foo',
1301 - children: [
1302 - {
1303 - displayName: 'View',
1304 - children: [],
1305 - },
1306 - ],
1307 - },
1308 - {
1309 - displayName: 'Text',
1310 - children: [
1311 - {
1312 - displayName: 'RCText',
1313 - children: [
1314 - {
1315 - displayName: '#text',
1316 - text: 'hi',
1317 - },
1318 - ],
1319 - },
1320 - ],
1321 - },
1322 - ],
1323 - };
1324 -
1325 - var element3 = (
1326 - <View>
1327 - <Foo />
1328 - </View>
1329 - );
1330 - var tree3 = {
1331 - displayName: 'View',
1332 - children: [
1333 - {
1334 - displayName: 'Foo',
1335 - children: [
1336 - {
1337 - displayName: 'View',
1338 - children: [],
1339 - },
1340 - ],
1341 - },
1342 - ],
1343 - };
1344 -
1345 - assertTreeMatches([
1346 - [element1, tree1],
1347 - [element2, tree2],
1348 - [element3, tree3],
1349 - ]);
1350 - });
1351 - });
1352 -
1353 - describe('functional component', () => {
1354 - it('updates with a host child', () => {
1355 - function Foo({children}) {
1356 - return children;
1357 - }
1358 -
1359 - var elementBefore = <Foo><View /></Foo>;
1360 - var treeBefore = {
1361 - displayName: 'Foo',
1362 - children: [
1363 - {
1364 - displayName: 'View',
1365 - children: [],
1366 - },
1367 - ],
1368 - };
1369 -
1370 - var elementAfter = <Foo><Image /></Foo>;
1371 - var treeAfter = {
1372 - displayName: 'Foo',
1373 - children: [
1374 - {
1375 - displayName: 'Image',
1376 - children: [],
1377 - },
1378 - ],
1379 - };
1380 -
1381 - assertTreeMatches([
1382 - [elementBefore, treeBefore],
1383 - [elementAfter, treeAfter],
1384 - ]);
1385 - });
1386 -
1387 - it('updates from null to a host child', () => {
1388 - function Foo({children}) {
1389 - return children;
1390 - }
1391 -
1392 - var elementBefore = <Foo>{null}</Foo>;
1393 - var treeBefore = {
1394 - displayName: 'Foo',
1395 - children: [],
1396 - };
1397 -
1398 - var elementAfter = <Foo><View /></Foo>;
1399 - var treeAfter = {
1400 - displayName: 'Foo',
1401 - children: [
1402 - {
1403 - displayName: 'View',
1404 - children: [],
1405 - },
1406 - ],
1407 - };
1408 -
1409 - assertTreeMatches([
1410 - [elementBefore, treeBefore],
1411 - [elementAfter, treeAfter],
1412 - ]);
1413 - });
1414 -
1415 - it('updates from a host child to null', () => {
1416 - function Foo({children}) {
1417 - return children;
1418 - }
1419 -
1420 - var elementBefore = <Foo><View /></Foo>;
1421 - var treeBefore = {
1422 - displayName: 'Foo',
1423 - children: [
1424 - {
1425 - displayName: 'View',
1426 - children: [],
1427 - },
1428 - ],
1429 - };
1430 -
1431 - var elementAfter = <Foo>{null}</Foo>;
1432 - var treeAfter = {
1433 - displayName: 'Foo',
1434 - children: [],
1435 - };
1436 -
1437 - assertTreeMatches([
1438 - [elementBefore, treeBefore],
1439 - [elementAfter, treeAfter],
1440 - ]);
1441 - });
1442 -
1443 - it('updates from a host child to a composite child', () => {
1444 - function Bar() {
1445 - return null;
1446 - }
1447 -
1448 - function Foo({children}) {
1449 - return children;
1450 - }
1451 -
1452 - var elementBefore = <Foo><View /></Foo>;
1453 - var treeBefore = {
1454 - displayName: 'Foo',
1455 - children: [
1456 - {
1457 - displayName: 'View',
1458 - children: [],
1459 - },
1460 - ],
1461 - };
1462 -
1463 - var elementAfter = <Foo><Bar /></Foo>;
1464 - var treeAfter = {
1465 - displayName: 'Foo',
1466 - children: [
1467 - {
1468 - displayName: 'Bar',
1469 - children: [],
1470 - },
1471 - ],
1472 - };
1473 -
1474 - assertTreeMatches([
1475 - [elementBefore, treeBefore],
1476 - [elementAfter, treeAfter],
1477 - ]);
1478 - });
1479 -
1480 - it('updates from a composite child to a host child', () => {
1481 - function Bar() {
1482 - return null;
1483 - }
1484 -
1485 - function Foo({children}) {
1486 - return children;
1487 - }
1488 -
1489 - var elementBefore = <Foo><Bar /></Foo>;
1490 - var treeBefore = {
1491 - displayName: 'Foo',
1492 - children: [
1493 - {
1494 - displayName: 'Bar',
1495 - children: [],
1496 - },
1497 - ],
1498 - };
1499 -
1500 - var elementAfter = <Foo><View /></Foo>;
1501 - var treeAfter = {
1502 - displayName: 'Foo',
1503 - children: [
1504 - {
1505 - displayName: 'View',
1506 - children: [],
1507 - },
1508 - ],
1509 - };
1510 -
1511 - assertTreeMatches([
1512 - [elementBefore, treeBefore],
1513 - [elementAfter, treeAfter],
1514 - ]);
1515 - });
1516 -
1517 - it('updates from null to a composite child', () => {
1518 - function Bar() {
1519 - return null;
1520 - }
1521 -
1522 - function Foo({children}) {
1523 - return children;
1524 - }
1525 -
1526 - var elementBefore = <Foo>{null}</Foo>;
1527 - var treeBefore = {
1528 - displayName: 'Foo',
1529 - children: [],
1530 - };
1531 -
1532 - var elementAfter = <Foo><Bar /></Foo>;
1533 - var treeAfter = {
1534 - displayName: 'Foo',
1535 - children: [
1536 - {
1537 - displayName: 'Bar',
1538 - children: [],
1539 - },
1540 - ],
1541 - };
1542 -
1543 - assertTreeMatches([
1544 - [elementBefore, treeBefore],
1545 - [elementAfter, treeAfter],
1546 - ]);
1547 - });
1548 -
1549 - it('updates from a composite child to null', () => {
1550 - function Bar() {
1551 - return null;
1552 - }
1553 -
1554 - function Foo({children}) {
1555 - return children;
1556 - }
1557 -
1558 - var elementBefore = <Foo><Bar /></Foo>;
1559 - var treeBefore = {
1560 - displayName: 'Foo',
1561 - children: [
1562 - {
1563 - displayName: 'Bar',
1564 - children: [],
1565 - },
1566 - ],
1567 - };
1568 -
1569 - var elementAfter = <Foo>{null}</Foo>;
1570 - var treeAfter = {
1571 - displayName: 'Foo',
1572 - children: [],
1573 - };
1574 -
1575 - assertTreeMatches([
1576 - [elementBefore, treeBefore],
1577 - [elementAfter, treeAfter],
1578 - ]);
1579 - });
1580 - });
1581 -
1582 - describe('class component', () => {
1583 - it('updates with a host child', () => {
1584 - class Foo extends React.Component {
1585 - render() {
1586 - return this.props.children;
1587 - }
1588 - }
1589 -
1590 - var elementBefore = <Foo><View /></Foo>;
1591 - var treeBefore = {
1592 - displayName: 'Foo',
1593 - children: [
1594 - {
1595 - displayName: 'View',
1596 - children: [],
1597 - },
1598 - ],
1599 - };
1600 -
1601 - var elementAfter = <Foo><Image /></Foo>;
1602 - var treeAfter = {
1603 - displayName: 'Foo',
1604 - children: [
1605 - {
1606 - displayName: 'Image',
1607 - children: [],
1608 - },
1609 - ],
1610 - };
1611 -
1612 - assertTreeMatches([
1613 - [elementBefore, treeBefore],
1614 - [elementAfter, treeAfter],
1615 - ]);
1616 - });
1617 -
1618 - it('updates from null to a host child', () => {
1619 - class Foo extends React.Component {
1620 - render() {
1621 - return this.props.children;
1622 - }
1623 - }
1624 -
1625 - var elementBefore = <Foo>{null}</Foo>;
1626 - var treeBefore = {
1627 - displayName: 'Foo',
1628 - children: [],
1629 - };
1630 -
1631 - var elementAfter = <Foo><View /></Foo>;
1632 - var treeAfter = {
1633 - displayName: 'Foo',
1634 - children: [
1635 - {
1636 - displayName: 'View',
1637 - children: [],
1638 - },
1639 - ],
1640 - };
1641 -
1642 - assertTreeMatches([
1643 - [elementBefore, treeBefore],
1644 - [elementAfter, treeAfter],
1645 - ]);
1646 - });
1647 -
1648 - it('updates from a host child to null', () => {
1649 - class Foo extends React.Component {
1650 - render() {
1651 - return this.props.children;
1652 - }
1653 - }
1654 -
1655 - var elementBefore = <Foo><View /></Foo>;
1656 - var treeBefore = {
1657 - displayName: 'Foo',
1658 - children: [
1659 - {
1660 - displayName: 'View',
1661 - children: [],
1662 - },
1663 - ],
1664 - };
1665 -
1666 - var elementAfter = <Foo>{null}</Foo>;
1667 - var treeAfter = {
1668 - displayName: 'Foo',
1669 - children: [],
1670 - };
1671 -
1672 - assertTreeMatches([
1673 - [elementBefore, treeBefore],
1674 - [elementAfter, treeAfter],
1675 - ]);
1676 - });
1677 -
1678 - it('updates from a host child to a composite child', () => {
1679 - class Bar extends React.Component {
1680 - render() {
1681 - return null;
1682 - }
1683 - }
1684 -
1685 - class Foo extends React.Component {
1686 - render() {
1687 - return this.props.children;
1688 - }
1689 - }
1690 -
1691 - var elementBefore = <Foo><View /></Foo>;
1692 - var treeBefore = {
1693 - displayName: 'Foo',
1694 - children: [
1695 - {
1696 - displayName: 'View',
1697 - children: [],
1698 - },
1699 - ],
1700 - };
1701 -
1702 - var elementAfter = <Foo><Bar /></Foo>;
1703 - var treeAfter = {
1704 - displayName: 'Foo',
1705 - children: [
1706 - {
1707 - displayName: 'Bar',
1708 - children: [],
1709 - },
1710 - ],
1711 - };
1712 -
1713 - assertTreeMatches([
1714 - [elementBefore, treeBefore],
1715 - [elementAfter, treeAfter],
1716 - ]);
1717 - });
1718 -
1719 - it('updates from a composite child to a host child', () => {
1720 - class Bar extends React.Component {
1721 - render() {
1722 - return null;
1723 - }
1724 - }
1725 -
1726 - class Foo extends React.Component {
1727 - render() {
1728 - return this.props.children;
1729 - }
1730 - }
1731 -
1732 - var elementBefore = <Foo><Bar /></Foo>;
1733 - var treeBefore = {
1734 - displayName: 'Foo',
1735 - children: [
1736 - {
1737 - displayName: 'Bar',
1738 - children: [],
1739 - },
1740 - ],
1741 - };
1742 -
1743 - var elementAfter = <Foo><View /></Foo>;
1744 - var treeAfter = {
1745 - displayName: 'Foo',
1746 - children: [
1747 - {
1748 - displayName: 'View',
1749 - children: [],
1750 - },
1751 - ],
1752 - };
1753 -
1754 - assertTreeMatches([
1755 - [elementBefore, treeBefore],
1756 - [elementAfter, treeAfter],
1757 - ]);
1758 - });
1759 -
1760 - it('updates from null to a composite child', () => {
1761 - class Bar extends React.Component {
1762 - render() {
1763 - return null;
1764 - }
1765 - }
1766 -
1767 - class Foo extends React.Component {
1768 - render() {
1769 - return this.props.children;
1770 - }
1771 - }
1772 -
1773 - var elementBefore = <Foo>{null}</Foo>;
1774 - var treeBefore = {
1775 - displayName: 'Foo',
1776 - children: [],
1777 - };
1778 -
1779 - var elementAfter = <Foo><Bar /></Foo>;
1780 - var treeAfter = {
1781 - displayName: 'Foo',
1782 - children: [
1783 - {
1784 - displayName: 'Bar',
1785 - children: [],
1786 - },
1787 - ],
1788 - };
1789 -
1790 - assertTreeMatches([
1791 - [elementBefore, treeBefore],
1792 - [elementAfter, treeAfter],
1793 - ]);
1794 - });
1795 -
1796 - it('updates from a composite child to null', () => {
1797 - class Bar extends React.Component {
1798 - render() {
1799 - return null;
1800 - }
1801 - }
1802 -
1803 - class Foo extends React.Component {
1804 - render() {
1805 - return this.props.children;
1806 - }
1807 - }
1808 -
1809 - var elementBefore = <Foo><Bar /></Foo>;
1810 - var treeBefore = {
1811 - displayName: 'Foo',
1812 - children: [
1813 - {
1814 - displayName: 'Bar',
1815 - children: [],
1816 - },
1817 - ],
1818 - };
1819 -
1820 - var elementAfter = <Foo>{null}</Foo>;
1821 - var treeAfter = {
1822 - displayName: 'Foo',
1823 - children: [],
1824 - };
1825 -
1826 - assertTreeMatches([
1827 - [elementBefore, treeBefore],
1828 - [elementAfter, treeAfter],
1829 - ]);
1830 - });
1831 - });
1832 - });
1833 -
1834 - it('tracks owner correctly', () => {
1835 - class Foo extends React.Component {
1836 - render() {
1837 - return <Bar><Text>Hi.</Text></Bar>;
1838 - }
1839 - }
1840 - function Bar({children}) {
1841 - return <View>{children}<Text>Mom</Text></View>;
1842 - }
1843 -
1844 - // Note that owner is not calculated for text nodes
1845 - // because they are not created from real elements.
1846 - var element = <View><Foo /></View>;
1847 - var tree = {
1848 - displayName: 'View',
1849 - children: [
1850 - {
1851 - displayName: 'Foo',
1852 - children: [
1853 - {
1854 - displayName: 'Bar',
1855 - ownerDisplayName: 'Foo',
1856 - children: [
1857 - {
1858 - displayName: 'View',
1859 - ownerDisplayName: 'Bar',
1860 - children: [
1861 - {
1862 - displayName: 'Text',
1863 - ownerDisplayName: 'Foo',
1864 - children: [
1865 - {
1866 - displayName: 'RCText',
1867 - ownerDisplayName: 'Text',
1868 - children: [
1869 - {
1870 - displayName: '#text',
1871 - text: 'Hi.',
1872 - },
1873 - ],
1874 - },
1875 - ],
1876 - },
1877 - {
1878 - displayName: 'Text',
1879 - ownerDisplayName: 'Bar',
1880 - children: [
1881 - {
1882 - displayName: 'RCText',
1883 - ownerDisplayName: 'Text',
1884 - children: [
1885 - {
1886 - displayName: '#text',
1887 - text: 'Mom',
1888 - },
1889 - ],
1890 - },
1891 - ],
1892 - },
1893 - ],
1894 - },
1895 - ],
1896 - },
1897 - ],
1898 - },
1899 - ],
1900 - };
1901 - assertTreeMatches([element, tree], {includeOwnerDisplayName: true});
1902 - });
1903 -
1904 - it('purges unmounted components automatically', () => {
1905 - var renderBar = true;
1906 - var fooInstance;
1907 - var barInstance;
1908 -
1909 - class Foo extends React.Component {
1910 - render() {
1911 - fooInstance = ReactInstanceMap.get(this);
1912 - return renderBar ? <Bar /> : null;
1913 - }
1914 - }
1915 -
1916 - class Bar extends React.Component {
1917 - render() {
1918 - barInstance = ReactInstanceMap.get(this);
1919 - return null;
1920 - }
1921 - }
1922 -
1923 - ReactNative.render(<Foo />, 1);
1924 - ReactComponentTreeTestUtils.expectTree(
1925 - barInstance._debugID,
1926 - {
1927 - displayName: 'Bar',
1928 - parentDisplayName: 'Foo',
1929 - parentID: fooInstance._debugID,
1930 - children: [],
1931 - },
1932 - 'Foo',
1933 - );
1934 -
1935 - renderBar = false;
1936 - ReactNative.render(<Foo />, 1);
1937 - ReactComponentTreeTestUtils.expectTree(
1938 - barInstance._debugID,
1939 - {
1940 - displayName: 'Unknown',
1941 - children: [],
1942 - parentID: null,
1943 - },
1944 - 'Foo',
1945 - );
1946 -
1947 - ReactNative.unmountComponentAtNode(1);
1948 - ReactComponentTreeTestUtils.expectTree(
1949 - barInstance._debugID,
1950 - {
1951 - displayName: 'Unknown',
1952 - children: [],
1953 - parentID: null,
1954 - },
1955 - 'Foo',
1956 - );
1957 - });
1958 -
1959 - it('reports update counts', () => {
1960 - ReactNative.render(<View />, 1);
1961 - var viewID = ReactComponentTreeHook.getRootIDs()[0];
1962 - expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1963 -
1964 - ReactNative.render(<Image />, 1);
1965 - var imageID = ReactComponentTreeHook.getRootIDs()[0];
1966 - expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1967 - expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(0);
1968 -
1969 - ReactNative.render(<Image />, 1);
1970 - expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1971 - expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(1);
1972 -
1973 - ReactNative.render(<Image />, 1);
1974 - expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1975 - expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(2);
1976 -
1977 - ReactNative.unmountComponentAtNode(1);
1978 - expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1979 - expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(0);
1980 - });
1981 -
1982 - it('does not report top-level wrapper as a root', () => {
1983 - ReactNative.render(<View><Image /></View>, 1);
1984 - expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([
1985 - 'View',
1986 - ]);
1987 -
1988 - ReactNative.render(<View><Text /></View>, 1);
1989 - expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([
1990 - 'View',
1991 - ]);
1992 -
1993 - ReactNative.unmountComponentAtNode(1);
1994 - expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
1995 - expectDev(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual(
1996 - [],
1997 - );
1998 - });
1999 -});
src/renderers/native/NativeMethodsMixin.js
+52 -129
@@ -11,15 +11,15 @@
11 */
12 'use strict';
13
14 -var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15 -var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
16 -var TextInputState = require('TextInputState');
17 -var UIManager = require('UIManager');
14 +const ReactNativeAttributePayload = require('ReactNativeAttributePayload');
15 +const TextInputState = require('TextInputState');
16 +const UIManager = require('UIManager');
17
19 -var invariant = require('fbjs/lib/invariant');
20 -var findNodeHandle = require('findNodeHandle');
18 +const invariant = require('fbjs/lib/invariant');
19 +const findNodeHandle = require('findNodeHandle');
20 +const findNumericNodeHandle = require('findNumericNodeHandle');
21
22 -var {
22 +const {
23 mountSafeCallback,
24 throwOnStylesProp,
25 warnForStyleProps,
@@ -35,10 +35,6 @@ import type {
35 ReactNativeBaseComponentViewConfig,
36 } from 'ReactNativeViewConfigRegistry';
37
38 -const findNumericNodeHandle = ReactNativeFeatureFlags.useFiber
39 - ? require('findNumericNodeHandleFiber')
40 - : require('findNumericNodeHandleStack');
41 -
38 /**
39 * `NativeMethodsMixin` provides methods to access the underlying native
40 * component directly. This can be useful in cases when you want to focus
@@ -54,7 +50,7 @@ const findNumericNodeHandle = ReactNativeFeatureFlags.useFiber
50 * Note the Flow $Exact<> syntax is required to support mixins.
51 * React createClass mixins can only be used with exact types.
52 */
57 -var NativeMethodsMixin: $Exact<NativeMethodsMixinType> = {
53 +const NativeMethodsMixin: $Exact<NativeMethodsMixinType> = {
54 /**
55 * Determines the location on screen, width, and height of the given view and
56 * returns the values via an async callback. If successful, the callback will
@@ -129,7 +125,49 @@ var NativeMethodsMixin: $Exact<NativeMethodsMixinType> = {
125 * Manipulation](docs/direct-manipulation.html)).
126 */
127 setNativeProps: function(nativeProps: Object) {
132 - injectedSetNativeProps(this, nativeProps);
128 + // Class components don't have viewConfig -> validateAttributes.
129 + // Nor does it make sense to set native props on a non-native component.
130 + // Instead, find the nearest host component and set props on it.
131 + // Use findNodeHandle() rather than findNumericNodeHandle() because
132 + // We want the instance/wrapper (not the native tag).
133 + let maybeInstance;
134 +
135 + // Fiber errors if findNodeHandle is called for an umounted component.
136 + // Tests using ReactTestRenderer will trigger this case indirectly.
137 + // Mimicking stack behavior, we should silently ignore this case.
138 + // TODO Fix ReactTestRenderer so we can remove this try/catch.
139 + try {
140 + maybeInstance = findNodeHandle(this);
141 + } catch (error) {}
142 +
143 + // If there is no host component beneath this we should fail silently.
144 + // This is not an error; it could mean a class component rendered null.
145 + if (maybeInstance == null) {
146 + return;
147 + }
148 +
149 + const viewConfig: ReactNativeBaseComponentViewConfig =
150 + maybeInstance.viewConfig;
151 +
152 + if (__DEV__) {
153 + warnForStyleProps(nativeProps, viewConfig.validAttributes);
154 + }
155 +
156 + const updatePayload = ReactNativeAttributePayload.create(
157 + nativeProps,
158 + viewConfig.validAttributes,
159 + );
160 +
161 + // Avoid the overhead of bridge calls if there's no update.
162 + // This is an expensive no-op for Android, and causes an unnecessary
163 + // view invalidation for certain components (eg RCTTextInput) on iOS.
164 + if (updatePayload != null) {
165 + UIManager.updateView(
166 + maybeInstance._nativeTag,
167 + viewConfig.uiViewClassName,
168 + updatePayload,
169 + );
170 + }
171 },
172
173 /**
@@ -148,126 +186,11 @@ var NativeMethodsMixin: $Exact<NativeMethodsMixinType> = {
186 },
187 };
188
151 -// TODO (bvaughn) Inline this once ReactNativeStack is dropped.
152 -function setNativePropsFiber(componentOrHandle: any, nativeProps: Object) {
153 - // Class components don't have viewConfig -> validateAttributes.
154 - // Nor does it make sense to set native props on a non-native component.
155 - // Instead, find the nearest host component and set props on it.
156 - // Use findNodeHandle() rather than findNumericNodeHandle() because
157 - // We want the instance/wrapper (not the native tag).
158 - let maybeInstance;
159 -
160 - // Fiber errors if findNodeHandle is called for an umounted component.
161 - // Tests using ReactTestRenderer will trigger this case indirectly.
162 - // Mimicking stack behavior, we should silently ignore this case.
163 - // TODO Fix ReactTestRenderer so we can remove this try/catch.
164 - try {
165 - maybeInstance = findNodeHandle(componentOrHandle);
166 - } catch (error) {}
167 -
168 - // If there is no host component beneath this we should fail silently.
169 - // This is not an error; it could mean a class component rendered null.
170 - if (maybeInstance == null) {
171 - return;
172 - }
173 -
174 - const viewConfig: ReactNativeBaseComponentViewConfig =
175 - maybeInstance.viewConfig;
176 -
177 - if (__DEV__) {
178 - warnForStyleProps(nativeProps, viewConfig.validAttributes);
179 - }
180 -
181 - var updatePayload = ReactNativeAttributePayload.create(
182 - nativeProps,
183 - viewConfig.validAttributes,
184 - );
185 -
186 - // Avoid the overhead of bridge calls if there's no update.
187 - // This is an expensive no-op for Android, and causes an unnecessary
188 - // view invalidation for certain components (eg RCTTextInput) on iOS.
189 - if (updatePayload != null) {
190 - UIManager.updateView(
191 - maybeInstance._nativeTag,
192 - viewConfig.uiViewClassName,
193 - updatePayload,
194 - );
195 - }
196 -}
197 -
198 -// TODO (bvaughn) Remove this once ReactNativeStack is dropped.
199 -function setNativePropsStack(componentOrHandle: any, nativeProps: Object) {
200 - // Class components don't have viewConfig -> validateAttributes.
201 - // Nor does it make sense to set native props on a non-native component.
202 - // Instead, find the nearest host component and set props on it.
203 - // Use findNodeHandle() rather than findNumericNodeHandle() because
204 - // We want the instance/wrapper (not the native tag).
205 - let maybeInstance = findNodeHandle(componentOrHandle);
206 -
207 - // If there is no host component beneath this we should fail silently.
208 - // This is not an error; it could mean a class component rendered null.
209 - if (maybeInstance == null) {
210 - return;
211 - }
212 -
213 - let viewConfig: ReactNativeBaseComponentViewConfig;
214 - if (maybeInstance.viewConfig !== undefined) {
215 - // ReactNativeBaseComponent
216 - viewConfig = maybeInstance.viewConfig;
217 - } else if (
218 - maybeInstance._instance !== undefined &&
219 - maybeInstance._instance.viewConfig !== undefined
220 - ) {
221 - // ReactCompositeComponentWrapper
222 - // Some instances (eg Text) define their own viewConfig
223 - viewConfig = maybeInstance._instance.viewConfig;
224 - } else {
225 - // ReactCompositeComponentWrapper
226 - // Other instances (eg TextInput) defer to their children's viewConfig
227 - while (maybeInstance._renderedComponent !== undefined) {
228 - maybeInstance = maybeInstance._renderedComponent;
229 - }
230 - viewConfig = maybeInstance.viewConfig;
231 - }
232 -
233 - const tag: number = typeof maybeInstance.getHostNode === 'function'
234 - ? maybeInstance.getHostNode()
235 - : maybeInstance._rootNodeID;
236 -
237 - if (__DEV__) {
238 - warnForStyleProps(nativeProps, viewConfig.validAttributes);
239 - }
240 -
241 - var updatePayload = ReactNativeAttributePayload.create(
242 - nativeProps,
243 - viewConfig.validAttributes,
244 - );
245 -
246 - if (updatePayload) {
247 - UIManager.updateView(tag, viewConfig.uiViewClassName, updatePayload);
248 - }
249 -}
250 -
251 -// Switching based on fiber vs stack to avoid a lot of inline checks at runtime.
252 -// HACK Normally this injection would be done by the renderer, but in this case
253 -// that would result in a cycle between ReactNative and NativeMethodsMixin.
254 -// We avoid requiring additional code for this injection so it's probably ok?
255 -// TODO (bvaughn) Remove this once ReactNativeStack is gone.
256 -let injectedSetNativeProps: (
257 - componentOrHandle: any,
258 - nativeProps: Object,
259 -) => void;
260 -if (ReactNativeFeatureFlags.useFiber) {
261 - injectedSetNativeProps = setNativePropsFiber;
262 -} else {
263 - injectedSetNativeProps = setNativePropsStack;
264 -}
265 -
189 if (__DEV__) {
190 // hide this from Flow since we can't define these properties outside of
191 // __DEV__ without actually implementing them (setting them to undefined
192 // isn't allowed by ReactClass)
270 - var NativeMethodsMixin_DEV = (NativeMethodsMixin: any);
193 + const NativeMethodsMixin_DEV = (NativeMethodsMixin: any);
194 invariant(
195 !NativeMethodsMixin_DEV.componentWillMount &&
196 !NativeMethodsMixin_DEV.componentWillReceiveProps,
src/renderers/native/ReactNativeBaseComponent.js deleted
-198
@@ -1,198 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeBaseComponent
10 - * @flow
11 - */
12 -
13 -'use strict';
14 -
15 -var NativeMethodsMixin = require('NativeMethodsMixin');
16 -var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
17 -var ReactNativeComponentTree = require('ReactNativeComponentTree');
18 -var ReactNativeTagHandles = require('ReactNativeTagHandles');
19 -var ReactMultiChild = require('ReactMultiChild');
20 -var UIManager = require('UIManager');
21 -
22 -var deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
23 -
24 -type ReactNativeBaseComponentViewConfig = {
25 - validAttributes: Object,
26 - uiViewClassName: string,
27 -};
28 -
29 -// require('UIManagerStatTracker').install(); // uncomment to enable
30 -
31 -/**
32 - * @constructor ReactNativeBaseComponent
33 - * @extends ReactComponent
34 - * @extends ReactMultiChild
35 - * @param {!object} UIKit View Configuration.
36 - */
37 -var ReactNativeBaseComponent = function(
38 - viewConfig: ReactNativeBaseComponentViewConfig,
39 -) {
40 - this.viewConfig = viewConfig;
41 -};
42 -
43 -/**
44 - * Mixin for containers that contain UIViews. NOTE: markup is rendered markup
45 - * which is a `viewID` ... see the return value for `mountComponent` !
46 - */
47 -ReactNativeBaseComponent.Mixin = {
48 - getPublicInstance: function() {
49 - // TODO: This should probably use a composite wrapper
50 - return this;
51 - },
52 -
53 - unmountComponent: function(safely, skipLifecycle) {
54 - ReactNativeComponentTree.uncacheNode(this);
55 - this.unmountChildren(safely, skipLifecycle);
56 - this._rootNodeID = 0;
57 - },
58 -
59 - /**
60 - * Every native component is responsible for allocating its own `tag`, and
61 - * issuing the native `createView` command. But it is not responsible for
62 - * recording the fact that its own `rootNodeID` is associated with a
63 - * `nodeHandle`. Only the code that actually adds its `nodeHandle` (`tag`) as
64 - * a child of a container can confidently record that in
65 - * `ReactNativeTagHandles`.
66 - */
67 - initializeChildren: function(children, containerTag, transaction, context) {
68 - var mountImages = this.mountChildren(children, transaction, context);
69 - // In a well balanced tree, half of the nodes are in the bottom row and have
70 - // no children - let's avoid calling out to the native bridge for a large
71 - // portion of the children.
72 - if (mountImages.length) {
73 - // TODO: Pool these per platform view class. Reusing the `mountImages`
74 - // array would likely be a jit deopt.
75 - var createdTags = [];
76 - for (var i = 0, l = mountImages.length; i < l; i++) {
77 - var mountImage = mountImages[i];
78 - var childTag = mountImage;
79 - createdTags[i] = childTag;
80 - }
81 - UIManager.setChildren(containerTag, createdTags);
82 - }
83 - },
84 -
85 - /**
86 - * Updates the component's currently mounted representation.
87 - *
88 - * @param {object} nextElement
89 - * @param {ReactReconcileTransaction} transaction
90 - * @param {object} context
91 - * @internal
92 - */
93 - receiveComponent: function(nextElement, transaction, context) {
94 - var prevElement = this._currentElement;
95 - this._currentElement = nextElement;
96 -
97 - if (__DEV__) {
98 - for (var key in this.viewConfig.validAttributes) {
99 - if (nextElement.props.hasOwnProperty(key)) {
100 - deepFreezeAndThrowOnMutationInDev(nextElement.props[key]);
101 - }
102 - }
103 - }
104 -
105 - var updatePayload = ReactNativeAttributePayload.diff(
106 - prevElement.props,
107 - nextElement.props,
108 - this.viewConfig.validAttributes,
109 - );
110 -
111 - if (updatePayload) {
112 - UIManager.updateView(
113 - this._rootNodeID,
114 - this.viewConfig.uiViewClassName,
115 - updatePayload,
116 - );
117 - }
118 -
119 - this.updateChildren(nextElement.props.children, transaction, context);
120 - },
121 -
122 - getName() {
123 - return this.constructor.displayName || this.constructor.name || 'Unknown';
124 - },
125 -
126 - /**
127 - * Currently this still uses IDs for reconciliation so this can return null.
128 - *
129 - * @return {null} Null.
130 - */
131 - getHostNode: function() {
132 - return this._rootNodeID;
133 - },
134 -
135 - /**
136 - * @param {ReactNativeReconcileTransaction} transaction
137 - * @param {?ReactNativeBaseComponent} the parent component instance
138 - * @param {?object} info about the host container
139 - * @param {object} context
140 - * @return {string} Unique iOS view tag.
141 - */
142 - mountComponent: function(
143 - transaction,
144 - hostParent,
145 - hostContainerInfo,
146 - context,
147 - ) {
148 - var tag = ReactNativeTagHandles.allocateTag();
149 -
150 - this._rootNodeID = tag;
151 - this._hostParent = hostParent;
152 - this._hostContainerInfo = hostContainerInfo;
153 -
154 - if (__DEV__) {
155 - for (var key in this.viewConfig.validAttributes) {
156 - if (this._currentElement.props.hasOwnProperty(key)) {
157 - deepFreezeAndThrowOnMutationInDev(this._currentElement.props[key]);
158 - }
159 - }
160 - }
161 -
162 - var updatePayload = ReactNativeAttributePayload.create(
163 - this._currentElement.props,
164 - this.viewConfig.validAttributes,
165 - );
166 -
167 - var nativeTopRootTag = hostContainerInfo._tag;
168 - UIManager.createView(
169 - tag,
170 - this.viewConfig.uiViewClassName,
171 - nativeTopRootTag,
172 - updatePayload,
173 - );
174 -
175 - ReactNativeComponentTree.precacheNode(this, tag);
176 -
177 - this.initializeChildren(
178 - this._currentElement.props.children,
179 - tag,
180 - transaction,
181 - context,
182 - );
183 - return tag;
184 - },
185 -};
186 -
187 -/**
188 - * Order of mixins is important. ReactNativeBaseComponent overrides methods in
189 - * ReactMultiChild.
190 - */
191 -Object.assign(
192 - ReactNativeBaseComponent.prototype,
193 - ReactMultiChild,
194 - ReactNativeBaseComponent.Mixin,
195 - NativeMethodsMixin,
196 -);
197 -
198 -module.exports = ReactNativeBaseComponent;
src/renderers/native/ReactNativeComponent.js
+37 -110
@@ -15,11 +15,11 @@
15
16 const React = require('react');
17 const ReactNativeAttributePayload = require('ReactNativeAttributePayload');
18 -const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
18 const TextInputState = require('TextInputState');
19 const UIManager = require('UIManager');
20
21 const findNodeHandle = require('findNodeHandle');
22 +const findNumericNodeHandle = require('findNumericNodeHandle');
23
24 const {mountSafeCallback} = require('NativeMethodsMixinUtils');
25
@@ -33,10 +33,6 @@ import type {
33 ReactNativeBaseComponentViewConfig,
34 } from 'ReactNativeViewConfigRegistry';
35
36 -const findNumericNodeHandle = ReactNativeFeatureFlags.useFiber
37 - ? require('findNumericNodeHandleFiber')
38 - : require('findNumericNodeHandleStack');
39 -
36 /**
37 * Superclass that provides methods to access the underlying native component.
38 * This can be useful when you want to focus a view or measure its dimensions.
@@ -136,118 +132,49 @@ class ReactNativeComponent<DefaultProps, Props, State>
132 * Manipulation](docs/direct-manipulation.html)).
133 */
134 setNativeProps(nativeProps: Object): void {
139 - injectedSetNativeProps(this, nativeProps);
140 - }
141 -}
142 -
143 -// eslint-disable-next-line no-unused-expressions
144 -(ReactNativeComponent.prototype: NativeMethodsMixinType);
135 + // Class components don't have viewConfig -> validateAttributes.
136 + // Nor does it make sense to set native props on a non-native component.
137 + // Instead, find the nearest host component and set props on it.
138 + // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
139 + // We want the instance/wrapper (not the native tag).
140 + let maybeInstance;
141 +
142 + // Fiber errors if findNodeHandle is called for an umounted component.
143 + // Tests using ReactTestRenderer will trigger this case indirectly.
144 + // Mimicking stack behavior, we should silently ignore this case.
145 + // TODO Fix ReactTestRenderer so we can remove this try/catch.
146 + try {
147 + maybeInstance = findNodeHandle(this);
148 + } catch (error) {}
149 +
150 + // If there is no host component beneath this we should fail silently.
151 + // This is not an error; it could mean a class component rendered null.
152 + if (maybeInstance == null) {
153 + return;
154 + }
155
146 -// TODO (bvaughn) Inline this once ReactNativeStack is dropped.
147 -function setNativePropsFiber(componentOrHandle: any, nativeProps: Object) {
148 - // Class components don't have viewConfig -> validateAttributes.
149 - // Nor does it make sense to set native props on a non-native component.
150 - // Instead, find the nearest host component and set props on it.
151 - // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
152 - // We want the instance/wrapper (not the native tag).
153 - let maybeInstance;
154 -
155 - // Fiber errors if findNodeHandle is called for an umounted component.
156 - // Tests using ReactTestRenderer will trigger this case indirectly.
157 - // Mimicking stack behavior, we should silently ignore this case.
158 - // TODO Fix ReactTestRenderer so we can remove this try/catch.
159 - try {
160 - maybeInstance = findNodeHandle(componentOrHandle);
161 - } catch (error) {}
162 -
163 - // If there is no host component beneath this we should fail silently.
164 - // This is not an error; it could mean a class component rendered null.
165 - if (maybeInstance == null) {
166 - return;
167 - }
156 + const viewConfig: ReactNativeBaseComponentViewConfig =
157 + maybeInstance.viewConfig;
158
169 - const viewConfig: ReactNativeBaseComponentViewConfig =
170 - maybeInstance.viewConfig;
171 -
172 - var updatePayload = ReactNativeAttributePayload.create(
173 - nativeProps,
174 - viewConfig.validAttributes,
175 - );
176 -
177 - // Avoid the overhead of bridge calls if there's no update.
178 - // This is an expensive no-op for Android, and causes an unnecessary
179 - // view invalidation for certain components (eg RCTTextInput) on iOS.
180 - if (updatePayload != null) {
181 - UIManager.updateView(
182 - maybeInstance._nativeTag,
183 - viewConfig.uiViewClassName,
184 - updatePayload,
159 + var updatePayload = ReactNativeAttributePayload.create(
160 + nativeProps,
161 + viewConfig.validAttributes,
162 );
186 - }
187 -}
163
189 -// TODO (bvaughn) Remove this once ReactNativeStack is dropped.
190 -function setNativePropsStack(componentOrHandle: any, nativeProps: Object) {
191 - // Class components don't have viewConfig -> validateAttributes.
192 - // Nor does it make sense to set native props on a non-native component.
193 - // Instead, find the nearest host component and set props on it.
194 - // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
195 - // We want the instance/wrapper (not the native tag).
196 - let maybeInstance = findNodeHandle(componentOrHandle);
197 -
198 - // If there is no host component beneath this we should fail silently.
199 - // This is not an error; it could mean a class component rendered null.
200 - if (maybeInstance == null) {
201 - return;
202 - }
203 -
204 - let viewConfig: ReactNativeBaseComponentViewConfig;
205 - if (maybeInstance.viewConfig !== undefined) {
206 - // ReactNativeBaseComponent
207 - viewConfig = maybeInstance.viewConfig;
208 - } else if (
209 - maybeInstance._instance !== undefined &&
210 - maybeInstance._instance.viewConfig !== undefined
211 - ) {
212 - // ReactCompositeComponentWrapper
213 - // Some instances (eg Text) define their own viewConfig
214 - viewConfig = maybeInstance._instance.viewConfig;
215 - } else {
216 - // ReactCompositeComponentWrapper
217 - // Other instances (eg TextInput) defer to their children's viewConfig
218 - while (maybeInstance._renderedComponent !== undefined) {
219 - maybeInstance = maybeInstance._renderedComponent;
164 + // Avoid the overhead of bridge calls if there's no update.
165 + // This is an expensive no-op for Android, and causes an unnecessary
166 + // view invalidation for certain components (eg RCTTextInput) on iOS.
167 + if (updatePayload != null) {
168 + UIManager.updateView(
169 + maybeInstance._nativeTag,
170 + viewConfig.uiViewClassName,
171 + updatePayload,
172 + );
173 }
221 - viewConfig = maybeInstance.viewConfig;
222 - }
223 -
224 - const tag: number = typeof maybeInstance.getHostNode === 'function'
225 - ? maybeInstance.getHostNode()
226 - : maybeInstance._rootNodeID;
227 -
228 - var updatePayload = ReactNativeAttributePayload.create(
229 - nativeProps,
230 - viewConfig.validAttributes,
231 - );
232 -
233 - if (updatePayload != null) {
234 - UIManager.updateView(tag, viewConfig.uiViewClassName, updatePayload);
174 }
175 }
176
238 -// Switching based on fiber vs stack to avoid a lot of inline checks at runtime.
239 -// HACK Normally this injection would be done by the renderer, but in this case
240 -// that would result in a cycle between ReactNative and NativeMethodsMixin.
241 -// We avoid requiring additional code for this injection so it's probably ok?
242 -// TODO (bvaughn) Remove this once ReactNativeStack is gone.
243 -let injectedSetNativeProps: (
244 - componentOrHandle: any,
245 - nativeProps: Object,
246 -) => void;
247 -if (ReactNativeFeatureFlags.useFiber) {
248 - injectedSetNativeProps = setNativePropsFiber;
249 -} else {
250 - injectedSetNativeProps = setNativePropsStack;
251 -}
177 +// eslint-disable-next-line no-unused-expressions
178 +(ReactNativeComponent.prototype: NativeMethodsMixinType);
179
180 module.exports = ReactNativeComponent;
src/renderers/native/ReactNativeComponentEnvironment.js deleted
-30
@@ -1,30 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeComponentEnvironment
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -var ReactNativeDOMIDOperations = require('ReactNativeDOMIDOperations');
15 -var ReactNativeReconcileTransaction = require('ReactNativeReconcileTransaction');
16 -
17 -var ReactNativeComponentEnvironment = {
18 - processChildrenUpdates: ReactNativeDOMIDOperations.dangerouslyProcessChildrenUpdates,
19 -
20 - replaceNodeWithMarkup: ReactNativeDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,
21 -
22 - /**
23 - * @param {DOMElement} Element to clear.
24 - */
25 - clearNode: function(/*containerView*/) {},
26 -
27 - ReactReconcileTransaction: ReactNativeReconcileTransaction,
28 -};
29 -
30 -module.exports = ReactNativeComponentEnvironment;
src/renderers/native/ReactNativeComponentTree.js
+1 -4
@@ -61,10 +61,7 @@ function getInstanceFromTag(tag) {
61 }
62
63 function getTagFromInstance(inst) {
64 - // TODO (bvaughn) Clean up once Stack is deprecated
65 - var tag = typeof inst.tag !== 'number'
66 - ? inst._rootNodeID
67 - : inst.stateNode._nativeTag;
64 + var tag = inst.stateNode._nativeTag;
65 invariant(tag, 'All native instances should have a tag.');
66 return tag;
67 }
src/renderers/native/ReactNativeContainerInfo.js deleted
-21
@@ -1,21 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeContainerInfo
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -function ReactNativeContainerInfo(tag: number) {
15 - var info = {
16 - _tag: tag,
17 - };
18 - return info;
19 -}
20 -
21 -module.exports = ReactNativeContainerInfo;
src/renderers/native/ReactNativeDOMIDOperations.js deleted
-85
@@ -1,85 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeDOMIDOperations
10 - */
11 -'use strict';
12 -
13 -var ReactNativeComponentTree = require('ReactNativeComponentTree');
14 -var UIManager = require('UIManager');
15 -
16 -/**
17 - * Updates a component's children by processing a series of updates.
18 - * For each of the update/create commands, the `fromIndex` refers to the index
19 - * that the item existed at *before* any of the updates are applied, and the
20 - * `toIndex` refers to the index after *all* of the updates are applied
21 - * (including deletes/moves). TODO: refactor so this can be shared with
22 - * DOMChildrenOperations.
23 - *
24 - * @param {ReactNativeBaseComponent} updates List of update configurations.
25 - * @param {array<string>} markup List of markup strings - in the case of React
26 - * IOS, the ids of new components assumed to be already created.
27 - */
28 -var dangerouslyProcessChildrenUpdates = function(inst, childrenUpdates) {
29 - if (!childrenUpdates.length) {
30 - return;
31 - }
32 -
33 - var containerTag = ReactNativeComponentTree.getNodeFromInstance(inst);
34 -
35 - var moveFromIndices;
36 - var moveToIndices;
37 - var addChildTags;
38 - var addAtIndices;
39 - var removeAtIndices;
40 -
41 - for (var i = 0; i < childrenUpdates.length; i++) {
42 - var update = childrenUpdates[i];
43 - if (update.type === 'MOVE_EXISTING') {
44 - (moveFromIndices || (moveFromIndices = [])).push(update.fromIndex);
45 - (moveToIndices || (moveToIndices = [])).push(update.toIndex);
46 - } else if (update.type === 'REMOVE_NODE') {
47 - (removeAtIndices || (removeAtIndices = [])).push(update.fromIndex);
48 - } else if (update.type === 'INSERT_MARKUP') {
49 - var mountImage = update.content;
50 - var tag = mountImage;
51 - (addAtIndices || (addAtIndices = [])).push(update.toIndex);
52 - (addChildTags || (addChildTags = [])).push(tag);
53 - }
54 - }
55 -
56 - UIManager.manageChildren(
57 - containerTag,
58 - moveFromIndices,
59 - moveToIndices,
60 - addChildTags,
61 - addAtIndices,
62 - removeAtIndices,
63 - );
64 -};
65 -
66 -/**
67 - * Operations used to process updates to DOM nodes. This is made injectable via
68 - * `ReactComponent.DOMIDOperations`.
69 - */
70 -var ReactNativeDOMIDOperations = {
71 - dangerouslyProcessChildrenUpdates,
72 -
73 - /**
74 - * Replaces a view that exists in the document with markup.
75 - *
76 - * @param {string} id ID of child to be replaced.
77 - * @param {string} markup Mount image to replace child with id.
78 - */
79 - dangerouslyReplaceNodeWithMarkupByID: function(id, mountImage) {
80 - var oldTag = id;
81 - UIManager.replaceExistingNonRootView(oldTag, mountImage);
82 - },
83 -};
84 -
85 -module.exports = ReactNativeDOMIDOperations;
src/renderers/native/ReactNativeFeatureFlags.js deleted
-19
@@ -1,19 +0,0 @@
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 - * @providesModule ReactNativeFeatureFlags
10 - * @flow
11 - */
12 -
13 -'use strict';
14 -
15 -var ReactNativeFeatureFlags = {
16 - useFiber: true,
17 -};
18 -
19 -module.exports = ReactNativeFeatureFlags;
src/renderers/native/ReactNativeFiberEntry.js
+1 -1
@@ -22,7 +22,7 @@ const ReactNativeFiberInspector = require('ReactNativeFiberInspector');
22 const ReactVersion = require('ReactVersion');
23 const UIManager = require('UIManager');
24
25 -const findNumericNodeHandle = require('findNumericNodeHandleFiber');
25 +const findNumericNodeHandle = require('findNumericNodeHandle');
26
27 const {injectInternals} = require('ReactFiberDevToolsHook');
28
src/renderers/native/ReactNativeGlobalResponderHandler.js
+1 -4
@@ -15,10 +15,7 @@ var UIManager = require('UIManager');
15 var ReactNativeGlobalResponderHandler = {
16 onChange: function(from, to, blockNativeResponder) {
17 if (to !== null) {
18 - // TODO (bvaughn) Clean up once Stack is deprecated
19 - var tag = typeof to.tag !== 'number'
20 - ? to._rootNodeID
21 - : to.stateNode._nativeTag;
18 + var tag = to.stateNode._nativeTag;
19 UIManager.setJSResponder(tag, blockNativeResponder);
20 } else {
21 UIManager.clearJSResponder();
src/renderers/native/ReactNativeMount.js deleted
-227
@@ -1,227 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeMount
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -var React = require('react');
15 -var ReactInstrumentation = require('ReactInstrumentation');
16 -var ReactNativeContainerInfo = require('ReactNativeContainerInfo');
17 -var ReactNativeTagHandles = require('ReactNativeTagHandles');
18 -var ReactReconciler = require('ReactReconciler');
19 -var ReactUpdateQueue = require('ReactUpdateQueue');
20 -var ReactUpdates = require('ReactUpdates');
21 -var UIManager = require('UIManager');
22 -
23 -var emptyObject = require('fbjs/lib/emptyObject');
24 -var instantiateReactComponent = require('instantiateReactComponent');
25 -var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
26 -
27 -/**
28 - * Temporary (?) hack so that we can store all top-level pending updates on
29 - * composites instead of having to worry about different types of components
30 - * here.
31 - */
32 -var TopLevelWrapper = function() {};
33 -TopLevelWrapper.prototype.isReactComponent = {};
34 -if (__DEV__) {
35 - TopLevelWrapper.displayName = 'TopLevelWrapper';
36 -}
37 -TopLevelWrapper.prototype.render = function() {
38 - return this.props.child;
39 -};
40 -TopLevelWrapper.isReactTopLevelWrapper = true;
41 -
42 -/**
43 - * Mounts this component and inserts it into the DOM.
44 - *
45 - * @param {ReactComponent} componentInstance The instance to mount.
46 - * @param {number} rootID ID of the root node.
47 - * @param {number} containerTag container element to mount into.
48 - * @param {ReactReconcileTransaction} transaction
49 - */
50 -function mountComponentIntoNode(componentInstance, containerTag, transaction) {
51 - var markup = ReactReconciler.mountComponent(
52 - componentInstance,
53 - transaction,
54 - null,
55 - ReactNativeContainerInfo(containerTag),
56 - emptyObject,
57 - 0 /* parentDebugID */,
58 - );
59 - componentInstance._renderedComponent._topLevelWrapper = componentInstance;
60 - ReactNativeMount._mountImageIntoNode(markup, containerTag);
61 -}
62 -
63 -/**
64 - * Batched mount.
65 - *
66 - * @param {ReactComponent} componentInstance The instance to mount.
67 - * @param {number} rootID ID of the root node.
68 - * @param {number} containerTag container element to mount into.
69 - */
70 -function batchedMountComponentIntoNode(componentInstance, containerTag) {
71 - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
72 - transaction.perform(
73 - mountComponentIntoNode,
74 - null,
75 - componentInstance,
76 - containerTag,
77 - transaction,
78 - );
79 - ReactUpdates.ReactReconcileTransaction.release(transaction);
80 -}
81 -
82 -/**
83 - * As soon as `ReactMount` is refactored to not rely on the DOM, we can share
84 - * code between the two. For now, we'll hard code the ID logic.
85 - */
86 -var ReactNativeMount = {
87 - _instancesByContainerID: {},
88 -
89 - // these two functions are needed by React Devtools
90 - findNodeHandle: require('findNodeHandle'),
91 -
92 - /**
93 - * @param {ReactComponent} instance Instance to render.
94 - * @param {containerTag} containerView Handle to native view tag
95 - */
96 - renderComponent: function(
97 - nextElement: ReactElement<*>,
98 - containerTag: number,
99 - callback?: ?() => void,
100 - ): ?ReactComponent<any, any, any> {
101 - var nextWrappedElement = React.createElement(TopLevelWrapper, {
102 - child: nextElement,
103 - });
104 -
105 - var topRootNodeID = containerTag;
106 - var prevComponent = ReactNativeMount._instancesByContainerID[topRootNodeID];
107 - if (prevComponent) {
108 - var prevWrappedElement = prevComponent._currentElement;
109 - var prevElement = prevWrappedElement.props.child;
110 - if (shouldUpdateReactComponent(prevElement, nextElement)) {
111 - ReactUpdateQueue.enqueueElementInternal(
112 - prevComponent,
113 - nextWrappedElement,
114 - emptyObject,
115 - );
116 - if (callback) {
117 - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
118 - }
119 - return prevComponent;
120 - } else {
121 - ReactNativeMount.unmountComponentAtNode(containerTag);
122 - }
123 - }
124 -
125 - if (!ReactNativeTagHandles.reactTagIsNativeTopRootID(containerTag)) {
126 - console.error('You cannot render into anything but a top root');
127 - return null;
128 - }
129 -
130 - ReactNativeTagHandles.assertRootTag(containerTag);
131 -
132 - var instance = instantiateReactComponent(nextWrappedElement, false);
133 - ReactNativeMount._instancesByContainerID[containerTag] = instance;
134 -
135 - if (callback) {
136 - var nonNullCallback = callback;
137 - instance._pendingCallbacks = [
138 - function() {
139 - nonNullCallback.call(instance._renderedComponent.getPublicInstance());
140 - },
141 - ];
142 - }
143 -
144 - // The initial render is synchronous but any updates that happen during
145 - // rendering, in componentWillMount or componentDidMount, will be batched
146 - // according to the current batching strategy.
147 -
148 - ReactUpdates.batchedUpdates(
149 - batchedMountComponentIntoNode,
150 - instance,
151 - containerTag,
152 - );
153 - var component = instance._renderedComponent.getPublicInstance();
154 - return component;
155 - },
156 -
157 - /**
158 - * @param {View} view View tree image.
159 - * @param {number} containerViewID View to insert sub-view into.
160 - */
161 - _mountImageIntoNode: function(mountImage: number, containerID: number) {
162 - // Since we now know that the `mountImage` has been mounted, we can
163 - // mark it as such.
164 - var childTag = mountImage;
165 - UIManager.setChildren(containerID, [childTag]);
166 - },
167 -
168 - /**
169 - * Standard unmounting of the component that is rendered into `containerID`,
170 - * but will also execute a command to remove the actual container view
171 - * itself. This is useful when a client is cleaning up a React tree, and also
172 - * knows that the container will no longer be needed. When executing
173 - * asynchronously, it's easier to just have this method be the one that calls
174 - * for removal of the view.
175 - */
176 - unmountComponentAtNodeAndRemoveContainer: function(containerTag: number) {
177 - ReactNativeMount.unmountComponentAtNode(containerTag);
178 - // call back into native to remove all of the subviews from this container
179 - UIManager.removeRootView(containerTag);
180 - },
181 -
182 - /**
183 - * Unmount component at container ID by iterating through each child component
184 - * that has been rendered and unmounting it. There should just be one child
185 - * component at this time.
186 - */
187 - unmountComponentAtNode: function(containerTag: number): boolean {
188 - if (!ReactNativeTagHandles.reactTagIsNativeTopRootID(containerTag)) {
189 - console.error('You cannot render into anything but a top root');
190 - return false;
191 - }
192 -
193 - var instance = ReactNativeMount._instancesByContainerID[containerTag];
194 - if (!instance) {
195 - return false;
196 - }
197 - if (__DEV__) {
198 - ReactInstrumentation.debugTool.onBeginFlush();
199 - }
200 - ReactNativeMount.unmountComponentFromNode(instance, containerTag);
201 - delete ReactNativeMount._instancesByContainerID[containerTag];
202 - if (__DEV__) {
203 - ReactInstrumentation.debugTool.onEndFlush();
204 - }
205 - return true;
206 - },
207 -
208 - /**
209 - * Unmounts a component and sends messages back to iOS to remove its subviews.
210 - *
211 - * @param {ReactComponent} instance React component instance.
212 - * @param {string} containerID ID of container we're removing from.
213 - * @final
214 - * @internal
215 - * @see {ReactNativeMount.unmountComponentAtNode}
216 - */
217 - unmountComponentFromNode: function(
218 - instance: ReactComponent<any, any, any>,
219 - containerID: number,
220 - ) {
221 - // Call back into native to remove all of the subviews from this container
222 - ReactReconciler.unmountComponent(instance);
223 - UIManager.removeSubviewsFromContainerWithID(containerID);
224 - },
225 -};
226 -
227 -module.exports = ReactNativeMount;
src/renderers/native/ReactNativeReconcileTransaction.js deleted
-132
@@ -1,132 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeReconcileTransaction
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -var CallbackQueue = require('CallbackQueue');
15 -var PooledClass = require('PooledClass');
16 -var Transaction = require('Transaction');
17 -var ReactInstrumentation = require('ReactInstrumentation');
18 -var ReactUpdateQueue = require('ReactUpdateQueue');
19 -
20 -/**
21 - * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks during
22 - * the performing of the transaction.
23 - */
24 -var ON_DOM_READY_QUEUEING = {
25 - /**
26 - * Initializes the internal `onDOMReady` queue.
27 - */
28 - initialize: function() {
29 - this.reactMountReady.reset();
30 - },
31 -
32 - /**
33 - * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
34 - */
35 - close: function() {
36 - this.reactMountReady.notifyAll();
37 - },
38 -};
39 -
40 -/**
41 - * Executed within the scope of the `Transaction` instance. Consider these as
42 - * being member methods, but with an implied ordering while being isolated from
43 - * each other.
44 - */
45 -var TRANSACTION_WRAPPERS = [ON_DOM_READY_QUEUEING];
46 -
47 -if (__DEV__) {
48 - TRANSACTION_WRAPPERS.push({
49 - initialize: ReactInstrumentation.debugTool.onBeginFlush,
50 - close: ReactInstrumentation.debugTool.onEndFlush,
51 - });
52 -}
53 -
54 -/**
55 - * Currently:
56 - * - The order that these are listed in the transaction is critical:
57 - * - Suppresses events.
58 - * - Restores selection range.
59 - *
60 - * Future:
61 - * - Restore document/overflow scroll positions that were unintentionally
62 - * modified via DOM insertions above the top viewport boundary.
63 - * - Implement/integrate with customized constraint based layout system and keep
64 - * track of which dimensions must be remeasured.
65 - *
66 - * @class ReactNativeReconcileTransaction
67 - */
68 -function ReactNativeReconcileTransaction() {
69 - this.reinitializeTransaction();
70 - this.reactMountReady = CallbackQueue.getPooled();
71 -}
72 -
73 -var Mixin = {
74 - /**
75 - * @see Transaction
76 - * @abstract
77 - * @final
78 - * @return {array<object>} List of operation wrap procedures.
79 - * TODO: convert to array<TransactionWrapper>
80 - */
81 - getTransactionWrappers: function() {
82 - return TRANSACTION_WRAPPERS;
83 - },
84 -
85 - /**
86 - * @return {object} The queue to collect `onDOMReady` callbacks with.
87 - * TODO: convert to ReactMountReady
88 - */
89 - getReactMountReady: function() {
90 - return this.reactMountReady;
91 - },
92 -
93 - /**
94 - * @return {object} The queue to collect React async events.
95 - */
96 - getUpdateQueue: function() {
97 - return ReactUpdateQueue;
98 - },
99 -
100 - /**
101 - * Save current transaction state -- if the return value from this method is
102 - * passed to `rollback`, the transaction will be reset to that state.
103 - */
104 - checkpoint: function() {
105 - // reactMountReady is the our only stateful wrapper
106 - return this.reactMountReady.checkpoint();
107 - },
108 -
109 - rollback: function(checkpoint) {
110 - this.reactMountReady.rollback(checkpoint);
111 - },
112 -
113 - /**
114 - * `PooledClass` looks for this, and will invoke this before allowing this
115 - * instance to be reused.
116 - */
117 - destructor: function() {
118 - CallbackQueue.release(this.reactMountReady);
119 - this.reactMountReady = null;
120 - },
121 -};
122 -
123 -Object.assign(
124 - ReactNativeReconcileTransaction.prototype,
125 - Transaction,
126 - ReactNativeReconcileTransaction,
127 - Mixin,
128 -);
129 -
130 -PooledClass.addPoolingTo(ReactNativeReconcileTransaction);
131 -
132 -module.exports = ReactNativeReconcileTransaction;
src/renderers/native/ReactNativeStackEntry.js deleted
-107
@@ -1,107 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeStackEntry
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -var ReactNativeComponentTree = require('ReactNativeComponentTree');
15 -var ReactNativeMount = require('ReactNativeMount');
16 -var ReactUpdates = require('ReactUpdates');
17 -var ReactNativeStackInspector = require('ReactNativeStackInspector');
18 -
19 -var findNumericNodeHandle = require('findNumericNodeHandleStack');
20 -
21 -import type {ReactNativeType} from 'ReactNativeTypes';
22 -
23 -require('ReactNativeInjection');
24 -require('ReactNativeStackInjection');
25 -
26 -var render = function(
27 - element: ReactElement<any>,
28 - mountInto: number,
29 - callback?: ?() => void,
30 -): ?ReactComponent<any, any, any> {
31 - return ReactNativeMount.renderComponent(element, mountInto, callback);
32 -};
33 -
34 -var ReactNativeStack: ReactNativeType = {
35 - NativeComponent: require('ReactNativeComponent'),
36 -
37 - hasReactNativeInitialized: false,
38 -
39 - findNodeHandle: findNumericNodeHandle,
40 -
41 - render: render,
42 -
43 - unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,
44 -
45 - /* eslint-disable camelcase */
46 - unstable_batchedUpdates: ReactUpdates.batchedUpdates,
47 - /* eslint-enable camelcase */
48 -
49 - unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,
50 -
51 - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
52 - // Used as a mixin in many createClass-based components
53 - NativeMethodsMixin: require('NativeMethodsMixin'),
54 -
55 - // Used by react-native-github/Libraries/ components
56 - ReactGlobalSharedState: require('ReactGlobalSharedState'), // Systrace
57 - ReactNativeComponentTree: require('ReactNativeComponentTree'), // InspectorUtils, ScrollResponder
58 - ReactNativePropRegistry: require('ReactNativePropRegistry'), // flattenStyle, Stylesheet
59 - TouchHistoryMath: require('TouchHistoryMath'), // PanResponder
60 - createReactNativeComponentClass: require('createReactNativeComponentClass'), // eg Text
61 - takeSnapshot: require('takeSnapshot'), // react-native-implementation
62 - },
63 -};
64 -
65 -if (__DEV__) {
66 - // $FlowFixMe
67 - Object.assign(
68 - ReactNativeStack.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
69 - {
70 - ReactDebugTool: require('ReactDebugTool'), // RCTRenderingPerf, Systrace
71 - ReactPerf: require('ReactPerf'), // ReactPerfStallHandler, RCTRenderingPerf
72 - },
73 - );
74 -}
75 -
76 -// Inject the runtime into a devtools global hook regardless of browser.
77 -// Allows for debugging when the hook is injected on the page.
78 -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
79 -if (
80 - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
81 - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function'
82 -) {
83 - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
84 - ComponentTree: {
85 - getClosestInstanceFromNode: function(node) {
86 - return ReactNativeComponentTree.getClosestInstanceFromNode(node);
87 - },
88 - getNodeFromInstance: function(inst) {
89 - // inst is an internal instance (but could be a composite)
90 - while (inst._renderedComponent) {
91 - inst = inst._renderedComponent;
92 - }
93 - if (inst) {
94 - return ReactNativeComponentTree.getNodeFromInstance(inst);
95 - } else {
96 - return null;
97 - }
98 - },
99 - },
100 - Mount: ReactNativeMount,
101 - Reconciler: require('ReactReconciler'),
102 - getInspectorDataForViewTag: ReactNativeStackInspector.getInspectorDataForViewTag,
103 - rendererPackageName: 'react-native',
104 - });
105 -}
106 -
107 -module.exports = ReactNativeStack;
src/renderers/native/ReactNativeStackInjection.js deleted
-71
@@ -1,71 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeStackInjection
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -/**
15 - * Make sure essential globals are available and are patched correctly. Please don't remove this
16 - * line. Bundles created by react-packager `require` it before executing any application code. This
17 - * ensures it exists in the dependency graph and can be `require`d.
18 - * TODO: require this in packager, not in React #10932517
19 - */
20 -require('InitializeCore');
21 -
22 -var React = require('react');
23 -var ReactComponentEnvironment = require('ReactComponentEnvironment');
24 -var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
25 -var ReactEmptyComponent = require('ReactEmptyComponent');
26 -var ReactGenericBatching = require('ReactGenericBatching');
27 -var ReactHostComponent = require('ReactHostComponent');
28 -var ReactNativeComponentEnvironment = require('ReactNativeComponentEnvironment');
29 -var ReactNativeTextComponent = require('ReactNativeTextComponent');
30 -var ReactSimpleEmptyComponent = require('ReactSimpleEmptyComponent');
31 -var ReactUpdates = require('ReactUpdates');
32 -
33 -var invariant = require('fbjs/lib/invariant');
34 -
35 -ReactGenericBatching.injection.injectStackBatchedUpdates(
36 - ReactUpdates.batchedUpdates,
37 -);
38 -
39 -ReactUpdates.injection.injectReconcileTransaction(
40 - ReactNativeComponentEnvironment.ReactReconcileTransaction,
41 -);
42 -
43 -ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
44 -
45 -ReactComponentEnvironment.injection.injectEnvironment(
46 - ReactNativeComponentEnvironment,
47 -);
48 -
49 -var EmptyComponent = instantiate => {
50 - // Can't import View at the top because it depends on React to make its composite
51 - var View = require('View');
52 - return new ReactSimpleEmptyComponent(
53 - React.createElement(View, {
54 - collapsable: true,
55 - style: {position: 'absolute'},
56 - }),
57 - instantiate,
58 - );
59 -};
60 -
61 -ReactEmptyComponent.injection.injectEmptyComponentFactory(EmptyComponent);
62 -
63 -ReactHostComponent.injection.injectTextComponentClass(ReactNativeTextComponent);
64 -ReactHostComponent.injection.injectGenericComponentClass(function(tag) {
65 - // Show a nicer error message for non-function tags
66 - var info = '';
67 - if (typeof tag === 'string' && /^[a-z]/.test(tag)) {
68 - info += ' Each component name should start with an uppercase letter.';
69 - }
70 - invariant(false, 'Expected a component class, got %s.%s', tag, info);
71 -});
src/renderers/native/ReactNativeStackInspector.js deleted
-106
@@ -1,106 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeStackInspector
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -const ReactNativeComponentTree = require('ReactNativeComponentTree');
15 -const getComponentName = require('getComponentName');
16 -const emptyObject = require('fbjs/lib/emptyObject');
17 -const UIManager = require('UIManager');
18 -const invariant = require('fbjs/lib/invariant');
19 -
20 -let getInspectorDataForViewTag;
21 -
22 -if (__DEV__) {
23 - var traverseOwnerTreeUp = function(hierarchy, instance) {
24 - if (instance) {
25 - hierarchy.unshift(instance);
26 - traverseOwnerTreeUp(hierarchy, instance._currentElement._owner);
27 - }
28 - };
29 -
30 - var getOwnerHierarchy = function(instance) {
31 - var hierarchy = [];
32 - traverseOwnerTreeUp(hierarchy, instance);
33 - return hierarchy;
34 - };
35 -
36 - var lastNotNativeInstance = function(hierarchy) {
37 - for (let i = hierarchy.length - 1; i > 1; i--) {
38 - const instance = hierarchy[i];
39 - if (!instance.viewConfig) {
40 - return instance;
41 - }
42 - }
43 - return hierarchy[0];
44 - };
45 -
46 - var getHostProps = function(component) {
47 - const instance = component._instance;
48 - if (instance) {
49 - return instance.props || emptyObject;
50 - }
51 - return emptyObject;
52 - };
53 -
54 - var createHierarchy = function(componentHierarchy) {
55 - return componentHierarchy.map(component => ({
56 - name: getComponentName(component),
57 - getInspectorData: () => ({
58 - measure: callback =>
59 - UIManager.measure(component.getHostNode(), callback),
60 - props: getHostProps(component),
61 - source: component._currentElement && component._currentElement._source,
62 - }),
63 - }));
64 - };
65 -
66 - getInspectorDataForViewTag = function(viewTag: any): Object {
67 - const component = ReactNativeComponentTree.getClosestInstanceFromNode(
68 - viewTag,
69 - );
70 -
71 - // Handle case where user clicks outside of ReactNative
72 - if (!component) {
73 - return {
74 - hierarchy: [],
75 - props: emptyObject,
76 - selection: null,
77 - source: null,
78 - };
79 - }
80 -
81 - const componentHierarchy = getOwnerHierarchy(component);
82 - const instance = lastNotNativeInstance(componentHierarchy);
83 - const hierarchy = createHierarchy(componentHierarchy);
84 - const props = getHostProps(instance);
85 - const source = instance._currentElement && instance._currentElement._source;
86 - const selection = componentHierarchy.indexOf(instance);
87 -
88 - return {
89 - hierarchy,
90 - props,
91 - selection,
92 - source,
93 - };
94 - };
95 -} else {
96 - getInspectorDataForViewTag = () => {
97 - invariant(
98 - false,
99 - 'getInspectorDataForViewTag() is not available in production',
100 - );
101 - };
102 -}
103 -
104 -module.exports = {
105 - getInspectorDataForViewTag,
106 -};
src/renderers/native/ReactNativeTextComponent.js deleted
-79
@@ -1,79 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule ReactNativeTextComponent
10 - */
11 -
12 -'use strict';
13 -
14 -var ReactNativeComponentTree = require('ReactNativeComponentTree');
15 -var ReactNativeTagHandles = require('ReactNativeTagHandles');
16 -var UIManager = require('UIManager');
17 -
18 -var invariant = require('fbjs/lib/invariant');
19 -
20 -var ReactNativeTextComponent = function(text) {
21 - // This is really a ReactText (ReactNode), not a ReactElement
22 - this._currentElement = text;
23 - this._stringText = '' + text;
24 - this._hostParent = null;
25 - this._rootNodeID = 0;
26 -};
27 -
28 -Object.assign(ReactNativeTextComponent.prototype, {
29 - mountComponent: function(
30 - transaction,
31 - hostParent,
32 - hostContainerInfo,
33 - context,
34 - ) {
35 - // TODO: hostParent should have this context already. Stop abusing context.
36 - invariant(
37 - context.isInAParentText,
38 - 'RawText "%s" must be wrapped in an explicit <Text> component.',
39 - this._stringText,
40 - );
41 - this._hostParent = hostParent;
42 - var tag = ReactNativeTagHandles.allocateTag();
43 - this._rootNodeID = tag;
44 - var nativeTopRootTag = hostContainerInfo._tag;
45 - UIManager.createView(tag, 'RCTRawText', nativeTopRootTag, {
46 - text: this._stringText,
47 - });
48 -
49 - ReactNativeComponentTree.precacheNode(this, tag);
50 -
51 - return tag;
52 - },
53 -
54 - getHostNode: function() {
55 - return this._rootNodeID;
56 - },
57 -
58 - receiveComponent: function(nextText, transaction, context) {
59 - if (nextText !== this._currentElement) {
60 - this._currentElement = nextText;
61 - var nextStringText = '' + nextText;
62 - if (nextStringText !== this._stringText) {
63 - this._stringText = nextStringText;
64 - UIManager.updateView(this._rootNodeID, 'RCTRawText', {
65 - text: this._stringText,
66 - });
67 - }
68 - }
69 - },
70 -
71 - unmountComponent: function() {
72 - ReactNativeComponentTree.uncacheNode(this);
73 - this._currentElement = null;
74 - this._stringText = null;
75 - this._rootNodeID = 0;
76 - },
77 -});
78 -
79 -module.exports = ReactNativeTextComponent;
src/renderers/native/__tests__/ReactNativeMount-test.js
+5 -19
@@ -11,7 +11,6 @@
11
12 'use strict';
13
14 -var PropTypes;
14 var React;
15 var ReactNative;
16 var createReactNativeComponentClass;
@@ -21,7 +20,6 @@ describe('ReactNative', () => {
20 beforeEach(() => {
21 jest.resetModules();
22
24 - PropTypes = require('prop-types');
23 React = require('react');
24 ReactNative = require('react-native');
25 UIManager = require('UIManager');
@@ -68,35 +66,23 @@ describe('ReactNative', () => {
66 uiViewClassName: 'Text',
67 });
68
71 - // Context hack is required for RN text rendering in stack.
72 - // TODO Remove this from the test when RN stack has been deleted.
73 - class Hack extends React.Component {
74 - static childContextTypes = {isInAParentText: PropTypes.bool};
75 - getChildContext() {
76 - return {isInAParentText: true};
77 - }
78 - render() {
79 - return this.props.children;
80 - }
81 - }
82 -
83 - ReactNative.render(<Hack><Text foo="a">1</Text></Hack>, 11);
69 + ReactNative.render(<Text foo="a">1</Text>, 11);
70 expect(UIManager.updateView).not.toBeCalled();
71
72 // If no properties have changed, we shouldn't call updateView.
87 - ReactNative.render(<Hack><Text foo="a">1</Text></Hack>, 11);
73 + ReactNative.render(<Text foo="a">1</Text>, 11);
74 expect(UIManager.updateView).not.toBeCalled();
75
76 // Only call updateView for the changed property (and not for text).
91 - ReactNative.render(<Hack><Text foo="b">1</Text></Hack>, 11);
77 + ReactNative.render(<Text foo="b">1</Text>, 11);
78 expect(UIManager.updateView.mock.calls.length).toBe(1);
79
80 // Only call updateView for the changed text (and no other properties).
95 - ReactNative.render(<Hack><Text foo="b">2</Text></Hack>, 11);
81 + ReactNative.render(<Text foo="b">2</Text>, 11);
82 expect(UIManager.updateView.mock.calls.length).toBe(2);
83
84 // Call updateView for both changed text and properties.
99 - ReactNative.render(<Hack><Text foo="c">3</Text></Hack>, 11);
85 + ReactNative.render(<Text foo="c">3</Text>, 11);
86 expect(UIManager.updateView.mock.calls.length).toBe(4);
87 });
88
src/renderers/native/__tests__/createReactNativeComponentClass-test.js
+14 -17
@@ -14,7 +14,6 @@
14 let createReactNativeComponentClass;
15 let React;
16 let ReactNative;
17 -let ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
17
18 describe('createReactNativeComponentClass', () => {
19 beforeEach(() => {
@@ -44,22 +43,20 @@ describe('createReactNativeComponentClass', () => {
43 ReactNative.render(<View />, 1);
44 });
45
47 - if (ReactNativeFeatureFlags.useFiber) {
48 - it('should not allow viewConfigs with duplicate uiViewClassNames to be registered', () => {
49 - const textViewConfig = {
50 - validAttributes: {},
51 - uiViewClassName: 'Text',
52 - };
53 - const altTextViewConfig = {
54 - validAttributes: {},
55 - uiViewClassName: 'Text', // Same
56 - };
46 + it('should not allow viewConfigs with duplicate uiViewClassNames to be registered', () => {
47 + const textViewConfig = {
48 + validAttributes: {},
49 + uiViewClassName: 'Text',
50 + };
51 + const altTextViewConfig = {
52 + validAttributes: {},
53 + uiViewClassName: 'Text', // Same
54 + };
55
58 - createReactNativeComponentClass(textViewConfig);
56 + createReactNativeComponentClass(textViewConfig);
57
60 - expect(() => {
61 - createReactNativeComponentClass(altTextViewConfig);
62 - }).toThrow('Tried to register two views with the same name Text');
63 - });
64 - }
58 + expect(() => {
59 + createReactNativeComponentClass(altTextViewConfig);
60 + }).toThrow('Tried to register two views with the same name Text');
61 + });
62 });
src/renderers/native/createReactNativeComponentClass.js
+12 -4
@@ -12,7 +12,7 @@
12
13 'use strict';
14
15 -const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15 +const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
16
17 // See also ReactNativeBaseComponent
18 export type ReactNativeBaseComponentViewConfig = {
@@ -21,6 +21,14 @@ export type ReactNativeBaseComponentViewConfig = {
21 propTypes?: Object,
22 };
23
24 -module.exports = ReactNativeFeatureFlags.useFiber
25 - ? require('createReactNativeComponentClassFiber')
26 - : require('createReactNativeComponentClassStack');
24 +/**
25 + * @param {string} config iOS View configuration.
26 + * @private
27 + */
28 +const createReactNativeComponentClass = function(
29 + viewConfig: ReactNativeBaseComponentViewConfig,
30 +): string {
31 + return ReactNativeViewConfigRegistry.register(viewConfig);
32 +};
33 +
34 +module.exports = createReactNativeComponentClass;
src/renderers/native/createReactNativeComponentClassFiber.js deleted
-31
@@ -1,31 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule createReactNativeComponentClassFiber
10 - * @flow
11 - */
12 -
13 -'use strict';
14 -
15 -const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
16 -
17 -import type {
18 - ReactNativeBaseComponentViewConfig,
19 -} from './createReactNativeComponentClass';
20 -
21 -/**
22 - * @param {string} config iOS View configuration.
23 - * @private
24 - */
25 -const createReactNativeComponentClassFiber = function(
26 - viewConfig: ReactNativeBaseComponentViewConfig,
27 -): string {
28 - return ReactNativeViewConfigRegistry.register(viewConfig);
29 -};
30 -
31 -module.exports = createReactNativeComponentClassFiber;
src/renderers/native/createReactNativeComponentClassStack.js deleted
-45
@@ -1,45 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule createReactNativeComponentClassStack
10 - * @flow
11 - */
12 -
13 -'use strict';
14 -
15 -const ReactNativeBaseComponent = require('ReactNativeBaseComponent');
16 -
17 -import type {
18 - ReactNativeBaseComponentViewConfig,
19 -} from './createReactNativeComponentClass';
20 -
21 -/**
22 - * @param {string} config iOS View configuration.
23 - * @private
24 - */
25 -const createReactNativeComponentClassStack = function(
26 - viewConfig: ReactNativeBaseComponentViewConfig,
27 -): ReactClass<any> {
28 - const Constructor = function(element) {
29 - this._currentElement = element;
30 - this._topLevelWrapper = null;
31 - this._hostParent = null;
32 - this._hostContainerInfo = null;
33 - this._rootNodeID = 0;
34 - this._renderedChildren = null;
35 - };
36 - Constructor.displayName = viewConfig.uiViewClassName;
37 - Constructor.viewConfig = viewConfig;
38 - Constructor.propTypes = viewConfig.propTypes;
39 - Constructor.prototype = new ReactNativeBaseComponent(viewConfig);
40 - Constructor.prototype.constructor = Constructor;
41 -
42 - return ((Constructor: any): ReactClass<any>);
43 -};
44 -
45 -module.exports = createReactNativeComponentClassStack;
src/renderers/native/findNodeHandle.js
+7 -17
@@ -13,7 +13,6 @@
13 'use strict';
14
15 var ReactInstanceMap = require('ReactInstanceMap');
16 -var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
16 var ReactNativeFiberRenderer = require('ReactNativeFiberRenderer');
17 var {ReactCurrentOwner} = require('ReactGlobalSharedState');
18 var getComponentName = require('getComponentName');
@@ -24,7 +23,6 @@ if (__DEV__) {
23 }
24
25 import type {Fiber} from 'ReactFiber';
27 -import type {ReactInstance} from 'ReactInstanceType';
26
27 /**
28 * ReactNative vs ReactWeb
@@ -56,21 +54,15 @@ import type {ReactInstance} from 'ReactInstanceType';
54 * nodeHandle N/A rootNodeID tag
55 */
56
59 -// Rollup will strip the ReactNativeFiberRenderer from the Stack build.
60 -const injectedFindNode = ReactNativeFeatureFlags.useFiber
61 - ? (fiber: Fiber) => ReactNativeFiberRenderer.findHostInstance(fiber)
62 - : instance => instance;
63 -
57 // TODO (bvaughn) Rename the findNodeHandle module to something more descriptive
58 // eg findInternalHostInstance. This will reduce the likelihood of someone
59 // accidentally deep-requiring this version.
60 function findNodeHandle(componentOrHandle: any): any {
61 if (__DEV__) {
69 - // TODO: fix this unsafe cast to work with Fiber.
70 - var owner = ((ReactCurrentOwner.current: any): ReactInstance | null);
71 - if (owner !== null) {
62 + var owner = ReactCurrentOwner.current;
63 + if (owner !== null && owner.stateNode !== null) {
64 warning(
73 - owner._warnedAboutRefsInRender,
65 + owner.stateNode._warnedAboutRefsInRender,
66 '%s is accessing findNodeHandle inside its render(). ' +
67 'render() should be a pure function of props and state. It should ' +
68 'never access something that requires stale data from the previous ' +
@@ -79,7 +71,7 @@ function findNodeHandle(componentOrHandle: any): any {
71 getComponentName(owner) || 'A component',
72 );
73
82 - owner._warnedAboutRefsInRender = true;
74 + owner.stateNode._warnedAboutRefsInRender = true;
75 }
76 }
77 if (componentOrHandle == null) {
@@ -94,18 +86,16 @@ function findNodeHandle(componentOrHandle: any): any {
86
87 // TODO (balpert): Wrap iOS native components in a composite wrapper, then
88 // ReactInstanceMap.get here will always succeed for mounted components
97 - var internalInstance = ReactInstanceMap.get(component);
89 + var internalInstance: Fiber = ReactInstanceMap.get(component);
90 if (internalInstance) {
99 - return injectedFindNode(internalInstance);
91 + return ReactNativeFiberRenderer.findHostInstance(internalInstance);
92 } else {
93 if (component) {
94 return component;
95 } else {
96 invariant(
97 // Native
106 - (typeof component === 'object' &&
107 - ('_rootNodeID' in component || // TODO (bvaughn) Clean up once Stack is deprecated
108 - '_nativeTag' in component)) ||
98 + (typeof component === 'object' && '_nativeTag' in component) ||
99 // Composite
100 (component.render != null && typeof component.render === 'function'),
101 'findNodeHandle(...): Argument is not a component ' +
src/renderers/native/findNumericNodeHandle.js renamed
+1 -1
@@ -6,7 +6,7 @@
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 - * @providesModule findNumericNodeHandleFiber
9 + * @providesModule findNumericNodeHandle
10 * @flow
11 */
12 'use strict';
src/renderers/native/findNumericNodeHandleStack.js deleted
-29
@@ -1,29 +0,0 @@
1 -/**
2 - * Copyright (c) 2015-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 - * @providesModule findNumericNodeHandleStack
10 - * @flow
11 - */
12 -'use strict';
13 -
14 -var findNodeHandle = require('findNodeHandle');
15 -
16 -/**
17 - * External users of findNodeHandle() expect the host tag number return type.
18 - * The injected findNodeHandle() strategy returns the instance wrapper though.
19 - * See NativeMethodsMixin#setNativeProps for more info on why this is done.
20 - */
21 -module.exports = function findNumericNodeHandleStack(
22 - componentOrHandle: any,
23 -): ?number {
24 - const nodeHandle = findNodeHandle(componentOrHandle);
25 - if (nodeHandle == null || typeof nodeHandle === 'number') {
26 - return nodeHandle;
27 - }
28 - return nodeHandle.getHostNode();
29 -};
src/renderers/native/takeSnapshot.js
+1 -4
@@ -11,12 +11,9 @@
11 */
12 'use strict';
13
14 -const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
14 const UIManager = require('UIManager');
15
17 -const findNumericNodeHandle = ReactNativeFeatureFlags.useFiber
18 - ? require('findNumericNodeHandleFiber')
19 - : require('findNumericNodeHandleStack');
16 +const findNumericNodeHandle = require('findNumericNodeHandle');
17
18 /**
19 * Capture an image of the screen, window or an individual view. The image