What are the valid node types for the Range SetEndAfter function in Safari?

advertisements

I am writing a module that should allow users to select parts of an HTML document. To get the internals to work I expand the Range of the selection to a valid HTML snippet.

For the case where B is a descendant of A I find the ancestor of B which is a child of A and want to set the range to end after that node using setEndAfter. This is what I have now:

var closestChild = function (node, descendant) {
    var parent;
    if (descendant.parentElement) {
        parent = descendant.parentElement;
        if ( node === parent ) {
            return descendant;
        }
        return closestChild(node, parent);
    }
    return false;
}

var legalRange = function (range) {
        var newRange = range.cloneRange(),
            child;
        if (range.startContainer === range.endContainer) {
            return newRange;
        }
        child = closestChild(range.startContainer.parentElement, range.endContainer.parentElement);
        if (child) {
            newRange.setEndAfter(child);
            return newRange;
        }
        return null;
};

But this throws a INVALID_NODE_TYPE_ERR: DOM Range Exception 2 when I try to set the end point. I have also tried using parentNode instead of parentElement with the same exception thrown. This is not a problem if i use setEnd(). What types of nodes should I pass to do this.

PS: It turns out that the code works in FireFox, so my problem is now with Safari and Chrome.


I found the solution. When I set up my test cases, I didn't add the elements to the document. It seems that Chrome and Safari treated the nodes as invalid when using setEndAfter if the nodes were not part of the document.