<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>
window.onload = runTest;

function removeNode()
{
    document.getElementById("target_element").remove();
}

function moveNode()
{
    var targetElement = document.getElementById("target_element");
    document.getElementById("final_container").appendChild(targetElement);
}

function test()
{
    var nodesById = {};

    InspectorProtocol.eventHandler["DOM.setChildNodes"] = onSetChildNodes;
    InspectorProtocol.eventHandler["DOM.childNodeRemoved"] = onChildNodeRemoved;
    InspectorProtocol.eventHandler["DOM.childNodeInserted"] = onChildNodeInserted;
    InspectorProtocol.eventHandler["Debugger.paused"] = onDebuggerPaused;
    InspectorProtocol.eventHandler["Debugger.scriptParsed"] = onScriptParsed;
    
    function createNodeAttributesMap(attributes)
    {
        var attributesMap = {};
        for (var i = 0; i < attributes.length; i += 2)
            attributesMap[attributes[i]] = attributes[i + 1];
        return attributesMap;
    }

    function collectNode(node)
    {
        if (node.nodeType === 1)
            node.attributes = createNodeAttributesMap(node.attributes);
        if (node.children)
            node.children.forEach(collectNode);
        nodesById[node.nodeId] = node;
    }

    function nodeToString(node)
    {
        switch (node.nodeType) {
        case 1:
            return node.localName + "#" + node.attributes.id;
        case 3:
            return "<text node " + JSON.stringify(node.nodeValue) + ">";
        default:
            return "<nodeType " + node.nodeType + ">";
        }
    }

    function getNodeIdentifier(nodeId)
    {
        if (!nodeId)
            return "<invalid node id>";
        var node = nodesById[nodeId];
        return node ? nodeToString(node) : "<unknown node>";
    }

    function onSetChildNodes(response)
    {
        response.params.nodes.forEach(collectNode);
    }

    function onChildNodeRemoved(response)
    {
        var nodeId = response.params.nodeId;
        ProtocolTest.expectThat(getNodeIdentifier(nodeId) === "div#target_element", "onChildNodeRemoved called for #target_element");
        delete nodesById[nodeId];
    }

    function onChildNodeInserted(response)
    {
        collectNode(response.params.node);
        ProtocolTest.expectThat(getNodeIdentifier(response.params.parentNodeId) === "div#final_container", "onChildNodeInserted called for parent node #final_container");
        ProtocolTest.expectThat(getNodeIdentifier(response.params.node.nodeId) === "div#target_element", "onChildNodeInserted called for child node #target_element");
    }

    function onDebuggerPaused(response)
    {   
        ProtocolTest.log("Stopped on DOM breakpoint");
        InspectorProtocol.sendCommand("Runtime.evaluate", {"expression": "moveNode()"}, function() {
            InspectorProtocol.sendCommand("Debugger.resume");
            ProtocolTest.completeTest();
        });
    }

    function onScriptParsed(messageObject)
    {
        // FIXME: The DOM breakpoints are not working unless there's a JS brakpoint set. Setting a fake breakpoint to workaround that.
        // https://bugs.webkit.org/show_bug.cgi?id=123770 
        if (/node-removed\.html$/.test(messageObject.params.url) && messageObject.params.startLine > 20) {
            InspectorProtocol.eventHandler["Debugger.scriptParsed"] = null;
            ProtocolTest.log("Found <script>");
            var location = {scriptId: messageObject.params.scriptId, lineNumber: messageObject.params.startLine + 2, columnNumber: 0};
            InspectorProtocol.sendCommand("Debugger.setBreakpoint", {location: location}, function() {
                InspectorProtocol.sendCommand("DOM.getDocument", {}, onGotDocument);
            });
        }
    }

    function onGotDocument(response)
    {
        InspectorProtocol.checkForError(response);
        InspectorProtocol.sendCommand("DOM.querySelectorAll", {"nodeId": response.result.root.nodeId, "selector": "#target_element,#final_container"}, onQuerySelectorAll);
    }

    function onQuerySelectorAll(response)
    {
        var targetElementId = response.result.nodeIds[0];
        var finalContainerId = response.result.nodeIds[1];

        InspectorProtocol.sendCommand("DOMDebugger.setDOMBreakpoint", {nodeId: targetElementId, type: "node-removed"});
        InspectorProtocol.sendCommand("DOM.requestChildNodes", {nodeId: finalContainerId});

        InspectorProtocol.sendCommand("Runtime.evaluate", {"expression": "removeNode()"});
    }

    InspectorProtocol.sendCommand("Debugger.enable", {});
}
</script>
</head>
<body>

<p>Testing that DOM.childNodeRemoved is correctly triggered even when the element is moved while paused in the debugger on a DOMDebugger "node-removed" breakpoint.</p>

<div id="target_element"></div>
<div id="final_container"></div>

<!-- Script tag required to workaround bug 123770. See onScriptParsed for details. -->
<script>// Line 0
function testFunction() { // Line 1
    console.log("FAIL: Workaround JS code should not run.");
}
</script>

</body>
</html>
