UNPKG

2.98 kBJavaScriptView Raw
1/**
2 * Copyright 2015, Yahoo! Inc.
3 * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4 */
5import { ForwardRef, Memo, isMemo } from 'react-is';
6
7const REACT_STATICS = {
8 childContextTypes: true,
9 contextType: true,
10 contextTypes: true,
11 defaultProps: true,
12 displayName: true,
13 getDefaultProps: true,
14 getDerivedStateFromError: true,
15 getDerivedStateFromProps: true,
16 mixins: true,
17 propTypes: true,
18 type: true
19};
20
21const KNOWN_STATICS = {
22 name: true,
23 length: true,
24 prototype: true,
25 caller: true,
26 callee: true,
27 arguments: true,
28 arity: true
29};
30
31const FORWARD_REF_STATICS = {
32 '$$typeof': true,
33 render: true,
34 defaultProps: true,
35 displayName: true,
36 propTypes: true
37};
38
39const MEMO_STATICS = {
40 '$$typeof': true,
41 compare: true,
42 defaultProps: true,
43 displayName: true,
44 propTypes: true,
45 type: true,
46}
47
48const TYPE_STATICS = {};
49TYPE_STATICS[ForwardRef] = FORWARD_REF_STATICS;
50TYPE_STATICS[Memo] = MEMO_STATICS;
51
52function getStatics(component) {
53 // React v16.11 and below
54 if (isMemo(component)) {
55 return MEMO_STATICS;
56 }
57
58 // React v16.12 and above
59 return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;
60}
61
62const defineProperty = Object.defineProperty;
63const getOwnPropertyNames = Object.getOwnPropertyNames;
64const getOwnPropertySymbols = Object.getOwnPropertySymbols;
65const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
66const getPrototypeOf = Object.getPrototypeOf;
67const objectPrototype = Object.prototype;
68
69export default function hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {
70 if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components
71
72 if (objectPrototype) {
73 const inheritedComponent = getPrototypeOf(sourceComponent);
74 if (inheritedComponent && inheritedComponent !== objectPrototype) {
75 hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);
76 }
77 }
78
79 let keys = getOwnPropertyNames(sourceComponent);
80
81 if (getOwnPropertySymbols) {
82 keys = keys.concat(getOwnPropertySymbols(sourceComponent));
83 }
84
85 const targetStatics = getStatics(targetComponent);
86 const sourceStatics = getStatics(sourceComponent);
87
88 for (let i = 0; i < keys.length; ++i) {
89 const key = keys[i];
90 if (!KNOWN_STATICS[key] &&
91 !(blacklist && blacklist[key]) &&
92 !(sourceStatics && sourceStatics[key]) &&
93 !(targetStatics && targetStatics[key])
94 ) {
95 const descriptor = getOwnPropertyDescriptor(sourceComponent, key);
96 try { // Avoid failures from read-only properties
97 defineProperty(targetComponent, key, descriptor);
98 } catch (e) {}
99 }
100 }
101 }
102
103 return targetComponent;
104};