Use promise version of PluginInterface on the client
[KiwiIRC.git] / client / src / helpers / plugininterface.js
CommitLineData
060391b1
JA
1function PluginInterface() {
2 this.listeners = [];
2a89ba11
D
3}
4
060391b1
JA
5PluginInterface.prototype.on = PluginInterface.prototype.addListener = function addListener(type, listener) {
6 if (typeof listener !== 'function') {
7 throw new TypeError('listener must be a function');
8 }
2a89ba11 9
060391b1
JA
10 if (this.listeners[type]) {
11 if (!_.contains(this.listeners[type], listener)) {
12 this.listeners[type].push(listener);
2a89ba11
D
13 }
14 } else {
060391b1 15 this.listeners[type] = [listener];
2a89ba11 16 }
2a89ba11 17
060391b1 18 return this;
2a89ba11
D
19};
20
060391b1
JA
21PluginInterface.prototype.once = function once(type, listener) {
22 if (typeof listener !== 'function') {
23 throw new TypeError('listener must be a function');
2a89ba11
D
24 }
25
060391b1 26 var fired = false;
2a89ba11 27
060391b1
JA
28 function g() {
29 this.removeListener(type, g);
2a89ba11 30
060391b1
JA
31 if (!fired) {
32 fired = true;
33 listener.apply(this, arguments);
2a89ba11
D
34 }
35 }
36
060391b1
JA
37 g.listener = listener;
38 this.on(type, g);
2a89ba11 39
060391b1
JA
40 return this;
41};
2a89ba11 42
060391b1
JA
43PluginInterface.prototype.off = PluginInterface.prototype.removeListener = function removeListener(type, listener) {
44 if (!this.listeners[type]) {
2a89ba11
D
45 return this;
46 }
47
060391b1 48 this.listeners[type] = _.without(this.listeners[type], listener);
2a89ba11 49
060391b1
JA
50 return this;
51};
2a89ba11 52
060391b1
JA
53PluginInterface.prototype.emit = function emit(type, data) {
54 var that = this;
55 return new Promise(function (emit_resolve, emit_reject) {
56 var rejected = false,
57 rejected_reasons = [];
2a89ba11 58
060391b1
JA
59 if (!that.listeners[type]) {
60 return emit_resolve(data);
61 }
2a89ba11 62
060391b1
JA
63 (that.listeners[type].reduce(function (listener_promise, listener) {
64 return listener_promise.then(function (data) {
65 return new Promise(function (resolve) {
66 listener({
67 callback: function () {
68 resolve(data);
69 },
70 preventDefault: function (reason) {
71 rejected = true;
72 if (reason) {
73 rejected_reasons.push(reason);
74 }
75 }
76 }, data);
77 });
78 });
79 }, Promise.resolve(data))).then(function (data) {
80 if (rejected) {
81 emit_reject({data: data, reasons: rejected_reasons});
82 } else {
83 emit_resolve(data);
84 }
85 });
86 });
2a89ba11
D
87};
88
2a89ba11
D
89// If running a node module, set the exports
90if (typeof module === 'object' && typeof module.exports !== 'undefined') {
91 module.exports = PluginInterface;
92}
93
060391b1 94/* Test cases
2a89ba11 95
060391b1
JA
96var p = new PluginInterface();
97p.on('test', function (event, data) {
98 data.a += '!';
99 event.callback();
2a89ba11
D
100});
101
060391b1
JA
102p.emit('test', {a: 'hello world'}).then(function (data) {
103 if (data.a === 'hello world!') {
104 console.log('Test passed');
105 } else {
106 console.error('Test failed!');
107 }
108}, function (err) {
109 console.error('Test failed!');
110});
2a89ba11
D
111
112
060391b1
JA
113var p = new PluginInterface();
114p.on('test', function (event, data) {
115 data.a += '!';
116 event.callback();
2a89ba11 117});
060391b1
JA
118p.on('test', function (event) {
119 event.preventDefault('testing');
120 event.callback();
121})
122
123p.emit('test', {a:'hello world'}).then(function (){
124 console.error('Test failed!');
125}, function (data, reasons) {
126 if ((data.data.a === 'hello world!') && (data.reasons.length === 1 && data.reasons[0] === 'testing')) {
127 console.log('Test passed');
128 } else {
129 console.error('Test failed!');
130 }
131});
132
133*/