]> git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blob - sources/core/skin.js
Validation initiale
[perso/Immae/Projets/packagist/ludivine-ckeditor-component.git] / sources / core / skin.js
1 /**
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
4 */
5
6 /**
7 * @fileOverview Defines the {@link CKEDITOR.skin} class that is used to manage skin parts.
8 */
9
10 ( function() {
11 var cssLoaded = {};
12
13 function getName() {
14 return CKEDITOR.skinName.split( ',' )[ 0 ];
15 }
16
17 function getConfigPath() {
18 return CKEDITOR.getUrl( CKEDITOR.skinName.split( ',' )[ 1 ] || ( 'skins/' + getName() + '/' ) );
19 }
20
21 /**
22 * Manages the loading of skin parts among all editor instances.
23 *
24 * @class
25 * @singleton
26 */
27 CKEDITOR.skin = {
28 /**
29 * Returns the root path to the skin directory.
30 *
31 * @method
32 * @todo
33 */
34 path: getConfigPath,
35
36 /**
37 * Loads a skin part into the page. Does nothing if the part has already been loaded.
38 *
39 * **Note:** The "editor" part is always auto loaded upon instance creation,
40 * thus this function is mainly used to **lazy load** other parts of the skin
41 * that do not have to be displayed until requested.
42 *
43 * // Load the dialog part.
44 * editor.skin.loadPart( 'dialog' );
45 *
46 * @param {String} part The name of the skin part CSS file that resides in the skin directory.
47 * @param {Function} fn The provided callback function which is invoked after the part is loaded.
48 */
49 loadPart: function( part, fn ) {
50 if ( CKEDITOR.skin.name != getName() ) {
51 CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( getConfigPath() + 'skin.js' ), function() {
52 loadCss( part, fn );
53 } );
54 } else {
55 loadCss( part, fn );
56 }
57 },
58
59 /**
60 * Retrieves the real URL of a (CSS) skin part.
61 *
62 * @param {String} part
63 */
64 getPath: function( part ) {
65 return CKEDITOR.getUrl( getCssPath( part ) );
66 },
67
68 /**
69 * The list of registered icons. To add new icons to this list, use {@link #addIcon}.
70 */
71 icons: {},
72
73 /**
74 * Registers an icon.
75 *
76 * @param {String} name The icon name.
77 * @param {String} path The path to the icon image file.
78 * @param {Number} [offset] The vertical offset position of the icon, if
79 * available inside a strip image.
80 * @param {String} [bgsize] The value of the CSS "background-size" property to
81 * use for this icon
82 */
83 addIcon: function( name, path, offset, bgsize ) {
84 name = name.toLowerCase();
85 if ( !this.icons[ name ] ) {
86 this.icons[ name ] = {
87 path: path,
88 offset: offset || 0,
89 bgsize: bgsize || '16px'
90 };
91 }
92 },
93
94 /**
95 * Gets the CSS background styles to be used to render a specific icon.
96 *
97 * @param {String} name The icon name, as registered with {@link #addIcon}.
98 * @param {Boolean} [rtl] Indicates that the RTL version of the icon is
99 * to be used, if available.
100 * @param {String} [overridePath] The path to the icon image file. It
101 * overrides the path defined by the named icon, if available, and is
102 * used if the named icon was not registered.
103 * @param {Number} [overrideOffset] The vertical offset position of the
104 * icon. It overrides the offset defined by the named icon, if
105 * available, and is used if the named icon was not registered.
106 * @param {String} [overrideBgsize] The value of the CSS "background-size" property
107 * to use for the icon. It overrides the value defined by the named icon,
108 * if available, and is used if the named icon was not registered.
109 */
110 getIconStyle: function( name, rtl, overridePath, overrideOffset, overrideBgsize ) {
111 var icon, path, offset, bgsize;
112
113 if ( name ) {
114 name = name.toLowerCase();
115 // If we're in RTL, try to get the RTL version of the icon.
116 if ( rtl )
117 icon = this.icons[ name + '-rtl' ];
118
119 // If not in LTR or no RTL version available, get the generic one.
120 if ( !icon )
121 icon = this.icons[ name ];
122 }
123
124 path = overridePath || ( icon && icon.path ) || '';
125 offset = overrideOffset || ( icon && icon.offset );
126 bgsize = overrideBgsize || ( icon && icon.bgsize ) || '16px';
127
128 // If we use apostrophes in background-image, we must escape apostrophes in path (just to be sure). (#13361)
129 if ( path )
130 path = path.replace( /'/g, '\\\'' );
131
132 return path &&
133 ( 'background-image:url(\'' + CKEDITOR.getUrl( path ) + '\');background-position:0 ' + offset + 'px;background-size:' + bgsize + ';' );
134 }
135 };
136
137 function getCssPath( part ) {
138 // Check for ua-specific version of skin part.
139 var uas = CKEDITOR.skin[ 'ua_' + part ], env = CKEDITOR.env;
140 if ( uas ) {
141
142 // Having versioned UA checked first.
143 uas = uas.split( ',' ).sort( function( a, b ) {
144 return a > b ? -1 : 1;
145 } );
146
147 // Loop through all ua entries, checking is any of them match the current ua.
148 for ( var i = 0, ua; i < uas.length; i++ ) {
149 ua = uas[ i ];
150
151 if ( env.ie ) {
152 if ( ( ua.replace( /^ie/, '' ) == env.version ) || ( env.quirks && ua == 'iequirks' ) )
153 ua = 'ie';
154 }
155
156 if ( env[ ua ] ) {
157 part += '_' + uas[ i ];
158 break;
159 }
160 }
161 }
162 return CKEDITOR.getUrl( getConfigPath() + part + '.css' );
163 }
164
165 function loadCss( part, callback ) {
166 // Avoid reload.
167 if ( !cssLoaded[ part ] ) {
168 CKEDITOR.document.appendStyleSheet( getCssPath( part ) );
169 cssLoaded[ part ] = 1;
170 }
171
172 // CSS loading should not be blocking.
173 callback && callback();
174 }
175
176 CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
177 /** Gets the color of the editor user interface.
178 *
179 * CKEDITOR.instances.editor1.getUiColor();
180 *
181 * @method
182 * @member CKEDITOR.editor
183 * @returns {String} uiColor The editor UI color or `undefined` if the UI color is not set.
184 */
185 getUiColor: function() {
186 return this.uiColor;
187 },
188
189 /** Sets the color of the editor user interface. This method accepts a color value in
190 * hexadecimal notation, with a `#` character (e.g. #ffffff).
191 *
192 * CKEDITOR.instances.editor1.setUiColor( '#ff00ff' );
193 *
194 * @method
195 * @member CKEDITOR.editor
196 * @param {String} color The desired editor UI color in hexadecimal notation.
197 */
198 setUiColor: function( color ) {
199 var uiStyle = getStylesheet( CKEDITOR.document );
200
201 return ( this.setUiColor = function( color ) {
202 this.uiColor = color;
203
204 var chameleon = CKEDITOR.skin.chameleon,
205 editorStyleContent = '',
206 panelStyleContent = '';
207
208 if ( typeof chameleon == 'function' ) {
209 editorStyleContent = chameleon( this, 'editor' );
210 panelStyleContent = chameleon( this, 'panel' );
211 }
212
213 var replace = [ [ uiColorRegexp, color ] ];
214
215 // Update general style.
216 updateStylesheets( [ uiStyle ], editorStyleContent, replace );
217
218 // Update panel styles.
219 updateStylesheets( uiColorMenus, panelStyleContent, replace );
220 } ).call( this, color );
221 }
222 } );
223
224 var uiColorStylesheetId = 'cke_ui_color',
225 uiColorMenus = [],
226 uiColorRegexp = /\$color/g;
227
228 function getStylesheet( document ) {
229 var node = document.getById( uiColorStylesheetId );
230 if ( !node ) {
231 node = document.getHead().append( 'style' );
232 node.setAttribute( 'id', uiColorStylesheetId );
233 node.setAttribute( 'type', 'text/css' );
234 }
235 return node;
236 }
237
238 function updateStylesheets( styleNodes, styleContent, replace ) {
239 var r, i, content;
240
241 // We have to split CSS declarations for webkit.
242 if ( CKEDITOR.env.webkit ) {
243 styleContent = styleContent.split( '}' ).slice( 0, -1 );
244 for ( i = 0; i < styleContent.length; i++ )
245 styleContent[ i ] = styleContent[ i ].split( '{' );
246 }
247
248 for ( var id = 0; id < styleNodes.length; id++ ) {
249 if ( CKEDITOR.env.webkit ) {
250 for ( i = 0; i < styleContent.length; i++ ) {
251 content = styleContent[ i ][ 1 ];
252 for ( r = 0; r < replace.length; r++ )
253 content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
254
255 styleNodes[ id ].$.sheet.addRule( styleContent[ i ][ 0 ], content );
256 }
257 } else {
258 content = styleContent;
259 for ( r = 0; r < replace.length; r++ )
260 content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
261
262 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 )
263 styleNodes[ id ].$.styleSheet.cssText += content;
264 else
265 styleNodes[ id ].$.innerHTML += content;
266 }
267 }
268 }
269
270 CKEDITOR.on( 'instanceLoaded', function( evt ) {
271 // The chameleon feature is not for IE quirks.
272 if ( CKEDITOR.env.ie && CKEDITOR.env.quirks )
273 return;
274
275 var editor = evt.editor,
276 showCallback = function( event ) {
277 var panel = event.data[ 0 ] || event.data;
278 var iframe = panel.element.getElementsByTag( 'iframe' ).getItem( 0 ).getFrameDocument();
279
280 // Add stylesheet if missing.
281 if ( !iframe.getById( 'cke_ui_color' ) ) {
282 var node = getStylesheet( iframe );
283 uiColorMenus.push( node );
284
285 var color = editor.getUiColor();
286 // Set uiColor for new panel.
287 if ( color )
288 updateStylesheets( [ node ], CKEDITOR.skin.chameleon( editor, 'panel' ), [ [ uiColorRegexp, color ] ] );
289
290 }
291 };
292
293 editor.on( 'panelShow', showCallback );
294 editor.on( 'menuShow', showCallback );
295
296 // Apply UI color if specified in config.
297 if ( editor.config.uiColor )
298 editor.setUiColor( editor.config.uiColor );
299 } );
300 } )();
301
302 /**
303 * The list of file names matching the browser user agent string from
304 * {@link CKEDITOR.env}. This is used to load the skin part file in addition
305 * to the "main" skin file for a particular browser.
306 *
307 * **Note:** For each of the defined skin parts the corresponding
308 * CSS file with the same name as the user agent must exist inside
309 * the skin directory.
310 *
311 * @property ua
312 * @todo type?
313 */
314
315 /**
316 * The name of the skin that is currently used.
317 *
318 * @property {String} name
319 * @todo
320 */
321
322 /**
323 * The editor skin name. Note that it is not possible to have editors with
324 * different skin settings in the same page. In such case just one of the
325 * skins will be used for all editors.
326 *
327 * This is a shortcut to {@link CKEDITOR#skinName}.
328 *
329 * It is possible to install skins outside the default `skin` folder in the
330 * editor installation. In that case, the absolute URL path to that folder
331 * should be provided, separated by a comma (`'skin_name,skin_path'`).
332 *
333 * config.skin = 'moono';
334 *
335 * config.skin = 'myskin,/customstuff/myskin/';
336 *
337 * @cfg {String} skin
338 * @member CKEDITOR.config
339 */
340
341 /**
342 * A function that supports the chameleon (skin color switch) feature, providing
343 * the skin color style updates to be applied in runtime.
344 *
345 * **Note:** The embedded `$color` variable is to be substituted with a specific UI color.
346 *
347 * @method chameleon
348 * @param {String} editor The editor instance that the color changes apply to.
349 * @param {String} part The name of the skin part where the color changes take place.
350 */