io-xdr.js revision cc779b2f03fd6bd9734830da2fe53bbdd2562f7f
124N/A /**
124N/A * Extends the IO base class to provide an alternate, Flash transport, for making
124N/A * cross-domain requests.
124N/A * @module io
124N/A * @submodule io-xdr
124N/A */
124N/A
124N/A /**
124N/A * @event io:xdrReady
124N/A * @description This event is fired by YUI.io when the specified transport is
124N/A * ready for use.
124N/A * @type Event Custom
124N/A */
124N/A var E_XDR_READY = Y.publish('io:xdrReady', { fireOnce: true }),
124N/A
124N/A /**
124N/A * @description Map of stored configuration objects when using
124N/A * Flash as the transport for cross-domain requests.
124N/A *
124N/A * @property _cB
5680N/A * @private
5680N/A * @type object
5230N/A */
124N/A _cB = {},
5680N/A
124N/A /**
124N/A * @description Map of transaction simulated readyState values
124N/A * when XDomainRequest is the transport.
7140N/A *
618N/A * @property _rS
124N/A * @private
844N/A * @type object
7140N/A */
618N/A _rS = {},
124N/A
7140N/A // Document reference
5648N/A d = Y.config.doc,
5680N/A // Window reference
6695N/A w = Y.config.win,
6695N/A // XDomainRequest cross-origin request detection
6695N/A xdr = w && w.XDomainRequest;
6695N/A
5680N/A /**
124N/A * @description Method that creates the Flash transport swf.
2960N/A *
2960N/A * @method _swf
2960N/A * @private
2960N/A * @param {string} uri - location of io.swf.
124N/A * @param {string} yid - YUI sandbox id.
124N/A * @param {string} yid - IO instance id.
5935N/A * @return void
5935N/A */
5935N/A function _swf(uri, yid, uid) {
5935N/A var o = '<object id="io_swf" type="application/x-shockwave-flash" data="' +
7003N/A uri + '" width="0" height="0">' +
7003N/A '<param name="movie" value="' + uri + '">' +
7003N/A '<param name="FlashVars" value="yid=' + yid + '&uid=' + uid + '">' +
5680N/A '<param name="allowScriptAccess" value="always">' +
5680N/A '</object>',
124N/A c = d.createElement('div');
5617N/A
124N/A d.body.appendChild(c);
124N/A c.innerHTML = o;
124N/A }
3878N/A
7140N/A /**
5935N/A * @description Sets event handlers for XDomainRequest transactions.
5935N/A *
124N/A * @method _evt
765N/A * @private
765N/A * @static
765N/A * @param {object} o - Transaction object generated by _create() in io-base.
765N/A * @param {object} c - configuration object for the transaction.
765N/A * @return void
1792N/A */
1792N/A function _evt(o, c) {
1792N/A var io = this,
765N/A i = o.id,
765N/A p = 'xdrResponse',
765N/A t = 'timeout';
765N/A
765N/A o.c.onprogress = function() { _rS[i] = 3; };
6184N/A o.c.onload = function() {
6184N/A _rS[i] = 4;
6184N/A io[p](o, c, 'success');
7003N/A };
6184N/A o.c.onerror = function() {
6184N/A _rS[i] = 4;
7003N/A io[p](o, c, 'failure');
6184N/A };
3817N/A if (c.timeout) {
3817N/A o.c.ontimeout = function() {
3817N/A _rS[i] = 4;
3817N/A io[p](o, c, t);
3817N/A };
7140N/A o.c[t] = c[t];
3817N/A }
3817N/A }
5111N/A
3817N/A /**
3817N/A * @description Creates a response object for XDR transactions, for success
3817N/A * and failure cases.
6067N/A *
6067N/A * @method _data
3817N/A * @private
3817N/A * @param {object} o - Transaction object generated by _create() in io-base.
3817N/A * @param {boolean} u - Configuration xdr.use.
3817N/A * @param {boolean} d - Configuration xdr.dataType.
3817N/A *
* @return object
*/
function _data(o, u, d) {
if (u === 'flash') {
o.c.responseText = decodeURI(o.c.responseText);
}
if (d === 'xml') {
o.c.responseXML = Y.DataType.XML.parse(o.c.responseXML);
}
return o;
}
/**
* @description Method for intiating an XDR transaction abort.
*
* @method _abort
* @private
* @param {object} o - Transaction object generated by _create() in io-base.
* @param {object} c - configuration object for the transaction.
*/
function _abort(o, c) {
return o.c.abort(o.id, c);
}
/**
* @description Method for determining if an XDR transaction has completed
* and all data are received.
*
* @method _isInProgress.
* @private
* @param {object} o - Transaction object generated by _create() in io-base.
*/
function _isInProgress(o) {
return xdr ? _rS[o.id] !== 4 : o.c.isInProgress(o.id);
}
Y.mix(Y.IO.prototype, {
/**
* @description Map of io transports.
*
* @property _transport
* @private
* @type object
*/
_transport: {},
/**
* @description Method for accessing the transport's interface for making a
* cross-domain transaction.
*
* @method xdr
* @public
* @param {string} uri - qualified path to transaction resource.
* @param {object} o - Transaction object generated by _create() in io-base.
* @param {object} c - configuration object for the transaction.
*/
xdr: function(uri, o, c) {
var io = this;
if (c.xdr.use === 'flash') {
// The configuration object cannot be serialized safely
// across Flash's ExternalInterface.
_cB[o.id] = c;
w.setTimeout(function() {
if (o.c.send) {
o.c.send(uri, { id: o.id,
uid: o.uid,
method: c.method,
data: c.data,
headers: c.headers });
}
else {
io.xdrResponse(o, c, 'transport error');
delete _cB[o.id];
}
}, Y.io.xdr.delay);
}
else if (xdr) {
_evt(o, c);
o.c.open(c.method || 'GET', uri);
o.c.send(c.data);
}
else {
o.c.send(uri, o, c);
}
return {
id: o.id,
abort: function() {
return o.c ? _abort(o, c) : false;
},
isInProgress: function() {
return o.c ? _isInProgress(o.id) : false;
},
io: io
};
},
/**
* @description Response controller for cross-domain requests when using the
* Flash transport or IE8's XDomainRequest object.
*
* @method xdrResponse
* @public
* @param {string} e - Event name
* @param {object} o - Transaction object generated by _create() in io-base.
* @param {object} c - configuration object for the transaction.
* @return object
*/
xdrResponse: function(e, o, c) {
c = _cB[o.id] ? _cB[o.id] : c;
var io = this,
m = xdr ? _rS : _cB,
u = c.xdr.use,
d = c.xdr.dataType;
switch (e) {
case 'start':
io.start(o, c);
break;
//case 'complete':
//This case is not used by Flash or XDomainRequest.
//io.complete(o, c);
//break;
case 'success':
io.success(_data(o, u, d), c);
delete m[o.id];
break;
case 'timeout':
case 'abort':
case 'transport error':
o.e = e;
case 'failure':
io.failure(_data(o, u, d), c);
delete m[o.id];
break;
}
},
/**
* @description Fires event "io:xdrReady"
*
* @method _xdrReady
* @private
* @param {number} yid - YUI sandbox id.
* @param {number} uid - IO instance id.
*
* @return void
*/
_xdrReady: function(yid, uid) {
Y.fire(E_XDR_READY, yid, uid);
},
/**
* @description Method to initialize the desired transport.
*
* @method transport
* @public
* @param {object} o - object of transport configurations.
* @return void
*/
transport: function(c) {
if (c.id === 'flash') {
_swf(Y.UA.ie ? c.src + '?d=' + new Date().valueOf().toString() : c.src, Y.id, c.uid);
}
this._transport[c.id] = (c.id === 'flash') ? d.getElementById('io_swf') : c.src;
}
});
/**
* @description Fires event "io:xdrReady"
*
* @method xdrReady
* @protected
* @static
* @param {number} yid - YUI sandbox id.
* @param {number} uid - IO instance id.
*
* @return void
*/
Y.io.xdrReady = function(yid, uid){
var io = Y.io._map[uid];
Y.io.xdr.delay = 0;
io._xdrReady.apply(io, [yid, uid]);
};
Y.io.xdrResponse = function(e, o, c){
var io = Y.io._map[o.uid];
io.xdrResponse.apply(io, [e, o, c]);
};
Y.io.transport = function(c){
var io = Y.io._map['io:0'] || new Y.IO();
c.uid = io._uid;
io.transport.apply(io, [c]);
};
/**
* @description Delay value to calling the Flash transport, in the
* event io.swf has not finished loading. Once the E_XDR_READY
* event is fired, this value will be set to 0.
*
* @property delay
* @public
* @static
* @type number
*/
Y.io.xdr = { delay : 100 };