Ticket #3352: 3352_3.patch

File 3352_3.patch, 12.0 KB (added by garry.yao, 6 years ago)
  • _source/tests/plugins/domiterator/domiterator.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>Plugin: domiterator</title>
     5        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     6        <link rel="stylesheet" type="text/css" href="../../test.css" />
     7        <script type="text/javascript" src="../../../../ckeditor_source.js"></script>
     8        <script type="text/javascript" src="../../test.js"></script>
     9        <script type="text/javascript">
     10
     11CKEDITOR.plugins.load( [ 'htmldataprocessor', 'htmlwriter', 'domiterator'] );
     12
     13
     14        </script>
     15        <script type="text/javascript">
     16        //<![CDATA[
     17
     18/**
     19 * IE always returning CRLF for linefeed, so remove it when retrieve pre-formated text from text area.
     20 * @param {Object} id
     21 */     
     22function getTextAreaValue( id )
     23{
     24        return CKEDITOR.document.getById( id ).getValue().replace(/\r/gi,'');
     25}
     26
     27CKEDITOR.test.addTestCase( (function()
     28{
     29       
     30        // Local references.
     31        var assert = CKEDITOR.test.assert,
     32                arrayAssert = YAHOO.util.ArrayAssert;
     33       
     34        var doc = new CKEDITOR.dom.document( document );
     35
     36        // In these tests, we may "reset" the writer rules to avoid it formatting
     37        // the output, making the assertion easier to the done. We don't need to
     38        // test formatting features here, so this is ok.
     39        var getDataProcessor = function()
     40        {
     41                var dataProcessor = new CKEDITOR.htmlDataProcessor();
     42                dataProcessor.writer._.rules = [];
     43                return dataProcessor;
     44        };
     45
     46        /**
     47         * IE always returning CRLF for line-feed, so remove it when retrieving
     48         * pre-formated text from text area.
     49         */
     50        function getTextAreaValue( id )
     51        {
     52                return CKEDITOR.document.getById( id ).getValue().replace( /\r/gi, '' );
     53        }
     54
     55        function assumeElementContentAreSame( container, textareaId )
     56        {
     57                if( typeof container == 'string' )
     58                        container = doc.getById( container );
     59                //Assume result document content
     60                var html = getDataProcessor().toDataFormat( container.getHtml() );
     61                assert.areSame( getTextAreaValue( textareaId ) , html );
     62        }
     63       
     64        function assumeElementAreSame( element, textareaId )
     65        {
     66                if( typeof element == 'string' )
     67                        element = doc.getById( element );
     68                //Assume result document content
     69                var html = getDataProcessor().toDataFormat( element.getOuterHtml() );
     70                assert.areSame( getTextAreaValue( textareaId ) , html );
     71        }
     72       
     73        /**
     74         *
     75         * @param {String|CKEDITOR.dom.range} containerId|range Either the id of html container which contents are treated as range, or a exisiting range object.
     76         * @param {Object} iteratorOption
     77         * @param {Array} expectedTagList block elements tagName list in iteration orders.
     78         */
     79        function assumeIterationSameAs( containerIdOrRange, iteratorOption, expectedTagList )
     80        {
     81                var range;
     82                if( typeof containerIdOrRange == 'string' )
     83                {
     84                        range = new CKEDITOR.dom.range( doc );
     85                        range.selectNodeContents( doc.getById( containerIdOrRange ) );
     86                }
     87                else
     88                        range = containerIdOrRange;
     89                       
     90                var iter = range.createIterator();
     91                CKEDITOR.tools.extend( iter, iteratorOption, true );
     92                var blockList = [], block;
     93                while (( block = iter.getNextParagraph() ) )
     94                {
     95                        blockList.push( block.getName() );
     96                }
     97                arrayAssert.itemsAreEqual( expectedTagList, blockList );
     98        }
     99       
     100        return {
     101               
     102                /**
     103                 * Test iterating over table cells.
     104                 */
     105                test_iterator_table_cells : function()
     106                {
     107                        var range = new CKEDITOR.dom.range( doc );
     108                        range.setStartAt( doc.getById( 'iterTarget2a' ), CKEDITOR.POSITION_AFTER_START );
     109                        range.setEndAt( doc.getById( 'iterTarget2b' ), CKEDITOR.POSITION_BEFORE_END );
     110                        assumeIterationSameAs( range, null, [ 'th', 'p', 'td' ]);
     111                        assumeElementContentAreSame( 'iterContainer2', 'iterResult2' );
     112                },
     113
     114                /**
     115                 * Test iterating over list items.
     116                 */
     117                test_iterator_listItems : function()
     118                {
     119                        var range = new CKEDITOR.dom.range( doc );
     120                        range.setStartAt( doc.getById( 'iterTarget3a' ), CKEDITOR.POSITION_AFTER_START );
     121                        range.setEndAt( doc.getById( 'iterTarget3b' ), CKEDITOR.POSITION_BEFORE_END );
     122                        assumeIterationSameAs( range, null, [ 'li', 'p', 'li' ,'p', 'li' ]);
     123                        assumeElementContentAreSame( 'iterContainer3', 'iterResult3' );
     124                },
     125
     126                /**
     127                 * Test iterating over pseudo block.
     128                 */
     129                test_iterator_pseudoBlock : function()
     130                {
     131                        var range = new CKEDITOR.dom.range( doc );
     132                        range.setStartAt( doc.getById( 'iterTarget4a' ), CKEDITOR.POSITION_AFTER_START );
     133                        range.setEndAt( doc.getById( 'iterTarget4b' ), CKEDITOR.POSITION_BEFORE_END );
     134                        assumeIterationSameAs( range, null, [ 'p', 'div' ] );
     135                        assumeElementContentAreSame( 'iterContainer4', 'iterResult4' );
     136                },
     137
     138                /**
     139                 * Test collapsed range before paraghraph end.
     140                 */
     141                test_iterator_collapsed_before_paragraph : function()
     142                {
     143                        var range = new CKEDITOR.dom.range( doc );
     144                        range.setStartAt( doc.getById( 'iterTarget7' ), CKEDITOR.POSITION_BEFORE_END );
     145                        assumeIterationSameAs( range, null, [ 'p' ]);
     146                        assumeElementContentAreSame( 'iterContainer7', 'iterResult7' );
     147                },
     148
     149                /**
     150                 * Test range collapsed  inside paraghraph.
     151                 */
     152                test_iterator_collapsed_inside_paragraph : function()
     153                {
     154                        var range = new CKEDITOR.dom.range( doc );
     155                        range.setStart( doc.getById( 'para8' ).getFirst(), 3 );
     156                        assumeIterationSameAs( range, null, [ 'p' ]);
     157                        assumeElementContentAreSame( 'iterContainer8', 'iterResult8' );
     158                },
     159
     160                /**
     161                 * Test fix paragraph-less content.
     162                 */
     163                test_iterator_establish_paragraph: function()
     164                {
     165                        var range = new CKEDITOR.dom.range(doc);
     166                        range.setStartAt(doc.getById('iterTarget9'), CKEDITOR.POSITION_AFTER_START);
     167                        range.setEndAt(doc.getById('iterTarget9'), CKEDITOR.POSITION_BEFORE_END);
     168                        assumeIterationSameAs(range, null, ['p']);
     169                        assumeElementContentAreSame( 'iterContainer9', 'iterResult9');
     170                },
     171
     172                /**
     173                 * Test iterating over more than one paragraphs. (#3352)
     174                 */
     175                test_iterator_multiple_paragraphs: function()
     176                {
     177                        var range = new CKEDITOR.dom.range( doc );
     178                        range.setStartAt(doc.getById( 'iterTarget10a' ), CKEDITOR.POSITION_AFTER_START );
     179                        range.setEndAt(doc.getById( 'iterTarget10b' ), CKEDITOR.POSITION_BEFORE_END );
     180                        assumeIterationSameAs( range, null, [ 'p', 'p' ] );
     181                },
     182
     183                name : document.title
     184        };
     185})() );
     186
     187        //]]>
     188        </script>
     189</head>
     190<body>
     191
     192
     193<div id="iterContainer2"><table summary="summary">
     194        <caption>caption</caption>
     195        <tr>
     196                <th id="iterTarget2a">
     197                        head1</th>
     198        </tr>
     199        <tr>   
     200                <td><p>cell1</p></td>
     201        </tr>
     202        <tr>   
     203                <td id="iterTarget2b">cell2</td>
     204        </tr>
     205</table></div>
     206<textarea id="iterResult2"><table summary="summary"><caption>caption</caption><tbody><tr><th id="iterTarget2a">head1</th></tr><tr><td><p>cell1</p></td></tr><tr><td id="iterTarget2b">cell2</td></tr></tbody></table></textarea>
     207
     208<div id="iterContainer3"><ul>
     209        <li id="iterTarget3a">item1</li>
     210        <li><p>item2</p></li>
     211        <li>
     212                <ul><li>item3</li></ul>
     213                <ul><li><p>item5</p></li></ul>         
     214        </li>
     215        <li id="iterTarget3b">item5</li>       
     216        </ul></div>
     217<textarea id="iterResult3"><ul><li id="iterTarget3a">item1</li><li><p>item2</p></li><li><ul><li>item3</li></ul><ul><li><p>item5</p></li></ul></li><li id="iterTarget3b">item5</li></ul></textarea>
     218
     219<div id="iterContainer4">
     220        <div id="iterTarget4b"><p id="iterTarget4a">paragraph</p>text</div>
     221</div>
     222<textarea id="iterResult4"><div id="iterTarget4b"><p id="iterTarget4a">paragraph</p>text</div></textarea>
     223
     224<div id="iterContainer7"><p id="iterTarget7">paragraph</p></div>
     225<textarea id="iterResult7"><p id="iterTarget7">paragraph</p></textarea>
     226
     227<div id="iterContainer8"><p id="para8">paragraph</p></div>
     228<textarea id="iterResult8"><p id="para8">paragraph</p></textarea>
     229
     230<form id="iterContainer9"><span id="iterTarget9">non-paragraph</span></form>
     231<textarea id="iterResult9"><p><span id="iterTarget9">non-paragraph</span></p></textarea>
     232
     233<div id="iterContainer10"><p id="iterTarget10a">para1</p><p id="iterTarget10b">para2</p></div>
     234
     235</body>
     236</html>\ No newline at end of file
  • _source/plugins/domiterator/plugin.js

     
    1111
    1212(function()
    1313{
    14         // Functions ported over from v2.
    15         function getTouchedStartNode( range )
    16         {
    17                 var container = range.startContainer;
    18 
    19                 if ( range.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
    20                         return container;
    21 
    22                 return container.getChildCount() > range.startOffset ? container.getChild( range.startOffset ) : container;
    23         }
    24 
    25         function getTouchedEndNode( range )
    26         {
    27                 var container = range.endContainer;
    28 
    29                 if ( range.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
    30                         return container;
    31 
    32                 return container.getChildCount() > range.endOffset ? container.getChild( range.endOffset ) : container;
    33         }
    34 
    35         function getNextSourceNode( currentNode, startFromSibling, nodeType, stopSearchNode )
     14       
     15        /**
     16         * Find next source order node, ignore bookmark nodes and stop at the specified end node.
     17         * @param {Object} currentNode
     18         * @param {Object} endNode
     19         */
     20        function getNextSourceNode( currentNode, endNode, startFromSibling )
    3621        {
    37                 if ( !currentNode )
    38                         return null;
    39 
    40                 var node;
    41 
    42                 if ( !startFromSibling && currentNode.getFirst && currentNode.getFirst() )
    43                         node = currentNode.getFirst();
    44                 else
     22                var next = currentNode;
     23                do
    4524                {
    46                         if ( stopSearchNode && currentNode.equals( stopSearchNode ) )
    47                                 return null;
    48 
    49                         node = currentNode.getNext();
    50 
    51                         if ( !node && ( !stopSearchNode || !stopSearchNode.equals( currentNode.parentNode ) ) )
    52                                 return getNextSourceNode( currentNode.getParent(), true, nodeType, stopSearchNode );
     25                        next = next.getNextSourceNode(
     26                                startFromSibling, null, endNode );
    5327                }
    54 
    55                 if ( nodeType && node && node.type != nodeType )
    56                         return getNextSourceNode( node, false, nodeType, stopSearchNode );
    57 
    58                 return node;
     28                while( next && next.getName
     29                                        && next.getName() == 'span'
     30                                        && next.getAttribute( '_fck_bookmark' ) )
     31                return next;
    5932        }
    6033
    6134        var iterator = function( range )
     
    9265                        {
    9366                                range = this.range.clone();
    9467                                range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
    95 
    96                                 this._.nextNode = getTouchedStartNode( range );
    97                                 this._.lastNode = getTouchedEndNode( range );
     68                               
     69                                var boundary = range.getBoundaryNodes();
     70                                this._.nextNode = boundary.startNode;
     71                                this._.lastNode = boundary.endNode.getNextSourceNode();
    9872
    9973                                // Let's reuse this variable.
    10074                                range = null;
     
    231205
    232206                                if ( isLast )
    233207                                        break;
    234 
    235                                 currentNode = getNextSourceNode( currentNode, continueFromSibling, null, lastNode );
     208                               
     209                                currentNode = getNextSourceNode( currentNode, lastNode, continueFromSibling );
    236210                        }
    237211
    238212                        // Now, based on the processed range, look for (or create) the block to be returned.
     
    303277                                        // lists) or the next sibling <li>.
    304278
    305279                                        this._.nextNode = ( block.equals( lastNode ) ? null :
    306                                                         getNextSourceNode( range.getBoundaryNodes().endNode, true, null, lastNode ) );
     280                                                getNextSourceNode( range.getBoundaryNodes().endNode, lastNode, true ) );
    307281                                }
    308282                        }
    309283
     
    334308                        // above block can be removed or changed, so we can rely on it for the
    335309                        // next interation.
    336310                        if ( !this._.nextNode )
    337                                 this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null : getNextSourceNode( block, true, null, lastNode );
     311                                this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null :
     312                                        getNextSourceNode( block, lastNode, true );
    338313
    339314                        return block;
    340315                }
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy