<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/extensions-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script>
<link rel="stylesheet" href="resources/audits-style1.css" type="text/css">
<script type="text/javascript" src="resources/test-script.js"></script>

<script type="text/javascript">
function logMessage()
{
    console.log("don't panic!");
}

function initialize_ExtensionResourceTests()
{

InspectorTest.clickOnURL = function()
{
    WebInspector.showPanel("console");
    var xpathResult = document.evaluate("//a[starts-with(., 'extensions-resources.html')]",
                                        WebInspector.panels.console.element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
    var click = document.createEvent("MouseEvent");
    click.initMouseEvent("click", true, true);
    xpathResult.singleNodeValue.dispatchEvent(click);
}

}

function extension_testGetAllResources(nextTest)
{
    function callback(resources)
    {
        function filter(resource)
        {
            // For some reason scripts from tests previously run in the same test shell sometimes appear, so we need to filter them out.
            const resourceURLsWhiteList = ["abe.png", "audits-style1.css", "extensions-resources.html", "extensions-test.js", "inspector-test.js", "test-script.js"];
            for (var i = 0; i < resourceURLsWhiteList.length; ++i) {
                if (resource.url.indexOf(resourceURLsWhiteList[i]) !== -1)
                  return true;
            }
            return false;
        }

        function compareResources(a, b)
        {
            return trimURL(a.url).localeCompare(trimURL(b.url));
        }
        resources = resources.filter(filter);
        resources.sort(compareResources);
        output("page resources:");
        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
    }
    webInspector.inspectedWindow.getResources(callbackAndNextTest(callback, nextTest));
}

function extension_runWithResource(regexp, callback)
{
    function onResources(resources)
    {
       for (var i = 0; i < resources.length; ++i) {
           if (regexp.test(resources[i].url)) {
               callback(resources[i])
               return;
           }
       }
       throw "Failed to find a resource: " + regexp.toString();
    }
    webInspector.inspectedWindow.getResources(onResources);
}

function extension_testGetResourceContent(nextTest)
{
    function onContent()
    {
        dumpObject(Array.prototype.slice.call(arguments));
    }
    extension_runWithResource(/test-script\.js$/, function(resource) {
        resource.getContent(callbackAndNextTest(onContent, nextTest));
    });
}

// Extensions tests override WebInspector.StyleFile.updateTimeout because otherwise extensions don't have any control over applying changes to domain specific bindings.
function extension_setFakeStyleSheetUpdateTimeout(callback)
{
    evaluateOnFrontend("WebInspector.oldStyleSheetUpdateTimeout = WebInspector.StyleFile.updateTimeout; WebInspector.StyleFile.updateTimeout = -1; reply();", callback);
}

function extension_resetStyleSheetUpdateTimeout(callback)
{
    evaluateOnFrontend("WebInspector.StyleFile.updateTimeout = WebInspector.oldStyleSheetUpdateTimeout; delete WebInspector.oldStyleSheetUpdateTimeout; reply();", callback);
}

function extension_testSetResourceContent(nextTest)
{
    extension_setFakeStyleSheetUpdateTimeout(step2);

    function step2()
    {
        extension_runWithResource(/audits-style1\.css$/, function(resource) {
            resource.setContent("div.test { width: 126px; height: 42px; }", false, step3);
        });
    }

    function step3()
    {
        webInspector.inspectedWindow.eval("document.getElementById('test-div').clientWidth", function(result) {
            output("div.test width after stylesheet edited (should be 126): " + result);
            step4();
        });
    }

    function step4()
    {
        extension_resetStyleSheetUpdateTimeout(nextTest);
    }
}

function extension_testOnContentCommitted(nextTest)
{
    var expected_content = "div.test { width: 220px; height: 42px; }";
    extension_setFakeStyleSheetUpdateTimeout(step2);

    function step2()
    {

        webInspector.inspectedWindow.onResourceContentCommitted.addListener(onContentCommitted);
        extension_runWithResource(/audits-style1\.css$/, function(resource) {
            resource.setContent("div.test { width: 140px; height: 42px; }", false);
        });
        // The next step is going to produce a console message that will be logged, so synchronize the output now.
        evaluateOnFrontend("InspectorTest.runAfterPendingDispatches(reply)", function() {
            extension_runWithResource(/abe\.png$/, function(resource) {
                resource.setContent("", true);
            });
            extension_runWithResource(/audits-style1\.css$/, function(resource) {
                resource.setContent(expected_content, true);
            });
        });
    }

    function onContentCommitted(resource, content)
    {
        output("content committed for resource " + trimURL(resource.url) + " (type: " + resource.type + "), new content: " + content);
        if (!/audits-style1\.css$/.test(resource.url) || content !== expected_content)
            output("FAIL: stray onContentEdited event");
        webInspector.inspectedWindow.onResourceContentCommitted.removeListener(onContentCommitted);
        resource.getContent(function(content) {
            output("Revision content: " + content);
            step3();
        });
    }

    function step3()
    {
        extension_resetStyleSheetUpdateTimeout(nextTest);
    }
}

function extension_testOnResourceAdded(nextTest)
{
    evaluateOnFrontend("InspectorTest.startDebuggerTest(reply);", step2);

    function step2()
    {
        webInspector.inspectedWindow.onResourceAdded.addListener(onResourceAdded);
        webInspector.inspectedWindow.eval("addResource()");
    }

    function onResourceAdded(resource)
    {
        if (resource.url.indexOf("test_func") === -1)
            return;
        output("resource added:");
        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
        webInspector.inspectedWindow.onResourceAdded.removeListener(onResourceAdded);

        evaluateOnFrontend("InspectorTest.finishDebuggerTest(reply);", nextTest);
    }
}

function extension_testOpenResourceHandler(nextTest)
{
    function handleOpenResource(resource, lineNumber)
    {
        output("handleOpenResource() invoked [this should only appear once!]: ");
        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
        webInspector.panels.setOpenResourceHandler(null);
        evaluateOnFrontend("InspectorTest.clickOnURL(); reply()", nextTest);
    }
    webInspector.panels.setOpenResourceHandler(handleOpenResource);
    webInspector.inspectedWindow.eval("logMessage()", function() {
        evaluateOnFrontend("InspectorTest.clickOnURL();");
        evaluateOnFrontend("WebInspector.openAnchorLocationRegistry.activeHandler = 'test extension'; InspectorTest.clickOnURL();");
    });
}

function addResource()
{
    var script = document.createElement("script");
    script.src = "data:application/javascript," + escape("function test_func(){};");
    document.head.appendChild(script);
}

</script>
</head>
<body onload="runTest()">
<p>Tests resource-related methods of WebInspector extension API</p>
<img src="resources/abe.png">
<div id="test-div" class="test"></div>
</body>
</html>
