<html manifest="resources/remove-cache.php">
<p>Test that a 404 response for manifest results in cache removal.</p>
<body>
<ul>
<li>Frame 1: Manifest is still available, so a new master resource is added to the cache.
<li>Frame 2: Manifest loading results in 404 response, so the cache group becomes obsolete, and an obsolete event is dispatched (because the document in frame was associated with a cache in the group).
<li>Frame 3: Manifest is still 404 - the document is never associated with a cache.
<li>Frame 4: Manifest is now available, so the document gets associated with a cache in a newly created group; the obsolete cache group is not affected.
</ul>
<p>Should say SUCCESS:</p>
<div id=result></div>

<script>
if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
}

function log(message)
{
    document.getElementById("result").innerHTML += message + "<br>";
}

function setManifestDeleted(state)
{
    var req = new XMLHttpRequest;
    req.open("GET", "resources/remove-cache.php?command=" + (state ? "delete" : "reset"), false);
    req.send(null);
}

function test()
{
    clearTimeout(timeoutId);

    // The frame will be associated to a cache, and its main resource will be added to the cache.
    var ifr = document.createElement("iframe");
    ifr.setAttribute("src", "resources/remove-cache-frame.html");
    document.body.appendChild(ifr);
    applicationCache.onnoupdate = test2;
}

function test2()
{
    applicationCache.onnoupdate = function() { log("Unexpected noupdate event") }
    applicationCache.oncached = function() { log("Unexpected cached event") }

    setManifestDeleted(true);
    // The frame will be associated to a cache, but update will obsolete it.
    var ifr = document.createElement("iframe");
    ifr.setAttribute("src", "resources/remove-cache-frame.html");
    document.body.appendChild(ifr);
    applicationCache.onobsolete = test3;
}

function test3()
{
    applicationCache.onchecking = function() { log("Unexpected checking event after obsolete event") }
    applicationCache.onupdateready = function() { log("Unexpected updateready event after obsolete event") }
    applicationCache.onerror = function() { log("Unexpected error event after obsolete event") }
    applicationCache.onnoupdate = function() { log("Unexpected noupdate event after obsolete event") }
    applicationCache.oncached = function() { log("Unexpected cached event after obsolete event") }

    // The frame will not be associated to a cache.
    var ifr = document.createElement("iframe");
    ifr.setAttribute("src", "resources/remove-cache-frame.html");
    document.body.appendChild(ifr);
    window.addEventListener("message", test4, false);
}

function test4()
{
    setManifestDeleted(false);

    window.removeEventListener("message", test4, false);
    applicationCache.onupdateready = null;

    // The frame will be associated to a cache.
    var ifr = document.createElement("iframe");
    ifr.setAttribute("src", "resources/remove-cache-frame-2.html");
    document.body.appendChild(ifr);
    window.addEventListener("message", test5, false);
}

function test5()
{
    log("SUCCESS");
    if (window.testRunner)
        testRunner.notifyDone();
}

function resetManifest()
{
    if (applicationCache.status != applicationCache.UNCACHED && applicationCache.status != applicationCache.OBSOLETE) {
        timeoutId = setTimeout(resetManifest, 100);
        return;
    }

    setManifestDeleted(false);
    location.reload();
}

applicationCache.onupdateready = function() { log("Unexpected updateready event") }
applicationCache.onnoupdate = test;
applicationCache.oncached = test;

// If the manifest script happened to be in a wrong state, reset it.
var timeoutId = setTimeout(resetManifest, 100);

</script>
</body>
</html>
