Ticket #5479: 5479_19.patch

File 5479_19.patch, 12.4 KB (added by Garry Yao, 10 years ago)
  • _source/plugins/selection/plugin.js

     
    9999                canUndo : false
    100100        };
    101101
    102         function createFillingChar( doc )
     102        function createFillingChar( range )
    103103        {
     104                var doc = range.document;
    104105                removeFillingChar( doc );
    105106
     107                // Place a zero-width space so browser will be able to
     108                // blink the cursor normally (#1272).
    106109                var fillingChar = doc.createText( '\u200B' );
    107110                doc.setCustomData( 'cke-fillingChar', fillingChar );
    108111
    109                 return fillingChar;
    110         }
     112                range.insertNode( fillingChar );
     113
     114                var next = fillingChar.getNext();
     115
     116                // If the filling char is followed by a <br>, without
     117                // having something before it, it'll not blink.
     118                // Let's remove it in this case.
     119                if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' )
     120                {
     121                        removeFillingChar( this.document );
     122                        range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
     123                }
     124                else
     125                        range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
     126        }
    111127
    112128        function getFillingChar( doc )
    113129        {
    114                 return doc && doc.getCustomData( 'cke-fillingChar' );
    115         }
     130                var filling = doc && doc.getCustomData( 'cke-fillingChar' );
     131                if ( filling )
     132                {
     133                        // Test if the filling node is still inside document,
     134                        // unwise clean up everything.
     135                        try
     136                        {
     137                                if ( !filling.getAscendant( 'html' ) )
     138                                        throw '';
     139                        }
     140                        catch( er )
     141                        {
     142                                doc.removeCustomData( 'cke-fillingChar' );
     143                                doc.removeCustomData( 'cke-fillingChar-ready');
     144                                filling = null;
     145                        }
     146                }
     147                return filling;
     148        }
    116149
    117150        // Checks if a filling char has been used, eventualy removing it (#1272).
    118151        function checkFillingChar( doc )
     
    122155                {
    123156                        // Use this flag to avoid removing the filling char right after
    124157                        // creating it.
    125                         if ( fillingChar.getCustomData( 'ready' ) )
     158                        if ( doc.getCustomData( 'cke-fillingChar-ready' ) )
    126159                                removeFillingChar( doc );
    127160                        else
    128                                 fillingChar.setCustomData( 'ready', 1 );
     161                                doc.setCustomData( 'cke-fillingChar-ready', 1 );
    129162                }
    130163        }
    131164
    132165        function removeFillingChar( doc )
    133166        {
    134                 var fillingChar = doc && doc.removeCustomData( 'cke-fillingChar' );
     167                var fillingChar  = getFillingChar( doc );
    135168                if ( fillingChar )
    136169                {
    137170                        // We can't simply remove the filling node because the user
     
    139172                        // invisible char from it.
    140173                        fillingChar.setText( fillingChar.getText().replace( /\u200B/g, '' ) );
    141174                        fillingChar = 0;
     175                        doc.removeCustomData( 'cke-fillingChar' );
     176                        doc.removeCustomData( 'cke-fillingChar-ready');
    142177                }
    143178        }
    144179
     
    148183                {
    149184                        // On WebKit only, we need a special "filling" char on some situations
    150185                        // (#1272). Here we set the events that should invalidate that char.
    151                         if ( CKEDITOR.env.webkit )
    152                         {
    153                                 editor.on( 'selectionChange', function() { checkFillingChar( editor.document ); } );
    154                                 editor.on( 'beforeSetMode', function() { removeFillingChar( editor.document ); } );
    155                                 editor.on( 'key', function( e )
    156                                         {
    157                                                 // Remove the filling char before some keys get
    158                                                 // executed, so they'll not get blocked by it.
    159                                                 switch ( e.data.keyCode )
    160                                                 {
    161                                                         case 37 :       // LEFT-ARROW
    162                                                         case 39 :       // RIGHT-ARROW
    163                                                         case 8 :        // BACKSPACE
    164                                                                 removeFillingChar( editor.document );
    165                                                 }
    166                                         });
     186                        editor.on( 'selectionChange', function() { checkFillingChar( editor.document ); } );
     187                        editor.on( 'beforeSetMode', function() { removeFillingChar( editor.document ); } );
     188                        editor.on( 'key', function( e )
     189                        {
     190                                // Remove the filling char before some keys get
     191                                // executed, so they'll not get blocked by it.
     192                                switch ( e.data.keyCode )
     193                                {
     194                                        case 37 :       // LEFT-ARROW
     195                                        case 39 :       // RIGHT-ARROW
     196                                        case 8 :        // BACKSPACE
     197                                                removeFillingChar( editor.document );
     198                                }
     199                        } );
    167200
    168                                 var fillingCharBefore;
    169                                 function beforeData()
    170                                 {
    171                                         var fillingChar = getFillingChar( editor.document );
    172                                         fillingCharBefore = fillingChar && fillingChar.getText();
    173                                         fillingCharBefore && fillingChar.setText( fillingCharBefore.replace( /\u200B/g, '' ) );
     201                        var fillingCharBefore;
     202                        function beforeData()
     203                        {
     204
     205                                var fillingChar = getFillingChar( editor.document );
     206                                if ( fillingChar )
     207                                {
     208                                        fillingCharBefore = fillingChar.getText();
     209                                        fillingChar.setText( fillingCharBefore.replace( /\u200B/g, '' ) );
    174210                                }
    175                                 function afterData()
    176                                 {
    177                                                 var fillingChar = getFillingChar( editor.document );
    178                                                 fillingChar && fillingChar.setText( fillingCharBefore );
    179                                 }
    180                                 editor.on( 'beforeUndoImage', beforeData );
    181                                 editor.on( 'afterUndoImage', afterData );
    182                                 editor.on( 'beforeGetData', beforeData, null, null, 0 );
    183                                 editor.on( 'getData', afterData );
    184                         }
     211                        }
     212                        function afterData()
     213                        {
     214                                var fillingChar = getFillingChar( editor.document );
     215                                fillingChar && fillingChar.setText( fillingCharBefore );
     216                        }
     217                        editor.on( 'beforeUndoImage', beforeData );
     218                        editor.on( 'afterUndoImage', afterData );
     219                        editor.on( 'beforeGetData', beforeData, null, null, 0 );
     220                        editor.on( 'getData', afterData );
    185221
    186222                        editor.on( 'contentDom', function()
    187223                                {
     
    11941230                 * by clearing up the original selection.
    11951231                 * @param {CKEDITOR.dom.range} ranges
    11961232                 */
    1197                 selectRanges : function( ranges )
     1233                selectRanges : function( ranges, forceExpand )
    11981234                {
    11991235                        if ( this.isLocked )
    12001236                        {
     
    12171253                                }
    12181254
    12191255                                if ( ranges[ 0 ] )
    1220                                         ranges[ 0 ].select();
     1256                                        ranges[ 0 ].select( forceExpand );
    12211257
    12221258                                this.reset();
    12231259                        }
     
    12331269                                {
    12341270                                        sel.removeAllRanges();
    12351271                                        // Remove any existing filling char first.
    1236                                         CKEDITOR.env.webkit && removeFillingChar( this.document );
     1272                                        removeFillingChar( this.document );
    12371273                                }
    12381274
    12391275                                for ( var i = 0 ; i < ranges.length ; i++ )
     
    12841320                                                startContainer.appendText( '' );
    12851321                                        }
    12861322
    1287                                         if ( range.collapsed && CKEDITOR.env.webkit )
    1288                                         {
    1289                                                 // Append a zero-width space so WebKit will not try to
    1290                                                 // move the selection by itself (#1272).
    1291                                                 var fillingChar = createFillingChar( this.document );
    1292                                                 range.insertNode( fillingChar ) ;
     1323                                        if ( range.collapsed && ( forceExpand || CKEDITOR.env.webkit ) )
     1324                                                createFillingChar( range );
    12931325
    1294                                                 var next = fillingChar.getNext();
    1295 
    1296                                                 // If the filling char is followed by a <br>, whithout
    1297                                                 // having something before it, it'll not blink.
    1298                                                 // Let's remove it in this case.
    1299                                                 if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' )
    1300                                                 {
    1301                                                         removeFillingChar( this.document );
    1302                                                         range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
    1303                                                 }
    1304                                                 else
    1305                                                         range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
    1306                                         }
    1307 
    13081326                                        nativeRange.setStart( range.startContainer.$, range.startOffset );
    13091327
    13101328                                        try
     
    13941412                        start.scrollIntoView();
    13951413                }
    13961414        };
    1397 })();
    13981415
    1399 ( function()
    1400 {
    14011416        var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),
    14021417                        fillerTextRegex = /\ufeff|\u00a0/,
    14031418                        nonCells = { table:1,tbody:1,tr:1 };
     
    14111426                                var isStartMarkerAlone;
    14121427                                var dummySpan;
    14131428
     1429                                 collapsed && forceExpand && createFillingChar( this );
     1430
    14141431                                // IE doesn't support selecting the entire table row/cell, move the selection into cells, e.g.
    14151432                                // <table><tbody><tr>[<td>cell</b></td>... => <table><tbody><tr><td>[cell</td>...
    14161433                                if ( this.startContainer.type == CKEDITOR.NODE_ELEMENT && this.startContainer.getName() in nonCells
     
    15081525                                this.document.fire( 'selectionchange' );
    15091526                        }
    15101527                :
    1511                         function()
     1528                        function( forceExpand )
    15121529                        {
    1513                                 this.document.getSelection().selectRanges( [ this ] );
     1530                                this.document.getSelection().selectRanges( [ this ], forceExpand );
    15141531                        };
    1515 } )();
     1532
     1533})();
  • _source/plugins/wysiwygarea/plugin.js

     
    1111(function()
    1212{
    1313        // List of elements in which has no way to move editing focus outside.
    14         var nonExitableElementNames = { table:1,pre:1 };
     14        var nonExitableElementNames = { table:1,pre:1, ul:1,ol:1,dl:1,blockquote:1,form:1 };
    1515
    1616        // Matching an empty paragraph at the end of document.
    1717        var emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;
     
    430430                                editor.selectionChange();
    431431                        }
    432432                }
    433 
    434                 // All browsers are incapable to moving cursor out of certain non-exitable
    435                 // blocks (e.g. table, list, pre) at the end of document, make this happen by
    436                 // place a bogus node there, which would be later removed by dataprocessor.
    437                 var walkerRange = new CKEDITOR.dom.range( editor.document ),
    438                         walker = new CKEDITOR.dom.walker( walkerRange );
    439                 walkerRange.selectNodeContents( body );
    440                 walker.evaluator = function( node )
    441                 {
    442                         return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames );
    443                 };
    444                 walker.guard = function( node, isMoveout )
    445                 {
    446                         return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout );
    447                 };
    448 
    449                 if ( walker.previous() )
    450                 {
    451                         editor.fire( 'updateSnapshot' );
    452                         restoreDirty( editor );
    453                         CKEDITOR.env.ie && restoreSelection( selection );
    454 
    455                         var paddingBlock;
    456                         if ( enterMode != CKEDITOR.ENTER_BR )
    457                                 paddingBlock = body.append( new CKEDITOR.dom.element( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) );
    458                         else
    459                                 paddingBlock = body;
    460 
    461                         if ( !CKEDITOR.env.ie )
    462                                 paddingBlock.appendBogus();
    463                 }
    464         }
     433        }
    465434
    466435        CKEDITOR.plugins.add( 'wysiwygarea',
    467436        {
     
    12161185                                }
    12171186                        });
    12181187
    1219                 }
    1220         });
     1188                        // All browsers are incapable to moving cursor out of certain non-exitable
     1189                        // blocks (e.g. table, list, pre) at the end of document, enable this when
     1190                        // user clicks on the padding bottom area of body.
     1191                        editor.addCss( 'body{padding-bottom: 20px;}');
     1192                        editor.on( 'contentDom', function ()
     1193                        {
     1194                                var doc = editor.document,
     1195                                        body = doc.getBody();
     1196
     1197                                body.on( 'click', function ( evt )
     1198                                {
     1199                                        evt = evt.data;
     1200
     1201                                        // All browsers are incapable to moving cursor out of certain non-exitable
     1202                                        // blocks (e.g. table, list, pre) at the end of document, make this happen by
     1203                                        // place a bogus node there, which would be later removed by dataprocessor.
     1204                                        if ( ( evt.$.offsetY || evt.$.layerY || evt.$.y  ) > body.$.clientHeight - parseInt( body.getComputedStyle( 'padding-bottom' ) ) )
     1205                                        {
     1206                                                var walkerRange = new CKEDITOR.dom.range( editor.document ),
     1207                                                                walker = new CKEDITOR.dom.walker( walkerRange );
     1208                                                walkerRange.selectNodeContents( body );
     1209                                                walker.evaluator = function( node )
     1210                                                {
     1211                                                        return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames );
     1212                                                };
     1213                                                walker.guard = function( node, isMoveout )
     1214                                                {
     1215                                                        return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout );
     1216                                                };
     1217
     1218                                                if ( walker.previous() )
     1219                                                {
     1220                                                        var range = new CKEDITOR.dom.range( doc );
     1221                                                        range.moveToPosition( body, CKEDITOR.POSITION_BEFORE_END );
     1222                                                        range.select( 1 );
     1223                                                        evt.preventDefault();
     1224                                                }
     1225                                        }
     1226                                });
     1227                        });
     1228                }
     1229        });
    12211230
    12221231        // Fixing Firefox 'Back-Forward Cache' break design mode. (#4514)
    12231232        if ( CKEDITOR.env.gecko )
  • _source/plugins/domiterator/plugin.js

     
    108108                                {
    109109                                        this._.lastNode = this._.docEndMarker = range.document.createText( '' );
    110110                                        this._.lastNode.insertAfter( lastNode );
     111                                        // If the current last is a bookmark, to make sure it will be included in the range,
     112                                        // we need another marker as "getNextSourceNode" will always skip it.
     113                                        if ( !bookmarkGuard( lastNode) )
     114                                                this._.lastNode.clone().insertAfter( lastNode );
    111115                                }
    112116
    113117                                // Let's reuse this variable.
© 2003 – 2021 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy