/* global ActiveXObject */ /** * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @fileOverview Defines the {@link CKEDITOR.ajax} object, which stores Ajax methods for * data loading. */ ( function() { CKEDITOR.plugins.add( 'ajax', { requires: 'xml' } ); /** * Ajax methods for data loading. * * @class * @singleton */ CKEDITOR.ajax = ( function() { function createXMLHttpRequest() { // In IE, using the native XMLHttpRequest for local files may throw // "Access is Denied" errors. if ( !CKEDITOR.env.ie || location.protocol != 'file:' ) { try { return new XMLHttpRequest(); } catch ( e ) { } } try { return new ActiveXObject( 'Msxml2.XMLHTTP' ); } catch ( e ) {} try { return new ActiveXObject( 'Microsoft.XMLHTTP' ); } catch ( e ) {} return null; } function checkStatus( xhr ) { // HTTP Status Codes: // 2xx : Success // 304 : Not Modified // 0 : Returned when running locally (file://) // 1223 : IE may change 204 to 1223 (see http://dev.jquery.com/ticket/1450) return ( xhr.readyState == 4 && ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status === 0 || xhr.status == 1223 ) ); } function getResponseText( xhr ) { if ( checkStatus( xhr ) ) return xhr.responseText; return null; } function getResponseXml( xhr ) { if ( checkStatus( xhr ) ) { var xml = xhr.responseXML; return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText ); } return null; } function load( url, callback, getResponseFn ) { var async = !!callback; var xhr = createXMLHttpRequest(); if ( !xhr ) return null; xhr.open( 'GET', url, async ); if ( async ) { // TODO: perform leak checks on this closure. xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { callback( getResponseFn( xhr ) ); xhr = null; } }; } xhr.send( null ); return async ? '' : getResponseFn( xhr ); } function post( url, data, contentType, callback, getResponseFn ) { var xhr = createXMLHttpRequest(); if ( !xhr ) return null; xhr.open( 'POST', url, true ); xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { if ( callback ) { callback( getResponseFn( xhr ) ); } xhr = null; } }; xhr.setRequestHeader( 'Content-type', contentType || 'application/x-www-form-urlencoded; charset=UTF-8' ); xhr.send( data ); } return { /** * Loads data from a URL as plain text. * * // Load data synchronously. * var data = CKEDITOR.ajax.load( 'somedata.txt' ); * alert( data ); * * // Load data asynchronously. * var data = CKEDITOR.ajax.load( 'somedata.txt', function( data ) { * alert( data ); * } ); * * @param {String} url The URL from which the data is loaded. * @param {Function} [callback] A callback function to be called on * data load. If not provided, the data will be loaded * synchronously. * @returns {String} The loaded data. For asynchronous requests, an * empty string. For invalid requests, `null`. */ load: function( url, callback ) { return load( url, callback, getResponseText ); }, /** * Creates an asynchronous POST `XMLHttpRequest` of the given `url`, `data` and optional `contentType`. * Once the request is done, regardless if it is successful or not, the `callback` is called * with `XMLHttpRequest#responseText` or `null` as an argument. * * CKEDITOR.ajax.post( 'url/post.php', 'foo=bar', null, function( data ) { * console.log( data ); * } ); * * CKEDITOR.ajax.post( 'url/post.php', JSON.stringify( { foo: 'bar' } ), 'application/json', function( data ) { * console.log( data ); * } ); * * @since 4.4 * @param {String} url The URL of the request. * @param {String/Object/Array} data Data passed to `XMLHttpRequest#send`. * @param {String} [contentType='application/x-www-form-urlencoded; charset=UTF-8'] The value of the `Content-type` header. * @param {Function} [callback] A callback executed asynchronously with `XMLHttpRequest#responseText` or `null` as an argument, * depending on the `status` of the request. */ post: function( url, data, contentType, callback ) { return post( url, data, contentType, callback, getResponseText ); }, /** * Loads data from a URL as XML. * * // Load XML synchronously. * var xml = CKEDITOR.ajax.loadXml( 'somedata.xml' ); * alert( xml.getInnerXml( '//' ) ); * * // Load XML asynchronously. * var data = CKEDITOR.ajax.loadXml( 'somedata.xml', function( xml ) { * alert( xml.getInnerXml( '//' ) ); * } ); * * @param {String} url The URL from which the data is loaded. * @param {Function} [callback] A callback function to be called on * data load. If not provided, the data will be loaded synchronously. * @returns {CKEDITOR.xml} An XML object storing the loaded data. For asynchronous requests, an * empty string. For invalid requests, `null`. */ loadXml: function( url, callback ) { return load( url, callback, getResponseXml ); } }; } )(); } )(jQuery);