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