2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
7 * @file Justify commands.
12 function getState( editor
, path
)
14 var firstBlock
= path
.block
|| path
.blockLimit
;
16 if ( !firstBlock
|| firstBlock
.getName() == 'body' )
17 return CKEDITOR
.TRISTATE_OFF
;
19 return ( getAlignment( firstBlock
, editor
.config
.useComputedState
) == this.value
) ?
20 CKEDITOR
.TRISTATE_ON
:
21 CKEDITOR
.TRISTATE_OFF
;
24 function getAlignment( element
, useComputedState
)
26 useComputedState
= useComputedState
=== undefined || useComputedState
;
29 if ( useComputedState
)
30 align
= element
.getComputedStyle( 'text-align' );
33 while ( !element
.hasAttribute
|| !( element
.hasAttribute( 'align' ) || element
.getStyle( 'text-align' ) ) )
35 var parent
= element
.getParent();
40 align
= element
.getStyle( 'text-align' ) || element
.getAttribute( 'align' ) || '';
43 align
&& ( align
= align
.replace( /-moz-|-webkit-|start|auto/i, '' ) );
45 !align
&& useComputedState
&& ( align
= element
.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' );
50 function onSelectionChange( evt
)
52 if ( evt
.editor
.readOnly
)
55 var command
= evt
.editor
.getCommand( this.name
);
56 command
.state
= getState
.call( this, evt
.editor
, evt
.data
.path
);
57 command
.fire( 'state' );
60 function justifyCommand( editor
, name
, value
)
65 var classes
= editor
.config
.justifyClasses
;
71 this.cssClassName
= classes
[0];
74 this.cssClassName
= classes
[1];
77 this.cssClassName
= classes
[2];
80 this.cssClassName
= classes
[3];
84 this.cssClassRegex
= new RegExp( '(?:^|\\s+)(?:' + classes
.join( '|' ) + ')(?=$|\\s)' );
88 function onDirChanged( e
)
90 var editor
= e
.editor
;
92 var range
= new CKEDITOR
.dom
.range( editor
.document
);
93 range
.setStartBefore( e
.data
.node
);
94 range
.setEndAfter( e
.data
.node
);
96 var walker
= new CKEDITOR
.dom
.walker( range
),
99 while ( ( node
= walker
.next() ) )
101 if ( node
.type
== CKEDITOR
.NODE_ELEMENT
)
103 // A child with the defined dir is to be ignored.
104 if ( !node
.equals( e
.data
.node
) && node
.getDirection() )
106 range
.setStartAfter( node
);
107 walker
= new CKEDITOR
.dom
.walker( range
);
111 // Switch the alignment.
112 var classes
= editor
.config
.justifyClasses
;
115 // The left align class.
116 if ( node
.hasClass( classes
[ 0 ] ) )
118 node
.removeClass( classes
[ 0 ] );
119 node
.addClass( classes
[ 2 ] );
121 // The right align class.
122 else if ( node
.hasClass( classes
[ 2 ] ) )
124 node
.removeClass( classes
[ 2 ] );
125 node
.addClass( classes
[ 0 ] );
129 // Always switch CSS margins.
130 var style
= 'text-align';
131 var align
= node
.getStyle( style
);
133 if ( align
== 'left' )
134 node
.setStyle( style
, 'right' );
135 else if ( align
== 'right' )
136 node
.setStyle( style
, 'left' );
141 justifyCommand
.prototype = {
142 exec : function( editor
)
144 var selection
= editor
.getSelection(),
145 enterMode
= editor
.config
.enterMode
;
150 var bookmarks
= selection
.createBookmarks(),
151 ranges
= selection
.getRanges( true );
153 var cssClassName
= this.cssClassName
,
157 var useComputedState
= editor
.config
.useComputedState
;
158 useComputedState
= useComputedState
=== undefined || useComputedState
;
160 for ( var i
= ranges
.length
- 1 ; i
>= 0 ; i
-- )
162 iterator
= ranges
[ i
].createIterator();
163 iterator
.enlargeBr
= enterMode
!= CKEDITOR
.ENTER_BR
;
165 while ( ( block
= iterator
.getNextParagraph( enterMode
== CKEDITOR
.ENTER_P
? 'p' : 'div' ) ) )
167 block
.removeAttribute( 'align' );
168 block
.removeStyle( 'text-align' );
170 // Remove any of the alignment classes from the className.
171 var className
= cssClassName
&& ( block
.$.className
=
172 CKEDITOR
.tools
.ltrim( block
.$.className
.replace( this.cssClassRegex
, '' ) ) );
175 ( this.state
== CKEDITOR
.TRISTATE_OFF
) &&
176 ( !useComputedState
|| ( getAlignment( block
, true ) != this.value
) );
180 // Append the desired class name.
182 block
.addClass( cssClassName
);
183 else if ( !className
)
184 block
.removeAttribute( 'class' );
187 block
.setStyle( 'text-align', this.value
);
193 editor
.forceNextSelectionCheck();
194 selection
.selectBookmarks( bookmarks
);
198 CKEDITOR
.plugins
.add( 'justify',
200 init : function( editor
)
202 var left
= new justifyCommand( editor
, 'justifyleft', 'left' ),
203 center
= new justifyCommand( editor
, 'justifycenter', 'center' ),
204 right
= new justifyCommand( editor
, 'justifyright', 'right' ),
205 justify
= new justifyCommand( editor
, 'justifyblock', 'justify' );
207 editor
.addCommand( 'justifyleft', left
);
208 editor
.addCommand( 'justifycenter', center
);
209 editor
.addCommand( 'justifyright', right
);
210 editor
.addCommand( 'justifyblock', justify
);
212 editor
.ui
.addButton( 'JustifyLeft',
214 label
: editor
.lang
.justify
.left
,
215 command
: 'justifyleft'
217 editor
.ui
.addButton( 'JustifyCenter',
219 label
: editor
.lang
.justify
.center
,
220 command
: 'justifycenter'
222 editor
.ui
.addButton( 'JustifyRight',
224 label
: editor
.lang
.justify
.right
,
225 command
: 'justifyright'
227 editor
.ui
.addButton( 'JustifyBlock',
229 label
: editor
.lang
.justify
.block
,
230 command
: 'justifyblock'
233 editor
.on( 'selectionChange', CKEDITOR
.tools
.bind( onSelectionChange
, left
) );
234 editor
.on( 'selectionChange', CKEDITOR
.tools
.bind( onSelectionChange
, right
) );
235 editor
.on( 'selectionChange', CKEDITOR
.tools
.bind( onSelectionChange
, center
) );
236 editor
.on( 'selectionChange', CKEDITOR
.tools
.bind( onSelectionChange
, justify
) );
237 editor
.on( 'dirChanged', onDirChanged
);
240 requires
: [ 'domiterator' ]
245 * List of classes to use for aligning the contents. If it's null, no classes will be used
246 * and instead the corresponding CSS values will be used. The array should contain 4 members, in the following order: left, center, right, justify.
247 * @name CKEDITOR.config.justifyClasses
251 * // Use the classes 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify'
252 * config.justifyClasses = [ 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' ];