      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