-
Notifications
You must be signed in to change notification settings - Fork 192
/
listener.js
127 lines (112 loc) · 3.78 KB
/
listener.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
var Promise = require('bluebird')
var React = require('react')
var PT = React.PropTypes
module.exports = function (options) {
if ('function' === typeof options) {
options = {
storeAttrs: options,
}
}
var pluginUpdates = []
var plugin = {
propTypes: {
store: PT.object.isRequired,
},
getInitialState: function () {
var state = options.storeAttrs.call(this, this.props.store.getters, this.props)
var extra
if (options.initStoreState) {
extra = options.initStoreState.call(this, state, this.props.store.getters, this.props)
for (var name in extra) state[name] = extra[name]
}
for (var i=0; i<pluginUpdates.length; i++) {
extra = pluginUpdates[i].call(this, state, this.props.store.getters, this.props)
for (name in extra) state[name] = extra[name]
}
return state
},
listen: function () {
var changes = [].slice.call(arguments)
if (arguments.length === 1 && Array.isArray(arguments[0])) {
changes = arguments[0]
}
pluginUpdates = []
if (this.props.plugins) {
this.props.plugins.forEach((plugin) => {
if (!plugin.listener) return
if (plugin.listener.updateStoreState) {
pluginUpdates.push(plugin.listener.updateStoreState)
}
if (plugin.listener.changes) {
changes = changes.concat(plugin.listener.changes)
}
})
}
this.props.store.on(changes, this._gotChanges)
// save it for later so we can remove the listener on unmount
if (!this._flux) this._flux = []
this._flux.push([changes, this._gotChanges])
},
_gotChanges: function () {
// if DEBUG
var state = options.storeAttrs.call(this, this.props.store.getters, this.props)
var extra, name
if (options.updateStoreState) {
extra = options.updateStoreState.call(this, state, this.props.store.getters, this.props)
for (name in extra) state[name] = extra[name]
}
for (var i=0; i<pluginUpdates.length; i++) {
extra = pluginUpdates[i].call(this, state, this.props.store.getters, this.props)
for (name in extra) state[name] = extra[name]
}
if (window.DEBUG_CHANGES) {
console.log('got changes', state)
}
var p = Promise.pending()
this.setState(state, function () {
p.resolve()
})
return p
},
_stopListening: function (store) {
store = store || this.props.store
for (var i=0; i<this._flux.length; i++) {
store.off(this._flux[i][0], this._flux[i][1])
}
this._flux = null
},
componentWillUnmount: function () {
if (!this._flux) return
this._stopListening()
},
}
if (options.shouldGetNew) {
plugin.componentWillReceiveProps = function (nextProps) {
if (options.shouldGetNew.call(this, nextProps)) {
if (options.getListeners) {
this._stopListening()
this.listen(options.getListeners(nextProps, nextProps.store.events))
}
var state = options.storeAttrs.call(this, nextProps.store.getters, nextProps)
var extra
if (options.initStoreState) {
extra = options.initStoreState.call(this, state, nextProps.store.getters, nextProps)
for (var name in extra) state[name] = extra[name]
}
this.setState(state)
}
}
}
if (options.getListeners) {
plugin.componentWillMount = function () {
this.listen(options.getListeners(this.props, this.props.store.events))
}
plugin.componentDidUpdate = function (prevProps) {
if (this.props.store !== prevProps.store) {
this._stopListening(prevProps.store)
this.listen(options.getListeners(this.props, this.props.store.events))
}
}
}
return plugin
}