Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js |
— | — | @@ -446,27 +446,41 @@ |
447 | 447 | * This method is pretty expensive. If you need to get different slices of the same content, get |
448 | 448 | * the content first, then slice it up locally. |
449 | 449 | * |
450 | | - * TODO: Rewrite this method to not use recursion, because the function call overhead is expensive |
451 | | - * |
452 | 450 | * @method |
453 | 451 | * @param {es.DocumentModelNode} node Node to get offset of |
454 | 452 | * @returns {Integer} Offset of node or -1 of node was not found |
455 | 453 | */ |
456 | 454 | es.DocumentModel.prototype.getOffsetFromNode = function( node ) { |
457 | | - var offset = 0; |
458 | | - for ( var i = 0; i < this.length; i++ ) { |
459 | | - if ( node === this[i] ) { |
460 | | - return offset; |
461 | | - } |
462 | | - if ( this[i].length ) { |
463 | | - var childOffset = es.DocumentModel.prototype.getOffsetFromNode.call( this[i], node ); |
464 | | - if ( childOffset !== -1 ) { |
465 | | - return offset + childOffset; |
| 455 | + var offset = 0, |
| 456 | + currentNode, |
| 457 | + iteration = [this, 0], |
| 458 | + iterations = [iteration]; |
| 459 | + while ( iterations[0][0].length < iteration[0][1] ) { |
| 460 | + currentNode = iteration[0][iteration[1]]; |
| 461 | + if ( currentNode === node ) { |
| 462 | + break; |
| 463 | + } else { |
| 464 | + if ( currentNode.length ) { |
| 465 | + // Include opening element when descending |
| 466 | + offset++; |
| 467 | + // Descend one level down |
| 468 | + iterations.push( [currentNode, 0] ); |
| 469 | + iteration = iterations[iterations.length - 1]; |
| 470 | + } else { |
| 471 | + // Include opening and closing when passing over |
| 472 | + offset += 2; |
466 | 473 | } |
467 | 474 | } |
468 | | - offset += this[i].getElementLength(); |
| 475 | + iteration[1]++; |
| 476 | + if ( iteration[1] >= iteration[0].length ) { |
| 477 | + // Include closing element when ascending |
| 478 | + offset++; |
| 479 | + // Ascend one level up |
| 480 | + iterations.pop(); |
| 481 | + iteration = iterations[iterations.length - 1]; |
| 482 | + } |
469 | 483 | } |
470 | | - return -1; |
| 484 | + return offset; |
471 | 485 | }; |
472 | 486 | |
473 | 487 | /** |