-
Notifications
You must be signed in to change notification settings - Fork 4k
/
provider.js
110 lines (91 loc) · 2.15 KB
/
provider.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
106
107
108
109
110
/**
* External dependencies
*/
import { pick, sortBy, forEach, without, noop } from 'lodash';
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
class SlotFillProvider extends Component {
constructor() {
super( ...arguments );
this.registerSlot = this.registerSlot.bind( this );
this.registerFill = this.registerFill.bind( this );
this.unregisterSlot = this.unregisterSlot.bind( this );
this.unregisterFill = this.unregisterFill.bind( this );
this.getSlot = this.getSlot.bind( this );
this.getFills = this.getFills.bind( this );
this.slots = {};
this.fills = {};
}
getChildContext() {
return pick( this, [
'registerSlot',
'registerFill',
'unregisterSlot',
'unregisterFill',
'getSlot',
'getFills',
] );
}
registerSlot( name, slot ) {
this.slots[ name ] = slot;
this.forceUpdateFills( name );
// Sometimes the fills are registered after the intial render of slot
// But before the registerSlot call, we need to rerender the slot
this.forceUpdateSlot( name );
}
registerFill( name, instance ) {
this.fills[ name ] = [
...( this.fills[ name ] || [] ),
instance,
];
this.forceUpdateSlot( name );
}
unregisterSlot( name ) {
delete this.slots[ name ];
this.forceUpdateFills( name );
}
unregisterFill( name, instance ) {
this.fills[ name ] = without(
this.fills[ name ],
instance
);
this.resetFillOccurrence( name );
this.forceUpdateSlot( name );
}
getSlot( name ) {
return this.slots[ name ];
}
getFills( name ) {
return sortBy( this.fills[ name ], 'occurrence' );
}
resetFillOccurrence( name ) {
forEach( this.fills[ name ], ( instance ) => {
instance.resetOccurrence();
} );
}
forceUpdateFills( name ) {
forEach( this.fills[ name ], ( instance ) => {
instance.forceUpdate();
} );
}
forceUpdateSlot( name ) {
const slot = this.getSlot( name );
if ( slot ) {
slot.forceUpdate();
}
}
render() {
return this.props.children;
}
}
SlotFillProvider.childContextTypes = {
registerSlot: noop,
unregisterSlot: noop,
registerFill: noop,
unregisterFill: noop,
getSlot: noop,
getFills: noop,
};
export default SlotFillProvider;