--- /dev/null
+/*\r
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * @fileOverview Defines the {@link CKEDITOR.skins} object, which is used to\r
+ * manage skins loading.\r
+ */\r
+\r
+/**\r
+ * Manages skins loading.\r
+ * @namespace\r
+ * @example\r
+ */\r
+CKEDITOR.skins = (function()\r
+{\r
+ // Holds the list of loaded skins.\r
+ var loaded = {},\r
+ paths = {};\r
+\r
+ var loadPart = function( editor, skinName, part, callback )\r
+ {\r
+ // Get the skin definition.\r
+ var skinDefinition = loaded[ skinName ];\r
+\r
+ if ( !editor.skin )\r
+ {\r
+ editor.skin = skinDefinition;\r
+\r
+ // Trigger init function if any.\r
+ if ( skinDefinition.init )\r
+ skinDefinition.init( editor );\r
+ }\r
+\r
+ var appendSkinPath = function( fileNames )\r
+ {\r
+ for ( var n = 0 ; n < fileNames.length ; n++ )\r
+ {\r
+ fileNames[ n ] = CKEDITOR.getUrl( paths[ skinName ] + fileNames[ n ] );\r
+ }\r
+ };\r
+\r
+ function fixCSSTextRelativePath( cssStyleText, baseUrl )\r
+ {\r
+ return cssStyleText.replace( /url\s*\(([\s'"]*)(.*?)([\s"']*)\)/g,\r
+ function( match, opener, path, closer )\r
+ {\r
+ if ( /^\/|^\w?:/.test( path ) )\r
+ return match;\r
+ else\r
+ return 'url(' + baseUrl + opener + path + closer + ')';\r
+ } );\r
+ }\r
+\r
+ // Get the part definition.\r
+ part = skinDefinition[ part ];\r
+ var partIsLoaded = !part || !!part._isLoaded;\r
+\r
+ // Call the callback immediately if already loaded.\r
+ if ( partIsLoaded )\r
+ callback && callback();\r
+ else\r
+ {\r
+ // Put the callback in a queue.\r
+ var pending = part._pending || ( part._pending = [] );\r
+ pending.push( callback );\r
+\r
+ // We may have more than one skin part load request. Just the first\r
+ // one must do the loading job.\r
+ if ( pending.length > 1 )\r
+ return;\r
+\r
+ // Check whether the "css" and "js" properties have been defined\r
+ // for that part.\r
+ var cssIsLoaded = !part.css || !part.css.length,\r
+ jsIsLoaded = !part.js || !part.js.length;\r
+\r
+ // This is the function that will trigger the callback calls on\r
+ // load.\r
+ var checkIsLoaded = function()\r
+ {\r
+ if ( cssIsLoaded && jsIsLoaded )\r
+ {\r
+ // Mark the part as loaded.\r
+ part._isLoaded = 1;\r
+\r
+ // Call all pending callbacks.\r
+ for ( var i = 0 ; i < pending.length ; i++ )\r
+ {\r
+ if ( pending[ i ] )\r
+ pending[ i ]();\r
+ }\r
+ }\r
+ };\r
+\r
+ // Load the "css" pieces.\r
+ if ( !cssIsLoaded )\r
+ {\r
+ var cssPart = part.css;\r
+\r
+ if ( CKEDITOR.tools.isArray( cssPart ) )\r
+ {\r
+ appendSkinPath( cssPart );\r
+ for ( var c = 0 ; c < cssPart.length ; c++ )\r
+ CKEDITOR.document.appendStyleSheet( cssPart[ c ] );\r
+ }\r
+ else\r
+ {\r
+ cssPart = fixCSSTextRelativePath(\r
+ cssPart, CKEDITOR.getUrl( paths[ skinName ] ) );\r
+ // Processing Inline CSS part.\r
+ CKEDITOR.document.appendStyleText( cssPart );\r
+ }\r
+\r
+ part.css = cssPart;\r
+\r
+ cssIsLoaded = 1;\r
+ }\r
+\r
+ // Load the "js" pieces.\r
+ if ( !jsIsLoaded )\r
+ {\r
+ appendSkinPath( part.js );\r
+ CKEDITOR.scriptLoader.load( part.js, function()\r
+ {\r
+ jsIsLoaded = 1;\r
+ checkIsLoaded();\r
+ });\r
+ }\r
+\r
+ // We may have nothing to load, so check it immediately.\r
+ checkIsLoaded();\r
+ }\r
+ };\r
+\r
+ return /** @lends CKEDITOR.skins */ {\r
+\r
+ /**\r
+ * Registers a skin definition.\r
+ * @param {String} skinName The skin name.\r
+ * @param {Object} skinDefinition The skin definition.\r
+ * @example\r
+ */\r
+ add : function( skinName, skinDefinition )\r
+ {\r
+ loaded[ skinName ] = skinDefinition;\r
+\r
+ skinDefinition.skinPath = paths[ skinName ]\r
+ || ( paths[ skinName ] =\r
+ CKEDITOR.getUrl(\r
+ '_source/' + // @Packager.RemoveLine\r
+ 'skins/' + skinName + '/' ) );\r
+ },\r
+\r
+ /**\r
+ * Loads a skin part. Skins are defined in parts, which are basically\r
+ * separated CSS files. This function is mainly used by the core code and\r
+ * should not have much use out of it.\r
+ * @param {String} skinName The name of the skin to be loaded.\r
+ * @param {String} skinPart The skin part to be loaded. Common skin parts\r
+ * are "editor" and "dialog".\r
+ * @param {Function} [callback] A function to be called once the skin\r
+ * part files are loaded.\r
+ * @example\r
+ */\r
+ load : function( editor, skinPart, callback )\r
+ {\r
+ var skinName = editor.skinName,\r
+ skinPath = editor.skinPath;\r
+\r
+ if ( loaded[ skinName ] )\r
+ loadPart( editor, skinName, skinPart, callback );\r
+ else\r
+ {\r
+ paths[ skinName ] = skinPath;\r
+ CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( skinPath + 'skin.js' ), function()\r
+ {\r
+ loadPart( editor, skinName, skinPart, callback );\r
+ });\r
+ }\r
+ }\r
+ };\r
+})();\r