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