diff --git a/CHANGELOG.md b/CHANGELOG.md index d00bd158e24..84aafa60cbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [next] +- chore(TS): fix type of modifed event that could cause unexpected behaviour in dev code [#9596](https://github.com/fabricjs/fabric.js/pull/9596) - fix(LayoutManager): remove unnecessary check [#9591](https://github.com/fabricjs/fabric.js/pull/9591) - fix(Text) Fix style transfer issue on a line that is not empty [#9461](https://github.com/fabricjs/fabric.js/pull/9461) - ci(): add a vue template [#9502](https://github.com/fabricjs/fabric.js/pull/9502) diff --git a/src/EventTypeDefs.ts b/src/EventTypeDefs.ts index 10ba08cc596..d41ed30ebb0 100644 --- a/src/EventTypeDefs.ts +++ b/src/EventTypeDefs.ts @@ -104,8 +104,8 @@ export type TModificationEvents = | 'resizing' | 'modifyPoly'; -export interface ModifiedEvent - extends TEvent { +export interface ModifiedEvent { + e?: E; transform: Transform; target: FabricObject; action?: string; @@ -123,6 +123,8 @@ type ObjectModificationEvents = ModificationEventsSpec; type CanvasModificationEvents = ModificationEventsSpec< 'object:', BasicTransformEvent & { target: FabricObject }, + // TODO: this typing makes not possible to use properties from modified event + // in object:modified ModifiedEvent | { target: FabricObject } > & { 'before:transform': TEvent & { transform: Transform }; diff --git a/src/canvas/Canvas.ts b/src/canvas/Canvas.ts index e4fb091ff76..acdad90de43 100644 --- a/src/canvas/Canvas.ts +++ b/src/canvas/Canvas.ts @@ -920,48 +920,6 @@ export class Canvas extends SelectableCanvas implements CanvasOptions { } } - /** - * End the current transform. - * You don't usually need to call this method unless you are interrupting a user initiated transform - * because of some other event ( a press of key combination, or something that block the user UX ) - * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event - */ - endCurrentTransform(e: TPointerEvent) { - const transform = this._currentTransform; - this._finalizeCurrentTransform(e); - if (transform && transform.target) { - // this could probably go inside _finalizeCurrentTransform - transform.target.isMoving = false; - } - this._currentTransform = null; - } - - /** - * @private - * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event - */ - _finalizeCurrentTransform(e: TPointerEvent) { - const transform = this._currentTransform!, - target = transform.target, - options = { - e, - target, - transform, - action: transform.action, - }; - - if (target._scaling) { - target._scaling = false; - } - - target.setCoords(); - - if (transform.actionPerformed) { - this.fire('object:modified', options); - target.fire('modified', options); - } - } - /** * @private * @param {Event} e Event object fired on mousedown diff --git a/src/canvas/SelectableCanvas.ts b/src/canvas/SelectableCanvas.ts index 1ef63a39cde..28eabf75555 100644 --- a/src/canvas/SelectableCanvas.ts +++ b/src/canvas/SelectableCanvas.ts @@ -1157,7 +1157,6 @@ export class SelectableCanvas return false; } if (this._currentTransform && this._currentTransform.target === obj) { - // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract this.endCurrentTransform(e); } this._activeObject = undefined; @@ -1188,6 +1187,48 @@ export class SelectableCanvas return discarded; } + /** + * End the current transform. + * You don't usually need to call this method unless you are interrupting a user initiated transform + * because of some other event ( a press of key combination, or something that block the user UX ) + * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event + */ + endCurrentTransform(e?: TPointerEvent) { + const transform = this._currentTransform; + this._finalizeCurrentTransform(e); + if (transform && transform.target) { + // this could probably go inside _finalizeCurrentTransform + transform.target.isMoving = false; + } + this._currentTransform = null; + } + + /** + * @private + * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event + */ + _finalizeCurrentTransform(e?: TPointerEvent) { + const transform = this._currentTransform!, + target = transform.target, + options = { + e, + target, + transform, + action: transform.action, + }; + + if (target._scaling) { + target._scaling = false; + } + + target.setCoords(); + + if (transform.actionPerformed) { + this.fire('object:modified', options); + target.fire('modified', options); + } + } + /** * Sets viewport transformation of this canvas instance * @param {Array} vpt a Canvas 2D API transform matrix diff --git a/src/shapes/IText/ITextBehavior.ts b/src/shapes/IText/ITextBehavior.ts index 28ae386c079..5009dc55f58 100644 --- a/src/shapes/IText/ITextBehavior.ts +++ b/src/shapes/IText/ITextBehavior.ts @@ -14,7 +14,7 @@ import type { SerializedTextProps, TextProps } from '../Text/Text'; import type { TOptions } from '../../typedefs'; import { getDocumentFromElement } from '../../util/dom_misc'; import { LEFT, RIGHT, reNewline } from '../../constants'; -import type { Canvas } from '../../canvas/Canvas'; +import type { IText } from './IText'; /** * extend this regex to support non english languages @@ -690,8 +690,9 @@ export abstract class ITextBehavior< this.fire('editing:exited'); isTextChanged && this.fire('modified'); if (this.canvas) { - // @ts-expect-error in reality it is an IText instance - this.canvas.fire('text:editing:exited', { target: this }); + this.canvas.fire('text:editing:exited', { + target: this as unknown as IText, + }); isTextChanged && this.canvas.fire('object:modified', { target: this }); } return this;