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