-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathindex.js
78 lines (69 loc) · 1.99 KB
/
index.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
/**
* External dependencies
*/
import { every, isEqual } from 'lodash';
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';
import isShallowEqual from '@wordpress/is-shallow-equal';
export default ( mapNodeToProps, computeWhenChange ) => createHigherOrderComponent(
( WrappedComponent ) => {
return class extends Component {
constructor() {
super( ...arguments );
this.nodeRef = this.props.node;
this.state = {
fallbackStyles: undefined,
grabStylesCompleted: false,
};
this.shouldRecomputeValues = this.shouldRecomputeValues().bind( this );
this.bindRef = this.bindRef.bind( this );
}
bindRef( node ) {
if ( ! node ) {
return;
}
this.nodeRef = node;
}
componentDidMount() {
this.grabFallbackStyles();
}
componentDidUpdate() {
this.grabFallbackStyles();
}
shouldRecomputeValues() {
let lastRecomputeValues = [];
return () => {
if ( ! computeWhenChange ) {
return ! this.state.grabStylesCompleted;
}
const newRecomputeValues = computeWhenChange( this.props );
if ( isShallowEqual( lastRecomputeValues, newRecomputeValues ) ) {
return false;
}
lastRecomputeValues = newRecomputeValues;
return true;
};
}
grabFallbackStyles() {
const { fallbackStyles } = this.state;
if ( this.nodeRef && this.shouldRecomputeValues() ) {
const newFallbackStyles = mapNodeToProps( this.nodeRef, this.props );
if ( ! isEqual( newFallbackStyles, fallbackStyles ) ) {
this.setState( {
fallbackStyles: newFallbackStyles,
grabStylesCompleted: !! every( newFallbackStyles ),
} );
}
}
}
render() {
const wrappedComponent = <WrappedComponent { ...this.props } { ...this.state.fallbackStyles } />;
return this.props.node ? wrappedComponent : <div ref={ this.bindRef }> { wrappedComponent } </div>;
}
};
},
'withFallbackStyles'
);