Selecting Text

getSelection().baseNode is an alias of getSelection().anchorNode. getSelection().extentNode is an alias of getSelection().focusNode.
RESETRUNFULL
<!DOCTYPE html><html>
    <head></head><body>
    <p id="p1">Q:<h2 id="h2a" contenteditable>What's the difference between Java and JavaScript?</h2>
        Java and JavaScript are similar in the same way car and carpet are.
    </p>
    <p id="p2">Q:<h2 id="h2b">The three most well known languages in India are English, Hindi, and...</h2>
        <strong id="str">JavaScript.</strong></p>
    <p id="p3"></p>
    <script>
        bodyNode = document.querySelector("body");
        h2aNode = document.querySelector("#h2a");
        p2Node = document.querySelector("#p2");
        strNode = document.querySelector("#str");
        document.onselectionchange = ()=>{
            var s = getSelection();
            if (s.anchorNode)
                 document.querySelector("#p3").innerText =
                    s.anchorNode.parentNode.id + " " +
                   s.anchorOffset + "\n" +
                   s.focusNode.parentNode.id + " " +
                   s.focusOffset + "\n" +
                   s.type + "\n" +         // Caret / Range
                   s.isCollapsed + "\n" +  // Caret only?
                   s.rangeCount + "\n" +
                   s.containsNode(strNode);
        }
    </script>
  <button onclick="getSelection().deleteFromDocument()">
       deleteFromDocument()</button><br/><button onclick="getSelection().removeRange(
                                   getSelection().getRangeAt(0))">
       removeRange()</button><br/><button onclick="getSelection().removeAllRanges()">
   removeAllRanges()</button><br/><button onclick="getSelection().empty()">
   empty() -- alias of removeAllRanges()</button><br/><button onclick="getSelection().collapse(h2aNode,1)">
   collapse() -- moves caret to the right of ...JavaScript?
   </button><br/><button onclick="getSelection().setPosition(h2aNode,1)">
   setPosition() -- alias of collapse()</button><br/><button onclick="getSelection().collapseToStart()">
   collapseToStart() -- sets caret to the start of
    selection</button><br/><button onclick="getSelection().collapseToEnd()">
   collapseToEnd() -- sets caret to the end of
     selection</button><br/><button onclick="getSelection().extend(strNode,1)">
   extend() -- extends selection to include strNode
   </button><br/><button onclick="getSelection().selectAllChildren(
   bodyNode)">selectAllChildren() –
    selects the entire body</button><br/><button onclick="getSelection().setBaseAndExtent(
    p2Node,1,strNode,1)">setBaseAndExtent() –
     sets a selection</button><br/><button onclick="alert(getSelection())">
    toString()</button><br/></body></html>

<!DOCTYPE html><html>
    <head></head><body>
    <p contenteditable>"JavaScript's global scope is like a public toilet. You can't avoid going in there, but try to limit your contact with surfaces when you do."
        <br/><strong>-- Dmitry Baranovskiy</strong></p>
    <h1></h1>
    <h2></h2>
    <script>
        var pNode = document.querySelector("p");
        var brNode = document.querySelector("br");
        var r1 = document.createRange(),
            r2 = document.createRange(),
            r3 = document.createRange();
        r1.setStart(pNode,0);  // excludes <p>
        r1.setEndBefore(brNode);
        r2.selectNode(pNode);   // includes <p>
        r3.selectNodeContents(pNode);  // excludes <p>
        console.log(r1.commonAncestorContainer==
                          r2.commonAncestorContainer,  // false
                  r1.startContainer==r2.startContainer,  // false
                  r1.startOffset==r2.startOffset,  // false
                  r2.collapsed);  // false
        console.log(r1.commonAncestorContainer==
                         r3.commonAncestorContainer,  // true
                    r1.startContainer==r3.startContainer,  // true
                    r1.startOffset==r3.startOffset,  // true
                    r3.collapsed);  // false
        console.log(r1.compareBoundaryPoints(
           Range.START_TO_START,r3)); // 0=>r1 starts as r3
        console.log(r2.compareBoundaryPoints(
           Range.START_TO_START,r3));             // -1 => r2 starts before r3
        console.log(r3.comparePoint(
           brNode,0));  // 0 => contains
        console.log(r3.isPointInRange(brNode,0));  // true
        console.log(r3.intersectsNode(brNode));  // true
        console.log(r1.cloneRange() == r1.cloneRange());                                               // false => different objects!
        console.log(r1.getBoundingClientRect().height);                                               // 17 : height in px
        console.log(r1.getClientRects());  // DOMRect[3]
        document.querySelector("h1").
                appendChild(r2.cloneContents());  // <p> copied
        document.querySelector("h2").
                appendChild(r2.extractContents());//<p> moved
        r2.deleteContents();  // (no effect. already removed!)
        r2.collapse(true);  // true=>toStart (no effect.)
        var r4 = document.createRange();
        r4.selectNode(document.querySelector("strong"));
        r4.insertNode(document.createTextNode(": by "));
        r4.surroundContents(document.createElement("i"));        //r4.detach();  // releases memory
        alert(r4.toString());  // : by -- Dmitry Baranovskiy
        document.body.appendChild(
          document.createRange().createContextualFragment(
          "<h3>Good!</h3>"))
    </script><button onclick="getSelection().addRange(r4)">
   addRange()</button><br/></body></html>