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