1 /* 2 * CKEditor - The text editor for Internet - http://ckeditor.com 3 * Copyright (C) 2003-2008 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 */ 21 22 /** 23 * @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to 24 * load core scripts and their dependencies from _source. 25 */ 26 27 if ( typeof CKEDITOR == 'undefined' ) 28 CKEDITOR = {}; 29 30 /** 31 * Load core scripts and their dependencies from _source. 32 * @namespace 33 * @example 34 */ 35 CKEDITOR.loader = (function() 36 { 37 // Table of script names and their dependencies. 38 var scripts = 39 { 40 'lang/en' : [], // TODO: Remove me 41 42 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptLoader', 'core/tools', /* The following are entries that we wnat to force loading to at the end to avoid dependence recursion */ 'core/dom/text' ], 43 'core/ajax' : [ 'core/xml' ], 44 'core/ckeditor' : [ 'core/ajax', 'core/ckeditor_basic', 'core/dom', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/tools' ], 45 'core/ckeditor_base' : [], 46 'core/ckeditor_basic' : [ 'core/env', 'core/event' ], 47 'core/config' : [ 'core/ckeditor_base' ], 48 'core/dom' : [], 49 'core/dom/document' : [ 'core/dom','core/dom/element', 'core/dom/domobject', 'core/dom/window' ], 50 'core/dom/element' : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/tools' ], 51 'core/dom/event' : [], 52 'core/dom/node' : [ 'core/dom/domobject' ], 53 'core/dom/domobject' : [ 'core/dom/event' ], 54 'core/dom/text' : [ 'core/dom/node', 'core/dom/domobject' ], 55 'core/dom/window' : [ 'core/dom/domobject' ], 56 'core/editor' : [ 'core/config', 'core/event', 'core/plugins', 'core/skins', 'core/themes', 'core/tools' ], 57 'core/env' : [], 58 'core/event' : [], 59 'core/plugins' : [ 'core/resourceManager' ], 60 'core/resourceManager' : [ 'core/scriptLoader', 'core/tools' ], 61 'core/scriptLoader' : [ 'core/dom/element', 'core/env' ], 62 'core/skins' : [], 63 'core/themes' : [ 'lang/en', 'core/resourceManager' ], 64 'core/tools' : [ 'core/env' ], 65 'core/xml' : [ 'core/env' ] 66 }; 67 68 var basePath = (function() 69 { 70 // This is a copy of CKEDITOR.basePath, but requires the script having 71 // "_source/core/loader.js". 72 if ( CKEDITOR && CKEDITOR.basePath ) 73 return CKEDITOR.basePath; 74 75 // Find out the editor directory path, based on its <script> tag. 76 var path = ''; 77 var scripts = document.getElementsByTagName( 'script' ); 78 79 for ( var i = 0 ; i < scripts.length ; i++ ) 80 { 81 var match = scripts[i].src.match( /(^|.*[\\\/])core\/loader.js(?:\?.*)?$/i ); 82 83 if ( match ) 84 { 85 path = match[1]; 86 break; 87 } 88 } 89 90 // In IE (only) the script.src string is the raw valued entered in the 91 // HTML. Other browsers return the full resolved URL instead. 92 if ( path.indexOf('://') == -1 ) 93 { 94 // Absolute path. 95 if ( path.indexOf( '/' ) === 0 ) 96 path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path; 97 // Relative path. 98 else 99 path = location.href.match( /^[^\?]*\// )[0] + path; 100 } 101 102 return path; 103 })(); 104 105 var timestamp = ( CKEDITOR && CKEDITOR.timestamp ) || ( new Date() ).valueOf(); // @Packager.RemoveLine 106 /* // @Packager.RemoveLine 107 * The production implementation contains a fixed timestamp // @Packager.RemoveLine 108 * generated by the releaser // @Packager.RemoveLine 109 var timestamp = '%TIMESTAMP%'; 110 */ // @Packager.RemoveLine 111 112 var getUrl = function( resource ) 113 { 114 if ( CKEDITOR && CKEDITOR.getUrl ) 115 return CKEDITOR.getUrl( resource ); 116 117 return basePath + resource + 118 ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 119 't=' + timestamp; 120 }; 121 122 /** @lends CKEDITOR.loader */ 123 return { 124 /** 125 * The list of loaded scripts in their loading order. 126 * @type Array 127 * @example 128 * // Alert the loaded script names. 129 * alert( <b>CKEDITOR.loader.loadedScripts</b> ); 130 */ 131 loadedScripts : [], 132 133 /** 134 * Loads a specific script, including its dependencies. This is not a 135 * synchronous loading, which means that the code the be loaded will 136 * not necessarily be available after this call. 137 * @example 138 * CKEDITOR.loader.load( 'core/dom/element' ); 139 */ 140 load : function( scriptName ) 141 { 142 // Check if the script has already been loaded. 143 if ( scriptName in this.loadedScripts ) 144 return; 145 146 // Get the script dependencies list. 147 var dependencies = scripts[ scriptName ]; 148 if ( !dependencies ) 149 throw 'The script name"' + scriptName + '" is not defined.'; 150 151 // Mark the script as loaded, even before really loading it, to 152 // avoid cross references recursion. 153 this.loadedScripts[ scriptName ] = true; 154 155 // Load all dependencies first. 156 for ( var i = 0 ; i < dependencies.length ; i++ ) 157 this.load( dependencies[ i ] ); 158 159 // Append this script to the list of loaded scripts. 160 this.loadedScripts.push( scriptName ); 161 162 var scriptSrc = getUrl( '_source/' + scriptName + '.js' ); 163 164 // Append the <script> element to the DOM. 165 if ( document.body ) 166 { 167 var script = document.createElement( 'script' ); 168 script.type = 'text/javascript'; 169 script.src = scriptSrc; 170 171 document.body.appendChild( script ); 172 } 173 else 174 document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' ); 175 } 176 }; 177 })(); 178 179 // Check if any script has been defined for autoload. 180 if ( CKEDITOR._autoLoad ) 181 { 182 CKEDITOR.loader.load( CKEDITOR._autoLoad ); 183 delete CKEDITOR._autoLoad; 184 } 185