Ticket #3051: 3051.patch
File 3051.patch, 15.5 KB (added by , 16 years ago) |
---|
-
_source/tests/plugins/domiterator/domiterator_10.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 11 CKEDITOR.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 */ 22 function getTextAreaValue( id ) 23 { 24 return CKEDITOR.document.getById( id ).getValue().replace(/\r/gi,''); 25 } 26 27 var tc; 28 CKEDITOR.test.addTestCase( tc = (function() 29 { 30 31 // Local references. 32 var assert = CKEDITOR.test.assert, 33 arrayAssert = YAHOO.util.ArrayAssert; 34 35 var doc = new CKEDITOR.dom.document( document ); 36 37 // In these tests, we may "reset" the writer rules to avoid it formatting 38 // the output, making the assertion easier to the done. We don't need to 39 // test formatting features here, so this is ok. 40 var getDataProcessor = function() 41 { 42 var dataProcessor = new CKEDITOR.htmlDataProcessor(); 43 dataProcessor.writer._.rules = []; 44 return dataProcessor; 45 }; 46 47 /** 48 * IE always returning CRLF for line-feed, so remove it when retrieving 49 * pre-formated text from text area. 50 */ 51 function getTextAreaValue( id ) 52 { 53 return CKEDITOR.document.getById( id ).getValue().replace( /\r/gi, '' ); 54 } 55 56 function assumeElementContentAreSame( container, textareaId ) 57 { 58 if( typeof container == 'string' ) 59 container = doc.getById( container ); 60 //Assume result document content 61 var html = getDataProcessor().toDataFormat( container.getHtml() ); 62 assert.areSame( getTextAreaValue( textareaId ) , html ); 63 } 64 65 function assumeElementAreSame( element, textareaId ) 66 { 67 if( typeof element == 'string' ) 68 element = doc.getById( element ); 69 //Assume result document content 70 var html = getDataProcessor().toDataFormat( element.getOuterHtml() ); 71 assert.areSame( getTextAreaValue( textareaId ) , html ); 72 } 73 74 /** 75 * 76 * @param {String|CKEDITOR.dom.range} containerId|range Either the id of html container which contents are treated as range, or a exisiting range object. 77 * @param {Object} iteratorOption 78 * @param {Array} expectedTagList block elements tagName list in iteration orders. 79 */ 80 function assumeIterationSameAs( containerIdOrRange, iteratorOption, expectedTagList ) 81 { 82 var range; 83 if( typeof containerIdOrRange == 'string' ) 84 { 85 range = new CKEDITOR.dom.range( doc ); 86 range.selectNodeContents( doc.getById( containerIdOrRange ) ); 87 } 88 else 89 range = containerIdOrRange; 90 91 var iter = range.createIterator(); 92 CKEDITOR.tools.extend( iter, iteratorOption, true ); 93 var blockList = [], block; 94 while (( block = iter.getNextParagraph() ) ) 95 { 96 blockList.push( block.getName() ); 97 } 98 arrayAssert.itemsAreEqual( expectedTagList, blockList ); 99 } 100 101 return { 102 103 /** 104 * Test 'enforceRealBlocks' option toggled on which establish new paragraph for pseudo paragraphs 105 */ 106 test_iterator6 : function() 107 { 108 assumeIterationSameAs( 'iterContainer6', { enforceRealBlocks: true}, [ 'p', 'p' ], 'iterResult6' ); 109 assumeElementContentAreSame( 'iterContainer6', 'iterResult6' ); 110 }, 111 112 /** 113 * Test 'enforceRealBlocks' option with multiple pseudo blocks. 114 */ 115 test_iterator7 : function() 116 { 117 var range = new CKEDITOR.dom.range(doc); 118 range.setEndAt( doc.getById( 'iterContainer7' ), CKEDITOR.POSITION_BEFORE_END ); 119 assumeIterationSameAs( range, { enforceRealBlocks: true }, [ 'p' ], 'iterResult7' ); 120 assumeElementContentAreSame( 'iterContainer7', 'iterResult7' ); 121 }, 122 123 /** 124 * Test 'enforceRealBlocks' option with multiple pseudo blocks. 125 */ 126 test_iterator8 : function() 127 { 128 var range = new CKEDITOR.dom.range(doc); 129 range.setEndAt( doc.getById( 'iterContainer8' ), CKEDITOR.POSITION_AFTER_START ); 130 assumeIterationSameAs( range, { enforceRealBlocks: true }, [ 'p' ], 'iterResult8' ); 131 assumeElementContentAreSame( 'iterContainer8', 'iterResult8' ); 132 }, 133 134 name : document.title 135 }; 136 })() ); 137 138 //window.onload = tc.test_iterator8; 139 //]]> 140 </script> 141 </head> 142 <body> 143 <div id="iterContainer6"><p>paragraph</p>text</div> 144 <textarea id="iterResult6"><p>paragraph</p><p>text</p></textarea> 145 146 <div id="iterContainer7">text<p>paragraph</p>text</div> 147 <textarea id="iterResult7">text<p>paragraph</p><p>text</p></textarea> 148 149 <div id="iterContainer8">text<p>paragraph</p>text</div> 150 <textarea id="iterResult8"><p>text</p><p>paragraph</p>text</textarea> 151 152 </body> 153 </html> -
_source/tests/core/dom/range_enlarge_pseudoBlock.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.range</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 13 var tc; 14 15 CKEDITOR.test.addTestCase( tc = ( function() 16 { 17 // Local references. 18 var assert = CKEDITOR.test.assert, 19 arrayAssert = YAHOO.util.ArrayAssert; 20 21 var doc = new CKEDITOR.dom.document( document ); 22 23 /** 24 * Set the range with the start/end position specified by the locator, which in form of bookmark2. 25 * @param {Object} range 26 * @param {Array} startPosition range start path including offset 27 * @param {Array|Boolean} endPositoin range end path including offset or is collapsed 28 */ 29 function setRange( range, startPosition, endPositoin ) 30 { 31 var bm = { 32 end : null, 33 start : null, 34 is2: true, 35 startOffset : 0, 36 endoffset : 0 37 }; 38 bm.start = startPosition.slice( 0, startPosition.length - 1 ); 39 bm.startOffset = startPosition[ startPosition.length -1]; 40 if( endPositoin === true ) 41 { 42 bm.end = bm.start.slice(); 43 bm.endOffset = bm.startOffset; 44 } 45 else 46 { 47 bm.end = endPositoin.slice( 0, endPositoin.length - 1 ); 48 bm.endOffset = endPositoin[ endPositoin.length -1 ]; 49 } 50 range.moveToBookmark( bm ); 51 } 52 53 function assumeRangeAreSame( range, startPosition, endPosition ){ 54 55 var bm = range.createBookmark2(); 56 bm.start.push( bm.startOffset ); 57 bm.end.push( bm.endOffset ); 58 arrayAssert.itemsAreEqual( startPosition, bm.start ); 59 if( endPosition !== true ) 60 arrayAssert.itemsAreEqual( endPosition, bm.end ); 61 } 62 63 return { 64 65 /** 66 * Test enlarge pseudo block of text node with range collapsed after it. 67 */ 68 test_enlarge_element_pseudoBlock : function() 69 { 70 //<div><p>paragraph</p>pseudoBlock^</div> 71 //<div><p>paragraph</p>[pseudoBlock]</div> 72 var range = new CKEDITOR.dom.range( doc ); 73 setRange( range, [ 1, 1, 2 ], true ) 74 range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 75 assumeRangeAreSame( range, [ 1, 1, 1 ], [ 1, 1, 2 ] ); 76 }, 77 78 /** 79 * Test enlarge pseudo block of text node with range collapsed before it. 80 */ 81 test_enlarge_element_pseudoBlock2 : function() 82 { 83 //<div>^pseudoBlock<p>paragraph</p></div> 84 //<div>[pseudoBlock]<p>paragraph</p></div> 85 var range = new CKEDITOR.dom.range( doc ); 86 setRange( range, [ 1, 3, 0 ], true ) 87 range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 88 assumeRangeAreSame( range, [ 1, 3, 0 ], [ 1, 3, 1 ] ); 89 }, 90 91 /** 92 * Test enlarge pseudo block of inline element with range collapsed before it. 93 */ 94 test_enlarge_element_pseudoBlock3 : function() 95 { 96 //<div>^<span>inline</span><b>inline</b><p>paragraph</p></div> 97 //<div>[<span>inline</span><b>inline</b>]<p>paragraph</p></div> 98 var range = new CKEDITOR.dom.range( doc ); 99 setRange( range, [ 1, 5, 0 ], true ) 100 range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 101 assumeRangeAreSame( range, [ 1, 5, 0 ], [ 1, 5, 2 ] ); 102 }, 103 104 /** 105 * Test enlarge pseudo block of inline element with range collapsed after it. 106 */ 107 test_enlarge_element_pseudoBlock4 : function() 108 { 109 //<div><p>paragraph</p><span>inline</span><b>inline</b>^</div> 110 //<div><p>paragraph</p>[<span>inline</span><b>inline</b>]</div> 111 var range = new CKEDITOR.dom.range( doc ); 112 setRange( range, [ 1, 7, 3 ], true ) 113 range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 114 assumeRangeAreSame( range, [ 1, 7, 1 ], [ 1, 7, 3 ] ); 115 }, 116 117 name : document.title 118 }; 119 })() ); 120 121 //window.onload = tc.test_enlarge_element_pseudoBlock3; 122 123 //]]> 124 </script> 125 </head> 126 <body> 127 <div><p>paragraph</p>pseudoBlock</div> 128 <div>pseudoBlock<p>paragraph</p></div> 129 <div><span>inline</span><b>inline</b><p>paragraph</p></div> 130 <div><p>paragraph</p><span>inline</span><b>inline</b></div> 131 </body> 132 </html> -
_source/plugins/domiterator/plugin.js
91 91 if ( !this._.lastNode ) 92 92 { 93 93 range = this.range.clone(); 94 range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 94 range.enlarge( this.forceBrBreak ? 95 CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 95 96 96 97 this._.nextNode = getTouchedStartNode( range ); 97 98 this._.lastNode = getTouchedEndNode( range ); … … 142 143 if ( range ) 143 144 { 144 145 range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START ); 146 147 if ( isLast = currentNode.equals( lastNode ) ); 148 break; 145 149 146 150 // The found boundary must be set as the next one at this 147 151 // point. (#1717) -
_source/core/dom/range.js
580 580 { 581 581 childCount = startNode.getChildCount(); 582 582 if ( childCount > startOffset ) 583 { 583 584 startNode = startNode.getChild( startOffset ); 585 586 if ( this.collapsed ) 587 startNode = startNode.getPreviousSourceNode( true ); 588 } 584 589 else if ( childCount < 1 ) 585 startNode = startNode.getPreviousSourceNode( );590 startNode = startNode.getPreviousSourceNode( true ); 586 591 else // startOffset > childCount but childCount is not 0 587 592 { 588 593 // Try to take the node just after the current position. … … 594 599 // Normally we should take the next node in DFS order. But it 595 600 // is also possible that we've already reached the end of 596 601 // document. 597 startNode = startNode.getNextSourceNode() || startNode; 602 if ( !this.collapsed ) 603 startNode = startNode.getNextSourceNode( true ) || startNode; 598 604 } 599 605 } 600 606 if ( endNode.type == CKEDITOR.NODE_ELEMENT ) … … 601 607 { 602 608 childCount = endNode.getChildCount(); 603 609 if ( childCount > endOffset ) 604 endNode = endNode.getChild( endOffset ).getPreviousSourceNode(); 610 { 611 endNode = endNode.getChild( endOffset ); 612 613 if( !this.collapsed ) 614 endNode = endNode.getPreviousSourceNode( true ); 615 } 605 616 else if ( childCount < 1 ) 606 endNode = endNode.getPreviousSourceNode( );617 endNode = endNode.getPreviousSourceNode( true ); 607 618 else // endOffset > childCount but childCount is not 0 608 619 { 609 620 // Try to take the node just before the current position. … … 608 619 { 609 620 // Try to take the node just before the current position. 610 621 endNode = endNode.$; 611 while ( endNode.lastChild ) 612 endNode = endNode.lastChild; 613 endNode = new CKEDITOR.dom.node( endNode ); 622 623 if( !this.collapsed ) 624 while ( endNode.lastChild ) 625 endNode = endNode.lastChild; 626 endNode = new CKEDITOR.dom.node( endNode ); 614 627 } 615 628 } 616 629 … … 1094 1107 1095 1108 case CKEDITOR.ENLARGE_BLOCK_CONTENTS: 1096 1109 case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS: 1110 1111 // Get the function used to check the enlarging limits. 1112 var guardFunction = ( unit == CKEDITOR.ENLARGE_BLOCK_CONTENTS ? 1113 CKEDITOR.dom.domWalker.blockBoundary() : 1114 CKEDITOR.dom.domWalker.listItemBoundary() ); 1115 1097 1116 // DFS backward to get the block/list item boundary at or before the start. 1098 1117 1099 1118 // Get the boundaries nodes. 1100 var startNode = this.getTouchedStartNode(), 1101 endNode = this.getTouchedEndNode(); 1119 var boundaries = this.getBoundaryNodes(), 1120 startNode = boundaries.startNode, 1121 endNode = boundaries.endNode; 1122 // var startNode = this.getTouchedStartNode(), 1123 // endNode = this.getTouchedEndNode(); 1102 1124 1103 1125 if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.isBlockBoundary() ) 1104 1126 { … … 1109 1131 } 1110 1132 else 1111 1133 { 1112 // Get the function used to check the enlaarging limits.1113 var guardFunction = ( unit == CKEDITOR.ENLARGE_BLOCK_CONTENTS ?1114 CKEDITOR.dom.domWalker.blockBoundary() :1115 CKEDITOR.dom.domWalker.listItemBoundary() );1116 1117 1134 // Create the DOM walker, which will traverse the DOM. 1118 1135 var walker = new CKEDITOR.dom.domWalker( startNode ); 1119 1136 … … 1134 1151 } 1135 1152 else 1136 1153 { 1154 // Create the DOM walker, which will traverse the DOM. 1155 walker = new CKEDITOR.dom.domWalker( endNode ); 1156 1137 1157 // DFS forward to get the block/list item boundary at or before the end. 1138 walker.setNode( endNode );1139 1158 data = walker.forward( guardFunction ); 1140 boundaryEvent = data.events. shift();1159 boundaryEvent = data.events.pop(); 1141 1160 1142 1161 this.setEndAfter( boundaryEvent.from ); 1143 1162 } -
_source/core/dom/node.js
288 288 { 289 289 var $ = this.$; 290 290 291 var node = ( !startFromSibling && $.firstChild ) ? 292 $.firstChild : 293 $.nextSibling; 291 var node = startFromSibling? 292 ( $.nextSibling || $.firstChild ) : 293 $.firstChild; 294 294 295 295 296 var parent; 296 297 … … 310 311 { 311 312 var $ = this.$; 312 313 313 var node = ( !startFromSibling && $.lastChild ) ?314 $.lastChild :315 $.previousSibling;314 var node = startFromSibling ? 315 ( $.previousSibling || $.parentNode ) 316 : $.parentNode; 316 317 317 318 var parent; 318 319