/** * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ CKEDITOR.dialog.add( 'cellProperties', function( editor ) { var langTable = editor.lang.table, langCell = langTable.cell, langCommon = editor.lang.common, validate = CKEDITOR.dialog.validate, widthPattern = /^(\d+(?:\.\d+)?)(px|%)$/, spacer = { type: 'html', html: ' ' }, hiddenSpacer, rtl = editor.lang.dir == 'rtl', colorDialog = editor.plugins.colordialog; // Returns a function, which runs regular "setup" for all selected cells to find out // whether the initial value of the field would be the same for all cells. If so, // the value is displayed just as if a regular "setup" was executed. Otherwise, // i.e. when there are several cells of different value of the property, a field // gets empty value. // // * @param {Function} setup Setup function which returns a value instead of setting it. // * @returns {Function} A function to be used in dialog definition. function setupCells( setup ) { return function( cells ) { var fieldValue = setup( cells[ 0 ] ); // If one of the cells would have a different value of the // property, set the empty value for a field. for ( var i = 1; i < cells.length; i++ ) { if ( setup( cells[ i ] ) !== fieldValue ) { fieldValue = null; break; } } // Setting meaningful or empty value only makes sense // when setup returns some value. Otherwise, a *default* value // is used for that field. if ( typeof fieldValue != 'undefined' ) { this.setValue( fieldValue ); // The only way to have an empty select value in Firefox is // to set a negative selectedIndex. if ( CKEDITOR.env.gecko && this.type == 'select' && !fieldValue ) this.getInputElement().$.selectedIndex = -1; } }; } // Reads the unit of width property of the table cell. // // * @param {CKEDITOR.dom.element} cell An element representing table cell. // * @returns {String} A unit of width: 'px', '%' or undefined if none. function getCellWidthType( cell ) { var match = widthPattern.exec( cell.getStyle( 'width' ) || cell.getAttribute( 'width' ) ); if ( match ) return match[ 2 ]; } return { title: langCell.title, minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 450 : 410, minHeight: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ? 230 : 220, contents: [ { id: 'info', label: langCell.title, accessKey: 'I', elements: [ { type: 'hbox', widths: [ '40%', '5%', '40%' ], children: [ { type: 'vbox', padding: 0, children: [ hiddenSpacer = { type: 'html', id: 'hiddenSpacer', html: ' ', style: 'display: none' }, spacer, { type: 'select', id: 'hAlign', label: langCell.hAlign, 'default': '', items: [ [ langCommon.notSet, '' ], [ langCommon.left, 'left' ], [ langCommon.center, 'center' ], [ langCommon.right, 'right' ] ], setup: setupCells( function( element ) { var alignAttr = element.getAttribute( 'align' ), textAlignStyle = element.getStyle( 'text-align' ); return textAlignStyle || alignAttr || ''; } ), commit: function( selectedCell ) { var value = this.getValue(); if ( value ) { selectedCell.setStyle( 'text-align', value ); selectedCell.setAttribute('class', value + 'align'); } else { selectedCell.removeStyle( 'text-align' ); selectedCell.removeAttribute( 'align' ); } } }, ] }, spacer, { type: 'vbox', padding: 0, children: [ { type: 'select', id: 'cellType', label: langCell.cellType, 'default': 'td', items: [ [ langCell.data, 'td' ], [ langCell.header, 'th' ] ], setup: setupCells( function( selectedCell ) { return selectedCell.getName(); } ), commit: function( selectedCell ) { selectedCell.renameNode( this.getValue() ); } }, spacer, { type: 'text', id: 'rowSpan', label: langCell.rowSpan, 'default': '', validate: validate.integer( langCell.invalidRowSpan ), setup: setupCells( function( selectedCell ) { var attrVal = parseInt( selectedCell.getAttribute( 'rowSpan' ), 10 ); if ( attrVal && attrVal != 1 ) return attrVal; } ), commit: function( selectedCell ) { var value = parseInt( this.getValue(), 10 ); if ( value && value != 1 ) selectedCell.setAttribute( 'rowSpan', this.getValue() ); else selectedCell.removeAttribute( 'rowSpan' ); } }, { type: 'text', id: 'colSpan', label: langCell.colSpan, 'default': '', validate: validate.integer( langCell.invalidColSpan ), setup: setupCells( function( element ) { var attrVal = parseInt( element.getAttribute( 'colSpan' ), 10 ); if ( attrVal && attrVal != 1 ) return attrVal; } ), commit: function( selectedCell ) { var value = parseInt( this.getValue(), 10 ); if ( value && value != 1 ) selectedCell.setAttribute( 'colSpan', this.getValue() ); else selectedCell.removeAttribute( 'colSpan' ); } }, ] } ] } ] } ], onShow: function() { this.cells = CKEDITOR.plugins.tabletools.getSelectedCells( this._.editor.getSelection() ); this.setupContent( this.cells ); }, onOk: function() { var selection = this._.editor.getSelection(), bookmarks = selection.createBookmarks(); var cells = this.cells; for ( var i = 0; i < cells.length; i++ ) this.commitContent( cells[ i ] ); this._.editor.forceNextSelectionCheck(); selection.selectBookmarks( bookmarks ); this._.editor.selectionChange(); }, onLoad: function() { var saved = {}; // Prevent from changing cell properties when the field's value // remains unaltered, i.e. when selected multiple cells and dialog loaded // only the properties of the first cell (https://dev.ckeditor.com/ticket/11439). this.foreach( function( field ) { if ( !field.setup || !field.commit ) return; // Save field's value every time after "setup" is called. field.setup = CKEDITOR.tools.override( field.setup, function( orgSetup ) { return function() { orgSetup.apply( this, arguments ); saved[ field.id ] = field.getValue(); }; } ); // Compare saved value with actual value. Update cell only if value has changed. field.commit = CKEDITOR.tools.override( field.commit, function( orgCommit ) { return function() { if ( saved[ field.id ] !== field.getValue() ) orgCommit.apply( this, arguments ); }; } ); } ); } }; } );