diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ae8d2e1a3c..26d60737479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [next] +- TS(): Moved cache properties to static properties on classes [#xxxx](https://github.com/fabricjs/fabric.js/pull/xxxx) +- refactor(): Moved cache properties to static properties on classes [#8662](https://github.com/fabricjs/fabric.js/pull/8662) - docs(): v6 announcements [#8664](https://github.com/fabricjs/fabric.js/issues/8664) - ci(): remove TS transformer [#8660](https://github.com/fabricjs/fabric.js/pull/8660) - refactor(): BREAKING remove stateful mixin and functionality [#8663](https://github.com/fabricjs/fabric.js/pull/8663) diff --git a/src/shapes/Circle.ts b/src/shapes/Circle.ts index 89def99132d..b3810c7ad75 100644 --- a/src/shapes/Circle.ts +++ b/src/shapes/Circle.ts @@ -31,6 +31,13 @@ export class Circle extends FabricObject { */ declare endAngle: number; + static cacheProperties = [ + ...cacheProperties, + 'radius', + 'startAngle', + 'endAngle', + ]; + /** * @private * @param {String} key @@ -198,7 +205,6 @@ export const circleDefaultValues: Partial> = { Object.assign(Circle.prototype, { ...circleDefaultValues, - cacheProperties: [...cacheProperties, 'radius', 'startAngle', 'endAngle'], }); classRegistry.setClass(Circle); diff --git a/src/shapes/Ellipse.ts b/src/shapes/Ellipse.ts index 19f0313a352..02adc7ce6ac 100644 --- a/src/shapes/Ellipse.ts +++ b/src/shapes/Ellipse.ts @@ -20,6 +20,8 @@ export class Ellipse extends FabricObject { */ declare ry: number; + static cacheProperties = [...cacheProperties, 'rx', 'ry']; + /** * Constructor * @param {Object} [options] Options object @@ -147,7 +149,6 @@ export const ellipseDefaultValues: Partial> = { Object.assign(Ellipse.prototype, { ...ellipseDefaultValues, - cacheProperties: [...cacheProperties, 'rx', 'ry'], }); classRegistry.setClass(Ellipse); diff --git a/src/shapes/Image.ts b/src/shapes/Image.ts index 42619cdb37a..06aff514099 100644 --- a/src/shapes/Image.ts +++ b/src/shapes/Image.ts @@ -118,6 +118,7 @@ export class Image extends FabricObject { protected declare _originalElement: ImageSource; protected declare _filteredEl: ImageSource; + static cacheProperties = [...cacheProperties, 'cropX', 'cropY']; /** * Constructor * Image can be initialized with any canvas drawable or a string. @@ -780,7 +781,6 @@ export const imageDefaultValues: Partial> = { Object.assign(Image.prototype, { ...imageDefaultValues, - cacheProperties: [...cacheProperties, 'cropX', 'cropY'], }); classRegistry.setClass(Image); diff --git a/src/shapes/Line.ts b/src/shapes/Line.ts index dbb85cf4d8e..47e0fb1bd46 100644 --- a/src/shapes/Line.ts +++ b/src/shapes/Line.ts @@ -39,6 +39,7 @@ export class Line extends FabricObject { */ declare y2: number; + static cacheProperties = [...cacheProperties, 'x1', 'x2', 'y1', 'y2']; /** * Constructor * @param {Array} [points] Array of points @@ -322,7 +323,6 @@ export const lineDefaultValues: Partial> = { Object.assign(Line.prototype, { ...lineDefaultValues, - cacheProperties: [...cacheProperties, 'x1', 'x2', 'y1', 'y2'], }); classRegistry.setClass(Line); diff --git a/src/shapes/Object/Object.ts b/src/shapes/Object/Object.ts index 2cab94bb70a..49702e9f1f9 100644 --- a/src/shapes/Object/Object.ts +++ b/src/shapes/Object/Object.ts @@ -477,7 +477,7 @@ export class FabricObject< * and refreshed at the next render * @type Array */ - declare cacheProperties: string[]; + static cacheProperties: string[] = cacheProperties; /** * a fabricObject that, without stroke define a clipping area with their shape. filled in black @@ -1023,7 +1023,8 @@ export class FabricObject< if (isChanged) { const groupNeedsUpdate = this.group && this.group.isOnACache(); - if (this.cacheProperties.includes(key)) { + // @ts-ignore TS and constructor issue + if (this.constructor.cacheProperties.includes(key)) { this.dirty = true; groupNeedsUpdate && this.group!.set('dirty', true); } else if (groupNeedsUpdate && this.stateProperties.includes(key)) { @@ -1889,7 +1890,6 @@ export class FabricObject< * For inheritance reasons ( used in the superclass but static in the subclass ) */ Object.assign(FabricObject.prototype, { - cacheProperties, stateProperties, ...fabricObjectDefaultValues, }); diff --git a/src/shapes/Path.ts b/src/shapes/Path.ts index ea1d9809064..f52b8083984 100644 --- a/src/shapes/Path.ts +++ b/src/shapes/Path.ts @@ -32,6 +32,8 @@ export class Path extends FabricObject { declare segmentsInfo?: TPathSegmentsInfo[]; + static cacheProperties = [...cacheProperties, 'path', 'fillRule']; + /** * Constructor * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) @@ -386,7 +388,6 @@ export const pathDefaultValues: Partial> = { Object.assign(Path.prototype, { ...pathDefaultValues, - cacheProperties: [...cacheProperties, 'path', 'fillRule'], }); classRegistry.setClass(Path); diff --git a/src/shapes/Polyline.ts b/src/shapes/Polyline.ts index 16d036f3ad3..479f7f20c74 100644 --- a/src/shapes/Polyline.ts +++ b/src/shapes/Polyline.ts @@ -44,6 +44,8 @@ export class Polyline extends FabricObject { declare strokeOffset: Point; + static cacheProperties = [...cacheProperties, 'points']; + /** * Constructor * @param {Array} points Array of points (where each point is an object with x and y) @@ -316,7 +318,6 @@ export const polylineDefaultValues: Partial> = { Object.assign(Polyline.prototype, { ...polylineDefaultValues, - cacheProperties: [...cacheProperties, 'points'], strokeBBoxAffectingProperties: [ 'skewX', 'skewY', diff --git a/src/shapes/Rect.ts b/src/shapes/Rect.ts index 38e71a43d7c..521300b2010 100644 --- a/src/shapes/Rect.ts +++ b/src/shapes/Rect.ts @@ -20,6 +20,8 @@ export class Rect extends FabricObject { */ declare ry: number; + static cacheProperties = [...cacheProperties, 'rx', 'ry']; + /** * Constructor * @param {Object} [options] Options object @@ -192,7 +194,6 @@ export const rectDefaultValues: Partial> = { Object.assign(Rect.prototype, { ...rectDefaultValues, - cacheProperties: [...cacheProperties, 'rx', 'ry'], }); classRegistry.setClass(Rect); diff --git a/src/shapes/Text/Text.ts b/src/shapes/Text/Text.ts index 2fd6205b71c..c141269171a 100644 --- a/src/shapes/Text/Text.ts +++ b/src/shapes/Text/Text.ts @@ -384,6 +384,8 @@ export class Text< declare initialized?: true; + static cacheProperties = [...cacheProperties, ...additionalProps]; + constructor(text: string, options: any) { super({ ...options, text, styles: options?.styles || {} }); this.initialized = true; @@ -1917,7 +1919,6 @@ export const textDefaultValues: Partial> = { baseline: 0.11, // baseline-shift factor (downwards) }, textBackgroundColor: '', - cacheProperties: [...cacheProperties, ...additionalProps], stroke: null, shadow: null, path: null, diff --git a/test/unit/object.js b/test/unit/object.js index d174bf22ffe..bd3d44ec246 100644 --- a/test/unit/object.js +++ b/test/unit/object.js @@ -962,13 +962,15 @@ QUnit.test('dirty flag on set property', function(assert) { var object = new fabric.Object({ scaleX: 3, scaleY: 2}); - object.cacheProperties = ['propA', 'propB']; + const originalCacheProps = fabric.Object.cacheProperties; + fabric.Object.cacheProperties = ['propA', 'propB']; object.dirty = false; assert.equal(object.dirty, false, 'object starts with dirty flag disabled'); object.set('propC', '3'); assert.equal(object.dirty, false, 'after setting a property out of cache, dirty flag is still false'); object.set('propA', '2'); assert.equal(object.dirty, true, 'after setting a property from cache, dirty flag is true'); + fabric.Object.cacheProperties = originalCacheProps; }); QUnit.test('_createCacheCanvas sets object as dirty', function(assert) { @@ -983,11 +985,13 @@ QUnit.test('isCacheDirty', function(assert) { var object = new fabric.Object({ scaleX: 3, scaleY: 2, width: 1, height: 2}); assert.equal(object.dirty, true, 'object is dirty after creation'); - object.cacheProperties = ['propA', 'propB']; + const originalCacheProps = fabric.Object.cacheProperties; + fabric.Object.cacheProperties = ['propA', 'propB']; object.dirty = false; assert.equal(object.isCacheDirty(), false, 'object is not dirty if dirty flag is false'); object.dirty = true; assert.equal(object.isCacheDirty(), true, 'object is dirty if dirty flag is true'); + fabric.Object.cacheProperties = originalCacheProps; }); QUnit.test('_getCacheCanvasDimensions returns dimensions and zoom for cache canvas', function(assert) { diff --git a/test/unit/rect.js b/test/unit/rect.js index e4869bdae28..c04ddc68e69 100644 --- a/test/unit/rect.js +++ b/test/unit/rect.js @@ -58,8 +58,8 @@ QUnit.test('cache properties', function(assert) { var rect = new fabric.Rect(); - assert.ok(rect.cacheProperties.indexOf('rx') > -1, 'rx is in cacheProperties array'); - assert.ok(rect.cacheProperties.indexOf('ry') > -1, 'ry is in cacheProperties array'); + assert.ok(fabric.Rect.cacheProperties.indexOf('rx') > -1, 'rx is in cacheProperties array'); + assert.ok(fabric.Rect.cacheProperties.indexOf('ry') > -1, 'ry is in cacheProperties array'); }); QUnit.test('toObject', function(assert) { diff --git a/test/unit/text.js b/test/unit/text.js index 2b99c005278..41d6d65f124 100644 --- a/test/unit/text.js +++ b/test/unit/text.js @@ -898,7 +898,7 @@ QUnit.test('cacheProperties for text', function(assert) { var text = new fabric.Text('a'); - assert.equal(text.cacheProperties.join('-'), 'fill-stroke-strokeWidth-strokeDashArray-width-height-paintFirst-strokeUniform-strokeLineCap-strokeDashOffset-strokeLineJoin-strokeMiterLimit-backgroundColor-clipPath-fontFamily-fontWeight-fontSize-text-underline-overline-linethrough-textAlign-fontStyle-lineHeight-textBackgroundColor-charSpacing-styles-direction-path-pathStartOffset-pathSide-pathAlign'); + assert.equal(fabric.Text.cacheProperties.join('-'), 'fill-stroke-strokeWidth-strokeDashArray-width-height-paintFirst-strokeUniform-strokeLineCap-strokeDashOffset-strokeLineJoin-strokeMiterLimit-backgroundColor-clipPath-fontFamily-fontWeight-fontSize-text-underline-overline-linethrough-textAlign-fontStyle-lineHeight-textBackgroundColor-charSpacing-styles-direction-path-pathStartOffset-pathSide-pathAlign'); }); QUnit.test('_getLineLeftOffset', function(assert) { diff --git a/test/unit/textbox.js b/test/unit/textbox.js index 5191cf67b4a..7091a6c686a 100644 --- a/test/unit/textbox.js +++ b/test/unit/textbox.js @@ -98,7 +98,7 @@ assert.equal(textbox.text, 'test'); assert.equal(textbox.type, 'textbox'); assert.deepEqual(textbox.styles, { }); - assert.ok(textbox.cacheProperties.indexOf('width') > -1, 'width is in cacheProperties'); + assert.ok(fabric.Textbox.cacheProperties.indexOf('width') > -1, 'width is in cacheProperties'); }); QUnit.test('toObject', function(assert) { @@ -530,7 +530,7 @@ var styles = {}; for (var index = 0; index < text.length; index++) { styles[index] = { fontSize: 4 }; - + } var textbox = new fabric.Textbox(text, { styles: { 0: styles },