Ticket #3367: 3367_2.patch

File 3367_2.patch, 21.5 KB (added by Frederico Caldeira Knabben, 13 years ago)
  • _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 blockerLTR = range.endContainer;
     44                        blockerLTR = blockerLTR.getChild( range.endOffset ) || blockerLTR.getNextSourceNode( true );
     45                       
     46                        this._.guardLTR = function( node )
    2447                        {
    25                                 var originalGuard;
    26                                 guard = function( node )
    27                                 {
    28                                         if ( node.equals( endNode ) )
    29                                                 return false;
     48                                return ( ( !blockerLTR || !node.equals( blockerLTR ) )
     49                                        && ( node.type != CKEDITOR.NODE_ELEMENT || node.name != 'body' ) );
     50                        }
     51                }
     52               
     53                // Create the RTL guard function, if necessary.
     54                if ( rtl && !this._.guardRTL )
     55                {
     56                        // Gets the node that stops the walker when going LTR.
     57                        var blockerRTL = range.startContainer;
     58                        blockerRTL = ( range.startOffset > 0 ) ? blockerRTL.getChild( range.startOffset - 1 ) : blockerRTL.getPreviousSourceNode( true );
     59                       
     60                        this._.guardRTL = function( node )
     61                        {
     62                                return ( ( !blockerRTL || !node.equals( blockerRTL ) )
     63                                        && ( node.type != CKEDITOR.NODE_ELEMENT || node.name != 'body' ) );
     64                        }
     65                }
     66               
     67                // Define which guard function to use.
     68                stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
    3069
    31                                         return originalGuard( node );
    32                                 }
     70                // Make the user defined guard function participate in the process,
     71                // otherwise simply use the boundary guard.
     72                if ( userGuard )
     73                {
     74                        guard = function( node )
     75                        {
     76                                if ( stopGuard( node ) === false )
     77                                        return false;
     78
     79                                return userGuard( node );
    3380                        }
    34                         else
    35                                 guard = endNode;
    3681                }
     82                else
     83                        guard = stopGuard;
    3784
    3885                if ( this.current )
    3986                        node = this.current[ getSourceNodeFn ]( false, type, guard );
    40                 else if ( this.startInclusive )
     87                else
    4188                {
    42                         node = this.startNode;
    43                         if ( this.guard && this.guard( node ) === false )
    44                                 node = null;
     89                        // Get the first node to be returned.
     90
     91                        if ( rtl )
     92                        {
     93                                node = range.endContainer;
     94                                node = ( range.endOffset > 0 ) ? node.getChild( range.endOffset - 1 ) : node.getPreviousSourceNode( true, type, guard );
     95                        }
     96                        else
     97                        {
     98                                node = range.startContainer;
     99                                node = node.getChild( range.startOffset ) || node.getNextSourceNode( true, type, guard );
     100                        }
    45101                }
    46                 else
    47                         node = this.startNode[ getSourceNodeFn ]( true, type, guard );
    48102
    49103                while ( node && !this._.end )
    50104                {
    51105                        this.current = node;
    52106
    53                         if ( node == this.endNode && !this.endInclusive )
    54                                 break;
    55 
    56107                        if ( !this.evaluator || this.evaluator( node ) !== false )
    57108                                return node;
    58109                        else if ( breakOnFalse && this.evaluator )
     
    65116                return this.current = null;
    66117        }
    67118
    68         function iterateToLast( rtl )
    69         {
    70                 var node, last = null;
     119//      function iterateToLast( rtl )
     120//      {
     121//              var node, last = null;
    71122
    72                 while ( node = iterate.call( this, rtl ) )
    73                         last = node;
     123//              while ( node = iterate.call( this, rtl ) )
     124//                      last = node;
    74125
    75                 return last;
    76         }
     126//              return last;
     127//      }
    77128
    78129        CKEDITOR.dom.walker = CKEDITOR.tools.createClass(
    79130        {
    80131                /**
    81                  * Utility class to "walk" inside a DOM tree starting from a specific
    82                  * node. Each step in the walk can be preciselly controlled.
     132                 * Utility class to "walk" the DOM inside a range boundaries. If
     133                 * necessary, partially included nodes (text nodes) are broken to
     134                 * reflect the boundaries limits, so DOM and range changes may happen.
     135                 * Outside changes to the range may break the walker.
     136                 *
     137                 * The walker may return nodes that are not totaly included into the
     138                 * range boundaires. Let's take the following range representation,
     139                 * where the square brackets indicate the boundaries:
     140                 *
     141                 * [<p>Some <b>sample] text</b>
     142                 *
     143                 * While walking forward into the above range, the following nodes are
     144                 * returned: <p>, "Some ", <b> and "sample". Going
     145                 * backwards instead we have: "sample" and "Some ". So note that the
     146                 * walker always returns nodes when "entering" them, but not when
     147                 * "leaving" them. The guard function is instead called both when
     148                 * entering and leaving nodes.
     149                 *
    83150                 * @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.
     151                 * @param {CKEDITOR.dom.range} range The range within which walk.
    89152                 */
    90                 $ : function( startNode, endNode )
     153                $ : function( range )
    91154                {
    92                         /**
    93                          * The node from which start walking.
    94                          * @type {CKEDITOR.dom.node}
    95                          */
    96                         this.startNode = startNode;
     155                        this.range = range;
    97156
    98157                        /**
    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                         /**
    123158                         * A function executed for every matched node, to check whether
    124159                         * it's to be considered into the walk or not. If not provided, all
    125160                         * matched nodes are considered good.
     
    146181                        this._ = {};
    147182                },
    148183
     184//              statics :
     185//              {
     186//                      /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
     187//                       * @param {CKEDITOR.dom.node} startNode The node from wich the walk
     188//                       *              will start.
     189//                       * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
     190//                       *              in the walk. No more nodes are retrieved after touching or
     191//                       *              passing it. If not provided, the walker stops at the
     192//                       *              <body> closing boundary.
     193//                       * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
     194//                       *              provided nodes.
     195//                       */
     196//                      createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
     197//                      {
     198//                              var range = new CKEDITOR.dom.range();
     199//                              range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
     200
     201//                              if ( endNode )
     202//                                      range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
     203//                              else
     204//                                      range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
     205
     206//                              return new CKEDITOR.dom.walker( range );
     207//                      }
     208//              },
     209
    149210                proto :
    150211                {
    151212                        /**
     
    166227                        {
    167228                                return iterate.call( this );
    168229                        },
    169 
     230                       
    170231                        /**
    171232                         * Retrieves the previous node (at left).
    172233                         * @returns {CKEDITOR.dom.node} The previous node or null if no more
     
    178239                        },
    179240
    180241                        /**
    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                         /**
    203242                         * Check all nodes at right, executing the evaluation fuction.
    204243                         * @returns {Boolean} "false" if the evaluator function returned
    205244                         *              "false" for any of the matched nodes. Otherwise "true".
     
    218257                        {
    219258                                return iterate.call( this, true, true ) !== false;
    220259                        }
     260
     261// The following features have been originally included in the implementation,
     262// but they are not used anywhere in the code, so they got commented out.
     263
     264//                      /**
     265//                       * Executes a full walk forward (to the right), until no more nodes
     266//                       * are available, returning the last valid node.
     267//                       * @returns {CKEDITOR.dom.node} The last node at the right or null
     268//                       *              if no valid nodes are available.
     269//                       */
     270//                      lastForward : function()
     271//                      {
     272//                              return iterateToLast.call( this );
     273//                      },
     274
     275//                      /**
     276//                       * Executes a full walk backwards (to the left), until no more nodes
     277//                       * are available, returning the last valid node.
     278//                       * @returns {CKEDITOR.dom.node} The last node at the left or null
     279//                       *              if no valid nodes are available.
     280//                       */
     281//                      lastBackward : function()
     282//                      {
     283//                              return iterateToLast.call( this, true );
     284//                      }
    221285                }
    222286        });
    223287})();
  • _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
     13CKEDITOR.test.addTestCase( (function()
     14{
     15        // Local reference to the "assert" object.
     16        var assert = CKEDITOR.test.assert;
     17
     18        var doc = new CKEDITOR.dom.document( document );
     19       
     20        function assertNodesList( wanted, nodes )
     21        {
     22                var simplifiedNodes = [];
     23               
     24                for ( var i = 0 ; i < nodes.length ; i++ )
     25                        simplifiedNodes.push( nodes[i].type == CKEDITOR.NODE_TEXT ? nodes[i].getText() : ( '<' + nodes[i].getName() + '>' ) );
     26
     27                assert.areSame( wanted.toString(), simplifiedNodes.toString() );
     28        }
     29
     30        return {
     31
     32                test_collapsed : function()
     33                {
     34                        var node = doc.getById( 'playground' );
     35                        node.setHtml( '<p>Test</p>' );
     36
     37                        var range = new CKEDITOR.dom.range( doc );
     38
     39                        range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
     40                        range.collapse( true );
     41                       
     42                        var walker = new CKEDITOR.dom.walker( range );
     43                       
     44                        assert.isNull( walker.next() );
     45                },
     46
     47                test_next_1 : function()
     48                {
     49                        var node = doc.getById( 'playground' );
     50                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     51
     52                        var range = new CKEDITOR.dom.range( doc );
     53                        range.selectNodeContents( node );
     54                       
     55                        var walker = new CKEDITOR.dom.walker( range );
     56
     57                        var nodes = [],
     58                                node;
     59                        while ( node = walker.next() )
     60                        {
     61                                nodes.push( node );
     62                        }
     63
     64                        assertNodesList( [ '<p>', 'This is ', '<b>', 'a ', '<i>', 'simple', ' test' ], nodes );
     65                },
     66
     67                test_next_2 : function()
     68                {
     69                        var node = doc.getById( 'playground' );
     70                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     71
     72                        var range = new CKEDITOR.dom.range( doc );
     73                        range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
     74                        range.setEnd( node.getChild( [0,1,1,0] ), 2 );
     75                       
     76                        var walker = new CKEDITOR.dom.walker( range );
     77
     78                        var nodes = [],
     79                                node;
     80                        while ( node = walker.next() )
     81                        {
     82                                nodes.push( node );
     83                        }
     84
     85                        assertNodesList( [ 'This is ', '<b>', 'a ', '<i>', 'si' ], nodes );
     86                },
     87
     88                test_next_3 : function()
     89                {
     90                        var node = doc.getById( 'playground' );
     91                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     92
     93                        var range = new CKEDITOR.dom.range( doc );
     94                        range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
     95                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     96                       
     97                        var walker = new CKEDITOR.dom.walker( range );
     98
     99                        var nodes = [],
     100                                node;
     101                        while ( node = walker.next() )
     102                        {
     103                                nodes.push( node );
     104                        }
     105
     106                        assertNodesList( [ '<h1>' ], nodes );
     107                },
     108
     109                test_next_4 : function()
     110                {
     111                        var node = doc.getById( 'playground' );
     112                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     113
     114                        var range = new CKEDITOR.dom.range( doc );
     115                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     116                        range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );
     117                       
     118                        var walker = new CKEDITOR.dom.walker( range );
     119
     120                        var nodes = [],
     121                                node;
     122                        while ( node = walker.next() )
     123                        {
     124                                nodes.push( node );
     125                        }
     126
     127                        assertNodesList( [], nodes );
     128                },
     129
     130                test_next_5 : function()
     131                {
     132                        var node = doc.getById( 'playground' );
     133                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     134
     135                        var range = new CKEDITOR.dom.range( doc );
     136                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     137                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     138                       
     139                        var walker = new CKEDITOR.dom.walker( range );
     140
     141                        var nodes = [],
     142                                node;
     143                        while ( node = walker.next() )
     144                        {
     145                                nodes.push( node );
     146                        }
     147
     148                        assertNodesList( [ '<h1>' ], nodes );
     149                },
     150
     151                test_previous_1 : function()
     152                {
     153                        var node = doc.getById( 'playground' );
     154                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     155
     156                        var range = new CKEDITOR.dom.range( doc );
     157                        range.selectNodeContents( node );
     158                       
     159                        var walker = new CKEDITOR.dom.walker( range );
     160
     161                        var nodes = [],
     162                                node;
     163                        while ( node = walker.previous() )
     164                        {
     165                                nodes.push( node );
     166                        }
     167
     168                        assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', 'a ', 'This is ' ], nodes );
     169                },
     170
     171                test_previous_2 : function()
     172                {
     173                        var node = doc.getById( 'playground' );
     174                        node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );
     175
     176                        var range = new CKEDITOR.dom.range( doc );
     177                        range.setEnd( node.getChild( [0,0] ), 2 );
     178                        range.setEnd( node.getChild( [0,1,1,0] ), 2 );
     179                       
     180                        var walker = new CKEDITOR.dom.walker( range );
     181
     182                        var nodes = [],
     183                                node;
     184                        while ( node = walker.previous() )
     185                        {
     186                                nodes.push( node );
     187                        }
     188
     189                        assertNodesList( [ 'si', 'a ', 'is is ' ], nodes );
     190                },
     191
     192                test_previous_3 : function()
     193                {
     194                        var node = doc.getById( 'playground' );
     195                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     196
     197                        var range = new CKEDITOR.dom.range( doc );
     198                        range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
     199                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     200                       
     201                        var walker = new CKEDITOR.dom.walker( range );
     202
     203                        var nodes = [],
     204                                node;
     205                        while ( node = walker.previous() )
     206                        {
     207                                nodes.push( node );
     208                        }
     209
     210                        assertNodesList( [ '' ], nodes );
     211                },
     212
     213                test_previous_4 : function()
     214                {
     215                        var node = doc.getById( 'playground' );
     216                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     217
     218                        var range = new CKEDITOR.dom.range( doc );
     219                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     220                        range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );
     221                       
     222                        var walker = new CKEDITOR.dom.walker( range );
     223
     224                        var nodes = [],
     225                                node;
     226                        while ( node = walker.previous() )
     227                        {
     228                                nodes.push( node );
     229                        }
     230
     231                        assertNodesList( [ '<p>' ], nodes );
     232                },
     233
     234                test_previous_5 : function()
     235                {
     236                        var node = doc.getById( 'playground' );
     237                        node.setHtml( '<p>Test</p><h1>More</h1>' );
     238
     239                        var range = new CKEDITOR.dom.range( doc );
     240                        range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
     241                        range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );
     242                       
     243                        var walker = new CKEDITOR.dom.walker( range );
     244
     245                        var nodes = [],
     246                                node;
     247                        while ( node = walker.previous() )
     248                        {
     249                                nodes.push( node );
     250                        }
     251
     252                        assertNodesList( [ '<p>' ], nodes );
     253                },
     254
     255                name : document.title
     256        };
     257})() );
     258
     259        //]]>
     260        </script>
     261</head>
     262<body>
     263        <div id="playground"></p>
     264</body>
     265</html>
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy