| <html> |
| <head> |
| <script src="../../resources/js-test-pre.js"></script> |
| <style> |
| #square { |
| display: table-cell; |
| vertical-align: middle; |
| background: blue; |
| width: 128px; |
| height: 128px; |
| color: white; |
| text-align: center; |
| padding: 10px; |
| cursor: default; |
| -webkit-user-drag: none; |
| -webkit-user-select: none; |
| } |
| </style> |
| <script> |
| var didFireMousedownForFirstMouseButton; |
| var didFireMousedownForSecondMouseButton; |
| var firstMouseButtonElem; |
| var previouslyChosenFirstMouseButton = 0; |
| var secondMouseButtonElem; |
| var square; |
| |
| // Extracted from the DOM Level 3 Events Mouse Event Types section <http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button>. |
| var LeftMouseButton = 0; |
| var MiddleMouseButton = 1; |
| var RightMouseButton = 2; |
| |
| window.onload = function() |
| { |
| firstMouseButtonElem = document.getElementById("firstMouseButton"); |
| secondMouseButtonElem = document.getElementById("secondMouseButton"); |
| firstMouseButtonElem.onchange = function() { |
| disableIllogicalSecondMouseButtonOptions(); |
| resetTest(); |
| } |
| secondMouseButtonElem.onchange = resetTest; |
| |
| square = document.getElementById("square"); |
| square.onmousedown = checkIfDoneOnMouseDown; |
| square.onmouseup = checkIfDoneOnMouseUp; |
| square.oncontextmenu = cancelContextMenu; |
| resetTest(); |
| runTest(); |
| } |
| |
| function toBitmaskMouseButton(w3cButton) |
| { |
| switch (w3cButton) { |
| case LeftMouseButton: |
| return 1 << 0; |
| case MiddleMouseButton: |
| return 1 << 1; |
| case RightMouseButton: |
| return 1 << 2; |
| } |
| return; // We shouldn't get here. |
| } |
| |
| function shortMouseButtonName(w3cButton) |
| { |
| switch (w3cButton) { |
| case LeftMouseButton: |
| return "left"; |
| case MiddleMouseButton: |
| return "middle"; |
| case RightMouseButton: |
| return "right"; |
| } |
| return; // We shouldn't get here. |
| } |
| |
| function mouseButtonName(w3cButton) |
| { |
| return shortMouseButtonName(w3cButton) + " mouse button"; |
| } |
| |
| function cancelContextMenu(event) |
| { |
| event = event || window.event; |
| if (event.preventDefault) |
| event.preventDefault(); |
| else { |
| // Assume this script is executing within Internet Explorer. |
| event.returnValue = false; |
| } |
| } |
| |
| function checkIfDoneOnMouseDown(event) |
| { |
| var pressedButtons = event.buttons; // A bitmask that represents the combination of buttons that are currently being pressed. |
| var chosenFirstMouseButton = firstMouseButtonElem.selectedIndex; |
| var chosenSecondMouseButton = secondMouseButtonElem.selectedIndex; |
| if (!didFireMousedownForFirstMouseButton && (pressedButtons & toBitmaskMouseButton(chosenFirstMouseButton)) == toBitmaskMouseButton(chosenFirstMouseButton)) { |
| didFireMousedownForFirstMouseButton = true; |
| square.innerHTML = "Now, " + shortMouseButtonName(chosenSecondMouseButton) + " click"; |
| } else if (didFireMousedownForFirstMouseButton && (pressedButtons & toBitmaskMouseButton(chosenSecondMouseButton)) == toBitmaskMouseButton(chosenSecondMouseButton)) |
| didFireMousedownForSecondMouseButton = true; |
| if (didFireMousedownForFirstMouseButton && didFireMousedownForSecondMouseButton) { |
| testPassed("received mousedown for the " + mouseButtonName(chosenSecondMouseButton) + " while pressing the " + mouseButtonName(chosenFirstMouseButton) + "."); |
| resetTest(); |
| } |
| } |
| |
| function checkIfDoneOnMouseUp() |
| { |
| if (didFireMousedownForFirstMouseButton && !didFireMousedownForSecondMouseButton) { |
| // Without loss of generality, either the mousedown for the right button button wasn't |
| // dispatched or the user didn't press the right mouse button while pressing left mouse button. |
| var chosenFirstMouseButton = firstMouseButtonElem.selectedIndex; |
| var chosenSecondMouseButton = secondMouseButtonElem.selectedIndex; |
| testFailed("didn't receive mousedown for the " + mouseButtonName(chosenSecondMouseButton) + " while pressing the " + mouseButtonName(chosenFirstMouseButton) + "."); |
| resetTest(); |
| } |
| } |
| |
| function resetTest() |
| { |
| didFireMousedownForFirstMouseButton = false; |
| didFireMousedownForSecondMouseButton = false; |
| square.innerHTML = "Press and hold the " + mouseButtonName(firstMouseButtonElem.selectedIndex) + " on me"; |
| } |
| |
| function disableIllogicalSecondMouseButtonOptions() |
| { |
| secondMouseButtonElem.options[previouslyChosenFirstMouseButton].disabled = false; |
| if (firstMouseButtonElem.selectedIndex === secondMouseButtonElem.selectedIndex) |
| secondMouseButtonElem.options[(secondMouseButtonElem.selectedIndex + 1) % secondMouseButtonElem.length].selected = true; |
| secondMouseButtonElem.options[firstMouseButtonElem.selectedIndex].disabled = true; |
| previouslyChosenFirstMouseButton = firstMouseButtonElem.selectedIndex; |
| } |
| |
| function runTest() |
| { |
| if (!window.eventSender) |
| return; |
| |
| var numFirstMouseButtonOptions = firstMouseButtonElem.options.length; |
| var numSecondMouseButtonOptions = secondMouseButtonElem.options.length; |
| eventSender.mouseMoveTo(square.offsetLeft + 10, square.offsetTop + 10); |
| var firstMouseButton = 0; |
| var secondMouseButton = 0; |
| while (firstMouseButton < numFirstMouseButtonOptions) { |
| if (firstMouseButton === secondMouseButton) |
| ++secondMouseButton; |
| if (secondMouseButton >= numSecondMouseButtonOptions) { |
| ++firstMouseButton; |
| secondMouseButton = 0; |
| } |
| if (firstMouseButton >= numFirstMouseButtonOptions) |
| break; |
| |
| firstMouseButtonElem.options[firstMouseButton].selected = true; |
| secondMouseButtonElem.options[secondMouseButton].selected = true; |
| if (secondMouseButton % numSecondMouseButtonOptions === 0) |
| debug('<br />When pressing and holding the "' + mouseButtonName(firstMouseButton) + '"<br />'); |
| eventSender.mouseDown(firstMouseButton); |
| eventSender.leapForward(100); |
| eventSender.mouseDown(secondMouseButton); |
| eventSender.mouseUp(secondMouseButton); |
| eventSender.mouseUp(firstMouseButton); |
| eventSender.leapForward(100); |
| ++secondMouseButton; |
| resetTest(); // We reset the test here in case neither a mousedown nor mouseup event was fired. |
| } |
| document.body.removeChild(document.getElementById("test-container")); |
| debug('<br /><span class="pass">TEST COMPLETE</span>'); |
| } |
| </script> |
| </head> |
| <body> |
| <p id="description"></p> |
| <div id="test-container"> |
| <p>Note: Ensure mouse gestures are disabled when running this test in Opera. In Opera 11.10 you can disable gestures by selecting Opera > Preferences > Advanced > Shortcuts. Then uncheck Enable mouse gestures. Also, to test "pressing-and-holding the right mouse button then clicking the left mouse" (*) ensure that Enable Mouse Flips is disabled. To disable it open <a href="opera:config" target="_blank">opera:config</a> then search for "Enable Mouse Flips" and uncheck it. As of 04/15/2011, for some reason (*) neither <span class="pass">PASS</span>es nor <span class="fail">FAIL</span>s.</p> |
| <!-- The <option>s in these <select>s are explicitly ordered to match the DOM Level 3 Events mouse button values for Left, Middle, and Right mouse buttons. --> |
| <label for="firstMouseButton">Will press and hold</label> <select id="firstMouseButton"> |
| <option>Left mouse button</option> |
| <option>Middle mouse button</option> |
| <option>Right mouse button</option> |
| </select> |
| <span>on blue square then</span> |
| <label for="secondMouseButton">click</label> <select id="secondMouseButton"> |
| <option disabled>Left mouse button</option> |
| <option selected>Middle mouse button</option> |
| <option>Right mouse button</option> |
| </select> |
| <br/><br/> |
| <div id="square"></div> |
| </div> |
| <hr/> |
| <div id="console"></div> |
| <script> |
| description("This test verifies that we fire a mousedown event whenever pressing and holding a mouse button A while simultaneously " + |
| "clicking with mouse button B, where A != B.<br/>" + |
| "For each mouse button that is pressed and held, iterates through the possible second mouse buttons that can be clicked."); |
| </script> |
| </body> |
| </html> |