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);