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): Path util typings and refactoring #8787

Merged
merged 48 commits into from
Apr 1, 2023

Conversation

Lazauya
Copy link
Contributor

@Lazauya Lazauya commented Mar 18, 2023

Things in this PR:

  • Created a folder for path utils (path) that includes a type file and a functions file
  • Added types for parsed and string commands, both relative and absolute
    • Functions for determining command type may be redundant, requires review
    • Created regex to match each (cleaned) path command
    • Simplified and "complex" (unsimplified) command types
  • Refactored path parsing to be simpler and more general
    • Removed specific arc edge case
  • Refactored makePathSimpler slightly to be more type friendly
    • Remove support for lowercase z (changed tests to reflect this)
  • Refactored other various other types in path.ts to make code more type-friendly (e.g. TPathSegmentInfo)
  • Changes the PathData type to the more specific TSimplePathData type elsewhere in the code

Rationale:
Properly typing the path parsing is a step towards a fully typed SVG parser. I also want to have real-time feedback for invalid/valid path commands. I had this particular issue when using the DefinitelyTyped library; not only were the signatures for path-related things screwed up, but the path command types were very unhelpful.

@asturur
Copy link
Member

asturur commented Mar 18, 2023

hi @Lazauya ll try to be quick and effective with this PR.
I didn't read it yet, but i have been trying to be super clear with @ShaMan123 too that continuos refactoring is making us stale in a beta stage too long.

I have a couple of things to merge the next hours and then i ll give an eye to this one

@Lazauya
Copy link
Contributor Author

Lazauya commented Mar 18, 2023

@ShaMan123 @asturur This PR only substantially changes one file (and adds another). There is a minor functionality change: lowercase z is not supported. This was to make the code simpler and more uniform. Other than that, all functionality should remain.

src/shapes/Path.ts Outdated Show resolved Hide resolved
src/brushes/PencilBrush.ts Outdated Show resolved Hide resolved
src/cache.ts Outdated Show resolved Hide resolved
src/util/path/path.ts Outdated Show resolved Hide resolved
current[1] += x;
current[2] += y;
// falls through
case 'L':
x = current[1];
y = current[2];
converted = ['L', current[1], current[2]];
Copy link
Member

Choose a reason for hiding this comment

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

i have read through the changes of makePathSimpler and i want to ask you what makes you prefer this converted array approach vs the mutation of the previous array.
Is more verbose.
current was a new array every command so is not a mutation issue. What is it?

Copy link
Contributor Author

@Lazauya Lazauya Mar 18, 2023

Choose a reason for hiding this comment

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

if we left it alone then it complains about not being able to assign 'm' to 'M' and things of that nature, which meant that either we'd need a ton of ugly casting or just plain ts-ignores. You can see the approach with types "just slapped on" more or less in the second commit. I think the current one is the most elegant and easiest to read/understand

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this bit but casting at the top to something loose and then recasting at the bottom to something strict should do the job w/o too much ugliness

Copy link
Contributor

Choose a reason for hiding this comment

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

You can always create a type util that does that for you inline I guess

Copy link
Member

Choose a reason for hiding this comment

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

we should at least reuse the named variables where possible.
converted = ['L', x, y] and there are other cases like this down the file
This is added code for nothing but shouldn't be much and most of it is minifiable

Copy link
Member

Choose a reason for hiding this comment

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

Yes in general i don't like the idea of changing code because TS doesn't like it.
TS main purpose is to help avoid errors, it helps with discovery too, but we shouldn't restrict JS at what TS understand, at least i didn't sign up for that when i decided to try a conversion.

Copy link
Contributor Author

@Lazauya Lazauya Mar 19, 2023

Choose a reason for hiding this comment

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

IDK I'm obviously biased but I still think that my refactoring is easier to follow. Also I'd like to point out that the refactored function is the same number of lines.

Copy link
Contributor

@ShaMan123 ShaMan123 Mar 19, 2023

Choose a reason for hiding this comment

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

Rejoining
I do prefer reconstructing over mutation if nothing is damaging
And here it is much readable IMO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I went ahead and made it use the vars instead of current[n] where possible. I'm still adamant that I think this refactoring is better than doing casting, especially since it's the same number of lines. I agree that sometimes TS is overbearing but I think it's perfectly reasonable in THIS particular case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I think this is the last open conversation. Is this a blocker? Or are we good to go?

src/util/path/path.ts Outdated Show resolved Hide resolved
@asturur
Copy link
Member

asturur commented Mar 19, 2023

Even exacluding the typecheck regexes i get

-rw-r--r--  1 abogazzi  staff  312885 Mar 19 14:30 dist/index.min.js

Now bundle aside i want to make a real point.
Regexes with the /g/ (global) flag have a special behaviour with test and exec.
They restart from the last match.
We build N regexp with global state but then we use ust one of them.
Now i think is more proficuos if we just create the regexp when needed and we keep in our file the source only.
What do you think? i can make that change if you agree.

Example, all of those becomes

- export const reArcCommand = new RegExp(
+ export const reArcCommand = 
  String.raw`(A) (?:${p} ${p} ${p} ([01]) ?([01]) ${p} ${p} ?)+`,
- 'gi'
- );

and in the path code, in the only place where we use

  for (const match of pathString.matchAll(rePathCommand)) {

we do

  const rePathCommandExp = new Regexp(rePathCommand)
  for (const match of pathString.matchAll(rePathCommandExp)) {

thoughts?

@asturur
Copy link
Member

asturur commented Mar 19, 2023

The only real blocker so far is that node 14 doens't like dgi and so we need to find an alternative.
It doesn't seem for the main regex is an issue, so i removed in favor of gi, but we are still using d in one place.

@Lazauya
Copy link
Contributor Author

Lazauya commented Mar 19, 2023

What do you think? i can make that change if you agree.

I think that makes a lot of sense and I agree with the change. I'll look into d alternatives today.

src/util/path/index.ts Outdated Show resolved Hide resolved
src/util/path/index.ts Outdated Show resolved Hide resolved
@asturur
Copy link
Member

asturur commented Mar 20, 2023

@Lazauya let me know when you think the code is done, that i will give another read.

@Lazauya
Copy link
Contributor Author

Lazauya commented Mar 24, 2023

@Lazauya let me know when you think the code is done, that i will give another read.

@asturur I've looked at everything and I think it's ready, feel free to read over again.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would love hearing about CD/DX, how is the app? Was it easy to set up and use?

@asturur
Copy link
Member

asturur commented Mar 24, 2023

@Lazauya i had a busy week, i ll get back here asap.
But the PR looks good

@asturur asturur merged commit 49acaa4 into fabricjs:master Apr 1, 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.

None yet

3 participants