<html>
    <head>
        <script>
            function setup()
            {
                var results = document.createElement('div');
                results.id = "res";
                results.appendChild(document.createTextNode("Results:"));
                document.body.appendChild(results);
            }
            function checkSelection(expected)
            {
                actual = getSelectedOptions("sl1");
                if (actual.toString() != expected)
                    log('Incorrect selection: "' + actual + '" instead of "' + expected + '"');
            }
            function test()
            {
                setup();
                
                if (window.testRunner) {
                    testRunner.dumpAsText();
                    testRunner.waitUntilDone();
                }

                checkSelection("0");

                log("1) Make sure onChange doesn't fire when clicking on an initially selected item");
                mouseDownOnSelect("sl1", 0, false, false);
                mouseUpOnSelect("sl1", 0, false, false);
                checkSelection("0");

                log("2) Make sure onChange fires when deselecting an initially selected item");
                mouseDownOnSelect("sl1", 0, false, true);
                mouseUpOnSelect("sl1", 0, false, true);
                checkSelection("");

                log("3) Make sure onChange fires when clicking");
                mouseDownOnSelect("sl1", 2, false, false);
                mouseUpOnSelect("sl1", 2, false, false);
                checkSelection("2");

                log("4) Make sure onChange doesn't fire when clicking again on the same item");
                mouseDownOnSelect("sl1", 2, false, false);
                mouseUpOnSelect("sl1", 2, false, false);
                checkSelection("2");

                log("5) Make sure onChange fires when clicking on a new item");
                mouseDownOnSelect("sl1", 0, false, false);
                mouseUpOnSelect("sl1", 0, false, false);
                checkSelection("0");

                log("6) Make sure onChange fires when changing the selection with the keyboard");
                keyDownOnSelect("sl1", "ArrowDown", true, false);
                checkSelection("0,1");

                log("7) Make sure onChange doesn't fire when setting the select element's value from JS");
                document.getElementById("sl1").value = "2";
                checkSelection("2");

                log("8) Make sure onChange doesn't fire when clicking on the already selected option");
                mouseDownOnSelect("sl1", 2, false, false);
                mouseUpOnSelect("sl1", 2, false, false);
                checkSelection("2");

                log("9) Make sure onChange doesn't fire when setting an option's selected state from JS");
                document.getElementById("sl1").item(3).selected = true;
                checkSelection("2,3");
                document.getElementById("sl1").item(2).selected = false;
                checkSelection("3");

                log("10) Make sure onChange doesn't fire when clicking on this option");
                mouseDownOnSelect("sl1", 3, false, false);
                mouseUpOnSelect("sl1", 3, false, false);
                checkSelection("3");

                log("11) Make sure onChange fires when deselecting the last selected option with a mouse click");
                mouseDownOnSelect("sl1", 3, false, true);
                mouseUpOnSelect("sl1", 3, false, true);
                checkSelection("");

                log("12) Make sure onChange doesn't fire when adding a new selected option");
                option = document.createElement("option");
                option.setAttribute("selected", "");
                option.appendChild(document.createTextNode("item 4"));
                document.getElementById("sl1").appendChild(option);
                checkSelection("4");

                log("13) Make sure onChange doesn't fire when clicking on it");
                mouseDownOnSelect("sl1", 4, false, false);
                mouseUpOnSelect("sl1", 4, false, false);
                checkSelection("4");

                log("14) Make sure onChange fires when clicking on a previously selected option");
                mouseDownOnSelect("sl1", 3, false, true);
                mouseUpOnSelect("sl1", 3, false, true);
                checkSelection("3,4");

                log("15) Make sure onChange doesn't fire when removing a selected option");
                document.getElementById("sl1").removeChild(document.getElementById("sl1").item(4));
                checkSelection("3");

                log("16) Make sure onChange doesn't fire when clicking on the option that remains selected");
                mouseDownOnSelect("sl1", 3, false, false);
                mouseUpOnSelect("sl1", 3, false, false);
                checkSelection("3");

                log("17) Make sure onChange fires when typing the name of an option");
                option = document.createElement("option");
                option.appendChild(document.createTextNode("keyboard test"));
                document.getElementById("sl1").appendChild(option);
                keyDownOnSelect("sl1", "K", false, false);
                checkSelection("4");

                log("18) Make sure onChange doesn't fire when leaving the select");
                document.getElementById("sl1").blur();
                checkSelection("4");

                if (window.testRunner)
                    testRunner.notifyDone();
            }

            function buildModifiers(shift, metaOrCtrl) {
                modifiers = [];
                if (shift)
                    modifiers.push("shiftKey");
                if (metaOrCtrl)
                    modifiers.push("addSelectionKey");
                return modifiers;
            }
            
            function mouseDownOnSelect(selId, index, shift, metaOrCtrl)
            {
                modifiers = buildModifiers(shift, metaOrCtrl);
                var sl = document.getElementById(selId);
                var rect = sl.options[index].getBoundingClientRect();
                if (window.eventSender) {
                    eventSender.mouseMoveTo(rect.left + 1, rect.top + 1);
                    eventSender.mouseDown(0, modifiers);
                } else {
                    testFailed("This test requires window.eventSender.");
                }
            }

            function mouseUpOnSelect(selId, index, shift, metaOrCtrl)
            {
                modifiers = buildModifiers(shift, metaOrCtrl);
                var sl = document.getElementById(selId);
                var rect = sl.options[index].getBoundingClientRect();
                if (window.eventSender) {
                    eventSender.mouseMoveTo(rect.left + 1, rect.top + 1);
                    eventSender.mouseUp(0, modifiers);
                } else {
                    testFailed("This test requires window.eventSender.");
                }
            }

            function keyDownOnSelect(selId, identifier, shift, metaOrCtrl)
            {
                modifiers = buildModifiers(shift, metaOrCtrl);
                document.getElementById(selId).focus();
                if (window.eventSender) {
                    eventSender.keyDown(identifier, modifiers);
                } else {
                    testFailed("This test requires window.eventSender.");
                }
            }
            
            function getSelectedOptions(selId)
            {
                result = new Array;
                var sl = document.getElementById(selId);
                for (i = 0; i < sl.options.length; ++i)
                    if (sl.item(i).selected)
                        result.push(i);
                return result;
            }
            
            function log(msg)
            {
                var r = document.getElementById('res');
                r.innerHTML = r.innerHTML + "<br>" + msg;
            }
        </script>
    </head>
    <body onload="test()">
    <select id="sl1" size=5 multiple onchange="log('onChange fired')">
    <option selected value="0">item 0</option>
    <option value="1">item 1
    <option value="2">item 2
    <option value="3">item 3
    </select>
    </body>
</html>
