Ticket #3190: 3190_6.patch

File 3190_6.patch, 7.0 KB (added by Garry Yao, 11 years ago)
  • _source/plugins/wysiwygarea/plugin.js

     
    114114                                this.getSelection().lock();
    115115                }
    116116        }
    117 
     117       
     118        /**
     119         *  Auto-fixing block-less content by wrapping paragraph, prevent
     120         *  non-exitable-block by padding extra br.
     121         */
     122        function onSelectionChangeFixBody( evt )
     123        {
     124                var editor = evt.editor,
     125                        path = evt.data.path,
     126                        blockLimit = path.blockLimit,
     127                        body = editor.document.getBody(),
     128                        enterMode = editor.config.enterMode;
     129
     130                // When enterMode set to block, we'll establing new paragraph if the
     131                // current range is block-less within body.
     132                if ( enterMode != CKEDITOR.ENTER_BR
     133                         && blockLimit.getName() == 'body'
     134                         && !path.block )
     135                {
     136                        var range = evt.data.selection.getRanges()[0],
     137                                fixedBlock = range.fixBlock( true,
     138                                editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'  );
     139
     140                        // For IE, we'll be removing any bogus br ( introduce by fixing body )
     141                        // right now to prevent it introducing visual line break.
     142                        if ( CKEDITOR.env.ie )
     143                        {
     144                                var children = fixedBlock.getChildren(), child;
     145                                for ( var i = 0 ; i <  children.count() ; i++ ) {
     146                                        if ( ( child = children.getItem( i ) ) && child.is
     147                                                        && child.is( 'br' ) && child.hasAttribute( '_cke_bogus' ) )
     148                                                child.remove();
     149                                }
     150                        }
     151
     152                        // It's been guaranteed we're always at the beginning of text in this case.
     153                        range.moveToElementEditStart( fixedBlock );
     154                        range.select();
     155                }
     156
     157                // Inserting the padding-br before body if it's preceded by an
     158                // unexitable block.
     159                var lastNode = body.getLast( true );
     160                if ( lastNode.getName && ( lastNode.getName() in CKEDITOR.dtd.$nonExitable ) )
     161                {
     162                        var paddingBlock = editor.document.createElement(
     163                                        ( CKEDITOR.env.ie && enterMode != CKEDITOR.ENTER_BR ) ?
     164                                                '<br _cke_bogus="true" />' : 'br' );
     165                        body.append( paddingBlock );
     166                }
     167        }
     168
    118169        CKEDITOR.plugins.add( 'wysiwygarea',
    119170        {
    120171                requires : [ 'editingblock' ],
     
    449500
    450501                                        editor.on( 'insertHtml', onInsertHtml, null, null, 20 );
    451502                                        editor.on( 'insertElement', onInsertElement, null, null, 20 );
     503                                        // Auto fixing on some document structure weakness to enhance usabilities. (#3190 and #3189)
     504                                        editor.on( 'selectionChange', onSelectionChangeFixBody, null, null, 1 );
    452505                                });
    453506                }
    454507        });
  • _source/core/dom/element.js

     
    643643                        return $ ? new CKEDITOR.dom.node( $ ) : null;
    644644                },
    645645
    646                 getLast : function()
     646                /**
     647                 * @param ignoreEmpty Skip empty text nodes.
     648                 */
     649                getLast : function( ignoreEmpty )
    647650                {
    648651                        var $ = this.$.lastChild;
    649                         return $ ? new CKEDITOR.dom.node( $ ) : null;
     652                        if ( ignoreEmpty && $ && ( $.nodeType == CKEDITOR.NODE_TEXT )
     653                                        && !CKEDITOR.tools.trim( $.nodeValue ) )
     654                                return new CKEDITOR.dom.node( $ ).getPrevious( true );
     655                        else
     656                                return $ ? new CKEDITOR.dom.node( $ ) : null;
    650657                },
    651658
    652659                getStyle : function( name )
  • _source/core/dom/node.js

     
    259259                        return -1;
    260260                },
    261261
    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 
    272262                getNextSourceNode : function( startFromSibling, nodeType, guard )
    273263                {
    274264                        // If "guard" is a node, transform it in a function.
     
    360350                        return node;
    361351                },
    362352
    363                 getPrevious : function()
     353                getPrevious : function( ignoreEmpty )
    364354                {
    365355                        var previous = this.$.previousSibling;
    366                         return previous ? new CKEDITOR.dom.node( previous ) : null;
     356                        if ( ignoreEmpty && previous && ( previous.nodeType == CKEDITOR.NODE_TEXT )
     357                                        && !CKEDITOR.tools.trim( previous.nodeValue ) )
     358                                return new CKEDITOR.dom.node( previous ).getPrevious();
     359                        else
     360                                return previous ? new CKEDITOR.dom.node( previous ) : null;
    367361                },
    368362
    369363                /**
    370364                 * Gets the node that follows this element in its parent's child list.
     365                 * @param {Boolean} ignoreEmpty Whether should ignore empty text nodes.
    371366                 * @returns {CKEDITOR.dom.node} The next node or null if not
    372367                 *              available.
    373368                 * @example
     
    375370                 * var first = <b>element.getFirst().getNext()</b>;
    376371                 * alert( first.getName() );  // "i"
    377372                 */
    378                 getNext : function()
     373                getNext : function( ignoreEmpty )
    379374                {
    380                         var $ = this.$.nextSibling;
    381                         return $ ? new CKEDITOR.dom.node( $ ) : null;
     375                        var next = this.$.nextSibling;
     376                        if ( ignoreEmpty && next && ( next.nodeType == CKEDITOR.NODE_TEXT )
     377                                  && !CKEDITOR.tools.trim( next.nodeValue ) )
     378                                return new CKEDITOR.dom.node( next ).getNext();
     379                        else
     380                                return next ? new CKEDITOR.dom.node( next ) : null;
    382381                },
    383382
    384383                /**
  • _source/core/dtd.js

     
    113113                 */
    114114                $tableContent : {caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1},
    115115
     116            /**
     117             * List of elements in which has no way to move editing focus outside.
     118             */
     119            $nonExitable :{table:1,pre:1},
     120
    116121        col : {},
    117122        tr : {td:1,th:1},
    118123        img : {},
  • _source/core/dom/range.js

     
    3131        // V2
    3232        var execContentsAction = function( range, action, docFrag )
    3333        {
     34                range.optimizeBookmark();
     35               
    3436                var startNode   = range.startContainer;
    3537                var endNode             = range.endContainer;
    3638
     
    653655                        }
    654656                },
    655657
     658                /**
     659                 * Move the range out of bookmark nodes if they're been the container.
     660                 */
     661                optimizeBookmark: function()
     662                {
     663                        var startNode = this.startContainer,
     664                                endNode = this.endContainer;
     665
     666                        if ( startNode.is && startNode.is( 'span' )
     667                                && startNode.hasAttribute( '_fck_bookmark' ) )
     668                                this.setStartAt( startNode, CKEDITOR.POSITION_BEFORE_START );
     669                        if ( endNode && endNode.is && endNode.is( 'span' )
     670                                && endNode.hasAttribute( '_fck_bookmark' ) )
     671                                this.setEndAt( endNode,  CKEDITOR.POSITION_AFTER_END );
     672                },
     673
    656674                trim : function( ignoreStart, ignoreEnd )
    657675                {
    658676                        var startContainer = this.startContainer;
     
    11361154                 */
    11371155                insertNode : function( node )
    11381156                {
     1157                        this.optimizeBookmark();
    11391158                        this.trim( false, true );
    11401159
    11411160                        var startContainer = this.startContainer;
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy