1 | /** |
---|
2 | * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. |
---|
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license |
---|
4 | */ |
---|
5 | |
---|
6 | ( function() { |
---|
7 | function addCombo( editor, comboName, styleType, lang, entries, defaultLabel, styleDefinition, order ) { |
---|
8 | var config = editor.config, |
---|
9 | style = new CKEDITOR.style( styleDefinition ); |
---|
10 | |
---|
11 | // Gets the list of fonts from the settings. |
---|
12 | var names = entries.split( ';' ), |
---|
13 | values = []; |
---|
14 | |
---|
15 | // Create style objects for all fonts. |
---|
16 | var styles = {}; |
---|
17 | for ( var i = 0; i < names.length; i++ ) { |
---|
18 | var parts = names[ i ]; |
---|
19 | |
---|
20 | if ( parts ) { |
---|
21 | parts = parts.split( '/' ); |
---|
22 | |
---|
23 | var vars = {}, |
---|
24 | name = names[ i ] = parts[ 0 ]; |
---|
25 | |
---|
26 | vars[ styleType ] = values[ i ] = parts[ 1 ] || name; |
---|
27 | |
---|
28 | styles[ name ] = new CKEDITOR.style( styleDefinition, vars ); |
---|
29 | styles[ name ]._.definition.name = name; |
---|
30 | } else { |
---|
31 | names.splice( i--, 1 ); |
---|
32 | } |
---|
33 | } |
---|
34 | |
---|
35 | editor.ui.addRichCombo( comboName, { |
---|
36 | label: lang.label, |
---|
37 | title: lang.panelTitle, |
---|
38 | toolbar: 'styles,' + order, |
---|
39 | allowedContent: style, |
---|
40 | requiredContent: style, |
---|
41 | |
---|
42 | panel: { |
---|
43 | css: [ CKEDITOR.skin.getPath( 'editor' ) ].concat( config.contentsCss ), |
---|
44 | multiSelect: false, |
---|
45 | attributes: { 'aria-label': lang.panelTitle } |
---|
46 | }, |
---|
47 | |
---|
48 | init: function() { |
---|
49 | this.startGroup( lang.panelTitle ); |
---|
50 | |
---|
51 | for ( var i = 0; i < names.length; i++ ) { |
---|
52 | var name = names[ i ]; |
---|
53 | |
---|
54 | // Add the tag entry to the panel list. |
---|
55 | this.add( name, styles[ name ].buildPreview(), name ); |
---|
56 | } |
---|
57 | }, |
---|
58 | |
---|
59 | onClick: function( value ) { |
---|
60 | editor.focus(); |
---|
61 | editor.fire( 'saveSnapshot' ); |
---|
62 | |
---|
63 | var previousValue = this.getValue(), |
---|
64 | style = styles[ value ]; |
---|
65 | |
---|
66 | // When applying one style over another, first remove the previous one (#12403). |
---|
67 | // NOTE: This is only a temporary fix. It will be moved to the styles system (#12687). |
---|
68 | if ( previousValue && value != previousValue ) { |
---|
69 | var previousStyle = styles[ previousValue ], |
---|
70 | range = editor.getSelection().getRanges()[ 0 ]; |
---|
71 | |
---|
72 | // If the range is collapsed we can't simply use the editor.removeStyle method |
---|
73 | // because it will remove the entire element and we want to split it instead. |
---|
74 | if ( range.collapsed ) { |
---|
75 | var path = editor.elementPath(), |
---|
76 | // Find the style element. |
---|
77 | matching = path.contains( function( el ) { |
---|
78 | return previousStyle.checkElementRemovable( el ); |
---|
79 | } ); |
---|
80 | |
---|
81 | if ( matching ) { |
---|
82 | var startBoundary = range.checkBoundaryOfElement( matching, CKEDITOR.START ), |
---|
83 | endBoundary = range.checkBoundaryOfElement( matching, CKEDITOR.END ), |
---|
84 | node, bm; |
---|
85 | |
---|
86 | // If we are at both boundaries it means that the element is empty. |
---|
87 | // Remove it but in a way that we won't lose other empty inline elements inside it. |
---|
88 | // Example: <p>x<span style="font-size:48px"><em>[]</em></span>x</p> |
---|
89 | // Result: <p>x<em>[]</em>x</p> |
---|
90 | if ( startBoundary && endBoundary ) { |
---|
91 | bm = range.createBookmark(); |
---|
92 | // Replace the element with its children (TODO element.replaceWithChildren). |
---|
93 | while ( ( node = matching.getFirst() ) ) { |
---|
94 | node.insertBefore( matching ); |
---|
95 | } |
---|
96 | matching.remove(); |
---|
97 | range.moveToBookmark( bm ); |
---|
98 | |
---|
99 | // If we are at the boundary of the style element, just move out. |
---|
100 | } else if ( startBoundary ) { |
---|
101 | range.moveToPosition( matching, CKEDITOR.POSITION_BEFORE_START ); |
---|
102 | } else if ( endBoundary ) { |
---|
103 | range.moveToPosition( matching, CKEDITOR.POSITION_AFTER_END ); |
---|
104 | } else { |
---|
105 | // Split the element and clone the elements that were in the path |
---|
106 | // (between the startContainer and the matching element) |
---|
107 | // into the new place. |
---|
108 | range.splitElement( matching ); |
---|
109 | range.moveToPosition( matching, CKEDITOR.POSITION_AFTER_END ); |
---|
110 | cloneSubtreeIntoRange( range, path.elements.slice(), matching ); |
---|
111 | } |
---|
112 | |
---|
113 | editor.getSelection().selectRanges( [ range ] ); |
---|
114 | } |
---|
115 | } else { |
---|
116 | editor.removeStyle( previousStyle ); |
---|
117 | } |
---|
118 | } |
---|
119 | |
---|
120 | editor[ previousValue == value ? 'removeStyle' : 'applyStyle' ]( style ); |
---|
121 | |
---|
122 | editor.fire( 'saveSnapshot' ); |
---|
123 | }, |
---|
124 | |
---|
125 | onRender: function() { |
---|
126 | editor.on( 'selectionChange', function( ev ) { |
---|
127 | var currentValue = this.getValue(); |
---|
128 | |
---|
129 | var elementPath = ev.data.path, |
---|
130 | elements = elementPath.elements; |
---|
131 | |
---|
132 | // For each element into the elements path. |
---|
133 | for ( var i = 0, element; i < elements.length; i++ ) { |
---|
134 | element = elements[ i ]; |
---|
135 | |
---|
136 | // Check if the element is removable by any of |
---|
137 | // the styles. |
---|
138 | for ( var value in styles ) { |
---|
139 | if ( styles[ value ].checkElementMatch( element, true, editor ) ) { |
---|
140 | if ( value != currentValue ) |
---|
141 | this.setValue( value ); |
---|
142 | return; |
---|
143 | } |
---|
144 | } |
---|
145 | } |
---|
146 | |
---|
147 | // If no styles match, just empty it. |
---|
148 | this.setValue( '', defaultLabel ); |
---|
149 | }, this ); |
---|
150 | }, |
---|
151 | |
---|
152 | refresh: function() { |
---|
153 | if ( !editor.activeFilter.check( style ) ) |
---|
154 | this.setState( CKEDITOR.TRISTATE_DISABLED ); |
---|
155 | } |
---|
156 | } ); |
---|
157 | } |
---|
158 | |
---|
159 | // Clones the subtree between subtreeStart (exclusive) and the |
---|
160 | // leaf (inclusive) and inserts it into the range. |
---|
161 | // |
---|
162 | // @param range |
---|
163 | // @param {CKEDITOR.dom.element[]} elements Elements path in the standard order: leaf -> root. |
---|
164 | // @param {CKEDITOR.dom.element/null} substreeStart The start of the subtree. |
---|
165 | // If null, then the leaf belongs to the subtree. |
---|
166 | function cloneSubtreeIntoRange( range, elements, subtreeStart ) { |
---|
167 | var current = elements.pop(); |
---|
168 | if ( !current ) { |
---|
169 | return; |
---|
170 | } |
---|
171 | // Rewind the elements array up to the subtreeStart and then start the real cloning. |
---|
172 | if ( subtreeStart ) { |
---|
173 | return cloneSubtreeIntoRange( range, elements, current.equals( subtreeStart ) ? null : subtreeStart ); |
---|
174 | } |
---|
175 | |
---|
176 | var clone = current.clone(); |
---|
177 | range.insertNode( clone ); |
---|
178 | range.moveToPosition( clone, CKEDITOR.POSITION_AFTER_START ); |
---|
179 | |
---|
180 | cloneSubtreeIntoRange( range, elements ); |
---|
181 | } |
---|
182 | |
---|
183 | CKEDITOR.plugins.add( 'font', { |
---|
184 | requires: 'richcombo', |
---|
185 | // jscs:disable maximumLineLength |
---|
186 | lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% |
---|
187 | // jscs:enable maximumLineLength |
---|
188 | init: function( editor ) { |
---|
189 | var config = editor.config; |
---|
190 | |
---|
191 | addCombo( editor, 'Font', 'family', editor.lang.font, config.font_names, config.font_defaultLabel, config.font_style, 30 ); |
---|
192 | addCombo( editor, 'FontSize', 'size', editor.lang.font.fontSize, config.fontSize_sizes, config.fontSize_defaultLabel, config.fontSize_style, 40 ); |
---|
193 | } |
---|
194 | } ); |
---|
195 | } )(); |
---|
196 | |
---|
197 | /** |
---|
198 | * The list of fonts names to be displayed in the Font combo in the toolbar. |
---|
199 | * Entries are separated by semi-colons (`';'`), while it's possible to have more |
---|
200 | * than one font for each entry, in the HTML way (separated by comma). |
---|
201 | * |
---|
202 | * A display name may be optionally defined by prefixing the entries with the |
---|
203 | * name and the slash character. For example, `'Arial/Arial, Helvetica, sans-serif'` |
---|
204 | * will be displayed as `'Arial'` in the list, but will be outputted as |
---|
205 | * `'Arial, Helvetica, sans-serif'`. |
---|
206 | * |
---|
207 | * config.font_names = |
---|
208 | * 'Arial/Arial, Helvetica, sans-serif;' + |
---|
209 | * 'Times New Roman/Times New Roman, Times, serif;' + |
---|
210 | * 'Verdana'; |
---|
211 | * |
---|
212 | * config.font_names = 'Arial;Times New Roman;Verdana'; |
---|
213 | * |
---|
214 | * @cfg {String} [font_names=see source] |
---|
215 | * @member CKEDITOR.config |
---|
216 | */ |
---|
217 | CKEDITOR.config.font_names = 'Arial/Arial, Helvetica, sans-serif;' + |
---|
218 | 'Comic Sans MS/Comic Sans MS, cursive;' + |
---|
219 | 'Courier New/Courier New, Courier, monospace;' + |
---|
220 | 'Georgia/Georgia, serif;' + |
---|
221 | 'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' + |
---|
222 | 'Tahoma/Tahoma, Geneva, sans-serif;' + |
---|
223 | 'Times New Roman/Times New Roman, Times, serif;' + |
---|
224 | 'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' + |
---|
225 | 'Verdana/Verdana, Geneva, sans-serif'; |
---|
226 | |
---|
227 | /** |
---|
228 | * The text to be displayed in the Font combo is none of the available values |
---|
229 | * matches the current cursor position or text selection. |
---|
230 | * |
---|
231 | * // If the default site font is Arial, we may making it more explicit to the end user. |
---|
232 | * config.font_defaultLabel = 'Arial'; |
---|
233 | * |
---|
234 | * @cfg {String} [font_defaultLabel=''] |
---|
235 | * @member CKEDITOR.config |
---|
236 | */ |
---|
237 | CKEDITOR.config.font_defaultLabel = 'Arial'; |
---|
238 | |
---|
239 | /** |
---|
240 | * The style definition to be used to apply the font in the text. |
---|
241 | * |
---|
242 | * // This is actually the default value for it. |
---|
243 | * config.font_style = { |
---|
244 | * element: 'span', |
---|
245 | * styles: { 'font-family': '#(family)' }, |
---|
246 | * overrides: [ { element: 'font', attributes: { 'face': null } } ] |
---|
247 | * }; |
---|
248 | * |
---|
249 | * @cfg {Object} [font_style=see example] |
---|
250 | * @member CKEDITOR.config |
---|
251 | */ |
---|
252 | CKEDITOR.config.font_style = { |
---|
253 | element: 'span', |
---|
254 | styles: { 'font-family': '#(family)' }, |
---|
255 | overrides: [ { |
---|
256 | element: 'font', attributes: { 'face': null } |
---|
257 | } ] |
---|
258 | }; |
---|
259 | |
---|
260 | /** |
---|
261 | * The list of fonts size to be displayed in the Font Size combo in the |
---|
262 | * toolbar. Entries are separated by semi-colons (`';'`). |
---|
263 | * |
---|
264 | * Any kind of "CSS like" size can be used, like `'12px'`, `'2.3em'`, `'130%'`, |
---|
265 | * `'larger'` or `'x-small'`. |
---|
266 | * |
---|
267 | * A display name may be optionally defined by prefixing the entries with the |
---|
268 | * name and the slash character. For example, `'Bigger Font/14px'` will be |
---|
269 | * displayed as `'Bigger Font'` in the list, but will be outputted as `'14px'`. |
---|
270 | * |
---|
271 | * config.fontSize_sizes = '16/16px;24/24px;48/48px;'; |
---|
272 | * |
---|
273 | * config.fontSize_sizes = '12px;2.3em;130%;larger;x-small'; |
---|
274 | * |
---|
275 | * config.fontSize_sizes = '12 Pixels/12px;Big/2.3em;30 Percent More/130%;Bigger/larger;Very Small/x-small'; |
---|
276 | * |
---|
277 | * @cfg {String} [fontSize_sizes=see source] |
---|
278 | * @member CKEDITOR.config |
---|
279 | */ |
---|
280 | CKEDITOR.config.fontSize_sizes = '8/8pt;9/9pt;10/10pt;11/11pt;12/12pt;14/14pt;15/15pt;16/16pt;18/18pt;20/20pt;22/22pt;24/24pt;26/26pt;28/28pt;36/36pt;48/48pt;72/72pt'; |
---|
281 | |
---|
282 | /** |
---|
283 | * The text to be displayed in the Font Size combo is none of the available |
---|
284 | * values matches the current cursor position or text selection. |
---|
285 | * |
---|
286 | * // If the default site font size is 12px, we may making it more explicit to the end user. |
---|
287 | * config.fontSize_defaultLabel = '12px'; |
---|
288 | * |
---|
289 | * @cfg {String} [fontSize_defaultLabel=''] |
---|
290 | * @member CKEDITOR.config |
---|
291 | */ |
---|
292 | CKEDITOR.config.fontSize_defaultLabel = '10'; |
---|
293 | |
---|
294 | /** |
---|
295 | * The style definition to be used to apply the font size in the text. |
---|
296 | * |
---|
297 | * // This is actually the default value for it. |
---|
298 | * config.fontSize_style = { |
---|
299 | * element: 'span', |
---|
300 | * styles: { 'font-size': '#(size)' }, |
---|
301 | * overrides: [ { element :'font', attributes: { 'size': null } } ] |
---|
302 | * }; |
---|
303 | * |
---|
304 | * @cfg {Object} [fontSize_style=see example] |
---|
305 | * @member CKEDITOR.config |
---|
306 | */ |
---|
307 | CKEDITOR.config.fontSize_style = { |
---|
308 | element: 'span', |
---|
309 | styles: { 'font-size': '#(size)' }, |
---|
310 | overrides: [ { |
---|
311 | element: 'font', attributes: { 'size': null } |
---|
312 | } ] |
---|
313 | }; |
---|