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