Ticket #6485: 6485_5.patch
File 6485_5.patch, 10.3 KB (added by , 14 years ago) |
---|
-
_source/plugins/bidi/plugin.js
1 /* 1 /* 2 2 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 3 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 4 */ 5 5 6 6 (function() 7 7 { 8 var guardElements = { table:1, ul:1, ol:1, blockquote:1, div:1 },8 var guardElements = { table:1, tbody: 1, ul:1, ol:1, blockquote:1, div:1, tr: 1 }, 9 9 directSelectionGuardElements = {}, 10 10 // All guard elements which can have a direction applied on them. 11 11 allGuardElements = {}; … … 130 130 return null; 131 131 } 132 132 133 function getFullySelected( selection, elements )133 function getFullySelected( range, elements ) 134 134 { 135 var ancestor = selection.getCommonAncestor(); 136 if ( ancestor.type != CKEDITOR.NODE_ELEMENT ) 137 return; 135 var ancestor = range.getCommonAncestor( false, true ); 138 136 139 var ranges = selection.getRanges();140 141 // Join multiple ranges.142 var range = new CKEDITOR.dom.range( selection.document );143 range.setStart( ranges[ 0 ].startContainer, ranges[ 0 ].startOffset );144 range.setEnd( ranges[ ranges.length - 1 ].endContainer, ranges[ ranges.length - 1 ].endOffset );145 146 137 range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 147 138 148 139 if ( range.checkBoundaryOfElement( ancestor, CKEDITOR.START ) 149 140 && range.checkBoundaryOfElement( ancestor, CKEDITOR.END ) ) 150 141 { 151 while ( ancestor.type == CKEDITOR.NODE_ELEMENT 152 && !( ancestor.getName() in elements ) 153 && ancestor.getParent().getChildCount() == 1 142 var parent; 143 while ( ancestor && ancestor.type == CKEDITOR.NODE_ELEMENT 144 && ( parent = ancestor.getParent() ) 145 && parent.getChildCount() == 1 146 && ( !( ancestor.getName() in elements ) || ( parent.getName() in elements ) ) 154 147 ) 155 ancestor = ancestor.getParent();148 ancestor = parent; 156 149 157 150 return ancestor.type == CKEDITOR.NODE_ELEMENT 158 151 && ( ancestor.getName() in elements ) … … 171 164 if ( ranges && ranges.length ) 172 165 { 173 166 var database = {}; 174 // Apply do directly selected elements from guardElements. 175 var selectedElement = ranges[ 0 ].getEnclosedNode(); 167 168 // Creates bookmarks for selection, as we may split some blocks. 169 var bookmarks = selection.createBookmarks(); 170 171 var rangeIterator = ranges.createIterator(), 172 range, 173 i = 0; 174 175 while ( ( range = rangeIterator.getNextRange( 1 ) ) ) 176 { 177 // Apply do directly selected elements from guardElements. 178 var selectedElement = range.getEnclosedNode(); 176 179 177 // If this is not our element of interest, apply to fully selected elements from guardElements.178 if ( !selectedElement || selectedElement179 && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements )180 )181 selectedElement = getFullySelected( selection, guardElements );180 // If this is not our element of interest, apply to fully selected elements from guardElements. 181 if ( !selectedElement || selectedElement 182 && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements ) 183 ) 184 selectedElement = getFullySelected( range, guardElements ); 182 185 183 if ( selectedElement && !selectedElement.isReadOnly() ) 184 switchDir( selectedElement, dir, editor, database ); 185 186 // Creates bookmarks for selection, as we may split some blocks. 187 var bookmarks = selection.createBookmarks(); 188 189 var iterator, 190 block; 186 if ( selectedElement && !selectedElement.isReadOnly() ) 187 switchDir( selectedElement, dir, editor, database ); 188 189 var iterator, 190 block; 191 191 192 for ( var i = ranges.length - 1 ; i >= 0 ; i-- )193 {194 // Array of elements processed as guardElements.195 var processedElements = [];196 192 // Walker searching for guardElements. 197 var walker = new CKEDITOR.dom.walker( ranges[ i ] ); 193 var walker = new CKEDITOR.dom.walker( range ); 194 195 var start = bookmarks[ i ].startNode, 196 end = bookmarks[ i++ ].endNode; 197 198 198 walker.evaluator = function( node ) 199 199 { 200 return node.type == CKEDITOR.NODE_ELEMENT 201 && node.getName() in guardElements 202 && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div' 203 && node.getParent().type == CKEDITOR.NODE_ELEMENT 204 && node.getParent().getName() == 'blockquote' 205 ); 200 return !! ( node.type == CKEDITOR.NODE_ELEMENT 201 && node.getName() in guardElements 202 && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div' 203 && node.getParent().type == CKEDITOR.NODE_ELEMENT 204 && node.getParent().getName() == 'blockquote' ) 205 // Element must be fully included in the range as well. (#6485). 206 && node.getPosition( start ) & CKEDITOR.POSITION_FOLLOWING 207 && ( ( node.getPosition( end ) & CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_CONTAINS ) == CKEDITOR.POSITION_PRECEDING ) ); 206 208 }; 207 209 208 210 while ( ( block = walker.next() ) ) 209 211 switchDir( block, dir, editor, database ); 210 212 211 iterator = range s[ i ].createIterator();213 iterator = range.createIterator(); 212 214 iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; 213 215 214 216 while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) 215 217 !block.isReadOnly() && switchDir( block, dir, editor, database ); 218 } 216 219 217 220 CKEDITOR.dom.element.clearAllMarkers( database ); 218 221 219 editor.forceNextSelectionCheck(); 220 // Restore selection position. 221 selection.selectBookmarks( bookmarks ); 222 } 222 editor.forceNextSelectionCheck(); 223 // Restore selection position. 224 selection.selectBookmarks( bookmarks ); 223 225 224 226 editor.focus(); 225 227 } -
_source/core/dom/walker.js
385 385 && isBookmarkNode( parent ) ); 386 386 // Is bookmark node? 387 387 isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node ); 388 return isReject ^ isBookmark;388 return !! ( isReject ^ isBookmark ); 389 389 }; 390 390 }; 391 391 … … 399 399 { 400 400 var isWhitespace = node && ( node.type == CKEDITOR.NODE_TEXT ) 401 401 && !CKEDITOR.tools.trim( node.getText() ); 402 return isReject ^ isWhitespace;402 return !! ( isReject ^ isWhitespace ); 403 403 }; 404 404 }; 405 405 … … 418 418 // 'offsetHeight' instead of 'offsetWidth' for properly excluding 419 419 // all sorts of empty paragraph, e.g. <br />. 420 420 var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight; 421 return isReject ^ isInvisible;421 return !! ( isReject ^ isInvisible ); 422 422 }; 423 423 }; 424 424 -
_source/plugins/domiterator/plugin.js
65 65 CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 66 66 67 67 var walker = new CKEDITOR.dom.walker( range ), 68 ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );68 ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( false, true ); 69 69 // Avoid anchor inside bookmark inner text. 70 70 walker.evaluator = ignoreBookmarkTextEvaluator; 71 71 this._.nextNode = walker.next(); -
_source/core/dom/rangelist.js
39 39 createIterator : function() 40 40 { 41 41 var rangeList = this, 42 bookmarks = [], 42 bookmark = CKEDITOR.dom.walker.bookmark(), 43 emptySpaces = CKEDITOR.dom.walker.whitespaces(), 44 guard = function( node ) { return ! ( node.is && node.is( 'tr' ) ); }, 45 bookmarks = [], 43 46 current; 44 47 45 48 /** … … 49 52 50 53 /** 51 54 * Retrieves the next range in the list. 55 * @param {Boolean} mergeConsequent Whether join two adjacent ranges into single, e.g. consequent table cells. 52 56 */ 53 getNextRange : function( )57 getNextRange : function( mergeConsequent ) 54 58 { 55 59 current = current == undefined ? 0 : current + 1; 56 60 … … 65 69 if ( !current ) 66 70 { 67 71 // Make sure bookmark correctness by reverse processing. 68 for ( var i = rangeList.length - 1; i > 0; i-- )72 for ( var i = rangeList.length - 1; i >= 0; i-- ) 69 73 bookmarks.unshift( rangeList[ i ].createBookmark( true ) ); 70 74 } 71 else 72 range.moveToBookmark( bookmarks.shift() ); 73 } 75 76 if ( mergeConsequent ) 77 { 78 // Figure out how many ranges should be merged. 79 var mergeCount = 0; 80 while ( rangeList[ current + mergeCount + 1 ] ) 81 { 82 var doc = range.document, 83 found = 0, 84 left = doc.getById( bookmarks[ mergeCount ].endNode ), 85 right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ), 86 next; 87 88 // Check subsequent range. 89 while ( 1 ) 90 { 91 next = left.getNextSourceNode( false ); 92 if ( !right.equals( next ) ) 93 { 94 // This could be yet another bookmark or 95 // walking across block boundaries. 96 if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) 97 { 98 left = next; 99 continue; 100 } 101 } 102 else 103 found = 1; 104 105 break; 106 } 107 108 if ( !found ) 109 break; 110 111 mergeCount++; 112 } 113 } 114 115 range.moveToBookmark( bookmarks.shift() ); 116 117 // Merge ranges finally after moving to bookmarks. 118 while( mergeCount-- ) 119 { 120 var next = rangeList[ ++current ]; 121 next.moveToBookmark( bookmarks.shift() ); 122 range.setEnd( next.endContainer, next.endOffset ); 123 } 124 } 74 125 75 126 return range; 76 127 }