Alloy UI

aui-io  1.0.1

 
Filters
AUI.add('aui-io-request', function(A) {
/**
 * 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 = YUI.AUI.namespace('defaults.io'),

	getDefault = function(attr) {
		return function() {
			return defaults[attr];
		};
	},

	ACTIVE = 'active',
	ARGUMENTS = 'arguments',
	AUTO_LOAD = 'autoLoad',
	CACHE = 'cache',
	CFG = 'cfg',
	COMPLETE = 'complete',
	CONTENT_TYPE = 'content-type',
	CONTEXT = 'context',
	DATA = 'data',
	DATA_TYPE = 'dataType',
	EMPTY_STRING = '',
	END = 'end',
	FAILURE = 'failure',
	FORM = 'form',
	GET = 'get',
	HEADERS = 'headers',
	IO_REQUEST = 'IORequest',
	JSON = 'json',
	METHOD = 'method',
	RESPONSE_DATA = 'responseData',
	START = 'start',
	SUCCESS = 'success',
	SYNC = 'sync',
	TIMEOUT = 'timeout',
	TRANSACTION = 'transaction',
	URI = 'uri',
	XDR = 'xdr',
	XML = 'xml',

	PARSE_ERROR = 'Parser error: IO dataType is not correctly parsing',

	ACCEPTS = {
		all: '*/*',
		html: 'text/html',
		json: 'application/json, text/javascript',
		text: 'text/plain',
		xml: 'application/xml, text/xml'
	};

/**
 * A base class for IORequest, providing:
 * <ul>
 *    <li>Response data normalization for XML, JSON, JavaScript</li>
 *    <li>Cache options</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>A.io.request(uri, config);</code></pre>
 *
 * Check the list of <a href="IORequest.html#configattributes">Configuration Attributes</a> available for
 * IORequest.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class IORequest
 * @constructor
 * @extends Plugin.Base
 * @uses io
 */
var IORequest = A.Component.create(
	{
		/**
		 * Static property provides a string to identify the class.
		 *
		 * @property IORequest.NAME
		 * @type String
		 * @static
		 */
		NAME: IO_REQUEST,

		/**
		 * Static property used to define the default attribute
		 * configuration for the IORequest.
		 *
		 * @property IORequest.ATTRS
		 * @type Object
		 * @static
		 */
		ATTRS: {
			/**
			 * If <code>true</code> invoke the
	         * <a href="IORequest.html#method_start">start</a> method automatically,
	         * initializing the IO transaction.
			 *
			 * @attribute autoLoad
			 * @default true
			 * @type boolean
			 */
			autoLoad: {
				value: true,
				validator: isBoolean
			},

			/**
			 * If <code>false</code> 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 || EMPTY_STRING).toLowerCase();
				},
				value: null,
				validator: isString
			},

			/**
			 * This is a normalized attribute for the response data. It's useful
	         * to retrieve the correct type for the
	         * <a href="IORequest.html#config_dataType">dataType</a> (i.e., in json
	         * requests the <code>responseData</code>) 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
	         * <a href="io.html#configattributes">IO Configuration Attributes</a>.
	         * This Object is passed to the <code>A.io</code> internally.
			 *
			 * @attribute cfg
			 * @default Object containing all the
	         * <a href="io.html#configattributes">IO Configuration Attributes</a>.
	         * @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.get(DATA),
						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://developer.yahoo.com/yui/3/io/

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute arguments
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type Object
			 */
			arguments: {
				valueFn: getDefault(ARGUMENTS)
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute context
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type Object
			 */
			context: {
				valueFn: getDefault(CONTEXT)
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute data
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type Object
			 */
			data: {
				valueFn: getDefault(DATA),
				setter: '_setIOData'
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @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(DATA_TYPE);

					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 <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute method
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type String
			 */
			method: {
				valueFn: getDefault(METHOD)
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute sync
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type boolean
			 */
			sync: {
				valueFn: getDefault(SYNC)
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	        * Configuration</a>.
			 *
			 * @attribute timeout
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type Number
			 */
			timeout: {
				valueFn: getDefault(TIMEOUT)
			},

			/**
			 * See <a href="http://developer.yahoo.com/yui/3/io/#configuration">IO
	         * Configuration</a>.
			 *
			 * @attribute xdr
			 * @default Value mapped on YUI.AUI.defaults.io.
			 * @type Object
			 */
			xdr: {
				valueFn: getDefault(XDR)
			}
		},

		EXTENDS: A.Plugin.Base,

		prototype: {
			/**
			 * Construction logic executed during IORequest instantiation. Lifecycle.
			 *
			 * @method initializer
			 * @protected
			 */
			init: function(config) {
				var instance = this;

				IORequest.superclass.init.apply(this, arguments);

				instance._autoStart();
			},

			/**
			 * Descructor 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);
			},

			/**
			 * Starts the IO transaction. Used to refresh the content also.
			 *
			 * @method start
			 */
			start: function() {
				var instance = this;

				instance.destructor();

				instance.set(ACTIVE, true);

				var transaction = A.io(
					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 <code>start</code> method (autoLoad attribute).
			 *
			 * @method _autoStart
			 * @protected
			 */
			_autoStart: function() {
				var instance = this;

				if (instance.get(AUTO_LOAD)) {
					instance.start();
				}
			},

			/**
			 * Parse the <a href="IORequest.html#config_uri">uri</a> to add a
		     * timestamp if <a href="IORequest.html#config_cache">cache</a> is
		     * <code>true</code>. Also applies the
		     * <code>YUI.AUI.defaults.io.uriFormatter</code>.
			 *
			 * @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.
			 * @protected
			 */
			_end: function(id) {
				var instance = this;

				instance.set(ACTIVE, false);
				instance.set(TRANSACTION, null);

				instance.fire(END, id);
			},

			/**
			 * Internal success callback for the IO transaction.
			 *
			 * @method _success
			 * @param {Number} id ID of the IO transaction.
			 * @param {Object} obj IO transaction Object.
			 * @protected
			 */
			_success: function(id, obj) {
				var instance = this;

				// update the responseData attribute with the new data from xhr
				instance.set(RESPONSE_DATA, obj);

				instance.fire(SUCCESS, id, obj);
			},

			/**
			 * Applies the <code>YUI.AUI.defaults.io.dataFormatter</code> if defined.
			 *
			 * @method _setIOData
			 * @param {Object} value
			 * @protected
			 * @return {String}
			 */
			_setIOData: function(value) {
				var instance = this;

				var dataFormatter = defaults.dataFormatter;

				if (isFunction(dataFormatter)) {
					value = dataFormatter.call(instance, value);
				}

				return value;
			},

			/**
			 * Setter for <a href="IORequest.html#config_responseData">responseData</a>.
			 *
			 * @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(DATA_TYPE);
					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 PARSE_ERROR;
						}
					}
					else {
						// otherwise use the responseText
						data = xhr.responseText;
					}

					// empty string is not a valid JSON, convert it to null
					if (data === EMPTY_STRING) {
						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 PARSE_ERROR;
						}
					}
				}

				return data;
			}
		}
	}
);

A.IORequest = IORequest;

/**
 * Alloy IO extension
 *
 * @class A.io
 * @static
 */

/**
 * Static method to invoke the <a href="IORequest.html">IORequest</a>. Likewise <a href="io.html#method_io">io</a>.
 *
 * @method A.io.request
 * @for A.io
 * @param {String} uri URI to be requested.
 * @param {Object} config Configuration Object for the <a href="io.html">IO</a>.
 * @return {IORequest}
 */
A.io.request = function(uri, config) {
	return new A.IORequest(
		A.merge(config, {
			uri: uri
		})
	);
};

}, '@VERSION@' ,{requires:['aui-base','io-base','json','plugin','querystring-stringify']});
AUI.add('aui-io-plugin', function(A) {
/**
 * The IOPlugin Utility - When plugged to a Node or Widget loads the content
 * of a URI and set as its content, parsing the <code>script</code> tags if
 * present on the code.
 *
 * @module aui-io
 * @submodule aui-io-plugin
 */

var L = A.Lang,
	isBoolean = L.isBoolean,
	isString = L.isString,

	isNode = function(v) {
		return (v instanceof A.Node);
	},

	StdMod = A.WidgetStdMod,

	TYPE_NODE = 'Node',
	TYPE_WIDGET = 'Widget',

	EMPTY = '',
	FAILURE = 'failure',
	FAILURE_MESSAGE = 'failureMessage',
	HOST = 'host',
	ICON = 'icon',
	IO = 'io',
	IO_PLUGIN = 'IOPlugin',
	LOADING = 'loading',
	LOADING_MASK = 'loadingMask',
	NODE = 'node',
	PARSE_CONTENT = 'parseContent',
	QUEUE = 'queue',
	RENDERED = 'rendered',
	SECTION = 'section',
	SHOW_LOADING = 'showLoading',
	SUCCESS = 'success',
	TYPE = 'type',
	WHERE = 'where',

	getCN = A.ClassNameManager.getClassName,

	CSS_ICON_LOADING = getCN(ICON, LOADING);

/**
 * A base class for IOPlugin, providing:
 * <ul>
 *    <li>Loads the content of a URI as content of a Node or Widget</li>
 *    <li>Use <a href="ParseContent.html">ParseContent</a> to parse the JavaScript tags from the content and evaluate them</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>A.one('#content').plug(A.Plugin.IO, { uri: 'assets/content.html', method: 'GET' });</code></pre>
 *
 * Check the list of <a href="A.Plugin.IO.html#configattributes">Configuration Attributes</a> available for
 * IOPlugin.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class A.Plugin.IO
 * @constructor
 * @extends IORequest
 */
var IOPlugin = A.Component.create(
	{
		/**
		 * Static property provides a string to identify the class.
		 *
		 * @property A.Plugin.IO.NAME
		 * @type String
		 * @static
		 */
		NAME: IO_PLUGIN,

		/**
		 * Static property provides a string to identify the namespace.
		 *
		 * @property A.Plugin.IO.NS
		 * @type String
		 * @static
		 */
		NS: IO,

		/**
		 * Static property used to define the default attribute
		 * configuration for the A.Plugin.IO.
		 *
		 * @property A.Plugin.IO.ATTRS
		 * @type Object
		 * @static
		 */
		ATTRS: {
			/**
			 * Plug IO in any object we want, the setContent will use the node to
	         * set the content.
			 *
			 * @attribute node
			 * @default null
			 * @type Node | String
			 */
			node: {
				value: null,
				getter: function(value) {
					var instance = this;

					if (!value) {
						var host = instance.get(HOST);
						var type = instance.get(TYPE);

						if (type == TYPE_NODE) {
							value = host;
						}
						else if (type == TYPE_WIDGET) {
							var section = instance.get(SECTION);

							// if there is no node for the SECTION, forces creation
							if (!host.getStdModNode(section)) {
								host.setStdModContent(section, EMPTY);
							}

							value = host.getStdModNode(section);
						}
					}

					return A.one(value);
				},
				validator: isNode
			},

			/**
			 * Message to be set on the content when the transaction fails.
			 *
			 * @attribute failureMessage
			 * @default 'Failed to retrieve content'
			 * @type String
			 */
			failureMessage: {
				value: 'Failed to retrieve content',
				validator: isString
			},

			/**
			 * Options passed to the <a href="LoadingMask.html">LoadingMask</a>.
			 *
			 * @attribute loadingMask
			 * @default {}
			 * @type Object
			 */
			loadingMask: {
				value: {}
			},

			/**
			 * If true the <a href="ParseContent.html">ParseContent</a> plugin
	         * will be plugged to the <a href="A.Plugin.IO.html#config_node">node</a>.
			 *
			 * @attribute parseContent
			 * @default true
			 * @type boolean
			 */
			parseContent: {
				value: true,
				validator: isBoolean
			},

			/**
			 * Show the <a href="LoadingMask.html">LoadingMask</a> covering the <a
	         * href="A.Plugin.IO.html#config_node">node</a> while loading.
			 *
			 * @attribute showLoading
			 * @default true
			 * @type boolean
			 */
			showLoading: {
				value: true,
				validator: isBoolean
			},

			/**
			 * Section where the content will be set in case you are plugging it
	         * on a instace of <a href="WidgetStdMod.html">WidgetStdMod</a>.
			 *
			 * @attribute section
			 * @default StdMod.BODY
			 * @type String
			 */
			section: {
				value: StdMod.BODY,
				validator: function(val) {
					return (!val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER);
				}
			},

			/**
			 * Type of the <code>instance</code> we are pluggin the A.Plugin.IO.
	         * Could be a Node, or a Widget.
			 *
			 * @attribute type
			 * @default 'Node'
			 * @readOnly
			 * @type String
			 */
			type: {
				readOnly: true,
				valueFn: function() {
					var instance = this;
					// NOTE: default type
					var type = TYPE_NODE;

					if (instance.get(HOST) instanceof A.Widget) {
						type = TYPE_WIDGET;
					}

					return type;
				},
				validator: isString
			},

			/**
			 * Where to insert the content, AFTER, BEFORE or REPLACE.
			 *
			 * @attribute where
			 * @default StdMod.REPLACE
			 * @type String
			 */
			where: {
				value: StdMod.REPLACE,
				validator: function(val) {
					return (!val || val == StdMod.AFTER || val == StdMod.BEFORE || val == StdMod.REPLACE);
				}
			}
		},

		EXTENDS: A.IORequest,

		prototype: {
			/**
			 * Bind the events on the A.Plugin.IO UI. Lifecycle.
			 *
			 * @method bindUI
			 * @protected
			 */
			bindUI: function() {
				var instance = this;

				instance.on('activeChange', instance._onActiveChange);

				instance.on(SUCCESS, instance._successHandler);
				instance.on(FAILURE, instance._failureHandler);

				if ((instance.get(TYPE) == TYPE_WIDGET) && instance.get(SHOW_LOADING)) {
					var host = instance.get(HOST);

					host.after('heightChange', instance._syncLoadingMaskUI, instance);
					host.after('widthChange', instance._syncLoadingMaskUI, instance);
				}
			},

			/**
			 * Invoke the <code>start</code> method (autoLoad attribute).
			 *
			 * @method _autoStart
			 * @protected
			 */
			_autoStart: function() {
				var instance = this;

				instance.bindUI();

				IOPlugin.superclass._autoStart.apply(this, arguments);
			},

			/**
			 * Bind the ParseContent plugin on the <code>instance</code>.
			 *
			 * @method _bindParseContent
			 * @protected
			 */
			_bindParseContent: function() {
				var instance = this;
				var node = instance.get(NODE);

				if (node && !node.ParseContent && instance.get(PARSE_CONTENT)) {
					node.plug(A.Plugin.ParseContent);
				}
			},

			/**
			 * Invoke the <a href="OverlayMask.html#method_hide">OverlayMask hide</a> method.
			 *
			 * @method hideLoading
			 */
			hideLoading: function() {
				var instance = this;

				var node = instance.get(NODE);

				if (node.loadingmask) {
					node.loadingmask.hide();
				}
			},

			/**
			 * Set the content of the <a href="A.Plugin.IO.html#config_node">node</a>.
			 *
			 * @method setContent
			 */
			setContent: function(content) {
				var instance = this;

				instance._bindParseContent();

				if (instance.overlayMaskBoundingBox) {
					instance.overlayMaskBoundingBox.remove();
				}

				instance._getContentSetterByType().apply(instance, [content]);
			},

			/**
			 * Invoke the <a href="OverlayMask.html#method_show">OverlayMask show</a> method.
			 *
			 * @method showLoading
			 */
			showLoading: function() {
				var instance = this;
				var node = instance.get(NODE);

				if (node.loadingmask) {
					if (instance.overlayMaskBoundingBox) {
						node.append(instance.overlayMaskBoundingBox);
					}
				}
				else {
					node.plug(
						A.LoadingMask,
						instance.get(LOADING_MASK)
					);

					instance.overlayMaskBoundingBox = node.loadingmask.overlayMask.get('boundingBox');
				}

				node.loadingmask.show();
			},

			/**
			 * Overload to the <a href="IORequest.html#method_start">IORequest
		     * start</a> method. Check if the <code>host</code> is already rendered,
		     * otherwise wait to after render phase and to show the LoadingMask.
			 *
			 * @method start
			 */
			start: function() {
				var instance = this;
				var host = instance.get(HOST);

				if (!host.get(RENDERED)) {
					host.after('render', function() {
						instance._setLoadingUI(true);
					});
				}

				IOPlugin.superclass.start.apply(instance, arguments);
			},

			/**
			 * Get the appropriated <a
		     * href="A.Plugin.IO.html#method_setContent">setContent</a> function
		     * implementation for each <a href="A.Plugin.IO.html#config_type">type</a>.
			 *
			 * @method _getContentSetterByType
			 * @protected
			 * @return {function}
			 */
			_getContentSetterByType: function() {
				var instance = this;

				var setters = {
					// NOTE: default setter, see 'type' attribute definition
					Node: function(content) {
						var instance = this;
						// when this.get(HOST) is a Node instance the NODE is the host
						var node = instance.get(NODE);

						node.setContent.apply(node, [content]);
					},

					// Widget forces set the content on the SECTION node using setStdModContent method
					Widget: function(content) {
						var instance = this;
						var host = instance.get(HOST);

						host.setStdModContent.apply(host, [
							instance.get(SECTION),
							content,
							instance.get(WHERE)
						]);
					}
				};

				return setters[this.get(TYPE)];
			},

			/**
			 * Whether the <code>show</code> is true show the LoadingMask.
			 *
			 * @method _setLoadingUI
			 * @param {boolean} show
			 * @protected
			 */
			_setLoadingUI: function(show) {
				var instance = this;

				if (instance.get(SHOW_LOADING)) {
					if (show) {
						instance.showLoading();
					}
					else {
						instance.hideLoading();
					}
				}
			},

			/**
			 * Sync the loading mask UI.
			 *
			 * @method _syncLoadingMaskUI
			 * @protected
			 */
			_syncLoadingMaskUI: function() {
				var instance = this;

				instance.get(NODE).loadingmask.refreshMask();
			},

			/**
			 * Internal success callback for the IO transaction.
			 *
			 * @method _successHandler
			 * @param {EventFavade} event
			 * @param {String} id Id of the IO transaction.
			 * @param {Object} obj XHR transaction Object.
			 * @protected
			 */
			_successHandler: function(event, id, xhr) {
				var instance = this;

				instance.setContent(
					xhr.responseText
				);
			},

			/**
			 * Internal failure callback for the IO transaction.
			 *
			 * @method _failureHandler
			 * @param {EventFavade} event
			 * @param {String} id Id of the IO transaction.
			 * @param {Object} obj XHR transaction Object.
			 * @protected
			 */
			_failureHandler: function(event, id, xhr) {
				var instance = this;

				instance.setContent(
					instance.get(FAILURE_MESSAGE)
				);
			},

			/**
			 * Fires after the value of the
			 * <a href="A.Plugin.IO.html#config_active">active</a> attribute change.
			 *
			 * @method _onActiveChange
			 * @param {EventFacade} event
			 * @protected
			 */
			_onActiveChange: function(event) {
				var instance = this;
				var host = instance.get(HOST);
				var widget = instance.get(TYPE) == TYPE_WIDGET;

				if (!widget || (widget && host && host.get(RENDERED))) {
					instance._setLoadingUI(event.newVal);
				}
			}
		}
	}
);

A.namespace('Plugin').IO = IOPlugin;

}, '@VERSION@' ,{requires:['aui-overlay-base','aui-parse-content','aui-io-request','aui-loading-mask']});


AUI.add('aui-io', function(A){}, '@VERSION@' ,{skinnable:false, use:['aui-io-request','aui-io-plugin']});