summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dom/events/EventStateManager.cpp54
-rw-r--r--dom/events/PointerEvent.cpp14
-rw-r--r--dom/events/PointerEvent.h2
-rw-r--r--dom/events/test/pointerevents/mochitest.ini1
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html65
-rw-r--r--dom/events/test/pointerevents/test_bug1285128.html7
-rw-r--r--dom/events/test/pointerevents/test_bug1323158.html93
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html3
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html4
-rw-r--r--dom/webidl/PointerEvent.webidl4
-rw-r--r--layout/base/nsIPresShell.h14
-rw-r--r--layout/base/nsPresShell.cpp142
-rw-r--r--layout/base/tests/bug1078327_inner.html8
-rw-r--r--layout/base/tests/bug1162990_inner_1.html4
-rw-r--r--layout/base/tests/bug1162990_inner_2.html2
-rw-r--r--layout/base/tests/bug976963_inner.html241
-rw-r--r--layout/base/tests/bug977003_inner_5.html8
-rw-r--r--layout/base/tests/bug977003_inner_6.html6
-rw-r--r--layout/base/tests/mochitest.ini2
-rw-r--r--layout/base/tests/test_bug976963.html35
-rw-r--r--widget/MouseEvents.h21
-rw-r--r--widget/nsGUIEventIPC.h39
23 files changed, 352 insertions, 444 deletions
diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp
index c23cdb575..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 =
@@ -4034,7 +4034,7 @@ public:
}
}
- ~EnterLeaveDispatcher()
+ void Dispatch()
{
if (mEventMessage == eMouseEnter || mEventMessage == ePointerEnter) {
for (int32_t i = mTargets.Count() - 1; i >= 0; --i) {
@@ -4106,19 +4106,14 @@ 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
DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? ePointerOut : eMouseOut,
wrapper->mLastOverElement, aMovingInto);
+ leaveDispatcher.Dispatch();
wrapper->mLastOverFrame = nullptr;
wrapper->mLastOverElement = nullptr;
@@ -4133,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
@@ -4162,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
@@ -4171,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);
@@ -4187,17 +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);
- 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;
@@ -4290,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 f4d5573ed..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
@@ -1,4 +1,4 @@
-<!doctype html>
+<!doctype html>
<html>
<head>
<title>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</title>
@@ -12,19 +12,27 @@
<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
- var suppressedEventsFail = false;
- // 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;
detected_pointertypes[event.pointerType] = true;
if (event.type == "gotpointercapture") {
f_gotPointerCapture = true;
@@ -35,12 +43,20 @@
f_gotPointerCapture = false;
check_PointerEvent(event);
}
- else if(event.type == "pointerover" || event.type == "pointerenter" || event.type == "pointerout" || event.type == "pointerleave") {
- if(!suppressedEventsFail) {
+ else if(event.type == "pointerover" || event.type == "pointerenter") {
+ if(captured_event && !overEnterEventsFail) {
+ test(function() {
+ 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;
+ }
+ }
+ else if(event.type == "pointerout" || event.type == "pointerleave") {
+ if(!outLeaveEventsFail) {
test(function() {
- assert_true(false, "Suppressed events were received");
- }, "Suppressed events were received");
- suppressedEventsFail = true;
+ assert_true(f_lostPointerCapture, "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;
}
}
else if (event.pointerId == captured_event.pointerId) {
@@ -50,19 +66,21 @@
}
else {
// if any other events are received after releaseCapture, then the test fails
- test_pointerEvent.step(function () {
- assert_true(false, event.target.id + "-" + event.type + " should be handled by target element handler");
- });
+ test(function () {
+ assert_unreached(event.target.id + "-" + event.type + " should be handled by target element handler");
+ }, expectedPointerType + " No other events should be recieved by capturing node after release");
}
}
}
function targetEventHandler(event) {
+ if (test_done)
+ return;
if (f_gotPointerCapture) {
if(event.type != "pointerout" && event.type != "pointerleave") {
- test_pointerEvent.step(function () {
- assert_true(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". ");
- });
+ test(function () {
+ assert_unreached("The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". ");
+ }, expectedPointerType + " The target element should not receive any events while capture is active");
}
}
@@ -77,12 +95,14 @@
assert_equals(event.pointerId, captured_event.pointerId, "pointerID is same for event captured and after release");
});
if (event.type == "pointerup") {
+ 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";
@@ -96,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 dc3903592..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,7 +19,8 @@ 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", "mousedown", {button:1});
+ sendMouseEvent(int_win, "btnCapture", "mousemove");
+ sendMouseEvent(int_win, "btnCapture", "mousedown");
sendMouseEvent(int_win, "target1", "mousemove");
sendMouseEvent(int_win, "target0", "mousemove");
sendMouseEvent(int_win, "target1", "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;
};
diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h
index cbbae0e8f..5990402ed 100644
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1298,11 +1298,11 @@ public:
}
};
- static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture,
- uint32_t aPointerId,
- uint16_t aPointerType,
- bool aIsPrimary,
- nsIContent* aCaptureTarget);
+ static void DispatchGotOrLostPointerCaptureEvent(
+ bool aIsGotCapture,
+ const mozilla::WidgetPointerEvent* aPointerEvent,
+ nsIContent* aCaptureTarget);
+
static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId);
static void SetPointerCapturingContent(uint32_t aPointerId,
nsIContent* aContent);
@@ -1311,8 +1311,8 @@ public:
// CheckPointerCaptureState checks cases, when got/lostpointercapture events
// should be fired.
- static void CheckPointerCaptureState(uint32_t aPointerId,
- uint16_t aPointerType, bool aIsPrimary);
+ static void CheckPointerCaptureState(
+ const mozilla::WidgetPointerEvent* aPointerEvent);
// GetPointerInfo returns true if pointer with aPointerId is situated in
// device, false otherwise.
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp
index 56ac370b9..63dfbd8a3 100644
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6514,10 +6514,11 @@ nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId)
}
/* static */ void
-nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId,
- uint16_t aPointerType, bool aIsPrimary)
+nsIPresShell::CheckPointerCaptureState(const WidgetPointerEvent* aPointerEvent)
{
- PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aPointerId);
+ PointerCaptureInfo* captureInfo =
+ GetPointerCaptureInfo(aPointerEvent->pointerId);
+
if (captureInfo &&
captureInfo->mPendingContent != captureInfo->mOverrideContent) {
// cache captureInfo->mPendingContent since it may be changed in the pointer
@@ -6525,17 +6526,16 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId,
nsIContent* pendingContent = captureInfo->mPendingContent.get();
if (captureInfo->mOverrideContent) {
DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ false,
- aPointerId, aPointerType, aIsPrimary,
+ aPointerEvent,
captureInfo->mOverrideContent);
}
if (pendingContent) {
- DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, aPointerId,
- aPointerType, aIsPrimary,
- pendingContent);
+ DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true,
+ aPointerEvent, pendingContent);
}
captureInfo->mOverrideContent = pendingContent;
if (captureInfo->Empty()) {
- sPointerCaptureList->Remove(aPointerId);
+ sPointerCaptureList->Remove(aPointerEvent->pointerId);
}
}
}
@@ -6976,37 +6976,30 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell,
return NS_OK;
}
-class ReleasePointerCaptureCaller
+class ReleasePointerCaptureCaller final
{
public:
- ReleasePointerCaptureCaller() :
- mPointerId(0),
- mPointerType(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN),
- mIsPrimary(false),
- mIsSet(false)
+ ReleasePointerCaptureCaller()
+ : mPointerEvent(nullptr)
{
}
~ReleasePointerCaptureCaller()
{
- if (mIsSet) {
- nsIPresShell::ReleasePointerCapturingContent(mPointerId);
- nsIPresShell::CheckPointerCaptureState(mPointerId, mPointerType,
- mIsPrimary);
+ if (mPointerEvent) {
+ nsIPresShell::ReleasePointerCapturingContent(mPointerEvent->pointerId);
+ nsIPresShell::CheckPointerCaptureState(mPointerEvent);
}
}
- void SetTarget(uint32_t aPointerId, uint16_t aPointerType, bool aIsPrimary)
+
+ void SetTarget(const WidgetPointerEvent* aPointerEvent)
{
- mPointerId = aPointerId;
- mPointerType = aPointerType;
- mIsPrimary = aIsPrimary;
- mIsSet = true;
+ MOZ_ASSERT(aPointerEvent);
+ mPointerEvent = aPointerEvent;
}
private:
- int32_t mPointerId;
- uint16_t mPointerType;
- bool mIsPrimary;
- bool mIsSet;
+ // This is synchronously used inside PresShell::HandleEvent.
+ const WidgetPointerEvent* mPointerEvent;
};
static bool
@@ -7719,9 +7712,7 @@ PresShell::HandleEvent(nsIFrame* aFrame,
nsWeakFrame frameKeeper(frame);
// Handle pending pointer capture before any pointer events except
// gotpointercapture / lostpointercapture.
- CheckPointerCaptureState(pointerEvent->pointerId,
- pointerEvent->inputSource,
- pointerEvent->mIsPrimary);
+ CheckPointerCaptureState(pointerEvent);
// Prevent application crashes, in case damaged frame.
if (!frameKeeper.IsAlive()) {
frame = nullptr;
@@ -7742,33 +7733,29 @@ PresShell::HandleEvent(nsIFrame* aFrame,
}
}
- if (aEvent->mClass == ePointerEventClass &&
- aEvent->mMessage != ePointerDown) {
- if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
- uint32_t pointerId = pointerEvent->pointerId;
+ // Mouse events should be fired to the same target as their mapped pointer
+ // events
+ if ((aEvent->mClass == ePointerEventClass ||
+ aEvent->mClass == eMouseEventClass) &&
+ aEvent->mMessage != ePointerDown && aEvent->mMessage != eMouseDown) {
+ if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
+ uint32_t pointerId = mouseEvent->pointerId;
nsIContent* pointerCapturingContent =
GetPointerCapturingContent(pointerId);
if (pointerCapturingContent) {
if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) {
- // If pointer capture is set, we should suppress
- // pointerover/pointerenter events for all elements except element
- // which have pointer capture. (Code in EventStateManager)
- pointerEvent->retargetedByPointerCapture =
- frame && frame->GetContent() &&
- !nsContentUtils::ContentIsDescendantOf(frame->GetContent(),
- pointerCapturingContent);
frame = capturingFrame;
}
- if (pointerEvent->mMessage == ePointerUp ||
- pointerEvent->mMessage == ePointerCancel) {
+ if (aEvent->mMessage == ePointerUp ||
+ aEvent->mMessage == ePointerCancel) {
// Implicitly releasing capture for given pointer.
// ePointerLostCapture should be send after ePointerUp or
// ePointerCancel.
- releasePointerCaptureCaller.SetTarget(pointerId,
- pointerEvent->inputSource,
- pointerEvent->mIsPrimary);
+ WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
+ MOZ_ASSERT(pointerEvent);
+ releasePointerCaptureCaller.SetTarget(pointerEvent);
}
}
}
@@ -8340,35 +8327,44 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent,
return rv;
}
-void
-nsIPresShell::DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture,
- uint32_t aPointerId,
- uint16_t aPointerType,
- bool aIsPrimary,
- nsIContent* aCaptureTarget)
-{
- PointerEventInit init;
- init.mPointerId = aPointerId;
- init.mBubbles = true;
- ConvertPointerTypeToString(aPointerType, init.mPointerType);
- init.mIsPrimary = aIsPrimary;
- RefPtr<mozilla::dom::PointerEvent> event;
- event = PointerEvent::Constructor(aCaptureTarget,
- aIsGotCapture
- ? NS_LITERAL_STRING("gotpointercapture")
- : NS_LITERAL_STRING("lostpointercapture"),
- init);
- if (event) {
+/* static */ void
+nsIPresShell::DispatchGotOrLostPointerCaptureEvent(
+ bool aIsGotCapture,
+ const WidgetPointerEvent* aPointerEvent,
+ nsIContent* aCaptureTarget)
+{
+ nsIDocument* targetDoc = aCaptureTarget->OwnerDoc();
+ nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell();
+ NS_ENSURE_TRUE_VOID(shell);
+
+ if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) {
+ // If the capturing element was removed from the DOM tree, fire
+ // ePointerLostCapture at the document.
+ PointerEventInit init;
+ init.mPointerId = aPointerEvent->pointerId;
+ init.mBubbles = true;
+ init.mComposed = true;
+ ConvertPointerTypeToString(aPointerEvent->inputSource, init.mPointerType);
+ init.mIsPrimary = aPointerEvent->mIsPrimary;
+ RefPtr<mozilla::dom::PointerEvent> event;
+ event = PointerEvent::Constructor(aCaptureTarget,
+ NS_LITERAL_STRING("lostpointercapture"),
+ init);
bool dummy;
- // If the capturing element was removed from the DOM tree,
- // lostpointercapture event should be fired at the document.
- if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) {
- aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(),
- &dummy);
- } else {
- aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy);
- }
+ targetDoc->DispatchEvent(event->InternalDOMEvent(), &dummy);
+ return;
}
+ nsEventStatus status = nsEventStatus_eIgnore;
+ WidgetPointerEvent localEvent(aPointerEvent->IsTrusted(),
+ aIsGotCapture ? ePointerGotCapture :
+ ePointerLostCapture,
+ aPointerEvent->mWidget);
+ localEvent.AssignPointerEventData(*aPointerEvent, true);
+ nsresult rv = shell->HandleEventWithTarget(
+ &localEvent,
+ aCaptureTarget->GetPrimaryFrame(),
+ aCaptureTarget, &status);
+ NS_ENSURE_SUCCESS_VOID(rv);
}
nsresult
diff --git a/layout/base/tests/bug1078327_inner.html b/layout/base/tests/bug1078327_inner.html
index 9e32fc996..0cfb9da7f 100644
--- a/layout/base/tests/bug1078327_inner.html
+++ b/layout/base/tests/bug1078327_inner.html
@@ -24,16 +24,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327
var test_mediator_move = false;
var test_mediator_out = false;
var test_listener = false;
+ var test_lost_capture = false;
function TargetHandler(event) {
logger("Target receive event: " + event.type + ". Mediator.setPointerCapture()");
mediator.setPointerCapture(event.pointerId);
test_target = true;
+ test_capture = true;
}
function MediatorHandler(event) {
logger("Mediator receive event: " + event.type);
- if(event.type == "gotpointercapture")
- test_capture = true;
if(!test_capture)
return;
if(event.type == "pointermove")
@@ -43,7 +43,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327
if(event.type == "pointerout")
test_mediator_out++;
if(event.type == "lostpointercapture")
- test_capture = false;
+ test_lost_capture = true;
}
function ListenerHandler(event) {
logger("Listener receive event: " + event.type);
@@ -86,7 +86,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327
}
function finishTest() {
parent.is(test_target, true, "pointerdown event should be received by target");
- parent.is(test_capture, false, "test_capture should be false at the end of the test");
+ parent.is(test_lost_capture, true, "mediator should receive lostpointercapture");
parent.is(test_mediator_over, 1, "mediator should receive pointerover event only once");
parent.is(test_mediator_move, 5, "mediator should receive pointermove event five times");
parent.is(test_mediator_out, 1, "mediator should receive pointerout event only once");
diff --git a/layout/base/tests/bug1162990_inner_1.html b/layout/base/tests/bug1162990_inner_1.html
index 4ea5edb5c..0f950df8d 100644
--- a/layout/base/tests/bug1162990_inner_1.html
+++ b/layout/base/tests/bug1162990_inner_1.html
@@ -111,10 +111,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990
}
function finishTest() {
- parent.is(test_basketLeave, 0, "Part1: basket should not receive pointerleave event after pointer capturing");
+ parent.is(test_basketLeave, 1, "Part1: basket should receive pointerleave event after pointer capturing");
parent.is(test_targetGotCapture, 1, "Part1: target should receive gotpointercapture event");
parent.is(test_targetLostCapture, 1, "Part1: target should receive lostpointercapture event");
- parent.is(test_targetLeave, 2, "Part1: target should receive pointerleave event two times");
+ parent.is(test_targetLeave, 1, "Part1: target should receive pointerleave event only one time");
parent.is(test_childLeave, 0, "Part1: child should not receive pointerleave event after pointer capturing");
parent.is(test_listenerDown, 1, "Part1: listener should receive pointerdown event");
parent.is(test_listenerLeave, 1, "Part1: listener should receive pointerleave event only one time");
diff --git a/layout/base/tests/bug1162990_inner_2.html b/layout/base/tests/bug1162990_inner_2.html
index 54aa74ca3..e418927bd 100644
--- a/layout/base/tests/bug1162990_inner_2.html
+++ b/layout/base/tests/bug1162990_inner_2.html
@@ -116,7 +116,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990
parent.is(test_targetDown, 1, "Part2: target should receive pointerdown event");
parent.is(test_targetGotCapture, 1, "Part2: target should receive gotpointercapture event");
parent.is(test_targetLostCapture, 1, "Part2: target should receive lostpointercapture event");
- parent.is(test_targetLeave, 1, "Part2: target should receive pointerleave event");
+ parent.is(test_targetLeave, 0, "Part2: target should not receive pointerleave event");
parent.is(test_childLeave, 0, "Part2: child should not receive pointerleave event after pointer capturing");
parent.is(test_listenerLeave, 0, "Part2: listener should not receive pointerleave event after pointer capturing");
logger("finishTest");
diff --git a/layout/base/tests/bug976963_inner.html b/layout/base/tests/bug976963_inner.html
deleted file mode 100644
index 2c55fbccd..000000000
--- a/layout/base/tests/bug976963_inner.html
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=976963
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 976963</title>
- <meta name="author" content="Maksim Lebedev" />
- <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <style>
- div#listener {
- background: yellow;
- position: absolute;
- top: -100px;
- }
- div#middler {
- background: yellow;
- margin: 10px;
- }
- div#target {
- background: yellow;
- }
- </style>
- <script type="application/javascript">
- /** Test for Bug 976963 **/
- var All_Pointer_Events = ["pointerover", "pointerenter",
- "pointermove",
- "pointerdown", "pointerup",
- "pointerout", "pointerleave",
- "pointercancel",
- "gotpointercapture", "lostpointercapture"];
-
- function on_event(object, event, callback) {
- object.addEventListener(event, callback, false);
- }
- function ok(check, msg) {
- parent.ok(check, msg);
- }
- function is(a, b, msg) {
- parent.is(a, b, msg);
- }
-
- var listener = undefined;
- var middler = undefined;
- var target = undefined;
-
- var test_ListenerGotCapture = 0;
- var test_ListenerUnwanted = 0;
- var test_ListenerLostCapture = 0;
- var test_ListenerAfterCapture = 0;
- var test_MiddlerGotCapture = 0;
- var test_MiddlerOver = 0;
- var test_MiddlerLeave = 0;
- var test_MiddlerUp = 0;
- var test_MiddlerLostCapture = 0;
- var test_TargetDown = 0;
- var test_TargetUnwanted = 0;
- var test_TargetUp = 0;
-
- var captured_event = undefined;
- var f_gotPointerCapture = false;
- var f_lostPointerCapture = false;
- var f_gotMiddlerPointerCapture = false;
-
- function listenerEventHandler(event) {
- logger("Listener: " + event.type + ". Captured_event: " + captured_event);
- if(test_ListenerLostCapture)
- test_ListenerAfterCapture++;
- if (event.type == "gotpointercapture") {
- f_gotPointerCapture = true;
- test_ListenerGotCapture++;
- }
- else if (event.type == "lostpointercapture") {
- f_lostPointerCapture = true;
- f_gotPointerCapture = false;
- test_ListenerLostCapture++;
- }
- else if (event.type == "pointermove") {
- ok(captured_event && captured_event.pointerId == event.pointerId, "Listener: equals pointerId for lostpointercapture event");
- if (f_gotPointerCapture) {
- // on first event received for capture, release capture
- logger("Listener call release");
- ok(!!listener, "Listener should be live!");
- ok(typeof(listener.releasePointerCapture) == "function", "Listener should have a function releasePointerCapture");
- listener.releasePointerCapture(event.pointerId);
- }
- else {
- logger("Listener.ASSERT: " + event.type);
- test_ListenerUnwanted++;
- // if any other events are received after releaseCapture, then the test fails
- ok(false, event.target.id + "-" + event.type + " should be handled by target element handler");
- }
- }
- else {
- test_ListenerUnwanted++;
- logger("Listener.ASSERT: " + event.type);
- ok(false, event.type + "should be never handled by listener");
- }
- }
-
- function middlerEventHandler(event) {
- logger("Middler: " + event.type + ". Captured_event: " + captured_event);
- if (event.type == "gotpointercapture") {
- test_MiddlerGotCapture++;
- f_gotMiddlerPointerCapture = true;
- ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for gotpointercapture event");
- }
- else if (event.type == "pointerover") {
- test_MiddlerOver++;
- ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerover event");
- }
- else if (event.type == "pointerleave") {
- test_MiddlerLeave++;
- ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerleave event");
- ok(!!listener, "Listener should be live!");
- ok(typeof(listener.setPointerCapture) == "function", "Listener should have a function setPointerCapture");
- listener.setPointerCapture(event.pointerId);
- }
- else if (event.type == "lostpointercapture") {
- test_MiddlerLostCapture++;
- f_gotMiddlerPointerCapture = false;
- ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for lostpointercapture event");
- }
- else if (event.type == "pointerup" ) {
- test_MiddlerUp++;
- }
- }
-
- function targetEventHandler(event) {
- logger("Target: " + event.type + ". Captured_event: " + captured_event);
- if (f_gotPointerCapture || f_gotMiddlerPointerCapture) {
- if (event.type != "pointerout" && event.type != "pointerleave") {
- logger("Target.ASSERT: " + event.type + " " + event.pointerId);
- test_TargetUnwanted++;
- ok(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". ");
- }
- }
- if (event.type == "pointerdown") {
- logger("Target.pointerdown 1: " + captured_event);
- test_TargetDown++;
- captured_event = event;
- ok(!!middler, "Middler should be live!");
- ok(typeof(middler.setPointerCapture) == "function", "Middler should have a function setPointerCapture");
- middler.setPointerCapture(event.pointerId);
- logger("Target.pointerdown 2: " + captured_event);
- }
- else if (event.type == "pointerup") {
- ok(f_lostPointerCapture, "Target should have received pointerup");
- ok(captured_event && captured_event.pointerId == event.pointerId, "Target: equals pointerId for lostpointercapture event");
- test_TargetUp++; // complete test
- }
- }
-
- function colorerHandler(event) {
- if(event.type == "pointerover")
- event.target.style.background = "red";
- else if(event.type == "pointerout")
- event.target.style.background = "yellow";
- }
-
- function setEventHandlers() {
- listener = document.getElementById("listener");
- middler = document.getElementById("middler");
- target = document.getElementById("target");
- target.style["touchAction"] = "none";
-
- // target and listener - handle all events
- for (var i = 0; i < All_Pointer_Events.length; i++) {
- on_event(target, All_Pointer_Events[i], targetEventHandler);
- on_event(listener, All_Pointer_Events[i], listenerEventHandler);
- on_event(middler, All_Pointer_Events[i], middlerEventHandler);
- on_event(target, All_Pointer_Events[i], colorerHandler);
- on_event(middler, All_Pointer_Events[i], colorerHandler);
- }
- }
-
- function prepareTest() {
- SpecialPowers.pushPrefEnv({
- "set": [
- ["dom.w3c_pointer_events.enabled", true]
- ]
- }, executeTest);
- }
-
- function executeTest()
- {
- logger("executeTest");
- setEventHandlers();
- document.body.offsetLeft;
- var rect = target.getBoundingClientRect();
- synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"});
- synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
- synthesizePointer(target, rect.width/3, rect.height/3, {type: "pointermove"});
- synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"});
- synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"});
- synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"});
- synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"});
- synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"});
- finishTest();
- }
-
- function finishTest() {
- setTimeout(function() {
- is(test_ListenerGotCapture, 1, "Listener should receive gotpointercapture event");
- is(test_ListenerUnwanted, 0, "Listener should not receive any unwanted events");
- is(test_ListenerLostCapture, 1, "Listener should receive lostpointercapture event");
- is(test_ListenerAfterCapture, 0, "Listener should not receive any events after release pointer capture");
- is(test_MiddlerGotCapture, 1, "Middler should receive gotpointercapture event");
- is(test_MiddlerOver, 1, "Middler should receive pointerover event");
- is(test_MiddlerLeave, 1, "Middler should receive pointerleave event");
- is(test_MiddlerUp, 0, "Middler should not receive pointerup event");
- is(test_MiddlerLostCapture, 1, "Middler should receive lostpointercapture event");
- is(test_TargetDown, 1, "Target should receive pointerdown event");
- is(test_TargetUnwanted, 0, "Target should not receive any event while pointer capture is active");
- is(test_TargetUp, 1, "Target should receive pointerup event");
- logger("finishTest");
- parent.finishTest();
- }, 1000);
- }
-
- function logger(message) {
- console.log(message);
- var log = document.getElementById('log');
- log.innerHTML = message + "<br>" + log.innerHTML;
- }
- </script>
-</head>
-<body onload="prepareTest()">
- <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=976963">Mozilla Bug 976963</a>
- <p id="display"></p>
- <div id="content" style="display: none">
- </div>
- <div id="listener">div id=listener</div>
- <div id="middler">div id=middler</div>
- <div id="target">div id=target</div>
- <pre id="log">
- </pre>
-</body>
-</html>
diff --git a/layout/base/tests/bug977003_inner_5.html b/layout/base/tests/bug977003_inner_5.html
index 70fc5ba40..81094043c 100644
--- a/layout/base/tests/bug977003_inner_5.html
+++ b/layout/base/tests/bug977003_inner_5.html
@@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139
var test_lost_listener = false;
var test_lost_type = "";
var test_move_listener = false;
+ var test_over_listener = false;
var test_listener = false;
var test_lost_primary = false;
@@ -53,6 +54,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139
logger("Receive event on Listener: " + event.type);
test_move_listener = true;
}
+ function ListenerOverHandler(event) {
+ logger("Receive event on Listener: " + event.type);
+ test_over_listener = true;
+ }
function ListenerHandler(event) {
logger("Receive event on Listener: " + event.type);
test_listener = true;
@@ -74,7 +79,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139
target.addEventListener("pointerdown", TargetDownHandler, false);
listener.addEventListener("gotpointercapture", ListenerGotPCHandler, false);
listener.addEventListener("lostpointercapture", ListenerLostPCHandler, false);
- listener.addEventListener("pointerover", ListenerHandler, false);
+ listener.addEventListener("pointerover", ListenerOverHandler, false);
listener.addEventListener("pointermove", ListenerMoveHandler, false);
listener.addEventListener("pointerup", ListenerHandler, false);
listener.addEventListener("pointerout", ListenerHandler, false);
@@ -93,6 +98,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139
parent.is(test_lost_type, "touch", "Part 5: lostpointercapture event should have pointerType touch");
parent.is(test_lost_primary, true, "Part 5: lostpointercapture event should have isPrimary as true");
parent.is(test_move_listener, true, "Part 5: gotpointercapture should be triggered by pointermove");
+ parent.is(test_over_listener, true, "Part 5: listener should receive pointerover when capturing pointer");
parent.is(test_listener, false, "Part 5: listener should not receive any other events");
logger("finishTest");
parent.finishTest();
diff --git a/layout/base/tests/bug977003_inner_6.html b/layout/base/tests/bug977003_inner_6.html
index 12424b1f2..b60ca5c31 100644
--- a/layout/base/tests/bug977003_inner_6.html
+++ b/layout/base/tests/bug977003_inner_6.html
@@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563
var listener = undefined;
var test_target = false;
var test_move = false;
+ var test_over = false;
var test_listener = false;
var receive_lostpointercapture = false;
@@ -44,6 +45,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563
}
} else if(event.type == "pointermove") {
test_move = true;
+ } else if(event.type == "pointerover") {
+ test_over = true;
} else {
test_listener = true;
}
@@ -81,7 +84,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563
// PE level 2 defines that the pending pointer capture is processed when firing next pointer events.
// In this test case, pointer capture release is processed when firing pointermove
parent.is(test_move, true, "Part 6: gotpointercapture should be triggered by pointermove");
- parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture");
+ parent.is(test_over, true, "Part 6: pointerover should be received when capturing pointer");
+ parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture except pointerover");
logger("finishTest");
parent.finishTest();
}
diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini
index 279b0af8a..405697977 100644
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -256,8 +256,6 @@ skip-if = toolkit == 'android'
support-files = bug851445_helper.html
[test_bug970964.html]
support-files = bug970964_inner.html
-[test_bug976963.html]
-support-files = bug976963_inner.html
[test_bug977003.html]
support-files =
bug977003_inner_1.html
diff --git a/layout/base/tests/test_bug976963.html b/layout/base/tests/test_bug976963.html
deleted file mode 100644
index 4b8da3a6e..000000000
--- a/layout/base/tests/test_bug976963.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=976963
--->
- <head>
- <meta charset="utf-8">
- <meta name="author" content="Maksim Lebedev" />
- <title>Test for Bug 976963</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="text/javascript">
- function prepareTest() {
- SimpleTest.waitForExplicitFinish();
- SimpleTest.requestFlakyTimeout("untriaged");
- SpecialPowers.pushPrefEnv({
- "set": [
- ["dom.w3c_pointer_events.enabled", true],
- ["layout.reflow.synthMouseMove", false]
- ]
- }, startTest);
- }
- function startTest() {
- var iframe = document.getElementById("testFrame");
- iframe.src = "bug976963_inner.html";
- }
- function finishTest() {
- SimpleTest.finish();
- }
- </script>
- </head>
- <body onload="prepareTest()">
- <iframe id="testFrame" height="700" width="700"></iframe>
- </body>
-</html>
diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h
index 643132618..442ac41e8 100644
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -43,22 +43,31 @@ namespace dom {
class WidgetPointerHelper
{
public:
- bool convertToPointer;
uint32_t pointerId;
uint32_t tiltX;
uint32_t tiltY;
- bool retargetedByPointerCapture;
+ uint32_t twist;
+ float tangentialPressure;
+ bool convertToPointer;
- WidgetPointerHelper() : convertToPointer(true), pointerId(0), tiltX(0), tiltY(0),
- retargetedByPointerCapture(false) {}
+ WidgetPointerHelper()
+ : pointerId(0)
+ , tiltX(0)
+ , tiltY(0)
+ , twist(0)
+ , tangentialPressure(0)
+ , convertToPointer(true)
+ {
+ }
void AssignPointerHelperData(const WidgetPointerHelper& aEvent)
{
- convertToPointer = aEvent.convertToPointer;
pointerId = aEvent.pointerId;
tiltX = aEvent.tiltX;
tiltY = aEvent.tiltY;
- retargetedByPointerCapture = aEvent.retargetedByPointerCapture;
+ twist = aEvent.twist;
+ tangentialPressure = aEvent.tangentialPressure;
+ convertToPointer = aEvent.convertToPointer;
}
};
diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h
index 7a9d870d9..e45189bb1 100644
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -219,6 +219,34 @@ struct ParamTraits<mozilla::WidgetWheelEvent>
};
template<>
+struct ParamTraits<mozilla::WidgetPointerHelper>
+{
+ typedef mozilla::WidgetPointerHelper paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ WriteParam(aMsg, aParam.pointerId);
+ WriteParam(aMsg, aParam.tiltX);
+ WriteParam(aMsg, aParam.tiltY);
+ WriteParam(aMsg, aParam.twist);
+ WriteParam(aMsg, aParam.tangentialPressure);
+ // We don't serialize convertToPointer since it's temporarily variable and
+ // should be reset to default.
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+ {
+ bool rv;
+ rv = ReadParam(aMsg, aIter, &aResult->pointerId) &&
+ ReadParam(aMsg, aIter, &aResult->tiltX) &&
+ ReadParam(aMsg, aIter, &aResult->tiltY) &&
+ ReadParam(aMsg, aIter, &aResult->twist) &&
+ ReadParam(aMsg, aIter, &aResult->tangentialPressure);
+ return rv;
+ }
+};
+
+template<>
struct ParamTraits<mozilla::WidgetMouseEvent>
{
typedef mozilla::WidgetMouseEvent paramType;
@@ -226,13 +254,13 @@ struct ParamTraits<mozilla::WidgetMouseEvent>
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, static_cast<mozilla::WidgetMouseEventBase>(aParam));
+ WriteParam(aMsg, static_cast<mozilla::WidgetPointerHelper>(aParam));
WriteParam(aMsg, aParam.mIgnoreRootScrollFrame);
WriteParam(aMsg, static_cast<paramType::ReasonType>(aParam.mReason));
WriteParam(aMsg, static_cast<paramType::ContextMenuTriggerType>(
aParam.mContextMenuTrigger));
WriteParam(aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom));
WriteParam(aMsg, aParam.mClickCount);
- WriteParam(aMsg, aParam.pointerId);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@@ -243,12 +271,13 @@ struct ParamTraits<mozilla::WidgetMouseEvent>
paramType::ExitFromType exitFrom = 0;
rv = ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
+ ReadParam(aMsg, aIter,
+ static_cast<mozilla::WidgetPointerHelper*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mIgnoreRootScrollFrame) &&
ReadParam(aMsg, aIter, &reason) &&
ReadParam(aMsg, aIter, &contextMenuTrigger) &&
ReadParam(aMsg, aIter, &exitFrom) &&
- ReadParam(aMsg, aIter, &aResult->mClickCount) &&
- ReadParam(aMsg, aIter, &aResult->pointerId);
+ ReadParam(aMsg, aIter, &aResult->mClickCount);
aResult->mReason = static_cast<paramType::Reason>(reason);
aResult->mContextMenuTrigger =
static_cast<paramType::ContextMenuTrigger>(contextMenuTrigger);
@@ -290,8 +319,6 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
WriteParam(aMsg, aParam.mWidth);
WriteParam(aMsg, aParam.mHeight);
- WriteParam(aMsg, aParam.tiltX);
- WriteParam(aMsg, aParam.tiltY);
WriteParam(aMsg, aParam.mIsPrimary);
}
@@ -301,8 +328,6 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mWidth) &&
ReadParam(aMsg, aIter, &aResult->mHeight) &&
- ReadParam(aMsg, aIter, &aResult->tiltX) &&
- ReadParam(aMsg, aIter, &aResult->tiltY) &&
ReadParam(aMsg, aIter, &aResult->mIsPrimary);
return rv;
}