]> git.immae.eu Git - perso/Immae/Projets/packagist/connexionswing-ckeditor-component.git/blame - sources/plugins/tabletools/dialogs/tableCell.js
Initial commit
[perso/Immae/Projets/packagist/connexionswing-ckeditor-component.git] / sources / plugins / tabletools / dialogs / tableCell.js
CommitLineData
7adcb81e
IB
1/**\r
2 * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.\r
3 * For licensing, see LICENSE.md or http://ckeditor.com/license\r
4 */\r
5\r
6CKEDITOR.dialog.add( 'cellProperties', function( editor ) {\r
7 var langTable = editor.lang.table,\r
8 langCell = langTable.cell,\r
9 langCommon = editor.lang.common,\r
10 validate = CKEDITOR.dialog.validate,\r
11 widthPattern = /^(\d+(?:\.\d+)?)(px|%)$/,\r
12 spacer = { type: 'html', html: ' ' },\r
13 rtl = editor.lang.dir == 'rtl',\r
14 colorDialog = editor.plugins.colordialog;\r
15\r
16 // Returns a function, which runs regular "setup" for all selected cells to find out\r
17 // whether the initial value of the field would be the same for all cells. If so,\r
18 // the value is displayed just as if a regular "setup" was executed. Otherwise,\r
19 // i.e. when there are several cells of different value of the property, a field\r
20 // gets empty value.\r
21 //\r
22 // * @param {Function} setup Setup function which returns a value instead of setting it.\r
23 // * @returns {Function} A function to be used in dialog definition.\r
24 function setupCells( setup ) {\r
25 return function( cells ) {\r
26 var fieldValue = setup( cells[ 0 ] );\r
27\r
28 // If one of the cells would have a different value of the\r
29 // property, set the empty value for a field.\r
30 for ( var i = 1; i < cells.length; i++ ) {\r
31 if ( setup( cells[ i ] ) !== fieldValue ) {\r
32 fieldValue = null;\r
33 break;\r
34 }\r
35 }\r
36\r
37 // Setting meaningful or empty value only makes sense\r
38 // when setup returns some value. Otherwise, a *default* value\r
39 // is used for that field.\r
40 if ( typeof fieldValue != 'undefined' ) {\r
41 this.setValue( fieldValue );\r
42\r
43 // The only way to have an empty select value in Firefox is\r
44 // to set a negative selectedIndex.\r
45 if ( CKEDITOR.env.gecko && this.type == 'select' && !fieldValue )\r
46 this.getInputElement().$.selectedIndex = -1;\r
47 }\r
48 };\r
49 }\r
50\r
51 // Reads the unit of width property of the table cell.\r
52 //\r
53 // * @param {CKEDITOR.dom.element} cell An element representing table cell.\r
54 // * @returns {String} A unit of width: 'px', '%' or undefined if none.\r
55 function getCellWidthType( cell ) {\r
56 var match = widthPattern.exec(\r
57 cell.getStyle( 'width' ) || cell.getAttribute( 'width' ) );\r
58\r
59 if ( match )\r
60 return match[ 2 ];\r
61 }\r
62\r
63 return {\r
64 title: langCell.title,\r
65 minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 450 : 410,\r
66 minHeight: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ? 230 : 220,\r
67 contents: [ {\r
68 id: 'info',\r
69 label: langCell.title,\r
70 accessKey: 'I',\r
71 elements: [ {\r
72 type: 'hbox',\r
73 widths: [ '40%', '5%', '40%' ],\r
74 children: [ {\r
75 type: 'vbox',\r
76 padding: 0,\r
77 children: [ {\r
78 type: 'hbox',\r
79 widths: [ '70%', '30%' ],\r
80 children: [ {\r
81 type: 'text',\r
82 id: 'width',\r
83 width: '100px',\r
84 label: langCommon.width,\r
85 validate: validate.number( langCell.invalidWidth ),\r
86\r
87 // Extra labelling of width unit type.\r
88 onLoad: function() {\r
89 var widthType = this.getDialog().getContentElement( 'info', 'widthType' ),\r
90 labelElement = widthType.getElement(),\r
91 inputElement = this.getInputElement(),\r
92 ariaLabelledByAttr = inputElement.getAttribute( 'aria-labelledby' );\r
93\r
94 inputElement.setAttribute( 'aria-labelledby', [ ariaLabelledByAttr, labelElement.$.id ].join( ' ' ) );\r
95 },\r
96\r
97 setup: setupCells( function( element ) {\r
98 var widthAttr = parseInt( element.getAttribute( 'width' ), 10 ),\r
99 widthStyle = parseInt( element.getStyle( 'width' ), 10 );\r
100\r
101 return !isNaN( widthStyle ) ? widthStyle :\r
102 !isNaN( widthAttr ) ? widthAttr : '';\r
103 } ),\r
104 commit: function( element ) {\r
105 var value = parseInt( this.getValue(), 10 ),\r
106\r
107 // There might be no widthType value, i.e. when multiple cells are\r
108 // selected but some of them have width expressed in pixels and some\r
109 // of them in percent. Try to re-read the unit from the cell in such\r
110 // case (#11439).\r
111 unit = this.getDialog().getValueOf( 'info', 'widthType' ) || getCellWidthType( element );\r
112\r
113 if ( !isNaN( value ) )\r
114 element.setStyle( 'width', value + unit );\r
115 else\r
116 element.removeStyle( 'width' );\r
117\r
118 element.removeAttribute( 'width' );\r
119 },\r
120 'default': ''\r
121 },\r
122 {\r
123 type: 'select',\r
124 id: 'widthType',\r
125 label: editor.lang.table.widthUnit,\r
126 labelStyle: 'visibility:hidden',\r
127 'default': 'px',\r
128 items: [\r
129 [ langTable.widthPx, 'px' ],\r
130 [ langTable.widthPc, '%' ]\r
131 ],\r
132 setup: setupCells( getCellWidthType )\r
133 } ]\r
134 },\r
135 {\r
136 type: 'hbox',\r
137 widths: [ '70%', '30%' ],\r
138 children: [ {\r
139 type: 'text',\r
140 id: 'height',\r
141 label: langCommon.height,\r
142 width: '100px',\r
143 'default': '',\r
144 validate: validate.number( langCell.invalidHeight ),\r
145\r
146 // Extra labelling of height unit type.\r
147 onLoad: function() {\r
148 var heightType = this.getDialog().getContentElement( 'info', 'htmlHeightType' ),\r
149 labelElement = heightType.getElement(),\r
150 inputElement = this.getInputElement(),\r
151 ariaLabelledByAttr = inputElement.getAttribute( 'aria-labelledby' );\r
152\r
153 inputElement.setAttribute( 'aria-labelledby', [ ariaLabelledByAttr, labelElement.$.id ].join( ' ' ) );\r
154 },\r
155\r
156 setup: setupCells( function( element ) {\r
157 var heightAttr = parseInt( element.getAttribute( 'height' ), 10 ),\r
158 heightStyle = parseInt( element.getStyle( 'height' ), 10 );\r
159\r
160 return !isNaN( heightStyle ) ? heightStyle :\r
161 !isNaN( heightAttr ) ? heightAttr : '';\r
162 } ),\r
163 commit: function( element ) {\r
164 var value = parseInt( this.getValue(), 10 );\r
165\r
166 if ( !isNaN( value ) )\r
167 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );\r
168 else\r
169 element.removeStyle( 'height' );\r
170\r
171 element.removeAttribute( 'height' );\r
172 }\r
173 },\r
174 {\r
175 id: 'htmlHeightType',\r
176 type: 'html',\r
177 html: '<br />' + langTable.widthPx\r
178 } ]\r
179 },\r
180 spacer,\r
181 {\r
182 type: 'select',\r
183 id: 'wordWrap',\r
184 label: langCell.wordWrap,\r
185 'default': 'yes',\r
186 items: [\r
187 [ langCell.yes, 'yes' ],\r
188 [ langCell.no, 'no' ]\r
189 ],\r
190 setup: setupCells( function( element ) {\r
191 var wordWrapAttr = element.getAttribute( 'noWrap' ),\r
192 wordWrapStyle = element.getStyle( 'white-space' );\r
193\r
194 if ( wordWrapStyle == 'nowrap' || wordWrapAttr )\r
195 return 'no';\r
196 } ),\r
197 commit: function( element ) {\r
198 if ( this.getValue() == 'no' )\r
199 element.setStyle( 'white-space', 'nowrap' );\r
200 else\r
201 element.removeStyle( 'white-space' );\r
202\r
203 element.removeAttribute( 'noWrap' );\r
204 }\r
205 },\r
206 spacer,\r
207 {\r
208 type: 'select',\r
209 id: 'hAlign',\r
210 label: langCell.hAlign,\r
211 'default': '',\r
212 items: [\r
213 [ langCommon.notSet, '' ],\r
214 [ langCommon.alignLeft, 'left' ],\r
215 [ langCommon.alignCenter, 'center' ],\r
216 [ langCommon.alignRight, 'right' ],\r
217 [ langCommon.alignJustify, 'justify' ]\r
218 ],\r
219 setup: setupCells( function( element ) {\r
220 var alignAttr = element.getAttribute( 'align' ),\r
221 textAlignStyle = element.getStyle( 'text-align' );\r
222\r
223 return textAlignStyle || alignAttr || '';\r
224 } ),\r
225 commit: function( selectedCell ) {\r
226 var value = this.getValue();\r
227\r
228 if ( value )\r
229 selectedCell.setStyle( 'text-align', value );\r
230 else\r
231 selectedCell.removeStyle( 'text-align' );\r
232\r
233 selectedCell.removeAttribute( 'align' );\r
234 }\r
235 },\r
236 {\r
237 type: 'select',\r
238 id: 'vAlign',\r
239 label: langCell.vAlign,\r
240 'default': '',\r
241 items: [\r
242 [ langCommon.notSet, '' ],\r
243 [ langCommon.alignTop, 'top' ],\r
244 [ langCommon.alignMiddle, 'middle' ],\r
245 [ langCommon.alignBottom, 'bottom' ],\r
246 [ langCell.alignBaseline, 'baseline' ]\r
247 ],\r
248 setup: setupCells( function( element ) {\r
249 var vAlignAttr = element.getAttribute( 'vAlign' ),\r
250 vAlignStyle = element.getStyle( 'vertical-align' );\r
251\r
252 switch ( vAlignStyle ) {\r
253 // Ignore all other unrelated style values..\r
254 case 'top':\r
255 case 'middle':\r
256 case 'bottom':\r
257 case 'baseline':\r
258 break;\r
259 default:\r
260 vAlignStyle = '';\r
261 }\r
262\r
263 return vAlignStyle || vAlignAttr || '';\r
264 } ),\r
265 commit: function( element ) {\r
266 var value = this.getValue();\r
267\r
268 if ( value )\r
269 element.setStyle( 'vertical-align', value );\r
270 else\r
271 element.removeStyle( 'vertical-align' );\r
272\r
273 element.removeAttribute( 'vAlign' );\r
274 }\r
275 } ]\r
276 },\r
277 spacer,\r
278 {\r
279 type: 'vbox',\r
280 padding: 0,\r
281 children: [ {\r
282 type: 'select',\r
283 id: 'cellType',\r
284 label: langCell.cellType,\r
285 'default': 'td',\r
286 items: [\r
287 [ langCell.data, 'td' ],\r
288 [ langCell.header, 'th' ]\r
289 ],\r
290 setup: setupCells( function( selectedCell ) {\r
291 return selectedCell.getName();\r
292 } ),\r
293 commit: function( selectedCell ) {\r
294 selectedCell.renameNode( this.getValue() );\r
295 }\r
296 },\r
297 spacer,\r
298 {\r
299 type: 'text',\r
300 id: 'rowSpan',\r
301 label: langCell.rowSpan,\r
302 'default': '',\r
303 validate: validate.integer( langCell.invalidRowSpan ),\r
304 setup: setupCells( function( selectedCell ) {\r
305 var attrVal = parseInt( selectedCell.getAttribute( 'rowSpan' ), 10 );\r
306 if ( attrVal && attrVal != 1 )\r
307 return attrVal;\r
308 } ),\r
309 commit: function( selectedCell ) {\r
310 var value = parseInt( this.getValue(), 10 );\r
311 if ( value && value != 1 )\r
312 selectedCell.setAttribute( 'rowSpan', this.getValue() );\r
313 else\r
314 selectedCell.removeAttribute( 'rowSpan' );\r
315 }\r
316 },\r
317 {\r
318 type: 'text',\r
319 id: 'colSpan',\r
320 label: langCell.colSpan,\r
321 'default': '',\r
322 validate: validate.integer( langCell.invalidColSpan ),\r
323 setup: setupCells( function( element ) {\r
324 var attrVal = parseInt( element.getAttribute( 'colSpan' ), 10 );\r
325 if ( attrVal && attrVal != 1 )\r
326 return attrVal;\r
327 } ),\r
328 commit: function( selectedCell ) {\r
329 var value = parseInt( this.getValue(), 10 );\r
330 if ( value && value != 1 )\r
331 selectedCell.setAttribute( 'colSpan', this.getValue() );\r
332 else\r
333 selectedCell.removeAttribute( 'colSpan' );\r
334 }\r
335 },\r
336 spacer,\r
337 {\r
338 type: 'hbox',\r
339 padding: 0,\r
340 widths: [ '60%', '40%' ],\r
341 children: [ {\r
342 type: 'text',\r
343 id: 'bgColor',\r
344 label: langCell.bgColor,\r
345 'default': '',\r
346 setup: setupCells( function( element ) {\r
347 var bgColorAttr = element.getAttribute( 'bgColor' ),\r
348 bgColorStyle = element.getStyle( 'background-color' );\r
349\r
350 return bgColorStyle || bgColorAttr;\r
351 } ),\r
352 commit: function( selectedCell ) {\r
353 var value = this.getValue();\r
354\r
355 if ( value )\r
356 selectedCell.setStyle( 'background-color', this.getValue() );\r
357 else\r
358 selectedCell.removeStyle( 'background-color' );\r
359\r
360 selectedCell.removeAttribute( 'bgColor' );\r
361 }\r
362 },\r
363 colorDialog ? {\r
364 type: 'button',\r
365 id: 'bgColorChoose',\r
366 'class': 'colorChooser', // jshint ignore:line\r
367 label: langCell.chooseColor,\r
368 onLoad: function() {\r
369 // Stick the element to the bottom (#5587)\r
370 this.getElement().getParent().setStyle( 'vertical-align', 'bottom' );\r
371 },\r
372 onClick: function() {\r
373 editor.getColorFromDialog( function( color ) {\r
374 if ( color )\r
375 this.getDialog().getContentElement( 'info', 'bgColor' ).setValue( color );\r
376 this.focus();\r
377 }, this );\r
378 }\r
379 } : spacer ]\r
380 },\r
381 spacer,\r
382 {\r
383 type: 'hbox',\r
384 padding: 0,\r
385 widths: [ '60%', '40%' ],\r
386 children: [ {\r
387 type: 'text',\r
388 id: 'borderColor',\r
389 label: langCell.borderColor,\r
390 'default': '',\r
391 setup: setupCells( function( element ) {\r
392 var borderColorAttr = element.getAttribute( 'borderColor' ),\r
393 borderColorStyle = element.getStyle( 'border-color' );\r
394\r
395 return borderColorStyle || borderColorAttr;\r
396 } ),\r
397 commit: function( selectedCell ) {\r
398 var value = this.getValue();\r
399 if ( value )\r
400 selectedCell.setStyle( 'border-color', this.getValue() );\r
401 else\r
402 selectedCell.removeStyle( 'border-color' );\r
403\r
404 selectedCell.removeAttribute( 'borderColor' );\r
405 }\r
406 },\r
407\r
408 colorDialog ? {\r
409 type: 'button',\r
410 id: 'borderColorChoose',\r
411 'class': 'colorChooser', // jshint ignore:line\r
412 label: langCell.chooseColor,\r
413 style: ( rtl ? 'margin-right' : 'margin-left' ) + ': 10px',\r
414 onLoad: function() {\r
415 // Stick the element to the bottom (#5587)\r
416 this.getElement().getParent().setStyle( 'vertical-align', 'bottom' );\r
417 },\r
418 onClick: function() {\r
419 editor.getColorFromDialog( function( color ) {\r
420 if ( color )\r
421 this.getDialog().getContentElement( 'info', 'borderColor' ).setValue( color );\r
422 this.focus();\r
423 }, this );\r
424 }\r
425 } : spacer ]\r
426 } ]\r
427 } ]\r
428 } ]\r
429 } ],\r
430 onShow: function() {\r
431 this.cells = CKEDITOR.plugins.tabletools.getSelectedCells( this._.editor.getSelection() );\r
432 this.setupContent( this.cells );\r
433 },\r
434 onOk: function() {\r
435 var selection = this._.editor.getSelection(),\r
436 bookmarks = selection.createBookmarks();\r
437\r
438 var cells = this.cells;\r
439 for ( var i = 0; i < cells.length; i++ )\r
440 this.commitContent( cells[ i ] );\r
441\r
442 this._.editor.forceNextSelectionCheck();\r
443 selection.selectBookmarks( bookmarks );\r
444 this._.editor.selectionChange();\r
445 },\r
446 onLoad: function() {\r
447 var saved = {};\r
448\r
449 // Prevent from changing cell properties when the field's value\r
450 // remains unaltered, i.e. when selected multiple cells and dialog loaded\r
451 // only the properties of the first cell (#11439).\r
452 this.foreach( function( field ) {\r
453 if ( !field.setup || !field.commit )\r
454 return;\r
455\r
456 // Save field's value every time after "setup" is called.\r
457 field.setup = CKEDITOR.tools.override( field.setup, function( orgSetup ) {\r
458 return function() {\r
459 orgSetup.apply( this, arguments );\r
460 saved[ field.id ] = field.getValue();\r
461 };\r
462 } );\r
463\r
464 // Compare saved value with actual value. Update cell only if value has changed.\r
465 field.commit = CKEDITOR.tools.override( field.commit, function( orgCommit ) {\r
466 return function() {\r
467 if ( saved[ field.id ] !== field.getValue() )\r
468 orgCommit.apply( this, arguments );\r
469 };\r
470 } );\r
471 } );\r
472 }\r
473 };\r
474} );\r