diff options
Diffstat (limited to 'dom/events/test/pointerevents/mochitest_support_external.js')
-rw-r--r-- | dom/events/test/pointerevents/mochitest_support_external.js | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/dom/events/test/pointerevents/mochitest_support_external.js b/dom/events/test/pointerevents/mochitest_support_external.js new file mode 100644 index 0000000000..86c3557e8e --- /dev/null +++ b/dom/events/test/pointerevents/mochitest_support_external.js @@ -0,0 +1,270 @@ +// This file supports translating W3C tests +// to tests on auto MochiTest system with minimum changes. +// Author: Maksim Lebedev <alessarik@gmail.com> + +// Function allows to prepare our tests after load document +addEventListener( + "load", + function(event) { + console.log("OnLoad external document"); + prepareTest(); + }, + false +); + +// Function allows to initialize prerequisites before testing +function prepareTest() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestCompleteLog(); + startTest(); +} + +function setImplicitPointerCapture(capture, callback) { + console.log("SET dom.w3c_pointer_events.implicit_capture as " + capture); + SpecialPowers.pushPrefEnv( + { + set: [["dom.w3c_pointer_events.implicit_capture", capture]], + }, + callback + ); +} + +var utils = SpecialPowers.Ci.nsIDOMWindowUtils; + +// Mouse Event Helper Object +var MouseEventHelper = (function() { + return { + MOUSE_ID: utils.DEFAULT_MOUSE_POINTER_ID, + PEN_ID: utils.DEFAULT_PEN_POINTER_ID, + // State + // TODO: Separate this to support mouse and pen simultaneously. + BUTTONS_STATE: utils.MOUSE_BUTTONS_NO_BUTTON, + + // Button + BUTTON_NONE: -1, // Used by test framework only. (replaced before sending) + BUTTON_LEFT: utils.MOUSE_BUTTON_LEFT_BUTTON, + BUTTON_MIDDLE: utils.MOUSE_BUTTON_MIDDLE_BUTTON, + BUTTON_RIGHT: utils.MOUSE_BUTTON_RIGHT_BUTTON, + + // Buttons + BUTTONS_NONE: utils.MOUSE_BUTTONS_NO_BUTTON, + BUTTONS_LEFT: utils.MOUSE_BUTTONS_LEFT_BUTTON, + BUTTONS_MIDDLE: utils.MOUSE_BUTTONS_MIDDLE_BUTTON, + BUTTONS_RIGHT: utils.MOUSE_BUTTONS_RIGHT_BUTTON, + BUTTONS_4TH: utils.MOUSE_BUTTONS_4TH_BUTTON, + BUTTONS_5TH: utils.MOUSE_BUTTONS_5TH_BUTTON, + + // Utils + computeButtonsMaskFromButton(aButton) { + // Since the range of button values is 0 ~ 2 (see nsIDOMWindowUtils.idl), + // we can use an array to find out the desired mask. + var mask = [ + this.BUTTONS_NONE, // -1 (MouseEventHelper.BUTTON_NONE) + this.BUTTONS_LEFT, // 0 + this.BUTTONS_MIDDLE, // 1 + this.BUTTONS_RIGHT, // 2 + ][aButton + 1]; + + ok(mask !== undefined, "Unrecognized button value caught!"); + return mask; + }, + + checkExitState() { + ok(!this.BUTTONS_STATE, "Mismatched mousedown/mouseup caught."); + }, + }; +})(); + +function createMouseEvent(aEventType, aParams) { + var eventObj = { type: aEventType }; + + // Default to mouse. + eventObj.inputSource = + aParams && "inputSource" in aParams + ? aParams.inputSource + : MouseEvent.MOZ_SOURCE_MOUSE; + // Compute pointerId + eventObj.id = + eventObj.inputSource === MouseEvent.MOZ_SOURCE_MOUSE + ? MouseEventHelper.MOUSE_ID + : MouseEventHelper.PEN_ID; + // Check or generate a |button| value. + var isButtonEvent = aEventType === "mouseup" || aEventType === "mousedown"; + + // Set |button| to the default value first. + eventObj.button = isButtonEvent + ? MouseEventHelper.BUTTON_LEFT + : MouseEventHelper.BUTTON_NONE; + + // |button| is passed, use and check it. + if (aParams && "button" in aParams) { + var hasButtonValue = aParams.button !== MouseEventHelper.BUTTON_NONE; + ok( + !isButtonEvent || hasButtonValue, + "Inappropriate |button| value caught." + ); + eventObj.button = aParams.button; + } + + // Generate a |buttons| value and update buttons state + var buttonsMask = MouseEventHelper.computeButtonsMaskFromButton( + eventObj.button + ); + switch (aEventType) { + case "mousedown": + MouseEventHelper.BUTTONS_STATE |= buttonsMask; // Set button flag. + break; + case "mouseup": + MouseEventHelper.BUTTONS_STATE &= ~buttonsMask; // Clear button flag. + break; + } + eventObj.buttons = MouseEventHelper.BUTTONS_STATE; + + // Replace the button value for mousemove events. + // Since in widget level design, even when no button is pressed at all, the + // value of WidgetMouseEvent.button is still 0, which is the same value as + // the one for mouse left button. + if (aEventType === "mousemove") { + eventObj.button = MouseEventHelper.BUTTON_LEFT; + } + return eventObj; +} + +// Helper function to send MouseEvent with different parameters +function sendMouseEvent(int_win, elemId, mouseEventType, params) { + var elem = int_win.document.getElementById(elemId); + if (elem) { + var rect = elem.getBoundingClientRect(); + var eventObj = createMouseEvent(mouseEventType, params); + + // Default to the center of the target element but we can still send to a + // position outside of the target element. + var offsetX = + params && "offsetX" in params ? params.offsetX : rect.width / 2; + var offsetY = + params && "offsetY" in params ? params.offsetY : rect.height / 2; + + console.log(elemId, eventObj); + synthesizeMouse(elem, offsetX, offsetY, eventObj, int_win); + } else { + is(!!elem, true, "Document should have element with id: " + elemId); + } +} + +// Helper function to send MouseEvent with position +function sendMouseEventAtPoint(aWindow, aLeft, aTop, aMouseEventType, aParams) { + var eventObj = createMouseEvent(aMouseEventType, aParams); + console.log(eventObj); + synthesizeMouseAtPoint(aLeft, aTop, eventObj, aWindow); +} + +// Touch Event Helper Object +var TouchEventHelper = { + // State + TOUCH_ID: utils.DEFAULT_TOUCH_POINTER_ID, + TOUCH_STATE: false, + + // Utils + checkExitState() { + ok(!this.TOUCH_STATE, "Mismatched touchstart/touchend caught."); + }, +}; + +// Helper function to send TouchEvent with different parameters +// TODO: Support multiple touch points to test more features such as +// PointerEvent.isPrimary and pinch-zoom. +function sendTouchEvent(int_win, elemId, touchEventType, params) { + var elem = int_win.document.getElementById(elemId); + if (elem) { + var rect = elem.getBoundingClientRect(); + var eventObj = { + type: touchEventType, + id: TouchEventHelper.TOUCH_ID, + }; + + // Update touch state + switch (touchEventType) { + case "touchstart": + TouchEventHelper.TOUCH_STATE = true; // Set touch flag. + break; + case "touchend": + case "touchcancel": + TouchEventHelper.TOUCH_STATE = false; // Clear touch flag. + break; + } + + // Default to the center of the target element but we can still send to a + // position outside of the target element. + var offsetX = + params && "offsetX" in params ? params.offsetX : rect.width / 2; + var offsetY = + params && "offsetY" in params ? params.offsetY : rect.height / 2; + + console.log(elemId, eventObj); + synthesizeTouch(elem, offsetX, offsetY, eventObj, int_win); + } else { + is(!!elem, true, "Document should have element with id: " + elemId); + } +} + +// Helper function to trigger drag and drop. +async function doDragAndDrop(int_win, srcElemId, destElemId, params = {}) { + params.srcElement = int_win.document.getElementById(srcElemId); + params.destElement = int_win.document.getElementById(destElemId); + params.srcWindow = int_win; + params.destWindow = int_win; + params.id = MouseEventHelper.MOUSE_ID; + // This is basically for android which has a larger drag threshold. + params.stepY = params.stepY || 25; + await synthesizePlainDragAndDrop(params); +} + +// Helper function to run Point Event test in a new tab. +function runTestInNewWindow(aFile) { + var testURL = + location.href.substring(0, location.href.lastIndexOf("/") + 1) + aFile; + var testWindow = window.open(testURL, "_blank"); + var testDone = false; + + // We start testing when receiving load event. Inject the mochitest helper js + // to the test case after DOM elements are constructed and before the load + // event is fired. + testWindow.addEventListener( + "DOMContentLoaded", + function() { + var e = testWindow.document.createElement("script"); + e.type = "text/javascript"; + e.src = + "../".repeat(aFile.split("/").length - 1) + + "mochitest_support_internal.js"; + testWindow.document.getElementsByTagName("head")[0].appendChild(e); + }, + { once: true } + ); + + window.addEventListener("message", function(aEvent) { + switch (aEvent.data.type) { + case "START": + // Update constants + MouseEventHelper.MOUSE_ID = aEvent.data.message.mouseId; + MouseEventHelper.PEN_ID = aEvent.data.message.penId; + TouchEventHelper.TOUCH_ID = aEvent.data.message.touchId; + + executeTest(testWindow); + return; + case "RESULT": + // Should not perform checking after SimpleTest.finish(). + if (!testDone) { + ok(aEvent.data.result, aEvent.data.message); + } + return; + case "FIN": + testDone = true; + MouseEventHelper.checkExitState(); + TouchEventHelper.checkExitState(); + testWindow.close(); + SimpleTest.finish(); + return; + } + }); +} |