Ticket #3475: 3475_6.patch
File 3475_6.patch, 35.6 KB (added by , 15 years ago) |
---|
-
_source/core/dom/rangelist.js
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 ( function() 6 { 7 /** 8 * Representation of multiple ranges within a selection. 9 * @param {CKEDITOR.dom.range | Array<{CKEDITOR.dom.range> | undefined } ranges 10 * The ranges consist of this list, note that if an array of ranges is specified, 11 * the range sequence should compliant with the selection order, this class is 12 * will not help to sort them. 13 */ 14 CKEDITOR.dom.rangeList = function( ranges ) 15 { 16 if ( typeof ranges == 'undefined' ) 17 ranges = []; 18 if( CKEDITOR.tools.isArray( ranges ) ) 19 ranges = ranges; 20 else if ( ranges instanceof CKEDITOR.dom.range ) 21 ranges = [ ranges ]; 22 else 23 throw 'Unknown ranges type.'; 24 25 var count = ranges.length; 26 27 /** 28 * Appending the specified range object to end of current list. 29 * @param { CKEDITOR.dom.range} range 30 * @example 31 * var rangeList = new CKEDITOR.dom.rangeList(); 32 * var range = new CKEDITOR.dom.range(); 33 * ... 34 * rangeList.add( range ); 35 * alert( rangeList.getItem( 0 ) ); 36 */ 37 this.add = function( range ) 38 { 39 ranges.push( range ); 40 count++; 41 }; 42 43 this.getItem = function( index ) 44 { 45 return ranges[ index ] || null; 46 }; 47 48 this.count = function() 49 { 50 return count; 51 }; 52 53 function iterator() 54 { 55 this._ = { 56 // // The current range under iteration. 57 // current : undefined, 58 // // The created bookmarks for the dirty ranges. 59 // bookmarks : [] 60 }; 61 } 62 63 iterator.prototype = { 64 65 getNextRange : function() 66 { 67 var current = this._.current; 68 if ( !count || current === count - 1 ) 69 return null; 70 else 71 current = typeof current == 'undefined' ? 0 : current + 1; 72 73 var range = ranges [ current ]; 74 75 // Multiple ranges might be mangled by previous. 76 if ( count > 1 ) 77 { 78 if ( !this._.bookmarks ) 79 this._.bookmarks = []; 80 81 // Bookmarking all other ranges on the first iteration. 82 if ( current == 0 ) 83 { 84 for ( var i = 1; i < count; i++ ) 85 { 86 this._.bookmarks.push( ranges[ i ].createBookmark() ); 87 } 88 } 89 // Update the _.current returning range. 90 else 91 { 92 range.moveToBookmark( this._.bookmarks.shift() ); 93 } 94 95 } 96 this._.current = current; 97 return range; 98 } 99 }; 100 101 /** 102 * Create an instance of rangeList iterator, it should be only used while 103 * the processing of each range is possibly polluting other ranges, e.g. destroy 104 * the following range's start container OR change others' offset value; 105 * Otherwise, simply iterating with {@link CKEDITOR.dom.rangeList::getItem} 106 * in a for loop. 107 */ 108 this.createIterator = function() 109 { 110 return new iterator(); 111 }; 112 113 // Update the specified range which has been mangled by previous insertion of 114 // range bookmark nodes.(#3256) 115 function updateDirtyRange( bookmark, dirtyRange , checkEnd ) 116 { 117 var serializable = bookmark.serializable, 118 container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ], 119 offset = checkEnd ? 'endOffset' : 'startOffset', 120 bookmarkStart = serializable ? 121 dirtyRange.document.getById( bookmark.startNode ) 122 : bookmark.startNode, 123 bookmarkEnd = serializable ? 124 dirtyRange.document.getById( bookmark.endNode ) 125 : bookmark.endNode; 126 127 if ( container.equals( bookmarkStart.getPrevious() ) ) 128 { 129 dirtyRange.startOffset = dirtyRange.startOffset 130 - container.getLength() - bookmarkEnd.getPrevious().getLength(); 131 container = bookmarkEnd.getNext(); 132 } 133 else if ( container.equals( bookmarkEnd.getPrevious() ) ) 134 { 135 dirtyRange.startOffset = dirtyRange.startOffset - container.getLength(); 136 container = bookmarkEnd.getNext(); 137 } 138 139 container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++; 140 container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++; 141 142 // Update and return this range. 143 dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container; 144 return dirtyRange; 145 } 146 147 this.createBookmarks = function( serializable ) 148 { 149 var retval = [], bookmark; 150 for ( var i = 0; i < count ; i++ ) 151 { 152 retval.push( bookmark = ranges[ i ]. 153 createBookmark( serializable, true) ); 154 // Updating the container & offset values for rest of ranges 155 // which have been mangled. 156 for ( var j = i + 1; j < count; j++ ) 157 { 158 ranges[ j ] = updateDirtyRange( bookmark, ranges[ j ] ); 159 ranges[ j ] = updateDirtyRange( bookmark, ranges[ j ], true ); 160 } 161 } 162 return retval; 163 }; 164 165 /** 166 * Apply each of the supplied bookmarks to the corresponding range at the index. 167 * @param bookmarks 168 */ 169 this.moveToBookmarks = function( bookmarks ) 170 { 171 for ( var i = 0 ; i < ranges.length ; i++ ) 172 ranges[ i ].moveToBookmark( bookmarks[ i ] ); 173 }; 174 175 this.createBookmarks2 = function( normalized ) 176 { 177 var bookmarks = []; 178 179 for ( var i = 0 ; i < ranges.length ; i++ ) 180 bookmarks.push( ranges[ i ].createBookmark2( normalized ) ); 181 182 return bookmarks; 183 }; 184 185 }; 186 187 188 189 } )(); -
_source/tests/core/dom/rangelist.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.rangelist</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 CKEDITOR.plugins.load( [ 'selection' ] ); 13 //]]> 14 </script> 15 <script type="text/javascript"> 16 //<![CDATA[ 17 var tc; 18 19 CKEDITOR.test.addTestCase( (function() 20 { 21 // Local references. 22 var assert = CKEDITOR.test.assert; 23 var doc = new CKEDITOR.dom.document( document ); 24 25 return tc = { 26 27 setUp : function() 28 { 29 doc.getById( 'playground').setHtml( '<p id="_P1">This is some <strong id="_B1">sample text</strong>. You are using</p>' ); 30 var sel = doc.getSelection(); 31 var range1 = new CKEDITOR.dom.range(); 32 range1.setStart( doc.getById( '_P1' ).getFirst(), 8 ); 33 range1.setEnd( doc.getById( '_B1' ).getFirst(), 2 ); 34 35 var range2 = new CKEDITOR.dom.range(); 36 range2.setStart( doc.getById( '_B1' ).getFirst(), 7 ); 37 range2.setEnd( doc.getById( '_P1' ).getChildren().getItem( 2 ), 5 ); 38 39 // <p id="_P1">This is [some <strong id="_B1">sa]mple [text</strong>. You] are using</p> 40 sel.selectRanges( new CKEDITOR.dom.rangeList( [ range1, range2 ] ) ); 41 }, 42 ///////////// 43 44 test_count_getItem : function() 45 { 46 var rangeList = doc.getSelection().getRanges(); 47 var count = rangeList.count(); 48 assert.areSame( 2, count ); 49 50 var range1 = rangeList.getItem( 0 ); 51 var range2 = rangeList.getItem( 1 ); 52 53 assert.areEqual( doc.getById( '_P1' ).getFirst().$, range1.startContainer.$ ); 54 assert.areEqual( 8, range1.startOffset ); 55 assert.areEqual( doc.getById( '_B1' ).getFirst().$, range1.endContainer.$ ); 56 assert.areEqual( 2, range1.endOffset ); 57 58 assert.areEqual( doc.getById( '_B1' ).getFirst().$, range2.startContainer.$ ); 59 assert.areEqual( 7, range2.startOffset ); 60 assert.areEqual( doc.getById( '_P1' ).getChildren().getItem( 2 ).$, range2.endContainer.$ ); 61 assert.areEqual( 5, range2.endOffset ); 62 }, 63 64 test_add : function() 65 { 66 var rangeList = doc.getSelection().getRanges(); 67 68 var range3 = new CKEDITOR.dom.range(); 69 range3.setStart( doc.getById( '_P1' ).getChildren().getItem( 2 ), 8 ); 70 range3.setEnd( doc.getById( '_P1' ).getChildren().getItem( 2 ), 14 ); 71 72 rangeList.add( range3 ); 73 74 doc.getSelection().selectRanges( rangeList ); 75 var range3 = doc.getSelection().getRanges().getItem( 2 ); 76 assert.areEqual( doc.getById( '_P1' ).getChildren().getItem( 2 ).$, range3.startContainer.$ ); 77 assert.areEqual( 8, range3.startOffset ); 78 assert.areEqual( doc.getById( '_P1' ).getChildren().getItem( 2 ).$, range3.endContainer.$ ); 79 assert.areEqual( 14, range3.endOffset ); 80 }, 81 82 test_createBookmarks : function() 83 { 84 85 var bookmarks = doc.getSelection().getRanges().createBookmarks(); 86 var range1 = new CKEDITOR.dom.range(); 87 range1.moveToBookmark( bookmarks[ 0 ] ); 88 var range2 = new CKEDITOR.dom.range(); 89 range2.moveToBookmark( bookmarks[ 1 ] ); 90 91 assert.areEqual( doc.getById( '_P1' ).$, range1.startContainer.$ ); 92 assert.areEqual( 1, range1.startOffset ); 93 assert.areEqual( doc.getById( '_B1' ).$, range1.endContainer.$ ); 94 assert.areEqual( 1, range1.endOffset ); 95 96 assert.areEqual( doc.getById( '_B1' ).$, range2.startContainer.$ ); 97 assert.areEqual( 2, range2.startOffset ); 98 assert.areEqual( doc.getById( '_P1' ).$, range2.endContainer.$ ); 99 assert.areEqual( 4, range2.endOffset ); 100 }, 101 102 test_iterator : function() 103 { 104 var sel = doc.getSelection(), 105 rangeList = sel.getRanges(), 106 iterator = rangeList.createIterator(), 107 range; 108 109 // Create bookmarks before iteration for easy comparison. 110 rangeList.moveToBookmarks( rangeList.createBookmarks() ); 111 var rangesBefore = [], rangesAfter = []; 112 for ( var i = 0 ; i < rangeList.count() ; i++ ) 113 { 114 rangesBefore.push( rangeList.getItem( i ).clone() ); 115 } 116 117 while( range = iterator.getNextRange() ) 118 { 119 var nextRange = rangeList.getItem( iterator._.current + 1 ); 120 // Destroy the next range. 121 nextRange && nextRange.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 122 rangesAfter.push( range ); 123 } 124 125 for( i = 0 ; i < rangesAfter.length ; i++ ) 126 { 127 var rangeBefore = rangesBefore[ i ], 128 rangeAfter = rangesAfter[ i ]; 129 assert.areSame( rangeBefore.startContainer.$, rangeAfter.startContainer.$ ); 130 assert.areSame( rangeBefore.startOffset, rangeAfter.startOffset ); 131 assert.areSame( rangeBefore.endContainer.$, rangeAfter.endContainer.$ ); 132 assert.areSame( rangeBefore.endOffset, rangeAfter.endOffset ); 133 } 134 }, 135 136 name : document.title 137 }; 138 })() ); 139 140 //window.onload = tests.test_iterator; 141 142 //]]> 143 </script> 144 </head> 145 <body> 146 <p id="playground"></p> 147 </body> 148 </html> -
_source/tests/testall.html
23 23 'core/dom/element', 24 24 'core/dom/node', 25 25 'core/dom/range', 26 'core/dom/rangelist', 26 27 'core/dom/text', 27 28 'core/dom/window', 28 29 'core/htmlparser/fragment', -
_source/plugins/pagebreak/plugin.js
82 82 83 83 var ranges = editor.getSelection().getRanges(); 84 84 85 for ( var range, i = 0 ; i < ranges. length; i++ )85 for ( var range, i = 0 ; i < ranges.count() ; i++ ) 86 86 { 87 range = ranges [ i ];87 range = ranges.getItem( i ); 88 88 89 89 if ( i > 0 ) 90 90 breakObject = breakObject.clone( true ); -
_source/plugins/link/dialogs/link.js
1001 1001 element = null, 1002 1002 me = this; 1003 1003 // Fill in all the relevant fields if there's already one link selected. 1004 if ( ranges. length == 1)1004 if ( ranges.count() ) 1005 1005 { 1006 1006 1007 var rangeRoot = ranges [0].getCommonAncestor( true );1007 var rangeRoot = ranges.getItem( 0 ).getCommonAncestor( true ); 1008 1008 element = rangeRoot.getAscendant( 'a', true ); 1009 1009 if ( element && element.getAttribute( 'href' ) ) 1010 1010 { … … 1128 1128 { 1129 1129 // Create element if current selection is collapsed. 1130 1130 var selection = editor.getSelection(), 1131 ranges = selection.getRanges(); 1132 if ( ranges.length == 1 && ranges[0].collapsed ) 1131 ranges = selection.getRanges(), 1132 range; 1133 if ( ranges.count() && 1134 ( range = ranges.getItem( 0 ) ) && range.collapsed ) 1133 1135 { 1134 1136 var text = new CKEDITOR.dom.text( attributes._cke_saved_href, editor.document ); 1135 range s[0].insertNode( text );1136 range s[0].selectNodeContents( text );1137 range.insertNode( text ); 1138 range.selectNodeContents( text ); 1137 1139 selection.selectRanges( ranges ); 1138 1140 } 1139 1141 -
_source/plugins/link/dialogs/anchor.js
6 6 CKEDITOR.dialog.add( 'anchor', function( editor ) 7 7 { 8 8 // Function called in onShow to load selected element. 9 var loadElements = function( e ditor, selection, ranges, element )9 var loadElements = function( element ) 10 10 { 11 11 this.editMode = true; 12 12 this.editObj = element; … … 63 63 64 64 var editor = this.getParentEditor(), 65 65 selection = editor.getSelection(), 66 ranges = selection.getRanges(); 66 ranges = selection.getRanges(), 67 range; 67 68 68 if ( ranges. length == 1)69 if ( ranges.count() ) 69 70 { 70 ranges[0].enlarge( CKEDITOR.ENLARGE_ELEMENT );71 var rangeRoot = range s[0].getCommonAncestor( true );71 ( range = ranges.getItem( 0 ) ).enlarge( CKEDITOR.ENLARGE_ELEMENT ); 72 var rangeRoot = range.getCommonAncestor( true ); 72 73 var element = rangeRoot.getAscendant( 'img', true ); 73 74 if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 74 75 { 75 76 this.fakeObj = element; 76 77 element = editor.restoreRealElement( this.fakeObj ); 77 loadElements. apply( this, [ editor, selection, ranges, element ]);78 loadElements.call( this, element ); 78 79 selection.selectElement( this.fakeObj ); 79 80 } 80 81 } -
_source/tests/plugins/list/list.html
113 113 114 114 setRange( range, [ 1, 0, 0, 0, 0 ], true ); 115 115 var sel = editor.getSelection(); 116 sel.selectRanges( [ range ]);116 sel.selectRanges( new CKEDITOR.dom.rangeList( range ) ); 117 117 118 118 // Waiting for 'comand state' effected. 119 119 this.wait( function(){ … … 255 255 256 256 setRange( range, [ 1, 0, 0, 0, 0 ], true ); 257 257 var sel = editor.getSelection(); 258 sel.selectRanges( [ range ]);258 sel.selectRanges( new CKEDITOR.dom.rangeList( range ) ); 259 259 260 260 // Waiting for 'comand state' effected. 261 261 this.wait( function(){ -
_source/plugins/wysiwygarea/plugin.js
70 70 71 71 var range, clone, lastElement, bookmark; 72 72 73 for ( var i = ranges. length- 1 ; i >= 0 ; i-- )73 for ( var i = ranges.count() - 1 ; i >= 0 ; i-- ) 74 74 { 75 range = ranges[ i ]; 76 75 range = ranges.getItem( i ); 77 76 // Remove the original contents. 78 77 range.deleteContents(); 79 78 … … 103 102 if ( next && next.type == CKEDITOR.NODE_ELEMENT ) 104 103 range.moveToElementEditStart( next ); 105 104 106 selection.selectRanges( [ range ]);105 selection.selectRanges( new CKEDITOR.dom.rangeList( range ) ); 107 106 108 107 if ( selIsLocked ) 109 108 this.getSelection().lock(); … … 128 127 path = evt.data.path, 129 128 blockLimit = path.blockLimit, 130 129 selection = evt.data.selection, 131 range = selection.getRanges() [0],130 range = selection.getRanges().getItem( 0 ), 132 131 body = editor.document.getBody(), 133 132 enterMode = editor.config.enterMode; 134 133 -
_source/plugins/removeformat/plugin.js
34 34 35 35 var ranges = editor.getSelection().getRanges(); 36 36 37 for ( var i = 0, range ; range = ranges[ i ]; i++ )37 for ( var range, i = 0 ; i < ranges.count() ; i++ ) 38 38 { 39 39 if ( range.collapsed ) 40 40 continue; -
_source/plugins/find/dialogs/find.js
242 242 this.removeHighlight(); 243 243 244 244 // Apply the highlight. 245 var range = this.toDomRange(); 245 var range = this.toDomRange(), 246 bookmark = range.createBookmark(); 246 247 highlightStyle.applyToRange( range ); 248 range.moveToBookmark( bookmark ); 247 249 this._.highlightRange = range; 248 250 249 251 // Scroll the editor to the highlighted area. … … 264 266 if ( !this._.highlightRange ) 265 267 return; 266 268 269 var bookmark = this._.highlightRange.createBookmark(); 267 270 highlightStyle.removeFromRange( this._.highlightRange ); 271 this._.highlightRange.moveToBookmark( bookmark ); 268 272 this.updateFromDomRange( this._.highlightRange ); 269 273 this._.highlightRange = null; 270 274 }, … … 547 551 { 548 552 var searchRange, 549 553 sel = editor.getSelection(), 554 ranges, 550 555 body = editor.document.getBody(); 551 if ( sel && !isDefault ) 556 if ( !isDefault && sel 557 && ( ranges = sel.getRanges() ) && ranges.count() ) 552 558 { 553 searchRange = sel.getRanges()[ 0 ].clone();559 searchRange = ranges.getItem( 0 ).clone(); 554 560 searchRange.collapse( true ); 555 561 } 556 562 else -
_source/plugins/table/dialogs/table.js
41 41 if ( selectedTable.getName() != 'table' ) 42 42 selectedTable = null; 43 43 } 44 else if ( ranges. length > 0)44 else if ( ranges.count() ) 45 45 { 46 var rangeRoot = ranges [0].getCommonAncestor( true );46 var rangeRoot = ranges.getItem( 0 ).getCommonAncestor( true ); 47 47 selectedTable = rangeRoot.getAscendant( 'table', true ); 48 48 } 49 49 -
ckeditor.pack
123 123 '_source/core/dom/domwalker.js', 124 124 '_source/core/dom/walker.js', 125 125 '_source/core/dom/range.js', 126 '_source/core/dom/rangelist.js', 126 127 '_source/core/_bootstrap.js', 127 128 // '_source/lang/en.js', 128 129 '_source/plugins/about/plugin.js', -
_source/plugins/list/plugin.js
361 361 ranges = selection && selection.getRanges(); 362 362 363 363 // There should be at least one selected range. 364 if ( !ranges || ranges.length < 1)364 if ( !ranges.count() ) 365 365 return; 366 366 367 367 // Midas lists rule #1 says we can create a list even in an empty document. … … 376 376 var paragraph = doc.createElement( editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 377 377 ( editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'br' ) ); 378 378 paragraph.appendTo( body ); 379 ranges = [ new CKEDITOR.dom.range( doc ) ];379 ranges = new CKEDITOR.dom.rangeList( new CKEDITOR.dom.range( doc ) ); 380 380 // IE exception on inserting anything when anchor inside <br>. 381 381 if ( paragraph.is( 'br' ) ) 382 382 { 383 ranges [ 0 ].setStartBefore( paragraph );384 ranges [ 0 ].setEndAfter( paragraph );383 ranges.getItem( 0 ).setStartBefore( paragraph ); 384 ranges.getItem( 0 ).setEndAfter( paragraph ); 385 385 } 386 386 else 387 ranges [ 0 ].selectNodeContents( paragraph );387 ranges.getItem( 0 ).selectNodeContents( paragraph ); 388 388 selection.selectRanges( ranges ); 389 389 } 390 390 } … … 396 396 var listGroups = [], 397 397 database = {}; 398 398 399 while ( ranges.length > 0)399 for ( var range, i = 0 ; i < ranges.count() ; i++ ) 400 400 { 401 var range = ranges.shift(),402 boundaryNodes = range.getBoundaryNodes(),401 range = ranges.getItem( i ); 402 var boundaryNodes = range.getBoundaryNodes(), 403 403 startNode = boundaryNodes.startNode, 404 404 endNode = boundaryNodes.endNode; 405 405 if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' ) -
_source/plugins/link/plugin.js
166 166 rangeRoot, 167 167 element; 168 168 169 for ( var i = 0 ; i < ranges.length; i++ )169 for ( var range, i = 0 ; i < ranges.count() ; i++ ) 170 170 { 171 rangeRoot = ranges[i].getCommonAncestor( true ); 171 range = ranges.getItem( i ); 172 rangeRoot = range.getCommonAncestor( true ); 172 173 element = rangeRoot.getAscendant( 'a', true ); 173 174 if ( !element ) 174 175 continue; 175 range s[i].selectNodeContents( element );176 range.selectNodeContents( element ); 176 177 } 177 178 178 179 selection.selectRanges( ranges ); -
_source/plugins/styles/plugin.js
299 299 // Get the DTD definition for the element. Defaults to "span". 300 300 var dtd = CKEDITOR.dtd[ elementName ] || ( isUnknownElement = true, CKEDITOR.dtd.span ); 301 301 302 // Bookmark the range so we can re-select it after processing.303 var bookmark = range.createBookmark();304 305 302 // Expand the range. 306 303 range.enlarge( CKEDITOR.ENLARGE_ELEMENT ); 307 304 range.trim(); … … 497 494 } 498 495 } 499 496 500 // this._FixBookmarkStart( startNode );501 502 range.moveToBookmark( bookmark );503 497 } 504 498 505 499 function removeInlineStyle( range ) … … 623 617 624 618 function applyBlockStyle( range ) 625 619 { 626 // Bookmark the range so we can re-select it after processing.627 var bookmark = range.createBookmark();628 629 620 var iterator = range.createIterator(); 630 621 iterator.enforceRealBlocks = true; 631 622 … … 668 659 // this._CheckAndSplitPre( newBlock ) ; // Split <br><br> in successive <pre>s. 669 660 } 670 661 671 range.moveToBookmark( bookmark );672 662 } 673 663 674 664 // Removes a style from an element itself, don't care about its subtree. … … 1000 990 1001 991 function applyStyle( document, remove ) 1002 992 { 1003 // Get all ranges from the selection. 1004 var selection = document.getSelection(); 1005 var ranges = selection.getRanges(); 1006 var func = remove ? this.removeFromRange : this.applyToRange; 993 var selection = document.getSelection(), 994 // Bookmark the range so we can re-select it after processing. 995 bookmarks = selection.createBookmarks(), 996 func = remove ? this.removeFromRange : this.applyToRange, 997 range; 1007 998 1008 // Apply the style to the ranges.1009 for ( var i = 0 ; i < ranges.length ; i++)1010 func.call( this, range s[ i ]);999 var iterator = selection.getRanges().createIterator(); 1000 while ( range = iterator.getNextRange() ) 1001 func.call( this, range ); 1011 1002 1012 // Select the ranges again. 1013 selection.selectRanges( ranges ); 1003 selection.selectBookmarks( bookmarks ); 1014 1004 } 1015 1005 })(); 1016 1006 -
_source/plugins/enterkey/plugin.js
312 312 var ranges = editor.getSelection().getRanges(); 313 313 314 314 // Delete the contents of all ranges except the first one. 315 for ( var i = ranges. length- 1 ; i > 0 ; i-- )315 for ( var i = ranges.count() - 1 ; i > 0 ; i-- ) 316 316 { 317 ranges [ i ].deleteContents();317 ranges.getItem( i ).deleteContents(); 318 318 } 319 319 320 320 // Return the first range. 321 return ranges [ 0 ];321 return ranges.getItem( 0 ); 322 322 } 323 323 })(); -
_source/plugins/justify/plugin.js
77 77 var cssClassName = this.cssClassName, 78 78 iterator, 79 79 block; 80 for ( var i = ranges. length - 1 ; i >= 0 ; i-- )80 for ( var i = ranges.count() - 1 ; i >= 0 ; i-- ) 81 81 { 82 iterator = ranges [ i ].createIterator();82 iterator = ranges.getItem( i ).createIterator(); 83 83 while ( ( block = iterator.getNextParagraph() ) ) 84 84 { 85 85 block.removeAttribute( 'align' ); -
_source/plugins/tabletools/plugin.js
41 41 } 42 42 } 43 43 44 for ( var i = 0 ; i < ranges. length; i++ )44 for ( var i = 0 ; i < ranges.count() ; i++ ) 45 45 { 46 var range = ranges [ i ];46 var range = ranges.getItem( i ); 47 47 48 48 if ( range.collapsed ) 49 49 { … … 438 438 439 439 // Maintain the selection point at where the table was deleted. 440 440 selection.selectElement( table ); 441 var range = selection.getRanges()[0];442 range .collapse();443 selection.selectRanges( [ range ]);441 var ranges = selection.getRanges(); 442 ranges.getItem( 0 ).collapse(); 443 selection.selectRanges( ranges ); 444 444 445 445 // If the table's parent has only one child, remove it as well. 446 446 if ( table.getParent().getChildCount() == 1 ) -
_source/plugins/selection/plugin.js
537 537 boundaryInfo = getBoundaryInformation( nativeRange ); 538 538 range.setEnd( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset ); 539 539 540 return ( cache.ranges = [ range ]);540 return ( cache.ranges = new CKEDITOR.dom.rangeList( range ) ); 541 541 } 542 542 else if ( type == CKEDITOR.SELECTION_ELEMENT ) 543 543 { 544 var retval = this._.cache.ranges = [];544 var retval = this._.cache.ranges = new CKEDITOR.dom.rangeList(); 545 545 546 546 for ( var i = 0 ; i < nativeRange.length ; i++ ) 547 547 { … … 556 556 557 557 range.setStart( new CKEDITOR.dom.node( parentElement ), j ); 558 558 range.setEnd( new CKEDITOR.dom.node( parentElement ), j + 1 ); 559 retval. push( range );559 retval.add( range ); 560 560 } 561 561 562 562 return retval; 563 563 } 564 564 565 return ( cache.ranges = []);565 return ( cache.ranges = new CKEDITOR.dom.rangeList() ); 566 566 }; 567 567 })() 568 568 : … … 576 576 // tranform the native ranges in CKEDITOR.dom.range 577 577 // instances. 578 578 579 var ranges = [];579 var ranges = new CKEDITOR.dom.rangeList(); 580 580 var sel = this.getNative(); 581 581 582 if ( !sel ) 583 return []; 584 585 for ( var i = 0 ; i < sel.rangeCount ; i++ ) 586 { 587 var nativeRange = sel.getRangeAt( i ); 588 var range = new CKEDITOR.dom.range( this.document ); 582 if( sel ) 583 for ( var i = 0 ; i < sel.rangeCount ; i++ ) 584 { 585 var nativeRange = sel.getRangeAt( i ); 586 var range = new CKEDITOR.dom.range( this.document ); 589 587 590 range.setStart( new CKEDITOR.dom.node( nativeRange.startContainer ), nativeRange.startOffset );591 range.setEnd( new CKEDITOR.dom.node( nativeRange.endContainer ), nativeRange.endOffset );592 ranges.push( range );593 }588 range.setStart( new CKEDITOR.dom.node( nativeRange.startContainer ), nativeRange.startOffset ); 589 range.setEnd( new CKEDITOR.dom.node( nativeRange.endContainer ), nativeRange.endOffset ); 590 ranges.add( range ); 591 } 594 592 595 593 return ( cache.ranges = ranges ); 596 594 }, … … 619 617 620 618 case CKEDITOR.SELECTION_TEXT : 621 619 622 var range = this.getRanges() [0];620 var range = this.getRanges().getItem( 0 ); 623 621 624 622 if ( range ) 625 623 { … … 783 781 784 782 this._.cache.selectedElement = element; 785 783 this._.cache.startElement = element; 786 this._.cache.ranges = [ range ];784 this._.cache.ranges = new CKEDITOR.dom.rangeList( range ); 787 785 this._.cache.type = CKEDITOR.SELECTION_ELEMENT; 788 786 789 787 return; … … 825 823 } 826 824 }, 827 825 828 selectRanges : function( range s)826 selectRanges : function( rangeList ) 829 827 { 830 828 if ( this.isLocked ) 831 829 { 832 830 this._.cache.selectedElement = null; 833 this._.cache.startElement = range s[ 0 ].getTouchedStartNode();834 this._.cache.ranges = range s;831 this._.cache.startElement = rangeList.getItem( 0 ).getTouchedStartNode(); 832 this._.cache.ranges = rangeList; 835 833 this._.cache.type = CKEDITOR.SELECTION_TEXT; 836 834 837 835 return; … … 841 839 { 842 840 // IE doesn't accept multiple ranges selection, so we just 843 841 // select the first one. 844 if ( range s[ 0 ])845 range s[ 0 ].select();842 if ( rangeList.count() ) 843 rangeList.getItem( 0 ).select(); 846 844 847 845 this.reset(); 848 846 } … … 851 849 var sel = this.getNative(); 852 850 sel.removeAllRanges(); 853 851 854 for ( var i = 0 ; i < range s.length; i++ )852 for ( var i = 0 ; i < rangeList.count() ; i++ ) 855 853 { 856 var range = range s[ i ];854 var range = rangeList.getItem( i ); 857 855 var nativeRange = this.document.$.createRange(); 858 856 nativeRange.setStart( range.startContainer.$, range.startOffset ); 859 857 nativeRange.setEnd( range.endContainer.$, range.endOffset ); … … 868 866 869 867 createBookmarks : function( serializable ) 870 868 { 871 var retval = [], 872 ranges = this.getRanges(), 873 length = ranges.length, 874 bookmark; 875 for ( var i = 0; i < length ; i++ ) 876 { 877 retval.push( bookmark = ranges[ i ].createBookmark( serializable, true ) ); 878 879 var serializable = bookmark.serializable, 880 bookmarkStart = serializable ? 881 this.document.getById( bookmark.startNode ) 882 : bookmark.startNode, 883 bookmarkEnd = serializable ? 884 this.document.getById( bookmark.endNode ) 885 : bookmark.endNode; 886 887 // Updating the offset values for rest of ranges which have been mangled(#3256). 888 for ( var j = i + 1 ; j < length ; j++ ) 889 { 890 var dirtyRange = ranges[ j ], 891 rangeStart = dirtyRange.startContainer, 892 rangeEnd = dirtyRange.endContainer; 893 894 rangeStart.equals( bookmarkStart.getParent() ) && dirtyRange.startOffset++; 895 rangeStart.equals( bookmarkEnd.getParent() ) && dirtyRange.startOffset++; 896 rangeEnd.equals( bookmarkStart.getParent() ) && dirtyRange.endOffset++; 897 rangeEnd.equals( bookmarkEnd.getParent() ) && dirtyRange.endOffset++; 898 } 899 } 900 901 return retval; 869 return this.getRanges().createBookmarks( serializable ); 902 870 }, 903 871 904 872 createBookmarks2 : function( normalized ) 905 873 { 906 var bookmarks = [], 907 ranges = this.getRanges(); 908 909 for ( var i = 0 ; i < ranges.length ; i++ ) 910 bookmarks.push( ranges[i].createBookmark2( normalized ) ); 911 912 return bookmarks; 874 return this.getRanges().createBookmarks2( normalized ); 913 875 }, 914 876 915 877 selectBookmarks : function( bookmarks ) 916 878 { 917 var ranges = [];879 var ranges = new CKEDITOR.dom.rangeList(); 918 880 for ( var i = 0 ; i < bookmarks.length ; i++ ) 919 881 { 920 882 var range = new CKEDITOR.dom.range( this.document ); 921 883 range.moveToBookmark( bookmarks[i] ); 922 ranges. push( range );884 ranges.add( range ); 923 885 } 924 886 this.selectRanges( ranges ); 925 887 return this; 926 888 } 889 927 890 }; 891 928 892 })(); 929 893 930 894 CKEDITOR.dom.range.prototype.select = -
_source/plugins/blockquote/plugin.js
47 47 { 48 48 var state = editor.getCommand( 'blockquote' ).state, 49 49 selection = editor.getSelection(), 50 range = selection && selection.getRanges()[0]; 50 ranges = selection && selection.getRanges(), 51 range = ranges.count() && ranges.getItem( 0 ); 51 52 52 53 if ( !range ) 53 54 return; -
_source/plugins/indent/plugin.js
219 219 exec : function( editor ) 220 220 { 221 221 var selection = editor.getSelection(), 222 range = selection && selection.getRanges() [0];222 range = selection && selection.getRanges().getItem( 0 ); 223 223 224 224 if ( !selection || !range ) 225 225 return; -
_source/core/loader.js
23 24 // Table of script names and their dependencies. 24 25 var scripts = 25 26 { 26 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/elementpath', 'core/dom/text', 'core/dom/range' ],27 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/elementpath', 'core/dom/text', 'core/dom/range', 'core/dom/rangelist' ], 27 28 'core/ajax' : [ 'core/xml' ], 28 29 'core/ckeditor' : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ], 29 30 'core/ckeditor_base' : [], … … 41 42 'core/dom/domobject' : [ 'core/dom/event' ], 42 43 'core/dom/domwalker' : [ 'core/dom/node', 'core/dom/element', 'core/dom/document' ], 43 44 'core/dom/range' : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/domwalker', 'core/dom/walker' ], 45 'core/dom/rangelist' : [ 'core/dom/range' ], 44 46 'core/dom/text' : [ 'core/dom/node', 'core/dom/domobject' ], 45 47 'core/dom/walker' : [ 'core/dom/node' ], 46 48 'core/dom/window' : [ 'core/dom/domobject' ],