<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <style type="text/css">
        .pass { color: green; }
        .fail { color: red; }
    </style>
    <script type="text/javascript" charset="utf-8">
        function printOut(msg)
        {
            var console = document.getElementById("console");
            var span = document.createElementNS('http://www.w3.org/1999/xhtml', 'span');
            // span.innerHTML = msg + "<br />";
            span.appendChild(document.createTextNode(msg));
            span.appendChild(document.createElementNS('http://www.w3.org/1999/xhtml', 'br'));
            console.appendChild(span);
        }

        function resultStringifier(result)
        {
            if (result === "")
                return "the empty string";
            else if (result === undefined)
                return "undefined";
            else if (result === null)
                return "null";
            return "the string '" + result + "'";
        }

        function nullTestElementAttribute(elementType, element, attr, expected)
        {
            element[attr] = null;

            var result;
            if (element[attr] === expected)
                result = "TEST SUCCEEDED: The value was " + resultStringifier(expected) + ".";
            else
                result = "TEST FAILED: The value should have been " + resultStringifier(expected) + " but was " + resultStringifier(element[attr]) + ".";

            result += " [tested " + elementType + "." + attr + "]";
            printOut(result);
        }
        
        function runTests()
        {
            if (window.testRunner)
                testRunner.dumpAsText();

            var listing = [
                {
                    type: 'Attr',
                    elementToUse: document.createAttributeNS('http://www.w3.org/1999/xhtml','anAttribute'),
                    attributes: [
                        {name: 'value', expectedNull: 'null'}
                    ]
                },
                {
                    type: 'ProcessingInstruction',
                    elementToUse: document.createProcessingInstruction('target', 'data'),
                    attributes: [
                        {name: 'data', expectedNull: ''}
                    ]
                },
                {
                    type: 'CharacterData',
                    elementToUse: document.createTextNode('text'),
                    attributes: [
                        {name: 'data', expectedNull: ''}
                    ]
                }
            ];

            for (element in listing) {
                var type = listing[element].type;
                var elementToUse = listing[element].elementToUse;
                var attrs = listing[element].attributes;
                for (attr in attrs) {
                    nullTestElementAttribute(type, elementToUse, attrs[attr].name, attrs[attr].expectedNull);
                }
                printOut('');
            }
        }
        
    </script>
</head>

<body onload="runTests();">
    <p>This test setting various attributes of a elements to JavaScript null.</p>
    <div id="console"></div>
</body>
</html>
