2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
7 * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
12 * Load scripts asynchronously.
16 CKEDITOR
.scriptLoader
= (function()
18 var uniqueScripts
= {},
21 return /** @lends CKEDITOR.scriptLoader */ {
23 * Loads one or more external script checking if not already loaded
24 * previously by this function.
25 * @param {String|Array} scriptUrl One or more URLs pointing to the
26 * scripts to be loaded.
27 * @param {Function} [callback] A function to be called when the script
28 * is loaded and executed. If a string is passed to "scriptUrl", a
29 * boolean parameter is passed to the callback, indicating the
30 * success of the load. If an array is passed instead, two array
31 * parameters are passed to the callback; the first contains the
32 * URLs that have been properly loaded, and the second the failed
34 * @param {Object} [scope] The scope ("this" reference) to be used for
35 * the callback call. Default to {@link CKEDITOR}.
36 * @param {Boolean} [showBusy] Changes the cursor of the document while
37 + * the script is loaded.
39 * CKEDITOR.scriptLoader.load( '/myscript.js' );
41 * CKEDITOR.scriptLoader.load( '/myscript.js', function( success )
43 * // Alerts "true" if the script has been properly loaded.
44 * // HTTP error 404 should return "false".
48 * CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed )
50 * alert( 'Number of scripts loaded: ' + completed.length );
51 * alert( 'Number of failures: ' + failed.length );
54 load : function( scriptUrl
, callback
, scope
, showBusy
)
56 var isString
= ( typeof scriptUrl
== 'string' );
59 scriptUrl
= [ scriptUrl
];
64 var scriptCount
= scriptUrl
.length
,
68 var doCallback = function( success
)
73 callback
.call( scope
, success
);
75 callback
.call( scope
, completed
, failed
);
79 if ( scriptCount
=== 0 )
85 var checkLoaded = function( url
, success
)
87 ( success
? completed
: failed
).push( url
);
89 if ( --scriptCount
<= 0 )
91 showBusy
&& CKEDITOR
.document
.getDocumentElement().removeStyle( 'cursor' );
92 doCallback( success
);
96 var onLoad = function( url
, success
)
98 // Mark this script as loaded.
99 uniqueScripts
[ url
] = 1;
101 // Get the list of callback checks waiting for this file.
102 var waitingInfo
= waitingList
[ url
];
103 delete waitingList
[ url
];
105 // Check all callbacks waiting for this file.
106 for ( var i
= 0 ; i
< waitingInfo
.length
; i
++ )
107 waitingInfo
[ i
]( url
, success
);
110 var loadScript = function( url
)
112 if ( uniqueScripts
[ url
] )
114 checkLoaded( url
, true );
118 var waitingInfo
= waitingList
[ url
] || ( waitingList
[ url
] = [] );
119 waitingInfo
.push( checkLoaded
);
121 // Load it only for the first request.
122 if ( waitingInfo
.length
> 1 )
125 // Create the <script> element.
126 var script
= new CKEDITOR
.dom
.element( 'script' );
127 script
.setAttributes( {
128 type
: 'text/javascript',
133 if ( CKEDITOR
.env
.ie
)
135 // FIXME: For IE, we are not able to return false on error (like 404).
138 script
.$.onreadystatechange = function ()
140 if ( script
.$.readyState
== 'loaded' || script
.$.readyState
== 'complete' )
142 script
.$.onreadystatechange
= null;
150 script
.$.onload = function()
152 // Some browsers, such as Safari, may call the onLoad function
153 // immediately. Which will break the loading sequence. (#3661)
154 setTimeout( function() { onLoad( url
, true ); }, 0 );
157 // FIXME: Opera and Safari will not fire onerror.
160 script
.$.onerror = function()
162 onLoad( url
, false );
167 // Append it to <head>.
168 script
.appendTo( CKEDITOR
.document
.getHead() );
170 CKEDITOR
.fire( 'download', url
); // @Packager.RemoveLine
173 showBusy
&& CKEDITOR
.document
.getDocumentElement().setStyle( 'cursor', 'wait' );
174 for ( var i
= 0 ; i
< scriptCount
; i
++ )
176 loadScript( scriptUrl
[ i
] );