Hironori Yoshida - JSONScriptRequest-0.01
NAME
JSONScriptRequest - Call JSONP using script element like XMLHttpRequest
SYNOPSIS
var req = new JSONScriptRequest();
req.open('GET', 'http://www.example.com/jsonp');
req.onreadystatechange = function() {
if (req.readyState == 4) {
alert(req.responseJSON);
}
};
req.send(null);
DESCRIPTION
See the document of XMLHttpRequest.
Class Properties
responseJSON
var json = req.responseJSON;
This attributes represents the response as a JSON object. NULL if the request is unsuccessful or has not yet been sent.
Constructor
JSONScriptRequest({...})
The following values can be specified for the argument.
- callback_param
- The name of the callback parameter key. Default is 'callback'.
TODO
- Implement the features that is not implemented yet.
- Change throw object to an exception class from a string.
SEE ALSO
XULPlanet http://www.xulplanet.com/references/objref/XMLHttpRequest.html
AUTHOR
Hironori Yoshida <yoshida@cpan.org>
COPYRIGHT
Copyright (c) 2006, Hironori Yoshida <yoshida@cpan.org>. All rights reserved.
This module is free software; you can redistribute it and/or modify it
under the terms of the Artistic license. Or whatever license I choose,
which I will do instead of keeping this documentation like it is.
var JSONScriptRequest = function (args) {
if (args) {
if (args['callback_param']) {
this._callback_param = args['callback_param'];
}
}
return;
}
JSONScriptRequest.VERSION = 0.01;
JSONScriptRequest._dispatchers = [];
JSONScriptRequest.prototype = {
_id: null,
_script: null,
_callback_param: 'callback',
multipart: false,
onreadystatechange: null,
readyState: 0,
responseText: null,
responseJSON: null,
status: 0,
statusText: '',
_readystatechange: function(readyState) {
if (this.readyState == readyState) {
// it does not change but do nothing to follow to
// ActiveXObject of IE and XMLHttpRequest of Firefox.
}
this.readyState = readyState;
if (this.onreadystatechange) {
this.onreadystatechange();
}
return;
},
_createDispatcher: function() {
for (this._id = 0; this._id < JSONScriptRequest._dispatchers.length; this._id++) {
if ( !JSONScriptRequest._dispatchers[this._id] ) {
break;
}
}
var owner = this;
JSONScriptRequest._dispatchers[this._id] = function(json) {
if (owner.multipart) {
throw 'Not implemented yet [JSONScriptRequest._dispatchers]';
}
owner._readystatechange(2);
owner.responseText = json.toSource().replace(/^\(/, '').replace(/\)$/, '');
owner._readystatechange(3);
owner.responseJSON = json;
owner._readystatechange(4);
JSONScriptRequest._dispatchers[owner._id] = null;
owner._id = null;
return;
};
return;
},
abort: function() {
if (this._id != null) {
var id = this._id;
JSONScriptRequest._dispatchers[id] = function(json) {
JSONScriptRequest._dispatchers[id] = null;
};
this._id = null
}
return;
},
addEventListener: function(type, listener, useCapture) {
throw 'Not implemented yet [JSONScriptRequest.addEventListener]';
return;
},
dispatchEvent: function(evt) {
throw 'Not implemented yet [JSONScriptRequest.dispatchEvent]';
return false;
},
getAllResponseHeaders: function() {
return '';
},
getResponseHeader: function(header) {
return '';
},
open: function(method, url) {
if ( arguments.length < 2 ) {
throw 'Not enough arguments [JSONScriptRequest.open]';
}
var async = (arguments[2] != null) ? arguments[2] : true;
var user = arguments[3];
var password = arguments[4];
this.openRequest(method, url, async, user, password);
return;
},
openRequest: function(method, url, async, user, password) {
if (arguments.length < 3) {
throw 'Not enough arguments [JSONScriptRequest.openRequest]';
}
this.abort();
// url
if (!url) {
throw 'Invalid url [JSONScriptRequest.openRequest]';
}
// method
var http_re = new RegExp('^https?://', 'i');
if (url.match(http_re) || location.href.match(http_re)) {
method = method.toUpperCase();
if (method != 'GET') {
throw 'Invalid method [JSONScriptRequest.openRequest]';
}
}
// async
if (this.multipart && !async) {
throw 'async must be true [JSONScriptRequest.openRequest]';
}
if (!async) {
throw 'Not implemented yet [JSONScriptRequest.openRequest]';
}
// user, password
if ( user || password ) {
// This will not work.
var userinfo = ( user ? user : '' ) + ':' + ( password ? password : '' );
url.replace(new RegExp('(https?://)(.+)', 'i'), RegExp.$1 + userinfo + '@' + RegExp.$2);
}
// process
this._createDispatcher();
var queries = [];
queries.push(this._callback_param + '=JSONScriptRequest._dispatchers[' + this._id + ']');
url += (url.match(/\?/) ? '&' : '?') + queries.join('&');
this._script = document.createElement('script');
this._script.src = url;
this._readystatechange(1);
return;
},
overrideMimeType: function(mimetype) {
throw 'Not implemented yet [JSONScriptRequest.overrideMimeType]';
return;
},
removeEventListener: function(type, listener, useCapture) {
throw 'Not implemented yet [JSONScriptRequest.removeEventListener]';
return;
},
send: function(body) {
if (this.readyState != 1) {
throw 'Not Initialized [JSONScriptRequest.send]';
}
this._readystatechange(1);
// body
if (body) {
if (typeof body != 'string') {
var NODE_DOCUMENT = 9;
if (body.nodeType == NODE_DOCUMENT) {
throw 'Not implemented yet [JSONScriptRequest.send]';
} else if (typeof body.read == 'function') {
throw 'Not implemented yet [JSONScriptRequest.send]';
}
}
this._script.src += '&' + body;
}
// process
this._script.type = this._script.type || 'text/javascript';
this._script.charset = this._script.charset || 'UTF-8';
var head = document.getElementsByTagName('head')[0];
head.appendChild(this._script);
head.removeChild(this._script);
this._script = null;
return;
},
setRequestHeader: function(header, value) {
if (this.readyState != 1) {
throw 'Not Initialized [JSONScriptRequest.setRequestHeader]';
}
if ( header.toUpperCase() == 'ACCEPT' ) {
this._script.type = value;
}
else if ( header.toUpperCase() == 'ACCEPT-CHARSET' ) {
this._script.charset = value;
}
else {
throw 'Invalid arguments';
}
return;
}
};
/*
=head1 NAME
JSONScriptRequest - Call JSONP using script element like XMLHttpRequest
=head1 SYNOPSIS
var req = new JSONScriptRequest();
req.open('GET', 'http://www.example.com/jsonp');
req.onreadystatechange = function() {
if (req.readyState == 4) {
alert(req.responseJSON);
}
};
req.send(null);
=head1 DESCRIPTION
See the document of XMLHttpRequest.
=head2 Class Properties
=head3 responseJSON
var json = req.responseJSON;
This attributes represents the response as a JSON object. NULL if the request is unsuccessful or has not yet been sent.
=head2 Constructor
=head3 JSONScriptRequest({...})
The following values can be specified for the argument.
=over
=item callback_param
The name of the callback parameter key. Default is 'callback'.
=back
=head1 TODO
=over
=item Implement the features that is not implemented yet.
=item Change throw object to an exception class from a string.
=back
=head1 SEE ALSO
XULPlanet
L<http://www.xulplanet.com/references/objref/XMLHttpRequest.html>
=head1 AUTHOR
Hironori Yoshida <yoshida@cpan.org>
=head1 COPYRIGHT
Copyright (c) 2006, Hironori Yoshida <yoshida@cpan.org>. All rights reserved.
This module is free software; you can redistribute it and/or modify it
under the terms of the Artistic license. Or whatever license I choose,
which I will do instead of keeping this documentation like it is.
=cut
*/