Repository: fabricjs/fabric.js
Pull request #9396 (2023-10-02 22:12:30)

fix(Canvas): in/out event names were swapped
Event names were swapped during the migration. 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d549e657b..60290dfe2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,9 @@
 # Changelog
 
-- fix(Canvas): `setActiveObject` should update `canvas#_activeSelection` [#9336](https://github.com/fabricjs/fabric.js/pull/9336)
-
 ## [next]
 
+- fix(Canvas): in/out event names were swapped [#9396](https://github.com/fabricjs/fabric.js/pull/9396)
+- fix(Canvas): `setActiveObject` should update `canvas#_activeSelection` [#9336](https://github.com/fabricjs/fabric.js/pull/9336)
 - patch(Coords): calc oCoords only with canvas ref [#9380](https://github.com/fabricjs/fabric.js/pull/9380)
 - patch(Control): pass object to `calcCornerCoords` [#9376](https://github.com/fabricjs/fabric.js/pull/9376)
 - fix(Canvas): invalidate `_objectsToRender` on stack change [#9387](https://github.com/fabricjs/fabric.js/pull/9387)
@@ -25,7 +25,7 @@
 - fix(IText): cursor width under group [#9341](https://github.com/fabricjs/fabric.js/pull/9341)
 - TS(Canvas): constructor optional el [#9348](https://github.com/fabricjs/fabric.js/pull/9348)
 
-## [6.0.0-b13]
+## [6.0.0-beta13]
 
 - fix(Textbox): implemente a fix for the style shifting issues on new lines [#9197](https://github.com/fabricjs/fabric.js/pull/9197)
 - Fix(Control) fix a regression in `wrap with fixed anchor`, regression from #8400 [#9326](https://github.com/fabricjs/fabric.js/pull/9326)
diff --git a/src/canvas/Canvas.ts b/src/canvas/Canvas.ts
index 603c71831..e795afcf1 100644
--- a/src/canvas/Canvas.ts
+++ b/src/canvas/Canvas.ts
@@ -1325,7 +1325,7 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
     const targetChanged = oldTarget !== target;
 
     if (oldTarget && targetChanged) {
-      const outOpt = {
+      const outOpt: CanvasEvents[typeof canvasOut] = {
         ...data,
         e,
         target: oldTarget,
@@ -1334,11 +1334,11 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
         pointer: this.getPointer(e, true),
         absolutePointer: this.getPointer(e),
       };
-      fireCanvas && this.fire(canvasIn, outOpt);
+      fireCanvas && this.fire(canvasOut, outOpt);
       oldTarget.fire(targetOut, outOpt);
     }
     if (target && targetChanged) {
-      const inOpt: TPointerEventInfo = {
+      const inOpt: CanvasEvents[typeof canvasIn] = {
         ...data,
         e,
         target,
@@ -1347,7 +1347,7 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
         pointer: this.getPointer(e, true),
         absolutePointer: this.getPointer(e),
       };
-      fireCanvas && this.fire(canvasOut, inOpt);
+      fireCanvas && this.fire(canvasIn, inOpt);
       target.fire(targetIn, inOpt);
     }
   }


Test patch:
diff --git a/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap b/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
index de66727f7..cdf524feb 100644
--- a/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
+++ b/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
@@ -187,7 +187,7 @@ exports[`Canvas event data HTML event "dragenter" should fire a corresponding ca
     },
   ],
   [
-    "drag:leave",
+    "drag:enter",
     {
       "absolutePointer": Point {
         "x": -30,
@@ -260,7 +260,7 @@ exports[`Canvas event data HTML event "dragover" should fire a corresponding can
     },
   ],
   [
-    "drag:leave",
+    "drag:enter",
     {
       "absolutePointer": Point {
         "x": -30,
@@ -579,3 +579,194 @@ exports[`Canvas event data HTML event "wheel" should fire a corresponding canvas
   ],
 ]
 `;
+
+exports[`should fire mouse over/out events on target 1`] = `
+[
+  [
+    "mouseover",
+    {
+      "absolutePointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "previousTarget": undefined,
+      "target": "target",
+    },
+  ],
+  [
+    "mousemove",
+    {
+      "absolutePointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "button": 1,
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "subTargets": [],
+      "target": "target",
+      "transform": null,
+    },
+  ],
+  [
+    "mouseout",
+    {
+      "absolutePointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "nextTarget": undefined,
+      "pointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "target": "target",
+    },
+  ],
+]
+`;
+
+exports[`should fire mouse over/out events on target 2`] = `
+[
+  [
+    "mouse:move:before",
+    {
+      "absolutePointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "button": 1,
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "subTargets": [],
+      "target": undefined,
+      "transform": null,
+    },
+  ],
+  [
+    "mouse:over",
+    {
+      "absolutePointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "previousTarget": undefined,
+      "target": "target",
+    },
+  ],
+  [
+    "mouse:move",
+    {
+      "absolutePointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "button": 1,
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 5,
+        "y": 5,
+      },
+      "subTargets": [],
+      "target": "target",
+      "transform": null,
+    },
+  ],
+  [
+    "mouse:move:before",
+    {
+      "absolutePointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "button": 1,
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "subTargets": [],
+      "target": undefined,
+      "transform": null,
+    },
+  ],
+  [
+    "mouse:out",
+    {
+      "absolutePointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "nextTarget": undefined,
+      "pointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "target": "target",
+    },
+  ],
+  [
+    "mouse:move",
+    {
+      "absolutePointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "button": 1,
+      "e": MouseEvent {
+        "isTrusted": false,
+      },
+      "isClick": false,
+      "pointer": Point {
+        "x": 20,
+        "y": 20,
+      },
+      "subTargets": [],
+      "target": undefined,
+      "transform": null,
+    },
+  ],
+]
+`;
diff --git a/src/canvas/__tests__/eventData.test.ts b/src/canvas/__tests__/eventData.test.ts
index 58c5d04a4..7b7180872 100644
--- a/src/canvas/__tests__/eventData.test.ts
+++ b/src/canvas/__tests__/eventData.test.ts
@@ -110,7 +110,7 @@ it('A selected subtarget should not fire an event twice', () => {
     subTargetCheck: true,
     interactive: true,
   });
-  const canvas = new Canvas(null);
+  const canvas = new Canvas();
   canvas.add(group);
   const targetSpy = jest.fn();
   target.on('mousedown', targetSpy);
@@ -122,3 +122,20 @@ it('A selected subtarget should not fire an event twice', () => {
   } as unknown as TPointerEvent);
   expect(targetSpy).toHaveBeenCalledTimes(1);
 });
+
+it('should fire mouse over/out events on target', () => {
+  const target = new FabricObject({ width: 10, height: 10 });
+  const canvas = new Canvas();
+  canvas.add(target);
+
+  jest.spyOn(target, 'toJSON').mockReturnValue('target');
+
+  const targetSpy = jest.spyOn(target, 'fire');
+  const canvasSpy = jest.spyOn(canvas, 'fire');
+  const enter = new MouseEvent('mousemove', { clientX: 5, clientY: 5 });
+  const exit = new MouseEvent('mousemove', { clientX: 20, clientY: 20 });
+  canvas._onMouseMove(enter);
+  canvas._onMouseMove(exit);
+  expect(targetSpy.mock.calls).toMatchSnapshot();
+  expect(canvasSpy.mock.calls).toMatchSnapshot();
+});