diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-04-20 22:18:52 +0200 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-04-20 22:18:52 +0200 |
commit | 09f456b2808224e7707e51bfab8957ef067154e4 (patch) | |
tree | 95d53f259f5807e2cbee9d455a7629eb4db53c77 /dom | |
parent | 9b1ba6833410c0b17e885b4bc2b7bff6cf86d5cd (diff) | |
download | UXP-09f456b2808224e7707e51bfab8957ef067154e4.tar UXP-09f456b2808224e7707e51bfab8957ef067154e4.tar.gz UXP-09f456b2808224e7707e51bfab8957ef067154e4.tar.lz UXP-09f456b2808224e7707e51bfab8957ef067154e4.tar.xz UXP-09f456b2808224e7707e51bfab8957ef067154e4.zip |
moebius#71: DOM - Pointer Events - improvements
https://github.com/MoonchildProductions/moebius/pull/71
Diffstat (limited to 'dom')
11 files changed, 186 insertions, 57 deletions
diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index f66cf3f90..c6b304183 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -731,6 +731,9 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, FlushPendingEvents(aPresContext); break; } + case ePointerGotCapture: + GenerateMouseEnterExit(mouseEvent); + break; case eDragStart: if (Prefs::ClickHoldContextMenu()) { // an external drag gesture event came in, not generated internally @@ -3890,10 +3893,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent, newPointerEvent->mWidth = sourcePointer->mWidth; newPointerEvent->mHeight = sourcePointer->mHeight; newPointerEvent->inputSource = sourcePointer->inputSource; - newPointerEvent->relatedTarget = - nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId) - ? nullptr - : aRelatedContent; + newPointerEvent->relatedTarget = aRelatedContent; aNewEvent = newPointerEvent.forget(); } else { aNewEvent = @@ -4106,14 +4106,8 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent, SetContentState(nullptr, NS_EVENT_STATE_HOVER); } - // In case we go out from capturing element (retargetedByPointerCapture is true) - // we should dispatch ePointerLeave event and only for capturing element. - RefPtr<nsIContent> movingInto = aMouseEvent->retargetedByPointerCapture - ? wrapper->mLastOverElement->GetParent() - : aMovingInto; - EnterLeaveDispatcher leaveDispatcher(this, wrapper->mLastOverElement, - movingInto, aMouseEvent, + aMovingInto, aMouseEvent, isPointer ? ePointerLeave : eMouseLeave); // Fire mouseout @@ -4134,13 +4128,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, { NS_ASSERTION(aContent, "Mouse must be over something"); - // If pointer capture is set, we should suppress pointerover/pointerenter events - // for all elements except element which have pointer capture. - bool dispatch = !aMouseEvent->retargetedByPointerCapture; - OverOutElementsWrapper* wrapper = GetWrapperByEventID(aMouseEvent); - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Before firing mouseover, check for recursion @@ -4163,7 +4153,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, } // Firing the DOM event in the parent document could cause all kinds // of havoc. Reverify and take care. - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Remember mLastOverElement as the related content for the @@ -4172,11 +4162,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, bool isPointer = aMouseEvent->mClass == ePointerEventClass; - Maybe<EnterLeaveDispatcher> enterDispatcher; - if (dispatch) { - enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent, - isPointer ? ePointerEnter : eMouseEnter); - } + EnterLeaveDispatcher enterDispatcher(this, aContent, lastOverElement, + aMouseEvent, + isPointer ? ePointerEnter : eMouseEnter); NotifyMouseOut(aMouseEvent, aContent); @@ -4188,18 +4176,13 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, SetContentState(aContent, NS_EVENT_STATE_HOVER); } - if (dispatch) { - // Fire mouseover - wrapper->mLastOverFrame = - DispatchMouseOrPointerEvent(aMouseEvent, - isPointer ? ePointerOver : eMouseOver, - aContent, lastOverElement); - enterDispatcher->Dispatch(); - wrapper->mLastOverElement = aContent; - } else { - wrapper->mLastOverFrame = nullptr; - wrapper->mLastOverElement = nullptr; - } + // Fire mouseover + wrapper->mLastOverFrame = + DispatchMouseOrPointerEvent(aMouseEvent, + isPointer ? ePointerOver : eMouseOver, + aContent, lastOverElement); + enterDispatcher.Dispatch(); + wrapper->mLastOverElement = aContent; // Turn recursion protection back off wrapper->mFirstOverEventElement = nullptr; @@ -4292,6 +4275,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) MOZ_FALLTHROUGH; case ePointerMove: case ePointerDown: + case ePointerGotCapture: { // Get the target content target (mousemove target == mouseover target) nsCOMPtr<nsIContent> targetElement = GetEventTargetContent(aMouseEvent); diff --git a/dom/events/PointerEvent.cpp b/dom/events/PointerEvent.cpp index f53739863..fbaa0f737 100644 --- a/dom/events/PointerEvent.cpp +++ b/dom/events/PointerEvent.cpp @@ -93,8 +93,10 @@ PointerEvent::Constructor(EventTarget* aOwner, widgetEvent->mWidth = aParam.mWidth; widgetEvent->mHeight = aParam.mHeight; widgetEvent->pressure = aParam.mPressure; + widgetEvent->tangentialPressure = aParam.mTangentialPressure; widgetEvent->tiltX = aParam.mTiltX; widgetEvent->tiltY = aParam.mTiltY; + widgetEvent->twist = aParam.mTwist; widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType); widgetEvent->mIsPrimary = aParam.mIsPrimary; widgetEvent->buttons = aParam.mButtons; @@ -145,6 +147,12 @@ PointerEvent::Pressure() return mEvent->AsPointerEvent()->pressure; } +float +PointerEvent::TangentialPressure() +{ + return mEvent->AsPointerEvent()->tangentialPressure; +} + int32_t PointerEvent::TiltX() { @@ -157,6 +165,12 @@ PointerEvent::TiltY() return mEvent->AsPointerEvent()->tiltY; } +int32_t +PointerEvent::Twist() +{ + return mEvent->AsPointerEvent()->twist; +} + bool PointerEvent::IsPrimary() { diff --git a/dom/events/PointerEvent.h b/dom/events/PointerEvent.h index 62c5a0c36..12d4941dc 100644 --- a/dom/events/PointerEvent.h +++ b/dom/events/PointerEvent.h @@ -44,8 +44,10 @@ public: int32_t Width(); int32_t Height(); float Pressure(); + float TangentialPressure(); int32_t TiltX(); int32_t TiltY(); + int32_t Twist(); bool IsPrimary(); void GetPointerType(nsAString& aPointerType); }; diff --git a/dom/events/test/pointerevents/mochitest.ini b/dom/events/test/pointerevents/mochitest.ini index 58eae12fe..5de7f27ea 100644 --- a/dom/events/test/pointerevents/mochitest.ini +++ b/dom/events/test/pointerevents/mochitest.ini @@ -148,5 +148,6 @@ support-files = support-files = bug1293174_implicit_pointer_capture_for_touch_1.html [test_bug1293174_implicit_pointer_capture_for_touch_2.html] support-files = bug1293174_implicit_pointer_capture_for_touch_2.html +[test_bug1323158.html] [test_empty_file.html] disabled = disabled # Bug 1150091 - Issue with support-files diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html index 31fe919af..2614790f3 100644 --- a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -12,20 +12,24 @@ <script type="text/javascript" src="pointerevent_support.js"></script> <script type="text/javascript" src="mochitest_support_internal.js"></script> <script type="text/javascript"> + var test_pointerEvent; var detected_pointertypes = {}; - var test_pointerEvent = async_test("lostpointercapture: subsequent events to target."); // set up test harness - // showPointerTypes is defined in pointerevent_support.js - // Requirements: the callback function will reference the test_pointerEvent object and - // will fail unless the async_test is created with the var name "test_pointerEvent". - add_completion_callback(showPointerTypes); - - var captured_event; + var captured_event = null; var test_done = false; var overEnterEventsFail = false; var outLeaveEventsFail = false; var f_gotPointerCapture = false; var f_lostPointerCapture = false; + function resetTestState() { + captured_event = null; + test_done = false; + overEnterEventsFail = false; + outLeaveEventsFail = false; + f_gotPointerCapture = false; + f_lostPointerCapture = false; + } + function listenerEventHandler(event) { if (test_done) return; @@ -40,10 +44,10 @@ check_PointerEvent(event); } else if(event.type == "pointerover" || event.type == "pointerenter") { - if(!overEnterEventsFail) { + if(captured_event && !overEnterEventsFail) { test(function() { - assert_true(f_gotPointerCapture, "pointerover/enter should not be received when the target doesn't have capture and pointer is not over it."); - }, "pointerover/enter should not be received when the target doesn't have capture and pointer is not over it."); + assert_false(f_gotPointerCapture, "pointerover/enter should be received before the target receives gotpointercapture even when the pointer is not over it."); + }, expectedPointerType + " pointerover/enter should be received before the target receives gotpointercapture even when the pointer is not over it."); overEnterEventsFail = true; } } @@ -51,7 +55,7 @@ if(!outLeaveEventsFail) { test(function() { assert_true(f_lostPointerCapture, "pointerout/leave should not be received unless the target just lost the capture."); - }, "pointerout/leave should not be received unless the target just lost the capture."); + }, expectedPointerType + " pointerout/leave should not be received unless the target just lost the capture."); outLeaveEventsFail = true; } } @@ -64,7 +68,7 @@ // if any other events are received after releaseCapture, then the test fails test(function () { assert_unreached(event.target.id + "-" + event.type + " should be handled by target element handler"); - }, "No other events should be recieved by capturing node after release"); + }, expectedPointerType + " No other events should be recieved by capturing node after release"); } } } @@ -76,7 +80,7 @@ if(event.type != "pointerout" && event.type != "pointerleave") { test(function () { assert_unreached("The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". "); - }, "The target element should not receive any events while capture is active"); + }, expectedPointerType + " The target element should not receive any events while capture is active"); } } @@ -91,13 +95,14 @@ assert_equals(event.pointerId, captured_event.pointerId, "pointerID is same for event captured and after release"); }); if (event.type == "pointerup") { - test_pointerEvent.done(); // complete test test_done = true; + test_pointerEvent.done(); // complete test } } } function run() { + test_pointerEvent = setup_pointerevent_test("got/lost pointercapture: subsequent events to target", ALL_POINTERS); // set up test harness var listener = document.getElementById("listener"); var target0 = document.getElementById("target0"); target0.style["touchAction"] = "none"; @@ -111,18 +116,19 @@ </script> </head> <body onload="run()"> + <h2 id="pointerTypeDescription"></h2> <div id="listener"></div> <h1>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</h1> <!-- <h4> Test Description: + Use your pointer and press down in the black box. Then move around in the box and release your pointer. After invoking the releasePointerCapture method on an element, subsequent events for the specified - pointer must follow normal hit testing mechanisms for determining the event target + pointer must follow normal hit testing mechanisms for determining the event target. </h4> <br /> --> <div id="target0"> - Use mouse, touch or pen to contact here and move around. </div> <div id="complete-notice"> <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p> diff --git a/dom/events/test/pointerevents/test_bug1285128.html b/dom/events/test/pointerevents/test_bug1285128.html index f7f1eb698..9577940c1 100644 --- a/dom/events/test/pointerevents/test_bug1285128.html +++ b/dom/events/test/pointerevents/test_bug1285128.html @@ -13,7 +13,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285128 <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1285128">Mozilla Bug 1285128</a> <p id="display"></p> -<div id="target0" style="width: 200px; height: 200px; background: green"></div> +<div id="target0" style="width: 50px; height: 50px; background: green"></div> +<div id="target1" style="width: 50px; height: 50px; background: red"></div> <script type="text/javascript"> /** Test for Bug 1285128 **/ @@ -31,7 +32,7 @@ function runTests() { }, false); }); - target0.addEventListener("mouseenter", () => { + target1.addEventListener("mouseup", () => { ok(!receivedPointerEvents, "synthesized mousemove should not trigger any pointer events"); SimpleTest.finish(); }); @@ -39,6 +40,8 @@ function runTests() { synthesizeMouseAtCenter(target0, { type: "mousemove", inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE, isWidgetEventSynthesized: true }); + synthesizeMouseAtCenter(target1, { type: "mousedown" }); + synthesizeMouseAtCenter(target1, { type: "mouseup" }); } SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, runTests); diff --git a/dom/events/test/pointerevents/test_bug1323158.html b/dom/events/test/pointerevents/test_bug1323158.html new file mode 100644 index 000000000..fac96c97a --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1323158.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1323158
+-->
+<head>
+ <meta charset="utf-8">
+ <title>This is a test to check if target and relatedTarget of mouse events are the same as pointer events</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="content"></p>
+<script type="text/javascript">
+
+/** Test for Bug 1323158 **/
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+ let content = document.getElementById('content');
+ let iframe = document.createElement('iframe');
+ iframe.width = 500;
+ iframe.height = 500;
+ content.appendChild(iframe);
+ iframe.contentDocument.body.innerHTML =
+ "<br><div id='target0' style='width: 30px; height: 30px; background: black;'></div>" +
+ "<br><div id='target1' style='width: 30px; height: 30px; background: red;'></div>" +
+ "<br><div id='done' style='width: 30px; height: 30px; background: green;'></div>";
+
+ let target0 = iframe.contentDocument.getElementById("target0");
+ let target1 = iframe.contentDocument.getElementById("target1");
+ let done = iframe.contentDocument.getElementById("done");
+ let pointerBoundaryEvents = ["pointerover", "pointerenter", "pointerleave", "pointerout"];
+ let mouseBoundaryEvents = ["mouseover", "mouseenter", "mouseleave", "mouseout"];
+ let receivedPointerBoundaryEvents = {};
+ let mouseEvent2pointerEvent = {"mouseover": "pointerover",
+ "mouseenter": "pointerenter",
+ "mouseleave": "pointerleave",
+ "mouseout": "pointerout"
+ };
+
+ pointerBoundaryEvents.forEach((event) => {
+ target1.addEventListener(event, (e) => {
+ receivedPointerBoundaryEvents[event] = e;
+ });
+ });
+
+ let attributes = ["target", "relatedTarget"];
+ mouseBoundaryEvents.forEach((event) => {
+ target1.addEventListener(event, (e) => {
+ let correspondingPointerEv = receivedPointerBoundaryEvents[mouseEvent2pointerEvent[event]];
+ ok(correspondingPointerEv, "Should receive " + mouseEvent2pointerEvent[event] + " before " + e.type);
+ if (correspondingPointerEv) {
+ attributes.forEach((attr) => {
+ ok(correspondingPointerEv[attr] == e[attr],
+ attr + " of " + e.type + " should be the same as the correcponding pointer event expect " +
+ correspondingPointerEv[attr] + " got " + e[attr]);
+ });
+ }
+ receivedPointerBoundaryEvents[mouseEvent2pointerEvent[event]] = null;
+ });
+ });
+ target0.addEventListener("pointerdown", (e) => {
+ target1.setPointerCapture(e.pointerId);
+ });
+ done.addEventListener("mouseup", () => {
+ SimpleTest.finish();
+ });
+ let source = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE;
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousedown", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mouseup", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(done, 5, 5, { type: "mousedown", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(done, 5, 5, { type: "mouseup", inputSource: source },
+ iframe.contentWindow);
+}
+
+SimpleTest.waitForFocus(() => {
+ SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, runTests);
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html index 5eb631f6a..2b08e2bb8 100644 --- a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html @@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target0", "mousemove"); sendMouseEvent(int_win, "target1", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mousemove"); sendMouseEvent(int_win, "btnCapture", "mousedown"); sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "target0", "mousemove"); diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html index cbf91df74..35350e016 100644 --- a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -17,9 +17,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 runTestInNewWindow("pointerevent_releasepointercapture_events_to_original_target-manual.html"); } function executeTest(int_win) { - sendTouchEvent(int_win, "target0", "touchstart"); - sendTouchEvent(int_win, "target0", "touchmove"); - sendTouchEvent(int_win, "target0", "touchend"); + // Synthesize mouse events to run this test. + sendMouseEvent(int_win, "target0", "mousemove"); + sendMouseEvent(int_win, "target0", "mousedown"); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup"); + + window.addEventListener("message", function(aEvent) { + if (aEvent.data == "Test Touch") { + // Synthesize touch events to run this test. + sendTouchEvent(int_win, "target0", "touchstart"); + sendTouchEvent(int_win, "target0", "touchmove"); + sendTouchEvent(int_win, "target0", "touchend"); + window.postMessage("Test Pen", "*"); + } else if (aEvent.data == "Test Pen") { + // Synthesize pen events to run this test. + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + } + }); + window.postMessage("Test Touch", "*"); } </script> </head> diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html index 0883d616b..09e97ec97 100644 --- a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html @@ -19,8 +19,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "btnCapture", "mousedown"); - sendMouseEvent(int_win, "target1", "mousemove"); - sendMouseEvent(int_win, "target1", "mouseup"); + sendMouseEvent(int_win, "btnCapture", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mouseup"); } </script> </head> diff --git a/dom/webidl/PointerEvent.webidl b/dom/webidl/PointerEvent.webidl index 2e83922c8..4e8a0eb90 100644 --- a/dom/webidl/PointerEvent.webidl +++ b/dom/webidl/PointerEvent.webidl @@ -17,8 +17,10 @@ interface PointerEvent : MouseEvent readonly attribute long width; readonly attribute long height; readonly attribute float pressure; + readonly attribute float tangentialPressure; readonly attribute long tiltX; readonly attribute long tiltY; + readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }; @@ -29,8 +31,10 @@ dictionary PointerEventInit : MouseEventInit long width = 1; long height = 1; float pressure = 0; + float tangentialPressure = 0; long tiltX = 0; long tiltY = 0; + long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; }; |