Skip to content

Commit b0019b4

Browse files
committed
Move view config registry to shims
This ensures that both Fabric and RN renderers share the same view config registry since it is stateful. I had to duplicate in the mocks for testing.
1 parent b6e0512 commit b0019b4

8 files changed

+136
-18
lines changed

packages/react-native-renderer/src/ReactFabricRenderer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type {
1818
import {mountSafeCallback, warnForStyleProps} from './NativeMethodsMixinUtils';
1919
import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
2020
import * as ReactNativeFrameScheduling from './ReactNativeFrameScheduling';
21-
import * as ReactNativeViewConfigRegistry from './ReactNativeViewConfigRegistry';
21+
import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
2222
import ReactFiberReconciler from 'react-reconciler';
2323

2424
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';

packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
accumulateTwoPhaseDispatches,
1313
accumulateDirectDispatches,
1414
} from 'events/EventPropagators';
15-
import * as ReactNativeViewConfigRegistry from './ReactNativeViewConfigRegistry';
15+
import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
1616
import SyntheticEvent from 'events/SyntheticEvent';
1717
import invariant from 'fbjs/lib/invariant';
1818

packages/react-native-renderer/src/ReactNativeFiberRenderer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import invariant from 'fbjs/lib/invariant';
1616
import UIManager from 'UIManager';
1717
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
1818

19-
import * as ReactNativeViewConfigRegistry from './ReactNativeViewConfigRegistry';
19+
import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
2020
import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
2121
import {
2222
precacheFiberNode,

packages/react-native-renderer/src/ReactNativeViewConfigRegistry.js renamed to packages/react-native-renderer/src/__mocks__/ReactNativeViewConfigRegistry.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,23 @@
66
*
77
* @flow
88
*/
9+
'use strict';
910

1011
import type {
1112
ReactNativeBaseComponentViewConfig,
1213
ViewConfigGetter,
1314
} from './ReactNativeTypes';
1415

15-
import invariant from 'fbjs/lib/invariant';
16+
const invariant = require('fbjs/lib/invariant');
1617

1718
// Event configs
18-
export const customBubblingEventTypes = {};
19-
export const customDirectEventTypes = {};
20-
export const eventTypes = {};
19+
const customBubblingEventTypes = {};
20+
const customDirectEventTypes = {};
21+
const eventTypes = {};
22+
23+
exports.customBubblingEventTypes = customBubblingEventTypes;
24+
exports.customDirectEventTypes = customDirectEventTypes;
25+
exports.eventTypes = eventTypes;
2126

2227
const viewConfigCallbacks = new Map();
2328
const viewConfigs = new Map();
@@ -64,22 +69,22 @@ function processEventTypes(
6469
* The callback is deferred until the view is actually rendered.
6570
* This is done to avoid causing Prepack deopts.
6671
*/
67-
export function register(name: string, callback: ViewConfigGetter): string {
72+
exports.register = function(name: string, callback: ViewConfigGetter): string {
6873
invariant(
6974
!viewConfigCallbacks.has(name),
7075
'Tried to register two views with the same name %s',
7176
name,
7277
);
7378
viewConfigCallbacks.set(name, callback);
7479
return name;
75-
}
80+
};
7681

7782
/**
7883
* Retrieves a config for the specified view.
7984
* If this is the first time the view has been used,
8085
* This configuration will be lazy-loaded from UIManager.
8186
*/
82-
export function get(name: string): ReactNativeBaseComponentViewConfig {
87+
exports.get = function(name: string): ReactNativeBaseComponentViewConfig {
8388
let viewConfig;
8489
if (!viewConfigs.has(name)) {
8590
const callback = viewConfigCallbacks.get(name);
@@ -97,4 +102,4 @@ export function get(name: string): ReactNativeBaseComponentViewConfig {
97102
}
98103
invariant(viewConfig, 'View config not found for name %s', name);
99104
return viewConfig;
100-
}
105+
};

packages/react-native-renderer/src/createReactNativeComponentClass.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import type {ViewConfigGetter} from './ReactNativeTypes';
1111

12-
import {register} from './ReactNativeViewConfigRegistry';
12+
import {register} from 'ReactNativeViewConfigRegistry';
1313

1414
/**
1515
* Creates a renderable ReactNative host component.

scripts/flow/react-native-host-hooks.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99

1010
/* eslint-disable */
1111

12+
import type {
13+
ReactNativeBaseComponentViewConfig,
14+
ViewConfigGetter,
15+
} from 'react-native-renderer/src/ReactNativeTypes';
16+
1217
declare module 'deepDiffer' {
1318
declare module.exports: (one: any, two: any) => boolean;
1419
}
@@ -142,11 +147,11 @@ declare module 'BatchedBridge' {
142147
declare function registerCallableModule(name: string, module: Object): void;
143148
}
144149

145-
declare module 'CSComponent' {
146-
declare type Element = any;
147-
declare type Options<Instance> = any;
148-
}
150+
declare module 'ReactNativeViewConfigRegistry' {
151+
declare var customBubblingEventTypes: Object;
152+
declare var customDirectEventTypes: Object;
153+
declare var eventTypes: Object;
149154

150-
declare module 'CSStatefulComponent' {
151-
declare function CSStatefulComponent(spec: any): any;
155+
declare function register(name: string, callback: ViewConfigGetter): string;
156+
declare function get(name: string): ReactNativeBaseComponentViewConfig;
152157
}

scripts/rollup/bundles.js

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ const bundles = [
128128
'deepDiffer',
129129
'deepFreezeAndThrowOnMutationInDev',
130130
'flattenStyle',
131+
'ReactNativeViewConfigRegistry',
131132
],
132133
},
133134

@@ -150,6 +151,7 @@ const bundles = [
150151
'deepDiffer',
151152
'deepFreezeAndThrowOnMutationInDev',
152153
'flattenStyle',
154+
'ReactNativeViewConfigRegistry',
153155
],
154156
},
155157

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @providesModule ReactNativeViewConfigRegistry
8+
* @flow
9+
*/
10+
'use strict';
11+
12+
import type {
13+
ReactNativeBaseComponentViewConfig,
14+
ViewConfigGetter,
15+
} from './ReactNativeTypes';
16+
17+
const invariant = require('fbjs/lib/invariant');
18+
19+
// Event configs
20+
const customBubblingEventTypes = {};
21+
const customDirectEventTypes = {};
22+
const eventTypes = {};
23+
24+
exports.customBubblingEventTypes = customBubblingEventTypes;
25+
exports.customDirectEventTypes = customDirectEventTypes;
26+
exports.eventTypes = eventTypes;
27+
28+
const viewConfigCallbacks = new Map();
29+
const viewConfigs = new Map();
30+
31+
function processEventTypes(
32+
viewConfig: ReactNativeBaseComponentViewConfig,
33+
): void {
34+
const {bubblingEventTypes, directEventTypes} = viewConfig;
35+
36+
if (__DEV__) {
37+
if (bubblingEventTypes != null && directEventTypes != null) {
38+
for (const topLevelType in directEventTypes) {
39+
invariant(
40+
bubblingEventTypes[topLevelType] == null,
41+
'Event cannot be both direct and bubbling: %s',
42+
topLevelType,
43+
);
44+
}
45+
}
46+
}
47+
48+
if (bubblingEventTypes != null) {
49+
for (const topLevelType in bubblingEventTypes) {
50+
if (customBubblingEventTypes[topLevelType] == null) {
51+
eventTypes[topLevelType] = customBubblingEventTypes[topLevelType] =
52+
bubblingEventTypes[topLevelType];
53+
}
54+
}
55+
}
56+
57+
if (directEventTypes != null) {
58+
for (const topLevelType in directEventTypes) {
59+
if (customDirectEventTypes[topLevelType] == null) {
60+
eventTypes[topLevelType] = customDirectEventTypes[topLevelType] =
61+
directEventTypes[topLevelType];
62+
}
63+
}
64+
}
65+
}
66+
67+
/**
68+
* Registers a native view/component by name.
69+
* A callback is provided to load the view config from UIManager.
70+
* The callback is deferred until the view is actually rendered.
71+
* This is done to avoid causing Prepack deopts.
72+
*/
73+
exports.register = function(name: string, callback: ViewConfigGetter): string {
74+
invariant(
75+
!viewConfigCallbacks.has(name),
76+
'Tried to register two views with the same name %s',
77+
name,
78+
);
79+
viewConfigCallbacks.set(name, callback);
80+
return name;
81+
};
82+
83+
/**
84+
* Retrieves a config for the specified view.
85+
* If this is the first time the view has been used,
86+
* This configuration will be lazy-loaded from UIManager.
87+
*/
88+
exports.get = function(name: string): ReactNativeBaseComponentViewConfig {
89+
let viewConfig;
90+
if (!viewConfigs.has(name)) {
91+
const callback = viewConfigCallbacks.get(name);
92+
invariant(
93+
typeof callback === 'function',
94+
'View config not found for name %s',
95+
name,
96+
);
97+
viewConfigCallbacks.set(name, null);
98+
viewConfig = callback();
99+
processEventTypes(viewConfig);
100+
viewConfigs.set(name, viewConfig);
101+
} else {
102+
viewConfig = viewConfigs.get(name);
103+
}
104+
invariant(viewConfig, 'View config not found for name %s', name);
105+
return viewConfig;
106+
};

0 commit comments

Comments
 (0)