From ae38caba31636226f93b0d00ebda1ab6a8e3e8b5 Mon Sep 17 00:00:00 2001 From: Neil Jenkins Date: Sat, 29 Nov 2014 20:08:53 +0700 Subject: [PATCH] Remove IE8 support. It was always a bit buggy, and realistically there's no point in putting in the time to fix it up. --- Demo.html | 3 - Makefile | 8 +- Readme.md | 6 +- build/document.html | 5 +- build/ie8.js | 1 - source/document.html | 5 +- source/ie8dom.js | 157 -------------- source/ie8range.js | 487 ------------------------------------------- source/ie8types.js | 63 ------ 9 files changed, 6 insertions(+), 729 deletions(-) delete mode 100644 build/ie8.js delete mode 100644 source/ie8dom.js delete mode 100644 source/ie8range.js delete mode 100644 source/ie8types.js diff --git a/Demo.html b/Demo.html index 217584c..9815714 100644 --- a/Demo.html +++ b/Demo.html @@ -27,9 +27,6 @@ margin: 5px 0; } - - \ No newline at end of file + diff --git a/build/ie8.js b/build/ie8.js deleted file mode 100644 index 41efb73..0000000 --- a/build/ie8.js +++ /dev/null @@ -1 +0,0 @@ -!function(){Array.prototype.indexOf=function(t,e){for(var n=this.length,r=0>e?Math.max(0,n+e):e||0;n>r;r+=1)if(this[r]===t)return r;return-1},Array.prototype.forEach=function(t,e){var n=this.length>>>0;if("function"!=typeof t)throw new TypeError;for(var r=0;n>r;r+=1)t.call(e,this[r],r,this)},Array.prototype.filter=function(t,e){for(var n=[],r=0,o=this.length;o>r;r+=1){var i=this[r];t.call(e,i,r,this)&&n.push(i)}return n},Object.keyOf=function(t,e){for(var n in t)if(t[n]===e)return n},Date.now=function(){return+new Date},String.prototype.trim=function(){for(var t=this.replace(/^\s\s*/,""),e=/\s/,n=t.length;e.test(t.charAt(n-=1)););return t.slice(0,n+1)}}(),function(){var t=document;window.ie=8,t.defaultView=window;var e={focus:"focusin",blur:"focusout"},n=function(){return!0},r=function(){return!1},o="altKey ctrlKey metaKey shiftKey clientX clientY charCode keyCode".split(" "),i=function(t){for(var n,r=t.type,i=document,a=t.srcElement||i,s=(a.ownerDocument||i).documentElement,c=o.length;c--;)n=o[c],this[n]=t[n];"propertychange"===r&&(r="INPUT"===a.nodeName&&"text"!==a.type&&"password"!==a.type?"change":"input"),this.type=Object.keyOf(e,r)||r,this.target=a,this.pageX=t.clientX+s.scrollLeft,this.pageY=t.clientY+s.scrollTop,t.button&&(this.button=4&t.button?1:2&t.button?2:0,this.which=this.button+1),this.relatedTarget=t.fromElement===a?t.toElement:t.fromElement,this._event=t};i.prototype={constructor:i,isEvent:!0,preventDefault:function(){this.isDefaultPrevented=n,this._event.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=n,this._event.cancelBubble=!0},isDefaultPrevented:r,isPropagationStopped:r},[t,Element.prototype].forEach(function(t){t.addEventListener=function(t,n){var r=n._ie_handleEvent||(n._ie_handleEvent=function(){var t=new i(window.event);"object"==typeof n?n.handleEvent(t):n.call(this,t)}),o=/paste|cut/.test(t)?this.body||this:this;n._ie_registeredCount=(n._ie_registeredCount||0)+1,o.attachEvent("on"+(e[t]||t),r)},t.addEventListener.isFake=!0,t.removeEventListener=function(t,n){var r=n._ie_handleEvent,o=/paste|cut/.test(t)?this.body||this:this;(n._ie_registeredCount-=1)||delete n._ie_handleEvent,r&&o.detachEvent("on"+(e[t]||t),r)},t.removeEventListener.isFake=!0}),t.defaultView.addEventListener=function(e,n,r){return t.addEventListener(e,n,r)},Object.defineProperty(Element.prototype,"textContent",{get:function(){return this.innerText},set:function(t){this.innerText=t}}),Element.prototype.compareDocumentPosition=function(t){1!==t.nodeType&&(t=t.parentNode);var e=this,n=e!==t,r=e.sourceIndex,o=t.sourceIndex;return(n&&e.contains(t)?16:0)+(n&&t.contains(e)?8:0)+(o>r?4:0)+(r>o?2:0)},HTMLDocument.prototype.normalize=function(){for(var t,e=this.childNodes,n=e.length;n--;)t=e[n],1===t.nodeType&&t.normalize()}}();var Range;!function(){var t=Array.prototype.indexOf,e=0,n=1,r=3,o=function(t,e){for(;e=e.parentNode;)if(t===e)return!0;return!1},i=function(t,e){var n,r,i,a,s;if(t===e||o(t,e))n=t;else if(o(e,t))n=e;else{for(r=[],i=[];t=t.parentNode;)r.push(t);for(;e=e.parentNode;)i.push(e);for(a=r.length,s=i.length;a--&&s--;)if(r[a]!==i[s]){n=r[a+1];break}n||(n=-1===a?r[0]:i[0])}return n};Range=function(t,e,n,r){t=t||document,e=e||0,this.startContainer=t,this.startOffset=e,this.endContainer=n||t,this.endOffset=void 0!==r?r:e,this._updateCollapsedAndAncestor()},Range.prototype={constructor:Range,_updateCollapsedAndAncestor:function(){this.collapsed=this.startContainer===this.endContainer&&this.startOffset===this.endOffset,this.commonAncestorContainer=i(this.startContainer,this.endContainer)},setStart:function(t,e){this.startContainer=t,this.startOffset=e,this._updateCollapsedAndAncestor()},setEnd:function(t,e){this.endContainer=t,this.endOffset=e,this._updateCollapsedAndAncestor()},setStartAfter:function(e){var n=e.parentNode;this.setStart(n,t.call(n.childNodes,e)+1)},setEndBefore:function(e){var n=e.parentNode;this.setEnd(n,t.call(n.childNodes,e))},selectNode:function(e){var n=e.parentNode,r=t.call(n.childNodes,e);this.setStart(n,r),this.setEnd(n,r+1)},selectNodeContents:function(t){this.setStart(t,0),this.setEnd(t,t.childNodes.length)},cloneRange:function(){return new Range(this.startContainer,this.startOffset,this.endContainer,this.endOffset)},collapse:function(t){t?this.setEnd(this.startContainer,this.startOffset):this.setStart(this.endContainer,this.endOffset)},compareBoundaryPoints:function(o,i){var a,s,c,d,f,u;if(o===e||o===r?(a=this.startContainer,s=this.startOffset):(a=this.endContainer,s=this.endOffset),o===e||o===n?(c=i.startContainer,d=i.startOffset):(c=i.endContainer,d=i.endOffset),a===c)return d>s?-1:s>d?1:0;for(f=a;u=f.parentNode;){if(u===c)return t.call(u.childNodes,f)c.sourceIndex?1:0}},document.createRange=function(){return new Range};var a=function(t,e){return t===e||o(t,e)},s=function(t){var e=t.nodeType;return 3===e||4===e||8===e},c=function(t,e){this.node=t,this.offset=e},d=function(t){var e,n,r,o,a=t.parentElement();return e=t.duplicate(),e.collapse(!0),n=e.parentElement(),e=t.duplicate(),e.collapse(!1),r=e.parentElement(),o=n===r?n:i(n,r),o===a?o:i(a,o)},f=function(e,n,r,o){var i=e.duplicate();i.collapse(r);var d=i.parentElement();if(a(n,d)||(d=n),!d.canHaveHTML)return new c(d.parentNode,t.call(d.parentNode.childNodes,d));var f,u,l,h,p,v=document.createElement("span"),m=r?"StartToStart":"StartToEnd";do d.insertBefore(v,v.previousSibling),i.moveToElementText(v),f=i.compareEndPoints(m,e);while(f>0&&v.previousSibling);if(p=v.nextSibling,-1===f&&p&&s(p)){i.setEndPoint(r?"EndToStart":"EndToEnd",e);var E;if(/[\r\n]/.test(p.data)||/[\r\n]/.test(i.text)){var g=i.duplicate(),y=g.text.replace(/\r\n/g,"\r").length;for(E=g.moveStart("character",y);-1===(f=g.compareEndPoints("StartToEnd",g));)E+=1,g.moveStart("character",1)}else E=i.text.length;h=new c(p,E)}else u=(o||!r)&&v.previousSibling,l=(o||r)&&v.nextSibling,h=l&&s(l)?new c(l,0):u&&s(u)?new c(u,u.data.length):new c(d,t.call(d.childNodes,v));return v.parentNode.removeChild(v),h},u=function(t,e){var n,r,o,i,a=t.offset,c=document,d=c.body.createTextRange(),f=s(t.node);return f?(n=t.node,r=n.parentNode):(i=t.node.childNodes,n=a - - \ No newline at end of file + diff --git a/source/ie8dom.js b/source/ie8dom.js deleted file mode 100644 index 0b6fd9e..0000000 --- a/source/ie8dom.js +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */ - -( function () { - -/*global window, document, Element, HTMLDocument */ -/*jshint strict: false */ - -var doc = document; - -// Add JS hook -window.ie = 8; - -// Add defaultView property to document -doc.defaultView = window; - -// Fake W3C events support -var translate = { - focus: 'focusin', - blur: 'focusout' -}; - -var returnTrue = function () { return true; }; -var returnFalse = function () { return false; }; - -var toCopy = 'altKey ctrlKey metaKey shiftKey clientX clientY charCode keyCode'.split( ' ' ); - -var DOMEvent = function ( event ) { - var type = event.type, - doc = document, - target = event.srcElement || doc, - html = ( target.ownerDocument || doc ).documentElement, - l = toCopy.length, - property; - - while ( l-- ) { - property = toCopy[l]; - this[ property ] = event[ property ]; - } - - if ( type === 'propertychange' ) { - type = ( target.nodeName === 'INPUT' && - target.type !== 'text' && target.type !== 'password' ) ? - 'change' : 'input'; - } - - this.type = Object.keyOf( translate, type ) || type; - this.target = target; - this.pageX = event.clientX + html.scrollLeft; - this.pageY = event.clientY + html.scrollTop; - - if ( event.button ) { - this.button = ( event.button & 4 ? 1 : - ( event.button & 2 ? 2 : 0 ) ); - this.which = this.button + 1; - } - - this.relatedTarget = event.fromElement === target ? - event.toElement : event.fromElement; - this._event = event; -}; - -DOMEvent.prototype = { - constructor: DOMEvent, - isEvent: true, - preventDefault: function () { - this.isDefaultPrevented = returnTrue; - this._event.returnValue = false; - }, - stopPropagation: function () { - this.isPropagationStopped = returnTrue; - this._event.cancelBubble = true; - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse -}; - -// Add W3C event add/remove methods to elements and document. -[ doc, Element.prototype ].forEach( - function ( dom ) { - dom.addEventListener = function ( type, handler, capture ) { - var fn = handler._ie_handleEvent || ( handler._ie_handleEvent = - function () { - var event = new DOMEvent( window.event ); - if ( typeof handler === 'object' ) { - handler.handleEvent( event ); - } else { - handler.call( this, event ); - } - } - ), - node = /paste|cut/.test( type ) ? this.body || this : this; - - handler._ie_registeredCount = ( handler._ie_registeredCount || 0 ) + 1; - - node.attachEvent( 'on' + ( translate[ type ] || type ), fn ); - }; - dom.addEventListener.isFake = true; - - dom.removeEventListener = function ( type, handler, capture ) { - var fn = handler._ie_handleEvent, - node = /paste|cut/.test( type ) ? this.body || this : this; - if ( !( handler._ie_registeredCount -= 1 ) ) { - delete handler._ie_handleEvent; - } - if ( fn ) { - node.detachEvent( 'on' + ( translate[ type ] || type ), fn ); - } - }; - dom.removeEventListener.isFake = true; -}); - -// The events that we normally attach to the window object, IE8 wants on the -// body. -doc.defaultView.addEventListener = function ( type, handler, capture ) { - return doc.addEventListener( type, handler, capture ); -}; - -// Add textContent property to elements. -Object.defineProperty( Element.prototype, 'textContent', { - get: function () { - return this.innerText; - }, - - set: function ( text ) { - this.innerText = text; - } -}); - -// Add compareDocumentPosition method to elements. -Element.prototype.compareDocumentPosition = function ( b ) { - if ( b.nodeType !== 1 ) { b = b.parentNode; } - var a = this, - different = ( a !== b ), - aIndex = a.sourceIndex, - bIndex = b.sourceIndex; - - return ( different && a.contains( b ) ? 16 : 0 ) + - ( different && b.contains( a ) ? 8 : 0 ) + - ( aIndex < bIndex ? 4 : 0 ) + - ( bIndex < aIndex ? 2 : 0 ); -}; - -// Add normalize method to document fragments -HTMLDocument.prototype.normalize = function () { - var children = this.childNodes, - l = children.length, - child; - - while ( l-- ) { - child = children[l]; - if ( child.nodeType === 1 ) { - child.normalize(); - } - } -}; - -}() ); diff --git a/source/ie8range.js b/source/ie8range.js deleted file mode 100644 index 1c54e52..0000000 --- a/source/ie8range.js +++ /dev/null @@ -1,487 +0,0 @@ -/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. - - IE TextRange <-> W3C Range code adapted from Rangy: - http://code.google.com/p/rangy/ - Copyright 2012, Tim Down. Licensed under the MIT license. -*/ - -var Range; - -( function () { - -/*global window, document */ -/*jshint strict: false */ - -var indexOf = Array.prototype.indexOf; - -var START_TO_START = 0; -var START_TO_END = 1; -var END_TO_START = 3; - -var contains = function ( a, b ) { - while ( b = b.parentNode ) { - if ( a === b ) { return true; } - } - return false; -}; - -var getCommonAncestor = function ( a, b ) { - var commonAncestor, - aParents, bParents, - aL, bL; - - if ( a === b || contains( a, b ) ) { - commonAncestor = a; - } else if ( contains( b, a ) ) { - commonAncestor = b; - } else { - aParents = []; - bParents = []; - while ( a = a.parentNode ) { - aParents.push( a ); - } - while ( b = b.parentNode ) { - bParents.push( b ); - } - aL = aParents.length; - bL = bParents.length; - while ( aL-- && bL-- ) { - if ( aParents[ aL ] !== bParents[ bL ] ) { - commonAncestor = aParents[ aL + 1 ]; - break; - } - } - if ( !commonAncestor ) { - commonAncestor = ( aL === -1 ? aParents[0] : bParents[0] ); - } - } - return commonAncestor; -}; - -Range = function ( startContainer, startOffset, endContainer, endOffset ) { - startContainer = startContainer || document; - startOffset = startOffset || 0; - - this.startContainer = startContainer; - this.startOffset = startOffset; - this.endContainer = endContainer || startContainer; - this.endOffset = endOffset !== undefined ? endOffset : startOffset; - this._updateCollapsedAndAncestor(); -}; - -Range.prototype = { - constructor: Range, - - _updateCollapsedAndAncestor: function () { - this.collapsed = ( - this.startContainer === this.endContainer && - this.startOffset === this.endOffset - ); - this.commonAncestorContainer = - getCommonAncestor( this.startContainer, this.endContainer ); - }, - setStart: function ( node, offset ) { - this.startContainer = node; - this.startOffset = offset; - this._updateCollapsedAndAncestor(); - }, - setEnd: function ( node, offset ) { - this.endContainer = node; - this.endOffset = offset; - this._updateCollapsedAndAncestor(); - }, - setStartAfter: function ( node ) { - var parent = node.parentNode; - this.setStart( parent, indexOf.call( parent.childNodes, node ) + 1 ); - }, - setEndBefore: function ( node ) { - var parent = node.parentNode; - this.setEnd( parent, indexOf.call( parent.childNodes, node ) ); - }, - selectNode: function ( node ) { - var parent = node.parentNode, - offset = indexOf.call( parent.childNodes, node ); - this.setStart( parent, offset ); - this.setEnd( parent, offset + 1 ); - }, - selectNodeContents: function ( node ) { - this.setStart( node, 0 ); - this.setEnd( node, node.childNodes.length ); - }, - cloneRange: function () { - return new Range( - this.startContainer, - this.startOffset, - this.endContainer, - this.endOffset - ); - }, - collapse: function ( toStart ) { - if ( toStart ) { - this.setEnd( this.startContainer, this.startOffset ); - } else { - this.setStart( this.endContainer, this.endOffset ); - } - }, - compareBoundaryPoints: function ( how, sourceRange ) { - var aContainer, aOffset, bContainer, bOffset, node, parent; - if ( how === START_TO_START || how === END_TO_START ) { - aContainer = this.startContainer; - aOffset = this.startOffset; - } else { - aContainer = this.endContainer; - aOffset = this.endOffset; - } - if ( how === START_TO_START || how === START_TO_END ) { - bContainer = sourceRange.startContainer; - bOffset = sourceRange.startOffset; - } else { - bContainer = sourceRange.endContainer; - bOffset = sourceRange.endOffset; - } - if ( aContainer === bContainer ) { - return aOffset < bOffset ? -1 : - aOffset > bOffset ? 1 : 0; - } - - node = aContainer; - while ( parent = node.parentNode ) { - if ( parent === bContainer ) { - return indexOf.call( parent.childNodes, node ) < bOffset ? - -1 : 1; - } - node = parent; - } - node = bContainer; - while ( parent = node.parentNode ) { - if ( parent === aContainer ) { - return indexOf.call( parent.childNodes, node ) < aOffset ? - 1 : -1; - } - node = parent; - } - if ( aContainer.nodeType !== 1 ) { - aContainer = aContainer.parentNode; - } - if ( bContainer.nodeType !== 1 ) { - bContainer = bContainer.parentNode; - } - return aContainer.sourceIndex < bContainer.sourceIndex ? -1 : - aContainer.sourceIndex > bContainer.sourceIndex ? 1 : 0; - } -}; - -document.createRange = function () { - return new Range(); -}; - -// --- - -var isAncestorOf = function ( ancestor, descendant ) { - return ancestor === descendant || contains( ancestor, descendant ); -}; - -var isCharacterDataNode = function ( node ) { - var nodeType = node.nodeType; - // Text, CDataSection or Comment - return nodeType === 3 || nodeType === 4 || nodeType === 8; -}; - -var DomPosition = function ( node, offset ) { - this.node = node; - this.offset = offset; -}; - -var getTextRangeContainerElement = function ( textRange ) { - var parentEl = textRange.parentElement(), - range, startEl, endEl, startEndContainer; - - range = textRange.duplicate(); - range.collapse( true ); - startEl = range.parentElement(); - range = textRange.duplicate(); - range.collapse( false ); - endEl = range.parentElement(); - startEndContainer = ( startEl === endEl ) ? - startEl : getCommonAncestor( startEl, endEl ); - - return startEndContainer === parentEl ? - startEndContainer : getCommonAncestor( parentEl, startEndContainer ); -}; - -// Gets the boundary of a TextRange expressed as a node and an offset within -// that node. This function started out as an improved version of code found in -// Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/) but has grown, -// fixing problems with line breaks in preformatted text, adding workaround for -// IE TextRange bugs, handling for inputs and images, plus optimizations. -var getTextRangeBoundaryPosition = function ( - textRange, wholeRangeContainerElement, isStart, isCollapsed ) { - var workingRange = textRange.duplicate(); - - workingRange.collapse( isStart ); - - var containerElement = workingRange.parentElement(); - - // Sometimes collapsing a TextRange that's at the start of a text node can - // move it into the previous node, so check for that TODO: Find out when. - // Workaround for wholeRangeContainerElement may break this - if ( !isAncestorOf( wholeRangeContainerElement, containerElement ) ) { - containerElement = wholeRangeContainerElement; - } - - // Deal with nodes that cannot "contain rich HTML markup". In practice, this - // means form inputs, images and similar. See - // http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx - if ( !containerElement.canHaveHTML ) { - return new DomPosition( - containerElement.parentNode, - indexOf.call( - containerElement.parentNode.childNodes, containerElement ) - ); - } - - var workingNode = document.createElement( 'span' ), - workingComparisonType = isStart ? 'StartToStart' : 'StartToEnd', - comparison, previousNode, nextNode, boundaryPosition, boundaryNode; - - // Move the working range through the container's children, starting at the - // end and working backwards, until the working range reaches or goes past - // the boundary we're interested in - do { - containerElement.insertBefore( - workingNode, workingNode.previousSibling ); - workingRange.moveToElementText( workingNode ); - comparison = - workingRange.compareEndPoints( workingComparisonType, textRange ); - } while ( comparison > 0 && workingNode.previousSibling ); - - // We've now reached or gone past the boundary of the text range we're - // interested in so have identified the node we want - boundaryNode = workingNode.nextSibling; - - if ( comparison === -1 && boundaryNode && - isCharacterDataNode( boundaryNode ) ) { - // This is a character data node (text, comment, cdata). The working - // range is collapsed at the start of the node containing the text - // range's boundary, so we move the end of the working range to the - // boundary point and measure the length of its text to get the - // boundary's offset within the node. - workingRange.setEndPoint( - isStart ? 'EndToStart' : 'EndToEnd', textRange ); - - var offset; - - if ( /[\r\n]/.test( boundaryNode.data ) || - /[\r\n]/.test( workingRange.text ) ) { - /* - For the particular case of a boundary within a text node containing - line breaks (within a
 element, for example), we need a
-            slightly complicated approach to get the boundary's offset in IE.
-            The facts:
-
-            - Each line break is represented as \r in the text node's
-              data/nodeValue properties
-            - Each line break is represented as \r\n in the TextRange's 'text'
-              property
-            - The 'text' property of the TextRange does not contain trailing
-              line breaks
-
-            To get round the problem presented by the final fact above, we can
-            use the fact that TextRange's moveStart() and moveEnd() methods
-            return the actual number of characters moved, which is not
-            necessarily the same as the number of characters it was instructed
-            to move. The simplest approach is to use this to store the
-            characters moved when moving both the start and end of the range to
-            the start of the document body and subtracting the start offset from
-            the end offset (the "move-negative-gazillion" method). However, this
-            is extremely slow when the document is large and the range is near
-            the end of it. Clearly doing the mirror image (i.e. moving the range
-            boundaries to the end of the document) has the same problem.
-
-            Another approach that works is to use moveStart() to move the start
-            boundary of the range up to the end boundary one character at a time
-            and incrementing a counter with the value returned by the
-            moveStart() call. However, the check for whether the start boundary
-            has reached the end boundary is expensive, so this method is slow
-            (although unlike "move-negative-gazillion" is largely unaffected by
-            the location of the range within the document).
-
-            The method below is a hybrid of the two methods above. It uses the
-            fact that a string containing the TextRange's 'text' property with
-            each \r\n converted to a single \r character cannot be longer than
-            the text of the TextRange, so the start of the range is moved that
-            length initially and then a character at a time to make up for any
-            trailing line breaks not contained in the 'text' property. This has
-            good performance in most situations compared to the previous two
-            methods.
-            */
-            var tempRange = workingRange.duplicate();
-            var rangeLength = tempRange.text.replace( /\r\n/g, '\r' ).length;
-
-            offset = tempRange.moveStart( 'character', rangeLength);
-            while ( ( comparison =
-                    tempRange.compareEndPoints( 'StartToEnd', tempRange )
-                    ) === -1 ) {
-                offset += 1;
-                tempRange.moveStart( 'character', 1 );
-            }
-        } else {
-            offset = workingRange.text.length;
-        }
-        boundaryPosition = new DomPosition( boundaryNode, offset );
-    }
-    else {
-        // If the boundary immediately follows a character data node and this is
-        // the end boundary, we should favour a position within that, and
-        // likewise for a start boundary preceding a character data node
-        previousNode = ( isCollapsed || !isStart ) &&
-            workingNode.previousSibling;
-        nextNode = ( isCollapsed || isStart ) && workingNode.nextSibling;
-
-        if ( nextNode && isCharacterDataNode( nextNode ) ) {
-            boundaryPosition = new DomPosition( nextNode, 0 );
-        } else if ( previousNode && isCharacterDataNode( previousNode ) ) {
-            // Strange bug: if we don't read the data property, the length
-            // property is often returned incorrectly as 0. Don't ask me why.
-            // Therefore get the length from the data property rather than
-            // reading it directly from the node.
-            boundaryPosition = new DomPosition(
-                previousNode, previousNode.data.length );
-        } else {
-            boundaryPosition = new DomPosition(
-                containerElement,
-                indexOf.call( containerElement.childNodes, workingNode )
-            );
-        }
-    }
-
-    // Clean up
-    workingNode.parentNode.removeChild( workingNode );
-
-    return boundaryPosition;
-};
-
-// Returns a TextRange representing the boundary of a TextRange expressed as a
-// node and an offset within that node. This function started out as an
-// optimized version of code found in Tim Cameron Ryan's IERange
-// (http://code.google.com/p/ierange/)
-var createBoundaryTextRange = function ( boundaryPosition, isStart ) {
-    var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
-    var doc = document;
-    var workingNode, childNodes, workingRange = doc.body.createTextRange();
-    var nodeIsDataNode = isCharacterDataNode( boundaryPosition.node );
-
-    if ( nodeIsDataNode ) {
-        boundaryNode = boundaryPosition.node;
-        boundaryParent = boundaryNode.parentNode;
-    } else {
-        childNodes = boundaryPosition.node.childNodes;
-        boundaryNode = ( boundaryOffset < childNodes.length ) ?
-            childNodes[ boundaryOffset ] : null;
-        boundaryParent = boundaryPosition.node;
-    }
-
-    // Position the range immediately before the node containing the boundary
-    workingNode = doc.createElement( 'span' );
-
-    // Making the working element non-empty element persuades IE to consider the
-    // TextRange boundary to be within the element rather than immediately
-    // before or after it, which is what we want
-    workingNode.innerHTML = '';
-
-    // insertBefore is supposed to work like appendChild if the second parameter
-    // is null. However, a bug report for IERange suggests that it can crash the
-    // browser: http://code.google.com/p/ierange/issues/detail?id=12
-    if ( boundaryNode ) {
-        boundaryParent.insertBefore( workingNode, boundaryNode );
-    } else {
-        boundaryParent.appendChild( workingNode );
-    }
-
-    workingRange.moveToElementText( workingNode );
-    workingRange.collapse( !isStart );
-
-    // Clean up
-    boundaryParent.removeChild( workingNode );
-
-    // Move the working range to the text offset, if required
-    if ( nodeIsDataNode ) {
-        workingRange[ isStart ? 'moveStart' : 'moveEnd' ](
-            'character', boundaryOffset );
-    }
-
-    return workingRange;
-};
-
-var toDOMRange = function ( textRange ) {
-    var rangeContainerElement = getTextRangeContainerElement( textRange ),
-        start, end;
-
-    if ( textRange.compareEndPoints( 'StartToEnd', textRange ) === 0 ) {
-        start = end = getTextRangeBoundaryPosition(
-            textRange, rangeContainerElement, true, true );
-    } else {
-        start = getTextRangeBoundaryPosition(
-            textRange, rangeContainerElement, true, false );
-        end = getTextRangeBoundaryPosition(
-            textRange, rangeContainerElement, false, false );
-    }
-    return new Range(
-        start.node,
-        start.offset,
-        end.node,
-        end.offset
-    );
-};
-
-var toTextRange = function ( range ) {
-    var textRange, startRange, endRange;
-    if ( range.collapsed ) {
-        textRange = createBoundaryTextRange(
-            new DomPosition( range.startContainer, range.startOffset ), true);
-    } else {
-        startRange = createBoundaryTextRange(
-            new DomPosition( range.startContainer, range.startOffset ), true);
-        endRange = createBoundaryTextRange(
-            new DomPosition( range.endContainer, range.endOffset ), false );
-        textRange = document.body.createTextRange();
-        textRange.setEndPoint( 'StartToStart', startRange);
-        textRange.setEndPoint( 'EndToEnd', endRange);
-    }
-    return textRange;
-};
-
-var selection = {
-    rangeCount: 0,
-    getRangeAt: function ( index ) {
-        if ( index !== 0 ) { return undefined; }
-        var sel = document.selection.createRange();
-        // Check if we have a control range.
-        if ( sel.add ) {
-            var range = document.createRange();
-            range.moveToElementText( sel.item( 0 ) );
-            range.collapse( false );
-            range.select();
-            sel = range;
-        }
-        return toDOMRange( sel );
-    },
-    removeAllRanges: function () {},
-    addRange: function ( range ) {
-        toTextRange( range ).select();
-    }
-};
-
-document.attachEvent( 'onbeforeactivate', function () {
-    selection.rangeCount = 1;
-});
-
-document.attachEvent( 'ondeactivate', function () {
-    selection.rangeCount = 0;
-});
-
-window.getSelection = function () {
-    return selection;
-};
-
-}() );
diff --git a/source/ie8types.js b/source/ie8types.js
deleted file mode 100644
index 7a3361c..0000000
--- a/source/ie8types.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */
-
-( function () {
-
-/*jshint strict: false */
-
-// Note: Does not inclue the `if ( i in this ) {}` check these function should
-// have, as IE8 will return false if this[i] is undefined (at least if the array
-// was defined with a literal, e.g. `[ undefined, undefined ]`).
-
-Array.prototype.indexOf = function ( item, from ) {
-    var l = this.length;
-    for ( var i = ( from < 0 ) ? Math.max( 0, l + from ) : from || 0;
-            i < l; i += 1 ) {
-        if ( this[i] === item ) {
-            return i;
-        }
-    }
-    return -1;
-};
-
-Array.prototype.forEach = function ( fn, bind ) {
-    var l = this.length >>> 0;
-    if ( typeof fn !== 'function' ) {
-        throw new TypeError();
-    }
-    for ( var i = 0; i < l; i += 1 ) {
-        fn.call( bind, this[i], i, this );
-    }
-};
-
-Array.prototype.filter = function ( fn, bind ) {
-    var results = [];
-    for ( var i = 0, l = this.length; i < l; i += 1 ) {
-        var value = this[i];
-        if ( fn.call( bind, value, i, this ) ) {
-            results.push( value );
-        }
-    }
-    return results;
-};
-
-Object.keyOf = function ( object, value ) {
-    for ( var key in object ) {
-        if ( object[ key ] === value ) {
-            return key;
-        }
-    }
-};
-
-Date.now = function () {
-    return +( new Date() );
-};
-
-String.prototype.trim = function () {
-    var str = this.replace( /^\s\s*/, '' ),
-        ws = /\s/,
-        i = str.length;
-    while ( ws.test( str.charAt( i -= 1 ) ) ) {/* Empty! */}
-    return str.slice( 0, i + 1 );
-};
-
-}() );