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 				range = selection && selection.getRanges()[0];
 71
 72 			if ( !range )
 73 				return;
 74
 75 			var bookmarks = selection.createBookmarks(),
 76 				cssClassName = this.cssClassName,
 77 				iterator = range.createIterator(),
 78 				block;
 79
 80 			while ( ( block = iterator.getNextParagraph() ) )
 81 			{
 82 				block.removeAttribute( 'align' );
 83
 84 				if ( cssClassName )
 85 				{
 86 					// Remove any of the alignment classes from the className.
 87 					var className = block.$.className =
 88 						CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) );
 89
 90 					// Append the desired class name.
 91 					if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )
 92 						block.addClass( cssClassName );
 93 					else if ( className.length == 0 )
 94 						block.removeAttribute( 'class' );
 95 				}
 96 				else
 97 				{
 98 					if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )
 99 						block.setStyle( 'text-align', this.value );
100 					else
101 						block.removeStyle( 'text-align' );
102 				}
103 			}
104
105 			editor.focus();
106 			editor.forceNextSelectionCheck();
107 			selection.selectBookmarks( bookmarks );
108 		}
109 	};
110
111 	CKEDITOR.plugins.add( 'justify',
112 	{
113 		init : function( editor )
114 		{
115 			var left = new justifyCommand( editor, 'justifyleft', 'left' ),
116 				center = new justifyCommand( editor, 'justifycenter', 'center' ),
117 				right = new justifyCommand( editor, 'justifyright', 'right' ),
118 				justify = new justifyCommand( editor, 'justifyblock', 'justify' );
119
120 			editor.addCommand( 'justifyleft', left );
121 			editor.addCommand( 'justifycenter', center );
122 			editor.addCommand( 'justifyright', right );
123 			editor.addCommand( 'justifyblock', justify );
124
125 			editor.ui.addButton( 'JustifyLeft',
126 				{
127 					label : editor.lang.justify.left,
128 					command : 'justifyleft'
129 				} );
130 			editor.ui.addButton( 'JustifyCenter',
131 				{
132 					label : editor.lang.justify.center,
133 					command : 'justifycenter'
134 				} );
135 			editor.ui.addButton( 'JustifyRight',
136 				{
137 					label : editor.lang.justify.right,
138 					command : 'justifyright'
139 				} );
140 			editor.ui.addButton( 'JustifyBlock',
141 				{
142 					label : editor.lang.justify.block,
143 					command : 'justifyblock'
144 				} );
145
146 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, left ) );
147 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, right ) );
148 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, center ) );
149 			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, justify ) );
150 		},
151
152 		requires : [ 'domiterator' ]
153 	});
154 })();
155
156 CKEDITOR.tools.extend( CKEDITOR.config,
157 	{
158 		justifyClasses : null
159 	} );
160