<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>
