From fb47690ed83d3021b208928d093a45a66041efe3 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sat, 25 May 2024 22:09:13 +0200 Subject: [PATCH 01/10] save work --- src/shapes/ActiveSelection.ts | 6 +++++- src/shapes/Circle.ts | 10 ++++++++++ src/shapes/Ellipse.ts | 10 ++++++++++ src/shapes/Group.ts | 5 +++-- src/shapes/Image.ts | 7 +++++-- src/shapes/Line.ts | 10 ++++++++-- src/shapes/Object/InteractiveObject.ts | 13 +++++++++++++ src/shapes/Object/Object.ts | 9 +++------ src/shapes/Path.ts | 5 ++++- src/shapes/Polygon.ts | 7 ------- src/shapes/Polyline.ts | 6 +++++- src/shapes/Rect.ts | 8 ++++---- src/shapes/Triangle.ts | 10 ++++++++++ 13 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/shapes/ActiveSelection.ts b/src/shapes/ActiveSelection.ts index 19ff25a0f65..7e119eadbce 100644 --- a/src/shapes/ActiveSelection.ts +++ b/src/shapes/ActiveSelection.ts @@ -62,10 +62,14 @@ export class ActiveSelection extends Group { options: Partial = {} ) { super(objects, { - ...options, layoutManager: options.layoutManager ?? new ActiveSelectionLayoutManager(), }); + Object.assign( + this, + (this.constructor as typeof ActiveSelection).ownDefaults + ); + this.setOptions(options); } /** diff --git a/src/shapes/Circle.ts b/src/shapes/Circle.ts index 050e3bbf025..66b67ab1b84 100644 --- a/src/shapes/Circle.ts +++ b/src/shapes/Circle.ts @@ -87,6 +87,16 @@ export class Circle< }; } + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options?: Props) { + super(); + Object.assign(this, (this.constructor as typeof Circle).ownDefaults); + this.setOptions(options); + } + /** * @private * @param {String} key diff --git a/src/shapes/Ellipse.ts b/src/shapes/Ellipse.ts index d56e8c610b5..5cdad507000 100644 --- a/src/shapes/Ellipse.ts +++ b/src/shapes/Ellipse.ts @@ -61,6 +61,16 @@ export class Ellipse< }; } + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options?: Props) { + super(); + Object.assign(this, (this.constructor as typeof Ellipse).ownDefaults); + this.setOptions(options); + } + /** * @private * @param {String} key diff --git a/src/shapes/Group.ts b/src/shapes/Group.ts index fe45a2e6bb6..c5904d4f643 100644 --- a/src/shapes/Group.ts +++ b/src/shapes/Group.ts @@ -137,8 +137,9 @@ export class Group * @param {Object} [options] Options object */ constructor(objects: FabricObject[] = [], options: Partial = {}) { - // @ts-expect-error options error - super(options); + super(); + Object.assign(this, (this.constructor as typeof Group).ownDefaults); + this.setOptions(options); this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller this.__objectSelectionTracker = this.__objectSelectionMonitor.bind( diff --git a/src/shapes/Image.ts b/src/shapes/Image.ts index 37038e759b9..34ac1547f12 100644 --- a/src/shapes/Image.ts +++ b/src/shapes/Image.ts @@ -196,8 +196,11 @@ export class FabricImage< */ constructor(elementId: string, options?: Props); constructor(element: ImageSource, options?: Props); - constructor(arg0: ImageSource | string, options: Props = {} as Props) { - super({ filters: [], ...options }); + constructor(arg0: ImageSource | string, options?: Props) { + super(); + this.filters = []; + Object.assign(this, (this.constructor as typeof FabricImage).ownDefaults); + this.setOptions(options); this.cacheKey = `texture${uid()}`; this.setElement( typeof arg0 === 'string' diff --git a/src/shapes/Line.ts b/src/shapes/Line.ts index 953a3af8340..83948be0d48 100644 --- a/src/shapes/Line.ts +++ b/src/shapes/Line.ts @@ -71,8 +71,14 @@ export class Line< * @param {Object} [options] Options object * @return {Line} thisArg */ - constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Props = {} as Props) { - super({ ...options, x1, y1, x2, y2 }); + constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) { + super(); + Object.assign(this, (this.constructor as typeof Line).ownDefaults); + this.setOptions(options); + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; this._setWidthHeight(); const { left, top } = options; typeof left === 'number' && this.set(LEFT, left); diff --git a/src/shapes/Object/InteractiveObject.ts b/src/shapes/Object/InteractiveObject.ts index 1a8c1b9b9e8..232cdefac0e 100644 --- a/src/shapes/Object/InteractiveObject.ts +++ b/src/shapes/Object/InteractiveObject.ts @@ -144,6 +144,19 @@ export class InteractiveFabricObject< }; } + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options?: Props) { + super(); + Object.assign( + this, + (this.constructor as typeof InteractiveFabricObject).ownDefaults + ); + this.setOptions(options); + } + /** * Update width and height of the canvas for cache * returns true or false if canvas needed resize. diff --git a/src/shapes/Object/Object.ts b/src/shapes/Object/Object.ts index e7c9ef58e80..ac81e002782 100644 --- a/src/shapes/Object/Object.ts +++ b/src/shapes/Object/Object.ts @@ -296,7 +296,7 @@ export class FabricObject< static ownDefaults = fabricObjectDefaultValues; static getDefaults(): Record { - return { ...FabricObject.ownDefaults }; + return FabricObject.ownDefaults; } /** @@ -333,12 +333,9 @@ export class FabricObject< * Constructor * @param {Object} [options] Options object */ - constructor(options: Props = {} as Props) { + constructor(options?: Props) { super(); - Object.assign( - this, - (this.constructor as typeof FabricObject).getDefaults() - ); + Object.assign(this, (this.constructor as typeof FabricObject).ownDefaults); this.setOptions(options); } diff --git a/src/shapes/Path.ts b/src/shapes/Path.ts index 6b9ae2c7a3d..f2571e45ac7 100644 --- a/src/shapes/Path.ts +++ b/src/shapes/Path.ts @@ -76,9 +76,12 @@ export class Path< */ constructor( path: TComplexPathData | string, + // todo: evaluate this spread here { path: _, left, top, ...options }: Partial = {} ) { - super(options as Props); + super(); + Object.assign(this, (this.constructor as typeof Path).ownDefaults); + this.setOptions(options); this._setPath(path || [], true); typeof left === 'number' && this.set(LEFT, left); typeof top === 'number' && this.set(TOP, top); diff --git a/src/shapes/Polygon.ts b/src/shapes/Polygon.ts index 4e1540f5eb4..8a0e52bf00d 100644 --- a/src/shapes/Polygon.ts +++ b/src/shapes/Polygon.ts @@ -6,13 +6,6 @@ export class Polygon extends Polyline { static type = 'Polygon'; - static getDefaults(): Record { - return { - ...super.getDefaults(), - ...Polyline.ownDefaults, - }; - } - protected isOpen() { return false; } diff --git a/src/shapes/Polyline.ts b/src/shapes/Polyline.ts index bcede176566..a729c156da8 100644 --- a/src/shapes/Polyline.ts +++ b/src/shapes/Polyline.ts @@ -65,6 +65,7 @@ export class Polyline< ...Polyline.ownDefaults, }; } + /** * A list of properties that if changed trigger a recalculation of dimensions * @todo check if you really need to recalculate for all cases @@ -108,7 +109,10 @@ export class Polyline< * }); */ constructor(points: XY[] = [], options: Props = {} as Props) { - super({ ...options, points }); + super(); + Object.assign(this, (this.constructor as typeof Polyline).ownDefaults); + this.setOptions(options); + this.points = points; const { left, top } = options; this.initialized = true; this.setBoundingBox(true); diff --git a/src/shapes/Rect.ts b/src/shapes/Rect.ts index 99bf14db3ed..fc59daf130c 100644 --- a/src/shapes/Rect.ts +++ b/src/shapes/Rect.ts @@ -64,13 +64,13 @@ export class Rect< /** * Constructor * @param {Object} [options] Options object - * @return {Object} thisArg */ - constructor(options: Props) { - super(options); + constructor(options?: Props) { + super(); + Object.assign(this, (this.constructor as typeof Rect).ownDefaults); + this.setOptions(options); this._initRxRy(); } - /** * Initializes rx/ry attributes * @private diff --git a/src/shapes/Triangle.ts b/src/shapes/Triangle.ts index abd78f7c8c2..f8840633062 100644 --- a/src/shapes/Triangle.ts +++ b/src/shapes/Triangle.ts @@ -25,6 +25,16 @@ export class Triangle< return { ...super.getDefaults(), ...Triangle.ownDefaults }; } + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options?: Props) { + super(); + Object.assign(this, (this.constructor as typeof Triangle).ownDefaults); + this.setOptions(options); + } + /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on From 39b76d4ff4e45f1cbe09794380d7371d6aa4f684 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 25 May 2024 20:11:43 +0000 Subject: [PATCH 02/10] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0a028d3612..099dd1cb4a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [next] +- perf(): Rework constructors to avoid the extra perf cost of current setup [#9891](https://github.com/fabricjs/fabric.js/pull/9891) - docs(): Improve JSDOCs for BlendImage [#9876](https://github.com/fabricjs/fabric.js/pull/9876) - fix(Group): Pass down the abort signal from group to objects [#9890](https://github.com/fabricjs/fabric.js/pull/9890) - fix(util): restore old composeMatrix code for performances improvement [#9851](https://github.com/fabricjs/fabric.js/pull/9851) From 60b14530477ce5dccf396c153c7ce2105353b2b8 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 08:20:42 +0200 Subject: [PATCH 03/10] save work --- src/Shadow.ts | 2 +- src/shapes/Circle.ts | 2 +- src/shapes/Ellipse.ts | 2 +- src/shapes/Group.ts | 2 +- src/shapes/IText/IText.ts | 5 +++-- src/shapes/Image.ts | 2 +- src/shapes/Line.ts | 2 +- src/shapes/Object/Object.ts | 2 +- src/shapes/Path.ts | 2 +- src/shapes/Polyline.ts | 2 +- src/shapes/Rect.ts | 2 +- src/shapes/Text/Text.ts | 7 +++++-- src/shapes/Textbox.ts | 11 +++++++++++ src/shapes/Triangle.ts | 2 +- 14 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/Shadow.ts b/src/Shadow.ts index f4f97ac9842..2681c5bff36 100644 --- a/src/Shadow.ts +++ b/src/Shadow.ts @@ -127,7 +127,7 @@ export class Shadow { constructor(arg0: string | Partial>) { const options: Partial> = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0; - Object.assign(this, (this.constructor as typeof Shadow).ownDefaults); + Object.assign(this, Shadow.ownDefaults); for (const prop in options) { // @ts-expect-error for loops are so messy in TS this[prop] = options[prop]; diff --git a/src/shapes/Circle.ts b/src/shapes/Circle.ts index 66b67ab1b84..0ebfb73fc1e 100644 --- a/src/shapes/Circle.ts +++ b/src/shapes/Circle.ts @@ -93,7 +93,7 @@ export class Circle< */ constructor(options?: Props) { super(); - Object.assign(this, (this.constructor as typeof Circle).ownDefaults); + Object.assign(this, Circle.ownDefaults); this.setOptions(options); } diff --git a/src/shapes/Ellipse.ts b/src/shapes/Ellipse.ts index 5cdad507000..141cb3cf467 100644 --- a/src/shapes/Ellipse.ts +++ b/src/shapes/Ellipse.ts @@ -67,7 +67,7 @@ export class Ellipse< */ constructor(options?: Props) { super(); - Object.assign(this, (this.constructor as typeof Ellipse).ownDefaults); + Object.assign(this, Ellipse.ownDefaults); this.setOptions(options); } diff --git a/src/shapes/Group.ts b/src/shapes/Group.ts index c5904d4f643..c9e85c282b6 100644 --- a/src/shapes/Group.ts +++ b/src/shapes/Group.ts @@ -138,7 +138,7 @@ export class Group */ constructor(objects: FabricObject[] = [], options: Partial = {}) { super(); - Object.assign(this, (this.constructor as typeof Group).ownDefaults); + Object.assign(this, Group.ownDefaults); this.setOptions(options); this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller diff --git a/src/shapes/IText/IText.ts b/src/shapes/IText/IText.ts index 7ed312ec130..989530ee28a 100644 --- a/src/shapes/IText/IText.ts +++ b/src/shapes/IText/IText.ts @@ -217,13 +217,14 @@ export class IText< } /** - * Constructor * @param {String} text Text string * @param {Object} [options] Options object */ constructor(text: string, options?: Props) { - super(text, options); + super(text); + Object.assign(this, IText.ownDefaults); + this.setOptions(options); this.initBehavior(); } diff --git a/src/shapes/Image.ts b/src/shapes/Image.ts index 34ac1547f12..e90eae1ebe3 100644 --- a/src/shapes/Image.ts +++ b/src/shapes/Image.ts @@ -199,7 +199,7 @@ export class FabricImage< constructor(arg0: ImageSource | string, options?: Props) { super(); this.filters = []; - Object.assign(this, (this.constructor as typeof FabricImage).ownDefaults); + Object.assign(this, FabricImage.ownDefaults); this.setOptions(options); this.cacheKey = `texture${uid()}`; this.setElement( diff --git a/src/shapes/Line.ts b/src/shapes/Line.ts index 83948be0d48..7da88f52575 100644 --- a/src/shapes/Line.ts +++ b/src/shapes/Line.ts @@ -73,7 +73,7 @@ export class Line< */ constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) { super(); - Object.assign(this, (this.constructor as typeof Line).ownDefaults); + Object.assign(this, Line.ownDefaults); this.setOptions(options); this.x1 = x1; this.x2 = x2; diff --git a/src/shapes/Object/Object.ts b/src/shapes/Object/Object.ts index ac81e002782..37363f2f2b6 100644 --- a/src/shapes/Object/Object.ts +++ b/src/shapes/Object/Object.ts @@ -335,7 +335,7 @@ export class FabricObject< */ constructor(options?: Props) { super(); - Object.assign(this, (this.constructor as typeof FabricObject).ownDefaults); + Object.assign(this, FabricObject.ownDefaults); this.setOptions(options); } diff --git a/src/shapes/Path.ts b/src/shapes/Path.ts index f2571e45ac7..1a7485d8d45 100644 --- a/src/shapes/Path.ts +++ b/src/shapes/Path.ts @@ -80,7 +80,7 @@ export class Path< { path: _, left, top, ...options }: Partial = {} ) { super(); - Object.assign(this, (this.constructor as typeof Path).ownDefaults); + Object.assign(this, Path.ownDefaults); this.setOptions(options); this._setPath(path || [], true); typeof left === 'number' && this.set(LEFT, left); diff --git a/src/shapes/Polyline.ts b/src/shapes/Polyline.ts index a729c156da8..1679a6e7536 100644 --- a/src/shapes/Polyline.ts +++ b/src/shapes/Polyline.ts @@ -110,7 +110,7 @@ export class Polyline< */ constructor(points: XY[] = [], options: Props = {} as Props) { super(); - Object.assign(this, (this.constructor as typeof Polyline).ownDefaults); + Object.assign(this, Polyline.ownDefaults); this.setOptions(options); this.points = points; const { left, top } = options; diff --git a/src/shapes/Rect.ts b/src/shapes/Rect.ts index fc59daf130c..c4e70a35345 100644 --- a/src/shapes/Rect.ts +++ b/src/shapes/Rect.ts @@ -67,7 +67,7 @@ export class Rect< */ constructor(options?: Props) { super(); - Object.assign(this, (this.constructor as typeof Rect).ownDefaults); + Object.assign(this, Rect.ownDefaults); this.setOptions(options); this._initRxRy(); } diff --git a/src/shapes/Text/Text.ts b/src/shapes/Text/Text.ts index 4dcd8312d83..ec1f6826220 100644 --- a/src/shapes/Text/Text.ts +++ b/src/shapes/Text/Text.ts @@ -420,8 +420,11 @@ export class FabricText< return { ...super.getDefaults(), ...FabricText.ownDefaults }; } - constructor(text: string, options: Props = {} as Props) { - super({ ...options, text, styles: options?.styles || {} }); + constructor(text: string, options?: Props) { + super(); + Object.assign(this, FabricText.ownDefaults); + this.text = text; + this.setOptions(options); this.initialized = true; if (this.path) { this.setPathInfo(); diff --git a/src/shapes/Textbox.ts b/src/shapes/Textbox.ts index 2f91768d92b..1e84a1c7179 100644 --- a/src/shapes/Textbox.ts +++ b/src/shapes/Textbox.ts @@ -102,6 +102,17 @@ export class Textbox< }; } + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + */ + constructor(text: string, options?: Props) { + super(text); + Object.assign(this, Textbox.ownDefaults); + this.setOptions(options); + } + /** * Unlike superclass's version of this function, Textbox does not update * its width. diff --git a/src/shapes/Triangle.ts b/src/shapes/Triangle.ts index f8840633062..a7716ebef29 100644 --- a/src/shapes/Triangle.ts +++ b/src/shapes/Triangle.ts @@ -31,7 +31,7 @@ export class Triangle< */ constructor(options?: Props) { super(); - Object.assign(this, (this.constructor as typeof Triangle).ownDefaults); + Object.assign(this, Triangle.ownDefaults); this.setOptions(options); } From 70be0993a3ae5cfbf84bffd55bf6980e9f9ad6be Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 09:01:40 +0200 Subject: [PATCH 04/10] testing --- src/shapes/Object/InteractiveObject.ts | 12 +++++++++++- src/shapes/Textbox.ts | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/shapes/Object/InteractiveObject.ts b/src/shapes/Object/InteractiveObject.ts index 232cdefac0e..eb458fe6098 100644 --- a/src/shapes/Object/InteractiveObject.ts +++ b/src/shapes/Object/InteractiveObject.ts @@ -139,7 +139,6 @@ export class InteractiveFabricObject< static getDefaults(): Record { return { ...super.getDefaults(), - controls: createObjectDefaultControls(), ...InteractiveFabricObject.ownDefaults, }; } @@ -152,11 +151,22 @@ export class InteractiveFabricObject< super(); Object.assign( this, + this.createControls(), (this.constructor as typeof InteractiveFabricObject).ownDefaults ); this.setOptions(options); } + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults + * @param {Object} [options] Options object + */ + protected createControls(): { controls: Record } { + return { controls: createObjectDefaultControls() }; + } + /** * Update width and height of the canvas for cache * returns true or false if canvas needed resize. diff --git a/src/shapes/Textbox.ts b/src/shapes/Textbox.ts index 1e84a1c7179..674436561ae 100644 --- a/src/shapes/Textbox.ts +++ b/src/shapes/Textbox.ts @@ -7,6 +7,7 @@ import type { TextStyleDeclaration } from './Text/StyledText'; import type { SerializedITextProps, ITextProps } from './IText/IText'; import type { ITextEvents } from './IText/ITextBehavior'; import type { TextLinesInfo } from './Text/Text'; +import type { Control } from '../controls/Control'; // @TODO: Many things here are configuration related and shouldn't be on the class nor prototype // regexes, list of properties that are not suppose to change by instances, magic consts. @@ -113,6 +114,15 @@ export class Textbox< this.setOptions(options); } + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults object + */ + protected createControls(): { controls: Record } { + return { controls: createTextboxDefaultControls() }; + } + /** * Unlike superclass's version of this function, Textbox does not update * its width. From b423c7a701471b7c967bf73d249c739d3d11e824 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 09:08:26 +0200 Subject: [PATCH 05/10] fix --- src/shapes/Object/InteractiveObject.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shapes/Object/InteractiveObject.ts b/src/shapes/Object/InteractiveObject.ts index eb458fe6098..71d1fb2b738 100644 --- a/src/shapes/Object/InteractiveObject.ts +++ b/src/shapes/Object/InteractiveObject.ts @@ -152,7 +152,7 @@ export class InteractiveFabricObject< Object.assign( this, this.createControls(), - (this.constructor as typeof InteractiveFabricObject).ownDefaults + InteractiveFabricObject.ownDefaults ); this.setOptions(options); } From e705b2e918be42493a8bf15b1f1f4adba287daf1 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 09:53:17 +0200 Subject: [PATCH 06/10] okish --- src/shapes/ActiveSelection.ts | 10 +++------- src/shapes/IText/IText.ts | 4 +--- src/shapes/Text/Text.ts | 2 +- src/shapes/Textbox.ts | 5 +---- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/shapes/ActiveSelection.ts b/src/shapes/ActiveSelection.ts index 7e119eadbce..d30668e4493 100644 --- a/src/shapes/ActiveSelection.ts +++ b/src/shapes/ActiveSelection.ts @@ -59,16 +59,12 @@ export class ActiveSelection extends Group { constructor( objects: FabricObject[] = [], - options: Partial = {} + { layoutManager, ...options }: Partial = {} ) { super(objects, { - layoutManager: - options.layoutManager ?? new ActiveSelectionLayoutManager(), + layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(), }); - Object.assign( - this, - (this.constructor as typeof ActiveSelection).ownDefaults - ); + Object.assign(this, ActiveSelection.ownDefaults); this.setOptions(options); } diff --git a/src/shapes/IText/IText.ts b/src/shapes/IText/IText.ts index 989530ee28a..bf1c9a48d34 100644 --- a/src/shapes/IText/IText.ts +++ b/src/shapes/IText/IText.ts @@ -222,9 +222,7 @@ export class IText< * @param {Object} [options] Options object */ constructor(text: string, options?: Props) { - super(text); - Object.assign(this, IText.ownDefaults); - this.setOptions(options); + super(text, { ...IText.ownDefaults, ...options } as Props); this.initBehavior(); } diff --git a/src/shapes/Text/Text.ts b/src/shapes/Text/Text.ts index ec1f6826220..4fefa1ed773 100644 --- a/src/shapes/Text/Text.ts +++ b/src/shapes/Text/Text.ts @@ -423,8 +423,8 @@ export class FabricText< constructor(text: string, options?: Props) { super(); Object.assign(this, FabricText.ownDefaults); - this.text = text; this.setOptions(options); + this.text = text; this.initialized = true; if (this.path) { this.setPathInfo(); diff --git a/src/shapes/Textbox.ts b/src/shapes/Textbox.ts index 674436561ae..5188c7ebca5 100644 --- a/src/shapes/Textbox.ts +++ b/src/shapes/Textbox.ts @@ -98,7 +98,6 @@ export class Textbox< static getDefaults(): Record { return { ...super.getDefaults(), - controls: createTextboxDefaultControls(), ...Textbox.ownDefaults, }; } @@ -109,9 +108,7 @@ export class Textbox< * @param {Object} [options] Options object */ constructor(text: string, options?: Props) { - super(text); - Object.assign(this, Textbox.ownDefaults); - this.setOptions(options); + super(text, { ...Textbox.ownDefaults, ...options } as Props); } /** From 3d9d8b813e44f5acb829de0126e556b84d59a4d4 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 09:57:12 +0200 Subject: [PATCH 07/10] fixed? --- src/shapes/Text/Text.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shapes/Text/Text.ts b/src/shapes/Text/Text.ts index 4fefa1ed773..0a8f3cd5446 100644 --- a/src/shapes/Text/Text.ts +++ b/src/shapes/Text/Text.ts @@ -424,6 +424,9 @@ export class FabricText< super(); Object.assign(this, FabricText.ownDefaults); this.setOptions(options); + if (!this.styles) { + this.styles = {}; + } this.text = text; this.initialized = true; if (this.path) { From 195baa97cc16fb9b22e43ca58fae0e24c85aeecb Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 12:27:55 +0200 Subject: [PATCH 08/10] one fixed --- test/unit/canvas.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/unit/canvas.js b/test/unit/canvas.js index 73b8d9ba760..bfffe7f4ee3 100644 --- a/test/unit/canvas.js +++ b/test/unit/canvas.js @@ -343,8 +343,11 @@ function initActiveSelection(canvas, activeObject, target, multiSelectionStacking) { fabric.classRegistry.setClass(class TextActiveSelection extends fabric.ActiveSelection { - static getDefaults() { - return {...super.getDefaults(),multiSelectionStacking} + static ownDefaults = { + multiSelectionStacking, + } + constructor(objects, options) { + super(objects, { ...TextActiveSelection.ownDefaults, ...options }) } }); canvas.setActiveObject(activeObject); From 516fee3e835e6838f60deb6b50759a090614bdc7 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 12:37:17 +0200 Subject: [PATCH 09/10] ok maybe better as static --- src/shapes/Object/InteractiveObject.ts | 4 ++-- src/shapes/Textbox.ts | 2 +- test/unit/object_interactivity.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shapes/Object/InteractiveObject.ts b/src/shapes/Object/InteractiveObject.ts index 71d1fb2b738..0bd13b9014e 100644 --- a/src/shapes/Object/InteractiveObject.ts +++ b/src/shapes/Object/InteractiveObject.ts @@ -151,7 +151,7 @@ export class InteractiveFabricObject< super(); Object.assign( this, - this.createControls(), + (this.constructor as typeof InteractiveFabricObject).createControls(), InteractiveFabricObject.ownDefaults ); this.setOptions(options); @@ -163,7 +163,7 @@ export class InteractiveFabricObject< * make this function return an empty object and add controls to the ownDefaults * @param {Object} [options] Options object */ - protected createControls(): { controls: Record } { + static createControls(): { controls: Record } { return { controls: createObjectDefaultControls() }; } diff --git a/src/shapes/Textbox.ts b/src/shapes/Textbox.ts index 5188c7ebca5..a8cffe32580 100644 --- a/src/shapes/Textbox.ts +++ b/src/shapes/Textbox.ts @@ -116,7 +116,7 @@ export class Textbox< * If you prefer to have on instance of controls shared among all objects * make this function return an empty object and add controls to the ownDefaults object */ - protected createControls(): { controls: Record } { + static createControls(): { controls: Record } { return { controls: createTextboxDefaultControls() }; } diff --git a/test/unit/object_interactivity.js b/test/unit/object_interactivity.js index a8ccb9634de..1befd91a6b2 100644 --- a/test/unit/object_interactivity.js +++ b/test/unit/object_interactivity.js @@ -147,7 +147,7 @@ // set size for bottom left corner and have different results for bl than normal setCornerCoords test QUnit.test('corner coords: custom control size', function(assert) { //set custom corner size - const sharedControls = fabric.Object.getDefaults().controls; + const sharedControls = fabric.FabricObject.createControls().controls; sharedControls.bl.sizeX = 30; sharedControls.bl.sizeY = 10; From 11c9db9a662f7b96f142b3646d8cddc023c6eeaf Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 26 May 2024 18:10:24 +0200 Subject: [PATCH 10/10] add export --- fabric.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fabric.ts b/fabric.ts index 623255692e8..4dc1cd7877b 100644 --- a/fabric.ts +++ b/fabric.ts @@ -56,6 +56,10 @@ export { */ FabricObject as Object, } from './src/shapes/Object/FabricObject'; +/** + * Exported so we can tweak default values + */ +export { FabricObject as BaseFabricObject } from './src/shapes/Object/Object'; export type { TFabricObjectProps,