Expand to smallest range for which canSurroundContents() === true

Answer to https://stackoverflow.com/questions/21309701/rangy-perform-smallest-possible-expansion-so-that-cansurroundcontents-true

HTML

<script src="http://rangy.googlecode.com/svn/trunk/currentrelease/rangy-core.js"></script>
<div>
    <p>Blah blah <strong>strong</strong> blah blah</p>
    <p>More</p>
</div>
<button id="surround">Surround</button>

JavaScript

// Provides the depth of ``descendant`` relative to ``ancestor``
function getDepth(ancestor, descendant) {
    var ret = 0;
    while (descendant !== ancestor) {
        ret++;
        descendant = descendant.parentNode;
        if (!descendant)
            throw new Error("not a descendant of ancestor!");
    }
    return ret;
}

function smallestExpansion() {
    var range = rangy.getSelection().getRangeAt(0);
    if (range.canSurroundContents()){
      	alert("true");
        return;
    };
    var common = range.commonAncestorContainer;
    alert(common.nodeName);
    var start_depth = getDepth(common, range.startContainer);
    var end_depth = getDepth(common, range.endContainer);

    while(!range.canSurroundContents()) {
        // In the following branches, we cannot just decrement the depth variables because the setStartBefore/setEndAfter may move the start or end of the range more than one level relative to ``common``. So we need to recompute the depth.
        if (start_depth > end_depth) {
            range.setStartBefore(range.startContainer.parentNode);
            start_depth = getDepth(common, range.startContainer);
        }
        else {
            range.setEndAfter(range.endContainer.parentNode);
            end_depth = getDepth(common, range.endContainer);
        }
    }
    alert(range.getNodes());
}

$("#surround").click(smallestExpansion);