<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Installed Plug-ins</title>
</head>
<body>
<script type="application/x-javascript">
if (window.testRunner)
    testRunner.dumpAsText()

navigator.plugins.refresh(false); // Supposedly helps if new plug-ins were added.

var foundTestPlugin = false;

for (var i = 0; i < navigator.plugins.length; i++) {
    var plugin = navigator.plugins[i];

    // We can only guarantee that the Test PlugIn is installed.
    if (plugin.name != "WebKit Test PlugIn")
        continue;
    else
        foundTestPlugin = true;

    document.writeln("<p>Name: " + plugin.name + "<\/p>");
    document.writeln("<p>Description: " + plugin.description + "<\/p>");
    document.writeln("<p>Filename: " + plugin.filename + "<\/p>");

    document.writeln("<p>Mime Types:<\/p>");
    for (var mi = 0; mi != plugin.length; ++mi) {
        document.writeln("<p>Type: " + plugin[mi].type + "<\/p>");
        document.writeln("<p>Description: " + plugin[mi].description + "<\/p>");
        document.writeln("<p>Suffixes: " + plugin[mi].suffixes + "<\/p>");
        document.writeln("<br>");

        if (plugin.item(mi).type == plugin[mi].type) {
            document.writeln("<p>Plugin.item() works.<\/p>");
        } else {
            document.writeln("<p>FAIL. Plugin.item() does not work.<\/p>");
        }

        if (plugin.namedItem(plugin[mi].type).type == plugin[mi].type) {
            document.writeln("<p>Plugin.namedItem() works.<\/p>");
        } else {
            document.writeln("<p>FAIL. Plugin.namedItem() does not work.<\/p>");
        }
    }

    if (navigator.plugins.item(i).name == plugin.name) {
        document.writeln("<p>PluginArray.item() works.<\/p>");
    } else {
        document.writeln("<p>FAIL. PluginArray.item() does not work.<\/p>");
    }

    if (navigator.plugins.namedItem(plugin.name).name == plugin.name) {
        document.writeln("<p>PluginArray.namedItem() works.<\/p>");
    } else {
        document.writeln("<p>FAIL. PluginArray.namedItem() does not work.<\/p>");
    }
}

for (var i = 0; i < navigator.mimeTypes.length; i++) {
    var mimeType = navigator.mimeTypes[i];

    // We can only guarantee that the Test PlugIn is installed.
    if (mimeType.type != "application/x-webkit-test-netscape")
        continue;

    document.writeln("<p>Type: " + mimeType.type + "<\/p>");
    document.writeln("<p>Description: " + mimeType.description + "<\/p>");
    document.writeln("<p>Suffixes: " + mimeType.suffixes + "<\/p>");

    if (navigator.mimeTypes.item(i).type == mimeType.type) {
        document.writeln("<p>MimeTypeArray.item() works.<\/p>");
    } else {
        document.writeln("<p>FAIL. MimeTypeArray.item() does not work.<\/p>");
    }

    if (navigator.mimeTypes.namedItem(mimeType.type).type == mimeType.type) {
        document.writeln("<p>MimeTypeArray.namedItem() works.<\/p>");
    } else {
        document.writeln("<p>FAIL. MimeTypeArray.namedItem() does not work.<\/p>");
    }
}

if (!foundTestPlugin)
    document.writeln("<p>FAILURE!  (Failed to find netscape test plugin)<\/p>");
</script>
</body>
</html>
