Skip to content

Commit

Permalink
Merge branch 'psyche/typing-2' of https://github.com/psychedelicious/…
Browse files Browse the repository at this point in the history
…konva into psychedelicious-psyche/typing-2
  • Loading branch information
lavrton committed Dec 6, 2024
2 parents be24e9b + 9c41a6e commit 09485ef
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 55 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "konva",
"version": "9.3.16",
"description": "HTML5 2d canvas library.",
"author": "Anton Lavrenov",
"files": [
"README.md",
Expand Down
123 changes: 102 additions & 21 deletions src/Factory.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,76 @@
import { Node } from './Node';
import { GetSet } from './types';
import { Util } from './Util';
import { getComponentValidator } from './Validators';

const GET = 'get',
SET = 'set';
const GET = 'get';
const SET = 'set';

/**
* Enforces that a type is a string.
*/
type EnforceString<T> = T extends string ? T : never;

/**
* Represents a class.
*/
type Constructor = abstract new (...args: any) => any;

/**
* An attribute of an instance of the provided class. Attributes names be strings.
*/
type Attr<T extends Constructor> = EnforceString<keyof InstanceType<T>>;

/**
* A function that is called after a setter is called.
*/
type AfterFunc<T extends Constructor> = (this: InstanceType<T>) => void;

/**
* Extracts the type of a GetSet.
*/
type ExtractGetSet<T> = T extends GetSet<infer U, any> ? U : never;

/**
* Extracts the type of a GetSet class attribute.
*/
type Value<T extends Constructor, U extends Attr<T>> = ExtractGetSet<
InstanceType<T>[U]
>;

/**
* A function that validates a value.
*/
type ValidatorFunc<T> = (val: ExtractGetSet<T>, attr: string) => T;

/**
* Extracts the "components" (keys) of a GetSet value. The value must be an object.
*/
type ExtractComponents<T extends Constructor, U extends Attr<T>> = Value<
T,
U
> extends Record<string, any>
? EnforceString<keyof Value<T, U>>[]
: never;

export const Factory = {
addGetterSetter(constructor, attr, def?, validator?, after?) {
addGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def?: Value<T, U>,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
): void {
Factory.addGetter(constructor, attr, def);
Factory.addSetter(constructor, attr, validator, after);
Factory.addOverloadedGetterSetter(constructor, attr);
},
addGetter(constructor, attr, def?) {
const method = GET + Util._capitalize(attr);
addGetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def?: Value<T, U>
) {
var method = GET + Util._capitalize(attr);

constructor.prototype[method] =
constructor.prototype[method] ||
Expand All @@ -22,15 +80,26 @@ export const Factory = {
};
},

addSetter(constructor, attr, validator?, after?) {
const method = SET + Util._capitalize(attr);
addSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
var method = SET + Util._capitalize(attr);

if (!constructor.prototype[method]) {
Factory.overWriteSetter(constructor, attr, validator, after);
}
},
overWriteSetter(constructor, attr, validator?, after?) {
const method = SET + Util._capitalize(attr);

overWriteSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
var method = SET + Util._capitalize(attr);
constructor.prototype[method] = function (val) {
if (validator && val !== undefined && val !== null) {
val = validator.call(this, val, attr);
Expand All @@ -45,12 +114,13 @@ export const Factory = {
return this;
};
},
addComponentsGetterSetter(
constructor,
attr: string,
components: Array<string>,
validator?: Function,
after?: Function

addComponentsGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
components: ExtractComponents<T, U>,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
const len = components.length,
capitalize = Util._capitalize,
Expand All @@ -76,7 +146,7 @@ export const Factory = {
const oldVal = this.attrs[attr];

if (validator) {
val = validator.call(this, val);
val = validator.call(this, val, attr);
}

if (basicValidator) {
Expand Down Expand Up @@ -106,8 +176,11 @@ export const Factory = {

Factory.addOverloadedGetterSetter(constructor, attr);
},
addOverloadedGetterSetter(constructor, attr) {
const capitalizedAttr = Util._capitalize(attr),
addOverloadedGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U
) {
var capitalizedAttr = Util._capitalize(attr),
setter = SET + capitalizedAttr,
getter = GET + capitalizedAttr;

Expand All @@ -121,7 +194,12 @@ export const Factory = {
return this[getter]();
};
},
addDeprecatedGetterSetter(constructor, attr, def, validator) {
addDeprecatedGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def: Value<T, U>,
validator: ValidatorFunc<Value<T, U>>
) {
Util.error('Adding deprecated ' + attr);

const method = GET + Util._capitalize(attr);
Expand All @@ -139,7 +217,10 @@ export const Factory = {
});
Factory.addOverloadedGetterSetter(constructor, attr);
},
backCompat(constructor, methods) {
backCompat<T extends Constructor>(
constructor: T,
methods: Record<string, string>
) {
Util.each(methods, function (oldMethodName, newMethodName) {
const method = constructor.prototype[newMethodName];
const oldGetter = GET + Util._capitalize(oldMethodName);
Expand All @@ -161,7 +242,7 @@ export const Factory = {
constructor.prototype[oldSetter] = deprecated;
});
},
afterSetFilter(this: Node) {
afterSetFilter(this: Node): void {
this._filterUpToDate = false;
},
};
6 changes: 3 additions & 3 deletions src/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2660,7 +2660,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
rotation: GetSet<number, this>;
zIndex: GetSet<number, this>;

scale: GetSet<Vector2d | undefined, this>;
scale: GetSet<Vector2d, this>;
scaleX: GetSet<number, this>;
scaleY: GetSet<number, this>;
skew: GetSet<Vector2d, this>;
Expand Down Expand Up @@ -3102,7 +3102,7 @@ addGetterSetter(Node, 'offsetY', 0, getNumberValidator());
* node.offsetY(3);
*/

addGetterSetter(Node, 'dragDistance', null, getNumberValidator());
addGetterSetter(Node, 'dragDistance', undefined, getNumberValidator());

/**
* get/set drag distance
Expand Down Expand Up @@ -3193,7 +3193,7 @@ addGetterSetter(Node, 'listening', true, getBooleanValidator());

addGetterSetter(Node, 'preventDefault', true, getBooleanValidator());

addGetterSetter(Node, 'filters', null, function (this: Node, val) {
addGetterSetter(Node, 'filters', undefined, function (this: Node, val) {
this._filterUpToDate = false;
return val;
});
Expand Down
5 changes: 5 additions & 0 deletions src/Shape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,11 @@ export class Shape<
strokeLinearGradientStartPoint: GetSet<Vector2d, this>;
strokeLinearGradientEndPoint: GetSet<Vector2d, this>;
strokeLinearGradientColorStops: GetSet<Array<number | string>, this>;
strokeLinearGradientStartPointX: GetSet<number, this>;
strokeLinearGradientStartPointY: GetSet<number, this>;
strokeLinearGradientEndPointX: GetSet<number, this>;
strokeLinearGradientEndPointY: GetSet<number, this>;
fillRule: GetSet<CanvasFillRule, this>;
}

Shape.prototype._fillFunc = _fillFunc;
Expand Down
48 changes: 24 additions & 24 deletions src/Validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export function alphaComponent(val: number) {
return val;
}

export function getNumberValidator() {
export function getNumberValidator<T>() {
if (Konva.isUnminified) {
return function <T>(val: T, attr: string): T | void {
return function (val: T, attr: string): T {
if (!Util._isNumber(val)) {
Util.warn(
_formatValue(val) +
Expand All @@ -49,11 +49,11 @@ export function getNumberValidator() {
}
}

export function getNumberOrArrayOfNumbersValidator(noOfElements: number) {
export function getNumberOrArrayOfNumbersValidator<T>(noOfElements: number) {
if (Konva.isUnminified) {
return function <T>(val: T, attr: string): T | void {
const isNumber = Util._isNumber(val);
const isValidArray = Util._isArray(val) && val.length == noOfElements;
return function (val: T, attr: string): T {
let isNumber = Util._isNumber(val);
let isValidArray = Util._isArray(val) && val.length == noOfElements;
if (!isNumber && !isValidArray) {
Util.warn(
_formatValue(val) +
Expand All @@ -69,11 +69,11 @@ export function getNumberOrArrayOfNumbersValidator(noOfElements: number) {
}
}

export function getNumberOrAutoValidator() {
export function getNumberOrAutoValidator<T>() {
if (Konva.isUnminified) {
return function <T extends string>(val: T, attr: string): T | void {
const isNumber = Util._isNumber(val);
const isAuto = val === 'auto';
return function (val: T, attr: string): T {
var isNumber = Util._isNumber(val);
var isAuto = val === 'auto';

if (!(isNumber || isAuto)) {
Util.warn(
Expand All @@ -88,9 +88,9 @@ export function getNumberOrAutoValidator() {
}
}

export function getStringValidator() {
export function getStringValidator<T>() {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
return function (val: T, attr: string): T {
if (!Util._isString(val)) {
Util.warn(
_formatValue(val) +
Expand All @@ -104,13 +104,13 @@ export function getStringValidator() {
}
}

export function getStringOrGradientValidator() {
export function getStringOrGradientValidator<T>() {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
return function (val: T, attr: string): T {
const isString = Util._isString(val);
const isGradient =
Object.prototype.toString.call(val) === '[object CanvasGradient]' ||
(val && val.addColorStop);
(val && val['addColorStop']);
if (!(isString || isGradient)) {
Util.warn(
_formatValue(val) +
Expand All @@ -124,9 +124,9 @@ export function getStringOrGradientValidator() {
}
}

export function getFunctionValidator() {
export function getFunctionValidator<T>() {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
return function (val: T, attr: string): T {
if (!Util._isFunction(val)) {
Util.warn(
_formatValue(val) +
Expand All @@ -139,9 +139,9 @@ export function getFunctionValidator() {
};
}
}
export function getNumberArrayValidator() {
export function getNumberArrayValidator<T>() {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
return function (val: T, attr: string): T {
// Retrieve TypedArray constructor as found in MDN (if TypedArray is available)
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#description
const TypedArray = Int8Array ? Object.getPrototypeOf(Int8Array) : null;
Expand Down Expand Up @@ -172,10 +172,10 @@ export function getNumberArrayValidator() {
};
}
}
export function getBooleanValidator() {
export function getBooleanValidator<T>() {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
const isBool = val === true || val === false;
return function (val: T, attr: string): T {
var isBool = val === true || val === false;
if (!isBool) {
Util.warn(
_formatValue(val) +
Expand All @@ -188,9 +188,9 @@ export function getBooleanValidator() {
};
}
}
export function getComponentValidator(components: any) {
export function getComponentValidator<T>(components: string[]) {
if (Konva.isUnminified) {
return function (val: any, attr: string) {
return function (val: T, attr: string): T {
// ignore validation on undefined value, because it will reset to defalt
if (val === undefined || val === null) {
return val;
Expand Down
4 changes: 2 additions & 2 deletions src/filters/Emboss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Factory.addGetterSetter(
Node,
'embossDirection',
'top-left',
null,
undefined,
Factory.afterSetFilter
);
/**
Expand All @@ -190,7 +190,7 @@ Factory.addGetterSetter(
Node,
'embossBlend',
false,
null,
undefined,
Factory.afterSetFilter
);
/**
Expand Down
5 changes: 4 additions & 1 deletion src/shapes/Label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,10 @@ export class Tag extends Shape<TagConfig> {
};
}

pointerDirection: GetSet<'left' | 'top' | 'right' | 'bottom' | 'up' | 'down', this>;
pointerDirection: GetSet<
'left' | 'up' | 'right' | 'down' | typeof NONE,
this
>;
pointerWidth: GetSet<number, this>;
pointerHeight: GetSet<number, this>;
cornerRadius: GetSet<number, this>;
Expand Down
Loading

0 comments on commit 09485ef

Please sign in to comment.