diff options
Diffstat (limited to 'sources/plugins/colorbutton/plugin.js')
-rw-r--r-- | sources/plugins/colorbutton/plugin.js | 134 |
1 files changed, 95 insertions, 39 deletions
diff --git a/sources/plugins/colorbutton/plugin.js b/sources/plugins/colorbutton/plugin.js index 5382333..a293ba6 100644 --- a/sources/plugins/colorbutton/plugin.js +++ b/sources/plugins/colorbutton/plugin.js | |||
@@ -11,7 +11,7 @@ | |||
11 | CKEDITOR.plugins.add( 'colorbutton', { | 11 | CKEDITOR.plugins.add( 'colorbutton', { |
12 | requires: 'panelbutton,floatpanel', | 12 | requires: 'panelbutton,floatpanel', |
13 | // jscs:disable maximumLineLength | 13 | // jscs:disable maximumLineLength |
14 | lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,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,oc,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% | 14 | lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,es-mx,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,oc,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% |
15 | // jscs:enable maximumLineLength | 15 | // jscs:enable maximumLineLength |
16 | icons: 'bgcolor,textcolor', // %REMOVE_LINE_CORE% | 16 | icons: 'bgcolor,textcolor', // %REMOVE_LINE_CORE% |
17 | hidpi: true, // %REMOVE_LINE_CORE% | 17 | hidpi: true, // %REMOVE_LINE_CORE% |
@@ -85,7 +85,8 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
85 | 85 | ||
86 | function addButton( name, type, title, order, options ) { | 86 | function addButton( name, type, title, order, options ) { |
87 | var style = new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ] ), | 87 | var style = new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ] ), |
88 | colorBoxId = CKEDITOR.tools.getNextId() + '_colorBox'; | 88 | colorBoxId = CKEDITOR.tools.getNextId() + '_colorBox', |
89 | panelBlock; | ||
89 | 90 | ||
90 | options = options || {}; | 91 | options = options || {}; |
91 | 92 | ||
@@ -105,10 +106,12 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
105 | }, | 106 | }, |
106 | 107 | ||
107 | onBlock: function( panel, block ) { | 108 | onBlock: function( panel, block ) { |
109 | panelBlock = block; | ||
110 | |||
108 | block.autoSize = true; | 111 | block.autoSize = true; |
109 | block.element.addClass( 'cke_colorblock' ); | 112 | block.element.addClass( 'cke_colorblock' ); |
110 | block.element.setHtml( renderColors( panel, type, colorBoxId ) ); | 113 | block.element.setHtml( renderColors( panel, type, colorBoxId ) ); |
111 | // The block should not have scrollbars (#5933, #6056) | 114 | // The block should not have scrollbars (http://dev.ckeditor.com/ticket/5933, http://dev.ckeditor.com/ticket/6056) |
112 | block.element.getDocument().getBody().setStyle( 'overflow', 'hidden' ); | 115 | block.element.getDocument().getBody().setStyle( 'overflow', 'hidden' ); |
113 | 116 | ||
114 | CKEDITOR.ui.fire( 'ready', this ); | 117 | CKEDITOR.ui.fire( 'ready', this ); |
@@ -129,13 +132,13 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
129 | this.setState( CKEDITOR.TRISTATE_DISABLED ); | 132 | this.setState( CKEDITOR.TRISTATE_DISABLED ); |
130 | }, | 133 | }, |
131 | 134 | ||
132 | // The automatic colorbox should represent the real color (#6010) | 135 | // The automatic colorbox should represent the real color (http://dev.ckeditor.com/ticket/6010) |
133 | onOpen: function() { | 136 | onOpen: function() { |
134 | 137 | ||
135 | var selection = editor.getSelection(), | 138 | var selection = editor.getSelection(), |
136 | block = selection && selection.getStartElement(), | 139 | block = selection && selection.getStartElement(), |
137 | path = editor.elementPath( block ), | 140 | path = editor.elementPath( block ), |
138 | color; | 141 | automaticColor; |
139 | 142 | ||
140 | if ( !path ) | 143 | if ( !path ) |
141 | return; | 144 | return; |
@@ -145,19 +148,46 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
145 | 148 | ||
146 | // The background color might be transparent. In that case, look up the color in the DOM tree. | 149 | // The background color might be transparent. In that case, look up the color in the DOM tree. |
147 | do { | 150 | do { |
148 | color = block && block.getComputedStyle( type == 'back' ? 'background-color' : 'color' ) || 'transparent'; | 151 | automaticColor = block && block.getComputedStyle( type == 'back' ? 'background-color' : 'color' ) || 'transparent'; |
149 | } | 152 | } |
150 | while ( type == 'back' && color == 'transparent' && block && ( block = block.getParent() ) ); | 153 | while ( type == 'back' && automaticColor == 'transparent' && block && ( block = block.getParent() ) ); |
151 | 154 | ||
152 | // The box should never be transparent. | 155 | // The box should never be transparent. |
153 | if ( !color || color == 'transparent' ) | 156 | if ( !automaticColor || automaticColor == 'transparent' ) |
154 | color = '#ffffff'; | 157 | automaticColor = '#ffffff'; |
155 | 158 | ||
156 | if ( config.colorButton_enableAutomatic !== false ) { | 159 | if ( config.colorButton_enableAutomatic !== false ) { |
157 | this._.panel._.iframe.getFrameDocument().getById( colorBoxId ).setStyle( 'background-color', color ); | 160 | this._.panel._.iframe.getFrameDocument().getById( colorBoxId ).setStyle( 'background-color', automaticColor ); |
158 | } | 161 | } |
159 | 162 | ||
160 | return color; | 163 | var range = selection && selection.getRanges()[ 0 ]; |
164 | |||
165 | if ( range ) { | ||
166 | var walker = new CKEDITOR.dom.walker( range ), | ||
167 | element = range.collapsed ? range.startContainer : walker.next(), | ||
168 | finalColor = '', | ||
169 | currentColor; | ||
170 | |||
171 | while ( element ) { | ||
172 | if ( element.type === CKEDITOR.NODE_TEXT ) { | ||
173 | element = element.getParent(); | ||
174 | } | ||
175 | |||
176 | currentColor = normalizeColor( element.getComputedStyle( type == 'back' ? 'background-color' : 'color' ) ); | ||
177 | finalColor = finalColor || currentColor; | ||
178 | |||
179 | if ( finalColor !== currentColor ) { | ||
180 | finalColor = ''; | ||
181 | break; | ||
182 | } | ||
183 | |||
184 | element = walker.next(); | ||
185 | } | ||
186 | |||
187 | selectColor( panelBlock, finalColor ); | ||
188 | } | ||
189 | |||
190 | return automaticColor; | ||
161 | } | 191 | } |
162 | } ); | 192 | } ); |
163 | } | 193 | } |
@@ -169,53 +199,44 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
169 | // Tells if we should include "More Colors..." button. | 199 | // Tells if we should include "More Colors..." button. |
170 | moreColorsEnabled = editor.plugins.colordialog && config.colorButton_enableMore !== false, | 200 | moreColorsEnabled = editor.plugins.colordialog && config.colorButton_enableMore !== false, |
171 | // aria-setsize and aria-posinset attributes are used to indicate size of options, because | 201 | // aria-setsize and aria-posinset attributes are used to indicate size of options, because |
172 | // screen readers doesn't play nice with table, based layouts (#12097). | 202 | // screen readers doesn't play nice with table, based layouts (http://dev.ckeditor.com/ticket/12097). |
173 | total = colors.length + ( moreColorsEnabled ? 2 : 1 ); | 203 | total = colors.length + ( moreColorsEnabled ? 2 : 1 ); |
174 | 204 | ||
175 | var clickFn = CKEDITOR.tools.addFunction( function( color, type ) { | 205 | var clickFn = CKEDITOR.tools.addFunction( function applyColorStyle( color, type ) { |
176 | var applyColorStyle = arguments.callee; | ||
177 | function onColorDialogClose( evt ) { | ||
178 | this.removeListener( 'ok', onColorDialogClose ); | ||
179 | this.removeListener( 'cancel', onColorDialogClose ); | ||
180 | 206 | ||
181 | evt.name == 'ok' && applyColorStyle( this.getContentElement( 'picker', 'selectedColor' ).getValue(), type ); | 207 | editor.focus(); |
182 | } | 208 | editor.fire( 'saveSnapshot' ); |
183 | 209 | ||
184 | if ( color == '?' ) { | 210 | if ( color == '?' ) { |
185 | editor.openDialog( 'colordialog', function() { | 211 | editor.getColorFromDialog( function( color ) { |
186 | this.on( 'ok', onColorDialogClose ); | 212 | if ( color ) { |
187 | this.on( 'cancel', onColorDialogClose ); | 213 | return applyColor( color ); |
214 | } | ||
188 | } ); | 215 | } ); |
189 | 216 | } else { | |
190 | return; | 217 | return applyColor( color ); |
191 | } | 218 | } |
192 | 219 | ||
193 | editor.focus(); | 220 | function applyColor( color ) { |
194 | 221 | // Clean up any conflicting style within the range. | |
195 | panel.hide(); | 222 | editor.removeStyle( new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ], { color: 'inherit' } ) ); |
196 | |||
197 | editor.fire( 'saveSnapshot' ); | ||
198 | |||
199 | // Clean up any conflicting style within the range. | ||
200 | editor.removeStyle( new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ], { color: 'inherit' } ) ); | ||
201 | |||
202 | if ( color ) { | ||
203 | var colorStyle = config[ 'colorButton_' + type + 'Style' ]; | 223 | var colorStyle = config[ 'colorButton_' + type + 'Style' ]; |
204 | 224 | ||
205 | colorStyle.childRule = type == 'back' ? | 225 | colorStyle.childRule = type == 'back' ? |
206 | function( element ) { | 226 | function( element ) { |
207 | // It's better to apply background color as the innermost style. (#3599) | 227 | // It's better to apply background color as the innermost style. (http://dev.ckeditor.com/ticket/3599) |
208 | // Except for "unstylable elements". (#6103) | 228 | // Except for "unstylable elements". (http://dev.ckeditor.com/ticket/6103) |
209 | return isUnstylable( element ); | 229 | return isUnstylable( element ); |
210 | } : function( element ) { | 230 | } : function( element ) { |
211 | // Fore color style must be applied inside links instead of around it. (#4772,#6908) | 231 | // Fore color style must be applied inside links instead of around it. (http://dev.ckeditor.com/ticket/4772,http://dev.ckeditor.com/ticket/6908) |
212 | return !( element.is( 'a' ) || element.getElementsByTag( 'a' ).count() ) || isUnstylable( element ); | 232 | return !( element.is( 'a' ) || element.getElementsByTag( 'a' ).count() ) || isUnstylable( element ); |
213 | }; | 233 | }; |
214 | 234 | ||
235 | editor.focus(); | ||
215 | editor.applyStyle( new CKEDITOR.style( colorStyle, { color: color } ) ); | 236 | editor.applyStyle( new CKEDITOR.style( colorStyle, { color: color } ) ); |
237 | editor.fire( 'saveSnapshot' ); | ||
216 | } | 238 | } |
217 | 239 | ||
218 | editor.fire( 'saveSnapshot' ); | ||
219 | } ); | 240 | } ); |
220 | 241 | ||
221 | if ( config.colorButton_enableAutomatic !== false ) { | 242 | if ( config.colorButton_enableAutomatic !== false ) { |
@@ -245,7 +266,7 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
245 | 266 | ||
246 | // The data can be only a color code (without #) or colorName + color code | 267 | // The data can be only a color code (without #) or colorName + color code |
247 | // If only a color code is provided, then the colorName is the color with the hash | 268 | // If only a color code is provided, then the colorName is the color with the hash |
248 | // Convert the color from RGB to RRGGBB for better compatibility with IE and <font>. See #5676 | 269 | // Convert the color from RGB to RRGGBB for better compatibility with IE and <font>. See http://dev.ckeditor.com/ticket/5676 |
249 | if ( !parts[ 1 ] ) | 270 | if ( !parts[ 1 ] ) |
250 | colorName = '#' + colorName.replace( /^(.)(.)(.)$/, '$1$1$2$2$3$3' ); | 271 | colorName = '#' + colorName.replace( /^(.)(.)(.)$/, '$1$1$2$2$3$3' ); |
251 | 272 | ||
@@ -255,6 +276,7 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
255 | ' title="', colorLabel, '"' + | 276 | ' title="', colorLabel, '"' + |
256 | ' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'', colorName, '\',\'', type, '\'); return false;"' + | 277 | ' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'', colorName, '\',\'', type, '\'); return false;"' + |
257 | ' href="javascript:void(\'', colorLabel, '\')"' + | 278 | ' href="javascript:void(\'', colorLabel, '\')"' + |
279 | ' data-value="' + colorCode + '"' + | ||
258 | ' role="option" aria-posinset="', ( i + 2 ), '" aria-setsize="', total, '">' + | 280 | ' role="option" aria-posinset="', ( i + 2 ), '" aria-setsize="', total, '">' + |
259 | '<span class="cke_colorbox" style="background-color:#', colorCode, '"></span>' + | 281 | '<span class="cke_colorbox" style="background-color:#', colorCode, '"></span>' + |
260 | '</a>' + | 282 | '</a>' + |
@@ -281,6 +303,40 @@ CKEDITOR.plugins.add( 'colorbutton', { | |||
281 | function isUnstylable( ele ) { | 303 | function isUnstylable( ele ) { |
282 | return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-nostyle' ); | 304 | return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-nostyle' ); |
283 | } | 305 | } |
306 | |||
307 | /* | ||
308 | * Selects the specified color in the specified panel block. | ||
309 | * | ||
310 | * @private | ||
311 | * @member CKEDITOR.plugins.colorbutton | ||
312 | * @param {CKEDITOR.ui.panel.block} block | ||
313 | * @param {String} color | ||
314 | */ | ||
315 | function selectColor( block, color ) { | ||
316 | var items = block._.getItems(); | ||
317 | |||
318 | for ( var i = 0; i < items.count(); i++ ) { | ||
319 | var item = items.getItem( i ); | ||
320 | |||
321 | item.removeAttribute( 'aria-selected' ); | ||
322 | |||
323 | if ( color && color == normalizeColor( item.getAttribute( 'data-value' ) ) ) { | ||
324 | item.setAttribute( 'aria-selected', true ); | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Converts a CSS color value to an easily comparable form. | ||
331 | * | ||
332 | * @private | ||
333 | * @member CKEDITOR.plugins.colorbutton | ||
334 | * @param {String} color | ||
335 | * @returns {String} | ||
336 | */ | ||
337 | function normalizeColor( color ) { | ||
338 | return CKEDITOR.tools.convertRgbToHex( color || '' ).replace( /#/, '' ).toLowerCase(); | ||
339 | } | ||
284 | } | 340 | } |
285 | } ); | 341 | } ); |
286 | 342 | ||