      1 /*
      2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
      3 For licensing, see LICENSE.html or http://ckeditor.com/license
      4 */
      5
      6 /**
      7  * @file Justify commands.
      8  */
      9
     10 (function()
     11 {
     12 	var alignRemoveRegex = /(-moz-|-webkit-|start|auto)/i;
     13
     14 	function getState( editor, path )
     15 	{
     16 		var firstBlock = path.block || path.blockLimit;
     17
     18 		if ( !firstBlock || firstBlock.getName() == 'body' )
     19 			return CKEDITOR.TRISTATE_OFF;
     20
     21 		var currentAlign = firstBlock.getComputedStyle( 'text-align' ).replace( alignRemoveRegex, '' );
     22 		if ( ( !currentAlign && this.isDefaultAlign ) || currentAlign == this.value )
     23 			return CKEDITOR.TRISTATE_ON;
     24 		return CKEDITOR.TRISTATE_OFF;
     25 	}
     26
     27 	function onSelectionChange( evt )
     28 	{
     29 		var command = evt.editor.getCommand( this.name );
     30 		command.state = getState.call( this, evt.editor, evt.data.path );
     31 		command.fire( 'state' );
     32 	}
     33
     34 	function justifyCommand( editor, name, value )
     35 	{
     36 		this.name = name;
     37 		this.value = value;
     38
     39 		var contentDir = editor.config.contentsLangDirection;
     40 		this.isDefaultAlign = ( value == 'left' && contentDir == 'ltr' ) ||
     41 			( value == 'right' && contentDir == 'rtl' );
     42
     43 		var classes = editor.config.justifyClasses;
     44 		if ( classes )
     45 		{
     46 			switch ( value )
     47 			{
     48 				case 'left' :
     49 					this.cssClassName = classes[0];
     50 					break;
     51 				case 'center' :
     52 					this.cssClassName = classes[1];
     53 					break;
     54 				case 'right' :
     55 					this.cssClassName = classes[2];
     56 					break;
     57 				case 'justify' :
     58 					this.cssClassName = classes[3];
     59 					break;
     60 			}
     61
     62 			this.cssClassRegex = new RegExp( '(?:^|\\s+)(?:' + classes.join( '|' ) + ')(?=$|\\s)' );
     63 		}
     64 	}
     65
     66 	justifyCommand.prototype = {
     67 		exec : function( editor )
     68 		{
     69 			var selection = editor.getSelection();
     70 			if ( !selection )
     71 				return;
     72
     73 			var bookmarks = selection.createBookmarks(),
     74 				ranges = selection.getRanges();
     75
     76
     77 			var cssClassName = this.cssClassName,
     78 				iterator,
     79 				block;
     80 			for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
     81 			{
     82 				iterator = ranges[ i ].createIterator();
     83 				while ( ( block = iterator.getNextParagraph() ) )
     84 				{
     85 					block.removeAttribute( 'align' );
     86
     87 					if ( cssClassName )
     88 					{
     89 						// Remove any of the alignment classes from the className.
     90 						var className = block.$.className =
     91 							CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) );
     92
     93 						// Append the desired class name.
     94 						if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )
     95 							block.addClass( cssClassName );
     96 						else if ( !className )
     97 							block.removeAttribute( 'class' );
     98 					}
     99 					else
    100 					{
    101 						if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )
    102 							block.setStyle( 'text-align', this.value );
    103 						else
    104 							block.removeStyle( 'text-align' );
    105 					}
    106 				}
    107
    108 			}
    109
    110 			editor.focus();
    111 			editor.forceNextSelectionCheck();
    112 			selection.selectBookmarks( bookmarks );
    113 		}
    114 	};
    115
    116 	CKEDITOR.plugins.add( 'justify',
    117 	{
    118 		init : function( editor )
    119 		{
    120 			var left = new justifyCommand( editor, 'justifyleft', 'left' ),
    121 				center = new justifyCommand( editor, 'justifycenter', 'center' ),
    122 				right = new justifyCommand( editor, 'justifyright', 'right' ),
    123 				justify = new justifyCommand( editor, 'justifyblock', 'justify' );
    124
    125 			editor.addCommand( 'justifyleft', left );
    126 			editor.addCommand( 'justifycenter', center );
    127 			editor.addCommand( 'justifyright', right );
    128 			editor.addCommand( 'justifyblock', justify );
    129
    130 			editor.ui.addButton( 'JustifyLeft',
    131 				{
    132 					label : editor.lang.justify.left,
    133 					command : 'justifyleft'
    134 				} );
    135 			editor.ui.addButton( 'JustifyCenter',
    136 				{
    137 					label : editor.lang.justify.center,
    138 					command : 'justifycenter'
    139 				} );
    140 			editor.ui.addButton( 'JustifyRight',
    141 				{
    142 					label : editor.lang.justify.right,
    143 					command : 'justifyright'
    144 				} );
    145 			editor.ui.addButton( 'JustifyBlock',
    146 				{
    147 					label : editor.lang.justify.block,
    148 					command : 'justifyblock'
    149 				} );
    150
    151 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, left ) );
    152 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, right ) );
    153 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, center ) );
    154 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, justify ) );
    155 		},
    156
    157 		requires : [ 'domiterator' ]
    158 	});
    159 })();
    160
    161 CKEDITOR.tools.extend( CKEDITOR.config,
    162 	{
    163 		justifyClasses : null
    164 	} );
    165