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/element', '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/domwalker'	: [ 'core/dom/node', 'core/dom/element', 'core/dom/document' ],
 43 			'core/dom/range'		: [ 'core/dom/document', 'core/dom/documentFragment', 'core/dom/element', 'core/dom/domwalker' ],
 44 			'core/dom/text'			: [ 'core/dom/node', 'core/dom/domobject' ],
 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' ],
 56 			'core/htmlparser/text'		: [ 'core/htmlparser' ],
 57 			'core/htmlparser/filter'	: [ 'core/htmlparser' ],
 58 			'core/htmlparser/basicwriter': [ 'core/htmlparser' ],
 59 			'core/imagecacher'		: [ 'core/dom/element' ],
 60 			'core/lang'				: [],
 61 			'core/plugins'			: [ 'core/resourcemanager' ],
 62 			'core/resourcemanager'	: [ 'core/scriptloader', 'core/tools' ],
 63 			'core/scriptloader'		: [ 'core/dom/element', 'core/env' ],
 64 			'core/skins'			: [ 'core/imagecacher', 'core/scriptloader' ],
 65 			'core/themes'			: [ 'core/resourcemanager' ],
 66 			'core/tools'			: [ 'core/env' ],
 67 			'core/ui'				: [],
 68 			'core/xml'				: [ 'core/env' ]
 69 		};
 70
 71 		var basePath = (function()
 72 		{
 73 			// This is a copy of CKEDITOR.basePath, but requires the script having
 74 			// "_source/core/loader.js".
 75 			if ( CKEDITOR && CKEDITOR.basePath )
 76 				return CKEDITOR.basePath;
 77
 78 			// Find out the editor directory path, based on its <script> tag.
 79 			var path = '';
 80 			var scripts = document.getElementsByTagName( 'script' );
 81
 82 			for ( var i = 0 ; i < scripts.length ; i++ )
 83 			{
 84 				var match = scripts[i].src.match( /(^|.*[\\\/])core\/loader.js(?:\?.*)?$/i );
 85
 86 				if ( match )
 87 				{
 88 					path = match[1];
 89 					break;
 90 				}
 91 			}
 92
 93 			// In IE (only) the script.src string is the raw valued entered in the
 94 			// HTML. Other browsers return the full resolved URL instead.
 95 			if ( path.indexOf('://') == -1 )
 96 			{
 97 				// Absolute path.
 98 				if ( path.indexOf( '/' ) === 0 )
 99 					path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path;
100 				// Relative path.
101 				else
102 					path = location.href.match( /^[^\?]*\// )[0] + path;
103 			}
104
105 			return path;
106 		})();
107
112 		var timestamp = '92L1';
114
115 		var getUrl = function( resource )
116 		{
117 			if ( CKEDITOR && CKEDITOR.getUrl )
118 				return CKEDITOR.getUrl( resource );
119
120 			return basePath + resource +
121 				( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) +
122 				't=' + timestamp;
123 		};
124
125 		/** @lends CKEDITOR.loader */
126 		return {
127 			/**
128 			 * The list of loaded scripts in their loading order.
129 			 * @type Array
130 			 * @example
131 			 * // Alert the loaded script names.
132 			 * alert( <b>CKEDITOR.loader.loadedScripts</b> );
133 			 */
134 			loadedScripts : [],
135
136 			/**
137 			 * Loads a specific script, including its dependencies. This is not a
138 			 * synchronous loading, which means that the code the be loaded will
139 			 * not necessarily be available after this call.
140 			 * @example
141 			 * CKEDITOR.loader.load( 'core/dom/element' );
142 			 */
143 			load : function( scriptName )
144 			{
145 				// Check if the script has already been loaded.
146 				if ( scriptName in this.loadedScripts )
147 					return;
148
149 				// Get the script dependencies list.
150 				var dependencies = scripts[ scriptName ];
151 				if ( !dependencies )
152 					throw 'The script name"' + scriptName + '" is not defined.';
153
154 				// Mark the script as loaded, even before really loading it, to
155 				// avoid cross references recursion.
156 				this.loadedScripts[ scriptName ] = true;
157
158 				// Load all dependencies first.
159 				for ( var i = 0 ; i < dependencies.length ; i++ )
160 					this.load( dependencies[ i ] );
161
162 				// Append this script to the list of loaded scripts.
163 				this.loadedScripts.push( scriptName );
164
165 				var scriptSrc = getUrl( '_source/' + scriptName + '.js' );
166
167 				// Append the <script> element to the DOM.
168 				if ( document.body )
169 				{
170 					var script = document.createElement( 'script' );
171 					script.type = 'text/javascript';
172 					script.src = scriptSrc;
173
174 					document.body.appendChild( script );
175 				}
176 				else
177 					document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
178 			}
179 		};
180 	})();
181 }
182
183 // Check if any script has been defined for autoload.
184 if ( CKEDITOR._autoLoad )
185 {
186 	CKEDITOR.loader.load( CKEDITOR._autoLoad );
187 	delete CKEDITOR._autoLoad;
188 }
189