1 /*
  2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
  3 For licensing, see LICENSE.html or http://ckeditor.com/license
  4 */
  5 
  6 /**
  7  * @fileOverview Defines the {@link CKEDITOR.ajax} object, which holds ajax methods for
  8  *		data loading.
  9  */
 10 
 11 (function()
 12 {
 13 	CKEDITOR.plugins.add( 'ajax',
 14 		{
 15 			requires : [ 'xml' ]
 16 		});
 17 
 18 	/**
 19 	 * Ajax methods for data loading.
 20 	 * @namespace
 21 	 * @example
 22 	 */
 23 	CKEDITOR.ajax = (function()
 24 	{
 25 		var createXMLHttpRequest = function()
 26 		{
 27 			// In IE, using the native XMLHttpRequest for local files may throw
 28 			// "Access is Denied" errors.
 29 			if ( !CKEDITOR.env.ie || location.protocol != 'file:' )
 30 				try { return new XMLHttpRequest(); } catch(e) {}
 31 
 32 			try { return new ActiveXObject( 'Msxml2.XMLHTTP' ); } catch (e) {}
 33 			try { return new ActiveXObject( 'Microsoft.XMLHTTP' ); } catch (e) {}
 34 
 35 			return null;
 36 		};
 37 
 38 		var checkStatus = function( xhr )
 39 		{
 40 			// HTTP Status Codes:
 41 			//	 2xx : Success
 42 			//	 304 : Not Modified
 43 			//	   0 : Returned when running locally (file://)
 44 			//	1223 : IE may change 204 to 1223 (see http://dev.jquery.com/ticket/1450)
 45 
 46 			return ( xhr.readyState == 4 &&
 47 					(	( xhr.status >= 200 && xhr.status < 300 ) ||
 48 						xhr.status == 304 ||
 49 						xhr.status === 0 ||
 50 						xhr.status == 1223 ) );
 51 		};
 52 
 53 		var getResponseText = function( xhr )
 54 		{
 55 			if ( checkStatus( xhr ) )
 56 				return xhr.responseText;
 57 			return null;
 58 		};
 59 
 60 		var getResponseXml = function( xhr )
 61 		{
 62 			if ( checkStatus( xhr ) )
 63 			{
 64 				var xml = xhr.responseXML;
 65 				return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
 66 			}
 67 			return null;
 68 		};
 69 
 70 		var load = function( url, callback, getResponseFn )
 71 		{
 72 			var async = !!callback;
 73 
 74 			var xhr = createXMLHttpRequest();
 75 
 76 			if ( !xhr )
 77 				return null;
 78 
 79 			xhr.open( 'GET', url, async );
 80 
 81 			if ( async )
 82 			{
 83 				// TODO: perform leak checks on this closure.
 84 				/** @ignore */
 85 				xhr.onreadystatechange = function()
 86 				{
 87 					if ( xhr.readyState == 4 )
 88 					{
 89 						callback( getResponseFn( xhr ) );
 90 						xhr = null;
 91 					}
 92 				};
 93 			}
 94 
 95 			xhr.send(null);
 96 
 97 			return async ? '' : getResponseFn( xhr );
 98 		};
 99 
100 		return 	/** @lends CKEDITOR.ajax */ {
101 
102 			/**
103 			 * Loads data from an URL as plain text.
104 			 * @param {String} url The URL from which load data.
105 			 * @param {Function} [callback] A callback function to be called on
106 			 *		data load. If not provided, the data will be loaded
107 			 *		synchronously.
108 			 * @returns {String} The loaded data. For asynchronous requests, an
109 			 *		empty string. For invalid requests, null.
110 			 * @example
111 			 * // Load data synchronously.
112 			 * var data = CKEDITOR.ajax.load( 'somedata.txt' );
113 			 * alert( data );
114 			 * @example
115 			 * // Load data asynchronously.
116 			 * var data = CKEDITOR.ajax.load( 'somedata.txt', function( data )
117 			 *     {
118 			 *         alert( data );
119 			 *     } );
120 			 */
121 			load : function( url, callback )
122 			{
123 				return load( url, callback, getResponseText );
124 			},
125 
126 			/**
127 			 * Loads data from an URL as XML.
128 			 * @param {String} url The URL from which load data.
129 			 * @param {Function} [callback] A callback function to be called on
130 			 *		data load. If not provided, the data will be loaded
131 			 *		synchronously.
132 			 * @returns {CKEDITOR.xml} An XML object holding the loaded data. For asynchronous requests, an
133 			 *		empty string. For invalid requests, null.
134 			 * @example
135 			 * // Load XML synchronously.
136 			 * var xml = CKEDITOR.ajax.loadXml( 'somedata.xml' );
137 			 * alert( xml.getInnerXml( '//' ) );
138 			 * @example
139 			 * // Load XML asynchronously.
140 			 * var data = CKEDITOR.ajax.loadXml( 'somedata.xml', function( xml )
141 			 *     {
142 			 *         alert( xml.getInnerXml( '//' ) );
143 			 *     } );
144 			 */
145 			loadXml : function( url, callback )
146 			{
147 				return load( url, callback, getResponseXml );
148 			}
149 		};
150 	})();
151 
152 })();
153