<html>
<head>
    <style type="text/css">
        .pass { color: green; }
        .fail { color: red; }
    </style>
    <style type="text/css">
        .foo { color: black; }
        @media screen {
            .bar { color: blue; }
        }
        </style>
    <script>
        function printOut(msg) {
            var console = document.getElementById("console");
            var span = document.createElement('span');
            span.innerHTML = msg + '<br>';
            console.appendChild(span);
        }

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

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

            var result;
            if (element[attr] === expected)
                result = "<span class='pass'>TEST SUCCEEDED:</span> The value was " + resultStringifier(expected) + ".";
            else
                result = "<span class='fail'>TEST FAILED:</span> The value should have been " + resultStringifier(expected) + " but was " + resultStringifier(element[attr]) + ".";

            result += " [tested " + elementType + "." + attr + "]";
            printOut(result);
        }

        function runTests() {
            if (window.layoutTestController)
                layoutTestController.dumpAsText();

            var rules = document.getElementsByTagName('style')[1].sheet.cssRules;

            var rule = rules.item(0);            
            var style = rule.style;
            var value = style.getPropertyCSSValue('color');
            var mediaList = rules.item(1).media;


            var listing = [
                {
                    type: 'CSSRule',
                    elementToUse: rule,
                    attributes: [
                         // for now, setting cssText does not doing anything. When it gets implemented, the expectedNull
                         // should become the empty string. 
                        {name: 'cssText', expectedNull: '.foo { color: black; }'}
                    ]
                },
                {
                    type: 'CSSStyleRule',
                    elementToUse: rule,
                    attributes: [
                         // for now, setting selectorText does not doing anything. When it gets implemented, the expectedNull
                         // should become the empty string. 
                        {name: 'selectorText', expectedNull: '.foo'}
                    ]
                },
                {
                    type: 'CSSStyleDeclaration',
                    elementToUse: style,
                    attributes: [
                        // cssText detects syntax errors, such as JS null, and sets the value to the empty string.
                        {name: 'cssText', expectedNull: ''}
                    ]
                },
                {
                    type: 'CSSValue',
                    elementToUse: value,
                    attributes: [
                        // for now, setting cssText does not doing anything. When it gets implemented, the expectedNull
                        // should become the empty string. 
                        {name: 'cssText', expectedNull: 'black'}
                    ]
                },
                {
                    type: 'MediaList',
                    elementToUse: mediaList,
                    attributes: [
                        {name: 'mediaText', expectedNull: ''}
                    ]
                }
                // ,{
                //     type: 'PageRule',
                //     elementToUse: mediaList,
                //     attributes: [
                //         {name: 'cssText', 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 CSSOM elements to JavaScript null.</p>
    <div id="console"></div>
</body>
</html>
