1/* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2003-2007 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 * 21 * FCKJustifyCommand Class: controls block justification. 22 */ 23 24var FCKJustifyCommand = function( alignValue ) 25{ 26 this.AlignValue = alignValue ; 27 28 // Detect whether this is the instance for the default alignment. 29 var contentDir = FCKConfig.ContentLangDirection.toLowerCase() ; 30 this.IsDefaultAlign = ( alignValue == 'left' && contentDir == 'ltr' ) || 31 ( alignValue == 'right' && contentDir == 'rtl' ) ; 32 33 // Get the class name to be used by this instance. 34 var cssClassName = this._CssClassName = ( function() 35 { 36 var classes = FCKConfig.JustifyClasses ; 37 if ( classes ) 38 { 39 switch ( alignValue ) 40 { 41 case 'left' : 42 return classes[0] ; 43 case 'center' : 44 return classes[1] ; 45 case 'right' : 46 return classes[2] ; 47 case 'justify' : 48 return classes[3] ; 49 } 50 } 51 return null ; 52 } )() ; 53 54 if ( cssClassName && cssClassName.length > 0 ) 55 this._CssClassRegex = new RegExp( '(?:^|\\s+)' + cssClassName + '(?=$|\\s)' ) ; 56} 57 58FCKJustifyCommand._GetClassNameRegex = function() 59{ 60 var regex = FCKJustifyCommand._ClassRegex ; 61 if ( regex != undefined ) 62 return regex ; 63 64 var names = [] ; 65 66 var classes = FCKConfig.JustifyClasses ; 67 if ( classes ) 68 { 69 for ( var i = 0 ; i < 4 ; i++ ) 70 { 71 var className = classes[i] ; 72 if ( className && className.length > 0 ) 73 names.push( className ) ; 74 } 75 } 76 77 if ( names.length > 0 ) 78 regex = new RegExp( '(?:^|\\s+)(?:' + names.join( '|' ) + ')(?=$|\\s)' ) ; 79 else 80 regex = null ; 81 82 return FCKJustifyCommand._ClassRegex = regex ; 83} 84 85FCKJustifyCommand.prototype = 86{ 87 Execute : function() 88 { 89 // Save an undo snapshot before doing anything. 90 FCKUndo.SaveUndoStep() ; 91 92 var range = new FCKDomRange( FCK.EditorWindow ) ; 93 range.MoveToSelection() ; 94 95 var currentState = this.GetState() ; 96 if ( currentState == FCK_TRISTATE_DISABLED ) 97 return ; 98 99 // Store a bookmark of the selection since the paragraph iterator might 100 // change the DOM tree and break selections. 101 var bookmark = range.CreateBookmark() ; 102 103 var cssClassName = this._CssClassName ; 104 105 // Apply alignment setting for each paragraph. 106 var iterator = new FCKDomRangeIterator( range ) ; 107 var block ; 108 while ( ( block = iterator.GetNextParagraph() ) ) 109 { 110 block.removeAttribute( 'align' ) ; 111 112 if ( cssClassName ) 113 { 114 // Remove the any of the alignment classes from the className. 115 var className = block.className.replace( FCKJustifyCommand._GetClassNameRegex(), '' ) ; 116 117 // Append the desired class name. 118 if ( currentState == FCK_TRISTATE_OFF ) 119 { 120 if ( className.length > 0 ) 121 className += ' ' ; 122 block.className = className + cssClassName ; 123 } 124 else if ( className.length == 0 ) 125 FCKDomTools.RemoveAttribute( block, 'class' ) ; 126 } 127 else 128 { 129 var style = block.style ; 130 if ( currentState == FCK_TRISTATE_OFF ) 131 style.textAlign = this.AlignValue ; 132 else 133 { 134 style.textAlign = '' ; 135 if ( style.cssText.length == 0 ) 136 block.removeAttribute( 'style' ) ; 137 } 138 } 139 } 140 141 // Restore previous selection. 142 range.MoveToBookmark( bookmark ) ; 143 range.Select() ; 144 145 FCK.Focus() ; 146 FCK.Events.FireEvent( 'OnSelectionChange' ) ; 147 }, 148 149 GetState : function() 150 { 151 // Disabled if not WYSIWYG. 152 if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow ) 153 return FCK_TRISTATE_DISABLED ; 154 155 // Retrieve the first selected block. 156 var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ; 157 var firstBlock = path.Block || path.BlockLimit ; 158 159 if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' ) 160 return FCK_TRISTATE_OFF ; 161 162 // Check if the desired style is already applied to the block. 163 var currentAlign ; 164 if ( FCKBrowserInfo.IsIE ) 165 currentAlign = firstBlock.currentStyle.textAlign ; 166 else 167 currentAlign = FCK.EditorWindow.getComputedStyle( firstBlock, '' ).getPropertyValue( 'text-align' ); 168 currentAlign = currentAlign.replace( /(-moz-|-webkit-|start|auto)/i, '' ); 169 if ( ( !currentAlign && this.IsDefaultAlign ) || currentAlign == this.AlignValue ) 170 return FCK_TRISTATE_ON ; 171 return FCK_TRISTATE_OFF ; 172 } 173} ; 174