Ticket #3176: 3176.patch
File 3176.patch, 8.8 KB (added by , 14 years ago) |
---|
-
_source/plugins/find/dialogs/find.js
8 8 // Element tag names which prevent characters counting. 9 9 var characterBoundaryElementsEnum = 10 10 { 11 address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,11 body : 1, address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1, 12 12 h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1 13 13 }; 14 14 … … 27 27 */ 28 28 var cursorStep = function() 29 29 { 30 if( !this.textNode ) 31 return null; 32 30 33 var obj = { 31 34 textNode : this.textNode, 32 35 offset : this.offset, 33 character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null,36 character : this.textNode.getText().charAt( this.offset ), 34 37 hitMatchBoundary : this._.matchBoundary 35 38 }; 36 39 return obj; … … 88 91 }; 89 92 90 93 characterWalker.prototype = { 94 95 current : function() 96 { 97 return cursorStep.call( this ); 98 }, 99 91 100 next : function() 92 101 { 93 102 // Already at the end of document, no more character available. … … 92 101 { 93 102 // Already at the end of document, no more character available. 94 103 if( this.textNode == null ) 95 return cursorStep.call( this );104 return null; 96 105 97 106 this._.matchBoundary = false; 98 107 … … 107 116 108 117 // If we are at the end of the text node, use dom walker to get 109 118 // the next text node. 110 var data = null; 111 while ( !data || ( data.node && data.node.type != 112 CKEDITOR.NODE_TEXT ) ) 119 var data; 120 do 113 121 { 114 122 data = this._.walker.forward( 115 123 guardDomWalkerNonEmptyTextNode ); … … 119 127 || ( data.node.type !== CKEDITOR.NODE_TEXT 120 128 && data.node.getName() in 121 129 characterBoundaryElementsEnum ) ) 130 { 122 131 this._.matchBoundary = true; 132 133 // Scope to content within body. 134 if ( data.node && data.node.getName() == 'body' ) 135 { 136 data.textNode = null; 137 break; 138 } 139 } 123 140 } 141 while ( data.node && data.node.type != 142 CKEDITOR.NODE_TEXT ) 143 124 144 this.textNode = data.node; 125 145 this.offset = 0; 126 146 return cursorStep.call( this ); … … 128 148 129 149 back : function() 130 150 { 151 // Already at the start of document, no more character available. 152 if( this.textNode == null ) 153 return null; 154 131 155 this._.matchBoundary = false; 132 156 133 157 // More characters -> decrement offset and return. … … 139 163 140 164 // Start of text node -> use dom walker to get the previous text node. 141 165 var data = null; 142 while ( !data 143 || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) ) 166 do 144 167 { 145 168 data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode ); 146 169 … … 147 170 // Block boundary? BR? Document boundary? 148 171 if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT && 149 172 data.node.getName() in characterBoundaryElementsEnum ) ) 173 { 150 174 this._.matchBoundary = true; 175 176 // Scope to characters within body 177 if ( data.node && data.node.getName() == 'body' ) 178 { 179 data.node = null; 180 break; 181 } 182 } 151 183 } 184 while ( data.node && data.node.type != 185 CKEDITOR.NODE_TEXT ) 152 186 this.textNode = data.node; 153 this.offset = data.node.length - 1;187 this.offset = this.textNode? data.node.length - 1 : 0; 154 188 return cursorStep.call( this ); 155 189 } 156 190 }; … … 194 228 var startNode = domRange.startContainer, 195 229 startIndex = domRange.startOffset, 196 230 endNode = domRange.endContainer, 197 endIndex = domRange.endOffset, 198 boundaryNodes = domRange.getBoundaryNodes(); 231 endIndex = domRange.endOffset; 199 232 200 233 if ( startNode.type != CKEDITOR.NODE_TEXT ) 201 234 { 202 startNode = boundaryNodes.startNode;235 startNode = domRange.getTouchedStartNode(); 203 236 while ( startNode.type != CKEDITOR.NODE_TEXT ) 204 startNode = startNode.get First();237 startNode = startNode.getNextSourceNode(); 205 238 startIndex = 0; 206 239 } 207 240 … … 207 240 208 241 if ( endNode.type != CKEDITOR.NODE_TEXT ) 209 242 { 210 endNode = boundaryNodes.endNode;243 endNode = domRange.getTouchedEndNode(); 211 244 while ( endNode.type != CKEDITOR.NODE_TEXT ) 212 endNode = endNode.get Last();213 endIndex = endNode.getLength() ;245 endNode = endNode.getPreviousSourceNode(); 246 endIndex = endNode.getLength() - 1; 214 247 } 215 248 216 249 // If the endNode is an empty text node, our walker would just walk through … … 216 249 // If the endNode is an empty text node, our walker would just walk through 217 250 // it without stopping. So need to backtrack to the nearest non-emtpy text 218 251 // node. 219 if ( endNode .getLength() < 1 )252 if ( endNode && endNode.getLength() < 1 ) 220 253 { 221 while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) ) ;222 endIndex = endNode.getLength();254 while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) ) 255 endIndex = endNode.getLength() - 1; 223 256 } 224 257 225 var cursor = new characterWalker( startNode, startIndex ); 226 this._.cursors = [ cursor ]; 227 if ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) ) 258 var walker = new characterWalker( startNode, startIndex ), cursor; 259 260 // DomRange contains at least one character. 261 ( this._.cursors = [] ).push( cursor = walker.current() ); 262 do 228 263 { 229 do 230 { 231 cursor = new characterWalker( cursor ); 232 cursor.next(); 233 this._.cursors.push( cursor ); 234 } 235 while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) ); 264 cursor = walker.next(); 265 this._.cursors.push( cursor ); 236 266 } 267 while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex ) ) 237 268 238 269 this._.rangeLength = this._.cursors.length; 239 270 }, … … 301 332 var retval = this._.walker.back(), 302 333 cursors = this._.cursors; 303 334 304 if ( retval.hitMatchBoundary )335 if ( !retval || retval.hitMatchBoundary ) 305 336 this._.cursors = cursors = []; 306 337 if( retval ) 338 { 307 339 cursors.unshift( retval ); 308 340 if ( cursors.length > this._.rangeLength ) 309 341 cursors.pop(); 342 } 310 343 311 344 return retval; 312 345 }, … … 317 350 cursors = this._.cursors; 318 351 319 352 // Clear the cursors queue if we've crossed a match boundary. 320 if ( retval.hitMatchBoundary )353 if ( !retval || retval.hitMatchBoundary ) 321 354 this._.cursors = cursors = []; 322 323 cursors.push( retval ); 324 if ( cursors.length > this._.rangeLength ) 325 cursors.shift(); 355 356 if ( retval ) 357 { 358 cursors.push( retval ); 359 if ( cursors.length > this._.rangeLength ) 360 cursors.shift(); 361 } 326 362 327 363 return retval; 328 364 }, … … 452 488 matchState = matcher.feedCharacter( character ); 453 489 if ( matchState == KMP_MATCHED ) 454 490 break; 455 if ( this.range.moveNext().hitMatchBoundary ) 491 var next = this.range.moveNext(); 492 if ( next && next.hitMatchBoundary ) 456 493 matcher.reset(); 457 494 } 458 495 … … 464 501 tail = cursors[ cursors.length - 1 ], 465 502 head = cursors[ 0 ], 466 503 headWalker = new characterWalker( head ), 467 tailWalker = new characterWalker( tail ); 504 tailWalker = new characterWalker( tail ), 505 headBoundaryCursor = headWalker.back(), 506 tailBoundaryCursor = tailWalker.next(); 468 507 469 if ( ! ( isWordSeparator( 470 headWalker.back().character ) 471 && isWordSeparator( 472 tailWalker.next().character ) ) ) 473 continue; 508 if ( !( ( !headBoundaryCursor 509 || headBoundaryCursor.hitMatchBoundary 510 || isWordSeparator( headBoundaryCursor.character ) ) 511 && 512 ( !tailBoundaryCursor 513 || tailBoundaryCursor.hitMatchBoundary 514 || isWordSeparator( tailBoundaryCursor.character ) ) ) ) 515 { 516 matchState = KMP_NOMATCH; 517 matcher.reset(); 518 continue; 519 } 474 520 } 475 521 476 522 this.range.setMatched(); -
_source/core/dom/range.js
1503 1503 if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT ) 1504 1504 return container ; 1505 1505 1506 return container.getChild [ this.endOffset - 1 ]|| container ;1506 return container.getChild( this.endOffset - 1 )|| container ; 1507 1507 } 1508 1508 }; 1509 1509 })();