<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.layoutTestController)
    layoutTestController.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>
