Permalink
Newer
100644
217 lines (181 sloc)
5.25 KB
2
* Copyright (C) 2016 Maxime Petazzoni <maxime.petazzoni@bulix.org>.
3
* All rights reserved.
11
this.INITIALIZING = -1;
12
this.CONNECTING = 0;
13
this.OPEN = 1;
14
this.CLOSED = 2;
15
16
this.url = url;
17
18
options = options || {};
19
this.headers = options.headers || {};
33
if (this.listeners[type] === undefined) {
34
this.listeners[type] = [];
35
}
36
37
if (this.listeners[type].indexOf(listener) === -1) {
38
this.listeners[type].push(listener);
39
}
42
this.removeEventListener = function(type, listener) {
43
if (this.listeners[type] === undefined) {
47
var filtered = [];
48
this.listeners[type].forEach(function(element) {
49
if (element !== listener) {
50
filtered.push(element);
51
}
52
});
53
if (filtered.length === 0) {
54
delete this.listeners[type];
55
} else {
56
this.listeners[type] = filtered;
57
}
66
67
var onHandler = 'on' + e.type;
68
if (this.hasOwnProperty(onHandler)) {
69
this[onHandler].call(this, e);
70
if (e.defaultPrevented) {
71
return false;
72
}
73
}
74
75
if (this.listeners[e.type]) {
76
return this.listeners[e.type].every(function(callback) {
77
callback(e);
78
return !e.defaultPrevented;
79
});
80
}
81
82
return true;
83
};
84
87
event.readyState = state;
88
this.readyState = state;
89
this.dispatchEvent(event);
90
};
91
92
this._onStreamFailure = function(e) {
99
this._onStreamAbort = function(e) {
100
this.dispatchEvent(new CustomEvent('abort'));
101
this.close();
102
}
103
110
this._onStreamFailure(e);
111
return;
112
}
113
114
if (this.readyState == this.CONNECTING) {
121
data.split(/(\r\n|\r|\n){2}/g).forEach(function(part) {
122
if (part.trim().length === 0) {
123
this.dispatchEvent(this._parseEventChunk(this.chunk.trim()));
124
this.chunk = '';
129
};
130
131
this._onStreamLoaded = function(e) {
132
this._onStreamProgress(e);
133
134
// Parse the last chunk.
135
this.dispatchEvent(this._parseEventChunk(this.chunk));
136
this.chunk = '';
137
};
138
139
/**
140
* Parse a received SSE event chunk into a constructed event object.
141
*/
142
this._parseEventChunk = function(chunk) {
144
return null;
145
}
146
147
var e = {'id': null, 'retry': null, 'data': '', 'event': 'message'};
151
if (index <= 0) {
152
// Line was either empty, or started with a separator and is a comment.
153
// Either way, ignore.
154
return;
155
}
156
157
var field = line.substring(0, index);
158
if (!(field in e)) {
159
return;
160
}
161
162
var value = line.substring(index + 1).trimLeft();
163
if (field === 'data') {
164
e[field] += value;
165
} else {
166
e[field] = value;
167
}
177
if (!this.xhr) {
178
return;
179
}
180
181
if (this.xhr.readyState === XMLHttpRequest.DONE) {
192
this.xhr.addEventListener('readystatechange', this._checkStreamClosed.bind(this));
195
this.xhr.open(this.method, this.url);
196
for (var header in this.headers) {
197
this.xhr.setRequestHeader(header, this.headers[header]);
198
}
205
return;
206
}
207
208
this.xhr.abort();
209
this.xhr = null;
210
this._setReadyState(this.CLOSED);
211
};
212
};
213
214
// Export our SSE module for npm.js