<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/extensions-test.js"></script>
<script type="text/javascript">

function initialize_extensionsSidebarTest()
{
    InspectorTest.expandSidebar = function(callback)
    {
        var sidebar = InspectorTest._extensionSidebar();
        InspectorTest.runAfterPendingDispatches(function() {
            sidebar.expand();
            callback();
        });
    }

    InspectorTest._extensionSidebar = function()
    {
        var sidebarPanes = WebInspector.panel("elements").sidebarPanes;
        // the sidebar of interest is presumed to always be last.
        return sidebarPanes[Object.keys(sidebarPanes).pop()];
    }
}

function extension_expandSidebar(callback)
{
    evaluateOnFrontend("InspectorTest.expandSidebar(reply);", callback);
}

function extension_testOnSelectionChanged(nextTest)
{
    function onSelectionChanged()
    {
        webInspector.panels.elements.onSelectionChanged.removeListener(onSelectionChanged);
        output("onSelectionChanged fired");
        nextTest();
    }
    webInspector.panels.elements.onSelectionChanged.addListener(onSelectionChanged);
    webInspector.inspectedWindow.eval("inspect(document.body.children[0]), 0");
}

function extension_testOnRequestFinished(nextTest)
{
    function onRequestFinished()
    {
        webInspector.network.onRequestFinished.removeListener(onRequestFinished);
        output("onRequestFinished fired");
        nextTest();
    }
    webInspector.network.onRequestFinished.addListener(onRequestFinished);
    webInspector.inspectedWindow.eval("var xhr = new XMLHttpRequest(); xhr.open('GET', '" + location.href + "', false); xhr.send(null);");
}

function extension_testOnNavigated(nextTest)
{
    var urls = [];
    var loadCount = 0;

    function onLoad()
    {
        ++loadCount;
        processEvent();
    }
    function processEvent()
    {
        if (loadCount !== urls.length)
            return;
        if (loadCount === 1)
            evaluateOnFrontend("InspectorTest.navigate(WebInspector.inspectedPageURL.substring(0, WebInspector.inspectedPageURL.indexOf('?')), reply)", onLoad);
        else {
            webInspector.network.onNavigated.removeListener(onNavigated);
            for (var i = 0; i < urls.length; ++i)
                output("Navigated to: " + urls[i]);
            nextTest();
        }
    }
    function onNavigated(url)
    {
        urls.push(url.replace(/^(.*\/)*/, ""));
        processEvent();
    }
    webInspector.network.onNavigated.addListener(onNavigated);
    evaluateOnFrontend("InspectorTest.navigate(WebInspector.inspectedPageURL + '?navigated', reply)", onLoad);
}

function extension_testViewShowHide(nextTest)
{
    var listenersToCleanup = [];
    var sidebar;
    var beenToExtensionPanel = false;

    function onViewEvent(type, viewName, viewWindow)
    {
        output("Got " + type + " event for " + viewName);
        if (type !== "onShown")
            return;
        if (viewName === "panel") {
            output("Panel shown, location: " + trimURL(viewWindow.location.href));
            extension_showPanel("elements");
        } else if (viewName === "sidebar") {
            output("Sidebar shown, location: " + trimURL(viewWindow.location.href));
            if (!beenToExtensionPanel) {
                extension_showPanel("extension");
                beenToExtensionPanel = true;
            } else {
                cleanupListeners();
                nextTest();
            }
        }
    }
    function addListener(view, viewName, type)
    {
        var listener = bind(onViewEvent, null, type, viewName);
        var event = view[type];
        listenersToCleanup.push({ event: event, listener: listener });
        event.addListener(listener);
    }
    function cleanupListeners()
    {
        for (var i = 0; i < listenersToCleanup.length; ++i)
            listenersToCleanup[i].event.removeListener(listenersToCleanup[i].listener);
    }
    function onPanelCreated(panel)
    {
        addListener(panel, "panel", "onShown");
        addListener(panel, "panel", "onHidden");
        addListener(sidebar, "sidebar", "onHidden");
        addListener(sidebar, "sidebar", "onShown");
        sidebar.setPage(basePath + "extension-sidebar.html");
    }
    extension_showPanel("elements", extension_expandSidebar);
    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
    function onSidebarCreated(sidebarPane)
    {
        sidebar = sidebarPane;
        webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
    }
    webInspector.panels.elements.createSidebarPane("Test Sidebar", onSidebarCreated);
}

function extension_testTimelineEvents(nextTest)
{
    function onTimelineEvent(record)
    {
        if (record.type === "Layout") {
            output("Got Layout event from timeline");
            webInspector.timeline.onEventRecorded.removeListener(onTimelineEvent);
            nextTest();
        }
    }

    webInspector.timeline.onEventRecorded.addListener(onTimelineEvent);

    // Trigger a relayout.
    webInspector.inspectedWindow.eval("document.body.style.float = 'left';");
}

</script>
</head>
<body onload="runTest()">
<p>Tests WebInspector extension API</p>
</body>
</html>
