Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81152 views
1
/**
2
* Copyright 2013-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 ReactPropTransferer
10
*/
11
12
"use strict";
13
14
var assign = require('Object.assign');
15
var emptyFunction = require('emptyFunction');
16
var invariant = require('invariant');
17
var joinClasses = require('joinClasses');
18
var warning = require('warning');
19
20
var didWarn = false;
21
22
/**
23
* Creates a transfer strategy that will merge prop values using the supplied
24
* `mergeStrategy`. If a prop was previously unset, this just sets it.
25
*
26
* @param {function} mergeStrategy
27
* @return {function}
28
*/
29
function createTransferStrategy(mergeStrategy) {
30
return function(props, key, value) {
31
if (!props.hasOwnProperty(key)) {
32
props[key] = value;
33
} else {
34
props[key] = mergeStrategy(props[key], value);
35
}
36
};
37
}
38
39
var transferStrategyMerge = createTransferStrategy(function(a, b) {
40
// `merge` overrides the first object's (`props[key]` above) keys using the
41
// second object's (`value`) keys. An object's style's existing `propA` would
42
// get overridden. Flip the order here.
43
return assign({}, b, a);
44
});
45
46
/**
47
* Transfer strategies dictate how props are transferred by `transferPropsTo`.
48
* NOTE: if you add any more exceptions to this list you should be sure to
49
* update `cloneWithProps()` accordingly.
50
*/
51
var TransferStrategies = {
52
/**
53
* Never transfer `children`.
54
*/
55
children: emptyFunction,
56
/**
57
* Transfer the `className` prop by merging them.
58
*/
59
className: createTransferStrategy(joinClasses),
60
/**
61
* Transfer the `style` prop (which is an object) by merging them.
62
*/
63
style: transferStrategyMerge
64
};
65
66
/**
67
* Mutates the first argument by transferring the properties from the second
68
* argument.
69
*
70
* @param {object} props
71
* @param {object} newProps
72
* @return {object}
73
*/
74
function transferInto(props, newProps) {
75
for (var thisKey in newProps) {
76
if (!newProps.hasOwnProperty(thisKey)) {
77
continue;
78
}
79
80
var transferStrategy = TransferStrategies[thisKey];
81
82
if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) {
83
transferStrategy(props, thisKey, newProps[thisKey]);
84
} else if (!props.hasOwnProperty(thisKey)) {
85
props[thisKey] = newProps[thisKey];
86
}
87
}
88
return props;
89
}
90
91
/**
92
* ReactPropTransferer are capable of transferring props to another component
93
* using a `transferPropsTo` method.
94
*
95
* @class ReactPropTransferer
96
*/
97
var ReactPropTransferer = {
98
99
TransferStrategies: TransferStrategies,
100
101
/**
102
* Merge two props objects using TransferStrategies.
103
*
104
* @param {object} oldProps original props (they take precedence)
105
* @param {object} newProps new props to merge in
106
* @return {object} a new object containing both sets of props merged.
107
*/
108
mergeProps: function(oldProps, newProps) {
109
return transferInto(assign({}, oldProps), newProps);
110
},
111
112
/**
113
* @lends {ReactPropTransferer.prototype}
114
*/
115
Mixin: {
116
117
/**
118
* Transfer props from this component to a target component.
119
*
120
* Props that do not have an explicit transfer strategy will be transferred
121
* only if the target component does not already have the prop set.
122
*
123
* This is usually used to pass down props to a returned root component.
124
*
125
* @param {ReactElement} element Component receiving the properties.
126
* @return {ReactElement} The supplied `component`.
127
* @final
128
* @protected
129
*/
130
transferPropsTo: function(element) {
131
invariant(
132
element._owner === this,
133
'%s: You can\'t call transferPropsTo() on a component that you ' +
134
'don\'t own, %s. This usually means you are calling ' +
135
'transferPropsTo() on a component passed in as props or children.',
136
this.constructor.displayName,
137
typeof element.type === 'string' ?
138
element.type :
139
element.type.displayName
140
);
141
142
if (__DEV__) {
143
if (!didWarn) {
144
didWarn = true;
145
warning(
146
false,
147
'transferPropsTo is deprecated. ' +
148
'See http://fb.me/react-transferpropsto for more information.'
149
);
150
}
151
}
152
153
// Because elements are immutable we have to merge into the existing
154
// props object rather than clone it.
155
transferInto(element.props, this.props);
156
157
return element;
158
}
159
160
}
161
};
162
163
module.exports = ReactPropTransferer;
164
165