IE9+ has support for window.getSelection, but we’re still using
document.selection for IE9/10. Only use the old IE selection API if the
modern one is unavailable.
In IE10/11, it is apparently possible to have a Selection or Range object that has the following properties:
- `anchorNode` === `focusNode` (Selection) or `startContainer` === `endContainer` (Range)
- `anchorOffset` === `focusOffset` (Selection) or `startOffset` === `endOffset` (Range)
- `isCollapsed` === `false` (Selection) or `collapsed` === `false` (Range)
As defined in http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html, this doesn't really make sense. Since the nodes and offsets are the same, the "collapsed" value should be `true`.
Moreover, when calling `selection.toString()` in this case, it appears that the entire text contents of `body` -- including `<script>` tag contents -- are considered within the selection. I thought maybe the selected nodes were missing from the DOM or something, but no, they're there.
Sidestep all of this in `ReactDOMSelection` by calculating the `collapsed` property manually and setting the selection length directly to zero if it is actually collapsed.
Side note: I think that for selection restoration on contenteditables, we shouldn't try to do this offset calculation. We should just use the structure provided natively (nodes and offsets) since we can restore using that structure as well.
We're now trying to access document directly at require time. Wrapping in a function prevented that before. But we can simply check what environment we're in first.
There is no point in doing the feature detection on every call, unless there is an IE bug where it is not sure about which support for selection it has (totally plausible).