Index: trunk/extensions/VisualEditor/modules/ve/ce/ve.ce.Surface.js |
— | — | @@ -563,6 +563,70 @@ |
564 | 564 | } |
565 | 565 | }; |
566 | 566 | |
| 567 | +ve.ce.Surface.prototype.getDOMNodeAndOffset = function( offset ) { |
| 568 | + var $node = this.documentView.getNodeFromOffset( offset ).$, |
| 569 | + nodeOffset = this.documentView.getOffsetFromNode( $node.data('view') ) + 1, |
| 570 | + current = [$node.contents(), 0], |
| 571 | + stack = [current], |
| 572 | + localNode, |
| 573 | + localOffset; |
| 574 | + |
| 575 | + while ( stack.length > 0 ) { |
| 576 | + if ( current[1] >= current[0].length ) { |
| 577 | + stack.pop(); |
| 578 | + current = stack[ stack.length - 1 ]; |
| 579 | + continue; |
| 580 | + } |
| 581 | + var item = current[0][current[1]], |
| 582 | + $item = current[0].eq( current[1] ); |
| 583 | + |
| 584 | + if ( item.nodeType === 3 ) { |
| 585 | + var length = item.textContent.length; |
| 586 | + if ( offset >= nodeOffset && offset <= nodeOffset + length ) { |
| 587 | + return { |
| 588 | + node: item, |
| 589 | + offset: offset - nodeOffset |
| 590 | + }; |
| 591 | + break; |
| 592 | + } else { |
| 593 | + nodeOffset += length; |
| 594 | + } |
| 595 | + } else if ( item.nodeType === 1 ) { |
| 596 | + if ( $( item ).attr('contentEditable') === 'false' ) { |
| 597 | + nodeOffset += 1; |
| 598 | + } else { |
| 599 | + stack.push( [$item.contents(), 0] ); |
| 600 | + current[1]++; |
| 601 | + current = stack[stack.length-1]; |
| 602 | + continue; |
| 603 | + } |
| 604 | + } |
| 605 | + current[1]++; |
| 606 | + } |
| 607 | + return null; |
| 608 | +}; |
| 609 | + |
| 610 | + |
| 611 | +/** |
| 612 | + * @method |
| 613 | + */ |
| 614 | +ve.ce.Surface.prototype.showCursor = function( offset ) { |
| 615 | + this.showSelection( new ve.Range( offset ) ); |
| 616 | +}; |
| 617 | + |
| 618 | +/** |
| 619 | + * @method |
| 620 | + */ |
| 621 | +ve.ce.Surface.prototype.showSelection = function( range ) { |
| 622 | + var start = this.getDOMNodeAndOffset( range.start ), |
| 623 | + stop = this.getDOMNodeAndOffset( range.end ), |
| 624 | + range = rangy.createRange(), |
| 625 | + sel = rangy.getSelection(); |
| 626 | + range.setStart( start.node, start.offset ); |
| 627 | + range.setEnd( stop.node, stop.offset ); |
| 628 | + sel.setSingleRange( range ); |
| 629 | +}; |
| 630 | + |
567 | 631 | ve.ce.Surface.prototype.getLeafNode = function( elem ) { |
568 | 632 | var $node = $( elem ); |
569 | 633 | while( !$node.hasClass( 'ce-leafNode' ) ) { |