/* DOM Ranges for Internet Explorer (m2) Copyright (c) 2009 Tim Cameron Ryan Released under the MIT/X License *//* Range reference: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsRange.cpp https://developer.mozilla.org/En/DOM:Range Selection reference: http://trac.webkit.org/browser/trunk/WebCore/page/DOMSelection.cpp TextRange reference: http://msdn.microsoft.com/en-us/library/ms535872.aspx Other links: http://jorgenhorstink.nl/test/javascript/range/range.js http://jorgenhorstink.nl/2006/07/05/dom-range-implementation-in-ecmascript-completed/ http://dylanschiemann.com/articles/dom2Range/dom2RangeExamples.html *///[TODO] better exception support (function(){function c(b){this._document=b,this.startContainer=this.endContainer=b.body,this.endOffset=a.getNodeLength(b.body)}function d(b){this.range=b;if(b.collapsed)return;var c=b.commonAncestorContainer;this._next=b.startContainer==c&&!a.isDataNode(b.startContainer)?b.startContainer.childNodes[b.startOffset]:a.findClosestAncestor(c,b.startContainer),this._end=b.endContainer==c&&!a.isDataNode(b.endContainer)?b.endContainer.childNodes[b.endOffset]:a.findClosestAncestor(c,b.endContainer).nextSibling}function e(a){this._document=a;var b=this;a.attachEvent("onselectionchange",function(){b._selectionChangeHandler()})}var a={findChildPosition:function(a){for(var b=0;a=a.previousSibling;b++)continue;return b},isDataNode:function(a){return a&&a.nodeValue!==null&&a.data!==null},isAncestorOf:function(b,c){return!a.isDataNode(b)&&(b.contains(a.isDataNode(c)?c.parentNode:c)||c.parentNode==b)},isAncestorOrSelf:function(b,c){return a.isAncestorOf(b,c)||b==c},findClosestAncestor:function(b,c){if(a.isAncestorOf(b,c))while(c&&c.parentNode!=b)c=c.parentNode;return c},getNodeLength:function(b){return a.isDataNode(b)?b.length:b.childNodes.length},splitDataNode:function(b,c){if(!a.isDataNode(b))return!1;var d=b.cloneNode(!1);b.deleteData(c,b.length),d.deleteData(0,c),b.parentNode.insertBefore(d,b.nextSibling)}},b={convertToDOMRange:function(a,b){function d(a,c,d){var e=b.createElement("a"),f=c.duplicate();f.collapse(d);var g=f.parentElement();do g.insertBefore(e,e.previousSibling),f.moveToElementText(e);while(f.compareEndPoints(d?"StartToStart":"StartToEnd",c)>0&&e.previousSibling);f.compareEndPoints(d?"StartToStart":"StartToEnd",c)==-1&&e.nextSibling?(f.setEndPoint(d?"EndToStart":"EndToEnd",c),a[d?"setStart":"setEnd"](e.nextSibling,f.text.length)):a[d?"setStartBefore":"setEndBefore"](e),e.parentNode.removeChild(e)}var e=new c(b);return d(e,a,!0),d(e,a,!1),e},convertFromDOMRange:function(b){function c(b,c,d){var e=c[d?"startContainer":"endContainer"],f=c[d?"startOffset":"endOffset"],g=0,h=a.isDataNode(e)?e:e.childNodes[f],i=a.isDataNode(e)?e.parentNode:e;if(e.nodeType==3||e.nodeType==4)g=f;var j=c._document.createElement("a");i.insertBefore(j,h);var k=c._document.body.createTextRange();k.moveToElementText(j),j.parentNode.removeChild(j),b.setEndPoint(d?"StartToStart":"EndToStart",k),b[d?"moveStart":"moveEnd"]("character",g)}var d=b._document.body.createTextRange();return c(d,b,!0),c(d,b,!1),d}};c.START_TO_START=0,c.START_TO_END=1,c.END_TO_END=2,c.END_TO_START=3,c.prototype={startContainer:null,startOffset:0,endContainer:null,endOffset:0,commonAncestorContainer:null,collapsed:!1,_document:null,_refreshProperties:function(){this.collapsed=this.startContainer==this.endContainer&&this.startOffset==this.endOffset;var b=this.startContainer;while(b&&b!=this.endContainer&&!a.isAncestorOf(b,this.endContainer))b=b.parentNode;this.commonAncestorContainer=b},setStart:function(a,b){this.startContainer=a,this.startOffset=b,this._refreshProperties()},setEnd:function(a,b){this.endContainer=a,this.endOffset=b,this._refreshProperties()},setStartBefore:function(b){this.setStart(b.parentNode,a.findChildPosition(b))},setStartAfter:function(b){this.setStart(b.parentNode,a.findChildPosition(b)+1)},setEndBefore:function(b){this.setEnd(b.parentNode,a.findChildPosition(b))},setEndAfter:function(b){this.setEnd(b.parentNode,a.findChildPosition(b)+1)},selectNode:function(a){this.setStartBefore(a),this.setEndAfter(a)},selectNodeContents:function(b){this.setStart(b,0),this.setEnd(b,a.getNodeLength(b))},collapse:function(a){a?this.setEnd(this.startContainer,this.startOffset):this.setStart(this.endContainer,this.endOffset)},cloneContents:function(){return function a(b){for(var c,d=document.createDocumentFragment();c=b.next();)c=c.cloneNode(!b.hasPartialSubtree()),b.hasPartialSubtree()&&c.appendChild(a(b.getSubtreeIterator())),d.appendChild(c);return d}(new d(this))},extractContents:function(){var b=this.cloneRange();return this.startContainer!=this.commonAncestorContainer&&this.setStartAfter(a.findClosestAncestor(this.commonAncestorContainer,this.startContainer)),this.collapse(!0),function c(a){for(var b,d=document.createDocumentFragment();b=a.next();)a.hasPartialSubtree()?b=b.cloneNode(!1):a.remove(),a.hasPartialSubtree()&&b.appendChild(c(a.getSubtreeIterator())),d.appendChild(b);return d}(new d(b))},deleteContents:function(){var b=this.cloneRange();this.startContainer!=this.commonAncestorContainer&&this.setStartAfter(a.findClosestAncestor(this.commonAncestorContainer,this.startContainer)),this.collapse(!0),function c(a){while(a.next())a.hasPartialSubtree()?c(a.getSubtreeIterator()):a.remove()}(new d(b))},insertNode:function(b){a.isDataNode(this.startContainer)?(a.splitDataNode(this.startContainer,this.startOffset),this.startContainer.parentNode.insertBefore(b,this.startContainer.nextSibling)):this.startContainer.insertBefore(b,this.startContainer.childNodes[this.startOffset]),this.setStart(this.startContainer,this.startOffset)},surroundContents:function(a){var b=this.extractContents();this.insertNode(a),a.appendChild(b),this.selectNode(a)},compareBoundaryPoints:function(a,b){var d,e,f,g;switch(a){case c.START_TO_START:case c.START_TO_END:d=this.startContainer,e=this.startOffset;break;case c.END_TO_END:case c.END_TO_START:d=this.endContainer,e=this.endOffset}switch(a){case c.START_TO_START:case c.END_TO_START:f=b.startContainer,g=b.startOffset;break;case c.START_TO_END:case c.END_TO_END:f=b.endContainer,g=b.endOffset}return d.sourceIndex-1&&d.compareEndPoints("EndToEnd",c)==-1?c.setEndPoint("StartToStart",d):d.compareEndPoints("EndToStart",c)<1&&d.compareEndPoints("EndToEnd",c)>-1&&c.setEndPoint("EndToEnd",d)),c.select()):d.select()},removeAllRanges:function(){this._document.selection.empty()},getRangeAt:function(a){var c=this._document.selection.createRange();return this._selectionExists(c)?b.convertToDOMRange(c,this._document):null},toString:function(){return this._document.selection.createRange().text}},document.createRange=function(){return new c(document)};var f=new e(document);window.getSelection=function(){return f}})();