Ticket #3367: 3367_3.patch

File 3367_3.patch, 24.7 KB (added by Frederico Caldeira Knabben, 13 years ago)
  • _source/core/dom/node.js

     
    286286
    287287                        while ( !node && ( parent = ( parent || this ).getParent() ) )
    288288                        {
    289                                 if ( guard && guard( parent ) === false )
     289                                // The guard check sends the "true" paramenter to indicate that
     290                                // we are moving "out" of the element.
     291                                if ( guard && guard( parent, true ) === false )
    290292                                        return null;
    291293
    292294                                node = parent.getNext();
     
    320322
    321323                        while ( !node && ( parent = ( parent || this ).getParent() ) )
    322324                        {
    323                                 if ( guard && guard( parent ) === false )
     325                                // The guard check sends the "true" paramenter to indicate that
     326                                // we are moving "out" of the element.
     327                                if ( guard && guard( parent, true ) === false )
    324328                                        return null;
    325329
    326330                                node = parent.getPrevious();
  • _source/core/dom/range.js

     
    14051405                        };
    14061406                },
    14071407
     1408                // Calls to this function may produce changes to the DOM. The range may
     1409                // be updated to reflect such changes.
    14081410                checkStartOfBlock : function()
    14091411                {
    14101412                        var startContainer = this.startContainer,
    1411                                 startOffset = this.startOffset,
    1412                                 startNode,
    1413                                 startInclusive;
     1413                                startOffset = this.startOffset;
    14141414
    1415                         if ( startOffset )
     1415                        // If the starting node is a text node, and non-empty before the offset,
     1416                        // then we're surely not at the start of block.
     1417                        if ( startOffset && startContainer.type == CKEDITOR.NODE_TEXT )
    14161418                        {
    1417                                 // If the starting node is a text node, and non-empty before the offset,
    1418                                 // then we're surely not at the start of block.
    1419                                 if ( startContainer.type == CKEDITOR.NODE_TEXT )
    1420                                 {
    1421                                         var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
    1422                                         if ( textBefore.length )
    1423                                                 return false;
    1424                                 }
    1425                                 else
    1426                                 {
    1427                                         startNode = startContainer.getChild( startOffset - 1 );
    1428                                         startInclusive = true;
    1429                                 }
     1419                                var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
     1420                                if ( textBefore.length )
     1421                                        return false;
    14301422                        }
    14311423                       
    1432                         if ( !startNode )
    1433                                 startNode = startContainer;
     1424                        // Antecipate the trim() call here, so the walker will not make
     1425                        // changes to the DOM, which would not get reflected into this
     1426                        // range otherwise.
     1427                        this.trim();
    14341428
    1435                         var path        = new CKEDITOR.dom.elementPath( startNode ),
    1436                                 walker  = new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
    1437 
    1438                         if ( ( path.block && startNode.equals( path.block ) )
    1439                                 || ( !path.block && startNode.equals( path.blockLimit ) ) )
    1440                         {
    1441                                 return true;
    1442                         }
    1443 
    1444                         walker.startInclusive = startInclusive;
    1445                         walker.evaluator = getCheckStartEndBlockEvalFunction( true );
     1429                        // We need to grab the block element holding the start boundary, so
     1430                        // let's use an element path for it.
     1431                        var path = new CKEDITOR.dom.elementPath( this.startContainer );
    14461432                       
     1433                        // Creates a range starting at the block start until the range start.
     1434                        var walkerRange = this.clone();
     1435                        walkerRange.collapse( true );
     1436                        walkerRange.setStartAt( path.block || path.blockLimit, CKEDITOR.POSITION_AFTER_START );
     1437                       
     1438                        var walker = new CKEDITOR.dom.walker( walkerRange );
     1439                        walker.evaluator = getCheckStartEndBlockEvalFunction( true );
     1440
    14471441                        return walker.checkBackward();
    14481442                },
    14491443
    14501444                checkEndOfBlock : function()
    14511445                {
    14521446                        var endContainer = this.endContainer,
    1453                                 endOffset = this.endOffset,
    1454                                 startNode,
    1455                                 startInclusive;
     1447                                endOffset = this.endOffset;
    14561448
    14571449                        // If the ending node is a text node, and non-empty after the offset,
    14581450                        // then we're surely not at the end of block.
     
    14621454                                if ( textAfter.length )
    14631455                                        return false;
    14641456                        }
    1465                         else
    1466                         {
    1467                                 startNode = endContainer.getChild( endOffset );
    1468                                 startInclusive = !!startNode;
    1469                         }
    14701457
    1471                         if ( !startNode )
    1472                                 startNode = endContainer;
     1458                        // Antecipate the trim() call here, so the walker will not make
     1459                        // changes to the DOM, which would not get reflected into this
     1460                        // range otherwise.
     1461                        this.trim();
    14731462
    1474                         var path        = new CKEDITOR.dom.elementPath( startNode ),
    1475                                 walker  = new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
    1476 
    1477                         if ( ( path.block && startNode.equals( path.block ) )
    1478                                 || ( !path.block && startNode.equals( path.blockLimit ) ) )
    1479                         {
    1480                                 return true;
    1481                         }
    1482 
    1483                         walker.startInclusive = startInclusive;
    1484                         walker.evaluator = getCheckStartEndBlockEvalFunction( false );
     1463                        // We need to grab the block element holding the start boundary, so
     1464                        // let's use an element path for it.
     1465                        var path = new CKEDITOR.dom.elementPath( this.endContainer );
    14851466                       
     1467                        // Creates a range starting at the block start until the range start.
     1468                        var walkerRange = this.clone();
     1469                        walkerRange.collapse( false );
     1470                        walkerRange.setEndAt( path.block || path.blockLimit, CKEDITOR.POSITION_BEFORE_END );
     1471                       
     1472                        var walker = new CKEDITOR.dom.walker( walkerRange );
     1473                        walker.evaluator = getCheckStartEndBlockEvalFunction( false );
     1474
    14861475                        return walker.checkForward();
    14871476                },
    14881477
  • _source/core/dom/walker.js

     
    88        // This function is to be called under a "walker" instance scope.
    99        function iterate( rtl, breakOnFalse )
    1010        {
     11                // Return null if we have reached the end.
    1112                if ( this._.end )
    1213                        return null;
    1314
    1415                var node,
     16                        range = this.range,
     17                        guard,
     18                        userGuard = this.guard,
    1519                        type = this.type,
    1620                        getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' );
    1721
    18                 var guard = this.guard,
    19                         endNode = this.endNode;
     22                // This is the first call. Initialize it.
     23                if ( !this._.start )
     24                {
     25                        this._.start = 1;
     26                       
     27                        // Trim text nodes and optmize the range boundaries. DOM changes
     28                        // may happen at this point.
     29                        range.trim();
    2030
    21                 if ( endNode )
     31                        // A collapsed range must return null at first call.
     32                        if ( range.collapsed )
     33                        {
     34                                this.end();
     35                                return null;
     36                        }
     37                }
     38
     39                // Create the LTR guard function, if necessary.
     40                if ( !rtl && !this._.guardLTR )
    2241                {
    23                         if ( guard )
     42                        // Gets the node that stops the walker when going LTR.
     43                        var limitLTR = range.endContainer,
     44                                blockerLTR = limitLTR.getChild( range.endOffset );
     45                       
     46                        this._.guardLTR = function( node, movingOut )
    2447                        {
    25                                 var originalGuard;
    26                                 guard = function( node )
    27                                 {
    28                                         if ( node.equals( endNode ) )
    29                                                 return false;
     48                                return ( ( !movingOut || !limitLTR.equals( node ) )
     49                                        && ( !blockerLTR || !node.equals( blockerLTR ) )
     50                                        && ( node.type != CKEDITOR.NODE_ELEMENT || node.name != 'body' ) );
     51                        }
     52                }
     53               
     54                // Create the RTL guard function, if necessary.
     55                if ( rtl && !this._.guardRTL )
     56                {
     57                        // Gets the node that stops the walker when going LTR.
     58                        var limitRTL = range.startContainer,
     59                                blockerRTL = ( range.startOffset > 0 ) && limitRTL.getChild( range.startOffset - 1 );
     60                       
     61                        this._.guardRTL = function( node, movingOut )
     62                        {
     63                                return ( ( !movingOut || !limitRTL.equals( node ) )
     64                                        && ( !blockerRTL || !node.equals( blockerRTL ) )
     65                                        && ( node.type != CKEDITOR.NODE_ELEMENT || node.name != 'body' ) );
     66                        }
     67                }
     68               
     69                // Define which guard function to use.
     70                stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
    3071
    31                                         return originalGuard( node );
    32                                 };
     72                // Make the user defined guard function participate in the process,
     73                // otherwise simply use the boundary guard.
     74                if ( userGuard )
     75                {
     76                        guard = function( node, movingOut )
     77                        {
     78                                if ( stopGuard( node, movingOut ) === false )
     79                                        return false;
     80
     81                                return userGuard( node );
    3382                        }
    34                         else
    35                                 guard = endNode;
    3683                }
     84                else
     85                        guard = stopGuard;
    3786
    3887                if ( this.current )
    3988                        node = this.current[ getSourceNodeFn ]( false, type, guard );
    40                 else if ( this.startInclusive )
     89                else
    4190                {
    42                         node = this.startNode;
    43                         if ( this.guard && this.guard( node ) === false )
    44                                 node = null;
     91                        // Get the first node to be returned.
     92
     93                        if ( rtl )
     94                        {
     95                                node = range.endContainer;
     96                               
     97                                if ( range.endOffset > 0 )
     98                                {
     99                                        node = node.getChild( range.endOffset - 1 );
     100                                        if ( guard( node ) === false )
     101                                                node = null;
     102                                }
     103                                else
     104                                        node = node.getPreviousSourceNode( true, type, guard );
     105                        }
     106                        else
     107                        {
     108                                node = range.startContainer;
     109                                node = node.getChild( range.startOffset );
     110
     111                                if ( node )
     112                                {
     113                                        if ( guard( node ) === false )
     114                                                node = null;
     115                                }
     116                                else
     117                                        node = range.startContainer.getNextSourceNode( true, type, guard );
     118                        }
    45119                }
    46                 else
    47                         node = this.startNode[ getSourceNodeFn ]( true, type, guard );
    48120
    49121                while ( node && !this._.end )
    50122                {
    51123                        this.current = node;
    52124
    53                         if ( node == this.endNode && !this.endInclusive )
    54                                 break;
    55 
    56125                        if ( !this.evaluator || this.evaluator( node ) !== false )
    57126                                return node;
    58127                        else if ( breakOnFalse && this.evaluator )
     
    65134                return this.current = null;
    66135        }
    67136
    68         function iterateToLast( rtl )
    69         {
    70                 var node, last = null;
     137//      function iterateToLast( rtl )
     138//      {
     139//              var node, last = null;
    71140
    72                 while ( node = iterate.call( this, rtl ) )
    73                         last = node;
     141//              while ( node = iterate.call( this, rtl ) )
     142//                      last = node;
    74143
    75                 return last;
    76         }
     144//              return last;
     145//      }
    77146
    78147        CKEDITOR.dom.walker = CKEDITOR.tools.createClass(
    79148        {
    80149                /**
    81                  * Utility class to "walk" inside a DOM tree starting from a specific
    82                  * node. Each step in the walk can be preciselly controlled.
     150                 * Utility class to "walk" the DOM inside a range boundaries. If
     151                 * necessary, partially included nodes (text nodes) are broken to
     152                 * reflect the boundaries limits, so DOM and range changes may happen.
     153                 * Outside changes to the range may break the walker.
     154                 *
     155                 * The walker may return nodes that are not totaly included into the
     156                 * range boundaires. Let's take the following range representation,
     157                 * where the square brackets indicate the boundaries:
     158                 *
     159                 * [<p>Some <b>sample] text</b>
     160                 *
     161                 * While walking forward into the above range, the following nodes are
     162                 * returned: <p>, "Some ", <b> and "sample". Going
     163                 * backwards instead we have: "sample" and "Some ". So note that the
     164                 * walker always returns nodes when "entering" them, but not when
     165                 * "leaving" them. The guard function is instead called both when
     166                 * entering and leaving nodes.
     167                 *
    83168                 * @constructor
    84                  * @param {CKEDITOR.dom.node} startNode The node from wich the walk
    85                  *              will start.
    86                  * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
    87                  *              in the walk. No more nodes are retrieved after touching or
    88                  *              passing it.
     169                 * @param {CKEDITOR.dom.range} range The range within which walk.
    89170                 */
    90                 $ : function( startNode, endNode )
     171                $ : function( range )
    91172                {
    92                         /**
    93                          * The node from which start walking.
    94                          * @type {CKEDITOR.dom.node}
    95                          */
    96                         this.startNode = startNode;
     173                        this.range = range;
    97174
    98175                        /**
    99                          * The end boundary node of the walk.
    100                          * @type {CKEDITOR.dom.node}
    101                          */
    102                         this.endNode = endNode;
    103 
    104                         /**
    105                          * Indicates that the start node is to be included in the walk.
    106                          * @name CKEDITOR.pluginDefinition.prototype.startInclusive
    107                          * @property
    108                          * @type Boolean
    109                          * @default false
    110                          */
    111                         // this.startInclusive = false;
    112 
    113                         /**
    114                          * Indicates that the end node is to be included in the walk.
    115                          * @name CKEDITOR.pluginDefinition.prototype.endInclusive
    116                          * @property
    117                          * @type Boolean
    118                          * @default false
    119                          */
    120                         // this.endInclusive = false;
    121 
    122                         /**
    123176                         * A function executed for every matched node, to check whether
    124177                         * it's to be considered into the walk or not. If not provided, all
    125178                         * matched nodes are considered good.
     
    146199                        this._ = {};
    147200                },
    148201
     202//              statics :
     203//              {
     204//                      /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
     205//                       * @param {CKEDITOR.dom.node} startNode The node from wich the walk
     206//                       *              will start.
     207//                       * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
     208//                       *              in the walk. No more nodes are retrieved after touching or
     209//                       *              passing it. If not provided, the walker stops at the
     210//                       *              <body> closing boundary.
     211//                       * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
     212//                       *              provided nodes.
     213//                       */
     214//                      createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
     215//                      {
     216//                              var range = new CKEDITOR.dom.range();
     217//                              range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
     218
     219//                              if ( endNode )
     220//                                      range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
     221//                              else
     222//                                      range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
     223
     224//                              return new CKEDITOR.dom.walker( range );
     225//                      }
     226//              },
     227
    149228                proto :
    150229                {
    151230                        /**
     
    166245                        {
    167246                                return iterate.call( this );
    168247                        },
    169 
     248                       
    170249                        /**
    171250                         * Retrieves the previous node (at left).
    172251                         * @returns {CKEDITOR.dom.node} The previous node or null if no more
     
    178257                        },
    179258
    180259                        /**
    181                          * Executes a full walk forward (to the right), until no more nodes
    182                          * are available, returning the last valid node.
    183                          * @returns {CKEDITOR.dom.node} The last node at the right or null
    184                          *              if no valid nodes are available.
    185                          */
    186                         lastForward : function()
    187                         {
    188                                 return iterateToLast.call( this );
    189                         },
    190 
    191                         /**
    192                          * Executes a full walk backwards (to the left), until no more nodes
    193                          * are available, returning the last valid node.
    194                          * @returns {CKEDITOR.dom.node} The last node at the left or null
    195                          *              if no valid nodes are available.
    196                          */
    197                         lastBackward : function()
    198                         {
    199                                 return iterateToLast.call( this, true );
    200                         },
    201 
    202                         /**
    203260                         * Check all nodes at right, executing the evaluation fuction.
    204261                         * @returns {Boolean} "false" if the evaluator function returned
    205262                         *              "false" for any of the matched nodes. Otherwise "true".
     
    218275                        {
    219276                                return iterate.call( this, true, true ) !== false;
    220277                        }
     278
     279// The following features have been originally included in the implementation,
     280// but they are not used anywhere in the code, so they got commented out.
     281
     282//                      /**
     283//                       * Executes a full walk forward (to the right), until no more nodes
     284//                       * are available, returning the last valid node.
     285//                       * @returns {CKEDITOR.dom.node} The last node at the right or null
     286//                       *              if no valid nodes are available.
     287//                       */
     288//                      lastForward : function()
     289//                      {
     290//                              return iterateToLast.call( this );
     291//                      },
     292
     293//                      /**
     294//                       * Executes a full walk backwards (to the left), until no more nodes
     295//                       * are available, returning the last valid node.
     296//                       * @returns {CKEDITOR.dom.node} The last node at the left or null
     297//                       *              if no valid nodes are available.
     298//                       */
     299//                      lastBackward : function()
     300//                      {
     301//                              return iterateToLast.call( this, true );
     302//                      }
    221303                }
    222304        });
    223305})();
  • _source/tests/core/dom/walker.html

     
     1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2<html xmlns="http://www.w3.org/1999/xhtml">
     3<head>
     4        <title>CKEDITOR.dom.walker</title>
     5        <link rel="stylesheet" type="text/css" href="../../test.css" />
     6        <script type="text/javascript" src="../../../../ckeditor_source.js"></script> <!-- %REMOVE_LINE%
     7        <script type="text/javascript" src="../../../ckeditor.js"></script>
     8        %REMOVE_LINE% -->
     9        <script type="text/javascript" src="../../test.js"></script>
     10        <script type="text/javascript">
     11        //<![CDATA[
     12
     13var tc;
     14
     15CKEDITOR.test.addTestCase( tc = (function()
     16{
     17        // Local reference to the "assert" object.
     18        var assert = CKEDITOR.test.assert;
     19
     20        var doc = new CKEDITOR.dom.document( document );
     21       
     22        function assertNodesList( wanted, nodes )
     23        {
     24                var simplifiedNodes = [];
     25               
     26                for ( var i = 0 ; i < nodes.length ; i++ )
     27                        simplifiedNodes.push( nodes[i].type == CKEDITOR.NODE_TEXT ? nodes[i].getText() : ( '<' + nodes[i].getName() + '>' ) );
     28
     29                assert.areSame( wanted.toString(), simplifiedNodes.toString() );
     30        }
     31
     32        return {
     33
     34                test_collapsed : function()
     35                {
     36                        var node = doc.getById( 'playground' );
     37                        node.setHtml( '<p>Test</p>' );
     38
     39                        var range = new CKEDITOR.dom.range( doc );
     40
     41                        range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
     42                        range.collapse( true );
     43                       
     44                        var walker = new CKEDITOR.dom.walker( range );
     45                       
     46                        assert.isNull( walker.next() );
     47                },
     48
     49                test_next_1 : function()
     50                {
     51                        var node = doc.getById( 'playground' );
     52                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     53
     54                        var range = new CKEDITOR.dom.range( doc );
     55                        range.selectNodeContents( node );
     56                       
     57                        var walker = new CKEDITOR.dom.walker( range );
     58
     59                        var nodes = [],
     60                                node;
     61                        while ( node = walker.next() )
     62                        {
     63                                nodes.push( node );
     64                        }
     65
     66                        assertNodesList( [ '<p>', 'This is ', '<b>', 'a ', '<i>', 'simple', ' test' ], nodes );
     67                },
     68
     69                test_next_2 : function()
     70                {
     71                        var node = doc.getById( 'playground' );
     72                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     73
     74                        var range = new CKEDITOR.dom.range( doc );
     75                        range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
     76                        range.setEnd( node.getChild( [0,1,1,0] ), 2 );
     77                       
     78                        var walker = new CKEDITOR.dom.walker( range );
     79
     80                        var nodes = [],
     81                                node;
     82                        while ( node = walker.next() )
     83                        {
     84                                nodes.push( node );
     85                        }
     86
     87                        assertNodesList( [ 'This is ', '<b>', 'a ', '<i>', 'si' ], nodes );
     88                },
     89
     90                test_next_3 : function()
     91                {
     92                        var node = doc.getById( 'playground' );
     93                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     94
     95                        var range = new CKEDITOR.dom.range( doc );
     96                        range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
     97                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     98                       
     99                        var walker = new CKEDITOR.dom.walker( range );
     100
     101                        var nodes = [],
     102                                node;
     103                        while ( node = walker.next() )
     104                        {
     105                                nodes.push( node );
     106                        }
     107
     108                        assertNodesList( [ '<h1>' ], nodes );
     109                },
     110
     111                test_next_4 : function()
     112                {
     113                        var node = doc.getById( 'playground' );
     114                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     115
     116                        var range = new CKEDITOR.dom.range( doc );
     117                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     118                        range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );
     119                       
     120                        var walker = new CKEDITOR.dom.walker( range );
     121
     122                        var nodes = [],
     123                                node;
     124                        while ( node = walker.next() )
     125                        {
     126                                nodes.push( node );
     127                        }
     128
     129                        assertNodesList( [], nodes );
     130                },
     131
     132                test_next_5 : function()
     133                {
     134                        var node = doc.getById( 'playground' );
     135                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     136
     137                        var range = new CKEDITOR.dom.range( doc );
     138                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     139                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     140                       
     141                        var walker = new CKEDITOR.dom.walker( range );
     142
     143                        var nodes = [],
     144                                node;
     145                        while ( node = walker.next() )
     146                        {
     147                                nodes.push( node );
     148                        }
     149
     150                        assertNodesList( [ '<h1>' ], nodes );
     151                },
     152
     153                test_previous_1 : function()
     154                {
     155                        var node = doc.getById( 'playground' );
     156                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     157
     158                        var range = new CKEDITOR.dom.range( doc );
     159                        range.selectNodeContents( node );
     160                       
     161                        var walker = new CKEDITOR.dom.walker( range );
     162
     163                        var nodes = [],
     164                                node;
     165                        while ( node = walker.previous() )
     166                        {
     167                                nodes.push( node );
     168                        }
     169
     170                        assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', 'a ', 'This is ' ], nodes );
     171                },
     172
     173                test_previous_2 : function()
     174                {
     175                        var node = doc.getById( 'playground' );
     176                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     177
     178                        var range = new CKEDITOR.dom.range( doc );
     179                        range.setEnd( node.getChild( [0,0] ), 2 );
     180                        range.setEnd( node.getChild( [0,1,1,0] ), 2 );
     181                       
     182                        var walker = new CKEDITOR.dom.walker( range );
     183
     184                        var nodes = [],
     185                                node;
     186                        while ( node = walker.previous() )
     187                        {
     188                                nodes.push( node );
     189                        }
     190
     191                        assertNodesList( [ 'si', 'a ', 'is is ' ], nodes );
     192                },
     193
     194                test_previous_3 : function()
     195                {
     196                        var node = doc.getById( 'playground' );
     197                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     198
     199                        var range = new CKEDITOR.dom.range( doc );
     200                        range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
     201                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     202                       
     203                        var walker = new CKEDITOR.dom.walker( range );
     204
     205                        var nodes = [],
     206                                node;
     207                        while ( node = walker.previous() )
     208                        {
     209                                nodes.push( node );
     210                        }
     211
     212                        assertNodesList( [ '' ], nodes );
     213                },
     214
     215                test_previous_4 : function()
     216                {
     217                        var node = doc.getById( 'playground' );
     218                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     219
     220                        var range = new CKEDITOR.dom.range( doc );
     221                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     222                        range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );
     223                       
     224                        var walker = new CKEDITOR.dom.walker( range );
     225
     226                        var nodes = [],
     227                                node;
     228                        while ( node = walker.previous() )
     229                        {
     230                                nodes.push( node );
     231                        }
     232
     233                        assertNodesList( [ '<p>' ], nodes );
     234                },
     235
     236                test_previous_5 : function()
     237                {
     238                        var node = doc.getById( 'playground' );
     239                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     240
     241                        var range = new CKEDITOR.dom.range( doc );
     242                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     243                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     244                       
     245                        var walker = new CKEDITOR.dom.walker( range );
     246
     247                        var nodes = [],
     248                                node;
     249                        while ( node = walker.previous() )
     250                        {
     251                                nodes.push( node );
     252                        }
     253
     254                        assertNodesList( [ '<p>' ], nodes );
     255                },
     256
     257                /**
     258                 *  Test guard function is invoked on every move when iterating forward.
     259                 */
     260                test_guard_1 : function()
     261                {
     262                        var node = doc.getById( 'playground' );
     263                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     264
     265                        var range = new CKEDITOR.dom.range( doc );
     266                        range.selectNodeContents( node );
     267                       
     268                        var walker = new CKEDITOR.dom.walker( range );
     269                        var nodes = [],
     270                                node;
     271                        walker.guard = function( node ){
     272                                nodes.push( node );
     273                                return true;
     274                        };
     275                        while ( node = walker.next() )
     276                        {}
     277
     278                        assertNodesList( [ '<p>', 'This is ', '<b>', 'a ', '<i>', 'simple', '<i>', '<b>',' test' , '<p>' ], nodes );
     279                },
     280
     281                /**
     282                 *  Test guard function is invoked on every move when iterating backward.
     283                 */
     284                test_guard_2 : function()
     285                {
     286                        var node = doc.getById( 'playground' );
     287                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     288
     289                        var range = new CKEDITOR.dom.range( doc );
     290                        range.selectNodeContents( node );
     291                       
     292                        var walker = new CKEDITOR.dom.walker( range );
     293                        var nodes = [],
     294                                node;
     295                        walker.guard = function( node ){
     296                                nodes.push( node );
     297                                return true;
     298                        };
     299                        while ( node = walker.previous() )
     300                        {}
     301
     302                        assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', '<i>', 'a ', '<b>', 'This is ', '<p>' ], nodes );
     303                },
     304
     305                /**
     306                 *  Test evaluator function is invoked on every  step when iterating backward.
     307                 */
     308                test_evaluator_1 : function()
     309                {
     310                        var node = doc.getById( 'playground' );
     311                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     312
     313                        var range = new CKEDITOR.dom.range( doc );
     314                        range.selectNodeContents( node );
     315                       
     316                        var walker = new CKEDITOR.dom.walker( range );
     317                        var nodes = [],
     318                                node;
     319                        walker.evaluator = function( node ){
     320                                nodes.push( node );
     321                                return true;
     322                        };
     323                        while ( node = walker.previous() )
     324                        {}
     325
     326                        assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', 'a ', 'This is ' ], nodes );
     327                },
     328
     329                name : document.title
     330        };
     331})() );
     332
     333        //]]>
     334        </script>
     335</head>
     336<body>
     337        <div id="playground"></p>
     338</body>
     339</html>
     340 No newline at end of file
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy