Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81152 views
1
/**
2
* Copyright 2014, 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 ReactLegacyElement
10
*/
11
12
"use strict";
13
14
var ReactCurrentOwner = require('ReactCurrentOwner');
15
16
var invariant = require('invariant');
17
var monitorCodeUse = require('monitorCodeUse');
18
var warning = require('warning');
19
20
var legacyFactoryLogs = {};
21
function warnForLegacyFactoryCall() {
22
if (!ReactLegacyElementFactory._isLegacyCallWarningEnabled) {
23
return;
24
}
25
var owner = ReactCurrentOwner.current;
26
var name = owner && owner.constructor ? owner.constructor.displayName : '';
27
if (!name) {
28
name = 'Something';
29
}
30
if (legacyFactoryLogs.hasOwnProperty(name)) {
31
return;
32
}
33
legacyFactoryLogs[name] = true;
34
warning(
35
false,
36
name + ' is calling a React component directly. ' +
37
'Use a factory or JSX instead. See: http://fb.me/react-legacyfactory'
38
);
39
monitorCodeUse('react_legacy_factory_call', { version: 3, name: name });
40
}
41
42
function warnForPlainFunctionType(type) {
43
var isReactClass =
44
type.prototype &&
45
typeof type.prototype.mountComponent === 'function' &&
46
typeof type.prototype.receiveComponent === 'function';
47
if (isReactClass) {
48
warning(
49
false,
50
'Did not expect to get a React class here. Use `Component` instead ' +
51
'of `Component.type` or `this.constructor`.'
52
);
53
} else {
54
if (!type._reactWarnedForThisType) {
55
try {
56
type._reactWarnedForThisType = true;
57
} catch (x) {
58
// just incase this is a frozen object or some special object
59
}
60
monitorCodeUse(
61
'react_non_component_in_jsx',
62
{ version: 3, name: type.name }
63
);
64
}
65
warning(
66
false,
67
'This JSX uses a plain function. Only React components are ' +
68
'valid in React\'s JSX transform.'
69
);
70
}
71
}
72
73
function warnForNonLegacyFactory(type) {
74
warning(
75
false,
76
'Do not pass React.DOM.' + type.type + ' to JSX or createFactory. ' +
77
'Use the string "' + type.type + '" instead.'
78
);
79
}
80
81
/**
82
* Transfer static properties from the source to the target. Functions are
83
* rebound to have this reflect the original source.
84
*/
85
function proxyStaticMethods(target, source) {
86
if (typeof source !== 'function') {
87
return;
88
}
89
for (var key in source) {
90
if (source.hasOwnProperty(key)) {
91
var value = source[key];
92
if (typeof value === 'function') {
93
var bound = value.bind(source);
94
// Copy any properties defined on the function, such as `isRequired` on
95
// a PropTypes validator.
96
for (var k in value) {
97
if (value.hasOwnProperty(k)) {
98
bound[k] = value[k];
99
}
100
}
101
target[key] = bound;
102
} else {
103
target[key] = value;
104
}
105
}
106
}
107
}
108
109
// We use an object instead of a boolean because booleans are ignored by our
110
// mocking libraries when these factories gets mocked.
111
var LEGACY_MARKER = {};
112
var NON_LEGACY_MARKER = {};
113
114
var ReactLegacyElementFactory = {};
115
116
ReactLegacyElementFactory.wrapCreateFactory = function(createFactory) {
117
var legacyCreateFactory = function(type) {
118
if (typeof type !== 'function') {
119
// Non-function types cannot be legacy factories
120
return createFactory(type);
121
}
122
123
if (type.isReactNonLegacyFactory) {
124
// This is probably a factory created by ReactDOM we unwrap it to get to
125
// the underlying string type. It shouldn't have been passed here so we
126
// warn.
127
if (__DEV__) {
128
warnForNonLegacyFactory(type);
129
}
130
return createFactory(type.type);
131
}
132
133
if (type.isReactLegacyFactory) {
134
// This is probably a legacy factory created by ReactCompositeComponent.
135
// We unwrap it to get to the underlying class.
136
return createFactory(type.type);
137
}
138
139
if (__DEV__) {
140
warnForPlainFunctionType(type);
141
}
142
143
// Unless it's a legacy factory, then this is probably a plain function,
144
// that is expecting to be invoked by JSX. We can just return it as is.
145
return type;
146
};
147
return legacyCreateFactory;
148
};
149
150
ReactLegacyElementFactory.wrapCreateElement = function(createElement) {
151
var legacyCreateElement = function(type, props, children) {
152
if (typeof type !== 'function') {
153
// Non-function types cannot be legacy factories
154
return createElement.apply(this, arguments);
155
}
156
157
var args;
158
159
if (type.isReactNonLegacyFactory) {
160
// This is probably a factory created by ReactDOM we unwrap it to get to
161
// the underlying string type. It shouldn't have been passed here so we
162
// warn.
163
if (__DEV__) {
164
warnForNonLegacyFactory(type);
165
}
166
args = Array.prototype.slice.call(arguments, 0);
167
args[0] = type.type;
168
return createElement.apply(this, args);
169
}
170
171
if (type.isReactLegacyFactory) {
172
// This is probably a legacy factory created by ReactCompositeComponent.
173
// We unwrap it to get to the underlying class.
174
if (type._isMockFunction) {
175
// If this is a mock function, people will expect it to be called. We
176
// will actually call the original mock factory function instead. This
177
// future proofs unit testing that assume that these are classes.
178
type.type._mockedReactClassConstructor = type;
179
}
180
args = Array.prototype.slice.call(arguments, 0);
181
args[0] = type.type;
182
return createElement.apply(this, args);
183
}
184
185
if (__DEV__) {
186
warnForPlainFunctionType(type);
187
}
188
189
// This is being called with a plain function we should invoke it
190
// immediately as if this was used with legacy JSX.
191
return type.apply(null, Array.prototype.slice.call(arguments, 1));
192
};
193
return legacyCreateElement;
194
};
195
196
ReactLegacyElementFactory.wrapFactory = function(factory) {
197
invariant(
198
typeof factory === 'function',
199
'This is suppose to accept a element factory'
200
);
201
var legacyElementFactory = function(config, children) {
202
// This factory should not be called when JSX is used. Use JSX instead.
203
if (__DEV__) {
204
warnForLegacyFactoryCall();
205
}
206
return factory.apply(this, arguments);
207
};
208
proxyStaticMethods(legacyElementFactory, factory.type);
209
legacyElementFactory.isReactLegacyFactory = LEGACY_MARKER;
210
legacyElementFactory.type = factory.type;
211
return legacyElementFactory;
212
};
213
214
// This is used to mark a factory that will remain. E.g. we're allowed to call
215
// it as a function. However, you're not suppose to pass it to createElement
216
// or createFactory, so it will warn you if you do.
217
ReactLegacyElementFactory.markNonLegacyFactory = function(factory) {
218
factory.isReactNonLegacyFactory = NON_LEGACY_MARKER;
219
return factory;
220
};
221
222
// Checks if a factory function is actually a legacy factory pretending to
223
// be a class.
224
ReactLegacyElementFactory.isValidFactory = function(factory) {
225
// TODO: This will be removed and moved into a class validator or something.
226
return typeof factory === 'function' &&
227
factory.isReactLegacyFactory === LEGACY_MARKER;
228
};
229
230
ReactLegacyElementFactory.isValidClass = function(factory) {
231
if (__DEV__) {
232
warning(
233
false,
234
'isValidClass is deprecated and will be removed in a future release. ' +
235
'Use a more specific validator instead.'
236
);
237
}
238
return ReactLegacyElementFactory.isValidFactory(factory);
239
};
240
241
ReactLegacyElementFactory._isLegacyCallWarningEnabled = true;
242
243
module.exports = ReactLegacyElementFactory;
244
245