This repository has been archived by the owner on Mar 19, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index_src.js
148 lines (130 loc) · 5.12 KB
/
index_src.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
module.exports = RukusSignal;
function dots(obj) {
/* takes an object and returns a getter which takes a dot path, ie:
* var find = dots({'a' : { b : 'woo'}});
* find('a.b') -> 'woo'
*/
return function(path) {
return path.split('.').reduce(
function(prv, i) {
return prv !== null ? (prv[i] || null) : null;
}, obj);
};
}
function RukusSignal(RukusApp, riot) {
if(!RukusApp.__find) RukusApp.__find = dots(RukusApp);
let signalBox = this;
signalBox.counter = 0;
signalBox.controllers = {};
signalBox.views = {};
this.doc = function() {
return {};
};
this.init = function(obj) {
obj.__emits = {}; // Signals I can emit
obj.__accepts = {}; // Signals I'll accept
obj.__binds = {}; // Other's emits I want to bind to
obj.__invokes = {}; // Other's accepts I will invoke
if(!obj.on) riot.observable(obj); // ensure obj is observable
if(obj.root) {
// we're a view component
obj.__sigKind = 'view';
obj.__sigName = obj.root.tagName ||
'unkownComponent.'+ (++signalBox.counter);
signalBox.views[obj.__sigName] = obj;
// for view components, bind when we are mounted and unbind
// when we are unmounted:
obj.on('mount', () => {
Object.keys(obj.__binds).forEach(function(sigStr) {
let [path, sig] = sigStr.split(':');
let obs = RukusApp.__find(path);
if(!obs) return console.error(`cannot find ${path} to bind`);
obs.on(sig, obj.__binds[sigStr]);
});
});
obj.on('unmount', () => {
Object.keys(obj.__binds).forEach(function(sigStr) {
let [path, sig] = sigStr.split(':');
let obs = RukusApp.__find(path);
if(!obs) return console.error(`cannot find ${path} to unbind`);
obs.off(sig, obj.__binds[sigStr]);
});
});
} else {
// we're a controller / store
obj.__sigKind = 'controller';
obj.__sigName = ++signalBox.counter;
signalBox.controllers[obj.__sigName] = obj;
}
// our own signals that we will emit (public API)
// takes one or more:
//
// { signal : 'name',
// desc : 'sig description',
// data : 'data emitted description'
// }
obj.emits = (...signals) => {
signals.forEach(function(sig) {
obj.__emits[sig.signal] = sig;
});
};
// emits a signal defined with this.emits by name, optionally with data
obj.emit = (sigName, data) => {
if(!obj.__emits[sigName]) {
return console.error(
`${sigName} is not declared with this.emits()`);
}
obj.trigger(sigName, data);
};
// our own signals that we'll respond to (public API)
// takes one or more:
//
// { signal : 'name',
// desc : 'sig description',
// data : 'data accepted description',
// func : function to call
// }
obj.accepts = (...signals) => {
signals.forEach(function(sig) {
obj.__accepts[sig.signal] = sig;
obj.on(sig.signal, sig.func);
});
};
// Other's signals that we'll bind too, takes:
//
// { 'dot.path.under.RukusApp:signalName' : func }
obj.binds = (signals) => {
Object.keys(signals).forEach(function(sigPath) {
obj.__binds[sigPath] = signals[sigPath];
//If we are a controller, bind immediately, views will
//be bound and unbound when their tag is mounted and unmounted
if(obj.__sigKind == 'controller') {
let [path, sig] = sigPath.split(':');
let obs = RukusApp.__find(path);
if(!obs) return console.error(`cannot find ${path} to bind`);
obs.on(sig, signals[sigPath]);
}
});
};
// Other's 'accepts' that we'll invoke, takes:
//
// { 'localSignalName' : 'dot.path.under.RukusApp:signalName' }
obj.invokes = (signals) => {
Object.keys(signals).forEach(function(localName) {
obj.__invokes[localName] = signals[localName];
});
};
// Invoke something defined with this.invokes(), takes:
//
// localSignalName, optional data
obj.invoke = (sigName, ...data) => {
let sigPath = obj.__invokes[sigName];
if(!sigPath) console.error(`${sigName} not declared with this.invokes()`);
let [path, sig] = sigPath.split(':');
let obs = RukusApp.__find(path);
if(!obs) return console.error(`cannot find ${path} to invoke`);
console.log('triggering', sig, 'on ', obs);
obs.trigger(sig, ...data);
};
};
};