Ticket #3352: 3352_3.patch

File 3352_3.patch, 12.0 KB (added by garry.yao, 5 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