1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | 'use strict';
|
14 |
|
15 | import type {
|
16 | ReactNativeBaseComponentViewConfig,
|
17 | ViewConfigGetter,
|
18 | } from './ReactNativeTypes';
|
19 |
|
20 | const invariant = require('invariant');
|
21 |
|
22 |
|
23 | const customBubblingEventTypes: $TEMPORARY$object<{||}> = {};
|
24 | const customDirectEventTypes: $TEMPORARY$object<{||}> = {};
|
25 |
|
26 | exports.customBubblingEventTypes = customBubblingEventTypes;
|
27 | exports.customDirectEventTypes = customDirectEventTypes;
|
28 |
|
29 | const viewConfigCallbacks = new Map();
|
30 | const viewConfigs = new Map();
|
31 |
|
32 | function processEventTypes(
|
33 | viewConfig: ReactNativeBaseComponentViewConfig<>,
|
34 | ): void {
|
35 | const {bubblingEventTypes, directEventTypes} = viewConfig;
|
36 |
|
37 | if (__DEV__) {
|
38 | if (bubblingEventTypes != null && directEventTypes != null) {
|
39 | for (const topLevelType in directEventTypes) {
|
40 | invariant(
|
41 | bubblingEventTypes[topLevelType] == null,
|
42 | 'Event cannot be both direct and bubbling: %s',
|
43 | topLevelType,
|
44 | );
|
45 | }
|
46 | }
|
47 | }
|
48 |
|
49 | if (bubblingEventTypes != null) {
|
50 | for (const topLevelType in bubblingEventTypes) {
|
51 | if (customBubblingEventTypes[topLevelType] == null) {
|
52 | customBubblingEventTypes[topLevelType] =
|
53 | bubblingEventTypes[topLevelType];
|
54 | }
|
55 | }
|
56 | }
|
57 |
|
58 | if (directEventTypes != null) {
|
59 | for (const topLevelType in directEventTypes) {
|
60 | if (customDirectEventTypes[topLevelType] == null) {
|
61 | customDirectEventTypes[topLevelType] = directEventTypes[topLevelType];
|
62 | }
|
63 | }
|
64 | }
|
65 | }
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | exports.register = function(name: string, callback: ViewConfigGetter): string {
|
73 | invariant(
|
74 | !viewConfigCallbacks.has(name),
|
75 | 'Tried to register two views with the same name %s',
|
76 | name,
|
77 | );
|
78 | viewConfigCallbacks.set(name, callback);
|
79 | return name;
|
80 | };
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 | exports.get = function(name: string): ReactNativeBaseComponentViewConfig<> {
|
88 | let viewConfig;
|
89 | if (!viewConfigs.has(name)) {
|
90 | const callback = viewConfigCallbacks.get(name);
|
91 | if (typeof callback !== 'function') {
|
92 | invariant(
|
93 | false,
|
94 | 'View config not found for name %s.%s',
|
95 | name,
|
96 | typeof name[0] === 'string' && /[a-z]/.test(name[0])
|
97 | ? ' Make sure to start component names with a capital letter.'
|
98 | : '',
|
99 | );
|
100 | }
|
101 | viewConfigCallbacks.set(name, null);
|
102 | viewConfig = callback();
|
103 | processEventTypes(viewConfig);
|
104 | viewConfigs.set(name, viewConfig);
|
105 | } else {
|
106 | viewConfig = viewConfigs.get(name);
|
107 | }
|
108 | invariant(viewConfig, 'View config not found for name %s', name);
|
109 | return viewConfig;
|
110 | };
|