/* Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ /** * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts * asynchronously. */ /** * Load scripts asynchronously. * @namespace * @example */ CKEDITOR.scriptLoader = (function() { var uniqueScripts = {}, waitingList = {}; return /** @lends CKEDITOR.scriptLoader */ { /** * Loads one or more external script checking if not already loaded * previously by this function. * @param {String|Array} scriptUrl One or more URLs pointing to the * scripts to be loaded. * @param {Function} [callback] A function to be called when the script * is loaded and executed. If a string is passed to "scriptUrl", a * boolean parameter is passed to the callback, indicating the * success of the load. If an array is passed instead, two array * parameters are passed to the callback; the first contains the * URLs that have been properly loaded, and the second the failed * ones. * @param {Object} [scope] The scope ("this" reference) to be used for * the callback call. Default to {@link CKEDITOR}. * @param {Boolean} [showBusy] Changes the cursor of the document while + * the script is loaded. * @example * CKEDITOR.scriptLoader.load( '/myscript.js' ); * @example * CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) * { * // Alerts "true" if the script has been properly loaded. * // HTTP error 404 should return "false". * alert( success ); * }); * @example * CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) * { * alert( 'Number of scripts loaded: ' + completed.length ); * alert( 'Number of failures: ' + failed.length ); * }); */ load : function( scriptUrl, callback, scope, showBusy ) { var isString = ( typeof scriptUrl == 'string' ); if ( isString ) scriptUrl = [ scriptUrl ]; if ( !scope ) scope = CKEDITOR; var scriptCount = scriptUrl.length, completed = [], failed = []; var doCallback = function( success ) { if ( callback ) { if ( isString ) callback.call( scope, success ); else callback.call( scope, completed, failed ); } }; if ( scriptCount === 0 ) { doCallback( true ); return; } var checkLoaded = function( url, success ) { ( success ? completed : failed ).push( url ); if ( --scriptCount <= 0 ) { showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' ); doCallback( success ); } }; var onLoad = function( url, success ) { // Mark this script as loaded. uniqueScripts[ url ] = 1; // Get the list of callback checks waiting for this file. var waitingInfo = waitingList[ url ]; delete waitingList[ url ]; // Check all callbacks waiting for this file. for ( var i = 0 ; i < waitingInfo.length ; i++ ) waitingInfo[ i ]( url, success ); }; var loadScript = function( url ) { if ( uniqueScripts[ url ] ) { checkLoaded( url, true ); return; } var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] ); waitingInfo.push( checkLoaded ); // Load it only for the first request. if ( waitingInfo.length > 1 ) return; // Create the