Show:
                            /**
                             * The IORequest Utility - Provides response data normalization for 'xml', 'json',
                             * JavaScript and cache option.
                             *
                             * @module aui-io
                             * @submodule aui-io-request
                             */
                            
                            var L = A.Lang,
                                isBoolean = L.isBoolean,
                                isFunction = L.isFunction,
                                isString = L.isString,
                            
                                defaults = A.namespace('config.io'),
                            
                                getDefault = function(attr) {
                                    return function() {
                                        return defaults[attr];
                                    };
                                },
                            
                                ACCEPTS = {
                                    all: '*/*',
                                    html: 'text/html',
                                    json: 'application/json, text/javascript',
                                    text: 'text/plain',
                                    xml: 'application/xml, text/xml'
                                };
                            
                            /**
                             * A base class for IORequest, providing:
                             *
                             * - Response data normalization for XML, JSON, JavaScript
                             * - Cache options
                             *
                             * Check the [live demo](http://alloyui.com/examples/io/).
                             *
                             * @class A.IORequest
                             * @extends Plugin.Base
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @uses io
                             * @constructor
                             * @example
                            ```
                            YUI().use(
                              'aui-io-request',
                              function (Y) {
                                Y.io.request(
                                  'https://alloyui.com/io/data/content.html',
                                  {
                                    on: {
                                      success: function() {
                                        var data = this.get('responseData');
                                        alert(data);
                                      }
                                    }
                                  }
                                );
                              }
                            );
                            ```
                             */
                            var IORequest = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'IORequest',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the IORequest.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * If `true` invoke the [start](A.IORequest.html#method_start) method
                                     * automatically, initializing the IO transaction.
                                     *
                                     * @attribute autoLoad
                                     * @default true
                                     * @type Boolean
                                     */
                                    autoLoad: {
                                        value: true,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * If `false` the current timestamp will be appended to the
                                     * url, avoiding the url to be cached.
                                     *
                                     * @attribute cache
                                     * @default true
                                     * @type Boolean
                                     */
                                    cache: {
                                        value: true,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * The type of the request (i.e., could be xml, json, javascript, text).
                                     *
                                     * @attribute dataType
                                     * @default null
                                     * @type String
                                     */
                                    dataType: {
                                        setter: function(v) {
                                            return (v || '').toLowerCase();
                                        },
                                        value: null,
                                        validator: isString
                                    },
                            
                                    /**
                                     * This is a normalized attribute for the response data. It's useful to
                                     * retrieve the correct type for the
                                     * [dataType](A.IORequest.html#attr_dataType) (i.e., in json requests
                                     * the `responseData`) is a JSONObject.
                                     *
                                     * @attribute responseData
                                     * @default null
                                     * @type String | JSONObject | XMLDocument
                                     */
                                    responseData: {
                                        setter: function(v) {
                                            return this._setResponseData(v);
                                        },
                                        value: null
                                    },
                            
                                    /**
                                     * URI to be requested using AJAX.
                                     *
                                     * @attribute uri
                                     * @default null
                                     * @type String
                                     */
                                    uri: {
                                        setter: function(v) {
                                            return this._parseURL(v);
                                        },
                                        value: null,
                                        validator: isString
                                    },
                            
                                    // User readOnly variables
                            
                                    /**
                                     * Whether the transaction is active or not.
                                     *
                                     * @attribute active
                                     * @default false
                                     * @type Boolean
                                     */
                                    active: {
                                        value: false,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Object containing all the [IO Configuration Attributes](A.io.html).
                                     * This Object is passed to the `A.io` internally.
                                     *
                                     * @attribute cfg
                                     * @default Object containing all the [IO Configuration
                                     *     Attributes](A.io.html).
                                     * @readOnly
                                     * @type String
                                     */
                                    cfg: {
                                        getter: function() {
                                            var instance = this;
                            
                                            // keep the current cfg object always synchronized with the
                                            // mapped public attributes when the user call .start() it
                                            // always retrieve the last set values for each mapped attr
                                            return {
                                                arguments: instance.get('arguments'),
                                                context: instance.get('context'),
                                                data: instance.getFormattedData(),
                                                form: instance.get('form'),
                                                headers: instance.get('headers'),
                                                method: instance.get('method'),
                                                on: {
                                                    complete: A.bind(instance.fire, instance, 'complete'),
                                                    end: A.bind(instance._end, instance),
                                                    failure: A.bind(instance.fire, instance, 'failure'),
                                                    start: A.bind(instance.fire, instance, 'start'),
                                                    success: A.bind(instance._success, instance)
                                                },
                                                sync: instance.get('sync'),
                                                timeout: instance.get('timeout'),
                                                xdr: instance.get('xdr')
                                            };
                                        },
                                        readOnly: true
                                    },
                            
                                    /**
                                     * Stores the IO Object of the current transaction.
                                     *
                                     * @attribute transaction
                                     * @default null
                                     * @type Object
                                     */
                                    transaction: {
                                        value: null
                                    },
                            
                                    // Configuration Object mapping
                                    // To take advantages of the Attribute listeners of A.Base
                                    // See: http://yuilibrary.com/yui/docs/io/
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute arguments
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Object
                                     */
                                    arguments: {
                                        valueFn: getDefault('arguments')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute context
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Object
                                     */
                                    context: {
                                        valueFn: getDefault('context')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute data
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Object
                                     */
                                    data: {
                                        valueFn: getDefault('data')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute form
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Object
                                     */
                                    form: {
                                        valueFn: getDefault('form')
                                    },
                            
                                    /**
                                     * Set the correct ACCEPT header based on the dataType.
                                     *
                                     * @attribute headers
                                     * @default Object
                                     * @type Object
                                     */
                                    headers: {
                                        getter: function(value) {
                                            var header = [];
                                            var instance = this;
                                            var dataType = instance.get('dataType');
                            
                                            if (dataType) {
                                                header.push(
                                                    ACCEPTS[dataType]
                                                );
                                            }
                            
                                            // always add *.* to the accept header
                                            header.push(
                                                ACCEPTS.all
                                            );
                            
                                            return A.merge(
                                                value, {
                                                    Accept: header.join(', ')
                                                }
                                            );
                                        },
                                        valueFn: getDefault('headers')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute method
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type String
                                     */
                                    method: {
                                        setter: function(val) {
                                            return val.toLowerCase();
                                        },
                                        valueFn: getDefault('method')
                                    },
                            
                                    /**
                                     * A selector to be used to query against the response of the
                                     * request. Only works if the response is XML or HTML.
                                     *
                                     * @attribute selector
                                     * @default null
                                     * @type String
                                     */
                                    selector: {
                                        value: null
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute sync
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Boolean
                                     */
                                    sync: {
                                        valueFn: getDefault('sync')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute timeout
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Number
                                     */
                                    timeout: {
                                        valueFn: getDefault('timeout')
                                    },
                            
                                    /**
                                     * See [IO
                                     * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     *
                                     * @attribute xdr
                                     * @default Value mapped on YUI.AUI.defaults.io.
                                     * @type Object
                                     */
                                    xdr: {
                                        valueFn: getDefault('xdr')
                                    }
                                },
                            
                                /**
                                 * Static property used to define which component it extends.
                                 *
                                 * @property EXTENDS
                                 * @type Object
                                 * @static
                                 */
                                EXTENDS: A.Plugin.Base,
                            
                                prototype: {
                            
                                    /**
                                     * Construction logic executed during IORequest instantiation.
                                     * Lifecycle.
                                     *
                                     * @method initializer
                                     * @param config
                                     * @protected
                                     */
                                    init: function() {
                                        var instance = this;
                            
                                        IORequest.superclass.init.apply(this, arguments);
                            
                                        instance._autoStart();
                                    },
                            
                                    /**
                                     * Destructor lifecycle implementation for the `IORequest` class.
                                     * Purges events attached to the node (and all child nodes).
                                     *
                                     * @method destructor
                                     * @protected
                                     */
                                    destructor: function() {
                                        var instance = this;
                            
                                        instance.stop();
                            
                                        instance.set('transaction', null);
                                    },
                            
                                    /**
                                     * Applies the `YUI.AUI.defaults.io.dataFormatter` if
                                     * defined and return the formatted data.
                                     *
                                     * @method getFormattedData
                                     * @return {String}
                                     */
                                    getFormattedData: function() {
                                        var instance = this;
                                        var value = instance.get('data');
                                        var dataFormatter = defaults.dataFormatter;
                            
                                        if (isFunction(dataFormatter)) {
                                            value = dataFormatter.call(instance, value);
                                        }
                            
                                        return value;
                                    },
                            
                                    /**
                                     * Starts the IO transaction. Used to refresh the content also.
                                     *
                                     * @method start
                                     */
                                    start: function() {
                                        var instance = this;
                            
                                        instance.destructor();
                            
                                        instance.set('active', true);
                            
                                        var ioObj = instance._yuiIOObj;
                            
                                        if (!ioObj) {
                                            ioObj = new A.IO();
                            
                                            instance._yuiIOObj = ioObj;
                                        }
                            
                                        var transaction = ioObj.send(
                                            instance.get('uri'),
                                            instance.get('cfg')
                                        );
                            
                                        instance.set('transaction', transaction);
                                    },
                            
                                    /**
                                     * Stops the IO transaction.
                                     *
                                     * @method stop
                                     */
                                    stop: function() {
                                        var instance = this;
                                        var transaction = instance.get('transaction');
                            
                                        if (transaction) {
                                            transaction.abort();
                                        }
                                    },
                            
                                    /**
                                     * Invoke the `start` method (autoLoad attribute).
                                     *
                                     * @method _autoStart
                                     * @protected
                                     */
                                    _autoStart: function() {
                                        var instance = this;
                            
                                        if (instance.get('autoLoad')) {
                                            instance.start();
                                        }
                                    },
                            
                                    /**
                                     * Parse the [uri](A.IORequest.html#attr_uri) to add a
                                     * timestamp if [cache](A.IORequest.html#attr_cache) is
                                     * `true`. Also applies the `YUI.AUI.defaults.io.uriFormatter`.
                                     *
                                     * @method _parseURL
                                     * @param {String} url
                                     * @protected
                                     * @return {String}
                                     */
                                    _parseURL: function(url) {
                                        var instance = this;
                                        var cache = instance.get('cache');
                                        var method = instance.get('method');
                            
                                        // reusing logic to add a timestamp on the url from jQuery 1.3.2
                                        if ((cache === false) && (method === 'get')) {
                                            var ts = +new Date();
                                            // try replacing _= if it is there
                                            var ret = url.replace(/(\?|&)_=.*?(&|$)/, '$1_=' + ts + '$2');
                                            // if nothing was replaced, add timestamp to the end
                                            url = ret + ((ret === url) ? (url.match(/\?/) ? '&' : '?') + '_=' + ts : '');
                                        }
                            
                                        // formatting the URL with the default uriFormatter after the cache
                                        // timestamp was added
                                        var uriFormatter = defaults.uriFormatter;
                            
                                        if (isFunction(uriFormatter)) {
                                            url = uriFormatter.apply(instance, [url]);
                                        }
                            
                                        return url;
                                    },
                            
                                    /**
                                     * Internal end callback for the IO transaction.
                                     *
                                     * @method _end
                                     * @param {Number} id ID of the IO transaction.
                                     * @param {Object} args Custom arguments, passed to the event handler.
                                     *     See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     * @protected
                                     */
                                    _end: function(id, args) {
                                        var instance = this;
                            
                                        instance.set('active', false);
                                        instance.set('transaction', null);
                            
                                        instance.fire('end', id, args);
                                    },
                            
                                    /**
                                     * Internal success callback for the IO transaction.
                                     *
                                     * @method _success
                                     * @param {Number} id ID of the IO transaction.
                                     * @param {Object} obj IO transaction Object.
                                     * @param {Object} args Custom arguments, passed to the event handler.
                                     *     See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
                                     * @protected
                                     */
                                    _success: function(id, obj, args) {
                                        var instance = this;
                            
                                        // update the responseData attribute with the new data from xhr
                                        instance.set('responseData', obj);
                            
                                        instance.fire('success', id, obj, args);
                                    },
                            
                                    /**
                                     * Setter for [responseData](A.IORequest.html#attr_responseData).
                                     *
                                     * @method _setResponseData
                                     * @protected
                                     * @param {Object} xhr XHR Object.
                                     * @return {Object}
                                     */
                                    _setResponseData: function(xhr) {
                                        var data = null;
                                        var instance = this;
                            
                                        if (xhr) {
                                            var dataType = instance.get('dataType');
                                            var contentType = xhr.getResponseHeader('content-type') || '';
                            
                                            // if the dataType or the content-type is XML...
                                            if ((dataType === 'xml') ||
                                                (!dataType && contentType.indexOf('xml') >= 0)) {
                            
                                                // use responseXML
                                                data = xhr.responseXML;
                            
                                                // check if the XML was parsed correctly
                                                if (data.documentElement.tagName === 'parsererror') {
                                                    throw 'Parser error: IO dataType is not correctly parsing';
                                                }
                                            }
                                            else {
                                                // otherwise use the responseText
                                                data = xhr.responseText;
                                            }
                            
                                            // empty string is not a valid 'json', convert it to null
                                            if (data === '') {
                                                data = null;
                                            }
                            
                                            // trying to parse to JSON if dataType is a valid json
                                            if (dataType === 'json') {
                                                try {
                                                    data = A.JSON.parse(data);
                                                }
                                                catch (e) {
                                                    // throw 'Parser error: IO dataType is not correctly parsing';
                                                }
                                            }
                                            else {
                                                var selector = instance.get('selector');
                            
                                                if (data && selector) {
                                                    var tempRoot;
                            
                                                    if (data.documentElement) {
                                                        tempRoot = A.one(data);
                                                    }
                                                    else {
                                                        tempRoot = A.Node.create(data);
                                                    }
                            
                                                    data = tempRoot.all(selector);
                                                }
                                            }
                                        }
                            
                                        return data;
                                    }
                                }
                            });
                            
                            A.IORequest = IORequest;
                            
                            /**
                             * Alloy IO extension
                             *
                             * @class A.io
                             * @static
                             */
                            
                            /**
                             * Static method to invoke the [IORequest](A.IORequest.html).
                             * Likewise [IO](A.io.html).
                             *
                             * @method A.io.request
                             * @for A.io
                             * @param {String} uri URI to be requested.
                             * @param {Object} config Configuration Object for the [IO](A.io.html).
                             * @return {IORequest}
                             */
                            A.io.request = function(uri, config) {
                                return new A.IORequest(
                                    A.merge(config, {
                                        uri: uri
                                    })
                                );
                            };