Ticket #6642: 6642.patch

File 6642.patch, 5.2 KB (added by Garry Yao, 8 years ago)
  • _source/core/dom/element.js

     
    272272                 */
    273273                breakParent : function( parent )
    274274                {
    275                         var range = new CKEDITOR.dom.range( this.getDocument() );
     275                        var range = new CKEDITOR.dom.range( this.getDocument() ),
     276                                testRange = range.clone();
    276277
    277                         // We'll be extracting part of this element, so let's use our
    278                         // range to get the correct piece.
    279                         range.setStartAfter( this );
    280                         range.setEndAfter( parent );
    281 
    282                         // Extract it.
    283                         var docFrag = range.extractContents();
     278                        testRange.setStartBefore( this );
     279                        testRange.setEndAfter( this );
     280
     281                        var atStart = testRange.checkBoundaryOfElement( parent, CKEDITOR.START ),
     282                                atEnd = testRange.checkBoundaryOfElement( parent, CKEDITOR.END );
     283
     284                        if ( atStart || atEnd )
     285                                this[ atStart ? 'insertBefore' : 'insertAfter' ]( parent );
     286                        else
     287                        {
     288                                // We'll be extracting part of this element, so let's use our
     289                                // range to get the correct piece.
     290                                range.setStartAfter( this );
     291                                range.setEndAfter( parent );
     292                                // Extract it.
     293                                var docFrag = range.extractContents();
    284294
    285                         // Move the element outside the broken element.
    286                         range.insertNode( this.remove() );
     295                                // Move the element outside the broken element.
     296                                range.insertNode( this.remove() );
    287297
    288                         // Re-insert the extracted piece after the element.
    289                         docFrag.insertAfterNode( this );
     298                                // Re-insert the extracted piece after the element.
     299                                docFrag.insertAfterNode( this );
     300                        }
    290301                },
    291302
    292303                contains :
  • _source/plugins/wysiwygarea/plugin.js

     
    4646                };
    4747        }
    4848
     49        function isDtdValid( element )
     50        {
     51                var parent = element.getParent().getName();
     52                var dtd = CKEDITOR.dtd[ parent ];
     53                return !dtd || parent == 'body' || element.getName() in dtd;
     54        }
     55
     56        function postFixPaste( root )
     57        {
     58                var doc = root.getDocument();
     59                var sel = doc.getSelection();
     60                var bms = sel.createBookmarks();
     61                var range = new CKEDITOR.dom.range();
     62                range.selectNodeContents( root );
     63                var walker = new CKEDITOR.dom.walker( range );
     64
     65                // Collect invalid structured and wrongly styled (Webkit only) elements for later fixing.
     66                var next, invalids = [], extras = [], type = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT );
     67                walker.evaluator = type;
     68                while( next = walker.next() )
     69                {
     70                        if ( !isDtdValid( next ) )
     71                                invalids.push( next );
     72
     73                        if ( next.is( 'span' ) && next.hasClass( 'Apple-style-span' ) )
     74                                extras.push( next );
     75                }
     76
     77                for ( var i = 0, toFix; toFix = invalids[ i ], i < invalids.length; i++ )
     78                {
     79                        // Correct them by splitting upward.
     80                        do
     81                                toFix.breakParent( toFix.getParent() );
     82                        while( !isDtdValid( toFix ) )
     83                }
     84
     85                for ( var j = 0, extra; extra = extras[ j ], j < extras.length; j++ )
     86                        extra.remove( 1 );
     87
     88                sel.selectBookmarks( bms );
     89        }
     90
    4991        function doInsertHtml( data )
    5092        {
    5193                if ( this.dataProcessor )
     
    5496                if ( !data )
    5597                        return;
    5698
     99                data = '<span id="cke_paste_marker"></span>' + data;
     100
    57101                // HTML insertion only considers the first range.
    58102                var selection = this.getSelection(),
    59103                        range = selection.getRanges()[ 0 ];
     
    61105                if ( range.checkReadOnly() )
    62106                        return;
    63107
    64                 // Opera: force block splitting when pasted content contains block. (#7801)
    65                 if ( CKEDITOR.env.opera )
    66                 {
    67                         var path = new CKEDITOR.dom.elementPath( range.startContainer );
    68                         if ( path.block )
    69                         {
    70                                 var nodes = CKEDITOR.htmlParser.fragment.fromHtml( data, false ).children;
    71                                 for ( var i = 0, count = nodes.length; i < count; i++ )
    72                                 {
    73                                         if ( nodes[ i ]._.isBlockLike )
    74                                         {
    75                                                 range.splitBlock( this.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
    76                                                 range.insertNode( range.document.createText( '' ) );
    77                                                 range.select();
    78                                                 break;
    79                                         }
    80                                 }
    81                         }
    82                 }
    83 
    84                 if ( CKEDITOR.env.ie )
    85                 {
    86                         var selIsLocked = selection.isLocked;
     108                var selIsLocked = selection.isLocked;
    87109
    88                         if ( selIsLocked )
    89                                 selection.unlock();
     110                selIsLocked && selection.unlock();
    90111
     112                if ( CKEDITOR.env.ie )
     113                {
    91114                        var $sel = selection.getNative();
    92115
    93116                        // Delete control selections to avoid IE bugs on pasteHTML.
     
    117140                                $sel.createRange().pasteHTML( data );
    118141                        }
    119142                        catch (e) {}
    120 
    121                         if ( selIsLocked )
    122                                 this.getSelection().lock();
    123143                }
    124144                else
    125145                        this.document.$.execCommand( 'inserthtml', false, data );
    126146
     147                // Figure out where the pasted contents start.
     148                var marker = this.document.getById( 'cke_paste_marker' );
     149                var pastedStart = marker.getNextSourceNode( 1 );
     150                marker.remove( 1 );
     151                var path = new CKEDITOR.dom.elementPath( pastedStart );
     152
     153                // Fix run at the path root.
     154                var root = path.elements[ path.elements.length - 2 ];
     155                root && postFixPaste( root );
     156
     157                selIsLocked && this.getSelection().lock();
     158
    127159                // Webkit does not scroll to the cursor position after pasting (#5558)
    128160                if ( CKEDITOR.env.webkit )
    129161                {
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy