| 596 | | range.moveToElementText(node); |
| 597 | | //(collapsed) && range.collapse(pos); |
| | 596 | if (3 == node.nodeType) |
| | 597 | { |
| | 598 | // Special handling for text nodes, since moveToElementText fails when |
| | 599 | // attempting to select a text node |
| | 600 | |
| | 601 | // Since the TextRange has a quite limited API, our strategy here is to |
| | 602 | // select (where possible) neighboring nodes, and then move our ranges |
| | 603 | // endpoints to be just inside of neighboring selections. |
| | 604 | if (node.parentNode) |
| | 605 | { |
| | 606 | range.moveToElementText(node.parentNode); |
| | 607 | } else |
| | 608 | { |
| | 609 | range.moveToElementText(this._doc.body); |
| | 610 | } |
| | 611 | var trimmingRange = this._doc.body.createTextRange(); |
| | 612 | |
| | 613 | // In rare situations (mostly html that's been monkeyed about with by |
| | 614 | // javascript, but that's what we're doing) there can be two adjacent |
| | 615 | // text nodes. Since we won't be able to handle these, we'll have to |
| | 616 | // hack an offset by 'move'ing the number of characters they contain. |
| | 617 | var texthackOffset = 0; |
| | 618 | var borderElement=node.previousSibling; |
| | 619 | for (; borderElement && (1 != borderElement.nodeType); borderElement = borderElement.previousSibling) |
| | 620 | { |
| | 621 | if (3 == borderElement.nodeType) |
| | 622 | { |
| | 623 | // IE doesn't count '\r' as a character, so we have to adjust the offset. |
| | 624 | texthackOffset += borderElement.nodeValue.length-borderElement.nodeValue.split('\r').length-1; |
| | 625 | } |
| | 626 | } |
| | 627 | if (borderElement && (1 == borderElement.nodeType)) |
| | 628 | { |
| | 629 | trimmingRange.moveToElementText(borderElement); |
| | 630 | range.setEndPoint('StartToEnd', trimmingRange); |
| | 631 | } |
| | 632 | if (texthackOffset) |
| | 633 | { |
| | 634 | // We now need to move the selection forward the number of characters |
| | 635 | // in all text nodes in between our text node and our ranges starting |
| | 636 | // border. |
| | 637 | range.moveStart('character',texthackOffset); |
| | 638 | } |
| | 639 | |
| | 640 | // Youpi! Now we get to repeat this trimming on the right side. |
| | 641 | texthackOffset = 0; |
| | 642 | borderElement=node.nextSibling; |
| | 643 | for (; borderElement && (1 != borderElement.nodeType); borderElement = borderElement.nextSibling) |
| | 644 | { |
| | 645 | if (3 == borderElement.nodeType) |
| | 646 | { |
| | 647 | // IE doesn't count '\r' as a character, so we have to adjust the offset. |
| | 648 | texthackOffset += borderElement.nodeValue.length-borderElement.nodeValue.split('\r').length-1; |
| | 649 | if (!borderElement.nextSibling) |
| | 650 | { |
| | 651 | // When a text node is the last child, IE adds an extra selection |
| | 652 | // "placeholder" for the newline character. We need to adjust for |
| | 653 | // this character as well. |
| | 654 | texthackOffset += 1; |
| | 655 | } |
| | 656 | } |
| | 657 | } |
| | 658 | if (borderElement && (1 == borderElement.nodeType)) |
| | 659 | { |
| | 660 | trimmingRange.moveToElementText(borderElement); |
| | 661 | range.setEndPoint('EndToStart', trimmingRange); |
| | 662 | } |
| | 663 | if (texthackOffset) |
| | 664 | { |
| | 665 | // We now need to move the selection backward the number of characters |
| | 666 | // in all text nodes in between our text node and our ranges ending |
| | 667 | // border. |
| | 668 | range.moveEnd('character',-texthackOffset); |
| | 669 | } |
| | 670 | if (!node.nextSibling) |
| | 671 | { |
| | 672 | // Above we performed a slight adjustment to the offset if the text |
| | 673 | // node contains a selectable "newline". We need to do the same if the |
| | 674 | // node we are trying to select contains a newline. |
| | 675 | range.moveEnd('character',-1); |
| | 676 | } |
| | 677 | } |
| | 678 | else |
| | 679 | { |
| | 680 | range.moveToElementText(node); |
| | 681 | } |