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.loader} objects, which is used to
|
---|
8 | * load core scripts and their dependencies from _source.
|
---|
9 | */
|
---|
10 |
|
---|
11 | if ( typeof CKEDITOR == 'undefined' )
|
---|
12 | CKEDITOR = {};
|
---|
13 |
|
---|
14 | if ( !CKEDITOR.loader )
|
---|
15 | {
|
---|
16 | /**
|
---|
17 | * Load core scripts and their dependencies from _source.
|
---|
18 | * @namespace
|
---|
19 | * @example
|
---|
20 | */
|
---|
21 | CKEDITOR.loader = (function()
|
---|
22 | {
|
---|
23 | // Table of script names and their dependencies.
|
---|
24 | var scripts =
|
---|
25 | {
|
---|
26 | 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/elementpath', 'core/dom/text', 'core/dom/range' ],
|
---|
27 | 'core/ajax' : [ 'core/xml' ],
|
---|
28 | 'core/ckeditor' : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ],
|
---|
29 | 'core/ckeditor_base' : [],
|
---|
30 | 'core/ckeditor_basic' : [ 'core/editor_basic', 'core/env', 'core/event' ],
|
---|
31 | 'core/command' : [],
|
---|
32 | 'core/config' : [ 'core/ckeditor_base' ],
|
---|
33 | 'core/dom' : [],
|
---|
34 | 'core/dom/document' : [ 'core/dom', 'core/dom/domobject', 'core/dom/window' ],
|
---|
35 | 'core/dom/documentfragment' : [ 'core/dom/element' ],
|
---|
36 | 'core/dom/element' : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/dom/nodelist', 'core/tools' ],
|
---|
37 | 'core/dom/elementpath' : [ 'core/dom/element' ],
|
---|
38 | 'core/dom/event' : [],
|
---|
39 | 'core/dom/node' : [ 'core/dom/domobject', 'core/tools' ],
|
---|
40 | 'core/dom/nodelist' : [ 'core/dom/node' ],
|
---|
41 | 'core/dom/domobject' : [ 'core/dom/event' ],
|
---|
42 | 'core/dom/range' : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/walker' ],
|
---|
43 | 'core/dom/text' : [ 'core/dom/node', 'core/dom/domobject' ],
|
---|
44 | 'core/dom/walker' : [ 'core/dom/node' ],
|
---|
45 | 'core/dom/window' : [ 'core/dom/domobject' ],
|
---|
46 | 'core/dtd' : [ 'core/tools' ],
|
---|
47 | 'core/editor' : [ 'core/command', 'core/config', 'core/editor_basic', 'core/focusmanager', 'core/lang', 'core/plugins', 'core/skins', 'core/themes', 'core/tools', 'core/ui' ],
|
---|
48 | 'core/editor_basic' : [ 'core/event' ],
|
---|
49 | 'core/env' : [],
|
---|
50 | 'core/event' : [],
|
---|
51 | 'core/focusmanager' : [],
|
---|
52 | 'core/htmlparser' : [],
|
---|
53 | 'core/htmlparser/comment' : [ 'core/htmlparser' ],
|
---|
54 | 'core/htmlparser/element' : [ 'core/htmlparser', 'core/htmlparser/fragment' ],
|
---|
55 | 'core/htmlparser/fragment' : [ 'core/htmlparser', 'core/htmlparser/comment', 'core/htmlparser/text', 'core/htmlparser/cdata' ],
|
---|
56 | 'core/htmlparser/text' : [ 'core/htmlparser' ],
|
---|
57 | 'core/htmlparser/cdata' : [ 'core/htmlparser' ],
|
---|
58 | 'core/htmlparser/filter' : [ 'core/htmlparser' ],
|
---|
59 | 'core/htmlparser/basicwriter': [ 'core/htmlparser' ],
|
---|
60 | 'core/imagecacher' : [ 'core/dom/element' ],
|
---|
61 | 'core/lang' : [],
|
---|
62 | 'core/plugins' : [ 'core/resourcemanager' ],
|
---|
63 | 'core/resourcemanager' : [ 'core/scriptloader', 'core/tools' ],
|
---|
64 | 'core/scriptloader' : [ 'core/dom/element', 'core/env' ],
|
---|
65 | 'core/skins' : [ 'core/imagecacher', 'core/scriptloader' ],
|
---|
66 | 'core/themes' : [ 'core/resourcemanager' ],
|
---|
67 | 'core/tools' : [ 'core/env' ],
|
---|
68 | 'core/ui' : [],
|
---|
69 | 'core/xml' : [ 'core/env' ]
|
---|
70 | };
|
---|
71 |
|
---|
72 | var basePath = (function()
|
---|
73 | {
|
---|
74 | // This is a copy of CKEDITOR.basePath, but requires the script having
|
---|
75 | // "_source/core/loader.js".
|
---|
76 | if ( CKEDITOR && CKEDITOR.basePath )
|
---|
77 | return CKEDITOR.basePath;
|
---|
78 |
|
---|
79 | // Find out the editor directory path, based on its <script> tag.
|
---|
80 | var path = '';
|
---|
81 | var scripts = document.getElementsByTagName( 'script' );
|
---|
82 |
|
---|
83 | for ( var i = 0 ; i < scripts.length ; i++ )
|
---|
84 | {
|
---|
85 | var match = scripts[i].src.match( /(^|.*[\\\/])core\/loader.js(?:\?.*)?$/i );
|
---|
86 |
|
---|
87 | if ( match )
|
---|
88 | {
|
---|
89 | path = match[1];
|
---|
90 | break;
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | // In IE (only) the script.src string is the raw valued entered in the
|
---|
95 | // HTML. Other browsers return the full resolved URL instead.
|
---|
96 | if ( path.indexOf('://') == -1 )
|
---|
97 | {
|
---|
98 | // Absolute path.
|
---|
99 | if ( path.indexOf( '/' ) === 0 )
|
---|
100 | path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path;
|
---|
101 | // Relative path.
|
---|
102 | else
|
---|
103 | path = location.href.match( /^[^\?]*\// )[0] + path;
|
---|
104 | }
|
---|
105 |
|
---|
106 | return path;
|
---|
107 | })();
|
---|
108 |
|
---|
109 | var timestamp = '99GE';
|
---|
110 |
|
---|
111 | var getUrl = function( resource )
|
---|
112 | {
|
---|
113 | if ( CKEDITOR && CKEDITOR.getUrl )
|
---|
114 | return CKEDITOR.getUrl( resource );
|
---|
115 |
|
---|
116 | return basePath + resource +
|
---|
117 | ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) +
|
---|
118 | 't=' + timestamp;
|
---|
119 | };
|
---|
120 |
|
---|
121 | var pendingLoad = [];
|
---|
122 |
|
---|
123 | /** @lends CKEDITOR.loader */
|
---|
124 | return {
|
---|
125 | /**
|
---|
126 | * The list of loaded scripts in their loading order.
|
---|
127 | * @type Array
|
---|
128 | * @example
|
---|
129 | * // Alert the loaded script names.
|
---|
130 | * alert( <b>CKEDITOR.loader.loadedScripts</b> );
|
---|
131 | */
|
---|
132 | loadedScripts : [],
|
---|
133 |
|
---|
134 | loadPending : function()
|
---|
135 | {
|
---|
136 | var scriptName = pendingLoad.shift();
|
---|
137 |
|
---|
138 | if ( !scriptName )
|
---|
139 | return;
|
---|
140 |
|
---|
141 | var scriptSrc = getUrl( '_source/' + scriptName + '.js' );
|
---|
142 |
|
---|
143 | var script = document.createElement( 'script' );
|
---|
144 | script.type = 'text/javascript';
|
---|
145 | script.src = scriptSrc;
|
---|
146 |
|
---|
147 | function onScriptLoaded()
|
---|
148 | {
|
---|
149 | // Append this script to the list of loaded scripts.
|
---|
150 | CKEDITOR.loader.loadedScripts.push( scriptName );
|
---|
151 |
|
---|
152 | // Load the next.
|
---|
153 | CKEDITOR.loader.loadPending();
|
---|
154 | }
|
---|
155 |
|
---|
156 | // We must guarantee the execution order of the scripts, so we
|
---|
157 | // need to load them one by one. (#4145)
|
---|
158 | // The followin if/else block has been taken from the scriptloader core code.
|
---|
159 | if ( CKEDITOR.env.ie )
|
---|
160 | {
|
---|
161 | /** @ignore */
|
---|
162 | script.onreadystatechange = function()
|
---|
163 | {
|
---|
164 | if ( script.readyState == 'loaded' || script.readyState == 'complete' )
|
---|
165 | {
|
---|
166 | script.onreadystatechange = null;
|
---|
167 | onScriptLoaded();
|
---|
168 | }
|
---|
169 | };
|
---|
170 | }
|
---|
171 | else
|
---|
172 | {
|
---|
173 | /** @ignore */
|
---|
174 | script.onload = function()
|
---|
175 | {
|
---|
176 | // Some browsers, such as Safari, may call the onLoad function
|
---|
177 | // immediately. Which will break the loading sequence. (#3661)
|
---|
178 | setTimeout( function() { onScriptLoaded( scriptName ); }, 0 );
|
---|
179 | };
|
---|
180 | }
|
---|
181 |
|
---|
182 | document.body.appendChild( script );
|
---|
183 | },
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * Loads a specific script, including its dependencies. This is not a
|
---|
187 | * synchronous loading, which means that the code the be loaded will
|
---|
188 | * not necessarily be available after this call.
|
---|
189 | * @example
|
---|
190 | * CKEDITOR.loader.load( 'core/dom/element' );
|
---|
191 | */
|
---|
192 | load : function( scriptName, defer )
|
---|
193 | {
|
---|
194 | // Check if the script has already been loaded.
|
---|
195 | if ( scriptName in this.loadedScripts )
|
---|
196 | return;
|
---|
197 |
|
---|
198 | // Get the script dependencies list.
|
---|
199 | var dependencies = scripts[ scriptName ];
|
---|
200 | if ( !dependencies )
|
---|
201 | throw 'The script name"' + scriptName + '" is not defined.';
|
---|
202 |
|
---|
203 | // Mark the script as loaded, even before really loading it, to
|
---|
204 | // avoid cross references recursion.
|
---|
205 | this.loadedScripts[ scriptName ] = true;
|
---|
206 |
|
---|
207 | // Load all dependencies first.
|
---|
208 | for ( var i = 0 ; i < dependencies.length ; i++ )
|
---|
209 | this.load( dependencies[ i ], true );
|
---|
210 |
|
---|
211 | var scriptSrc = getUrl( '_source/' + scriptName + '.js' );
|
---|
212 |
|
---|
213 | // Append the <script> element to the DOM.
|
---|
214 | if ( document.body )
|
---|
215 | {
|
---|
216 | pendingLoad.push( scriptName );
|
---|
217 |
|
---|
218 | if ( !defer )
|
---|
219 | this.loadPending();
|
---|
220 | }
|
---|
221 | else
|
---|
222 | {
|
---|
223 | // Append this script to the list of loaded scripts.
|
---|
224 | this.loadedScripts.push( scriptName );
|
---|
225 |
|
---|
226 | document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
|
---|
227 | }
|
---|
228 | }
|
---|
229 | };
|
---|
230 | })();
|
---|
231 | }
|
---|
232 |
|
---|
233 | // Check if any script has been defined for autoload.
|
---|
234 | if ( CKEDITOR._autoLoad )
|
---|
235 | {
|
---|
236 | CKEDITOR.loader.load( CKEDITOR._autoLoad );
|
---|
237 | delete CKEDITOR._autoLoad;
|
---|
238 | }
|
---|