2 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license
\r
9 * Represents a list os CKEDITOR.dom.range objects, which can be easily
\r
10 * iterated sequentially.
\r
12 * @param {CKEDITOR.dom.range|Array} [ranges] The ranges contained on this list.
\r
13 * Note that, if an array of ranges is specified, the range sequence
\r
14 * should match its DOM order. This class will not help to sort them.
\r
16 CKEDITOR.dom.rangeList = function( ranges )
\r
18 if ( ranges instanceof CKEDITOR.dom.rangeList )
\r
23 else if ( ranges instanceof CKEDITOR.dom.range )
\r
24 ranges = [ ranges ];
\r
26 return CKEDITOR.tools.extend( ranges, mixins );
\r
30 /** @lends CKEDITOR.dom.rangeList.prototype */
\r
33 * Creates an instance of the rangeList iterator, it should be used
\r
34 * only when the ranges processing could be DOM intrusive, which
\r
35 * means it may pollute and break other ranges in this list.
\r
36 * Otherwise, it's enough to just iterate over this array in a for loop.
\r
37 * @returns {CKEDITOR.dom.rangeListIterator}
\r
39 createIterator : function()
\r
41 var rangeList = this,
\r
46 * @lends CKEDITOR.dom.rangeListIterator.prototype
\r
51 * Retrieves the next range in the list.
\r
53 getNextRange : function()
\r
55 current = current == undefined ? 0 : current + 1;
\r
57 var range = rangeList[ current ];
\r
59 // Multiple ranges might be mangled by each other.
\r
60 if ( range && rangeList.length > 1 )
\r
62 // Bookmarking all other ranges on the first iteration,
\r
63 // the range correctness after it doesn't matter since we'll
\r
64 // restore them before the next iteration.
\r
67 // Make sure bookmark correctness by reverse processing.
\r
68 for ( var i = rangeList.length - 1; i > 0; i-- )
\r
69 bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
\r
72 range.moveToBookmark( bookmarks.shift() );
\r
80 createBookmarks : function( serializable )
\r
82 var retval = [], bookmark;
\r
83 for ( var i = 0; i < this.length ; i++ )
\r
85 retval.push( bookmark = this[ i ].createBookmark( serializable, true) );
\r
87 // Updating the container & offset values for ranges
\r
88 // that have been touched.
\r
89 for ( var j = i + 1; j < this.length; j++ )
\r
91 this[ j ] = updateDirtyRange( bookmark, this[ j ] );
\r
92 this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
\r
98 createBookmarks2 : function( normalized )
\r
100 var bookmarks = [];
\r
102 for ( var i = 0 ; i < this.length ; i++ )
\r
103 bookmarks.push( this[ i ].createBookmark2( normalized ) );
\r
109 * Move each range in the list to the position specified by a list of bookmarks.
\r
110 * @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
\r
112 moveToBookmarks : function( bookmarks )
\r
114 for ( var i = 0 ; i < this.length ; i++ )
\r
115 this[ i ].moveToBookmark( bookmarks[ i ] );
\r
119 // Update the specified range which has been mangled by previous insertion of
\r
120 // range bookmark nodes.(#3256)
\r
121 function updateDirtyRange( bookmark, dirtyRange, checkEnd )
\r
123 var serializable = bookmark.serializable,
\r
124 container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
\r
125 offset = checkEnd ? 'endOffset' : 'startOffset';
\r
127 var bookmarkStart = serializable ?
\r
128 dirtyRange.document.getById( bookmark.startNode )
\r
129 : bookmark.startNode;
\r
131 var bookmarkEnd = serializable ?
\r
132 dirtyRange.document.getById( bookmark.endNode )
\r
133 : bookmark.endNode;
\r
135 if ( container.equals( bookmarkStart.getPrevious() ) )
\r
137 dirtyRange.startOffset = dirtyRange.startOffset
\r
138 - container.getLength()
\r
139 - bookmarkEnd.getPrevious().getLength();
\r
140 container = bookmarkEnd.getNext();
\r
142 else if ( container.equals( bookmarkEnd.getPrevious() ) )
\r
144 dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
\r
145 container = bookmarkEnd.getNext();
\r
148 container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
\r
149 container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
\r
151 // Update and return this range.
\r
152 dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
\r
158 * (Virtual Class) Do not call this constructor. This class is not really part
\r
159 * of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
\r
160 * @name CKEDITOR.dom.rangeListIterator
\r