io-xdr.js revision db6bcdca3c01def23cea443aa1bb08552d696ba6
YUI.add('io-xdr', function(Y) {
/**
* Extends the IO base class to provide an alternate, Flash transport, for making
* cross-domain requests.
* @module io
* @submodule io-xdr
*/
/**
* @event io:xdrReady
* @description This event is fired by YUI.io when the specified transport is
* ready for use.
* @type Event Custom
*/
var E_XDR_READY = 'io:xdrReady';
/**
* @description Method that creates the Flash transport swf.
*
* @method _swf
* @private
* @static
* @param {string} uri - location of io.swf.
* @param {string} yid - YUI instance id.
* @return void
*/
function _swf(uri, yid) {
var o = '<object id="yuiIoSwf" type="application/x-shockwave-flash" data="' +
uri + '" width="0" height="0">' +
'<param name="movie" value="' + uri + '">' +
'<param name="FlashVars" value="yid=' + yid + '">' +
'<param name="allowScriptAccess" value="always">' +
'</object>',
c = document.createElement('div');
document.body.appendChild(c);
c.innerHTML = o;
}
function _ie(o, c) {
//o.c.onprogress
o.c.onload = function() { Y.io.xdrResponse(o, c, 'success'); };
o.c.onerror = function() { Y.io.xdrResponse(o, c, 'failure'); };
if (c.timeout) {
o.c.ontimeout = function() { Y.io.xdrResponse(o, c, 'timeout') };
o.c.timeout = c.timeout;
}
}
function _data(o, isFlash, isXML) {
var text = isFlash ? decodeURI(o.c.responseText) : o.c.responseText,
xml = isXML ? Y.DataType.XML.parse(text) : null,
r = o.status ? { status: o.status } : {
id: o.id,
c: { responseText: text, responseXML: xml }
};
return r;
}
function _abort(o, c) {
o.c.abort(o.id, c);
}
function _isInProgress(o, t) {
return o.c.isInProgress(o.id);
}
Y.mix(Y.io, {
/**
* @description Map of io transports.
*
* @property _transport
* @private
* @static
* @type object
*/
_transport: {},
/**
* @description Object that stores callback handlers for cross-domain requests
* when using Flash as the transport.
*
* @property _fn
* @private
* @static
* @type object
*/
_fn: {},
/**
* @description Method for accessing the transport's interface for making a
* cross-domain transaction.
*
* @method _xdr
* @private
* @static
* @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 t = c.xdr.use;
if (c.on && t === 'flash') {
this._fn[o.id] = { on: c.on, arguments: c.arguments };
o.c.send(uri, c, o.id);
}
else if (window.XDomainRequest) {
_ie(o, c);
o.c.open(c.method || 'GET', uri);
o.c.send(c.data);
}
return {
id: o.id,
abort: function() { _abort(o, c); },
isInProgress: function() { _isInProgress(o, t); }
}
},
/**
* @description Response controller for cross-domain requests when using the
* Flash transport or IE8's XDomainRequest object.
*
* @method xdrResponse
* @private
* @static
* @param {object} o - Transaction object generated by _create() in io-base.
* @param {object} c - configuration object for the transaction.
* @param {string} e - Event name
* @return object
*/
xdrResponse: function(o, c, e) {
var m, fn,
isFlash = c.xdr.use === 'flash' ? true : false,
isXML = c.xdr.dataType === 'xml' ? true : false;
c.on = c.on || {};
if (isFlash) {
m = Y.io._fn || {};
fn = m[o.id] ? m[o.id] : null;
if (fn) {
c.on = fn.on;
c.arguments = fn.arguments;
}
}
if (e === ('abort' || 'timeout')) {
o.status = e;
}
switch (e) {
case 'start':
Y.io.start(o.id, c);
break;
case 'success':
Y.io.success(_data(o, isFlash, isXML), c);
if (isFlash) {
delete m[o.id];
}
break;
case 'timeout':
case 'abort':
case 'failure':
Y.io.failure(_data(o, isFlash, isXML), c);
if (isFlash) {
delete m[o.id];
}
break;
}
},
/**
* @description Fires event "io:xdrReady"
*
* @method xdrReady
* @private
* @static
* @param {number} id - transaction id
* @param {object} c - configuration object for the transaction.
*
* @return void
*/
xdrReady: function(id) {
Y.fire(E_XDR_READY, id);
},
/**
* @description Method to initialize the desired transport.
*
* @method transport
* @public
* @static
* @param {object} o - object of transport configurations.
* @return void
*/
transport: function(o) {
var id = o.yid ? o.yid : Y.id;
_swf(o.src, id);
this._transport.flash = document.getElementById('yuiIoSwf');
}
});
}, '@VERSION@' ,{requires:['io-base','datatype-xml']});