text: ﻿/*
  Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
  For licensing, see LICENSE.html or http://ckeditor.com/license
  */
  
  /**
   * @file Justify commands.
   */
  
  (function()
  {
  	function getState( editor, path )
  	{
  		var firstBlock = path.block || path.blockLimit;
  
  		if ( !firstBlock || firstBlock.getName() == 'body' )
  			return CKEDITOR.TRISTATE_OFF;
  
  		return ( getAlignment( firstBlock, editor.config.useComputedState ) == this.value ) ?
  			CKEDITOR.TRISTATE_ON :
  			CKEDITOR.TRISTATE_OFF;
  	}
  
  	function getAlignment( element, useComputedState )
  	{
  		useComputedState = useComputedState === undefined || useComputedState;
  
  		var align;
  		if ( useComputedState )
  			align = element.getComputedStyle( 'text-align' );
  		else
  		{
  			while ( !element.hasAttribute || !( element.hasAttribute( 'align' ) || element.getStyle( 'text-align' ) ) )
  			{
  				var parent = element.getParent();
  				if ( !parent )
  					break;
  				element = parent;
  			}
  			align = element.getStyle( 'text-align' ) || element.getAttribute( 'align' ) || '';
  		}
  
  		align && ( align = align.replace( /-moz-|-webkit-|start|auto/i, '' ) );
  
  		!align && useComputedState && ( align = element.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' );
  
  		return align;
  	}
  
  	function onSelectionChange( evt )
  	{
  		var command = evt.editor.getCommand( this.name );
  		command.state = getState.call( this, evt.editor, evt.data.path );
  		command.fire( 'state' );
  	}
  
  	function justifyCommand( editor, name, value )
  	{
  		this.name = name;
  		this.value = value;
  
  		var classes = editor.config.justifyClasses;
  		if ( classes )
  		{
  			switch ( value )
  			{
  				case 'left' :
  					this.cssClassName = classes[0];
  					break;
  				case 'center' :
  					this.cssClassName = classes[1];
  					break;
  				case 'right' :
  					this.cssClassName = classes[2];
  					break;
  				case 'justify' :
  					this.cssClassName = classes[3];
  					break;
  			}
  
  			this.cssClassRegex = new RegExp( '(?:^|\\s+)(?:' + classes.join( '|' ) + ')(?=$|\\s)' );
  		}
  	}
  
  	justifyCommand.prototype = {
  		exec : function( editor )
  		{
  			var selection = editor.getSelection(),
  				enterMode = editor.config.enterMode;
  
  			if ( !selection )
  				return;
  
  			var bookmarks = selection.createBookmarks(),
  				ranges = selection.getRanges( true );
  
  			var cssClassName = this.cssClassName,
  				iterator,
  				block;
  
  			var useComputedState = editor.config.useComputedState;
  			useComputedState = useComputedState === undefined || useComputedState;
  
  			for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
  			{
  				iterator = ranges[ i ].createIterator();
  				iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
  
  				while ( ( block = iterator.getNextParagraph() ) )
  				{
  					block.removeAttribute( 'align' );
  					block.removeStyle( 'text-align' );
  
  					// Remove any of the alignment classes from the className.
  					var className = cssClassName && ( block.$.className =
  						CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) ) );
  
  					var apply =
  						( this.state == CKEDITOR.TRISTATE_OFF ) &&
  						( !useComputedState || ( getAlignment( block, true ) != this.value ) );
  
  					if ( cssClassName )
  					{
  						// Append the desired class name.
  						if ( apply )
  							block.addClass( cssClassName );
  						else if ( !className )
  							block.removeAttribute( 'class' );
  					}
  					else if ( apply )
  						block.setStyle( 'text-align', this.value );
  				}
  
  			}
  
  			editor.focus();
  			editor.forceNextSelectionCheck();
  			selection.selectBookmarks( bookmarks );
  		}
  	};
  
  	CKEDITOR.plugins.add( 'justify',
  	{
  		init : function( editor )
  		{
  			var left = new justifyCommand( editor, 'justifyleft', 'left' ),
  				center = new justifyCommand( editor, 'justifycenter', 'center' ),
  				right = new justifyCommand( editor, 'justifyright', 'right' ),
  				justify = new justifyCommand( editor, 'justifyblock', 'justify' );
  
  			editor.addCommand( 'justifyleft', left );
  			editor.addCommand( 'justifycenter', center );
  			editor.addCommand( 'justifyright', right );
  			editor.addCommand( 'justifyblock', justify );
  
  			editor.ui.addButton( 'JustifyLeft',
  				{
  					label : editor.lang.justify.left,
  					command : 'justifyleft'
  				} );
  			editor.ui.addButton( 'JustifyCenter',
  				{
  					label : editor.lang.justify.center,
  					command : 'justifycenter'
  				} );
  			editor.ui.addButton( 'JustifyRight',
  				{
  					label : editor.lang.justify.right,
  					command : 'justifyright'
  				} );
  			editor.ui.addButton( 'JustifyBlock',
  				{
  					label : editor.lang.justify.block,
  					command : 'justifyblock'
  				} );
  
  			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, left ) );
  			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, right ) );
  			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, center ) );
  			editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, justify ) );
  		},
  
  		requires : [ 'domiterator' ]
  	});
  })();
  
  CKEDITOR.tools.extend( CKEDITOR.config,
  	{
  		justifyClasses : null
  	} );
  