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.skins} object, which is used to 8 * manage skins loading. 9 */ 10 11 /** 12 * Manages skins loading. 13 * @namespace 14 * @example 15 */ 16 CKEDITOR.skins = (function() 17 { 18 // Holds the list of loaded skins. 19 var loaded = {}; 20 var preloaded = {}; 21 var paths = {}; 22 23 var loadedPart = function( skinName, part, callback ) 24 { 25 // Get the skin definition. 26 var skinDefinition = loaded[ skinName ]; 27 28 var appendSkinPath = function( fileNames ) 29 { 30 for ( var n = 0 ; n < fileNames.length ; n++ ) 31 { 32 fileNames[ n ] = CKEDITOR.getUrl( paths[ skinName ] + fileNames[ n ] ); 33 } 34 }; 35 36 // Check if we need to preload images from it. 37 if ( !preloaded[ skinName ] ) 38 { 39 var preload = skinDefinition.preload; 40 if ( preload && preload.length > 0 ) 41 { 42 appendSkinPath( preload ); 43 CKEDITOR.imageCacher.load( preload, function() 44 { 45 preloaded[ skinName ] = 1; 46 loadedPart( skinName, part, callback ); 47 } ); 48 return; 49 } 50 51 // Mark it as preloaded. 52 preloaded[ skinName ] = 1; 53 } 54 55 // Get the part definition. 56 part = skinDefinition[ part ]; 57 var partIsLoaded = !part || !!part._isLoaded; 58 59 // Call the callback immediately if already loaded. 60 if ( partIsLoaded ) 61 callback && callback(); 62 else 63 { 64 // Put the callback in a queue. 65 var pending = part._pending || ( part._pending = [] ); 66 pending.push( callback ); 67 68 // We may have more than one skin part load request. Just the first 69 // one must do the loading job. 70 if ( pending.length > 1 ) 71 return; 72 73 // Check whether the "css" and "js" properties have been defined 74 // for that part. 75 var cssIsLoaded = !part.css || !part.css.length; 76 var jsIsLoaded = !part.js || !part.js.length; 77 78 // This is the function that will trigger the callback calls on 79 // load. 80 var checkIsLoaded = function() 81 { 82 if ( cssIsLoaded && jsIsLoaded ) 83 { 84 // Mark the part as loaded. 85 part._isLoaded = 1; 86 87 // Call all pending callbacks. 88 for ( var i = 0 ; i < pending.length ; i++ ) 89 { 90 if ( pending[ i ] ) 91 pending[ i ](); 92 } 93 } 94 }; 95 96 // Load the "css" pieces. 97 if ( !cssIsLoaded ) 98 { 99 appendSkinPath( part.css ); 100 101 for ( var c = 0 ; c < part.css.length ; c++ ) 102 CKEDITOR.document.appendStyleSheet( part.css[ c ] ); 103 104 cssIsLoaded = 1; 105 } 106 107 // Load the "js" pieces. 108 if ( !jsIsLoaded ) 109 { 110 appendSkinPath( part.js ); 111 CKEDITOR.scriptLoader.load( part.js, function() 112 { 113 jsIsLoaded = 1; 114 checkIsLoaded(); 115 }); 116 } 117 118 // We may have nothing to load, so check it immediately. 119 checkIsLoaded(); 120 } 121 }; 122 123 return /** @lends CKEDITOR.skins */ { 124 125 /** 126 * Registers a skin definition. 127 * @param {String} skinName The skin name. 128 * @param {Object} skinDefinition The skin definition. 129 * @example 130 */ 131 add : function( skinName, skinDefinition ) 132 { 133 loaded[ skinName ] = skinDefinition; 134 135 skinDefinition.skinPath = paths[ skinName ] 136 || ( paths[ skinName ] = 137 CKEDITOR.getUrl( 139 'skins/' + skinName + '/' ) ); 140 }, 141 142 /** 143 * Loads a skin part. Skins are defined in parts, which are basically 144 * separated CSS files. This function is mainly used by the core code and 145 * should not have much use out of it. 146 * @param {String} skinName The name of the skin to be loaded. 147 * @param {String} skinPart The skin part to be loaded. Common skin parts 148 * are "editor" and "dialog". 149 * @param {Function} [callback] A function to be called once the skin 150 * part files are loaded. 151 * @example 152 */ 153 load : function( editor, skinPart, callback ) 154 { 155 var skinName = editor.skinName, 156 skinPath = editor.skinPath; 157 158 if ( loaded[ skinName ] ) 159 { 160 loadedPart( skinName, skinPart, callback ); 161 162 // Get the skin definition. 163 var skinDefinition = loaded[ skinName ]; 164 165 // Trigger init function if any. 166 if ( skinDefinition.init ) 167 skinDefinition.init( editor ); 168 } 169 else 170 { 171 paths[ skinName ] = skinPath; 172 CKEDITOR.scriptLoader.load( skinPath + 'skin.js', function() 173 { 174 loadedPart( skinName, skinPart, callback ); 175 176 // Get the skin definition. 177 var skinDefinition = loaded[ skinName ]; 178 179 // Trigger init function if any. 180 if ( skinDefinition.init ) 181 skinDefinition.init( editor ); 182 }); 183 } 184 } 185 }; 186 })(); 187