JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.4.3
[ckeditor.git] / _source / plugins / justify / plugin.js
index 39bf8f6..2de9b0b 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -9,8 +9,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
 (function()\r
 {\r
-       var alignRemoveRegex = /(-moz-|-webkit-|start|auto)/i;\r
-\r
        function getState( editor, path )\r
        {\r
                var firstBlock = path.block || path.blockLimit;\r
@@ -18,10 +16,35 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                if ( !firstBlock || firstBlock.getName() == 'body' )\r
                        return CKEDITOR.TRISTATE_OFF;\r
 \r
-               var currentAlign = firstBlock.getComputedStyle( 'text-align' ).replace( alignRemoveRegex, '' );\r
-               if ( ( !currentAlign && this.isDefaultAlign ) || currentAlign == this.value )\r
-                       return CKEDITOR.TRISTATE_ON;\r
-               return CKEDITOR.TRISTATE_OFF;\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
@@ -36,10 +59,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                this.name = name;\r
                this.value = value;\r
 \r
-               var contentDir = editor.config.contentsLangDirection;\r
-               this.isDefaultAlign = ( value == 'left' && contentDir == 'ltr' ) ||\r
-                       ( value == 'right' && contentDir == 'rtl' );\r
-\r
                var classes = editor.config.justifyClasses;\r
                if ( classes )\r
                {\r
@@ -63,46 +82,106 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                }\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
+                       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();\r
-\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() ) )\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
-                                               // Remove any of the alignment classes from the className.\r
-                                               var className = block.$.className =\r
-                                                       CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) );\r
-\r
                                                // Append the desired class name.\r
-                                               if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )\r
+                                               if ( apply )\r
                                                        block.addClass( cssClassName );\r
                                                else if ( !className )\r
                                                        block.removeAttribute( 'class' );\r
                                        }\r
-                                       else\r
-                                       {\r
-                                               if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign )\r
-                                                       block.setStyle( 'text-align', this.value );\r
-                                               else\r
-                                                       block.removeStyle( 'text-align' );\r
-                                       }\r
+                                       else if ( apply )\r
+                                               block.setStyle( 'text-align', this.value );\r
                                }\r
 \r
                        }\r
@@ -152,13 +231,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        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
-\r
-CKEDITOR.tools.extend( CKEDITOR.config,\r
-       {\r
-               justifyClasses : null\r
-       } );\r