"use strict";
// Written by Aryeh Gregor <ayg@aryeh.name>

// TODO: iframes, contenteditable/designMode

// Everything is done in functions in this test harness, so we have to declare
// all the variables before use to make sure they can be reused.
var testDiv, paras, detachedDiv, detachedPara1, detachedPara2,
    foreignDoc, foreignPara1, foreignPara2, xmlDoc, xmlElement,
    detachedXmlElement, detachedTextNode, foreignTextNode,
    detachedForeignTextNode, xmlTextNode, detachedXmlTextNode,
    processingInstruction, detachedProcessingInstruction, comment,
    detachedComment, foreignComment, detachedForeignComment, xmlComment,
    detachedXmlComment, docfrag, foreignDocfrag, xmlDocfrag, doctype,
    foreignDoctype, xmlDoctype;
var testRangesShort, testRanges, testPoints, testNodesShort, testNodes;

function setupRangeTests() {
    testDiv = document.querySelector("#test");
    if (testDiv) {
        testDiv.parentNode.removeChild(testDiv);
    }
    testDiv = document.createElement("div");
    testDiv.id = "test";
    document.body.insertBefore(testDiv, document.body.firstChild);

    paras = [];
    paras.push(document.createElement("p"));
    paras[0].setAttribute("id", "a");
    // Test some diacritics, to make sure browsers are using code units here
    // and not something like grapheme clusters.
    paras[0].textContent = "A\u0308b\u0308c\u0308d\u0308e\u0308f\u0308g\u0308h\u0308\n";
    testDiv.appendChild(paras[0]);

    paras.push(document.createElement("p"));
    paras[1].setAttribute("id", "b");
    paras[1].setAttribute("style", "display:none");
    paras[1].textContent = "Ijklmnop\n";
    testDiv.appendChild(paras[1]);

    paras.push(document.createElement("p"));
    paras[2].setAttribute("id", "c");
    paras[2].textContent = "Qrstuvwx";
    testDiv.appendChild(paras[2]);

    paras.push(document.createElement("p"));
    paras[3].setAttribute("id", "d");
    paras[3].setAttribute("style", "display:none");
    paras[3].textContent = "Yzabcdef";
    testDiv.appendChild(paras[3]);

    paras.push(document.createElement("p"));
    paras[4].setAttribute("id", "e");
    paras[4].setAttribute("style", "display:none");
    paras[4].textContent = "Ghijklmn";
    testDiv.appendChild(paras[4]);

    detachedDiv = document.createElement("div");
    detachedPara1 = document.createElement("p");
    detachedPara1.appendChild(document.createTextNode("Opqrstuv"));
    detachedPara2 = document.createElement("p");
    detachedPara2.appendChild(document.createTextNode("Wxyzabcd"));
    detachedDiv.appendChild(detachedPara1);
    detachedDiv.appendChild(detachedPara2);

    // Opera doesn't automatically create a doctype for a new HTML document,
    // contrary to spec.  It also doesn't let you add doctypes to documents
    // after the fact through any means I've tried.  So foreignDoc in Opera
    // will have no doctype, foreignDoctype will be null, and Opera will fail
    // some tests somewhat mysteriously as a result.
    foreignDoc = document.implementation.createHTMLDocument("");
    foreignPara1 = foreignDoc.createElement("p");
    foreignPara1.appendChild(foreignDoc.createTextNode("Efghijkl"));
    foreignPara2 = foreignDoc.createElement("p");
    foreignPara2.appendChild(foreignDoc.createTextNode("Mnopqrst"));
    foreignDoc.body.appendChild(foreignPara1);
    foreignDoc.body.appendChild(foreignPara2);

    // Now we get to do really silly stuff, which nobody in the universe is
    // ever going to actually do, but the spec defines behavior, so too bad.
    // Testing is fun!
    xmlDoctype = document.implementation.createDocumentType("qorflesnorf", "abcde", "x\"'y");
    xmlDoc = document.implementation.createDocument(null, null, xmlDoctype);
    detachedXmlElement = xmlDoc.createElement("everyone-hates-hyphenated-element-names");
    detachedTextNode = document.createTextNode("Uvwxyzab");
    detachedForeignTextNode = foreignDoc.createTextNode("Cdefghij");
    detachedXmlTextNode = xmlDoc.createTextNode("Klmnopqr");
    // PIs only exist in XML documents, so don't bother with document or
    // foreignDoc.
    detachedProcessingInstruction = xmlDoc.createProcessingInstruction("whippoorwill", "chirp chirp chirp");
    detachedComment = document.createComment("Stuvwxyz");
    // Hurrah, we finally got to "z" at the end!
    detachedForeignComment = foreignDoc.createComment("אריה יהודה");
    detachedXmlComment = xmlDoc.createComment("בן חיים אליעזר");

    // We should also test with document fragments that actually contain stuff
    // . . . but, maybe later.
    docfrag = document.createDocumentFragment();
    foreignDocfrag = foreignDoc.createDocumentFragment();
    xmlDocfrag = xmlDoc.createDocumentFragment();

    xmlElement = xmlDoc.createElement("igiveuponcreativenames");
    xmlTextNode = xmlDoc.createTextNode("do re mi fa so la ti");
    xmlElement.appendChild(xmlTextNode);
    processingInstruction = xmlDoc.createProcessingInstruction("somePI", 'Did you know that ":syn sync fromstart" is very useful when using vim to edit large amounts of JavaScript embedded in HTML?');
    xmlDoc.appendChild(xmlElement);
    xmlDoc.appendChild(processingInstruction);
    xmlComment = xmlDoc.createComment("I maliciously created a comment that will break incautious XML serializers, but Firefox threw an exception, so all I got was this lousy T-shirt");
    xmlDoc.appendChild(xmlComment);

    comment = document.createComment("Alphabet soup?");
    testDiv.appendChild(comment);

    foreignComment = foreignDoc.createComment('"Commenter" and "commentator" mean different things.  I\'ve seen non-native speakers trip up on this.');
    foreignDoc.appendChild(foreignComment);
    foreignTextNode = foreignDoc.createTextNode("I admit that I harbor doubts about whether we really need so many things to test, but it's too late to stop now.");
    foreignDoc.body.appendChild(foreignTextNode);

    doctype = document.doctype;
    foreignDoctype = foreignDoc.doctype;

    testRangesShort = [
        // Various ranges within the text node children of different
        // paragraphs.  All should be valid.
        "[paras[0].firstChild, 0, paras[0].firstChild, 0]",
        "[paras[0].firstChild, 0, paras[0].firstChild, 1]",
        "[paras[0].firstChild, 2, paras[0].firstChild, 8]",
        "[paras[0].firstChild, 2, paras[0].firstChild, 9]",
        "[paras[1].firstChild, 0, paras[1].firstChild, 0]",
        "[paras[1].firstChild, 2, paras[1].firstChild, 9]",
        "[detachedPara1.firstChild, 0, detachedPara1.firstChild, 0]",
        "[detachedPara1.firstChild, 2, detachedPara1.firstChild, 8]",
        "[foreignPara1.firstChild, 0, foreignPara1.firstChild, 0]",
        "[foreignPara1.firstChild, 2, foreignPara1.firstChild, 8]",
        // Now try testing some elements, not just text nodes.
        "[document.documentElement, 0, document.documentElement, 1]",
        "[document.documentElement, 0, document.documentElement, 2]",
        "[document.documentElement, 1, document.documentElement, 2]",
        "[document.head, 1, document.head, 1]",
        "[document.body, 4, document.body, 5]",
        "[foreignDoc.documentElement, 0, foreignDoc.documentElement, 1]",
        "[paras[0], 0, paras[0], 1]",
        "[detachedPara1, 0, detachedPara1, 1]",
        // Now try some ranges that span elements.
        "[paras[0].firstChild, 0, paras[1].firstChild, 0]",
        "[paras[0].firstChild, 0, paras[1].firstChild, 8]",
        "[paras[0].firstChild, 3, paras[3], 1]",
        // How about something that spans a node and its descendant?
        "[paras[0], 0, paras[0].firstChild, 7]",
        "[testDiv, 2, paras[4], 1]",
        // Then a few more interesting things just for good measure.
        "[document, 0, document, 1]",
        "[document, 0, document, 2]",
        "[comment, 2, comment, 3]",
        "[testDiv, 0, comment, 5]",
        "[foreignDoc, 1, foreignComment, 2]",
        "[foreignDoc.body, 0, foreignTextNode, 36]",
        "[xmlDoc, 1, xmlComment, 0]",
        "[detachedTextNode, 0, detachedTextNode, 8]",
        "[detachedForeignTextNode, 0, detachedForeignTextNode, 8]",
        "[detachedXmlTextNode, 0, detachedXmlTextNode, 8]",
        "[detachedComment, 3, detachedComment, 4]",
        "[detachedForeignComment, 0, detachedForeignComment, 1]",
        "[detachedXmlComment, 2, detachedXmlComment, 6]",
        "[docfrag, 0, docfrag, 0]",
        "[processingInstruction, 0, processingInstruction, 4]",
    ];

    testRanges = testRangesShort.concat([
        "[paras[1].firstChild, 0, paras[1].firstChild, 1]",
        "[paras[1].firstChild, 2, paras[1].firstChild, 8]",
        "[detachedPara1.firstChild, 0, detachedPara1.firstChild, 1]",
        "[foreignPara1.firstChild, 0, foreignPara1.firstChild, 1]",
        "[foreignDoc.head, 1, foreignDoc.head, 1]",
        "[foreignDoc.body, 0, foreignDoc.body, 0]",
        "[paras[0], 0, paras[0], 0]",
        "[detachedPara1, 0, detachedPara1, 0]",
        "[testDiv, 1, paras[2].firstChild, 5]",
        "[document.documentElement, 1, document.body, 0]",
        "[foreignDoc.documentElement, 1, foreignDoc.body, 0]",
        "[document, 1, document, 2]",
        "[paras[2].firstChild, 4, comment, 2]",
        "[paras[3], 1, comment, 8]",
        "[foreignDoc, 0, foreignDoc, 0]",
        "[xmlDoc, 0, xmlDoc, 0]",
        "[detachedForeignTextNode, 7, detachedForeignTextNode, 7]",
        "[detachedXmlTextNode, 7, detachedXmlTextNode, 7]",
        "[detachedComment, 5, detachedComment, 5]",
        "[detachedForeignComment, 4, detachedForeignComment, 4]",
        "[foreignDocfrag, 0, foreignDocfrag, 0]",
        "[xmlDocfrag, 0, xmlDocfrag, 0]",
    ]);

    testPoints = [
        // Various positions within the page, some invalid.  Remember that
        // paras[0] is visible, and paras[1] is display: none.
        "[paras[0].firstChild, -1]",
        "[paras[0].firstChild, 0]",
        "[paras[0].firstChild, 1]",
        "[paras[0].firstChild, 2]",
        "[paras[0].firstChild, 8]",
        "[paras[0].firstChild, 9]",
        "[paras[0].firstChild, 10]",
        "[paras[0].firstChild, 65535]",
        "[paras[1].firstChild, -1]",
        "[paras[1].firstChild, 0]",
        "[paras[1].firstChild, 1]",
        "[paras[1].firstChild, 2]",
        "[paras[1].firstChild, 8]",
        "[paras[1].firstChild, 9]",
        "[paras[1].firstChild, 10]",
        "[paras[1].firstChild, 65535]",
        "[detachedPara1.firstChild, 0]",
        "[detachedPara1.firstChild, 1]",
        "[detachedPara1.firstChild, 8]",
        "[detachedPara1.firstChild, 9]",
        "[foreignPara1.firstChild, 0]",
        "[foreignPara1.firstChild, 1]",
        "[foreignPara1.firstChild, 8]",
        "[foreignPara1.firstChild, 9]",
        // Now try testing some elements, not just text nodes.
        "[document.documentElement, -1]",
        "[document.documentElement, 0]",
        "[document.documentElement, 1]",
        "[document.documentElement, 2]",
        "[document.documentElement, 7]",
        "[document.head, 1]",
        "[document.body, 3]",
        "[foreignDoc.documentElement, 0]",
        "[foreignDoc.documentElement, 1]",
        "[foreignDoc.head, 0]",
        "[foreignDoc.body, 1]",
        "[paras[0], 0]",
        "[paras[0], 1]",
        "[paras[0], 2]",
        "[paras[1], 0]",
        "[paras[1], 1]",
        "[paras[1], 2]",
        "[detachedPara1, 0]",
        "[detachedPara1, 1]",
        "[testDiv, 0]",
        "[testDiv, 3]",
        // Then a few more interesting things just for good measure.
        "[document, -1]",
        "[document, 0]",
        "[document, 1]",
        "[document, 2]",
        "[document, 3]",
        "[comment, -1]",
        "[comment, 0]",
        "[comment, 4]",
        "[comment, 96]",
        "[foreignDoc, 0]",
        "[foreignDoc, 1]",
        "[foreignComment, 2]",
        "[foreignTextNode, 0]",
        "[foreignTextNode, 36]",
        "[xmlDoc, -1]",
        "[xmlDoc, 0]",
        "[xmlDoc, 1]",
        "[xmlDoc, 5]",
        "[xmlComment, 0]",
        "[xmlComment, 4]",
        "[processingInstruction, 0]",
        "[processingInstruction, 5]",
        "[processingInstruction, 9]",
        "[detachedTextNode, 0]",
        "[detachedTextNode, 8]",
        "[detachedForeignTextNode, 0]",
        "[detachedForeignTextNode, 8]",
        "[detachedXmlTextNode, 0]",
        "[detachedXmlTextNode, 8]",
        "[detachedProcessingInstruction, 12]",
        "[detachedComment, 3]",
        "[detachedComment, 5]",
        "[detachedForeignComment, 0]",
        "[detachedForeignComment, 4]",
        "[detachedXmlComment, 2]",
        "[docfrag, 0]",
        "[foreignDocfrag, 0]",
        "[xmlDocfrag, 0]",
        "[doctype, 0]",
        "[doctype, -17]",
        "[doctype, 1]",
        "[foreignDoctype, 0]",
        "[xmlDoctype, 0]",
    ];

    testNodesShort = [
        "paras[0]",
        "paras[0].firstChild",
        "paras[1].firstChild",
        "foreignPara1",
        "foreignPara1.firstChild",
        "detachedPara1",
        "detachedPara1.firstChild",
        "document",
        "detachedDiv",
        "foreignDoc",
        "foreignPara2",
        "xmlDoc",
        "xmlElement",
        "detachedTextNode",
        "foreignTextNode",
        "processingInstruction",
        "detachedProcessingInstruction",
        "comment",
        "detachedComment",
        "docfrag",
        "doctype",
        "foreignDoctype",
    ];

    testNodes = testNodesShort.concat([
        "paras[1]",
        "detachedPara2",
        "detachedPara2.firstChild",
        "testDiv",
        "detachedXmlElement",
        "detachedForeignTextNode",
        "xmlTextNode",
        "detachedXmlTextNode",
        "xmlComment",
        "foreignComment",
        "detachedForeignComment",
        "detachedXmlComment",
        "foreignDocfrag",
        "xmlDocfrag",
        "xmlDoctype",
    ]);
}
if ("setup" in window) {
    setup(setupRangeTests);
} else {
    // Presumably we're running from within an iframe or something
    setupRangeTests();
}

/**
 * The "length" of a node as defined by the Ranges section of DOM4.
 */
function nodeLength(node) {
    // "The length of a node node depends on node:
    //
    // "DocumentType
    //   "0."
    if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
        return 0;
    }
    // "Text
    // "ProcessingInstruction
    // "Comment
    //   "Its length attribute value."
    // Browsers don't historically support the length attribute on
    // ProcessingInstruction, so to avoid spurious failures, do
    // node.data.length instead of node.length.
    if (node.nodeType == Node.TEXT_NODE || node.nodeType == Node.PROCESSING_INSTRUCTION_NODE || node.nodeType == Node.COMMENT_NODE) {
        return node.data.length;
    }
    // "Any other node
    //   "Its number of children."
    return node.childNodes.length;
}

/**
 * Returns the furthest ancestor of a Node as defined by the spec.
 */
function furthestAncestor(node) {
    var root = node;
    while (root.parentNode != null) {
        root = root.parentNode;
    }
    return root;
}

/**
 * "The ancestor containers of a Node are the Node itself and all its
 * ancestors."
 *
 * Is node1 an ancestor container of node2?
 */
function isAncestorContainer(node1, node2) {
    return node1 == node2 ||
        (node2.compareDocumentPosition(node1) & Node.DOCUMENT_POSITION_CONTAINS);
}

/**
 * Returns the first Node that's after node in tree order, or null if node is
 * the last Node.
 */
function nextNode(node) {
    if (node.hasChildNodes()) {
        return node.firstChild;
    }
    return nextNodeDescendants(node);
}

/**
 * Returns the last Node that's before node in tree order, or null if node is
 * the first Node.
 */
function previousNode(node) {
    if (node.previousSibling) {
        node = node.previousSibling;
        while (node.hasChildNodes()) {
            node = node.lastChild;
        }
        return node;
    }
    return node.parentNode;
}

/**
 * Returns the next Node that's after node and all its descendants in tree
 * order, or null if node is the last Node or an ancestor of it.
 */
function nextNodeDescendants(node) {
    while (node && !node.nextSibling) {
        node = node.parentNode;
    }
    if (!node) {
        return null;
    }
    return node.nextSibling;
}

/**
 * Returns the ownerDocument of the Node, or the Node itself if it's a
 * Document.
 */
function ownerDocument(node) {
    return node.nodeType == Node.DOCUMENT_NODE
        ? node
        : node.ownerDocument;
}

/**
 * Returns true if ancestor is an ancestor of descendant, false otherwise.
 */
function isAncestor(ancestor, descendant) {
    if (!ancestor || !descendant) {
        return false;
    }
    while (descendant && descendant != ancestor) {
        descendant = descendant.parentNode;
    }
    return descendant == ancestor;
}

/**
 * Returns true if ancestor is an inclusive ancestor of descendant, false
 * otherwise.
 */
function isInclusiveAncestor(ancestor, descendant) {
    return ancestor === descendant || isAncestor(ancestor, descendant);
}

/**
 * Returns true if descendant is a descendant of ancestor, false otherwise.
 */
function isDescendant(descendant, ancestor) {
    return isAncestor(ancestor, descendant);
}

/**
 * Returns true if descendant is an inclusive descendant of ancestor, false
 * otherwise.
 */
function isInclusiveDescendant(descendant, ancestor) {
    return descendant === ancestor || isDescendant(descendant, ancestor);
}

/**
 * The position of two boundary points relative to one another, as defined by
 * the spec.
 */
function getPosition(nodeA, offsetA, nodeB, offsetB) {
    // "If node A is the same as node B, return equal if offset A equals offset
    // B, before if offset A is less than offset B, and after if offset A is
    // greater than offset B."
    if (nodeA == nodeB) {
        if (offsetA == offsetB) {
            return "equal";
        }
        if (offsetA < offsetB) {
            return "before";
        }
        if (offsetA > offsetB) {
            return "after";
        }
    }

    // "If node A is after node B in tree order, compute the position of (node
    // B, offset B) relative to (node A, offset A). If it is before, return
    // after. If it is after, return before."
    if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_FOLLOWING) {
        var pos = getPosition(nodeB, offsetB, nodeA, offsetA);
        if (pos == "before") {
            return "after";
        }
        if (pos == "after") {
            return "before";
        }
    }

    // "If node A is an ancestor of node B:"
    if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_CONTAINS) {
        // "Let child equal node B."
        var child = nodeB;

        // "While child is not a child of node A, set child to its parent."
        while (child.parentNode != nodeA) {
            child = child.parentNode;
        }

        // "If the index of child is less than offset A, return after."
        if (indexOf(child) < offsetA) {
            return "after";
        }
    }

    // "Return before."
    return "before";
}

/**
 * "contained" as defined by DOM Range: "A Node node is contained in a range
 * range if node's furthest ancestor is the same as range's root, and (node, 0)
 * is after range's start, and (node, length of node) is before range's end."
 */
function isContained(node, range) {
    var pos1 = getPosition(node, 0, range.startContainer, range.startOffset);
    var pos2 = getPosition(node, nodeLength(node), range.endContainer, range.endOffset);

    return furthestAncestor(node) == furthestAncestor(range.startContainer)
        && pos1 == "after"
        && pos2 == "before";
}

/**
 * "partially contained" as defined by DOM Range: "A Node is partially
 * contained in a range if it is an ancestor container of the range's start but
 * not its end, or vice versa."
 */
function isPartiallyContained(node, range) {
    var cond1 = isAncestorContainer(node, range.startContainer);
    var cond2 = isAncestorContainer(node, range.endContainer);
    return (cond1 && !cond2) || (cond2 && !cond1);
}

/**
 * Index of a node as defined by the spec.
 */
function indexOf(node) {
    if (!node.parentNode) {
        // No preceding sibling nodes, right?
        return 0;
    }
    var i = 0;
    while (node != node.parentNode.childNodes[i]) {
        i++;
    }
    return i;
}

/**
 * extractContents() implementation, following the spec.  If an exception is
 * supposed to be thrown, will return a string with the name (e.g.,
 * "HIERARCHY_REQUEST_ERR") instead of a document fragment.  It might also
 * return an arbitrary human-readable string if a condition is hit that implies
 * a spec bug.
 */
function myExtractContents(range) {
    // "Let frag be a new DocumentFragment whose ownerDocument is the same as
    // the ownerDocument of the context object's start node."
    var ownerDoc = range.startContainer.nodeType == Node.DOCUMENT_NODE
        ? range.startContainer
        : range.startContainer.ownerDocument;
    var frag = ownerDoc.createDocumentFragment();

    // "If the context object's start and end are the same, abort this method,
    // returning frag."
    if (range.startContainer == range.endContainer
    && range.startOffset == range.endOffset) {
        return frag;
    }

    // "Let original start node, original start offset, original end node, and
    // original end offset be the context object's start and end nodes and
    // offsets, respectively."
    var originalStartNode = range.startContainer;
    var originalStartOffset = range.startOffset;
    var originalEndNode = range.endContainer;
    var originalEndOffset = range.endOffset;

    // "If original start node is original end node, and they are a Text,
    // ProcessingInstruction, or Comment node:"
    if (range.startContainer == range.endContainer
    && (range.startContainer.nodeType == Node.TEXT_NODE
    || range.startContainer.nodeType == Node.PROCESSING_INSTRUCTION_NODE
    || range.startContainer.nodeType == Node.COMMENT_NODE)) {
        // "Let clone be the result of calling cloneNode(false) on original
        // start node."
        var clone = originalStartNode.cloneNode(false);

        // "Set the data of clone to the result of calling
        // substringData(original start offset, original end offset − original
        // start offset) on original start node."
        clone.data = originalStartNode.substringData(originalStartOffset,
            originalEndOffset - originalStartOffset);

        // "Append clone as the last child of frag."
        frag.appendChild(clone);

        // "Call deleteData(original start offset, original end offset −
        // original start offset) on original start node."
        originalStartNode.deleteData(originalStartOffset,
            originalEndOffset - originalStartOffset);

        // "Abort this method, returning frag."
        return frag;
    }

    // "Let common ancestor equal original start node."
    var commonAncestor = originalStartNode;

    // "While common ancestor is not an ancestor container of original end
    // node, set common ancestor to its own parent."
    while (!isAncestorContainer(commonAncestor, originalEndNode)) {
        commonAncestor = commonAncestor.parentNode;
    }

    // "If original start node is an ancestor container of original end node,
    // let first partially contained child be null."
    var firstPartiallyContainedChild;
    if (isAncestorContainer(originalStartNode, originalEndNode)) {
        firstPartiallyContainedChild = null;
    // "Otherwise, let first partially contained child be the first child of
    // common ancestor that is partially contained in the context object."
    } else {
        for (var i = 0; i < commonAncestor.childNodes.length; i++) {
            if (isPartiallyContained(commonAncestor.childNodes[i], range)) {
                firstPartiallyContainedChild = commonAncestor.childNodes[i];
                break;
            }
        }
        if (!firstPartiallyContainedChild) {
            throw "Spec bug: no first partially contained child!";
        }
    }

    // "If original end node is an ancestor container of original start node,
    // let last partially contained child be null."
    var lastPartiallyContainedChild;
    if (isAncestorContainer(originalEndNode, originalStartNode)) {
        lastPartiallyContainedChild = null;
    // "Otherwise, let last partially contained child be the last child of
    // common ancestor that is partially contained in the context object."
    } else {
        for (var i = commonAncestor.childNodes.length - 1; i >= 0; i--) {
            if (isPartiallyContained(commonAncestor.childNodes[i], range)) {
                lastPartiallyContainedChild = commonAncestor.childNodes[i];
                break;
            }
        }
        if (!lastPartiallyContainedChild) {
            throw "Spec bug: no last partially contained child!";
        }
    }

    // "Let contained children be a list of all children of common ancestor
    // that are contained in the context object, in tree order."
    //
    // "If any member of contained children is a DocumentType, raise a
    // HIERARCHY_REQUEST_ERR exception and abort these steps."
    var containedChildren = [];
    for (var i = 0; i < commonAncestor.childNodes.length; i++) {
        if (isContained(commonAncestor.childNodes[i], range)) {
            if (commonAncestor.childNodes[i].nodeType
            == Node.DOCUMENT_TYPE_NODE) {
                return "HIERARCHY_REQUEST_ERR";
            }
            containedChildren.push(commonAncestor.childNodes[i]);
        }
    }

    // "If original start node is an ancestor container of original end node,
    // set new node to original start node and new offset to original start
    // offset."
    var newNode, newOffset;
    if (isAncestorContainer(originalStartNode, originalEndNode)) {
        newNode = originalStartNode;
        newOffset = originalStartOffset;
    // "Otherwise:"
    } else {
        // "Let reference node equal original start node."
        var referenceNode = originalStartNode;

        // "While reference node's parent is not null and is not an ancestor
        // container of original end node, set reference node to its parent."
        while (referenceNode.parentNode
        && !isAncestorContainer(referenceNode.parentNode, originalEndNode)) {
            referenceNode = referenceNode.parentNode;
        }

        // "Set new node to the parent of reference node, and new offset to one
        // plus the index of reference node."
        newNode = referenceNode.parentNode;
        newOffset = 1 + indexOf(referenceNode);
    }

    // "If first partially contained child is a Text, ProcessingInstruction, or
    // Comment node:"
    if (firstPartiallyContainedChild
    && (firstPartiallyContainedChild.nodeType == Node.TEXT_NODE
    || firstPartiallyContainedChild.nodeType == Node.PROCESSING_INSTRUCTION_NODE
    || firstPartiallyContainedChild.nodeType == Node.COMMENT_NODE)) {
        // "Let clone be the result of calling cloneNode(false) on original
        // start node."
        var clone = originalStartNode.cloneNode(false);

        // "Set the data of clone to the result of calling substringData() on
        // original start node, with original start offset as the first
        // argument and (length of original start node − original start offset)
        // as the second."
        clone.data = originalStartNode.substringData(originalStartOffset,
            nodeLength(originalStartNode) - originalStartOffset);

        // "Append clone as the last child of frag."
        frag.appendChild(clone);

        // "Call deleteData() on original start node, with original start
        // offset as the first argument and (length of original start node −
        // original start offset) as the second."
        originalStartNode.deleteData(originalStartOffset,
            nodeLength(originalStartNode) - originalStartOffset);
    // "Otherwise, if first partially contained child is not null:"
    } else if (firstPartiallyContainedChild) {
        // "Let clone be the result of calling cloneNode(false) on first
        // partially contained child."
        var clone = firstPartiallyContainedChild.cloneNode(false);

        // "Append clone as the last child of frag."
        frag.appendChild(clone);

        // "Let subrange be a new Range whose start is (original start node,
        // original start offset) and whose end is (first partially contained
        // child, length of first partially contained child)."
        var subrange = ownerDoc.createRange();
        subrange.setStart(originalStartNode, originalStartOffset);
        subrange.setEnd(firstPartiallyContainedChild,
            nodeLength(firstPartiallyContainedChild));

        // "Let subfrag be the result of calling extractContents() on
        // subrange."
        var subfrag = myExtractContents(subrange);

        // "For each child of subfrag, in order, append that child to clone as
        // its last child."
        for (var i = 0; i < subfrag.childNodes.length; i++) {
            clone.appendChild(subfrag.childNodes[i]);
        }
    }

    // "For each contained child in contained children, append contained child
    // as the last child of frag."
    for (var i = 0; i < containedChildren.length; i++) {
        frag.appendChild(containedChildren[i]);
    }

    // "If last partially contained child is a Text, ProcessingInstruction, or
    // Comment node:"
    if (lastPartiallyContainedChild
    && (lastPartiallyContainedChild.nodeType == Node.TEXT_NODE
    || lastPartiallyContainedChild.nodeType == Node.PROCESSING_INSTRUCTION_NODE
    || lastPartiallyContainedChild.nodeType == Node.COMMENT_NODE)) {
        // "Let clone be the result of calling cloneNode(false) on original
        // end node."
        var clone = originalEndNode.cloneNode(false);

        // "Set the data of clone to the result of calling substringData(0,
        // original end offset) on original end node."
        clone.data = originalEndNode.substringData(0, originalEndOffset);

        // "Append clone as the last child of frag."
        frag.appendChild(clone);

        // "Call deleteData(0, original end offset) on original end node."
        originalEndNode.deleteData(0, originalEndOffset);
    // "Otherwise, if last partially contained child is not null:"
    } else if (lastPartiallyContainedChild) {
        // "Let clone be the result of calling cloneNode(false) on last
        // partially contained child."
        var clone = lastPartiallyContainedChild.cloneNode(false);

        // "Append clone as the last child of frag."
        frag.appendChild(clone);

        // "Let subrange be a new Range whose start is (last partially
        // contained child, 0) and whose end is (original end node, original
        // end offset)."
        var subrange = ownerDoc.createRange();
        subrange.setStart(lastPartiallyContainedChild, 0);
        subrange.setEnd(originalEndNode, originalEndOffset);

        // "Let subfrag be the result of calling extractContents() on
        // subrange."
        var subfrag = myExtractContents(subrange);

        // "For each child of subfrag, in order, append that child to clone as
        // its last child."
        for (var i = 0; i < subfrag.childNodes.length; i++) {
            clone.appendChild(subfrag.childNodes[i]);
        }
    }

    // "Set the context object's start and end to (new node, new offset)."
    range.setStart(newNode, newOffset);
    range.setEnd(newNode, newOffset);

    // "Return frag."
    return frag;
}

/**
 * insertNode() implementation, following the spec.  If an exception is meant
 * to be thrown, will return a string with the expected exception name, for
 * instance "HIERARCHY_REQUEST_ERR".
 */
function myInsertNode(range, node) {
    // "If range's start node is a ProcessingInstruction or Comment node, or is
    // a Text node whose parent is null, or is node, throw an
    // "HierarchyRequestError" exception and terminate these steps."
    if (range.startContainer.nodeType == Node.PROCESSING_INSTRUCTION_NODE
            || range.startContainer.nodeType == Node.COMMENT_NODE
            || (range.startContainer.nodeType == Node.TEXT_NODE
                && !range.startContainer.parentNode)
            || range.startContainer == node) {
                    return "HIERARCHY_REQUEST_ERR";
    }

    // "Let referenceNode be null."
    var referenceNode = null;

    // "If range's start node is a Text node, set referenceNode to that Text node."
    if (range.startContainer.nodeType == Node.TEXT_NODE) {
        referenceNode = range.startContainer;

        // "Otherwise, set referenceNode to the child of start node whose index is
        // start offset, and null if there is no such child."
    } else {
        if (range.startOffset < range.startContainer.childNodes.length) {
            referenceNode = range.startContainer.childNodes[range.startOffset];
        } else {
            referenceNode = null;
        }
    }

    // "Let parent be range's start node if referenceNode is null, and
    // referenceNode's parent otherwise."
    var parent_ = referenceNode === null ? range.startContainer :
        referenceNode.parentNode;

    // "Ensure pre-insertion validity of node into parent before
    // referenceNode."
    var error = ensurePreInsertionValidity(node, parent_, referenceNode);
    if (error) {
        return error;
    }

    // "If range's start node is a Text node, set referenceNode to the result
    // of splitting it with offset range's start offset."
    if (range.startContainer.nodeType == Node.TEXT_NODE) {
        referenceNode = range.startContainer.splitText(range.startOffset);
    }

    // "If node is referenceNode, set referenceNode to its next sibling."
    if (node == referenceNode) {
        referenceNode = referenceNode.nextSibling;
    }

    // "If node's parent is not null, remove node from its parent."
    if (node.parentNode) {
        node.parentNode.removeChild(node);
    }

    // "Let newOffset be parent's length if referenceNode is null, and
    // referenceNode's index otherwise."
    var newOffset = referenceNode === null ? nodeLength(parent_) :
        indexOf(referenceNode);

    // "Increase newOffset by node's length if node is a DocumentFragment node,
    // and one otherwise."
    newOffset += node.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
        nodeLength(node) : 1;

    // "Pre-insert node into parent before referenceNode."
    parent_.insertBefore(node, referenceNode);

    // "If range's start and end are the same, set range's end to (parent,
    // newOffset)."
    if (range.startContainer == range.endContainer
    && range.startOffset == range.endOffset) {
        range.setEnd(parent_, newOffset);
    }
}

// To make filter() calls more readable
function isElement(node) {
    return node.nodeType == Node.ELEMENT_NODE;
}

function isText(node) {
    return node.nodeType == Node.TEXT_NODE;
}

function isDoctype(node) {
    return node.nodeType == Node.DOCUMENT_TYPE_NODE;
}

function ensurePreInsertionValidity(node, parent_, child) {
    // "If parent is not a Document, DocumentFragment, or Element node, throw a
    // HierarchyRequestError."
    if (parent_.nodeType != Node.DOCUMENT_NODE
            && parent_.nodeType != Node.DOCUMENT_FRAGMENT_NODE
            && parent_.nodeType != Node.ELEMENT_NODE) {
                return "HIERARCHY_REQUEST_ERR";
    }

    // "If node is a host-including inclusive ancestor of parent, throw a
    // HierarchyRequestError."
    //
    // XXX Does not account for host
    if (isInclusiveAncestor(node, parent_)) {
        return "HIERARCHY_REQUEST_ERR";
    }

    // "If child is not null and its parent is not parent, throw a NotFoundError
    // exception."
    if (child && child.parentNode != parent_) {
        return "NOT_FOUND_ERR";
    }

    // "If node is not a DocumentFragment, DocumentType, Element, Text,
    // ProcessingInstruction, or Comment node, throw a HierarchyRequestError."
    if (node.nodeType != Node.DOCUMENT_FRAGMENT_NODE
            && node.nodeType != Node.DOCUMENT_TYPE_NODE
            && node.nodeType != Node.ELEMENT_NODE
            && node.nodeType != Node.TEXT_NODE
            && node.nodeType != Node.PROCESSING_INSTRUCTION_NODE
            && node.nodeType != Node.COMMENT_NODE) {
                return "HIERARCHY_REQUEST_ERR";
    }

    // "If either node is a Text node and parent is a document, or node is a
    // doctype and parent is not a document, throw a HierarchyRequestError."
    if ((node.nodeType == Node.TEXT_NODE
                && parent_.nodeType == Node.DOCUMENT_NODE)
            || (node.nodeType == Node.DOCUMENT_TYPE_NODE
                && parent_.nodeType != Node.DOCUMENT_NODE)) {
                    return "HIERARCHY_REQUEST_ERR";
    }

    // "If parent is a document, and any of the statements below, switched on
    // node, are true, throw a HierarchyRequestError."
    if (parent_.nodeType == Node.DOCUMENT_NODE) {
        switch (node.nodeType) {
        case Node.DOCUMENT_FRAGMENT_NODE:
            // "If node has more than one element child or has a Text node
            // child.  Otherwise, if node has one element child and either
            // parent has an element child, child is a doctype, or child is not
            // null and a doctype is following child."
            if ([].filter.call(node.childNodes, isElement).length > 1) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if ([].some.call(node.childNodes, isText)) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if ([].filter.call(node.childNodes, isElement).length == 1) {
                if ([].some.call(parent_.childNodes, isElement)) {
                    return "HIERARCHY_REQUEST_ERR";
                }

                if (child && child.nodeType == Node.DOCUMENT_TYPE_NODE) {
                    return "HIERARCHY_REQUEST_ERR";
                }

                if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
                               .filter(isDoctype)) {
                    return "HIERARCHY_REQUEST_ERR";
                }
            }
            break;

        case Node.ELEMENT_NODE:
            // "parent has an element child, child is a doctype, or child is
            // not null and a doctype is following child."
            if ([].some.call(parent_.childNodes, isElement)) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if (child.nodeType == Node.DOCUMENT_TYPE_NODE) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
                           .filter(isDoctype)) {
                return "HIERARCHY_REQUEST_ERR";
            }
            break;

        case Node.DOCUMENT_TYPE_NODE:
            // "parent has a doctype child, an element is preceding child, or
            // child is null and parent has an element child."
            if ([].some.call(parent_.childNodes, isDoctype)) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if (child && [].slice.call(parent_.childNodes, 0, indexOf(child))
                           .some(isElement)) {
                return "HIERARCHY_REQUEST_ERR";
            }

            if (!child && [].some.call(parent_.childNodes, isElement)) {
                return "HIERARCHY_REQUEST_ERR";
            }
            break;
        }
    }
}

/**
 * Asserts that two nodes are equal, in the sense of isEqualNode().  If they
 * aren't, tries to print a relatively informative reason why not.  TODO: Move
 * this to testharness.js?
 */
function assertNodesEqual(actual, expected, msg) {
    if (!actual.isEqualNode(expected)) {
        msg = "Actual and expected mismatch for " + msg + ".  ";

        while (actual && expected) {
            assert_true(actual.nodeType === expected.nodeType
                && actual.nodeName === expected.nodeName
                && actual.nodeValue === expected.nodeValue,
                "First differing node: expected " + format_value(expected)
                + ", got " + format_value(actual) + " [" + msg + "]");
            actual = nextNode(actual);
            expected = nextNode(expected);
        }

        assert_unreached("DOMs were not equal but we couldn't figure out why");
    }
}

/**
 * Given a DOMException, return the name (e.g., "HIERARCHY_REQUEST_ERR").
 */
function getDomExceptionName(e) {
    var ret = null;
    for (var prop in e) {
        if (/^[A-Z_]+_ERR$/.test(prop) && e[prop] == e.code) {
            return prop;
        }
    }

    throw "Exception seems to not be a DOMException?  " + e;
}

/**
 * Given an array of endpoint data [start container, start offset, end
 * container, end offset], returns a Range with those endpoints.
 */
function rangeFromEndpoints(endpoints) {
    // If we just use document instead of the ownerDocument of endpoints[0],
    // WebKit will throw on setStart/setEnd.  This is a WebKit bug, but it's in
    // range, not selection, so we don't want to fail anything for it.
    var range = ownerDocument(endpoints[0]).createRange();
    range.setStart(endpoints[0], endpoints[1]);
    range.setEnd(endpoints[2], endpoints[3]);
    return range;
}
