Index: trunk/extensions/VisualEditor/modules/es/bases/es.DocumentBranchNode.js |
— | — | @@ -282,11 +282,12 @@ |
283 | 283 | * @method |
284 | 284 | * @param {es.Range} range Range to select nodes within |
285 | 285 | * @param {Boolean} [shallow] Do not recurse into child nodes of child nodes |
| 286 | + * @param {Number} [offset] Used for recursive invocations. Callers should not pass this parameter |
286 | 287 | * @returns {Array} List of objects with 'node', 'range' and 'globalRange' properties describing nodes which are |
287 | 288 | * covered by the range and the range within the node that is covered. If an entire node is covered, 'range' is |
288 | 289 | * absent but 'globalRange' is still set |
289 | 290 | */ |
290 | | -es.DocumentBranchNode.prototype.selectNodes = function( range, shallow ) { |
| 291 | +es.DocumentBranchNode.prototype.selectNodes = function( range, shallow, offset ) { |
291 | 292 | if ( typeof range === 'undefined' ) { |
292 | 293 | range = new es.Range( 0, this.model.getContentLength() ); |
293 | 294 | } else { |
— | — | @@ -301,8 +302,8 @@ |
302 | 303 | end = range.end, |
303 | 304 | startInside, |
304 | 305 | endInside, |
305 | | - childNode, |
306 | | - result; |
| 306 | + childNode; |
| 307 | + offset = offset || 0; |
307 | 308 | |
308 | 309 | if ( start < 0 ) { |
309 | 310 | throw 'The start offset of the range is negative'; |
— | — | @@ -314,7 +315,7 @@ |
315 | 316 | if ( end > this.getContentLength() ) { |
316 | 317 | throw 'The end offset of the range is past the end of the node'; |
317 | 318 | } |
318 | | - return [{ 'node': this, 'range': new es.Range( start, end ), 'globalRange': new es.Range( start, end ) }]; |
| 319 | + return [{ 'node': this, 'range': new es.Range( start, end ), 'globalRange': new es.Range( start + offset, end + offset ) }]; |
319 | 320 | } |
320 | 321 | |
321 | 322 | // This node has children, loop over them |
— | — | @@ -326,7 +327,7 @@ |
327 | 328 | |
328 | 329 | if ( start == end && ( start == left - 1 || start == right + 1 ) ) { |
329 | 330 | // Empty range outside of any node |
330 | | - return [{ 'node': this, 'range': new es.Range( start, end ), 'globalRange': new es.Range( start, end ) }]; |
| 331 | + return [{ 'node': this, 'range': new es.Range( start, end ), 'globalRange': new es.Range( start + offset, end + offset ) }]; |
331 | 332 | } |
332 | 333 | |
333 | 334 | startInside = start >= left && start <= right; // is the start inside childNode? |
— | — | @@ -344,19 +345,12 @@ |
345 | 346 | { |
346 | 347 | 'node': childNode, |
347 | 348 | 'range': new es.Range( start - left, end - left ), |
348 | | - 'globalRange': new es.Range( start, end ) |
| 349 | + 'globalRange': new es.Range( start + offset, end + offset ) |
349 | 350 | } |
350 | 351 | ]; |
351 | 352 | } else { |
352 | 353 | // Recurse into childNode |
353 | | - nodes = childNode.selectNodes( new es.Range( start - left, end - left ) ); |
354 | | - // Adjust globalRange |
355 | | - // TODO: do this with an extra parameter |
356 | | - for ( j = 0; j < nodes.length; j++ ) { |
357 | | - if ( nodes[j].globalRange !== undefined ) { |
358 | | - nodes[j].globalRange = es.Range.newFromTranslatedRange( nodes[j].globalRange, left ); |
359 | | - } |
360 | | - } |
| 354 | + nodes = childNode.selectNodes( new es.Range( start - left, end - left ), false, left + offset ); |
361 | 355 | } |
362 | 356 | // Since the start and end are both inside childNode, we know for sure that we're |
363 | 357 | // done, so return |
— | — | @@ -368,18 +362,10 @@ |
369 | 363 | nodes.push( { |
370 | 364 | 'node': childNode, |
371 | 365 | 'range': new es.Range( start - left, right - left ), |
372 | | - 'globalRange': new es.Range( start, right ) |
| 366 | + 'globalRange': new es.Range( start + offset, right + offset ) |
373 | 367 | } ); |
374 | 368 | } else { |
375 | | - result = childNode.selectNodes( new es.Range( start - left, right - left ) ); |
376 | | - // Adjust globalRange |
377 | | - // TODO: do this with an extra parameter |
378 | | - for ( j = 0; j < result.length; j++ ) { |
379 | | - if ( result[j].globalRange !== undefined ) { |
380 | | - result[j].globalRange = es.Range.newFromTranslatedRange( result[j].globalRange, left ); |
381 | | - } |
382 | | - } |
383 | | - nodes = nodes.concat( result ); |
| 369 | + nodes = nodes.concat( childNode.selectNodes( new es.Range( start - left, right - left ), false, left + offset ) ); |
384 | 370 | } |
385 | 371 | } else if ( endInside ) { |
386 | 372 | // The end is inside childNode but the start isn't |
— | — | @@ -388,18 +374,10 @@ |
389 | 375 | nodes.push( { |
390 | 376 | 'node': childNode, |
391 | 377 | 'range': new es.Range( 0, end - left ), |
392 | | - 'globalRange': new es.Range( left, end ) |
| 378 | + 'globalRange': new es.Range( left + offset, end + offset ) |
393 | 379 | } ); |
394 | 380 | } else { |
395 | | - result = childNode.selectNodes( new es.Range( 0, end - left ) ); |
396 | | - // Adjust globalRange |
397 | | - // TODO: do this with an extra parameter |
398 | | - for ( j = 0; j < result.length; j++ ) { |
399 | | - if ( result[j].globalRange !== undefined ) { |
400 | | - result[j].globalRange = es.Range.newFromTranslatedRange( result[j].globalRange, left ); |
401 | | - } |
402 | | - } |
403 | | - nodes = nodes.concat( result ); |
| 381 | + nodes = nodes.concat( childNode.selectNodes( new es.Range( 0, end - left ), false, left + offset ) ); |
404 | 382 | } |
405 | 383 | // We've found the end, so we're done |
406 | 384 | return nodes; |
— | — | @@ -407,19 +385,19 @@ |
408 | 386 | // end is between childNode and this.children[i+1] |
409 | 387 | // start is not inside childNode, so the selection covers |
410 | 388 | // all of childNode, then ends |
411 | | - nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1, right + 1 ) } ); |
| 389 | + nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1 + offset, right + 1 + offset ) } ); |
412 | 390 | // We've reached the end so we're done |
413 | 391 | return nodes; |
414 | 392 | } else if ( start == left - 1 ) { |
415 | 393 | // start is between this.children[i-1] and childNode |
416 | 394 | // end is not inside childNode, so the selection covers |
417 | 395 | // all of childNode and more |
418 | | - nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1, right + 1 ) } ); |
| 396 | + nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1 + offset, right + 1 + offset ) } ); |
419 | 397 | } else if ( nodes.length > 0 ) { |
420 | 398 | // Neither the start nor the end is inside childNode, but nodes is non-empty, |
421 | 399 | // so childNode must be between the start and the end |
422 | 400 | // Add the entire node, so no range property |
423 | | - nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1, right + 1 ) } ); |
| 401 | + nodes.push( { 'node': childNode, 'globalRange': new es.Range( left - 1 + offset, right + 1 + offset ) } ); |
424 | 402 | } |
425 | 403 | |
426 | 404 | // Move left to the start of this.children[i+1] for the next iteration |