Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(TS): types for toObject and additionaProperties #8677

Merged
merged 35 commits into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
445e630
interface
ShaMan123 Feb 8, 2023
f50c4c9
Update Object.ts
ShaMan123 Feb 8, 2023
f732868
Update CHANGELOG.md
ShaMan123 Feb 8, 2023
de8f05f
interactive object props
ShaMan123 Feb 8, 2023
6d5903c
circle props
ShaMan123 Feb 8, 2023
bed8b49
ws
ShaMan123 Feb 8, 2023
c5eb848
Update defaultValues.ts
ShaMan123 Feb 8, 2023
1179483
`toObject` types
ShaMan123 Feb 8, 2023
098bb2a
fix generics
ShaMan123 Feb 8, 2023
e8c0b9f
`fromObject` generic return value
ShaMan123 Feb 8, 2023
9a0af44
Update Circle.ts
ShaMan123 Feb 8, 2023
b13e583
Update ObjectProps.ts
ShaMan123 Feb 12, 2023
d715e07
Update Object.ts
ShaMan123 Feb 12, 2023
f49420d
transient: not to break types for now
ShaMan123 Feb 12, 2023
6486798
Merge branch 'master' into types-to-object
ShaMan123 Feb 12, 2023
0471c17
Merge branch 'master' into types-to-object
asturur Feb 25, 2023
a405c30
Merge branch 'master' into types-to-object
ShaMan123 Feb 27, 2023
440d222
Update Shadow.ts
ShaMan123 Feb 27, 2023
514de91
props redo
ShaMan123 Feb 27, 2023
657dd54
Update Circle.ts
ShaMan123 Feb 27, 2023
7cf6e8a
switch generic order
ShaMan123 Feb 27, 2023
f4d3843
Update typedefs.ts
ShaMan123 Feb 27, 2023
d1c229f
finish
ShaMan123 Feb 27, 2023
5e8fa31
Update Circle.ts
ShaMan123 Feb 27, 2023
8dd3e5a
cleanup
ShaMan123 Feb 27, 2023
6fb954e
Update Circle.ts
ShaMan123 Feb 27, 2023
3391f70
Update Circle.ts
ShaMan123 Feb 27, 2023
266ddce
Update CHANGELOG.md
ShaMan123 Feb 27, 2023
21d5334
cleanup
ShaMan123 Feb 27, 2023
1ca52e8
Update Object.ts
ShaMan123 Feb 27, 2023
40f3241
imports
ShaMan123 Feb 27, 2023
1851226
cleanup
ShaMan123 Feb 27, 2023
87a8ac4
Merge branch 'master' into types-to-object
asturur Feb 28, 2023
781ee39
restore import orders
asturur Mar 4, 2023
68a45c7
Update Circle.ts
asturur Mar 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [next]

- chore(TS): type Object props [#8677](https://github.com/fabricjs/fabric.js/issues/8677)
- chore(TS): remove default values from filter prototypes [#8742](https://github.com/fabricjs/fabric.js/issues/8742)
- chore(TS): remove default values from Objects prototypes, ( filters in a followup ) [#8719](https://github.com/fabricjs/fabric.js/issues/8719)
- fix(Intersection): bug causing selection edge case [#8735](https://github.com/fabricjs/fabric.js/pull/8735)
Expand Down
2 changes: 1 addition & 1 deletion src/Shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class Shadow {
}

const defaults = Shadow.ownDefaults;
const out: Record<string, unknown> = {};
const out: Partial<typeof data> = {};
for (const key in data) {
if (
data[key as keyof typeof data] !== defaults[key as keyof typeof data]
Expand Down
2 changes: 1 addition & 1 deletion src/controls/controlRendering.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { twoMathPi } from '../constants';
import type { FabricObject } from '../shapes/Object/Object';
import type { FabricObject } from '../shapes/Object/FabricObject';
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
import type { Control } from './Control';

Expand Down
72 changes: 45 additions & 27 deletions src/shapes/Circle.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ObjectEvents } from '../EventTypeDefs';
import { SHARED_ATTRIBUTES } from '../parser/attributes';
import { parseAttributes } from '../parser/parseAttributes';
import { cos } from '../util/misc/cos';
Expand All @@ -6,15 +7,13 @@ import { sin } from '../util/misc/sin';
import { classRegistry } from '../ClassRegistry';
import { FabricObject, cacheProperties } from './Object/FabricObject';
import { TClassProperties } from '../typedefs';
import { FabricObjectProps } from './Object/ObjectProps';
import {
FabricObjectProps,
SerializedObjectProps,
TProps,
} from './Object/types';

export const circleDefaultValues: Partial<TClassProperties<Circle>> = {
radius: 0,
startAngle: 0,
endAngle: 360,
};

export interface CircleProps extends FabricObjectProps {
interface UniqCircleProps {
/**
* Radius of this circle
* @type Number
Expand All @@ -39,17 +38,33 @@ export interface CircleProps extends FabricObjectProps {
endAngle: number;
}

export class Circle extends FabricObject implements CircleProps {
export interface SerializedCircleProps
extends SerializedObjectProps,
UniqCircleProps {}

export interface CircleProps extends FabricObjectProps, UniqCircleProps {}

const CIRCLE_PROPS = ['radius', 'startAngle', 'endAngle'] as const;

export const circleDefaultValues: UniqCircleProps = {
radius: 0,
startAngle: 0,
endAngle: 360,
};

export class Circle<
Props extends TProps<CircleProps> = Partial<CircleProps>,
SProps extends SerializedCircleProps = SerializedCircleProps,
EventSpec extends ObjectEvents = ObjectEvents
>
extends FabricObject<Props, SProps, EventSpec>
implements UniqCircleProps
{
declare radius: number;
declare startAngle: number;
declare endAngle: number;

static cacheProperties = [
...cacheProperties,
'radius',
'startAngle',
'endAngle',
];
static cacheProperties = [...cacheProperties, ...CIRCLE_PROPS];

static ownDefaults: Record<string, any> = circleDefaultValues;

Expand All @@ -60,10 +75,6 @@ export class Circle extends FabricObject implements CircleProps {
};
}

constructor(options?: CircleProps) {
super(options);
}

/**
* @private
* @param {String} key
Expand Down Expand Up @@ -125,13 +136,11 @@ export class Circle extends FabricObject implements CircleProps {
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {Object} object representation of an instance
*/
toObject(propertiesToInclude: string[] = []): object {
return super.toObject([
'radius',
'startAngle',
'endAngle',
...propertiesToInclude,
]);
toObject<
T extends Omit<Props & TClassProperties<this>, keyof SProps>,
K extends keyof T = never
>(propertiesToInclude: K[] = []): { [R in K]: T[K] } & SProps {
return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]);
}

/* _TO_SVG_START_ */
Expand Down Expand Up @@ -200,7 +209,7 @@ export class Circle extends FabricObject implements CircleProps {
top = 0,
radius,
...otherParsedAttributes
} = parseAttributes(element, this.ATTRIBUTE_NAMES);
} = parseAttributes(element, this.ATTRIBUTE_NAMES) as Partial<CircleProps>;

if (!radius || radius < 0) {
throw new Error(
Expand All @@ -220,6 +229,15 @@ export class Circle extends FabricObject implements CircleProps {
}

/* _FROM_SVG_END_ */

/**
* @todo how do we declare this??
*/
static fromObject<T extends TProps<SerializedCircleProps>>(
object: T
): Promise<Circle> {
return super.fromObject(object) as unknown as Promise<Circle>;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something i noticed in the previous PR too, i would argue this can be solved with a declaration?
is weird that TS would force me to add code that does nothing to obey types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct
I was lazy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another TS problem. Static class methods can't be generic using straight forward TS

}

// @ts-expect-error
Expand Down
18 changes: 12 additions & 6 deletions src/shapes/Object/FabricObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ import { ObjectEvents } from '../../EventTypeDefs';
import { FabricObjectSVGExportMixin } from './FabricObjectSVGExportMixin';
import { InteractiveFabricObject } from './InteractiveObject';
import { applyMixins } from '../../util/applyMixins';
import { FabricObjectProps } from './ObjectProps';
import { FabricObjectProps } from './types/FabricObjectProps';
import { TFabricObjectProps, SerializedObjectProps } from './types';

// TODO somehow we have to make a tree-shakeable import

// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars
export interface FabricObject<EventSpec extends ObjectEvents = ObjectEvents>
extends FabricObjectSVGExportMixin {}
export interface FabricObject<
Props extends TFabricObjectProps = Partial<FabricObjectProps>,
SProps extends SerializedObjectProps = SerializedObjectProps,
EventSpec extends ObjectEvents = ObjectEvents
> extends FabricObjectSVGExportMixin {}

export class FabricObject<EventSpec extends ObjectEvents = ObjectEvents>
extends InteractiveFabricObject<EventSpec>
implements FabricObjectProps {}
export class FabricObject<
Props extends TFabricObjectProps = Partial<FabricObjectProps>,
SProps extends SerializedObjectProps = SerializedObjectProps,
EventSpec extends ObjectEvents = ObjectEvents
> extends InteractiveFabricObject<Props, SProps, EventSpec> {}

applyMixins(FabricObject, [FabricObjectSVGExportMixin]);

Expand Down
75 changes: 51 additions & 24 deletions src/shapes/Object/InteractiveObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { sizeAfterTransform } from '../../util/misc/objectTransforms';
import { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';
import type { Canvas } from '../../canvas/Canvas';
import type { ControlRenderingStyleOverride } from '../../controls/controlRendering';
import { FabricObjectProps } from './ObjectProps';
import { FabricObjectProps } from './types/FabricObjectProps';
import { TFabricObjectProps, SerializedObjectProps } from './types';

type TOCoord = Point & {
corner: TCornerPoint;
Expand All @@ -23,13 +24,13 @@ type TOCoord = Point & {
type TControlSet = Record<string, Control>;

type TBorderRenderingStyleOverride = Partial<
Pick<FabricObject, 'borderColor' | 'borderDashArray'>
Pick<InteractiveFabricObject, 'borderColor' | 'borderDashArray'>
>;

type TStyleOverride = ControlRenderingStyleOverride &
TBorderRenderingStyleOverride &
Partial<
Pick<FabricObject, 'hasBorders' | 'hasControls'> & {
Pick<InteractiveFabricObject, 'hasBorders' | 'hasControls'> & {
forActiveSelection: boolean;
}
>;
Expand All @@ -42,11 +43,53 @@ export interface DragMethods {
export type FabricObjectWithDragSupport = InteractiveFabricObject & DragMethods;

export class InteractiveFabricObject<
Props extends TFabricObjectProps = Partial<FabricObjectProps>,
SProps extends SerializedObjectProps = SerializedObjectProps,
EventSpec extends ObjectEvents = ObjectEvents
>
extends FabricObject<EventSpec>
extends FabricObject<Props, SProps, EventSpec>
implements FabricObjectProps
{
declare noScaleCache: boolean;
declare centeredScaling: false;

declare snapAngle?: TDegree;
declare snapThreshold?: TDegree;
declare centeredRotation: true;

declare lockMovementX: boolean;
declare lockMovementY: boolean;
declare lockRotation: boolean;
declare lockScalingX: boolean;
declare lockScalingY: boolean;
declare lockSkewingX: boolean;
declare lockSkewingY: boolean;
declare lockScalingFlip: boolean;

declare cornerSize: number;
declare touchCornerSize: number;
declare transparentCorners: boolean;
declare cornerColor: string;
declare cornerStrokeColor: string;
declare cornerStyle: 'rect' | 'circle';
declare cornerDashArray: number[] | null;
declare hasControls: boolean;

declare borderColor: string;
declare borderDashArray: number[] | null;
declare borderOpacityWhenMoving: number;
declare borderScaleFactor: number;
declare hasBorders: boolean;
declare selectionBackgroundColor: string;

declare selectable: boolean;
declare evented: boolean;
declare perPixelTargetFind: boolean;
declare activeOn: 'down' | 'up';

declare hoverCursor: CSSStyleDeclaration['cursor'] | null;
declare moveCursor: CSSStyleDeclaration['cursor'] | null;

/**
* Describe object's corner position in canvas element coordinates.
* properties are depending on control keys and padding the main controls.
Expand Down Expand Up @@ -75,10 +118,6 @@ export class InteractiveFabricObject<
*/
declare _controlsVisibility: Record<string, boolean>;

declare noScaleCache: boolean;
declare snapAngle?: TDegree;
declare snapThreshold?: TDegree;

/**
* holds the controls for the object.
* controls are added by default_controls.js
Expand All @@ -103,14 +142,6 @@ export class InteractiveFabricObject<

declare canvas?: Canvas;

/**
* Constructor
* @param {Object} [options] Options object
*/
constructor(options?: FabricObjectProps) {
super(options);
}

/**
* Update width and height of the canvas for cache
* returns true or false if canvas needed resize.
Expand All @@ -122,10 +153,7 @@ export class InteractiveFabricObject<
if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {
const target = targetCanvas._currentTransform.target,
action = targetCanvas._currentTransform.action;
if (
this === (target as InteractiveFabricObject) &&
action.startsWith('scale')
) {
if (this === (target as unknown as this) && action.startsWith('scale')) {
return false;
}
}
Expand All @@ -136,7 +164,7 @@ export class InteractiveFabricObject<
* Determines which corner is under the mouse cursor, represented by `pointer`.
* This function is return a corner only if the object is the active one.
* This is done to avoid selecting corner of non active object and activating transformations
* rather than drag action. The default behaviour of fabricJS is that if you want to trasform
* rather than drag action. The default behavior of fabricJS is that if you want to transform
* an object, first you select it to show the control set
* @private
* @param {Object} pointer The pointer indicating the mouse position
Expand All @@ -147,7 +175,7 @@ export class InteractiveFabricObject<
if (
!this.hasControls ||
!this.canvas ||
(this.canvas._activeObject as InteractiveFabricObject) !== this
(this.canvas._activeObject as unknown as this) !== this
) {
return 0;
}
Expand Down Expand Up @@ -312,8 +340,7 @@ export class InteractiveFabricObject<
if (
!this.selectionBackgroundColor ||
(this.canvas && !this.canvas.interactive) ||
(this.canvas &&
(this.canvas._activeObject as InteractiveFabricObject) !== this)
(this.canvas && (this.canvas._activeObject as unknown as this) !== this)
) {
return;
}
Expand Down
Loading