Skip to content

Commit 98bfed0

Browse files
committed
JSLint
1 parent 0bda0ae commit 98bfed0

File tree

1 file changed

+110
-102
lines changed

1 file changed

+110
-102
lines changed

lib/XMLHttpRequest.js

Lines changed: 110 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/*jslint node:true, vars:true, todo:true, stupid:true, regexp:true*/
12
/**
23
* Wrapper for built-in http.js to emulate the browser XMLHttpRequest object.
34
*
@@ -16,6 +17,7 @@ var Url = require("url")
1617
, fs = require('fs');
1718

1819
exports.XMLHttpRequest = function() {
20+
'use strict';
1921
/**
2022
* Private variables
2123
*/
@@ -37,7 +39,7 @@ exports.XMLHttpRequest = function() {
3739
// Set some default headers
3840
var defaultHeaders = {
3941
"User-Agent": "node-XMLHttpRequest",
40-
"Accept": "*/*",
42+
"Accept": "*/*"
4143
};
4244

4345
var headers = defaultHeaders;
@@ -113,6 +115,27 @@ exports.XMLHttpRequest = function() {
113115
* Private methods
114116
*/
115117

118+
/**
119+
* Changes readyState and calls onreadystatechange.
120+
*
121+
* @param int state New state
122+
*/
123+
var setState = function(state) {
124+
if (state === self.LOADING || self.readyState !== state) {
125+
self.readyState = state;
126+
127+
if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
128+
self.dispatchEvent("readystatechange");
129+
}
130+
131+
if (self.readyState === self.DONE && !errorFlag) {
132+
self.dispatchEvent("load");
133+
// @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
134+
self.dispatchEvent("loadend");
135+
}
136+
}
137+
};
138+
116139
/**
117140
* Check if the specified header is allowed.
118141
*
@@ -183,7 +206,7 @@ exports.XMLHttpRequest = function() {
183206
* @param string value Header value
184207
*/
185208
this.setRequestHeader = function(header, value) {
186-
if (this.readyState != this.OPENED) {
209+
if (this.readyState !== this.OPENED) {
187210
throw "INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN";
188211
}
189212
if (!isAllowedHttpHeader(header)) {
@@ -226,11 +249,13 @@ exports.XMLHttpRequest = function() {
226249
return "";
227250
}
228251
var result = "";
229-
230-
for (var i in response.headers) {
231-
// Cookie headers are excluded
232-
if (i !== "set-cookie" && i !== "set-cookie2") {
233-
result += i + ": " + response.headers[i] + "\r\n";
252+
var i;
253+
for (i in response.headers) {
254+
if (response.headers.hasOwnProperty(i)) {
255+
// Cookie headers are excluded
256+
if (i !== "set-cookie" && i !== "set-cookie2") {
257+
result += i + ": " + response.headers[i] + "\r\n";
258+
}
234259
}
235260
}
236261
return result.substr(0, result.length - 2);
@@ -257,7 +282,7 @@ exports.XMLHttpRequest = function() {
257282
* @param string data Optional data to send as request body.
258283
*/
259284
this.send = function(data) {
260-
if (this.readyState != this.OPENED) {
285+
if (this.readyState !== this.OPENED) {
261286
throw "INVALID_STATE_ERR: connection must be opened before send() is called";
262287
}
263288

@@ -273,6 +298,7 @@ exports.XMLHttpRequest = function() {
273298
case 'https:':
274299
ssl = true;
275300
// SSL & non-SSL both need host, no break here.
301+
/* falls through */
276302
case 'http:':
277303
host = url.hostname;
278304
break;
@@ -323,21 +349,21 @@ exports.XMLHttpRequest = function() {
323349
// to use http://localhost:port/path
324350
var port = url.port || (ssl ? 443 : 80);
325351
// Add query string if one is used
326-
var uri = url.pathname + (url.search ? url.search : '');
352+
var uri = url.pathname + (url.search || '');
327353

328354
// Set the Host header or the server may reject the request
329-
headers["Host"] = host;
355+
headers.Host = host;
330356
if (!((ssl && port === 443) || port === 80)) {
331-
headers["Host"] += ':' + url.port;
357+
headers.Host += ':' + url.port;
332358
}
333359

334360
// Set Basic Auth if necessary
335361
if (settings.user) {
336-
if (typeof settings.password == "undefined") {
362+
if (settings.password === undefined) {
337363
settings.password = "";
338364
}
339365
var authBuf = new Buffer(settings.user + ":" + settings.password);
340-
headers["Authorization"] = "Basic " + authBuf.toString("base64");
366+
headers.Authorization = "Basic " + authBuf.toString("base64");
341367
}
342368

343369
// Set content length header
@@ -364,82 +390,84 @@ exports.XMLHttpRequest = function() {
364390
agent: false
365391
};
366392

393+
var doRequest;
394+
367395
// Reset error flag
368396
errorFlag = false;
369397

370-
// Handle async requests
371-
if (settings.async) {
372-
// Use the proper protocol
373-
var doRequest = ssl ? https.request : http.request;
398+
// Error handler for the request
399+
function errorHandler(error) {
400+
self.handleError(error);
401+
}
374402

375-
// Request is being sent, set send flag
376-
sendFlag = true;
403+
// Handler for the response
404+
function responseHandler(resp) {
405+
// Set response var to the response we got back
406+
// This is so it remains accessable outside this scope
407+
response = resp;
408+
// Check for redirect
409+
// @TODO Prevent looped redirects
410+
if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
411+
// Change URL to the redirect location
412+
settings.url = response.headers.location;
413+
url = Url.parse(settings.url);
414+
// Set host var in case it's used later
415+
host = url.hostname;
416+
// Options for the new request
417+
var newOptions = {
418+
hostname: url.hostname,
419+
port: url.port,
420+
path: url.path,
421+
method: response.statusCode === 303 ? 'GET' : settings.method,
422+
headers: headers
423+
};
424+
425+
// Issue the new request
426+
request = doRequest(newOptions, responseHandler).on('error', errorHandler);
427+
request.end();
428+
// @TODO Check if an XHR event needs to be fired here
429+
return;
430+
}
377431

378-
// As per spec, this is called here for historical reasons.
379-
self.dispatchEvent("readystatechange");
432+
response.setEncoding("utf8");
380433

381-
// Handler for the response
382-
function responseHandler(resp) {
383-
// Set response var to the response we got back
384-
// This is so it remains accessable outside this scope
385-
response = resp;
386-
// Check for redirect
387-
// @TODO Prevent looped redirects
388-
if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
389-
// Change URL to the redirect location
390-
settings.url = response.headers.location;
391-
var url = Url.parse(settings.url);
392-
// Set host var in case it's used later
393-
host = url.hostname;
394-
// Options for the new request
395-
var newOptions = {
396-
hostname: url.hostname,
397-
port: url.port,
398-
path: url.path,
399-
method: response.statusCode === 303 ? 'GET' : settings.method,
400-
headers: headers
401-
};
402-
403-
// Issue the new request
404-
request = doRequest(newOptions, responseHandler).on('error', errorHandler);
405-
request.end();
406-
// @TODO Check if an XHR event needs to be fired here
407-
return;
408-
}
434+
setState(self.HEADERS_RECEIVED);
435+
self.status = response.statusCode;
409436

410-
response.setEncoding("utf8");
437+
response.on('data', function(chunk) {
438+
// Make sure there's some data
439+
if (chunk) {
440+
self.responseText += chunk;
441+
}
442+
// Don't emit state changes if the connection has been aborted.
443+
if (sendFlag) {
444+
setState(self.LOADING);
445+
}
446+
});
411447

412-
setState(self.HEADERS_RECEIVED);
413-
self.status = response.statusCode;
448+
response.on('end', function() {
449+
if (sendFlag) {
450+
// Discard the 'end' event if the connection has been aborted
451+
setState(self.DONE);
452+
sendFlag = false;
453+
}
454+
});
414455

415-
response.on('data', function(chunk) {
416-
// Make sure there's some data
417-
if (chunk) {
418-
self.responseText += chunk;
419-
}
420-
// Don't emit state changes if the connection has been aborted.
421-
if (sendFlag) {
422-
setState(self.LOADING);
423-
}
424-
});
456+
response.on('error', function(error) {
457+
self.handleError(error);
458+
});
459+
}
425460

426-
response.on('end', function() {
427-
if (sendFlag) {
428-
// Discard the 'end' event if the connection has been aborted
429-
setState(self.DONE);
430-
sendFlag = false;
431-
}
432-
});
461+
// Handle async requests
462+
if (settings.async) {
463+
// Use the proper protocol
464+
doRequest = ssl ? https.request : http.request;
433465

434-
response.on('error', function(error) {
435-
self.handleError(error);
436-
});
437-
}
466+
// Request is being sent, set send flag
467+
sendFlag = true;
438468

439-
// Error handler for the request
440-
function errorHandler(error) {
441-
self.handleError(error);
442-
}
469+
// As per spec, this is called here for historical reasons.
470+
self.dispatchEvent("readystatechange");
443471

444472
// Create the request
445473
request = doRequest(options, responseHandler).on('error', errorHandler);
@@ -483,7 +511,6 @@ exports.XMLHttpRequest = function() {
483511
+ "req.end();";
484512
// Start the other Node Process, executing this string
485513
var syncProc = spawn(process.argv[0], ["-e", execString]);
486-
var statusText;
487514
while(fs.existsSync(syncFile)) {
488515
// Wait while the sync file is empty
489516
}
@@ -544,7 +571,7 @@ exports.XMLHttpRequest = function() {
544571
* Adds an event listener. Preferred method of binding to events.
545572
*/
546573
this.addEventListener = function(event, callback) {
547-
if (!(event in listeners)) {
574+
if (!(listeners.hasOwnProperty(event))) {
548575
listeners[event] = [];
549576
}
550577
// Currently allows duplicate callbacks. Should it?
@@ -556,7 +583,7 @@ exports.XMLHttpRequest = function() {
556583
* Only works on the matching funciton, cannot be a copy.
557584
*/
558585
this.removeEventListener = function(event, callback) {
559-
if (event in listeners) {
586+
if (listeners.hasOwnProperty(event)) {
560587
// Filter will return a new array with the callback removed
561588
listeners[event] = listeners[event].filter(function(ev) {
562589
return ev !== callback;
@@ -571,31 +598,12 @@ exports.XMLHttpRequest = function() {
571598
if (typeof self["on" + event] === "function") {
572599
self["on" + event]();
573600
}
574-
if (event in listeners) {
575-
for (var i = 0, len = listeners[event].length; i < len; i++) {
601+
var i, len;
602+
if (listeners.hasOwnProperty(event)) {
603+
for (i = 0, len = listeners[event].length; i < len; i++) {
576604
listeners[event][i].call(self);
577605
}
578606
}
579607
};
580608

581-
/**
582-
* Changes readyState and calls onreadystatechange.
583-
*
584-
* @param int state New state
585-
*/
586-
var setState = function(state) {
587-
if (state == self.LOADING || self.readyState !== state) {
588-
self.readyState = state;
589-
590-
if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
591-
self.dispatchEvent("readystatechange");
592-
}
593-
594-
if (self.readyState === self.DONE && !errorFlag) {
595-
self.dispatchEvent("load");
596-
// @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
597-
self.dispatchEvent("loadend");
598-
}
599-
}
600-
};
601609
};

0 commit comments

Comments
 (0)