Ticket #6485: 6485_5.patch

File 6485_5.patch, 10.3 KB (added by Garry Yao, 14 years ago)
  • _source/plugins/bidi/plugin.js

     
    1 /*
     1/*
    22Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
    33For licensing, see LICENSE.html or http://ckeditor.com/license
    44*/
    55
    66(function()
    77{
    8         var guardElements = { table:1, ul:1, ol:1, blockquote:1, div:1 },
     8        var guardElements = { table:1, tbody: 1, ul:1, ol:1, blockquote:1, div:1, tr: 1 },
    99                directSelectionGuardElements = {},
    1010                // All guard elements which can have a direction applied on them.
    1111                allGuardElements = {};
     
    130130                return null;
    131131        }
    132132
    133         function getFullySelected( selection, elements )
     133        function getFullySelected( range, elements )
    134134        {
    135                 var ancestor = selection.getCommonAncestor();
    136                 if ( ancestor.type != CKEDITOR.NODE_ELEMENT )
    137                         return;
     135                var ancestor = range.getCommonAncestor( false, true );
    138136
    139                 var ranges = selection.getRanges();
    140 
    141                 // Join multiple ranges.
    142                 var range = new CKEDITOR.dom.range( selection.document );
    143                 range.setStart( ranges[ 0 ].startContainer, ranges[ 0 ].startOffset );
    144                 range.setEnd( ranges[ ranges.length - 1 ].endContainer, ranges[ ranges.length - 1 ].endOffset );
    145 
    146137                range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
    147138
    148139                if ( range.checkBoundaryOfElement( ancestor, CKEDITOR.START )
    149140                                && range.checkBoundaryOfElement( ancestor, CKEDITOR.END ) )
    150141                {
    151                         while ( ancestor.type == CKEDITOR.NODE_ELEMENT
    152                                         && !( ancestor.getName() in elements )
    153                                         && ancestor.getParent().getChildCount() == 1
     142                        var parent;
     143                        while ( ancestor && ancestor.type == CKEDITOR.NODE_ELEMENT
     144                                        && ( parent = ancestor.getParent() )
     145                                        && parent.getChildCount() == 1
     146                                        && ( !( ancestor.getName() in elements ) || ( parent.getName() in elements ) )
    154147                                        )
    155                                 ancestor = ancestor.getParent();
     148                                ancestor = parent;
    156149
    157150                        return ancestor.type == CKEDITOR.NODE_ELEMENT
    158151                                        && ( ancestor.getName() in elements )
     
    171164                        if ( ranges && ranges.length )
    172165                        {
    173166                                var database = {};
    174                                 // Apply do directly selected elements from guardElements.
    175                                 var selectedElement = ranges[ 0 ].getEnclosedNode();
     167
     168                                // Creates bookmarks for selection, as we may split some blocks.
     169                                var bookmarks = selection.createBookmarks();
     170
     171                                var rangeIterator = ranges.createIterator(),
     172                                        range,
     173                                        i = 0;
     174
     175                                while ( ( range = rangeIterator.getNextRange( 1 ) ) )
     176                                {
     177                                        // Apply do directly selected elements from guardElements.
     178                                        var selectedElement = range.getEnclosedNode();
    176179
    177                                 // If this is not our element of interest, apply to fully selected elements from guardElements.
    178                                 if ( !selectedElement || selectedElement
    179                                                 && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements )
    180                                         )
    181                                         selectedElement = getFullySelected( selection, guardElements );
     180                                        // If this is not our element of interest, apply to fully selected elements from guardElements.
     181                                        if ( !selectedElement || selectedElement
     182                                                        && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements )
     183                                                )
     184                                                selectedElement = getFullySelected( range, guardElements );
    182185
    183                                 if ( selectedElement && !selectedElement.isReadOnly() )
    184                                         switchDir( selectedElement, dir, editor, database );
    185                                
    186                                 // Creates bookmarks for selection, as we may split some blocks.
    187                                 var bookmarks = selection.createBookmarks();
    188 
    189                                 var iterator,
    190                                         block;
     186                                        if ( selectedElement && !selectedElement.isReadOnly() )
     187                                                switchDir( selectedElement, dir, editor, database );
     188
     189                                        var iterator,
     190                                                block;
    191191
    192                                 for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
    193                                 {
    194                                         // Array of elements processed as guardElements.
    195                                         var processedElements = [];
    196192                                        // Walker searching for guardElements.
    197                                         var walker = new CKEDITOR.dom.walker( ranges[ i ] );
     193                                        var walker = new CKEDITOR.dom.walker( range );
     194
     195                                        var start = bookmarks[ i ].startNode,
     196                                                end = bookmarks[ i++ ].endNode;
     197
    198198                                        walker.evaluator = function( node )
    199199                                        {
    200                                                 return node.type == CKEDITOR.NODE_ELEMENT
    201                                                         && node.getName() in guardElements
    202                                                         && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div'
    203                                                                 && node.getParent().type == CKEDITOR.NODE_ELEMENT
    204                                                                 && node.getParent().getName() == 'blockquote'
    205                                                         );
     200                                                return !! ( node.type == CKEDITOR.NODE_ELEMENT
     201                                                                && node.getName() in guardElements
     202                                                                && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div'
     203                                                                        && node.getParent().type == CKEDITOR.NODE_ELEMENT
     204                                                                        && node.getParent().getName() == 'blockquote' )
     205                                                                // Element must be fully included in the range as well. (#6485).
     206                                                                && node.getPosition( start ) & CKEDITOR.POSITION_FOLLOWING
     207                                                                && ( ( node.getPosition( end ) & CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_CONTAINS ) == CKEDITOR.POSITION_PRECEDING ) );
    206208                                        };
    207209
    208210                                        while ( ( block = walker.next() ) )
    209211                                                switchDir( block, dir, editor, database );
    210212
    211                                         iterator = ranges[ i ].createIterator();
     213                                        iterator = range.createIterator();
    212214                                        iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
    213215
    214216                                        while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )
    215217                                                !block.isReadOnly() && switchDir( block, dir, editor, database );
     218                                }
    216219
    217                                         CKEDITOR.dom.element.clearAllMarkers( database );
     220                                CKEDITOR.dom.element.clearAllMarkers( database );
    218221
    219                                         editor.forceNextSelectionCheck();
    220                                         // Restore selection position.
    221                                         selection.selectBookmarks( bookmarks );
    222                                 }
     222                                editor.forceNextSelectionCheck();
     223                                // Restore selection position.
     224                                selection.selectBookmarks( bookmarks );
    223225
    224226                                editor.focus();
    225227                        }
  • _source/core/dom/walker.js

     
    385385                                                && isBookmarkNode( parent ) );
    386386                        // Is bookmark node?
    387387                        isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node );
    388                         return isReject ^ isBookmark;
     388                        return !! ( isReject ^ isBookmark );
    389389                };
    390390        };
    391391
     
    399399                {
    400400                        var isWhitespace = node && ( node.type == CKEDITOR.NODE_TEXT )
    401401                                                        && !CKEDITOR.tools.trim( node.getText() );
    402                         return isReject ^ isWhitespace;
     402                        return !! ( isReject ^ isWhitespace );
    403403                };
    404404        };
    405405
     
    418418                        // 'offsetHeight' instead of 'offsetWidth' for properly excluding
    419419                        // all sorts of empty paragraph, e.g. <br />.
    420420                        var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight;
    421                         return isReject ^ isInvisible;
     421                        return !! ( isReject ^ isInvisible );
    422422                };
    423423        };
    424424
  • _source/plugins/domiterator/plugin.js

     
    6565                                                           CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
    6666
    6767                                var walker = new CKEDITOR.dom.walker( range ),
    68                                         ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
     68                                        ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( false, true );
    6969                                // Avoid anchor inside bookmark inner text.
    7070                                walker.evaluator = ignoreBookmarkTextEvaluator;
    7171                                this._.nextNode = walker.next();
  • _source/core/dom/rangelist.js

     
    3939                        createIterator : function()
    4040                        {
    4141                                var rangeList = this,
    42                                         bookmarks = [],
     42                                        bookmark = CKEDITOR.dom.walker.bookmark(),
     43                                        emptySpaces = CKEDITOR.dom.walker.whitespaces(),
     44                                        guard = function( node ) { return ! ( node.is && node.is( 'tr' ) ); },
     45                                                bookmarks = [],
    4346                                        current;
    4447
    4548                                /**
     
    4952
    5053                                        /**
    5154                                         * Retrieves the next range in the list.
     55                                         * @param {Boolean} mergeConsequent Whether join two adjacent ranges into single, e.g. consequent table cells.
    5256                                         */
    53                                         getNextRange : function()
     57                                        getNextRange : function( mergeConsequent )
    5458                                        {
    5559                                                current = current == undefined ? 0 : current + 1;
    5660
     
    6569                                                        if ( !current )
    6670                                                        {
    6771                                                                // Make sure bookmark correctness by reverse processing.
    68                                                                 for ( var i = rangeList.length - 1; i > 0; i-- )
     72                                                                for ( var i = rangeList.length - 1; i >= 0; i-- )
    6973                                                                        bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
    7074                                                        }
    71                                                         else
    72                                                                 range.moveToBookmark( bookmarks.shift() );
    73                                                 }
     75
     76                                                        if ( mergeConsequent )
     77                                                        {
     78                                                                // Figure out how many ranges should be merged.
     79                                                                var mergeCount = 0;
     80                                                                while ( rangeList[ current + mergeCount + 1 ] )
     81                                                                {
     82                                                                        var doc = range.document,
     83                                                                                found = 0,
     84                                                                                left =  doc.getById( bookmarks[ mergeCount ].endNode ),
     85                                                                                right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
     86                                                                                next;
     87
     88                                                                        // Check subsequent range.
     89                                                                        while ( 1 )
     90                                                                        {
     91                                                                                next = left.getNextSourceNode( false );
     92                                                                                if ( !right.equals( next ) )
     93                                                                                {
     94                                                                                        // This could be yet another bookmark or
     95                                                                                        // walking across block boundaries.
     96                                                                                        if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) )
     97                                                                                        {
     98                                                                                                left = next;
     99                                                                                                continue;
     100                                                                                        }
     101                                                                                }
     102                                                                                else
     103                                                                                        found = 1;
     104
     105                                                                                break;
     106                                                                        }
     107
     108                                                                        if ( !found )
     109                                                                                break;
     110
     111                                                                        mergeCount++;
     112                                                                }
     113                                                        }
     114
     115                                                        range.moveToBookmark( bookmarks.shift() );
     116                                                       
     117                                                        // Merge ranges finally after moving to bookmarks.
     118                                                        while( mergeCount-- )
     119                                                        {
     120                                                                var next = rangeList[ ++current ];
     121                                                                next.moveToBookmark( bookmarks.shift() );
     122                                                                range.setEnd( next.endContainer, next.endOffset );
     123                                                        }
     124                                                }
    74125
    75126                                                return range;
    76127                                        }
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy