/
hoist.js
105 lines (88 loc) 路 2.31 KB
/
hoist.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// @flow
/**
* This is a modified version of hoist-non-react-statics v3.
* BSD License: https://github.com/mridgway/hoist-non-react-statics/blob/master/LICENSE.md
*/
import { ForwardRef } from 'react-is'
const REACT_STATICS = {
childContextTypes: true,
contextTypes: true,
defaultProps: true,
displayName: true,
getDerivedStateFromProps: true,
propTypes: true,
type: true,
}
const KNOWN_STATICS = {
name: true,
length: true,
prototype: true,
caller: true,
callee: true,
arguments: true,
arity: true,
}
const TYPE_STATICS = {
[ForwardRef]: {
$$typeof: true,
render: true,
},
}
const {
defineProperty,
getOwnPropertyNames,
getOwnPropertySymbols = () => [],
getOwnPropertyDescriptor,
getPrototypeOf,
prototype: objectPrototype,
} = Object
const { prototype: arrayPrototype } = Array
export default function hoistNonReactStatics(
targetComponent: any,
sourceComponent: any,
blacklist: ?Object
): any {
if (typeof sourceComponent !== 'string') {
// don't hoist over string (html) components
const inheritedComponent = getPrototypeOf(sourceComponent)
if (inheritedComponent && inheritedComponent !== objectPrototype) {
hoistNonReactStatics(targetComponent, inheritedComponent, blacklist)
}
const keys = arrayPrototype.concat(
getOwnPropertyNames(sourceComponent),
// $FlowFixMe
getOwnPropertySymbols(sourceComponent)
)
const targetStatics =
TYPE_STATICS[targetComponent.$$typeof] || REACT_STATICS
const sourceStatics =
TYPE_STATICS[sourceComponent.$$typeof] || REACT_STATICS
let i = keys.length
let descriptor
let key
// eslint-disable-next-line no-plusplus
while (i--) {
key = keys[i]
if (
// $FlowFixMe
!KNOWN_STATICS[key] &&
!(blacklist && blacklist[key]) &&
!(sourceStatics && sourceStatics[key]) &&
// $FlowFixMe
!(targetStatics && targetStatics[key])
) {
descriptor = getOwnPropertyDescriptor(sourceComponent, key)
if (descriptor) {
try {
// Avoid failures from read-only properties
defineProperty(targetComponent, key, descriptor)
} catch (e) {
/* fail silently */
}
}
}
}
return targetComponent
}
return targetComponent
}