X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fjustify%2Fplugin.js;h=1532a801c91c4f284a1a88232a15538ef7c73411;hb=3fe9cac293e090ea459a3ee10d78cbe9e1dd0e03;hp=95bc5b21db0a02c433e192f39e8e742862409fd0;hpb=941b0a9ba4e673e292510d80a5a86806994b8ea6;p=ckeditor.git diff --git a/_source/plugins/justify/plugin.js b/_source/plugins/justify/plugin.js index 95bc5b2..1532a80 100644 --- a/_source/plugins/justify/plugin.js +++ b/_source/plugins/justify/plugin.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -9,37 +9,47 @@ For licensing, see LICENSE.html or http://ckeditor.com/license (function() { - var alignRemoveRegex = /(-moz-|-webkit-|start|auto)/i; - - function getState( editor, path ) + function getAlignment( element, useComputedState ) { - var firstBlock = path.block || path.blockLimit; + 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' ) || ''; + } + + // Sometimes computed values doesn't tell. + align && ( align = align.replace( /(?:-(?:moz|webkit)-)?(?:start|auto)/i, '' ) ); - if ( !firstBlock || firstBlock.getName() == 'body' ) - return CKEDITOR.TRISTATE_OFF; + !align && useComputedState && ( align = element.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' ); - var currentAlign = firstBlock.getComputedStyle( 'text-align' ).replace( alignRemoveRegex, '' ); - if ( ( !currentAlign && this.isDefaultAlign ) || currentAlign == this.value ) - return CKEDITOR.TRISTATE_ON; - return CKEDITOR.TRISTATE_OFF; + 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' ); + if ( evt.editor.readOnly ) + return; + + evt.editor.getCommand( this.name ).refresh( evt.data.path ); } function justifyCommand( editor, name, value ) { + this.editor = editor; this.name = name; this.value = value; - var contentDir = editor.config.contentsLangDirection; - this.isDefaultAlign = ( value == 'left' && contentDir == 'ltr' ) || - ( value == 'right' && contentDir == 'rtl' ); - var classes = editor.config.justifyClasses; if ( classes ) { @@ -63,46 +73,106 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } } + function onDirChanged( e ) + { + var editor = e.editor; + + var range = new CKEDITOR.dom.range( editor.document ); + range.setStartBefore( e.data.node ); + range.setEndAfter( e.data.node ); + + var walker = new CKEDITOR.dom.walker( range ), + node; + + while ( ( node = walker.next() ) ) + { + if ( node.type == CKEDITOR.NODE_ELEMENT ) + { + // A child with the defined dir is to be ignored. + if ( !node.equals( e.data.node ) && node.getDirection() ) + { + range.setStartAfter( node ); + walker = new CKEDITOR.dom.walker( range ); + continue; + } + + // Switch the alignment. + var classes = editor.config.justifyClasses; + if ( classes ) + { + // The left align class. + if ( node.hasClass( classes[ 0 ] ) ) + { + node.removeClass( classes[ 0 ] ); + node.addClass( classes[ 2 ] ); + } + // The right align class. + else if ( node.hasClass( classes[ 2 ] ) ) + { + node.removeClass( classes[ 2 ] ); + node.addClass( classes[ 0 ] ); + } + } + + // Always switch CSS margins. + var style = 'text-align'; + var align = node.getStyle( style ); + + if ( align == 'left' ) + node.setStyle( style, 'right' ); + else if ( align == 'right' ) + node.setStyle( style, 'left' ); + } + } + } + justifyCommand.prototype = { exec : function( editor ) { - var selection = editor.getSelection(); + var selection = editor.getSelection(), + enterMode = editor.config.enterMode; + if ( !selection ) return; var bookmarks = selection.createBookmarks(), - ranges = selection.getRanges(); - + 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(); - while ( ( block = iterator.getNextParagraph() ) ) + iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; + + while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) { 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 ) { - // Remove any of the alignment classes from the className. - var className = block.$.className = - CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) ); - // Append the desired class name. - if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign ) + if ( apply ) block.addClass( cssClassName ); else if ( !className ) block.removeAttribute( 'class' ); } - else - { - if ( this.state == CKEDITOR.TRISTATE_OFF && !this.isDefaultAlign ) - block.setStyle( 'text-align', this.value ); - else - block.removeStyle( 'text-align' ); - } + else if ( apply ) + block.setStyle( 'text-align', this.value ); } } @@ -110,6 +180,16 @@ For licensing, see LICENSE.html or http://ckeditor.com/license editor.focus(); editor.forceNextSelectionCheck(); selection.selectBookmarks( bookmarks ); + }, + + refresh : function( path ) + { + var firstBlock = path.block || path.blockLimit; + + this.setState( firstBlock.getName() != 'body' && + getAlignment( firstBlock, this.editor.config.useComputedState ) == this.value ? + CKEDITOR.TRISTATE_ON : + CKEDITOR.TRISTATE_OFF ); } }; @@ -152,13 +232,20 @@ For licensing, see LICENSE.html or http://ckeditor.com/license editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, right ) ); editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, center ) ); editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, justify ) ); + editor.on( 'dirChanged', onDirChanged ); }, requires : [ 'domiterator' ] }); })(); -CKEDITOR.tools.extend( CKEDITOR.config, - { - justifyClasses : null - } ); + /** + * List of classes to use for aligning the contents. If it's null, no classes will be used + * and instead the corresponding CSS values will be used. The array should contain 4 members, in the following order: left, center, right, justify. + * @name CKEDITOR.config.justifyClasses + * @type Array + * @default null + * @example + * // Use the classes 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' + * config.justifyClasses = [ 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' ]; + */