autobench 0.0.1alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +16 -0
- data/README.md +123 -0
- data/bin/autobench +180 -0
- data/bin/autobench-config +162 -0
- data/lib/autobench.rb +28 -0
- data/lib/autobench/client.rb +78 -0
- data/lib/autobench/common.rb +49 -0
- data/lib/autobench/config.rb +62 -0
- data/lib/autobench/render.rb +102 -0
- data/lib/autobench/version.rb +3 -0
- data/lib/autobench/yslow.rb +75 -0
- data/lib/phantomas/README.md +296 -0
- data/lib/phantomas/core/formatter.js +65 -0
- data/lib/phantomas/core/helper.js +64 -0
- data/lib/phantomas/core/modules/requestsMonitor/requestsMonitor.js +214 -0
- data/lib/phantomas/core/pads.js +16 -0
- data/lib/phantomas/core/phantomas.js +418 -0
- data/lib/phantomas/lib/args.js +27 -0
- data/lib/phantomas/lib/modules/_coffee-script.js +2 -0
- data/lib/phantomas/lib/modules/assert.js +326 -0
- data/lib/phantomas/lib/modules/events.js +216 -0
- data/lib/phantomas/lib/modules/http.js +55 -0
- data/lib/phantomas/lib/modules/path.js +441 -0
- data/lib/phantomas/lib/modules/punycode.js +510 -0
- data/lib/phantomas/lib/modules/querystring.js +214 -0
- data/lib/phantomas/lib/modules/tty.js +7 -0
- data/lib/phantomas/lib/modules/url.js +625 -0
- data/lib/phantomas/lib/modules/util.js +520 -0
- data/lib/phantomas/modules/ajaxRequests/ajaxRequests.js +15 -0
- data/lib/phantomas/modules/assetsTypes/assetsTypes.js +21 -0
- data/lib/phantomas/modules/cacheHits/cacheHits.js +28 -0
- data/lib/phantomas/modules/caching/caching.js +66 -0
- data/lib/phantomas/modules/cookies/cookies.js +54 -0
- data/lib/phantomas/modules/domComplexity/domComplexity.js +130 -0
- data/lib/phantomas/modules/domQueries/domQueries.js +148 -0
- data/lib/phantomas/modules/domains/domains.js +49 -0
- data/lib/phantomas/modules/globalVariables/globalVariables.js +44 -0
- data/lib/phantomas/modules/headers/headers.js +48 -0
- data/lib/phantomas/modules/localStorage/localStorage.js +14 -0
- data/lib/phantomas/modules/requestsStats/requestsStats.js +71 -0
- data/lib/phantomas/modules/staticAssets/staticAssets.js +40 -0
- data/lib/phantomas/modules/waterfall/waterfall.js +62 -0
- data/lib/phantomas/modules/windowPerformance/windowPerformance.js +36 -0
- data/lib/phantomas/package.json +27 -0
- data/lib/phantomas/phantomas.js +35 -0
- data/lib/phantomas/run-multiple.js +177 -0
- data/lib/yslow.js +5 -0
- metadata +135 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
/**
|
2
|
+
* Simple phantom.args parser
|
3
|
+
*/
|
4
|
+
exports.parse = function(args) {
|
5
|
+
var res = {};
|
6
|
+
args = args || [];
|
7
|
+
|
8
|
+
args.forEach(function(item) {
|
9
|
+
var idx = item.indexOf('='),
|
10
|
+
key, val;
|
11
|
+
|
12
|
+
// --foo
|
13
|
+
if (idx < 0) {
|
14
|
+
key = item.substring(2);
|
15
|
+
val = true;
|
16
|
+
}
|
17
|
+
// --foo=bar
|
18
|
+
else {
|
19
|
+
key = item.substring(2, idx);
|
20
|
+
val = item.substring(idx+1);
|
21
|
+
}
|
22
|
+
|
23
|
+
res[key] = val;
|
24
|
+
});
|
25
|
+
|
26
|
+
return res;
|
27
|
+
};
|
@@ -0,0 +1,326 @@
|
|
1
|
+
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
2
|
+
//
|
3
|
+
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
4
|
+
//
|
5
|
+
// Originally from narwhal.js (http://narwhaljs.org)
|
6
|
+
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
7
|
+
//
|
8
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
// of this software and associated documentation files (the 'Software'), to
|
10
|
+
// deal in the Software without restriction, including without limitation the
|
11
|
+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
12
|
+
// sell copies of the Software, and to permit persons to whom the Software is
|
13
|
+
// furnished to do so, subject to the following conditions:
|
14
|
+
//
|
15
|
+
// The above copyright notice and this permission notice shall be included in
|
16
|
+
// all copies or substantial portions of the Software.
|
17
|
+
//
|
18
|
+
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
22
|
+
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
// UTILITY
|
26
|
+
var util = require('util');
|
27
|
+
var pSlice = Array.prototype.slice;
|
28
|
+
|
29
|
+
// 1. The assert module provides functions that throw
|
30
|
+
// AssertionError's when particular conditions are not met. The
|
31
|
+
// assert module must conform to the following interface.
|
32
|
+
|
33
|
+
var assert = module.exports = ok;
|
34
|
+
|
35
|
+
// 2. The AssertionError is defined in assert.
|
36
|
+
// new assert.AssertionError({ message: message,
|
37
|
+
// actual: actual,
|
38
|
+
// expected: expected })
|
39
|
+
|
40
|
+
assert.AssertionError = function AssertionError(options) {
|
41
|
+
this.name = 'AssertionError';
|
42
|
+
this.message = options.message;
|
43
|
+
this.actual = options.actual;
|
44
|
+
this.expected = options.expected;
|
45
|
+
this.operator = options.operator;
|
46
|
+
var stackStartFunction = options.stackStartFunction || fail;
|
47
|
+
|
48
|
+
if (Error.captureStackTrace) {
|
49
|
+
Error.captureStackTrace(this, stackStartFunction);
|
50
|
+
}
|
51
|
+
};
|
52
|
+
util.inherits(assert.AssertionError, Error);
|
53
|
+
|
54
|
+
function replacer(key, value) {
|
55
|
+
if (value === undefined) {
|
56
|
+
return '' + value;
|
57
|
+
}
|
58
|
+
if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
|
59
|
+
return value.toString();
|
60
|
+
}
|
61
|
+
if (typeof value === 'function' || value instanceof RegExp) {
|
62
|
+
return value.toString();
|
63
|
+
}
|
64
|
+
return value;
|
65
|
+
}
|
66
|
+
|
67
|
+
function truncate(s, n) {
|
68
|
+
if (typeof s == 'string') {
|
69
|
+
return s.length < n ? s : s.slice(0, n);
|
70
|
+
} else {
|
71
|
+
return s;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
assert.AssertionError.prototype.toString = function() {
|
76
|
+
if (this.message) {
|
77
|
+
return [this.name + ':', this.message].join(' ');
|
78
|
+
} else {
|
79
|
+
return [
|
80
|
+
this.name + ':',
|
81
|
+
truncate(JSON.stringify(this.actual, replacer), 128),
|
82
|
+
this.operator,
|
83
|
+
truncate(JSON.stringify(this.expected, replacer), 128)
|
84
|
+
].join(' ');
|
85
|
+
}
|
86
|
+
};
|
87
|
+
|
88
|
+
// assert.AssertionError instanceof Error
|
89
|
+
|
90
|
+
assert.AssertionError.__proto__ = Error.prototype;
|
91
|
+
|
92
|
+
// At present only the three keys mentioned above are used and
|
93
|
+
// understood by the spec. Implementations or sub modules can pass
|
94
|
+
// other keys to the AssertionError's constructor - they will be
|
95
|
+
// ignored.
|
96
|
+
|
97
|
+
// 3. All of the following functions must throw an AssertionError
|
98
|
+
// when a corresponding condition is not met, with a message that
|
99
|
+
// may be undefined if not provided. All assertion methods provide
|
100
|
+
// both the actual and expected values to the assertion error for
|
101
|
+
// display purposes.
|
102
|
+
|
103
|
+
function fail(actual, expected, message, operator, stackStartFunction) {
|
104
|
+
throw new assert.AssertionError({
|
105
|
+
message: message,
|
106
|
+
actual: actual,
|
107
|
+
expected: expected,
|
108
|
+
operator: operator,
|
109
|
+
stackStartFunction: stackStartFunction
|
110
|
+
});
|
111
|
+
}
|
112
|
+
|
113
|
+
// EXTENSION! allows for well behaved errors defined elsewhere.
|
114
|
+
assert.fail = fail;
|
115
|
+
|
116
|
+
// 4. Pure assertion tests whether a value is truthy, as determined
|
117
|
+
// by !!guard.
|
118
|
+
// assert.ok(guard, message_opt);
|
119
|
+
// This statement is equivalent to assert.equal(true, guard,
|
120
|
+
// message_opt);. To test strictly for the value true, use
|
121
|
+
// assert.strictEqual(true, guard, message_opt);.
|
122
|
+
|
123
|
+
function ok(value, message) {
|
124
|
+
if (!!!value) fail(value, true, message, '==', assert.ok);
|
125
|
+
}
|
126
|
+
assert.ok = ok;
|
127
|
+
|
128
|
+
// 5. The equality assertion tests shallow, coercive equality with
|
129
|
+
// ==.
|
130
|
+
// assert.equal(actual, expected, message_opt);
|
131
|
+
|
132
|
+
assert.equal = function equal(actual, expected, message) {
|
133
|
+
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
|
134
|
+
};
|
135
|
+
|
136
|
+
// 6. The non-equality assertion tests for whether two objects are not equal
|
137
|
+
// with != assert.notEqual(actual, expected, message_opt);
|
138
|
+
|
139
|
+
assert.notEqual = function notEqual(actual, expected, message) {
|
140
|
+
if (actual == expected) {
|
141
|
+
fail(actual, expected, message, '!=', assert.notEqual);
|
142
|
+
}
|
143
|
+
};
|
144
|
+
|
145
|
+
// 7. The equivalence assertion tests a deep equality relation.
|
146
|
+
// assert.deepEqual(actual, expected, message_opt);
|
147
|
+
|
148
|
+
assert.deepEqual = function deepEqual(actual, expected, message) {
|
149
|
+
if (!_deepEqual(actual, expected)) {
|
150
|
+
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
|
151
|
+
}
|
152
|
+
};
|
153
|
+
|
154
|
+
function _deepEqual(actual, expected) {
|
155
|
+
// 7.1. All identical values are equivalent, as determined by ===.
|
156
|
+
if (actual === expected) {
|
157
|
+
return true;
|
158
|
+
|
159
|
+
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
|
160
|
+
if (actual.length != expected.length) return false;
|
161
|
+
|
162
|
+
for (var i = 0; i < actual.length; i++) {
|
163
|
+
if (actual[i] !== expected[i]) return false;
|
164
|
+
}
|
165
|
+
|
166
|
+
return true;
|
167
|
+
|
168
|
+
// 7.2. If the expected value is a Date object, the actual value is
|
169
|
+
// equivalent if it is also a Date object that refers to the same time.
|
170
|
+
} else if (actual instanceof Date && expected instanceof Date) {
|
171
|
+
return actual.getTime() === expected.getTime();
|
172
|
+
|
173
|
+
// 7.3. Other pairs that do not both pass typeof value == 'object',
|
174
|
+
// equivalence is determined by ==.
|
175
|
+
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
176
|
+
return actual == expected;
|
177
|
+
|
178
|
+
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
179
|
+
// determined by having the same number of owned properties (as verified
|
180
|
+
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
181
|
+
// (although not necessarily the same order), equivalent values for every
|
182
|
+
// corresponding key, and an identical 'prototype' property. Note: this
|
183
|
+
// accounts for both named and indexed properties on Arrays.
|
184
|
+
} else {
|
185
|
+
return objEquiv(actual, expected);
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
function isUndefinedOrNull(value) {
|
190
|
+
return value === null || value === undefined;
|
191
|
+
}
|
192
|
+
|
193
|
+
function isArguments(object) {
|
194
|
+
return Object.prototype.toString.call(object) == '[object Arguments]';
|
195
|
+
}
|
196
|
+
|
197
|
+
function objEquiv(a, b) {
|
198
|
+
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
199
|
+
return false;
|
200
|
+
// an identical 'prototype' property.
|
201
|
+
if (a.prototype !== b.prototype) return false;
|
202
|
+
//~~~I've managed to break Object.keys through screwy arguments passing.
|
203
|
+
// Converting to array solves the problem.
|
204
|
+
if (isArguments(a)) {
|
205
|
+
if (!isArguments(b)) {
|
206
|
+
return false;
|
207
|
+
}
|
208
|
+
a = pSlice.call(a);
|
209
|
+
b = pSlice.call(b);
|
210
|
+
return _deepEqual(a, b);
|
211
|
+
}
|
212
|
+
try {
|
213
|
+
var ka = Object.keys(a),
|
214
|
+
kb = Object.keys(b),
|
215
|
+
key, i;
|
216
|
+
} catch (e) {//happens when one is a string literal and the other isn't
|
217
|
+
return false;
|
218
|
+
}
|
219
|
+
// having the same number of owned properties (keys incorporates
|
220
|
+
// hasOwnProperty)
|
221
|
+
if (ka.length != kb.length)
|
222
|
+
return false;
|
223
|
+
//the same set of keys (although not necessarily the same order),
|
224
|
+
ka.sort();
|
225
|
+
kb.sort();
|
226
|
+
//~~~cheap key test
|
227
|
+
for (i = ka.length - 1; i >= 0; i--) {
|
228
|
+
if (ka[i] != kb[i])
|
229
|
+
return false;
|
230
|
+
}
|
231
|
+
//equivalent values for every corresponding key, and
|
232
|
+
//~~~possibly expensive deep test
|
233
|
+
for (i = ka.length - 1; i >= 0; i--) {
|
234
|
+
key = ka[i];
|
235
|
+
if (!_deepEqual(a[key], b[key])) return false;
|
236
|
+
}
|
237
|
+
return true;
|
238
|
+
}
|
239
|
+
|
240
|
+
// 8. The non-equivalence assertion tests for any deep inequality.
|
241
|
+
// assert.notDeepEqual(actual, expected, message_opt);
|
242
|
+
|
243
|
+
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
244
|
+
if (_deepEqual(actual, expected)) {
|
245
|
+
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
246
|
+
}
|
247
|
+
};
|
248
|
+
|
249
|
+
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
250
|
+
// assert.strictEqual(actual, expected, message_opt);
|
251
|
+
|
252
|
+
assert.strictEqual = function strictEqual(actual, expected, message) {
|
253
|
+
if (actual !== expected) {
|
254
|
+
fail(actual, expected, message, '===', assert.strictEqual);
|
255
|
+
}
|
256
|
+
};
|
257
|
+
|
258
|
+
// 10. The strict non-equality assertion tests for strict inequality, as
|
259
|
+
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
260
|
+
|
261
|
+
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
262
|
+
if (actual === expected) {
|
263
|
+
fail(actual, expected, message, '!==', assert.notStrictEqual);
|
264
|
+
}
|
265
|
+
};
|
266
|
+
|
267
|
+
function expectedException(actual, expected) {
|
268
|
+
if (!actual || !expected) {
|
269
|
+
return false;
|
270
|
+
}
|
271
|
+
|
272
|
+
if (expected instanceof RegExp) {
|
273
|
+
return expected.test(actual);
|
274
|
+
} else if (actual instanceof expected) {
|
275
|
+
return true;
|
276
|
+
} else if (expected.call({}, actual) === true) {
|
277
|
+
return true;
|
278
|
+
}
|
279
|
+
|
280
|
+
return false;
|
281
|
+
}
|
282
|
+
|
283
|
+
function _throws(shouldThrow, block, expected, message) {
|
284
|
+
var actual;
|
285
|
+
|
286
|
+
if (typeof expected === 'string') {
|
287
|
+
message = expected;
|
288
|
+
expected = null;
|
289
|
+
}
|
290
|
+
|
291
|
+
try {
|
292
|
+
block();
|
293
|
+
} catch (e) {
|
294
|
+
actual = e;
|
295
|
+
}
|
296
|
+
|
297
|
+
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
|
298
|
+
(message ? ' ' + message : '.');
|
299
|
+
|
300
|
+
if (shouldThrow && !actual) {
|
301
|
+
fail('Missing expected exception' + message);
|
302
|
+
}
|
303
|
+
|
304
|
+
if (!shouldThrow && expectedException(actual, expected)) {
|
305
|
+
fail('Got unwanted exception' + message);
|
306
|
+
}
|
307
|
+
|
308
|
+
if ((shouldThrow && actual && expected &&
|
309
|
+
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
|
310
|
+
throw actual;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
// 11. Expected to throw an error:
|
315
|
+
// assert.throws(block, Error_opt, message_opt);
|
316
|
+
|
317
|
+
assert.throws = function(block, /*optional*/error, /*optional*/message) {
|
318
|
+
_throws.apply(this, [true].concat(pSlice.call(arguments)));
|
319
|
+
};
|
320
|
+
|
321
|
+
// EXTENSION! This is annoying to write outside this module.
|
322
|
+
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
|
323
|
+
_throws.apply(this, [false].concat(pSlice.call(arguments)));
|
324
|
+
};
|
325
|
+
|
326
|
+
assert.ifError = function(err) { if (err) {throw err;}};
|
@@ -0,0 +1,216 @@
|
|
1
|
+
// Copyright Joyent, Inc. and other Node contributors.
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
// copy of this software and associated documentation files (the
|
5
|
+
// "Software"), to deal in the Software without restriction, including
|
6
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
// persons to whom the Software is furnished to do so, subject to the
|
9
|
+
// following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included
|
12
|
+
// in all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
17
|
+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
18
|
+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
19
|
+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
20
|
+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
var isArray = Array.isArray;
|
23
|
+
|
24
|
+
function EventEmitter() { }
|
25
|
+
exports.EventEmitter = EventEmitter;
|
26
|
+
|
27
|
+
// By default EventEmitters will print a warning if more than
|
28
|
+
// 10 listeners are added to it. This is a useful default which
|
29
|
+
// helps finding memory leaks.
|
30
|
+
//
|
31
|
+
// Obviously not all Emitters should be limited to 10. This function allows
|
32
|
+
// that to be increased. Set to zero for unlimited.
|
33
|
+
var defaultMaxListeners = 10;
|
34
|
+
EventEmitter.prototype.setMaxListeners = function(n) {
|
35
|
+
if (!this._events) this._events = {};
|
36
|
+
this._maxListeners = n;
|
37
|
+
};
|
38
|
+
|
39
|
+
|
40
|
+
EventEmitter.prototype.emit = function() {
|
41
|
+
var type = arguments[0];
|
42
|
+
// If there is no 'error' event listener then throw.
|
43
|
+
if (type === 'error') {
|
44
|
+
if (!this._events || !this._events.error ||
|
45
|
+
(isArray(this._events.error) && !this._events.error.length))
|
46
|
+
{
|
47
|
+
if (arguments[1] instanceof Error) {
|
48
|
+
throw arguments[1]; // Unhandled 'error' event
|
49
|
+
} else {
|
50
|
+
throw new Error("Uncaught, unspecified 'error' event.");
|
51
|
+
}
|
52
|
+
return false;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
if (!this._events) return false;
|
57
|
+
var handler = this._events[type];
|
58
|
+
if (!handler) return false;
|
59
|
+
|
60
|
+
if (typeof handler == 'function') {
|
61
|
+
switch (arguments.length) {
|
62
|
+
// fast cases
|
63
|
+
case 1:
|
64
|
+
handler.call(this);
|
65
|
+
break;
|
66
|
+
case 2:
|
67
|
+
handler.call(this, arguments[1]);
|
68
|
+
break;
|
69
|
+
case 3:
|
70
|
+
handler.call(this, arguments[1], arguments[2]);
|
71
|
+
break;
|
72
|
+
// slower
|
73
|
+
default:
|
74
|
+
var l = arguments.length;
|
75
|
+
var args = new Array(l - 1);
|
76
|
+
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
|
77
|
+
handler.apply(this, args);
|
78
|
+
}
|
79
|
+
return true;
|
80
|
+
|
81
|
+
} else if (isArray(handler)) {
|
82
|
+
var l = arguments.length;
|
83
|
+
var args = new Array(l - 1);
|
84
|
+
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
|
85
|
+
|
86
|
+
var listeners = handler.slice();
|
87
|
+
for (var i = 0, l = listeners.length; i < l; i++) {
|
88
|
+
listeners[i].apply(this, args);
|
89
|
+
}
|
90
|
+
return true;
|
91
|
+
|
92
|
+
} else {
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
// EventEmitter is defined in src/node_events.cc
|
98
|
+
// EventEmitter.prototype.emit() is also defined there.
|
99
|
+
EventEmitter.prototype.addListener = function(type, listener) {
|
100
|
+
if ('function' !== typeof listener) {
|
101
|
+
throw new Error('addListener only takes instances of Function');
|
102
|
+
}
|
103
|
+
|
104
|
+
if (!this._events) this._events = {};
|
105
|
+
|
106
|
+
// To avoid recursion in the case that type == "newListeners"! Before
|
107
|
+
// adding it to the listeners, first emit "newListeners".
|
108
|
+
this.emit('newListener', type, listener);
|
109
|
+
|
110
|
+
if (!this._events[type]) {
|
111
|
+
// Optimize the case of one listener. Don't need the extra array object.
|
112
|
+
this._events[type] = listener;
|
113
|
+
} else if (isArray(this._events[type])) {
|
114
|
+
|
115
|
+
// If we've already got an array, just append.
|
116
|
+
this._events[type].push(listener);
|
117
|
+
|
118
|
+
// Check for listener leak
|
119
|
+
if (!this._events[type].warned) {
|
120
|
+
var m;
|
121
|
+
if (this._maxListeners !== undefined) {
|
122
|
+
m = this._maxListeners;
|
123
|
+
} else {
|
124
|
+
m = defaultMaxListeners;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (m && m > 0 && this._events[type].length > m) {
|
128
|
+
this._events[type].warned = true;
|
129
|
+
console.error('(node) warning: possible EventEmitter memory ' +
|
130
|
+
'leak detected. %d listeners added. ' +
|
131
|
+
'Use emitter.setMaxListeners() to increase limit.',
|
132
|
+
this._events[type].length);
|
133
|
+
console.trace();
|
134
|
+
}
|
135
|
+
}
|
136
|
+
} else {
|
137
|
+
// Adding the second element, need to change to array.
|
138
|
+
this._events[type] = [this._events[type], listener];
|
139
|
+
}
|
140
|
+
|
141
|
+
return this;
|
142
|
+
};
|
143
|
+
|
144
|
+
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
145
|
+
|
146
|
+
EventEmitter.prototype.once = function(type, listener) {
|
147
|
+
if ('function' !== typeof listener) {
|
148
|
+
throw new Error('.once only takes instances of Function');
|
149
|
+
}
|
150
|
+
|
151
|
+
var self = this;
|
152
|
+
function g() {
|
153
|
+
self.removeListener(type, g);
|
154
|
+
listener.apply(this, arguments);
|
155
|
+
};
|
156
|
+
|
157
|
+
g.listener = listener;
|
158
|
+
self.on(type, g);
|
159
|
+
|
160
|
+
return this;
|
161
|
+
};
|
162
|
+
|
163
|
+
EventEmitter.prototype.removeListener = function(type, listener) {
|
164
|
+
if ('function' !== typeof listener) {
|
165
|
+
throw new Error('removeListener only takes instances of Function');
|
166
|
+
}
|
167
|
+
|
168
|
+
// does not use listeners(), so no side effect of creating _events[type]
|
169
|
+
if (!this._events || !this._events[type]) return this;
|
170
|
+
|
171
|
+
var list = this._events[type];
|
172
|
+
|
173
|
+
if (isArray(list)) {
|
174
|
+
var position = -1;
|
175
|
+
for (var i = 0, length = list.length; i < length; i++) {
|
176
|
+
if (list[i] === listener ||
|
177
|
+
(list[i].listener && list[i].listener === listener))
|
178
|
+
{
|
179
|
+
position = i;
|
180
|
+
break;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
if (position < 0) return this;
|
185
|
+
list.splice(position, 1);
|
186
|
+
if (list.length == 0)
|
187
|
+
delete this._events[type];
|
188
|
+
} else if (list === listener ||
|
189
|
+
(list.listener && list.listener === listener))
|
190
|
+
{
|
191
|
+
delete this._events[type];
|
192
|
+
}
|
193
|
+
|
194
|
+
return this;
|
195
|
+
};
|
196
|
+
|
197
|
+
EventEmitter.prototype.removeAllListeners = function(type) {
|
198
|
+
if (arguments.length === 0) {
|
199
|
+
this._events = {};
|
200
|
+
return this;
|
201
|
+
}
|
202
|
+
|
203
|
+
// does not use listeners(), so no side effect of creating _events[type]
|
204
|
+
if (type && this._events && this._events[type]) this._events[type] = null;
|
205
|
+
return this;
|
206
|
+
};
|
207
|
+
|
208
|
+
EventEmitter.prototype.listeners = function(type) {
|
209
|
+
if (!this._events) this._events = {};
|
210
|
+
if (!this._events[type]) this._events[type] = [];
|
211
|
+
if (!isArray(this._events[type])) {
|
212
|
+
this._events[type] = [this._events[type]];
|
213
|
+
}
|
214
|
+
return this._events[type];
|
215
|
+
};
|
216
|
+
|