Ticket #3304: 3304_3.patch

File 3304_3.patch, 11.9 KB (added by Garry Yao, 11 years ago)
  • _source/plugins/find/dialogs/find.js

     
    55
    66(function()
    77{
    8         // Element tag names which prevent characters counting.
    9         var characterBoundaryElementsEnum =
     8        function guardDomWalkerNonEmptyTextNode( node )
    109        {
    11                 address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
    12                 h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1
    13         };
     10                if ( node.type == CKEDITOR.NODE_TEXT && node.$.length > 0 )
     11                        return true;
     12                else
     13                        return false;
     14        }
    1415
    15         var guardDomWalkerNonEmptyTextNode = function( evt )
     16        /**
     17         * Elements which break characters been considered as sequence.
     18        */
     19        function checkCharactersBoundary ( node )
    1620        {
    17                 if ( evt.data.to && evt.data.to.type == CKEDITOR.NODE_TEXT
    18                         && evt.data.to.$.length > 0 )
    19                         this.stop();
    20                 CKEDITOR.dom.domWalker.blockBoundary( { br : 1 } ).call( this, evt );
    21         };
    22 
     21                var dtd = CKEDITOR.dtd;
     22                return node.isBlockBoundary(
     23                        CKEDITOR.tools.extend( {}, dtd.$empty, dtd.$nonEditable ) );
     24        }
    2325
    2426        /**
    2527         * Get the cursor object which represent both current character and it's dom
     
    7577                 * Iterator which walk through document char by char.
    7678                 * @param {Object} start
    7779                 * @param {Number} offset
     80                 * @param {Boolean} isStrict
    7881                 */
    79                 var characterWalker = function( start, offset )
     82                var characterWalker = function( start, offset , isStrict )
    8083                {
    8184                        var isCursor = typeof( start.textNode ) !== 'undefined';
    8285                        this.textNode = isCursor ? start.textNode : start;
     
    8184                        var isCursor = typeof( start.textNode ) !== 'undefined';
    8285                        this.textNode = isCursor ? start.textNode : start;
    8386                        this.offset = isCursor ? start.offset : offset;
     87                        var walker = new CKEDITOR.dom.walker( this.textNode );
     88                        walker[ isStrict? 'guard' : 'evaluator' ] =
     89                                guardDomWalkerNonEmptyTextNode;
    8490                        this._ = {
    85                                 walker : new CKEDITOR.dom.domWalker( this.textNode ),
     91                                walker : walker,
    8692                                matchBoundary : false
    8793                        };
    8894                };
     
    107113
    108114                                // If we are at the end of the text node, use dom walker to get
    109115                                // the next text node.
    110                                 var data = null;
    111                                 while ( !data || ( data.node && data.node.type !=
    112                                         CKEDITOR.NODE_TEXT ) )
     116                                var node = null;
     117                                while ( !node )
    113118                                {
    114                                         data = this._.walker.forward(
    115                                                 guardDomWalkerNonEmptyTextNode );
     119                                        node = this._.walker.next( true );
    116120
    117                                         // Block boundary? BR? Document boundary?
    118                                         if ( !data.node
    119                                                 || ( data.node.type !== CKEDITOR.NODE_TEXT
    120                                                         && data.node.getName() in
    121                                                         characterBoundaryElementsEnum ) )
     121                                        // Marking as match boundaries.
     122                                        if( node === false
     123                                           && checkCharactersBoundary( this._.walker.current ) )
    122124                                                this._.matchBoundary = true;
     125                                        // Already reach document end.
     126                                        if ( !this._.walker.current )
     127                                                break;
     128                                       
    123129                                }
    124                                 this.textNode = data.node;
     130                                this.textNode = node;
    125131                                this.offset = 0;
    126132                                return cursorStep.call( this );
    127133                        },
     
    138144                                }
    139145
    140146                                // Start of text node -> use dom walker to get the previous text node.
    141                                 var data = null;
    142                                 while ( !data
    143                                 || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
     147                                var node = null;
     148                                while ( !node )
    144149                                {
    145                                         data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
     150                                        node = this._.walker.previous( true );
    146151
    147                                         // Block boundary? BR? Document boundary?
    148                                         if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
    149                                         data.node.getName() in characterBoundaryElementsEnum ) )
     152                                        // Marking as match boundaries.
     153                                        if( node === false
     154                                                && checkCharactersBoundary( this._.walker.current ) )
    150155                                                this._.matchBoundary = true;
     156                                       
     157                                        // Already reach document end.
     158                                        if ( !this._.walker.current )
     159                                                break;
    151160                                }
    152                                 this.textNode = data.node;
    153                                 this.offset = data.node.length - 1;
     161                                this.textNode = node;
     162                                this.offset = node.length - 1;
    154163                                return cursorStep.call( this );
    155164                        }
    156165                };
     
    465474                                                        var cursors = this.range.getCursors(),
    466475                                                                tail = cursors[ cursors.length - 1 ],
    467476                                                                head = cursors[ 0 ],
    468                                                                 headWalker = new characterWalker( head ),
    469                                                                 tailWalker = new characterWalker( tail );
     477                                                                headWalker = new characterWalker( head, null, true ),
     478                                                                tailWalker = new characterWalker( tail, null, true );
    470479
    471480                                                        if ( ! ( isWordSeparator(
    472481                                                                                headWalker.back().character )
  • _source/core/loader.js

     
    3939                        'core/dom/node'                 : [ 'core/dom/domobject', 'core/tools' ],
    4040                        'core/dom/nodelist'             : [ 'core/dom/node' ],
    4141                        'core/dom/domobject'    : [ 'core/dom/event' ],
    42                         'core/dom/domwalker'    : [ 'core/dom/node', 'core/dom/element', 'core/dom/document' ],
    43                         'core/dom/range'                : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/domwalker', 'core/dom/walker' ],
     42                        'core/dom/range'                : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/walker' ],
    4443                        'core/dom/text'                 : [ 'core/dom/node', 'core/dom/domobject' ],
    4544                        'core/dom/walker'               : [ 'core/dom/node' ],
    4645                        'core/dom/window'               : [ 'core/dom/domobject' ],
  • _source/core/dom/range.js

     
    10881088                                case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
    10891089                                case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
    10901090                                        // DFS backward to get the block/list item boundary at or before the start.
    1091 
    1092                                         // Get the boundaries nodes.
    1093                                         var startNode = this.getTouchedStartNode(),
    1094                                                 endNode = this.getTouchedEndNode();
    1095 
    1096                                         if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.isBlockBoundary() )
     1091                                        // Get the outter boundaries nodes.
     1092                                        var startNode, endNode;
     1093                                       
     1094                                        // Use bookmark nodes to mock boundary nodes for collapsed
     1095                                        // range.
     1096                                        if( this.collapsed )
    10971097                                        {
    1098                                                 this.setStartAt( startNode,
    1099                                                         CKEDITOR.dtd.$empty[ startNode.getName() ] ?
    1100                                                                 CKEDITOR.POSITION_AFTER_END :
    1101                                                                 CKEDITOR.POSITION_AFTER_START );
     1098                                                var bm = this.createBookmark();
     1099                                                startNode= bm.startNode;
     1100                                                endNode = startNode;
    11021101                                        }
    11031102                                        else
    11041103                                        {
    1105                                                 // Get the function used to check the enlaarging limits.
    1106                                                 var guardFunction = ( unit == CKEDITOR.ENLARGE_BLOCK_CONTENTS ?
    1107                                                                 CKEDITOR.dom.domWalker.blockBoundary() :
    1108                                                                 CKEDITOR.dom.domWalker.listItemBoundary() );
    1109 
    1110                                                 // Create the DOM walker, which will traverse the DOM.
    1111                                                 var walker = new CKEDITOR.dom.domWalker( startNode );
     1104                                                var boundaries = this.getBoundaryNodes(),
     1105                                                        startNode = boundaries.startNode,
     1106                                                        endNode = boundaries.endNode;
     1107                                        }
    11121108
    1113                                                 // Go walk in reverse sense.
    1114                                                 var data = walker.reverse( guardFunction );
    1115 
    1116                                                 var boundaryEvent = data.events.shift();
     1109                                        // function used to check the enlarging limits.
     1110                                        function checkOnBoundary( toNode, fromNode, customNodeNames )
     1111                                        {
     1112                                                // Check the enlarged node.
     1113                                                if( toNode && toNode.type == CKEDITOR.NODE_ELEMENT
     1114                                                        && toNode.isBlockBoundary(
     1115                                                                unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS? { br : 1 } : null ) )   
     1116                                                        return true;
    11171117
    1118                                                 this.setStartBefore( boundaryEvent.from );
     1118                                                // Check the current node.
     1119                                                else if( currentNode.type == CKEDITOR.NODE_ELEMENT &&
     1120                                                                        currentNode.isBlockBoundary(
     1121                                                                        unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS? { br : 1 } : null )
     1122                                                                        && ( enlargedNode.$ == currentNode.$.parentNode
     1123                                                                                        || enlargedNode.$ == currentNode.$.previousSibling ) )
     1124                                                        return true;
    11191125                                        }
    1120 
    1121                                         if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.isBlockBoundary() )
     1126                                       
     1127                                        // Enlarging the start boundary.
     1128                                        var walker = new CKEDITOR.dom.walker( startNode ),
     1129                                                enlargedNode = startNode,
     1130                                                currentNode = enlargedNode;
     1131                                        while( enlargedNode )
    11221132                                        {
    1123                                                 this.setEndAt( endNode,
    1124                                                         CKEDITOR.dtd.$empty[ endNode.getName() ] ?
    1125                                                                 CKEDITOR.POSITION_BEFORE_START :
    1126                                                                 CKEDITOR.POSITION_BEFORE_END );
     1133                                                // Check for those opening element.
     1134                                                if( !currentNode.getPrevious() &&
     1135                                                        checkOnBoundary( currentNode.getParent(), currentNode ) )
     1136                                                        break;
     1137                                                enlargedNode = walker.previous();
     1138                                                if( checkOnBoundary( enlargedNode, currentNode ) )
     1139                                                        break;
     1140                                                currentNode = enlargedNode;
    11271141                                        }
    1128                                         else
     1142                                        this.setStartAt( enlargedNode, CKEDITOR.POSITION_AFTER_END );
     1143                                       
     1144                                        // Enlarging the end boundary.
     1145                                        walker = new CKEDITOR.dom.walker( endNode ),
     1146                                                enlargedNode = endNode,
     1147                                                currentNode = enlargedNode;
     1148                                        while( enlargedNode )
    11291149                                        {
    1130                                                 // DFS forward to get the block/list item boundary at or before the end.
    1131                                                 walker.setNode( endNode );
    1132                                                 data = walker.forward( guardFunction );
    1133                                                 boundaryEvent = data.events.shift();
    1134 
    1135                                                 this.setEndAfter( boundaryEvent.from );
     1150                                                // Check for those closing element.
     1151                                                if( !currentNode.getNext() &&
     1152                                                        checkOnBoundary( currentNode.getParent(), currentNode ) )
     1153                                                        break;
     1154                                                enlargedNode = walker.next();
     1155                                                if( checkOnBoundary( enlargedNode, currentNode ) )
     1156                                                        break;
     1157                                                currentNode = enlargedNode;
     1158                                        }
     1159                                        this.setEndAt( enlargedNode, CKEDITOR.POSITION_BEFORE_START );
     1160                                       
     1161                                        if( bm )
     1162                                        {
     1163                                                // Backup current range.
     1164                                                var enlargedBm = this.createBookmark();
     1165                                               
     1166                                                // Destroy the marker bookmark.
     1167                                                this.moveToBookmark( bm );
     1168                                                this.moveToBookmark( enlargedBm );
    11361169                                        }
    11371170                        }
    11381171                },
  • _source/core/dom/walker.js

     
    4444                                node = null;
    4545                }
    4646                else
    47                         node = this.startNode[ getSourceNodeFn ]( true, type, guard );
     47                        node = this.startNode[ getSourceNodeFn ]( false, type, guard );
    4848
    4949                while ( node && !this._.end )
    5050                {
     
    217217                        checkBackward : function()
    218218                        {
    219219                                return iterate.call( this, true, true ) !== false;
     220                        },
     221                       
     222                        /**
     223                         * Reset walker to initial state.
     224                         */
     225                        reset : function()
     226                        {
     227                                delete this._.end;
     228                                delete this.current;
    220229                        }
    221230                }
    222231        });
     232
     233        /*
     234         * Anything whose display computed style is block, list-item, table,
     235         * table-row-group, table-header-group, table-footer-group, table-row,
     236         * table-column-group, table-column, table-cell, table-caption, or whose node
     237         * name is hr, br (when enterMode is br only) is a block boundary.
     238         */
     239        var blockBoundaryDisplayMatch =
     240        {
     241                block : 1,
     242                'list-item' : 1,
     243                table : 1,
     244                'table-row-group' : 1,
     245                'table-header-group' : 1,
     246                'table-footer-group' : 1,
     247                'table-row' : 1,
     248                'table-column-group' : 1,
     249                'table-column' : 1,
     250                'table-cell' : 1,
     251                'table-caption' : 1
     252        },
     253        blockBoundaryNodeNameMatch = { hr : 1 };
     254
     255        CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames )
     256        {
     257                var nodeNameMatches = CKEDITOR.tools.extend(
     258                        blockBoundaryNodeNameMatch, customNodeNames || {} );
     259
     260                return blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] ||
     261                        nodeNameMatches[ this.getName() ];
     262        };
     263
     264        CKEDITOR.dom.walker.blockBoundary = function( customNodeNames )
     265        {
     266                return function( node , type )
     267                {
     268                        return ! ( node.type == CKEDITOR.NODE_ELEMENT
     269                                                && node.isBlockBoundary( customNodeNames ) );
     270                };
     271        };
     272       
     273        CKEDITOR.dom.walker.listItemBoundary = function()
     274        {
     275                        return this.blockBoundary( { br : 1 } );
     276        };
     277
    223278})();
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy