Ticket #2865: 2865.patch

File 2865.patch, 12.1 KB (added by Martin Kou, 15 years ago)
  • _source/lang/en.js

     
    366366        elementsPath :
    367367        {
    368368                eleTitle : '%1 element'
    369         }
     369        },
     370
     371        indent : 'Increase Indent',
     372        outdent : 'Decrease Indent'
    370373};
  • _source/plugins/indent/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @file Increse and decrease indent commands.
     8 */
     9
     10(function()
     11{
     12        var listNodeNames = { ol : 1, ul : 1 };
     13
     14        function setState( editor, state )
     15        {
     16                var command = editor.getCommand( this.name );
     17                command.state = state;
     18                command.fire( 'state' );
     19        }
     20
     21        function onSelectionChange( evt )
     22        {
     23                var elements = evt.data.path.elements,
     24                        listNode, listItem,
     25                        editor = evt.editor;
     26
     27                for ( var i = 0 ; i < elements.length ; i++ )
     28                {
     29                        if ( elements[i].getName() == 'li' )
     30                        {
     31                                listItem = elements[i];
     32                                continue;
     33                        }
     34                        if ( listNodeNames[ elements[i].getName() ] )
     35                        {
     36                                listNode = elements[i];
     37                                break;
     38                        }
     39                }
     40
     41                if ( listNode )
     42                {
     43                        if ( this.name == 'outdent' )
     44                                return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     45                        else
     46                        {
     47                                while ( listItem && ( listItem = listItem.getPrevious() ) )
     48                                {
     49                                        if ( listItem.getName && listItem.getName() == 'li' )
     50                                                return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     51                                }
     52                                return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
     53                        }
     54                }
     55
     56                if ( !this.useIndentClasses && this.name == 'indent' )
     57                        return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     58
     59                var path = evt.data.path,
     60                        firstBlock = path.block || path.blockLimit;
     61                if ( !firstBlock )
     62                        return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
     63
     64                if ( this.useIndentClasses )
     65                {
     66                        var indentClass = firstBlock.$.className.match( this.classNameRegex ),
     67                                indentStep = 0;
     68                        if ( indentClass != null )
     69                        {
     70                                indentClass = indentClass[1];
     71                                indentStep = this.indentClassMap[ indentClass ];
     72                        }
     73                        if ( ( this.name == 'outdent' && indentStep == 0 ) ||
     74                                        ( this.name == 'indent' && indentStep == editor.config.indentClass.length ) )
     75                                return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
     76                        return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     77                }
     78                else
     79                {
     80                        var indent = parseInt( firstBlock.getComputedStyle( this.indentCssProperty ), 10 );
     81                        if ( isNaN( indent ) )
     82                                indent = 0;
     83                        if ( indent <= 0 )
     84                                return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
     85                        return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     86                }
     87        }
     88
     89        function indentList( editor, range, listNode )
     90        {
     91                // Our starting and ending points of the range might be inside some blocks under a list item...
     92                // So before playing with the iterator, we need to expand the block to include the list items.
     93                var startContainer = range.startContainer,
     94                        endContainer = range.endContainer;
     95                while ( startContainer && !startContainer.getParent().equals( listNode ) )
     96                        startContainer = startContainer.getParent();
     97                while ( endContainer && !endContainer.getParent().equals( listNode ) )
     98                        endContainer = endContainer.getParent();
     99
     100                if ( !startContainer || !endContainer )
     101                        return;
     102
     103                // Now we can iterate over the individual items on the same tree depth.
     104                var block = startContainer,
     105                        itemsToMove = [],
     106                        stopFlag = false;
     107                while ( stopFlag == false )
     108                {
     109                        if ( block.equals( endContainer ) )
     110                                stopFlag = true;
     111                        itemsToMove.push( block );
     112                        block = block.getNext();
     113                }
     114                if ( itemsToMove.length < 1 )
     115                        return;
     116
     117                // Do indent or outdent operations on the array model of the list, not the
     118                // list's DOM tree itself. The array model demands that it knows as much as
     119                // possible about the surrounding lists, we need to feed it the further
     120                // ancestor node that is still a list.
     121                var listParents = listNode.getParents();
     122                for ( var i = listParents.length - 1 ; i >= 0 ; i-- )
     123                {
     124                        if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] )
     125                        {
     126                                listNode = listParents[i];
     127                                break;
     128                        }
     129                }
     130                var indentOffset = this.name == 'indent' ? 1 : -1,
     131                        startItem = itemsToMove[0],
     132                        lastItem = itemsToMove[ itemsToMove.length - 1 ],
     133                        database = {};
     134
     135                // Convert the list DOM tree into a one dimensional array.
     136                var listArray = CKEDITOR.plugins.list.listToArray( listNode, database );
     137
     138                // Apply indenting or outdenting on the array.
     139                var baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent;
     140                for ( var i = startItem.getCustomData( 'listarray_index' ) ; i <= lastItem.getCustomData( 'listarray_index' ) ; i++ )
     141                        listArray[i].indent += indentOffset;
     142                for ( var i = lastItem.getCustomData( 'listarray_index' ) + 1 ;
     143                                i < listArray.length && listArray[i].indent > baseIndent ; i++ )
     144                        listArray[i].indent += indentOffset;
     145
     146                // Convert the array back to a DOM forest (yes we might have a few subtrees now).
     147                // And replace the old list with the new forest.
     148                var newList = CKEDITOR.plugins.list.arrayToList( listArray, null, null, editor.config.enterMode );
     149                if ( newList )
     150                        newList.listNode.replace( listNode );
     151
     152                // Clean up the markers.
     153                CKEDITOR.dom.element.clearAllMarkers( database );
     154        }
     155
     156        function indentBlock( editor, range )
     157        {
     158                var iterator = range.createIterator();
     159                iterator.enforceRealBlocks = true;
     160
     161                range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     162                var commonParent = range.getCommonAncestor(),
     163                        block;
     164
     165                while ( ( block = iterator.getNextParagraph() ) )
     166                {
     167                        // We don't want to indent subtrees recursively, so only perform the indent
     168                        // operation if the block itself is the nearestParent, or the block's parent
     169                        // is the commonParent.
     170                        if ( !( block.equals( commonParent ) || block.getParent().equals( commonParent ) ) )
     171                                continue;
     172
     173                        if ( this.useIndentClasses )
     174                        {
     175                                // Transform current class name to indent step index.
     176                                var indentClass = block.$.className.match( this.classNameRegex ),
     177                                        indentStep = 0;
     178                                if ( indentClass != null )
     179                                {
     180                                        indentClass = indentClass[1];
     181                                        indentStep = this.indentClassMap[ indentClass ];
     182                                }
     183
     184                                // Operate on indent step index, transform indent step index back to class
     185                                // name.
     186                                if ( this.name == 'outdent' )
     187                                        indentStep--;
     188                                else
     189                                        indentStep++;
     190                                indentStep = Math.min( indentStep, editor.config.indentClasses.length );
     191                                indentStep = Math.max( indentStep, 0 );
     192                                var className = CKEDITOR.tools.ltrim( block.$.className.replace( this.classNameRegex, '' ) );
     193                                if ( indentStep < 1 )
     194                                        block.$.className = className;
     195                                else
     196                                        block.addClass( editor.config.indentClasses[ indentStep - 1 ] );
     197                        }
     198                        else
     199                        {
     200                                var currentOffset = parseInt( block.getComputedStyle( this.indentCssProperty ), 10 );
     201                                if ( isNaN( currentOffset ) )
     202                                        currentOffset = 0;
     203                                currentOffset += ( this.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset;
     204                                currentOffset = Math.max( currentOffset, 0 );
     205                                currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset;
     206                                block.setStyle( this.indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' );
     207                                if ( block.getAttribute( 'style' ) == '' )
     208                                        block.removeAttribute( 'style' );
     209                        }
     210                }
     211        }
     212
     213        function indentCommand( editor, name )
     214        {
     215                this.name = name;
     216                this.useIndentClasses = editor.config.indentClasses && editor.config.indentClasses.length > 0;
     217                if ( this.useIndentClasses )
     218                {
     219                        this.classNameRegex = new RegExp( '(?:^|\\s+)(' + editor.config.indentClasses.join( '|' ) + ')(?=$|\\s)' );
     220                        this.indentClassMap = {};
     221                        for ( var i = 0 ; i < editor.config.indentClasses.length ; i++ )
     222                                this.indentClassMap[ editor.config.indentClasses[i] ] = i + 1;
     223                }
     224                else
     225                        this.indentCssProperty = editor.config.contentsLangDirection == 'ltr' ? 'margin-left' : 'margin-right';
     226        }
     227
     228        indentCommand.prototype = {
     229                exec : function( editor )
     230                {
     231                        var selection = editor.getSelection(),
     232                                range = selection && selection.getRanges()[0];
     233
     234                        if ( !selection || !range )
     235                                return;
     236
     237                        var bookmarks = selection.createBookmarks(),
     238                                boundaryNodes = range.getBoundaryNodes(),
     239                                nearestListBlock = boundaryNodes.startNode.getCommonAncestor( boundaryNodes.endNode );
     240
     241                        while ( nearestListBlock )
     242                        {
     243                                if ( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ nearestListBlock.getName() ] )
     244                                        break;
     245                                nearestListBlock = nearestListBlock.getParent();
     246                        }
     247
     248                        if ( nearestListBlock )
     249                                indentList.call( this, editor, range, nearestListBlock );
     250                        else
     251                                indentBlock.call( this, editor, range );
     252
     253                        editor.focus();
     254                        selection.selectBookmarks( bookmarks );
     255                }
     256        };
     257
     258        CKEDITOR.plugins.add( 'indent',
     259        {
     260                init : function( editor )
     261                {
     262                        // Register commands.
     263                        var indent = new indentCommand( editor, 'indent' ),
     264                                outdent = new indentCommand( editor, 'outdent' );
     265                        editor.addCommand( 'indent', indent );
     266                        editor.addCommand( 'outdent', outdent );
     267
     268                        // Register the toolbar buttons.
     269                        editor.ui.addButton( 'Indent',
     270                                {
     271                                        label : editor.lang.indent,
     272                                        command : 'indent'
     273                                });
     274                        editor.ui.addButton( 'Outdent',
     275                                {
     276                                        label : editor.lang.outdent,
     277                                        command : 'outdent'
     278                                });
     279
     280                        // Register the state changing handlers.
     281                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, indent ) );
     282                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, outdent ) );
     283                },
     284               
     285                requires : [ 'domiterator', 'list' ]
     286        } );
     287})();
     288
     289CKEDITOR.tools.extend( CKEDITOR.config,
     290        {
     291                indentOffset : 40,
     292                indentUnit : 'px',
     293                indentClasses : null
     294        });
  • _source/plugins/toolbar/plugin.js

    Property changes on: _source/plugins/domiterator/plugin.js
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    209209                'Source', '-',
    210210                'NewPage', '-',
    211211                'Bold', 'Italic', 'Underline', 'Strike', '-',
     212                'Outdent', 'Indent', '-',
    212213                'Subscript', 'Superscript', '-',
    213214                'SelectAll', 'RemoveFormat', '-',
    214215                'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak'
  • _source/skins/default/toolbar.css

     
    305305{
    306306        background-position: 0 -880px;
    307307}
     308
     309.cke_skin_default a.cke_button_outdent .cke_icon
     310{
     311        background-position: 0 -432px;
     312}
     313
     314.cke_skin_default a.cke_button_indent .cke_icon
     315{
     316        background-position: 0 -448px;
     317}
  • _source/core/config.js

     
    146146         * @example
    147147         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
    148148         */
    149         plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,sourcearea,specialchar,tab,toolbar,wysiwygarea',
     149        plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,indent,sourcearea,specialchar,tab,toolbar,wysiwygarea',
    150150
    151151        /**
    152152         * The theme to be used to build the UI.
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy