]> git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blame - sources/core/scriptloader.js
Update to 4.7.3
[perso/Immae/Projets/packagist/ludivine-ckeditor-component.git] / sources / core / scriptloader.js
CommitLineData
c63493c8
IB
1/**
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
4 */
5
6/**
7 * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
8 * asynchronously.
9 */
10
11/**
12 * Load scripts asynchronously.
13 *
14 * @class
15 * @singleton
16 */
17CKEDITOR.scriptLoader = ( function() {
18 var uniqueScripts = {},
19 waitingList = {};
20
21 return {
22 /**
23 * Loads one or more external script checking if not already loaded
24 * previously by this function.
25 *
26 * CKEDITOR.scriptLoader.load( '/myscript.js' );
27 *
28 * CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) {
29 * // Alerts true if the script has been properly loaded.
30 * // HTTP error 404 should return false.
31 * alert( success );
32 * } );
33 *
34 * CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) {
35 * alert( 'Number of scripts loaded: ' + completed.length );
36 * alert( 'Number of failures: ' + failed.length );
37 * } );
38 *
39 * @param {String/Array} scriptUrl One or more URLs pointing to the
40 * scripts to be loaded.
41 * @param {Function} [callback] A function to be called when the script
42 * is loaded and executed. If a string is passed to `scriptUrl`, a
43 * boolean parameter is passed to the callback, indicating the
44 * success of the load. If an array is passed instead, two arrays
45 * parameters are passed to the callback - the first contains the
46 * URLs that have been properly loaded and the second the failed ones.
47 * @param {Object} [scope] The scope (`this` reference) to be used for
48 * the callback call. Defaults to {@link CKEDITOR}.
49 * @param {Boolean} [showBusy] Changes the cursor of the document while
50 * the script is loaded.
51 */
52 load: function( scriptUrl, callback, scope, showBusy ) {
53 var isString = ( typeof scriptUrl == 'string' );
54
55 if ( isString )
56 scriptUrl = [ scriptUrl ];
57
58 if ( !scope )
59 scope = CKEDITOR;
60
61 var scriptCount = scriptUrl.length,
62 completed = [],
63 failed = [];
64
65 var doCallback = function( success ) {
66 if ( callback ) {
67 if ( isString )
68 callback.call( scope, success );
69 else
70 callback.call( scope, completed, failed );
71 }
72 };
73
74 if ( scriptCount === 0 ) {
75 doCallback( true );
76 return;
77 }
78
79 var checkLoaded = function( url, success ) {
80 ( success ? completed : failed ).push( url );
81
82 if ( --scriptCount <= 0 ) {
83 showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' );
84 doCallback( success );
85 }
86 };
87
88 var onLoad = function( url, success ) {
89 // Mark this script as loaded.
90 uniqueScripts[ url ] = 1;
91
92 // Get the list of callback checks waiting for this file.
93 var waitingInfo = waitingList[ url ];
94 delete waitingList[ url ];
95
96 // Check all callbacks waiting for this file.
97 for ( var i = 0; i < waitingInfo.length; i++ )
98 waitingInfo[ i ]( url, success );
99 };
100
101 var loadScript = function( url ) {
102 if ( uniqueScripts[ url ] ) {
103 checkLoaded( url, true );
104 return;
105 }
106
107 var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] );
108 waitingInfo.push( checkLoaded );
109
110 // Load it only for the first request.
111 if ( waitingInfo.length > 1 )
112 return;
113
114 // Create the <script> element.
115 var script = new CKEDITOR.dom.element( 'script' );
116 script.setAttributes( {
117 type: 'text/javascript',
118 src: url
119 } );
120
121 if ( callback ) {
1794320d 122 // The onload or onerror event does not fire in IE8 and IE9 Quirks Mode (http://dev.ckeditor.com/ticket/14849).
c63493c8
IB
123 if ( CKEDITOR.env.ie && ( CKEDITOR.env.version <= 8 || CKEDITOR.env.ie9Compat ) ) {
124 script.$.onreadystatechange = function() {
125 if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' ) {
126 script.$.onreadystatechange = null;
127 onLoad( url, true );
128 }
129 };
130 } else {
131 script.$.onload = function() {
132 // Some browsers, such as Safari, may call the onLoad function
1794320d 133 // immediately. Which will break the loading sequence. (http://dev.ckeditor.com/ticket/3661)
c63493c8
IB
134 setTimeout( function() {
135 onLoad( url, true );
136 }, 0 );
137 };
138
139 script.$.onerror = function() {
140 onLoad( url, false );
141 };
142 }
143 }
144
145 // Append it to <head>.
146 script.appendTo( CKEDITOR.document.getHead() );
147
148 CKEDITOR.fire( 'download', url ); // %REMOVE_LINE%
149 };
150
151 showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' );
152 for ( var i = 0; i < scriptCount; i++ ) {
153 loadScript( scriptUrl[ i ] );
154 }
155 },
156
157 /**
158 * Loads a script in a queue, so only one is loaded at the same time.
159 *
160 * @since 4.1.2
161 * @param {String} scriptUrl URL pointing to the script to be loaded.
162 * @param {Function} [callback] A function to be called when the script
163 * is loaded and executed. A boolean parameter is passed to the callback,
164 * indicating the success of the load.
165 *
166 * @see CKEDITOR.scriptLoader#load
167 */
168 queue: ( function() {
169 var pending = [];
170
171 // Loads the very first script from queue and removes it.
172 function loadNext() {
173 var script;
174
175 if ( ( script = pending[ 0 ] ) )
176 this.load( script.scriptUrl, script.callback, CKEDITOR, 0 );
177 }
178
179 return function( scriptUrl, callback ) {
180 var that = this;
181
182 // This callback calls the standard callback for the script
183 // and loads the very next script from pending list.
184 function callbackWrapper() {
185 callback && callback.apply( this, arguments );
186
187 // Removed the just loaded script from the queue.
188 pending.shift();
189
190 loadNext.call( that );
191 }
192
193 // Let's add this script to the queue
194 pending.push( { scriptUrl: scriptUrl, callback: callbackWrapper } );
195
196 // If the queue was empty, then start loading.
197 if ( pending.length == 1 )
198 loadNext.call( this );
199 };
200 } )()
201 };
202} )();