[go: up one dir, main page]

Menu

[r18]: / tags / 0.1 / ratax.js  Maximize  Restore  History

Download this file

107 lines (87 with data), 2.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
/*
ratax.js
Esta sencilla clase sirve para trabajar con JSON asíncrono.
*/
function ratax() {
this.className = 'ratax';
this.version = 'Ratax 0.1a';
this.rpcuri = '';
this.rpcid = 0;
// Correctly escape strings for JSON
this.escaper = function(data) {
data = data.replace(/(["\/])/,'\$1');
data = data.replace(/\f/,'\\f');
data = data.replace(/\n/,'\\n');
data = data.replace(/\r/,'\\r');
data = data.replace(/\t/,'\\t');
return data;
}
// Serialize an object into JSON
this.serializer = function(data) {
if ( data == null ) { return 'null'; }
if ( typeof(data) == 'object' || typeof(data) == 'array' ) {
var ret = '';
for (var i in data) {
ret += (ret=='')?'':',';
ret += this.serializer(i)+':'+this.serializer(data[i]);
}
return '{'+ret+'}';
}
if ( typeof(data) == 'number' ) { return data; }
if ( typeof(data) == 'string' ) { return '"'+this.escaper(data)+'"'; }
throw new Error('Unhandled data type: '+typeof(data));
}
// JSON-RPC call
this.call = function (method, args, callback, sync) {
var call = new Object();
call.method = method;
call.params = args;
call.id = ++this.rpcid;
var callData = this.serializer(call);
// If no sync-mode specified, assume it's async/non-blocking
if ( sync != false ) { sync = true; }
var xml = new XMLHttpRequest();
xml.ratax = this;
xml.callback = callback;
if ( sync ) { xml.onreadystatechange = this.handler; }
xml.open('POST',this.rpcuri,sync);
xml.setRequestHeader('Content-type', 'application/json');
xml.setRequestHeader('Content-length', callData.length);
xml.setRequestHeader('Connection', 'close');
xml.send(callData);
if ( !sync )
return this.process(xml.responseText);
}
// This is the actual processing of the response
this.process = function(response) {
// Error handling
try { var data = eval('('+response+')'); }
catch (e) { throw new Error('Bad response\n'+response); }
if ( data == null ) { throw new Error('Null data received'); }
// If response is error, throw it
if ( data.error != null ) { throw new Error(data.error); }
// If we actually have a method call, validate and call it
if ( typeof(data.method) != 'undefined' ) {
if ( eval('typeof '+data.method) == 'function' ) {
eval(data.method)(data.params);
}
}
// If a handler is set, cascade to it
if ( typeof(this.callback) == 'function' ) { this.callback(data); }
// If in sync mode, we will return the actual result
return data.result;
}
// Asynchronous XHR handler
this.handler = function () {
if (this.readyState==4) {// 4 = "loaded"
if (this.status==200)
{// 200 = OK
return this.ratax.process(this.responseText);
}
else
{
throw new Error('Error '+this.status+' when reading '+this);
}
}
}
}