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): Parse transform attribute typing #8878

Merged
merged 11 commits into from
May 3, 2023

Conversation

Lazauya
Copy link
Contributor

@Lazauya Lazauya commented Apr 30, 2023

Some minor typing to move towards a fully-typed parser.
Includes some minor logic changes, meaning simpler regex and smarter parsing.
Removed the superfluous numberRegExStr constant and spruced up the reNum type.

@asturur
Copy link
Member

asturur commented Apr 30, 2023

Seems good so me apart that minor comment.

@Lazauya
Copy link
Contributor Author

Lazauya commented Apr 30, 2023

OK @asturur should be ready now.

@asturur
Copy link
Member

asturur commented May 1, 2023

Good to me, let's wait @ShaMan123 too.

Comment on lines +37 to +41
attributeValue = attributeValue
.replace(new RegExp(`(${reNum})`, 'gi'), ' $1 ')
// replace annoying commas and arbitrary whitespace with single spaces
.replace(/,/gi, ' ')
.replace(/\s+/gi, ' ')
Copy link
Member

Choose a reason for hiding this comment

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

actually, sorry, this part here is duplicated in path. Do we want to do a function util, under utils/internals that clean up the string? so we can also test that the input and output of those 3 asserts combined are always what we want.

Copy link
Member

Choose a reason for hiding this comment

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

it can totally be called removeExtraSpaceAndCommasFromSVGAttributes it doesn't have to be generic or anything like that.

Copy link
Contributor

Choose a reason for hiding this comment

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

If it is used more than once, sure

Copy link
Contributor

Choose a reason for hiding this comment

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

Even if used once

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW why use 2 regexp replace instead of combining the rexep into one with an or command?

Copy link
Member

Choose a reason for hiding this comment

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

i don't know, it could be because we replace first the comma with a 'space' and only then we can clean up multiple spaces. Probably this is safer to follow and a single regexp is a bit more hard to read and be sure it does what it has to do.

Comment on lines +64 to +65
const operation = matchedParams[1];
const args = matchedParams.slice(2).map(parseFloat);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const operation = matchedParams[1];
const args = matchedParams.slice(2).map(parseFloat);
const [ _, operation, ...rawArgs ] = matchedParams;

Would this work?

then

const args = rawArgs.map((arg) => parseFloat(arg));

There is a risk using parseFloat inside a map like that, that we are calling parseFloat as

(value, index, wholeArray) => parseFloat(value, index, wholeArray)

And you never know what happens

Copy link
Contributor

@ShaMan123 ShaMan123 May 1, 2023

Choose a reason for hiding this comment

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

I agree,
Should call parseFloat with no additional params
Regarding spreading, whatever

operation = m[1],
args = m.slice(2).map(parseFloat);
for (const match of attributeValue.matchAll(reTransform)) {
const transformMatch = new RegExp(transform).exec(match[0]);
Copy link
Member

Choose a reason for hiding this comment

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

i never remember how regexp work, in this case can we create the regexp before the loop and just use it for each match[0]?

Copy link
Contributor

@ShaMan123 ShaMan123 May 1, 2023

Choose a reason for hiding this comment

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

Dido.
It never does what I want it to.
And mdn says one thing while chrome does another from what I remember

@asturur
Copy link
Member

asturur commented May 1, 2023

Sorry i got some additional minor comments, feel free to comment if you think some are unnecessary

Copy link
Contributor

@ShaMan123 ShaMan123 left a comment

Choose a reason for hiding this comment

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

Regexp can be great if you know how to.
For me it takes time to trial and error so I don't like it but appreciate the power.
So I can't really review those parts. Unless I dive into it.
My main comment is naming or the signature of the parsing methods. Read more where I commented.
And another thing about combining replacers.

*/
type TMatScale = [x: number] | [x: number, y: number];

export function scaleMatrix(matrix: TMat2D, args: TMatScale | number[]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to return a matrix from these methods instead of passing one and mutating it?
Better because of isolation

Copy link
Contributor

Choose a reason for hiding this comment

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

At least naming should imply it
setScaleFromSVGMatrix or something

Copy link
Member

Choose a reason for hiding this comment

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

So i think the code is very old and bad.
I would argue we fix it in a followup since @Lazauya made a work on types and regex and i think we can focus on that.
But yes, definetely this matrix loop is wrong, it has a mutable array that gets renewed evey loop with a new one, in a let. Is just bad code.

Comment on lines +75 to +81
export type TMat2D = [
a: number,
b: number,
c: number,
d: number,
e: number,
f: number
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice

Comment on lines +37 to +41
attributeValue = attributeValue
.replace(new RegExp(`(${reNum})`, 'gi'), ' $1 ')
// replace annoying commas and arbitrary whitespace with single spaces
.replace(/,/gi, ' ')
.replace(/\s+/gi, ' ')
Copy link
Contributor

Choose a reason for hiding this comment

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

BTW why use 2 regexp replace instead of combining the rexep into one with an or command?

@asturur
Copy link
Member

asturur commented May 3, 2023

@Lazauya i want to publish a new beta i m merging this and following up myself for the minor changes requested

@asturur asturur merged commit dc644fb into fabricjs:master May 3, 2023
@asturur asturur mentioned this pull request May 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants