/*\r
-Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\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
(function()\r
{\r
- var listNodeNames = { ol : 1, ul : 1 };\r
-\r
- var isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),\r
+ var listNodeNames = { ol : 1, ul : 1 },\r
+ isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),\r
isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true );\r
\r
- function setState( editor, state )\r
- {\r
- editor.getCommand( this.name ).setState( state );\r
- }\r
-\r
function onSelectionChange( evt )\r
{\r
var editor = evt.editor;\r
list = elementPath && elementPath.contains( listNodeNames );\r
\r
if ( list )\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );\r
+ return this.setState( CKEDITOR.TRISTATE_OFF );\r
\r
if ( !this.useIndentClasses && this.name == 'indent' )\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );\r
+ return this.setState( CKEDITOR.TRISTATE_OFF );\r
\r
var path = evt.data.path,\r
firstBlock = path.block || path.blockLimit;\r
if ( !firstBlock )\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );\r
+ return this.setState( CKEDITOR.TRISTATE_DISABLED );\r
\r
if ( this.useIndentClasses )\r
{\r
}\r
if ( ( this.name == 'outdent' && !indentStep ) ||\r
( this.name == 'indent' && indentStep == editor.config.indentClasses.length ) )\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );\r
+ return this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+ return this.setState( CKEDITOR.TRISTATE_OFF );\r
}\r
else\r
{\r
if ( isNaN( indent ) )\r
indent = 0;\r
if ( indent <= 0 )\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );\r
- return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );\r
+ return this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+ return this.setState( CKEDITOR.TRISTATE_OFF );\r
}\r
}\r
\r
}\r
\r
// Returns the CSS property to be used for identing a given element.\r
- function getIndentCssProperty( element )\r
+ function getIndentCssProperty( element, dir )\r
{\r
- return element.getComputedStyle( 'direction' ) == 'ltr' ? 'margin-left' : 'margin-right';\r
+ return ( dir || element.getComputedStyle( 'direction' ) ) == 'ltr' ? 'margin-left' : 'margin-right';\r
}\r
\r
function isListItem( node )\r
\r
// Convert the array back to a DOM forest (yes we might have a few subtrees now).\r
// And replace the old list with the new forest.\r
- var newListDir = listNode.getAttribute( 'dir' ) || listNode.getStyle( 'direction' );\r
- var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, newListDir );\r
+ var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, listNode.getDirection() );\r
\r
// Avoid nested <li> after outdent even they're visually same,\r
// recording them for later refactoring.(#3982)\r
iterator.enforceRealBlocks = true;\r
iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;\r
var block;\r
- while ( ( block = iterator.getNextParagraph() ) )\r
+ while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )\r
indentElement( block );\r
}\r
\r
- function indentElement( element )\r
+ function indentElement( element, dir )\r
{\r
if ( element.getCustomData( 'indent_processed' ) )\r
return false;\r
\r
indentStep = Math.min( indentStep, editor.config.indentClasses.length );\r
indentStep = Math.max( indentStep, 0 );\r
- var className = CKEDITOR.tools.ltrim( element.$.className.replace( self.classNameRegex, '' ) );\r
- if ( indentStep < 1 )\r
- element.$.className = className;\r
- else\r
+ element.$.className = CKEDITOR.tools.ltrim( element.$.className.replace( self.classNameRegex, '' ) );\r
+ if ( indentStep > 0 )\r
element.addClass( editor.config.indentClasses[ indentStep - 1 ] );\r
}\r
else\r
{\r
- var indentCssProperty = getIndentCssProperty( element ),\r
+ var indentCssProperty = getIndentCssProperty( element, dir ),\r
currentOffset = parseInt( element.getStyle( indentCssProperty ), 10 );\r
if ( isNaN( currentOffset ) )\r
currentOffset = 0;\r
\r
if ( nearestListBlock )\r
{\r
- var firstListItem = nearestListBlock.getFirst( function( node )\r
- {\r
- return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' );\r
- }),\r
+ var firstListItem = nearestListBlock.getFirst( isListItem ),\r
+ hasMultipleItems = !!firstListItem.getNext( isListItem ),\r
rangeStart = range.startContainer,\r
indentWholeList = firstListItem.equals( rangeStart ) || firstListItem.contains( rangeStart );\r
\r
// Only do that for indenting or when using indent classes or when there is something to outdent. (#6141)\r
if ( !( indentWholeList &&\r
( self.name == 'indent' || self.useIndentClasses || parseInt( nearestListBlock.getStyle( getIndentCssProperty( nearestListBlock ) ), 10 ) ) &&\r
- indentElement( nearestListBlock ) ) )\r
+ indentElement( nearestListBlock, !hasMultipleItems && firstListItem.getDirection() ) ) )\r
indentList( nearestListBlock );\r
}\r
else\r
init : function( editor )\r
{\r
// Register commands.\r
- var indent = new indentCommand( editor, 'indent' ),\r
- outdent = new indentCommand( editor, 'outdent' );\r
- editor.addCommand( 'indent', indent );\r
- editor.addCommand( 'outdent', outdent );\r
+ var indent = editor.addCommand( 'indent', new indentCommand( editor, 'indent' ) ),\r
+ outdent = editor.addCommand( 'outdent', new indentCommand( editor, 'outdent' ) );\r
\r
// Register the toolbar buttons.\r
editor.ui.addButton( 'Indent',\r
editor.on( 'dirChanged', function( e )\r
{\r
var range = new CKEDITOR.dom.range( editor.document );\r
- range.setStartBefore( e.data );\r
- range.setEndAfter( e.data );\r
+ range.setStartBefore( e.data.node );\r
+ range.setEndAfter( e.data.node );\r
\r
var walker = new CKEDITOR.dom.walker( range ),\r
node;\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.getDirection() )\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 alignment classes.\r
+ var classes = editor.config.indentClasses;\r
+ if ( classes )\r
+ {\r
+ var suffix = ( e.data.dir == 'ltr' ) ? [ '_rtl', '' ] : [ '', '_rtl' ];\r
+ for ( var i = 0; i < classes.length; i++ )\r
+ {\r
+ if ( node.hasClass( classes[ i ] + suffix[ 0 ] ) )\r
+ {\r
+ node.removeClass( classes[ i ] + suffix[ 0 ] );\r
+ node.addClass( classes[ i ] + suffix[ 1 ] );\r
+ }\r
+ }\r
+ }\r
+\r
// Switch the margins.\r
var marginLeft = node.getStyle( 'margin-right' ),\r
marginRight = node.getStyle( 'margin-left' );\r
\r
/**\r
* Size of each indentation step\r
+ * @name CKEDITOR.config.indentOffset\r
* @type Number\r
* @default 40\r
* @example\r
\r
/**\r
* Unit for the indentation style\r
+ * @name CKEDITOR.config.indentUnit\r
* @type String\r
* @default 'px'\r
* @example\r
/**\r
* List of classes to use for indenting the contents. If it's null, no classes will be used\r
* and instead the {@link #indentUnit} and {@link #indentOffset} properties will be used.\r
+ * @name CKEDITOR.config.indentClasses\r
* @type Array\r
* default null\r
* @example\r