Ticket #3189: 3189.patch

File 3189.patch, 4.8 KB (added by Garry Yao, 15 years ago)
  • _source/plugins/wysiwygarea/plugin.js

     
    114114                                this.getSelection().lock();
    115115                }
    116116        }
     117       
     118        /**
     119         *  Auto-fixing block-less content by wrapping paragraph, prevent
     120         *  non-exitable-block by padding extra nodes.
     121         */
     122        function onSelectionChangeFixBody( evt )
     123        {
     124                var editor = evt.editor,
     125                        path = evt.data.path,
     126                        blockLimit = path.blockLimit,
     127                        selection = evt.data.selection,
     128                        bms = selection.createBookmarks(),
     129                        ranges = selection.getRanges(),
     130                        range = ranges[ 0 ],
     131                        body = editor.document.getBody(),
     132                        enterMode = editor.config.enterMode;
     133
     134                // When enterMode set to block, we'll establing new paragraph if the
     135                // current range is block-less within body.
     136                if ( enterMode != CKEDITOR.ENTER_BR
     137                         && blockLimit.getName() == 'body'
     138                         && !path.block )
     139                {
     140                        var fixedBlock = range.fixBlock( true,
     141                                editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'  );
     142                       
     143                        // For IE, if there's only a padding br inside, we'll drop it since now
     144                        // we have a block.
     145                        if ( CKEDITOR.env.ie && !CKEDITOR.tools.trim( fixedBlock.getText() ) )
     146                        {
     147                                var children = fixedBlock.getChildren(), child;
     148                                for ( var i = 0 ; i <  children.count() ; i++ ) {
     149                                        if ( ( child = children.getItem( i ) ) && child.is && child.is( 'br' ) )
     150                                                child.remove();
     151                                }
     152                        }
     153                }
     154               
     155                // Fixing non-exitable blocks when selection inside.
     156                if ( path.elements )
     157                {
     158                        var blockToFix,
     159                        blockNext,      // The block following 'blockToFix'.
     160                        unexitableBlock = CKEDITOR.tools.clone( CKEDITOR.dtd.$block );
     161                       
     162                        // Exlude block tag already defined by enterMode, since 'enterkey' behavior
     163                        // will help to exit.
     164                        if ( enterMode != CKEDITOR.ENTER_BR )
     165                                delete unexitableBlock[ enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ];
     166                       
     167                        // Find the target block on the path.
     168                        var elements = path.elements,
     169                                l = elements.length,
     170                                element;
     171                        for ( var i = 0; i < l ; i++) {
     172                                element = elements[ i ];
     173                                if ( element.getName && ( element.getName() in unexitableBlock ) )
     174                                {
     175                                        blockToFix = element;
     176                                        break;
     177                                }
     178                        }
     179                       
     180                        // Inserting the padding-block-node if it's followed by another
     181                        // non-exitable-block OR it reachs document end.
     182                        if ( blockToFix &&
     183                                typeof ( blockNext = blockToFix.getNext( CKEDITOR.env.ie? false : true ) ) != 'undefined'
     184                                && ( !blockNext ||( blockNext.getName && blockNext.getName() in unexitableBlock ) ) )
     185                        {
     186                                var paddingBlock = editor.document.createElement( 'br' );
     187                                paddingBlock.insertAfter( blockToFix );
     188                        }
     189                }
     190               
     191                selection.selectBookmarks( bms );
     192        }
    117193
    118194        CKEDITOR.plugins.add( 'wysiwygarea',
    119195        {
     
    449525
    450526                                        editor.on( 'insertHtml', onInsertHtml, null, null, 20 );
    451527                                        editor.on( 'insertElement', onInsertElement, null, null, 20 );
     528                                        // Auto fixing on some document structure weakness to enhance usabilities. (#3190 and #3189)
     529                                        editor.on( 'selectionChange', onSelectionChangeFixBody, null, null, 1 );
    452530                                });
    453531                }
    454532        });
  • _source/core/dom/node.js

     
    259265                        return -1;
    260266                },
    261267
    262                 /**
    263                  * Gets the node following this node (next sibling).
    264                  * @returns {CKEDITOR.dom.node} The next node.
    265                  */
    266                 getNext : function()
    267                 {
    268                         var next = this.$.nextSibling;
    269                         return next ? new CKEDITOR.dom.node( next ) : null;
    270                 },
    271 
    272268                getNextSourceNode : function( startFromSibling, nodeType, guard )
    273269                {
    274270                        var node = ( !startFromSibling && this.getFirst && this.getFirst() ) || this.getNext(),
     
    349345                },
    350346
    351347                /**
    352                  * Gets the node that follows this element in its parent's child list.
     348                 * Gets the node following this node (next sibling).
     349                 * @param {Boolean} ignoreEmpty Whether should ignore empty text nodes.
    353350                 * @returns {CKEDITOR.dom.node} The next node or null if not
    354351                 *              available.
    355352                 * @example
     
    357354                 * var first = <b>element.getFirst().getNext()</b>;
    358355                 * alert( first.getName() );  // "i"
    359356                 */
    360                 getNext : function()
     357                getNext : function( ignoreEmpty )
    361358                {
    362                         var $ = this.$.nextSibling;
    363                         return $ ? new CKEDITOR.dom.node( $ ) : null;
     359                        var next = this.$.nextSibling;
     360                        if ( ignoreEmpty && next && ( next.nodeType == CKEDITOR.NODE_TEXT )
     361                                  && !CKEDITOR.tools.trim( next.nodeValue ) )
     362                                return new CKEDITOR.dom.node( next ).getNext();
     363                        else
     364                                return next ? new CKEDITOR.dom.node( next ) : null;
    364365                },
    365366
    366367                /**
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy